diff --git a/ci-scripts/Jenkinsfile-trig-nsa b/ci-scripts/Jenkinsfile-trig-nsa
index 8f623ffb057cbec3cdcf312f7c8f9c9ae1c9b734..44527a1a383d6af80812e0949e763c3ecde9fb07 100644
--- a/ci-scripts/Jenkinsfile-trig-nsa
+++ b/ci-scripts/Jenkinsfile-trig-nsa
@@ -48,21 +48,30 @@ pipeline {
                         COMMIT_ID=COMMIT_ID.trim()
                         echo "Testing NSA on : ${MR} ${SRC_BRANCH} ${COMMIT_ID}"
                         //calling NSA sub job
-                        build job: "RAN-NSA-Mini-Module", wait : false, propagate : false, parameters: [
+                        build job: "RAN-NSA-Mini-Module", wait : true, propagate : false, parameters: [
                             string(name: 'eNB_MR', value: String.valueOf(MR)),                          
                             string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
                             string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
                             string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
                             booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
                         ]
-                        //calling Benetel sub job
-                        //build job: "RAN-CI-BENETEL", wait : false, propagate : false, parameters: [
-                        //    string(name: 'eNB_MR', value: String.valueOf(MR)),                          
-                        //    string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
-                        //    string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
-                        //    string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
-                        //    booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
-                        //]
+                        //calling NSA long sub job
+                        build job: "RAN-NSA-Mini-Module-Long", wait : true, propagate : false, parameters: [
+                            string(name: 'eNB_MR', value: String.valueOf(MR)),                          
+                            string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
+                            string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
+                            string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
+                            booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
+                        ]
+                        //calling NSA attach/detach job
+                        build job: "RAN-NSA-Mini-Module-Attach-Detach", wait : true, propagate : false, parameters: [
+                            string(name: 'eNB_MR', value: String.valueOf(MR)),                          
+                            string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
+                            string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
+                            string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
+                            booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
+                        ]
+
                     }
                 }                                  
             }   
diff --git a/ci-scripts/cls_module_ue.py b/ci-scripts/cls_module_ue.py
index cb5c81e271d158391cde283c36035fd9a224fefb..75b628fd1f4333086970d4e4b8cc0c10281b27ba 100644
--- a/ci-scripts/cls_module_ue.py
+++ b/ci-scripts/cls_module_ue.py
@@ -50,7 +50,8 @@ class Module_UE:
 			setattr(self, k, v)
 		self.UEIPAddress = ""
 		#dictionary linking command names and related module scripts
-		self.cmd_dict= {"wup": self.WakeupScript,"detach":self.DetachScript}#dictionary of function scripts		
+		self.cmd_dict= {"wup": self.WakeupScript,"detach":self.DetachScript}#dictionary of function scripts
+		self.ue_trace=''		
 
 
 
@@ -75,9 +76,10 @@ class Module_UE:
 			logging.debug('Starting ' + self.Process['Name'])
 			mySSH = sshconnection.SSHConnection()
 			mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
-			mySSH.command('echo ' + self.HostPassword + ' | sudo -S ' + self.Process['Cmd'] + ' &','\$',5)
+			mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S ' + self.Process['Cmd'] + ' &','\$',5)
 			mySSH.close()
 			#checking the process
+			time.sleep(5)
 			HOST=self.HostIPAddress
 			COMMAND="ps aux | grep " + self.Process['Name'] + " | grep -v grep "
 			logging.debug(COMMAND)
@@ -130,13 +132,14 @@ class Module_UE:
 				return -1
 
 	def EnableTrace(self):
-		mySSH = sshconnection.SSHConnection()
-		mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
-		#delete old artifacts
-		mySSH.command('echo ' + self.HostPassword + ' | sudo -S rm -rf ci_qlog','\$',5)
-		#start Trace, artifact is created in home dir
-		mySSH.command('echo $USER; nohup sudo -E QLog/QLog -s ci_qlog -f NR5G.cfg &','\$', 5)
-		mySSH.close()
+		if self.ue_trace=="yes":
+			mySSH = sshconnection.SSHConnection()
+			mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
+			#delete old artifacts
+			mySSH.command('echo ' + self.HostPassword + ' | sudo -S rm -rf ci_qlog','\$',5)
+			#start Trace, artifact is created in home dir
+			mySSH.command('echo $USER; nohup sudo -E QLog/QLog -s ci_qlog -f NR5G.cfg &','\$', 5)
+			mySSH.close()
 
 	def DisableTrace(self):
 		mySSH = sshconnection.SSHConnection()
@@ -153,18 +156,20 @@ class Module_UE:
 
 
 	def LogCollect(self):
-		mySSH = sshconnection.SSHConnection()
-		mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
-		#archive qlog to USB stick in /media/usb-drive/ci_qlogs with datetime suffix
-		now=datetime.now()
-		now_string = now.strftime("%Y%m%d-%H%M")
-		source='ci_qlog'
-		destination='/media/usb-drive/ci_qlogs/ci_qlog_'+now_string+'.zip'
-		#qlog artifact is zipped into the target folder
-		mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S zip -r '+destination+' '+source+' &','\$', 10)
-		mySSH.close()
-		#post action : log cleaning to make sure enough space is reserved for the next run
-		Log_Mgt=cls_log_mgt.Log_Mgt(self.HostIPAddress, self.HostPassword, "/media/usb-drive/ci_qlogs")
-		Log_Mgt.LogRotation()
-
+		if self.ue_trace=="yes":
+			mySSH = sshconnection.SSHConnection()
+			mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
+			#archive qlog to USB stick in /media/usb-drive/ci_qlogs with datetime suffix
+			now=datetime.now()
+			now_string = now.strftime("%Y%m%d-%H%M")
+			source='ci_qlog'
+			destination='/media/usb-drive/ci_qlogs/ci_qlog_'+now_string+'.zip'
+			#qlog artifact is zipped into the target folder
+			mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S zip -r '+destination+' '+source+' &','\$', 10)
+			mySSH.close()
+			#post action : log cleaning to make sure enough space is reserved for the next run
+			Log_Mgt=cls_log_mgt.Log_Mgt(self.HostIPAddress, self.HostPassword, "/media/usb-drive/ci_qlogs")
+			Log_Mgt.LogRotation()
+		else:
+			destination=""
 		return destination
diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py
index d3d1d70c1356beaa45f471d222dcd66a5315b852..377592781df1c36baba3f730d5f51b0536e165e5 100644
--- a/ci-scripts/cls_oaicitest.py
+++ b/ci-scripts/cls_oaicitest.py
@@ -160,6 +160,7 @@ class OaiCiTest():
 		self.air_interface=''
 		self.expectedNbOfConnectedUEs = 0
 		self.ue_id = '' #used for module identification
+		self.ue_trace ='' #used to enable QLog trace for Module UE, passed to Module UE object at InitializeUE()
 
 
 	def BuildOAIUE(self,HTML):
@@ -367,7 +368,7 @@ class OaiCiTest():
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
-	def InitializeUE(self,HTML,RAN,EPC, COTS_UE, InfraUE):
+	def InitializeUE(self,HTML,RAN,EPC, COTS_UE, InfraUE,ue_trace):
 		if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB
 			if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
 				HELP.GenericHelp(CONST.Version)
@@ -386,6 +387,7 @@ class OaiCiTest():
 		else: #if an ID is specified, it is a module from the yaml infrastructure file
 			#RH
 			Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
+			Module_UE.ue_trace=ue_trace
 			is_module=Module_UE.CheckCMProcess()
 			if is_module:
 				Module_UE.EnableTrace()
@@ -586,7 +588,7 @@ class OaiCiTest():
 				SSH.command('ifconfig oaitun_ue1', '\$', 4)
 				SSH.command('ifconfig oaitun_ue1', '\$', 4)
 				# ifconfig output is different between ubuntu 16 and ubuntu 18
-				result = re.search('inet addr:1|inet 1', SSH.getBefore())
+				result = re.search('inet addr:[0-9]|inet [0-9]', SSH.getBefore())
 				if result is not None:
 					logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m')
 					tunnelInterfaceStatus = True
@@ -994,38 +996,55 @@ class OaiCiTest():
 			for job in multi_jobs:
 				job.join()
 
-		if (status_queue.empty()):
-			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
-			return
-		else:
-			attach_status = True
-			html_queue = SimpleQueue()
-			while (not status_queue.empty()):
-				count = status_queue.get()
-				if (count < 0):
-					attach_status = False
-				device_id = status_queue.get()
-				message = status_queue.get()
-				if (count < 0):
-					html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + '</pre>'
-				else:
-					html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + ' in ' + str(count + 2) + ' seconds</pre>'
-				html_queue.put(html_cell)
-			if (attach_status):
-				cnt = 0
-				while cnt < len(self.UEDevices):
-					if self.UEDevicesStatus[cnt] == CONST.UE_STATUS_ATTACHING:
-						self.UEDevicesStatus[cnt] = CONST.UE_STATUS_ATTACHED
-					cnt += 1
-				HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
-				result = re.search('T_stdout', str(RAN.Initialize_eNB_args))
-				if result is not None:
-					logging.debug('Waiting 5 seconds to fill up record file')
-					time.sleep(5)
+			if (status_queue.empty()):
+				HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
+				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
+				return
 			else:
-				HTML.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue)
+				attach_status = True
+				html_queue = SimpleQueue()
+				while (not status_queue.empty()):
+					count = status_queue.get()
+					if (count < 0):
+						attach_status = False
+					device_id = status_queue.get()
+					message = status_queue.get()
+					if (count < 0):
+						html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + '</pre>'
+					else:
+						html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + ' in ' + str(count + 2) + ' seconds</pre>'
+					html_queue.put(html_cell)
+				if (attach_status):
+					cnt = 0
+					while cnt < len(self.UEDevices):
+						if self.UEDevicesStatus[cnt] == CONST.UE_STATUS_ATTACHING:
+							self.UEDevicesStatus[cnt] = CONST.UE_STATUS_ATTACHED
+						cnt += 1
+					HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
+					result = re.search('T_stdout', str(RAN.Initialize_eNB_args))
+					if result is not None:
+						logging.debug('Waiting 5 seconds to fill up record file')
+						time.sleep(5)
+				else:
+					HTML.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue)
+					self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
+
+		else: #if an ID is specified, it is a module from the yaml infrastructure file
+			#Attention, as opposed to InitializeUE, the connect manager process is not checked as it is supposed to be active already
+			#only 1- module wakeup, 2- check IP address
+			Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
+			Module_UE.Command("wup")
+			logging.debug("Waiting for IP address to be assigned")
+			time.sleep(20)
+			logging.debug("Retrieve IP address")
+			status=Module_UE.GetModuleIPAddress()
+			if status==0:
+				HTML.CreateHtmlTestRow(Module_UE.UEIPAddress, 'OK', CONST.ALL_PROCESSES_OK)	
+				logging.debug('UE IP addresss : '+ Module_UE.UEIPAddress)
+			else: #status==-1 failed to retrieve IP address
+				HTML.CreateHtmlTestRow('N/A', 'KO', CONST.UE_IP_ADDRESS_ISSUE)
 				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
+				return					
 
 	def DetachUE_common(self, device_id, idx,COTS_UE):
 		try:
@@ -1084,10 +1103,7 @@ class OaiCiTest():
 		else:#if an ID is specified, it is a module from the yaml infrastructure file
 			Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
 			Module_UE.Command("detach")
-			Module_UE.DisableTrace()
-			Module_UE.DisableCM()
-			archive_destination=Module_UE.LogCollect()
-			HTML.CreateHtmlTestRow('QLog at : '+archive_destination, 'OK', CONST.ALL_PROCESSES_OK)	
+			HTML.CreateHtmlTestRow('NA', 'OK', CONST.ALL_PROCESSES_OK)	
 				
 							
 
@@ -2248,7 +2264,7 @@ class OaiCiTest():
 			SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
 			#send for analysis
 			filename='iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
-			self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, self.iperf_args,filename,1)		
+			self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, self.iperf_args,filename,1)
 		else :
 			logging.debug("Incorrect or missing IPERF direction in XML")
 
@@ -3088,20 +3104,32 @@ class OaiCiTest():
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
-	def TerminateUE(self,HTML,COTS_UE):
-		terminate_ue_flag = False
-		self.GetAllUEDevices(terminate_ue_flag)
-		multi_jobs = []
-		i = 0
-		for device_id in self.UEDevices:
-			p = Process(target= self.TerminateUE_common, args = (device_id,i,COTS_UE,))
-			p.daemon = True
-			p.start()
-			multi_jobs.append(p)
-			i += 1
-		for job in multi_jobs:
-			job.join()
-		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+	def TerminateUE(self,HTML,COTS_UE,InfraUE,ue_trace):
+		if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB
+			terminate_ue_flag = False
+			self.GetAllUEDevices(terminate_ue_flag)
+			multi_jobs = []
+			i = 0
+			for device_id in self.UEDevices:
+				p = Process(target= self.TerminateUE_common, args = (device_id,i,COTS_UE,))
+				p.daemon = True
+				p.start()
+				multi_jobs.append(p)
+				i += 1
+			for job in multi_jobs:
+				job.join()
+			HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+		else: #if an ID is specified, it is a module from the yaml infrastructure file
+			Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
+			Module_UE.ue_trace=ue_trace
+			Module_UE.Command("detach")	
+			Module_UE.DisableTrace()
+			Module_UE.DisableCM()
+			archive_destination=Module_UE.LogCollect()
+			if Module_UE.ue_trace=='yes':
+				HTML.CreateHtmlTestRow('QLog at : '+archive_destination, 'OK', CONST.ALL_PROCESSES_OK)
+			else:
+				HTML.CreateHtmlTestRow('QLog trace is disabled', 'OK', CONST.ALL_PROCESSES_OK)			
 
 	def TerminateOAIUE(self,HTML,RAN,COTS_UE,EPC, InfraUE):
 		SSH = sshconnection.SSHConnection()
@@ -3158,20 +3186,13 @@ class OaiCiTest():
 			HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def AutoTerminateUEandeNB(self,HTML,RAN,COTS_UE,EPC,InfraUE):
-		if self.ue_id!='':
-			Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
-			Module_UE.Command("detach")
-			Module_UE.DisableTrace()
-			Module_UE.DisableCM()
-			archive_destination=Module_UE.LogCollect()
-			HTML.CreateHtmlTestRow('QLog at : '+archive_destination, 'OK', CONST.ALL_PROCESSES_OK)	
 		if (self.ADBIPAddress != 'none'):
 			self.testCase_id = 'AUTO-KILL-UE'
 			HTML.testCase_id=self.testCase_id
 			self.desc = 'Automatic Termination of UE'
 			HTML.desc='Automatic Termination of UE'
 			self.ShowTestID()
-			self.TerminateUE(HTML,COTS_UE)
+			self.TerminateUE(HTML,COTS_UE,InfraUE,self.ue_trace)
 		if (self.Initialize_OAI_UE_args != ''):
 			self.testCase_id = 'AUTO-KILL-OAI-UE'
 			HTML.testCase_id=self.testCase_id
diff --git a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf
index 056c4bdb6a302badc04481bb11d0f85480ffcc4b..fff3cd1b9aac11df2b9f76c891220fb0365dbb4e 100644
--- a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf
@@ -244,7 +244,7 @@ MACRLCs = (
 THREAD_STRUCT = (
   {
     parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
-    worker_config   = "ENABLE";
+    worker_config   = "WORKER_ENABLE";
   }
 );
 
diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpb210.conf
new file mode 100644
index 0000000000000000000000000000000000000000..494be845a694c5b3b17d913c4f8ec71ba4ea4e62
--- /dev/null
+++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpb210.conf
@@ -0,0 +1,297 @@
+Active_gNBs = ( "gNB-Eurecom-DU");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+gNBs =
+(
+ {
+    ////////// Identification parameters:
+    gNB_ID    =  0xe00;
+    gNB_name  =  "gNB-Eurecom-DU";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  1;
+    plmn_list = ({
+                  mcc = 222;
+                  mnc = 01;
+                  mnc_length = 2;
+                  snssaiList = (
+                    {
+                      sst = 1;
+                      sd  = 0x1; // 0 false, else true
+                    },
+                    {
+                      sst = 1;
+                      sd  = 0x112233; // 0 false, else true
+                    }
+                  );
+
+                  });
+
+    nr_cellid = 12345678L;
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
+
+     pdcch_ConfigSIB1 = (
+      {
+        controlResourceSetZero = 12;
+        searchSpaceZero = 0;
+      }
+      );
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                             = 641280;
+      dl_frequencyBand                                                 = 78;
+      # this is 3600 MHz
+      dl_absoluteFrequencyPointA                                       = 640008;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        dl_subcarrierSpacing                                           = 1;
+        dl_carrierBandwidth                                            = 106;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=27,L=48 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                               = 12952; # 6366 12925 12956 28875 12952
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialDLBWPsubcarrierSpacing                                   = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                              = 12;
+        initialDLBWPsearchSpaceZero                                     = 0;
+      #pdsch-ConfigCommon
+        #pdschTimeDomainAllocationList (up to 16 entries)
+        initialDLBWPk0_0                    = 0;  #for DL slot
+        initialDLBWPmappingType_0           = 0;  #0=typeA,1=typeB
+        initialDLBWPstartSymbolAndLength_0  = 40; #this is SS=1,L=13
+
+        initialDLBWPk0_1                    = 0;  #for mixed slot
+        initialDLBWPmappingType_1           = 0;
+        initialDLBWPstartSymbolAndLength_1  = 57; #this is SS=1,L=5
+
+  #uplinkConfigCommon
+     #frequencyInfoUL
+      ul_frequencyBand                                              = 78;
+      #scs-SpecificCarrierList
+      ul_offstToCarrier                                             = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      ul_subcarrierSpacing                                          = 1;
+      ul_carrierBandwidth                                           = 106;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                            = 12952;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialULBWPsubcarrierSpacing                               = 1;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+          prach_msg1_FDM                                            = 0;
+          prach_msg1_FrequencyStart                                 = 0;
+          zeroCorrelationZoneConfig                                 = 13;
+          preambleReceivedTargetPower                               = -96;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+          preambleTransMax                                          = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+        powerRampingStep                                            = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+        ra_ResponseWindow                                           = 4;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 14;
+#ra_ContentionResolutionTimer
+#(0..7) 8,16,24,32,40,48,56,64
+        ra_ContentionResolutionTimer                                = 7;
+        rsrp_ThresholdSSB                                           = 19;
+#prach-RootSequenceIndex_PR
+#1 = 839, 2 = 139
+        prach_RootSequenceIndex_PR                                  = 2;
+        prach_RootSequenceIndex                                     = 1;
+        # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
+        #
+        msg1_SubcarrierSpacing                                      = 1,
+# restrictedSetConfig
+# 0=unrestricted, 1=restricted type A, 2=restricted type B
+        restrictedSetConfig                                         = 0,
+
+      # pusch-ConfigCommon (up to 16 elements)
+        initialULBWPk2_0                      = 6;  # used for UL slot
+        initialULBWPmappingType_0             = 1
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 6;  # used for mixed slot
+        initialULBWPmappingType_1             = 1;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=0 L=12
+
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
+        initialULBWPmappingType_2             = 1;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
+
+        msg3_DeltaPreamble                                          = 1;
+        p0_NominalWithGrant                                         =-90;
+
+# pucch-ConfigCommon setup :
+# pucchGroupHopping
+# 0 = neither, 1= group hopping, 2=sequence hopping
+        pucchGroupHopping                                           = 0;
+        hoppingId                                                   = 40;
+        p0_nominal                                                  = -90;
+# ssb_PositionsInBurs_BitmapPR
+# 1=short, 2=medium, 3=long
+      ssb_PositionsInBurst_PR                                       = 2;
+      ssb_PositionsInBurst_Bitmap                                   = 1;
+
+# ssb_periodicityServingCell
+# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
+      ssb_periodicityServingCell                                    = 2;
+
+# dmrs_TypeA_position
+# 0 = pos2, 1 = pos3
+      dmrs_TypeA_Position                                           = 0;
+
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      subcarrierSpacing                                             = 1;
+
+
+  #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      referenceSubcarrierSpacing                                    = 1;
+      # pattern1
+      # dl_UL_TransmissionPeriodicity
+      # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+      dl_UL_TransmissionPeriodicity                                 = 6;
+      nrofDownlinkSlots                                             = 7;
+      nrofDownlinkSymbols                                           = 6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4;
+
+      ssPBCH_BlockPower                                             = -25;
+  }
+
+  );
+
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    amf_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+
+    NETWORK_INTERFACES :
+    {
+        GNB_INTERFACE_NAME_FOR_NG_AMF            = "eth0";
+        GNB_IPV4_ADDRESS_FOR_NG_AMF              = "CI_GNB_IP_ADDR";
+        GNB_INTERFACE_NAME_FOR_NGU               = "eth0";
+        GNB_IPV4_ADDRESS_FOR_NGU                 = "CI_GNB_IP_ADDR";
+        GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+
+  }
+);
+
+MACRLCs = (
+	{
+	num_cc = 1;
+	tr_s_preference = "local_L1";
+	tr_n_preference = "local_RRC";
+        }
+);
+
+L1s = (
+    {
+	num_cc = 1;
+	tr_n_preference = "local_mac";
+	pusch_proc_threads = 8;
+    }
+);
+
+RUs = (
+    {
+       local_rf       = "yes"
+         nb_tx          = 1
+         nb_rx          = 1
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 114;
+         eNB_instances  = [0];
+         #beamforming 1x4 matrix:
+         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+         clock_src = "internal";
+    }
+);
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_SINGLE_THREAD";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+rfsimulator :
+{
+    serveraddr = "server";
+    serverport = "4043";
+    options = (); #("saviq"); or/and "chanmod"
+    modelname = "AWGN";
+    IQfile = "/tmp/rfsimulator.iqs";
+};
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+       ngap_log_level                         ="debug";
+       ngap_log_verbosity                     ="medium";
+    };
+
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
index 5838e9699915355f2a85917d9eb82434be01aaa8..205922af0c25b6a87766bffd8c80cf7bb14db4d3 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
@@ -120,11 +120,11 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 2;  # used for UL slot
+        initialULBWPk2_0                      = 6;  # used for UL slot
         initialULBWPmappingType_0             = 1
         initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
 
-        initialULBWPk2_1                      = 2;  # used for mixed slot
+        initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
         initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index cbd323366b433981a326b522c8812ce46186b537..0718ee63969f5634fff3d578c8d78505cc9cbd5e 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -197,6 +197,7 @@ def GetParametersFromXML(action):
 
 	elif action == 'Initialize_UE':
 		ue_id = test.findtext('id')
+		CiTestObj.ue_trace=test.findtext('UE_Trace')#temporary variable, to be passed to Module_UE in Initialize_UE call
 		if (ue_id is None):
 			CiTestObj.ue_id = ""
 		else:
@@ -210,12 +211,25 @@ def GetParametersFromXML(action):
 			CiTestObj.ue_id = ue_id
 
 	elif action == 'Attach_UE':
+		ue_id = test.findtext('id')
+		if (ue_id is None):
+			CiTestObj.ue_id = ""
+		else:
+			CiTestObj.ue_id = ue_id
 		nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach')
 		if (nbMaxUEtoAttach is None):
 			CiTestObj.nbMaxUEtoAttach = -1
 		else:
 			CiTestObj.nbMaxUEtoAttach = int(nbMaxUEtoAttach)
 
+	elif action == 'Terminate_UE':
+		ue_id = test.findtext('id')
+		if (ue_id is None):
+			CiTestObj.ue_id = ""
+		else:
+			CiTestObj.ue_id = ue_id
+
+
 	elif action == 'CheckStatusUE':
 		expectedNBUE = test.findtext('expectedNbOfConnectedUEs')
 		if (expectedNBUE is None):
@@ -469,7 +483,7 @@ elif re.match('^TerminateUE$', mode, re.IGNORECASE):
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	signal.signal(signal.SIGUSR1, receive_signal)
-	CiTestObj.TerminateUE(HTML,COTS_UE)
+	CiTestObj.TerminateUE(HTML,COTS_UE,InfraUE,CiTestObj.ue_trace)
 elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE):
 	if CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '':
 		HELP.GenericHelp(CONST.Version)
@@ -714,9 +728,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 				elif action == 'Terminate_eNB':
 					RAN.TerminateeNB(HTML, EPC)
 				elif action == 'Initialize_UE':
-					CiTestObj.InitializeUE(HTML,RAN, EPC, COTS_UE, InfraUE)
+					CiTestObj.InitializeUE(HTML,RAN, EPC, COTS_UE, InfraUE, CiTestObj.ue_trace)
 				elif action == 'Terminate_UE':
-					CiTestObj.TerminateUE(HTML,COTS_UE)
+					CiTestObj.TerminateUE(HTML,COTS_UE, InfraUE, CiTestObj.ue_trace)
 				elif action == 'Attach_UE':
 					CiTestObj.AttachUE(HTML,RAN,EPC,COTS_UE,InfraUE)
 				elif action == 'Detach_UE':
diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh
index 105c95786f5a3c73a039aeb9c4480b70f22863c4..7290507b4e4f52487207764191794f672489e366 100755
--- a/ci-scripts/reportTestLocally.sh
+++ b/ci-scripts/reportTestLocally.sh
@@ -748,6 +748,82 @@ function report_test {
         echo "        <th>Statistics</th>" >> ./test_simulator_results.html
         echo "      </tr>" >> ./test_simulator_results.html
 
+        #SA
+        EPC_CONFIGS=("noS1")
+        TRANS_MODES=("tdd")
+        FR_MODE=("SA")
+        BW_CASES=(106)
+        for CN_CONFIG in ${EPC_CONFIGS[@]}
+        do
+          for TMODE in ${TRANS_MODES[@]}
+          do
+            for BW in ${BW_CASES[@]}
+            do
+                echo "      <tr bgcolor = \"#8FBC8F\" >" >> ./test_simulator_results.html
+                if [[ $CN_CONFIG =~ .*wS1.* ]]
+                then
+                    echo "          <td align = \"center\" colspan = 4 >Test with EPC (aka withS1): ${TMODE} -- ${BW}PRB -- ${FR_MODE}</td>" >> ./test_simulator_results.html
+                else
+                    echo "          <td align = \"center\" colspan = 4 >Test without EPC (aka noS1): ${TMODE} -- ${BW}PRB -- ${FR_MODE}</td>" >> ./test_simulator_results.html
+                fi
+                echo "      </tr>" >> ./test_simulator_results.html
+
+
+                #SA test (--sa option)
+
+                SA_ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb_sa_test.log
+                SA_UE_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_ue_sa_test.log
+                if [ -f $RA_ENB_LOG ] && [ -f $RA_UE_LOG ]
+                then
+                    #get rid of full path
+                    NAME_ENB=`echo $SA_ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"`
+                    NAME_UE=`echo $SA_UE_LOG | sed -e "s#$ARCHIVES_LOC/##"`
+                    echo "      <tr>" >> ./test_simulator_results.html
+                    echo "        <td>$NAME_ENB --- $NAME_UE</td>" >> ./test_simulator_results.html
+                    echo "        <td>Check if SA proc succeeded</td>" >> ./test_simulator_results.html
+
+
+                    RRC_CHECK=`egrep -c "Received rrcSetupComplete" $SA_ENB_LOG`
+                    CBRA_CHECK=`egrep -c "Received Ack of RA-Msg4\. CBRA procedure succeeded" $SA_ENB_LOG`
+                    SIB1_CHECK=`egrep -c "SIB1 decoded" $SA_UE_LOG`
+
+
+                    if [ $RRC_CHECK -gt 0 ] && [ $CBRA_CHECK -gt 0 ] && [ $SIB1_CHECK -gt 0 ]
+                    then
+                        echo "        <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html
+                    else
+                        echo "        <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html
+                    fi
+
+                    echo "        <td><pre>" >> ./test_simulator_results.html
+                    if [ $RRC_CHECK -gt 0 ]
+                    then
+                        echo "<font color = \"blue\">- Received rrcSetupComplete OK</font>" >> ./test_simulator_results.html
+                    else
+                        echo "<font color = \"red\"><b>- Received rrcSetupComplete KO</b></font>" >> ./test_simulator_results.html
+                    fi
+                    if [ $CBRA_CHECK -gt 0 ]
+                    then
+                        echo "<font color = \"blue\">- CBRA procedure succeeded OK</font>" >> ./test_simulator_results.html
+                    else
+                        echo "<font color = \"red\"><b>- CBRA procedure succeeded KO</b></font>" >> ./test_simulator_results.html
+                    fi
+                    if [ $SIB1_CHECK -gt 0 ]
+                    then
+                        echo "<font color = \"blue\">- SIB1 decoded OK</font>" >> ./test_simulator_results.html
+                    else
+                        echo "<font color = \"red\"><b>- SIB1 decoded KO</b></font>" >> ./test_simulator_results.html
+                    fi
+
+                    echo "        </pre></td>" >> ./test_simulator_results.html
+                    echo "      </tr>" >> ./test_simulator_results.html
+                fi
+
+            done
+          done
+        done
+
+        
         EPC_CONFIGS=("noS1")
         TRANS_MODES=("tdd")
         FR_MODE=("FR2")
diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index b9a1adb6af5f5306594fc8481886a1a7355525f2..058d64b0ba21a33b679f66bf4b4e85ee176924f6 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -277,6 +277,46 @@ function check_ping_result {
 }
 
 
+function check_sa_result {
+    local LOC_GNB_LOG=$1
+    local LOC_UE_LOG=$2
+
+    #if log files exist
+    if [ -f $LOC_GNB_LOG ] && [ -f $LOC_UE_LOG ]
+    then
+
+        #gNB  SA test
+        #console check
+        echo "Checking gNB Log for SA success"
+        egrep "Received rrcSetupComplete" $1
+        egrep "Received Ack of RA-Msg4\. CBRA procedure succeeded" $1
+
+        #script check
+        local RRC_CHECK=`egrep -c "Received rrcSetupComplete" $1`        
+        local CBRA_CHECK=`egrep -c "Received Ack of RA-Msg4\. CBRA procedure succeeded" $1`
+
+        #UE SA test
+        #console check
+        echo 'Checking UE Log for SA success'
+        egrep "SIB1 decoded" $2
+        #script check
+        local SIB1_CHECK=`egrep -c "SIB1 decoded" $2`
+
+        #generate status
+        if [ $RRC_CHECK -eq 0 ] || [ $CBRA_CHECK -eq 0 ] || [ $SIB1_CHECK -eq 0 ]
+        then
+            SA_STATUS=-1
+            echo "SA test FAILED, could not find the markers"
+        fi
+    #case where log files do not exist
+    else
+        echo "SA test log files not present"
+        SA_STATUS=-1        
+    fi
+
+}
+
+
 function check_ra_result {
     local LOC_GNB_LOG=$1
     local LOC_UE_LOG=$2
@@ -1215,8 +1255,8 @@ function start_rf_sim_gnb {
     local LOC_CONF_FILE=$5
     # 1 is with S1 and 0 without S1 aka noS1
     local LOC_S1_CONFIGURATION=$6
-    #LOC_RA_TEST=1 will run the RA test check
-    local LOC_RA_TEST=$7
+    #LOC_RA_SA_TEST=1 will run the RA test check ; =2 will run the SA test
+    local LOC_RA_SA_TEST=$7
 
     if [ -e rbconfig.raw ]; then rm -f rbconfig.raw; fi
     if [ -e reconfig.raw ]; then rm -f reconfig.raw; fi
@@ -1239,11 +1279,14 @@ function start_rf_sim_gnb {
     echo "sudo rm -f r*config.raw" >> $1
     if [ $LOC_S1_CONFIGURATION -eq 0 ]
     then
-        if [ $LOC_RA_TEST -eq 0 ] #no RA test => use --phy-test option
+        if [ $LOC_RA_SA_TEST -eq 0 ] #no RA test => use --phy-test option
         then
             echo "echo \"./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --noS1 --nokrnmod 1 --rfsim --phy-test --lowmem --noS1\" > ./my-nr-softmodem-run.sh " >> $1
-        else #RA test => use --do-ra option
+        elif [ $LOC_RA_SA_TEST -eq 1 ] #RA test => use --do-ra option
+        then
             echo "echo \"./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --rfsim --do-ra --lowmem --noS1\" > ./my-nr-softmodem-run.sh " >> $1
+        else #SA test => use --sa option
+            echo "echo \"./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --rfsim --sa --lowmem \" > ./my-nr-softmodem-run.sh " >> $1
         fi
     fi
     echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1
@@ -1279,7 +1322,7 @@ function start_rf_sim_gnb {
     fi
 
     # check noS1 config only outside RA test (as it does not support noS1)
-    if [ $LOC_S1_CONFIGURATION -eq 0 ] && [ $LOC_RA_TEST -eq 0 ]
+    if [ $LOC_S1_CONFIGURATION -eq 0 ] && [ $LOC_RA_SA_TEST -eq 0 ]
     then
         echo "ifconfig oaitun_enb1 | egrep -c \"inet addr\"" > $1
         # Checking oaitun_enb1 interface has now an IP address
@@ -1324,8 +1367,8 @@ function start_rf_sim_nr_ue {
     local LOC_FREQUENCY=$6
     # 1 is with S1 and 0 without S1 aka noS1
     local LOC_S1_CONFIGURATION=$7
-    #LOC_RA_TEST=1 will run the RA test check
-    local LOC_RA_TEST=$8
+    #LOC_RA_SA_TEST=1 will run the RA test check ; =2 will run the SA test
+    local LOC_RA_SA_TEST=$8
 
     # Copy the RAW files from the gNB run
     scp -o StrictHostKeyChecking=no rbconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp
@@ -1342,11 +1385,14 @@ function start_rf_sim_nr_ue {
     echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
     if [ $LOC_S1_CONFIGURATION -eq 0 ]
     then
-        if [ $LOC_RA_TEST -eq 0 ] #no RA test => use --phy-test option
+        if [ $LOC_RA_SA_TEST -eq 0 ] #no RA test => use --phy-test option
         then
             echo "echo \"./nr-uesoftmodem --nokrnmod 1 --rfsim --phy-test --rrc_config_path /home/ubuntu/tmp/cmake_targets/ran_build/build/ --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1
-        else #RA test => use --do-ra option
+        elif [ $LOC_RA_SA_TEST -eq 1 ] #RA test => use --do-ra option
+        then
             echo "echo \"./nr-uesoftmodem --rfsim --do-ra --log_config.global_log_options level,nocolor --rrc_config_path /home/ubuntu/tmp/cmake_targets/ran_build/build/\" > ./my-nr-softmodem-run.sh " >> $1
+        else #SA test => use --sa option
+            echo "echo \"./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --sa --log_config.global_log_options level,nocolor\" > ./my-nr-softmodem-run.sh " >> $1
         fi
     fi
     echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1
@@ -1381,7 +1427,7 @@ function start_rf_sim_nr_ue {
         echo "RF-SIM NR-UE is sync'ed w/ gNB"
     fi
     # Checking oaitun_ue1 interface has now an IP address (only outside RA test)
-    if [ $LOC_RA_TEST -eq  0 ]
+    if [ $LOC_RA_SA_TEST -eq  0 ]
     then
       i="0"
       echo "ifconfig oaitun_ue1 | egrep -c \"inet addr\"" > $1
@@ -2195,6 +2241,88 @@ function run_test_on_vm {
 
     if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]]
     then
+        echo "############################################################"
+        echo "SA TEST"
+        echo "############################################################"
+        #SA test, attention : has a different config file from the rest of the test
+        CN_CONFIG="noS1"
+        CONF_FILE=gnb.band78.sa.fr1.106PRB.usrpb210.conf 
+        S1_NOS1_CFG=0
+        PRB=106
+        FREQUENCY=3510
+
+        if [ ! -d $ARCHIVES_LOC ]
+        then
+            mkdir --parents $ARCHIVES_LOC
+        fi
+
+        local try_cnt=0
+        NR_STATUS=0
+
+        ######### start of SA TEST loop
+        while [ $try_cnt -lt 5 ] #5 because it hardly succeed within CI
+        do
+
+            SYNC_STATUS=0
+            SA_STATUS=0
+            rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}*sa_test.log
+
+            echo "############################################################"
+            echo "${CN_CONFIG} : Starting the gNB"
+            echo "############################################################"
+            CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb_sa_test.log
+            #last argument = 2 is to enable --sa for SA test
+            start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 2
+
+            echo "############################################################"
+            echo "${CN_CONFIG} : Starting the NR-UE"
+            echo "############################################################"
+            CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue_sa_test.log
+            #last argument = 2 is to enable --sa for SA test
+            start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 2
+            if [ $NR_UE_SYNC -eq 0 ]
+            then
+                echo "Problem w/ gNB and NR-UE not syncing"
+                terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
+                terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1
+                scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC
+                scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC
+                SYNC_STATUS=-1
+                try_cnt=$((try_cnt+1))
+                continue
+            fi
+
+            echo "############################################################"
+            echo "${CN_CONFIG} : Terminate gNB/NR-UE simulators"
+            echo "############################################################"
+            sleep 20
+            terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
+            terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1
+            scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC
+            scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC
+
+            #check SA markers in gNB and NR UE log files
+            echo "############################################################"
+            echo "${CN_CONFIG} : Checking SA on gNB / NR-UE"
+            echo "############################################################"
+
+            # Proper check to be done when SA test is working!
+            check_sa_result $ARCHIVES_LOC/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC/$CURRENT_NR_UE_LOG_FILE
+            if [ $SA_STATUS -ne 0 ]
+            then
+                echo "SA test NOT OK"
+                echo "try_cnt = " $try_cnt
+                try_cnt=$((try_cnt+1))
+            else
+                try_cnt=$((try_cnt+10))
+            fi
+        done
+        ########### end SA test
+
+        sleep 30
+
+
+
         echo "############################################################"
         echo "RA TEST FR2"
         echo "############################################################"
@@ -2499,6 +2627,7 @@ function run_test_on_vm {
         echo "Checking run status"
         echo "############################################################"
 
+        if [ $SA_STATUS -ne 0 ]; then NR_STATUS=-1; fi     
         if [ $RA_FR2_STATUS -ne 0 ]; then NR_STATUS=-1; fi        
         if [ $RA_STATUS -ne 0 ]; then NR_STATUS=-1; fi
         if [ $SYNC_STATUS -ne 0 ]; then NR_STATUS=-1; fi
diff --git a/ci-scripts/xml_files/fr1_nsa_quectel.xml b/ci-scripts/xml_files/fr1_nsa_quectel.xml
index 2e8c07968d7976e481689309441f00618b3867bd..7ec3a5f1402ceb1d6365c731b6d467235a01ceda 100644
--- a/ci-scripts/xml_files/fr1_nsa_quectel.xml
+++ b/ci-scripts/xml_files/fr1_nsa_quectel.xml
@@ -48,12 +48,13 @@
 		<class>Initialize_UE</class>
 		<desc>Initialize Quectel</desc>
 		<id>idefix</id>
+		<UE_Trace>yes</UE_Trace>
 	</testCase>
 
 
 	<testCase id="010002">
-		<class>Detach_UE</class>
-		<desc>Detach UE</desc>
+		<class>Terminate_UE</class>
+		<desc>Terminate Quectel</desc>
 		<id>idefix</id>
 	</testCase>
 
diff --git a/ci-scripts/xml_files/fr1_nsa_quectel_attach_detach.xml b/ci-scripts/xml_files/fr1_nsa_quectel_attach_detach.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2263f731c582219bda3c234f8c6246499f8f8269
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_nsa_quectel_attach_detach.xml
@@ -0,0 +1,168 @@
+<!--
+
+ 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
+
+-->
+<testCaseList>
+	<htmlTabRef>TEST-NSA-FR1-TM1</htmlTabRef>
+	<htmlTabName>NSA Ping Attach Detach with QUECTEL</htmlTabName>
+	<htmlTabIcon>tasks</htmlTabIcon>
+	<repeatCount>1</repeatCount>
+	<TestCaseRequestedList>
+ 030000
+ 040000
+ 000002
+ 010000
+ 000001
+ 050000
+ 000001
+ 010004
+ 000001
+ 010003
+ 000001
+ 050000
+ 000001
+ 010004
+ 000001
+ 010003
+ 000001
+ 050000
+ 000001
+ 010002
+ 080001
+ 080000
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="010000">
+		<class>Initialize_UE</class>
+		<desc>Initialize Quectel</desc>
+		<id>idefix</id>
+		<UE_Trace>yes</UE_Trace>
+	</testCase>
+
+
+	<testCase id="010002">
+		<class>Terminate_UE</class>
+		<desc>Terminate Quectel</desc>
+		<id>idefix</id>
+	</testCase>
+
+	<testCase id="010003">
+		<class>Attach_UE</class>
+		<desc>Attach Quectel</desc>
+		<id>idefix</id>
+	</testCase>
+
+	<testCase id="010004">
+		<class>Detach_UE</class>
+		<desc>Detach Quectel</desc>
+		<id>idefix</id>
+	</testCase>	
+
+
+	<testCase id="030000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize eNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf</Initialize_eNB_args>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<air_interface>lte</air_interface>
+		<eNB_Trace>yes</eNB_Trace>
+	</testCase>
+
+
+	<testCase id="040000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize gNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E -q</Initialize_eNB_args>
+		<eNB_instance>1</eNB_instance>
+		<eNB_serverId>1</eNB_serverId>
+		<air_interface>nr</air_interface>
+	</testCase>
+
+	<testCase id="000001">
+		<class>IdleSleep</class>
+		<desc>Sleep</desc>
+		<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
+	</testCase>
+
+	<testCase id="000002">
+		<class>IdleSleep</class>
+		<desc>Sleep</desc>
+		<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
+	</testCase>
+
+
+	<testCase id="050000">
+		<class>Ping</class>
+		<desc>Ping: 20pings in 20sec</desc>
+		<id>idefix</id>
+		<ping_args>-c 20</ping_args>
+		<ping_packetloss_threshold>50</ping_packetloss_threshold>
+	</testCase>
+
+	<testCase id="050001">
+		<class>Ping</class>
+		<desc>Ping: 100pings in 20sec</desc>
+		<id>idefix</id>
+		<ping_args>-c 100 -i 0.2</ping_args>
+		<ping_packetloss_threshold>50</ping_packetloss_threshold>
+	</testCase>
+
+	<testCase id="070000">
+		<class>Iperf</class>
+		<desc>iperf (DL/20Mbps/UDP)(60 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 20M -t 60</iperf_args>
+		<direction>DL</direction>
+		<id>idefix</id>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>single-ue</iperf_profile>
+	</testCase>
+
+	<testCase id="070001">
+		<class>Iperf</class>
+		<desc>iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 3M -t 60</iperf_args>
+		<direction>UL</direction>
+		<id>idefix</id>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>single-ue</iperf_profile>
+	</testCase>
+
+
+	<testCase id="080000">
+		<class>Terminate_eNB</class>
+		<desc>Terminate eNB</desc>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<air_interface>lte</air_interface>
+	</testCase>
+
+	<testCase id="080001">
+		<class>Terminate_eNB</class>
+		<desc>Terminate gNB</desc>
+		<eNB_instance>1</eNB_instance>
+		<eNB_serverId>1</eNB_serverId>
+		<air_interface>nr</air_interface>
+	</testCase>
+
+</testCaseList>
+
diff --git a/ci-scripts/xml_files/fr1_nsa_quectel_long.xml b/ci-scripts/xml_files/fr1_nsa_quectel_long.xml
new file mode 100644
index 0000000000000000000000000000000000000000..21ff7a63c5b3dfbc4712dd036233b6fdb66f61e1
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_nsa_quectel_long.xml
@@ -0,0 +1,148 @@
+<!--
+
+ 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
+
+-->
+<testCaseList>
+	<htmlTabRef>TEST-NSA-FR1-TM1</htmlTabRef>
+	<htmlTabName>NSA Ping DL UL with QUECTEL (Longer)</htmlTabName>
+	<htmlTabIcon>tasks</htmlTabIcon>
+	<repeatCount>1</repeatCount>
+	<TestCaseRequestedList>
+ 030000
+ 040000
+ 000002
+ 010000
+ 000001
+ 050000
+ 050001
+ 000001
+ 070000
+ 000001
+ 070001
+ 000001
+ 010002
+ 080001
+ 080000
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="010000">
+		<class>Initialize_UE</class>
+		<desc>Initialize Quectel</desc>
+		<id>idefix</id>
+	</testCase>
+
+
+	<testCase id="010002">
+		<class>Terminate_UE</class>
+		<desc>Terminate Quectel</desc>
+		<id>idefix</id>
+	</testCase>
+
+
+	<testCase id="030000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize eNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf</Initialize_eNB_args>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<air_interface>lte</air_interface>
+		<eNB_Trace>yes</eNB_Trace>
+	</testCase>
+
+
+	<testCase id="040000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize gNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E -q</Initialize_eNB_args>
+		<eNB_instance>1</eNB_instance>
+		<eNB_serverId>1</eNB_serverId>
+		<air_interface>nr</air_interface>
+	</testCase>
+
+	<testCase id="000001">
+		<class>IdleSleep</class>
+		<desc>Sleep</desc>
+		<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
+	</testCase>
+
+	<testCase id="000002">
+		<class>IdleSleep</class>
+		<desc>Sleep</desc>
+		<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
+	</testCase>
+
+
+	<testCase id="050000">
+		<class>Ping</class>
+		<desc>Ping: 20pings in 20sec</desc>
+		<id>idefix</id>
+		<ping_args>-c 20</ping_args>
+		<ping_packetloss_threshold>50</ping_packetloss_threshold>
+	</testCase>
+
+	<testCase id="050001">
+		<class>Ping</class>
+		<desc>Ping: 100pings in 20sec</desc>
+		<id>idefix</id>
+		<ping_args>-c 100 -i 0.2</ping_args>
+		<ping_packetloss_threshold>50</ping_packetloss_threshold>
+	</testCase>
+
+	<testCase id="070000">
+		<class>Iperf</class>
+		<desc>iperf (DL/20Mbps/UDP)(600 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 20M -t 600</iperf_args>
+		<direction>DL</direction>
+		<id>idefix</id>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>single-ue</iperf_profile>
+	</testCase>
+
+	<testCase id="070001">
+		<class>Iperf</class>
+		<desc>iperf (UL/3Mbps/UDP)(600 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 3M -t 600</iperf_args>
+		<direction>UL</direction>
+		<id>idefix</id>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>single-ue</iperf_profile>
+	</testCase>
+
+
+	<testCase id="080000">
+		<class>Terminate_eNB</class>
+		<desc>Terminate eNB</desc>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<air_interface>lte</air_interface>
+	</testCase>
+
+	<testCase id="080001">
+		<class>Terminate_eNB</class>
+		<desc>Terminate gNB</desc>
+		<eNB_instance>1</eNB_instance>
+		<eNB_serverId>1</eNB_serverId>
+		<air_interface>nr</air_interface>
+	</testCase>
+
+</testCaseList>
+
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 8d8e88455a4137da65ce97f8d71c2c6ea64f7e29..b8992573cdaedce50b227cb59eea42e94a0d1a58 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -320,7 +320,7 @@ if (CUDA_FOUND)
     set(CUDA_CMAKE_CXX_FLAGS
 	"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -std=c++11 -D CUDA_FLAG"
     )
-	
+
 	set(CMAKE_C_FLAGS
            "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D${MKVER} -D CUDA_FLAG"
     )
@@ -338,8 +338,8 @@ else (CUDA_FOUND)
 endif ()
 
 if (SANITIZE_ADDRESS)
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-common")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-common")
 endif ()
 
 add_definitions("-DASN_DISABLE_OER_SUPPORT")
@@ -349,7 +349,7 @@ set(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${CMAKE_CU
 #########################
 # set a flag for changes in the source code
 # these changes are related to hardcoded path to include .h files
-set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g3 -O0 -DMALLOC_CHECK_=3")
+set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g3 -Og -DMALLOC_CHECK_=3")
 set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3 -O2 -fno-delete-null-pointer-checks")
 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS}  -O3")
 
@@ -414,7 +414,6 @@ add_boolean_option(UE_AUTOTEST_TRACE   False "Activate UE autotest specific logs
 add_boolean_option(UE_DEBUG_TRACE      False "Activate UE debug trace")
 add_boolean_option(UE_TIMING_TRACE     False "Activate UE timing trace")
 add_boolean_option(DEBUG_CONSOLE       False "makes debugging easier, disables stdout/stderr buffering")
-add_boolean_option(NEW_GTPU       False "NEW_GTP")
 
 set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti)
 add_library(ITTI
@@ -496,7 +495,7 @@ add_custom_target (
   DEPENDS ${NR_RRC_GRAMMAR}
   )
 
-add_library(NR_RRC_LIB ${nr_rrc_h} ${nr_rrc_source} 
+add_library(NR_RRC_LIB ${nr_rrc_h} ${nr_rrc_source}
     ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1_msg.c
     )
 add_dependencies(NR_RRC_LIB nr_rrc_flag)
@@ -530,21 +529,21 @@ endif (${RU} STREQUAL 0)
   add_custom_target (
     s1ap_flag ALL
     ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh  "S1AP_" -fno-include-deps "${S1AP_C_DIR}" "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}"
-    DEPENDS  "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" 
+    DEPENDS  "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}"
   )
 
-  add_library(S1AP_LIB
-    ${S1AP_source}
-    ${S1AP_DIR}/s1ap_common.c
-    )
-  add_dependencies(S1AP_LIB rrc_flag s1ap_flag)
+add_library(S1AP_LIB
+  ${S1AP_source}
+  ${S1AP_DIR}/s1ap_common.c
+  )
+add_dependencies(S1AP_LIB rrc_flag s1ap_flag)
 
-  include_directories ("${S1AP_C_DIR}")
-  include_directories ("${S1AP_DIR}")
+include_directories ("${S1AP_C_DIR}")
+include_directories ("${S1AP_DIR}")
 
 add_library(S1AP_ENB
-    ${S1AP_DIR}/s1ap_eNB.c
-    ${S1AP_DIR}/s1ap_eNB_context_management_procedures.c
+  ${S1AP_DIR}/s1ap_eNB.c
+  ${S1AP_DIR}/s1ap_eNB_context_management_procedures.c
   ${S1AP_DIR}/s1ap_eNB_decoder.c
   ${S1AP_DIR}/s1ap_eNB_encoder.c
   ${S1AP_DIR}/s1ap_eNB_handlers.c
@@ -575,7 +574,7 @@ set(NGAP_C_DIR ${asn1_generated_dir}/NGAP_${NGAP_RELEASE})
 
 # Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
 execute_process(
-  COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "NGAP_" "-fno-include-deps -findirect-choice" "${NGAP_C_DIR}" "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}" 
+  COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "NGAP_" "-fno-include-deps -findirect-choice" "${NGAP_C_DIR}" "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}"
   RESULT_VARIABLE ret)
 if (NOT ${ret} STREQUAL 0)
   message(FATAL_ERROR "${ret}: error")
@@ -585,7 +584,7 @@ file(GLOB NGAP_source ${NGAP_C_DIR}/*.c)
 add_custom_target (
   ngap_flag ALL
   ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh  "NGAP_" "-fno-include-deps -findirect-choice" "${NGAP_C_DIR}" "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}"
-  DEPENDS  "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}" 
+  DEPENDS  "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}"
 )
 
 add_library(NGAP_LIB
@@ -643,7 +642,7 @@ set(M2AP_C_DIR ${asn1_generated_dir}/M2AP_${M2AP_RELEASE})
 # Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
 if (${RU} STREQUAL 0)
   execute_process(
-    COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh  "M2AP_" "-fno-include-deps -DEMIT_ASN_DEBUG=1" "${M2AP_C_DIR}" "${M2AP_ASN_DIR}/${M2AP_ASN_FILES}" 
+    COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh  "M2AP_" "-fno-include-deps -DEMIT_ASN_DEBUG=1" "${M2AP_C_DIR}" "${M2AP_ASN_DIR}/${M2AP_ASN_FILES}"
     RESULT_VARIABLE ret)
   if (NOT ${ret} STREQUAL 0)
     message(FATAL_ERROR "${ret}: error")
@@ -716,7 +715,7 @@ set(M3AP_C_DIR ${asn1_generated_dir}/M3AP_${M3AP_RELEASE})
 # Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
 if (${RU} STREQUAL 0)
   execute_process(
-    COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh  "M3AP_" -fno-include-deps "${M3AP_C_DIR}" "${M3AP_ASN_DIR}/${M3AP_ASN_FILES}" 
+    COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh  "M3AP_" -fno-include-deps "${M3AP_C_DIR}" "${M3AP_ASN_DIR}/${M3AP_ASN_FILES}"
     RESULT_VARIABLE ret)
   if (NOT ${ret} STREQUAL 0)
     message(FATAL_ERROR "${ret}: error")
@@ -813,6 +812,7 @@ add_dependencies(X2AP_ENB X2AP_LIB rrc_flag x2_flag)
 
 # F1AP
 ##############
+set (F1AP_RELEASE R16)
 add_list1_option(F1AP_RELEASE R16 "F1AP ASN.1 grammar version" R16)
 set(F1AP_DIR ${OPENAIR2_DIR}/F1AP)
 if (${F1AP_RELEASE} STREQUAL "R16")
@@ -841,7 +841,7 @@ if (${RU} STREQUAL 0)
   if (NOT ${ret} STREQUAL 0)
     message(FATAL_ERROR "asn1c: error")
   endif (NOT ${ret} STREQUAL 0)
-  
+
   add_custom_target (
     f1_flag ALL
     COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "F1AP_" "-findirect-choice -fno-include-deps" ${F1AP_ASN_GENERATED_C_DIR} ${F1AP_ASN_FILES}
@@ -1021,6 +1021,7 @@ add_boolean_option(PHY_TX_THREAD            False         "enable UE_EXPANSION w
 add_boolean_option(PRE_SCD_THREAD           False         "enable UE_EXPANSION with max 256 UE")
 add_boolean_option(UESIM_EXPANSION          False         "enable UESIM_EXPANSION with max 256 UE")
 add_boolean_option(ITTI_SIM                 False         "enable itti simulator")
+add_boolean_option(RFSIM_NAS                False         "enable rfsim nas")
 
 ########################
 # Include order
@@ -1502,11 +1503,11 @@ add_dependencies(SCHED_UE_LIB rrc_flag)
 set(SCHED_SRC_NR_UE
   ${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c
   ${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c
-  ${OPENAIR1_DIR}/SCHED_NR_UE/fapi_nr_ue_l1.c 
+  ${OPENAIR1_DIR}/SCHED_NR_UE/fapi_nr_ue_l1.c
   ${OPENAIR1_DIR}/SCHED_NR_UE/phy_frame_config_nr_ue.c
   ${OPENAIR1_DIR}/SCHED_NR_UE/harq_nr.c
   ${OPENAIR1_DIR}/SCHED_NR_UE/pucch_uci_ue_nr.c
-  ${OPENAIR1_DIR}/SCHED_NR_UE/pucch_power_control_ue_nr.c 
+  ${OPENAIR1_DIR}/SCHED_NR_UE/pucch_power_control_ue_nr.c
 )
 add_library(SCHED_NR_UE_LIB ${SCHED_SRC_NR_UE})
 
@@ -1816,7 +1817,7 @@ set(PHY_SRC_UE
   ${PHY_POLARSRC}
   ${PHY_SMALLBLOCKSRC}
   ${PHY_NR_CODINGIF}
-  ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c 
+  ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c
   ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_uci_tools_common.c
   )
   set(PHY_NR_UE_SRC
@@ -1995,7 +1996,7 @@ set(NR_RLC_SRC
   ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_sdu.c
   ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_ue_manager.c
   )
-  
+
 set(NR_PDCP_SRC
   ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
   ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
@@ -2022,12 +2023,13 @@ set(L2_SRC
   ${RRC_DIR}/rrc_eNB_S1AP.c
   ${RRC_DIR}/rrc_eNB_M2AP.c
   ${RRC_DIR}/rrc_eNB_UE_context.c
+  ${NR_RRC_DIR}/rrc_gNB_UE_context.c
   ${RRC_DIR}/rrc_common.c
   ${RRC_DIR}/L2_interface.c
   ${RRC_DIR}/L2_interface_common.c
   ${RRC_DIR}/L2_interface_ue.c
   )
-  
+
 set(L2_RRC_SRC
   ${OPENAIR2_DIR}/LAYER2/openair2_proc.c
   #  ${RRC_DIR}/rrc_UE.c
@@ -2073,14 +2075,14 @@ set(L2_SRC_UE
   ${RRC_DIR}/L2_interface_common.c
   ${RRC_DIR}/L2_interface_ue.c
   )
-  
+
 set(L2_RRC_SRC_UE
   ${RRC_DIR}/rrc_UE.c
   ${RRC_DIR}/rrc_common.c
   ${RRC_DIR}/L2_interface_common.c
   ${RRC_DIR}/L2_interface_ue.c
-  )  
-  
+  )
+
 set(NR_L2_SRC_UE
   ${NR_RLC_SRC}
   ${NR_PDCP_SRC}
@@ -2138,7 +2140,7 @@ set (MAC_SRC_UE
   ${MAC_DIR}/rar_tools_ue.c
   ${MAC_DIR}/config_ue.c
  )
- 
+
 set (MAC_NR_SRC_UE
   ${NR_UE_PHY_INTERFACE_DIR}/NR_IF_Module.c
   ${NR_UE_MAC_DIR}/config_ue.c
@@ -2210,6 +2212,7 @@ add_library(L2_NR
   ${MAC_NR_SRC}
   ${GNB_APP_SRC}
   )
+target_compile_definitions(L2_NR PUBLIC NEW_GTPU)
 
 add_library(L2_LTE_NR
   ${L2_RRC_SRC}
@@ -2217,7 +2220,8 @@ add_library(L2_LTE_NR
   ${ENB_APP_SRC}
   ${MCE_APP_SRC}
 )
-  
+target_compile_definitions(L2_LTE_NR PUBLIC NEW_GTPU)
+
 add_dependencies(L2_NR rrc_flag nr_rrc_flag s1ap_flag x2_flag)
 
 add_library(L2_UE
@@ -2264,6 +2268,7 @@ add_library (GTPV1U_OCP
   ${RRC_DIR}/rrc_eNB_GTPV1U.c
 ${OPENAIR3_DIR}/ocp-gtpu/gtp_itf.cpp
 )
+target_compile_definitions(GTPV1U_OCP PUBLIC NEW_GTPU)
 add_dependencies(GTPV1U_OCP rrc_flag)
 include_directories(${OPENAIR3_DIR}/ocp-gtp)
 
@@ -2282,12 +2287,6 @@ set (NR_GTPV1U_SRC
 add_library(NR_GTPV1U ${NR_GTPV1U_SRC})
 add_dependencies(NR_GTPV1U rrc_flag)
 
-if (${NEW_GTPU})
-set(GTPV1U GTPV1U_OCP)
-else()
-set(GTPV1U NR_GTPV1U)
-endif()
-
 set (MME_APP_SRC
   ${OPENAIR3_DIR}/MME_APP/mme_app.c
   ${OPENAIR3_DIR}/MME_APP/mme_config.c
@@ -2566,7 +2565,7 @@ if(NAS_UE)
 endif()
 
 
-if(ITTI_SIM)
+if(ITTI_SIM OR RFSIM_NAS)
   set(libnas_ue_api_OBJS
     ${NAS_SRC}UE/API/USER/at_command.c
     ${NAS_SRC}UE/API/USER/at_error.c
@@ -2759,7 +2758,7 @@ add_library(SIMU_COMMON
 
 # Simulation library
 ##########################
-set (SIMUSRC 
+set (SIMUSRC
   ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
   ${OPENAIR1_DIR}/SIMULATION/TOOLS/multipath_channel.c
   ${OPENAIR1_DIR}/SIMULATION/TOOLS/multipath_tv_channel.c
@@ -2822,7 +2821,7 @@ add_library(nrscope MODULE ${XFORMS_SOURCE_NR})
 target_link_libraries(nrscope ${XFORMS_LIBRARIES})
 
 
-add_library(rfsimulator MODULE 
+add_library(rfsimulator MODULE
   ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c
   ${OPENAIR_TARGETS}/ARCH/rfsimulator/apply_channelmod.c
   ${OPENAIR_TARGETS}/ARCH/rfsimulator/new_channel_sim.c
@@ -2830,7 +2829,7 @@ add_library(rfsimulator MODULE
 	)
 target_link_libraries(rfsimulator SIMU_COMMON ${ATLAS_LIBRARIES})
 
-add_library(oai_iqplayer MODULE 
+add_library(oai_iqplayer MODULE
 	${OPENAIR_TARGETS}/ARCH/iqplayer/iqplayer_lib.c
 	)
 set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
@@ -2900,7 +2899,7 @@ add_executable(measurement_display
   ${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c)
 target_link_libraries (measurement_display minimal_lib)
 
-add_executable(test5Gnas 
+add_executable(test5Gnas
   ${OPENAIR_DIR}/openair3/TEST/test5Gnas.c
 )
 target_link_libraries (test5Gnas LIB_5GNAS_GNB CONFIG_LIB minimal_lib )
@@ -2925,6 +2924,7 @@ add_executable(lte-softmodem
   ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
   ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
   ${OPENAIR2_DIR}/RRC/NAS/rb_config.c
+  ${OPENAIR2_DIR}/F1AP/dummy_enb.c
   ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
   ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
   ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
@@ -2943,11 +2943,11 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer)
 target_link_libraries (lte-softmodem
   -Wl,--start-group
 
-  RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB 
+  RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB NR_GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
   PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB LFDS7
   ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
   -Wl,--end-group z dl)
-  
+
 target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES})
 target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB}  ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES})
 target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES})
@@ -2986,7 +2986,7 @@ add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer coding params_l
 target_link_libraries (ocp-enb
   -Wl,--start-group
 
-  RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB 
+  RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB NR_GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
   PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB MISC_NFAPI_LTE_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON
   ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
   -Wl,--end-group z dl)
@@ -3040,10 +3040,10 @@ add_executable(oairu
 )
 target_link_libraries (oairu
   -Wl,--start-group
-  SCHED_RU_LIB 
-  PHY_COMMON PHY_RU 
+  SCHED_RU_LIB
+  PHY_COMMON PHY_RU
   -Wl,--end-group z dl)
-  
+
 target_link_libraries (oairu pthread m ${CONFIG_LIB} rt ${CMAKE_DL_LIBS} ${T_LIB})
 
 
@@ -3083,7 +3083,7 @@ target_link_libraries (lte-uesoftmodem
   -Wl,--start-group
   RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP F1AP_LIB
 
-  ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON
+  NR_GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON
   PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB
   ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${ATLAS_LIBRARIES}
   -Wl,--end-group z dl)
@@ -3124,10 +3124,11 @@ add_executable(nr-softmodem
   ${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api_to_fix.c
   )
 
+target_compile_definitions(nr-softmodem PUBLIC NEW_GTPU)
 target_link_libraries (nr-softmodem
   -Wl,--start-group
-  UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS ${GTPV1U} SECU_CN SECU_OSA
-  ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB 
+  UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS GTPV1U_OCP SECU_CN SECU_OSA
+  ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB
   NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
   X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB}
   -Wl,--end-group z dl)
@@ -3165,8 +3166,8 @@ add_executable(ocp-gnb
 
 target_link_libraries (ocp-gnb
   -Wl,--start-group
-  UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS ${GTPV1U} SECU_CN SECU_OSA
-  ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB 
+  UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS GTPV1U_OCP SECU_CN SECU_OSA
+  ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB
   NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
   X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB SIMU_COMMON
   -Wl,--end-group z dl)
@@ -3214,7 +3215,7 @@ target_link_libraries (nr-uesoftmodem
   NFAPI_USER_LIB MISC_NFAPI_NR_LIB S1AP_LIB S1AP_ENB
   ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
   NFAPI_USER_LIB S1AP_LIB S1AP_ENB
-  ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} LIB_5GNAS_GNB ${NAS_SIM_LIB}
+  ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} LIB_5GNAS_GNB LIB_NAS_SIMUE ${NAS_SIM_LIB}
   -Wl,--end-group z dl)
 
 target_link_libraries (nr-uesoftmodem ${LIBXML2_LIBRARIES})
@@ -3244,7 +3245,7 @@ target_link_libraries (dlsim_tm4
   pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${T_LIB}
   )
 
-add_executable(rftest 
+add_executable(rftest
   ${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_test.c
   ${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_scope.c
   ${OPENAIR_DIR}/common/utils/system.c
@@ -3255,7 +3256,7 @@ add_executable(rftest
 )
 target_link_libraries(rftest minimal_lib PHY_NR_COMMON pthread dl m forms ${T_LIB} )
 
-add_executable(polartest 
+add_executable(polartest
   ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c
   ${OPENAIR_DIR}/common/utils/backtrace.c
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
@@ -3268,7 +3269,7 @@ target_link_libraries(polartest
   m pthread ${ATLAS_LIBRARIES} dl
   )
 
-add_executable(smallblocktest 
+add_executable(smallblocktest
   ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/smallblocktest.c
   ${OPENAIR_DIR}/common/utils/backtrace.c
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
@@ -3286,17 +3287,17 @@ target_link_libraries(smallblocktest
 
 # temp_C_flag = CMAKE_C_FLAGS
 #set(CMAKE_C_FLAGS " ")
-set (TEMP_C_FLAG ${CMAKE_C_FLAGS}) 
+set (TEMP_C_FLAG ${CMAKE_C_FLAGS})
 set (CMAKE_C_FLAGS ${CUDA_CMAKE_C_FLAGS})
 
-set (TEMP_CXX_FLAG ${CMAKE_CXX_FLAGS}) 
+set (TEMP_CXX_FLAG ${CMAKE_CXX_FLAGS})
 set (CMAKE_CXX_FLAGS ${CUDA_CMAKE_CXX_FLAGS})
 if (CUDA_FOUND)
 ###################################################
-# For CUDA library 
+# For CUDA library
 ###################################################
-    
-    CUDA_ADD_LIBRARY(LDPC_CU 
+
+    CUDA_ADD_LIBRARY(LDPC_CU
       ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
       )
     CUDA_ADD_CUFFT_TO_TARGET(LDPC_CU)
@@ -3306,14 +3307,14 @@ if (CUDA_FOUND)
       ${SHLIB_LOADER_SOURCES}
       )
     target_link_libraries(ldpctest -ldl
-      -Wl,--start-group 
-      LDPC_CU UTIL SIMU PHY_NR CONFIG_LIB 
+      -Wl,--start-group
+      LDPC_CU UTIL SIMU PHY_NR CONFIG_LIB
       -Wl,--end-group
       m pthread ${ATLAS_LIBRARIES} dl
       )
 
 else (CUDA_FOUND)
-    add_executable(ldpctest  
+    add_executable(ldpctest
        ${PHY_NR_CODINGIF}
        ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
        ${T_SOURCE}
@@ -3325,21 +3326,21 @@ set (CMAKE_C_FLAGS ${TEMP_C_FLAG})
 set (CMAKE_CXX_FLAGS ${TEMP_CXX_FLAG})
 
 
-# add_executable(ldpctest  
+# add_executable(ldpctest
   # ${PHY_NR_CODINGIF}
   # ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
   # ${T_SOURCE}
   # ${SHLIB_LOADER_SOURCES}
   # )
-add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) 
+add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
 
 target_link_libraries(ldpctest
   -Wl,--start-group UTIL SIMU_COMMON  SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} dl
   )
 
-add_executable(nr_dlschsim  
-  ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c 
+add_executable(nr_dlschsim
+  ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c
   ${OPENAIR_DIR}/common/utils/system.c
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
   ${OPENAIR_DIR}/common/utils/utils.c
@@ -3348,13 +3349,13 @@ add_executable(nr_dlschsim
   ${T_SOURCE}
   ${SHLIB_LOADER_SOURCES}
   )
-target_link_libraries(nr_dlschsim 
+target_link_libraries(nr_dlschsim
   -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
   )
 
-add_executable(nr_pbchsim  
-  ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c 
+add_executable(nr_pbchsim
+  ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c
   ${OPENAIR_DIR}/common/utils/system.c
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
   ${OPENAIR_DIR}/common/utils/utils.c
@@ -3369,8 +3370,8 @@ target_link_libraries(nr_pbchsim
   )
 
 #PUCCH ---> Prashanth
-add_executable(nr_pucchsim  
-  ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c 
+add_executable(nr_pucchsim
+  ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c
   ${OPENAIR_DIR}/common/utils/backtrace.c
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
   ${OPENAIR_DIR}/common/utils/system.c
@@ -3398,7 +3399,7 @@ add_executable(nr_dlsim
   ${UTIL_SRC}
   ${T_SOURCE}
   ${SHLIB_LOADER_SOURCES}
-  )   
+  )
 target_link_libraries(nr_dlsim
   -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} ${OPENSSL_LIBRARIES} dl
@@ -3406,7 +3407,7 @@ target_link_libraries(nr_dlsim
 target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR)
 
 add_executable(nr_prachsim
-  ${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c 
+  ${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c
   ${OPENAIR_DIR}/common/utils/utils.c
   ${OPENAIR_DIR}/common/utils/system.c
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
@@ -3418,7 +3419,7 @@ add_executable(nr_prachsim
   ${UTIL_SRC}
   ${T_SOURCE}
   ${SHLIB_LOADER_SOURCES})
-target_link_libraries(nr_prachsim  
+target_link_libraries(nr_prachsim
   -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} ${OPENSSL_LIBRARIES} dl)
 
@@ -3458,7 +3459,7 @@ target_link_libraries(nr_ulsim
 target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR)
 
 foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim)
-  
+
   add_executable(${myExe}
     ${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c
     ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
@@ -3478,7 +3479,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
     -Wl,--start-group SIMU_COMMON SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_NR_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group
     pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES}  ${XFORMS_LIBRARIES} ${T_LIB} dl
     )
-   
+
 endforeach(myExe)
 
 add_executable(test_epc_generate_scenario
@@ -3490,7 +3491,7 @@ add_executable(test_epc_generate_scenario
   ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h
   )
 target_link_libraries (test_epc_generate_scenario
-  -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP ${GTPV1U} LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB}
+  -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP NR_GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB}
   )
 
 add_executable(test_epc_play_scenario
@@ -3509,7 +3510,7 @@ add_executable(test_epc_play_scenario
   )
 target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c)
 target_link_libraries (test_epc_play_scenario
-  -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP ${GTPV1U} LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB}
+  -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP NR_GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB}
   )
 
 
@@ -3541,13 +3542,13 @@ endforeach(myExe)
 if (${T_TRACER})
   foreach(i
         #all "add_executable" definitions (except tests, rb_tool, updatefw)
-        lte-softmodem lte-uesoftmodem nr-softmodem 
+        lte-softmodem lte-uesoftmodem nr-softmodem
         nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 nr-ittisim
         ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim
         syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim
         nr_ulschsim ldpctest polartest smallblocktest cu_test du_test
         #all "add_library" definitions
-        ITTI RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP 
+        ITTI RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP
         params_libconfig oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif oai_iqplayer
         oai_eth_transpro oai_mobipass tcp_bridge tcp_bridge_oai
         coding FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO
@@ -3555,7 +3556,7 @@ if (${T_TRACER})
         NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
         PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX
         L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR NGAP_GNB
-        CN_UTILS ${GTPV1U} SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB
+        CN_UTILS NR_GTPV1U GTPV1U_OCP SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB
         ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT dfts)
     if (TARGET ${i})
       add_dependencies(${i} generate_T)
@@ -3660,14 +3661,15 @@ add_executable(nr-ittisim
   ${CONFIG_SOURCES}
   ${SHLIB_LOADER_SOURCES}
   )
+target_compile_definitions(nr-ittisim PUBLIC NEW_GTPU)
 
 target_link_libraries (nr-ittisim
   -Wl,--start-group
-  UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS ${GTPV1U} SECU_CN SECU_OSA
-  ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_SIM_LIB} RRC_LIB NR_RRC_LIB 
+  UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS GTPV1U_OCP SECU_CN SECU_OSA
+  ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_SIM_LIB} RRC_LIB NR_RRC_LIB
   NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
   X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB}
-  PHY_NR_UE SCHED_NR_UE_LIB NR_L2_UE 
+  PHY_NR_UE SCHED_NR_UE_LIB NR_L2_UE
   -Wl,--end-group z dl)
 
 target_link_libraries (nr-ittisim ${LIBXML2_LIBRARIES})
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 279b9489e00333f1f5eaa85d1499d5b6389ae20c..d95b30e052406ccdf9c95a957caf977d4b65134d 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -68,6 +68,7 @@ USRP_REC_PLAY="False"
 BUILD_ECLIPSE=0
 NR="False"
 ITTI_SIM="False"
+RFSIM_NAS="False"
 SANITIZE_ADDRESS="False"
 OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc"
 RU=0
@@ -106,7 +107,7 @@ Options
 --nrUE
   Makes the NR UE softmodem
 --RU
-  Makes the OAI RRU (without full stack) 
+  Makes the OAI RRU (without full stack)
 --UE
    Makes the UE specific parts (ue_ip, usim, nvram) from the given configuration file
 --UE-conf-nvram [configuration file]
@@ -259,7 +260,7 @@ function main() {
             echo_info "Will compile gNB"
             shift;;
        --RU)
-	    RU=1
+	          RU=1
             echo_info "Will compile RRU"
 	    shift;;
        -a | --agent)
@@ -273,6 +274,8 @@ function main() {
        --nrUE)
             RU=0
             nrUE=1
+            rfsimNas=1
+            RFSIM_NAS="True"
             NR="True"
             echo_info "Will compile NR UE"
             shift;;
@@ -308,7 +311,7 @@ function main() {
             shift 2;;
        -P | --phy_simulators)
             SIMUS_PHY=1
-	    RU=0
+	          RU=0
             echo_info "Will compile dlsim, ulsim, ..."
             shift;;
        -S | --core_simulators)
@@ -604,7 +607,7 @@ function main() {
   config_libconfig_shlib=params_libconfig
   
   # first generate the CMakefile in the right directory
-  if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$RU" = "1" -o "$nrUE" = "1" -o "$HW" = "EXMIMO" -o "$ittiSIM" = "1" ] ; then
+  if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$RU" = "1" -o "$nrUE" = "1" -o "$HW" = "EXMIMO" -o "$ittiSIM" = "1" -o "$rfsimNas" = "1" ] ; then
 
     # softmodem compilation
 
@@ -630,6 +633,7 @@ function main() {
     echo "set ( SKIP_SHARED_LIB_FLAG $SKIP_SHARED_LIB_FLAG )"             >> $cmake_file
     echo "set ( RU $RU )"                                                 >> $cmake_file
     echo "set ( ITTI_SIM $ITTI_SIM )"                                     >> $cmake_file
+    echo "set ( RFSIM_NAS $RFSIM_NAS )"                                   >> $cmake_file
     echo "set ( SANITIZE_ADDRESS $SANITIZE_ADDRESS )"                     >> $cmake_file
     echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)'         >> $cmake_file
     cd  $DIR/$build_dir/build
diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c
index 1df1bc16f7df9795e4bbac22de08e0c8bac0fc62..f5dfae06b6c000d896427155a8cc10462f853d17 100644
--- a/common/config/config_cmdline.c
+++ b/common/config/config_cmdline.c
@@ -211,7 +211,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
 
   while (c > 0 ) {
     char *oneargv = strdup(config_get_if()->argv[i]);          /* we use strtok_r which modifies its string paramater, and we don't want argv to be modified */
-
+    if(!oneargv) abort();
     /* first check help options, either --help, -h or --help_<section> */
     if (strncmp(oneargv, "-h",2) == 0 || strncmp(oneargv, "--help",6) == 0 ) {
       char *tokctx = NULL;
diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c
index 8029ba826bc81799e355f998438c8faa12721924..d0a53a755b27ca807f5df975aa0f9f5c597446a0 100644
--- a/common/utils/LOG/log.c
+++ b/common/utils/LOG/log.c
@@ -460,7 +460,7 @@ int logInit (void)
   register_log_component("LOCALIZE","log",LOCALIZE);
   register_log_component("NAS","log",NAS);
   register_log_component("UDP","",UDP_);
-  register_log_component("GTPV1U","",GTPU);
+  register_log_component("GTPU","",GTPU);
   register_log_component("S1AP","",S1AP);
   register_log_component("F1AP","",F1AP);
   register_log_component("M2AP","",M2AP);
diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c
index 0671aed813d6b4f6c81265fdba82e08dcae53e8a..cc2860191af34fd80ebc78e8bb93e9a204a64ad2 100644
--- a/common/utils/nr/nr_common.c
+++ b/common/utils/nr/nr_common.c
@@ -111,8 +111,6 @@ const size_t nr_bandtable_size = sizeof(nr_bandtable) / sizeof(nr_bandentry_t);
 int NRRIV2BW(int locationAndBandwidth,int N_RB) {
   int tmp = locationAndBandwidth/N_RB;
   int tmp2 = locationAndBandwidth%N_RB;
-
-
   if (tmp <= ((N_RB>>1)+1) && (tmp+tmp2)<N_RB) return(tmp+1);
   else                      return(N_RB+1-tmp);
 
@@ -121,8 +119,6 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB) {
 int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB) {
   int tmp = locationAndBandwidth/N_RB;
   int tmp2 = locationAndBandwidth%N_RB;
-
-
   if (tmp <= ((N_RB>>1)+1) && (tmp+tmp2)<N_RB) return(tmp2);
   else                      return(N_RB-1-tmp2);
 }
diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h
index 944ca12b01e728e341bb9c4a387aae185e0fefcd..7c17a6f3b12fe9d060b8fb3a9053d7c922ead83f 100644
--- a/common/utils/ocp_itti/intertask_interface.h
+++ b/common/utils/ocp_itti/intertask_interface.h
@@ -346,6 +346,7 @@ void *rrc_enb_process_msg(void *);
   TASK_DEF(TASK_DU_F1,    TASK_PRIORITY_MED,  200, NULL, NULL) \
   TASK_DEF(TASK_RRC_UE_SIM,   TASK_PRIORITY_MED,  200, NULL, NULL)  \
   TASK_DEF(TASK_RRC_GNB_SIM,  TASK_PRIORITY_MED,  200, NULL, NULL)  \
+  TASK_DEF(TASK_NAS_NRUE,     TASK_PRIORITY_MED,  200, NULL, NULL)  \
   TASK_DEF(TASK_MAX,      TASK_PRIORITY_MED,  200, NULL, NULL)
 
 #define TASK_DEF(TaskID, pRIO, qUEUEsIZE, FuNc, ThreadFunc)          { pRIO, qUEUEsIZE, #TaskID, FuNc, ThreadFunc },
diff --git a/common/utils/system.c b/common/utils/system.c
index 2ed986fe8576e84ecf46ee280d06bcc817202b8c..d8b66c51d3210287bfe95fa8f6165d0a23539937 100644
--- a/common/utils/system.c
+++ b/common/utils/system.c
@@ -101,10 +101,13 @@ static int baseRunTimeCommand(char* cmd, size_t cmdSize) {
   size_t retSize = 0;
 
   fp = popen(cmd, "r");
-
-  memset(cmd, 0, cmdSize);
-  retSize = fread(cmd, 1, cmdSize, fp);
-  fclose(fp);
+  if(fp) {
+    memset(cmd, 0, cmdSize);
+    retSize = fread(cmd, 1, cmdSize, fp);
+    fclose(fp);
+  } else {
+    LOG_D(HW,"%s:%d:%s: Cannot open %s\n", __FILE__, __LINE__, __FUNCTION__, cmd);
+  }
 
   if (retSize == 0) {
     return 0;
diff --git a/configuration/bladeRF/enb-band7-5mhz.conf b/configuration/bladeRF/enb-band7-5mhz.conf
index 9156a74fb0b2e717bd8ce19f36add48488c661a7..9d192075223ebd1ad1a6d525ec39e167946e18b6 100644
--- a/configuration/bladeRF/enb-band7-5mhz.conf
+++ b/configuration/bladeRF/enb-band7-5mhz.conf
@@ -238,7 +238,7 @@ MACRLCs = (
 THREAD_STRUCT = (
   {
     parallel_config = "PARALLEL_RU_L1_TRX_SPLITaaaaaa";
-    worker_config = "ENABLE";
+    worker_config = "WORKER_ENABLE";
   }
 );
 
diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md
index 8d84646e071ea2bba568b05dcc3c81177bfcf3f4..dc7a982310bf1f0c4c929c7d1d9f79afc7409b68 100644
--- a/doc/RUNMODEM.md
+++ b/doc/RUNMODEM.md
@@ -134,22 +134,24 @@ With the RF simulator (on the same machine):
 
 ## SA setup with OAI
 
-The sa flag is used to run gNB in standalone mode. Currently OAI in NR standalone mode transmits and receives SIB1 and triggers the RA procedure for initial access.
+The sa flag is used to run gNB in standalone mode.
 
-In order to run gNB in standalone mode, the following flag is needed at gNB:
+In order to run gNB and UE in standalone mode, the following flag is needed:
 
 `--sa`
 
-### Run OAI in sa mode
-
-At the gNB the --sa flag does the following
-- it reads the RRC configuration from the configuration file
-- it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files rbconfig.raw and reconfig.raw
-- the RRC encodes SIB1 according the configuration file and transmits it through PDSCH
+At the gNB the --sa flag does the following:
+- The RRC encodes SIB1 according to the configuration file and transmits it through NR-BCCH-DL-SCH.
 
 At the UE the --sa flag will:
-- Read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them
-- After the successful decoding of a SIB1 at RRC, the UE will start the 5G NR Initial Access Procedure by triggering the RA procedure.
+- Decode SIB1 and starts the 5G NR Initial Access Procedure for SA:
+  1) 5G-NR RRC Connection Setup
+  2) NAS Authentication and Security
+  3) 5G-NR AS Security Procedure
+  4) 5G-NR RRC Reconfiguration
+  5) Start Downlink and Uplink Data Transfer
+
+### Run OAI in SA mode
 
 From the `cmake_targets/ran_build/build` folder:
 
@@ -159,13 +161,13 @@ gNB on machine 1:
 
 UE on machine 2:
 
-`sudo ./nr-uesoftmodem --rrc_config_path . --sa`
+`sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --sa`
 
 With the RF simulator (on the same machine):
 
 `sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --rfsim --sa`
 
-`sudo ./nr-uesoftmodem --rrc_config_path . --rfsim --sa`
+`sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --sa`
 
 ## IF setup with OAI
 
diff --git a/doc/TESTING_5GSA_setup.md b/doc/TESTING_5GSA_setup.md
new file mode 100644
index 0000000000000000000000000000000000000000..786af5e27cc855c6f8d1c6f8be0ce195956d39ec
--- /dev/null
+++ b/doc/TESTING_5GSA_setup.md
@@ -0,0 +1,162 @@
+
+# OAI 5G SA tutorial [Under construction]
+
+In the following tutorial we describe how to deploy configure and test the two SA OAI setups:
+
+ - SA setup with OAI gNB and COTS UE
+ - SA setup with OAI gNB and OAI UE
+ 
+The operating system and hardware requirements to support OAI 5G NR are described [here](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/5g-nr-development-and-setup). 
+
+# 1.  SA setup with COTS UE
+At the moment of writing this document interoperability with the following COTS UE devices is being tested:
+
+ - [Quectel RM500Q-GL](https://www.quectel.com/product/5g-rm500q-gl/)
+ - [Simcom SIMCOM8200EA](https://www.simcom.com/product/SIM8200G.html)
+ - Huawei Mate 30 Pro
+
+ End-to-end control plane signaling to achieve a 5G SA connection, UE registration and PDU session establishment with the CN, as well as some basic user-plane traffic tests have been validated so far using the Quectel module and Huawei Mate 30 pro and partially validated with SIMCOM module. In terms of interoperability with different 5G Core Networks, so far this setup has been tested with:
+ 
+
+ - [OAI CN](https://openairinterface.org/oai-5g-core-network-project/)
+ - Nokia SA Box
+ - [Free CN](https://www.free5gc.org/)
+
+ 
+ ## 1.1  gNB build and configuration
+At the moment of writing this document, most of the code to support the SA setup is not merged into develop branch yet, but it is accessible through the following branches:
+
+ - NR_SA_F1AP_5GRECORDS
+ - develop-NR_SA_F1AP_5GRECORDS (up-to-date with latest develop branch)
+
+To build the gNB executable:
+```bash
+    cd cmake_targets
+    ./build_oai -I -w USRP #For OAI first time installation only to install software dependencies
+    ./build_oai --gNB -w USRP
+```
+
+A reference configuration file for the gNB is provided  [here](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop-NR_SA_F1AP_5GRECORDS/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf).     
+
+
+In the following, we highlight the fields of the file that have to be configured according to the configuration and interfaces of the Core Network. First, the PLMN section has to be filled with the proper values that match the configuration of the AMF and the UE USIM.
+```bash
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  1;
+    plmn_list = ({
+			 mcc = 208;
+			 mnc = 99;
+			 mnc_length = 2;
+			 snssaiList = (
+			 {
+				sst = 1;
+				sd  = 0x1; // 0 false, else true
+			 },
+			 {
+				 sst = 1;
+				 sd  = 0x112233; // 0 false, else true
+			 }
+			);
+		});
+```		
+Then, the source and destination IP interfaces for the communication with
+the Core Network also need to be set as shown below.
+
+```bash
+	////////// MME parameters:
+	 amf_ip_address      = ( { ipv4       = "192.168.70.132";
+			           ipv6       = "192:168:30::17";
+				   active     = "yes";
+				   preference = "ipv4";
+				 }
+			       );
+	 NETWORK_INTERFACES :
+	 {
+		 GNB_INTERFACE_NAME_FOR_NG_AMF            = "demo-oai";
+		 GNB_IPV4_ADDRESS_FOR_NG_AMF              = "192.168.70.129/24";
+		 GNB_INTERFACE_NAME_FOR_NGU               = "demo-oai";
+		 GNB_IPV4_ADDRESS_FOR_NGU                 = "192.168.70.129/24";
+		 GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
+	 };
+```	 
+In the first part (*amf_ip_address*) we specify the IP of the AMF and in the second part (*NETWORK_INTERFACES*) we specify the gNB local interface with AMF (N2 interface) and the UPF (N3 interface).
+
+### **gNB configuration in CU/DU split mode**
+For the configuration of the gNB in CU and DU blocks the following sample configuration files are provided for the CU and DU entities respectively. 
+......
+At the point of writing this document the control-plane exchanges between the CU and the DU over *F1-C* interface have been validated. The integration of *F1-U* over gtp-u for the support of data plane traffic is ongoing.
+
+## 1.2  OAI 5G Core Network installation and configuration
+The instructions for the installation of OAI CN components (AMF, SMF, NRF, UPF) using docker compose can be found [here](https://gitlab.eurecom.fr/oai/cn5g). Below are some complementary instructions which can be useful for the deployment.
+
+ ## 1.3  Execution of SA scenario
+
+After having configured the gNB, we can start the individual components in the following sequence:
+
+ - Launch Core Network
+ - Launch gNB
+ - Launch COTS UE (disable airplane mode)
+
+The execution command to start the gNB (in monolithic mode) is the following:
+```bash
+cd cmake_targets/ran_build/build
+sudo ./nr-softmodem -E --sa -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
+```	
+
+# 2. SA Setup with OAI UE 
+The SA setup with OAI UE has been validated with RFSIMULATOR for the moment. The control plane for the successful UE registration and PDU Session establishment has been verified with OAI and Nokia SA Box CNs. User-plane traffic validation after the establishment of the 5G connection is still pending for this setup. 
+
+In the following, we provide the instructions on how to build, configure and execute this SA setup. 
+
+## 2.1 Build and configuration
+To build the gNB and OAI UE executables:  
+
+```bash
+    cd cmake_targets
+    ./build_oai -I #For OAI first time installation only to install software dependencies
+    ./build_oai --gNB --nrUE -w SIMU
+```
+The gNB configuration can be performed according to what is described in section 1.1, using the same reference configuration file as with the RF scenario.
+
+### NAS configuration for the OAI UE
+At the moment, the NAS configuration parameters of the OAI UE are hardcoded in ***openair3/NAS/NR_UE/nr_nas_msg_sim.c***.  More specifically:
+
+ - The SUCI (*Subscription Concealed Identifier*) corresponding to default IMSI 2089900007487 is hardcoded in functions *generateRegistrationRequest()* and *generateIdentityResponse()* through the following lines:
+```bash
+    mm_msg->registration_request.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI;
+    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit1 = 9;
+    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit2 = 9;
+    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit3 = 0xf;
+    mm_msg->registration_request.fgsmobileidentity.suci.mccdigit1 = 2;
+    mm_msg->registration_request.fgsmobileidentity.suci.mccdigit2 = 0;
+    mm_msg->registration_request.fgsmobileidentity.suci.mccdigit3 = 8;
+    mm_msg->registration_request.fgsmobileidentity.suci.schemeoutput = 0x4778;
+```
+ - USIM_API_K and OPc keys are hardcoded at the beginning of the file:
+```bash
+// USIM_API_K: fe c8 6b a6 eb 70 7e d0 89 05 75 7b 1b b4 4b 8f 
+uint8_t k[16] = {0xfe, 0xc8, 0x6b, 0xa6, 0xeb, 0x70, 0x7e, 0xd0, 0x89, 0x05, 0x75, 0x7b, 0x1b, 0xb4, 0x4b, 0x8f};
+// OPC: c4 24 49 36 3b ba d0 2b 66 d1 6b c9 75 d7 7c c1
+const uint8_t opc[16] = {0xc4, 0x24, 0x49, 0x36, 0x3b, 0xba, 0xd0, 0x2b, 0x66, 0xd1, 0x6b, 0xc9, 0x75, 0xd7, 0x7c, 0xc1};
+```
+-  The NSSAI (*Network Slice Assistance Information*) and DNN (*Data Network Name*) are hardcoded in function *generatePduSessionEstablishRequest()*
+```bash
+  uint8_t             nssai[]={1,0,0,1}; //Corresponding to SST:1, SD:1
+  uint8_t             dnn[4]={0x4,0x6f,0x61,0x69}; //Corresponding to dnn:"oai"
+```
+For interoperability with OAI or other CNs, it should be ensured that the configuration of the aforementioned parameters match the configuration of the corresponding subscribed user at the core network.
+Hardcoding of the USIM information will soon be substituted with parsing those parameters from a configuration file. 
+
+## 2.2 Execution of SA scenario
+
+The order of starting the different components should be the same as the one described in section 1.3. 
+
+ - To launch the gNB:
+ ```bash
+ sudo RFSIMULATOR=server ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --rfsim --sa
+ ```
+- To launch the OAI UE:
+ ```bash
+sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --sa --nokrnmod
+```
+The IP address at the execution command of the OAI UE corresponds to the target IP of the gNB host that the RFSIMULATOR at the UE will connect to. In the above example, we assume that the gNB and UE are running on the same host so the specified address (127.0.0.1) is the one of the loopback interface.  
diff --git a/doc/testing_gnb_w_cots_ue_resources/enb.conf b/doc/testing_gnb_w_cots_ue_resources/enb.conf
index 35249aac25d2aeaeef64feb7808afa6dcda0ca9b..a6bbd98bda359b47c0d817d52245d8588b09565a 100755
--- a/doc/testing_gnb_w_cots_ue_resources/enb.conf
+++ b/doc/testing_gnb_w_cots_ue_resources/enb.conf
@@ -238,7 +238,7 @@ MACRLCs = (
 THREAD_STRUCT = (
   {
     parallel_config = "PARALLEL_RU_L1_TRX_SPLITaaaaaa";
-    worker_config = "ENABLE";
+    worker_config = "WORKER_ENABLE";
   }
 );
 
diff --git a/executables/main-ocp.c b/executables/main-ocp.c
index b0f0b05315b17b5d7a21e7e71fdf98d0b5c7e718..c5f18419a3d397319fc106d2086423493738eab7 100644
--- a/executables/main-ocp.c
+++ b/executables/main-ocp.c
@@ -86,6 +86,7 @@ char * split73_config;
 int split73;
 AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]= {0};
 AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]= {0};
+uint8_t proto_agent_flag = 0;
 void flexran_agent_slice_update(mid_t module_idP) {
 }
 int proto_agent_start(mod_id_t mod_id, const cudu_params_t *p){
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index 8b3d6fc64e3dd788781a19930263c4fd67980cb2..ea675eba9e8caf737f41edff715b8135da91ac36 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -86,6 +86,8 @@
 #include "T.h"
 #include "nfapi/oai_integration/vendor_ext.h"
 #include <nfapi/oai_integration/nfapi_pnf.h>
+#include <PHY/NR_TRANSPORT/nr_ulsch.h>
+#include <PHY/NR_ESTIMATION/nr_ul_estimation.h>
 //#define DEBUG_THREADS 1
 
 //#define USRP_DEBUG 1
@@ -347,6 +349,22 @@ static void *process_stats_thread(void *param) {
   return(NULL);
 }
 
+void *nrL1_stats_thread(void *param) {
+  PHY_VARS_gNB     *gNB      = (PHY_VARS_gNB *)param;
+  wait_sync("L1_stats_thread");
+  FILE *fd;
+  while (!oai_exit) {
+    sleep(1);
+    fd=fopen("nrL1_stats.log","w");
+    AssertFatal(fd!=NULL,"Cannot open ngL1_stats.log\n");
+    dump_nr_I0_stats(fd,gNB);
+    dump_pusch_stats(fd,gNB);
+    //    nr_dump_uci_stats(fd,eNB,eNB->proc.L1_proc_tx.frame_tx);
+    fclose(fd);
+  }
+  return(NULL);
+}
+
 void init_gNB_Tpool(int inst) {
   PHY_VARS_gNB *gNB;
   gNB = RC.gNB[inst];
@@ -383,7 +401,9 @@ void init_gNB_Tpool(int inst) {
   initNotifiedFIFO(gNB->resp_RU_tx);
 
   // Stats measurement thread
-  if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
+  if(opp_enabled == 1) threadCreate(&proc->process_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
+  threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW);
+
 }
 
 
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 0a042ba9b1d5da8451cca3b6e07a889b44a13cad..421ff4ad3ec54401399652ad2403343181a6e9b1 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -24,14 +24,8 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/mman.h>
 #include <sched.h>
 #include <linux/sched.h>
-#include <signal.h>
-#include <execinfo.h>
-#include <getopt.h>
 #include <sys/sysinfo.h>
 #include <math.h>
 
@@ -39,7 +33,6 @@
 
 #include "common/utils/assertions.h"
 #include "common/utils/system.h"
-#include "msc.h"
 
 #include "../../ARCH/COMMON/common_lib.h"
 #include "../../ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
@@ -50,20 +43,15 @@
 #include "PHY/types.h"
 #include "PHY/defs_nr_common.h"
 #include "PHY/phy_extern.h"
-#include "PHY/LTE_TRANSPORT/transport_proto.h"
 #include "PHY/NR_TRANSPORT/nr_transport_proto.h"
 #include "PHY/INIT/phy_init.h"
-#include "SCHED/sched_eNB.h"
 #include "SCHED_NR/sched_nr.h"
 
 #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
-#include "RRC/LTE/rrc_extern.h"
-#include "PHY_INTERFACE/phy_interface.h"
 
 #include "common/utils/LOG/log.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 
-#include "enb_config.h"
 #include <executables/softmodem-common.h>
 
 #ifdef SMBV
@@ -1948,39 +1936,41 @@ static void NRRCconfig_RU(void)
       if (config_isparamset(RUParamList.paramarray[j], RU_SDR_CLK_SRC)) {
         if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "internal") == 0) {
           RC.ru[j]->openair0_cfg.clock_source = internal;
-          LOG_D(PHY, "RU clock source set as internal\n");
+          LOG_I(PHY, "RU clock source set as internal\n");
         } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "external") == 0) {
           RC.ru[j]->openair0_cfg.clock_source = external;
-          LOG_D(PHY, "RU clock source set as external\n");
+          LOG_I(PHY, "RU clock source set as external\n");
         } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "gpsdo") == 0) {
           RC.ru[j]->openair0_cfg.clock_source = gpsdo;
-          LOG_D(PHY, "RU clock source set as gpsdo\n");
+          LOG_I(PHY, "RU clock source set as gpsdo\n");
         } else {
           LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr));
         }
       }
       else {
-        RC.ru[j]->openair0_cfg.clock_source = unset;
+        LOG_I(PHY,"Setting clock source to internal\n");
+        RC.ru[j]->openair0_cfg.clock_source = internal;
       }
 
       if (config_isparamset(RUParamList.paramarray[j], RU_SDR_TME_SRC)) {
         if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "internal") == 0) {
           RC.ru[j]->openair0_cfg.time_source = internal;
-          LOG_D(PHY, "RU time source set as internal\n");
+          LOG_I(PHY, "RU time source set as internal\n");
         } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "external") == 0) {
           RC.ru[j]->openair0_cfg.time_source = external;
-          LOG_D(PHY, "RU time source set as external\n");
+          LOG_I(PHY, "RU time source set as external\n");
         } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "gpsdo") == 0) {
           RC.ru[j]->openair0_cfg.time_source = gpsdo;
-          LOG_D(PHY, "RU time source set as gpsdo\n");
+          LOG_I(PHY, "RU time source set as gpsdo\n");
         } else {
           LOG_E(PHY, "Erroneous RU time source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr));
         }
       }
       else {
-	RC.ru[j]->openair0_cfg.time_source = unset;
+        LOG_I(PHY,"Setting time source to internal\n");
+	      RC.ru[j]->openair0_cfg.time_source = internal;
       }
-      
+
       if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) {
         if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) {
           RC.ru[j]->if_south                        = LOCAL_RF;
@@ -2050,7 +2040,7 @@ static void NRRCconfig_RU(void)
           RC.ru[j]->if_south                     = REMOTE_IF4p5;
           RC.ru[j]->function                     = NGFI_RAU_IF4p5;
           RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
-        } 
+        }
       }  /* strcmp(local_rf, "yes") != 0 */
 
       RC.ru[j]->nb_tx                             = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr);
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index 353751a66a0d267c9e69afd60ffbac2b459271fc..4727d09b043290dcc4f66a98f14fe1caefef8e4f 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -98,7 +98,6 @@ pthread_cond_t sync_cond;
 pthread_mutex_t sync_mutex;
 int sync_var=-1; //!< protected by mutex \ref sync_mutex.
 int config_sync_var=-1;
-msc_interface_t msc_interface;
 
 volatile int             start_gNB = 0;
 volatile int             oai_exit = 0;
@@ -165,6 +164,8 @@ uint32_t timing_advance = 0;
 uint64_t num_missed_slots=0; // counter for the number of missed slots
 
 #include <executables/split_headers.h>
+#include <SIMULATION/ETH_TRANSPORT/proto.h>
+
 int split73=0;
 void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
   AssertFatal(false, "Must not be called in this context\n");
@@ -344,7 +345,7 @@ int create_gNB_tasks(uint32_t gnb_nb) {
   }
 
 
-  if (AMF_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0 && get_softmodem_params()->sa==0)) {
+  if (AMF_MODE_ENABLED) {
     if (gnb_nb > 0) {
       /*
       if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
@@ -369,25 +370,31 @@ int create_gNB_tasks(uint32_t gnb_nb) {
         }
       }
 
-      if (itti_create_task (TASK_GTPV1_U, &gtpv1u_gNB_task, NULL) < 0) {
+      /*if (itti_create_task (TASK_GTPV1_U, &nr_gtpv1u_gNB_task, NULL) < 0) {
         LOG_E(GTPU, "Create task for GTPV1U failed\n");
         return -1;
-      }
+      }*/
     }
   }
 
-
   if (gnb_nb > 0) {
     if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
       LOG_E(GNB_APP, "Create task for gNB APP failed\n");
       return -1;
     }
-    LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
 
+    LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
     if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) {
       LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n");
       return -1;
     }
+    //Use check on x2ap to consider the NSA scenario and check on AMF_MODE_ENABLED for the SA scenario 
+    if(is_x2ap_enabled() || AMF_MODE_ENABLED){
+      if (itti_create_task (TASK_GTPV1_U, &nr_gtpv1u_gNB_task, NULL) < 0) {
+        LOG_E(GTPU, "Create task for GTPV1U failed\n");
+        return -1;
+      }
+    }
   }
 
   return 0;
@@ -623,33 +630,36 @@ static  void wait_nfapi_init(char *thread_name) {
 }
 
 void init_pdcp(void) {
-  //if (!NODE_IS_DU(RC.rrc[0]->node_type)) {
-  pdcp_layer_init();
-  uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
-                           (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
-
-  if (IS_SOFTMODEM_NOS1) {
-    printf("IS_SOFTMODEM_NOS1 option enabled \n");
-    pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT  ;
-  }
+  if (!NODE_IS_DU(RC.nrrrc[0]->node_type)) {
+    // pdcp_layer_init();
+    uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
+                            (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
+    if (IS_SOFTMODEM_NOS1) {
+      printf("IS_SOFTMODEM_NOS1 option enabled \n");
+      pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT;
+    }
 
-  pdcp_module_init(pdcp_initmask);
+    pdcp_module_init(pdcp_initmask);
 
-  /*if (NODE_IS_CU(RC.rrc[0]->node_type)) {
-    pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req);
-  } else {*/
-  pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
-  pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
-  //}
-  /*} else {
+    if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
+      LOG_I(PDCP, "node is CU, pdcp send rlc_data_req by proto_agent \n");
+      pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req);
+    } else {
+      LOG_I(PDCP, "node is gNB \n");
+      pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
+      pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
+    }
+  } else {
+    LOG_I(PDCP, "node is DU, rlc send pdcp_data_ind by proto_agent \n");
     pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind);
-  }*/
+  }
 }
 
 
 int main( int argc, char **argv )
 {
   int ru_id, CC_id = 0;
+
   start_background_system();
 
   ///static configuration for NR at the moment
@@ -675,8 +685,8 @@ int main( int argc, char **argv )
   }
 
   openair0_cfg[0].threequarter_fs = threequarter_fs;
-  AMF_MODE_ENABLED = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test;
-  NGAP_CONF_MODE   = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test;
+  AMF_MODE_ENABLED = get_softmodem_params()->sa;
+  NGAP_CONF_MODE   = get_softmodem_params()->sa;
 
   if (get_softmodem_params()->do_ra)
     AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
@@ -717,15 +727,11 @@ if(!IS_SOFTMODEM_NOS1)
 #endif
   LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
 
-  if(IS_SOFTMODEM_NOS1)
-    init_pdcp();
-
   if (RC.nb_nr_L1_inst > 0)
     RCconfig_NR_L1();
-  if (RC.nb_nr_inst > 0)  {
+
     // don't create if node doesn't connect to RRC/S1/GTP
     AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n");
-  }
 
   /* Start the agent. If it is turned off in the configuration, it won't start */
   /*
@@ -806,36 +812,38 @@ if(!IS_SOFTMODEM_NOS1)
     wait_nfapi_init("main?");
   }
 
-  printf("wait RUs\n");
-  wait_RUs();
-  printf("ALL RUs READY!\n");
-  printf("RC.nb_RU:%d\n", RC.nb_RU);
-  // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration)
-  printf("ALL RUs ready - init gNBs\n");
-  if(IS_SOFTMODEM_DOSCOPE) {
-    sleep(1);	
-    scopeParms_t p;
-    p.argc=&argc;
-    p.argv=argv;
-    p.gNB=RC.gNB[0];
-    p.ru=RC.ru[0];
-    load_softscope("nr",&p);
-  }
+  if (RC.nb_nr_L1_inst > 0) {
+    printf("wait RUs\n");
+    wait_RUs();
+    printf("ALL RUs READY!\n");
+    printf("RC.nb_RU:%d\n", RC.nb_RU);
+    // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration)
+    printf("ALL RUs ready - init gNBs\n");
+    if(IS_SOFTMODEM_DOSCOPE) {
+      sleep(1);
+      scopeParms_t p;
+      p.argc=&argc;
+      p.argv=argv;
+      p.gNB=RC.gNB[0];
+      p.ru=RC.ru[0];
+      load_softscope("nr",&p);
+    }
 
-  if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF) {
-    printf("Not NFAPI mode - call init_eNB_afterRU()\n");
-    init_eNB_afterRU();
-  } else {
-    printf("NFAPI mode - DO NOT call init_gNB_afterRU()\n");
-  }
+    if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF) {
+      printf("Not NFAPI mode - call init_eNB_afterRU()\n");
+      init_eNB_afterRU();
+    } else {
+      printf("NFAPI mode - DO NOT call init_gNB_afterRU()\n");
+    }
 
-  printf("ALL RUs ready - ALL gNBs ready\n");
-  // connect the TX/RX buffers
-  printf("Sending sync to all threads\n");
-  pthread_mutex_lock(&sync_mutex);
-  sync_var=0;
-  pthread_cond_broadcast(&sync_cond);
-  pthread_mutex_unlock(&sync_mutex);
+    printf("ALL RUs ready - ALL gNBs ready\n");
+    // connect the TX/RX buffers
+    printf("Sending sync to all threads\n");
+    pthread_mutex_lock(&sync_mutex);
+    sync_var=0;
+    pthread_cond_broadcast(&sync_cond);
+    pthread_mutex_unlock(&sync_mutex);
+  }
   printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
   end_configmodule();
   printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
@@ -873,7 +881,10 @@ if(!IS_SOFTMODEM_NOS1)
   printf("stopping MODEM threads\n");
   // cleanup
   stop_gNB(NB_gNB_INST);
-  stop_RU(NB_RU);
+
+  if (RC.nb_nr_L1_inst > 0) {
+    stop_RU(NB_RU);
+  }
 
   /* release memory used by the RU/gNB threads (incomplete), after all
    * threads have been stopped (they partially use the same memory) */
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index a35a11a0332b4a3d301549f82d94ee872e7a2546..53ec70330c0c9c1ced9481f1146286a2a1ef4153 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -290,6 +290,7 @@ void processSlotTX(void *arg) {
   int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx);
   uint8_t gNB_id = 0;
 
+  LOG_D(PHY,"%d.%d => slot type %d\n",proc->frame_tx,proc->nr_slot_tx,tx_slot_type);
   if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){
 
     // trigger L2 to run ue_scheduler thru IF module
@@ -343,7 +344,7 @@ void processSlotRX(void *arg) {
     LOG_D(PHY, "In %s: slot %d, time %lu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc()-a)/3500);
 #endif
 
-    if(IS_SOFTMODEM_NOS1){
+    if(IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa){
       NR_UE_MAC_INST_t *mac = get_mac_inst(0);
       protocol_ctxt_t ctxt;
       PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO, mac->crnti, proc->frame_rx, proc->nr_slot_rx, 0);
@@ -607,7 +608,7 @@ void *UE_thread(void *arg) {
     thread_idx = absolute_slot % NR_RX_NB_TH;
     int slot_nr = absolute_slot % nb_slot_frame;
     notifiedFIFO_elt_t *msgToPush;
-    AssertFatal((msgToPush=pullTpool(&freeBlocks,&(get_nrUE_params()->Tpool))) != NULL,"chained list failure");
+    AssertFatal((msgToPush=pullNotifiedFIFO_nothreadSafe(&freeBlocks)) != NULL,"chained list failure");
     nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(msgToPush);
     curMsg->UE=UE;
     // update thread index for received subframe
@@ -714,7 +715,13 @@ void *UE_thread(void *arg) {
     if (openair0_cfg[0].duplex_mode == duplex_mode_TDD) {
 
       uint8_t    tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots;
-      int   nrofUplinkSlots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
+
+      int   nrofUplinkSlots = 0;
+      if (mac->scc_SIB)
+	      nrofUplinkSlots = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
+      else if (mac->scc)
+	      nrofUplinkSlots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
+
       uint8_t  num_UL_slots = nrofUplinkSlots + (nrofUplinkSlots != 0);
       uint8_t first_tx_slot = tdd_period - num_UL_slots;
 
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 83b3d433aa54d1e3e6f68727acdca399d571e21d..cbc79912a2c96f0b1679790e72695702dc2008fd 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -86,8 +86,11 @@ unsigned short config_frames[4] = {2,9,11,13};
 #include "executables/softmodem-common.h"
 #include "executables/thread-common.h"
 
+#if defined(ITTI_SIM) || defined(RFSIM_NAS)
+#include "nr_nas_msg_sim.h"
+#endif
+
 extern const char *duplex_mode[];
-msc_interface_t msc_interface;
 THREAD_STRUCT thread_struct;
 nrUE_params_t nrUE_params;
 
@@ -150,8 +153,9 @@ int     transmission_mode = 1;
 int            numerology = 0;
 int           oaisim_flag = 0;
 int            emulate_rf = 0;
-
-char uecap_xer[1024],uecap_xer_in=0;
+uint32_t       N_RB_DL    = 106;
+char         uecap_xer_in = 0;
+char         uecap_xer[1024];
 
 /* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
  * this is very hackish - find a proper solution
@@ -191,7 +195,12 @@ int create_tasks_nrue(uint32_t ue_nb) {
       LOG_E(NR_RRC, "Create task for RRC UE failed\n");
       return -1;
     }
-
+#if defined(ITTI_SIM) || defined(RFSIM_NAS)
+  if (itti_create_task (TASK_NAS_NRUE, nas_nrue_task, NULL) < 0) {
+    LOG_E(NR_RRC, "Create task for NAS UE failed\n");
+    return -1;
+  }
+#endif
   }
 
   itti_wait_ready(0);
@@ -327,8 +336,9 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
     LOG_I(PHY, "Set UE frame_type %d\n", fp->frame_type);
   }
 
-  LOG_I(PHY, "Set UE N_RB_DL %d\n", fp->N_RB_DL);
+  fp->N_RB_DL = N_RB_DL;
 
+  LOG_I(PHY, "Set UE N_RB_DL %d\n", N_RB_DL);
   LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs);
 
 }
@@ -390,10 +400,10 @@ void init_pdcp(void) {
   }
   pdcp_layer_init();
   nr_DRB_preconfiguration();*/
+  pdcp_layer_init();
   pdcp_module_init(pdcp_initmask);
   pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
   pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
-  LOG_I(PDCP, "Before getting out from init_pdcp() \n");
 }
 
 // Stupid function addition because UE itti messages queues definition is common with eNB
@@ -445,7 +455,7 @@ int main( int argc, char **argv ) {
   LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
 
   init_NR_UE(1,rrc_config_path);
-  if(IS_SOFTMODEM_NOS1)
+  if(IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa)
 	  init_pdcp();
 
   NB_UE_INST=1;
@@ -473,8 +483,22 @@ int main( int argc, char **argv ) {
       mac->if_module->phy_config_request(&mac->phy_config);
 
     fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config;
-
-    nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]);
+    if (get_softmodem_params()->sa) { // set frame config to initial values from command line and assume that the SSB is centered on the grid
+      nrUE_config->ssb_config.scs_common = get_softmodem_params()->numerology;
+      nrUE_config->carrier_config.dl_grid_size[nrUE_config->ssb_config.scs_common] = UE[CC_id]->frame_parms.N_RB_DL;
+      nrUE_config->carrier_config.ul_grid_size[nrUE_config->ssb_config.scs_common] = UE[CC_id]->frame_parms.N_RB_DL;
+      nrUE_config->carrier_config.dl_frequency =  (downlink_frequency[0][0] -(6*UE[CC_id]->frame_parms.N_RB_DL*(15000<<nrUE_config->ssb_config.scs_common)))/1000;
+      nrUE_config->carrier_config.uplink_frequency =  (downlink_frequency[0][0] -(6*UE[CC_id]->frame_parms.N_RB_DL*(15000<<nrUE_config->ssb_config.scs_common)))/1000;
+      nrUE_config->ssb_table.ssb_offset_point_a = (UE[CC_id]->frame_parms.N_RB_DL - 20)>>1;
+
+      // Initialize values, will be updated upon SIB1 reception
+      nrUE_config->cell_config.frame_duplex_type = TDD;
+      nrUE_config->ssb_table.ssb_mask_list[0].ssb_mask = 0xFFFFFFFF;
+      nrUE_config->ssb_table.ssb_period = 1;
+    }
+    
+    nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, 
+			   mac->scc == NULL ? 78 : *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]);
 
     init_symbol_rotation(&UE[CC_id]->frame_parms);
     init_nr_ue_vars(UE[CC_id], 0, abstraction_flag);
@@ -496,7 +520,7 @@ int main( int argc, char **argv ) {
   configure_linux();
   mlockall(MCL_CURRENT | MCL_FUTURE);
  
-  if(IS_SOFTMODEM_DOSCOPE) { 
+  if(IS_SOFTMODEM_DOSCOPE) {
     load_softscope("nr",PHY_vars_UE_g[0][0]);
   }     
 
diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h
index 5c082b7bbbc8c4cc3fcf02261c5ec18801838376..be3ca2d1a27ad4c7920d12d513814e38238ab2f9 100644
--- a/executables/nr-uesoftmodem.h
+++ b/executables/nr-uesoftmodem.h
@@ -55,7 +55,7 @@
     {"ue-scan-carrier",          CONFIG_HLP_UESCAN,      PARAMFLAG_BOOL,  iptr:&(UE->UE_scan_carrier),        defintval:0,           TYPE_INT,      0},     \
     {"ue-fo-compensation",       CONFIG_HLP_UEFO,        PARAMFLAG_BOOL,  iptr:&(UE->UE_fo_compensation),     defintval:0,           TYPE_INT,      0},     \
     {"ue-max-power",             NULL,                   0,               iptr:&(tx_max_power[0]),            defintval:90,          TYPE_INT,      0},     \
-    {"r"  ,                      CONFIG_HLP_PRB,         0,               iptr:&(fp->N_RB_DL),                defintval:25,          TYPE_UINT,     0},     \
+    {"r"  ,                      CONFIG_HLP_PRB,         0,               uptr:&(N_RB_DL),                    defuintval:160,         TYPE_UINT,     0},     \
     {"A" ,                       CONFIG_HLP_TADV,        0,               iptr:&(UE->timing_advance),         defintval:0,           TYPE_INT,      0}, \
     {"E" ,                       CONFIG_HLP_TQFS,        PARAMFLAG_BOOL,  u8ptr:&(fp->threequarter_fs),       defintval:0,           TYPE_UINT8,    0}, \
     {"T" ,                       CONFIG_HLP_TDD,         PARAMFLAG_BOOL,  iptr:&tddflag,                      defintval:0,           TYPE_INT,      0}, \
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index ad349d4d019930a94861b3495a69b5cec5df550e..b6a2b18215ab51b617b86a655f40e9ef6dc06f30 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -85,6 +85,7 @@ extern "C"
 #define CONFIG_HLP_TNOFORK       "to ease debugging with gdb\n"
 
 #define CONFIG_HLP_NUMEROLOGY    "adding numerology for 5G\n"
+#define CONFIG_HLP_BAND          "band index\n"
 #define CONFIG_HLP_EMULATE_RF    "Emulated RF enabled(disable by defult)\n"
 #define CONFIG_HLP_PARALLEL_CMD  "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n"
 #define CONFIG_HLP_WORKER_CMD    "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n"
@@ -111,6 +112,7 @@ extern "C"
 #define SINGLE_THREAD_FLAG  softmodem_params.single_thread_flag
 #define CHAIN_OFFSET        softmodem_params.chain_offset
 #define NUMEROLOGY          softmodem_params.numerology
+#define BAND                softmodem_params.band
 #define EMULATE_RF          softmodem_params.emulate_rf
 #define CLOCK_SOURCE        softmodem_params.clock_source
 #define TIMING_SOURCE       softmodem_params.timing_source
@@ -125,22 +127,23 @@ extern "C"
 extern int usrp_tx_thread;
 #define CMDLINE_PARAMS_DESC {  \
     {"rf-config-file",       CONFIG_HLP_RFCFGF,       0,              strptr:(char **)&RF_CONFIG_FILE,    defstrval:NULL,        TYPE_STRING, sizeof(RF_CONFIG_FILE)},\
-    {"split73",              CONFIG_HLP_SPLIT73,      0,              strptr:(char **)&SPLIT73,           defstrval:NULL,        TYPE_STRING, sizeof(SPLIT73)},\
-    {"thread-pool",          CONFIG_HLP_TPOOL,        0,              strptr:(char **)&TP_CONFIG,         defstrval:"n",         TYPE_STRING, sizeof(TP_CONFIG)}, \
+    {"split73",              CONFIG_HLP_SPLIT73,      0,              strptr:(char **)&SPLIT73,           defstrval:NULL,        TYPE_STRING, sizeof(SPLIT73)},       \
+    {"thread-pool",          CONFIG_HLP_TPOOL,        0,              strptr:(char **)&TP_CONFIG,         defstrval:"n",         TYPE_STRING, sizeof(TP_CONFIG)},     \
     {"phy-test",             CONFIG_HLP_PHYTST,       PARAMFLAG_BOOL, iptr:&PHY_TEST,                     defintval:0,           TYPE_INT,    0},                     \
     {"do-ra",                CONFIG_HLP_DORA,         PARAMFLAG_BOOL, iptr:&DO_RA,                        defintval:0,           TYPE_INT,    0},                     \
-    {"sa",                   CONFIG_HLP_SA,           PARAMFLAG_BOOL, iptr:&SA,                             defintval:0,           TYPE_INT,    0},                     \
+    {"sa",                   CONFIG_HLP_SA,           PARAMFLAG_BOOL, iptr:&SA,                           defintval:0,           TYPE_INT,    0},                     \
     {"usim-test",            CONFIG_HLP_USIM,         PARAMFLAG_BOOL, u8ptr:&USIM_TEST,                   defintval:0,           TYPE_UINT8,  0},                     \
-    {"clock-source",                CONFIG_HLP_CLK,          0,              uptr:&CLOCK_SOURCE,                 defintval:0,           TYPE_UINT,   0},                     \
-    {"time-source",                CONFIG_HLP_TME,          0,              uptr:&TIMING_SOURCE,                 defintval:0,           TYPE_UINT,   0},                     \
+    {"clock-source",         CONFIG_HLP_CLK,          0,              uptr:&CLOCK_SOURCE,                 defintval:0,           TYPE_UINT,   0},                     \
+    {"time-source",          CONFIG_HLP_TME,          0,              uptr:&TIMING_SOURCE,                defintval:0,           TYPE_UINT,   0},                     \
     {"wait-for-sync",        NULL,                    PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC,                defintval:0,           TYPE_INT,    0},                     \
     {"single-thread-enable", CONFIG_HLP_NOSNGLT,      PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG,           defintval:0,           TYPE_INT,    0},                     \
-    {"C" ,                   CONFIG_HLP_DLF,          0,              u64ptr:&(downlink_frequency[0][0]), defuintval:0, TYPE_UINT64,   0},                     \
-    {"CO" ,                  CONFIG_HLP_ULF,          0,              iptr:&(uplink_frequency_offset[0][0]), defintval:0, TYPE_INT,   0},                     \
+    {"C" ,                   CONFIG_HLP_DLF,          0,              u64ptr:&(downlink_frequency[0][0]),     defuintval:3619200000,  TYPE_UINT64,   0},              \
+    {"CO" ,                  CONFIG_HLP_ULF,          0,              iptr:&(uplink_frequency_offset[0][0]),  defintval:0,   TYPE_INT,      0},              \
     {"a" ,                   CONFIG_HLP_CHOFF,        0,              iptr:&CHAIN_OFFSET,                 defintval:0,           TYPE_INT,    0},                     \
     {"d" ,                   CONFIG_HLP_SOFTS,        PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms,         defintval:0,           TYPE_INT8,   0},                     \
     {"q" ,                   CONFIG_HLP_STMON,        PARAMFLAG_BOOL, iptr:&opp_enabled,                  defintval:0,           TYPE_INT,    0},                     \
-    {"numerology" ,          CONFIG_HLP_NUMEROLOGY,   PARAMFLAG_BOOL, iptr:&NUMEROLOGY,                   defintval:0,           TYPE_INT,    0},                     \
+    {"numerology" ,          CONFIG_HLP_NUMEROLOGY,   PARAMFLAG_BOOL, iptr:&NUMEROLOGY,                   defintval:1,           TYPE_INT,    0},                     \
+    {"band" ,                CONFIG_HLP_BAND,         PARAMFLAG_BOOL, iptr:&BAND,                         defintval:78,          TYPE_INT,    0},                     \
     {"emulate-rf" ,          CONFIG_HLP_EMULATE_RF,   PARAMFLAG_BOOL, iptr:&EMULATE_RF,                   defintval:0,           TYPE_INT,    0},                     \
     {"parallel-config",      CONFIG_HLP_PARALLEL_CMD, 0,              strptr:(char **)&parallel_config,   defstrval:NULL,        TYPE_STRING, 0},                     \
     {"worker-config",        CONFIG_HLP_WORKER_CMD,   0,              strptr:(char **)&worker_config,     defstrval:NULL,        TYPE_STRING, 0},                     \
@@ -150,9 +153,9 @@ extern int usrp_tx_thread;
     {"nokrnmod",             CONFIG_HLP_NOKRNMOD,     PARAMFLAG_BOOL, uptr:&nokrnmod,                     defintval:0,           TYPE_INT,    0},                     \
     {"nbiot-disable",        CONFIG_HLP_DISABLNBIOT,  PARAMFLAG_BOOL, uptr:&nonbiot,                      defuintval:0,          TYPE_INT,    0},                     \
     {"use-256qam-table",     CONFIG_HLP_256QAM,       PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE,             defintval:0,           TYPE_INT,    0},                     \
-    {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0,              iptr:&usrp_tx_thread,               defstrval:0,           TYPE_INT,    0},        \
-    {"nfapi",                CONFIG_HLP_NFAPI,        0,              u8ptr:&nfapi_mode,                       defintval:0,           TYPE_UINT8,  0},                     \
-    {"non-stop",            CONFIG_HLP_NONSTOP,      PARAMFLAG_BOOL, iptr:&NON_STOP,                       defintval:0,           TYPE_INT,  0},                     \
+    {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0,              iptr:&usrp_tx_thread,               defstrval:0,           TYPE_INT,    0},                     \
+    {"nfapi",                CONFIG_HLP_NFAPI,        0,              u8ptr:&nfapi_mode,                  defintval:0,           TYPE_UINT8,  0},                     \
+    {"non-stop",            CONFIG_HLP_NONSTOP,      PARAMFLAG_BOOL, iptr:&NON_STOP,                      defintval:0,           TYPE_INT,    0},                     \
   }
 
   
@@ -236,6 +239,7 @@ typedef struct {
   int            single_thread_flag; //eNodeB only
   int            chain_offset;
   int            numerology;
+  int            band;
   unsigned int   start_msc;
   uint32_t       clock_source;
   uint32_t       timing_source;
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
index 0a83c1a27f015a2e0bd5c49960ae515fba602319..8e6bf9a8026ae90dd7d5ab3a0a9d65af53e5f233 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
@@ -14,7 +14,7 @@
 
 
 /// RX_IND
-#define FAPI_NR_RX_PDU_TYPE_MIB 0x01
+#define FAPI_NR_RX_PDU_TYPE_SSB 0x01
 #define FAPI_NR_RX_PDU_TYPE_SIB 0x02 
 #define FAPI_NR_RX_PDU_TYPE_DLSCH 0x03 
 #define FAPI_NR_DCI_IND 0x04
@@ -45,6 +45,8 @@
 #define FAPI_NR_DL_CONFIG_TYPE_DLSCH 0x02
 #define FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH 0x03
 #define FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH 0x04
+#define FAPI_NR_DL_CONFIG_TYPE_P_DLSCH 0x05
+#define FAPI_NR_DL_CONFIG_TYPES 0x05
 
 #define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
 #define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02
@@ -59,6 +61,6 @@
 #define FAPI_NR_UL_CONFIG_TYPE_PUCCH 0x02
 #define FAPI_NR_UL_CONFIG_TYPE_PUSCH 0x03
 #define FAPI_NR_UL_CONFIG_TYPE_SRS   0x04
-
+#define FAPI_NR_UL_CONFIG_TYPES      0x04
 
 #endif
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 0436f92a8d493ed2904ac073527a29df7ff283f6..c0abf6acb041f7cfa4d0358c5e3daf0ffcdfabbf 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
@@ -111,8 +111,8 @@ typedef struct {
   uint8_t ssb_index;
   uint8_t ssb_length;
   uint16_t cell_id;
-
-} fapi_nr_mib_pdu_t;
+  uint16_t ssb_start_subcarrier;
+} fapi_nr_ssb_pdu_t;
 
 typedef struct {
   uint32_t pdu_length;
@@ -124,7 +124,7 @@ typedef struct {
   uint8_t pdu_type;
   union {
     fapi_nr_pdsch_pdu_t pdsch_pdu;
-    fapi_nr_mib_pdu_t mib_pdu;
+    fapi_nr_ssb_pdu_t ssb_pdu;
     fapi_nr_sib_pdu_t sib_pdu;
   };
 } fapi_nr_rx_indication_body_t;
diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c
index 1afe82497a3b0ed6d02477605468fd623f5d25bb..b1ce6ab0de1f023a5357221937b1e2cd95d1e3fa 100644
--- a/openair1/PHY/CODING/nr_rate_matching.c
+++ b/openair1/PHY/CODING/nr_rate_matching.c
@@ -493,8 +493,8 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
   }
 
   ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z;
-  AssertFatal(Foffset <= E,"Foffset %d > E %d\n",Foffset,E); 
-  AssertFatal(Foffset <= Ncb,"Foffset %d > Ncb %d\n",Foffset,Ncb); 
+  AssertFatal(Foffset <= E,"Foffset %d > E %d\n",Foffset,E);
+  AssertFatal(Foffset <= Ncb,"Foffset %d > Ncb %d\n",Foffset,Ncb);
 
 #ifdef RM_DEBUG
   printf("nr_rate_matching_ldpc_rx: Clear %d, E %d, k0 %d, Ncb %d, rvidx %d\n", clear, E, ind, Ncb, rvidx);
diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c
index 5ab46ccda24b54e19d63d178806db7bc176c90a5..8189a7ab341b6ab266df8633e050c3aaf503fe1b 100644
--- a/openair1/PHY/INIT/nr_init_ru.c
+++ b/openair1/PHY/INIT/nr_init_ru.c
@@ -121,7 +121,7 @@ int nr_phy_init_RU(RU_t *ru) {
     AssertFatal(ru->num_gNB <= NUMBER_OF_gNB_MAX,"gNB instances %d > %d\n",
 		ru->num_gNB,NUMBER_OF_gNB_MAX);
 
-    LOG_E(PHY,"[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB);
+    LOG_I(PHY,"[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB);
     
     int beam_count = 0;
     if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1
diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c
index 34938501e33c43a14bb5c8d74a7c89753354e677..3a9d8a6c18f9398f5c25b9d0912c5c3728235b1d 100644
--- a/openair1/PHY/INIT/nr_parms.c
+++ b/openair1/PHY/INIT/nr_parms.c
@@ -264,6 +264,9 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
   uint64_t dl_bw_khz = (12*config->carrier_config.dl_grid_size[config->ssb_config.scs_common])*(15<<config->ssb_config.scs_common);
   fp->dl_CarrierFreq = ((dl_bw_khz>>1) + config->carrier_config.dl_frequency)*1000 ;
 
+  LOG_D(PHY,"dl_bw_kHz %lu\n",dl_bw_khz);
+  LOG_D(PHY,"dl_CarrierFreq %lu\n",fp->dl_CarrierFreq);
+
   uint64_t ul_bw_khz = (12*config->carrier_config.ul_grid_size[config->ssb_config.scs_common])*(15<<config->ssb_config.scs_common);
   fp->ul_CarrierFreq = ((ul_bw_khz>>1) + config->carrier_config.uplink_frequency)*1000 ;
 
@@ -277,7 +280,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
 
   LOG_I(PHY, "Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, uplink_frequency_offset);
 
-  AssertFatal(fp->frame_type==config->cell_config.frame_duplex_type, "Invalid duplex type in config request file for band %d\n", fp->nr_band);
+  AssertFatal(fp->frame_type==config->cell_config.frame_duplex_type, "Invalid duplex type (frame_type %d,cell_config.frame_duplex_type %d) in config request file for band %d\n", fp->frame_type,config->cell_config.frame_duplex_type,fp->nr_band);
 
   AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + uplink_frequency_offset), "Disagreement in uplink frequency for band %d: ul_CarrierFreq = %lu Hz vs expected %lu Hz\n", fp->nr_band, fp->ul_CarrierFreq, fp->dl_CarrierFreq + uplink_frequency_offset);
 
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
index eab9b3f321a76b1f4265d8d9cbb6166a29d91e31..0ce716ef2082f3883c577f30bda5583e52642516 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
@@ -35,7 +35,7 @@ static int16_t ru_90c[2*128] = {32767, 0,32766, -402,32758, -804,32746, -1206,32
 #define SCALE 0x3FFF
 
 static const short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
-static const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
+//static const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
 
 extern unsigned short dftsizes[34];
 extern int16_t *ul_ref_sigs_rx[30][2][34];
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index f11a39e24991e9de27bb8777682b622259f41c59..61af617d6e6a6ae7dd47147a751a5bcdb83acd3e 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -61,12 +61,17 @@ int find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) {
     if (eNB->dlsch[i][0] == NULL) continue;
     LOG_D(PHY,"searching for rnti %x : UE index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,eNB->dlsch[i][0]->harq_mask,eNB->dlsch[i][0]->rnti,first_free_index);
 
-    if ((eNB->dlsch[i][0]->harq_mask >0) &&
-        (eNB->dlsch[i][0]->rnti==rnti))       return i;
-    else if ((eNB->dlsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
+    if (type == SEARCH_EXIST_RA) {
+      if (eNB->dlsch[i][0]->rnti==rnti) return i;
+    } else {
+      if ((eNB->dlsch[i][0]->harq_mask >0) &&
+          (eNB->dlsch[i][0]->rnti==rnti))       return i;
+      else if ((eNB->dlsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
+    }
+
   }
 
-  if (type == SEARCH_EXIST)
+  if (type == SEARCH_EXIST_RA || type == SEARCH_EXIST)
     return -1;
 
   if (first_free_index != -1)
@@ -83,12 +88,16 @@ int find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) {
   for (int i=0; i<NUMBER_OF_ULSCH_MAX; i++) {
     if (eNB->ulsch[i]==NULL) continue;
 
-    if ((eNB->ulsch[i]->harq_mask >0) &&
-        (eNB->ulsch[i]->rnti==rnti))       return i;
-    else if ((eNB->ulsch[i]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
+    if (type == SEARCH_EXIST_RA) {
+      if (eNB->ulsch[i]->rnti == rnti) return i;
+    } else {
+      if ((eNB->ulsch[i]->harq_mask >0) &&
+          (eNB->ulsch[i]->rnti==rnti))       return i;
+      else if ((eNB->ulsch[i]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
+    }
   }
 
-  if (type == SEARCH_EXIST)
+  if (type == SEARCH_EXIST_RA || type == SEARCH_EXIST)
     return -1;
 
   if (first_free_index != -1)
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index 585a9d92a5c623fb560cb467fef01e629bf6a598..32700664480e2d9a37a60b2ead13dfcbacc0221a 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -982,7 +982,14 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
         break;
       } else if (first_uci_stats == NULL && eNB->uci_stats[i].rnti == 0) first_uci_stats = &eNB->uci_stats[i];
 
-    if (uci_stats == NULL) { uci_stats=first_uci_stats; uci_stats->rnti = eNB->uci_vars[UCI_id].rnti;}
+    if (uci_stats == NULL) {
+      if (first_uci_stats == NULL) {
+        LOG_E(PHY,"first_uci_stats is NULL\n");
+        return -1;
+      }
+      uci_stats=first_uci_stats;
+      uci_stats->rnti = eNB->uci_vars[UCI_id].rnti;
+    }
 
     AssertFatal(uci_stats!=NULL,"No stat index found\n");
     uci_stats->frame = frame;
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common.h b/openair1/PHY/LTE_TRANSPORT/transport_common.h
index 7c1065736d77f70b7fa0d9fc7023da187ee3f549..93ca7195deeb40a6f9a312ea7ec8134d5ef59556 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_common.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_common.h
@@ -93,7 +93,8 @@
 #define PMI_2A_R1_1j 2
 
 typedef enum { SEARCH_EXIST=0,
-               SEARCH_EXIST_OR_FREE
+               SEARCH_EXIST_OR_FREE,
+               SEARCH_EXIST_RA
              } find_type_t;
 
 typedef enum {
diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c
index 0be635ba0b052175c614ee5b858f96b079fa4612..39c730bfac3a5b8c973e9e9643e40acbaf61cee0 100644
--- a/openair1/PHY/MODULATION/slot_fep_nr.c
+++ b/openair1/PHY/MODULATION/slot_fep_nr.c
@@ -211,16 +211,19 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
     memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
 
     int16_t *rxdata_ptr;
+    rx_offset%=frame_length_samples*2;
 
-    if (frame_length_samples - rx_offset < frame_parms->ofdm_symbol_size) {
+    if (rx_offset+frame_parms->ofdm_symbol_size > frame_length_samples*2 ) {
+      // rxdata is 2 frames len
+      // we have to wrap on the end
 
       memcpy((void *)&tmp_dft_in[0],
              (void *)&common_vars->rxdata[aa][rx_offset],
-             (frame_length_samples - rx_offset) * sizeof(int32_t));
-      memcpy((void *)&tmp_dft_in[frame_length_samples - rx_offset],
+             (frame_length_samples*2 - rx_offset) * sizeof(int32_t));
+      memcpy((void *)&tmp_dft_in[frame_length_samples*2 - rx_offset],
              (void *)&common_vars->rxdata[aa][0],
-             (frame_parms->ofdm_symbol_size - (frame_length_samples - rx_offset)) * sizeof(int32_t));
-      rxdata_ptr = (int16_t *)&tmp_dft_in[0];
+             (frame_parms->ofdm_symbol_size - (frame_length_samples*2 - rx_offset)) * sizeof(int32_t));
+      rxdata_ptr = (int16_t *)tmp_dft_in;
 
     } else if ((rx_offset & 7) != 0) {
 
@@ -228,7 +231,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
       memcpy((void *)&tmp_dft_in[0],
              (void *)&common_vars->rxdata[aa][rx_offset],
              frame_parms->ofdm_symbol_size * sizeof(int32_t));
-      rxdata_ptr = (int16_t *)&tmp_dft_in[0];
+      rxdata_ptr = (int16_t *)tmp_dft_in;
 
     } else {
 
@@ -308,7 +311,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
     memcpy((void *)&tmp_dft_in[sample_offset - rxdata_offset],
            (void *)&rxdata[0],
            (frame_parms->ofdm_symbol_size - sample_offset + rxdata_offset) * sizeof(int32_t));
-    rxdata_ptr = (int16_t *)&tmp_dft_in[0];
+    rxdata_ptr = (int16_t *)tmp_dft_in;
 
   } else if (((rxdata_offset - sample_offset) & 7) != 0) {
 
@@ -316,7 +319,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
     memcpy((void *)&tmp_dft_in[0],
            (void *)&rxdata[rxdata_offset - sample_offset],
            (frame_parms->ofdm_symbol_size) * sizeof(int32_t));
-    rxdata_ptr = (int16_t *)&tmp_dft_in[0];
+    rxdata_ptr = (int16_t *)tmp_dft_in;
 
   } else {
 
diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
index d3e33a91a889e7803186ee0dd27032b0f7dc1398..91b6a592487790093dd52038108875960e73373b 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
@@ -70,51 +70,81 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
 }
 
 
-void gNB_I0_measurements(PHY_VARS_gNB *gNB) {
+void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) {
+
+
+    int min_I0=1000,max_I0=0;
+    int amin=0,amax=0;
+    for (int i=0; i<gNB->frame_parms.N_RB_UL; i++) {
+      if (i==(gNB->frame_parms.N_RB_UL>>1) - 1) i+=2;
+
+      if (gNB->measurements.n0_subband_power_tot_dB[i]<min_I0) {min_I0 = gNB->measurements.n0_subband_power_tot_dB[i]; amin=i;}
+
+      if (gNB->measurements.n0_subband_power_tot_dB[i]>max_I0) {max_I0 = gNB->measurements.n0_subband_power_tot_dB[i]; amax=i;}
+    }
+
+    for (int i=0; i<gNB->frame_parms.N_RB_UL; i++) {
+     fprintf(fd,"%2d.",gNB->measurements.n0_subband_power_tot_dB[i]-gNB->measurements.n0_subband_power_avg_dB);
+     if (i%25 == 24) fprintf(fd,"\n");
+    }
+
+    fprintf(fd,"\nmax_I0 %d (rb %d), min_I0 %d (rb %d), avg I0 %d\n", max_I0, amax, min_I0, amin, gNB->measurements.n0_subband_power_avg_dB);
+
+    fprintf(fd,"PRACH I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
+
+
+}
+
+
+
+void gNB_I0_measurements(PHY_VARS_gNB *gNB,int first_symb,int num_symb) {
 
   NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
   NR_gNB_COMMON *common_vars = &gNB->common_vars;
   PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
-  NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
-  double rx_gain = openair0_cfg[0].rx_gain[0];
-  double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
   uint32_t *rb_mask = gNB->rb_mask_ul;
-  int symbol = gNB->ulmask_symb;
-  int rb, offset, nb_rb;
-  uint32_t n0_subband_power_temp = 0;
+  int rb, offset, offset0, nb_rb, len;
   int32_t *ul_ch;
-
-  if (symbol>-1) {
-    measurements->n0_power_tot = 0;
-    for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-      nb_rb = 0;
-      for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
-        if ((rb_mask[rb>>5]&(1<<(rb&31))) == 0) {  // check that rb was not used in this subframe
-          nb_rb++;
-          offset = (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
-          offset += (symbol*frame_parms->ofdm_symbol_size);
-          ul_ch  = &common_vars->rxdataF[aarx][offset];
-          //TODO what about DC?
-          n0_subband_power_temp += signal_energy_nodc(ul_ch,12);
-        }
-      }
-
-      if (nb_rb != 0) {
-        measurements->n0_power[aarx] = n0_subband_power_temp/nb_rb;
-        measurements->n0_power_dB[aarx] = dB_fixed(measurements->n0_power[aarx]);
-        measurements->n0_power_tot += measurements->n0_power[aarx];
-      }
-
+  int32_t n0_power_tot;
+  int64_t n0_power_tot2;
+
+  nb_rb = 0;
+  n0_power_tot2=0;
+  for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
+    n0_power_tot=0;
+    offset0 = (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
+    if ((rb_mask[rb>>5]&(1<<(rb&31))) == 0) {  // check that rb was not used in this subframe
+      nb_rb++;
+      for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+	       measurements->n0_subband_power[aarx][rb]=0;
+	       for (int s=first_symb;s<(first_symb+num_symb);s++) {
+
+	          offset = offset0 + (s*frame_parms->ofdm_symbol_size);
+	          ul_ch  = &common_vars->rxdataF[aarx][offset];
+	          len = 12;
+	          if (((frame_parms->N_RB_UL&1) == 1) && 
+	               (rb==(frame_parms->N_RB_UL>>1))) {
+	             len=6;
+	          }
+	          AssertFatal(ul_ch, "RX signal buffer (freq) problem\n");
+	          measurements->n0_subband_power[aarx][rb] += signal_energy_nodc(ul_ch,len);
+	        } // symbol
+          measurements->n0_subband_power[aarx][rb]/=num_symb;
+          measurements->n0_subband_power_dB[aarx][rb] = dB_fixed(measurements->n0_subband_power[aarx][rb]);
+          n0_power_tot += measurements->n0_subband_power[aarx][rb];
+      } //antenna
+      n0_power_tot/=frame_parms->nb_antennas_rx;
+      n0_power_tot2 += n0_power_tot;
+      measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_power_tot);
+      measurements->n0_subband_power_tot_dBm[rb] = measurements->n0_subband_power_tot_dB[rb] - gNB->rx_total_gain_dB - dB_fixed(frame_parms->N_RB_UL);
     }
+  } //rb
 
-    measurements->n0_power_tot_dB = dB_fixed(measurements->n0_power_tot);
-    measurements->n0_power_tot_dBm = measurements->n0_power_tot_dB + 30 - 10 * log10(pow(2, 30)) - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size);
-
-    LOG_D(PHY, "In %s: tot n0 power %d dBm for %d RBs (tot N0 power = %d)\n", __FUNCTION__, measurements->n0_power_tot_dBm, nb_rb, measurements->n0_power_tot);
+  if (nb_rb>0) measurements->n0_subband_power_avg_dB = dB_fixed(n0_power_tot2/nb_rb);
 
-  }
 }
 
+
 // Scope: This function computes the UL SNR from the UL channel estimates
 //
 // Todo:
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index 625519b95368f2453b9bf28f38f9b3b96ea5b25a..5e1528c92252a6c932d27981f51e9484dadb8852 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -80,7 +80,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
   uint16_t nb_rb_pusch = pusch_pdu->rb_size;
 
 #ifdef DEBUG_CH
-  LOG_D(PHY, "In %s: ch_offset %d, symbol_offset %d OFDM size %d, Ns = %d, k = %d symbol %d\n",
+  LOG_I(PHY, "In %s: ch_offset %d, symbol_offset %d OFDM size %d, Ns = %d, k = %d symbol %d\n",
         __FUNCTION__,
         ch_offset,
         symbol_offset,
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
index 7bd004a4d471e0f2d994063e9c922bb52184b4ae..89bb5b2807323f262694bff010e48854fda7443b 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
@@ -47,7 +47,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
                                 unsigned short bwp_start_subcarrier,
                                 nfapi_nr_pusch_pdu_t *pusch_pdu);
 
-void gNB_I0_measurements(PHY_VARS_gNB *gNB);
+void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
+
+void gNB_I0_measurements(PHY_VARS_gNB *gNB,int first_symb,int num_symb);
 
 void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol);
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index d208167855444d42fb61372c07787763cde0d888..ea9675618422895ad556652a0fc8933b13849ebd 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -94,6 +94,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
      * in time: by its first slot and its first symbol*/
     const nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[d];
 
+    LOG_D(PHY,"DCI pdu %d, rnti %x, aggregation %d CCE %d Scrambling_Id %x ScramblingRNTI %x PayloadSizeBits %d\n",d,dci_pdu->RNTI,dci_pdu->AggregationLevel,dci_pdu->CceIndex,dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits);
     cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
     cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
     dci_idx = 0;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
index 0884c11a9beeb96c26819043d221809f1a875d1c..c562dfaa41b5710d3a3cf9df176d0e7c13ed6ecb 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
@@ -255,12 +255,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
     dlsch->harq_mask                |= (1<<harq_pid);
     dlsch->rnti                      = pdcch_pdu_rel15->dci_pdu[i].RNTI;
     
-    //    nr_fill_cce_list(gNB,0);  
-    /*
-    LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]);
-    LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx);
-    */
-
+    //    nr_fill_cce_list(gNB,0);
   }
 
 }
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index 96918792a03792e74d2cf9daf304b9cbb273d7e5..b1dbc7c7d94fe8a879150098c67fac07acdb8205 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -86,7 +86,7 @@ void nr_pdsch_codeword_scrambling_optim(uint8_t *in,
   for (int i=0; i<((size>>5)+((size&0x1f) > 0 ? 1 : 0)); i++) {
     in32=_mm256_movemask_epi8(_mm256_slli_epi16(((__m256i*)in)[i],7));
     out[i]=(in32^s);
-    //    printf("in[%d] %x => %x\n",i,in32,out[i]);
+    //printf("in[%d] %x => %x\n",i,in32,out[i]);
     s=lte_gold_generic(&x1, &x2, 0);
   }
 #elif defined(__SSE4__)
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index b4416352460605f3014fe90daa95ec929154e3a5..1e372eb9e0b75704c3750e5eaadbd499440c8330 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -44,6 +44,7 @@
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "common/utils/LOG/log.h"
 #include <syscall.h>
+#include <openair2/UTIL/OPT/opt.h>
 
 //#define DEBUG_DLSCH_CODING
 //#define DEBUG_DLSCH_FREE 1
@@ -288,7 +289,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
   }
   G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nrOfLayers);
 
-  LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order);
+  LOG_D(NR_PHY,"dlsch coding A %d G %d (nb_rb %d, nb_symb_sch %d, nb_re_dmrs %d, length_dmrs %d, mod_order %d)\n", A,G, nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs,mod_order);
 
   if (A > 3824) {
     // Add 24-bit crc (polynomial A) to payload
@@ -406,7 +407,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
     E = nr_get_E(G, harq->C, mod_order, rel15->nrOfLayers, r);
 
     //#ifdef DEBUG_DLSCH_CODING
-    LOG_D(PHY,"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d)...\n",
+    LOG_D(NR_PHY,"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d)...\n",
 	  r,
 	  harq->C,
 	  G,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index 6b22ece2bd97d2bd43c8fe47e04de39d27932af8..994ff18bc844f6cd43cc6cacbafd7d6165c2afa2 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -355,6 +355,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
                       nfapi_nr_pucch_pdu_t* pucch_pdu);
 
 void nr_decode_pucch0(PHY_VARS_gNB *gNB,
+                      int frame,
                       int slot,
                       nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu,
                       nfapi_nr_pucch_pdu_t* pucch_pdu);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
index e6e8fdb01b11e0cb19bb32bb297bea37ec40728e..53ff90404b430636719235bcd3689e6157cbe27e 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
@@ -137,12 +137,27 @@ void nr_ulsch_unscrambling_optim(int16_t* llr,
 #endif
 }
 
-void dump_pusch_stats(PHY_VARS_gNB *gNB) {
+#define STATSTRLEN 16384
+void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB) {
 
-  for (int i=0;i<gNB->number_of_nr_ulsch_max;i++)
-    if (gNB->ulsch_stats[i].rnti>0) 
-      LOG_I(PHY,"ULSCH RNTI %x: round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d, current_Qm %d, current_RI %d, total_bytes RX/SCHED %d/%d\n",
-	    gNB->ulsch_stats[i].rnti,
+  char output[16384];
+  int stroff=0;
+
+  for (int i=0;i<gNB->number_of_nr_ulsch_max;i++) {
+    if (gNB->ulsch_stats[i].rnti>0) {
+      for (int aa=0;aa<gNB->frame_parms.nb_antennas_rx;aa++)
+          if (aa==0) stroff+=sprintf(output+stroff,"ULSCH RNTI %4x: ulsch_power[%d] %d,%d ulsch_noise_power[%d] %d.%d\n",
+                                     gNB->ulsch_stats[i].rnti,
+                                     aa,gNB->ulsch_stats[i].power[aa]/10,gNB->ulsch_stats[i].power[aa]%10,
+                                     aa,gNB->ulsch_stats[i].noise_power[aa]/10,gNB->ulsch_stats[i].noise_power[aa]%10);
+          else       stroff+=sprintf(output+stroff,"                  ulsch_power[%d] %d.%d, ulsch_noise_power[%d] %d.%d\n",
+                                     aa,gNB->ulsch_stats[i].power[aa]/10,gNB->ulsch_stats[i].power[aa]%10,
+                                     aa,gNB->ulsch_stats[i].noise_power[aa]/10,gNB->ulsch_stats[i].noise_power[aa]%10);
+
+      AssertFatal(stroff<(STATSTRLEN-1000),"Increase STATSTRLEN\n");
+
+
+      stroff+=sprintf(output+stroff,"                 round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d, DTX %d, current_Qm %d, current_RI %d, total_bytes RX/SCHED %d/%d\n",
 	    gNB->ulsch_stats[i].round_trials[0],
 	    (double)gNB->ulsch_stats[i].round_trials[1]/gNB->ulsch_stats[i].round_trials[0],
 	    gNB->ulsch_stats[i].round_trials[1],
@@ -150,11 +165,14 @@ void dump_pusch_stats(PHY_VARS_gNB *gNB) {
 	    gNB->ulsch_stats[i].round_trials[2],
 	    (double)gNB->ulsch_stats[i].round_trials[3]/gNB->ulsch_stats[i].round_trials[0],
 	    gNB->ulsch_stats[i].round_trials[3],
+      gNB->ulsch_stats[i].DTX,
 	    gNB->ulsch_stats[i].current_Qm,
 	    gNB->ulsch_stats[i].current_RI,
 	    gNB->ulsch_stats[i].total_bytes_rx,
 	    gNB->ulsch_stats[i].total_bytes_tx);
-  
+    }
+ }
+ fprintf(fd,"%s",output);
 }
 
 void clear_pusch_stats(PHY_VARS_gNB *gNB) {
@@ -162,3 +180,20 @@ void clear_pusch_stats(PHY_VARS_gNB *gNB) {
   for (int i=0;i<gNB->number_of_nr_ulsch_max;i++)
     memset((void*)&gNB->ulsch_stats[i],0,sizeof(gNB->ulsch_stats[i]));
 }
+
+NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch) {
+   NR_gNB_SCH_STATS_t *stats=NULL;
+   int first_free=-1;
+   for (int i=0;i<gNB->number_of_nr_ulsch_max;i++) {
+       if (gNB->ulsch_stats[i].rnti == 0 && first_free == -1) {
+          first_free = i;
+          stats=&gNB->ulsch_stats[i];
+       }
+       if (gNB->ulsch_stats[i].rnti == ulsch->rnti) {
+           stats=&gNB->ulsch_stats[i];
+           break;
+       }
+   }
+   return(stats);
+}
+
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
index de9b5f48c3bd7d62ad86b9ecff770d19a05b6f79..2ca8e24af1315c05230c7c2df20cb90c0b9b3474 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
@@ -89,6 +89,8 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
                          uint8_t harq_pid);
 int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
 
-void dump_pusch_stats(PHY_VARS_gNB *gNB);
+void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB);
 
 void clear_pusch_stats(PHY_VARS_gNB *gNB);
+
+NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index b572a6e5bb3fb4c22169f6f1dcd4e1d148308c9f..3aad4980bc813e05e3f350cf76a26e517382e963 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -449,7 +449,7 @@ void nr_processULSegment(void* arg) {
 }
 
 uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
-                           uint8_t UE_id,
+                           uint8_t ULSCH_id,
                            short *ulsch_llr,
                            NR_DL_FRAME_PARMS *frame_parms,
                            nfapi_nr_pusch_pdu_t *pusch_pdu,
@@ -471,7 +471,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
 #endif
   
 
-  NR_gNB_ULSCH_t                       *ulsch                 = phy_vars_gNB->ulsch[UE_id][0];
+  NR_gNB_ULSCH_t                       *ulsch                 = phy_vars_gNB->ulsch[ULSCH_id][0];
+  NR_gNB_PUSCH                         *pusch                 = phy_vars_gNB->pusch_vars[ULSCH_id];
   NR_UL_gNB_HARQ_t                     *harq_process          = ulsch->harq_processes[harq_pid];
 
   if (!harq_process) {
@@ -557,9 +558,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
   if (stats) {
     stats->rnti = ulsch->rnti;
     stats->round_trials[harq_process->round]++;
-  }
-  if (harq_process->round == 0) {
-    if (stats) {
+    for (int aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) {
+       stats->power[aarx]=dB_fixed_x10(pusch->ulsch_power[aarx]);
+       stats->noise_power[aarx]=dB_fixed_x10(pusch->ulsch_noise_power[aarx]);
+    }
+    if (harq_process->round == 0) {
       stats->current_Qm = Qm;
       stats->current_RI = n_layers;
       stats->total_bytes_tx += harq_process->TBS;
@@ -639,7 +642,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
     rdata->Tbslbrm = Tbslbrm;
     rdata->offset = offset;
     rdata->ulsch = ulsch;
-    rdata->ulsch_id = UE_id;
+    rdata->ulsch_id = ULSCH_id;
     pushTpool(phy_vars_gNB->threadPool,req);
     phy_vars_gNB->nbDecode++;
     LOG_D(PHY,"Added a block to decode, in pipe: %d\n",phy_vars_gNB->nbDecode);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index 72db5488c493cc3e976f20873f134cf89a3046e0..7a4555d2548898a4e38d33c32e39d69347031798 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -1184,7 +1184,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
   start_meas(&gNB->ulsch_channel_estimation_stats);
   for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) {
     uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01;
-    LOG_D(PHY,"symbol %d, dmrs_symbol_flag :%d\n", symbol, dmrs_symbol_flag);
+    LOG_D(PHY, "symbol %d, dmrs_symbol_flag :%d\n", symbol, dmrs_symbol_flag);
     if (dmrs_symbol_flag == 1) {
       if (gNB->pusch_vars[ulsch_id]->dmrs_symbol == INVALID_VALUE)
         gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol;
@@ -1200,10 +1200,18 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
       nr_gnb_measurements(gNB, ulsch_id, harq_pid, symbol);
 
       for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
-        gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] = signal_energy_nodc(&gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][symbol*frame_parms->ofdm_symbol_size],
-                                                                          rel15_ul->rb_size*12);
-        if (gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] == 1)
-          return 1;
+        if (symbol == rel15_ul->start_symbol_index) {
+          gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] = 0;
+          gNB->pusch_vars[ulsch_id]->ulsch_noise_power[aarx] = 0;
+        }
+        gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] += signal_energy_nodc(
+            &gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][symbol * frame_parms->ofdm_symbol_size],
+            rel15_ul->rb_size * 12);
+        for (int rb = 0; rb < rel15_ul->rb_size; rb++) {
+          gNB->pusch_vars[ulsch_id]->ulsch_noise_power[aarx] +=
+              gNB->measurements.n0_subband_power[aarx][rel15_ul->bwp_start + rel15_ul->rb_start + rb] /
+              rel15_ul->rb_size;
+        }
       }
     }
   }
diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
index 8145cf893c47103803c97b56cd6f4d612a271db5..2b5343aa609815ce844ba469197267196a7b05ff 100644
--- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c
+++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
@@ -161,6 +161,7 @@ int16_t idft12_im[12][12] = {
 
 
 void nr_decode_pucch0(PHY_VARS_gNB *gNB,
+                      int frame,
                       int slot,
                       nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu,
                       nfapi_nr_pucch_pdu_t* pucch_pdu) {
@@ -177,6 +178,19 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
 	      "Either bit_len_harq (%d) or sr_flag (%d) must be > 0\n",
 	      pucch_pdu->bit_len_harq,pucch_pdu->sr_flag);
 
+  NR_gNB_UCI_STATS_t *uci_stats=NULL;
+  NR_gNB_UCI_STATS_t *first_uci_stats=NULL;
+  for (int i=0;i<NUMBER_OF_NR_UCI_STATS_MAX;i++)
+     if (gNB->uci_stats[i].rnti == pucch_pdu->rnti) {
+        uci_stats = &gNB->uci_stats[i];
+        break;
+     } else if (first_uci_stats == NULL && gNB->uci_stats[i].rnti == 0) first_uci_stats = &gNB->uci_stats[i];
+
+  if (uci_stats == NULL) { uci_stats=first_uci_stats; uci_stats->rnti = pucch_pdu->rnti;}
+
+  AssertFatal(uci_stats!=NULL,"No stat index found\n");
+  uci_stats->frame = frame;
+
   if(pucch_pdu->bit_len_harq==0){
     mcs=table1_mcs;
     nr_sequences=1;
@@ -190,6 +204,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
     nr_sequences=8>>(1-pucch_pdu->sr_flag);
   }
 
+  LOG_D(PHY,"pucch0: nr_symbols %d, start_symbol %d, prb_start %d, second_hop_prb %d,  group_hop_flag %d, sequence_hop_flag %d, O_ACK %d, O_SR %d, mcs %d\n",pucch_pdu->nr_of_symbols,pucch_pdu->start_symbol_index,pucch_pdu->prb_start,pucch_pdu->second_hop_prb,pucch_pdu->group_hop_flag,pucch_pdu->sequence_hop_flag,pucch_pdu->bit_len_harq,pucch_pdu->sr_flag,mcs[0]);
+
   int cs_ind = get_pucch0_cs_lut_index(gNB,pucch_pdu);
   /*
    * Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation
@@ -216,178 +232,133 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
    * x(l*12+n) = r_u_v_alpha_delta(n)
    */
   // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1
-  uint8_t u=0,v=0;//,delta=0;
-  // if frequency hopping is disabled by the higher-layer parameter PUCCH-frequency-hopping
-  //              n_hop = 0
-  // if frequency hopping is enabled by the higher-layer parameter PUCCH-frequency-hopping
-  //              n_hop = 0 for first hop
-  //              n_hop = 1 for second hop
-  uint8_t n_hop = 0;  // Frequnecy hopping not implemented FIXME!!
+  uint8_t u[2]={0,0},v[2]={0,0};
 
   // x_n contains the sequence r_u_v_alpha_delta(n)
 
   int n,i,l;
-  nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,n_hop,slot,&u,&v); // calculating u and v value
+  int prb_offset[2] = {pucch_pdu->bwp_start+pucch_pdu->prb_start, pucch_pdu->bwp_start+pucch_pdu->prb_start};
 
-  uint32_t re_offset=0;
-  uint8_t l2;
+  nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,0,slot,&u[0],&v[0]); // calculating u and v value first hop
+  LOG_D(PHY,"pucch0: u %d, v %d\n",u[0],v[0]);
 
-#ifdef OLD_IMPL
-  int16_t x_n_re[nr_sequences][24],x_n_im[nr_sequences][24];
 
-  for(i=0;i<nr_sequences;i++){ 
-    // we proceed to calculate alpha according to TS 38.211 Subclause 6.3.2.2.2
-    for (l=0; l<pucch_pdu->nr_of_symbols; l++){
-      double alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,pucch_pdu->initial_cyclic_shift,mcs[i],l,pucch_pdu->start_symbol_index,slot);
-#ifdef DEBUG_NR_PUCCH_RX
-      printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d/%d,mcs %d)\n",u,v,alpha,l,l+pucch_pdu->start_symbol_index,mcs[i]);
-      printf("lut output %d\n",gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index]);
-#endif
-      alpha=0.0;
-      for (n=0; n<12; n++){
-        x_n_re[i][(12*l)+n] = (int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
-						   - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))); // Re part of base sequence shifted by alpha
-        x_n_im[i][(12*l)+n] =(int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
-						  + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))); // Im part of base sequence shifted by alpha
-#ifdef DEBUG_NR_PUCCH_RX
-	printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d) %d,%d\n",
-	       u,v,alpha,l,n,x_n_re[i][(12*l)+n],x_n_im[i][(12*l)+n],
-	       (int32_t)(round(32767*cos(alpha*n))),
-	       (int32_t)(round(32767*sin(alpha*n))));
-#endif
-      }
-    }
+  if (pucch_pdu->freq_hop_flag == 1) {
+    nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,1,slot,&u[1],&v[1]); // calculating u and v value second hop
+    LOG_D(PHY,"pucch0 second hop: u %d, v %d\n",u[1],v[1]);
+    prb_offset[1] = pucch_pdu->bwp_start+pucch_pdu->second_hop_prb;
   }
-  /*
-   * Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources
-   */
-
-  int16_t r_re[24],r_im[24];
-
-  for (l=0; l<pucch_pdu->nr_of_symbols; l++) {
 
-    l2 = l+pucch_pdu->start_symbol_index;
-    re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset;
-    if (re_offset>= frame_parms->ofdm_symbol_size) 
-      re_offset-=frame_parms->ofdm_symbol_size;
+  AssertFatal(pucch_pdu->nr_of_symbols < 3,"nr_of_symbols %d not allowed\n",pucch_pdu->nr_of_symbols);
+  uint32_t re_offset[2]={0,0};
+  uint8_t l2;
 
-    for (n=0; n<12; n++){
+  const int16_t *x_re[2],*x_im[2];
+  x_re[0] = table_5_2_2_2_2_Re[u[0]];
+  x_im[0] = table_5_2_2_2_2_Im[u[0]];
+  x_re[1] = table_5_2_2_2_2_Re[u[1]];
+  x_im[1] = table_5_2_2_2_2_Im[u[1]];
 
-      r_re[(12*l)+n]=((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[0];
-      r_im[(12*l)+n]=((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[1];
-#ifdef DEBUG_NR_PUCCH_RX
-      printf("\t [nr_generate_pucch0] mapping to RE \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
-	     frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,(l2*frame_parms->ofdm_symbol_size)+re_offset,
-	     l,n,((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[0],
-	     ((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[1]);
-#endif
-      re_offset++;
-      if (re_offset>= frame_parms->ofdm_symbol_size) 
-        re_offset-=frame_parms->ofdm_symbol_size;
-    }
-  }  
-  double corr[nr_sequences],corr_re[nr_sequences],corr_im[nr_sequences];
-  memset(corr,0,nr_sequences*sizeof(double));
-  memset(corr_re,0,nr_sequences*sizeof(double));
-  memset(corr_im,0,nr_sequences*sizeof(double));
-  for(i=0;i<nr_sequences;i++){
-    for(l=0;l<pucch_pdu->nr_of_symbols;l++){
-      for(n=0;n<12;n++){
-        corr_re[i]+= (double)(r_re[12*l+n])/32767*(double)(x_n_re[i][12*l+n])/32767+(double)(r_im[12*l+n])/32767*(double)(x_n_im[i][12*l+n])/32767;
-	corr_im[i]+= (double)(r_re[12*l+n])/32767*(double)(x_n_im[i][12*l+n])/32767-(double)(r_im[12*l+n])/32767*(double)(x_n_re[i][12*l+n])/32767;
-      }
-    }
-    corr[i]=corr_re[i]*corr_re[i]+corr_im[i]*corr_im[i];
-  }
-  float max_corr=corr[0];
-  uint8_t index=0;
-  for(i=1;i<nr_sequences;i++){
-    if(corr[i]>max_corr){
-      index= i;
-      max_corr=corr[i];
-    }
-  }
-#else
-
-  const int16_t *x_re = table_5_2_2_2_2_Re[u],*x_im = table_5_2_2_2_2_Im[u];
-  int16_t xr[24]  __attribute__((aligned(32)));
-  //int16_t xrt[24] __attribute__((aligned(32)));
-  int32_t xrtmag=0;
+  int16_t xr[2][24]  __attribute__((aligned(32)));
+  int64_t xrtmag=0;
   uint8_t maxpos=0;
-  int n2=0;
   uint8_t index=0;
-  memset((void*)xr,0,24*sizeof(int16_t));
+  memset((void*)xr[0],0,24*sizeof(int16_t));
+  memset((void*)xr[1],0,24*sizeof(int16_t));
+  int n2;
 
   for (l=0; l<pucch_pdu->nr_of_symbols; l++) {
-
     l2 = l+pucch_pdu->start_symbol_index;
-    re_offset = (12*pucch_pdu->prb_start) + frame_parms->first_carrier_offset;
-    if (re_offset>= frame_parms->ofdm_symbol_size) 
-      re_offset-=frame_parms->ofdm_symbol_size;
+    re_offset[l] = (12*prb_offset[l]) + frame_parms->first_carrier_offset;
+    if (re_offset[l]>= frame_parms->ofdm_symbol_size)
+      re_offset[l]-=frame_parms->ofdm_symbol_size;
   
-    AssertFatal(re_offset+12 < frame_parms->ofdm_symbol_size,"pucch straddles DC carrier, handle this!\n");
+    AssertFatal(re_offset[l]+12 < frame_parms->ofdm_symbol_size,"pucch straddles DC carrier, handle this!\n");
 
-    int16_t *r=(int16_t*)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size+re_offset)];
+    int16_t *r=(int16_t*)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset[l]];
+    n2=0;
     for (n=0;n<12;n++,n2+=2) {
-      xr[n2]  =(int16_t)(((int32_t)x_re[n]*r[n2]+(int32_t)x_im[n]*r[n2+1])>>15);
-      xr[n2+1]=(int16_t)(((int32_t)x_re[n]*r[n2+1]-(int32_t)x_im[n]*r[n2])>>15);
+      xr[l][n2]  =(int16_t)(((int32_t)x_re[l][n]*r[n2]+(int32_t)x_im[l][n]*r[n2+1])>>15);
+      xr[l][n2+1]=(int16_t)(((int32_t)x_re[l][n]*r[n2+1]-(int32_t)x_im[l][n]*r[n2])>>15);
 #ifdef DEBUG_NR_PUCCH_RX
-      printf("x (%d,%d), r (%d,%d), xr (%d,%d)\n",
-	     x_re[n],x_im[n],r[n2],r[n2+1],xr[n2],xr[n2+1]);
+      printf("x (%d,%d), r%d.%d (%d,%d), xr (%d,%d)\n",
+	     x_re[l][n],x_im[l][n],l2,re_offset[l],r[n2],r[n2+1],xr[l][n2],xr[l][n2+1]);
 #endif
     }
   }
-  int32_t corr_re,corr_im,temp,no_corr=0;
-  int32_t av_corr=0;
+
+  int32_t corr_re[2];
+  int32_t corr_im[2];
+  //int32_t no_corr = 0;
   int seq_index;
+  int64_t temp;
+  int64_t av_corr=0;
 
   for(i=0;i<nr_sequences;i++){
-    corr_re=0;corr_im=0;
-    n2=0;
     for (l=0;l<pucch_pdu->nr_of_symbols;l++) {
-
+      corr_re[l]=0;
+      corr_im[l]=0;
       seq_index = (pucch_pdu->initial_cyclic_shift+
 		   mcs[i]+
 		   gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
+#ifdef DEBUG_NR_PUCCH_RX
+      printf("PUCCH symbol %d seq %d, seq_index %d, mcs %d\n",l,i,seq_index,mcs[i]);
+#endif
+      n2=0;
       for (n=0;n<12;n++,n2+=2) {
-	corr_re+=(xr[n2]*idft12_re[seq_index][n]+xr[n2+1]*idft12_im[seq_index][n])>>15;
-	corr_im+=(xr[n2]*idft12_im[seq_index][n]-xr[n2+1]*idft12_re[seq_index][n])>>15;
+	       corr_re[l]+=(xr[l][n2]*idft12_re[seq_index][n]+xr[l][n2+1]*idft12_im[seq_index][n])>>15;
+	       corr_im[l]+=(xr[l][n2]*idft12_im[seq_index][n]-xr[l][n2+1]*idft12_re[seq_index][n])>>15;
       }
     }
 
 #ifdef DEBUG_NR_PUCCH_RX
-    printf("PUCCH IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re,corr_im,10*log10(corr_re*corr_re + corr_im*corr_im));
+    LOG_I(PHY,"PUCCH IDFT = (%d,%d)=>%f\n",corr_re[0],corr_im[0],10*log10((double)corr_re[0]*corr_re[0] + (double)corr_im[0]*corr_im[0]));
+    if (l>1) LOG_I(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re[1],corr_im[1],10*log10((double)corr_re[1]*corr_re[1] + (double)corr_im[1]*corr_im[1]));
 #endif
-    temp=corr_re*corr_re + corr_im*corr_im;
+    if (pucch_pdu->freq_hop_flag == 0 && l==1) // non-coherent correlation
+      temp=(int64_t)corr_re[0]*corr_re[0] + (int64_t)corr_im[0]*corr_im[0];
+    else if (pucch_pdu->freq_hop_flag == 0 && l==2) {
+      int64_t corr_re2 = (int64_t)corr_re[0]+corr_re[1];
+      int64_t corr_im2 = (int64_t)corr_im[0]+corr_im[1];
+      // coherent combining of 2 symbols and then complex modulus for single-frequency case
+      temp=corr_re2*corr_re2 + corr_im2*corr_im2;
+    }
+    else if (pucch_pdu->freq_hop_flag == 1)
+      // full non-coherent combining of 2 symbols for frequency-hopping case
+      temp = (int64_t)corr_re[0]*corr_re[0] + (int64_t)corr_im[0]*corr_im[0] + (int64_t)corr_re[1]*corr_re[1] + (int64_t)corr_im[1]*corr_im[1];
+    else AssertFatal(1==0,"shouldn't happen\n");
+
     av_corr+=temp;
     if (temp>xrtmag) {
       xrtmag=temp;
       maxpos=i;
+      uci_stats->current_pucch0_stat0 = dB_fixed64((int64_t)corr_re[0]*corr_re[0] + (int64_t)corr_im[0]*corr_im[0]);
+      if (l==2) uci_stats->current_pucch0_stat1 = dB_fixed64((int64_t)corr_re[1]*corr_re[1] + (int64_t)corr_im[1]*corr_im[1]);
     }
   }
-  if(nr_sequences>1)
-    no_corr=(av_corr-xrtmag)/(nr_sequences-1);
-  av_corr/=nr_sequences;
 
-  uint8_t xrtmag_dB = dB_fixed(xrtmag);
+  av_corr/=nr_sequences/l;
+
+  uint8_t xrtmag_dB = dB_fixed64(xrtmag);
  
 #ifdef DEBUG_NR_PUCCH_RX
   printf("PUCCH 0 : maxpos %d\n",maxpos);
 #endif
 
   index=maxpos;
-#endif
 
   // estimate CQI for MAC (from antenna port 0 only)
-  int SNRtimes10 = dB_fixed_times10(signal_energy_nodc(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset],12)) - (10*gNB->measurements.n0_power_tot_dB);
+  int max_n0 = uci_stats->pucch0_n00>uci_stats->pucch0_n01 ? uci_stats->pucch0_n00:uci_stats->pucch0_n01;
+  int SNRtimes10 = dB_fixed_times10(signal_energy_nodc(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset[0]],12)) - (10*max_n0);
   int cqi;
   if (SNRtimes10 < -640) cqi=0;
   else if (SNRtimes10 >  635) cqi=255;
   else cqi=(640+SNRtimes10)/5;
 
+  uci_stats->pucch0_thres = gNB->pucch0_thres + (10*max_n0);
   bool no_conf=false;
   if (nr_sequences>1) {
-    if ((xrtmag_dB<(11+dB_fixed(no_corr))) || (dB_fixed(av_corr)<(13+gNB->measurements.n0_power_tot_dB))) //TODO  these are temporary threshold based on measurments with the phone
+    if (10*xrtmag_dB < uci_stats->pucch0_thres)
       no_conf=true;
   }
   gNB->bad_pucch += no_conf;
@@ -397,13 +368,18 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
   uci_pdu->rnti = pucch_pdu->rnti;
   uci_pdu->ul_cqi = cqi;
   uci_pdu->timing_advance = 0xffff; // currently not valid
-  uci_pdu->rssi = 1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(signal_energy_nodc(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset],12)));
+  uci_pdu->rssi = 1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(signal_energy_nodc(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset[0]],12)));
+
+  uci_stats->pucch0_n00 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]];
+  uci_stats->pucch0_n01 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]];
   if (pucch_pdu->bit_len_harq==0) {
     uci_pdu->harq = NULL;
     uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
-    uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(13+gNB->measurements.n0_power_tot_dB)) ? 1 : 0;
+    uci_pdu->sr->sr_confidence_level = no_conf ? 1 : 0;
+    uci_stats->pucch0_sr_trials++;
     if (xrtmag_dB>(gNB->measurements.n0_power_tot_dB)) {
       uci_pdu->sr->sr_indication = 1;
+      uci_stats->pucch0_positive_SR++;
     } else {
       uci_pdu->sr->sr_indication = 0;
     }
@@ -411,16 +387,18 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
   else if (pucch_pdu->bit_len_harq==1) {
     uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
     uci_pdu->harq->num_harq = 1;
-    uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0;
+    uci_pdu->harq->harq_confidence_level = no_conf ? 1 : 0;
     uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1);
     uci_pdu->harq->harq_list[0].harq_value = index&0x01;
-    LOG_D(PHY, "Slot %d HARQ value %d with confidence level (0 is good, 1 is bad) %d\n",
-          slot,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level);
+    LOG_D(PHY, "Slot %d HARQ value %d with confidence level (0 is good, 1 is bad) %d xrt_mag %d n0 %d pucch0_thres %d\n",
+          slot,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level,xrtmag_dB,max_n0,uci_stats->pucch0_thres);
     if (pucch_pdu->sr_flag == 1) {
       uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
       uci_pdu->sr->sr_indication = (index>1) ? 1 : 0;
-      uci_pdu->sr->sr_confidence_level = (no_conf) ? 1 : 0;
+      uci_pdu->sr->sr_confidence_level = no_conf ? 1 : 0;
+      uci_stats->pucch0_positive_SR++;
     }
+    uci_stats->pucch01_trials++;
   }
   else {
     uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
@@ -429,8 +407,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
     uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2);
     uci_pdu->harq->harq_list[1].harq_value = index&0x01;
     uci_pdu->harq->harq_list[0].harq_value = (index>>1)&0x01;
-    LOG_D(PHY, "Slot %d HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d\n",
-          slot,uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level);
+    LOG_D(PHY, "Slot %d HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d, xrt_mag %d\n",
+          slot,uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level,xrtmag_dB);
     if (pucch_pdu->sr_flag == 1) {
       uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
       uci_pdu->sr->sr_indication = (index>3) ? 1 : 0;
@@ -1663,4 +1641,33 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
     uci_pdu->pduBitmap|=8;
   }
 }
-    
+
+void nr_dump_uci_stats(FILE *fd,PHY_VARS_gNB *gNB,int frame) {
+
+   int strpos=0;
+   char output[16384];
+
+   for (int i=0;i<NUMBER_OF_NR_UCI_STATS_MAX;i++){
+      if (gNB->uci_stats[i].rnti>0) {
+         NR_gNB_UCI_STATS_t *uci_stats = &gNB->uci_stats[i];
+         if (uci_stats->pucch0_sr_trials > 0)
+             strpos+=sprintf(output+strpos,"UCI %d RNTI %x: pucch0_sr_trials %d, pucch0_n00 %d dB, pucch0_n01 %d dB, pucch0_sr_thres %d dB, current pucch1_stat0 %d dB, current pucch1_stat1 %d dB, positive SR count %d\n",
+                             i,uci_stats->rnti,uci_stats->pucch0_sr_trials,uci_stats->pucch0_n00,uci_stats->pucch0_n01,uci_stats->pucch0_sr_thres,dB_fixed(uci_stats->current_pucch0_sr_stat0),dB_fixed(uci_stats->current_pucch0_sr_stat1),uci_stats->pucch0_positive_SR);
+         if (uci_stats->pucch01_trials > 0)
+            strpos+=sprintf(output+strpos,"UCI %d RNTI %x: pucch01_trials %d, pucch0_n00 %d dB, pucch0_n01 %d dB, pucch0_thres %d dB, current pucch0_stat0 %d dB, current pucch1_stat1 %d dB, pucch01_DTX %d\n",
+                            i,uci_stats->rnti,uci_stats->pucch01_trials,uci_stats->pucch0_n01,uci_stats->pucch0_n01,uci_stats->pucch0_thres,dB_fixed(uci_stats->current_pucch0_stat0),dB_fixed(uci_stats->current_pucch0_stat1),uci_stats->pucch01_DTX);
+
+         if (uci_stats->pucch02_trials > 0)
+             strpos+=sprintf(output+strpos,"UCI %d RNTI %x: pucch01_trials %d, pucch0_n00 %d dB, pucch0_n01 %d dB, pucch0_thres %d dB, current pucch0_stat0 %d dB, current pucch0_stat1 %d dB, pucch01_DTX %d\n",
+                             i,uci_stats->rnti,uci_stats->pucch02_trials,uci_stats->pucch0_n00,uci_stats->pucch0_n01,uci_stats->pucch0_thres,dB_fixed(uci_stats->current_pucch0_stat0),dB_fixed(uci_stats->current_pucch0_stat1),uci_stats->pucch02_DTX);
+
+         if (uci_stats->pucch2_trials > 0)
+           strpos+=sprintf(output+strpos,"UCI %d RNTI %x: pucch2_trials %d, pucch2_DTX %d\n",
+                           i,uci_stats->rnti,
+                           uci_stats->pucch2_trials,
+                           uci_stats->pucch2_DTX);
+       }
+    }
+    if (fd) fprintf(fd,"%s",output);
+    else    printf("%s",output);
+}
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
index 0318ed6478c6d7972120b506005fd70b361e970b..a2f824e4686e70226b8e96478b7db1229b7a3053 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
@@ -105,7 +105,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
       {
           first_time = 0;
           ue->time_sync_cell = 1;
-          if (get_softmodem_params()->do_ra) {
+          if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
               LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
               //mac_resynch();
               //dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id);
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
index 3f52b2928110ee373794b8d800df85b656c4ca76..44f1844ae96dd180262410994dd973df2f295414 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
@@ -180,11 +180,11 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
     ue->measurements.wideband_cqi_avg[gNB_id] = dB_fixed2(ue->measurements.rx_power_avg[gNB_id], ue->measurements.n0_power_avg);
     ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - 10*log10(pow(2, 30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
 
-    LOG_I(PHY, "[gNB %d] Slot %d, RSSI %d dBm/RE, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d \n",
+    LOG_D(PHY, "[gNB %d] Slot %d, RSSI %d dB (%d dBm/RE), WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n",
       gNB_id,
       slot,
-      ue->measurements.rx_rssi_dBm[gNB_id],
       ue->measurements.rx_power_avg_dB[gNB_id],
+      ue->measurements.rx_rssi_dBm[gNB_id],
       ue->measurements.wideband_cqi_avg[gNB_id],
       ue->measurements.rx_power_avg[gNB_id],
       ue->measurements.n0_power_tot);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index 15303bb0c85c8f638b4a2821257780e344cc3e22..5d4d9df47e26782831a77b9e741d5684497396cc 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -50,6 +50,16 @@
 #include "assertions.h"
 #include "T.h"
 
+char nr_dci_format_string[8][30] = {
+  "NR_DL_DCI_FORMAT_1_0",
+  "NR_DL_DCI_FORMAT_1_1",
+  "NR_DL_DCI_FORMAT_2_0",
+  "NR_DL_DCI_FORMAT_2_1",
+  "NR_DL_DCI_FORMAT_2_2",
+  "NR_DL_DCI_FORMAT_2_3",
+  "NR_UL_DCI_FORMAT_0_0",
+  "NR_UL_DCI_FORMAT_0_1"};
+
 //#define DEBUG_DCI_DECODING 1
 
 //#define NR_LTE_PDCCH_DCI_SWITCH
@@ -722,6 +732,10 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
     rel15 = &pdcch_vars->pdcch_config[i];
     int n_rb,rb_offset;
     get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset);
+
+    LOG_D(PHY,"pdcch coreset: freq %x, n_rb %d, rb_offset %d\n",
+          rel15->coreset.frequency_domain_resource[0],n_rb,rb_offset);
+
     for (int s=rel15->coreset.StartSymbolIndex; s<(rel15->coreset.StartSymbolIndex+rel15->coreset.duration); s++) {
       LOG_D(PHY,"in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n");
 
@@ -890,7 +904,7 @@ uint16_t nr_dci_false_detection(uint64_t *dci,
                             int rnti) {
 
   uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
-  polar_encoder_fast(dci, (void*)encoder_output, rnti, 1, polar_param);
+  polar_encoder_fast(dci, (void*)encoder_output, rnti, 1, (t_nrPolar_params *)polar_param);
   uint8_t *enout_p = (uint8_t*)encoder_output;
   uint16_t x = 0;
 
@@ -949,10 +963,10 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
                                           currentPtrDCI);
 
         n_rnti = rel15->rnti;
-
+	      LOG_D(PHY, "(%i.%i) dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d)\n", proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length);
         if (crc == n_rnti) {
-          LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n",
-                proc->frame_rx, proc->nr_slot_rx,n_rnti,rel15->dci_format_options[k],CCEind,dci_length,*(unsigned long long*)dci_estimation);
+          LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d,payload %llx)\n",
+                proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length,*(unsigned long long*)dci_estimation);
           uint16_t mb = nr_dci_false_detection(dci_estimation,tmp_e,currentPtrDCI,L*108,n_rnti);
           ue->dci_thres = (ue->dci_thres + mb) / 2;
           if (mb > (ue->dci_thres+20)) {
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index d5c0245fdcdd2960cd6c39d90ef629f40d691c69..4f6871ca4f9b89fed334a146195429da1e764ff5 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -588,7 +588,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
       }
       else {
         LOG_D(PHY,"CRC NOT OK\n\033[0m");
-        ret = 1 + dlsch->max_ldpc_iterations;
       }
 
 
@@ -691,8 +690,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
               harq_process->F>>3,
               (void *)(uint64_t)(harq_process->c[r]) );
       if (frame%100 == 0){
-          LOG_D (PHY, "Printing 10 first payload bytes at frame: %d ", frame);
-          for (int i = 0; i <10 ; i++){ //Kr_bytes
+          LOG_D (PHY, "Printing 60 first payload bytes at frame: %d ", frame);
+          for (int i = 0; i <60 ; i++){ //Kr_bytes
             LOG_D(PHY, "[%d] : %x ", i, harq_process->b[i]);
           }
         }
@@ -1122,7 +1121,6 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
         ret = 2;
       }
       else {
-        LOG_D(PHY,"CRC NOK\n");
         ret = 1+dlsch->max_ldpc_iterations;
       }
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 35baef1792d96b3aa49f584974ab511d1666d26a..2046c13eaa626f1caa7c2bf8d801023d00a1a625 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -3367,99 +3367,6 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
 }
 //==============================================================================================
 
-#ifdef USER_MODE
-
-
-void dump_dlsch2(PHY_VARS_UE *ue,uint8_t gNB_id,uint8_t nr_slot_rx,unsigned int *coded_bits_per_codeword,int round,  unsigned char harq_pid)
-{
-  unsigned int nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12;
-  char fname[32],vname[32];
-  int N_RB_DL=ue->frame_parms.N_RB_DL;
-
-  snprintf(fname, 32, "dlsch%d_rxF_r%d_ext0.m", gNB_id, round);
-  snprintf(vname, 32, "dl%d_rxF_r%d_ext0", gNB_id, round);
-  write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1);
-
-  if (ue->frame_parms.nb_antennas_rx >1) {
-    snprintf(fname, 32, "dlsch%d_rxF_r%d_ext1.m", gNB_id, round);
-    snprintf(vname, 32, "dl%d_rxF_r%d_ext1", gNB_id, round);
-    write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1);
-  }
-
-  snprintf(fname, 32, "dlsch%d_ch_r%d_ext00.m", gNB_id, round);
-  snprintf(vname, 32, "dl%d_ch_r%d_ext00", gNB_id, round);
-  write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
-
-  if (ue->transmission_mode[gNB_id]==7){
-    snprintf(fname, 32, "dlsch%d_bf_ch_r%d.m", gNB_id, round);
-    snprintf(vname, 32, "dl%d_bf_ch_r%d", gNB_id, round);
-    write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1);
-    //write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[gNB_id]->dl_bf_ch_estimates[0],512,1,1);
-
-    snprintf(fname, 32, "dlsch%d_bf_ch_r%d_ext00.m", gNB_id, round);
-    snprintf(vname, 32, "dl%d_bf_ch_r%d_ext00", gNB_id, round);
-    write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
-  }
-
-  if (ue->frame_parms.nb_antennas_rx == 2) {
-    snprintf(fname, 32, "dlsch%d_ch_r%d_ext01.m", gNB_id, round);
-    snprintf(vname, 32, "dl%d_ch_r%d_ext01", gNB_id, round);
-    write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
-  }
-
-  if (ue->frame_parms.nb_antenna_ports_gNB == 2) {
-    snprintf(fname, 32, "dlsch%d_ch_r%d_ext10.m", gNB_id, round);
-    snprintf(vname, 32, "dl%d_ch_r%d_ext10", gNB_id, round);
-    write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
-
-    if (ue->frame_parms.nb_antennas_rx == 2) {
-      snprintf(fname, 32, "dlsch%d_ch_r%d_ext11.m",gNB_id,round);
-      snprintf(vname, 32, "dl%d_ch_r%d_ext11",gNB_id,round);
-      write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
-    }
-  }
-
-  snprintf(fname, 32, "dlsch%d_rxF_r%d_uespec0.m", gNB_id, round);
-  snprintf(vname, 32, "dl%d_rxF_r%d_uespec0", gNB_id, round);
-  write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1);
-
-  /*
-    write_output("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[gNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
-    write_output("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[gNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
-    write_output("dlsch%d_ch_ext11.m","dl11_ch0_ext",pdsch_vars[gNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
-  */
-  snprintf(fname, 32, "dlsch%d_r%d_rho.m", gNB_id, round);
-  snprintf(vname, 32, "dl_rho_r%d_%d", gNB_id, round);
-
-  write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
-
-  snprintf(fname, 32, "dlsch%d_r%d_rho2.m", gNB_id, round);
-  snprintf(vname, 32, "dl_rho2_r%d_%d", gNB_id, round);
-
-  write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1);
-
-  snprintf(fname, 32, "dlsch%d_rxF_r%d_comp0.m", gNB_id, round);
-  snprintf(vname, 32, "dl%d_rxF_r%d_comp0", gNB_id, round);
-  write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1);
-  if (ue->frame_parms.nb_antenna_ports_gNB == 2) {
-    snprintf(fname, 32, "dlsch%d_rxF_r%d_comp1.m", gNB_id, round);
-    snprintf(vname, 32, "dl%d_rxF_r%d_comp1", gNB_id, round);
-    write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
-  }
-
-  snprintf(fname, 32, "dlsch%d_rxF_r%d_llr.m", gNB_id, round);
-  snprintf(vname, 32, "dl%d_r%d_llr", gNB_id, round);
-  write_output(fname, vname, ue->pdsch_vars[proc->thread_id][gNB_id]->llr[0], coded_bits_per_codeword[0], 1, 0);
-  snprintf(fname, 32, "dlsch%d_r%d_mag1.m", gNB_id, round);
-  snprintf(vname, 32, "dl%d_r%d_mag1", gNB_id, round);
-  write_output(fname, vname, ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_mag0[0], 12*N_RB_DL*nsymb, 1, 1);
-  snprintf(fname, 32, "dlsch%d_r%d_mag2.m", gNB_id, round);
-  snprintf(vname, 32, "dl%d_r%d_mag2", gNB_id, round);
-  write_output(fname, vname, ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_magb0[0], 12*N_RB_DL*nsymb, 1, 1);
-
-  //  printf("log2_maxh = %d\n",ue->pdsch_vars[gNB_id]->log2_maxh);
-}
-#endif
 
 #ifdef DEBUG_DLSCH_DEMOD
 /*
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index 66c3de97eaffa726dbd842e62f8299eef2aed13b..f0e6e9984b949f57b1c3fc8cb8f5d45f2233dcfa 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
@@ -613,7 +613,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
   uint16_t number_pdus = 1;
 
   nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
-  nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_MIB, gNB_id, ue, NULL, number_pdus);
+  nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, number_pdus);
 
   if (ue->if_inst && ue->if_inst->dl_indication)
     ue->if_inst->dl_indication(&dl_indication, NULL);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
index 2c4c0b9e14874a0436580400a32010da21934449..0d372deedf5f94ccbeed8bf3c29a1839bd0f07a6 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
@@ -66,7 +66,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
 
   uint8_t Mod_id, fd_occasion, preamble_index, restricted_set, not_found;
   uint16_t rootSequenceIndex, prach_fmt_id, NCS, *prach_root_sequence_map, preamble_offset = 0;
-  uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx;
+  uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start=0, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx;
   int16_t prach_tmp[98304*2*4] __attribute__((aligned(32)));
 
   int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu;
@@ -74,6 +74,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
   int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k, prachStartSymbol, sample_offset_slot;
   //int restricted_Type;
 
+  fd_occasion             = 0;
+  prach_len               = 0;
+  dftlen                  = 0;
+  first_nonzero_root_idx  = 0;
   prach                   = prach_tmp;
   prachF                  = ue->prach_vars[gNB_id]->prachF;
   amp                     = ue->prach_vars[gNB_id]->amp;
@@ -83,14 +87,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
   mu                      = nrUE_config->prach_config.prach_sub_c_spacing;
   restricted_set          = prach_pdu->restricted_set;
   rootSequenceIndex       = prach_pdu->root_seq_id;
-  n_ra_prb                = prach_pdu->freq_msg1;
+  n_ra_prb                = nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1,//prach_pdu->freq_msg1;
   NCS                     = prach_pdu->num_cs;
   prach_fmt_id            = prach_pdu->prach_format;
   preamble_index          = prach_resources->ra_PreambleIndex;
-  fd_occasion             = 0;
-  prach_len               = 0;
-  dftlen                  = 0;
-  first_nonzero_root_idx  = 0;
   kbar                    = 1;
   K                       = 24;
   k                       = 12*n_ra_prb - 6*fp->N_RB_UL;
@@ -217,10 +217,11 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
   k += kbar;
   k *= 2;
 
-  LOG_I(PHY, "PRACH [UE %d] in slot %d, placing PRACH in position %d, msg1 frequency start %d, preamble_offset %d, first_nonzero_root_idx %d\n", Mod_id,
+  LOG_I(PHY, "PRACH [UE %d] in slot %d, placing PRACH in position %d, msg1 frequency start %d (k1 %d), preamble_offset %d, first_nonzero_root_idx %d\n", Mod_id,
     slot,
     k,
     n_ra_prb,
+    nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1,
     preamble_offset,
     first_nonzero_root_idx);
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
index 76fc5f298fbed056abcbfad05d5ef2d3f4adad0c..6cf782d9d83d0ce0c11edaceba8ce880dda505a1 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
@@ -31,13 +31,15 @@
 #include "PHY/defs_nr_UE.h"
 #include "PHY/phy_extern_nr_ue.h"
 #include "nr_transport_proto_ue.h"
+#include "executables/softmodem-common.h"
 
 void nr_get_carrier_frequencies(NR_DL_FRAME_PARMS *fp, uint64_t *dl_carrier, uint64_t *ul_carrier){
 
-  if (downlink_frequency[0][0])
-    *dl_carrier = downlink_frequency[0][0];
-  else
+  if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1 || !downlink_frequency[0][0]) {
     *dl_carrier = fp->dl_CarrierFreq;
+  } else {
+    *dl_carrier = downlink_frequency[0][0];
+  }
 
   if (uplink_frequency_offset[0][0])
     *ul_carrier = *dl_carrier + uplink_frequency_offset[0][0];
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index 1a39def26b27ea8990305b987a357fa254f0a85c..8f3d1987bcf1a587fdbb449731c59ea70c7cd579 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -264,21 +264,24 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
 
   LOG_D(PHY,"ulsch coding nb_rb %d, Nl = %d\n", nb_rb, harq_process->pusch_pdu.nrOfLayers);
   LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order);
+  LOG_D(PHY,"harq_pid %d harq_process->ndi %d, pusch_data.new_data_indicator %d\n",
+        harq_pid,harq_process->ndi,harq_process->pusch_pdu.pusch_data.new_data_indicator);
 
-  if (harq_process->ndi != harq_process->pusch_pdu.pusch_data.new_data_indicator) {  // this is a new packet
+  if (harq_process->first_tx == 1 ||
+      harq_process->ndi != harq_process->pusch_pdu.pusch_data.new_data_indicator) {  // this is a new packet
 #ifdef DEBUG_ULSCH_CODING
   printf("encoding thinks this is a new packet \n");
 #endif
-
+  harq_process->first_tx = 0;
 ///////////////////////// a---->| add CRC |---->b /////////////////////////
 ///////////
-    /*
+   /* 
     int i;
     printf("ulsch (tx): \n");
     for (i=0;i<(A>>3);i++)
-      printf("%02x.",a[i]);
+      printf("%02x.",harq_process->a[i]);
     printf("\n");
-    */
+   */ 
 
     if (A > 3824) {
       // Add 24-bit crc (polynomial A) to payload
@@ -412,6 +415,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
 
 ///////////
 ///////////////////////////////////////////////////////////////////////////////
+    LOG_D(PHY,"setting ndi to %d from pusch_data\n", harq_process->pusch_pdu.pusch_data.new_data_indicator);
     harq_process->ndi = harq_process->pusch_pdu.pusch_data.new_data_indicator;
   }
   F = harq_process->F;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 60b87fae08396efc7cf53db2002777ff5c4f34b4..fae6b5b2e79c4c3570d27420d414fc469b66d40b 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -146,6 +146,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
     get_num_re_dmrs(pusch_pdu, &nb_dmrs_re_per_rb, &number_dmrs_symbols);
 
+    LOG_D(PHY,"ulsch %x : start_rb %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n",
+          rnti,start_rb,pusch_pdu->bwp_start,start_sc,start_symbol,number_of_symbols,cdm_grps_no_data,number_dmrs_symbols,nb_dmrs_re_per_rb);
+
     // TbD num_of_mod_symbols is set but never used
     N_RE_prime = NR_NB_SC_PER_RB*number_of_symbols - nb_dmrs_re_per_rb*number_dmrs_symbols - N_PRB_oh;
     harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*num_of_codewords;
@@ -361,6 +364,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
           // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part
           // Perform this on gold sequence, not required when SC FDMA operation is done,
+	        LOG_D(PHY,"DMRS in symbol %d\n",l);
           nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
         
         } else {
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
index 3560b235502de2d1e4927c2b7fa93fe2455d6bb8..c7bf459f6f5a185decc1087cab3d2ab6731ba524 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
@@ -59,10 +59,11 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
                         int16_t amp,
                         int nr_slot_tx,
                         uint8_t m0,
-			uint8_t mcs,
+			                  uint8_t mcs,
                         uint8_t nrofSymbols,
                         uint8_t startingSymbolIndex,
-                        uint16_t startingPRB) {
+                        uint16_t startingPRB,
+			                  uint16_t secondHopPRB) {
 #ifdef DEBUG_NR_PUCCH_TX
   printf("\t [nr_generate_pucch0] start function at slot(nr_slot_tx)=%d\n",nr_slot_tx);
 #endif
@@ -94,38 +95,35 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
    * x(l*12+n) = r_u_v_alpha_delta(n)
    */
   // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1
-  uint8_t u=0,v=0;//,delta=0;
-  // if frequency hopping is disabled by the higher-layer parameter PUCCH-frequency-hopping
-  //              n_hop = 0
-  // if frequency hopping is enabled by the higher-layer parameter PUCCH-frequency-hopping
-  //              n_hop = 0 for first hop
-  //              n_hop = 1 for second hop
-  uint8_t n_hop = 0;
-  //uint8_t PUCCH_Frequency_Hopping; // from higher layers FIXME!!
+  uint8_t u[2]={0,0},v[2]={0,0};
+
 #ifdef DEBUG_NR_PUCCH_TX
   printf("\t [nr_generate_pucch0] sequence generation: variable initialization for test\n");
 #endif
   // x_n contains the sequence r_u_v_alpha_delta(n)
-  int16_t x_n_re[24],x_n_im[24];
+  int16_t x_n_re[2][24],x_n_im[2][24];
 
   // we proceed to calculate alpha according to TS 38.211 Subclause 6.3.2.2.2
+  int prb_offset[2]={startingPRB,startingPRB};
+  nr_group_sequence_hopping(pucch_GroupHopping,hoppingId,0,nr_slot_tx,&u[0],&v[0]); // calculating u and v value
+  if (startingPRB!=secondHopPRB) {
+    nr_group_sequence_hopping(pucch_GroupHopping,hoppingId,1,nr_slot_tx,&u[1],&v[1]); // calculating u and v value
+    prb_offset[1] = secondHopPRB;
+  }
   for (int l=0; l<nrofSymbols; l++) {
-    // if frequency hopping is enabled n_hop = 1 for second hop. Not sure frequency hopping concerns format 0. FIXME!!!
-    // if ((PUCCH_Frequency_Hopping == 1)&&(l == (nrofSymbols-1))) n_hop = 1;
-    nr_group_sequence_hopping(pucch_GroupHopping,hoppingId,n_hop,nr_slot_tx,&u,&v); // calculating u and v value
     alpha = nr_cyclic_shift_hopping(hoppingId,m0,mcs,l,startingSymbolIndex,nr_slot_tx);
 #ifdef DEBUG_NR_PUCCH_TX
-    printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u,v,alpha,l);
+    printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u[l],v[l],alpha,l);
 #endif
 
     for (int n=0; n<12; n++) {
-      x_n_re[(12*l)+n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
-                                    - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha
-      x_n_im[(12*l)+n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
-                                    + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of base sequence shifted by alpha
+      x_n_re[l][n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u[l]][n])>>15)
+                                    - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u[l]][n])>>15))); // Re part of base sequence shifted by alpha
+      x_n_im[l][n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u[l]][n])>>15)
+                                    + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u[l]][n])>>15))); // Im part of base sequence shifted by alpha
 #ifdef DEBUG_NR_PUCCH_TX
       printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d)\n",
-             u,v,alpha,l,n,x_n_re[(12*l)+n],x_n_im[(12*l)+n]);
+             u[l],v[l],alpha,l,n,x_n_re[l][n],x_n_im[l][n]);
 #endif
     }
   }
@@ -139,15 +137,18 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
 
   for (int l=0; l<nrofSymbols; l++) {
     l2=l+startingSymbolIndex;
-    re_offset = (12*startingPRB) + frame_parms->first_carrier_offset;
+    re_offset = (12*prb_offset[l]) + frame_parms->first_carrier_offset;
     if (re_offset>= frame_parms->ofdm_symbol_size) 
       re_offset-=frame_parms->ofdm_symbol_size;
 
     //txptr = &txdataF[0][re_offset];
+#ifdef DEBUG_NR_PUCCH_TX
+    printf("\t [nr_generate_pucch0] symbol %d PRB %d (%d)\n",l,prb_offset[l],re_offset);
+#endif    
     for (int n=0; n<12; n++) {
 
-      ((int16_t *)&txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset])[0] = (int16_t)(((int32_t)(amp) * x_n_re[(12*l)+n])>>15);
-      ((int16_t *)&txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset])[1] = (int16_t)(((int32_t)(amp) * x_n_im[(12*l)+n])>>15);
+      ((int16_t *)&txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset])[0] = (int16_t)(((int32_t)(amp) * x_n_re[l][n])>>15);
+      ((int16_t *)&txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset])[1] = (int16_t)(((int32_t)(amp) * x_n_im[l][n])>>15);
       //((int16_t *)txptr[0][re_offset])[0] = (int16_t)((int32_t)amp * x_n_re[(12*l)+n])>>15;
       //((int16_t *)txptr[0][re_offset])[1] = (int16_t)((int32_t)amp * x_n_im[(12*l)+n])>>15;
       //txptr[re_offset] = (x_n_re[(12*l)+n]<<16) + x_n_im[(12*l)+n];
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h
index c7f318f588e0be25d67d6d1b2c62d6f975537063..665dec244370cfb1cb7673c56a7eadd1efc35fb8 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h
@@ -54,10 +54,12 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
                         int16_t amp,
                         int nr_slot_tx,
                         uint8_t m0,
-			uint8_t mcs,
+			                  uint8_t mcs,
                         uint8_t nrofSymbols,
                         uint8_t startingSymbolIndex,
-                        uint16_t startingPRB);
+                        uint16_t startingPRB,
+			                  uint16_t secondHopPRB);
+
 void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
                         int32_t **txdataF,
                         NR_DL_FRAME_PARMS *frame_parms,
@@ -72,10 +74,11 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
                         uint16_t startingPRB_intraSlotHopping,
                         uint8_t timeDomainOCC,
                         uint8_t nr_bit);
+
 void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
                         uint16_t crnti,
-			uint32_t dmrs_scrambling_id,
-			uint32_t data_scrambling_id,
+			                  uint32_t dmrs_scrambling_id,
+			                  uint32_t data_scrambling_id,
                         int32_t **txdataF,
                         NR_DL_FRAME_PARMS *frame_parms,
                         PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
@@ -87,6 +90,7 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
                         uint8_t nrofPRB,
                         uint16_t startingPRB,
                         uint8_t nr_bit);
+
 void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
                           uint16_t crnti,
                           int32_t **txdataF,
diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h
index b9c776f1c8477a6a837d31525c437b2f9bce11a9..a371b2334ba4f008fcdf0a76dbda3cf4f9b0dd47 100644
--- a/openair1/PHY/defs_common.h
+++ b/openair1/PHY/defs_common.h
@@ -869,7 +869,8 @@ typedef enum {
   RA_RESPONSE=2,
   RA_WAIT_CR=3,
   PUSCH=4,
-  RESYNCH=5
+  RESYNCH=5,
+  NUM_UE_MODE=6
 } UE_MODE_t;
 
 #define FOREACH_PARALLEL(GEN)   \
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index d815c755675232350bfde0faf319aa560660655a..364e3a118abe1157e659ba2b2d2128aec3641f6e 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -133,8 +133,32 @@ typedef struct {
   int total_bytes_rx;
   int current_Qm;
   int current_RI;
+  int power[NB_ANTENNAS_RX];
+  int noise_power[NB_ANTENNAS_RX];
+  int DTX;
 } NR_gNB_SCH_STATS_t;
 
+typedef struct {
+  int frame;
+  uint16_t rnti;
+  int pucch0_sr_trials;
+  int pucch0_sr_thres;
+  int current_pucch0_sr_stat0;
+  int current_pucch0_sr_stat1;
+  int pucch0_positive_SR;
+  int pucch01_trials;
+  int pucch0_n00;
+  int pucch0_n01;
+  int pucch0_thres;
+  int current_pucch0_stat0;
+  int current_pucch0_stat1;
+  int pucch01_DTX;
+  int pucch02_trials;
+  int pucch02_DTX;
+  int pucch2_trials;
+  int pucch2_DTX;
+} NR_gNB_UCI_STATS_t;
+
 typedef struct {
   /// Pointers to variables related to DLSCH harq process
   NR_DL_gNB_HARQ_t harq_process;
@@ -465,7 +489,13 @@ typedef struct {
   /// - second index: ? [0..168*N_RB_UL[
   int32_t **ul_ch_magb1[8][8];
   /// measured RX power based on DRS
-  int ulsch_power[2];
+  int ulsch_power[8];
+  /// total signal over antennas
+  int ulsch_power_tot;
+  /// measured RX noise power
+  int ulsch_noise_power[8];
+  /// total noise over antennas
+  int ulsch_noise_power_tot;
   /// \brief llr values.
   /// - first index: ? [0..1179743] (hard coded)
   int16_t *llr;
@@ -486,6 +516,8 @@ typedef struct {
   int16_t *ul_valid_re_per_slot;
   /// flag to verify if channel level computation is done
   uint8_t cl_done;
+  /// flag to indicate DTX on reception
+  int DTX;
 } NR_gNB_PUSCH;
 
 /// Context data structure for RX/TX portion of slot processing
@@ -562,8 +594,10 @@ typedef struct gNB_L1_proc_t_s {
   pthread_t pthread_single;
   /// pthread structure for asychronous RX/TX processing thread
   pthread_t pthread_asynch_rxtx;
-  /// pthread structure for printing time meas
+  /// pthread structure for dumping L1 stats
   pthread_t L1_stats_thread;
+  /// pthread structure for printing time meas
+  pthread_t process_stats_thread;
   /// flag to indicate first RX acquisition
   int first_rx;
   /// flag to indicate first TX transmission
@@ -629,6 +663,8 @@ typedef struct {
   unsigned short n0_subband_power[MAX_NUM_RU_PER_gNB][275];
   //! estimated avg noise power per RB per RX ant (dB)
   unsigned short n0_subband_power_dB[MAX_NUM_RU_PER_gNB][275];
+  //! estimated avg subband noise power (dB)
+  unsigned short n0_subband_power_avg_dB;
   //! estimated avg noise power per RB (dB)
   short n0_subband_power_tot_dB[275];
   //! estimated avg noise power per RB (dBm)
@@ -733,7 +769,7 @@ typedef struct PHY_VARS_gNB_s {
   NR_gNB_SCH_STATS_t dlsch_stats[NUMBER_OF_NR_SCH_STATS_MAX];
   /// statistics for ULSCH measurement collection
   NR_gNB_SCH_STATS_t ulsch_stats[NUMBER_OF_NR_SCH_STATS_MAX];
-
+  NR_gNB_UCI_STATS_t uci_stats[NUMBER_OF_NR_UCI_STATS_MAX];
   t_nrPolar_params    *uci_polarParams;
 
   uint8_t pbch_configured;
@@ -800,6 +836,8 @@ typedef struct PHY_VARS_gNB_s {
   int prach_energy_counter;
 
   int pucch0_thres;
+  int pusch_thres;
+  int prach_thres;
   uint64_t bad_pucch;
   /*
   time_stats_t phy_proc;
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index f40f760f45b825db200a243cb3ee6f93e0aae64a..973c921d2347d7c14f276af87255c83a067b5988 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -55,7 +55,6 @@
 #include "common/ran_context.h"
 extern RAN_CONTEXT_t RC;
 
-nfapi_ue_release_request_body_t release_rntis;
 
 int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t ULSCH_id,uint8_t harq_pid, uint8_t bw_factor) {
   uint32_t Nre,sumKr,MPR_x100,Kr,r;
diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c
index 5a98b17cea7a8b0b77b8629ac7b3b73e63c36064..c95d3dc937b4b02647563f1d994514adc90ffa88 100644
--- a/openair1/SCHED_NR/nr_prach_procedures.c
+++ b/openair1/SCHED_NR/nr_prach_procedures.c
@@ -121,8 +121,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) {
 	    max_preamble_delay[0],
 	    gNB->prach_energy_counter);
 
-      if ((gNB->prach_energy_counter == 100) && 
-	  (max_preamble_energy[0] > gNB->measurements.prach_I0+100)) {
+      if ((gNB->prach_energy_counter == 100) && (max_preamble_energy[0] > gNB->measurements.prach_I0+gNB->prach_thres)) {
 	
 	LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d start symbol %u freq index %u\n",
 	      gNB->Mod_id,
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 83483f3a7f40fc9cc5cf994e2173af03ce8915b6..717487c101539e9ef70814fe053e51060c4aa5c4 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -355,7 +355,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
 }
 
 
-void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, uint8_t harq_pid, uint8_t crc_flag) {
+  void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, uint8_t harq_pid, uint8_t crc_flag) {
 
   pthread_mutex_lock(&gNB->UL_INFO_mutex);
 
@@ -381,10 +381,12 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
 
   LOG_D(PHY, "Estimated timing advance PUSCH is  = %d, timing_advance_update is %d \n", sync_pos,timing_advance_update);
 
-  // estimate UL_CQI for MAC (from antenna port 0 only)
-  int SNRtimes10 = dB_fixed_times10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0]) - (10*gNB->measurements.n0_power_dB[0]);
+  // estimate UL_CQI for MAC
 
-  LOG_D(PHY, "Estimated SNR for PUSCH is = %d dB\n", SNRtimes10/10);
+  int SNRtimes10 = dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot) -
+                   dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot);
+
+  LOG_D(PHY, "Estimated SNR for PUSCH is = %f dB (ulsch_power %f, noise %f)\n", SNRtimes10/10.0,dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot)/10.0,dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot)/10.0);
 
   if      (SNRtimes10 < -640) cqi=0;
   else if (SNRtimes10 >  635) cqi=255;
@@ -445,14 +447,14 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
         NR_gNB_PUCCH_t *pucch = gNB->pucch[i];
         if (pucch) {
           if ((pucch->active == 1) &&
-	      (pucch->frame == frame_rx) &&
-	      (pucch->slot == slot_rx) ) {
+	            (pucch->frame == frame_rx) &&
+	            (pucch->slot == slot_rx) ) {
             gNB->ulmask_symb = symbol;
             nfapi_nr_pucch_pdu_t  *pucch_pdu = &pucch->pucch_pdu;
             if ((symbol>=pucch_pdu->start_symbol_index) &&
                 (symbol<(pucch_pdu->start_symbol_index + pucch_pdu->nr_of_symbols))){
               for (rb=0; rb<pucch_pdu->prb_size; rb++) {
-                rb2 = rb+pucch_pdu->prb_start;
+                rb2 = rb+pucch_pdu->prb_start+pucch_pdu->bwp_start;
                 gNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
               }
               nb_rb+=pucch_pdu->prb_size;
@@ -480,7 +482,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
               if ((symbol>=symbol_start) &&
                   (symbol<symbol_end)){
                 for (rb=0; rb<ulsch_harq->ulsch_pdu.rb_size; rb++) {
-                  rb2 = rb+ulsch_harq->ulsch_pdu.rb_start;
+                  rb2 = rb+ulsch_harq->ulsch_pdu.rb_start+ulsch_harq->ulsch_pdu.bwp_start;
                   gNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
                 }
                 nb_rb+=ulsch_harq->ulsch_pdu.rb_size;
@@ -534,11 +536,19 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
   if (gNB->frame_parms.frame_type == TDD)
     fill_ul_rb_mask(gNB, frame_rx, slot_rx);
 
-  gNB_I0_measurements(gNB);
+  int first_symb=0,num_symb=0;
+  if (gNB->frame_parms.frame_type == TDD)
+    for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
+      if (gNB->gNB_config.tdd_table.max_tdd_periodicity_list[slot_rx].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==1) {
+	      if (num_symb==0) first_symb=symbol_count;
+	      num_symb++;
+      }
+    }
+  else num_symb=NR_NUMBER_OF_SYMBOLS_PER_SLOT;
+  gNB_I0_measurements(gNB,first_symb,num_symb);
 
-  // measure enegry in SS=10 L=4, nb_rb = 18, first_rb = 0 (corresponds to msg3)
   int offset = 10*gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset;
-  int power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset],12*18);
+  int power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset+(47*12)],12*18);
   LOG_D(PHY,"frame %d, slot %d: UL signal energy %d\n",frame_rx,slot_rx,power_rxF);
 
   start_meas(&gNB->phy_proc_rx);
@@ -547,8 +557,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
     NR_gNB_PUCCH_t *pucch = gNB->pucch[i];
     if (pucch) {
       if ((pucch->active == 1) &&
-	  (pucch->frame == frame_rx) &&
-	  (pucch->slot == slot_rx) ) {
+	       (pucch->frame == frame_rx) &&
+	       (pucch->slot == slot_rx) ) {
 
         pucch_decode_done = 1;
 
@@ -569,13 +579,14 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
           LOG_D(PHY,"frame %d, slot %d: PUCCH signal energy %d\n",frame_rx,slot_rx,power_rxF);
 
           nr_decode_pucch0(gNB,
-	                   slot_rx,
+	                         frame_rx,
+                           slot_rx,
                            uci_pdu_format0,
                            pucch_pdu);
 
           gNB->UL_INFO.uci_ind.num_ucis += 1;
           pucch->active = 0;
-	  break;
+	        break;
         case 2:
           num_ucis = gNB->UL_INFO.uci_ind.num_ucis;
           gNB->UL_INFO.uci_ind.uci_list = &gNB->uci_pdu_list[0];
@@ -594,7 +605,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
           pucch->active = 0;
           break;
         default:
-	  AssertFatal(1==0,"Only PUCCH formats 0 and 2 are currently supported\n");
+	        AssertFatal(1==0,"Only PUCCH formats 0 and 2 are currently supported\n");
         }
       }
     }
@@ -610,15 +621,18 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
         (ulsch->rnti > 0)) {
       // for for an active HARQ process
       for (harq_pid=0;harq_pid<NR_MAX_ULSCH_HARQ_PROCESSES;harq_pid++) {
-	ulsch_harq = ulsch->harq_processes[harq_pid];
-    	AssertFatal(ulsch_harq!=NULL,"harq_pid %d is not allocated\n",harq_pid);
-    	if ((ulsch_harq->status == NR_ACTIVE) &&
-          (ulsch_harq->frame == frame_rx) &&
-          (ulsch_harq->slot == slot_rx) &&
-          (ulsch_harq->handled == 0)){
+	      ulsch_harq = ulsch->harq_processes[harq_pid];
+    	  AssertFatal(ulsch_harq!=NULL,"harq_pid %d is not allocated\n",harq_pid);
+    	  if ((ulsch_harq->status == NR_ACTIVE) &&
+            (ulsch_harq->frame == frame_rx) &&
+            (ulsch_harq->slot == slot_rx) &&
+            (ulsch_harq->handled == 0)){
 
           LOG_D(PHY, "PUSCH detection started in frame %d slot %d\n",
                 frame_rx,slot_rx);
+          int num_dmrs=0;
+          for (int s=0;s<NR_NUMBER_OF_SYMBOLS_PER_SLOT; s++)
+             num_dmrs+=(ulsch_harq->ulsch_pdu.ul_dmrs_symb_pos>>s)&1;
 
 #ifdef DEBUG_RXDATA
           NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
@@ -647,13 +661,35 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
           pusch_decode_done = 1;
 
           VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1);
-          start_meas(&gNB->rx_pusch_stats);
+	        start_meas(&gNB->rx_pusch_stats);
           no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, harq_pid);
           if (no_sig) {
-            LOG_I(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx);
+            LOG_D(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx);
             nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid, 1);
             return 1;
           }
+          gNB->pusch_vars[ULSCH_id]->ulsch_power_tot=0;
+          gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot=0;
+          for (int aarx=0;aarx<gNB->frame_parms.nb_antennas_rx;aarx++) {
+             gNB->pusch_vars[ULSCH_id]->ulsch_power[aarx]/=num_dmrs;
+             gNB->pusch_vars[ULSCH_id]->ulsch_power_tot += gNB->pusch_vars[ULSCH_id]->ulsch_power[aarx];
+             gNB->pusch_vars[ULSCH_id]->ulsch_noise_power[aarx]/=num_dmrs;
+             gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot += gNB->pusch_vars[ULSCH_id]->ulsch_noise_power[aarx];
+          }
+          if (dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot) <
+              dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot) + gNB->pusch_thres) {
+             NR_gNB_SCH_STATS_t *stats=get_ulsch_stats(gNB,ulsch);
+
+             LOG_D(PHY, "PUSCH not detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx,
+                   dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot),
+                   dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot),gNB->pusch_thres);
+             gNB->pusch_vars[ULSCH_id]->ulsch_power_tot = gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot;
+             nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1);
+             gNB->pusch_vars[ULSCH_id]->DTX=1;
+             stats->DTX++;
+             return 1;
+          } else gNB->pusch_vars[ULSCH_id]->DTX=0;
+
           stop_meas(&gNB->rx_pusch_stats);
           VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,0);
           //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1);
@@ -669,7 +705,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
   stop_meas(&gNB->phy_proc_rx);
   // figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS
   if ((frame_rx&127) == 0 && slot_rx==19) {
-    dump_pusch_stats(gNB);
     LOG_I(PHY, "Number of bad PUCCH received: %lu\n", gNB->bad_pucch);
   }
 
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index c8ac871bbf28820a6c646fa0b59475170242ec76..c276de847d1c1e677c56f64f863b3233e0935608 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -42,7 +42,7 @@
 
 extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
 
-const char *dl_pdu_type[]={"DCI", "DLSCH", "RA_DLSCH"};
+const char *dl_pdu_type[]={"DCI", "DLSCH", "RA_DLSCH", "SI_DLSCH", "P_DLSCH"};
 const char *ul_pdu_type[]={"PRACH", "PUCCH", "PUSCH", "SRS"};
 
 int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
@@ -67,7 +67,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
       pdcch_vars->nb_search_space = 0;
 
       for (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);
+        AssertFatal(dl_config->dl_config_list[i].pdu_type<=FAPI_NR_DL_CONFIG_TYPES,"pdu_type %d > 2\n",dl_config->dl_config_list[i].pdu_type);
         LOG_D(PHY, "In %s: received 1 DL %s PDU of %d total DL PDUs:\n", __FUNCTION__, dl_pdu_type[dl_config->dl_config_list[i].pdu_type - 1], dl_config->number_pdus);
 
         if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI) {
@@ -151,6 +152,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
 
       for (i = 0; i < ul_config->number_pdus; ++i){
 
+        AssertFatal(ul_config->ul_config_list[i].pdu_type <= FAPI_NR_UL_CONFIG_TYPES,"pdu_type %d out of bounds\n",ul_config->ul_config_list[i].pdu_type);
         LOG_D(PHY, "In %s: processing %s PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], ul_config->number_pdus, ul_config);
 
         uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, pucch_resource_id, current_harq_pid, format, gNB_id = 0;
@@ -183,7 +185,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
 
             if (scheduled_response->tx_request){ 
               fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[i];
-
+              LOG_D(PHY,"%d.%d Copying %d bytes to harq_process_ul_ue->a (harq_pid %d)\n",scheduled_response->frame,slot,tx_req_body->pdu_length,current_harq_pid);
               memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length);
 
               harq_process_ul_ue->status = ACTIVE;
@@ -269,9 +271,11 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){
 
   fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config;
 
-  if(phy_config != NULL)
+  if(phy_config != NULL) {
       memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t));
-
+      if (PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->UE_mode[0] == NOT_SYNCHED)
+	      PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->UE_mode[0] = PRACH;
+  }
   return 0;
 }
 
diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c b/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c
index 6254f6a2d239f76454231470197a2d5de57ecea8..696828a970ed34c86c73a2af3aeb813cdf6cad13 100644
--- a/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c
@@ -46,6 +46,8 @@ int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_slot)
   if (cfg->cell_config.frame_duplex_type == FDD) {
     return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT);
   }
+  if (cfg->tdd_table.max_tdd_periodicity_list == NULL) // this happens before receiving TDD configuration
+    return (NR_DOWNLINK_SLOT);
 
   if (nr_frame%2 == 0) {
     for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index ba81d9b205a1a6e28fa83303b0b0799b3273b484..e3d4c54f5aaa809c8de5985bf87131c8b3e38ba8 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -77,7 +77,7 @@ fifo_dump_emos_UE emos_dump_UE;
 #include "intertask_interface.h"
 #include "T.h"
 
-char nr_mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"};
+char nr_mode_string[NUM_UE_MODE][20] = {"NOT SYNCHED","PRACH","RAR","RA_WAIT_CR", "PUSCH", "RESYNCH"};
 
 const uint8_t nr_rv_round_map_ue[4] = {0, 2, 1, 3};
 
@@ -139,12 +139,13 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
       rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b;
       rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS / 8;
     break;
-    case FAPI_NR_RX_PDU_TYPE_MIB:
-      rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.pdu = ue->pbch_vars[gNB_id]->decoded_output;
-      rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.additional_bits = ue->pbch_vars[gNB_id]->xtra_byte;
-      rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_index = (frame_parms->ssb_index)&0x7;
-      rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_length = frame_parms->Lmax;
-      rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.cell_id = frame_parms->Nid_cell;
+    case FAPI_NR_RX_PDU_TYPE_SSB:
+      rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.pdu = ue->pbch_vars[gNB_id]->decoded_output;
+      rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.additional_bits = ue->pbch_vars[gNB_id]->xtra_byte;
+      rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.ssb_index = (frame_parms->ssb_index)&0x7;
+      rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.ssb_length = frame_parms->Lmax;
+      rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.cell_id = frame_parms->Nid_cell;
+      rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier;
     break;
     default:
     break;
@@ -1760,7 +1761,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   }
 
 #endif //NR_PDCCH_SCHED
-  
+
   // Start PUSCH processing here. It runs in parallel with PDSCH processing
   notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), proc->nr_slot_tx,txFifo,processSlotTX);
   nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(newElt);
@@ -1899,7 +1900,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
 
  }
- 
+
 #if UE_TIMING_TRACE
 start_meas(&ue->generic_stat);
 #endif
@@ -2061,9 +2062,8 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
 
   } else {
 
-    LOG_D(PHY, "In %s:[%d.%d] getting PRACH resources\n", __FUNCTION__, frame_tx, nr_slot_tx);
     nr_prach = nr_ue_get_rach(prach_resources, &ue->prach_vars[0]->prach_pdu, mod_id, ue->CC_id, frame_tx, gNB_id, nr_slot_tx);
-
+    LOG_D(PHY, "In %s:[%d.%d] getting PRACH resources : %d\n", __FUNCTION__, frame_tx, nr_slot_tx,nr_prach);
   }
 
   if (nr_prach == GENERATE_PREAMBLE) {
@@ -2073,7 +2073,7 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
       int16_t ra_preamble_rx_power = (int16_t)(prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30);
       ue->tx_power_dBm[nr_slot_tx] = min(nr_get_Pcmax(mod_id), ra_preamble_rx_power);
 
-      LOG_I(PHY,"DEBUG [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d dB, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n",
+      LOG_D(PHY,"DEBUG [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d dB, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n",
         mod_id,
         frame_tx,
         nr_slot_tx,
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
index 07c03f4238c6d87533543945cd04d1855f528c12..9af50d28e036437f53504463b1986fd45a4df651 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
@@ -41,6 +41,7 @@
 #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
 #include "openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h"
 #include <openair1/PHY/impl_defs_nr.h>
+#include <common/utils/nr/nr_common.h>
 
 #ifndef NO_RAT_NR
 
@@ -118,7 +119,7 @@ static const int sequence_cyclic_shift_1_harq_ack_bit_positive_sr[2]
 /* Sequence cyclic shift */ = { 3,   9 }
 ;
 
-static float RSRP_meas_mapping_nr[98] 
+static float RSRP_meas_mapping_nr[98]
 = {
   -140,
     -139,
@@ -433,7 +434,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
     pucch_resource_indicator = ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack.pucch_resource_indicator;
   }
 
-  LOG_D(PHY, "PUCCH: %d.%d dl_harq_pid = %d, pucch_resource_indicator = %d\n", frame_tx, nr_slot_tx, dl_harq_pid, pucch_resource_indicator);
+  LOG_D(PHY, "PUCCH: %d.%d bwp_id %ld dl_harq_pid = %d, pucch_resource_indicator = %d\n", frame_tx, nr_slot_tx, bwp_id,dl_harq_pid, pucch_resource_indicator);
 
   /* Part - I
    * Collect feedback that should be transmitted at this nr_slot_tx :
@@ -468,22 +469,27 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
   ri_status = ((ue->cqi_report_config[gNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
                                                          (nr_is_ri_TXOp(ue,proc,gNB_id) == 1));
 
-  
-  NR_CSI_MeasConfig_t *csi_MeasConfig = mac->scg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
-  
-  uint16_t report_slot_csi =csi_MeasConfig->csi_ReportConfigToAddModList->list.array[0]->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320;
 
-  //if (mac->csirc->reportQuantity.choice.ssb_Index_RSRP){ 
-	  if (report_slot_csi == proc->nr_slot_tx)
-		csi_status = get_csi_nr(mac, ue, gNB_id, &csi_payload);
-	  else
-	    csi_status = 0;
-  //}
+  if (mac->cg &&
+      mac->cg->spCellConfig &&
+      mac->cg->spCellConfig->spCellConfigDedicated &&
+      mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig&&
+      mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) {
+    NR_CSI_MeasConfig_t *csi_MeasConfig = mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
+
+    uint16_t report_slot_csi =csi_MeasConfig->csi_ReportConfigToAddModList->list.array[0]->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320;
 
-  O_CSI = cqi_status + ri_status + csi_status;
+    //if (mac->csirc->reportQuantity.choice.ssb_Index_RSRP){
+    if (report_slot_csi == proc->nr_slot_tx)
+      csi_status = get_csi_nr(mac, ue, gNB_id, &csi_payload);
+    else
+      csi_status = 0;
+    //}
 
-  /* Part - II */
-  /* if payload is empty or only negative SR -> no pucch transmission */
+    O_CSI = cqi_status + ri_status + csi_status;
+
+    /* Part - II */
+    /* if payload is empty or only negative SR -> no pucch transmission */
 
   if(O_ACK == 0) {
     N_UCI = O_SR + O_CSI;
@@ -506,24 +512,25 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
         csi_payload = 0;
       }
 
-      if (O_CSI == 0) {
-        /* only SR has to be send */
-        /* in this case there is no DCI related to PUCCH parameters so pucch resource should be get from sr configuration */
-        /* TS 38.213 9.2.4 UE procedure for reporting SR */
-        pucch_resource_set = 0; /* force it to a valid value */
-        if (ue->scheduling_request_config_nr[gNB_id].sr_ResourceConfig[ue->scheduling_request_config_nr[gNB_id].active_sr_id] != NULL) {
-         pucch_resource_id = ue->scheduling_request_config_nr[gNB_id].sr_ResourceConfig[ue->scheduling_request_config_nr[gNB_id].active_sr_id]->resource;
-        }
-        else {
-         LOG_E(PHY,"PUCCH No scheduling request configuration : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-         return(FALSE);
-        }
+	if (O_CSI == 0) {
+	  /* only SR has to be send */
+	  /* in this case there is no DCI related to PUCCH parameters so pucch resource should be get from sr configuration */
+	  /* TS 38.213 9.2.4 UE procedure for reporting SR */
+	  pucch_resource_set = 0; /* force it to a valid value */
+	  if (ue->scheduling_request_config_nr[gNB_id].sr_ResourceConfig[ue->scheduling_request_config_nr[gNB_id].active_sr_id] != NULL) {
+	    pucch_resource_id = ue->scheduling_request_config_nr[gNB_id].sr_ResourceConfig[ue->scheduling_request_config_nr[gNB_id].active_sr_id]->resource;
+	  }
+	  else {
+	    LOG_E(PHY,"PUCCH No scheduling request configuration : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+	    return(FALSE);
+	  }
+	}
       }
     }
   }
-  else {
-    N_UCI = O_SR + O_ACK + O_CSI;
-  }
+
+  N_UCI = O_SR + O_ACK + O_CSI;
+  if (N_UCI ==0) return(TRUE);
 
   /* Part - III */
   /* Choice PUCCH format and its related parameters */
@@ -531,8 +538,8 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
   uint8_t  starting_symbol_index=0;
   uint8_t nb_symbols_total = 0;
   uint8_t  nb_symbols = 0;
-  uint16_t starting_prb = 0;;  /* it can be considered as first  hop on case of pucch hopping */
-  uint16_t second_hop = 0;     /* second part for pucch for hopping */
+  uint16_t startingPRB = 0;;  /* it can be considered as first  hop on case of pucch hopping */
+  uint16_t secondHopPRB = 0;     /* second part for pucch for hopping */
   uint8_t  nb_of_prbs = 0;
   int m_0 = 0;                 /* format 0 only */
   int m_CS = 0;                /* for all format except for format 0 */
@@ -541,6 +548,8 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
   int time_domain_occ = 0;
   int occ_length = 0;
   int occ_Index = 0;
+  int BWPsize = 0;
+  int BWPstart = 0;
 
   NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack;
 
@@ -549,29 +558,32 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
     /* use of initial pucch configuration provided by system information 1 */
     /***********************************************************************/
     if (initial_pucch_id != NB_INITIAL_PUCCH_RESOURCE) {
+      LOG_D(MAC,"Selecting INITIAL PUCCH Resource\n");
       format = initial_pucch_resource[initial_pucch_id].format;
       starting_symbol_index = initial_pucch_resource[initial_pucch_id].startingSymbolIndex;
       nb_symbols_total = initial_pucch_resource[initial_pucch_id].nrofSymbols;
 
       int N_CS = initial_pucch_resource[initial_pucch_id].nb_CS_indexes;
       /* see TS 38213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */
+      BWPsize = NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      BWPstart = NRRIV2PRBOFFSET(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
       int RB_BWP_offset;
       if (initial_pucch_id == 15) {
-        RB_BWP_offset = ue->systemInformationBlockType1_nr.N_BWP_SIZE/4;
+        RB_BWP_offset =BWPsize/4;
       }
       else
       {
         RB_BWP_offset = initial_pucch_resource[initial_pucch_id].PRB_offset;
       }
       if (initial_pucch_id/8 == 0) {
-        starting_prb = RB_BWP_offset + (initial_pucch_id/N_CS);
-        second_hop = ue->systemInformationBlockType1_nr.N_BWP_SIZE - 1 - RB_BWP_offset - (initial_pucch_id/N_CS);
+        startingPRB = RB_BWP_offset + (initial_pucch_id/N_CS);
+        secondHopPRB = BWPsize - 1 - RB_BWP_offset - (initial_pucch_id/N_CS);
         m_0 = initial_pucch_resource[initial_pucch_id].initial_CS_indexes[initial_pucch_id%N_CS];
       }
       else if (initial_pucch_id/8 == 1)
       {
-        starting_prb = RB_BWP_offset + (initial_pucch_id/N_CS);
-        second_hop = ue->systemInformationBlockType1_nr.N_BWP_SIZE - 1 - RB_BWP_offset - ((initial_pucch_id - 8)/N_CS);
+        startingPRB = RB_BWP_offset + (initial_pucch_id/N_CS);
+        secondHopPRB = BWPsize - 1 - RB_BWP_offset - ((initial_pucch_id - 8)/N_CS);
         m_0 =  initial_pucch_resource[initial_pucch_id].initial_CS_indexes[(initial_pucch_id - 8)%N_CS];
       }
       if ((ue->UE_mode[gNB_id] != PUSCH) && (O_ACK > 1)) {
@@ -580,26 +592,55 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
         LOG_W(PHY,"PUCCH ue is not expected to generate more than one HARQ-ACK at AbsSubframe %d.%d \n", frame_tx%1024, nr_slot_tx);
       }
       NR_TST_PHY_PRINTF("PUCCH common configuration with index %d \n", initial_pucch_id);
+      startingPRB += BWPstart;
+      secondHopPRB += BWPstart;
     }
     /* use dedicated pucch resource configuration */
     /**********************************************/
     else if ((pucch_resource_set != MAX_NB_OF_PUCCH_RESOURCE_SETS) && (pucch_resource_id != MAX_NB_OF_PUCCH_RESOURCES)) {
       /* check that current configuration is supported */
-      if ((mac->scg->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH != NULL)
-         || (mac->scg->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook != 1)) {
+      if (mac->cg &&
+	        mac->cg->physicalCellGroupConfig &&
+          (mac->cg->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH != NULL || mac->cg->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook != 1)) {
         LOG_E(PHY,"PUCCH Unsupported cell group configuration : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
         return(FALSE);
       }
-      else if (mac->scg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) {
+      else if (mac->cg &&
+               mac->cg->spCellConfig &&
+               mac->cg->spCellConfig->spCellConfigDedicated &&
+               mac->cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig &&
+               mac->cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup &&
+               mac->cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) {
         LOG_E(PHY,"PUCCH Unsupported code block group for serving cell config : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
         return(FALSE);
       }
-      pucch_resource = select_resource_by_id(pucch_resource_id, mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup);
+      NR_PUCCH_Config_t *pucch_Config;
+      if (bwp_id>0 &&
+          mac->ULbwp[bwp_id-1] &&
+          mac->ULbwp[bwp_id-1]->bwp_Dedicated &&
+          mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config &&
+          mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup)
+          pucch_Config =  mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup;
+      else if (bwp_id==0 &&
+               mac->cg &&
+               mac->cg->spCellConfig &&
+               mac->cg->spCellConfig->spCellConfigDedicated &&
+               mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+               mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
+               mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config &&
+               mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
+        pucch_Config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
+        BWPsize  =  NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
+        BWPstart =  NRRIV2PRBOFFSET(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
+      }
+
+      else AssertFatal(1==0,"no pucch_Config\n");
+      pucch_resource = select_resource_by_id(pucch_resource_id, pucch_Config);
       format = pucch_resource->format.present;
       nb_symbols_total = get_nb_symbols_pucch(pucch_resource, format);
       starting_symbol_index = get_starting_symb_idx(pucch_resource, format);
-      starting_prb = pucch_resource->startingPRB;
-      second_hop = starting_prb;
+      startingPRB   = BWPstart + pucch_resource->startingPRB;
+      secondHopPRB = pucch_resource->intraSlotFrequencyHopping ? (BWPstart+*pucch_resource->secondHopPRB) : startingPRB;
       if (format==pucch_format1_nr)
         time_domain_occ = pucch_resource->format.choice.format1->timeDomainOCC;
       if (format==pucch_format4_nr) {
@@ -787,8 +828,8 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
   NR_TST_PHY_PRINTF("PUCCH ( format : %d ) ( modulation : %s ) ( nb prb : %d ) ( nb symbols total: %d ) ( nb symbols : %d ) ( max code rate*100 : %d ) ( starting_symbol_index : %d ) \n",
                              format, (Q_m == BITS_PER_SYMBOL_QPSK ? " QPSK " : " BPSK "), nb_of_prbs, nb_symbols_total, nb_symbols, max_code_rate, starting_symbol_index);
 
-  NR_TST_PHY_PRINTF("PUCCH ( starting_prb : %d ) ( second_hop : %d ) ( m_0 : %d ) ( m_CS : %d ) ( time_domain_occ %d ) (occ_length : %d ) ( occ_Index : %d ) \n",
-                             starting_prb,         second_hop,         m_0,         m_CS,         time_domain_occ,      occ_length,         occ_Index);
+  NR_TST_PHY_PRINTF("PUCCH ( startingPRB : %d ) ( secondHopPRB : %d ) ( m_0 : %d ) ( m_CS : %d ) ( time_domain_occ %d ) (occ_length : %d ) ( occ_Index : %d ) \n",
+		    startingPRB (absolute),         secondHopPRB (absolute),         m_0,         m_CS,         time_domain_occ,      occ_length,         occ_Index);
 
   /* Part - IV */
   /* Generate PUCCH signal according to its format and parameters */
@@ -817,17 +858,27 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
   switch(format) {
     case pucch_format0_nr:
     {
+      int pucch_GroupHopping = mac->ULbwp[bwp_id-1] ?
+            mac->ULbwp[bwp_id-1]->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_GroupHopping:
+            mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon->choice.setup->pucch_GroupHopping;
+      int hoppingId = mac->ULbwp[bwp_id-1] ?
+            mac->ULbwp[bwp_id-1]->bwp_Common->pucch_ConfigCommon->choice.setup->hoppingId[0]:
+            (mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon->choice.setup->hoppingId?
+             mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon->choice.setup->hoppingId[0]:
+             mac->physCellId);
       nr_generate_pucch0(ue,ue->common_vars.txdataF,
                          &ue->frame_parms,
-                         mac->ULbwp[bwp_id-1]->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_GroupHopping,
-                         mac->ULbwp[bwp_id-1]->bwp_Common->pucch_ConfigCommon->choice.setup->hoppingId[0],
+                         pucch_GroupHopping,
+                         hoppingId,
                          tx_amp,
                          nr_slot_tx,
                          (uint8_t)m_0,
                          (uint8_t)m_CS,
                          nb_symbols_total,
                          starting_symbol_index,
-                         starting_prb);
+                         startingPRB,
+                         secondHopPRB
+                         );
       break;
     }
     case pucch_format1_nr:
@@ -841,8 +892,8 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
                          (uint8_t)m_0,
                          nb_symbols_total,
                          starting_symbol_index,
-                         starting_prb,
-                         second_hop,
+                         startingPRB,
+                         secondHopPRB,
                          (uint8_t)time_domain_occ,
                          (uint8_t)N_UCI);
       break;
@@ -862,7 +913,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
                          nb_symbols_total,
                          starting_symbol_index,
                          nb_of_prbs,
-                         starting_prb,
+                         startingPRB,
                          (uint8_t)N_UCI);
       break;
     }
@@ -881,8 +932,8 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
                            nb_symbols_total,
                            starting_symbol_index,
                            nb_of_prbs,
-                           starting_prb,
-                           second_hop,
+                           startingPRB,
+                           secondHopPRB,
                            (uint8_t)N_UCI,
                            (uint8_t)occ_length,
                            (uint8_t)occ_Index);
@@ -940,7 +991,11 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id,  UE_nr_rxtx_proc_t
   NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id;
   if (mac->DLbwp[dl_bwp_id-1] == NULL) return 0;
 
-  if (mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI[0] == 2) {
+  if (mac->DLbwp[dl_bwp_id-1] &&
+      mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated &&
+      mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config &&
+      mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup &&
+      mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI[0] == 2) {
     two_transport_blocks = TRUE;
     number_of_code_word = 2;
   }
@@ -1017,7 +1072,9 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id,  UE_nr_rxtx_proc_t
    U_DAI_c = number_harq_feedback/number_of_code_word;
    N_m_c_rx = number_harq_feedback;
    int N_SPS_c = 0; /* FFS TODO_NR multicells and SPS are not supported at the moment */
-   if (mac->scg->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH == NULL) {
+   if (mac->cg != NULL &&
+       mac->cg->physicalCellGroupConfig != NULL &&
+       mac->cg->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH != NULL) {
      int N_TB_max_DL = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI[0];
      *n_HARQ_ACK = (((V_DAI_m_DL - U_DAI_c)%4) * N_TB_max_DL) + N_m_c_rx + N_SPS_c;
      NR_TST_PHY_PRINTF("PUCCH power n(%d) = ( V(%d) - U(%d) )mod4 * N_TB(%d) + N(%d) \n", *n_HARQ_ACK, V_DAI_m_DL, U_DAI_c, N_TB_max_DL, N_m_c_rx);
@@ -1130,12 +1187,30 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8
   //*resource_set_id = MAX_NB_OF_PUCCH_RESOURCE_SETS;
   //*resource_id = MAX_NB_OF_PUCCH_RESOURCES;
 
-  if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[0] == NULL) {
+  if ((bwp_id ==0 &&
+       mac->cg == NULL) ||
+      (bwp_id == 0 &&
+       mac->cg &&
+       mac->cg->spCellConfig &&
+       mac->cg->spCellConfig->spCellConfigDedicated &&
+       mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+       mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
+       mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config &&
+       mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup &&
+       mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList &&
+       mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList->list.array[0] == NULL) ||
+      (mac->ULbwp[bwp_id-1] &&
+       mac->ULbwp[bwp_id-1]->bwp_Dedicated &&
+       mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config &&
+       mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup &&
+       mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList &&
+       mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[0] == NULL)
+      ){
 
     /* No resource set has been already configured so pucch_configCommon from Sib1 should be used in this case */
 
     if (ue->UE_mode[gNB_id] != PUSCH) {
-      *initial_pucch_id = mac->ULbwp[bwp_id-1]->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon[0];
+      *initial_pucch_id = *mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon->choice.setup->pucch_ResourceCommon;
       if (*initial_pucch_id >= NB_INITIAL_PUCCH_RESOURCE) {
         LOG_E(PHY,"PUCCH Invalid initial resource index : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
         *initial_pucch_id = NB_INITIAL_PUCCH_RESOURCE;
@@ -1152,8 +1227,7 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8
       int n_CCE_0 = harq_status->n_CCE;
       int N_CCE_0 = harq_status->N_CCE;
       if (N_CCE_0 == 0) {
-        LOG_E(PHY,"PUCCH No compatible pucch format found : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-        return (FALSE);
+        AssertFatal(1==0,"PUCCH No compatible pucch format found : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
       }
       int r_PUCCH = ((2 * n_CCE_0)/N_CCE_0) + (2 * delta_PRI);
       *initial_pucch_id = r_PUCCH;
@@ -1196,18 +1270,29 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8
 
       if (pucch_resource_indicator < MAX_PUCCH_RESOURCE_INDICATOR) {
         // Verify that the value of pucch_resource_indicator is valid
-        if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.count <= pucch_resource_indicator)
+        struct NR_PUCCH_Config__resourceSetToAddModList *resourceSetToAddModList = NULL;
+	      struct NR_PUCCH_Config__resourceToAddModList *resourceToAddModList = NULL;
+        if (bwp_id > 0 && mac->ULbwp[bwp_id-1]) {
+           AssertFatal(mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList!=NULL,"mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList is null\n");
+           resourceSetToAddModList = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList;
+           resourceToAddModList = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList;
+        } else if (bwp_id == 0 && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList!=NULL) {
+	        resourceSetToAddModList = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList;
+          resourceToAddModList = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceToAddModList;
+        }
+        if (resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.count <= pucch_resource_indicator)
         {
           LOG_E(PHY, "Value of pucch_resource_indicator is out of bounds! Possibly due to a false DCI. \n");
           return (FALSE);
         }
         /* check if resource indexing by pucch_resource_indicator of this set is compatible */
-        if ((ready_pucch_resource_id == TRUE) || (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.array[pucch_resource_indicator][0] != MAX_NB_OF_PUCCH_RESOURCES)) {
+        if ((ready_pucch_resource_id == TRUE) || (resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.array[pucch_resource_indicator][0] != MAX_NB_OF_PUCCH_RESOURCES)) {
+
           if (ready_pucch_resource_id == TRUE) {
             current_resource_id = *resource_id;
           }
           else {
-            int R_PUCCH = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.count;
+            int R_PUCCH = resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.count;
             /* is it the first resource and its size exceeds 8 */
             if ((pucch_resource_set_id == 0)
              && (R_PUCCH > MAX_NB_OF_PUCCH_RESOURCES_PER_SET_NOT_0)) {
@@ -1229,17 +1314,14 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8
               current_resource_id = r_PUCCH;
             }
             else {
-		if (pucch_resource_set_id !=0 )
-			current_resource_id = 3; //TBC mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.array[pucch_resource_indicator][0];
-		else
-			current_resource_id = 1;
+		          current_resource_id = resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.array[pucch_resource_indicator][0];
             }
           }
 
-          uint8_t pucch_resource_count = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList->list.count;
+          uint8_t pucch_resource_count = resourceToAddModList->list.count;
           for (uint8_t i=0; i<pucch_resource_count; i++) {
-            if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList->list.array[i]->pucch_ResourceId == current_resource_id)
-              pucch_resource = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList->list.array[i];
+            if (resourceToAddModList->list.array[i]->pucch_ResourceId == current_resource_id)
+              pucch_resource = resourceToAddModList->list.array[i];
           }
           if (pucch_resource != NULL) {
             format_pucch = pucch_resource->format.present;
@@ -1306,10 +1388,24 @@ int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size)
   */
   /* look for the first resource set which supports uci_size number of bits for payload */
   while (pucch_resource_set_id < MAX_NB_OF_PUCCH_RESOURCE_SETS) {
-    if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id] != NULL) {
-      //pucch_max_pl_bits = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->maxPayloadMinus1;
-      if (uci_size <= 2) { //TBC rrc (((pucch_max_pl_bits != NULL) ? *pucch_max_pl_bits : 1706) + 1)) {
-        //NR_TST_PHY_PRINTF("PUCCH found resource set %d max bits %d\n",  pucch_resource_set_id, pucch_max_pl_bits);
+    if ((bwp_id>0 &&
+         mac->ULbwp[bwp_id-1] &&
+         mac->ULbwp[bwp_id-1]->bwp_Dedicated &&
+         mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config &&
+         mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup &&
+         mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList &&
+         mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id] != NULL) ||
+        (bwp_id==0 &&
+         mac->cg &&
+         mac->cg->spCellConfig &&
+         mac->cg->spCellConfig->spCellConfigDedicated &&
+         mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+         mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
+         mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config &&
+         mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup &&
+         mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList &&
+         mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id] != NULL)) {
+      if (uci_size <= 2) {
         pucch_resource_set_id = 0;
         return (pucch_resource_set_id);
         break;
@@ -1506,7 +1602,7 @@ uint16_t get_nr_csi_bitlen(NR_UE_MAC_INST_t *mac) {
   uint16_t nb_ssbri_cri = 0; 
   uint16_t cri_ssbri_bitlen = 0;
   
-  NR_CSI_MeasConfig_t *csi_MeasConfig = mac->scg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
+  NR_CSI_MeasConfig_t *csi_MeasConfig = mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
   struct NR_CSI_ResourceConfig__csi_RS_ResourceSetList__nzp_CSI_RS_SSB * nzp_CSI_RS_SSB = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[0]->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB;
 
   uint16_t nb_csi_ssb_report = nzp_CSI_RS_SSB->csi_SSB_ResourceSetList!=NULL ? nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.count:0;
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index aed4cb68ed65ae6a2f873e93fe30b941cf435bac..848b6d4e7507f1afcf25ea625f27672960bcef2a 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -88,7 +88,7 @@ uint64_t downlink_frequency[MAX_NUM_CCs][4];
 THREAD_STRUCT thread_struct;
 nfapi_ue_release_request_body_t release_rntis;
 msc_interface_t msc_interface;
-
+uint32_t N_RB_DL = 106;
 
 // dummy functions
 int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info)              { return(0);  }
@@ -131,6 +131,12 @@ rrc_data_ind(
 {
 }
 
+int ocp_gtpv1u_create_s1u_tunnel(instance_t instance,
+                                 const gtpv1u_enb_create_tunnel_req_t  *create_tunnel_req,
+                                 gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp) {
+    return 0;
+}
+
 int
 gtpv1u_create_s1u_tunnel(
   const instance_t                              instanceP,
@@ -166,6 +172,10 @@ gtpv1u_update_ngu_tunnel(
   return 0;
 }
 
+int ocp_gtpv1u_delete_s1u_tunnel(const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP) {
+  return 0;
+}
+
 int
 nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
   const protocol_ctxt_t *const ctxt_pP,
@@ -204,6 +214,17 @@ int is_x2ap_enabled(void)
   return 0;
 }
 
+int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t     module_idP,
+                                            int             CC_idP,
+                                            int             UE_id,
+                                            rnti_t          rntiP,
+                                            const uint8_t   *sduP,
+                                            sdu_size_t      sdu_lenP,
+                                            const uint8_t   *sdu2P,
+                                            sdu_size_t      sdu2_lenP) {
+  return 0;
+}
+
 void processSlotTX(void *arg) {}
 
 //nFAPI P7 dummy functions
@@ -217,7 +238,7 @@ int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0);  }
 openair0_config_t openair0_cfg[MAX_CARDS];
 void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex,int8_t *ptrs_arg);
 void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg);
-extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration 
+extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
 
 /* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs from command line of
    dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */
@@ -228,22 +249,22 @@ void nr_dlsim_preprocessor(module_id_t module_id,
   NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
   AssertFatal(UE_info->num_UEs == 1, "can have only a single UE\n");
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[0];
+  NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
 
   /* manually set free CCE to 0 */
   const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
-  sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
+  sched_ctrl->search_space = get_searchspace(scc, sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, target_ss);
   uint8_t nr_of_candidates;
   find_aggregation_candidates(&sched_ctrl->aggregation_level,
                               &nr_of_candidates,
                               sched_ctrl->search_space);
-  sched_ctrl->coreset = get_coreset(
-      sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
+  sched_ctrl->coreset = get_coreset(scc, sched_ctrl->active_bwp, sched_ctrl->search_space, target_ss);
   sched_ctrl->cce_index = 0;
 
   NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
-  const NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
+
   nr_set_pdsch_semi_static(scc,
-                           UE_info->secondaryCellGroup[0],
+                           UE_info->CellGroup[0],
                            sched_ctrl->active_bwp,
                            /* tda = */ 2,
                            /* num_dmrs_cdm_grps_no_data = */ 1,
@@ -293,7 +314,7 @@ void nr_dlsim_preprocessor(module_id_t module_id,
 typedef struct {
   uint64_t       optmask;   //mask to store boolean config options
   uint8_t        nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
-  tpool_t        Tpool;             // thread pool 
+  tpool_t        Tpool;             // thread pool
 } nrUE_params_t;
 
 nrUE_params_t nrUE_params;
@@ -367,8 +388,6 @@ int main(int argc, char **argv)
   NR_UE_MAC_INST_t *UE_mac;
   int cyclic_prefix_type = NFAPI_CP_NORMAL;
   int run_initial_sync=0;
-  int pusch_tgt_snrx10 = 200;
-  int pucch_tgt_snrx10 = 200;
   int loglvl=OAILOG_INFO;
 
   //float target_error_rate = 0.01;
@@ -754,9 +773,9 @@ int main(int argc, char **argv)
   AssertFatal((gNB->if_inst         = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
   gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
   // common configuration
-  rrc_mac_config_req_gNB(0,0,n_tx,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
+  rrc_mac_config_req_gNB(0,0, n_tx, n_tx, scc, 0, 0, NULL);
   // UE dedicated configuration
-  rrc_mac_config_req_gNB(0,0,n_tx,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
+  rrc_mac_config_req_gNB(0,0, n_tx, n_tx, scc, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
   // reset preprocessor to the one of DLSIM after it has been set during
   // rrc_mac_config_req_gNB
   gNB_mac->pre_processor_dl = nr_dlsim_preprocessor;
@@ -915,8 +934,7 @@ int main(int argc, char **argv)
   //Configure UE
   rrc.carrier.MIB = (uint8_t*) malloc(4);
   rrc.carrier.sizeof_MIB = do_MIB_NR(&rrc,0);
-
-  nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup);
+  nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib, NULL, NULL, secondaryCellGroup);
 
 
   nr_dcireq_t dcireq;
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index bba0a6996f1a24daf08f17a895b5e0283849b152..93bed5514f7455c5c366d7963577c45903d22ded 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -66,8 +66,10 @@ double cpuf;
 extern uint16_t prach_root_sequence_map0_3[838];
 openair0_config_t openair0_cfg[MAX_CARDS];
 //uint8_t nfapi_mode=0;
+uint64_t downlink_frequency[MAX_NUM_CCs][4];
 uint16_t sl_ahead = 0;
 msc_interface_t msc_interface;
+uint32_t N_RB_DL = 106;
 
 //void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
 
@@ -90,6 +92,12 @@ rrc_data_ind(
 {
 }
 
+int ocp_gtpv1u_create_s1u_tunnel(instance_t instance,
+                                 const gtpv1u_enb_create_tunnel_req_t  *create_tunnel_req,
+                                 gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp) {
+    return 0;
+}
+
 int
 gtpv1u_create_s1u_tunnel(
   const instance_t                              instanceP,
@@ -125,6 +133,10 @@ gtpv1u_update_ngu_tunnel(
   return 0;
 }
 
+int ocp_gtpv1u_delete_s1u_tunnel(const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP) {
+  return 0;
+}
+
 int
 nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
   const protocol_ctxt_t *const ctxt_pP,
@@ -174,10 +186,21 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
   return 0;
 }
 
+int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t     module_idP,
+                                            int             CC_idP,
+                                            int             UE_id,
+                                            rnti_t          rntiP,
+                                            const uint8_t   *sduP,
+                                            sdu_size_t      sdu_lenP,
+                                            const uint8_t   *sdu2P,
+                                            sdu_size_t      sdu2_lenP) {
+  return 0;
+}
+
 typedef struct {
   uint64_t       optmask;   //mask to store boolean config options
   uint8_t        nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
-  tpool_t        Tpool;             // thread pool 
+  tpool_t        Tpool;             // thread pool
 } nrUE_params_t;
 
 nrUE_params_t nrUE_params;
diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c
index 758afc6b3cf99a0e150d45d84f01576034765526..9c5fa5b8c9fc2726190394f64c8aa14bc8586d54 100644
--- a/openair1/SIMULATION/NR_PHY/pucchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pucchsim.c
@@ -92,6 +92,7 @@ int main(int argc, char **argv)
   //uint8_t nacktoack_flag=0;
   int16_t amp=0x7FFF;
   int nr_slot_tx=0;
+  int nr_frame_tx=0;
   uint64_t actual_payload=0,payload_received;
   int nr_bit=1; // maximum value possible is 2
   uint8_t m0=0;// higher layer paramater initial cyclic shift
@@ -502,13 +503,13 @@ int main(int argc, char **argv)
     for (trial=0; trial<n_trials; trial++) {
       bzero(txdataF[aa],frame_parms->ofdm_symbol_size*sizeof(int));
       if(format==0){
-        nr_generate_pucch0(UE,txdataF,frame_parms,PUCCH_GroupHopping,hopping_id,amp,nr_slot_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB);
+        nr_generate_pucch0(UE,txdataF,frame_parms,PUCCH_GroupHopping,hopping_id,amp,nr_slot_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB, 0);
       }
       else if (format == 1){
         nr_generate_pucch1(UE,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_slot_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit);
       }
       else {
-	nr_generate_pucch2(UE,0x1234,dmrs_scrambling_id,data_scrambling_id,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_slot_tx,nrofSymbols,startingSymbolIndex,nrofPRB,startingPRB,nr_bit);
+	      nr_generate_pucch2(UE,0x1234,dmrs_scrambling_id,data_scrambling_id,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_slot_tx,nrofSymbols,startingSymbolIndex,nrofPRB,startingPRB,nr_bit);
       }
       
       int txlev = signal_energy(&txdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size],
@@ -533,7 +534,7 @@ int main(int argc, char **argv)
         int rb2 = rb+startingPRB;
         gNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
       }
-      gNB_I0_measurements(gNB);
+      gNB_I0_measurements(gNB, startingSymbolIndex, nrofSymbols);
 
       if (n_trials==1) printf("rxlev %d (%d dB), sigma2 %f dB, SNR %f, TX %f\n",rxlev,dB_fixed(rxlev),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12));
       if(format==0){
@@ -551,7 +552,9 @@ int main(int argc, char **argv)
         pucch_pdu.initial_cyclic_shift  = 0;
         pucch_pdu.start_symbol_index    = startingSymbolIndex;
         pucch_pdu.prb_start             = startingPRB;
-        nr_decode_pucch0(gNB,nr_slot_tx,&uci_pdu,&pucch_pdu);
+        pucch_pdu.bwp_start             = 0;
+        pucch_pdu.freq_hop_flag         = 0;
+        nr_decode_pucch0(gNB, nr_frame_tx, nr_slot_tx,&uci_pdu,&pucch_pdu);
         if(sr_flag==1){
           if (uci_pdu.sr->sr_indication == 0 || uci_pdu.sr->sr_confidence_level == 1)
             sr_errors+=1;
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 5dd05848c0690d28efd262aadacdb6369ae36ffa..62f4420e75af13ff17e9659f3b2eab4240ed9737 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -84,6 +84,7 @@ uint64_t downlink_frequency[MAX_NUM_CCs][4];
 THREAD_STRUCT thread_struct;
 nfapi_ue_release_request_body_t release_rntis;
 msc_interface_t msc_interface;
+uint32_t N_RB_DL = 106;
 
 extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
 
@@ -120,6 +121,12 @@ rrc_data_ind(
 {
 }
 
+int ocp_gtpv1u_create_s1u_tunnel(instance_t instance,
+                                 const gtpv1u_enb_create_tunnel_req_t  *create_tunnel_req,
+                                 gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp) {
+    return 0;
+}
+
 int
 gtpv1u_create_s1u_tunnel(
   const instance_t                              instanceP,
@@ -129,6 +136,10 @@ gtpv1u_create_s1u_tunnel(
   return 0;
 }
 
+int ocp_gtpv1u_delete_s1u_tunnel(const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP) {
+  return 0;
+}
+
 int
 rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
   const protocol_ctxt_t *const ctxt_pP,
@@ -185,6 +196,17 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
   return 0;
 }
 
+int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t     module_idP,
+                                            int             CC_idP,
+                                            int             UE_id,
+                                            rnti_t          rntiP,
+                                            const uint8_t   *sduP,
+                                            sdu_size_t      sdu_lenP,
+                                            const uint8_t   *sdu2P,
+                                            sdu_size_t      sdu2_lenP) {
+  return 0;
+}
+
 //nFAPI P7 dummy functions
 
 int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0);  }
@@ -296,8 +318,6 @@ int main(int argc, char **argv)
   int file_offset = 0;
 
   double DS_TDL = .03;
-  int pusch_tgt_snrx10 = 200;
-  int pucch_tgt_snrx10 = 200;
   int ibwps=24;
   int ibwp_rboffset=41;
   int params_from_file = 0;
@@ -688,9 +708,9 @@ int main(int argc, char **argv)
 
   gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
   // common configuration
-  rrc_mac_config_req_gNB(0,0,n_tx,n_rx,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
+  rrc_mac_config_req_gNB(0,0, n_tx, n_tx, scc, 0, 0, NULL);
   // UE dedicated configuration
-  rrc_mac_config_req_gNB(0,0,1,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
+  rrc_mac_config_req_gNB(0,0, n_tx, n_tx, scc, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
   phy_init_nr_gNB(gNB,0,1);
   N_RB_DL = gNB->frame_parms.N_RB_DL;
 
@@ -748,7 +768,7 @@ int main(int argc, char **argv)
   rrc.carrier.MIB = (uint8_t*) malloc(4);
   rrc.carrier.sizeof_MIB = do_MIB_NR(&rrc,0);
 
-  nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup);
+  nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib, NULL, NULL, secondaryCellGroup);
 
   nr_ue_phy_config_request(&UE_mac->phy_config);
 
@@ -1306,7 +1326,8 @@ int main(int argc, char **argv)
 	   (double)errors_scrambling[3]/available_bits/round_trials[0],
 	   roundStats[snrRun],effRate,effRate/TBS*100,TBS);
 
-    dump_pusch_stats(gNB);
+    FILE *fd=fopen("nr_ulsim.log","w");
+    dump_pusch_stats(fd,gNB);
 
     printf("*****************************************\n");
     printf("\n");
diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h
index 9e341f9bcbc87c2a19f1e28ba7d994b31153f96a..6b1c6d94954582f0347caa77711702ea3e0b4eba 100644
--- a/openair2/COMMON/f1ap_messages_def.h
+++ b/openair2/COMMON/f1ap_messages_def.h
@@ -24,10 +24,13 @@ MESSAGE_DEF(F1AP_CU_SCTP_REQ        , MESSAGE_PRIORITY_MED, f1ap_cu_setup_req_t
 
 /* eNB_DU application layer -> F1AP messages or CU F1AP -> RRC*/
 MESSAGE_DEF(F1AP_SETUP_REQ          , MESSAGE_PRIORITY_MED, f1ap_setup_req_t          , f1ap_setup_req)
+MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE         , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_acknowledge_t          , f1ap_gnb_cu_configuration_update_acknowledge)
+MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE         , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_failure_t          , f1ap_gnb_cu_configuration_update_failure)
 
 /* F1AP -> eNB_DU or eNB_CU_RRC -> F1AP application layer messages */
 MESSAGE_DEF(F1AP_SETUP_RESP         , MESSAGE_PRIORITY_MED, f1ap_setup_resp_t          , f1ap_setup_resp)
 MESSAGE_DEF(F1AP_SETUP_FAILURE         , MESSAGE_PRIORITY_MED, f1ap_setup_failure_t          , f1ap_setup_failure)
+MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE         , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_t          , f1ap_gnb_cu_configuration_update)
 
 /* MAC -> F1AP messages */
 MESSAGE_DEF(F1AP_INITIAL_UL_RRC_MESSAGE           , MESSAGE_PRIORITY_MED, f1ap_initial_ul_rrc_message_t             , f1ap_initial_ul_rrc_message)
diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h
index d83f9cb71d74c9f00ba6ef2a6d7ee32e1665103a..c2fb4a9cf7b7e4f1d1adc3c8047e81e033933651 100644
--- a/openair2/COMMON/f1ap_messages_types.h
+++ b/openair2/COMMON/f1ap_messages_types.h
@@ -31,6 +31,9 @@
 
 #define F1AP_SETUP_REQ(mSGpTR)                     (mSGpTR)->ittiMsg.f1ap_setup_req
 #define F1AP_SETUP_RESP(mSGpTR)                    (mSGpTR)->ittiMsg.f1ap_setup_resp
+#define F1AP_GNB_CU_CONFIGURATION_UPDATE(mSGpTR)   (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update
+#define F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(mSGpTR)   (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update_acknowledge
+#define F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(mSGpTR)   (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update_failure
 #define F1AP_SETUP_FAILURE(mSGpTR)                 (mSGpTR)->ittiMsg.f1ap_setup_failure
 
 #define F1AP_INITIAL_UL_RRC_MESSAGE(mSGpTR)        (mSGpTR)->ittiMsg.f1ap_initial_ul_rrc_message
@@ -55,6 +58,8 @@
 // Note this should be 512 from maxval in 38.473
 #define F1AP_MAX_NB_CELLS 2
 
+#define F1AP_MAX_NO_OF_TNL_ASSOCIATIONS 32
+#define F1AP_MAX_NO_UE_ID 1024 
 typedef struct f1ap_net_ip_address_s {
   unsigned ipv4:1;
   unsigned ipv6:1;
@@ -98,7 +103,7 @@ typedef struct f1ap_setup_req_s {
 
   // Served Cell Information
   /* Tracking area code */
-  uint16_t tac[F1AP_MAX_NB_CELLS];
+  uint32_t tac[F1AP_MAX_NB_CELLS];
 
   /* Mobile Country Codes
    * Mobile Network Codes
@@ -174,6 +179,24 @@ typedef struct f1ap_setup_req_s {
 
 } f1ap_setup_req_t;
 
+typedef struct served_cells_to_activate_s {
+  /// mcc of DU cells
+  uint16_t mcc;
+  /// mnc of DU cells
+  uint16_t mnc;
+  /// mnc digit length of DU cells
+  uint8_t mnc_digit_length;
+  // NR Global Cell Id
+  uint64_t nr_cellid;
+  /// NRPCI
+  uint16_t nrpci;
+  /// num SI messages per DU cell
+  uint8_t num_SI;
+  /// SI message containers (up to 21 messages per cell)
+  uint8_t *SI_container[21];
+  int      SI_container_length[21];
+} served_cells_to_activate_t;
+
 typedef struct f1ap_setup_resp_s {
   /* Connexion id used between SCTP/F1AP */
   uint16_t cnx_id;
@@ -189,29 +212,62 @@ typedef struct f1ap_setup_resp_s {
   char     *gNB_CU_name;
   /// number of DU cells to activate
   uint16_t num_cells_to_activate; //0< num_cells_to_activate <= 512;
-  /// mcc of DU cells
-  uint16_t mcc[F1AP_MAX_NB_CELLS];
-  /// mnc of DU cells
-  uint16_t mnc[F1AP_MAX_NB_CELLS];
-  /// mnc digit length of DU cells
-  uint8_t mnc_digit_length[F1AP_MAX_NB_CELLS];
-  // NR Global Cell Id
-  uint64_t nr_cellid[F1AP_MAX_NB_CELLS];
-  /// NRPCI
-  uint16_t nrpci[F1AP_MAX_NB_CELLS];
-  /// num SI messages per DU cell
-  uint8_t num_SI[F1AP_MAX_NB_CELLS];
-  /// SI message containers (up to 21 messages per cell)
-  uint8_t *SI_container[F1AP_MAX_NB_CELLS][21];
-  int      SI_container_length[F1AP_MAX_NB_CELLS][21];
+  served_cells_to_activate_t cells_to_activate[F1AP_MAX_NB_CELLS];
 } f1ap_setup_resp_t;
 
+typedef struct f1ap_gnb_cu_configuration_update_s {
+  /* Connexion id used between SCTP/F1AP */
+  uint16_t cnx_id;
+
+  /* SCTP association id */
+  int32_t  assoc_id;
+
+  /* Number of SCTP streams used for a mme association */
+  uint16_t sctp_in_streams;
+  uint16_t sctp_out_streams;
+
+  /// string holding gNB_CU_name
+  char     *gNB_CU_name;
+  /// number of DU cells to activate
+  uint16_t num_cells_to_activate; //0< num_cells_to_activate/mod <= 512;
+  served_cells_to_activate_t cells_to_activate[F1AP_MAX_NB_CELLS];
+} f1ap_gnb_cu_configuration_update_t;
+
 typedef struct f1ap_setup_failure_s {
   uint16_t cause;
   uint16_t time_to_wait;
   uint16_t criticality_diagnostics; 
 } f1ap_setup_failure_t;
 
+typedef struct f1ap_gnb_cu_configuration_update_acknowledge_s {
+  uint16_t num_cells_failed_to_be_activated;
+  uint16_t mcc[F1AP_MAX_NB_CELLS];
+  uint16_t mnc[F1AP_MAX_NB_CELLS];
+  uint8_t mnc_digit_length[F1AP_MAX_NB_CELLS];
+  uint64_t nr_cellid[F1AP_MAX_NB_CELLS];
+  uint16_t cause[F1AP_MAX_NB_CELLS];
+  int have_criticality;
+  uint16_t criticality_diagnostics; 
+  uint16_t noofTNLAssociations_to_setup;
+  uint16_t have_port[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS];
+  in_addr_t tl_address[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS]; // currently only IPv4 supported
+  uint16_t noofTNLAssociations_failed;
+  in_addr_t tl_address_failed[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS]; // currently only IPv4 supported
+  uint16_t cause_failed[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS];
+  uint16_t noofDedicatedSIDeliveryNeededUEs;
+  uint32_t gNB_CU_ue_id[F1AP_MAX_NO_UE_ID]; 
+  uint16_t ue_mcc[F1AP_MAX_NO_UE_ID]; 
+  uint16_t ue_mnc[F1AP_MAX_NO_UE_ID]; 
+  uint8_t  ue_mnc_digit_length[F1AP_MAX_NO_UE_ID]; 
+  uint64_t ue_nr_cellid[F1AP_MAX_NO_UE_ID];  
+} f1ap_gnb_cu_configuration_update_acknowledge_t;
+
+typedef struct f1ap_gnb_cu_configuration_update_failure_s {
+  uint16_t cause;
+  uint16_t time_to_wait;
+  uint16_t criticality_diagnostics; 
+} f1ap_gnb_cu_configuration_update_failure_t;
+
 typedef struct f1ap_dl_rrc_message_s {
 
   uint32_t gNB_CU_ue_id;
@@ -243,7 +299,7 @@ typedef struct f1ap_initial_ul_rrc_message_s {
   uint16_t crnti;
   uint8_t *rrc_container;
   int      rrc_container_length;
-  uint8_t *du2cu_rrc_container;
+  int8_t *du2cu_rrc_container;
   int      du2cu_rrc_container_length;
 } f1ap_initial_ul_rrc_message_t;
 
diff --git a/openair2/COMMON/gtpv1_u_messages_def.h b/openair2/COMMON/gtpv1_u_messages_def.h
index 86103dd91151b910a930814211c7119631b4e451..e5ce496701ad552f1431e6c3d5df622f934f1499 100644
--- a/openair2/COMMON/gtpv1_u_messages_def.h
+++ b/openair2/COMMON/gtpv1_u_messages_def.h
@@ -33,4 +33,5 @@ MESSAGE_DEF(GTPV1U_ENB_S1_REQ,        MESSAGE_PRIORITY_MED, Gtpv1uS1Req,    gtpv
 
 MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_REQ,   MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_req_t,  NRGtpv1uDeleteTunnelReq)
 MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_RESP,  MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_resp_t, NRGtpv1uDeleteTunnelResp)
-MESSAGE_DEF(GTPV1U_GNB_NG_REQ,        MESSAGE_PRIORITY_MED, Gtpv1uNGReq,    gtpv1uNGReq)
+MESSAGE_DEF(GTPV1U_GNB_NG_REQ,              MESSAGE_PRIORITY_MED, Gtpv1uNGReq,                     gtpv1uNGReq)
+MESSAGE_DEF(GTPV1U_GNB_TUNNEL_DATA_REQ,     MESSAGE_PRIORITY_MED, gtpv1u_gnb_tunnel_data_req_t,    NRGtpv1uTunnelDataReq)
diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h
index f5b6314fe1e8d0b66d9656d604dd61d481794d69..75df3253f6cefa9542246fbabf03728fbef95ab3 100644
--- a/openair2/COMMON/gtpv1_u_messages_types.h
+++ b/openair2/COMMON/gtpv1_u_messages_types.h
@@ -44,6 +44,7 @@
 #define GTPV1U_GNB_DELETE_TUNNEL_REQ(mSGpTR)  (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelReq
 #define GTPV1U_GNB_DELETE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelResp
 #define GTPV1U_GNB_NG_REQ(mSGpTR)             (mSGpTR)->ittiMsg.gtpv1uNGReq
+#define GTPV1U_GNB_TUNNEL_DATA_REQ(mSGpTR)    (mSGpTR)->ittiMsg.NRGtpv1uTunnelDataReq
 
 #define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF
 
@@ -167,21 +168,23 @@ typedef struct gtpv1u_enb_end_marker_ind_s {
   uint32_t 			 sdu_size;
   uint8_t 			 *sdu_p;
   uint8_t 			 mode;
-  uint16_t     			 rnti;
-  uint8_t      			 module_id;
+  uint16_t     	 rnti;
+  uint8_t      	 module_id;
   uint8_t 			 eNB_index;
 } gtpv1u_enb_end_marker_ind_t;
 
 typedef struct {
   in_addr_t             enb_ip_address_for_S1u_S12_S4_up;
   tcp_udp_port_t        enb_port_for_S1u_S12_S4_up;
-  char addrStr[256];
-  char portStr[256];
+  char                  addrStr[256];
+  char                  portStr[256];
 } Gtpv1uS1Req;
 
 typedef struct {
   in_addr_t             gnb_ip_address_for_NGu_up;
   tcp_udp_port_t        gnb_port_for_NGu_up;
+  char                  addrStr[256];
+  char                  portStr[256];
 } Gtpv1uNGReq;
 typedef struct gtpv1u_gnb_create_tunnel_req_s {
   rnti_t                 rnti;
@@ -212,4 +215,12 @@ typedef struct gtpv1u_gnb_delete_tunnel_resp_s {
   teid_t                 gnb_NGu_teid;         ///< local NGU Tunnel Endpoint Identifier to be deleted
 } gtpv1u_gnb_delete_tunnel_resp_t;
 
+typedef struct gtpv1u_gnb_tunnel_data_req_s {
+  uint8_t               *buffer;
+  uint32_t               length;
+  uint32_t               offset;               ///< start of message offset in buffer
+  rnti_t                 rnti;
+  pdusessionid_t         pdusession_id;
+} gtpv1u_gnb_tunnel_data_req_t;
+
 #endif /* GTPV1_U_MESSAGES_TYPES_H_ */
diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h
index f42813ecb0a4f2496d385a144b594a0efac3b0cd..a9336a58a999817c90f7bbe571134d9d29f57e54 100644
--- a/openair2/COMMON/mac_messages_types.h
+++ b/openair2/COMMON/mac_messages_types.h
@@ -30,6 +30,7 @@
 #define MAC_MESSAGES_TYPES_H_
 
 #include <LTE_DRX-Config.h>
+#include "OCTET_STRING.h"
 
 //-------------------------------------------------------------------------------------------//
 // Defines to access message fields.
@@ -143,6 +144,7 @@ typedef struct NRRrcMacCcchDataInd_s {
   uint16_t  rnti;
   uint32_t  sdu_size;
   uint8_t   sdu[CCCH_SDU_SIZE];
+  OCTET_STRING_t *du_to_cu_rrc_container;
   uint8_t   gnb_index;
   int       CC_id;
 } NRRrcMacCcchDataInd;
diff --git a/openair2/COMMON/pdcp_messages_def.h b/openair2/COMMON/pdcp_messages_def.h
index b148ae0e1f79174b4dc2ad3ca4e8339e1fbfc43a..59d47eb81b992c660c4d9b47a3e19724edf01189 100644
--- a/openair2/COMMON/pdcp_messages_def.h
+++ b/openair2/COMMON/pdcp_messages_def.h
@@ -33,4 +33,5 @@ MESSAGE_DEF(RRC_DCCH_DATA_IND,          MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataIn
 MESSAGE_DEF(RRC_PCCH_DATA_REQ,          MESSAGE_PRIORITY_MED_PLUS, RrcPcchDataReq,              rrc_pcch_data_req)
 
 // gNB
+MESSAGE_DEF(NR_RRC_DCCH_DATA_REQ,       MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataReq,           nr_rrc_dcch_data_req)
 MESSAGE_DEF(NR_RRC_DCCH_DATA_IND,       MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataInd,           nr_rrc_dcch_data_ind)
diff --git a/openair2/COMMON/pdcp_messages_types.h b/openair2/COMMON/pdcp_messages_types.h
index daf8ba7cac9eb8b0175d4298da3e361db7694954..0390fd80f440dc8af4c02971991085d2ec89799a 100644
--- a/openair2/COMMON/pdcp_messages_types.h
+++ b/openair2/COMMON/pdcp_messages_types.h
@@ -36,6 +36,7 @@
 #define RRC_PCCH_DATA_REQ(mSGpTR)               (mSGpTR)->ittiMsg.rrc_pcch_data_req
 
 // gNB
+#define NR_RRC_DCCH_DATA_REQ(mSGpTR)            (mSGpTR)->ittiMsg.nr_rrc_dcch_data_req
 #define NR_RRC_DCCH_DATA_IND(mSGpTR)            (mSGpTR)->ittiMsg.nr_rrc_dcch_data_ind
 
 //-------------------------------------------------------------------------------------------//
@@ -64,6 +65,20 @@ typedef struct RrcDcchDataInd_s {
   uint8_t      eNB_index; // LG: needed in UE
 } RrcDcchDataInd;
 
+typedef struct NRRrcDcchDataReq_s {
+  uint32_t frame;
+  uint8_t  gnb_flag;
+  rb_id_t  rb_id;
+  uint32_t muip;
+  uint32_t confirmp;
+  uint32_t sdu_size;
+  uint8_t *sdu_p;
+  uint8_t  mode;
+  uint16_t rnti;
+  uint8_t  module_id;
+  uint8_t  gNB_index;
+} NRRrcDcchDataReq;
+
 typedef struct NRRrcDcchDataInd_s {
   uint32_t frame;
   uint8_t dcch_index;
diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h
index acfc0920aa019be1d2542464f96eecee697a9013..c56a31711a081d73465266abf3681cb94814427f 100644
--- a/openair2/COMMON/platform_constants.h
+++ b/openair2/COMMON/platform_constants.h
@@ -89,6 +89,7 @@
   #define MAX_gNB                      2
 #endif
 
+#define NUMBER_OF_NR_UCI_STATS_MAX 16
 #define MAX_MANAGED_ENB_PER_MOBILE  2
 #define MAX_MANAGED_GNB_PER_MOBILE  2
 
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index fe706b214379b0369f118199ae57ea4bef871c0c..4751596931cbbb78d7acdb7162cdb37d8b15f5a8 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -3161,25 +3161,25 @@ void handle_f1ap_setup_resp(f1ap_setup_resp_t *resp) {
       rrc_eNB_carrier_data_t *carrier =  &RC.rrc[i]->carrier[0];
       // identify local index of cell j by nr_cellid, plmn identity and physical cell ID
       LOG_I(ENB_APP, "Checking cell %d, rrc inst %d : rrc->nr_cellid %lx, resp->nr_cellid %lx\n",
-            j,i,RC.rrc[i]->nr_cellid,resp->nr_cellid[j]);
+            j,i,RC.rrc[i]->nr_cellid,resp->cells_to_activate[j].nr_cellid);
 
-      if (RC.rrc[i]->nr_cellid == resp->nr_cellid[j] &&
-          (check_plmn_identity(carrier, resp->mcc[j], resp->mnc[j], resp->mnc_digit_length[j])>0 &&
-           resp->nrpci[j] == carrier->physCellId)) {
+      if (RC.rrc[i]->nr_cellid == resp->cells_to_activate[j].nr_cellid &&
+          (check_plmn_identity(carrier, resp->cells_to_activate[j].mcc, resp->cells_to_activate[j].mnc, resp->cells_to_activate[j].mnc_digit_length)>0 &&
+           resp->cells_to_activate[j].nrpci == carrier->physCellId)) {
         // copy system information and decode it
-        for (si_ind=2; si_ind<10; si_ind++)  {
-          //printf("SI %d size %d: ", si_ind, resp->SI_container_length[j][si_ind]);
-          //for (int n=0;n<resp->SI_container_length[j][si_ind];n++)
-          //  printf("%02x ",resp->SI_container[j][si_ind][n]);
+        for (si_ind=2; si_ind<resp->cells_to_activate[j].num_SI + 2; si_ind++)  {
+          //printf("SI %d size %d: ", si_ind, resp->cells_to_activate[j].SI_container_length[si_ind]);
+          //for (int n=0;n<resp->cells_to_activate[j].SI_container_length[si_ind];n++)
+          //  printf("%02x ",resp->cells_to_activate[j].SI_container[si_ind][n]);
           //printf("\n");
           if (si_ind==6) si_ind=9;
-          if (resp->SI_container[j][si_ind] != NULL) {
-            extract_and_decode_SI(i,	
+          if (resp->cells_to_activate[j].SI_container[si_ind] != NULL) {
+            extract_and_decode_SI(i,
                                   si_ind,
-                                  resp->SI_container[j][si_ind],
-                                  resp->SI_container_length[j][si_ind]);
+                                  resp->cells_to_activate[j].SI_container[si_ind],
+                                  resp->cells_to_activate[j].SI_container_length[si_ind]);
           }
-          
+
         }
 
         // perform MAC/L1 common configuration
diff --git a/openair2/F1AP/dummy_enb.c b/openair2/F1AP/dummy_enb.c
new file mode 100644
index 0000000000000000000000000000000000000000..ee98b9ec4687b3bef354773b40207e111cc25ef6
--- /dev/null
+++ b/openair2/F1AP/dummy_enb.c
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#include "COMMON/platform_types.h"
+#include "COMMON/platform_constants.h"
+#include "common/ran_context.h"
+
+#include "common/utils/LOG/log.h"
+#include "common/utils/LOG/vcd_signal_dumper.h"
+
+#include "NR_BCCH-BCH-Message.h"
+#include "NR_ServingCellConfigCommon.h"
+
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "SCHED_NR/phy_frame_config_nr.h"
+
+#include "NR_MIB.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
+#include "../../../../nfapi/oai_integration/vendor_ext.h"
+/* Softmodem params */
+#include "executables/softmodem-common.h"
+
+
+int rrc_mac_config_req_gNB(module_id_t Mod_idP,
+                           int ssb_SubcarrierOffset,
+                           int pdsch_AntennaPorts,
+                           int pusch_AntennaPorts,
+                           NR_ServingCellConfigCommon_t *scc,
+                           int add_ue,
+                           uint32_t rnti,
+                           NR_CellGroupConfig_t *CellGroup){
+abort();
+return 0;
+}
+rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP,
+    const NR_SRB_ToAddModList_t   * const srb2add_listP,
+    const NR_DRB_ToAddModList_t   * const drb2add_listP,
+    const NR_DRB_ToReleaseList_t  * const drb2release_listP,
+    const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
+    struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list){
+abort();
+return 0;
+}
diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c
index 20926c10d1f94353af85d501b12f433145658d89..057d0d97a0bbc3b835a3974539f2a6c61d9e72b2 100644
--- a/openair2/F1AP/f1ap_cu_interface_management.c
+++ b/openair2/F1AP/f1ap_cu_interface_management.c
@@ -37,6 +37,7 @@
 #include "f1ap_cu_interface_management.h"
 
 extern f1ap_setup_req_t *f1ap_du_data_from_du;
+extern RAN_CONTEXT_t RC;
 
 int CU_send_RESET(instance_t instance, F1AP_Reset_t *Reset) {
   AssertFatal(1==0,"Not implemented yet\n");
@@ -102,8 +103,12 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance,
               assoc_id, stream);
   }
 
-  message_p = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_SETUP_REQ); 
-  
+  if(RC.nrrrc) {
+    message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_SETUP_REQ);
+  } else {
+    message_p = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_SETUP_REQ);
+  }
+
   /* assoc_id */
   F1AP_SETUP_REQ(message_p).assoc_id = assoc_id;
   
@@ -134,58 +139,57 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance,
   int num_cells_available = F1AP_SETUP_REQ(message_p).num_cells_available;
 
   for (i=0; i<num_cells_available; i++) {
-    F1AP_GNB_DU_Served_Cells_Item_t *served_celles_item_p;
+    F1AP_GNB_DU_Served_Cells_Item_t *served_cells_item_p;
 
-    served_celles_item_p = &(((F1AP_GNB_DU_Served_Cells_ItemIEs_t *)ie->value.choice.GNB_DU_Served_Cells_List.list.array[i])->value.choice.GNB_DU_Served_Cells_Item);
+    served_cells_item_p = &(((F1AP_GNB_DU_Served_Cells_ItemIEs_t *)ie->value.choice.GNB_DU_Served_Cells_List.list.array[i])->value.choice.GNB_DU_Served_Cells_Item);
     
     /* tac */
-    if (served_celles_item_p->served_Cell_Information.fiveGS_TAC) {
-      OCTET_STRING_TO_INT16(served_celles_item_p->served_Cell_Information.fiveGS_TAC, F1AP_SETUP_REQ(message_p).tac[i]);
-      LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).tac[%d] %d \n",
-            i, F1AP_SETUP_REQ(message_p).tac[i]);
+    if (served_cells_item_p->served_Cell_Information.fiveGS_TAC) {
+      OCTET_STRING_TO_INT16(served_cells_item_p->served_Cell_Information.fiveGS_TAC, F1AP_SETUP_REQ(message_p).tac[i]);
+      LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).tac[%d] %d \n", i, F1AP_SETUP_REQ(message_p).tac[i]);
     }
     /* - nRCGI */
-    TBCD_TO_MCC_MNC(&(served_celles_item_p->served_Cell_Information.nRCGI.pLMN_Identity), F1AP_SETUP_REQ(message_p).mcc[i],
+    TBCD_TO_MCC_MNC(&(served_cells_item_p->served_Cell_Information.nRCGI.pLMN_Identity), F1AP_SETUP_REQ(message_p).mcc[i],
                     F1AP_SETUP_REQ(message_p).mnc[i],
                     F1AP_SETUP_REQ(message_p).mnc_digit_length[i]);
     
     
     // NR cellID
-    BIT_STRING_TO_NR_CELL_IDENTITY(&served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity,
+    BIT_STRING_TO_NR_CELL_IDENTITY(&served_cells_item_p->served_Cell_Information.nRCGI.nRCellIdentity,
 				   F1AP_SETUP_REQ(message_p).nr_cellid[i]);
     LOG_D(F1AP, "[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu\n", assoc_id,
           F1AP_SETUP_REQ(message_p).mcc[i],
           F1AP_SETUP_REQ(message_p).mnc[i],
           (long long unsigned int)F1AP_SETUP_REQ(message_p).nr_cellid[i]);
     LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n",
-          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[0],
-          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[1],
-          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[2],
-          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[3],
-          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[4]);
+          served_cells_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[0],
+          served_cells_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[1],
+          served_cells_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[2],
+          served_cells_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[3],
+          served_cells_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[4]);
     /* - nRPCI */
-    F1AP_SETUP_REQ(message_p).nr_pci[i] = served_celles_item_p->served_Cell_Information.nRPCI;
+    F1AP_SETUP_REQ(message_p).nr_pci[i] = served_cells_item_p->served_Cell_Information.nRPCI;
     LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).nr_pci[%d] %d \n",
           i, F1AP_SETUP_REQ(message_p).nr_pci[i]);
   
     // System Information
     /* mib */
-    F1AP_SETUP_REQ(message_p).mib[i] = calloc(served_celles_item_p->gNB_DU_System_Information->mIB_message.size + 1, sizeof(char));
-    memcpy(F1AP_SETUP_REQ(message_p).mib[i], served_celles_item_p->gNB_DU_System_Information->mIB_message.buf,
-           served_celles_item_p->gNB_DU_System_Information->mIB_message.size);
+    F1AP_SETUP_REQ(message_p).mib[i] = calloc(served_cells_item_p->gNB_DU_System_Information->mIB_message.size + 1, sizeof(char));
+    memcpy(F1AP_SETUP_REQ(message_p).mib[i], served_cells_item_p->gNB_DU_System_Information->mIB_message.buf,
+           served_cells_item_p->gNB_DU_System_Information->mIB_message.size);
     /* Convert the mme name to a printable string */
-    F1AP_SETUP_REQ(message_p).mib[i][served_celles_item_p->gNB_DU_System_Information->mIB_message.size] = '\0';
-    F1AP_SETUP_REQ(message_p).mib_length[i] = served_celles_item_p->gNB_DU_System_Information->mIB_message.size;
+    F1AP_SETUP_REQ(message_p).mib[i][served_cells_item_p->gNB_DU_System_Information->mIB_message.size] = '\0';
+    F1AP_SETUP_REQ(message_p).mib_length[i] = served_cells_item_p->gNB_DU_System_Information->mIB_message.size;
     LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).mib[%d] %s , len = %d \n",
           i, F1AP_SETUP_REQ(message_p).mib[i], F1AP_SETUP_REQ(message_p).mib_length[i]);
 
     /* sib1 */
-    F1AP_SETUP_REQ(message_p).sib1[i] = calloc(served_celles_item_p->gNB_DU_System_Information->sIB1_message.size + 1, sizeof(char));
-    memcpy(F1AP_SETUP_REQ(message_p).sib1[i], served_celles_item_p->gNB_DU_System_Information->sIB1_message.buf,
-           served_celles_item_p->gNB_DU_System_Information->sIB1_message.size);
+    F1AP_SETUP_REQ(message_p).sib1[i] = calloc(served_cells_item_p->gNB_DU_System_Information->sIB1_message.size + 1, sizeof(char));
+    memcpy(F1AP_SETUP_REQ(message_p).sib1[i], served_cells_item_p->gNB_DU_System_Information->sIB1_message.buf,
+           served_cells_item_p->gNB_DU_System_Information->sIB1_message.size);
     /* Convert the mme name to a printable string */
-    F1AP_SETUP_REQ(message_p).sib1[i][served_celles_item_p->gNB_DU_System_Information->sIB1_message.size] = '\0';
-    F1AP_SETUP_REQ(message_p).sib1_length[i] = served_celles_item_p->gNB_DU_System_Information->sIB1_message.size;
+    F1AP_SETUP_REQ(message_p).sib1[i][served_cells_item_p->gNB_DU_System_Information->sIB1_message.size] = '\0';
+    F1AP_SETUP_REQ(message_p).sib1_length[i] = served_cells_item_p->gNB_DU_System_Information->sIB1_message.size;
     LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).sib1[%d] %s , len = %d \n",
           i, F1AP_SETUP_REQ(message_p).sib1[i], F1AP_SETUP_REQ(message_p).sib1_length[i]);
   }
@@ -246,10 +250,18 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance,
   );
 
   if (num_cells_available > 0) {
-    itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+    if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_CU) {
+      itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p);
+    } else {
+      itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+    }
   } else {
     CU_send_F1_SETUP_FAILURE(instance);
-    itti_free(TASK_RRC_ENB,message_p);
+    if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_CU) {
+      itti_free(TASK_RRC_GNB,message_p);
+    } else {
+      itti_free(TASK_RRC_ENB,message_p);
+    }
     return -1;
   }
   return 0;
@@ -306,45 +318,51 @@ int CU_send_F1_SETUP_RESPONSE(instance_t instance,
 
   /* mandatory */
   /* c3. cells to be Activated list */
-  ie = (F1AP_F1SetupResponseIEs_t *)calloc(1, sizeof(F1AP_F1SetupResponseIEs_t));
-  ie->id                        = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List;
-  ie->criticality               = F1AP_Criticality_reject;
-  ie->value.present             = F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List;
-
   int num_cells_to_activate = f1ap_setup_resp->num_cells_to_activate;
   LOG_D(F1AP, "num_cells_to_activate = %d \n", num_cells_to_activate);
-  for (i=0;
-       i<num_cells_to_activate;
-       i++) {
-
-    F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies;
-    cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Activated_List_ItemIEs_t));
-    cells_to_be_activated_list_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
-    cells_to_be_activated_list_item_ies->criticality = F1AP_Criticality_reject;
-    cells_to_be_activated_list_item_ies->value.present = F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item;
-
-    /* 3.1 cells to be Activated list item */
-    F1AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item;
-    memset((void *)&cells_to_be_activated_list_item, 0, sizeof(F1AP_Cells_to_be_Activated_List_Item_t));
-
-    /* - nRCGI */
-    F1AP_NRCGI_t nRCGI;
-    memset(&nRCGI, 0, sizeof(F1AP_NRCGI_t));
-    MCC_MNC_TO_PLMNID(f1ap_setup_resp->mcc[i], f1ap_setup_resp->mnc[i], f1ap_setup_resp->mnc_digit_length[i],
-                                     &nRCGI.pLMN_Identity);
-    NR_CELL_ID_TO_BIT_STRING(f1ap_setup_resp->nr_cellid[i], &nRCGI.nRCellIdentity);
-    cells_to_be_activated_list_item.nRCGI = nRCGI;
-
-    /* optional */
-    /* - nRPCI */
-    if (1) {
-      cells_to_be_activated_list_item.nRPCI = (F1AP_NRPCI_t *)calloc(1, sizeof(F1AP_NRPCI_t));
-      *cells_to_be_activated_list_item.nRPCI = f1ap_setup_resp->nrpci[i];  // int 0..1007
-    }
+  if (num_cells_to_activate >0) {
+    ie = (F1AP_F1SetupResponseIEs_t *)calloc(1, sizeof(F1AP_F1SetupResponseIEs_t));
+    ie->id                        = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List;
+    ie->criticality               = F1AP_Criticality_reject;
+    ie->value.present             = F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List;
+
+    for (i=0; i<num_cells_to_activate; i++) {
+
+      LOG_D(F1AP, "[c3] (cell %d) mcc = %d, mnc = %d, mnc_digit_length = %d, nr_cellid = %lu\n",
+            i,
+            f1ap_setup_resp->cells_to_activate[i].mcc,
+            f1ap_setup_resp->cells_to_activate[i].mnc,
+            f1ap_setup_resp->cells_to_activate[i].mnc_digit_length,
+            f1ap_setup_resp->cells_to_activate[i].nr_cellid);
+
+      F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies;
+      cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Activated_List_ItemIEs_t));
+      cells_to_be_activated_list_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
+      cells_to_be_activated_list_item_ies->criticality = F1AP_Criticality_reject;
+      cells_to_be_activated_list_item_ies->value.present = F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item;
+
+      /* 3.1 cells to be Activated list item */
+      F1AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item;
+      memset((void *)&cells_to_be_activated_list_item, 0, sizeof(F1AP_Cells_to_be_Activated_List_Item_t));
+
+      /* - nRCGI */
+      F1AP_NRCGI_t nRCGI;
+      memset(&nRCGI, 0, sizeof(F1AP_NRCGI_t));
+      MCC_MNC_TO_PLMNID(f1ap_setup_resp->cells_to_activate[i].mcc, f1ap_setup_resp->cells_to_activate[i].mnc, f1ap_setup_resp->cells_to_activate[i].mnc_digit_length,
+			&nRCGI.pLMN_Identity);
+      NR_CELL_ID_TO_BIT_STRING(f1ap_setup_resp->cells_to_activate[i].nr_cellid, &nRCGI.nRCellIdentity);
+      cells_to_be_activated_list_item.nRCGI = nRCGI;
+
+      /* optional */
+      /* - nRPCI */
+      if (1) {
+        cells_to_be_activated_list_item.nRPCI = (F1AP_NRPCI_t *)calloc(1, sizeof(F1AP_NRPCI_t));
+        *cells_to_be_activated_list_item.nRPCI = f1ap_setup_resp->cells_to_activate[i].nrpci;  // int 0..1007
+      }
 
-    /* optional */
-    /* - gNB-CU System Information */
-    if (1) {
+      /* optional */
+      /* - gNB-CU System Information */
+      if (1) {
       /* 3.1.2 gNB-CUSystem Information */
       F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs;
       cells_to_be_activated_list_itemExtIEs = (F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Activated_List_ItemExtIEs_t));
@@ -356,47 +374,44 @@ int CU_send_F1_SETUP_RESPONSE(instance_t instance,
       //LOG_I(F1AP, "%s() SI %d size %d: ", __func__, i, f1ap_setup_resp->SI_container_length[i][0]);
       //for (int n = 0; n < f1ap_setup_resp->SI_container_length[i][0]; n++)
       //  printf("%02x ", f1ap_setup_resp->SI_container[i][0][n]);
-      //printf("\n");
-      for (int j=2;
-           j<10;
-           j++) {
-        if (j==6) j=9;
-        if (f1ap_setup_resp->SI_container[i][j]!=NULL) {
-          LOG_I(F1AP,"SETUP RESP: SI %d, Type %d\n",i,j);
-          AssertFatal((j < 6) || (j == 9), "Illegal SI type %d\n",j);
+          //printf("\n");
+
+          // for (int sIBtype=2;sIBtype<33;sIBtype++) { //21 ? 33 ?
+      for (int sIBtype=2;sIBtype<21;sIBtype++) {
+        if (f1ap_setup_resp->cells_to_activate[i].SI_container[sIBtype]!=NULL) {
+          AssertFatal(sIBtype < 6 || sIBtype == 9, "Illegal SI type %d\n",sIBtype);
           F1AP_SibtypetobeupdatedListItem_t *sib_item = calloc(1,sizeof(*sib_item));
-	  sib_item->sIBtype = j;
+          memset((void*)sib_item,0,sizeof(*sib_item));
+          sib_item->sIBtype = sIBtype;
           OCTET_STRING_fromBuf(&sib_item->sIBmessage,
-                               (const char*)f1ap_setup_resp->SI_container[i][j], 
-                               f1ap_setup_resp->SI_container_length[i][j]);
-        
-          LOG_I(F1AP, "f1ap_setup_resp->SI_container_length[%d][%d] = %d \n", i,j,f1ap_setup_resp->SI_container_length[i][j]);
-	  ASN_SEQUENCE_ADD(&gNB_CUSystemInformation->sibtypetobeupdatedlist.list,sib_item);
+             (const char*)f1ap_setup_resp->cells_to_activate[i].SI_container[sIBtype],
+             f1ap_setup_resp->cells_to_activate[i].SI_container_length[sIBtype]);
+
+          LOG_D(F1AP, "f1ap_setup_resp->SI_container_length[%d][%d] = %d \n", i,sIBtype,f1ap_setup_resp->cells_to_activate[i].SI_container_length[sIBtype]);
+          ASN_SEQUENCE_ADD(&gNB_CUSystemInformation->sibtypetobeupdatedlist.list,sib_item);
         }
       }
       cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation = *gNB_CUSystemInformation;
 
-
       F1AP_ProtocolExtensionContainer_154P112_t p_154P112_t;
       memset((void *)&p_154P112_t, 0, sizeof(F1AP_ProtocolExtensionContainer_154P112_t));
 
-      ASN_SEQUENCE_ADD(&p_154P112_t.list,
-                      cells_to_be_activated_list_itemExtIEs);
+      ASN_SEQUENCE_ADD(&p_154P112_t.list, cells_to_be_activated_list_itemExtIEs);
       cells_to_be_activated_list_item.iE_Extensions = (struct F1AP_ProtocolExtensionContainer*)&p_154P112_t;
 
       free(gNB_CUSystemInformation);
       gNB_CUSystemInformation = NULL;
+      }
+      /* ADD */
+      cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item;
+      ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list, cells_to_be_activated_list_item_ies);
     }
-    /* ADD */
-    cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item;
-    ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list,
-                  cells_to_be_activated_list_item_ies);
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
   }
-  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
   /* encode */
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
-    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    LOG_E(F1AP, "Failed to encode F1 setup response\n");
     return -1;
   }
 
@@ -482,7 +497,7 @@ int CU_send_F1_SETUP_FAILURE(instance_t instance) {
 
   /* encode */
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
-    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    LOG_E(F1AP, "Failed to encode F1 setup failure\n");
     return -1;
   }
 
@@ -521,7 +536,7 @@ int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
 */
 
 //void CU_send_gNB_CU_CONFIGURATION_UPDATE(F1AP_GNBCUConfigurationUpdate_t *GNBCUConfigurationUpdate) {
-int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_idP) {
+int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update) {
   F1AP_F1AP_PDU_t                    pdu;
   F1AP_GNBCUConfigurationUpdate_t    *out;
   F1AP_GNBCUConfigurationUpdateIEs_t *ie;
@@ -530,10 +545,6 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_
   uint32_t  len;
   int       i = 0;
 
-  // for test
-  int mcc = 208;
-  int mnc = 93;
-  int mnc_digit_length = 8;
 
   /* Create */
   /* 0. Message Type */
@@ -551,304 +562,355 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_
   ie->id                        = F1AP_ProtocolIE_ID_id_TransactionID;
   ie->criticality               = F1AP_Criticality_reject;
   ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID;
-  ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(instance, du_mod_idP);
+  ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(instance, 0);
   ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
 
 
-  /* mandatory */
-  /* c2. Cells_to_be_Activated_List */
-  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
-  ie->id                        = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List;
-  ie->criticality               = F1AP_Criticality_reject;
-  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List;
-
-  for (i=0;
-       i<1;
-       i++) {
-
-       F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies;
-       cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Activated_List_ItemIEs_t));
-       cells_to_be_activated_list_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
-       cells_to_be_activated_list_item_ies->criticality = F1AP_Criticality_reject;
-       cells_to_be_activated_list_item_ies->value.present = F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item;
-
-     /* 2.1 cells to be Activated list item */
-     F1AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item;
-     memset((void *)&cells_to_be_activated_list_item, 0, sizeof(F1AP_Cells_to_be_Activated_List_Item_t));
-
-     /* - nRCGI */
-     F1AP_NRCGI_t nRCGI;
-     memset(&nRCGI, 0, sizeof(F1AP_NRCGI_t));
-     MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
-                                         &nRCGI.pLMN_Identity);
-     NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
-     cells_to_be_activated_list_item.nRCGI = nRCGI;
-
-     /* optional */
-     /* - nRPCI */
-     if (0) {
-       cells_to_be_activated_list_item.nRPCI = (F1AP_NRPCI_t *)calloc(1, sizeof(F1AP_NRPCI_t));
-       *cells_to_be_activated_list_item.nRPCI = 321L;  // int 0..1007
-     }
-
-     /* optional */
-     /* - gNB-CU System Information */
-     //if (1) {
-
-     //}
-     /* ADD */
-     cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item;
-     ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list,
-                      cells_to_be_activated_list_item_ies);
-  }  
-  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  // mandatory
+  // c2. Cells_to_be_Activated_List
+  if (f1ap_gnb_cu_configuration_update->num_cells_to_activate > 0) {
+    ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+    ie->id                        = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List;
+    ie->criticality               = F1AP_Criticality_reject;
+    ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List;
+
+    for (i=0; i<f1ap_gnb_cu_configuration_update->num_cells_to_activate; i++) {
+
+      LOG_D(F1AP, "[c2] (cell %d) mcc = %d, mnc = %d, mnc_digit_length = %d, nr_cellid = %lu\n",
+            i,
+            f1ap_gnb_cu_configuration_update->cells_to_activate[i].mcc,
+            f1ap_gnb_cu_configuration_update->cells_to_activate[i].mnc,
+            f1ap_gnb_cu_configuration_update->cells_to_activate[i].mnc_digit_length,
+            f1ap_gnb_cu_configuration_update->cells_to_activate[i].nr_cellid);
+
+      F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies;
+      cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Activated_List_ItemIEs_t));
+      cells_to_be_activated_list_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
+      cells_to_be_activated_list_item_ies->criticality = F1AP_Criticality_reject;
+      cells_to_be_activated_list_item_ies->value.present = F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item;
+
+      // 2.1 cells to be Activated list item
+      F1AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item;
+      memset((void *)&cells_to_be_activated_list_item, 0, sizeof(F1AP_Cells_to_be_Activated_List_Item_t));
+
+      // - nRCGI
+      F1AP_NRCGI_t nRCGI;
+      memset(&nRCGI, 0, sizeof(F1AP_NRCGI_t));
+      MCC_MNC_TO_PLMNID(f1ap_gnb_cu_configuration_update->cells_to_activate[i].mcc,
+			f1ap_gnb_cu_configuration_update->cells_to_activate[i].mnc,
+			f1ap_gnb_cu_configuration_update->cells_to_activate[i].mnc_digit_length,
+			&nRCGI.pLMN_Identity);
+      NR_CELL_ID_TO_BIT_STRING(f1ap_gnb_cu_configuration_update->cells_to_activate[i].nr_cellid,
+			       &nRCGI.nRCellIdentity);
+      cells_to_be_activated_list_item.nRCGI = nRCGI;
+
+      if(RC.nrrrc) {
+
+        // optional
+        // -nRPCI
+        cells_to_be_activated_list_item.nRPCI = (F1AP_NRPCI_t *)calloc(1, sizeof(F1AP_NRPCI_t));
+        *cells_to_be_activated_list_item.nRPCI = f1ap_gnb_cu_configuration_update->cells_to_activate[i].nrpci;  // int 0..1007
+
+        // optional
+        // 3.1.2 gNB-CUSystem Information
+        F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs;
+        cells_to_be_activated_list_itemExtIEs = (F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Activated_List_ItemExtIEs_t));
+        cells_to_be_activated_list_itemExtIEs->id                     = F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation;
+        cells_to_be_activated_list_itemExtIEs->criticality            = F1AP_Criticality_reject;
+        cells_to_be_activated_list_itemExtIEs->extensionValue.present = F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation;
+
+        if (f1ap_gnb_cu_configuration_update->cells_to_activate[i].num_SI > 0) {
+          F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = (F1AP_GNB_CUSystemInformation_t *)calloc(1, sizeof(F1AP_GNB_CUSystemInformation_t));
+          //LOG_I(F1AP, "%s() SI %d size %d: ", __func__, i, f1ap_setup_resp->SI_container_length[i][0]);
+          //for (int n = 0; n < f1ap_setup_resp->SI_container_length[i][0]; n++)
+          //  printf("%02x ", f1ap_setup_resp->SI_container[i][0][n]);
+          //printf("\n");
+
+          // for (int sIBtype=2;sIBtype<33;sIBtype++) { //21 ? 33 ?
+          for (int sIBtype=2;sIBtype<21;sIBtype++) {
+            if (f1ap_gnb_cu_configuration_update->cells_to_activate[i].SI_container[sIBtype]!=NULL) {
+              AssertFatal(sIBtype < 6 || sIBtype == 9, "Illegal SI type %d\n",sIBtype);
+              F1AP_SibtypetobeupdatedListItem_t *sib_item = calloc(1,sizeof(*sib_item));
+              memset((void*)sib_item,0,sizeof(*sib_item));
+              sib_item->sIBtype = sIBtype;
+              OCTET_STRING_fromBuf(&sib_item->sIBmessage,
+                                   (const char*)f1ap_gnb_cu_configuration_update->cells_to_activate[i].SI_container[sIBtype],
+                                   f1ap_gnb_cu_configuration_update->cells_to_activate[i].SI_container_length[sIBtype]);
+
+              LOG_D(F1AP, "f1ap_setup_resp->SI_container_length[%d][%d] = %d \n", i,sIBtype,f1ap_gnb_cu_configuration_update->cells_to_activate[i].SI_container_length[sIBtype]);
+              ASN_SEQUENCE_ADD(&gNB_CUSystemInformation->sibtypetobeupdatedlist.list,sib_item);
+            }
+          }
+          cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation = *gNB_CUSystemInformation;
+
+
+          F1AP_ProtocolExtensionContainer_154P112_t p_154P112_t;
+          memset((void *)&p_154P112_t, 0, sizeof(F1AP_ProtocolExtensionContainer_154P112_t));
+
+          ASN_SEQUENCE_ADD(&p_154P112_t.list,
+                           cells_to_be_activated_list_itemExtIEs);
+          cells_to_be_activated_list_item.iE_Extensions = (struct F1AP_ProtocolExtensionContainer*)&p_154P112_t;
+
+          free(gNB_CUSystemInformation);
+          gNB_CUSystemInformation = NULL;
+        }
+      }
 
+      // ADD
+      cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item;
+      ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list,
+		       cells_to_be_activated_list_item_ies);
+    }
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
+  }
 
-  /* mandatory */
-  /* c3. Cells_to_be_Deactivated_List */
-  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
-  ie->id                        = F1AP_ProtocolIE_ID_id_Cells_to_be_Deactivated_List;
-  ie->criticality               = F1AP_Criticality_reject;
-  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Deactivated_List;
-
-  for (i=0;
-       i<1;
-       i++) {
-
-       F1AP_Cells_to_be_Deactivated_List_ItemIEs_t *cells_to_be_deactivated_list_item_ies;
-       cells_to_be_deactivated_list_item_ies = (F1AP_Cells_to_be_Deactivated_List_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Deactivated_List_ItemIEs_t));
-       cells_to_be_deactivated_list_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
-       cells_to_be_deactivated_list_item_ies->criticality = F1AP_Criticality_reject;
-       cells_to_be_deactivated_list_item_ies->value.present = F1AP_Cells_to_be_Deactivated_List_ItemIEs__value_PR_Cells_to_be_Deactivated_List_Item;
-
-       /* 3.1 cells to be Deactivated list item */
-       F1AP_Cells_to_be_Deactivated_List_Item_t cells_to_be_deactivated_list_item;
-       memset((void *)&cells_to_be_deactivated_list_item, 0, sizeof(F1AP_Cells_to_be_Deactivated_List_Item_t));
-
-       /* - nRCGI */
-       F1AP_NRCGI_t nRCGI;
-       memset(&nRCGI, 0, sizeof(F1AP_NRCGI_t));
-       MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
-                                           &nRCGI.pLMN_Identity);
-       NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
-       cells_to_be_deactivated_list_item.nRCGI = nRCGI;
-
-       //}
-       /* ADD */
-       cells_to_be_deactivated_list_item_ies->value.choice.Cells_to_be_Deactivated_List_Item = cells_to_be_deactivated_list_item;
-       ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Deactivated_List.list,
-                        cells_to_be_deactivated_list_item_ies);
-  }  
-  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
+  if(!RC.nrrrc) {
 
-  /* mandatory */
-  /* c4. GNB_CU_TNL_Association_To_Add_List */
-  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
-  ie->id                        = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Add_List;
-  ie->criticality               = F1AP_Criticality_reject;
-  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Add_List;
-
-  for (i=0;
-       i<1;
-       i++) {
-
-       F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t *gnb_cu_tnl_association_to_add_item_ies;
-       gnb_cu_tnl_association_to_add_item_ies = (F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t));
-       gnb_cu_tnl_association_to_add_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Add_Item;
-       gnb_cu_tnl_association_to_add_item_ies->criticality = F1AP_Criticality_reject;
-       gnb_cu_tnl_association_to_add_item_ies->value.present = F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Add_Item;
-
-       /* 4.1 GNB_CU_TNL_Association_To_Add_Item */
-       F1AP_GNB_CU_TNL_Association_To_Add_Item_t gnb_cu_tnl_association_to_add_item;
-       memset((void *)&gnb_cu_tnl_association_to_add_item, 0, sizeof(F1AP_GNB_CU_TNL_Association_To_Add_Item_t));
-
-
-       /* 4.1.1 tNLAssociationTransportLayerAddress */
-       F1AP_CP_TransportLayerAddress_t transportLayerAddress;
-       memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
-       transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
-       TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
-       
-       // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
-       // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
-       // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
-       // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
-
-       gnb_cu_tnl_association_to_add_item.tNLAssociationTransportLayerAddress = transportLayerAddress;
-
-       /* 4.1.2 tNLAssociationUsage */
-       gnb_cu_tnl_association_to_add_item.tNLAssociationUsage = F1AP_TNLAssociationUsage_non_ue;
-       
-
-       /* ADD */
-       gnb_cu_tnl_association_to_add_item_ies->value.choice.GNB_CU_TNL_Association_To_Add_Item = gnb_cu_tnl_association_to_add_item;
-       ASN_SEQUENCE_ADD(&ie->value.choice.GNB_CU_TNL_Association_To_Add_List.list,
-                        gnb_cu_tnl_association_to_add_item_ies);
-  }  
-  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+    /* mandatory */
+    /* c3. Cells_to_be_Deactivated_List */
+    ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+    ie->id                        = F1AP_ProtocolIE_ID_id_Cells_to_be_Deactivated_List;
+    ie->criticality               = F1AP_Criticality_reject;
+    ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Deactivated_List;
 
+    for (i=0;
+         i<1;
+         i++) {
 
+      F1AP_Cells_to_be_Deactivated_List_ItemIEs_t *cells_to_be_deactivated_list_item_ies;
+      cells_to_be_deactivated_list_item_ies = (F1AP_Cells_to_be_Deactivated_List_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Deactivated_List_ItemIEs_t));
+      cells_to_be_deactivated_list_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
+      cells_to_be_deactivated_list_item_ies->criticality = F1AP_Criticality_reject;
+      cells_to_be_deactivated_list_item_ies->value.present = F1AP_Cells_to_be_Deactivated_List_ItemIEs__value_PR_Cells_to_be_Deactivated_List_Item;
 
-  /* mandatory */
-  /* c5. GNB_CU_TNL_Association_To_Remove_List */
-  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
-  ie->id                        = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Remove_List;
-  ie->criticality               = F1AP_Criticality_reject;
-  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Remove_List;
-  for (i=0;
-       i<1;
-       i++) {
-
-       F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t *gnb_cu_tnl_association_to_remove_item_ies;
-       gnb_cu_tnl_association_to_remove_item_ies = (F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t));
-       gnb_cu_tnl_association_to_remove_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Remove_Item;
-       gnb_cu_tnl_association_to_remove_item_ies->criticality = F1AP_Criticality_reject;
-       gnb_cu_tnl_association_to_remove_item_ies->value.present = F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Remove_Item;
-
-       /* 4.1 GNB_CU_TNL_Association_To_Remove_Item */
-       F1AP_GNB_CU_TNL_Association_To_Remove_Item_t gnb_cu_tnl_association_to_remove_item;
-       memset((void *)&gnb_cu_tnl_association_to_remove_item, 0, sizeof(F1AP_GNB_CU_TNL_Association_To_Remove_Item_t));
-
-
-       /* 4.1.1 tNLAssociationTransportLayerAddress */
-       F1AP_CP_TransportLayerAddress_t transportLayerAddress;
-       memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
-       transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
-       TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
-       
-       // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
-       // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
-       // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
-       // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
-
-       gnb_cu_tnl_association_to_remove_item.tNLAssociationTransportLayerAddress = transportLayerAddress;
-   
+      // 3.1 cells to be Deactivated list item
+      F1AP_Cells_to_be_Deactivated_List_Item_t cells_to_be_deactivated_list_item;
+      memset((void *)&cells_to_be_deactivated_list_item, 0, sizeof(F1AP_Cells_to_be_Deactivated_List_Item_t));
 
-       /* ADD */
-       gnb_cu_tnl_association_to_remove_item_ies->value.choice.GNB_CU_TNL_Association_To_Remove_Item = gnb_cu_tnl_association_to_remove_item;
-       ASN_SEQUENCE_ADD(&ie->value.choice.GNB_CU_TNL_Association_To_Remove_List.list,
-                        gnb_cu_tnl_association_to_remove_item_ies);
-  }  
-  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
-  /* mandatory */
-  /* c6. GNB_CU_TNL_Association_To_Update_List */
-  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
-  ie->id                        = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Update_List;
-  ie->criticality               = F1AP_Criticality_reject;
-  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Update_List;
-  for (i=0;
-       i<1;
-       i++) {
-
-       F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t *gnb_cu_tnl_association_to_update_item_ies;
-       gnb_cu_tnl_association_to_update_item_ies = (F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t));
-       gnb_cu_tnl_association_to_update_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Update_Item;
-       gnb_cu_tnl_association_to_update_item_ies->criticality = F1AP_Criticality_reject;
-       gnb_cu_tnl_association_to_update_item_ies->value.present = F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Update_Item;
-
-       /* 4.1 GNB_CU_TNL_Association_To_Update_Item */
-       F1AP_GNB_CU_TNL_Association_To_Update_Item_t gnb_cu_tnl_association_to_update_item;
-       memset((void *)&gnb_cu_tnl_association_to_update_item, 0, sizeof(F1AP_GNB_CU_TNL_Association_To_Update_Item_t));
-
-
-       /* 4.1.1 tNLAssociationTransportLayerAddress */
-       F1AP_CP_TransportLayerAddress_t transportLayerAddress;
-       memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
-       transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
-       TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
-       
-       // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
-       // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
-       // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
-       // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
-
-       gnb_cu_tnl_association_to_update_item.tNLAssociationTransportLayerAddress = transportLayerAddress;
-   
+      F1AP_NRCGI_t nRCGI;
+      memset(&nRCGI, 0, sizeof(F1AP_NRCGI_t));
+      MCC_MNC_TO_PLMNID(f1ap_gnb_cu_configuration_update->cells_to_activate[i].mcc,
+                        f1ap_gnb_cu_configuration_update->cells_to_activate[i].mnc,
+                        f1ap_gnb_cu_configuration_update->cells_to_activate[i].mnc_digit_length,
+                        &nRCGI.pLMN_Identity);
+      NR_CELL_ID_TO_BIT_STRING(f1ap_gnb_cu_configuration_update->cells_to_activate[i].nr_cellid, &nRCGI.nRCellIdentity);
+      cells_to_be_deactivated_list_item.nRCGI = nRCGI;
 
-       /* 4.1.2 tNLAssociationUsage */
-       if (1) {
-         gnb_cu_tnl_association_to_update_item.tNLAssociationUsage = (F1AP_TNLAssociationUsage_t *)calloc(1, sizeof(F1AP_TNLAssociationUsage_t));
-         *gnb_cu_tnl_association_to_update_item.tNLAssociationUsage = F1AP_TNLAssociationUsage_non_ue;
-       }
-       
-       /* ADD */
-       gnb_cu_tnl_association_to_update_item_ies->value.choice.GNB_CU_TNL_Association_To_Update_Item = gnb_cu_tnl_association_to_update_item;
-       ASN_SEQUENCE_ADD(&ie->value.choice.GNB_CU_TNL_Association_To_Update_List.list,
-                        gnb_cu_tnl_association_to_update_item_ies);
-  }  
-  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+      cells_to_be_deactivated_list_item_ies->value.choice.Cells_to_be_Deactivated_List_Item = cells_to_be_deactivated_list_item;
+      ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Deactivated_List.list,
+                       cells_to_be_deactivated_list_item_ies);
+    }
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
 
+    /* mandatory */
+    /* c4. GNB_CU_TNL_Association_To_Add_List */
+    ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+    ie->id                        = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Add_List;
+    ie->criticality               = F1AP_Criticality_reject;
+    ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Add_List;
 
-  /* mandatory */
-  /* c7. Cells_to_be_Barred_List */
-  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
-  ie->id                        = F1AP_ProtocolIE_ID_id_Cells_to_be_Barred_List;
-  ie->criticality               = F1AP_Criticality_reject;
-  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Barred_List;
-  for (i=0;
-       i<1;
-       i++) {
-
-       F1AP_Cells_to_be_Barred_ItemIEs_t *cells_to_be_barred_item_ies;
-       cells_to_be_barred_item_ies = (F1AP_Cells_to_be_Barred_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Barred_ItemIEs_t));
-       cells_to_be_barred_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
-       cells_to_be_barred_item_ies->criticality = F1AP_Criticality_reject;
-       cells_to_be_barred_item_ies->value.present = F1AP_Cells_to_be_Barred_ItemIEs__value_PR_Cells_to_be_Barred_Item;
-
-       /* 7.1 cells to be Deactivated list item */
-       F1AP_Cells_to_be_Barred_Item_t cells_to_be_barred_item;
-       memset((void *)&cells_to_be_barred_item, 0, sizeof(F1AP_Cells_to_be_Barred_Item_t));
-
-       /* - nRCGI */
-       F1AP_NRCGI_t nRCGI;
-       memset(&nRCGI,0,sizeof(F1AP_NRCGI_t));
-       MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
-                                           &nRCGI.pLMN_Identity);
-       NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
-       cells_to_be_barred_item.nRCGI = nRCGI;
-       
-       /* 7.2 cellBarred*/
-       cells_to_be_barred_item.cellBarred = F1AP_CellBarred_not_barred;
-
-       /* ADD */
-       cells_to_be_barred_item_ies->value.choice.Cells_to_be_Barred_Item = cells_to_be_barred_item;
-       ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Barred_List.list,
-                        cells_to_be_barred_item_ies);
-  }
-  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+    for (i=0;
+         i<1;
+         i++) {
 
+      F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t *gnb_cu_tnl_association_to_add_item_ies;
+      gnb_cu_tnl_association_to_add_item_ies = (F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t));
+      gnb_cu_tnl_association_to_add_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Add_Item;
+      gnb_cu_tnl_association_to_add_item_ies->criticality = F1AP_Criticality_reject;
+      gnb_cu_tnl_association_to_add_item_ies->value.present = F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Add_Item;
 
+      // 4.1 GNB_CU_TNL_Association_To_Add_Item
+      F1AP_GNB_CU_TNL_Association_To_Add_Item_t gnb_cu_tnl_association_to_add_item;
+      memset((void *)&gnb_cu_tnl_association_to_add_item, 0, sizeof(F1AP_GNB_CU_TNL_Association_To_Add_Item_t));
 
-  /* mandatory */
-  /* c8. Protected_EUTRA_Resources_List */
-  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
-  ie->id                        = F1AP_ProtocolIE_ID_id_Protected_EUTRA_Resources_List;
-  ie->criticality               = F1AP_Criticality_reject;
-  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Protected_EUTRA_Resources_List;
 
-  for (i=0;
-       i<1;
-       i++) {
+      // 4.1.1 tNLAssociationTransportLayerAddress
+      F1AP_CP_TransportLayerAddress_t transportLayerAddress;
+      memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
+      transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
+      TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
 
+      // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
+      // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
+      // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
+      // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
 
-       F1AP_Protected_EUTRA_Resources_ItemIEs_t *protected_eutra_resources_item_ies;
+      gnb_cu_tnl_association_to_add_item.tNLAssociationTransportLayerAddress = transportLayerAddress;
 
-       /* 8.1 SpectrumSharingGroupID */
-       protected_eutra_resources_item_ies = (F1AP_Protected_EUTRA_Resources_ItemIEs_t *)calloc(1, sizeof(F1AP_Protected_EUTRA_Resources_ItemIEs_t));
-       protected_eutra_resources_item_ies->id = F1AP_ProtocolIE_ID_id_Protected_EUTRA_Resources_List;
-       protected_eutra_resources_item_ies->criticality = F1AP_Criticality_reject;
-       protected_eutra_resources_item_ies->value.present = F1AP_Protected_EUTRA_Resources_ItemIEs__value_PR_Protected_EUTRA_Resources_Item;
-       ((F1AP_Protected_EUTRA_Resources_Item_t*)&protected_eutra_resources_item_ies->value.choice.Protected_EUTRA_Resources_Item)->spectrumSharingGroupID = 123L;
-       memset(&protected_eutra_resources_item_ies->value.choice.Protected_EUTRA_Resources_Item,0,
-	      sizeof(F1AP_Protected_EUTRA_Resources_Item_t));
-       ASN_SEQUENCE_ADD(&ie->value.choice.Protected_EUTRA_Resources_List.list, protected_eutra_resources_item_ies);
+      // 4.1.2 tNLAssociationUsage
+      gnb_cu_tnl_association_to_add_item.tNLAssociationUsage = F1AP_TNLAssociationUsage_non_ue;
 
-/*
+
+
+      gnb_cu_tnl_association_to_add_item_ies->value.choice.GNB_CU_TNL_Association_To_Add_Item = gnb_cu_tnl_association_to_add_item;
+      ASN_SEQUENCE_ADD(&ie->value.choice.GNB_CU_TNL_Association_To_Add_List.list,
+                       gnb_cu_tnl_association_to_add_item_ies);
+    }
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+    /* mandatory */
+    /* c5. GNB_CU_TNL_Association_To_Remove_List */
+    ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+    ie->id                        = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Remove_List;
+    ie->criticality               = F1AP_Criticality_reject;
+    ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Remove_List;
+    for (i=0;
+         i<1;
+         i++) {
+
+      F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t *gnb_cu_tnl_association_to_remove_item_ies;
+      gnb_cu_tnl_association_to_remove_item_ies = (F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t));
+      gnb_cu_tnl_association_to_remove_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Remove_Item;
+      gnb_cu_tnl_association_to_remove_item_ies->criticality = F1AP_Criticality_reject;
+      gnb_cu_tnl_association_to_remove_item_ies->value.present = F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Remove_Item;
+
+      // 4.1 GNB_CU_TNL_Association_To_Remove_Item
+      F1AP_GNB_CU_TNL_Association_To_Remove_Item_t gnb_cu_tnl_association_to_remove_item;
+      memset((void *)&gnb_cu_tnl_association_to_remove_item, 0, sizeof(F1AP_GNB_CU_TNL_Association_To_Remove_Item_t));
+
+
+      // 4.1.1 tNLAssociationTransportLayerAddress
+      F1AP_CP_TransportLayerAddress_t transportLayerAddress;
+      memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
+      transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
+      TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
+
+      // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
+      // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
+      // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
+      // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
+
+      gnb_cu_tnl_association_to_remove_item.tNLAssociationTransportLayerAddress = transportLayerAddress;
+
+
+
+      gnb_cu_tnl_association_to_remove_item_ies->value.choice.GNB_CU_TNL_Association_To_Remove_Item = gnb_cu_tnl_association_to_remove_item;
+      ASN_SEQUENCE_ADD(&ie->value.choice.GNB_CU_TNL_Association_To_Remove_List.list,
+                       gnb_cu_tnl_association_to_remove_item_ies);
+    }
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+    /* mandatory */
+    /* c6. GNB_CU_TNL_Association_To_Update_List */
+    ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+    ie->id                        = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Update_List;
+    ie->criticality               = F1AP_Criticality_reject;
+    ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Update_List;
+    for (i=0;
+         i<1;
+         i++) {
+
+      F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t *gnb_cu_tnl_association_to_update_item_ies;
+      gnb_cu_tnl_association_to_update_item_ies = (F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t));
+      gnb_cu_tnl_association_to_update_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Update_Item;
+      gnb_cu_tnl_association_to_update_item_ies->criticality = F1AP_Criticality_reject;
+      gnb_cu_tnl_association_to_update_item_ies->value.present = F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Update_Item;
+
+      // 4.1 GNB_CU_TNL_Association_To_Update_Item
+      F1AP_GNB_CU_TNL_Association_To_Update_Item_t gnb_cu_tnl_association_to_update_item;
+      memset((void *)&gnb_cu_tnl_association_to_update_item, 0, sizeof(F1AP_GNB_CU_TNL_Association_To_Update_Item_t));
+
+
+      // 4.1.1 tNLAssociationTransportLayerAddress
+      F1AP_CP_TransportLayerAddress_t transportLayerAddress;
+      memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
+      transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
+      TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
+
+      // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
+      // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
+      // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
+      // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
+
+      gnb_cu_tnl_association_to_update_item.tNLAssociationTransportLayerAddress = transportLayerAddress;
+
+
+      // 4.1.2 tNLAssociationUsage
+      if (1) {
+        gnb_cu_tnl_association_to_update_item.tNLAssociationUsage = (F1AP_TNLAssociationUsage_t *)calloc(1, sizeof(F1AP_TNLAssociationUsage_t));
+        *gnb_cu_tnl_association_to_update_item.tNLAssociationUsage = F1AP_TNLAssociationUsage_non_ue;
+      }
+
+
+      gnb_cu_tnl_association_to_update_item_ies->value.choice.GNB_CU_TNL_Association_To_Update_Item = gnb_cu_tnl_association_to_update_item;
+      ASN_SEQUENCE_ADD(&ie->value.choice.GNB_CU_TNL_Association_To_Update_List.list,
+                       gnb_cu_tnl_association_to_update_item_ies);
+    }
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+    /* mandatory */
+    /* c7. Cells_to_be_Barred_List */
+    ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+    ie->id                        = F1AP_ProtocolIE_ID_id_Cells_to_be_Barred_List;
+    ie->criticality               = F1AP_Criticality_reject;
+    ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Barred_List;
+    for (i=0;
+         i<1;
+         i++) {
+
+      F1AP_Cells_to_be_Barred_ItemIEs_t *cells_to_be_barred_item_ies;
+      cells_to_be_barred_item_ies = (F1AP_Cells_to_be_Barred_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Barred_ItemIEs_t));
+      cells_to_be_barred_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
+      cells_to_be_barred_item_ies->criticality = F1AP_Criticality_reject;
+      cells_to_be_barred_item_ies->value.present = F1AP_Cells_to_be_Barred_ItemIEs__value_PR_Cells_to_be_Barred_Item;
+
+      // 7.1 cells to be Deactivated list item
+      F1AP_Cells_to_be_Barred_Item_t cells_to_be_barred_item;
+      memset((void *)&cells_to_be_barred_item, 0, sizeof(F1AP_Cells_to_be_Barred_Item_t));
+
+      // - nRCGI
+      F1AP_NRCGI_t nRCGI;
+      memset(&nRCGI,0,sizeof(F1AP_NRCGI_t));
+      MCC_MNC_TO_PLMNID(f1ap_gnb_cu_configuration_update->cells_to_activate[i].mcc,
+                        f1ap_gnb_cu_configuration_update->cells_to_activate[i].mnc,
+                        f1ap_gnb_cu_configuration_update->cells_to_activate[i].mnc_digit_length,
+                        &nRCGI.pLMN_Identity);
+      NR_CELL_ID_TO_BIT_STRING(f1ap_gnb_cu_configuration_update->cells_to_activate[i].nr_cellid, &nRCGI.nRCellIdentity);
+      cells_to_be_barred_item.nRCGI = nRCGI;
+
+      // 7.2 cellBarred
+      cells_to_be_barred_item.cellBarred = F1AP_CellBarred_not_barred;
+
+      cells_to_be_barred_item_ies->value.choice.Cells_to_be_Barred_Item = cells_to_be_barred_item;
+      ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Barred_List.list,
+                       cells_to_be_barred_item_ies);
+    }
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+    /* mandatory */
+    /* c8. Protected_EUTRA_Resources_List */
+    ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+    ie->id                        = F1AP_ProtocolIE_ID_id_Protected_EUTRA_Resources_List;
+    ie->criticality               = F1AP_Criticality_reject;
+    ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Protected_EUTRA_Resources_List;
+
+    for (i=0;
+         i<1;
+         i++) {
+
+
+      F1AP_Protected_EUTRA_Resources_ItemIEs_t *protected_eutra_resources_item_ies;
+
+      // 8.1 SpectrumSharingGroupID
+      protected_eutra_resources_item_ies = (F1AP_Protected_EUTRA_Resources_ItemIEs_t *)calloc(1, sizeof(F1AP_Protected_EUTRA_Resources_ItemIEs_t));
+      protected_eutra_resources_item_ies->id = F1AP_ProtocolIE_ID_id_Protected_EUTRA_Resources_List;
+      protected_eutra_resources_item_ies->criticality = F1AP_Criticality_reject;
+      protected_eutra_resources_item_ies->value.present = F1AP_Protected_EUTRA_Resources_ItemIEs__value_PR_Protected_EUTRA_Resources_Item;
+      ((F1AP_Protected_EUTRA_Resources_Item_t*)&protected_eutra_resources_item_ies->value.choice.Protected_EUTRA_Resources_Item)->spectrumSharingGroupID = 123L;
+      memset(&protected_eutra_resources_item_ies->value.choice.Protected_EUTRA_Resources_Item,0,
+             sizeof(F1AP_Protected_EUTRA_Resources_Item_t));
+      ASN_SEQUENCE_ADD(&ie->value.choice.Protected_EUTRA_Resources_List.list, protected_eutra_resources_item_ies);
+
+      /*
        F1AP_Served_EUTRA_Cells_Information_t served_eutra_cells_information;
        memset((void *)&served_eutra_cells_information, 0, sizeof(F1AP_Served_EUTRA_Cells_Information_t));
 
@@ -879,17 +941,22 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_
        ASN_SEQUENCE_ADD(&protected_eutra_resources_item_ies->value.choice.ListofEUTRACellsinGNBDUCoordination.list, &served_eutra_cells_information);
 
        ASN_SEQUENCE_ADD(&ie->value.choice.Protected_EUTRA_Resources_List.list, protected_eutra_resources_item_ies);
-*/
+      */
+    }
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
   }
-  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
 
   /* encode */
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
-    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    LOG_E(F1AP, "Failed to encode F1 gNB-CU CONFIGURATION UPDATE\n");
     return -1;
   }
 
+  LOG_D(F1AP, "F1AP gNB-CU CONFIGURATION UPDATE\n");
+  //for (int i=0;i<len;i++) printf("%02x ",buffer[i]);
+  //printf("\n");
+
   cu_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data_from_du->assoc_id, buffer, len, 0);
   return 0;
 }
@@ -905,7 +972,8 @@ int CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
                                                        uint32_t assoc_id,
                                                        uint32_t stream,
                                                        F1AP_F1AP_PDU_t *pdu) {
-  AssertFatal(1==0,"Not implemented yet\n");
+  LOG_D(F1AP,"Cell Configuration ok (assoc_id %d)\n",assoc_id);
+  return(0);
 }
 
 
diff --git a/openair2/F1AP/f1ap_cu_interface_management.h b/openair2/F1AP/f1ap_cu_interface_management.h
index acad13836dea4e8043791945cb853fa3551d30ec..de7dcfe99ba9b9b475813010a406a0a12d6297af 100644
--- a/openair2/F1AP/f1ap_cu_interface_management.h
+++ b/openair2/F1AP/f1ap_cu_interface_management.h
@@ -85,8 +85,7 @@ int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
 /*
  * gNB-CU Configuration Update
  */
-int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_idP);
-
+int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update);
 int CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
                                                   uint32_t assoc_id,
                                                   uint32_t stream,
diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
index f4c09c4725408ec063c28d3e7eeb5b2ce64e7836..03cfcc73298f89361b4198de52c1e1d476765eba 100644
--- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
+++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
@@ -114,28 +114,62 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t             instance,
   /* RRC Container */
   F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
                              F1AP_ProtocolIE_ID_id_RRCContainer, true);
-
+  AssertFatal(ie!=NULL,"RRCContainer is missing\n");
   // create an ITTI message and copy SDU
-  message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_MAC_CCCH_DATA_IND);
-  memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
-  ccch_sdu_len = ie->value.choice.RRCContainer.size;
-  memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf,
-         ccch_sdu_len);
-
-  //LOG_I(F1AP, "%s() RRCContainer (CCCH) size %ld: ", __func__,
-  //      ie->value.choice.RRCContainer.size);
-  //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
-  //  printf("%02x ", RRC_MAC_CCCH_DATA_IND (message_p).sdu[i]);
-  //printf("\n");
+  if (RC.nrrrc && RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU) {
+    message_p = itti_alloc_new_message (TASK_CU_F1, 0, NR_RRC_MAC_CCCH_DATA_IND);
+    memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
+    ccch_sdu_len = ie->value.choice.RRCContainer.size;
+    memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf,
+           ccch_sdu_len);
+  } else {
+    message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_MAC_CCCH_DATA_IND);
+    memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
+    ccch_sdu_len = ie->value.choice.RRCContainer.size;
+    memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf,
+           ccch_sdu_len);
+  }
+
+  if (RC.nrrrc && RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU) {
+
+    LOG_D(F1AP, "%s() RRCContainer (CCCH) size %ld: ", __func__, ie->value.choice.RRCContainer.size);
+    //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
+    //  printf("%02x ", RRC_MAC_CCCH_DATA_IND (message_p).sdu[i]);
+    //printf("\n");
+
+    /* DUtoCURRCContainer */
+    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
+                               F1AP_ProtocolIE_ID_id_DUtoCURRCContainer, true);
+    if (ie) {
+      NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container = malloc(sizeof(OCTET_STRING_t));
+      NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->size = ie->value.choice.DUtoCURRCContainer.size;
+      NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf = malloc(
+          ie->value.choice.DUtoCURRCContainer.size);
+      memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf,
+             ie->value.choice.DUtoCURRCContainer.buf,
+             ie->value.choice.DUtoCURRCContainer.size);
+    }
+  }
 
   // Find instance from nr_cellid
   int rrc_inst = -1;
-  for (int i=0;i<RC.nb_inst;i++) {
+  if (RC.nrrrc && RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU) {
+    for (int i=0;i<RC.nb_nr_inst;i++) {
+      // first get RRC instance (note, no the ITTI instance)
+      gNB_RRC_INST *rrc = RC.nrrrc[i];
+      if (rrc->nr_cellid == nr_cellid) {
+        rrc_inst = i;
+        break;
+      }
+    }
+  } else {
+    for (int i=0;i<RC.nb_inst;i++) {
           // first get RRC instance (note, no the ITTI instance)
-    eNB_RRC_INST *rrc = RC.rrc[i];
-    if (rrc->nr_cellid == nr_cellid) {
-      rrc_inst = i; 
-      break;
+      eNB_RRC_INST *rrc = RC.rrc[i];
+      if (rrc->nr_cellid == nr_cellid) {
+        rrc_inst = i;
+        break;
+      }
     }
   }
   AssertFatal(rrc_inst>=0,"couldn't find an RRC instance for nr_cell %llu\n",(unsigned long long int)nr_cellid);
@@ -148,15 +182,23 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t             instance,
   }
   f1ap_cu_inst[rrc_inst].f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id;
 
-
-  RRC_MAC_CCCH_DATA_IND (message_p).frame     = 0; 
-  RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0;
-  RRC_MAC_CCCH_DATA_IND (message_p).sdu_size  = ccch_sdu_len;
-  RRC_MAC_CCCH_DATA_IND (message_p).enb_index = rrc_inst; // CU instance 
-  RRC_MAC_CCCH_DATA_IND (message_p).rnti      = rnti;
-  RRC_MAC_CCCH_DATA_IND (message_p).CC_id      = CC_id; 
-  itti_send_msg_to_task (TASK_RRC_ENB, instance, message_p);
-
+  if (RC.nrrrc && RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU) {
+    NR_RRC_MAC_CCCH_DATA_IND (message_p).frame     = 0;
+    NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0;
+    NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size  = ccch_sdu_len;
+    NR_RRC_MAC_CCCH_DATA_IND (message_p).gnb_index = rrc_inst; // CU instance
+    NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti      = rnti;
+    NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id     = CC_id;
+    itti_send_msg_to_task (TASK_RRC_GNB, instance, message_p);
+  } else {
+    RRC_MAC_CCCH_DATA_IND (message_p).frame      = 0;
+    RRC_MAC_CCCH_DATA_IND (message_p).sub_frame  = 0;
+    RRC_MAC_CCCH_DATA_IND (message_p).sdu_size   = ccch_sdu_len;
+    RRC_MAC_CCCH_DATA_IND (message_p).enb_index  = rrc_inst; // CU instance
+    RRC_MAC_CCCH_DATA_IND (message_p).rnti       = rnti;
+    RRC_MAC_CCCH_DATA_IND (message_p).CC_id      = CC_id;
+    itti_send_msg_to_task (TASK_RRC_ENB, instance, message_p);
+  }
 
   return 0;
 }
@@ -171,7 +213,8 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t                instance,
                                     f1ap_dl_rrc_message_t    *f1ap_dl_rrc)
                                     {
 
-  F1AP_F1AP_PDU_t                 pdu; 
+  LOG_D(F1AP, "CU send DL_RRC_MESSAGE_TRANSFER \n");
+  F1AP_F1AP_PDU_t                 pdu;
   F1AP_DLRRCMessageTransfer_t    *out;
   F1AP_DLRRCMessageTransferIEs_t *ie;
 
@@ -252,10 +295,12 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t                instance,
   OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, (const char*)f1ap_dl_rrc->rrc_container, f1ap_dl_rrc->rrc_container_length);
   ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
-  //LOG_I(F1AP, "%s() RRCContainer size %d: ", __func__, f1ap_dl_rrc->rrc_container_length);
-  //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
-  //  printf("%02x ", f1ap_dl_rrc->rrc_container[i]);
-  //printf("\n");
+  if (RC.nrrrc && RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU) {
+    LOG_I(F1AP, "%s() RRCContainer size %d: ", __func__, f1ap_dl_rrc->rrc_container_length);
+    for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
+      printf("%02x ", f1ap_dl_rrc->rrc_container[i]);
+    printf("\n");
+  }
 
   /* optional */
   /* c7. RAT_FrequencyPriorityInformation */
@@ -279,7 +324,7 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t                instance,
  
   /* encode */
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
-    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    LOG_E(F1AP, "Failed to encode F1 DL RRC MESSAGE TRANSFER \n");
     return -1;
   }
 
@@ -302,7 +347,6 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t       instance,
   F1AP_ULRRCMessageTransfer_t    *container;
   F1AP_ULRRCMessageTransferIEs_t *ie;
 
-  
   uint64_t        cu_ue_f1ap_id;
   uint64_t        du_ue_f1ap_id;
   uint64_t        srb_id;
@@ -351,6 +395,7 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t       instance,
   // print message in debug mode 
 
   // create an ITTI message and copy SDU
+
   /*
   
   message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_DCCH_DATA_IND);
@@ -373,6 +418,8 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t       instance,
   ctxt.instance = instance;
   ctxt.rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], cu_ue_f1ap_id);
   ctxt.enb_flag = 1;
+  ctxt.eNB_index = 0;
+  ctxt.configured = 1;
   mem_block_t *mb = get_free_mem_block(ie->value.choice.RRCContainer.size,__func__);
   memcpy((void*)mb->data,(void*)ie->value.choice.RRCContainer.buf,ie->value.choice.RRCContainer.size);
   LOG_I(F1AP, "Calling pdcp_data_ind for UE RNTI %x srb_id %lu with size %ld (DCCH) \n", ctxt.rnti, srb_id, ie->value.choice.RRCContainer.size);
diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c
index d2f4c3a56b8295b01c3a2f528ee73d7df1a24d7d..b261d8e85b2bd63b0af30ee4605b8f01d7504279 100644
--- a/openair2/F1AP/f1ap_cu_task.c
+++ b/openair2/F1AP/f1ap_cu_task.c
@@ -39,6 +39,7 @@
 #include "proto_agent.h"
 
 extern RAN_CONTEXT_t RC;
+extern uint8_t proto_agent_flag;
 
 f1ap_setup_req_t *f1ap_du_data_from_du;
 f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB];
@@ -71,7 +72,12 @@ void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat
   f1ap_du_data_from_du->sctp_out_streams = sctp_new_association_resp->out_streams;
 
   /* setup parameters for F1U and start the server */
-  const cudu_params_t params = {
+  const cudu_params_t params = (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_CU) ? (cudu_params_t){
+    .local_ipv4_address  = RC.nrrrc[instance]->eth_params_s.my_addr,
+    .local_port          = RC.nrrrc[instance]->eth_params_s.my_portd,
+    .remote_ipv4_address = RC.nrrrc[instance]->eth_params_s.remote_addr,
+    .remote_port         = RC.nrrrc[instance]->eth_params_s.remote_portd
+  } : (cudu_params_t){
     .local_ipv4_address  = RC.rrc[instance]->eth_params_s.my_addr,
     .local_port          = RC.rrc[instance]->eth_params_s.my_portd,
     .remote_ipv4_address = RC.rrc[instance]->eth_params_s.remote_addr,
@@ -79,6 +85,7 @@ void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat
   };
   AssertFatal(proto_agent_start(instance, &params) == 0,
               "could not start PROTO_AGENT for F1U on instance %ld!\n", instance);
+  proto_agent_flag = 1;
 }
 
 void cu_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
@@ -107,7 +114,11 @@ void cu_task_send_sctp_init_req(instance_t enb_id) {
   message_p->ittiMsg.sctp_init.ipv4 = 1;
   message_p->ittiMsg.sctp_init.ipv6 = 0;
   message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
-  message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
+  if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_CU) {
+    message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.nrrrc[enb_id]->eth_params_s.my_addr);
+  } else{
+    message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
+  }
   /*
    * SR WARNING: ipv6 multi-homing fails sometimes for localhost.
    * * * * Disable it for now.
@@ -166,13 +177,27 @@ void *F1AP_CU_task(void *arg) {
                                                &F1AP_SETUP_RESP(received_msg));
         break;
 
-     case F1AP_DL_RRC_MESSAGE: // from rrc
+      case F1AP_GNB_CU_CONFIGURATION_UPDATE: // from rrc
+        LOG_I(F1AP, "CU Task Received F1AP_GNB_CU_CONFIGURAITON_UPDATE\n");
+        // CU_send_f1setup_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
+        //                                       &F1AP_SETUP_RESP(received_msg));
+        CU_send_gNB_CU_CONFIGURATION_UPDATE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
+					    &F1AP_GNB_CU_CONFIGURATION_UPDATE(received_msg));
+        break;
+
+      case F1AP_DL_RRC_MESSAGE: // from rrc
         LOG_I(F1AP, "CU Task Received F1AP_DL_RRC_MESSAGE\n");
         CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
                                                &F1AP_DL_RRC_MESSAGE(received_msg));
         break;
 
-     case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc
+      case F1AP_UE_CONTEXT_SETUP_REQ: // from rrc
+        LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_SETUP_REQ\n");
+        CU_send_UE_CONTEXT_SETUP_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
+                                               &F1AP_UE_CONTEXT_SETUP_REQ(received_msg));
+        break;
+
+      case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc
         LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_RELEASE_CMD\n");
         CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
                                            &F1AP_UE_CONTEXT_RELEASE_CMD(received_msg));
diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c
index 1857678ce9a7d7e60585fa13ffc76f388197a04b..317f0058b26323696f0462f6fa7c66832b181ce3 100644
--- a/openair2/F1AP/f1ap_cu_ue_context_management.c
+++ b/openair2/F1AP/f1ap_cu_ue_context_management.c
@@ -45,6 +45,7 @@
 extern f1ap_setup_req_t *f1ap_du_data_from_du;
 extern f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB];
 extern RAN_CONTEXT_t RC;
+extern uint32_t f1ap_assoc_id;
 
 int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
                                      f1ap_ue_context_setup_req_t *f1ap_ue_context_setup_req) {
@@ -263,7 +264,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
                        f1ap_ue_context_setup_req->mnc,
                        f1ap_ue_context_setup_req->mnc_digit_length,
                        &nRCGI.pLMN_Identity);
-     NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+     NR_CELL_ID_TO_BIT_STRING(12345678, &nRCGI.nRCellIdentity);
      scell_toBeSetup_item.sCell_ID = nRCGI;
 
      /* 10.1.2 sCellIndex */
@@ -475,7 +476,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
         /* OPTIONAL */
         /* gBR_QoS_Flow_Information */
         if (0) {
-          DRB_Information->dRB_QoS.gBR_QoS_Flow_Information = (F1AP_GBR_QoSFlowInformation_t *)calloc(1, sizeof(F1AP_GBR_QoSFlowInformation_t)); 
+          DRB_Information->dRB_QoS.gBR_QoS_Flow_Information = (F1AP_GBR_QoSFlowInformation_t *)calloc(1, sizeof(F1AP_GBR_QoSFlowInformation_t));
           asn_long2INTEGER(&DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxFlowBitRateDownlink, 1L);
           asn_long2INTEGER(&DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxFlowBitRateUplink, 1L);
           asn_long2INTEGER(&DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->guaranteedFlowBitRateDownlink, 1L);
@@ -484,14 +485,14 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
           /* OPTIONAL */
           /* maxPacketLossRateDownlink */
           if (0) {
-            DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t)); 
+            DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t));
             *DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = 1L;
           }
 
           /* OPTIONAL */
           /* maxPacketLossRateUplink */
           if (0) {
-            DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t)); 
+            DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t));
             *DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink = 1L;
           }
 
@@ -500,7 +501,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
         /* OPTIONAL */
         /* reflective_QoS_Attribute */
         if (0) {
-          DRB_Information->dRB_QoS.reflective_QoS_Attribute = (long *)calloc(1, sizeof(long)); 
+          DRB_Information->dRB_QoS.reflective_QoS_Attribute = (long *)calloc(1, sizeof(long));
           *DRB_Information->dRB_QoS.reflective_QoS_Attribute = 1L;
         }
 
@@ -581,8 +582,9 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
 
               /* packetErrorRate */
               flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->packetErrorRate.pER_Scalar = 1L;
-	      flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->packetErrorRate.pER_Exponent = 6L;
-              /* OPTIONAL */
+	            flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->packetErrorRate.pER_Exponent = 6L;
+
+	            /* OPTIONAL */
               /* delayCritical */
               if (0) {
                 flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->delayCritical = (long *)calloc(1, sizeof(long));
@@ -727,7 +729,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
     ie->criticality                    = F1AP_Criticality_reject;
     ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_RAT_FrequencyPriorityInformation;
 
-    int endc = 1; // RK: Get this from somewhere ... 
+    int endc = 1; // RK: Get this from somewhere ...
     if (endc) {
       ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_eNDC;
       ie->value.choice.RAT_FrequencyPriorityInformation.choice.eNDC = 11L;
@@ -740,13 +742,13 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
 
   /* OPTIONAL */
   /* RRCContainer */
-  if (0) {
+  if(RC.nrrrc) {
     ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
     ie->id                             = F1AP_ProtocolIE_ID_id_RRCContainer;
     ie->criticality                    = F1AP_Criticality_reject;
     ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_RRCContainer;
-    OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, "asdsa1d32sa1d31asd31as",
-                         strlen("asdsa1d32sa1d31asd31as"));
+    OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, (const char*)f1ap_ue_context_setup_req->rrc_container,
+                          f1ap_ue_context_setup_req->rrc_container_length);
     ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
   }
 
@@ -763,10 +765,28 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
 
   /* encode */
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
-    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    LOG_E(F1AP, "Failed to encode F1 UE CONTEXT SETUP REQUEST\n");
     return -1;
   }
 
+  // xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, (void *)pdu);
+
+  // asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
+  // res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
+  // buffer = res.buffer;
+  // len = res.result.encoded;
+
+  // if (res.result.encoded <= 0) {
+  //   LOG_E(F1AP, "ASN1 message encoding failed (%s, %lu)!\n", res.result.failed_type->name, res.result.encoded);
+  //   return -1;
+  // }
+
+  LOG_D(F1AP,"F1AP UEContextSetupRequest Encoded %u bits\n", len);
+
+  if(RC.nrrrc) {
+    cu_f1ap_itti_send_sctp_data_req(instance, f1ap_assoc_id /* BK: fix me*/ , buffer, len, 0 /* BK: fix me*/);
+  }
+
   return 0;
 }
 
@@ -774,7 +794,42 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t       instance,
                                         uint32_t         assoc_id,
                                         uint32_t         stream,
                                         F1AP_F1AP_PDU_t *pdu) {
-  AssertFatal(1==0,"Not implemented yet\n");
+  F1AP_UEContextSetupResponse_t    *container;
+  F1AP_UEContextSetupResponseIEs_t *ie;
+
+  DevAssert(pdu);
+
+  container = &pdu->choice.successfulOutcome->value.choice.UEContextSetupResponse;
+
+  /* GNB_CU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
+
+  /* GNB_DU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
+
+  /* DUtoCURRCInformation */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, true);
+
+  /* DRBs_Setup_List */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_DRBs_Setup_List, true);
+
+  /* SRBs_FailedToBeSetup_List */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetup_List, true);
+
+  /* DRBs_FailedToBeSetup_List */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetup_List, true);
+
+  /* SCell_FailedtoSetup_List */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_SCell_FailedtoSetup_List, true);
+
+  return 0;
 }
 
 int CU_handle_UE_CONTEXT_SETUP_FAILURE(instance_t       instance,
@@ -1030,8 +1085,8 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
 
   // for test
   int mcc = 208;
-  int mnc = 93;
-  int mnc_digit_length = 8;
+  int mnc = 92;
+  int mnc_digit_length = 2;
 
   /* Create */
   /* 0. Message Type */
@@ -1072,7 +1127,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
     F1AP_NRCGI_t nRCGI;
     MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
                                          &nRCGI.pLMN_Identity);
-    NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+    NR_CELL_ID_TO_BIT_STRING(12345678, &nRCGI.nRCellIdentity);
     ie->value.choice.NRCGI = nRCGI;
 
     ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
@@ -1197,7 +1252,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
      memset(&nRCGI, 0, sizeof(F1AP_NRCGI_t));
      MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
                                         &nRCGI.pLMN_Identity);
-     NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+     NR_CELL_ID_TO_BIT_STRING(12345678, &nRCGI.nRCellIdentity);
      scell_toBeSetupMod_item.sCell_ID = nRCGI;
 
      /* sCellIndex */
@@ -1237,7 +1292,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
      memset(&nRCGI, 0, sizeof(F1AP_NRCGI_t));
      MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
                                         &nRCGI.pLMN_Identity);
-     NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+     NR_CELL_ID_TO_BIT_STRING(12345678, &nRCGI.nRCellIdentity);
      scell_toBeRemoved_item.sCell_ID = nRCGI;
 
      /* ADD */
@@ -1484,7 +1539,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
 
   /* encode */
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
-    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    LOG_E(F1AP, "Failed to encode F1 UE CONTEXT_MODIFICATION REQUEST\n");
     return -1;
   }
 
diff --git a/openair2/F1AP/f1ap_decoder.c b/openair2/F1AP/f1ap_decoder.c
index 7bd5359e29fa0665f387134c28a6a1be8c5dd837..ac55db7fda7f9f16603d850d74004098f67b4f3a 100644
--- a/openair2/F1AP/f1ap_decoder.c
+++ b/openair2/F1AP/f1ap_decoder.c
@@ -49,6 +49,11 @@ static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu)
       LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_F1Setup\n", __func__);
       break;
 
+    case F1AP_ProcedureCode_id_gNBCUConfigurationUpdate:
+      //res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
+      LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_gNBCUConfigurationUpdate\n", __func__);
+      break;
+
     case F1AP_ProcedureCode_id_InitialULRRCMessageTransfer:
       //res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
       LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_InitialULRRCMessageTransfer\n", __func__);
@@ -69,6 +74,9 @@ static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu)
     case F1AP_ProcedureCode_id_UEContextReleaseRequest:
       LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextReleaseRequest\n", __func__);
       break;
+    case F1AP_ProcedureCode_id_UEContextSetup:
+      LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextSetup\n", __func__);
+      break;
     // case F1AP_ProcedureCode_id_InitialContextSetup:
     //   res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
     //   message_id = F1AP_INITIAL_CONTEXT_SETUP_LOG;
@@ -102,6 +110,10 @@ static int f1ap_decode_successful_outcome(F1AP_F1AP_PDU_t *pdu)
       LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_F1Setup\n", __func__);
       break;
 
+    case F1AP_ProcedureCode_id_gNBCUConfigurationUpdate:
+      LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_gNBCUConfigurationUpdate\n", __func__);
+      break;
+
     case F1AP_ProcedureCode_id_UEContextRelease:
       LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextRelease\n", __func__);
       break;
@@ -157,7 +169,7 @@ int f1ap_decode_pdu(F1AP_F1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t
   //LOG_I(F1AP, "f1ap_decode_pdu.dec_ret.code = %d\n", dec_ret.code);
 
   if (dec_ret.code != RC_OK) {
-    LOG_E(F1AP, "Failed to decode pdu\n");
+    AssertFatal(1==0,"Failed to decode pdu\n");
     return -1;
   }
 
diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c
index 0b71ce38b7eeed765beb79ed2721019aff1cda9b..b6ece9b13ff9c207d7e8ac0e61c464dd839e44e5 100644
--- a/openair2/F1AP/f1ap_du_interface_management.c
+++ b/openair2/F1AP/f1ap_du_interface_management.c
@@ -38,7 +38,18 @@
 #include "assertions.h"
 
 extern f1ap_setup_req_t *f1ap_du_data;
+extern RAN_CONTEXT_t RC;
 
+int nrb_lut[29] = {11, 18, 24, 25, 31, 32, 38, 51, 52, 65, 66, 78, 79, 93, 106, 107, 121, 132, 133, 135, 160, 162, 189, 216, 217, 245, 264, 270, 273};
+
+int to_NRNRB(int nrb) {
+  if (RC.nrrrc) {
+    for (int i=0;i<29;i++) if (nrb_lut[i] == nrb) return i;
+    AssertFatal(1==0,"nrb %d is not in the list of possible NRNRB\n",nrb);
+  } else {
+    return nrb;
+  }
+}
 
 int DU_handle_RESET(instance_t instance,
                                 uint32_t assoc_id,
@@ -188,9 +199,19 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
         served_cell_information.nRPCI = f1ap_du_data->nr_pci[i];  // int 0..1007
 
         /* - fiveGS_TAC */
-        OCTET_STRING_fromBuf(served_cell_information.fiveGS_TAC,
-                             (const char*)&f1ap_du_data->tac[i],
-                             3);
+        if (RC.nrrrc) {
+          uint8_t fiveGS_TAC[3];
+          fiveGS_TAC[0] = ((uint8_t*)&f1ap_du_data->tac[i])[2];
+          fiveGS_TAC[1] = ((uint8_t*)&f1ap_du_data->tac[i])[1];
+          fiveGS_TAC[2] = ((uint8_t*)&f1ap_du_data->tac[i])[0];
+          OCTET_STRING_fromBuf(served_cell_information.fiveGS_TAC,
+                               (const char *)fiveGS_TAC,
+                               3);
+        } else {
+          OCTET_STRING_fromBuf(served_cell_information.fiveGS_TAC,
+                               (const char*)&f1ap_du_data->tac[i],
+                               3);
+        }
 
         /* - Configured_EPS_TAC */
         if(0){
@@ -299,10 +320,10 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
 
           /* FDD.3 UL Transmission Bandwidth */
           fDD_Info->uL_Transmission_Bandwidth.nRSCS = f1ap_du_data->nr_mode_info[i].fdd.ul_scs;
-          fDD_Info->uL_Transmission_Bandwidth.nRNRB = f1ap_du_data->nr_mode_info[i].fdd.ul_nrb;
+          fDD_Info->uL_Transmission_Bandwidth.nRNRB = to_NRNRB(f1ap_du_data->nr_mode_info[i].fdd.ul_nrb);
           /* FDD.4 DL Transmission Bandwidth */
           fDD_Info->dL_Transmission_Bandwidth.nRSCS = f1ap_du_data->nr_mode_info[i].fdd.dl_scs;
-          fDD_Info->dL_Transmission_Bandwidth.nRNRB = f1ap_du_data->nr_mode_info[i].fdd.dl_nrb;
+          fDD_Info->dL_Transmission_Bandwidth.nRNRB = to_NRNRB(f1ap_du_data->nr_mode_info[i].fdd.dl_nrb);
           
           nR_Mode_Info.choice.fDD = fDD_Info;
         } else { // TDD
@@ -354,7 +375,7 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
 
           /* TDD.2 transmission_Bandwidth */
           tDD_Info->transmission_Bandwidth.nRSCS = f1ap_du_data->nr_mode_info[i].tdd.scs;
-          tDD_Info->transmission_Bandwidth.nRNRB = f1ap_du_data->nr_mode_info[i].tdd.nrb;
+          tDD_Info->transmission_Bandwidth.nRNRB = to_NRNRB(f1ap_du_data->nr_mode_info[i].tdd.nrb);
      
           nR_Mode_Info.choice.tDD = tDD_Info;
         } // if nR_Mode_Info
@@ -376,6 +397,7 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
                              (const char*)f1ap_du_data->mib[i],//f1ap_du_data->mib,
                              f1ap_du_data->mib_length[i]);
 
+        LOG_D(F1AP,"Filling SIB1_message for cell %d, length %d\n",i,f1ap_du_data->sib1_length[i]);
         OCTET_STRING_fromBuf(&gNB_DU_System_Information->sIB1_message,  // sept. 2018
                              (const char*)f1ap_du_data->sib1[i],
                              f1ap_du_data->sib1_length[i]);
@@ -391,6 +413,20 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
   }
   ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
+  /* mandatory */
+  /* c5. RRC VERSION */
+  if(RC.nrrrc) {
+    ie = (F1AP_F1SetupRequestIEs_t *) calloc(1, sizeof(F1AP_F1SetupRequestIEs_t));
+    ie->id = F1AP_ProtocolIE_ID_id_GNB_DU_RRC_Version;
+    ie->criticality = F1AP_Criticality_reject;
+    ie->value.present = F1AP_F1SetupRequestIEs__value_PR_RRC_Version;
+    ie->value.choice.RRC_Version.latest_RRC_Version.buf = calloc(1, sizeof(char));
+    ie->value.choice.RRC_Version.latest_RRC_Version.buf[0] = 0xe0;
+    ie->value.choice.RRC_Version.latest_RRC_Version.size = 1;
+    ie->value.choice.RRC_Version.latest_RRC_Version.bits_unused = 5;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
   /* encode */
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
     LOG_E(F1AP, "Failed to encode F1 setup request\n");
@@ -417,158 +453,175 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance,
 				F1AP_F1AP_PDU_t       *pdu)
 {
 
-   LOG_D(F1AP, "DU_handle_F1_SETUP_RESPONSE\n");
-
-   AssertFatal(pdu->present == F1AP_F1AP_PDU_PR_successfulOutcome,
-	       "pdu->present != F1AP_F1AP_PDU_PR_successfulOutcome\n");
-   AssertFatal(pdu->choice.successfulOutcome->procedureCode  == F1AP_ProcedureCode_id_F1Setup,
-	       "pdu->choice.successfulOutcome->procedureCode != F1AP_ProcedureCode_id_F1Setup\n");
-   AssertFatal(pdu->choice.successfulOutcome->criticality  == F1AP_Criticality_reject,
-	       "pdu->choice.successfulOutcome->criticality != F1AP_Criticality_reject\n");
-   AssertFatal(pdu->choice.successfulOutcome->value.present  == F1AP_SuccessfulOutcome__value_PR_F1SetupResponse,
-	       "pdu->choice.successfulOutcome->value.present != F1AP_SuccessfulOutcome__value_PR_F1SetupResponse\n");
-
-   F1AP_F1SetupResponse_t    *in = &pdu->choice.successfulOutcome->value.choice.F1SetupResponse;
-
-
-   F1AP_F1SetupResponseIEs_t *ie;
-   int TransactionId = -1;
-   int num_cells_to_activate = 0;
-   F1AP_Cells_to_be_Activated_List_Item_t *cell;
-
-   MessageDef *msg_p = itti_alloc_new_message (TASK_DU_F1, 0, F1AP_SETUP_RESP);
-
-   LOG_D(F1AP, "F1AP: F1Setup-Resp: protocolIEs.list.count %d\n",
-         in->protocolIEs.list.count);
-   for (int i=0;i < in->protocolIEs.list.count; i++) {
-     ie = in->protocolIEs.list.array[i];
-     switch (ie->id) {
-     case F1AP_ProtocolIE_ID_id_TransactionID:
-       AssertFatal(ie->criticality == F1AP_Criticality_reject,
-		   "ie->criticality != F1AP_Criticality_reject\n");
-       AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_TransactionID,
-		   "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_TransactionID\n");
-       TransactionId=ie->value.choice.TransactionID;
-       LOG_D(F1AP, "F1AP: F1Setup-Resp: TransactionId %d\n",
-             TransactionId);
-       break;
-     case F1AP_ProtocolIE_ID_id_gNB_CU_Name:
-       AssertFatal(ie->criticality == F1AP_Criticality_ignore,
-		   "ie->criticality != F1AP_Criticality_ignore\n");
-       AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name,
-		   "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_TransactionID\n");
-       F1AP_SETUP_RESP (msg_p).gNB_CU_name = malloc(ie->value.choice.GNB_CU_Name.size+1);
-       memcpy(F1AP_SETUP_RESP (msg_p).gNB_CU_name,ie->value.choice.GNB_CU_Name.buf,ie->value.choice.GNB_CU_Name.size);
-       F1AP_SETUP_RESP (msg_p).gNB_CU_name[ie->value.choice.GNB_CU_Name.size]='\0';
-       LOG_D(F1AP, "F1AP: F1Setup-Resp: gNB_CU_name %s\n",
-             F1AP_SETUP_RESP (msg_p).gNB_CU_name);
-       break;
-     case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List:
-       AssertFatal(ie->criticality == F1AP_Criticality_reject,
-		   "ie->criticality != F1AP_Criticality_reject\n");
-       AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List,
-		   "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List\n");
-       num_cells_to_activate = ie->value.choice.Cells_to_be_Activated_List.list.count;
-       LOG_D(F1AP, "F1AP: Activating %d cells\n",num_cells_to_activate);
-       for (int i=0;i<num_cells_to_activate;i++) {
-	 
-	 F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *) ie->value.choice.Cells_to_be_Activated_List.list.array[i];
-
-	 AssertFatal(cells_to_be_activated_list_item_ies->id == F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item,
-		   "cells_to_be_activated_list_item_ies->id != F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item");
-	 AssertFatal(cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject,
-		     "cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject");
-	 AssertFatal(cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item,
-		     "cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item");
-
-	 cell = &cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item;
-
-	 TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity, F1AP_SETUP_RESP (msg_p).mcc[i], F1AP_SETUP_RESP (msg_p).mnc[i], F1AP_SETUP_RESP (msg_p).mnc_digit_length[i]);
-	 AssertFatal(cell->nRPCI != NULL, "nRPCI is null\n");
-	 LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n",
-         cell->nRCGI.nRCellIdentity.buf[0],
-         cell->nRCGI.nRCellIdentity.buf[1],
-         cell->nRCGI.nRCellIdentity.buf[2],
-         cell->nRCGI.nRCellIdentity.buf[3],
-         cell->nRCGI.nRCellIdentity.buf[4]);
-	 BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity,
-					F1AP_SETUP_RESP (msg_p).nr_cellid[i]);
-	 F1AP_SETUP_RESP (msg_p).nrpci[i] = *cell->nRPCI;
-
-	 F1AP_ProtocolExtensionContainer_154P112_t *ext = (F1AP_ProtocolExtensionContainer_154P112_t *)cell->iE_Extensions;
-	 AssertFatal(ext!=NULL,"Extension is null\n");
-         for (int cnt=0;cnt<ext->list.count;cnt++) {
+  LOG_D(F1AP, "DU_handle_F1_SETUP_RESPONSE\n");
+
+  AssertFatal(pdu->present == F1AP_F1AP_PDU_PR_successfulOutcome,
+        "pdu->present != F1AP_F1AP_PDU_PR_successfulOutcome\n");
+  AssertFatal(pdu->choice.successfulOutcome->procedureCode  == F1AP_ProcedureCode_id_F1Setup,
+        "pdu->choice.successfulOutcome->procedureCode != F1AP_ProcedureCode_id_F1Setup\n");
+  AssertFatal(pdu->choice.successfulOutcome->criticality  == F1AP_Criticality_reject,
+        "pdu->choice.successfulOutcome->criticality != F1AP_Criticality_reject\n");
+  AssertFatal(pdu->choice.successfulOutcome->value.present  == F1AP_SuccessfulOutcome__value_PR_F1SetupResponse,
+        "pdu->choice.successfulOutcome->value.present != F1AP_SuccessfulOutcome__value_PR_F1SetupResponse\n");
+
+  F1AP_F1SetupResponse_t    *in = &pdu->choice.successfulOutcome->value.choice.F1SetupResponse;
+
+
+  F1AP_F1SetupResponseIEs_t *ie;
+  int TransactionId = -1;
+  int num_cells_to_activate = 0;
+  F1AP_Cells_to_be_Activated_List_Item_t *cell;
+
+  MessageDef *msg_p = itti_alloc_new_message (TASK_DU_F1, 0, F1AP_SETUP_RESP);
+
+  LOG_D(F1AP, "F1AP: F1Setup-Resp: protocolIEs.list.count %d\n",
+        in->protocolIEs.list.count);
+  for (int i=0;i < in->protocolIEs.list.count; i++) {
+    ie = in->protocolIEs.list.array[i];
+    switch (ie->id) {
+      case F1AP_ProtocolIE_ID_id_TransactionID:
+        AssertFatal(ie->criticality == F1AP_Criticality_reject,
+        "ie->criticality != F1AP_Criticality_reject\n");
+        AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_TransactionID,
+        "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_TransactionID\n");
+        TransactionId=ie->value.choice.TransactionID;
+        LOG_D(F1AP, "F1AP: F1Setup-Resp: TransactionId %d\n",
+              TransactionId);
+        break;
+      case F1AP_ProtocolIE_ID_id_gNB_CU_Name:
+        AssertFatal(ie->criticality == F1AP_Criticality_ignore,
+        "ie->criticality != F1AP_Criticality_ignore\n");
+        AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name,
+        "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_TransactionID\n");
+        F1AP_SETUP_RESP (msg_p).gNB_CU_name = malloc(ie->value.choice.GNB_CU_Name.size+1);
+        memcpy(F1AP_SETUP_RESP (msg_p).gNB_CU_name,ie->value.choice.GNB_CU_Name.buf,ie->value.choice.GNB_CU_Name.size);
+        F1AP_SETUP_RESP (msg_p).gNB_CU_name[ie->value.choice.GNB_CU_Name.size]='\0';
+        LOG_D(F1AP, "F1AP: F1Setup-Resp: gNB_CU_name %s\n",
+              F1AP_SETUP_RESP (msg_p).gNB_CU_name);
+        break;
+      case F1AP_ProtocolIE_ID_id_GNB_CU_RRC_Version:
+        LOG_D(F1AP, "F1AP: Received GNB-CU-RRC-Version, ignoring\n");
+        break;
+      case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List:
+      {
+        AssertFatal(ie->criticality == F1AP_Criticality_reject,
+          "ie->criticality != F1AP_Criticality_reject\n");
+        AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List,
+          "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List\n");
+        num_cells_to_activate = ie->value.choice.Cells_to_be_Activated_List.list.count;
+        LOG_D(F1AP, "F1AP: Activating %d cells\n",num_cells_to_activate);
+        for (int i=0;i<num_cells_to_activate;i++) {
+
+          F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *) ie->value.choice.Cells_to_be_Activated_List.list.array[i];
+
+          AssertFatal(cells_to_be_activated_list_item_ies->id == F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item,
+              "cells_to_be_activated_list_item_ies->id != F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item");
+          AssertFatal(cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject,
+                "cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject");
+          AssertFatal(cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item,
+                "cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item");
+
+          cell = &cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item;
+
+          TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity, F1AP_SETUP_RESP (msg_p).cells_to_activate[i].mcc, F1AP_SETUP_RESP (msg_p).cells_to_activate[i].mnc, F1AP_SETUP_RESP (msg_p).cells_to_activate[i].mnc_digit_length);
+
+          LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n",
+                cell->nRCGI.nRCellIdentity.buf[0],
+                cell->nRCGI.nRCellIdentity.buf[1],
+                cell->nRCGI.nRCellIdentity.buf[2],
+                cell->nRCGI.nRCellIdentity.buf[3],
+                cell->nRCGI.nRCellIdentity.buf[4]);
+
+          BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity,
+          F1AP_SETUP_RESP (msg_p).cells_to_activate[i].nr_cellid);
+          F1AP_ProtocolExtensionContainer_154P112_t *ext = (F1AP_ProtocolExtensionContainer_154P112_t *)cell->iE_Extensions;
+
+          if (ext==NULL) continue;
+
+          for (int cnt=0;cnt<ext->list.count;cnt++) {
             F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs=(F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *)ext->list.array[cnt];
             switch (cells_to_be_activated_list_itemExtIEs->id) {
-/*
-               case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_NOTHING:
-               case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation,
-               case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailablePLMNList,
-               case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_ExtendedAvailablePLMN_List,
-               case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_IAB_Info_IAB_donor_CU,
-               case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailableSNPN_ID_List
-*/
-	       case F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation:
-                  {
-                    F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = (F1AP_GNB_CUSystemInformation_t*)&cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation;
-                    F1AP_SETUP_RESP (msg_p).num_SI[i] = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count;
-                    AssertFatal(ext->list.count==1,"At least one SI message should be there, and only 1 for now!\n");
-                    LOG_D(F1AP, "F1AP: F1Setup-Resp Cell %d MCC %d MNC %d NRCellid %lx num_si %d\n",
-                          i, F1AP_SETUP_RESP (msg_p).mcc[i], F1AP_SETUP_RESP (msg_p).mnc[i],
-                          F1AP_SETUP_RESP (msg_p).nr_cellid[i], F1AP_SETUP_RESP (msg_p).num_SI[i]);
-                    for (int si =0;si < gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count;si++) {
-                        F1AP_SibtypetobeupdatedListItem_t *sib_item = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.array[si];
-                        size_t size = sib_item->sIBmessage.size;
-                        F1AP_SETUP_RESP (msg_p).SI_container_length[i][sib_item->sIBtype] = size;
-                        LOG_I(F1AP, "F1AP: F1Setup-Resp SI_container_length[%d][%d] %ld bytes\n", i, (int)sib_item->sIBtype, size);
-                        F1AP_SETUP_RESP (msg_p).SI_container[i][sib_item->sIBtype] = malloc(size);
-                        memcpy((void*)F1AP_SETUP_RESP (msg_p).SI_container[i][sib_item->sIBtype],
-                               (void*)sib_item->sIBmessage.buf,
-                               size);
-                    }
-                 }
-                 break;
-               case F1AP_ProtocolIE_ID_id_AvailablePLMNList:
-                 AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
-                 break;
-	       case F1AP_ProtocolIE_ID_id_ExtendedAvailablePLMN_List:
-                 AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
-                 break;
-               case F1AP_ProtocolIE_ID_id_IAB_Info_IAB_donor_CU:
-                 AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
-                 break;
-               case F1AP_ProtocolIE_ID_id_AvailableSNPN_ID_List:
-                 AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
-                 break;
-	       default:
-                 AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n",(int)cells_to_be_activated_list_itemExtIEs->id);
-                 break;
+  /*
+                case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_NOTHING:
+                case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation,
+                case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailablePLMNList,
+                case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_ExtendedAvailablePLMN_List,
+                case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_IAB_Info_IAB_donor_CU,
+                case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailableSNPN_ID_List
+  */
+              case F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation:
+              {
+                F1AP_SETUP_RESP (msg_p).cells_to_activate[i].nrpci = (cell->nRPCI != NULL) ? *cell->nRPCI : 0;
+                F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = (F1AP_GNB_CUSystemInformation_t*)&cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation;
+                F1AP_SETUP_RESP (msg_p).cells_to_activate[i].num_SI = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count;
+                AssertFatal(ext->list.count==1,"At least one SI message should be there, and only 1 for now!\n");
+                LOG_D(F1AP, "F1AP: Cell %d MCC %d MNC %d NRCellid %lx num_si %d\n",
+                      i, F1AP_SETUP_RESP (msg_p).cells_to_activate[i].mcc, F1AP_SETUP_RESP (msg_p).cells_to_activate[i].mnc,
+                      F1AP_SETUP_RESP (msg_p).cells_to_activate[i].nr_cellid, F1AP_SETUP_RESP (msg_p).cells_to_activate[i].num_SI);
+                for (int si = 0;si < gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count;si++) {
+                  F1AP_SibtypetobeupdatedListItem_t *sib_item = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.array[si];
+                  size_t size = sib_item->sIBmessage.size;
+                  F1AP_SETUP_RESP (msg_p).cells_to_activate[i].SI_container_length[sib_item->sIBtype] = size;
+                  LOG_I(F1AP, "F1AP: SI_container_length[%d][%d] %ld bytes\n", i, (int)sib_item->sIBtype, size);
+                  F1AP_SETUP_RESP (msg_p).cells_to_activate[i].SI_container[sib_item->sIBtype] = malloc(size);
+                  memcpy((void*)F1AP_SETUP_RESP (msg_p).cells_to_activate[i].SI_container[sib_item->sIBtype],
+                          (void*)sib_item->sIBmessage.buf,
+                          size);
+                }
+                break;
+              }
+              case F1AP_ProtocolIE_ID_id_AvailablePLMNList:
+                AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
+                break;
+              case F1AP_ProtocolIE_ID_id_ExtendedAvailablePLMN_List:
+                AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
+                break;
+              case F1AP_ProtocolIE_ID_id_IAB_Info_IAB_donor_CU:
+                AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
+                break;
+              case F1AP_ProtocolIE_ID_id_AvailableSNPN_ID_List:
+                AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
+                break;
+              default:
+                AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n",(int)cells_to_be_activated_list_itemExtIEs->id);
+                break;
             }
-         } // for (cnt=...
-       } // for (cells_to_activate...
-     } // switch ie
-   } // for IE
-   AssertFatal(TransactionId!=-1,"TransactionId was not sent\n");
-   AssertFatal(num_cells_to_activate>0,"No cells activated\n");
-   F1AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate;
-
-   for (int i=0;i<num_cells_to_activate;i++)  
-     AssertFatal(F1AP_SETUP_RESP (msg_p).num_SI[i] > 0, "System Information %d is missing",i);
-
-   MSC_LOG_RX_MESSAGE(
-    MSC_F1AP_DU,
-    MSC_F1AP_CU,
-    0,
-    0,
-    MSC_AS_TIME_FMT" DU_handle_F1_SETUP_RESPONSE successfulOutcome assoc_id %d",
-    0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
-    assoc_id);
- 
-   LOG_D(F1AP, "Sending F1AP_SETUP_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n",
+          } // for (cnt=...
+        } // for (cells_to_activate...
+        break;
+      } // case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List
+
+      default:
+        AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n", (int)ie->id);
+        break;
+    } // switch ie
+  } // for IE
+  AssertFatal(TransactionId!=-1,"TransactionId was not sent\n");
+  F1AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate;
+
+  for (int i=0;i<num_cells_to_activate;i++)
+    AssertFatal(F1AP_SETUP_RESP (msg_p).cells_to_activate[i].num_SI > 0, "System Information %d is missing",i);
+
+  MSC_LOG_RX_MESSAGE(
+  MSC_F1AP_DU,
+  MSC_F1AP_CU,
+  0,
+  0,
+  MSC_AS_TIME_FMT" DU_handle_F1_SETUP_RESPONSE successfulOutcome assoc_id %d",
+  0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+  assoc_id);
+
+  if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) {
+    LOG_D(F1AP, "Sending F1AP_SETUP_RESP ITTI message to GNB_APP with assoc_id (%d->%d)\n",
          assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id));
-   itti_send_msg_to_task(TASK_ENB_APP, instance, msg_p);
+    itti_send_msg_to_task(TASK_GNB_APP, GNB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p);
+  } else {
+    LOG_D(F1AP, "Sending F1AP_SETUP_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n",
+         assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id));
+    itti_send_msg_to_task(TASK_ENB_APP, instance, msg_p);
+  }
 
-   return 0;
+  return 0;
 }
 
 // SETUP FAILURE
@@ -577,6 +630,26 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance,
                                uint32_t stream,
                                F1AP_F1AP_PDU_t *pdu) {
   LOG_E(F1AP, "DU_handle_F1_SETUP_FAILURE\n");
+
+  F1AP_F1SetupFailure_t    *out;
+  F1AP_F1SetupFailureIEs_t *ie;
+
+  out = &pdu->choice.unsuccessfulOutcome->value.choice.F1SetupFailure;
+
+  /* Transaction ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupFailureIEs_t, ie, out,
+                              F1AP_ProtocolIE_ID_id_TransactionID, true);
+
+  /* Cause */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupFailureIEs_t, ie, out,
+                              F1AP_ProtocolIE_ID_id_Cause, true);
+
+  if(0) {
+    /* TimeToWait */
+    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupFailureIEs_t, ie, out,
+                              F1AP_ProtocolIE_ID_id_TimeToWait, true);
+  }
+
   return 0;
 }
 
@@ -659,9 +732,19 @@ int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
         served_cell_information.nRPCI = f1ap_setup_req->nr_pci[i];  // int 0..1007
 
         /* - fiveGS_TAC */
-        OCTET_STRING_fromBuf(served_cell_information.fiveGS_TAC,
-                             (const char *) &f1ap_setup_req->tac[i],
-                             3);
+        if (RC.nrrrc) {
+          uint8_t fiveGS_TAC[3];
+          fiveGS_TAC[0] = ((uint8_t*)&f1ap_setup_req->tac[i])[2];
+          fiveGS_TAC[1] = ((uint8_t*)&f1ap_setup_req->tac[i])[1];
+          fiveGS_TAC[2] = ((uint8_t*)&f1ap_setup_req->tac[i])[0];
+          OCTET_STRING_fromBuf(served_cell_information.fiveGS_TAC,
+                               (const char *)fiveGS_TAC,
+                               3);
+        } else {
+          OCTET_STRING_fromBuf(served_cell_information.fiveGS_TAC,
+                               (const char *) &f1ap_setup_req->tac[i],
+                               3);
+        }
 
         /* - Configured_EPS_TAC */
         if(1){
@@ -676,7 +759,6 @@ int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
         MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i], &servedPLMN_item->pLMN_Identity);
         ASN_SEQUENCE_ADD(&served_cell_information.servedPLMNs.list, servedPLMN_item);
 
-
         // // /* - CHOICE NR-MODE-Info */
         F1AP_NR_Mode_Info_t nR_Mode_Info;
 
@@ -838,8 +920,6 @@ int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
         MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i], &servedPLMN_item->pLMN_Identity);
         ASN_SEQUENCE_ADD(&served_cell_information.servedPLMNs.list, servedPLMN_item);
 
-
-
         // // /* - CHOICE NR-MODE-Info */
         F1AP_NR_Mode_Info_t nR_Mode_Info;
 
@@ -978,7 +1058,7 @@ int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
 
 
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
-    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    LOG_E(F1AP, "Failed to encode F1 gNB-DU CONFIGURATION UPDATE\n");
     return -1;
   }
 
@@ -1006,17 +1086,229 @@ int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance,
                                 uint32_t assoc_id,
                                 uint32_t stream,
                                 F1AP_F1AP_PDU_t *pdu) {
-  AssertFatal(1==0,"Not implemented yet\n");
+
+  if(!RC.nrrrc) {
+    return 0;
+  }
+
+  LOG_D(F1AP, "DU_handle_gNB_CU_CONFIGURATION_UPDATE\n");
+
+  AssertFatal(pdu->present == F1AP_F1AP_PDU_PR_initiatingMessage,
+        "pdu->present != F1AP_F1AP_PDU_PR_initiatingMessage\n");
+  AssertFatal(pdu->choice.initiatingMessage->procedureCode  == F1AP_ProcedureCode_id_gNBCUConfigurationUpdate,
+        "pdu->choice.initiatingMessage->procedureCode != F1AP_ProcedureCode_id_gNBCUConfigurationUpdate\n");
+  AssertFatal(pdu->choice.initiatingMessage->criticality  == F1AP_Criticality_reject,
+        "pdu->choice.initiatingMessage->criticality != F1AP_Criticality_reject\n");
+  AssertFatal(pdu->choice.initiatingMessage->value.present  == F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate,
+        "pdu->choice.initiatingMessage->value.present != F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate\n");
+
+  F1AP_GNBCUConfigurationUpdate_t *in = &pdu->choice.initiatingMessage->value.choice.GNBCUConfigurationUpdate;
+
+
+  F1AP_GNBCUConfigurationUpdateIEs_t *ie;
+  int TransactionId = -1;
+  int num_cells_to_activate = 0;
+  F1AP_Cells_to_be_Activated_List_Item_t *cell;
+
+  MessageDef *msg_p = itti_alloc_new_message (TASK_DU_F1, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE);
+
+  LOG_D(F1AP, "F1AP: gNB_CU_Configuration_Update: protocolIEs.list.count %d\n",
+        in->protocolIEs.list.count);
+  for (int i=0;i < in->protocolIEs.list.count; i++) {
+    ie = in->protocolIEs.list.array[i];
+    switch (ie->id) {
+      case F1AP_ProtocolIE_ID_id_TransactionID:
+        AssertFatal(ie->criticality == F1AP_Criticality_reject,
+        "ie->criticality != F1AP_Criticality_reject\n");
+        AssertFatal(ie->value.present == F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID,
+        "ie->value.present != F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID\n");
+        TransactionId=ie->value.choice.TransactionID;
+        LOG_D(F1AP, "F1AP: GNB-CU-ConfigurationUpdate: TransactionId %d\n",
+              TransactionId);
+        break;
+      case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List:
+      {
+        AssertFatal(ie->criticality == F1AP_Criticality_reject,
+          "ie->criticality != F1AP_Criticality_reject\n");
+        AssertFatal(ie->value.present == F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List,
+          "ie->value.present != F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List\n");
+        num_cells_to_activate = ie->value.choice.Cells_to_be_Activated_List.list.count;
+        LOG_D(F1AP, "F1AP: Activating %d cells\n",num_cells_to_activate);
+        for (int i=0;i<num_cells_to_activate;i++) {
+
+          F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *) ie->value.choice.Cells_to_be_Activated_List.list.array[i];
+
+          AssertFatal(cells_to_be_activated_list_item_ies->id == F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item,
+              "cells_to_be_activated_list_item_ies->id != F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item");
+          AssertFatal(cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject,
+                "cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject");
+          AssertFatal(cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item,
+                "cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item");
+
+          cell = &cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item;
+
+          TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity, F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].mcc, F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].mnc, F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].mnc_digit_length);
+
+          LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n",
+                cell->nRCGI.nRCellIdentity.buf[0],
+                cell->nRCGI.nRCellIdentity.buf[1],
+                cell->nRCGI.nRCellIdentity.buf[2],
+                cell->nRCGI.nRCellIdentity.buf[3],
+                cell->nRCGI.nRCellIdentity.buf[4]);
+          BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity,
+					 F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].nr_cellid);
+	  F1AP_ProtocolExtensionContainer_154P112_t *ext = (F1AP_ProtocolExtensionContainer_154P112_t *)cell->iE_Extensions;
+
+	  if (ext==NULL) continue;
+
+          for (int cnt=0;cnt<ext->list.count;cnt++) {
+            F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs=(F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *)ext->list.array[cnt];
+            switch (cells_to_be_activated_list_itemExtIEs->id) {
+  /*
+                case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_NOTHING:
+                case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation,
+                case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailablePLMNList,
+                case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_ExtendedAvailablePLMN_List,
+                case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_IAB_Info_IAB_donor_CU,
+                case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailableSNPN_ID_List
+  */
+              case F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation:
+              {
+                F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].nrpci = (cell->nRPCI != NULL) ? *cell->nRPCI : 0;
+                F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = (F1AP_GNB_CUSystemInformation_t*)&cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation;
+                F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].num_SI = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count;
+                AssertFatal(ext->list.count==1,"At least one SI message should be there, and only 1 for now!\n");
+                LOG_D(F1AP, "F1AP: Cell %d MCC %d MNC %d NRCellid %lx num_si %d\n",
+                      i, F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].mcc, F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].mnc,
+                      F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].nr_cellid, F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].num_SI);
+                for (int si = 0;si < gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count;si++) {
+                  F1AP_SibtypetobeupdatedListItem_t *sib_item = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.array[si];
+                  size_t size = sib_item->sIBmessage.size;
+                  F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_container_length[sib_item->sIBtype] = size;
+                  LOG_I(F1AP, "F1AP: SI_container_length[%d][%d] %ld bytes\n", i, (int)sib_item->sIBtype, size);
+                  F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_container[sib_item->sIBtype] = malloc(size);
+                  memcpy((void*)F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_container[sib_item->sIBtype],
+                          (void*)sib_item->sIBmessage.buf,
+                          size);
+                }
+                break;
+              }
+              case F1AP_ProtocolIE_ID_id_AvailablePLMNList:
+                AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
+                break;
+              case F1AP_ProtocolIE_ID_id_ExtendedAvailablePLMN_List:
+                AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
+                break;
+              case F1AP_ProtocolIE_ID_id_IAB_Info_IAB_donor_CU:
+                AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
+                break;
+              case F1AP_ProtocolIE_ID_id_AvailableSNPN_ID_List:
+                AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
+                break;
+              default:
+                AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n",(int)cells_to_be_activated_list_itemExtIEs->id);
+                break;
+            }
+          } // for (cnt=...
+        } // for (cells_to_activate...
+        break;
+      } // case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List
+
+      default:
+        AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n", (int)ie->id);
+        break;
+    } // switch ie
+  } // for IE
+  AssertFatal(TransactionId!=-1,"TransactionId was not sent\n");
+  LOG_D(F1AP,"F1AP: num_cells_to_activate %d\n",num_cells_to_activate);
+  F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).num_cells_to_activate = num_cells_to_activate;
+
+  MSC_LOG_RX_MESSAGE(
+  MSC_F1AP_DU,
+  MSC_F1AP_CU,
+  0,
+  0,
+  MSC_AS_TIME_FMT" DU_handle_GNB_CU_CONFIGURATION_UPDATE initiatingMessage assoc_id %d",
+  0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+  assoc_id);
+
+  if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) {
+    LOG_D(F1AP, "Sending F1AP_GNB_CU_CONFIGURATION_UPDATE ITTI message to GNB_APP with assoc_id (%d->%d)\n",
+         assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id));
+    itti_send_msg_to_task(TASK_GNB_APP, GNB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p);
+  } else {
+    LOG_D(F1AP, "Sending F1AP_GNB_CU_CONFIGURATION_UPDATE ITTI message to ENB_APP with assoc_id (%d->%d)\n",
+         assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id));
+    itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p);
+  }
+
+  return 0;
 }
 
 int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
-                    F1AP_GNBCUConfigurationUpdateFailure_t *GNBCUConfigurationUpdateFailure) {
-  AssertFatal(1==0,"Not implemented yet\n");
+						f1ap_gnb_cu_configuration_update_failure_t *GNBCUConfigurationUpdateFailure) {
+  AssertFatal(1==0,"received gNB CU CONFIGURATION UPDATE FAILURE with cause %d\n",
+	      GNBCUConfigurationUpdateFailure->cause);
 }
 
 int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
-                    F1AP_GNBCUConfigurationUpdateAcknowledge_t *GNBCUConfigurationUpdateAcknowledge) {
-  AssertFatal(1==0,"Not implemented yet\n");
+						    f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge) {
+
+  if(!RC.nrrrc) {
+    return 0;
+  }
+
+  AssertFatal(GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated == 0,
+	      "%d cells failed to activate\n",
+	      GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated);
+
+  AssertFatal(GNBCUConfigurationUpdateAcknowledge->noofTNLAssociations_to_setup == 0,
+	      "%d TNLAssociations to setup, handle this ...\n",
+	      GNBCUConfigurationUpdateAcknowledge->noofTNLAssociations_to_setup);
+
+
+  AssertFatal(GNBCUConfigurationUpdateAcknowledge->noofTNLAssociations_failed == 0,
+	      "%d TNLAssociations failed\n",
+	      GNBCUConfigurationUpdateAcknowledge->noofTNLAssociations_failed);
+
+  AssertFatal(GNBCUConfigurationUpdateAcknowledge->noofDedicatedSIDeliveryNeededUEs == 0,
+	      "%d DedicatedSIDeliveryNeededUEs\n",
+	      GNBCUConfigurationUpdateAcknowledge->noofDedicatedSIDeliveryNeededUEs);
+
+  F1AP_F1AP_PDU_t           pdu;
+  uint8_t  *buffer;
+  uint32_t  len;
+
+  /* Create */
+  /* 0. pdu Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
+  pdu.choice.successfulOutcome = (F1AP_SuccessfulOutcome_t *)calloc(1, sizeof(F1AP_SuccessfulOutcome_t));
+  pdu.choice.successfulOutcome->procedureCode = F1AP_ProcedureCode_id_gNBCUConfigurationUpdate;
+  pdu.choice.successfulOutcome->criticality   = F1AP_Criticality_reject;
+  pdu.choice.successfulOutcome->value.present = F1AP_SuccessfulOutcome__value_PR_GNBCUConfigurationUpdateAcknowledge;
+  F1AP_GNBCUConfigurationUpdateAcknowledge_t *out = &pdu.choice.successfulOutcome->value.choice.GNBCUConfigurationUpdateAcknowledge;
+
+  /* mandatory */
+  /* c1. Transaction ID (integer value)*/
+  F1AP_GNBCUConfigurationUpdateAcknowledgeIEs_t *ie = (F1AP_GNBCUConfigurationUpdateAcknowledgeIEs_t *)calloc(1, sizeof(F1AP_F1SetupResponseIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_TransactionID;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBCUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID;
+  ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(0, 0);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode GNB-DU-Configuration-Update-Acknowledge\n");
+    return -1;
+  }
+
+  du_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data->assoc_id, buffer, len, 0);
+
+
+
+  return 0;
 }
 
 
diff --git a/openair2/F1AP/f1ap_du_interface_management.h b/openair2/F1AP/f1ap_du_interface_management.h
index 941b86a6d4228d7e61539c5de198178de363471e..619b725f38832478d4260d89ff9d4b844875a6fb 100644
--- a/openair2/F1AP/f1ap_du_interface_management.h
+++ b/openair2/F1AP/f1ap_du_interface_management.h
@@ -98,17 +98,17 @@ int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance,
                                           F1AP_F1AP_PDU_t *pdu);
 
 int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
-                    F1AP_GNBCUConfigurationUpdateFailure_t *GNBCUConfigurationUpdateFailure);
+                                                f1ap_gnb_cu_configuration_update_failure_t *GNBCUConfigurationUpdateFailure);
 
 int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
-                    F1AP_GNBCUConfigurationUpdateAcknowledge_t *GNBCUConfigurationUpdateAcknowledge);
+                                                    f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge);
 
 
 /*
  * gNB-DU Resource Coordination
  */
 int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance,
-                    F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest);
+                                                 F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest);
 
 int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance,
                                                     uint32_t assoc_id,
diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
index 1d6e729ab2cf2ea450ca2ca632c2e1f6d71f8cbb..07df0b4a78748e375394e4f1ac5018cdbf114350 100644
--- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c
+++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
@@ -42,13 +42,19 @@
 #include "LTE_DL-DCCH-Message.h"
 #include "LTE_UL-DCCH-Message.h"
 
+#include "NR_DL-CCCH-Message.h"
+#include "NR_UL-CCCH-Message.h"
+#include "NR_DL-DCCH-Message.h"
+#include "NR_UL-DCCH-Message.h"
 // for SRB1_logicalChannelConfig_defaultValue
 #include "rrc_extern.h"
 #include "common/ran_context.h"
 
 #include "rrc_eNB_UE_context.h"
+#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
 #include "asn1_msg.h"
 #include "intertask_interface.h"
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
 
 // undefine C_RNTI from
 // openair1/PHY/LTE_TRANSPORT/transport_common.h which
@@ -61,13 +67,32 @@ extern f1ap_setup_req_t *f1ap_du_data;
 extern RAN_CONTEXT_t RC;
 extern f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB];
 
+extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP,
+                                                   const NR_SRB_ToAddModList_t   * const srb2add_listP,
+                                                   const NR_DRB_ToAddModList_t   * const drb2add_listP,
+                                                   const NR_DRB_ToReleaseList_t  * const drb2release_listP,
+                                                   const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
+                                                   struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_srb_bearer2add_list,
+                                                   struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_drb_bearer2add_list);
 
+uint8_t du_ccch_flag = 1;
+
+int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t       instance,
+                                         uint32_t         assoc_id,
+                                         uint32_t         stream,
+                                         F1AP_F1AP_PDU_t *pdu);
 
 /*  DL RRC Message Transfer */
 int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t       instance,
                                       uint32_t         assoc_id,
                                       uint32_t         stream,
                                       F1AP_F1AP_PDU_t *pdu) {
+
+  if (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
+    LOG_I(F1AP, "node is gNB DU, call DU_handle_DL_NR_RRC_MESSAGE_TRANSFER \n");
+    return DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance, assoc_id, stream, pdu);
+  }
+
   LOG_D(F1AP, "DU_handle_DL_RRC_MESSAGE_TRANSFER \n");
   
   F1AP_DLRRCMessageTransfer_t    *container;
@@ -454,36 +479,36 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t       instance,
                       DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->logicalChannelIdentity;
                     }
 
-                    rrc_mac_config_req_eNB(
-                      ctxt.module_id,
-                      0,0,0,0,0,0,
-                   0,
-                   ue_context_p->ue_context.rnti,
-                   (LTE_BCCH_BCH_Message_t *) NULL,
-                   (LTE_RadioResourceConfigCommonSIB_t *) NULL,
-                   (LTE_RadioResourceConfigCommonSIB_t *) NULL,
-                   physicalConfigDedicated,
-                   (LTE_SCellToAddMod_r10_t *)NULL,
-                   //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
-                   (LTE_MeasObjectToAddMod_t **) NULL,
-                   mac_MainConfig,
-                   DRB2LCHAN[i],
-                   DRB_configList->list.array[i]->logicalChannelConfig,
-                   measGapConfig,
-                   (LTE_TDD_Config_t *) NULL,
-                   NULL,
-                   (LTE_SchedulingInfoList_t *) NULL,
-                   0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
-                   , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL,
-                   (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL,
-                         0,
-                         (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
-                         (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
-                         (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
-                         (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
-                         (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
-                         (LTE_MBSFNAreaConfiguration_r9_t*) NULL
-                   );
+                     rrc_mac_config_req_eNB(
+                     ctxt.module_id,
+                     0,0,0,0,0,0,
+                     0,
+                     ue_context_p->ue_context.rnti,
+                     (LTE_BCCH_BCH_Message_t *) NULL,
+                     (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+                     (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+                     physicalConfigDedicated,
+                     (LTE_SCellToAddMod_r10_t *)NULL,
+                     //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
+                     (LTE_MeasObjectToAddMod_t **) NULL,
+                     mac_MainConfig,
+                     DRB2LCHAN[i],
+                     DRB_configList->list.array[i]->logicalChannelConfig,
+                     measGapConfig,
+                     (LTE_TDD_Config_t *) NULL,
+                     NULL,
+                     (LTE_SchedulingInfoList_t *) NULL,
+                     0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
+                     , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL,
+                     (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL,
+                     0,
+                     (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL,
+                     (LTE_SchedulingInfo_MBMS_r14_t *) NULL,
+                     (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL,
+                     (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL,
+                     (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+                     (LTE_MBSFNAreaConfiguration_r9_t*) NULL
+                     );
                   }
 
                 } else {        // remove LCHAN from MAC/PHY
@@ -765,7 +790,7 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
   }
     /* encode */
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
-    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    LOG_E(F1AP, "Failed to encode F1 UL RRC MESSAGE TRANSFER\n");
     return -1;
   }
 
@@ -780,7 +805,10 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t     module_idP,
                                             int             UE_id,
                                             rnti_t          rntiP,
                                             const uint8_t   *sduP,
-                                            sdu_size_t      sdu_lenP) {
+                                            sdu_size_t      sdu_lenP,
+                                            const int8_t   *sdu2P,
+					                                  sdu_size_t      sdu2_lenP) {
+
   F1AP_F1AP_PDU_t                       pdu;
   F1AP_InitialULRRCMessageTransfer_t    *out;
   F1AP_InitialULRRCMessageTransferIEs_t *ie;
@@ -850,29 +878,36 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t     module_idP,
 
   /* optional */
   /* c5. DUtoCURRCContainer */
-  if (0) {
+  if (sdu2P && RC.nrrrc) {
     ie = (F1AP_InitialULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_InitialULRRCMessageTransferIEs_t));
     ie->id                             = F1AP_ProtocolIE_ID_id_DUtoCURRCContainer;
     ie->criticality                    = F1AP_Criticality_reject;
     ie->value.present                  = F1AP_InitialULRRCMessageTransferIEs__value_PR_DUtoCURRCContainer;
-    OCTET_STRING_fromBuf(&ie->value.choice.DUtoCURRCContainer, "dummy_val",
-                       strlen("dummy_val"));
+    OCTET_STRING_fromBuf(&ie->value.choice.DUtoCURRCContainer, (char *)sdu2P, sdu2_lenP);
     ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
-  }
+  }    
 
     /* encode */
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
-    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    LOG_E(F1AP, "Failed to encode F1 INITIAL UL RRC MESSAGE TRANSFER\n");
     return -1;
   }
 
-
-  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_allocate_new_UE_context(RC.rrc[module_idP]);
-  ue_context_p->ue_id_rnti                    = rntiP; 
-  ue_context_p->ue_context.rnti               = rntiP;
-  ue_context_p->ue_context.random_ue_identity = rntiP;
-  ue_context_p->ue_context.Srb0.Active        = 1;
-  RB_INSERT(rrc_ue_tree_s, &RC.rrc[module_idP]->rrc_ue_head, ue_context_p);
+  if (RC.nrrrc && RC.nrrrc[module_idP]->node_type == ngran_gNB_DU) {
+    struct rrc_gNB_ue_context_s* ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[module_idP]);
+    ue_context_p->ue_id_rnti                    = rntiP; 
+    ue_context_p->ue_context.rnti               = rntiP;
+    ue_context_p->ue_context.random_ue_identity = rntiP;
+    ue_context_p->ue_context.Srb0.Active        = 1;
+    RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[module_idP]->rrc_ue_head, ue_context_p);
+  } else {
+    struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_allocate_new_UE_context(RC.rrc[module_idP]);
+    ue_context_p->ue_id_rnti                    = rntiP; 
+    ue_context_p->ue_context.rnti               = rntiP;
+    ue_context_p->ue_context.random_ue_identity = rntiP;
+    ue_context_p->ue_context.Srb0.Active        = 1;
+    RB_INSERT(rrc_ue_tree_s, &RC.rrc[module_idP]->rrc_ue_head, ue_context_p);
+  }
   du_f1ap_itti_send_sctp_data_req(module_idP, f1ap_du_data->assoc_id, buffer, len,  f1ap_du_data->default_sctp_stream_id);
 
   return 0;
@@ -884,4 +919,631 @@ void init_f1ap_du_ue_inst (void) {
    memset(f1ap_du_inst, 0, sizeof(f1ap_du_inst));
 }
 
+int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, 
+                                    const f1ap_ul_rrc_message_t *msg) {
+  const rnti_t rnti = msg->rnti;
+
+  F1AP_F1AP_PDU_t                pdu;
+  F1AP_ULRRCMessageTransfer_t    *out;
+  F1AP_ULRRCMessageTransferIEs_t *ie;
+
+  uint8_t *buffer = NULL;
+  uint32_t len;
+
+
+  LOG_I(F1AP, "[DU %ld] %s: size %d UE RNTI %x in SRB %d\n",
+        instance, __func__, msg->rrc_container_length, rnti, msg->srb_id);
+
+  //LOG_I(F1AP, "%s() RRCContainer size %d: ", __func__, msg->rrc_container_length);
+  //for (int i = 0;i < msg->rrc_container_length; i++)
+  //  printf("%02x ", msg->rrc_container[i]);
+  //printf("\n");
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_ULRRCMessageTransfer;
+  pdu.choice.initiatingMessage->criticality   = F1AP_Criticality_ignore;
+  pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_ULRRCMessageTransfer;
+  out = &pdu.choice.initiatingMessage->value.choice.ULRRCMessageTransfer;
+  
+  /* mandatory */
+  /* c1. GNB_CU_UE_F1AP_ID */
+  ie = (F1AP_ULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_ULRRCMessageTransferIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID;
+
+  ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_du_inst[instance], rnti);
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. GNB_DU_UE_F1AP_ID */
+  ie = (F1AP_ULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_ULRRCMessageTransferIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
+  ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_du_inst[instance], rnti);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c3. SRBID */
+  ie = (F1AP_ULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_ULRRCMessageTransferIEs_t));
+  ie->id                            = F1AP_ProtocolIE_ID_id_SRBID;
+  ie->criticality                   = F1AP_Criticality_reject;
+  ie->value.present                 = F1AP_ULRRCMessageTransferIEs__value_PR_SRBID;
+  ie->value.choice.SRBID            = msg->srb_id;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  // issue in here
+  /* mandatory */
+  /* c4. RRCContainer */
+  ie = (F1AP_ULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_ULRRCMessageTransferIEs_t));
+  ie->id                            = F1AP_ProtocolIE_ID_id_RRCContainer;
+  ie->criticality                   = F1AP_Criticality_reject;
+  ie->value.present                 = F1AP_ULRRCMessageTransferIEs__value_PR_RRCContainer;
+  OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer,
+                       (const char *) msg->rrc_container,
+                       msg->rrc_container_length);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  if (msg->srb_id == 1 || msg->srb_id == 2) {
+    struct rrc_gNB_ue_context_s* ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti);
+
+
+    NR_UL_DCCH_Message_t* ul_dcch_msg=NULL;
+    asn_dec_rval_t dec_rval;
+    dec_rval = uper_decode(NULL,
+         &asn_DEF_NR_UL_DCCH_Message,
+         (void**)&ul_dcch_msg,
+         &ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header
+         msg->rrc_container_length, 0, 0);
+
+    if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
+      LOG_E(F1AP, " Failed to decode UL-DCCH (%zu bytes)\n",dec_rval.consumed);
+      /* for rfsim, because UE send RRCSetupRequest in SRB1 */
+      // NR_UL_CCCH_Message_t *ul_ccch_msg;
+      // dec_rval = uper_decode(NULL,
+      //    &asn_DEF_NR_UL_CCCH_Message,
+      //    (void**)&ul_ccch_msg,
+      //    &ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header
+      //    msg->rrc_container_length, 0, 0);
+      // if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
+      //   LOG_E(F1AP, " Failed to decode UL-CCCH (%zu bytes)\n",dec_rval.consumed);
+      // } else {
+      //   LOG_I(F1AP, "decode UL-CCCH success \n");
+      //   LOG_I(F1AP, "Received message: present %d and c1 present %d\n",
+      //       ul_ccch_msg->message.present, ul_ccch_msg->message.choice.c1->present);
+
+      //   if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) {
+      //     if (ul_ccch_msg->message.choice.c1->present == NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest) {
+      //       LOG_I(F1AP, "[MSG] RRC Setup Request\n");
+
+      //     }
+      //   }
+      // }
+    }
+    else
+      LOG_I(F1AP, "Received message: present %d and c1 present %d\n",
+            ul_dcch_msg->message.present, ul_dcch_msg->message.choice.c1->present);
+
+    if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) {
+
+      switch (ul_dcch_msg->message.choice.c1->present) {
+      case NR_UL_DCCH_MessageType__c1_PR_NOTHING:   /* No components present */
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_measurementReport:
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete:
+        LOG_I(F1AP, "[MSG] RRC UL rrcReconfigurationComplete\n");
+
+        /* CDRX: activated when RRC Connection Reconfiguration Complete is received */
+#if(0)
+        int UE_id_mac = find_nr_UE_id(instance, rnti);
+
+        if (UE_id_mac == -1) {
+          LOG_E(F1AP, "Can't find UE_id(MAC) of UE rnti %x\n", rnti);
+          break;
+        }
+
+        UE_sched_ctrl_t *UE_scheduling_control = &(RC.nrmac[instance]->UE_info.UE_sched_ctrl[UE_id_mac]);
+
+        if (UE_scheduling_control->cdrx_waiting_ack == TRUE) {
+          UE_scheduling_control->cdrx_waiting_ack = FALSE;
+          UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration Complete is received
+          LOG_I(F1AP, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n");
+        }
+        /* End of CDRX processing */
+#endif
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete:
+        LOG_I(F1AP, "[MSG] RRC UL rrcSetupComplete \n");
+
+        if(!ue_context_p){
+          LOG_E(F1AP, "Did not find the UE context associated with UE RNTOI %x, ue_context_p is NULL\n", rnti);
+
+        } else {
+          LOG_I(F1AP, "Processing RRCSetupComplete UE %x\n", rnti);
+          ue_context_p->ue_context.StatusRrc = NR_RRC_CONNECTED;
+        }
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete:
+        LOG_I(F1AP, "[MSG] RRC ReestablishmentComplete \n");
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_rrcResumeComplete:
+        LOG_I(F1AP, "[MSG] RRC ResumeComplete \n");
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete:
+        LOG_I(F1AP, "[MSG] RRC securityModeComplete \n");
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure:
+        LOG_I(F1AP, "[MSG] RRC securityModeFailure \n");
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
+        LOG_I(F1AP, "[MSG] RRC UL Information Transfer \n");
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_locationMeasurementIndication:
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation:
+        LOG_I(F1AP, "[MSG] RRC ueCapabilityInformation \n");
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_ueAssistanceInformation:
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_failureInformation:
+       break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_scgFailureInformation:
+        break;
+
+      case NR_UL_DCCH_MessageType__c1_PR_scgFailureInformationEUTRA:
+       break;
+
+      default:
+        LOG_E(NR_RRC, "Unknown UL DCCH message type, present %d \n", ul_dcch_msg->message.choice.c1->present);
+       break;
+      }
+    }
+  }
+    /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 UL RRC MESSAGE TRANSFER \n");
+    return -1;
+  }
+
+  du_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data->assoc_id, buffer, len, f1ap_du_data->default_sctp_stream_id);
+  return 0;
+}
+
+/*  DL NR RRC Message Transfer */
+int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t       instance,
+                                         uint32_t         assoc_id,
+                                         uint32_t         stream,
+                                         F1AP_F1AP_PDU_t *pdu) {
+  LOG_D(F1AP, "DU_handle_DL_NR_RRC_MESSAGE_TRANSFER \n");
+  
+  F1AP_DLRRCMessageTransfer_t    *container;
+  F1AP_DLRRCMessageTransferIEs_t *ie;
+
+  uint64_t        cu_ue_f1ap_id;
+  uint64_t        du_ue_f1ap_id;
+  uint64_t        srb_id;
+  int             executeDuplication;
+  sdu_size_t      rrc_dl_sdu_len;
+  //uint64_t        subscriberProfileIDforRFP;
+  //uint64_t        rAT_FrequencySelectionPriority;
+
+  DevAssert(pdu != NULL);
+
+  if (stream != 0) {
+    LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n",
+               assoc_id, stream);
+    return -1;
+  }
+
+  container = &pdu->choice.initiatingMessage->value.choice.DLRRCMessageTransfer;
+
+
+  /* GNB_CU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
+  cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
+  LOG_D(F1AP, "cu_ue_f1ap_id %lu \n", cu_ue_f1ap_id);
+
+
+  /* GNB_DU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
+  du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
+  LOG_D(F1AP, "du_ue_f1ap_id %lu associated with UE RNTI %x \n",
+        du_ue_f1ap_id,
+        f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], du_ue_f1ap_id)); // this should be the one transmitted via initial ul rrc message transfer
+
+  if (f1ap_du_add_cu_ue_id(&f1ap_du_inst[instance],du_ue_f1ap_id, cu_ue_f1ap_id) < 0 ) {
+    LOG_E(F1AP, "Failed to find the F1AP UID \n");
+    //return -1;
+  }
+
+  /* optional */
+  /* oldgNB_DU_UE_F1AP_ID */
+  if (0) {
+    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, true);
+  }
+
+  /* mandatory */
+  /* SRBID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_SRBID, true);
+  srb_id = ie->value.choice.SRBID;
+  LOG_D(F1AP, "srb_id %lu \n", srb_id);
+
+  /* optional */
+  /* ExecuteDuplication */
+  if (0) {
+    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_ExecuteDuplication, true);
+    executeDuplication = ie->value.choice.ExecuteDuplication;
+    LOG_D(F1AP, "ExecuteDuplication %d \n", executeDuplication);
+  }
+
+  // issue in here
+  /* mandatory */
+  /* RRC Container */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_RRCContainer, true);
+  // BK: need check
+  // create an ITTI message and copy SDU
+
+  //  message_p = itti_alloc_new_message (TASK_CU_F1, RRC_MAC_CCCH_DATA_IND);
+  //  memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
+  rrc_dl_sdu_len = ie->value.choice.RRCContainer.size;
+  //  memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf,
+  //         ccch_sdu_len);
+
+  //LOG_I(F1AP, "%s() RRCContainer size %lu: ", __func__, ie->value.choice.RRCContainer.size);
+  //for (int i = 0;i < ie->value.choice.RRCContainer.size; i++)
+  //  printf("%02x ", ie->value.choice.RRCContainer.buf[i]);
+  //printf("\n");
+
+  /* optional */
+  /* RAT_FrequencyPriorityInformation */
+  if (0) {
+    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation, true);
+
+    switch(ie->value.choice.RAT_FrequencyPriorityInformation.present) {
+      case F1AP_RAT_FrequencyPriorityInformation_PR_eNDC:
+        //subscriberProfileIDforRFP = ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP;
+        break;
+      case F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN:
+        //rAT_FrequencySelectionPriority = ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority;
+        break;
+      default:
+        LOG_W(F1AP, "unhandled IE RAT_FrequencyPriorityInformation.present\n");
+        break;
+    }
+  }
+
+  // decode RRC Container and act on the message type
+  AssertFatal(srb_id<3,"illegal srb_id\n");
+
+  protocol_ctxt_t ctxt;
+  ctxt.rnti      = f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], du_ue_f1ap_id);
+  ctxt.module_id = instance;
+  ctxt.instance  = instance;
+  ctxt.enb_flag  = 1;
+
+  struct rrc_gNB_ue_context_s* ue_context_p = rrc_gNB_get_ue_context(
+								     RC.nrrrc[ctxt.module_id],
+								     ctxt.rnti);
+
+  if (srb_id == 0) {
+    NR_DL_CCCH_Message_t* dl_ccch_msg=NULL;
+    asn_dec_rval_t dec_rval;
+    dec_rval = uper_decode(NULL,
+                           &asn_DEF_NR_DL_CCCH_Message,
+			   (void**)&dl_ccch_msg,
+			   ie->value.choice.RRCContainer.buf,
+			   rrc_dl_sdu_len,0,0);
+    AssertFatal(dec_rval.code == RC_OK, "could not decode F1AP message\n");
+    switch (dl_ccch_msg->message.choice.c1->present) {
+
+      case NR_DL_CCCH_MessageType__c1_PR_NOTHING:
+
+        LOG_I(F1AP, "Received PR_NOTHING on DL-CCCH-Message\n");
+        break;
+
+      case NR_DL_CCCH_MessageType__c1_PR_rrcReject:
+        LOG_I(F1AP,
+              "Logical Channel DL-CCCH (SRB0), Received RRCReject\n");
+        break;
+
+      case NR_DL_CCCH_MessageType__c1_PR_rrcSetup:
+      {
+        LOG_I(F1AP,
+              "Logical Channel DL-CCCH (SRB0), Received RRCSetup DU_ID %lx/RNTI %x\n",
+              du_ue_f1ap_id,
+              f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], du_ue_f1ap_id));
+          // Get configuration
+
+        NR_RRCSetup_t* rrcSetup = dl_ccch_msg->message.choice.c1->choice.rrcSetup;
+        AssertFatal(rrcSetup!=NULL, "rrcSetup is null\n");
+        NR_RRCSetup_IEs_t *rrcSetup_ies = rrcSetup->criticalExtensions.choice.rrcSetup;
+
+	ue_context_p->ue_context.SRB_configList = rrcSetup_ies->radioBearerConfig.srb_ToAddModList;
+        AssertFatal(rrcSetup_ies->masterCellGroup.buf!=NULL,"masterCellGroup is null\n");
+	asn_dec_rval_t dec_rval;
+	dec_rval = uper_decode(NULL,
+			       &asn_DEF_NR_CellGroupConfig,
+			       (void**)&ue_context_p->ue_context.masterCellGroup,
+			       rrcSetup_ies->masterCellGroup.buf,
+			       rrcSetup_ies->masterCellGroup.size,0,0);
+	AssertFatal(dec_rval.code == RC_OK, "could not decode masterCellGroup\n");
+
+	// configure MAC
+	gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
+	rrc_mac_config_req_gNB(ctxt.module_id,
+			       rrc->carrier.ssb_SubcarrierOffset,
+			       rrc->carrier.pdsch_AntennaPorts,
+			       rrc->carrier.pusch_AntennaPorts,
+			       NULL,
+			       0,
+			       ue_context_p->ue_context.rnti,
+			       ue_context_p->ue_context.masterCellGroup
+			       );
+
+	// rrc_rlc_config_asn1_req
+	nr_rrc_rlc_config_asn1_req(&ctxt,
+				   ue_context_p->ue_context.SRB_configList,
+				   NULL,
+				   NULL,
+				   NULL,
+				   NULL,
+				   NULL);
+
+      // This should be somewhere in the f1ap_cudu_ue_inst_t
+      /*int macrlc_instance = 0;
+
+      rnti_t rnti = f1ap_get_rnti_by_du_id(&f1ap_du_inst[0], du_ue_f1ap_id);
+      struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[macrlc_instance],rnti);
+      */
+      gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
+      AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n");
+
+      memcpy((void*)ue_p->Srb0.Tx_buffer.Payload,
+             (void*)ie->value.choice.RRCContainer.buf,
+             rrc_dl_sdu_len); // ie->value.choice.RRCContainer.size
+
+      ue_p->Srb0.Tx_buffer.payload_size = rrc_dl_sdu_len;
+
+      // NR_MAC_CellGroupConfig_t *mac_CellGroupConfig  = NULL;
+      // if (cellGroupConfig->mac_CellGroupConfig)
+      //   mac_CellGroupConfig = cellGroupConfig->mac_CellGroupConfig;
+
+      // rrc_mac_config_req_gNB
+          break;
+      } // case
+
+      case NR_DL_CCCH_MessageType__c1_PR_spare2:
+        LOG_I(F1AP,
+              "Logical Channel DL-CCCH (SRB0), Received spare2\n");
+        break;
+
+      case NR_DL_CCCH_MessageType__c1_PR_spare1:
+        LOG_I(F1AP,
+              "Logical Channel DL-CCCH (SRB0), Received spare1\n");
+        break;
+
+      default:
+        AssertFatal(1==0,
+        "Unknown message\n");
+        break;
+    }// switch case
+    return(0);
+  } else if (srb_id == 1) { 
+
+    NR_DL_DCCH_Message_t* dl_dcch_msg=NULL;
+    asn_dec_rval_t dec_rval;
+    dec_rval = uper_decode(NULL,
+         &asn_DEF_NR_DL_DCCH_Message,
+         (void**)&dl_dcch_msg,
+         &ie->value.choice.RRCContainer.buf[2], // buf[0] includes the pdcp header
+         rrc_dl_sdu_len-6,0,0);
+
+    if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) 
+      LOG_E(F1AP," Failed to decode DL-DCCH (%zu bytes)\n",dec_rval.consumed);
+    else
+      LOG_D(F1AP, "Received message: present %d and c1 present %d\n",
+            dl_dcch_msg->message.present, dl_dcch_msg->message.choice.c1->present);
+
+    if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) {
+      switch (dl_dcch_msg->message.choice.c1->present) {
+        case NR_DL_DCCH_MessageType__c1_PR_NOTHING:
+          LOG_I(F1AP, "Received PR_NOTHING on DL-DCCH-Message\n");
+          return 0;
+
+        case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration:
+        // handle RRCReconfiguration
+          LOG_I(F1AP,
+                "Logical Channel DL-DCCH (SRB1), Received RRCReconfiguration DU_ID %lx/RNTI %x\n",
+                du_ue_f1ap_id,
+                f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], du_ue_f1ap_id));
+    
+          NR_RRCReconfiguration_t* rrcReconfiguration = dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration;
+
+          if (rrcReconfiguration->criticalExtensions.present == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration) {
+            NR_RRCReconfiguration_IEs_t* rrcReconfiguration_ies =
+              rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration;
+
+            if (rrcReconfiguration_ies->measConfig != NULL) {
+              LOG_I(F1AP, "Measurement Configuration is present\n");
+            }
+
+              if (rrcReconfiguration_ies->radioBearerConfig) {
+                LOG_I(F1AP, "Radio Resource Configuration is present\n");
+                long drb_id;
+                int i;
+                NR_DRB_ToAddModList_t  *DRB_configList  = rrcReconfiguration_ies->radioBearerConfig->drb_ToAddModList;
+                NR_SRB_ToAddModList_t  *SRB_configList  = rrcReconfiguration_ies->radioBearerConfig->srb_ToAddModList;
+                // NR_DRB_ToReleaseList_t *DRB_ReleaseList = rrcReconfiguration_ies->radioBearerConfig->drb_ToReleaseList;
+
+                // rrc_rlc_config_asn1_req
 
+                if (SRB_configList != NULL) {
+                  for (i = 0; (i < SRB_configList->list.count) && (i < 3); i++) {
+                    if (SRB_configList->list.array[i]->srb_Identity == 1 ){
+                      ue_context_p->ue_context.Srb1.Active=1;
+                    }
+                    else if (SRB_configList->list.array[i]->srb_Identity == 2 )  {
+                      ue_context_p->ue_context.Srb2.Active=1;
+                      ue_context_p->ue_context.Srb2.Srb_info.Srb_id=2;
+                      LOG_I(F1AP, "[DU %d] SRB2 is now active\n",ctxt.module_id);
+                    } else {
+                      LOG_W(F1AP, "[DU %d] invalide SRB identity %ld\n",ctxt.module_id,
+                      SRB_configList->list.array[i]->srb_Identity);
+                    }
+                  }
+                }
+
+                if (DRB_configList != NULL) {
+                  for (i = 0; i < DRB_configList->list.count; i++) {  // num max DRB (11-3-8)
+                    if (DRB_configList->list.array[i]) {
+                      drb_id = (int)DRB_configList->list.array[i]->drb_Identity;
+                      LOG_I(F1AP,
+                            "[DU %d] Logical Channel UL-DCCH, Received RRCConnectionReconfiguration for UE rnti %x, reconfiguring DRB %d\n",
+                            ctxt.module_id,
+                            ctxt.rnti,
+                            (int)DRB_configList->list.array[i]->drb_Identity);
+                            // (int)*DRB_configList->list.array[i]->logicalChannelIdentity);
+
+                    if (ue_context_p->ue_context.DRB_active[drb_id] == 0) {
+                      ue_context_p->ue_context.DRB_active[drb_id] = 1;
+
+                      // logicalChannelIdentity
+                      // rrc_mac_config_req_eNB
+                    }
+
+                  } else {        // remove LCHAN from MAC/PHY
+                    AssertFatal(1==0,"Can't handle this yet in DU\n");  
+                  } 
+                }
+              }
+            }
+        }
+        break;
+      case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
+        LOG_I(F1AP,"Received rrcResume\n");
+        break;	
+      case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
+        LOG_I(F1AP,"Received rrcRelease\n");
+        break;  
+      case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
+        LOG_I(F1AP,"Received rrcReestablishment\n");
+        break;  
+      case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
+        LOG_I(F1AP,"Received securityModeCommand\n");
+        break;
+      case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
+        LOG_I(F1AP, "Received dlInformationTransfer\n");
+  	    break;
+      case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
+        LOG_I(F1AP, "Received ueCapabilityEnquiry\n");
+          break; 
+      case NR_DL_DCCH_MessageType__c1_PR_counterCheck:
+        LOG_I(F1AP, "Received counterCheck\n");
+          break;
+      case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand:
+      case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16:
+      case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16:
+      case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16:
+      case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16:
+      case NR_DL_DCCH_MessageType__c1_PR_spare3:
+      case NR_DL_DCCH_MessageType__c1_PR_spare2:
+      case NR_DL_DCCH_MessageType__c1_PR_spare1:
+        break;
+    }
+   }
+  }
+  else if (srb_id == 2) {
+    // TODO
+  }
+
+  LOG_I(F1AP, "Received DL RRC Transfer on srb_id %ld\n", srb_id);
+
+
+//   rlc_op_status_t    rlc_status;
+//   boolean_t          ret             = TRUE;
+  mem_block_t       *pdcp_pdu_p      = NULL; 
+  pdcp_pdu_p = get_free_mem_block(rrc_dl_sdu_len, __func__);
+
+  //LOG_I(F1AP, "PRRCContainer size %lu:", ie->value.choice.RRCContainer.size);
+  //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
+  //  printf("%02x ", ie->value.choice.RRCContainer.buf[i]);
+
+  //printf (", PDCP PDU size %d:", rrc_dl_sdu_len);
+  //for (int i=0;i<rrc_dl_sdu_len;i++) printf("%2x ",pdcp_pdu_p->data[i]);
+  //printf("\n");
+
+  if (pdcp_pdu_p != NULL) {
+    memset(pdcp_pdu_p->data, 0, rrc_dl_sdu_len);
+    memcpy(&pdcp_pdu_p->data[0], ie->value.choice.RRCContainer.buf, rrc_dl_sdu_len);
+
+    /* for rfsim */
+    du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, rrc_dl_sdu_len, pdcp_pdu_p);
+    //   rlc_status = rlc_data_req(&ctxt
+    //                             , 1
+    //                             , MBMS_FLAG_NO
+    //                             , srb_id
+    //                             , 0
+    //                             , 0
+    //                             , rrc_dl_sdu_len
+    //                             , pdcp_pdu_p
+    //                             ,NULL
+    //                             ,NULL
+    //                             );
+    //   switch (rlc_status) {
+    //     case RLC_OP_STATUS_OK:
+    //       //LOG_I(F1AP, "Data sending request over RLC succeeded!\n");
+    //       ret=TRUE;
+    //       break;
+
+    //     case RLC_OP_STATUS_BAD_PARAMETER:
+    //       LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
+    //       ret= FALSE;
+    //       break;
+
+    //     case RLC_OP_STATUS_INTERNAL_ERROR:
+    //       LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
+    //       ret= FALSE;
+    //       break;
+
+    //     case RLC_OP_STATUS_OUT_OF_RESSOURCES:
+    //       LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
+    //       ret= FALSE;
+    //       break;
+
+    //     default:
+    //       LOG_W(F1AP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status);
+    //       ret= FALSE;
+    //       break;
+    //   } // switch case
+    //   return ret; 
+    } // if pdcp_pdu_p
+
+  return 0;
+}
diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.h b/openair2/F1AP/f1ap_du_rrc_message_transfer.h
index 1406e48f3d3a76320a2d4ca99b7fc1b5cbdd6bd6..3036c66d709942babf98e857620ab56e2964bbf2 100644
--- a/openair2/F1AP/f1ap_du_rrc_message_transfer.h
+++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.h
@@ -42,12 +42,15 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t       instance,
                                       F1AP_F1AP_PDU_t *pdu);
 
 int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg);
+int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg);
 
 int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t     module_idP,
                                             int             CC_idP,
                                             int             UE_id,
                                             rnti_t          rntiP,
                                             const uint8_t   *sduP,
-                                            sdu_size_t      sdu_lenP);
+                                            sdu_size_t      sdu_lenP,
+                                            const int8_t   *sdu2P,
+                                            sdu_size_t      sdu2_lenP);
 
 #endif /* F1AP_DU_RRC_MESSAGE_TRANSFER_H_ */
diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c
index c8aa4a61192c62d7990a2097cd2e658d54b27546..50f7cdff805ec3811ab4bd70fc958da1bec101ef 100644
--- a/openair2/F1AP/f1ap_du_task.c
+++ b/openair2/F1AP/f1ap_du_task.c
@@ -102,7 +102,12 @@ void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat
   f1ap_du_data->default_sctp_stream_id = 0;
 
   /* setup parameters for F1U and start the server */
-  const cudu_params_t params = {
+  const cudu_params_t params = (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) ? (cudu_params_t){
+    .local_ipv4_address  = RC.nrmac[instance]->eth_params_n.my_addr,
+    .local_port          = RC.nrmac[instance]->eth_params_n.my_portd,
+    .remote_ipv4_address = RC.nrmac[instance]->eth_params_n.remote_addr,
+    .remote_port         = RC.nrmac[instance]->eth_params_n.remote_portd
+  } : (cudu_params_t){
     .local_ipv4_address  = RC.mac[instance]->eth_params_n.my_addr,
     .local_port          = RC.mac[instance]->eth_params_n.my_portd,
     .remote_ipv4_address = RC.mac[instance]->eth_params_n.remote_addr,
@@ -159,6 +164,14 @@ void *F1AP_DU_task(void *arg) {
         du_task_send_sctp_association_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
                                               &F1AP_SETUP_REQ(received_msg));
         break;
+      case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
+	      DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
+							&F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(received_msg));
+	      break;
+      case F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE:
+	      DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
+						    &F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(received_msg));
+	      break;
 
       case SCTP_NEW_ASSOCIATION_RESP:
         // 1. store the respon
@@ -175,10 +188,26 @@ void *F1AP_DU_task(void *arg) {
                                     &received_msg->ittiMsg.sctp_data_ind);
         break;
 
+      case F1AP_INITIAL_UL_RRC_MESSAGE: // to rrc
+        LOG_I(F1AP, "DU Task Received F1AP_INITIAL_UL_RRC_MESSAGE\n");
+
+        f1ap_initial_ul_rrc_message_t *msg = &F1AP_INITIAL_UL_RRC_MESSAGE(received_msg);
+        DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(0,0,0,msg->crnti,
+                                                msg->rrc_container,
+                                                msg->rrc_container_length,
+                                                (const int8_t*)msg->du2cu_rrc_container,
+                                                msg->du2cu_rrc_container_length);
+        break;
+
      case F1AP_UL_RRC_MESSAGE: // to rrc
         LOG_I(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n");
-        DU_send_UL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
-                                        &F1AP_UL_RRC_MESSAGE(received_msg));
+        if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) {
+          DU_send_UL_NR_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
+                                             &F1AP_UL_RRC_MESSAGE(received_msg));
+        } else {
+          DU_send_UL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
+                                          &F1AP_UL_RRC_MESSAGE(received_msg));
+        }
         break;
 
       case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC
diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c
index bfd0e8e9af138b395e0e7a25dfb65b214203c68a..b79e9feb588077dd800c2d7791a39ebbbaa6e456 100644
--- a/openair2/F1AP/f1ap_du_ue_context_management.c
+++ b/openair2/F1AP/f1ap_du_ue_context_management.c
@@ -108,51 +108,82 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t       instance,
     f1ap_ue_context_setup_req->cellULConfigured = NULL;
   }
 
-  /* CUtoDURRCInformation */
-  /* Candidate_SpCell_List */
-  /* optional */
-  /* DRXCycle */
-  /* optional */
-  /* ResourceCoordinationTransferContainer */
-  /* SCell_ToBeSetup_List */
-  /* SRBs_ToBeSetup_List */
-  /* DRBs_ToBeSetup_List */
-  /* Decode DRBs_ToBeSetup_List */
-  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
-                             F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List, true);
-  f1ap_ue_context_setup_req->drbs_to_be_setup_length = ie->value.choice.DRBs_ToBeSetup_List.list.count;
-  f1ap_ue_context_setup_req->drbs_to_be_setup = calloc(f1ap_ue_context_setup_req->drbs_to_be_setup_length,
-      sizeof(f1ap_drb_to_be_setup_t));
-  AssertFatal(f1ap_ue_context_setup_req->drbs_to_be_setup,
-              "could not allocate memory for f1ap_ue_context_setup_req->drbs_to_be_setup\n");
-
-  for (i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; ++i) {
-    f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_setup_req->drbs_to_be_setup[i];
-    F1AP_DRBs_ToBeSetup_Item_t *drbs_tobesetup_item_p;
-    drbs_tobesetup_item_p = &((F1AP_DRBs_ToBeSetup_ItemIEs_t *)ie->value.choice.DRBs_ToBeSetup_List.list.array[i])->value.choice.DRBs_ToBeSetup_Item;
-    drb_p->drb_id = drbs_tobesetup_item_p->dRBID;
-    /* TODO in the following, assume only one UP UL TNL is present.
-     * this matches/assumes OAI CU implementation, can be up to 2! */
-    drb_p->up_ul_tnl_length = 1;
-    AssertFatal(drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.count > 0,
-                "no UL UP TNL Information in DRBs to be Setup list\n");
-    F1AP_ULUPTNLInformation_ToBeSetup_Item_t *ul_up_tnl_info_p = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.array[0];
-    F1AP_GTPTunnel_t *ul_up_tnl0 = ul_up_tnl_info_p->uLUPTNLInformation.choice.gTPTunnel;
-    BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&ul_up_tnl0->transportLayerAddress, drb_p->up_ul_tnl[0].tl_address);
-    OCTET_STRING_TO_INT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].gtp_teid);
-
-    switch (drbs_tobesetup_item_p->rLCMode) {
-      case F1AP_RLCMode_rlc_am:
-        drb_p->rlc_mode = RLC_MODE_AM;
-        break;
+  if (RC.nrrrc) {
+    /* RRCContainer */
+    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
+                               F1AP_ProtocolIE_ID_id_RRCContainer, false);
+    if (ie) {
+      /* correct here */
+      f1ap_ue_context_setup_req->rrc_container = malloc(ie->value.choice.RRCContainer.size);
+      memcpy(f1ap_ue_context_setup_req->rrc_container, ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size);
+    } else {
+      LOG_E(F1AP, "can't find RRCContainer in UEContextSetupRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer);
+    }
 
-      default:
-        drb_p->rlc_mode = RLC_MODE_TM;
-        break;
+    // AssertFatal(0, "check configuration, send to appropriate handler\n");
+
+    protocol_ctxt_t ctxt;
+    // ctxt.rnti      = f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], ie->value.choice.GNB_DU_UE_F1AP_ID);
+    ctxt.rnti = 0x1234;
+    ctxt.module_id = instance;
+    ctxt.instance  = instance;
+    ctxt.enb_flag  = 1;
+
+    mem_block_t *pdcp_pdu_p = NULL;
+    pdcp_pdu_p = get_free_mem_block(ie->value.choice.RRCContainer.size, __func__);
+    if (pdcp_pdu_p != NULL) {
+      memset(pdcp_pdu_p->data, 0, ie->value.choice.RRCContainer.size);
+      memcpy(&pdcp_pdu_p->data[0], ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size);
+
+      /* for rfsim */
+      du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, ie->value.choice.RRCContainer.size, pdcp_pdu_p);
+    }
+  } else {
+    /* CUtoDURRCInformation */
+    /* Candidate_SpCell_List */
+    /* optional */
+    /* DRXCycle */
+    /* optional */
+    /* ResourceCoordinationTransferContainer */
+    /* SCell_ToBeSetup_List */
+    /* SRBs_ToBeSetup_List */
+    /* DRBs_ToBeSetup_List */
+    /* Decode DRBs_ToBeSetup_List */
+    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
+                               F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List, true);
+    f1ap_ue_context_setup_req->drbs_to_be_setup_length = ie->value.choice.DRBs_ToBeSetup_List.list.count;
+    f1ap_ue_context_setup_req->drbs_to_be_setup = calloc(f1ap_ue_context_setup_req->drbs_to_be_setup_length,
+                                                         sizeof(f1ap_drb_to_be_setup_t));
+    AssertFatal(f1ap_ue_context_setup_req->drbs_to_be_setup,
+                "could not allocate memory for f1ap_ue_context_setup_req->drbs_to_be_setup\n");
+
+    for (i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; ++i) {
+      f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_setup_req->drbs_to_be_setup[i];
+      F1AP_DRBs_ToBeSetup_Item_t *drbs_tobesetup_item_p;
+      drbs_tobesetup_item_p = &((F1AP_DRBs_ToBeSetup_ItemIEs_t *)ie->value.choice.DRBs_ToBeSetup_List.list.array[i])->value.choice.DRBs_ToBeSetup_Item;
+      drb_p->drb_id = drbs_tobesetup_item_p->dRBID;
+      /* TODO in the following, assume only one UP UL TNL is present.
+      * this matches/assumes OAI CU implementation, can be up to 2! */
+      drb_p->up_ul_tnl_length = 1;
+      AssertFatal(drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.count > 0,
+                  "no UL UP TNL Information in DRBs to be Setup list\n");
+      F1AP_ULUPTNLInformation_ToBeSetup_Item_t *ul_up_tnl_info_p = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.array[0];
+      F1AP_GTPTunnel_t *ul_up_tnl0 = ul_up_tnl_info_p->uLUPTNLInformation.choice.gTPTunnel;
+      BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&ul_up_tnl0->transportLayerAddress, drb_p->up_ul_tnl[0].tl_address);
+      OCTET_STRING_TO_INT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].gtp_teid);
+
+      switch (drbs_tobesetup_item_p->rLCMode) {
+        case F1AP_RLCMode_rlc_am:
+          drb_p->rlc_mode = RLC_MODE_AM;
+          break;
+
+        default:
+          drb_p->rlc_mode = RLC_MODE_TM;
+          break;
+      }
     }
   }
 
-  AssertFatal(0, "check configuration, send to appropriate handler\n");
   return 0;
 }
 
@@ -511,7 +542,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance) {
 
   /* encode */
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
-    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    LOG_E(F1AP, "Failed to encode F1 UE CONTEXT SETUP RESPONSE\n");
     return -1;
   }
 
@@ -1181,7 +1212,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) {
 
   /* encode */
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
-    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    LOG_E(F1AP, "Failed to encode F1 UE CONTEXT MODIFICATION RESPONSE\n");
     return -1;
   }
 
diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c
index 45f76d3dabf08c2b71ef9f0024cc2d6014c1659f..5aca059ae40d297a607fb9779bac8993cb5b74ab 100644
--- a/openair2/F1AP/f1ap_handlers.c
+++ b/openair2/F1AP/f1ap_handlers.c
@@ -50,7 +50,7 @@ f1ap_message_decoded_callback f1ap_messages_callback[][3] = {
   { CU_handle_F1_SETUP_REQUEST, DU_handle_F1_SETUP_RESPONSE, DU_handle_F1_SETUP_FAILURE }, /* F1Setup */
   { 0, 0, 0 }, /* ErrorIndication */
   { 0, 0, 0 }, /* gNBDUConfigurationUpdate */
-  { 0, 0, 0 }, /* gNBCUConfigurationUpdate */
+  { DU_handle_gNB_CU_CONFIGURATION_UPDATE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE }, /* gNBCUConfigurationUpdate */
   { DU_handle_UE_CONTEXT_SETUP_REQUEST, CU_handle_UE_CONTEXT_SETUP_RESPONSE, 0 }, /* UEContextSetup */
   { DU_handle_UE_CONTEXT_RELEASE_COMMAND, CU_handle_UE_CONTEXT_RELEASE_COMPLETE, 0 }, /* UEContextRelease */
   { 0, 0, 0 }, /* UEContextModification */
diff --git a/openair2/GNB_APP/L1_nr_paramdef.h b/openair2/GNB_APP/L1_nr_paramdef.h
index 88f2cb1615ea01bb18f5e0f0c8131f08b456e0cb..fd22e9273023542aa0376c551078dee85f10be80 100644
--- a/openair2/GNB_APP/L1_nr_paramdef.h
+++ b/openair2/GNB_APP/L1_nr_paramdef.h
@@ -47,7 +47,9 @@
 #define CONFIG_STRING_L1_REMOTE_N_PORTD                    "remote_n_portd"
 #define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE            "tr_n_preference"
 #define CONFIG_STRING_L1_PUSCH_PROC_THREADS                "pusch_proc_threads"
-
+#define CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD              "pucch0_dtx_threshold"
+#define CONFIG_STRING_L1_PRACH_DTX_THRESHOLD               "prach_dtx_threshold"
+#define CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD               "pusch_dtx_threshold"
 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            L1 configuration parameters                                                                             */
 /*   optname                                         helpstr   paramflags    XXXptr              defXXXval                  type           numelt     */
@@ -62,7 +64,10 @@
 {CONFIG_STRING_L1_REMOTE_N_PORTC,                    NULL,      0,         uptr:NULL,           defintval:50030,           TYPE_UINT,     0},         \
 {CONFIG_STRING_L1_LOCAL_N_PORTD,                     NULL,      0,         uptr:NULL,           defintval:50031,           TYPE_UINT,     0},         \
 {CONFIG_STRING_L1_REMOTE_N_PORTD,                    NULL,      0,         uptr:NULL,           defintval:50031,           TYPE_UINT,     0},         \
-{CONFIG_STRING_L1_PUSCH_PROC_THREADS,                NULL,      0,         uptr:NULL,           defintval:3,               TYPE_UINT,     0} \
+{CONFIG_STRING_L1_PUSCH_PROC_THREADS,                NULL,      0,         uptr:NULL,           defintval:1,               TYPE_UINT,     0},         \
+{CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD,              NULL,      0,         uptr:NULL,           defintval:100,             TYPE_UINT,     0},         \
+{CONFIG_STRING_L1_PRACH_DTX_THRESHOLD,               NULL,      0,         uptr:NULL,           defintval:200,             TYPE_UINT,     0},         \
+{CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD,               NULL,      0,         uptr:NULL,           defintval:50,              TYPE_UINT,     0}          \
 }
 #define L1_CC_IDX                                          0
 #define L1_TRANSPORT_N_PREFERENCE_IDX                      1
@@ -74,6 +79,9 @@
 #define L1_LOCAL_N_PORTD_IDX                               7
 #define L1_REMOTE_N_PORTD_IDX                              8
 #define L1_PUSCH_PROC_THREADS                              9
+#define L1_PUCCH0_DTX_THRESHOLD                            10
+#define L1_PRACH_DTX_THRESHOLD                             11
+#define L1_PUSCH_DTX_THRESHOLD                             12
 
 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/
 #endif
diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h
index 60b40cb349b3143dcd05b248ea9f37b41f4cf8f0..bf8b32f591e96b20c86e49a72fa211c254c762bc 100644
--- a/openair2/GNB_APP/MACRLC_nr_paramdef.h
+++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h
@@ -56,6 +56,10 @@
 #define CONFIG_STRING_MACRLC_LOCAL_S_PORTD                 "local_s_portd"
 #define CONFIG_STRING_MACRLC_REMOTE_S_PORTD                "remote_s_portd"
 #define CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY    "ulsch_max_slots_inactivity"
+#define CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10             "pusch_TargetSNRx10"
+#define CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10             "pucch_TargetSNRx10"
+#define CONFIG_STRING_MACRLC_PUCCHFAILURETHRES             "pucch_FailureThres"
+#define CONFIG_STRING_MACRLC_PUSCHFAILURETHRES             "pusch_FailureThres"
 
 /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            MacRLC  configuration parameters                                                                           */
@@ -80,6 +84,10 @@
 {CONFIG_STRING_MACRLC_LOCAL_S_PORTD,                     NULL,     0,          uptr:NULL,           defintval:50021,           TYPE_UINT,     0},        \
 {CONFIG_STRING_MACRLC_REMOTE_S_PORTD,                    NULL,     0,          uptr:NULL,           defintval:50021,           TYPE_UINT,     0},        \
 {CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY,        "Maximum number of slots before a UE is scheduled ULSCH due to inactivity", 0, uptr:NULL, defintval:200, TYPE_UINT, 0}, \
+{CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10,                 NULL,     0,          iptr:NULL,           defintval:200,             TYPE_INT,      0},        \
+{CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10,                 NULL,     0,          iptr:NULL,           defintval:150,             TYPE_INT,      0},        \
+{CONFIG_STRING_MACRLC_PUCCHFAILURETHRES,                 NULL,     0,          iptr:NULL,           defintval:10,              TYPE_INT,      0},        \
+{CONFIG_STRING_MACRLC_PUSCHFAILURETHRES,                 NULL,     0,          iptr:NULL,           defintval:10,              TYPE_INT,      0},        \
 }
 #define MACRLC_CC_IDX                                          0
 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX                      1
@@ -99,5 +107,9 @@
 #define MACRLC_LOCAL_S_PORTD_IDX                               15
 #define MACRLC_REMOTE_S_PORTD_IDX                              16
 #define MACRLC_ULSCH_MAX_SLOTS_INACTIVITY                      17
+#define MACRLC_PUSCHTARGETSNRX10_IDX                           17
+#define MACRLC_PUCCHTARGETSNRX10_IDX                           18
+#define MACRLC_PUCCHFAILURETHRES_IDX                           19
+#define MACRLC_PUSCHFAILURETHRES_IDX                           20
 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #endif
diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h
index a410bcac6a701e95e53ba04318fd489a25d4afd3..c1cb4afdd906d2d5b6fc77e753e96318bd1c9a0c 100644
--- a/openair2/GNB_APP/RRC_nr_paramsvalues.h
+++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h
@@ -141,6 +141,7 @@
 #define GNB_CONFIG_STRING_PUCCHGROUPHOPPING                     "pucchGroupHopping"
 #define GNB_CONFIG_STRING_HOPPINGID                             "hoppingId"
 #define GNB_CONFIG_STRING_P0NOMINAL                             "p0_nominal"
+#define GNB_CONFIG_STRING_PUCCHRES                              "pucch_ResourceCommon"
 #define GNB_CONFIG_STRING_INITIALULBWPK2_0                      "initialULBWPk2_0"
 #define GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_0             "initialULBWPmappingType_0"
 #define GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_0    "initialULBWPstartSymbolAndLength_0"
@@ -413,6 +414,7 @@
 {GNB_CONFIG_STRING_PUCCHGROUPHOPPING, NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_GroupHopping,defint64val:NR_PUCCH_ConfigCommon__pucch_GroupHopping_neither,TYPE_INT64,0},\
 {GNB_CONFIG_STRING_HOPPINGID, NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->hoppingId,defint64val:40,TYPE_INT64,0},\
 {GNB_CONFIG_STRING_P0NOMINAL, NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal,defint64val:1,TYPE_INT64,0},\
+{GNB_CONFIG_STRING_PUCCHRES, NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon,defint64val:0,TYPE_INT64,0},\
 {GNB_CONFIG_STRING_SSBPOSITIONSINBURSTPR,NULL,0,uptr:&scc->ssb_PositionsInBurst->present,defuintval:NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap,TYPE_UINT,0/*140*/}, \
 {GNB_CONFIG_STRING_SSBPOSITIONSINBURST,NULL,0,u64ptr:&ssb_bitmap,defintval:0xff,TYPE_UINT64,0}, \
 {GNB_CONFIG_STRING_REFERENCESUBCARRIERSPACING,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing,defint64val:NR_SubcarrierSpacing_kHz30,TYPE_INT64,0},\
diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c
index b525e7edb7cc670ee2102d8848e5ff0d9b97c2a6..66302d056bdd75cbdd757e3cb11deb8485cad6b1 100644
--- a/openair2/GNB_APP/gnb_app.c
+++ b/openair2/GNB_APP/gnb_app.c
@@ -29,6 +29,10 @@
 
 #include <string.h>
 #include <stdio.h>
+#include <nr_pdcp/nr_pdcp.h>
+#include <softmodem-common.h>
+#include <split_headers.h>
+#include <proto_agent.h>
 
 #include "gnb_app.h"
 #include "gnb_config.h"
@@ -43,7 +47,9 @@
 #include "sctp_eNB_task.h"
 #include "gtpv1u_eNB_task.h"
 #include "PHY/INIT/phy_init.h" 
-
+#include "f1ap_cu_task.h"
+#include "f1ap_du_task.h"
+#include "nfapi/oai_integration/vendor_ext.h"
 extern unsigned char NB_gNB_INST;
 
 extern RAN_CONTEXT_t RC;
@@ -61,7 +67,7 @@ static void configure_nr_rrc(uint32_t gnb_id)
   if (RC.nrrrc[gnb_id]) {
     RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]);
     
-
+    LOG_I(GNB_APP, "RRC starting with node type %d\n", RC.nrrrc[gnb_id]->node_type);
     LOG_I(GNB_APP,"Sending configuration message to NR_RRC task\n");
     itti_send_msg_to_task (TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
 
@@ -82,26 +88,25 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//,
     {
       if(NGAP_CONF_MODE){
         ngap_register_gnb_req_t *ngap_register_gNB; //Type Temporarily reuse
-        
-        // note:  there is an implicit relationship between the data structure and the message name 
+          
+        // note:  there is an implicit relationship between the data structure and the message name
         msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NGAP_REGISTER_GNB_REQ); //Message Temporarily reuse
 
         RCconfig_NR_NG(msg_p, gnb_id);
-		
-        ngap_register_gNB = &NGAP_REGISTER_GNB_REQ(msg_p); //Message Temporarily reuse
 
-		LOG_I(GNB_APP,"default drx %d\n",ngap_register_gNB->default_drx);
+        ngap_register_gNB = &NGAP_REGISTER_GNB_REQ(msg_p); //Message Temporarily reuse
 
-		itti_send_msg_to_task (TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
-	  }
+        LOG_I(GNB_APP,"default drx %d\n",ngap_register_gNB->default_drx);
 
+        itti_send_msg_to_task (TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
+      }
       if (gnb_id == 0) RCconfig_nr_gtpu();
+    }
 
-	  LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id));
+    LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id));
 
-      register_gnb_pending++;
+    register_gnb_pending++;
     }
-  }
 
   return register_gnb_pending;
 }
@@ -126,15 +131,42 @@ static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end)
   return register_gnb_x2_pending;
 }
 
+/*------------------------------------------------------------------------------*/
+
+static void init_pdcp(void) {
+  if (!NODE_IS_DU(RC.nrrrc[0]->node_type)) {
+    pdcp_layer_init();
+    uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
+                             (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
+    if (IS_SOFTMODEM_NOS1) {
+      LOG_I(PDCP, "IS_SOFTMODEM_NOS1 option enabled\n");
+      pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT;
+    }
+
+    pdcp_module_init(pdcp_initmask);
+
+    if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
+      LOG_I(PDCP, "node is CU, pdcp send rlc_data_req by proto_agent \n");
+      pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req);
+    } else {
+      LOG_I(PDCP, "node is gNB \n");
+      pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
+      pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
+    }
+  } else {
+    LOG_I(PDCP, "node is DU, rlc send pdcp_data_ind by proto_agent \n");
+    pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind);
+  }
+}
 
 /*------------------------------------------------------------------------------*/
+
 void *gNB_app_task(void *args_p)
 {
 
   uint32_t                        gnb_nb = RC.nb_nr_inst; 
   uint32_t                        gnb_id_start = 0;
   uint32_t                        gnb_id_end = gnb_id_start + gnb_nb;
-
   uint32_t                        gnb_id;
   MessageDef                      *msg_p           = NULL;
   const char                      *msg_name        = NULL;
@@ -143,11 +175,12 @@ void *gNB_app_task(void *args_p)
   /* for no gcc warnings */
   (void)instance;
 
+  int cell_to_activate = 0;
   itti_mark_task_ready (TASK_GNB_APP);
 
   LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__);
 
-  RCconfig_nr_macrlc();
+  if (RC.nb_nr_macrlc_inst>0) RCconfig_nr_macrlc();
 
   LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
 
@@ -169,19 +202,43 @@ void *gNB_app_task(void *args_p)
     configure_nr_rrc(gnb_id);
   }
 
+  if (RC.nb_nr_inst > 0)  {
+    init_pdcp();
+  }
+
   if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type)
 	  LOG_I(X2AP, "X2AP enabled \n");
 	  __attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
   }
 
-  if (AMF_MODE_ENABLED) {
-  /* Try to register each gNB */
-  //registered_gnb = 0;
-  __attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p);
-  } else {
-  /* Start L2L1 task */
-    msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, INITIALIZE_MESSAGE);
-    itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p);
+  /* For the CU case the gNB registration with the AMF might have to take place after the F1 setup, as the PLMN info
+     * can originate from the DU. Add check on whether x2ap is enabled to account for ENDC NSA scenario.*/
+  if ((AMF_MODE_ENABLED || is_x2ap_enabled()) && !NODE_IS_DU(RC.nrrrc[0]->node_type) && !NODE_IS_CU(RC.nrrrc[0]->node_type)) {
+    /* Try to register each gNB */
+    //registered_gnb = 0;
+    __attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);
+  }
+
+  if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
+
+     if (itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL) < 0) {
+        LOG_E(F1AP, "Create task for F1AP CU failed\n");
+        AssertFatal(1==0,"exiting");
+     }
+  }
+
+  if (NODE_IS_DU(RC.nrrrc[0]->node_type)) {
+
+    if (itti_create_task(TASK_DU_F1, F1AP_DU_task, NULL) < 0) {
+       LOG_E(F1AP, "Create task for F1AP DU failed\n");
+       AssertFatal(1==0,"exiting");
+    }
+    // configure F1AP here for F1C
+    LOG_I(GNB_APP,"ngran_gNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n");
+    msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, F1AP_SETUP_REQ);
+    RCconfig_NR_DU_F1(msg_p, 0);
+    
+    itti_send_msg_to_task (TASK_DU_F1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
   }
 
   do {
@@ -245,6 +302,29 @@ void *gNB_app_task(void *args_p)
 */
       break;
 
+    case F1AP_SETUP_RESP:
+      AssertFatal(NODE_IS_DU(RC.nrrrc[0]->node_type), "Should not have received F1AP_SETUP_RESP in CU/gNB\n");
+
+      LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
+      F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate);
+      cell_to_activate = F1AP_SETUP_RESP(msg_p).num_cells_to_activate;
+      
+      gNB_app_handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p));
+
+      break;
+    case F1AP_GNB_CU_CONFIGURATION_UPDATE:
+      AssertFatal(NODE_IS_DU(RC.nrrrc[0]->node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n");
+
+      LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
+      F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).gNB_CU_name,F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate);
+      
+      cell_to_activate += F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate;
+      gNB_app_handle_f1ap_gnb_cu_configuration_update(&F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p));
+
+      /* Check if at least gNB is registered with one AMF */
+      AssertFatal(cell_to_activate == 1,"No cells to activate or cells > 1 %d\n",cell_to_activate);
+
+      break;
     case NGAP_DEREGISTERED_GNB_IND:
       LOG_W(GNB_APP, "[gNB %ld] Received %s: associated AMF %d\n", instance, msg_name,
             NGAP_DEREGISTERED_GNB_IND(msg_p).nb_amf);
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index b9f394dad9d5199ea6729a5dcb4a8530539ff4ed..2a75e5955ee8095700893c23eb12bf6e25ade2b1 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -43,6 +43,7 @@
 #include "ngap_gNB.h"
 #include "sctp_eNB_task.h"
 #include "sctp_default_values.h"
+#include "F1AP_CauseRadioNetwork.h"
 // #include "SystemInformationBlockType2.h"
 // #include "LAYER2/MAC/extern.h"
 // #include "LAYER2/MAC/proto.h"
@@ -79,7 +80,12 @@
 #include "NR_ControlResourceSet.h"
 #include "NR_EUTRA-MBSFN-SubframeConfig.h"
 
+#include "RRC/NR/MESSAGES/asn1_msg.h"
+#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h"
+
 extern uint16_t sf_ahead;
+int macrlc_has_f1 = 0;
+extern ngran_node_t node_type;
 
 extern int config_check_band_frequencies(int ind, int16_t band, uint64_t downlink_frequency,
                                          int32_t uplink_frequency_offset, uint32_t  frame_type);
@@ -323,6 +329,10 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
     free(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing);
     scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing=NULL;
   }
+
+  // check pucch_ResourceConfig
+  AssertFatal(*scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon < 2,
+	      "pucch_ResourceConfig should be 0 or 1 for now\n");
 }
 
 /* Function to allocate dedicated serving cell config strutures */
@@ -605,11 +615,13 @@ void RCconfig_NR_L1(void) {
         RC.gNB[j]                       = (PHY_VARS_gNB *)malloc(sizeof(PHY_VARS_gNB));
         LOG_I(NR_PHY,"RC.gNB[%d] = %p\n",j,RC.gNB[j]);
         memset(RC.gNB[j],0,sizeof(PHY_VARS_gNB));
-	RC.gNB[j]->Mod_id  = j;
+	      RC.gNB[j]->Mod_id  = j;
       }
 
       RC.gNB[j]->pusch_proc_threads = *(L1_ParamList.paramarray[j][L1_PUSCH_PROC_THREADS].uptr);
-
+      RC.gNB[j]->pucch0_thres       = *(L1_ParamList.paramarray[j][L1_PUCCH0_DTX_THRESHOLD].uptr);
+      RC.gNB[j]->prach_thres        = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_THRESHOLD].uptr);
+      RC.gNB[j]->pusch_thres        = *(L1_ParamList.paramarray[j][L1_PUSCH_DTX_THRESHOLD].uptr);
       if(strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) {
         //sf_ahead = 2; // Need 4 subframe gap between RX and TX
       }else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) {
@@ -679,10 +691,25 @@ void RCconfig_nr_macrlc() {
 
     for (j=0;j<RC.nb_nr_macrlc_inst;j++) {
       RC.nb_nr_mac_CC[j] = *(MacRLC_ParamList.paramarray[j][MACRLC_CC_IDX].iptr);
-
+      RC.nrmac[j]->pusch_target_snrx10                   = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCHTARGETSNRX10_IDX].iptr);
+      RC.nrmac[j]->pucch_target_snrx10                   = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCHTARGETSNRX10_IDX].iptr);
+      RC.nrmac[j]->pucch_failure_thres                   = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCHFAILURETHRES_IDX].iptr);
+      RC.nrmac[j]->pusch_failure_thres                   = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCHFAILURETHRES_IDX].iptr);
+      
       if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) {
   // check number of instances is same as RRC/PDCP
   
+      }else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "f1") == 0) {
+        printf("Configuring F1 interfaces for MACRLC\n");
+        RC.nrmac[j]->eth_params_n.local_if_name            = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr));
+        RC.nrmac[j]->eth_params_n.my_addr                  = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr));
+        RC.nrmac[j]->eth_params_n.remote_addr              = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr));
+        RC.nrmac[j]->eth_params_n.my_portc                 = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr);
+        RC.nrmac[j]->eth_params_n.remote_portc             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr);
+        RC.nrmac[j]->eth_params_n.my_portd                 = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr);
+        RC.nrmac[j]->eth_params_n.remote_portd             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);;
+        RC.nrmac[j]->eth_params_n.transp_preference        = ETH_UDP_MODE;
+        macrlc_has_f1                                      = 1;
       }else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) {
         RC.nrmac[j]->eth_params_n.local_if_name            = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr));
         RC.nrmac[j]->eth_params_n.my_addr                  = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr));
@@ -708,8 +735,6 @@ void RCconfig_nr_macrlc() {
         RC.nrmac[j]->eth_params_s.remote_portd             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr);
         RC.nrmac[j]->eth_params_s.transp_preference        = ETH_UDP_MODE;
 
-        //sf_ahead = 2; // Cannot cope with 4 subframes between RX and TX - set it to 2
-
         printf("**************** vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc);
         configure_nr_nfapi_vnf(RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc);
         printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc);
@@ -719,7 +744,8 @@ void RCconfig_nr_macrlc() {
       RC.nrmac[j]->ulsch_max_slots_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_SLOTS_INACTIVITY].uptr);
     }//  for (j=0;j<RC.nb_nr_macrlc_inst;j++)
   }else {// MacRLC_ParamList.numelt > 0
-    AssertFatal (0,"No " CONFIG_STRING_MACRLC_LIST " configuration found");     
+    LOG_E(PHY,"No %s configuration found\n", CONFIG_STRING_MACRLC_LIST);
+    // AssertFatal (0,"No " CONFIG_STRING_MACRLC_LIST " configuration found");     
   }
 
 }
@@ -824,7 +850,8 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
   int                    num_gnbs                                                      = 0;
   char aprefix[MAX_OPTNAME_SIZE*2 + 8];
   int32_t                gnb_id                                                        = 0;
-  int k;
+  int                    k                                                             = 0;
+
   paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
   ////////// Identification parameters
   paramdef_t GNBParams[]  = GNBPARAMS_DESC;
@@ -940,6 +967,41 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
     fix_scd(scd);
 
     printf("NRRRC %d: Southbound Transport %s\n",i,*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr));
+
+    if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) {
+      paramdef_t SCTPParams[]  = GNBSCTPPARAMS_DESC;
+      char aprefix[MAX_OPTNAME_SIZE*2 + 8];
+      sprintf(aprefix,"%s.[%u].%s",GNB_CONFIG_STRING_GNB_LIST,i,GNB_CONFIG_STRING_SCTP_CONFIG);
+      config_get(SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix);
+      rrc->node_id        = *(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr);
+      LOG_I(GNB_APP,"F1AP: gNB_CU_id[%d] %d\n",k,rrc->node_id);
+      rrc->node_name = strdup(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr));
+      LOG_I(GNB_APP,"F1AP: gNB_CU_name[%d] %s\n",k,rrc->node_name);
+      rrc->eth_params_s.local_if_name            = strdup(*(GNBParamList.paramarray[i][GNB_LOCAL_S_IF_NAME_IDX].strptr));
+      rrc->eth_params_s.my_addr                  = strdup(*(GNBParamList.paramarray[i][GNB_LOCAL_S_ADDRESS_IDX].strptr));
+      rrc->eth_params_s.remote_addr              = strdup(*(GNBParamList.paramarray[i][GNB_REMOTE_S_ADDRESS_IDX].strptr));
+      rrc->eth_params_s.my_portc                 = *(GNBParamList.paramarray[i][GNB_LOCAL_S_PORTC_IDX].uptr);
+      rrc->eth_params_s.remote_portc             = *(GNBParamList.paramarray[i][GNB_REMOTE_S_PORTC_IDX].uptr);
+      rrc->eth_params_s.my_portd                 = *(GNBParamList.paramarray[i][GNB_LOCAL_S_PORTD_IDX].uptr);
+      rrc->eth_params_s.remote_portd             = *(GNBParamList.paramarray[i][GNB_REMOTE_S_PORTD_IDX].uptr);
+      rrc->eth_params_s.transp_preference        = ETH_UDP_MODE;
+      rrc->node_type                             = ngran_gNB_CU;
+      rrc->sctp_in_streams                       = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
+      rrc->sctp_out_streams                      = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr);
+    } else {
+      // set to ngran_gNB for now, it will get set to ngran_gNB_DU if macrlc entity which uses F1 is present
+      // Note: we will have to handle the case of ngran_ng_gNB_DU
+      if (macrlc_has_f1 == 0) {
+        rrc->node_type = ngran_gNB;
+        LOG_I(NR_RRC,"Setting node_type to ngran_gNB\n");
+      } else {
+        rrc->node_type = ngran_gNB_DU;
+        LOG_I(NR_RRC,"Setting node_type to ngran_gNB_DU\n");
+      }
+    }
+
+    rrc->nr_cellid        = (uint64_t)*(GNBParamList.paramarray[i][GNB_NRCELLID_IDX].u64ptr);
+
     if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) {
       
     } else if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "cudu") == 0) {
@@ -1006,16 +1068,13 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
         NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr;
         printf("pusch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PUSCH_ANTENNAPORTS_IDX].iptr);
         NRRRC_CONFIGURATION_REQ (msg_p).pusch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PUSCH_ANTENNAPORTS_IDX].iptr;
-        printf("pusch_TargetSNRx10 %d\n",*GNBParamList.paramarray[i][GNB_PUSCH_TARGETPOW_X10_IDX].iptr);
-        NRRRC_CONFIGURATION_REQ (msg_p).pusch_TargetSNRx10 = *GNBParamList.paramarray[i][GNB_PUSCH_TARGETPOW_X10_IDX].iptr;
-        printf("pucch_TargetSNRx10 %d\n",*GNBParamList.paramarray[i][GNB_PUCCH_TARGETPOW_X10_IDX].iptr);
-        NRRRC_CONFIGURATION_REQ (msg_p).pucch_TargetSNRx10 = *GNBParamList.paramarray[i][GNB_PUCCH_TARGETPOW_X10_IDX].iptr;
         NRRRC_CONFIGURATION_REQ (msg_p).scc = scc;
         NRRRC_CONFIGURATION_REQ (msg_p).scd = scd;
 
 	  
       }//
     }//End for (k=0; k <num_gnbs ; k++)
+    memcpy(&rrc->configuration, &NRRRC_CONFIGURATION_REQ(msg_p), sizeof(NRRRC_CONFIGURATION_REQ(msg_p)));
   }//End if (num_gnbs>0)
 
   config_security(rrc);
@@ -1077,15 +1136,17 @@ int RCconfig_nr_gtpu(void ) {
         IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
         LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
         GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U;
+        strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address);
+        sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", gnb_port_for_NGU);
       } else {// TODO SA
         message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_GNB_NG_REQ);
         AssertFatal(message!=NULL,"");
         IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_GNB_NG_REQ(message).gnb_ip_address_for_NGu_up, "BAD IP ADDRESS FORMAT FOR gNB NG_U !\n" );
         LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_GNB_NG_REQ(message).gnb_ip_address_for_NGu_up);
         GTPV1U_GNB_NG_REQ(message).gnb_port_for_NGu_up = gnb_port_for_NGU;
+        strcpy(GTPV1U_GNB_NG_REQ(message).addrStr,address);
+        sprintf(GTPV1U_GNB_NG_REQ(message).portStr,"%d", gnb_port_for_NGU);
       }
-    strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address);
-    sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", gnb_port_for_NGU);
      itti_send_msg_to_task (TASK_VARIABLE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
     } else
     LOG_E(GTPU,"invalid address for NGU\n");
@@ -1264,10 +1325,12 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) {
                 NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv6 = 1;
               }
 
+              /* not in configuration yet ...
               if (NGParamList.paramarray[l][GNB_AMF_BROADCAST_PLMN_INDEX].iptr)
                 NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] = NGParamList.paramarray[l][GNB_AMF_BROADCAST_PLMN_INDEX].numelt;
               else
                 NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] = 0;
+              */
 
               AssertFatal(NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] <= NGAP_REGISTER_GNB_REQ(msg_p).num_plmn,
                           "List of broadcast PLMN to be sent to AMF can not be longer than actual "
@@ -1374,7 +1437,7 @@ void NRRCConfig(void) {
 
 	// Get num MACRLC instances
   config_getlist( &MACRLCParamList,NULL,0, NULL);
-  RC.nb_macrlc_inst  = MACRLCParamList.numelt;
+  RC.nb_nr_macrlc_inst  = MACRLCParamList.numelt;
   // Get num L1 instances
   config_getlist( &L1ParamList,NULL,0, NULL);
   RC.nb_nr_L1_inst = L1ParamList.numelt;
@@ -1593,3 +1656,461 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
   return 0;
 }
 
+int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) {
+  int k;
+  paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
+  paramdef_t GNBParams[]  = GNBPARAMS_DESC;
+  paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
+  config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL);
+  int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
+  AssertFatal (i < num_gnbs,
+               "Failed to parse config file no %uth element in %s \n",i, GNB_CONFIG_STRING_ACTIVE_GNBS);
+
+  if (num_gnbs > 0) {
+    // Output a list of all eNBs.
+    config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
+    AssertFatal(GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr != NULL,
+                "gNB id %u is not defined in configuration file\n",i);
+    F1AP_SETUP_REQ (msg_p).num_cells_available = 0;
+
+    for (k=0; k <num_gnbs ; k++) {
+      if (strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[k], *(GNBParamList.paramarray[i][GNB_GNB_NAME_IDX].strptr)) == 0) {
+        char aprefix[MAX_OPTNAME_SIZE*2 + 8];
+        sprintf(aprefix,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k);
+        paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC;
+        paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0};
+        /* map parameter checking array instances to parameter definition array instances */
+        checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
+
+        for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
+          PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
+
+        config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
+        paramdef_t SCTPParams[]  = SCTPPARAMS_DESC;
+        F1AP_SETUP_REQ (msg_p).num_cells_available++;
+        F1AP_SETUP_REQ (msg_p).gNB_DU_id        = *(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr);
+        LOG_I(GNB_APP,"F1AP: gNB_DU_id[%d] %ld\n",k,F1AP_SETUP_REQ (msg_p).gNB_DU_id);
+        F1AP_SETUP_REQ (msg_p).gNB_DU_name      = strdup(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr));
+        LOG_I(GNB_APP,"F1AP: gNB_DU_name[%d] %s\n",k,F1AP_SETUP_REQ (msg_p).gNB_DU_name);
+        F1AP_SETUP_REQ (msg_p).tac[k]              = *GNBParamList.paramarray[i][GNB_TRACKING_AREA_CODE_IDX].uptr;
+        LOG_I(GNB_APP,"F1AP: tac[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).tac[k]);
+        F1AP_SETUP_REQ (msg_p).mcc[k]              = *PLMNParamList.paramarray[0][GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
+        LOG_I(GNB_APP,"F1AP: mcc[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mcc[k]);
+        F1AP_SETUP_REQ (msg_p).mnc[k]              = *PLMNParamList.paramarray[0][GNB_MOBILE_NETWORK_CODE_IDX].uptr;
+        LOG_I(GNB_APP,"F1AP: mnc[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mnc[k]);
+        F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] = *PLMNParamList.paramarray[0][GNB_MNC_DIGIT_LENGTH].u8ptr;
+        LOG_I(GNB_APP,"F1AP: mnc_digit_length[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mnc_digit_length[k]);
+        AssertFatal((F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] == 2) ||
+                    (F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] == 3),
+                    "BAD MNC DIGIT LENGTH %d",
+                    F1AP_SETUP_REQ (msg_p).mnc_digit_length[k]);
+        F1AP_SETUP_REQ (msg_p).nr_cellid[k] = (uint64_t)*(GNBParamList.paramarray[i][GNB_NRCELLID_IDX].u64ptr);
+        LOG_I(GNB_APP,"F1AP: nr_cellid[%d] %ld\n",k,F1AP_SETUP_REQ (msg_p).nr_cellid[k]);
+        LOG_I(GNB_APP,"F1AP: CU_ip4_address in DU %s\n",RC.nrmac[k]->eth_params_n.remote_addr);
+        LOG_I(GNB_APP,"FIAP: CU_ip4_address in DU %p, strlen %d\n",F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4_address,(int)strlen(RC.nrmac[k]->eth_params_n.remote_addr));
+        F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv6 = 0;
+        F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4 = 1;
+        //strcpy(F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv6_address, "");
+        strcpy(F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4_address, RC.nrmac[k]->eth_params_n.remote_addr);
+        LOG_I(GNB_APP,"F1AP: DU_ip4_address in DU %s\n",RC.nrmac[k]->eth_params_n.my_addr);
+        LOG_I(GNB_APP,"FIAP: DU_ip4_address in DU %p, strlen %d\n",F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4_address,(int)strlen(RC.nrmac[k]->eth_params_n.my_addr));
+        F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv6 = 0;
+        F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4 = 1;
+        //strcpy(F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv6_address, "");
+        strcpy(F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4_address, RC.nrmac[k]->eth_params_n.my_addr);
+        //strcpy(F1AP_SETUP_REQ (msg_p).CU_ip_address[l].ipv6_address,*(F1ParamList.paramarray[l][ENB_CU_IPV6_ADDRESS_IDX].strptr));
+        sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_SCTP_CONFIG);
+        config_get(SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix);
+        F1AP_SETUP_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
+        F1AP_SETUP_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr);
+        gNB_RRC_INST *rrc = RC.nrrrc[k];
+        // wait until RRC cell information is configured
+        int cell_info_configured = 0;
+
+        do {
+          LOG_I(GNB_APP,"ngran_gNB_DU: Waiting for basic cell configuration\n");
+          usleep(100000);
+          pthread_mutex_lock(&rrc->cell_info_mutex);
+          cell_info_configured = rrc->cell_info_configured;
+          pthread_mutex_unlock(&rrc->cell_info_mutex);
+        } while (cell_info_configured == 0);
+
+        rrc->configuration.mcc[0] = F1AP_SETUP_REQ (msg_p).mcc[k];
+        rrc->configuration.mnc[0] = F1AP_SETUP_REQ (msg_p).mnc[k];
+        rrc->configuration.tac    = F1AP_SETUP_REQ (msg_p).tac[k];
+        rrc->nr_cellid = F1AP_SETUP_REQ (msg_p).nr_cellid[k];
+        F1AP_SETUP_REQ (msg_p).nr_pci[k]    = *rrc->configuration.scc->physCellId;
+        F1AP_SETUP_REQ (msg_p).num_ssi[k] = 0;
+
+        if (rrc->configuration.scc->tdd_UL_DL_ConfigurationCommon) {
+          LOG_I(GNB_APP,"ngran_DU: Configuring Cell %d for TDD\n",k);
+          F1AP_SETUP_REQ (msg_p).fdd_flag = 0;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nr_arfcn = rrc->configuration.scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.scs = rrc->configuration.scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nrb = rrc->configuration.scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.num_frequency_bands = 1;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nr_band[0] = *rrc->configuration.scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.sul_active              = 0;
+        } else {
+          /***************** for test *****************/
+          LOG_I(GNB_APP,"ngran_DU: Configuring Cell %d for FDD\n",k);
+          F1AP_SETUP_REQ (msg_p).fdd_flag = 1;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_arfcn             = 26200UL;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nr_arfcn             = 26200UL;
+          // For LTE use scs field to carry prefix type and number of antennas
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_scs                  = 0;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_scs                  = 0;
+          // use nrb field to hold LTE N_RB_DL (0...5)
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nrb                  = 3;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nrb                  = 3;
+          // RK: we need to check there value for FDD's frequency_bands DL/UL
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_num_frequency_bands  = 1;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nr_band[0]           = 7;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_num_frequency_bands  = 1;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_band[0]           = 7;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_num_sul_frequency_bands  = 0;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nr_sul_band[0]           = 7;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_num_sul_frequency_bands  = 0;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_sul_band[0]           = 7;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.sul_active              = 0;
+          /***************** for test *****************/
+        }
+
+        F1AP_SETUP_REQ (msg_p).measurement_timing_information[k]             = "0";
+        F1AP_SETUP_REQ (msg_p).ranac[k]                                      = 0;
+        F1AP_SETUP_REQ (msg_p).mib[k]                                        = rrc->carrier.MIB;
+        F1AP_SETUP_REQ (msg_p).sib1[k]                                       = rrc->carrier.SIB1;
+        F1AP_SETUP_REQ (msg_p).mib_length[k]                                 = rrc->carrier.sizeof_MIB;
+        F1AP_SETUP_REQ (msg_p).sib1_length[k]                                = rrc->carrier.sizeof_SIB1;
+        break;
+      }
+    }
+  }
+  return 0;
+}
+
+int du_check_plmn_identity(rrc_gNB_carrier_data_t *carrier,uint16_t mcc,uint16_t mnc,uint8_t mnc_digit_length) {
+  NR_SIB1_t *sib1 = carrier->siblock1->message.choice.c1->choice.systemInformationBlockType1;
+  AssertFatal(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->plmn_IdentityList.list.count > 0,
+              "plmn info isn't there\n");
+  AssertFatal(mnc_digit_length == 2 || mnc_digit_length == 3,
+              "impossible mnc_digit_length %d\n", mnc_digit_length);
+  NR_PLMN_Identity_t *plmn_Identity = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]
+                                            ->plmn_IdentityList.list.array[0];
+
+  // check if mcc is different and return failure if so
+  if (mcc !=
+      ((*plmn_Identity->mcc->list.array[0])*100)+
+      ((*plmn_Identity->mcc->list.array[1])*10) +
+      (*plmn_Identity->mcc->list.array[2])) {
+    LOG_E(GNB_APP, "mcc in F1AP_SETUP_RESP message is different from mcc in DU \n");
+    return(0);
+  }
+
+  // check that mnc digit length is different and return failure if so
+  if (mnc_digit_length != plmn_Identity->mnc.list.count) {
+    LOG_E(GNB_APP, "mnc(length: %d) in F1AP_SETUP_RESP message is different from mnc(length: %d) in DU \n",
+                    mnc_digit_length, plmn_Identity->mnc.list.count);
+    return 0;
+  }
+
+  // check that 2 digit mnc is different and return failure if so
+  if (mnc_digit_length == 2 &&
+      (mnc !=
+       (*plmn_Identity->mnc.list.array[0]*10) +
+       (*plmn_Identity->mnc.list.array[1]))) {
+    LOG_E(GNB_APP, "mnc(%d) in F1AP_SETUP_RESP message is different from mnc(%ld%ld) in DU \n",
+                    mnc, *plmn_Identity->mnc.list.array[0], *plmn_Identity->mnc.list.array[1]);
+    return(0);
+  }
+  else if (mnc_digit_length == 3 &&
+           (mnc !=
+            (*plmn_Identity->mnc.list.array[0]*100) +
+            (*plmn_Identity->mnc.list.array[1]*10) +
+            (*plmn_Identity->mnc.list.array[2]))) {
+    LOG_E(GNB_APP, "mnc(%d) in F1AP_SETUP_RESP message is different from mnc(%ld%ld%ld) in DU \n",
+                    mnc, *plmn_Identity->mnc.list.array[0], *plmn_Identity->mnc.list.array[1], *plmn_Identity->mnc.list.array[2]);
+    return(0);
+  }
+
+  // if we're here, the mcc/mnc match so return success
+  return(1);
+}
+
+void du_extract_and_decode_SI(int inst, int si_ind, uint8_t *si_container, int si_container_length) {
+  gNB_RRC_INST *rrc = RC.nrrrc[inst];
+  rrc_gNB_carrier_data_t *carrier = &rrc->carrier;
+  NR_BCCH_DL_SCH_Message_t *bcch_message ;
+  AssertFatal(si_ind == 0, "Can only handle a single SI block for now\n");
+  LOG_I(GNB_APP, "rrc inst %d: Trying to decode SI block %d @ %p, length %d\n", inst, si_ind, si_container, si_container_length);
+  // point to first SI block
+  bcch_message = &carrier->systemInformation;
+  asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
+                            &asn_DEF_NR_BCCH_DL_SCH_Message,
+                            (void **)&bcch_message,
+                            (const void *)si_container,
+                            si_container_length);
+
+  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
+    AssertFatal(1==0, "[GNB_APP][NR_RRC inst %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
+                inst,
+                dec_rval.consumed );
+  }
+
+  if (bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1) {
+    switch (bcch_message->message.choice.c1->present) {
+      case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1:
+        AssertFatal(1 == 0, "Should have received SIB1 from CU\n");
+        break;
+
+      case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
+      {
+        NR_SystemInformation_t *si = bcch_message->message.choice.c1->choice.systemInformation;
+
+        if (si->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_systemInformation) {
+          for (int i = 0; i < si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count; i++) {
+            LOG_I(GNB_APP, "Extracting SI %d/%d\n", i, si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count);
+            SystemInformation_IEs__sib_TypeAndInfo__Member *typeAndInfo;
+            typeAndInfo = si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.array[i];
+
+            switch(typeAndInfo->present) {
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_NOTHING:
+                AssertFatal(0, "Should have received SIB2 SIB3 from CU\n");
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2:
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB2 in CU F1AP_SETUP_RESP message\n", inst);
+                carrier->sib2 = typeAndInfo->choice.sib2;
+                carrier->SIB23 = (uint8_t *)malloc(64);
+                memcpy((void *)carrier->SIB23, (void *)si_container, si_container_length);
+                carrier->sizeof_SIB23 = si_container_length;
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3:
+                carrier->sib3 = typeAndInfo->choice.sib3;
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB3 in CU F1AP_SETUP_RESP message\n", inst);
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib4:
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB4 in CU F1AP_SETUP_RESP message\n", inst);
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib5:
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB5 in CU F1AP_SETUP_RESP message\n", inst);
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib6:
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB6 in CU F1AP_SETUP_RESP message\n", inst);
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib7:
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB7 in CU F1AP_SETUP_RESP message\n", inst);
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib8:
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB8 in CU F1AP_SETUP_RESP message\n", inst);
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib9:
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB9 in CU F1AP_SETUP_RESP message\n", inst);
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib10_v1610:
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB10 in CU F1AP_SETUP_RESP message\n", inst);
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib11_v1610:
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB11 in CU F1AP_SETUP_RESP message\n", inst);
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib12_v1610:
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB12 in CU F1AP_SETUP_RESP message\n", inst);
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib13_v1610:
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB13 in CU F1AP_SETUP_RESP message\n", inst);
+                break;
+              case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib14_v1610:
+                LOG_I(GNB_APP, "[NR_RRC %"PRIu8"] Found SIB14 in CU F1AP_SETUP_RESP message\n", inst);
+                break;
+              default:
+                AssertFatal(1 == 0,"Shouldn't have received this SI %d\n", typeAndInfo->present);
+                break;
+            }
+          }
+        }
+
+        break;
+      }
+
+      case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
+        AssertFatal(0, "Should have received SIB1 from CU\n");
+        break;
+    }
+  } else AssertFatal(1 == 0, "No SI messages\n");
+}
+
+void configure_gnb_du_mac(int inst) {
+  gNB_RRC_INST *rrc = RC.nrrrc[inst];
+  // LOG_I(GNB_APP,"Configuring MAC/L1 %d, carrier->sib2 %p\n", inst, &carrier->sib2->radioResourceConfigCommon);
+  LOG_I(GNB_APP,"Configuring gNB DU MAC/L1 %d \n", inst);
+  rrc_mac_config_req_gNB(rrc->module_id,
+                        rrc->configuration.ssb_SubcarrierOffset,
+                        rrc->configuration.pdsch_AntennaPorts,
+                        rrc->configuration.pusch_AntennaPorts,
+                        rrc->configuration.scc,
+                        0,
+                        0, // rnti
+                        (NR_CellGroupConfig_t *)NULL
+                        );
+}
+
+
+int gNB_app_handle_f1ap_setup_resp(f1ap_setup_resp_t *resp) {
+  int i, j, si_ind;
+  int ret=0;
+  LOG_I(GNB_APP, "cells_to_activate %d, RRC instances %d\n",
+        resp->num_cells_to_activate, RC.nb_nr_inst);
+
+  for (j = 0; j < resp->num_cells_to_activate; j++) {
+    for (i = 0; i < RC.nb_nr_inst; i++) {
+      rrc_gNB_carrier_data_t *carrier =  &RC.nrrrc[i]->carrier;
+      // identify local index of cell j by nr_cellid, plmn identity and physical cell ID
+      LOG_I(GNB_APP, "Checking cell %d, rrc inst %d : rrc->nr_cellid %lx, resp->nr_cellid %lx\n",
+            j, i, RC.nrrrc[i]->nr_cellid, resp->cells_to_activate[j].nr_cellid);
+
+      if (RC.nrrrc[i]->nr_cellid == resp->cells_to_activate[j].nr_cellid &&
+          (du_check_plmn_identity(carrier, resp->cells_to_activate[j].mcc, resp->cells_to_activate[j].mnc, resp->cells_to_activate[j].mnc_digit_length)>0 &&
+           resp->cells_to_activate[j].nrpci == carrier->physCellId)) {
+        // copy system information and decode it
+        for (si_ind=0; si_ind<resp->cells_to_activate[j].num_SI; si_ind++)  {
+
+          du_extract_and_decode_SI(i,
+                                   si_ind,
+                                   resp->cells_to_activate[j].SI_container[2+si_ind],
+                                   resp->cells_to_activate[j].SI_container_length[2+si_ind]);
+        }
+
+        // perform MAC/L1 common configuration
+        configure_gnb_du_mac(i);
+	ret++;
+      } else {
+        LOG_E(GNB_APP, "F1 Setup Response not matching\n");
+      }
+    }
+  }
+  return(ret);
+}
+
+int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_update_t *gnb_cu_cfg_update) {
+  int i, j, si_ind, ret=0;
+  LOG_I(GNB_APP, "cells_to_activate %d, RRC instances %d\n",
+        gnb_cu_cfg_update->num_cells_to_activate, RC.nb_nr_inst);
+
+  for (j = 0; j < gnb_cu_cfg_update->num_cells_to_activate; j++) {
+    for (i = 0; i < RC.nb_nr_inst; i++) {
+      rrc_gNB_carrier_data_t *carrier =  &RC.nrrrc[i]->carrier;
+      // identify local index of cell j by nr_cellid, plmn identity and physical cell ID
+      LOG_I(GNB_APP, "Checking cell %d, rrc inst %d : rrc->nr_cellid %lx, gnb_cu_cfg_updatenr_cellid %lx\n",
+            j, i, RC.nrrrc[i]->nr_cellid, gnb_cu_cfg_update->cells_to_activate[j].nr_cellid);
+
+      if (RC.nrrrc[i]->nr_cellid == gnb_cu_cfg_update->cells_to_activate[j].nr_cellid &&
+          (du_check_plmn_identity(carrier, gnb_cu_cfg_update->cells_to_activate[j].mcc, gnb_cu_cfg_update->cells_to_activate[j].mnc, gnb_cu_cfg_update->cells_to_activate[j].mnc_digit_length)>0 &&
+           gnb_cu_cfg_update->cells_to_activate[j].nrpci == carrier->physCellId)) {
+        // copy system information and decode it
+        for (si_ind=0; si_ind<gnb_cu_cfg_update->cells_to_activate[j].num_SI; si_ind++)  {
+
+          du_extract_and_decode_SI(i,
+                                   si_ind,
+                                   gnb_cu_cfg_update->cells_to_activate[j].SI_container[2+si_ind],
+                                   gnb_cu_cfg_update->cells_to_activate[j].SI_container_length[2+si_ind]);
+        }
+
+        // perform MAC/L1 common configuration
+        configure_gnb_du_mac(i);
+	ret++;
+      } else {
+        LOG_E(GNB_APP, "GNB_CU_CONFIGURATION_UPDATE not matching\n");
+      }
+    }
+  }
+  MessageDef *msg_ack_p = NULL;
+  if (ret > 0) {
+    // generate gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE
+    msg_ack_p = itti_alloc_new_message (TASK_GNB_APP, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE);
+    F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).num_cells_failed_to_be_activated = 0;
+    F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).have_criticality = 0; 
+    F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).noofTNLAssociations_to_setup =0;
+    F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).noofTNLAssociations_failed = 0;
+    F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).noofDedicatedSIDeliveryNeededUEs = 0;
+    itti_send_msg_to_task (TASK_DU_F1, INSTANCE_DEFAULT, msg_ack_p);
+
+  }
+  else {
+    // generate gNB_CU_CONFIGURATION_UPDATE_FAILURE
+    msg_ack_p = itti_alloc_new_message (TASK_GNB_APP, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE);
+    F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(msg_ack_p).cause = F1AP_CauseRadioNetwork_cell_not_available;
+
+    itti_send_msg_to_task (TASK_DU_F1, INSTANCE_DEFAULT, msg_ack_p);
+
+  }
+
+  return(ret);
+}
+
+void set_node_type(void) {
+  int               j;
+  paramdef_t        MacRLC_Params[] = MACRLCPARAMS_DESC;
+  paramlist_def_t   MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
+  paramdef_t        GNBParams[]  = GNBPARAMS_DESC;
+  paramlist_def_t   GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
+
+  config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL);   
+  config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);  
+
+  if ( MacRLC_ParamList.numelt > 0) {
+    RC.nb_nr_macrlc_inst = MacRLC_ParamList.numelt; 
+    for (j=0;j<RC.nb_nr_macrlc_inst;j++) {
+      if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "f1") == 0) {
+        macrlc_has_f1 = 1;
+      }
+    }
+  }
+
+  if (strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) {
+      node_type = ngran_gNB_CU;
+    } else {
+      if (macrlc_has_f1 == 0) {
+        node_type = ngran_gNB;
+        LOG_I(NR_RRC,"Setting node_type to ngran_gNB\n");
+      } else {
+        node_type = ngran_gNB_DU;
+        LOG_I(NR_RRC,"Setting node_type to ngran_gNB_DU\n");
+      }
+    }
+}
+
+void nr_read_config_and_init(void) {
+  MessageDef *msg_p = NULL;
+  uint32_t    gnb_id;
+  uint32_t    gnb_nb = RC.nb_nr_inst;
+
+  RCconfig_NR_L1();
+  set_node_type();
+  RCconfig_nr_macrlc();
+
+  LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
+
+  if (RC.nb_nr_L1_inst>0) AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n");
+
+  AssertFatal (gnb_nb <= RC.nb_nr_inst,
+               "Number of gNB is greater than gNB defined in configuration file (%d/%d)!",
+               gnb_nb, RC.nb_nr_inst);
+
+  LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst);
+
+  RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *));
+  LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc);
+
+  for (gnb_id = 0; gnb_id < RC.nb_nr_inst ; gnb_id++) {
+    RC.nrrrc[gnb_id] = (gNB_RRC_INST*)malloc(sizeof(gNB_RRC_INST));
+    LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, RC.nb_nr_inst);
+    memset((void *)RC.nrrrc[gnb_id],0,sizeof(gNB_RRC_INST));
+    msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NRRRC_CONFIGURATION_REQ);
+    RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]);
+  }
+
+  if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
+    pdcp_layer_init();
+//    nr_DRB_preconfiguration(0x1234);
+    rrc_init_nr_global_param();
+  }
+}
diff --git a/openair2/GNB_APP/gnb_config.h b/openair2/GNB_APP/gnb_config.h
index 4f305b1f4d104755de1d250997b678e00aec6663..46102e44888f601a6a589b8f9fcba3e4265cc0a8 100644
--- a/openair2/GNB_APP/gnb_config.h
+++ b/openair2/GNB_APP/gnb_config.h
@@ -40,6 +40,7 @@
 #include "PHY/defs_eNB.h"
 #include "s1ap_messages_types.h"
 #include "ngap_messages_types.h"
+#include "f1ap_messages_types.h"
 
 #ifdef CMAKER
 #include "rrc_messages_types.h"
@@ -105,6 +106,10 @@ extern void NRRCConfig(void);
 void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc);
 int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i);
 int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i);
+int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i);
+int gNB_app_handle_f1ap_setup_resp(f1ap_setup_resp_t *resp);
+int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_update_t *gnb_cu_cfg_update);
+void nr_read_config_and_init(void);
 
 #endif /* GNB_CONFIG_H_ */
 /** @} */
diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h
index 8b326d58c9b780e0dd805505b676167f041cd2fd..6d9c9b83420da30c67c91251d8adfd5992ed5262 100644
--- a/openair2/GNB_APP/gnb_paramdef.h
+++ b/openair2/GNB_APP/gnb_paramdef.h
@@ -116,8 +116,7 @@ typedef enum {
 #define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET           "ssb_SubcarrierOffset"
 #define GNB_CONFIG_STRING_PDSCHANTENNAPORTS             "pdsch_AntennaPorts"
 #define GNB_CONFIG_STRING_PUSCHANTENNAPORTS             "pusch_AntennaPorts"
-#define GNB_CONFIG_STRING_PUSCHTARGETPOWX10             "pusch_TargetSNRx10"
-#define GNB_CONFIG_STRING_PUCCHTARGETPOWX10             "pucch_TargetSNRx10"
+#define GNB_CONFIG_STRING_NRCELLID                      "nr_cellid"
 
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            cell configuration parameters                                                                */
@@ -141,8 +140,7 @@ typedef enum {
 {GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET,          NULL,   0,            iptr:NULL,   defintval:31,                TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_PDSCHANTENNAPORTS,            NULL,   0,            iptr:NULL,   defintval:1,                 TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_PUSCHANTENNAPORTS,            NULL,   0,            iptr:NULL,   defintval:1,                 TYPE_INT,       0},  \
-{GNB_CONFIG_STRING_PUSCHTARGETPOWX10,            NULL,   0,            iptr:NULL,   defintval:200,               TYPE_INT,       0},  \
-{GNB_CONFIG_STRING_PUCCHTARGETPOWX10,            NULL,   0,            iptr:NULL,   defintval:200,               TYPE_INT,       0},  \
+{GNB_CONFIG_STRING_NRCELLID         ,            NULL,   0,            u64ptr:NULL, defint64val:1,               TYPE_UINT64,       0},  \
 }															     	
 
 #define GNB_GNB_ID_IDX                  0
@@ -162,8 +160,7 @@ typedef enum {
 #define GNB_SSB_SUBCARRIEROFFSET_IDX    14
 #define GNB_PDSCH_ANTENNAPORTS_IDX      15
 #define GNB_PUSCH_ANTENNAPORTS_IDX      16
-#define GNB_PUSCH_TARGETPOW_X10_IDX     17
-#define GNB_PUCCH_TARGETPOW_X10_IDX     18
+#define GNB_NRCELLID_IDX                17
 
 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
 #define GNBPARAMS_CHECK {                                         \
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index c83cc1d9d374fc063c35fb27aaa2a089a0671434..d4f486f76162e683fd5f2c327767eddbc4e769b6 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -303,7 +303,22 @@ rx_sdu(const module_id_t enb_mod_idP,
 
     first_rb = ra->msg3_first_rb;
 
-    if (sduP == NULL) { // we've got an error on Msg3
+    bool no_sig = true;
+    if (sduP) {
+      for (int k = 0; k < sdu_lenP; k++) {
+        if(sduP[k]!=0) {
+          no_sig = false;
+          break;
+        }
+      }
+    }
+
+    if (no_sig || sduP == NULL) { // we've got an error on Msg3
+
+      if(no_sig) {
+        LOG_D(MAC,"No signal in Msg3\n");
+      }
+
       LOG_D(MAC, "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n",
             enb_mod_idP,
             CC_idP,
@@ -312,6 +327,20 @@ rx_sdu(const module_id_t enb_mod_idP,
             (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
 
       if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) {
+
+        // Release RNTI of LTE PHY when RA does not succeed
+        UE_free_list_t *free_list = NULL;
+        pthread_mutex_lock(&lock_ue_freelist);
+        free_list = &mac->UE_free_list;
+        free_list->UE_free_ctrl[free_list->tail_freelist].rnti = current_rnti;
+        free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = 1;
+        free_list->UE_free_ctrl[free_list->tail_freelist].raFlag = 1;
+        free_list->num_UEs++;
+        mac->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[mac->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = current_rnti;
+        mac->UE_release_req.ue_release_request_body.number_of_TLVs++;
+        free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1);
+        pthread_mutex_unlock(&lock_ue_freelist);
+
         cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
         nfapi_hi_dci0_request_t *hi_dci0_req = NULL;
         uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP);
@@ -690,6 +719,19 @@ rx_sdu(const module_id_t enb_mod_idP,
           break;
         }
 
+        bool no_sig = true;
+        for (int k = 0; k < sdu_lenP; k++) {
+          if(sduP[k]!=0) {
+            no_sig = false;
+            break;
+          }
+        }
+
+        if(no_sig) {
+          LOG_D(MAC, "No signal\n");
+          break;
+        }
+
         LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH:  %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n",
               enb_mod_idP,
               CC_idP,
diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h
index 062f613526cd429c09ae5e871285c6ec423dd8b9..cb93c2feb8839668a1c36cbe6ae3fcdb767ecc3a 100644
--- a/openair2/LAYER2/MAC/mac.h
+++ b/openair2/LAYER2/MAC/mac.h
@@ -1192,6 +1192,8 @@ typedef struct {
   rnti_t rnti;
   ///remove UE context flag
   boolean_t removeContextFlg;
+  ///remove RA flag
+  boolean_t raFlag;
 } UE_free_ctrl_t;
 /*! \brief REMOVE UE list used by eNB to order UEs/CC for deleting*/
 typedef struct {
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c
index 452ed45b3a9872c9bbefa6913e59acb1a5317ade..996c2fbe27c07b8bec4c6d2018a160da70754033 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c
@@ -51,6 +51,8 @@ uint32_t nr_compute_tbs(uint16_t Qm,
   uint32_t Ninfo, Np_info, C;
   uint8_t n, scale;
 
+  LOG_D(MAC,"nb_symb_sch %d, nb_dmrs_prb %d, nb_rb_oh %d\n",nb_symb_sch,nb_dmrs_prb,nb_rb_oh);
+
   nbp_re = NR_NB_SC_PER_RB * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
   nb_re = min(156, nbp_re) * nb_rb;
   scale = (R>1024)?11:10;
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index 91f009da303f4df87c0ea21a6ce537bea2af72c3..93c6c1dbc7e5e0238177a4833d7f82b3fd903769 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -1179,12 +1179,12 @@ int get_format0(uint8_t index,
   return format;
 }
 
-int64_t *get_prach_config_info(uint32_t pointa,
+int64_t *get_prach_config_info(frequency_range_t freq_range,
                                uint8_t index,
                                uint8_t unpaired) {
   int64_t *prach_config_info_p;
 
-  if (pointa > 2016666) { //FR2
+  if (freq_range == FR2) { //FR2
     prach_config_info_p = table_6_3_3_2_4_prachConfig_Index[index];
   }
   else { // FR1
@@ -2524,7 +2524,7 @@ uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB) {
 
 // Set the transform precoding status according to 6.1.3 of 3GPP TS 38.214 version 16.3.0 Release 16:
 // - "UE procedure for applying transform precoding on PUSCH"
-uint8_t get_transformPrecoding(const NR_ServingCellConfigCommon_t *scc,
+uint8_t get_transformPrecoding(const NR_BWP_UplinkCommon_t *initialUplinkBWP,
                                const NR_PUSCH_Config_t *pusch_config,
                                const NR_BWP_Uplink_t *ubwp,
                                uint8_t *dci_format,
@@ -2539,7 +2539,7 @@ uint8_t get_transformPrecoding(const NR_ServingCellConfigCommon_t *scc,
     }
   }
 
-  if (rnti_type != NR_RNTI_RA) {
+  if (rnti_type != NR_RNTI_RA && rnti_type != NR_RNTI_TC) {
     if (*dci_format != NR_UL_DCI_FORMAT_0_0) {
       if (pusch_config->transformPrecoder != NULL) {
         return *pusch_config->transformPrecoder;
@@ -2547,7 +2547,7 @@ uint8_t get_transformPrecoding(const NR_ServingCellConfigCommon_t *scc,
     }
   }
 
-  if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) {
+  if (initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) {
     return 1; // Transformprecoding disabled
   } else {
     LOG_D(PHY, "MAC_COMMON: Transform Precodig enabled through msg3_transformPrecoder\n");
@@ -2558,8 +2558,8 @@ uint8_t get_transformPrecoding(const NR_ServingCellConfigCommon_t *scc,
   return -1;
 }
 
-uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
-                     const NR_CellGroupConfig_t *secondaryCellGroup,
+uint16_t nr_dci_size(const NR_BWP_UplinkCommon_t *initialUplinkBWP,
+                     const NR_CellGroupConfig_t *cg,
                      dci_pdu_rel15_t *dci_pdu,
                      nr_dci_format_t format,
 		     nr_rnti_type_t rnti_type,
@@ -2578,8 +2578,9 @@ uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
   NR_PUSCH_Config_t *pusch_Config = NULL;
   NR_SRS_Config_t *srs_config = NULL;
   if(bwp_id > 0) {
-    bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
-    ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
+    AssertFatal(cg!=NULL,"Cellgroup is null and bwp_id!=0");
+    bwp=cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
+    ubwp=cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
     pdsch_config = bwp->bwp_Dedicated->pdsch_Config->choice.setup;
     pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup;
     srs_config = ubwp->bwp_Dedicated->srs_Config->choice.setup;
@@ -2591,7 +2592,7 @@ uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
       /// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20
       size += 20;
       size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment -- hopping scenario to be updated
-      size += nr_dci_size(scc,secondaryCellGroup,dci_pdu,NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, bwp_id) - size; // Padding to match 1_0 size
+      size += nr_dci_size(initialUplinkBWP,cg,dci_pdu,NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, bwp_id) - size; // Padding to match 1_0 size
       // UL/SUL indicator assumed to be 0
       break;
 
@@ -2599,24 +2600,24 @@ uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
       /// fixed: Format identifier 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2, ULSCH indicator 1 --16
       size += 16;
       // Carrier indicator
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL) {
+      if (cg->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL) {
         dci_pdu->carrier_indicator.nbits=3;
         size += dci_pdu->carrier_indicator.nbits;
       }
       // UL/SUL indicator
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->supplementaryUplink != NULL) {
+      if (cg->spCellConfig->spCellConfigDedicated->supplementaryUplink != NULL) {
         dci_pdu->carrier_indicator.nbits=1;
         size += dci_pdu->ul_sul_indicator.nbits;
       }
       // BWP Indicator
-      uint8_t n_ul_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
+      uint8_t n_ul_bwp = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
       if (n_ul_bwp < 2)
         dci_pdu->bwp_indicator.nbits = n_ul_bwp;
       else
         dci_pdu->bwp_indicator.nbits = 2;
       size += dci_pdu->bwp_indicator.nbits;
       // Freq domain assignment
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pusch_Config->choice.setup->rbg_Size != NULL)
+      if (cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pusch_Config->choice.setup->rbg_Size != NULL)
         rbg_size_config = 1;
       else
         rbg_size_config = 0;
@@ -2647,13 +2648,13 @@ uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
         size += 1;
       }
       // 1st DAI
-      if (secondaryCellGroup->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook==NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic)
+      if (cg->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook==NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic)
         dci_pdu->dai[0].nbits = 2;
       else
         dci_pdu->dai[0].nbits = 1;
       size += dci_pdu->dai[0].nbits;
       // 2nd DAI
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) { //TODO not sure about that
+      if (cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) { //TODO not sure about that
         dci_pdu->dai[1].nbits = 2;
         size += dci_pdu->dai[1].nbits;
       }
@@ -2673,9 +2674,9 @@ uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
         else {
           int lmin,Lmax = 0;
           int lsum = 0;
-          if ( secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig != NULL) {
-            if ( secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers != NULL)
-              Lmax = *secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers;
+          if ( cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig != NULL) {
+            if ( cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers != NULL)
+              Lmax = *cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers;
             else
               AssertFatal(1==0,"MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n");
           }
@@ -2695,7 +2696,7 @@ uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
         }
       }
       // Precoding info and number of layers
-      long transformPrecoder = get_transformPrecoding(scc, pusch_Config, ubwp, (uint8_t*)&format, rnti_type, 0);
+      long transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, ubwp, (uint8_t*)&format, rnti_type, 0);
 
       if (pusch_Config->txConfig != NULL){
         if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook){
@@ -2739,21 +2740,21 @@ uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
         dci_pdu->antenna_ports.nbits = xb;
       size += dci_pdu->antenna_ports.nbits;
       // SRS request
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->supplementaryUplink==NULL)
+      if (cg->spCellConfig->spCellConfigDedicated->supplementaryUplink==NULL)
         dci_pdu->srs_request.nbits = 2;
       else
         dci_pdu->srs_request.nbits = 3;
       size += dci_pdu->srs_request.nbits;
       // CSI request
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig != NULL) {
-        if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup->reportTriggerSize != NULL) {
-          dci_pdu->csi_request.nbits = *secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup->reportTriggerSize;
+      if (cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig != NULL) {
+        if (cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup->reportTriggerSize != NULL) {
+          dci_pdu->csi_request.nbits = *cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup->reportTriggerSize;
           size += dci_pdu->csi_request.nbits;
         }
       }
       // CBGTI
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) {
-        int num = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->codeBlockGroupTransmission->choice.setup->maxCodeBlockGroupsPerTransportBlock;
+      if (cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) {
+        int num = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->codeBlockGroupTransmission->choice.setup->maxCodeBlockGroupsPerTransportBlock;
         dci_pdu->cbgti.nbits = 2 + (num<<1);
         size += dci_pdu->cbgti.nbits;
       }
@@ -2786,7 +2787,6 @@ uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
       dci_pdu->frequency_domain_assignment.nbits = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
       dci_pdu->time_domain_assignment.nbits = 4;
       dci_pdu->vrb_to_prb_mapping.nbits = 1;
-
       break;
 
     case NR_DL_DCI_FORMAT_1_1:
@@ -2794,19 +2794,19 @@ uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
       // Format identifier
       size = 1;
       // Carrier indicator
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL) {
+      if (cg->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL) {
         dci_pdu->carrier_indicator.nbits=3;
         size += dci_pdu->carrier_indicator.nbits;
       }
       // BWP Indicator
-      uint8_t n_dl_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count;
+      uint8_t n_dl_bwp = cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count;
       if (n_dl_bwp < 2)
         dci_pdu->bwp_indicator.nbits = n_dl_bwp;
       else
         dci_pdu->bwp_indicator.nbits = 2;
       size += dci_pdu->bwp_indicator.nbits;
       // Freq domain assignment
-      rbg_size_config = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rbg_Size;
+      rbg_size_config = cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rbg_Size;
       numRBG = getNRBG(NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE),
                        NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE),
                        rbg_size_config);
@@ -2862,7 +2862,7 @@ uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
       // HARQ PID
       size += 4;
       // DAI
-      if (secondaryCellGroup->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook == NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic) { // FIXME in case of more than one serving cell
+      if (cg->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook == NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic) { // FIXME in case of more than one serving cell
         dci_pdu->dai[0].nbits = 2;
         size += dci_pdu->dai[0].nbits;
       }
@@ -2887,20 +2887,20 @@ uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
         size += dci_pdu->transmission_configuration_indication.nbits;
       }
       // SRS request
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->supplementaryUplink==NULL)
+      if (cg->spCellConfig->spCellConfigDedicated->supplementaryUplink==NULL)
         dci_pdu->srs_request.nbits = 2;
       else
         dci_pdu->srs_request.nbits = 3;
       size += dci_pdu->srs_request.nbits;
       // CBGTI
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) {
-        uint8_t maxCBGperTB = (secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission->choice.setup->maxCodeBlockGroupsPerTransportBlock + 1) * 2;
+      if (cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) {
+        uint8_t maxCBGperTB = (cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission->choice.setup->maxCodeBlockGroupsPerTransportBlock + 1) * 2;
         long *maxCWperDCI_rrc = pdsch_config->maxNrofCodeWordsScheduledByDCI;
         uint8_t maxCW = (maxCWperDCI_rrc == NULL) ? 1 : *maxCWperDCI_rrc;
         dci_pdu->cbgti.nbits = maxCBGperTB * maxCW;
         size += dci_pdu->cbgti.nbits;
         // CBGFI
-        if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission->choice.setup->codeBlockGroupFlushIndicator) {
+        if (cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission->choice.setup->codeBlockGroupFlushIndicator) {
           dci_pdu->cbgfi.nbits = 1;
           size += dci_pdu->cbgfi.nbits;
         }
@@ -2951,64 +2951,64 @@ int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig, long transformPrec
 
 int tdd_period_to_num[8] = {500,625,1000,1250,2000,2500,5000,10000};
 
-int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) {
+int is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,slot_t slot) {
 
   int period,period1,period2=0;
 
-  if (scc->tdd_UL_DL_ConfigurationCommon==NULL) return(1);
+  if (tdd_UL_DL_ConfigurationCommon==NULL) return(1);
 
-  if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 &&
-      scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530)
-    period1 = 3000+*scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
+  if (tdd_UL_DL_ConfigurationCommon->pattern1.ext1 &&
+      tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530)
+    period1 = 3000+*tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
   else
-    period1 = tdd_period_to_num[scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity];
+    period1 = tdd_period_to_num[tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity];
 			       
-  if (scc->tdd_UL_DL_ConfigurationCommon->pattern2) {
-    if (scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1 &&
-	scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530)
-      period2 = 3000+*scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530;
+  if (tdd_UL_DL_ConfigurationCommon->pattern2) {
+    if (tdd_UL_DL_ConfigurationCommon->pattern2->ext1 &&
+        tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530)
+      period2 = 3000+*tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530;
     else
-      period2 = tdd_period_to_num[scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity];
+      period2 = tdd_period_to_num[tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity];
   }    
   period = period1+period2;
-  int scs=scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing;
+  int scs=tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing;
   int slots=period*(1<<scs)/1000;
   int slots1=period1*(1<<scs)/1000;
   int slot_in_period = slot % slots;
-  if (slot_in_period < slots1) return(slot_in_period <= scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots ? 1 : 0);
-  else return(slot_in_period <= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0);
+  if (slot_in_period < slots1) return(slot_in_period <= tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots ? 1 : 0);
+  else return(slot_in_period <= slots1+tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0);    
 }
 
-int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slot, lte_frame_type_t frame_type) {
+int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t	*tdd_UL_DL_ConfigurationCommon, slot_t slot, lte_frame_type_t frame_type) {
 
   int period,period1,period2=0;
 
   // Note: condition on frame_type
   // goal: the UL scheduler assumes mode is TDD therefore this hack is needed to make FDD work
-  if (scc->tdd_UL_DL_ConfigurationCommon == NULL || frame_type == FDD) {
+  if (tdd_UL_DL_ConfigurationCommon == NULL || frame_type == FDD) {
     return(1);
   }
 
-  if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 &&
-      scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530)
-    period1 = 3000+*scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
+  if (tdd_UL_DL_ConfigurationCommon->pattern1.ext1 &&
+      tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530)
+    period1 = 3000+*tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
   else
-    period1 = tdd_period_to_num[scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity];
+    period1 = tdd_period_to_num[tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity];
 			       
-  if (scc->tdd_UL_DL_ConfigurationCommon->pattern2) {
-    if (scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1 &&
-	scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530)
-      period2 = 3000+*scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530;
+  if (tdd_UL_DL_ConfigurationCommon->pattern2) {
+    if (tdd_UL_DL_ConfigurationCommon->pattern2->ext1 &&
+	      tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530)
+      period2 = 3000+*tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530;
     else
-      period2 = tdd_period_to_num[scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity];
+      period2 = tdd_period_to_num[tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity];
   }    
   period = period1+period2;
-  int scs=scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing;
+  int scs=tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing;
   int slots=period*(1<<scs)/1000;
   int slots1=period1*(1<<scs)/1000;
   int slot_in_period = slot % slots;
-  if (slot_in_period < slots1) return(slot_in_period >= scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots ? 1 : 0);
-  else return(slot_in_period >= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0);
+  if (slot_in_period < slots1) return(slot_in_period >= tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots ? 1 : 0);
+  else return(slot_in_period >= slots1+tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0);    
 }
 
 int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols, int startSymbol, int mappingtype_fromDCI) {
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index 9c24eea77203b5742a2d5ce1418d1c15acdfd860..a6adb47c0a1374650d26f7fd2fd6cb05b9278ef1 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -49,16 +49,16 @@ uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, ui
 
 int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols,int startSymbol,int mappingtype_fromDCI);
 
-int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
+int is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,slot_t slotP);
 
-int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slotP, lte_frame_type_t frame_type);
+int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slotP, lte_frame_type_t frame_type);
 
-uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
-                     const NR_CellGroupConfig_t *secondaryCellGroup,
+uint16_t nr_dci_size(const NR_BWP_UplinkCommon_t *initialULBWP,
+                     const NR_CellGroupConfig_t *cg,
                      dci_pdu_rel15_t *dci_pdu,
                      nr_dci_format_t format,
-		     nr_rnti_type_t rnti_type,
-		     uint16_t N_RB,
+                     nr_rnti_type_t rnti_type,
+                     uint16_t N_RB,
                      int bwp_id);
 
 void find_aggregation_candidates(uint8_t *aggregation_level,
@@ -113,7 +113,7 @@ int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig,long transformPreco
 
 int get_format0(uint8_t index, uint8_t unpaired,frequency_range_t);
 
-int64_t *get_prach_config_info(uint32_t pointa,
+int64_t *get_prach_config_info(frequency_range_t freq_range,
                                uint8_t index,
                                uint8_t unpaired);
 
@@ -162,7 +162,7 @@ uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Posi
 @param    rnti_type        rnti type
 @param    configuredGrant  indicates whether a configured grant was received or not
 @returns                   transformPrecoding value */
-uint8_t get_transformPrecoding(const NR_ServingCellConfigCommon_t *scc,
+uint8_t get_transformPrecoding(const NR_BWP_UplinkCommon_t *initialUplinkBWP,
                                const NR_PUSCH_Config_t *pusch_config,
                                const NR_BWP_Uplink_t *ubwp,
                                uint8_t *dci_format,
diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c
index 111fee48833c3eeb718eefae92fd0e95d49792f9..bfa5d6a93f6a3fd20b08cef50c26085f88867c23 100755
--- a/openair2/LAYER2/NR_MAC_UE/config_ue.c
+++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c
@@ -35,7 +35,9 @@
 #include "NR_MAC_UE/mac_proto.h"
 #include "NR_MAC-CellGroupConfig.h"
 #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
-#include "executables/softmodem-common.h"
+#include <executables/softmodem-common.h>
+
+extern uint32_t N_RB_DL;
 
 int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
                          int mu,
@@ -149,6 +151,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
 
   fapi_nr_config_request_t        *cfg = &mac->phy_config.config_req;
   NR_ServingCellConfigCommon_t    *scc = mac->scc;
+  NR_ServingCellConfigCommonSIB_t *scc_SIB = mac->scc_SIB;
   int i;
 
   mac->phy_config.Mod_id = module_id;
@@ -157,18 +160,187 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
   // carrier config
   LOG_D(MAC, "Entering UE Config Common\n");
 
-  cfg->carrier_config.dl_bandwidth = config_bandwidth(scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
-                                                      scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
-                                                      *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]);
+  AssertFatal(scc==NULL || scc_SIB==NULL,"Both scc and scc_SIB cannot be null\n");
+
+  if (scc) {
+    cfg->carrier_config.dl_bandwidth = config_bandwidth(scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
+							scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
+							*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]);
+    
+    cfg->carrier_config.dl_frequency = from_nrarfcn(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],
+						    *scc->ssbSubcarrierSpacing,
+						    scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA)/1000; // freq in kHz
+    
+    for (i=0; i<5; i++) {
+      if (i==scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
+        cfg->carrier_config.dl_grid_size[i] = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
+        cfg->carrier_config.dl_k0[i] = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
+      }
+      else {
+        cfg->carrier_config.dl_grid_size[i] = 0;
+        cfg->carrier_config.dl_k0[i] = 0;
+      }
+    }
+    
+    cfg->carrier_config.uplink_bandwidth = config_bandwidth(scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
+							    scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
+							    *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]);
+    
+    int UL_pointA;
+    if (scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA == NULL)
+      UL_pointA = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
+    else
+      UL_pointA = *scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA; 
+    
+    cfg->carrier_config.uplink_frequency = from_nrarfcn(*scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0],
+							*scc->ssbSubcarrierSpacing,
+							UL_pointA)/1000; // freq in kHz
+    
+    
+    for (i=0; i<5; i++) {
+      if (i==scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
+	cfg->carrier_config.ul_grid_size[i] = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
+	cfg->carrier_config.ul_k0[i] = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
+      }
+      else {
+	cfg->carrier_config.ul_grid_size[i] = 0;
+	cfg->carrier_config.ul_k0[i] = 0;
+      }
+    }
+    
+    uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+    mac->frequency_range = band<100?FR1:FR2;
+    
+    lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
+
+    // cell config
+    
+    cfg->cell_config.phy_cell_id = *scc->physCellId;
+    cfg->cell_config.frame_duplex_type = frame_type;
+    
+    // SSB config
+    cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower;
+    cfg->ssb_config.scs_common = *scc->ssbSubcarrierSpacing;
+    
+    // SSB Table config
+    int scs_scaling = 1<<(cfg->ssb_config.scs_common);
+    if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000)
+      scs_scaling = scs_scaling*3;
+    if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666)
+      scs_scaling = scs_scaling>>2;
+    uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
+    cfg->ssb_table.ssb_offset_point_a = absolute_diff/(12*scs_scaling) - 10;
+    cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell;
+    cfg->ssb_table.ssb_subcarrier_offset = 0; // TODO currently not in RRC?
+
+    switch (scc->ssb_PositionsInBurst->present) {
+    case 1 :
+      cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0]<<24;
+      cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
+      break;
+    case 2 :
+      cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]<<24;
+      cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
+      break;
+    case 3 :
+      cfg->ssb_table.ssb_mask_list[0].ssb_mask = 0;
+      cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
+      for (i=0; i<4; i++) {
+        cfg->ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[3-i]<<i*8);
+        cfg->ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-i]<<i*8);
+      }
+      break;
+    default:
+      AssertFatal(1==0,"SSB bitmap size value %d undefined (allowed values 1,2,3) \n", scc->ssb_PositionsInBurst->present);
+    }
+    
+    // TDD Table Configuration
+    if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 == NULL)
+      cfg->tdd_table.tdd_period = scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity;
+    else {
+      AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL,
+		  "scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n");
+      cfg->tdd_table.tdd_period = *scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
+    }
+    if(cfg->cell_config.frame_duplex_type == TDD){
+      LOG_I(MAC,"Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period);
+      int return_tdd = set_tdd_config_nr_ue(cfg,
+					    scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
+					    scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots,
+					    scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols,
+					    scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
+					    scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols
+					    );
+      
+      if (return_tdd !=0)
+	LOG_E(PHY,"TDD configuration can not be done\n");
+      else
+	LOG_I(PHY,"TDD has been properly configurated\n");
+    }
+    
+    // PRACH configuration
+    
+    uint8_t nb_preambles = 64;
+    if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
+      nb_preambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
+    
+    cfg->prach_config.prach_sequence_length = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1;
+    
+    if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
+      cfg->prach_config.prach_sub_c_spacing = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
+    else 
+      cfg->prach_config.prach_sub_c_spacing = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+    
+    cfg->prach_config.restricted_set_config = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig;
+    
+    switch (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM) {
+    case 0 :
+      cfg->prach_config.num_prach_fd_occasions = 1;
+      break;
+    case 1 :
+      cfg->prach_config.num_prach_fd_occasions = 2;
+      break;
+    case 2 :
+      cfg->prach_config.num_prach_fd_occasions = 4;
+      break;
+    case 3 :
+      cfg->prach_config.num_prach_fd_occasions = 8;
+      break;
+    default:
+      AssertFatal(1==0,"msg1 FDM identifier %ld undefined (0,1,2,3) \n", scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM);
+    }
+    
+    cfg->prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions*sizeof(fapi_nr_num_prach_fd_occasions_t));
+    for (i=0; i<cfg->prach_config.num_prach_fd_occasions; i++) {
+      cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i;
+      if (cfg->prach_config.prach_sequence_length)
+	      cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139;
+      else
+	      cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839;
+      
+      cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart;
+      cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
+      cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup,
+                                                                                                nb_preambles, frame_type,mac->frequency_range);
+      //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ???
+    }
+
+    cfg->prach_config.ssb_per_rach = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
+    
+  } // scc
 
-  cfg->carrier_config.dl_frequency = from_nrarfcn(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],
-                                                  *scc->ssbSubcarrierSpacing,
-                                                  scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA)/1000; // freq in kHz
+  else { // scc_SIB
+
+  cfg->carrier_config.dl_bandwidth = config_bandwidth(scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
+                                                      scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
+                                                      *scc_SIB->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR);
+
+  cfg->carrier_config.dl_frequency = downlink_frequency[0][0] - (10+scc_SIB->downlinkConfigCommon.frequencyInfoDL.offsetToPointA)*(15<<scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing); 
 
   for (i=0; i<5; i++) {
-    if (i==scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
-      cfg->carrier_config.dl_grid_size[i] = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
-      cfg->carrier_config.dl_k0[i] = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
+    if (i==scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
+      cfg->carrier_config.dl_grid_size[i] = scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
+      cfg->carrier_config.dl_k0[i] = scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
     }
     else {
       cfg->carrier_config.dl_grid_size[i] = 0;
@@ -176,25 +348,23 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
     }
   }
 
-  cfg->carrier_config.uplink_bandwidth = config_bandwidth(scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
-                                                          scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
-                                                          *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]);
-
-  int UL_pointA;
-  if (scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA == NULL)
-    UL_pointA = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
-  else
-    UL_pointA = *scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA; 
+  cfg->carrier_config.uplink_bandwidth = config_bandwidth(scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
+                                                          scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
+                                                          scc_SIB->uplinkConfigCommon->frequencyInfoUL.frequencyBandList==NULL ? *scc_SIB->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR : *scc_SIB->uplinkConfigCommon->frequencyInfoUL.frequencyBandList->list.array[0]->freqBandIndicatorNR);
 
-  cfg->carrier_config.uplink_frequency = from_nrarfcn(*scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0],
-                                                      *scc->ssbSubcarrierSpacing,
-                                                      UL_pointA)/1000; // freq in kHz
 
+  if (scc_SIB->uplinkConfigCommon->frequencyInfoUL.absoluteFrequencyPointA == NULL)
+    cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency;
+  else  
+    cfg->carrier_config.uplink_frequency = from_nrarfcn(*scc_SIB->uplinkConfigCommon->frequencyInfoUL.frequencyBandList->list.array[0]->freqBandIndicatorNR,
+							scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
+							*scc_SIB->uplinkConfigCommon->frequencyInfoUL.absoluteFrequencyPointA)/1000; // freq in kHz
+    
 
   for (i=0; i<5; i++) {
-    if (i==scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
-      cfg->carrier_config.ul_grid_size[i] = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
-      cfg->carrier_config.ul_k0[i] = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
+    if (i==scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
+      cfg->carrier_config.ul_grid_size[i] = scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
+      cfg->carrier_config.ul_k0[i] = scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
     }
     else {
       cfg->carrier_config.ul_grid_size[i] = 0;
@@ -202,68 +372,55 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
     }
   }
 
-  uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+  uint32_t band = *scc_SIB->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR;
   frequency_range_t  frequency_range = band<100?FR1:FR2;
  
-  mac->frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
+  lte_frame_type_t frame_type = get_frame_type(band, get_softmodem_params()->numerology);
 
   // cell config
 
-  cfg->cell_config.phy_cell_id = *scc->physCellId;
-  cfg->cell_config.frame_duplex_type = mac->frame_type;
+  cfg->cell_config.phy_cell_id = mac->physCellId;
+  cfg->cell_config.frame_duplex_type = frame_type;
 
   // SSB config
-  cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower;
-  cfg->ssb_config.scs_common = *scc->ssbSubcarrierSpacing;
+  cfg->ssb_config.ss_pbch_power = scc_SIB->ss_PBCH_BlockPower;
+  cfg->ssb_config.scs_common = get_softmodem_params()->numerology;
 
   // SSB Table config
-  int scs_scaling = 1<<(cfg->ssb_config.scs_common);
-  if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000)
-    scs_scaling = scs_scaling*3;
-  if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666)
-    scs_scaling = scs_scaling>>2;
-  uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
-  cfg->ssb_table.ssb_offset_point_a = absolute_diff/(12*scs_scaling) - 10;
-  cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell;
+
+  cfg->ssb_table.ssb_offset_point_a = scc_SIB->downlinkConfigCommon.frequencyInfoDL.offsetToPointA;
+  cfg->ssb_table.ssb_period = scc_SIB->ssb_PeriodicityServingCell;
   cfg->ssb_table.ssb_subcarrier_offset = 0; // TODO currently not in RRC?
 
-  switch (scc->ssb_PositionsInBurst->present) {
-    case 1 :
-      cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0]<<24;
-      cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
-      break;
-    case 2 :
-      cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]<<24;
-      cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
-      break;
-    case 3 :
-      cfg->ssb_table.ssb_mask_list[0].ssb_mask = 0;
-      cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
-      for (i=0; i<4; i++) {
-        cfg->ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[3-i]<<i*8);
-        cfg->ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-i]<<i*8);
-      }
-      break;
-    default:
-      AssertFatal(1==0,"SSB bitmap size value %d undefined (allowed values 1,2,3) \n", scc->ssb_PositionsInBurst->present);
-  }
+  AssertFatal(scc_SIB->ssb_PositionsInBurst.groupPresence==NULL, "Cannot handle more than 8 SSBs for now (%x.%x.%x.%x.%x.%x.%x.%x)\n",
+	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[0],
+	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[1],
+	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[2],
+	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[3],
+	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[4],
+	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[5],
+	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[6],
+	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[7]);
+  cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc_SIB->ssb_PositionsInBurst.inOneGroup.buf[0]<<24;
+  cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
+ 
 
   // TDD Table Configuration
-  if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 == NULL)
-    cfg->tdd_table.tdd_period = scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity;
+  if (scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 == NULL)
+    cfg->tdd_table.tdd_period = scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity;
   else {
-    AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL,
-		"scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n");
-    cfg->tdd_table.tdd_period = *scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
+    AssertFatal(scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL,
+		"scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n");
+    cfg->tdd_table.tdd_period = *scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
   }
   if(cfg->cell_config.frame_duplex_type == TDD){
     LOG_I(MAC,"Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period);
     int return_tdd = set_tdd_config_nr_ue(cfg,
-		     scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
-                     scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots,
-                     scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols,
-                     scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
-                     scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols
+		     scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
+                     scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots,
+                     scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols,
+                     scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
+                     scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols
                      );
 
     if (return_tdd !=0)
@@ -275,19 +432,19 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
   // PRACH configuration
 
   uint8_t nb_preambles = 64;
-  if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
-     nb_preambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
+  if(scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
+     nb_preambles = *scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
 
-  cfg->prach_config.prach_sequence_length = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1;
+  cfg->prach_config.prach_sequence_length = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1;
 
-  if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
-    cfg->prach_config.prach_sub_c_spacing = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
+  if (scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
+    cfg->prach_config.prach_sub_c_spacing = *scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
   else 
-    cfg->prach_config.prach_sub_c_spacing = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+    cfg->prach_config.prach_sub_c_spacing = scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
 
-  cfg->prach_config.restricted_set_config = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig;
+  cfg->prach_config.restricted_set_config = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->restrictedSetConfig;
 
-  switch (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM) {
+  switch (scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM) {
     case 0 :
       cfg->prach_config.num_prach_fd_occasions = 1;
       break;
@@ -301,37 +458,37 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
       cfg->prach_config.num_prach_fd_occasions = 8;
       break;
     default:
-      AssertFatal(1==0,"msg1 FDM identifier %ld undefined (0,1,2,3) \n", scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM);
+      AssertFatal(1==0,"msg1 FDM identifier %ld undefined (0,1,2,3) \n", scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM);
   }
 
   cfg->prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions*sizeof(fapi_nr_num_prach_fd_occasions_t));
   for (i=0; i<cfg->prach_config.num_prach_fd_occasions; i++) {
     cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i;
     if (cfg->prach_config.prach_sequence_length)
-      cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139; 
+      cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139; 
     else
-      cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839;
-    if (get_softmodem_params()->sa) {
-      cfg->prach_config.num_prach_fd_occasions_list[i].k1 = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
-    } else {
-      cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
-    }
-    cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
-    cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, mac->frame_type, frequency_range);
+      cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839;
+    cfg->prach_config.num_prach_fd_occasions_list[i].k1 = NRRIV2PRBOFFSET(scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE) + scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing, scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
+    cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
+    cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup, nb_preambles, mac->frame_type, frequency_range);
     //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ???
   }
 
-  cfg->prach_config.ssb_per_rach = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
+  cfg->prach_config.ssb_per_rach = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
 
+
+  }
+    
 }
 
 /** \brief This function performs some configuration routines according to clause 12 "Bandwidth part operation" 3GPP TS 38.213 version 16.3.0 Release 16
     @param NR_UE_MAC_INST_t mac: pointer to local MAC instance
     @returns void
     */
+
 void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format){
 
-  NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated;
+  NR_ServingCellConfig_t *scd = mac->cg->spCellConfig->spCellConfigDedicated;
 
   if (bwp_ind && dci_format){
 
@@ -366,6 +523,70 @@ void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format
 
 }
 
+
+void fill_default_coreset_zero(NR_UE_MAC_INST_t *mac) {
+
+  // Search space zero
+
+  if(mac->search_space_zero == NULL) mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero));
+  if(mac->search_space_zero->controlResourceSetId == NULL) mac->search_space_zero->controlResourceSetId=calloc(1,sizeof(*mac->search_space_zero->controlResourceSetId));
+  if(mac->search_space_zero->monitoringSymbolsWithinSlot == NULL) mac->search_space_zero->monitoringSymbolsWithinSlot = calloc(1,sizeof(*mac->search_space_zero->monitoringSymbolsWithinSlot));
+  if(mac->search_space_zero->monitoringSymbolsWithinSlot->buf == NULL) mac->search_space_zero->monitoringSymbolsWithinSlot->buf = calloc(1,2);
+  if(mac->search_space_zero->nrofCandidates == NULL) mac->search_space_zero->nrofCandidates = calloc(1,sizeof(*mac->search_space_zero->nrofCandidates));
+  if(mac->search_space_zero->searchSpaceType == NULL) mac->search_space_zero->searchSpaceType = calloc(1,sizeof(*mac->search_space_zero->searchSpaceType));
+  if(mac->search_space_zero->searchSpaceType->choice.common == NULL) mac->search_space_zero->searchSpaceType->choice.common=calloc(1,sizeof(*mac->search_space_zero->searchSpaceType->choice.common));
+  if(mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 == NULL) mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0));
+  mac->search_space_zero->searchSpaceId = 0;
+  *mac->search_space_zero->controlResourceSetId = 0;
+  mac->search_space_zero->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*mac->search_space_zero->monitoringSlotPeriodicityAndOffset));
+  mac->search_space_zero->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1;
+  mac->search_space_zero->duration=NULL;
+  // should be '1100 0000 0000 00'B (LSB first!), first two symbols in slot, adjust if needed
+  mac->search_space_zero->monitoringSymbolsWithinSlot->buf[1] = 0;
+  mac->search_space_zero->monitoringSymbolsWithinSlot->buf[0] = (1<<7);
+  mac->search_space_zero->monitoringSymbolsWithinSlot->size = 2;
+  mac->search_space_zero->monitoringSymbolsWithinSlot->bits_unused = 2;
+
+  // FIXME: update values from TS38.213 Section 10.1 Table 10.1-1: CCE aggregation levels and maximum number of PDCCH candidates per CCE aggregation level for CSS sets configured by searchSpaceSIB1
+  mac->search_space_zero->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
+  mac->search_space_zero->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
+  mac->search_space_zero->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2;
+  mac->search_space_zero->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
+  mac->search_space_zero->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
+  mac->search_space_zero->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common;
+
+  // Coreset0
+  if(mac->coreset0 == NULL) mac->coreset0 = calloc(1,sizeof(*mac->coreset0));
+  mac->coreset0->controlResourceSetId = 0;
+  // frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B,
+  if(mac->coreset0->frequencyDomainResources.buf == NULL) mac->coreset0->frequencyDomainResources.buf = calloc(1,6);
+  mac->coreset0->frequencyDomainResources.buf[0] = 0xff;
+  mac->coreset0->frequencyDomainResources.buf[1] = 0;
+  mac->coreset0->frequencyDomainResources.buf[2] = 0;
+  mac->coreset0->frequencyDomainResources.buf[3] = 0;
+  mac->coreset0->frequencyDomainResources.buf[4] = 0;
+  mac->coreset0->frequencyDomainResources.buf[5] = 0;
+  mac->coreset0->frequencyDomainResources.size = 6;
+  mac->coreset0->frequencyDomainResources.bits_unused = 3;
+  mac->coreset0->duration = 1;
+  mac->coreset0->cce_REG_MappingType.present=NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved;
+  mac->coreset0->cce_REG_MappingType.choice.interleaved=calloc(1,sizeof(*mac->coreset0->cce_REG_MappingType.choice.interleaved));
+  mac->coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6;
+  mac->coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n2;
+  mac->coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex = NULL;
+  mac->coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle;
+  if(mac->coreset0->tci_StatesPDCCH_ToAddList == NULL) mac->coreset0->tci_StatesPDCCH_ToAddList = calloc(1,sizeof(*mac->coreset0->tci_StatesPDCCH_ToAddList));
+  NR_TCI_StateId_t *tci[8];
+  for (int i=0;i<8;i++) {
+    tci[i]=calloc(1,sizeof(*tci[i]));
+    *tci[i] = i;
+    ASN_SEQUENCE_ADD(&mac->coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]);
+  }
+  mac->coreset0->tci_StatesPDCCH_ToReleaseList = NULL;
+  mac->coreset0->tci_PresentInDCI = NULL;
+  mac->coreset0->pdcch_DMRS_ScramblingID = NULL;
+}
+
 /** \brief This function is relavant for the UE procedures for control. It loads the search spaces, the BWPs and the CORESETs into the MAC instance and
     \brief performs assert checks on the relevant RRC configuration.
     @param NR_UE_MAC_INST_t mac: pointer to local MAC instance
@@ -375,7 +596,7 @@ void config_control_ue(NR_UE_MAC_INST_t *mac){
 
   uint8_t coreset_id = 1, ss_id;
 
-  NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated;
+  NR_ServingCellConfig_t *scd = mac->cg->spCellConfig->spCellConfigDedicated;
   AssertFatal(scd->downlinkBWP_ToAddModList != NULL, "downlinkBWP_ToAddModList is null\n");
   AssertFatal(scd->downlinkBWP_ToAddModList->list.count <= 4, "downlinkBWP_ToAddModList->list->count is %d\n", scd->downlinkBWP_ToAddModList->list.count);
 
@@ -455,65 +676,7 @@ void config_control_ue(NR_UE_MAC_INST_t *mac){
     ss_id++;
   }
 
-  // TODO: Merge this code in a single function as fill_default_searchSpaceZero() in rrc_gNB_reconfig.c
-  // Search space zero
-  if(mac->search_space_zero == NULL) mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero));
-  if(mac->search_space_zero->controlResourceSetId == NULL) mac->search_space_zero->controlResourceSetId=calloc(1,sizeof(*mac->search_space_zero->controlResourceSetId));
-  if(mac->search_space_zero->monitoringSymbolsWithinSlot == NULL) mac->search_space_zero->monitoringSymbolsWithinSlot = calloc(1,sizeof(*mac->search_space_zero->monitoringSymbolsWithinSlot));
-  if(mac->search_space_zero->monitoringSymbolsWithinSlot->buf == NULL) mac->search_space_zero->monitoringSymbolsWithinSlot->buf = calloc(1,2);
-  if(mac->search_space_zero->nrofCandidates == NULL) mac->search_space_zero->nrofCandidates = calloc(1,sizeof(*mac->search_space_zero->nrofCandidates));
-  if(mac->search_space_zero->searchSpaceType == NULL) mac->search_space_zero->searchSpaceType = calloc(1,sizeof(*mac->search_space_zero->searchSpaceType));
-  if(mac->search_space_zero->searchSpaceType->choice.common == NULL) mac->search_space_zero->searchSpaceType->choice.common=calloc(1,sizeof(*mac->search_space_zero->searchSpaceType->choice.common));
-  if(mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 == NULL) mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0));
-  mac->search_space_zero->searchSpaceId = 0;
-  *mac->search_space_zero->controlResourceSetId = 0;
-  mac->search_space_zero->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*mac->search_space_zero->monitoringSlotPeriodicityAndOffset));
-  mac->search_space_zero->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1;
-  mac->search_space_zero->duration=NULL;
-  // should be '1100 0000 0000 00'B (LSB first!), first two symbols in slot, adjust if needed
-  mac->search_space_zero->monitoringSymbolsWithinSlot->buf[1] = 0;
-  mac->search_space_zero->monitoringSymbolsWithinSlot->buf[0] = (1<<7);
-  mac->search_space_zero->monitoringSymbolsWithinSlot->size = 2;
-  mac->search_space_zero->monitoringSymbolsWithinSlot->bits_unused = 2;
-
-  // FIXME: update values from TS38.213 Section 10.1 Table 10.1-1: CCE aggregation levels and maximum number of PDCCH candidates per CCE aggregation level for CSS sets configured by searchSpaceSIB1
-  mac->search_space_zero->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
-  mac->search_space_zero->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
-  mac->search_space_zero->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2;
-  mac->search_space_zero->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
-  mac->search_space_zero->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
-  mac->search_space_zero->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common;
-
-  // Coreset0
-  if(mac->coreset0 == NULL) mac->coreset0 = calloc(1,sizeof(*mac->coreset0));
-  mac->coreset0->controlResourceSetId = 0;
-  // frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B,
-  if(mac->coreset0->frequencyDomainResources.buf == NULL) mac->coreset0->frequencyDomainResources.buf = calloc(1,6);
-  mac->coreset0->frequencyDomainResources.buf[0] = 0xff;
-  mac->coreset0->frequencyDomainResources.buf[1] = 0;
-  mac->coreset0->frequencyDomainResources.buf[2] = 0;
-  mac->coreset0->frequencyDomainResources.buf[3] = 0;
-  mac->coreset0->frequencyDomainResources.buf[4] = 0;
-  mac->coreset0->frequencyDomainResources.buf[5] = 0;
-  mac->coreset0->frequencyDomainResources.size = 6;
-  mac->coreset0->frequencyDomainResources.bits_unused = 3;
-  mac->coreset0->duration = 1;
-  mac->coreset0->cce_REG_MappingType.present=NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved;
-  mac->coreset0->cce_REG_MappingType.choice.interleaved=calloc(1,sizeof(*mac->coreset0->cce_REG_MappingType.choice.interleaved));
-  mac->coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6;
-  mac->coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n2;
-  mac->coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex = NULL;
-  mac->coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle;
-  if(mac->coreset0->tci_StatesPDCCH_ToAddList == NULL) mac->coreset0->tci_StatesPDCCH_ToAddList = calloc(1,sizeof(*mac->coreset0->tci_StatesPDCCH_ToAddList));
-  NR_TCI_StateId_t *tci[8];
-  for (int i=0;i<8;i++) {
-    tci[i]=calloc(1,sizeof(*tci[i]));
-    *tci[i] = i;
-    ASN_SEQUENCE_ADD(&mac->coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]);
-  }
-  mac->coreset0->tci_StatesPDCCH_ToReleaseList = NULL;
-  mac->coreset0->tci_PresentInDCI = NULL;
-  mac->coreset0->pdcch_DMRS_ScramblingID = NULL;
+  fill_default_coreset_zero(mac);
 
 }
 
@@ -522,10 +685,11 @@ int nr_rrc_mac_config_req_ue(
     int                             cc_idP,
     uint8_t                         gNB_index,
     NR_MIB_t                        *mibP,
-    //    NR_ServingCellConfigCommon_t    *sccP,
+    NR_ServingCellConfigCommonSIB_t *sccP,
     //    NR_MAC_CellGroupConfig_t        *mac_cell_group_configP,
     //    NR_PhysicalCellGroupConfig_t    *phy_cell_group_configP,
-    NR_CellGroupConfig_t            *cell_group_config ){
+    NR_CellGroupConfig_t            *cell_group_config,
+    NR_CellGroupConfig_t            *scell_group_config){
 
     NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
     RA_config_t *ra = &mac->ra;
@@ -533,25 +697,71 @@ int nr_rrc_mac_config_req_ue(
     //  TODO do something FAPI-like P5 L1/L2 config interface in config_si, config_mib, etc.
 
     if(mibP != NULL){
+
+      // if this is the first MIB intialize coreset0 for SA
+      if (mac->mib == NULL) fill_default_coreset_zero(mac);
+
       mac->mib = mibP;    //  update by every reception
+      mac->phy_config.Mod_id = module_id;
+      mac->phy_config.CC_id = cc_idP;
+      mac->phy_config.config_req.ssb_table.ssb_subcarrier_offset = 0; // TODO currently not in RRC?
+      mac->phy_config.config_req.tdd_table.tdd_period_in_slots=5<<get_softmodem_params()->numerology;
+      mac->phy_config.config_req.ssb_table.ssb_offset_point_a = (N_RB_DL-20)>>1;
     }
-
-    if(cell_group_config != NULL ){
-      mac->scg = cell_group_config;
-      mac->servCellIndex = *cell_group_config->spCellConfig->servCellIndex;
+    AssertFatal(scell_group_config == NULL || cell_group_config == NULL,
+		"both scell_group_config and cell_group_config cannot be non-NULL\n");
+    
+    if (sccP != NULL) {
+
+      mac->scc_SIB=sccP;
+      LOG_I(MAC,"Keeping ServingCellConfigCommonSIB\n");
+      config_common_ue(mac,module_id,cc_idP);
+      int num_slots_ul = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
+      if (mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols>0) num_slots_ul++;
+      LOG_I(MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul);
+      mac->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t));
+      // Setup the SSB to Rach Occasions mapping according to the config
+      build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type);
+      mac->if_module->phy_config_request(&mac->phy_config);
+      mac->common_configuration_complete = 1;
+    }
+    if(scell_group_config != NULL ){
+      mac->cg = scell_group_config;
+      mac->servCellIndex = *scell_group_config->spCellConfig->servCellIndex;
       config_control_ue(mac);
-      if (cell_group_config->spCellConfig->reconfigurationWithSync) {
-        if (cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) {
-          ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
+      if (scell_group_config->spCellConfig->reconfigurationWithSync) {
+        if (scell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) {
+          ra->rach_ConfigDedicated = scell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
         }
-        mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
+        mac->scc = scell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
+	      mac->physCellId = *mac->scc->physCellId;
         config_common_ue(mac,module_id,cc_idP);
-        mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity;
+        mac->crnti = scell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity;
         LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
       }
 
       // Setup the SSB to Rach Occasions mapping according to the config
-      build_ssb_to_ro_map(mac->scc, mac->phy_config.config_req.cell_config.frame_duplex_type);
+      build_ssb_to_ro_map(mac);
+    }
+    else if (cell_group_config != NULL){
+      LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
+      mac->cg = cell_group_config;
+      mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0;
+      if(get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) {
+        config_control_ue(mac);
+        if (cell_group_config->spCellConfig->reconfigurationWithSync) {
+          if (cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) {
+            ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
+          }
+          mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
+          config_common_ue(mac,module_id,cc_idP);
+          mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity;
+          LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
+        }
+
+        // Setup the SSB to Rach Occasions mapping according to the config
+        build_ssb_to_ro_map(mac);
+      }
 
       /*      
       if(mac_cell_group_configP != NULL){
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index c33173cf381e9ade87222eb9fe06fd7d0df4ad1d..3347ddf19cb87dd6ed613dde408f55e52bbe5a96 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -315,10 +315,13 @@ typedef struct {
 typedef struct {
 
   NR_ServingCellConfigCommon_t    *scc;
-  NR_CellGroupConfig_t            *scg;
+  NR_ServingCellConfigCommonSIB_t *scc_SIB;
+  NR_CellGroupConfig_t            *cg;
   int                             servCellIndex;
   NR_CSI_ReportConfig_t           *csirc;
+  long                            physCellId;
   ////  MAC config
+  int                             common_configuration_complete;
   NR_DRX_Config_t                 *drx_Config;
   NR_SchedulingRequestConfig_t    *schedulingRequestConfig;
   NR_BSR_Config_t                 *bsr_Config;
@@ -361,7 +364,8 @@ typedef struct {
   uint8_t mib_ssb;
   /// Last NDI of UL HARQ processes
   uint8_t UL_ndi[NR_MAX_HARQ_PROCESSES];
-
+  /// first ULTX of UL HARQ processes
+  int first_ul_tx[NR_MAX_HARQ_PROCESSES];
   ////	FAPI-like interface message
   fapi_nr_ul_config_request_t *ul_config_request;
   fapi_nr_dl_config_request_t dl_config_request;
@@ -380,6 +384,7 @@ typedef struct {
   NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
   NR_SearchSpace_t *search_space_zero;
   NR_ControlResourceSet_t *coreset0;
+  frequency_range_t frequency_range;
 
   dci_pdu_rel15_t def_dci_pdu_rel15[8];
 
@@ -502,5 +507,8 @@ typedef struct ssb_list_info {
   uint8_t   nb_tx_ssb;
 } ssb_list_info_t;
 
+void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id);
+void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
+
 /*@}*/
 #endif /*__LAYER2_MAC_DEFS_H__ */
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 394ab58fc72beae57ac363ec66d20f1429b5d3dc..2d00aa00034efc3683002c18199645cc61aaa635 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -53,7 +53,8 @@ int8_t nr_ue_decode_mib(
     uint8_t extra_bits, 
     uint32_t ssb_length, 
     uint32_t ssb_index,
-    void *pduP, 
+    void *pduP,
+    uint16_t ssb_start_subcarrier,
     uint16_t cell_id );
 
 /**\brief decode SIB1 and other SIs pdus in NR_UE, from if_module dl_ind
@@ -82,8 +83,10 @@ int nr_rrc_mac_config_req_ue(
     int                             cc_idP,
     uint8_t                         gNB_index,
     NR_MIB_t                        *mibP,
-    //NR_ServingCellConfigCommon_t    *sccP,
-    NR_CellGroupConfig_t            *cell_group_config);
+    NR_ServingCellConfigCommonSIB_t *sccP,
+    NR_CellGroupConfig_t            *cell_group_config,
+    NR_CellGroupConfig_t            *scell_group_config
+);
 
 /**\brief initialization NR UE MAC instance(s), total number of MAC instance based on NB_NR_UE_MAC_INST*/
 NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst);
@@ -166,6 +169,10 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
                                     unsigned short post_padding,
                                     uint16_t buflen);
 
+void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
+
+void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id);
+
 void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot);
 
 uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
@@ -301,7 +308,7 @@ void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu,
                      uint8_t *nb_dmrs_re_per_rb,
                      uint16_t *number_dmrs_symbols);
 
-void build_ssb_to_ro_map(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired);
+void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac);
 
 void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format);
 
diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
index bbb44ba47afe758cbff0efa3b4dfd13c56b4ea9c..768f65bf635abebc6abecfcac462ae3c22447605 100644
--- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
+++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
@@ -39,6 +39,7 @@
 #include "PHY/defs_UE.h"
 #include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h"
 #include "executables/softmodem-common.h"
+#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h"
 
 static NR_UE_MAC_INST_t *nr_ue_mac_inst; 
 
@@ -50,12 +51,26 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst)
     
     //init mac here
     nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t),NB_NR_UE_MAC_INST);
-    if (rrc_inst) {
-      nr_rrc_mac_config_req_ue(0,0,0,NULL,rrc_inst->cell_group_config);
-      if (IS_SOFTMODEM_NOS1){
+    for (int j=0;j<NB_NR_UE_MAC_INST;j++)
+	    for (int i=0;i<NR_MAX_HARQ_PROCESSES;i++)
+	      nr_ue_mac_inst[j].first_ul_tx[i]=1;
+
+    if (rrc_inst && (rrc_inst->scell_group_config || rrc_inst->cell_group_config)) {
+
+      if(rrc_inst->scell_group_config) {
+        nr_rrc_mac_config_req_ue(0,0,0,NULL,NULL,NULL,rrc_inst->scell_group_config);
+        //if (IS_SOFTMODEM_NOS1){
+        //  AssertFatal(rlc_module_init(0) == 0, "%s: Could not initialize RLC layer\n", __FUNCTION__);
+        //  nr_pdcp_layer_init();
+        //  nr_DRB_preconfiguration(nr_ue_mac_inst->crnti);
+        //}
+      } else if (rrc_inst->cell_group_config) {
+        nr_rrc_mac_config_req_ue(0,0,0,NULL,NULL,rrc_inst->cell_group_config,NULL);
         AssertFatal(rlc_module_init(0) == 0, "%s: Could not initialize RLC layer\n", __FUNCTION__);
-        pdcp_layer_init();
-        nr_DRB_preconfiguration(nr_ue_mac_inst->crnti);
+        if (IS_SOFTMODEM_NOS1){
+          pdcp_layer_init();
+          nr_DRB_preconfiguration(nr_ue_mac_inst->crnti);
+        }
       }
 
       // Allocate memory for ul_config_request in the mac instance. This is now a pointer and will
@@ -68,8 +83,14 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst)
         LOG_D(MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul);
         nr_ue_mac_inst->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t));
       }
+
+    } else {
+      LOG_I(MAC,"Running without CellGroupConfig\n");
+      nr_rrc_mac_config_req_ue(0,0,0,NULL,NULL,NULL,NULL);
+      if(get_softmodem_params()->sa == 1) {
+        AssertFatal(rlc_module_init(0) == 0, "%s: Could not initialize RLC layer\n", __FUNCTION__);
+      }
     }
-    else LOG_I(MAC,"Running without RRC instance\n");
 
     return (nr_ue_mac_inst);
 }
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c
index 2f4697c25dbc02cb578367dd458ec2990dd623b9..7f1011fb28feaed58da6519eb692ae8fab985728 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c
@@ -41,10 +41,11 @@
 int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_format){
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
-  NR_ServingCellConfigCommon_t *scc = mac->scc;
-  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc!=NULL) ? 
+    mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup:
+    mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
   NR_SubcarrierSpacing_t scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
-  int prach_sequence_length = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present - 1;
+  int prach_sequence_length = (mac->scc!=NULL)?(mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present - 1) : (mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1);
   uint8_t prachConfigIndex, mu;
 
   AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
@@ -145,11 +146,10 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_forma
 int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t mod_id, uint8_t CC_id){
   
   NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
-  NR_ServingCellConfigCommon_t *scc = mac->scc;
   int8_t receivedTargerPower;
   int8_t delta_preamble;
 
-  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc != NULL) ? mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup: mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
   long preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower;
   delta_preamble = nr_get_DELTA_PREAMBLE(mod_id, CC_id, prach_resources->prach_format);
 
@@ -205,7 +205,8 @@ void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu,
 long nr_get_Pcmax(module_id_t mod_id){
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
-  uint32_t band = *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+  uint32_t band = (mac->scc!=NULL) ? *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] :
+    *mac->scc_SIB->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR;
   NR_P_Max_t p_max           = 0;
   uint8_t P_powerclass       = 23;
   uint8_t delta_P_powerclass = 0;
@@ -224,17 +225,18 @@ long nr_get_Pcmax(module_id_t mod_id){
     delta_MPR_c = 0.5;
   }
 
-  if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1){
-    if (*mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1->powerBoostPi2BPSK == 1){
+  if (mac->cg && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1){
+    if (*mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1->powerBoostPi2BPSK == 1){
       // TbD: assuming power class 3 capable UE operating in TDD bands n40, n41, n77, n78, and n79 with Pi/2 BPSK modulation
       delta_P_powerclass = -3;
       p_max += 3;
     }
   }
 
-  if (mac->scc->uplinkConfigCommon->frequencyInfoUL->p_Max){
+  NR_P_Max_t *p_Max = (mac->scc!=NULL) ? mac->scc->uplinkConfigCommon->frequencyInfoUL->p_Max : mac->scc_SIB->uplinkConfigCommon->frequencyInfoUL.p_Max;
+  if (p_Max){
 
-    p_max += *mac->scc->uplinkConfigCommon->frequencyInfoUL->p_Max;
+    p_max += *p_Max;
 
     LOG_D(MAC, "In %s maximum UL transmission power p_max is %ld dBm \n", __FUNCTION__, p_max);
 
@@ -256,4 +258,4 @@ long nr_get_Pcmax(module_id_t mod_id){
 
   return P_cmax;
 
-}
\ No newline at end of file
+}
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
index 7f4d536e3f435b35178671e1d0796f62d6db9201..7c54c85632c5a86682f7350c3246072e29c76a96 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
@@ -246,16 +246,18 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t
   long deltaPreamble_Msg3 = 0;
   uint8_t noGroupB = 0;
   RA_config_t *ra = &mac->ra;
-  NR_ServingCellConfigCommon_t *scc = mac->scc;
-  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
-  NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &nr_rach_ConfigCommon->rach_ConfigGeneric;
+  NR_RACH_ConfigCommon_t *setup;
+  if (mac->scc) setup = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+  else          setup = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
+  NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
 
-  if (scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble){
-    deltaPreamble_Msg3 = (*scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble) * 2; // dB
+  NR_BWP_UplinkCommon_t *initialUplinkBWP = (mac->scc) ? mac->scc->uplinkConfigCommon->initialUplinkBWP : &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP;
+  if (initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble){
+    deltaPreamble_Msg3 = (*initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble) * 2; // dB
     LOG_D(MAC, "In %s: deltaPreamble_Msg3 set to %ld\n", __FUNCTION__, deltaPreamble_Msg3);
   }
 
-  if (!nr_rach_ConfigCommon->groupBconfigured) {
+  if (!setup->groupBconfigured) {
     noGroupB = 1;
     LOG_D(MAC, "In %s:%d: preambles group B is not configured...\n", __FUNCTION__, __LINE__);
   } else {
@@ -263,8 +265,8 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t
     // - Random Access Preambles group B is configured for 4-step RA type
     // - Defining the number of RA preambles in RA Preamble Group A for each SSB
     LOG_D(MAC, "In %s:%d: preambles group B is configured...\n", __FUNCTION__, __LINE__);
-    sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA;
-    switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){
+    sizeOfRA_PreamblesGroupA = setup->groupBconfigured->numberOfRA_PreamblesGroupA;
+    switch (setup->groupBconfigured->ra_Msg3SizeGroupA){
       /* - Threshold to determine the groups of RA preambles */
       case 0:
       messageSizeGroupA = 56;
@@ -297,13 +299,13 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t
       messageSizeGroupA = 72;
       break;
       default:
-      AssertFatal(1 == 0, "Unknown ra_Msg3SizeGroupA %lu\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA);
+      AssertFatal(1 == 0, "Unknown ra_Msg3SizeGroupA %lu\n", setup->groupBconfigured->ra_Msg3SizeGroupA);
       /* todo cases 10 -15*/
       }
 
       /* Power offset for preamble selection in dB */
       messagePowerOffsetGroupB = -9999;
-      switch (nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB){
+      switch (setup->groupBconfigured->messagePowerOffsetGroupB){
       case 0:
       messagePowerOffsetGroupB = -9999;
       break;
@@ -329,7 +331,7 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t
       messagePowerOffsetGroupB = 18;
       break;
       default:
-      AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB);
+      AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", setup->groupBconfigured->messagePowerOffsetGroupB);
     }
 
     PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
@@ -420,7 +422,10 @@ void nr_get_prach_resources(module_id_t mod_id,
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
   RA_config_t *ra = &mac->ra;
-  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+
+  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc)?
+    mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup : 
+    mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
 
   LOG_D(PHY, "In %s: getting PRACH resources frame (first_Msg3 %d)\n", __FUNCTION__, ra->first_Msg3);
 
@@ -455,7 +460,9 @@ void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint
 void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
-  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc) ? 
+    mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup:
+    mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
   RA_config_t *ra = &mac->ra;
 
   LOG_D(MAC,"In %s: [UE %d] Frame %d, CB-RA: starting contention resolution timer\n", __FUNCTION__, mod_id, frameP);
@@ -499,9 +506,9 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
   uint8_t *payload;
   uint16_t size_sdu = 0;
   unsigned short post_padding;
-  NR_ServingCellConfigCommon_t *scc = mac->scc;
-  AssertFatal(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup != NULL, "In %s: FATAL! nr_rach_ConfigCommon is NULL...\n", __FUNCTION__);
-  NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+  NR_RACH_ConfigCommon_t *setup;
+  if (mac->scc) setup = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+  else          setup = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
   AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__);
   NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
   NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = ra->rach_ConfigDedicated;
@@ -513,19 +520,23 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
 
   // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side
   if (!prach_resources->init_msg1) {
-    if (((MAX_FRAME_NUMBER + frame - prach_resources->sync_frame) % MAX_FRAME_NUMBER) > 150){
+    if ( (mac->common_configuration_complete>0 || get_softmodem_params()->do_ra==1) && ((MAX_FRAME_NUMBER+frame-prach_resources->sync_frame)%MAX_FRAME_NUMBER)>150 ){
       prach_resources->init_msg1 = 1;
     } else {
+      LOG_D(NR_MAC,"PRACH Condition not met: frame %d, prach_resources->sync_frame %d\n",frame,prach_resources->sync_frame);
       return 0;
     }
   }
 
+  LOG_D(NR_MAC,"frame %d prach_resources->init_msg1 %d, ra->ra_state %d, ra->RA_active %d\n",
+	frame,prach_resources->init_msg1,ra->ra_state,ra->RA_active);
+
   if (prach_resources->init_msg1 && ra->ra_state != RA_SUCCEEDED) {
 
     if (ra->RA_active == 0) {
       /* RA not active - checking if RRC is ready to initiate the RA procedure */
 
-      LOG_D(MAC, "RA not active. Checking for data to transmit from upper layers...\n");
+      LOG_D(NR_MAC, "RA not active. Checking for data to transmit from upper layers...\n");
 
       uint8_t TBS_max = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
       payload = (uint8_t*) mac->CCCH_pdu.payload;
@@ -546,7 +557,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
 
       sdu_lengths[0] = size_sdu;
 
-      LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu);
+      LOG_D(NR_MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu);
 
       if (size_sdu > 0) {
 
@@ -555,7 +566,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
         // Random Access Procedure has been successful after reception of Msg4
         memcpy(ra->cont_res_id, mac_sdus, sizeof(uint8_t) * 6);
 
-        LOG_D(MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx);
+        LOG_D(NR_MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx);
 
         ra->Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
 
@@ -564,9 +575,9 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
         nr_get_RA_window(mac);
 
         // Fill in preamble and PRACH resources
-        if (ra->generate_nr_prach == GENERATE_PREAMBLE)
+        if (ra->generate_nr_prach == GENERATE_PREAMBLE) {
           nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
-
+        }
         offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus,              // sdus buffer
                                        (uint8_t *) payload,               // UL MAC pdu pointer
                                        num_sdus,                          // num sdus
@@ -632,15 +643,16 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
 
         // Fill in preamble and PRACH resources
         ra->RA_window_cnt--;
-        nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
-
+        if (ra->generate_nr_prach == GENERATE_PREAMBLE) {
+          nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
+        }
       } else if (ra->RA_backoff_cnt > 0) {
 
         LOG_D(MAC, "[UE %d][%d.%d]: RAR not received yet (RA backoff count %d) \n", mod_id, frame, nr_slot_tx, ra->RA_backoff_cnt);
 
         ra->RA_backoff_cnt--;
 
-        if ((ra->RA_backoff_cnt > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0){
+        if ((ra->RA_backoff_cnt > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0) {
           nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
         }
 
@@ -652,6 +664,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
     nr_ue_contention_resolution(mod_id, CC_id, frame, nr_slot_tx, prach_resources);
   }
 
+  LOG_D(MAC,"ra->generate_nr_prach %d ra->ra_state %d (GENERATE_IDLE %d)\n",ra->generate_nr_prach,ra->ra_state,GENERATE_IDLE);
   if(ra->generate_nr_prach != GENERATE_IDLE) {
     return ra->generate_nr_prach;
   } else {
@@ -664,17 +677,21 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac){
 
   uint8_t mu, ra_ResponseWindow;
   RA_config_t *ra = &mac->ra;
-  NR_ServingCellConfigCommon_t *scc = mac->scc;
-  NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+  NR_RACH_ConfigCommon_t *setup;
+  if (mac->scc) setup = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+  else          setup = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
+  AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__);
   NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
-  NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
-
+  long scs = (mac->scc) ? 
+    mac->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing :
+    mac->scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+ 
   ra_ResponseWindow = rach_ConfigGeneric->ra_ResponseWindow;
 
   if (setup->msg1_SubcarrierSpacing)
     mu = *setup->msg1_SubcarrierSpacing;
   else
-    mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+    mu = scs;
 
   ra->RA_window_cnt = ra->RA_offset*nr_slots_per_frame[mu]; // taking into account the 2 frames gap introduced by OAI gNB
 
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
index cea476354f28dd6e209567d274e212d9bddcd1d6..037287e8750b4b8d9aedccff07e8c95daf21a7f3 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
@@ -47,7 +47,7 @@
 #endif
 #define LOG_DCI_PARM(a...) LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci)" a)
 
-// #define DEBUG_DCI
+//#define DEBUG_DCI
 
 void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
 
@@ -70,11 +70,22 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
   uint16_t monitoringSymbolsWithinSlot = 0;
   uint8_t coreset_id = 1;
   int sps = 0;
-  AssertFatal(mac->scc != NULL, "scc is null\n");
+
+  AssertFatal(mac->scc == NULL || mac->scc_SIB == NULL, "both scc and scc_SIB cannot be non-null\n");
+
   NR_BWP_Id_t bwp_id = mac->DL_BWP_Id;
   NR_ServingCellConfigCommon_t *scc = mac->scc;
-  NR_BWP_DownlinkCommon_t *bwp_Common = mac->DLbwp[bwp_id - 1]->bwp_Common;
-  NR_BWP_DownlinkCommon_t *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP;
+  NR_ServingCellConfigCommonSIB_t *scc_SIB = mac->scc_SIB;
+  NR_BWP_DownlinkCommon_t *bwp_Common=NULL;
+  NR_BWP_DownlinkCommon_t *initialDownlinkBWP=NULL;
+  NR_BWP_UplinkCommon_t *initialUplinkBWP=NULL;
+
+  if (scc!=NULL || scc_SIB != NULL) {
+    initialDownlinkBWP =  scc!=NULL ? scc->downlinkConfigCommon->initialDownlinkBWP : &scc_SIB->downlinkConfigCommon.initialDownlinkBWP;
+    initialUplinkBWP = scc!=NULL ? scc->uplinkConfigCommon->initialUplinkBWP : &scc_SIB->uplinkConfigCommon->initialUplinkBWP;
+
+    bwp_Common = bwp_id>0 ? mac->DLbwp[bwp_id-1]->bwp_Common : NULL;
+  }
 
   NR_SearchSpace_t *ss;
   NR_ControlResourceSet_t *coreset;
@@ -101,8 +112,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
     struct NR_ControlResourceSet__cce_REG_MappingType__interleaved *interleaved = coreset->cce_REG_MappingType.choice.interleaved;
     rel15->coreset.RegBundleSize = (interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2 + interleaved->reg_BundleSize);
     rel15->coreset.InterleaverSize = (interleaved->interleaverSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2 + interleaved->interleaverSize);
-    AssertFatal(scc->physCellId != NULL, "mac->scc->physCellId is null\n");
-    rel15->coreset.ShiftIndex = interleaved->shiftIndex != NULL ? *interleaved->shiftIndex : *scc->physCellId;
+    rel15->coreset.ShiftIndex = interleaved->shiftIndex != NULL ? *interleaved->shiftIndex : mac->physCellId;
   } else {
     rel15->coreset.RegBundleSize = 0;
     rel15->coreset.InterleaverSize = 0;
@@ -116,7 +126,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
     rel15->coreset.pdcch_dmrs_scrambling_id = *coreset->pdcch_DMRS_ScramblingID;
     rel15->coreset.scrambling_rnti = mac->crnti;
   } else {
-    rel15->coreset.pdcch_dmrs_scrambling_id = *scc->physCellId;
+    rel15->coreset.pdcch_dmrs_scrambling_id = mac->physCellId;
     rel15->coreset.scrambling_rnti = 0;
   }
 
@@ -128,15 +138,23 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
   switch(rnti_type) {
     case NR_RNTI_C:
     // we use DL BWP dedicated
-    sps = bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
+      sps = bwp_Common ?
+	      (bwp_Common->genericParameters.cyclicPrefix ? 12 : 14) :
+        initialDownlinkBWP->genericParameters.cyclicPrefix ? 12 : 14;
     // for SPS=14 8 MSBs in positions 13 down to 6
     monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
     rel15->rnti = mac->crnti;
-    rel15->BWPSize = NRRIV2BW(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing;
+    if (!bwp_Common) {
+      rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      rel15->BWPStart = NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    }
+    else {
+      rel15->BWPSize = NRRIV2BW(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing;
+    }
     for (int i = 0; i < rel15->num_dci_options; i++) {
-      rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id);
+      rel15->dci_length_options[i] = nr_dci_size(initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id);
     }
     break;
     case NR_RNTI_RA:
@@ -151,7 +169,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
       rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
     }
     rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
-    rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id);
+    rel15->dci_length_options[0] = nr_dci_size(initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id);
     break;
     case NR_RNTI_P:
     break;
@@ -165,13 +183,14 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
       rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
       rel15->BWPStart = NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
       rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
-      rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_TC, rel15->BWPSize, bwp_id);
+      rel15->dci_length_options[0] = nr_dci_size(initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_TC, rel15->BWPSize, bwp_id);
     break;
     case NR_RNTI_SP_CSI:
     break;
     case NR_RNTI_SI:
       // we use DL BWP dedicated
-      sps = bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
+      if (bwp_Common) sps = bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
+      else sps=14; // note: normally this would be found with SSS detection
 
       // for SPS=14 8 MSBs in positions 13 down to 6
       monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
@@ -182,7 +201,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
       rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon;
 
       for (int i = 0; i < rel15->num_dci_options; i++) {
-        rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_SI, rel15->BWPSize, 0);
+        rel15->dci_length_options[i] = nr_dci_size(initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_SI, rel15->BWPSize, 0);
       }
     break;
     case NR_RNTI_SFI:
@@ -224,168 +243,175 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
 
   RA_config_t *ra = &mac->ra;
   int ss_id;
-  uint8_t bwp_id = mac->DL_BWP_Id;
-  uint8_t coreset_id = 1;
-  //NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated;
-  NR_BWP_Downlink_t *bwp = mac->DLbwp[bwp_id - 1];
 
-  #ifdef DEBUG_DCI
-    LOG_D(MAC, "[DCI_CONFIG] ra_rnti %p (%x) crnti %p (%x) t_crnti %p (%x)\n", &ra->ra_rnti, ra->ra_rnti, &mac->crnti, mac->crnti, &ra->t_crnti, ra->t_crnti);
-  #endif
-
-  // loop over all available SS for BWP ID 1, CORESET ID 1
-  for (ss_id = 0; ss_id < FAPI_NR_MAX_SS_PER_CORESET && mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id] != NULL; ss_id++){
-    NR_SearchSpace_t *ss = mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id];
-    fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
-    NR_BWP_DownlinkCommon_t *bwp_Common = bwp->bwp_Common;
-    NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
-    struct NR_PhysicalCellGroupConfig *phy_cgc = mac->scg->physicalCellGroupConfig;
-    switch (ss->searchSpaceType->present){
-      case NR_SearchSpace__searchSpaceType_PR_common:
-      // this is for CSSs, we use BWP common and pdcch_ConfigCommon
-
-      // Fetch configuration for searchSpaceZero
-      // note: The search space with the SearchSpaceId = 0 identifies the search space configured via PBCH (MIB) and in ServingCellConfigCommon (searchSpaceZero).
-      if (pdcch_ConfigCommon->choice.setup->searchSpaceZero){
-        if (pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 == NULL){
-          pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=calloc(1,sizeof(*pdcch_ConfigCommon->choice.setup->searchSpaceSIB1));
-        }
-        *pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 = 0;
-        LOG_D(MAC, "[DCI_CONFIG] Configure SearchSpace#0 of the initial BWP\n");
-      }
-      if (ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0){
-        // check available SS IDs
-        if (pdcch_ConfigCommon->choice.setup->ra_SearchSpace){
-          if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->ra_SearchSpace){
-            switch(ra->ra_state){
-              case WAIT_RAR:
-                LOG_D(NR_MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space (RA-Msg2)\n");
-                rel15->num_dci_options = 1;
-                rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
-                if (get_softmodem_params()->sa) {
-                  config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, -1);
-                } else {
-                  config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id);
-                }
-                fill_dci_search_candidates(ss, rel15);
-                break;
-              case WAIT_CONTENTION_RESOLUTION:
-                LOG_D(NR_MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space (RA-Msg4)\n");
-                rel15->num_dci_options = 1;
-                rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
-                config_dci_pdu(mac, rel15, dl_config, NR_RNTI_TC, -1);
-                fill_dci_search_candidates(ss, rel15);
-              break;
-              default:
-              break;
-            }
-          }
-        }
-        if (pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){
-          if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){
-            // Configure monitoring of PDCCH candidates in Type0-PDCCH common search space on the MCG
-            LOG_W(MAC, "[DCI_CONFIG] This seach space should not be configured yet...");
-          }
-        }
-        if (pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation){
-          if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation){
-            // Configure monitoring of PDCCH candidates in Type0-PDCCH common search space on the MCG
-            LOG_W(MAC, "[DCI_CONFIG] This seach space should not be configured yet...");
-          }
-        }
-        if (pdcch_ConfigCommon->choice.setup->pagingSearchSpace){
-          if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->pagingSearchSpace){
-            // Configure monitoring of PDCCH candidates in Type2-PDCCH common search space on the MCG
-            LOG_W(MAC, "[DCI_CONFIG] This seach space should not be configured yet...");
-          }
-        }
-        if (phy_cgc){
-          if (phy_cgc->cs_RNTI){
-            LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by CS-RNTI...\n");
-            LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
-          }
-          if (phy_cgc->ext1){
-            if (phy_cgc->ext1->mcs_C_RNTI){
-            LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by MCS-C-RNTI...\n");
-            LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
-            }
-          }
-        }
-      } // end DCI 00 and 01
-      // DCI 2_0
-      if (ss->searchSpaceType->choice.common->dci_Format2_0){
-        LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_0 with CRC scrambled by SFI-RNTI \n");
-        LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet...");
-      }
-      // DCI 2_1
-      if (ss->searchSpaceType->choice.common->dci_Format2_1){
-        LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_1 with CRC scrambled by INT-RNTI \n");
-        LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet...");
-      }
-      // DCI 2_2
-      if (ss->searchSpaceType->choice.common->dci_Format2_2){
-        LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_2 with CRC scrambled by TPC-RNTI \n");
-        LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet...");
-      }
-      // DCI 2_3
-      if (ss->searchSpaceType->choice.common->dci_Format2_3){
-        LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_3 with CRC scrambled by TPC-SRS-RNTI \n");
-        LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet...");
-      }
-
-      break;
-      case NR_SearchSpace__searchSpaceType_PR_ue_Specific:
-      // this is an USS
-      if (ss->searchSpaceType->choice.ue_Specific){
-        if(ss->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_1_And_1_1){
-          // Monitors DCI 01 and 11 scrambled with C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI
-          if ((ra->ra_state == RA_SUCCEEDED || get_softmodem_params()->phy_test) && mac->crnti > 0) {
-            LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in the user specific search space\n");
-            rel15->num_dci_options = 2;
-            rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_1;
-            rel15->dci_format_options[1] = NR_UL_DCI_FORMAT_0_1;
-            config_dci_pdu(mac, rel15, dl_config, NR_RNTI_C, ss_id);
-            fill_dci_search_candidates(ss, rel15);
-
-            #ifdef DEBUG_DCI
-            LOG_D(MAC, "[DCI_CONFIG] ss %d ue_Specific %p searchSpaceType->present %d dci_Formats %d\n",
-              ss_id,
-              ss->searchSpaceType->choice.ue_Specific,
-              ss->searchSpaceType->present,
-              ss->searchSpaceType->choice.ue_Specific->dci_Formats);
-            #endif
-          }
-          if (phy_cgc){
-            if (phy_cgc->cs_RNTI){
-              LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by CS-RNTI...\n");
-              LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
-            }
-            if (phy_cgc->sp_CSI_RNTI){
-              LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by SP-CSI-RNTI...\n");
-              LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
-            }
-            if (phy_cgc->ext1){
-              if (phy_cgc->ext1->mcs_C_RNTI){
-                LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by MCS-C-RNTI...\n");
-                LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
-              }
-            }
-          }
-        }
+  uint8_t bwp_id = (mac->cg) ? mac->DL_BWP_Id : 0, coreset_id = (mac->cg) ? 1 : 0;
+  //NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated;
+  NR_BWP_Downlink_t *bwp = (mac->cg) ? mac->DLbwp[bwp_id - 1] : NULL;
+
+  LOG_D(MAC, "[DCI_CONFIG] ra_rnti %p (%x) crnti %p (%x) t_crnti %p (%x)\n", &ra->ra_rnti, ra->ra_rnti, &mac->crnti, mac->crnti, &ra->t_crnti, ra->t_crnti);
+
+  if (mac->cg) { // do this only after we have a Master or Secondary Cell group
+    // loop over all available SS for BWP ID 1, CORESET ID 1
+    if (bwp) {
+      for (ss_id = 0; ss_id < FAPI_NR_MAX_SS_PER_CORESET && mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id] != NULL; ss_id++){
+	LOG_D(MAC, "[DCI_CONFIG] ss_id %d\n",ss_id);
+	NR_SearchSpace_t *ss = mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id];
+	fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
+	NR_BWP_DownlinkCommon_t *bwp_Common = bwp->bwp_Common;
+	NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
+	struct NR_PhysicalCellGroupConfig *phy_cgc = mac->cg->physicalCellGroupConfig;
+	switch (ss->searchSpaceType->present){
+	case NR_SearchSpace__searchSpaceType_PR_common:
+	  // this is for CSSs, we use BWP common and pdcch_ConfigCommon
+
+	  // Fetch configuration for searchSpaceZero
+	  // note: The search space with the SearchSpaceId = 0 identifies the search space configured via PBCH (MIB) and in ServingCellConfigCommon (searchSpaceZero).
+	  if (pdcch_ConfigCommon->choice.setup->searchSpaceZero){
+	    if (pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 == NULL){
+	      pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=calloc(1,sizeof(*pdcch_ConfigCommon->choice.setup->searchSpaceSIB1));
+	    }
+	    *pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 = 0;
+	    LOG_D(MAC, "[DCI_CONFIG] Configure SearchSpace#0 of the initial BWP\n");
+	  }
+	  if (ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0){
+	    // check available SS IDs
+	    if (pdcch_ConfigCommon->choice.setup->ra_SearchSpace){
+	      if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->ra_SearchSpace){
+		switch(ra->ra_state){
+		case WAIT_RAR:
+		  LOG_D(NR_MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space (RA-Msg2)\n");
+		  rel15->num_dci_options = 1;
+		  rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
+		  if (get_softmodem_params()->sa) {
+		    config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, -1);
+		  } else {
+		    config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id);
+		  }
+		  fill_dci_search_candidates(ss, rel15);
+		  break;
+		case WAIT_CONTENTION_RESOLUTION:
+		  LOG_D(NR_MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space (RA-Msg4)\n");
+		  rel15->num_dci_options = 1;
+		  rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
+		  config_dci_pdu(mac, rel15, dl_config, NR_RNTI_TC, -1);
+		  fill_dci_search_candidates(ss, rel15);
+		  break;
+		default:
+		  break;
+		}
+	      }
+	    }
+	    if (pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){
+	      if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){
+		// Configure monitoring of PDCCH candidates in Type0-PDCCH common search space on the MCG
+		LOG_W(MAC, "[DCI_CONFIG] This seach space should not be configured yet...");
+	      }
+	    }
+	    if (pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation){
+	      if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation){
+		// Configure monitoring of PDCCH candidates in Type0-PDCCH common search space on the MCG
+		LOG_W(MAC, "[DCI_CONFIG] This seach space should not be configured yet...");
+	      }
+	    }
+	    if (pdcch_ConfigCommon->choice.setup->pagingSearchSpace){
+	      if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->pagingSearchSpace){
+		// Configure monitoring of PDCCH candidates in Type2-PDCCH common search space on the MCG
+		LOG_W(MAC, "[DCI_CONFIG] This seach space should not be configured yet...");
+	      }
+	    }
+	    if (phy_cgc){
+	      if (phy_cgc->cs_RNTI){
+		LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by CS-RNTI...\n");
+		LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
+	      }
+	      if (phy_cgc->ext1){
+		if (phy_cgc->ext1->mcs_C_RNTI){
+		  LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by MCS-C-RNTI...\n");
+		  LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
+		}
+	      }
+	    }
+	  } // end DCI 00 and 01
+	  // DCI 2_0
+	  if (ss->searchSpaceType->choice.common->dci_Format2_0){
+	    LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_0 with CRC scrambled by SFI-RNTI \n");
+	    LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet...");
+	  }
+	  // DCI 2_1
+	  if (ss->searchSpaceType->choice.common->dci_Format2_1){
+	    LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_1 with CRC scrambled by INT-RNTI \n");
+	    LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet...");
+	  }
+	  // DCI 2_2
+	  if (ss->searchSpaceType->choice.common->dci_Format2_2){
+	    LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_2 with CRC scrambled by TPC-RNTI \n");
+	    LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet...");
+	  }
+	  // DCI 2_3
+	  if (ss->searchSpaceType->choice.common->dci_Format2_3){
+	    LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_3 with CRC scrambled by TPC-SRS-RNTI \n");
+	    LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet...");
+	  }
+
+	  break;
+	case NR_SearchSpace__searchSpaceType_PR_ue_Specific:
+	  // this is an USS
+	  if (ss->searchSpaceType->choice.ue_Specific){
+	    if(ss->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_1_And_1_1){
+	      // Monitors DCI 01 and 11 scrambled with C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI
+	      if ((ra->ra_state == RA_SUCCEEDED || get_softmodem_params()->phy_test) && mac->crnti > 0) {
+          LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in the user specific search space\n");
+          rel15->num_dci_options = 2;
+          rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_1;
+          rel15->dci_format_options[1] = NR_UL_DCI_FORMAT_0_1;
+          config_dci_pdu(mac, rel15, dl_config, NR_RNTI_C, ss_id);
+          fill_dci_search_candidates(ss, rel15);
+
+#ifdef DEBUG_DCI
+		LOG_D(MAC, "[DCI_CONFIG] ss %d ue_Specific %p searchSpaceType->present %d dci_Formats %d\n",
+		      ss_id,
+		      ss->searchSpaceType->choice.ue_Specific,
+		      ss->searchSpaceType->present,
+		      ss->searchSpaceType->choice.ue_Specific->dci_Formats);
+#endif
+	      }
+	      if (phy_cgc){
+		if (phy_cgc->cs_RNTI){
+		  LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by CS-RNTI...\n");
+		  LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
+		}
+		if (phy_cgc->sp_CSI_RNTI){
+		  LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by SP-CSI-RNTI...\n");
+		  LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
+		}
+		if (phy_cgc->ext1){
+		  if (phy_cgc->ext1->mcs_C_RNTI){
+		    LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by MCS-C-RNTI...\n");
+		    LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
+		  }
+		}
+	      }
+	    }
+	  }
+	  break;
+	default:
+	  AssertFatal(1 == 0, "[DCI_CONFIG] Unrecognized search space type...");
+	  break;
+	}
       }
-      break;
-      default:
-      AssertFatal(1 == 0, "[DCI_CONFIG] Unrecognized search space type...");
-      break;
     }
   }
+  else {
 
+    AssertFatal(1==0,"Handle DCI searching when CellGroup without dedicated BWP\n");
+  }
   // Search space 0, CORESET ID 0
 
-  NR_BWP_DownlinkCommon_t *bwp_Common = bwp->bwp_Common;
-  NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
+  NR_BWP_DownlinkCommon_t *bwp_Common = bwp ? bwp->bwp_Common : NULL;
+  NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp?bwp_Common->pdcch_ConfigCommon:NULL;
 
-  if (pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){
+  if (pdcch_ConfigCommon &&
+      pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){
 
     NR_SearchSpace_t *ss0 = mac->search_space_zero;
     fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
@@ -399,5 +425,13 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
       }
     }
   }
-
+  else { // use coreset0/ss0
+    NR_SearchSpace_t *ss0 = mac->search_space_zero;
+    fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15;
+    rel15->num_dci_options = 1;
+    rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
+    config_dci_pdu(mac, rel15, dl_config, NR_RNTI_C , -1);
+    fill_dci_search_candidates(ss0, rel15);
+    dl_config->number_pdus = 1;
+  }
 }
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index bdf7daa9ee9435c3488646d5fda03a8a9a5c794c..9191a8a493be6ce292a479371f53f1265611b770 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -62,10 +62,13 @@
 #include "common/utils/LOG/log.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 
+//#define DEBUG_MIB
 //#define ENABLE_MAC_PAYLOAD_DEBUG 1
 //#define DEBUG_EXTRACT_DCI
 //#define DEBUG_RAR
 
+extern uint32_t N_RB_DL;
+
 int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti){
 
     RA_config_t *ra = &mac->ra;
@@ -99,47 +102,54 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
                         uint32_t ssb_length,
                         uint32_t ssb_index,
                         void *pduP,
+                        uint16_t ssb_start_subcarrier,
                         uint16_t cell_id)
 {
   LOG_D(MAC,"[L2][MAC] decode mib\n");
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
-  NR_ServingCellConfigCommon_t    *scc = mac->scc;
-  frequency_range_t frequency_range;
+  mac->physCellId = cell_id;
+
   nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_BCH, (uint8_t *) pduP, 3 );    //  fixed 3 bytes MIB PDU
     
   AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n");
   //if(mac->mib != NULL){
   uint16_t frame = (mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused);
   uint16_t frame_number_4lsb = 0;
+
   for (int i=0; i<4; i++)
     frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i);
-  uint8_t half_frame_bit = ( extra_bits >> 4 ) & 0x1;               //	extra bits[4]
+
   uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1;    //	extra bits[5]
   uint8_t ssb_subcarrier_offset = (uint8_t)mac->mib->ssb_SubcarrierOffset;
 
   frame = frame << 4;
   frame = frame | frame_number_4lsb;
   if(ssb_length == 64){
-    frequency_range = FR2;
+    mac->frequency_range = FR2;
     for (int i=0; i<3; i++)
       ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i));
   }else{
-    frequency_range = FR1;
+    mac->frequency_range = FR1;
     if(ssb_subcarrier_offset_msb){
       ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
     }
   }
 
-  LOG_D(MAC,"system frame number(6 MSB bits): %d\n",  mac->mib->systemFrameNumber.buf[0]);
-  LOG_D(MAC,"system frame number(with LSB): %d\n", (int)frame);
-  LOG_D(MAC,"subcarrier spacing (0=15or60, 1=30or120): %d\n", (int)mac->mib->subCarrierSpacingCommon);
-  LOG_D(MAC,"ssb carrier offset(with MSB):  %d\n", (int)ssb_subcarrier_offset);
-  LOG_D(MAC,"dmrs type A position (0=pos2,1=pos3): %d\n", (int)mac->mib->dmrs_TypeA_Position);
-  LOG_D(MAC,"cell barred (0=barred,1=notBarred): %d\n", (int)mac->mib->cellBarred);
-  LOG_D(MAC,"intra frequency reselection (0=allowed,1=notAllowed): %d\n", (int)mac->mib->intraFreqReselection);
-  LOG_D(MAC,"half frame bit(extra bits):    %d\n", (int)half_frame_bit);
-  LOG_D(MAC,"ssb index(extra bits):         %d\n", (int)ssb_index);
+#ifdef DEBUG_MIB
+  uint8_t half_frame_bit = ( extra_bits >> 4 ) & 0x1; //	extra bits[4]
+  LOG_I(MAC,"system frame number(6 MSB bits): %d\n",  mac->mib->systemFrameNumber.buf[0]);
+  LOG_I(MAC,"system frame number(with LSB): %d\n", (int)frame);
+  LOG_I(MAC,"subcarrier spacing (0=15or60, 1=30or120): %d\n", (int)mac->mib->subCarrierSpacingCommon);
+  LOG_I(MAC,"ssb carrier offset(with MSB):  %d\n", (int)ssb_subcarrier_offset);
+  LOG_I(MAC,"dmrs type A position (0=pos2,1=pos3): %d\n", (int)mac->mib->dmrs_TypeA_Position);
+  LOG_I(MAC,"controlResourceSetZero: %d\n", (int)mac->mib->pdcch_ConfigSIB1.controlResourceSetZero);
+  LOG_I(MAC,"searchSpaceZero: %d\n", (int)mac->mib->pdcch_ConfigSIB1.searchSpaceZero);
+  LOG_I(MAC,"cell barred (0=barred,1=notBarred): %d\n", (int)mac->mib->cellBarred);
+  LOG_I(MAC,"intra frequency reselection (0=allowed,1=notAllowed): %d\n", (int)mac->mib->intraFreqReselection);
+  LOG_I(MAC,"half frame bit(extra bits):    %d\n", (int)half_frame_bit);
+  LOG_I(MAC,"ssb index(extra bits):         %d\n", (int)ssb_index);
+#endif
 
   //storing ssb index in the mac structure
   mac->mib_ssb = ssb_index;
@@ -147,16 +157,10 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
   if (get_softmodem_params()->sa == 1) {
 
     // TODO these values shouldn't be taken from SCC in SA
-    uint8_t scs_ssb = *scc->ssbSubcarrierSpacing;
-    uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
-    int scs_scaling = 1<<scs_ssb;
-    if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000)
-      scs_scaling = scs_scaling*3;
-    if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666)
-      scs_scaling = scs_scaling>>2;
-    uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
-
+    uint8_t scs_ssb = get_softmodem_params()->numerology;
+    uint32_t band   = get_softmodem_params()->band;
     uint16_t ssb_start_symbol = get_ssb_start_symbol(band,scs_ssb,ssb_index);
+    uint16_t ssb_offset_point_a = (ssb_start_subcarrier - ssb_subcarrier_offset)/12;
 
     get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config,
                                           frame,
@@ -165,9 +169,9 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
                                           ssb_subcarrier_offset,
                                           ssb_start_symbol,
                                           scs_ssb,
-                                          frequency_range,
+                                          mac->frequency_range,
                                           ssb_index,
-                                          absolute_diff/(12*scs_scaling)-10);
+                                          ssb_offset_point_a);
 
 
     mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern;
@@ -230,10 +234,10 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
       return -1;
     }
 
-    LOG_D(MAC,"riv = %i\n", riv);
-    LOG_D(MAC,"n_RB_DLBWP = %i\n", n_RB_DLBWP);
-    LOG_D(MAC,"number_rbs = %i\n", dlsch_config_pdu->number_rbs);
-    LOG_D(MAC,"start_rb = %i\n", dlsch_config_pdu->start_rb);
+    LOG_D(MAC,"DLSCH riv = %i\n", riv);
+    LOG_D(MAC,"DLSCH n_RB_DLBWP = %i\n", n_RB_DLBWP);
+    LOG_D(MAC,"DLSCH number_rbs = %i\n", dlsch_config_pdu->number_rbs);
+    LOG_D(MAC,"DLSCH start_rb = %i\n", dlsch_config_pdu->start_rb);
 
   }
   if(pusch_config_pdu != NULL){
@@ -256,7 +260,10 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
       LOG_W(MAC, "Frequency domain assignment values are invalid! #RBs: %d, Start RB: %d, n_RB_ULBWP: %d \n",pusch_config_pdu->rb_size, pusch_config_pdu->rb_start, n_RB_ULBWP);
       return -1;
     }
-
+    LOG_D(MAC,"ULSCH riv = %i\n", riv);
+    LOG_D(MAC,"ULSCH n_RB_DLBWP = %i\n", n_RB_ULBWP);
+    LOG_D(MAC,"ULSCH number_rbs = %i\n", pusch_config_pdu->rb_size);
+    LOG_D(MAC,"ULSCH start_rb = %i\n", pusch_config_pdu->rb_start);
   }
   return 0;
 }
@@ -265,9 +272,10 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
 						      nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
 						      fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
 						      uint8_t time_domain_ind,
-						      bool use_default){
+						      bool use_default
+						      ){
+  int dmrs_typeA_pos = (mac->scc != NULL) ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position;
 
-  int dmrs_typeA_pos = mac->scc->dmrs_TypeA_Position;
 //  uint8_t k_offset=0;
   uint8_t sliv_S=0;
   uint8_t sliv_L=0;
@@ -319,10 +327,16 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
    */
   if(dlsch_config_pdu != NULL){
     NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL;
-    if (mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
+    if (mac->DLbwp[dl_bwp_id-1] &&
+        mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated &&
+        mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config &&
+        mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
       pdsch_TimeDomainAllocationList = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList->choice.setup;
-    else if (mac->DLbwp[dl_bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
+    else if (mac->DLbwp[dl_bwp_id-1] && mac->DLbwp[dl_bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
       pdsch_TimeDomainAllocationList = mac->DLbwp[dl_bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+    else if (mac->scc_SIB && mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup)
+      pdsch_TimeDomainAllocationList = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+
     if (pdsch_TimeDomainAllocationList && use_default==false) {
 
       if (time_domain_ind >= pdsch_TimeDomainAllocationList->list.count) {
@@ -372,13 +386,22 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
 	 */
   if(pusch_config_pdu != NULL){
     NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
-    if (mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
+    if (mac->ULbwp[ul_bwp_id-1] &&
+        mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated &&
+        mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config &&
+        mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup &&
+        mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
       pusch_TimeDomainAllocationList = mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
     }
-    else if (mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+    else if (mac->ULbwp[ul_bwp_id-1] &&
+      mac->ULbwp[ul_bwp_id-1]->bwp_Common &&
+      mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon &&
+      mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup &&
+      mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
       pusch_TimeDomainAllocationList = mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
     }
-    	
+    else pusch_TimeDomainAllocationList = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+
     if (pusch_TimeDomainAllocationList && use_default==false) {
       if (time_domain_ind >= pusch_TimeDomainAllocationList->list.count) {
         LOG_E(MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n",
@@ -388,6 +411,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
         return -1;
       }
       
+      LOG_D(NR_MAC,"Filling Time-Domain Allocation from pusch_TimeDomainAllocationList\n");
       int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[time_domain_ind]->startSymbolAndLength;
       int S,L;
       SLIV2SL(startSymbolAndLength,&S,&L);
@@ -395,6 +419,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
       pusch_config_pdu->nr_of_symbols=L;
     }
     else {
+      LOG_D(NR_MAC,"Filling Time-Domain Allocation from tables\n");
 //      k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0];
       sliv_S   = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind][1];
       sliv_L   = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind][2];
@@ -404,6 +429,8 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
       pusch_config_pdu->nr_of_symbols = sliv_L;
       pusch_config_pdu->start_symbol_index = sliv_S;
     }
+    LOG_D(NR_MAC,"start_symbol = %i\n", pusch_config_pdu->start_symbol_index);
+    LOG_D(NR_MAC,"number_symbols = %i\n", pusch_config_pdu->nr_of_symbols);
   }
   return 0;
 }
@@ -411,13 +438,14 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
 int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci) {
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
+  dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format];
 
   LOG_D(MAC,"Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n",
 	dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits);
-
-  if (nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, (uint64_t *)dci->payloadBits, &mac->def_dci_pdu_rel15[dci->dci_format]))
-    return -1;
-  return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, &mac->def_dci_pdu_rel15[dci->dci_format], dci->rnti, dci->dci_format));
+  int8_t ret = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15);
+  if ((ret&1) == 1) return -1;
+  else if (ret == 2) dci->dci_format = NR_UL_DCI_FORMAT_0_0;
+  return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci->rnti, dci->dci_format));
 }
 
 int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, uint16_t rnti, uint8_t dci_format){
@@ -434,11 +462,10 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
   NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id;
   NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
 
-  //const uint16_t n_RB_DLBWP = dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP; //make sure this has been set
-  AssertFatal(mac->DLbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n");
-  AssertFatal(mac->ULbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n");
-
-  const uint16_t n_RB_DLBWP = (ra->ra_state == WAIT_RAR || ra->ra_state == WAIT_CONTENTION_RESOLUTION) ? NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) : NRRIV2BW(mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  uint16_t n_RB_DLBWP;
+  if (mac->DLbwp[dl_bwp_id-1]) n_RB_DLBWP = NRRIV2BW(mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  else if (mac->scc_SIB) n_RB_DLBWP =  NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
+  else n_RB_DLBWP = mac->type0_PDCCH_CSS_config.num_rbs;
 
   LOG_D(MAC, "In %s: Processing received DCI format %s (DL BWP %d)\n", __FUNCTION__, dci_formats[dci_format], n_RB_DLBWP);
 
@@ -477,6 +504,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
         return -1;
       }
 
+      AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
       nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
 
       fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
@@ -601,14 +629,15 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 
     dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti;
     fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_0 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15;
-    NR_PDSCH_Config_t *pdsch_config = NULL;
-    uint16_t BWPSize = 0;
+    NR_PDSCH_Config_t *pdsch_config= (mac->DLbwp[dl_bwp_id-1]) ? mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup : NULL;
+    uint16_t BWPSize = n_RB_DLBWP;
 
     if(rnti == SI_RNTI) {
       dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH;
       dlsch_config_pdu_1_0->BWPSize = mac->type0_PDCCH_CSS_config.num_rbs;
       dlsch_config_pdu_1_0->BWPStart = mac->type0_PDCCH_CSS_config.cset_start_rb;
       dlsch_config_pdu_1_0->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon;
+      if (pdsch_config) pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; // For PDSCH with mapping type A, the UE shall assume dmrs-AdditionalPosition='pos2'
       BWPSize = dlsch_config_pdu_1_0->BWPSize;
     } else {
       if (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti){
@@ -617,20 +646,30 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
         dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
       }
       if( (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti) || (rnti == ra->t_crnti) ) {
-        dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-        if (get_softmodem_params()->sa) {
+        if (mac->scc == NULL) {
+          dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+          dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+        }
+        else {
+          dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
           dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-        } else { // NSA mode is not using the Initial BWP
+        }
+        if (!get_softmodem_params()->sa) { // NSA mode is not using the Initial BWP
           dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
           pdsch_config = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup;
+          BWPSize = dlsch_config_pdu_1_0->BWPSize;
         }
-      } else {
+      } else if (mac->DLbwp[dl_bwp_id-1]) {
         dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
         dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
         dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing;
         pdsch_config = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup;
+      } else if (mac->scc_SIB) {
+        dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+        dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+        dlsch_config_pdu_1_0->SubcarrierSpacing = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.subcarrierSpacing;
+        pdsch_config = NULL;
       }
-      BWPSize = n_RB_DLBWP;
     }
 
     /* IDENTIFIER_DCI_FORMATS */
@@ -646,24 +685,25 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     }
 
     NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL;
-    if (mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
+    if (mac->DLbwp[dl_bwp_id-1] &&
+        mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated &&
+        mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config &&
+        mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
       pdsch_TimeDomainAllocationList = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList->choice.setup;
-    else if (mac->DLbwp[dl_bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
+    else if (mac->DLbwp[dl_bwp_id-1] && mac->DLbwp[dl_bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
       pdsch_TimeDomainAllocationList = mac->DLbwp[dl_bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+    else if (mac->scc_SIB && mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup)
+      pdsch_TimeDomainAllocationList = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
 
-    int mappingtype = pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType;
+    int mappingtype = pdsch_TimeDomainAllocationList ? pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType : ((dlsch_config_pdu_1_0->start_symbol <= 3)? typeA: typeB);
 
     /* dmrs symbol positions*/
-    dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(NULL,
-							 mac->scc->dmrs_TypeA_Position,
-               dlsch_config_pdu_1_0->number_symbols,
-               dlsch_config_pdu_1_0->start_symbol,
-               mappingtype);
-
-    // For DCI 1_0, dmrs type is type1. referred to section 5.1.6.2 of 3GPP TS 38.214
-    dlsch_config_pdu_1_0->dmrsConfigType = 0;
-    LOG_D(MAC, "DCI 1_0 start_sym:%d NR Symb:%d, DMRS_symb_pos:%x\n", dlsch_config_pdu_1_0->start_symbol, dlsch_config_pdu_1_0->number_symbols, dlsch_config_pdu_1_0->dlDmrsSymbPos);
-
+    dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
+                                                         mac->mib->dmrs_TypeA_Position,
+                                                         dlsch_config_pdu_1_0->number_symbols,
+                                                         dlsch_config_pdu_1_0->start_symbol,
+                                                         mappingtype);
+    dlsch_config_pdu_1_0->dmrsConfigType = (mac->DLbwp[dl_bwp_id-1] != NULL) ? (mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0;
     /* number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214 version 15.9.0 Release 15 */
     if (dlsch_config_pdu_1_0->number_symbols == 2)
       dlsch_config_pdu_1_0->n_dmrs_cdm_groups = 1;
@@ -712,20 +752,42 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     dlsch_config_pdu_1_0->pucch_resource_id = dci->pucch_resource_indicator;
     // Sanity check for pucch_resource_indicator value received to check for false DCI.
     valid = 0;
-    pucch_res_set_cnt = mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.count;
-    for (int id = 0; id < pucch_res_set_cnt; id++) {
-      if (dlsch_config_pdu_1_0->pucch_resource_id < mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) {
-        valid = 1;
-        break;
+    if (mac->ULbwp[ul_bwp_id-1] &&
+        mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated &&
+        mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config &&
+        mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup&&
+        mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList) {
+      pucch_res_set_cnt = mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.count;
+      for (int id = 0; id < pucch_res_set_cnt; id++) {
+	if (dlsch_config_pdu_1_0->pucch_resource_id < mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) {
+	  valid = 1;
+	  break;
+	}
       }
     }
+    else if (mac->cg &&
+             mac->cg->spCellConfig &&
+             mac->cg->spCellConfig->spCellConfigDedicated &&
+             mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+             mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
+             mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config &&
+             mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup &&
+             mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList){
+      pucch_res_set_cnt = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList->list.count;
+      for (int id = 0; id < pucch_res_set_cnt; id++) {
+        if (dlsch_config_pdu_1_0->pucch_resource_id < mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) {
+          valid = 1;
+          break;
+        }
+      }
+    } else valid=1;
     if (!valid) {
       LOG_W(MAC, "[%d.%d] pucch_resource_indicator value %d is out of bounds. Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_0->pucch_resource_id);
       return -1;
     }
 
     /* PDSCH_TO_HARQ_FEEDBACK_TIME_IND (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI)*/
-    dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind = mac->ULbwp[mac->UL_BWP_Id-1]->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0];
+    dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind = 1+dci->pdsch_to_harq_feedback_timing_indicator.val;
 
     LOG_D(MAC,"(nr_ue_procedures.c) rnti = %x dl_config->number_pdus = %d\n",
 	  dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti,
@@ -820,12 +882,17 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     }
 
     NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL;
-    if (mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
+    if (mac->DLbwp[dl_bwp_id-1] &&
+        mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated &&
+        mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config &&
+        mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
       pdsch_TimeDomainAllocationList = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList->choice.setup;
-    else if (mac->DLbwp[dl_bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
+    else if (mac->DLbwp[dl_bwp_id-1] && mac->DLbwp[dl_bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
       pdsch_TimeDomainAllocationList = mac->DLbwp[dl_bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+    else if (mac->scc_SIB && mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup)
+      pdsch_TimeDomainAllocationList = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
 
-    int mappingtype = pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType;
+    int mappingtype = pdsch_TimeDomainAllocationList ? pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType : ((dlsch_config_pdu_1_1->start_symbol <= 3)? typeA: typeB);
 
     /* dmrs symbol positions*/
     dlsch_config_pdu_1_1->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
@@ -1135,24 +1202,34 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
                             uint64_t *dci_pdu,
                             dci_pdu_rel15_t *dci_pdu_rel15) {
 
-  int rnti_type = get_rnti_type(mac, rnti);
+  int N_RB = 0;
+  int pos = 0;
+  int fsize = 0;
 
-  AssertFatal(mac->DLbwp[0] != NULL, "DLbwp[0] shouldn't be null here!\n");
-  AssertFatal(mac->ULbwp[0] != NULL, "ULbwp[0] shouldn't be null here!\n");
-  int N_RB = get_n_rb(mac, rnti_type);
+  int rnti_type = get_rnti_type(mac, rnti);
   NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
-  int N_RB_UL = (mac->scg != NULL) ? 
-    NRRIV2BW(mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) :
-    NRRIV2BW(mac->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id;
 
-  int pos=0;
-  int fsize=0;
+  int N_RB_UL = 0;
+  if(mac->scc_SIB) {
+    N_RB_UL = NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  } else if(mac->ULbwp[ul_bwp_id-1]) {
+    N_RB_UL = NRRIV2BW(mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  } else if(mac->scc) {
+    N_RB_UL = NRRIV2BW(mac->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  }
 
+  LOG_D(MAC,"nr_extract_dci_info : dci_pdu %lx, size %d\n",*dci_pdu,dci_size);
   switch(dci_format) {
 
   case NR_DL_DCI_FORMAT_1_0:
     switch(rnti_type) {
     case NR_RNTI_RA:
+      if(mac->scc_SIB) {
+        N_RB = NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      } else {
+        N_RB = get_n_rb(mac, rnti_type);
+      }
       // Freq domain assignment
       fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
       pos=fsize;
@@ -1192,11 +1269,19 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
       //Identifier for DCI formats
       pos++;
       dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
+
+      //switch to DCI_0_0
       if (dci_pdu_rel15->format_indicator == 0)
-        return 1; // discard dci, format indicator not corresponding to dci_format
+        return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, dci_pdu, dci_pdu_rel15);
+
 #ifdef DEBUG_EXTRACT_DCI
       LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu);
 #endif
+
+      // check BWP id
+      if (mac->DLbwp[dl_bwp_id-1]) N_RB=NRRIV2BW(mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      else         N_RB=NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
       // Freq domain assignment (275rb >> fsize = 16)
       fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
       pos+=fsize;
@@ -1336,46 +1421,50 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
       break;
   	
     case NR_RNTI_SI:
+      N_RB = mac->type0_PDCCH_CSS_config.num_rbs;
+      // Freq domain assignment 0-16 bit
+      fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
+      pos+=fsize;
+      dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
 
-        // Freq domain assignment 0-16 bit
-        fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
-        pos+=fsize;
-        dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
-
-        // Time domain assignment 4 bit
-        pos+=4;
-        dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf;
+      // Time domain assignment 4 bit
+      pos+=4;
+      dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf;
 
-        // VRB to PRB mapping 1 bit
-        pos++;
-        dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&0x1;
+      // VRB to PRB mapping 1 bit
+      pos++;
+      dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&0x1;
 
-        // MCS 5bit  //bit over 32, so dci_pdu ++
-        pos+=5;
-        dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f;
+      // MCS 5bit  //bit over 32, so dci_pdu ++
+      pos+=5;
+      dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f;
 
-        // Redundancy version  2 bit
-        pos+=2;
-        dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&3;
+      // Redundancy version  2 bit
+      pos+=2;
+      dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&3;
 
-        // System information indicator 1 bit
-        pos++;
-        dci_pdu_rel15->system_info_indicator = (*dci_pdu>>(dci_size-pos))&0x1;
-
-        LOG_D(MAC,"N_RB = %i\n", N_RB);
-        LOG_D(MAC,"dci_size = %i\n", dci_size);
-        LOG_D(MAC,"fsize = %i\n", fsize);
-        LOG_D(MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val);
-        LOG_D(MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val);
-        LOG_D(MAC,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val);
-        LOG_D(MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs);
-        LOG_D(MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv);
-        LOG_D(MAC,"dci_pdu_rel15->system_info_indicator = %i\n", dci_pdu_rel15->system_info_indicator);
+      // System information indicator 1 bit
+      pos++;
+      dci_pdu_rel15->system_info_indicator = (*dci_pdu>>(dci_size-pos))&0x1;
+
+      LOG_D(MAC,"N_RB = %i\n", N_RB);
+      LOG_D(MAC,"dci_size = %i\n", dci_size);
+      LOG_D(MAC,"fsize = %i\n", fsize);
+      LOG_D(MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val);
+      LOG_D(MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val);
+      LOG_D(MAC,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val);
+      LOG_D(MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs);
+      LOG_D(MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv);
+      LOG_D(MAC,"dci_pdu_rel15->system_info_indicator = %i\n", dci_pdu_rel15->system_info_indicator);
 
       break;
 	
     case NR_RNTI_TC:
 
+      // check BWP id
+      if (mac->DLbwp[dl_bwp_id-1]) N_RB=NRRIV2BW(mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      else         N_RB=NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
       // indicating a DL DCI format - 1 bit
       pos++;
       dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
@@ -1448,38 +1537,68 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
     break;
   
   case NR_UL_DCI_FORMAT_0_0:
+    if (mac->ULbwp[ul_bwp_id-1]) N_RB_UL=NRRIV2BW(mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    else         N_RB_UL=NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
     switch(rnti_type)
       {
       case NR_RNTI_C:
         //Identifier for DCI formats
         pos++;
         dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
+#ifdef DEBUG_EXTRACT_DCI
+	LOG_D(MAC,"Format indicator %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,dci_size-pos,*dci_pdu);
+#endif
         if (dci_pdu_rel15->format_indicator == 1)
           return 1; // discard dci, format indicator not corresponding to dci_format
 	fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) );
 	pos+=fsize;
 	dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
+#ifdef DEBUG_EXTRACT_DCI
+	LOG_D(MAC,"Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,dci_size-pos,*dci_pdu);
+#endif
 	// Time domain assignment 4bit
 	pos+=4;
 	dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf;
+#ifdef DEBUG_EXTRACT_DCI
+      LOG_D(MAC,"time-domain assignment %d  (4 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,dci_size-pos,*dci_pdu);
+#endif
 	// Frequency hopping flag  E1 bit
 	pos++;
 	dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1;
+#ifdef DEBUG_EXTRACT_DCI
+      LOG_D(MAC,"frequency_hopping %d  (1 bit)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_hopping_flag.val,dci_size-pos,*dci_pdu);
+#endif
 	// MCS  5 bit
 	pos+=5;
 	dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f;
+#ifdef DEBUG_EXTRACT_DCI
+      LOG_D(MAC,"mcs %d  (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu);
+#endif
 	// New data indicator 1bit
 	pos++;
 	dci_pdu_rel15->ndi= (*dci_pdu>>(dci_size-pos))&1;
+#ifdef DEBUG_EXTRACT_DCI
+	LOG_D(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu);
+#endif
 	// Redundancy version  2bit
 	pos+=2;
 	dci_pdu_rel15->rv= (*dci_pdu>>(dci_size-pos))&3;
+#ifdef DEBUG_EXTRACT_DCI
+	LOG_D(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu);
+#endif
 	// HARQ process number  4bit
 	pos+=4;
 	dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
+#ifdef DEBUG_EXTRACT_DCI
+	LOG_D(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_pid,4,dci_size-pos,*dci_pdu);
+#endif
 	// TPC command for scheduled PUSCH  E2 bits
 	pos+=2;
 	dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3;
+#ifdef DEBUG_EXTRACT_DCI
+	LOG_D(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc,2,dci_size-pos,*dci_pdu);
+#endif
 	// UL/SUL indicator  E1 bit
 	/* commented for now (RK): need to get this from BWP descriptor
 	   if (cfg->pucch_config.pucch_GroupHopping.value)
@@ -1640,10 +1759,7 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
 
         // Freq domain assignment  max 16 bit
         fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) );
-        //pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
         pos+=fsize;
-        
-        //pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
         dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
         
         // Time domain assignment 4bit
@@ -1779,7 +1895,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
   frame_t frameP         = dl_info->frame;
   int slot               = dl_info->slot;
   uint8_t *pduP          = (dl_info->rx_ind->rx_indication_body + pdu_id)->pdsch_pdu.pdu;
-  int32_t pdu_len        = (dl_info->rx_ind->rx_indication_body + pdu_id)->pdsch_pdu.pdu_length;
+  int16_t pdu_len        = (int16_t)(dl_info->rx_ind->rx_indication_body + pdu_id)->pdsch_pdu.pdu_length;
   uint8_t gNB_index      = dl_info->gNB_index;
   uint8_t CC_id          = dl_info->cc_id;
   uint8_t done           = 0;
@@ -1797,9 +1913,6 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
         mac_subheader_len = 0x0001; //  default to fixed-length subheader = 1-oct
         mac_sdu_len = 0x0000;
         rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
-	  //#ifdef DEBUG_HEADER_PARSING
-              LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID, pdu_len);
-	      //#endif
 
         LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", rx_lcid, pdu_len);
         switch(rx_lcid){
@@ -2012,8 +2125,8 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
                     LOG_T(MAC, "\n");
                 #endif
 
-                if (IS_SOFTMODEM_NOS1){
-                  if (rx_lcid < NB_RB_MAX && rx_lcid >= DL_SCH_LCID_DTCH) {
+//                if (IS_SOFTMODEM_NOS1){
+                  if (rx_lcid < NB_RB_MAX && rx_lcid >= DL_SCH_LCID_DCCH) {
 
                     mac_rlc_data_ind(module_idP,
                                      mac->crnti,
@@ -2029,7 +2142,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
                   } else {
                     LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, gNB_index);
                   }
-                }
+//                }
 
             break;
         }
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index ecf1ce1a83adc6303e29faf0ec4a7fb8406a2b63..f75b70254ca5ff3fa3363fbe810f67c95e9131f2 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -63,7 +63,7 @@ void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, in
   ul_config->sfn = frame_tx;
   ul_config->number_pdus++;
 
-  LOG_D(MAC, "In %s: Set config request for UL transmission in [%d.%d], number of UL PDUs: %d\n", __FUNCTION__, ul_config->sfn, ul_config->slot, ul_config->number_pdus);
+  LOG_D(NR_MAC, "In %s: Set config request for UL transmission in [%d.%d], number of UL PDUs: %d\n", __FUNCTION__, ul_config->sfn, ul_config->slot, ul_config->number_pdus);
 
 }
 
@@ -96,17 +96,25 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) {
   long k2 = -1;
   NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
   // Get K2 from RRC configuration
-  NR_PUSCH_Config_t *pusch_config=mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup;
+  NR_PUSCH_Config_t *pusch_config=mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : NULL;
   NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
-  if (pusch_config->pusch_TimeDomainAllocationList) {
+  if (pusch_config && pusch_config->pusch_TimeDomainAllocationList) {
     pusch_TimeDomainAllocationList = pusch_config->pusch_TimeDomainAllocationList->choice.setup;
   }
-  else if (mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+  else if (mac->ULbwp[ul_bwp_id-1] &&
+	   mac->ULbwp[ul_bwp_id-1]->bwp_Common&&
+	   mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon&&
+	   mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup &&
+	   mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
     pusch_TimeDomainAllocationList = mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
   }
+  else if (mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList)
+    pusch_TimeDomainAllocationList=mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+  else AssertFatal(1==0,"need to fall back to default PUSCH time-domain allocations\n");
+
   if (pusch_TimeDomainAllocationList) {
     if (time_domain_ind >= pusch_TimeDomainAllocationList->list.count) {
-      LOG_E(MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n",
+      LOG_E(NR_MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n",
             time_domain_ind, pusch_TimeDomainAllocationList->list.count);
       return -1;
     }
@@ -117,7 +125,7 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) {
               "Slot offset K2 (%ld) cannot be less than DURATION_RX_TO_TX (%d)\n",
               k2,DURATION_RX_TO_TX);
 
-  LOG_D(MAC, "get_k2(): k2 is %ld\n", k2);
+  LOG_D(NR_MAC, "get_k2(): k2 is %ld\n", k2);
   return k2;
 }
 
@@ -128,22 +136,26 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) {
 fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot)
 {
   NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
+  NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->scc==NULL ? mac->scc_SIB->tdd_UL_DL_ConfigurationCommon : mac->scc->tdd_UL_DL_ConfigurationCommon;
+
   //Check if request to access ul_config is for a UL slot
-  if (is_nr_UL_slot(mac->scc, slot, mac->frame_type) == 0) {
-    LOG_W(MAC, "Slot %d is not a UL slot. %s called for wrong slot!!!\n", slot, __FUNCTION__);
+  if (is_nr_UL_slot(tdd_config, slot, mac->frame_type) == 0) {
+    LOG_W(NR_MAC, "Slot %d is not a UL slot. %s called for wrong slot!!!\n", slot, __FUNCTION__);
     return NULL;
   }
 
   // Calculate the index of the UL slot in mac->ul_config_request list. This is
   // based on the TDD pattern (slot configuration period) and number of UL+mixed
   // slots in the period. TS 38.213 Sec 11.1
-  int mu = mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing;
-  NR_TDD_UL_DL_Pattern_t *tdd_pattern = &mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1;
+  int mu = mac->ULbwp[ul_bwp_id-1] ?
+    mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing :
+    mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
+  NR_TDD_UL_DL_Pattern_t *tdd_pattern = &tdd_config->pattern1;
   const int num_slots_per_tdd = nr_slots_per_frame[mu] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity);
   const int num_slots_ul = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0);
-  int index = (slot + num_slots_ul - num_slots_per_tdd) % num_slots_per_tdd;
+  int index = slot % num_slots_ul;
 
-  LOG_D(MAC, "In %s slots per tdd %d, num_slots_ul %d, index %d\n", __FUNCTION__,
+  LOG_D(NR_MAC, "In %s slots per tdd %d, num_slots_ul %d, index %d\n", __FUNCTION__,
                 num_slots_per_tdd,
                 num_slots_ul,
                 index);
@@ -499,7 +511,6 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
   uint16_t number_dmrs_symbols = 0;
   int                N_PRB_oh  = 0;
 
-  NR_ServingCellConfigCommon_t *scc = mac->scc;
   int rnti_type = get_rnti_type(mac, rnti);
   NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
 
@@ -508,6 +519,9 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
   pusch_config_pdu->pdu_bit_map      = PUSCH_PDU_BITMAP_PUSCH_DATA;
   pusch_config_pdu->nrOfLayers       = 1;
   pusch_config_pdu->rnti             = rnti;
+  NR_BWP_UplinkCommon_t *initialUplinkBWP;
+  if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP;
+  else          initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP;
 
   pusch_dmrs_AdditionalPosition_t add_pos = pusch_dmrs_pos2;
   pusch_maxLength_t dmrslength = pusch_len1;
@@ -515,23 +529,39 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
   if (rar_grant) {
 
     // Note: for Msg3 or MsgA PUSCH transmission the N_PRB_oh is always set to 0
-
     NR_BWP_Uplink_t *ubwp = mac->ULbwp[ul_bwp_id-1];
-    NR_BWP_UplinkDedicated_t *ibwp = mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP;
-    NR_PUSCH_Config_t *pusch_Config = ibwp->pusch_Config->choice.setup;
-    int startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[rar_grant->Msg3_t_alloc]->startSymbolAndLength;
-    int mappingtype = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[rar_grant->Msg3_t_alloc]->mappingType;
-
-
-    // active BWP start
-    int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    int abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    NR_BWP_UplinkDedicated_t *ibwp;
+    int scs,abwp_start,abwp_size,startSymbolAndLength,mappingtype;
+    NR_PUSCH_Config_t *pusch_Config=NULL;
+    if (mac->cg && ubwp &&
+        mac->cg->spCellConfig &&
+        mac->cg->spCellConfig->spCellConfigDedicated &&
+        mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+        mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) {
+
+      ibwp = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP;
+      pusch_Config = ibwp->pusch_Config->choice.setup;
+      startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[rar_grant->Msg3_t_alloc]->startSymbolAndLength;
+      mappingtype = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[rar_grant->Msg3_t_alloc]->mappingType;
+
+      // active BWP start
+      abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+    }
+    else {
+      startSymbolAndLength = initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[rar_grant->Msg3_t_alloc]->startSymbolAndLength;
+      mappingtype = initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[rar_grant->Msg3_t_alloc]->mappingType;
 
-    // initial BWP start
-    int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      // active BWP start
+      abwp_start = NRRIV2PRBOFFSET(initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      abwp_size = NRRIV2BW(initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      scs = initialUplinkBWP->genericParameters.subcarrierSpacing;
+    }
+    int ibwp_start = NRRIV2PRBOFFSET(initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    int ibwp_size = NRRIV2BW(initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
 
-    // BWP start selection according to 8.3 of TS 38.213
+      // BWP start selection according to 8.3 of TS 38.213
     if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size)) {
       pusch_config_pdu->bwp_start = abwp_start;
       pusch_config_pdu->bwp_size = abwp_size;
@@ -559,11 +589,11 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
     pusch_config_pdu->start_symbol_index = StartSymbolIndex;
     pusch_config_pdu->nr_of_symbols = NrOfSymbols;
 
-    l_prime_mask = get_l_prime(NrOfSymbols, mappingtype, add_pos, dmrslength, StartSymbolIndex, scc->dmrs_TypeA_Position);
+    l_prime_mask = get_l_prime(NrOfSymbols, mappingtype, add_pos, dmrslength, StartSymbolIndex, mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position);
     LOG_D(MAC, "MSG3 start_sym:%d NR Symb:%d mappingtype:%d , DMRS_MASK:%x\n", pusch_config_pdu->start_symbol_index, pusch_config_pdu->nr_of_symbols, mappingtype, l_prime_mask);
 
     #ifdef DEBUG_MSG3
-    LOG_D(MAC, "In %s BWP assignment (BWP (start %d, size %d) \n", __FUNCTION__, pusch_config_pdu->bwp_start, pusch_config_pdu->bwp_size);
+    LOG_D(NR_MAC, "In %s BWP assignment (BWP (start %d, size %d) \n", __FUNCTION__, pusch_config_pdu->bwp_start, pusch_config_pdu->bwp_size);
     #endif
 
     // MCS
@@ -580,17 +610,17 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
     pusch_config_pdu->scid = 0;
 
     // Transform precoding according to 6.1.3 UE procedure for applying transform precoding on PUSCH in 38.214
-    pusch_config_pdu->transform_precoding = get_transformPrecoding(scc, pusch_Config, NULL, NULL, NR_RNTI_RA, 0); // TBR fix rnti and take out
+    pusch_config_pdu->transform_precoding = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, NULL, NR_RNTI_TC, 0); // TBR fix rnti and take out
 
     // Resource allocation in frequency domain according to 6.1.2.2 in TS 38.214
-    pusch_config_pdu->resource_alloc = pusch_Config->resourceAllocation;
+    pusch_config_pdu->resource_alloc = (mac->cg) ? pusch_Config->resourceAllocation : 1;
 
     //// Completing PUSCH PDU
     pusch_config_pdu->mcs_table = 0;
     pusch_config_pdu->cyclic_prefix = 0;
-    pusch_config_pdu->data_scrambling_id = *scc->physCellId;
-    pusch_config_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
-    pusch_config_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+    pusch_config_pdu->data_scrambling_id = mac->physCellId;
+    pusch_config_pdu->ul_dmrs_scrambling_id = mac->physCellId;
+    pusch_config_pdu->subcarrier_spacing = scs;
     pusch_config_pdu->vrb_to_prb_mapping = 0;
     pusch_config_pdu->uplink_frequency_shift_7p5khz = 0;
     //Optional Data only included if indicated in pduBitmap
@@ -603,18 +633,29 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
 
     int target_ss;
     bool valid_ptrs_setup = 0;
-    uint16_t n_RB_ULBWP = NRRIV2BW(mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup;
+    uint16_t n_RB_ULBWP;
+    if (mac->ULbwp[ul_bwp_id-1] && mac->ULbwp[ul_bwp_id-1]->bwp_Common) {
+      n_RB_ULBWP = NRRIV2BW(mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      pusch_config_pdu->bwp_start = NRRIV2PRBOFFSET(mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    }
+    else {
+      pusch_config_pdu->bwp_start = NRRIV2PRBOFFSET(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      n_RB_ULBWP = NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    }
+
+    pusch_config_pdu->bwp_size = n_RB_ULBWP;
+
+    NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : NULL;
 
     // Basic sanity check for MCS value to check for a false or erroneous DCI
     if (dci->mcs > 28) {
-      LOG_W(MAC, "MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", dci->mcs);
+      LOG_W(NR_MAC, "MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", dci->mcs);
       return -1;
     }
 
     /* Transform precoding */
     if (rnti_type != NR_RNTI_CS || (rnti_type == NR_RNTI_CS && dci->ndi == 1)) {
-      pusch_config_pdu->transform_precoding = get_transformPrecoding(scc, pusch_Config, NULL, dci_format, rnti_type, 0);
+      pusch_config_pdu->transform_precoding = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, dci_format, rnti_type, 0);
     }
 
     /*DCI format-related configuration*/
@@ -625,7 +666,10 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
     } else if (*dci_format == NR_UL_DCI_FORMAT_0_1) {
 
       /* BANDWIDTH_PART_IND */
-      
+      // if (dci->bwp_indicator.val != 1) {
+      //   LOG_W(NR_MAC, "bwp_indicator != 1! Possibly due to false DCI. Ignoring DCI!\n");
+      //   return -1;
+      // }
       config_bwp_ue(mac, &dci->bwp_indicator.val, dci_format);
       target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
       ul_layers_config(mac, pusch_config_pdu, dci);
@@ -633,24 +677,33 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
 
     } else {
 
-      LOG_E(MAC, "In %s: UL grant from DCI format %d is not handled...\n", __FUNCTION__, *dci_format);
+      LOG_E(NR_MAC, "In %s: UL grant from DCI format %d is not handled...\n", __FUNCTION__, *dci_format);
       return -1;
 
     }
 
     NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
-    if (pusch_Config->pusch_TimeDomainAllocationList) {
+    if (pusch_Config && pusch_Config->pusch_TimeDomainAllocationList) {
       pusch_TimeDomainAllocationList = pusch_Config->pusch_TimeDomainAllocationList->choice.setup;
     }
-    else if (mac->ULbwp[mac->UL_BWP_Id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
-      pusch_TimeDomainAllocationList = mac->ULbwp[mac->UL_BWP_Id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+    else if (mac->ULbwp[ul_bwp_id-1] &&
+             mac->ULbwp[ul_bwp_id-1]->bwp_Common&&
+             mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon&&
+             mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup &&
+             mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+      pusch_TimeDomainAllocationList = mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
     }
+    else if (mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList)
+      pusch_TimeDomainAllocationList=mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+    else AssertFatal(1==0,"need to fall back to default PUSCH time-domain allocations\n");
 
     int mappingtype = pusch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType;
 
     NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = NULL;
-    NR_DMRS_ulconfig = (mappingtype == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA)
-                ? pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup : pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
+    if(pusch_Config) {
+      NR_DMRS_ulconfig = (mappingtype == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA)
+                         ? pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup : pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
+    }
 
     /* TRANSFORM PRECODING ------------------------------------------------------------------------------------------*/
 
@@ -674,7 +727,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
       else
         AssertFatal(1==0,"SequenceGroupHopping or sequenceHopping are NOT Supported\n");
 
-      LOG_D(MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d \n", pusch_config_pdu->num_dmrs_cdm_grps_no_data,
+      LOG_D(NR_MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d \n", pusch_config_pdu->num_dmrs_cdm_grps_no_data,
                 pusch_config_pdu->dfts_ofdm.low_papr_group_number);
     }
 
@@ -691,7 +744,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
     }
 
     /* FREQ_HOPPING_FLAG */
-    if ((pusch_Config->frequencyHopping!=NULL) && (pusch_Config->resourceAllocation != NR_PUSCH_Config__resourceAllocation_resourceAllocationType0)){
+    if ((pusch_Config!=NULL) && (pusch_Config->frequencyHopping!=NULL) && (pusch_Config->resourceAllocation != NR_PUSCH_Config__resourceAllocation_resourceAllocationType0)){
       pusch_config_pdu->frequency_hopping = dci->frequency_hopping_flag.val;
     }
 
@@ -700,9 +753,9 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
 
     /* MCS TABLE */
     if (pusch_config_pdu->transform_precoding == transform_precoder_disabled) {
-      pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_Table, 0, *dci_format, rnti_type, target_ss, false);
+      pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config ? pusch_Config->mcs_Table : NULL, 0, *dci_format, rnti_type, target_ss, false);
     } else {
-      pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_TableTransformPrecoder, 1, *dci_format, rnti_type, target_ss, false);
+      pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config ? pusch_Config->mcs_TableTransformPrecoder : NULL, 1, *dci_format, rnti_type, target_ss, false);
     }
 
     /* NDI */
@@ -732,19 +785,30 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
     }
 
     /* DMRS */
-    l_prime_mask = get_l_prime(pusch_config_pdu->nr_of_symbols, mappingtype, add_pos, dmrslength, pusch_config_pdu->start_symbol_index, scc->dmrs_TypeA_Position);
-    if (pusch_config_pdu->transform_precoding == transform_precoder_disabled)
+    l_prime_mask = get_l_prime(pusch_config_pdu->nr_of_symbols, mappingtype, add_pos, dmrslength, pusch_config_pdu->start_symbol_index, mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position);
+    if ((mac->ULbwp[ul_bwp_id-1] && pusch_config_pdu->transform_precoding == transform_precoder_disabled))
       pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1;
+    else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[ul_bwp_id-1] && pusch_config_pdu->transform_precoding == transform_precoder_enabled))
+      pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2;
 
     // Num PRB Overhead from PUSCH-ServingCellConfig
-    if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead == NULL) {
-      N_PRB_oh = 0;
-    } else {
-      N_PRB_oh = *mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead;
-    }
+    if (mac->cg &&
+        mac->cg->spCellConfig &&
+        mac->cg->spCellConfig->spCellConfigDedicated &&
+        mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+        mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig &&
+        mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead)
+      N_PRB_oh = *mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead;
+
+    else N_PRB_oh = 0;
 
     /* PTRS */
-    if (mac->ULbwp[mac->UL_BWP_Id -1]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS != NULL) {
+    if (mac->ULbwp[mac->UL_BWP_Id -1] &&
+        mac->ULbwp[mac->UL_BWP_Id -1]->bwp_Dedicated &&
+        mac->ULbwp[mac->UL_BWP_Id -1]->bwp_Dedicated->pusch_Config &&
+        mac->ULbwp[mac->UL_BWP_Id -1]->bwp_Dedicated->pusch_Config->choice.setup &&
+        mac->ULbwp[mac->UL_BWP_Id -1]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB &&
+        mac->ULbwp[mac->UL_BWP_Id -1]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) {
       if (pusch_config_pdu->transform_precoding == transform_precoder_disabled) {
         nfapi_nr_ue_ptrs_ports_t ptrs_ports_list;
         pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list;
@@ -756,13 +820,13 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
         if(valid_ptrs_setup==true) {
           pusch_config_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS;
         }
-        LOG_D(MAC, "UL PTRS values: PTRS time den: %d, PTRS freq den: %d\n", pusch_config_pdu->pusch_ptrs.ptrs_time_density, pusch_config_pdu->pusch_ptrs.ptrs_freq_density);
+        LOG_D(NR_MAC, "UL PTRS values: PTRS time den: %d, PTRS freq den: %d\n", pusch_config_pdu->pusch_ptrs.ptrs_time_density, pusch_config_pdu->pusch_ptrs.ptrs_freq_density);
       }
     }
 
   }
 
-  LOG_D(MAC, "In %s: received UL grant (rb_start %d, rb_size %d, start_symbol_index %d, nr_of_symbols %d) for RNTI type %s \n",
+  LOG_D(NR_MAC, "In %s: received UL grant (rb_start %d, rb_size %d, start_symbol_index %d, nr_of_symbols %d) for RNTI type %s \n",
     __FUNCTION__,
     pusch_config_pdu->rb_start,
     pusch_config_pdu->rb_size,
@@ -775,7 +839,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
   pusch_config_pdu->qam_mod_order = nr_get_Qm_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
 
   if (pusch_config_pdu->target_code_rate == 0 || pusch_config_pdu->qam_mod_order == 0) {
-    LOG_W(MAC, "In %s: Invalid code rate or Mod order, likely due to unexpected UL DCI. Ignoring DCI! \n", __FUNCTION__);
+    LOG_W(NR_MAC, "In %s: Invalid code rate or Mod order, likely due to unexpected UL DCI. Ignoring DCI! \n", __FUNCTION__);
     return -1;
   }
 
@@ -818,8 +882,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
 
     // check type0 from 38.213 13 if we have no CellGroupConfig
     // TODO: implementation to be completed
-    if (mac->scg == NULL) {
-
+    LOG_D(NR_MAC,"nr_ue_scheduler(): mac->cg %p\n",mac->cg);
+    if (mac->cg == NULL) {
       if(dl_info->ssb_index != -1){
 
         if(mac->type0_pdcch_ss_mux_pattern == 1){
@@ -860,17 +924,39 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
         dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti = 0xaaaa;        //      to be set
         dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = 106;       //      to be set
 
-        LOG_I(MAC,"nr_ue_scheduler Type0 PDCCH with rnti %x, BWP %d\n",
+        LOG_I(NR_MAC,"nr_ue_scheduler Type0 PDCCH with rnti %x, BWP %d\n",
         dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti,
         dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP);
         */
-        dl_config->number_pdus = dl_config->number_pdus + 1;
-
-        fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id);
-        if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
-          mac->if_module->scheduled_response(&scheduled_response);
+	NR_SearchSpace_t *ss0 = mac->search_space_zero;
+	fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
+
+
+	if( mac->scc == NULL && mac->scc_SIB == NULL && (rx_frame%2 == mac->type0_PDCCH_CSS_config.sfn_c) && (rx_slot == mac->type0_PDCCH_CSS_config.n_0) ){
+	  rel15->num_dci_options = 1;
+	  rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
+	  config_dci_pdu(mac, rel15, dl_config, NR_RNTI_SI, -1);
+	  fill_dci_search_candidates(ss0, rel15);
+	  dl_config->number_pdus = 1;
+	  LOG_D(NR_MAC,"Calling fill_scheduled_response, type0_pdcch, num_pdus %d\n",dl_config->number_pdus);
+	  fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id);
+	  if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
+	    mac->if_module->scheduled_response(&scheduled_response);
+	}
+	// this is for Msg2/Msg4
+	if (mac->ra.ra_state >= WAIT_RAR) {
+	  rel15->num_dci_options = 1;
+	  rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
+	  config_dci_pdu(mac, rel15, dl_config, mac->ra.ra_state == WAIT_RAR ? NR_RNTI_RA : NR_RNTI_TC , -1);
+	  fill_dci_search_candidates(ss0, rel15);
+	  dl_config->number_pdus = 1;
+	  LOG_D(NR_MAC,"mac->cg %p: Calling fill_scheduled_response rnti %x, type0_pdcch, num_pdus %d\n",mac->cg,rel15->rnti,dl_config->number_pdus);
+	  fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id);
+	  if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
+	    mac->if_module->scheduled_response(&scheduled_response);
+	}
       }
-    } else { // we have an scg
+    } else { // we have a Master or Secondary CellGroupConfig
 
       dcireq.module_id = mod_id;
       dcireq.gNB_index = gNB_index;
@@ -916,9 +1002,9 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
 
     // Schedule ULSCH only if the current frame and slot match those in ul_config_req
     // AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus)
-    if ((ul_info->slot_tx == ul_config->slot && ul_info->frame_tx == ul_config->sfn) && ul_config->number_pdus > 0){
+    if (ul_config && (ul_info->slot_tx == ul_config->slot && ul_info->frame_tx == ul_config->sfn) && ul_config->number_pdus > 0){
 
-      LOG_D(MAC, "In %s:[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", __FUNCTION__, frame_tx, slot_tx, ul_config->number_pdus, ul_config->sfn, ul_config->slot);
+      LOG_D(NR_MAC, "In %s:[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", __FUNCTION__, frame_tx, slot_tx, ul_config->number_pdus, ul_config->sfn, ul_config->slot);
 
       uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
       uint8_t data_existing = 0;
@@ -932,15 +1018,26 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
         if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) {
 
           uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size;
-
+          LOG_D(NR_MAC,"harq_id %d, NDI %d NDI_DCI %d, TBS_bytes %d (ra_state %d\n",
+                ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id,
+                mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id],
+                ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator,
+                TBS_bytes,
+                ra->ra_state);
           if (ra->ra_state == WAIT_RAR && !ra->cfra){
             memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes);
             LOG_D(NR_MAC,"[RAPROC] Msg3 to be transmitted:\n");
             for (int k = 0; k < TBS_bytes; k++) {
               LOG_D(NR_MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]);
             }
+            LOG_D(NR_MAC,"Flipping NDI for harq_id %d (Msg3)\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator);
+            mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator;
+	          mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0;
           } else {
-            if (IS_SOFTMODEM_NOS1 && (mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator)){
+
+            if ( (mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator ||
+                    mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id]==1)){
+
               // Getting IP traffic to be transmitted
               data_existing = nr_ue_get_sdu(mod_id,
                                             cc_id,
@@ -952,15 +1049,19 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
                                             &access_mode);
             }
 
+            LOG_D(NR_MAC,"Flipping NDI for harq_id %d\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator);
             mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator;
+            mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0;
+
             //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
-            if (!IS_SOFTMODEM_NOS1 || !data_existing) {
+            if (!data_existing) {
               //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
               //and block this traffic from being forwarded to the upper layers at the gNB
               LOG_D(PHY, "In %s: Random data to be transmitted: TBS_bytes %d \n", __FUNCTION__, TBS_bytes);
 
-              // Make the first byte padding so that gNB ignores the PHY random
-              // data in the TB for the PHY at the MAC layer
+              //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
+              //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
+              //have a valid LCID (nr_process_mac_pdu function)
               ulsch_input_buffer[0] = UL_SCH_LCID_PADDING;
 
               for (int i = 1; i < TBS_bytes; i++) {
@@ -1023,8 +1124,13 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac,
   int delta = 0;
   NR_BWP_Uplink_t *ubwp = mac->ULbwp[mac->UL_BWP_Id-1];
   // Get the numerology to calculate the Tx frame and slot
-  int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
-  struct NR_PUSCH_TimeDomainResourceAllocationList *pusch_TimeDomainAllocationList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+  int mu = ubwp ?
+    ubwp->bwp_Common->genericParameters.subcarrierSpacing :
+    mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
+
+  NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ubwp ?
+    ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
+    mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
   // k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1
   // PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon
   int k2;
@@ -1072,14 +1178,14 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac,
 
   }
 
-  LOG_D(MAC, "In %s: currently at [%d.%d] UL transmission in [%d.%d] (k2 %d delta %d)\n", __FUNCTION__, current_frame, current_slot, *frame_tx, *slot_tx, k2, delta);
+  LOG_D(NR_MAC, "In %s: currently at [%d.%d] UL transmission in [%d.%d] (k2 %d delta %d)\n", __FUNCTION__, current_frame, current_slot, *frame_tx, *slot_tx, k2, delta);
 
   return 0;
 
 }
 
 // Build the list of all the valid RACH occasions in the maximum association pattern period according to the PRACH config
-static void build_ro_list(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired) {
+static void build_ro_list(NR_UE_MAC_INST_t *mac) {
 
   int x,y; // PRACH Configuration Index table variables used to compute the valid frame numbers
   int y2;  // PRACH Configuration Index table additional variable used to compute the valid frame numbers
@@ -1097,7 +1203,6 @@ static void build_ro_list(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired) {
   int nb_fdm;
 
   uint8_t config_index, mu;
-  uint32_t pointa;
   int msg1_FDM;
 
   uint8_t prach_conf_period_idx;
@@ -1105,18 +1210,21 @@ static void build_ro_list(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired) {
   uint8_t prach_conf_period_frame_idx;
   int64_t *prach_config_info_p;
 
-  NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
-  NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
+  NR_RACH_ConfigCommon_t *setup = (mac->scc) ?
+    mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup:
+    mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
   NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
 
   config_index = rach_ConfigGeneric->prach_ConfigurationIndex;
 
-  if (setup->msg1_SubcarrierSpacing)
+  if (setup->msg1_SubcarrierSpacing) {
     mu = *setup->msg1_SubcarrierSpacing;
-  else
-    mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+  } else if(mac->scc) {
+    mu = mac->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+  } else {
+    mu = get_softmodem_params()->numerology;
+  }
 
-  pointa = frequencyInfoDL->absoluteFrequencyPointA;
   msg1_FDM = rach_ConfigGeneric->msg1_FDM;
 
   switch (msg1_FDM){
@@ -1134,12 +1242,13 @@ static void build_ro_list(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired) {
   // ==============================
   // WIP: For now assume no rejected PRACH occasions because of conflict with SSB or TDD_UL_DL_ConfigurationCommon schedule
 
+  int unpaired = mac->phy_config.config_req.cell_config.frame_duplex_type;
   // Identify the proper PRACH Configuration Index table according to the operating frequency
-  LOG_D(MAC,"Pointa %u, mu = %u, PRACH config index  = %u, unpaired = %u\n", pointa, mu, config_index, unpaired);
+  LOG_D(NR_MAC,"mu = %u, PRACH config index  = %u, unpaired = %u\n", mu, config_index, unpaired);
 
-  prach_config_info_p = get_prach_config_info(pointa, config_index, unpaired);
+  prach_config_info_p = get_prach_config_info(mac->frequency_range, config_index, unpaired);
 
-  if (pointa > 2016666) { //FR2
+  if (mac->frequency_range == FR2) { //FR2
 
     x = prach_config_info_p[2];
     y = prach_config_info_p[3];
@@ -1170,6 +1279,7 @@ static void build_ro_list(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired) {
     prach_conf_start_symbol = prach_config_info_p[5];
     N_t_slot = prach_config_info_p[7];
     N_dur = prach_config_info_p[8];
+    LOG_D(NR_MAC,"N_t_slot %d, N_dur %d\n",N_t_slot,N_dur);
     if (prach_config_info_p[1] != -1)
       format2 = (uint8_t) prach_config_info_p[1];
     format = ((uint8_t) prach_config_info_p[0]) | (format2<<8);
@@ -1185,7 +1295,7 @@ static void build_ro_list(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired) {
   prach_assoc_pattern.nb_of_prach_conf_period_in_max_period = MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD / x;
   nb_of_frames_per_prach_conf_period = x;
 
-  LOG_D(MAC,"nb_of_prach_conf_period_in_max_period %d\n", prach_assoc_pattern.nb_of_prach_conf_period_in_max_period);
+  LOG_D(NR_MAC,"nb_of_prach_conf_period_in_max_period %d\n", prach_assoc_pattern.nb_of_prach_conf_period_in_max_period);
 
   // Fill in the PRACH occasions table for every slot in every frame in every PRACH configuration periods in the maximum association pattern period
   // ----------------------------------------------------------------------------------------------------------------------------------------------
@@ -1197,14 +1307,14 @@ static void build_ro_list(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired) {
     prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_frame = nb_of_frames_per_prach_conf_period;
     prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_slot = nr_slots_per_frame[mu];
 
-    LOG_D(MAC,"PRACH Conf Period Idx %d\n", prach_conf_period_idx);
+    LOG_D(NR_MAC,"PRACH Conf Period Idx %d\n", prach_conf_period_idx);
 
     // For every frames in a PRACH configuration period
     // ------------------------------------------------
     for (prach_conf_period_frame_idx=0; prach_conf_period_frame_idx<nb_of_frames_per_prach_conf_period; prach_conf_period_frame_idx++) {
       frame = (prach_conf_period_idx * nb_of_frames_per_prach_conf_period) + prach_conf_period_frame_idx;
 
-      LOG_D(MAC,"PRACH Conf Period Frame Idx %d - Frame %d\n", prach_conf_period_frame_idx, frame);
+      LOG_D(NR_MAC,"PRACH Conf Period Frame Idx %d - Frame %d\n", prach_conf_period_frame_idx, frame);
       // Is it a valid frame for this PRACH configuration index? (n_sfn mod x = y)
       if ( (frame%x)==y || (frame%x)==y2 ) {
 
@@ -1231,7 +1341,7 @@ static void build_ro_list(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired) {
 
             for (n_prach_occ_in_time=0; n_prach_occ_in_time<N_t_slot; n_prach_occ_in_time++) {
               uint8_t start_symbol = prach_conf_start_symbol + n_prach_occ_in_time * N_dur;
-              LOG_D(MAC,"PRACH Occ in time %d\n", n_prach_occ_in_time);
+              LOG_D(NR_MAC,"PRACH Occ in time %d\n", n_prach_occ_in_time);
 
               for (n_prach_occ_in_freq=0; n_prach_occ_in_freq<nb_fdm; n_prach_occ_in_freq++) {
                 prach_occasion_info_t *prach_occasion_p = &prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].prach_occasion[n_prach_occ_in_time][n_prach_occ_in_freq];
@@ -1243,7 +1353,7 @@ static void build_ro_list(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired) {
                 prach_occasion_p->format = format;
                 prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_prach_occasion++;
 
-                LOG_D(MAC,"Adding a PRACH occasion: frame %u, slot-symbol %d-%d, occ_in_time-occ_in-freq %d-%d, nb ROs in conf period %d, for this slot: RO# in time %d, RO# in freq %d\n",
+                LOG_D(NR_MAC,"Adding a PRACH occasion: frame %u, slot-symbol %d-%d, occ_in_time-occ_in-freq %d-%d, nb ROs in conf period %d, for this slot: RO# in time %d, RO# in freq %d\n",
                     frame, slot, start_symbol, n_prach_occ_in_time, n_prach_occ_in_freq, prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_prach_occasion,
                     prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_time,
                     prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_freq);
@@ -1257,7 +1367,7 @@ static void build_ro_list(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired) {
 }
 
 // Build the list of all the valid/transmitted SSBs according to the config
-static void build_ssb_list(NR_ServingCellConfigCommon_t *scc) {
+static void build_ssb_list(NR_UE_MAC_INST_t *mac) {
 
   // Create the list of transmitted SSBs
   // ===================================
@@ -1265,19 +1375,21 @@ static void build_ssb_list(NR_ServingCellConfigCommon_t *scc) {
   uint64_t ssb_positionsInBurst;
   uint8_t ssb_idx = 0;
 
-  switch (scc->ssb_PositionsInBurst->present) {
+  if (mac->scc) {
+    NR_ServingCellConfigCommon_t *scc = mac->scc;
+    switch (scc->ssb_PositionsInBurst->present) {
     case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap:
       ssb_bitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
 
       ssb_positionsInBurst = BIT_STRING_to_uint8(ssb_bitmap);
-      LOG_D(MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst);
+      LOG_D(NR_MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst);
 
       for (uint8_t bit_nb=3; bit_nb<=3; bit_nb--) {
         // If SSB is transmitted
         if ((ssb_positionsInBurst>>bit_nb) & 0x01) {
           ssb_list.nb_tx_ssb++;
           ssb_list.tx_ssb[ssb_idx].transmitted = true;
-          LOG_D(MAC,"SSB idx %d transmitted\n", ssb_idx);
+          LOG_D(NR_MAC,"SSB idx %d transmitted\n", ssb_idx);
         }
         ssb_idx++;
       }
@@ -1286,14 +1398,14 @@ static void build_ssb_list(NR_ServingCellConfigCommon_t *scc) {
       ssb_bitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
 
       ssb_positionsInBurst = BIT_STRING_to_uint8(ssb_bitmap);
-      LOG_D(MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst);
+      LOG_D(NR_MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst);
 
       for (uint8_t bit_nb=7; bit_nb<=7; bit_nb--) {
         // If SSB is transmitted
         if ((ssb_positionsInBurst>>bit_nb) & 0x01) {
           ssb_list.nb_tx_ssb++;
           ssb_list.tx_ssb[ssb_idx].transmitted = true;
-          LOG_D(MAC,"SSB idx %d transmitted\n", ssb_idx);
+          LOG_D(NR_MAC,"SSB idx %d transmitted\n", ssb_idx);
         }
         ssb_idx++;
       }
@@ -1302,14 +1414,14 @@ static void build_ssb_list(NR_ServingCellConfigCommon_t *scc) {
       ssb_bitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;
 
       ssb_positionsInBurst = BIT_STRING_to_uint64(ssb_bitmap);
-      LOG_D(MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst);
+      LOG_D(NR_MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst);
 
       for (uint8_t bit_nb=63; bit_nb<=63; bit_nb--) {
         // If SSB is transmitted
         if ((ssb_positionsInBurst>>bit_nb) & 0x01) {
           ssb_list.nb_tx_ssb++;
           ssb_list.tx_ssb[ssb_idx].transmitted = true;
-          LOG_D(MAC,"SSB idx %d transmitted\n", ssb_idx);
+          LOG_D(NR_MAC,"SSB idx %d transmitted\n", ssb_idx);
         }
         ssb_idx++;
       }
@@ -1317,16 +1429,36 @@ static void build_ssb_list(NR_ServingCellConfigCommon_t *scc) {
     default:
       AssertFatal(false,"ssb_PositionsInBurst not present\n");
       break;
+    }
+  } else { // This is configuration from SIB1
+
+    AssertFatal(mac->scc_SIB->ssb_PositionsInBurst.groupPresence == NULL, "Handle case for >8 SSBs\n");
+    ssb_bitmap = &mac->scc_SIB->ssb_PositionsInBurst.inOneGroup;
+
+    ssb_positionsInBurst = BIT_STRING_to_uint8(ssb_bitmap);
+    LOG_D(NR_MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst);
+
+    for (uint8_t bit_nb=7; bit_nb<=7; bit_nb--) {
+      // If SSB is transmitted
+      if ((ssb_positionsInBurst>>bit_nb) & 0x01) {
+        ssb_list.nb_tx_ssb++;
+        ssb_list.tx_ssb[ssb_idx].transmitted = true;
+        LOG_D(NR_MAC,"SSB idx %d transmitted\n", ssb_idx);
+      }
+      ssb_idx++;
+    }
   }
 }
 
 // Map the transmitted SSBs to the ROs and create the association pattern according to the config
-static void map_ssb_to_ro(NR_ServingCellConfigCommon_t *scc) {
+static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) {
 
   // Map SSBs to PRACH occasions
   // ===========================
   // WIP: Assumption: No PRACH occasion is rejected because of a conflict with SSBs or TDD_UL_DL_ConfigurationCommon schedule
-  NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+  NR_RACH_ConfigCommon_t *setup = (mac->scc) ?
+    mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup:
+    mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
   NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
 
   boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB
@@ -1373,14 +1505,14 @@ static void map_ssb_to_ro(NR_ServingCellConfigCommon_t *scc) {
       AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config);
       break;
   }
-  LOG_D(MAC,"SSB rach ratio %d, Multiple SSB per RO %d\n", ssb_rach_ratio, multiple_ssb_per_ro);
+  LOG_D(NR_MAC,"SSB rach ratio %d, Multiple SSB per RO %d\n", ssb_rach_ratio, multiple_ssb_per_ro);
 
   // Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period
   // ==============================================================================================================
   // WIP: Assumption for now is that all the PRACH configuration periods within a maximum association pattern period have the same number of PRACH occasions
   //      (No PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule)
   //      There is only one possible association period which can contain up to 16 PRACH configuration periods
-  LOG_D(MAC,"Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period\n");
+  LOG_D(NR_MAC,"Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period\n");
   if (true == multiple_ssb_per_ro) {
     required_nb_of_prach_occasion = ((ssb_list.nb_tx_ssb-1) + ssb_rach_ratio) / ssb_rach_ratio;
   }
@@ -1388,6 +1520,7 @@ static void map_ssb_to_ro(NR_ServingCellConfigCommon_t *scc) {
     required_nb_of_prach_occasion = ssb_list.nb_tx_ssb * ssb_rach_ratio;
   }
 
+  AssertFatal(prach_assoc_pattern.prach_conf_period_list[0].nb_of_prach_occasion>0,"prach_assoc_pattern.prach_conf_period_list[0].nb_of_prach_occasion shouldn't be 0 (ssb_list.nb_tx_ssb %d, ssb_rach_ratio %d\n",ssb_list.nb_tx_ssb,ssb_rach_ratio);
   required_nb_of_prach_conf_period = ((required_nb_of_prach_occasion-1) + prach_assoc_pattern.prach_conf_period_list[0].nb_of_prach_occasion) / prach_assoc_pattern.prach_conf_period_list[0].nb_of_prach_occasion;
 
   if (required_nb_of_prach_conf_period == 1) {
@@ -1413,7 +1546,7 @@ static void map_ssb_to_ro(NR_ServingCellConfigCommon_t *scc) {
   prach_assoc_pattern.prach_association_period_list[0].nb_of_frame = prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period * prach_assoc_pattern.prach_conf_period_list[0].nb_of_frame;
   prach_assoc_pattern.nb_of_frame = prach_assoc_pattern.prach_association_period_list[0].nb_of_frame;
 
-  LOG_D(MAC,"Assoc period %d, Nb of frames in assoc period %d\n",
+  LOG_D(NR_MAC,"Assoc period %d, Nb of frames in assoc period %d\n",
         prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period,
         prach_assoc_pattern.prach_association_period_list[0].nb_of_frame);
 
@@ -1425,7 +1558,7 @@ static void map_ssb_to_ro(NR_ServingCellConfigCommon_t *scc) {
   prach_conf_period_t *prach_conf_period_p;
 
   // Map all the association periods within the association pattern period
-  LOG_D(MAC,"Proceed to the SSB to RO mapping\n");
+  LOG_D(NR_MAC,"Proceed to the SSB to RO mapping\n");
   for (association_period_idx=0; association_period_idx<prach_assoc_pattern.nb_of_assoc_period; association_period_idx++) {
     uint8_t n_prach_conf=0; // PRACH Configuration period index within the association period
     uint8_t frame=0;
@@ -1473,8 +1606,8 @@ static void map_ssb_to_ro(NR_ServingCellConfigCommon_t *scc) {
                     ssb_list.tx_ssb[ssb_idx].nb_mapped_ro++;
                     AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > ssb_list.tx_ssb[ssb_idx].nb_mapped_ro,"Too many mapped ROs (%d) to a single SSB\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro);
 
-                    LOG_D(MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n", ssb_idx, ro_p->slot, ro_p->start_symbol, slot, ro_in_time, ro_in_freq, prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq);
-                    LOG_D(MAC,"Nb mapped ROs for this ssb idx: in the association period only %u\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro);
+                    LOG_D(NR_MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n", ssb_idx, ro_p->slot, ro_p->start_symbol, slot, ro_in_time, ro_in_freq, prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq);
+                    LOG_D(NR_MAC,"Nb mapped ROs for this ssb idx: in the association period only %u\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro);
 
                     // If all the required SSBs are mapped to this RO, exit the loop of SSBs
                     if (ro_p->nb_mapped_ssb == ssb_rach_ratio) {
@@ -1521,6 +1654,9 @@ static void map_ssb_to_ro(NR_ServingCellConfigCommon_t *scc) {
       for (ssb_idx=0; ssb_idx<MAX_NB_SSB; ssb_idx++) {
         uint8_t nb_mapped_ro_in_association_period=0; // Reset the nb of mapped ROs for the new SSB index
 
+	      LOG_D(NR_MAC,"Checking ssb_idx %d => %d\n",
+	      ssb_idx,ssb_list.tx_ssb[ssb_idx].transmitted);
+
         // Map only the transmitted ssb_idx
         if (true == ssb_list.tx_ssb[ssb_idx].transmitted) {
 
@@ -1545,8 +1681,8 @@ static void map_ssb_to_ro(NR_ServingCellConfigCommon_t *scc) {
                     AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > ssb_list.tx_ssb[ssb_idx].nb_mapped_ro,"Too many mapped ROs (%d) to a single SSB\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro);
                     nb_mapped_ro_in_association_period++;
 
-                    LOG_D(MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n", ssb_idx, ro_p->slot, ro_p->start_symbol, slot, ro_in_time, ro_in_freq, prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq);
-                    LOG_D(MAC,"Nb mapped ROs for this ssb idx: in the association period only %u / total %u\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro, nb_mapped_ro_in_association_period);
+                    LOG_D(NR_MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n", ssb_idx, ro_p->slot, ro_p->start_symbol, slot, ro_in_time, ro_in_freq, prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq);
+                    LOG_D(NR_MAC,"Nb mapped ROs for this ssb idx: in the association period only %u / total %u\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro, nb_mapped_ro_in_association_period);
 
                     // Exit the loop if this SSB has been mapped to all the required ROs
                     // WIP: Assuming that ssb_rach_ratio equals the maximum nb of times a given ssb_idx is mapped within an association period:
@@ -1609,7 +1745,9 @@ static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx,
   //      - exact slot number
   //      - frame offset
   ssb_info_p = &ssb_list.tx_ssb[ssb_idx];
+  LOG_D(NR_MAC,"checking for prach : ssb_info_p->nb_mapped_ro %d\n",ssb_info_p->nb_mapped_ro);
   for (uint8_t n_mapped_ro=0; n_mapped_ro<ssb_info_p->nb_mapped_ro; n_mapped_ro++) {
+    LOG_D(NR_MAC,"%d.%d: mapped_ro[%d]->frame.slot %d.%d, prach_assoc_pattern.nb_of_frame %d\n",frame,slot,n_mapped_ro,ssb_info_p->mapped_ro[n_mapped_ro]->frame,ssb_info_p->mapped_ro[n_mapped_ro]->slot,prach_assoc_pattern.nb_of_frame);
     if ((slot == ssb_info_p->mapped_ro[n_mapped_ro]->slot) &&
         (ssb_info_p->mapped_ro[n_mapped_ro]->frame == (frame % prach_assoc_pattern.nb_of_frame))) {
 
@@ -1669,24 +1807,24 @@ static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx,
 }
 
 // Build the SSB to RO mapping upon RRC configuration update
-void build_ssb_to_ro_map(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired){
+void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac) {
 
   // Clear all the lists and maps
   memset(&prach_assoc_pattern, 0, sizeof(prach_association_pattern_t));
   memset(&ssb_list, 0, sizeof(ssb_list_info_t));
 
   // Build the list of all the valid RACH occasions in the maximum association pattern period according to the PRACH config
-  LOG_D(MAC,"Build RO list\n");
-  build_ro_list(scc, unpaired);
+  LOG_D(NR_MAC,"Build RO list\n");
+  build_ro_list(mac);
 
   // Build the list of all the valid/transmitted SSBs according to the config
-  LOG_D(MAC,"Build SSB list\n");
-  build_ssb_list(scc);
+  LOG_D(NR_MAC,"Build SSB list\n");
+  build_ssb_list(mac);
 
   // Map the transmitted SSBs to the ROs and create the association pattern according to the config
-  LOG_D(MAC,"Map SSB to RO\n");
-  map_ssb_to_ro(scc);
-  LOG_D(MAC,"Map SSB to RO done\n");
+  LOG_D(NR_MAC,"Map SSB to RO\n");
+  map_ssb_to_ro(mac);
+  LOG_D(NR_MAC,"Map SSB to RO done\n");
 }
 
 // This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x
@@ -1710,13 +1848,17 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
   nr_scheduled_response_t scheduled_response;
 
   NR_ServingCellConfigCommon_t *scc = mac->scc;
-  NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+  NR_ServingCellConfigCommonSIB_t *scc_SIB = mac->scc_SIB;
+  NR_RACH_ConfigCommon_t *setup;
+  if (scc!=NULL) setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+  else           setup = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
   NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
 
   ra->RA_offset = 2; // to compensate the rx frame offset at the gNB
   ra->generate_nr_prach = GENERATE_IDLE; // Reset flag for PRACH generation
+  NR_TDD_UL_DL_ConfigCommon_t *tdd_config = scc==NULL ? scc_SIB->tdd_UL_DL_ConfigurationCommon : scc->tdd_UL_DL_ConfigurationCommon;
 
-  if (is_nr_UL_slot(scc, slotP, mac->frame_type)) {
+  if (is_nr_UL_slot(tdd_config, slotP, mac->frame_type)) {
 
     // WIP Need to get the proper selected ssb_idx
     //     Initial beam selection functionality is not available yet
@@ -1746,7 +1888,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
 
       ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig);
 
-      prach_config_pdu->phys_cell_id = *scc->physCellId;
+      prach_config_pdu->phys_cell_id = mac->physCellId;
       prach_config_pdu->num_prach_ocas = 1;
       prach_config_pdu->prach_slot = prach_occasion_info_p->slot;
       prach_config_pdu->prach_start_symbol = prach_occasion_info_p->start_symbol;
@@ -1757,7 +1899,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
       prach_config_pdu->restricted_set = prach_config->restricted_set_config;
       prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1;
 
-      LOG_D(MAC,"Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", frameP, prach_config_pdu->prach_slot, prach_config_pdu->prach_start_symbol, prach_config_pdu->num_ra);
+      LOG_D(NR_MAC,"Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", frameP, prach_config_pdu->prach_slot, prach_config_pdu->prach_start_symbol, prach_config_pdu->num_ra);
 
       // Search which SSB is mapped in the RO (among all the SSBs mapped to this RO)
       for (prach_config_pdu->ssb_nb_in_ro=0; prach_config_pdu->ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb; prach_config_pdu->ssb_nb_in_ro++) {
@@ -1826,6 +1968,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
   } // if is_nr_UL_slot
 }
 
+#define MAX_LCID 8 //Fixme: also defined in LCID table
 uint8_t
 nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
            sub_frame_t subframe, uint8_t eNB_index,
@@ -1833,17 +1976,16 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
   uint8_t total_rlc_pdu_header_len = 0;
   int16_t buflen_remain = 0;
   uint8_t lcid = 0;
-  uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-  uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+  uint16_t sdu_lengths[MAX_LCID] = { 0 };
+  uint8_t sdu_lcids[MAX_LCID] = { 0 };
   uint16_t payload_offset = 0, num_sdus = 0;
   uint8_t ulsch_sdus[MAX_ULSCH_PAYLOAD_BYTES];
   uint16_t sdu_length_total = 0;
   //unsigned short post_padding = 0;
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
 
-  rlc_buffer_occupancy_t lcid_buffer_occupancy_old =
-    0, lcid_buffer_occupancy_new = 0;
-  LOG_D(MAC,
+  rlc_buffer_occupancy_t lcid_buffer_occupancy_new = 0;
+  LOG_D(NR_MAC,
         "[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n",
         module_idP, frameP, subframe, buflen);
   AssertFatal(CC_id == 0,
@@ -1852,23 +1994,20 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
   // Check for DCCH first
   // TO DO: Multiplex in the order defined by the logical channel prioritization
   for (lcid = UL_SCH_LCID_SRB1;
-       lcid < NR_MAX_NUM_LCID; lcid++) {
-
-      lcid_buffer_occupancy_old = mac_rlc_get_buffer_occupancy_ind(module_idP, mac->crnti, eNB_index, frameP, subframe, ENB_FLAG_NO, lcid);
-      lcid_buffer_occupancy_new = lcid_buffer_occupancy_old;
-
-      if(lcid_buffer_occupancy_new){
+       lcid < MAX_LCID; lcid++) {
+    lcid_buffer_occupancy_new = mac_rlc_get_buffer_occupancy_ind(module_idP, mac->crnti, eNB_index, frameP, subframe, ENB_FLAG_NO, lcid);
 
+    if(lcid_buffer_occupancy_new) {
         buflen_remain =
           buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE);
-        LOG_D(MAC,
+        LOG_D(NR_MAC,
               "[UE %d] Frame %d : UL-DXCH -> ULSCH, RLC %d has %d bytes to "
               "send (Transport Block size %d SDU Length Total %d , mac header len %d, buflen_remain %d )\n", //BSR byte before Tx=%d
               module_idP, frameP, lcid, lcid_buffer_occupancy_new,
               buflen, sdu_length_total,
               total_rlc_pdu_header_len, buflen_remain); // ,nr_ue_mac_inst->scheduling_info.BSR_bytes[nr_ue_mac_inst->scheduling_info.LCGID[lcid]]
 
-        while(buflen_remain > 0 && lcid_buffer_occupancy_new){
+      while(buflen_remain > 0 && lcid_buffer_occupancy_new){
 
         sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
                                 mac->crnti,
@@ -1896,20 +2035,13 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
         }
 
         /* Get updated BO after multiplexing this PDU */
-        lcid_buffer_occupancy_new = mac_rlc_get_buffer_occupancy_ind(module_idP,
-                                                                     mac->crnti,
-                                                                     eNB_index,
-                                                                     frameP,
-                                                                     subframe,
-                                                                     ENB_FLAG_NO,
-                                                                     lcid);
+        lcid_buffer_occupancy_new = mac_rlc_get_buffer_occupancy_ind(module_idP,mac->crnti,eNB_index,frameP, subframe, ENB_FLAG_NO, lcid);
         buflen_remain =
                   buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE);
-        }
+      }
+    }
   }
 
-}
-
   // Generate ULSCH PDU
   if (num_sdus>0) {
   payload_offset = nr_generate_ulsch_pdu(ulsch_sdus,
@@ -1924,9 +2056,9 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
                                          0, // long_bsr
                                          0, // post_padding 
                                          buflen);  // TBS in bytes
+  } else {
+    return 0;
   }
-  else
-          return 0;
 
   // Padding: fill remainder of ULSCH with 0
   if (buflen - payload_offset > 0){
@@ -1935,7 +2067,7 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
   }
 
 #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
-  LOG_I(MAC, "Printing UL MAC payload UE side, payload_offset: %d \n", payload_offset);
+  LOG_I(NR_MAC, "Printing UL MAC payload UE side, payload_offset: %d \n", payload_offset);
   for (int i = 0; i < buflen ; i++) {
           //harq_process_ul_ue->a[i] = (unsigned char) rand();
           //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 98e9ce4351b80ef4cfa488c68e93c1254269c489..87cc7851ff2261186c6e76261812b999883ebf89 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -54,6 +54,87 @@ extern RAN_CONTEXT_t RC;
 extern void mac_top_init_gNB(void);
 extern uint8_t nfapi_mode;
 
+void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list,
+                             struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_bearer2release_list,
+                             NR_UE_sched_ctrl_t *sched_ctrl) {
+
+  if (rlc_bearer2add_list)
+  // keep lcids
+    for (int i=0;i<rlc_bearer2add_list->list.count;i++) {
+      sched_ctrl->lcid_mask |= (1<<rlc_bearer2add_list->list.array[i]->logicalChannelIdentity);
+      LOG_I(NR_MAC,"Adding LCID %d (%s %d)\n",
+            (int)rlc_bearer2add_list->list.array[i]->logicalChannelIdentity,
+            rlc_bearer2add_list->list.array[i]->logicalChannelIdentity<4 ? "SRB" : "DRB",
+            (int)rlc_bearer2add_list->list.array[i]->logicalChannelIdentity);
+    }
+  if (rlc_bearer2release_list)
+    for (int i=0;i<rlc_bearer2release_list->list.count;i++)
+      sched_ctrl->lcid_mask |= (1<<*rlc_bearer2release_list->list.array[i]);
+
+}
+
+
+void process_drx_Config(NR_UE_sched_ctrl_t *sched_ctrl,NR_SetupRelease_DRX_Config_t *drx_Config) {
+ if (!drx_Config) return;
+ AssertFatal(drx_Config->present != NR_SetupRelease_DRX_Config_PR_NOTHING, "Cannot have NR_SetupRelease_DRX_Config_PR_NOTHING\n");
+
+ if (drx_Config->present == NR_SetupRelease_DRX_Config_PR_setup) {
+   LOG_I(NR_MAC,"Adding DRX config\n");
+ }
+ else {
+   LOG_I(NR_MAC,"Removing DRX config\n");
+ }
+}
+
+void process_schedulingRequestConfig(NR_UE_sched_ctrl_t *sched_ctrl,NR_SchedulingRequestConfig_t *schedulingRequestConfig) {
+ if (!schedulingRequestConfig) return;
+
+   LOG_I(NR_MAC,"Adding SchedulingRequestconfig\n");
+}
+
+void process_bsrConfig(NR_UE_sched_ctrl_t *sched_ctrl,NR_BSR_Config_t *bsr_Config) {
+  if (!bsr_Config) return;
+  LOG_I(NR_MAC,"Adding BSR config\n");
+}
+
+void process_tag_Config(NR_UE_sched_ctrl_t *sched_ctrl,NR_TAG_Config_t *tag_Config) {
+  if (!tag_Config) return;
+  LOG_I(NR_MAC,"Adding TAG config\n");
+}
+
+void process_phr_Config(NR_UE_sched_ctrl_t *sched_ctrl,NR_SetupRelease_PHR_Config_t *phr_Config) {
+   if (!phr_Config) return;
+   AssertFatal(phr_Config->present != NR_SetupRelease_PHR_Config_PR_NOTHING, "Cannot have NR_SetupRelease_PHR_Config_PR_NOTHING\n");
+
+   if (phr_Config->present == NR_SetupRelease_PHR_Config_PR_setup) {
+     LOG_I(NR_MAC,"Adding PHR config\n");
+   }
+   else {
+     LOG_I(NR_MAC,"Removing PHR config\n");
+   }
+}
+
+void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl) {
+
+   AssertFatal(CellGroup, "CellGroup is null\n");
+   NR_MAC_CellGroupConfig_t   *mac_CellGroupConfig = CellGroup->mac_CellGroupConfig;
+
+
+   if (mac_CellGroupConfig) {
+     process_drx_Config(sched_ctrl,mac_CellGroupConfig->drx_Config);
+     process_schedulingRequestConfig(sched_ctrl,mac_CellGroupConfig->schedulingRequestConfig);
+     process_bsrConfig(sched_ctrl,mac_CellGroupConfig->bsr_Config);
+     process_tag_Config(sched_ctrl,mac_CellGroupConfig->tag_Config);
+     process_phr_Config(sched_ctrl,mac_CellGroupConfig->phr_Config);
+   }
+   else {
+     // apply defaults
+
+   }
+
+   process_rlcBearerConfig(CellGroup->rlc_BearerToAddModList,CellGroup->rlc_BearerToReleaseList,sched_ctrl);
+
+}
 void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
 
   nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0];
@@ -67,7 +148,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
                                                             *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]);
   cfg->carrier_config.dl_bandwidth.tl.tag   = NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG; //temporary
   cfg->num_tlv++;
-  LOG_I(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, cfg->carrier_config.dl_bandwidth.value);
+  LOG_I(NR_MAC,"%s() dl_BandwidthP:%d\n", __FUNCTION__, cfg->carrier_config.dl_bandwidth.value);
 
   cfg->carrier_config.dl_frequency.value = from_nrarfcn(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],
                                                         *scc->ssbSubcarrierSpacing,
@@ -95,7 +176,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
                                                                 *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]);
   cfg->carrier_config.uplink_bandwidth.tl.tag   = NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG; //temporary
   cfg->num_tlv++;
-  LOG_I(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, cfg->carrier_config.uplink_bandwidth.value);
+  LOG_I(NR_MAC,"%s() dl_BandwidthP:%d\n", __FUNCTION__, cfg->carrier_config.uplink_bandwidth.value);
 
   int UL_pointA;
   if (scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA == NULL)
@@ -298,7 +379,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
   cfg->carrier_config.num_rx_ant.value = pusch_AntennaPorts;
   AssertFatal(pusch_AntennaPorts > 0 && pusch_AntennaPorts < 13, "pusch_AntennaPorts in 1...12\n");
   cfg->carrier_config.num_rx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_RX_ANT_TAG;
-  LOG_I(MAC,"Set TX/RX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,num_ssb,cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,cfg->ssb_table.ssb_mask_list[1].ssb_mask.value);
+  LOG_I(NR_MAC,"Set TX/RX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,num_ssb,cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,cfg->ssb_table.ssb_mask_list[1].ssb_mask.value);
   AssertFatal(cfg->carrier_config.num_tx_ant.value > 0,"carrier_config.num_tx_ant.value %d !\n",cfg->carrier_config.num_tx_ant.value );
   cfg->num_tlv++;
   cfg->num_tlv++;
@@ -315,7 +396,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
     cfg->tdd_table.tdd_period.value = *scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
   }
   if(cfg->cell_config.frame_duplex_type.value == TDD){
-    LOG_I(MAC,"Setting TDD configuration period to %d\n",cfg->tdd_table.tdd_period.value);
+    LOG_I(NR_MAC,"Setting TDD configuration period to %d\n",cfg->tdd_table.tdd_period.value);
     int periods_per_frame = set_tdd_config_nr(cfg,
                                               scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
                                               scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots,
@@ -324,9 +405,9 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
                                               scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols);
 
     if (periods_per_frame < 0)
-      LOG_E(MAC,"TDD configuration can not be done\n");
+      LOG_E(NR_MAC,"TDD configuration can not be done\n");
     else {
-      LOG_I(MAC,"TDD has been properly configurated\n");
+      LOG_I(NR_MAC,"TDD has been properly configurated\n");
       RC.nrmac[Mod_idP]->tdd_beam_association = (int16_t *)malloc16(periods_per_frame*sizeof(int16_t));
     }
   }
@@ -338,12 +419,10 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
                            int ssb_SubcarrierOffset,
                            int pdsch_AntennaPorts,
                            int pusch_AntennaPorts,
-                           int pusch_tgt_snrx10,
-                           int pucch_tgt_snrx10,
                            NR_ServingCellConfigCommon_t *scc,
-			   int add_ue,
-			   uint32_t rnti,
-			   NR_CellGroupConfig_t *secondaryCellGroup){
+	                         int add_ue,
+                           uint32_t rnti,
+	                         NR_CellGroupConfig_t *CellGroup) {
 
   if (scc != NULL ) {
     AssertFatal((scc->ssb_PositionsInBurst->present > 0) && (scc->ssb_PositionsInBurst->present < 4), "SSB Bitmap type %d is not valid\n",scc->ssb_PositionsInBurst->present);
@@ -372,14 +451,14 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
     AssertFatal(RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL,
                 "could not allocate memory for RC.nrmac[]->common_channels[0].vrb_map_UL\n");
 
-    LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n");
+    LOG_I(NR_MAC,"Configuring common parameters from NR ServingCellConfig\n");
 
     config_common(Mod_idP,
                   ssb_SubcarrierOffset,
                   pdsch_AntennaPorts,
                   pusch_AntennaPorts,
-		  scc);
-    LOG_E(MAC, "%s() %s:%d RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req);
+		              scc);
+    LOG_D(NR_MAC, "%s() %s:%d RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req);
   
     // if in nFAPI mode 
     if ( (NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) && (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) ){
@@ -389,10 +468,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
         printf("Waiting for PHY_config_req\n");
       }
     }
-
     RC.nrmac[Mod_idP]->ssb_SubcarrierOffset = ssb_SubcarrierOffset;
-    RC.nrmac[Mod_idP]->pusch_target_snrx10 = pusch_tgt_snrx10;
-    RC.nrmac[Mod_idP]->pucch_target_snrx10 = pucch_tgt_snrx10;
+
     NR_PHY_Config_t phycfg;
     phycfg.Mod_id = Mod_idP;
     phycfg.CC_id  = 0;
@@ -407,14 +484,14 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
     const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots;
     const int nr_dlmix_slots = tdd->nrofDownlinkSlots + (tdd->nrofDownlinkSymbols != 0);
     const int nr_ulstart_slot = tdd->nrofDownlinkSlots + (tdd->nrofUplinkSymbols == 0);
+
     for (int slot = 0; slot < n; ++slot) {
       /* FIXME: it seems there is a problem with slot 0/10/slots right after UL:
        * we just get retransmissions. Thus, do not schedule such slots in DL */
       if (slot % nr_slots_period != 0)
         RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] |= ((slot % nr_slots_period) < nr_dlmix_slots) << (slot % 64);
       RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] |= ((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
-      LOG_D(MAC,
-            "slot %d DL %d UL %d\n",
+      LOG_D(NR_MAC, "slot %d DL %d UL %d\n",
             slot,
             (RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] & (1 << (slot % 64))) != 0,
             (RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] & (1 << (slot % 64))) != 0);
@@ -427,32 +504,47 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
       RC.nrmac[Mod_idP]->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(Mod_idP, 0);
       RC.nrmac[Mod_idP]->pre_processor_ul = nr_init_fr1_ulsch_preprocessor(Mod_idP, 0);
     }
+
+    if (get_softmodem_params()->sa > 0) {
+      NR_COMMON_channels_t *cc = &RC.nrmac[Mod_idP]->common_channels[0];
+      for (int n=0;n<NR_NB_RA_PROC_MAX;n++ ) {
+	       cc->ra[n].cfra = false;
+	       cc->ra[n].rnti = 0;
+	       cc->ra[n].preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES;
+	       cc->ra[n].preambles.preamble_list = (uint8_t *) malloc(MAX_NUM_NR_PRACH_PREAMBLES*sizeof(uint8_t));
+	       for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++)
+	          cc->ra[n].preambles.preamble_list[i] = i;
+      }
+    }
   }
   
-  if (secondaryCellGroup) {
+  if (CellGroup) {
 
-    RC.nrmac[Mod_idP]->secondaryCellGroupCommon = secondaryCellGroup;
+    const NR_ServingCellConfig_t *servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated;
 
-    const NR_ServingCellConfig_t *servingCellConfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated;
     const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
-    AssertFatal(bwpList->list.count > 0, "downlinkBWP_ToAddModList has no BWPs!\n");
-    for (int i = 0; i < bwpList->list.count; ++i) {
-      const NR_BWP_Downlink_t *bwp = bwpList->list.array[i];
-      calculate_preferred_dl_tda(Mod_idP, bwp);
+    if(bwpList) {
+      AssertFatal(bwpList->list.count > 0, "downlinkBWP_ToAddModList has no BWPs!\n");
+      for (int i = 0; i < bwpList->list.count; ++i) {
+        const NR_BWP_Downlink_t *bwp = bwpList->list.array[i];
+        calculate_preferred_dl_tda(Mod_idP, bwp);
+      }
     }
 
-    const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList =
-        servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
-    AssertFatal(ubwpList->list.count > 0, "downlinkBWP_ToAddModList no BWPs!\n");
-    for (int i = 0; i < ubwpList->list.count; ++i) {
-      const NR_BWP_Uplink_t *ubwp = ubwpList->list.array[i];
-      calculate_preferred_ul_tda(Mod_idP, ubwp);
+    const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
+    if(ubwpList) {
+      AssertFatal(ubwpList->list.count > 0, "downlinkBWP_ToAddModList no BWPs!\n");
+      for (int i = 0; i < ubwpList->list.count; ++i) {
+        const NR_BWP_Uplink_t *ubwp = ubwpList->list.array[i];
+        calculate_preferred_ul_tda(Mod_idP, ubwp);
+      }
     }
 
     NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
     if (add_ue == 1 && get_softmodem_params()->phy_test) {
-      const int UE_id = add_new_nr_ue(Mod_idP, rnti, secondaryCellGroup);
-      LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti);
+      const int UE_id = add_new_nr_ue(Mod_idP, rnti, CellGroup);
+      LOG_I(NR_MAC,"Added new UE_id %d/%x with initial CellGroup\n",UE_id,rnti);
+      process_CellGroup(CellGroup,&UE_info->UE_sched_ctrl[UE_id]);
     } else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
       const int CC_id = 0;
       NR_COMMON_channels_t *cc = &RC.nrmac[Mod_idP]->common_channels[CC_id];
@@ -462,16 +554,17 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
         if((cc->ra[ra_index].state == RA_IDLE) && (!cc->ra[ra_index].cfra)) break;
       }
       if (ra_index == NR_NB_RA_PROC_MAX) {
-        LOG_E(MAC, "%s() %s:%d RA processes are not available for CFRA RNTI :%x\n", __FUNCTION__, __FILE__, __LINE__, rnti);
+        LOG_E(NR_MAC, "%s() %s:%d RA processes are not available for CFRA RNTI :%x\n", __FUNCTION__, __FILE__, __LINE__, rnti);
         return -1;
       }	
       NR_RA_t *ra = &cc->ra[ra_index];
-      ra->secondaryCellGroup = secondaryCellGroup;
-      if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated!=NULL) {
-        if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) {
+      ra->CellGroup = CellGroup;
+      if (CellGroup->spCellConfig && CellGroup->spCellConfig->reconfigurationWithSync &&
+	        CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated!=NULL) {
+        if (CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) {
           ra->cfra = true;
           ra->rnti = rnti;
-          struct NR_CFRA *cfra = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra;
+          struct NR_CFRA *cfra = CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra;
           uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count;
           ra->preambles.num_preambles = num_preamble;
           ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t));
@@ -494,11 +587,12 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
         for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++)
           ra->preambles.preamble_list[i] = i;
       }
-      LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti);
-    } else { // secondaryCellGroup has been updated
+      LOG_I(NR_MAC,"Added new RA process for UE RNTI %04x with initial CellGroup\n", rnti);
+    } else { // CellGroup has been updated
       const int UE_id = find_nr_UE_id(Mod_idP,rnti);
-      UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup;
-      LOG_I(PHY,"Modified UE_id %d/%x with secondaryCellGroup\n",UE_id,rnti);
+      UE_info->CellGroup[UE_id] = CellGroup;
+      LOG_I(NR_MAC,"Modified UE_id %d/%x with CellGroup\n",UE_id,rnti);
+      process_CellGroup(CellGroup,&UE_info->UE_sched_ctrl[UE_id]);
     }
   }
   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.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index f655d3d65e1d280522486cfd5ccb663d52933042..def32e25eec51cbfd7292be8abd3fe853577280d 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -66,7 +66,7 @@ void dump_mac_stats(gNB_MAC_INST *gNB)
   NR_UE_info_t *UE_info = &gNB->UE_info;
   int num = 1;
   for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
-    LOG_I(MAC, "UE ID %d RNTI %04x (%d/%d) PH %d dB PCMAX %d dBm\n",
+    LOG_I(NR_MAC, "UE ID %d RNTI %04x (%d/%d) PH %d dB PCMAX %d dBm\n",
           UE_id,
           UE_info->rnti[UE_id],
           num++,
@@ -75,32 +75,29 @@ void dump_mac_stats(gNB_MAC_INST *gNB)
           UE_info->UE_sched_ctrl[UE_id].pcmax);
     NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
     const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0;
-    LOG_I(MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n",
+    LOG_I(NR_MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n",
           UE_id,
           stats->dlsch_rounds[0], stats->dlsch_rounds[1],
           stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors,
           avg_rsrp, stats->num_rsrp_meas);
     stats->num_rsrp_meas = 0;
     stats->cumul_rsrp = 0 ;
-    LOG_I(MAC, "UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes);
-    const NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
-    LOG_I(MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_errors %d, PUSCH SNR %2.1f dB, PUCCH SNR %2.1f dB, noise rssi %2.1f dB\n",
+    LOG_I(NR_MAC, "UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes);
+    LOG_I(NR_MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n",
           UE_id,
           stats->ulsch_rounds[0], stats->ulsch_rounds[1],
           stats->ulsch_rounds[2], stats->ulsch_rounds[3],
-          stats->ulsch_errors,
-          (float) sched_ctrl->pusch_snrx10 / 10,
-          (float) sched_ctrl->pucch_snrx10 / 10,
-          (float) (sched_ctrl->raw_rssi - 1280) / 10);
-    LOG_I(MAC,
+          stats->ulsch_DTX,
+          stats->ulsch_errors);
+    LOG_I(NR_MAC,
           "UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n",
           UE_id,
           stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx);
     for (int lc_id = 0; lc_id < 63; lc_id++) {
       if (stats->lc_bytes_tx[lc_id] > 0)
-        LOG_I(MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
+        LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
       if (stats->lc_bytes_rx[lc_id] > 0)
-        LOG_I(MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
+        LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
     }
   }
   print_meas(&gNB->eNB_scheduler, "DL & UL scheduling timing stats", NULL, NULL);
@@ -322,14 +319,13 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
                                frame_t frame,
                                sub_frame_t slot){
 
-  protocol_ctxt_t   ctxt;
+  protocol_ctxt_t   ctxt={0};
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP);
  
 
   gNB_MAC_INST *gNB = RC.nrmac[module_idP];
   NR_COMMON_channels_t *cc = gNB->common_channels;
   NR_ServingCellConfigCommon_t        *scc     = cc->ServingCellConfigCommon;
-  const int bwp_id = *gNB->secondaryCellGroupCommon->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id;
 
   if (slot==0 && (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]>=257)) {
     const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
@@ -355,8 +351,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
     nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
   }
 
-  memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
-  memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1
+  memset(RC.nrmac[module_idP]->cce_list[0][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
+  for(int i_bwp = 0; i_bwp < MAX_NUM_BWP; i_bwp++)
+    memset(RC.nrmac[module_idP]->cce_list[i_bwp][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid i
+    
   NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
   for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id])
     for (int i=0; i<MAX_NUM_CORESET; i++)
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index 3cbd188ecd20080211c03afd7d5a6d92a2be26dc..79a63ceefefb30a4dcf877a43eca0df026002937 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -246,7 +246,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
   nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][slotP];
   nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
 
-  if (is_nr_UL_slot(scc, slotP, cc->frame_type)) {
+  if (is_nr_UL_slot(scc->tdd_UL_DL_ConfigurationCommon, slotP, cc->frame_type)) {
 
     uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
     uint8_t mu,N_dur,N_t_slot,start_symbol = 0,N_RA_slot;
@@ -539,10 +539,13 @@ void nr_initiate_ra_proc(module_id_t module_idP,
       else
         ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8);
 
-      ra->bwp_id = 1;
-      NR_BWP_Downlink_t *bwp = NULL; // For SA we use InitialBWP
-      if(get_softmodem_params()->sa != 1) {
-        bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+      // This should be handled differently when we use the initialBWP for RA
+      ra->bwp_id = 0;
+      NR_BWP_Downlink_t *bwp=NULL;
+      if (ra->CellGroup && ra->CellGroup->spCellConfig && ra->CellGroup->spCellConfig->spCellConfigDedicated &&
+          ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) {
+        ra->bwp_id = 1;
+	      bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
       }
 
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
@@ -585,13 +588,15 @@ void nr_initiate_ra_proc(module_id_t module_idP,
       }
       AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n");
 
-      // Common searchspace list
+      // Common SearchSpace list
       for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
         ss = commonSearchSpaceList->list.array[i];
         if (ss->searchSpaceId == ra_SearchSpace)
           ra->ra_ss = ss;
       }
 
+      AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n");
+
       // retrieving ra pdcch monitoring period and offset
       find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset);
 
@@ -612,8 +617,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
       LOG_D(NR_MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
 
       int loop = 0;
-      // This condition allows for the usage of a preconfigured rnti for the first UE
-      if (!ra->cfra || ra->rnti == 0) {
+      if (ra->rnti == 0) { // This condition allows for the usage of a preconfigured rnti for the CFRA
         do {
           ra->rnti = (taus() % 65518) + 1;
           loop++;
@@ -690,12 +694,18 @@ void nr_get_Msg3alloc(module_id_t module_id,
 
     uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes
 
-    int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+    int mu = ubwp ?
+      ubwp->bwp_Common->genericParameters.subcarrierSpacing :
+      scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
     int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot;
     ra->Msg3_tda_id = 16; // initialization to a value above limit
 
-    for (int i=0; i<ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count; i++) {
-      startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
+    NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList= ubwp ?
+      ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
+      scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+
+    for (int i=0; i<pusch_TimeDomainAllocationList->list.count; i++) {
+      startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
       SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
       // we want to transmit in the uplink symbols of mixed slot
       if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) {
@@ -705,7 +715,7 @@ void nr_get_Msg3alloc(module_id_t module_id,
     }
     AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
 
-    uint8_t k2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
+    uint8_t k2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
 
     temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
     ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
@@ -729,7 +739,10 @@ void nr_get_Msg3alloc(module_id_t module_id,
   LOG_D(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex);
   uint16_t *vrb_map_UL =
       &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE];
-  const uint16_t bwpSize = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  const uint16_t bwpSize = NRRIV2BW(ubwp ?
+				    ubwp->bwp_Common->genericParameters.locationAndBandwidth :
+				    scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
+				    MAX_BWP_SIZE);
 
     /* search msg3_nb_rb free RBs */
   int rbSize = 0;
@@ -786,12 +799,28 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
   nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu;
   memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
   future_ul_tti_req->n_pdus += 1;
+  int ibwp_size  = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  int abwp_size = ibwp_size;
+  int abwp_start = ibwp_start;
+  int scs = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
+  int fh = 0;
+  int startSymbolAndLength = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
+  int mappingtype = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType;
+
+  if (ra->CellGroup) {
+    AssertFatal(ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count <= 4,
+		"downlinkBWP_ToAddModList has %d BWP!\n", ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
+    NR_BWP_Uplink_t *ubwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
+
+    startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
+    mappingtype = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType;
+    abwp_size  = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+    fh = ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping ? 1 : 0;
+  }
 
-  AssertFatal(ra->secondaryCellGroup,
-              "no secondaryCellGroup for RNTI %04x\n",
-              ra->crnti);
-  
-  NR_BWP_Uplink_t *ubwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
   LOG_D(NR_MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
     frameP,
     slotP,
@@ -802,24 +831,19 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
     ra->msg3_round,
     ra->rnti);
 
-  int startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
   int start_symbol_index,nr_of_symbols;
   SLIV2SL(startSymbolAndLength, &start_symbol_index, &nr_of_symbols);
-  int mappingtype = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType;
 
   pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
   pusch_pdu->rnti = ra->rnti;
   pusch_pdu->handle = 0;
-  int abwp_size  = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-  int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-  int ibwp_size  = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-  int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
   if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size))
     pusch_pdu->bwp_start = abwp_start;
   else
     pusch_pdu->bwp_start = ibwp_start;
   pusch_pdu->bwp_size = ibwp_size;
-  pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+  pusch_pdu->subcarrier_spacing = scs;
   pusch_pdu->cyclic_prefix = 0;
   pusch_pdu->mcs_index = 0;
   pusch_pdu->mcs_table = 0;
@@ -848,10 +872,8 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
   else
     pusch_pdu->rb_size = ra->msg3_nb_rb;
   pusch_pdu->vrb_to_prb_mapping = 0;
-  if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping == NULL)
-    pusch_pdu->frequency_hopping = 0;
-  else
-    pusch_pdu->frequency_hopping = 1;
+
+  pusch_pdu->frequency_hopping = fh;
   //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
   pusch_pdu->uplink_frequency_shift_7p5khz = 0;
   //Resource Allocation in time domain
@@ -893,24 +915,29 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
 
     long BWPSize  = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
 
-    NR_BWP_Downlink_t *bwp = NULL; // For SA we use InitialBWP
-    if(get_softmodem_params()->sa != 1) {
-      bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
-    }
-
+    NR_BWP_Downlink_t *bwp = NULL;
     NR_ControlResourceSet_t *coreset = NULL;
-    if(bwp) {
-      coreset = get_coreset(bwp, ss, 0);
-    } else {
-      coreset = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
-    }
-
+    NR_BWP_t *genericParameters = NULL;
+    NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList=NULL;
     long BWPStart = 0;
-    if (get_softmodem_params()->sa != 1) {
-      BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    } else {
-      BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
+    if (ra->CellGroup &&
+        ra->CellGroup->spCellConfig &&
+        ra->CellGroup->spCellConfig->spCellConfigDedicated &&
+        ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList &&
+        ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]) {
+      bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+      genericParameters = &bwp->bwp_Common->genericParameters;
+      pdsch_TimeDomainAllocationList = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+    }
+    else {
+      genericParameters= &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
+      pdsch_TimeDomainAllocationList = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
     }
+    BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+    coreset = get_coreset(scc,bwp, ss, NR_SearchSpace__searchSpaceType_PR_common);
+
+    AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg2\n");
 
     uint16_t *vrb_map = cc[CC_id].vrb_map;
     for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) {
@@ -943,25 +970,19 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
 
     // Calculate number of symbols
     int startSymbolIndex, nrOfSymbols;
-    const int startSymbolAndLength = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->
-        downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->
-        pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
+    const int startSymbolAndLength = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
     SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
     AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n");
 
-    int mappingtype = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->
-        downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->
-        pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType;
+    LOG_D(MAC,"Msg2 startSymbolIndex.nrOfSymbols %d.%d\n",startSymbolIndex,nrOfSymbols);
 
-    uint8_t numDmrsCdmGrpsNoData = 2;
-    if (nrOfSymbols == 2) {
-      numDmrsCdmGrpsNoData = 1;
-    }
+    int mappingtype = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType;
 
     // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially
     // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them
+    const int bwpid = bwp ? bwp->bwp_Id : 0;
     const int coresetid = coreset->controlResourceSetId;
-    nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid];
+    nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid];
     if (!pdcch_pdu_rel15) {
       nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
       memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t));
@@ -970,7 +991,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
       dl_req->nPDUs += 1;
       pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
       nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, bwp);
-      nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid] = pdcch_pdu_rel15;
+      nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15;
     }
 
     nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
@@ -983,32 +1004,39 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     LOG_I(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d\n",
           module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state);
 
-    AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->RA_rnti);
-
     // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control
     // information to data and is reset every slot.
     const int pduindex = nr_mac->pdu_index[CC_id]++;
 
     uint8_t mcsTableIdx = 0;
-    if (bwp==NULL || bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL)
-      mcsTableIdx = 0;
-    else{
+    if (bwp &&
+        bwp->bwp_Dedicated &&
+        bwp->bwp_Dedicated->pdsch_Config &&
+        bwp->bwp_Dedicated->pdsch_Config->choice.setup &&
+        bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table) {
       if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0)
         mcsTableIdx = 1;
       else
         mcsTableIdx = 2;
     }
-
-    AssertFatal(numDmrsCdmGrpsNoData == 1 || numDmrsCdmGrpsNoData == 2,
-                "nr_mac->schedCtrlCommon->numDmrsCdmGrpsNoData %d is not possible",
-                numDmrsCdmGrpsNoData);
+    else mcsTableIdx = 0;
+
+    int dmrsConfigType=0;
+    if (bwp &&
+        bwp->bwp_Dedicated &&
+        bwp->bwp_Dedicated->pdsch_Config &&
+        bwp->bwp_Dedicated->pdsch_Config->choice.setup &&
+        bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA &&
+        bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup &&
+        bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type)
+      dmrsConfigType = 1;
 
     pdsch_pdu_rel15->pduBitmap = 0;
     pdsch_pdu_rel15->rnti = ra->RA_rnti;
     pdsch_pdu_rel15->pduIndex = pduindex;
     pdsch_pdu_rel15->BWPSize  = BWPSize;
     pdsch_pdu_rel15->BWPStart = BWPStart;
-    pdsch_pdu_rel15->SubcarrierSpacing = bwp!=NULL ? bwp->bwp_Common->genericParameters.subcarrierSpacing : scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing;
+    pdsch_pdu_rel15->SubcarrierSpacing = genericParameters->subcarrierSpacing;
     pdsch_pdu_rel15->CyclicPrefix = 0;
     pdsch_pdu_rel15->NrOfCodewords = 1;
     pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,mcsTableIdx);
@@ -1020,10 +1048,10 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     pdsch_pdu_rel15->nrOfLayers = 1;
     pdsch_pdu_rel15->transmissionScheme = 0;
     pdsch_pdu_rel15->refPoint = 0;
-    pdsch_pdu_rel15->dmrsConfigType = bwp!=NULL ? (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0;
+    pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType;
     pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
     pdsch_pdu_rel15->SCID = 0;
-    pdsch_pdu_rel15->numDmrsCdmGrpsNoData = numDmrsCdmGrpsNoData;
+    pdsch_pdu_rel15->numDmrsCdmGrpsNoData = nrOfSymbols <= 2 ? 1 : 2;
     pdsch_pdu_rel15->dmrsPorts = 1;
     pdsch_pdu_rel15->resourceAlloc = 1;
     pdsch_pdu_rel15->rbStart = rbStart;
@@ -1083,19 +1111,21 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
           pdcch_pdu_rel15->DurationSymbols);
 
     fill_dci_pdu_rel15(scc,
-                       nr_mac->secondaryCellGroupCommon,
+                       ra->CellGroup,
                        &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1],
                        &dci_payload,
                        NR_DL_DCI_FORMAT_1_0,
                        NR_RNTI_RA,
                        pdsch_pdu_rel15->BWPSize,
-                       ra->bwp_id);
+                       bwpid);
 
     // DL TX request
     nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
 
     // Program UL processing for Msg3
-    NR_BWP_Uplink_t *ubwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+    NR_BWP_Uplink_t *ubwp = ra->CellGroup ?
+      ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1] :
+      NULL;
     nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra, nr_mac->tdd_beam_association);
     nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]);
 
@@ -1137,24 +1167,34 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
     NR_SearchSpace_t *ss = ra->ra_ss;
 
-    NR_BWP_Downlink_t *bwp = NULL; // For SA we use InitialBWP
-    if(get_softmodem_params()->sa != 1) {
-      bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
-    }
-
+    NR_BWP_Downlink_t *bwp = NULL;
     NR_ControlResourceSet_t *coreset = NULL;
-    if(bwp) {
-      coreset = get_coreset(bwp, ss, 0);
-    } else {
-      coreset = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
+    NR_BWP_t *genericParameters = NULL;
+    NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList=NULL;
+
+    if (ra->CellGroup &&
+        ra->CellGroup->spCellConfig &&
+        ra->CellGroup->spCellConfig->spCellConfigDedicated &&
+        ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList &&
+        ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]) {
+      bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+      genericParameters = &bwp->bwp_Common->genericParameters;
+      pdsch_TimeDomainAllocationList = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
     }
+    else {
+      genericParameters= &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
+      pdsch_TimeDomainAllocationList = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+    }
+    coreset = get_coreset(scc,bwp, ss, NR_SearchSpace__searchSpaceType_PR_common);
+
+    AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg4\n");
 
     int UE_id = find_nr_UE_id(module_idP, ra->rnti);
     NR_UE_info_t *UE_info = &nr_mac->UE_info;
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
 
-    long BWPSize  = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    long BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    long BWPSize  = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+    long BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
 
     // HARQ management
     AssertFatal(sched_ctrl->available_dl_harq.head >= 0,
@@ -1167,7 +1207,27 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     harq->is_waiting = true;
     ra->harq_pid = current_harq_pid;
 
-    int alloc = nr_acknack_scheduling(module_idP, UE_id, frameP, slotP);
+    // get CCEindex, needed also for PUCCH and then later for PDCCH
+    uint8_t aggregation_level;
+    uint8_t nr_of_candidates;
+    find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
+    int CCEIndex = allocate_nr_CCEs(nr_mac, bwp, coreset, aggregation_level,0,0,nr_of_candidates);
+    if (CCEIndex < 0) {
+      LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti);
+      return;
+    }
+
+    int n_rb=0;
+    for (int i=0;i<6;i++)
+      for (int j=0;j<8;j++) {
+	      n_rb+=((coreset->frequencyDomainResources.buf[i]>>j)&1);
+      }
+    n_rb*=6;
+    const uint16_t N_cce = n_rb * coreset->duration / NR_NB_REG_PER_CCE;
+    const int delta_PRI=0;
+    int r_pucch = ((CCEIndex<<1)/N_cce)+(delta_PRI<<1);
+
+    int alloc = nr_acknack_scheduling(module_idP, UE_id, frameP, slotP, r_pucch);
     AssertFatal(alloc>=0,"Couldn't find a pucch allocation for ack nack (msg4)\n");
     NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc];
     harq->feedback_slot = pucch->ul_slot;
@@ -1184,22 +1244,18 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->L = mac_sdu_length;
     mac_pdu_length = mac_pdu_length + mac_sdu_length + sizeof(NR_MAC_SUBHEADER_SHORT);
 
-    LOG_D(NR_MAC,"Encoded RRCSetup Piggyback (%d + 2 bytes), mac_pdu_length %d\n",mac_sdu_length,mac_pdu_length);
+    LOG_D(NR_MAC,"Encoded RRCSetup Piggyback (%d + %d bytes), mac_pdu_length %d\n", mac_sdu_length, (int)sizeof(NR_MAC_SUBHEADER_SHORT), mac_pdu_length);
 
     // Calculate number of symbols
     int startSymbolIndex, nrOfSymbols;
-    const int startSymbolAndLength = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->
-        downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->
-        pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
+    const int startSymbolAndLength = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
     SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
     AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n");
 
-    int mappingtype = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->
-        downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->
-        pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType;
+    int mappingtype = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType;
 
     uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL,
-                                            nr_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position,
+                                            scc->dmrs_TypeA_Position,
                                             nrOfSymbols,
                                             startSymbolIndex,
                                             mappingtype);
@@ -1227,14 +1283,17 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     }
 
     uint8_t mcsTableIdx = 0;
-    if (bwp==NULL || bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL)
-      mcsTableIdx = 0;
-    else{
+    if (bwp &&
+        bwp->bwp_Dedicated &&
+        bwp->bwp_Dedicated->pdsch_Config &&
+        bwp->bwp_Dedicated->pdsch_Config->choice.setup &&
+        bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table) {
       if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0)
         mcsTableIdx = 1;
       else
         mcsTableIdx = 2;
     }
+    else mcsTableIdx = 0;
 
     int rbStart = 0;
     int rbSize = 0;
@@ -1267,19 +1326,12 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
       return;
     }
 
-    uint8_t aggregation_level;
-    uint8_t nr_of_candidates;
-    find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
-    int CCEIndex = allocate_nr_CCEs(nr_mac, bwp, coreset, aggregation_level,0,0,nr_of_candidates);
-    if (CCEIndex < 0) {
-      LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti);
-      return;
-    }
 
     // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially
     // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them
+    const int bwpid = bwp ? bwp->bwp_Id : 0;
     const int coresetid = coreset->controlResourceSetId;
-    nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid];
+    nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid];
     if (!pdcch_pdu_rel15) {
       nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
       memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t));
@@ -1288,7 +1340,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
       dl_req->nPDUs += 1;
       pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
       nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, bwp);
-      nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid] = pdcch_pdu_rel15;
+      nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15;
     }
 
     nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
@@ -1300,12 +1352,6 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
 
     LOG_I(NR_MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
 
-    AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->rnti);
-
-    AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
-                  "downlinkBWP_ToAddModList has %d BWP!\n",
-                  ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
-
     // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control
     // information to data and is reset every slot.
     const int pduindex = nr_mac->pdu_index[CC_id]++;
@@ -1315,7 +1361,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     pdsch_pdu_rel15->pduIndex = pduindex;
     pdsch_pdu_rel15->BWPSize  = BWPSize;
     pdsch_pdu_rel15->BWPStart = BWPStart;
-    pdsch_pdu_rel15->SubcarrierSpacing = bwp!=NULL ? bwp->bwp_Common->genericParameters.subcarrierSpacing : scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing;
+    pdsch_pdu_rel15->SubcarrierSpacing = genericParameters->subcarrierSpacing;
     pdsch_pdu_rel15->CyclicPrefix = 0;
     pdsch_pdu_rel15->NrOfCodewords = 1;
     pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,mcsTableIdx);
@@ -1330,7 +1376,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType;
     pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
     pdsch_pdu_rel15->SCID = 0;
-    pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2;
+    pdsch_pdu_rel15->numDmrsCdmGrpsNoData = nrOfSymbols <= 2 ? 1 : 2;
     pdsch_pdu_rel15->dmrsPorts = 1;
     pdsch_pdu_rel15->resourceAlloc = 1;
     pdsch_pdu_rel15->rbStart = rbStart;
@@ -1375,11 +1421,11 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     dci_payload.ndi = harq->ndi;
     dci_payload.dai[0].val = (pucch->dai_c-1)&3;
     dci_payload.tpc = sched_ctrl->tpc1; // TPC for PUCCH: table 7.2.1-1 in 38.213
-    dci_payload.pucch_resource_indicator = pucch->resource_indicator;
+    dci_payload.pucch_resource_indicator = delta_PRI; // This is delta_PRI from 9.2.1 in 38.213
     dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch->timing_indicator;
 
     LOG_D(NR_MAC,
-          "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n",
+          "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d pucchres %d harqtiming %d\n",
           dci_payload.frequency_domain_assignment.val,
           pdsch_pdu_rel15->rbStart,
           pdsch_pdu_rel15->rbSize,
@@ -1387,7 +1433,9 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
           dci_payload.time_domain_assignment.val,
           dci_payload.vrb_to_prb_mapping.val,
           dci_payload.mcs,
-          dci_payload.tb_scaling);
+          dci_payload.tb_scaling,
+          dci_payload.pucch_resource_indicator,
+          dci_payload.pdsch_to_harq_feedback_timing_indicator.val);
 
     LOG_D(NR_MAC,
           "[RAPROC] DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d  n_symb %d\n",
@@ -1399,13 +1447,13 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
           pdcch_pdu_rel15->DurationSymbols);
 
     fill_dci_pdu_rel15(scc,
-                       nr_mac->secondaryCellGroupCommon,
+                       ra->CellGroup,
                        &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1],
                        &dci_payload,
                        NR_DL_DCI_FORMAT_1_0,
                        NR_RNTI_TC,
                        pdsch_pdu_rel15->BWPSize,
-                       ra->bwp_id);
+                       bwpid);
 
     // Add padding header and zero rest out if there is space left
     if (mac_pdu_length < harq->tb_size) {
@@ -1470,6 +1518,7 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
       LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti);
       nr_clear_ra_proc(module_id, CC_id, frame, ra);
       UE_info->active[UE_id] = true;
+      UE_info->Msg4_ACKed[UE_id] = true;
     }
     else
     {
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index f93ad92a1391940116b5f8e92fe41fca0ed96e68..8b12742fccef1ad5fc66c4f71ad2d5602ee04433 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -139,8 +139,7 @@ void schedule_ssb(frame_t frame, sub_frame_t slot,
 
 }
 
-void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
-{
+void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
   gNB_MAC_INST *gNB = RC.nrmac[module_idP];
   NR_COMMON_channels_t *cc;
   nfapi_nr_dl_tti_request_t      *dl_tti_request;
@@ -380,14 +379,13 @@ void schedule_control_sib1(module_id_t module_id,
   uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex, mappingtype);
   uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos);
 
+  LOG_D(MAC,"dlDmrsSymbPos %x\n",dlDmrsSymbPos);
   int rbSize = 0;
   uint32_t TBS = 0;
   do {
     rbSize++;
-    TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs,
-                                      gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx),
-                         nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs,
-                                             gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx),
+    TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx),
+                         nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx),
                          rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0, 0,1) >> 3;
   } while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes);
 
@@ -398,6 +396,8 @@ void schedule_control_sib1(module_id_t module_id,
   LOG_D(MAC,"nrOfSymbols = %i\n", nrOfSymbols);
   LOG_D(MAC, "rbSize = %i\n", gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize);
   LOG_D(MAC,"TBS = %i\n", TBS);
+  LOG_D(MAC,"dmrs_length %d\n",dmrs_length);
+  LOG_D(MAC,"N_PRB_DMRS = %d\n",N_PRB_DMRS);
   LOG_D(MAC,"mappingtype = %d\n", mappingtype);
 
   // Mark the corresponding RBs as used
@@ -417,7 +417,6 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
   gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP];
   NR_COMMON_channels_t *cc = gNB_mac->common_channels;
   NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
-  NR_CellGroupConfig_t *secondaryCellGroup = gNB_mac->secondaryCellGroupCommon;
   NR_BWP_Downlink_t *bwp = gNB_mac->sched_ctrlCommon->active_bwp;
 
   nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
@@ -524,7 +523,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
   int rnti_type = NR_RNTI_SI;
 
   fill_dci_pdu_rel15(scc,
-                     secondaryCellGroup,
+                     NULL,
                      &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1],
                      &dci_payload,
                      dci_format,
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index b43c9e2e2ca91c39bf95336d0492bcfa63acca59..47614ed8c0743810d4b7eaa9699fdc38c3a2a4d4 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -55,11 +55,12 @@
 #define HALFWORD 16
 #define WORD 32
 //#define SIZE_OF_POINTER sizeof (void *)
+static int loop_dcch_dtch = DL_SCH_LCID_DTCH;
 
 void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp)
 {
   gNB_MAC_INST *nrmac = RC.nrmac[module_id];
-  const int bwp_id = bwp->bwp_Id;
+  const int bwp_id = bwp ? bwp->bwp_Id : 0;
   if (nrmac->preferred_dl_tda[bwp_id])
     return;
 
@@ -69,9 +70,10 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
       scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
   const int symb_dlMixed = tdd ? (1 << tdd->nrofDownlinkSymbols) - 1 : 0;
 
-  const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
-  const NR_SearchSpace_t *search_space = get_searchspace(bwp, target_ss);
-  const NR_ControlResourceSet_t *coreset = get_coreset(bwp, search_space, 1 /* dedicated */);
+  const int target_ss = bwp ? NR_SearchSpace__searchSpaceType_PR_ue_Specific : NR_SearchSpace__searchSpaceType_PR_common;
+  NR_SearchSpace_t *search_space = get_searchspace(scc, bwp ? bwp->bwp_Dedicated : NULL, target_ss);
+  const NR_ControlResourceSet_t *coreset = get_coreset(scc, (NR_BWP_Downlink_t*)bwp, search_space, target_ss);
+
   // get coreset symbol "map"
   const uint16_t symb_coreset = (1 << coreset->duration) - 1;
 
@@ -176,7 +178,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
       ((NR_MAC_CE_TA *) ce_ptr)->TAGID = tag_id;
     }
 
-    LOG_D(MAC, "NR MAC CE timing advance command = %d (%d) TAG ID = %d\n", timing_advance_cmd, ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND, tag_id);
+    LOG_D(NR_MAC, "NR MAC CE timing advance command = %d (%d) TAG ID = %d\n", timing_advance_cmd, ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND, tag_id);
     mac_ce_size = sizeof(NR_MAC_CE_TA);
     // Copying  bytes for MAC CEs to the mac pdu pointer
     memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
@@ -195,7 +197,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
     // contention resolution identity MAC ce has a fixed 48 bit size
     // this contains the UL CCCH SDU. If UL CCCH SDU is longer than 48 bits,
     // it contains the first 48 bits of the UL CCCH SDU
-    LOG_T(MAC, "[gNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
+    LOG_T(NR_MAC, "[gNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
           ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2],
           ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]);
     // Copying bytes (6 octects) to CEs pointer
@@ -220,7 +222,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
     nr_UESpec_TCI_StateInd_PDCCH.ServingCellId = (ue_sched_ctl->UE_mac_ce_ctrl.pdcch_state_ind.servingCellId) & 0x1F; //extracting LSB 5 Bits
     nr_UESpec_TCI_StateInd_PDCCH.TciStateId = (ue_sched_ctl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId) & 0x7F; //extracting LSB 7 bits
     nr_UESpec_TCI_StateInd_PDCCH.CoresetId2 = (ue_sched_ctl->UE_mac_ce_ctrl.pdcch_state_ind.coresetId) & 0x1; //extracting LSB 1 bit
-    LOG_D(MAC, "NR MAC CE TCI state indication for UE Specific PDCCH = %d \n", nr_UESpec_TCI_StateInd_PDCCH.TciStateId);
+    LOG_D(NR_MAC, "NR MAC CE TCI state indication for UE Specific PDCCH = %d \n", nr_UESpec_TCI_StateInd_PDCCH.TciStateId);
     mac_ce_size = sizeof(NR_TCI_PDCCH);
     // Copying  bytes for MAC CEs to the mac pdu pointer
     memcpy((void *) mac_pdu_ptr, (void *)&nr_UESpec_TCI_StateInd_PDCCH, mac_ce_size);
@@ -331,7 +333,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
     ((NR_MAC_CE_SP_ZP_CSI_RS_RES_SET *) mac_pdu_ptr)->BWPID = ue_sched_ctl->UE_mac_ce_ctrl.sp_zp_csi_rs.bwpid & 0x3; //2 bits
     ((NR_MAC_CE_SP_ZP_CSI_RS_RES_SET *) mac_pdu_ptr)->CSIRS_RSC_ID = ue_sched_ctl->UE_mac_ce_ctrl.sp_zp_csi_rs.rsc_id & 0xF; //4 bits
     ((NR_MAC_CE_SP_ZP_CSI_RS_RES_SET *) mac_pdu_ptr)->R = 0;
-    LOG_D(MAC, "NR MAC CE of ZP CSIRS Serv cell ID = %d BWPID= %d Rsc set ID = %d\n", ue_sched_ctl->UE_mac_ce_ctrl.sp_zp_csi_rs.serv_cell_id, ue_sched_ctl->UE_mac_ce_ctrl.sp_zp_csi_rs.bwpid,
+    LOG_D(NR_MAC, "NR MAC CE of ZP CSIRS Serv cell ID = %d BWPID= %d Rsc set ID = %d\n", ue_sched_ctl->UE_mac_ce_ctrl.sp_zp_csi_rs.serv_cell_id, ue_sched_ctl->UE_mac_ce_ctrl.sp_zp_csi_rs.bwpid,
           ue_sched_ctl->UE_mac_ce_ctrl.sp_zp_csi_rs.rsc_id);
     mac_ce_size = sizeof(NR_MAC_CE_SP_ZP_CSI_RS_RES_SET);
     mac_pdu_ptr += (unsigned char) mac_ce_size;
@@ -388,7 +390,15 @@ void nr_store_dlsch_buffer(module_id_t module_id,
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
 
     sched_ctrl->num_total_bytes = 0;
-    const int lcid = DL_SCH_LCID_DTCH;
+    if ((sched_ctrl->lcid_mask&(1<<4)) > 0 && loop_dcch_dtch == DL_SCH_LCID_DCCH1)
+      loop_dcch_dtch = DL_SCH_LCID_DTCH;
+    else if ((sched_ctrl->lcid_mask&(1<<1)) > 0 && loop_dcch_dtch == DL_SCH_LCID_DTCH)
+      loop_dcch_dtch = DL_SCH_LCID_DCCH;
+    else if ((sched_ctrl->lcid_mask&(1<<2)) > 0 && loop_dcch_dtch == DL_SCH_LCID_DCCH)
+      loop_dcch_dtch = DL_SCH_LCID_DCCH1;
+
+    const int lcid = loop_dcch_dtch;
+    // const int lcid = DL_SCH_LCID_DTCH;
     const uint16_t rnti = UE_info->rnti[UE_id];
     sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
                                                       rnti,
@@ -401,11 +411,23 @@ void nr_store_dlsch_buffer(module_id_t module_id,
                                                       0,
                                                       0);
     sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
-    LOG_D(MAC,
-          "[%s][%d.%d], DTCH%d->DLSCH, RLC status %d bytes TA %d\n",
+    LOG_D(NR_MAC,
+        "%d.%d, LCID%d:->DLSCH, RLC status %d bytes. \n",
+        frame,
+        slot,
+        lcid,
+        sched_ctrl->num_total_bytes);
+
+    if (sched_ctrl->num_total_bytes == 0
+        && !sched_ctrl->ta_apply) /* If TA should be applied, give at least one RB */
+      return;
+
+    LOG_D(NR_MAC,
+          "[%s][%d.%d], %s%d->DLSCH, RLC status %d bytes TA %d\n",
           __func__,
           frame,
           slot,
+          lcid<4?"DCCH":"DTCH",
           lcid,
           sched_ctrl->rlc_status[lcid].bytes_in_buffer,
           sched_ctrl->ta_apply);
@@ -418,18 +440,25 @@ bool allocate_dl_retransmission(module_id_t module_id,
                                 uint8_t *rballoc_mask,
                                 int *n_rb_sched,
                                 int UE_id,
-                                int current_harq_pid)
-{
+                                int current_harq_pid) {
+
   const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon;
   NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
   NR_sched_pdsch_t *retInfo = &sched_ctrl->harq_processes[current_harq_pid].sched_pdsch;
-  const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-  int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-  const uint8_t num_dmrs_cdm_grps_no_data = 1;
+  NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
+                                &sched_ctrl->active_bwp->bwp_Common->genericParameters :
+                                &RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
+
+  const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+  int rbStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+
+  NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
+  const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
+  const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_bwp ? (f ? 1 : (ps->nrOfSymbols == 2 ? 1 : 2)) : (ps->nrOfSymbols == 2 ? 1 : 2);
 
   int rbSize = 0;
-  const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot];
+  const int tda = sched_ctrl->active_bwp ? RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot] : 1;
   if (tda == retInfo->time_domain_allocation) {
     /* Check that there are enough resources for retransmission */
     while (rbSize < retInfo->rbSize) {
@@ -438,7 +467,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
       while (rbStart < bwpSize && !rballoc_mask[rbStart])
         rbStart++;
       if (rbStart >= bwpSize) {
-        LOG_D(MAC, "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]);
+        LOG_D(NR_MAC, "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]);
         return false;
       }
       while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize] && rbSize < retInfo->rbSize)
@@ -446,10 +475,9 @@ bool allocate_dl_retransmission(module_id_t module_id,
     }
     /* check whether we need to switch the TDA allocation since the last
      * (re-)transmission */
-    NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
     if (ps->time_domain_allocation != tda || ps->numDmrsCdmGrpsNoData != num_dmrs_cdm_grps_no_data)
       nr_set_pdsch_semi_static(
-          scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
+          scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
   } else {
     /* the retransmission will use a different time domain allocation, check
      * that we have enough resources */
@@ -459,7 +487,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
       rbSize++;
     NR_pdsch_semi_static_t temp_ps;
     nr_set_pdsch_semi_static(
-        scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, &temp_ps);
+        scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, &temp_ps);
     uint32_t new_tbs;
     uint16_t new_rbSize;
     bool success = nr_find_nb_rb(retInfo->Qm,
@@ -492,7 +520,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
 
   /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
    * allocation after CCE alloc fail would be more complex) */
-  const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot);
+  const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1);
   if (alloc<0) {
     LOG_D(MAC,
           "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
@@ -532,8 +560,10 @@ void pf_dl(module_id_t module_id,
            int max_num_ue,
            int n_rb_sched,
            uint8_t *rballoc_mask) {
-  const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon;
-  NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
+
+  gNB_MAC_INST *mac = RC.nrmac[module_id];
+  NR_UE_info_t *UE_info = &mac->UE_info;
+  NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
   float coeff_ue[MAX_MOBILES_PER_GNB];
   // UEs that could be scheduled
   int ue_array[MAX_MOBILES_PER_GNB];
@@ -541,6 +571,7 @@ void pf_dl(module_id_t module_id,
 
   /* Loop UE_info->list to check retransmission */
   for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
+    if (UE_info->Msg4_ACKed[UE_id] != true) continue;
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
     NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
     NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
@@ -558,7 +589,7 @@ void pf_dl(module_id_t module_id,
       bool r = allocate_dl_retransmission(
           module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pdsch->dl_harq_pid);
       if (!r) {
-        LOG_D(MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot);
+        LOG_D(NR_MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot);
         continue;
       }
       /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
@@ -573,7 +604,7 @@ void pf_dl(module_id_t module_id,
       sched_pdsch->mcs = 9;
       uint32_t tbs = pf_tbs[ps->mcsTableIdx][sched_pdsch->mcs];
       coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id];
-      LOG_D(MAC,"b %d, thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
+      LOG_D(NR_MAC,"b %d, thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
             b, UE_id, thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]);
       /* Create UE_sched list for UEs eligible for new transmission*/
       add_tail_nr_list(&UE_sched, UE_id);
@@ -601,14 +632,19 @@ void pf_dl(module_id_t module_id,
     *p = -1;
 
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+    int bwp_Id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0;
     const uint16_t rnti = UE_info->rnti[UE_id];
-    const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
+      &sched_ctrl->active_bwp->bwp_Common->genericParameters:
+      &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
+
+    const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
+    int rbStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
 
     /* Find a free CCE */
     bool freeCCE = find_free_CCE(module_id, slot, UE_id);
     if (!freeCCE) {
-      LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, UE_id, rnti);
+      LOG_D(NR_MAC, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, UE_id, rnti);
       continue;
     }
     /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
@@ -617,9 +653,9 @@ void pf_dl(module_id_t module_id,
 
     /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
     * allocation after CCE alloc fail would be more complex) */
-    const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot);
+    const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1);
     if (alloc<0) {
-      LOG_D(MAC,
+      LOG_D(NR_MAC,
             "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
             __func__,
             UE_id,
@@ -628,7 +664,7 @@ void pf_dl(module_id_t module_id,
             slot);
       int cid = sched_ctrl->coreset->controlResourceSetId;
       UE_info->num_pdcch_cand[UE_id][cid]--;
-      int *cce_list = RC.nrmac[module_id]->cce_list[sched_ctrl->active_bwp->bwp_Id][cid];
+      int *cce_list = mac->cce_list[bwp_Id][cid];
       for (int i = 0; i < sched_ctrl->aggregation_level; i++)
         cce_list[sched_ctrl->cce_index + i] = 0;
       return;
@@ -641,13 +677,14 @@ void pf_dl(module_id_t module_id,
       max_rbSize++;
 
     /* MCS has been set above */
-    const uint8_t num_dmrs_cdm_grps_no_data = 1;
-    const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot];
+    const int tda = sched_ctrl->active_bwp ? RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot] : 1;
     NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
     NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
+    const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
+    const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_bwp ? (f ? 1 : (ps->nrOfSymbols == 2 ? 1 : 2)) : (ps->nrOfSymbols == 2 ? 1 : 2);
     if (ps->time_domain_allocation != tda || ps->numDmrsCdmGrpsNoData != num_dmrs_cdm_grps_no_data)
       nr_set_pdsch_semi_static(
-          scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
+          scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
     sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
     sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
     sched_pdsch->pucch_allocation = alloc;
@@ -677,6 +714,7 @@ void pf_dl(module_id_t module_id,
 void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
 {
   NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
+  NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
 
   if (UE_info->num_UEs == 0)
     return;
@@ -688,11 +726,10 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
   int UE_id = UE_info->list.head;
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
 
-  const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot];
-  if (tda < 0)
-    return;
-
-  const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp ?
+				    sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth:
+				    scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,
+				    MAX_BWP_SIZE);
 
   uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
   uint8_t rballoc_mask[bwpSize];
@@ -764,6 +801,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
   NR_list_t *UE_list = &UE_info->list;
   for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+    if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
     NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
     UE_info->mac_stats[UE_id].dlsch_current_bytes = 0;
 
@@ -773,7 +811,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
      * If we add the CE, ta_apply will be reset */
     if (frame == (sched_ctrl->ta_frame + 10) % 1024){
       sched_ctrl->ta_apply = true; /* the timer is reset once TA CE is scheduled */
-      LOG_D(MAC, "[UE %d][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE_id, frame, slot);
+      LOG_D(NR_MAC, "[UE %d][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE_id, frame, slot);
     }
 
     if (sched_pdsch->rbSize <= 0)
@@ -819,7 +857,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
     harq->is_waiting = true;
     UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++;
 
-    LOG_D(MAC,
+    LOG_D(NR_MAC,
           "%4d.%2d RNTI %04x start %3d RBs %3d startSymbol %2d nb_symbol %2d MCS %2d TBS %4d HARQ PID %2d round %d NDI %d\n",
           frame,
           slot,
@@ -835,15 +873,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
           harq->ndi);
 
     NR_BWP_Downlink_t *bwp = sched_ctrl->active_bwp;
-    AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList,
-                "searchSpacesToAddModList is null\n");
-    AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count > 0,
-                "searchSPacesToAddModList is empty\n");
 
     /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not
      * exist, create it */
-    const int bwpid = sched_ctrl->active_bwp->bwp_Id;
-    const int coresetid = sched_ctrl->coreset->controlResourceSetId;
+    const int bwpid = bwp ? bwp->bwp_Id : 0;
+    const int coresetid = bwp ? sched_ctrl->coreset->controlResourceSetId : gNB_mac->sched_ctrlCommon->coreset->controlResourceSetId;
     nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid];
     if (!pdcch_pdu) {
       nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
@@ -852,7 +886,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
       dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
       dl_req->nPDUs += 1;
       pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
-      nr_configure_pdcch(pdcch_pdu, sched_ctrl->search_space, sched_ctrl->coreset, scc, bwp);
+      LOG_D(NR_MAC,"Trying to configure DL pdcch for bwp %d, cs %d\n",bwpid,coresetid);
+      NR_SearchSpace_t *ss = bwp ? sched_ctrl->search_space:gNB_mac->sched_ctrlCommon->search_space;
+      NR_ControlResourceSet_t *coreset = bwp? sched_ctrl->coreset:gNB_mac->sched_ctrlCommon->coreset;
+      nr_configure_pdcch(pdcch_pdu, ss, coreset, scc, bwp);
       gNB_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu;
     }
 
@@ -872,13 +909,13 @@ void nr_schedule_ue_spec(module_id_t module_id,
     pdsch_pdu->pduIndex = pduindex;
 
     // BWP
-    pdsch_pdu->BWPSize  = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    pdsch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
-    pdsch_pdu->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
-    if (bwp->bwp_Common->genericParameters.cyclicPrefix)
-      pdsch_pdu->CyclicPrefix = *bwp->bwp_Common->genericParameters.cyclicPrefix;
-    else
-      pdsch_pdu->CyclicPrefix = 0;
+    NR_BWP_t *genericParameters = bwp ? &bwp->bwp_Common->genericParameters : &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
+
+    pdsch_pdu->BWPSize  = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+    pdsch_pdu->BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
+    pdsch_pdu->SubcarrierSpacing = genericParameters->subcarrierSpacing;
+
+    pdsch_pdu->CyclicPrefix = genericParameters->cyclicPrefix ? *genericParameters->cyclicPrefix : 0;
 
     // Codeword information
     pdsch_pdu->NrOfCodewords = 1;
@@ -886,6 +923,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
     pdsch_pdu->qamModOrder[0] = Qm;
     pdsch_pdu->mcsIndex[0] = sched_pdsch->mcs;
     pdsch_pdu->mcsTable[0] = ps->mcsTableIdx;
+    AssertFatal(harq!=NULL,"harq is null\n");
     AssertFatal(harq->round<4,"%d",harq->round);
     pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round];
     pdsch_pdu->TBSize[0] = TBS;
@@ -913,9 +951,16 @@ void nr_schedule_ue_spec(module_id_t module_id,
     pdsch_pdu->StartSymbolIndex = ps->startSymbolIndex;
     pdsch_pdu->NrOfSymbols = ps->nrOfSymbols;
 
+    NR_PDSCH_Config_t *pdsch_Config=NULL;
+    if (bwp &&
+        bwp->bwp_Dedicated &&
+        bwp->bwp_Dedicated->pdsch_Config &&
+        bwp->bwp_Dedicated->pdsch_Config->choice.setup)
+      pdsch_Config =  bwp->bwp_Dedicated->pdsch_Config->choice.setup;
+
     /* Check and validate PTRS values */
     struct NR_SetupRelease_PTRS_DownlinkConfig *phaseTrackingRS =
-        bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS;
+      pdsch_Config ? pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS : NULL;
     if (phaseTrackingRS) {
       bool valid_ptrs_setup = set_dl_ptrs_values(phaseTrackingRS->choice.setup,
                                                  pdsch_pdu->rbSize,
@@ -935,7 +980,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
     nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu->dci_pdu[pdcch_pdu->numDlDci];
     pdcch_pdu->numDlDci++;
     dci_pdu->RNTI = rnti;
-    if (sched_ctrl->coreset->pdcch_DMRS_ScramblingID &&
+    if (sched_ctrl->coreset &&
+        sched_ctrl->search_space &&
+        sched_ctrl->coreset->pdcch_DMRS_ScramblingID &&
         sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) {
       dci_pdu->ScramblingId = *sched_ctrl->coreset->pdcch_DMRS_ScramblingID;
       dci_pdu->ScramblingRNTI = rnti;
@@ -952,20 +999,19 @@ void nr_schedule_ue_spec(module_id_t module_id,
     dci_pdu_rel15_t dci_payload;
     memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t));
     // bwp indicator
-    
-    const int n_dl_bwp = UE_info->secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count;
-      AssertFatal(n_dl_bwp <= 4,
-          "downlinkBWP_ToAddModList has %d BWP!\n",
-          n_dl_bwp);
+    const int n_dl_bwp = bwp ? UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count : 0;
+    AssertFatal(n_dl_bwp <= 4, "downlinkBWP_ToAddModList has %d BWP!\n", n_dl_bwp);
+
     // as per table 7.3.1.1.2-1 in 38.212
-    dci_payload.bwp_indicator.val = n_dl_bwp < 4 ? bwp->bwp_Id : bwp->bwp_Id - 1;
-    AssertFatal(bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1,
-                "Only frequency resource allocation type 1 is currently supported\n");
+    dci_payload.bwp_indicator.val = bwp ? (n_dl_bwp < 4 ? bwp->bwp_Id : bwp->bwp_Id - 1) : 0;
+    if (bwp) AssertFatal(bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1,
+			 "Only frequency resource allocation type 1 is currently supported\n");
     dci_payload.frequency_domain_assignment.val =
         PRBalloc_to_locationandbandwidth0(
             pdsch_pdu->rbSize,
             pdsch_pdu->rbStart,
             pdsch_pdu->BWPSize);
+    dci_payload.format_indicator = 1;
     dci_payload.time_domain_assignment.val = ps->time_domain_allocation;
     dci_payload.mcs = sched_pdsch->mcs;
     dci_payload.rv = pdsch_pdu->rvIndex[0];
@@ -977,9 +1023,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
     dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch->timing_indicator; // PDSCH to HARQ TI
     dci_payload.antenna_ports.val = 0;  // nb of cdm groups w/o data 1 and dmrs port 0
     dci_payload.dmrs_sequence_initialization.val = pdsch_pdu->SCID;
-    LOG_D(MAC,
+    LOG_D(NR_MAC,
           "%4d.%2d DCI type 1 payload: freq_alloc %d (%d,%d,%d), "
-          "time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n",
+          "time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d tpc %d\n",
           frame,
           slot,
           dci_payload.frequency_domain_assignment.val,
@@ -991,22 +1037,23 @@ void nr_schedule_ue_spec(module_id_t module_id,
           dci_payload.mcs,
           dci_payload.tb_scaling,
           dci_payload.ndi,
-          dci_payload.rv);
+          dci_payload.rv,
+          dci_payload.tpc);
 
     const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
-    const int dci_format = f ? NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0;
+    const int dci_format = bwp ? (f ? NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0) : NR_DL_DCI_FORMAT_1_0;
     const int rnti_type = NR_RNTI_C;
 
     fill_dci_pdu_rel15(scc,
-                       UE_info->secondaryCellGroup[UE_id],
+                       UE_info->CellGroup[UE_id],
                        dci_pdu,
                        &dci_payload,
                        dci_format,
                        rnti_type,
                        pdsch_pdu->BWPSize,
-                       bwp->bwp_Id);
+                       bwp? bwp->bwp_Id : 0);
 
-    LOG_D(MAC,
+    LOG_D(NR_MAC,
           "coreset params: FreqDomainResource %llx, start_symbol %d  n_symb %d\n",
           (unsigned long long)pdcch_pdu->FreqDomainResource,
           pdcch_pdu->StartSymbolIndex,
@@ -1016,7 +1063,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
       /* we do not have to do anything, since we do not require to get data
        * from RLC or encode MAC CEs. The TX_req structure is filled below 
        * or copy data to FAPI structures */
-      LOG_D(MAC,
+      LOG_D(NR_MAC,
             "%d.%2d DL retransmission UE %d/RNTI %04x HARQ PID %d round %d NDI %d\n",
             frame,
             slot,
@@ -1025,13 +1072,14 @@ void nr_schedule_ue_spec(module_id_t module_id,
             current_harq_pid,
             harq->round,
             harq->ndi);
+
       AssertFatal(harq->sched_pdsch.tb_size == TBS,
                   "UE %d mismatch between scheduled TBS and buffered TB for HARQ PID %d\n",
                   UE_id,
                   current_harq_pid);
     } else { /* initial transmission */
 
-      LOG_D(MAC, "[%s] Initial HARQ transmission in %d.%d\n", __FUNCTION__, frame, slot);
+      LOG_D(NR_MAC, "[%s] Initial HARQ transmission in %d.%d\n", __FUNCTION__, frame, slot);
 
       uint8_t *buf = (uint8_t *) harq->tb;
 
@@ -1047,7 +1095,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
 
       /* next, get RLC data */
 
-      const int lcid = DL_SCH_LCID_DTCH;
+      // const int lcid = DL_SCH_LCID_DTCH;
+      const int lcid = loop_dcch_dtch;
       int dlsch_total_bytes = 0;
       if (sched_ctrl->num_total_bytes > 0) {
         tbs_size_t len = 0;
@@ -1074,12 +1123,13 @@ void nr_schedule_ue_spec(module_id_t module_id,
                                  0,
                                  0);
 
-          LOG_D(MAC,
-                "%4d.%2d RNTI %04x: %d bytes from DTCH %d (ndata %d, remaining size %d)\n",
+          LOG_D(NR_MAC,
+                "%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %d)\n",
                 frame,
                 slot,
                 rnti,
                 len,
+                lcid < 4 ? "DCCH" : "DTCH",
                 lcid,
                 ndata,
                 size);
@@ -1108,7 +1158,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
         buf += 3;
         size -= 3;
         DevAssert(size > 0);
-        LOG_D(MAC, "Configuring DL_TX in %d.%d: TBS %d with %d B of random data\n", frame, slot, TBS, size);
+        LOG_D(NR_MAC, "Configuring DL_TX in %d.%d: TBS %d with %d B of random data\n", frame, slot, TBS, size);
         // fill dlsch_buffer with random data
         for (int i = 0; i < size; i++)
           buf[i] = lrand48() & 0xff;
@@ -1150,7 +1200,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
       if (sched_ctrl->ta_apply) {
         sched_ctrl->ta_apply = false;
         sched_ctrl->ta_frame = frame;
-        LOG_D(MAC,
+        LOG_D(NR_MAC,
               "%d.%2d UE %d TA scheduled, resetting TA frame\n",
               frame,
               slot,
@@ -1173,6 +1223,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
     gNB_mac->TX_req[CC_id].Slot = slot;
 
     /* mark UE as scheduled */
-    memset(sched_pdsch, 0, sizeof(*sched_pdsch));
+    sched_pdsch->rbSize = 0;
   }
 }
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 4986ed747dfdb586b28ab3c1a15c10bdd8dde27c..1dda52b56719cd6e0237da0ddd9068ecd423dcbb 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -271,10 +271,10 @@ void nr_preprocessor_phytest(module_id_t module_id,
 {
   if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot))
     return;
-  const int CC_id = 0;
-  const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon;
   NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
+  NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
   const int UE_id = 0;
+  const int CC_id = 0;
   AssertFatal(UE_info->active[UE_id],
               "%s(): expected UE %d to be active\n",
               __func__,
@@ -341,7 +341,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
               __func__,
               UE_id);
 
-  const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot);
+  const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1);
   if (alloc < 0) {
     LOG_D(MAC,
           "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
@@ -366,11 +366,11 @@ void nr_preprocessor_phytest(module_id_t module_id,
   sched_pdsch->pucch_allocation = alloc;
   sched_pdsch->rbStart = rbStart;
   sched_pdsch->rbSize = rbSize;
-  const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot];
+  const int tda = sched_ctrl->active_bwp ? RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot] : 1;
   const uint8_t num_dmrs_cdm_grps_no_data = 1;
   if (ps->time_domain_allocation != tda || ps->numDmrsCdmGrpsNoData != num_dmrs_cdm_grps_no_data)
     nr_set_pdsch_semi_static(
-        scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
+        scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
 
   sched_pdsch->mcs = target_dl_mcs;
   sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
@@ -416,7 +416,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
 
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
 
-  const int tda = RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot];
+  const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
   if (tda < 0)
     return false;
   const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
@@ -425,7 +425,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
               "time domain assignment %d >= %d\n",
               tda,
               tdaList->list.count);
-  int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu);
+  int K2 = get_K2(scc,sched_ctrl->active_ubwp, tda, mu);
   const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
   const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
   /* check if slot is UL, and that slot is 8 (assuming K2=6 because of UE
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 0ff413605714b78c4e789457236f8e9e6d17c4a5..958ceed323c6d0415b08439636b9b242a3567c33 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -122,15 +122,21 @@ static inline uint8_t get_max_cces(uint8_t scs) {
   return (nr_max_number_of_cces_per_slot[scs]);
 }
 
-NR_ControlResourceSet_t *get_coreset(const NR_BWP_Downlink_t *bwp, const NR_SearchSpace_t *ss, int ss_type)
-{
+NR_ControlResourceSet_t *get_coreset(NR_ServingCellConfigCommon_t *scc,
+                                     NR_BWP_Downlink_t *bwp,
+                                     NR_SearchSpace_t *ss,
+                                     NR_SearchSpace__searchSpaceType_PR ss_type) {
   NR_ControlResourceSetId_t coreset_id = *ss->controlResourceSetId;
-  if (ss_type == 0) { // common search space
-    AssertFatal(coreset_id != 0, "coreset0 currently not supported\n");
-    NR_ControlResourceSet_t *coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
-    AssertFatal(coreset_id == coreset->controlResourceSetId,
-                "ID of common ss coreset does not correspond to id set in the "
-                "search space\n");
+  if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { // common search space
+    NR_ControlResourceSet_t *coreset;
+    if (bwp) coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
+    else if (scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet)
+      coreset = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
+    else coreset = NULL;
+
+    if (coreset) AssertFatal(coreset_id == coreset->controlResourceSetId,
+			     "ID of common ss coreset does not correspond to id set in the "
+			     "search space\n");
     return coreset;
   } else {
     const int n = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count;
@@ -145,21 +151,24 @@ NR_ControlResourceSet_t *get_coreset(const NR_BWP_Downlink_t *bwp, const NR_Sear
   }
 }
 
-NR_SearchSpace_t *get_searchspace(const NR_BWP_Downlink_t *bwp, NR_SearchSpace__searchSpaceType_PR target_ss)
-{
-  DevAssert(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList);
-  DevAssert(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count > 0);
+NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc,
+				  NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
+				  NR_SearchSpace__searchSpaceType_PR target_ss) {
 
-  const int n = bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;
+  const int n = bwp_Dedicated ?
+    bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count:
+    scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count;
   for (int i=0;i<n;i++) {
-    NR_SearchSpace_t *ss = bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
+    NR_SearchSpace_t *ss = bwp_Dedicated ?
+      bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]:
+      scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i];
     AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n");
     AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n");
     if (ss->searchSpaceType->present == target_ss) {
       return ss;
     }
   }
-  AssertFatal(0, "Couldn't find an adequate searchspace\n");
+  AssertFatal(0, "Couldn't find an adequate searchspace bwp_Dedicated %p\n",bwp_Dedicated);
 }
 
 int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
@@ -176,8 +185,8 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
   int coreset_id = coreset->controlResourceSetId;
 
   int *cce_list;
-  if( bwp==NULL || bwp->bwp_Id == 0 ) {
-    cce_list = nr_mac->cce_list[1][0];
+  if(bwp == NULL || bwp->bwp_Id == 0) {
+    cce_list = nr_mac->cce_list[0][0];
   } else {
     cce_list = nr_mac->cce_list[bwp->bwp_Id][coreset_id];
   }
@@ -265,36 +274,35 @@ void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
 {
   ps->time_domain_allocation = tda;
 
-  const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
-      bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+  const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = bwp ?
+      bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList :
+      scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
   AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count);
   const int mapping_type = tdaList->list.array[tda]->mappingType;
   const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
   SLIV2SL(startSymbolAndLength, &ps->startSymbolIndex, &ps->nrOfSymbols);
 
-  if (!secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup
-           ->mcs_Table)
-    ps->mcsTableIdx = 0;
-  else if (*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup
-                ->mcs_Table
-           == 0)
-    ps->mcsTableIdx = 1;
-  else
-    ps->mcsTableIdx = 2;
+  ps->mcsTableIdx = 0;
+  if (bwp &&
+      bwp->bwp_Dedicated &&
+      bwp->bwp_Dedicated->pdsch_Config &&
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup &&
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table) {
+    if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0)
+      ps->mcsTableIdx = 1;
+    else
+      ps->mcsTableIdx = 2;
+  }
+  else ps->mcsTableIdx = 0;
 
   ps->numDmrsCdmGrpsNoData = num_dmrs_cdm_grps_no_data;
-  ps->dmrsConfigType =
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type
-              == NULL
-          ? 0
-          : 1;
+  ps->dmrsConfigType = bwp!=NULL ? (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0;
+
   // if no data in dmrs cdm group is 1 only even REs have no data
   // if no data in dmrs cdm group is 2 both odd and even REs have no data
   ps->N_PRB_DMRS = num_dmrs_cdm_grps_no_data * (ps->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4);
-  ps->N_DMRS_SLOT =
-      get_num_dmrs_symbols(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, ps->nrOfSymbols, ps->startSymbolIndex, mapping_type);
-  ps->dl_dmrs_symb_pos =
-      fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, ps->nrOfSymbols, ps->startSymbolIndex, mapping_type);
+  ps->dl_dmrs_symb_pos = fill_dmrs_mask(bwp ? bwp->bwp_Dedicated->pdsch_Config->choice.setup : NULL, scc->dmrs_TypeA_Position, ps->nrOfSymbols, ps->startSymbolIndex, mapping_type);
+  ps->N_DMRS_SLOT = get_num_dmrs(ps->dl_dmrs_symb_pos);
 }
 
 void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc,
@@ -308,27 +316,29 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc,
   ps->time_domain_allocation = tda;
 
   const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
-      ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+    ubwp?
+    ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
+    scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList ;
   const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
   SLIV2SL(startSymbolAndLength,
           &ps->startSymbolIndex,
           &ps->nrOfSymbols);
 
-  ps->pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup;
-  if (!ps->pusch_Config->transformPrecoder)
+  ps->pusch_Config = ubwp?ubwp->bwp_Dedicated->pusch_Config->choice.setup:NULL;
+  if (ps->pusch_Config == NULL || !ps->pusch_Config->transformPrecoder)
     ps->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder;
   else
     ps->transform_precoding = *ps->pusch_Config->transformPrecoder;
   const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
   if (ps->transform_precoding)
-    ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config->mcs_Table,
+    ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config ? ps->pusch_Config->mcs_Table : NULL,
                                     0,
                                     ps->dci_format,
                                     NR_RNTI_C,
                                     target_ss,
                                     false);
   else {
-    ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config->mcs_TableTransformPrecoder,
+    ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config ? ps->pusch_Config->mcs_TableTransformPrecoder : NULL,
                                     1,
                                     ps->dci_format,
                                     NR_RNTI_C,
@@ -341,20 +351,20 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc,
 
   /* DMRS calculations */
   ps->mapping_type = tdaList->list.array[tda]->mappingType;
-  ps->NR_DMRS_UplinkConfig =
-      ps->mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA
-          ? ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup
-          : ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
-  ps->dmrs_config_type = ps->NR_DMRS_UplinkConfig->dmrs_Type == NULL ? 0 : 1;
+  ps->NR_DMRS_UplinkConfig = ps->pusch_Config ?
+    (ps->mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA ?
+     ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup :
+     ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup) : NULL;
+  ps->dmrs_config_type = ps->NR_DMRS_UplinkConfig ? ((ps->NR_DMRS_UplinkConfig->dmrs_Type == NULL ? 0 : 1)) : 0;
   const pusch_dmrs_AdditionalPosition_t additional_pos =
-      ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL
-          ? 2
-          : (*ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition ==
-                     NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3
-                 ? 3
-                 : *ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition);
+						     ps->NR_DMRS_UplinkConfig ? (ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL
+										 ? 2
+										 : (*ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition ==
+										    NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3
+										    ? 3
+										    : *ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition)):2;
   const pusch_maxLength_t pusch_maxLength =
-      ps->NR_DMRS_UplinkConfig->maxLength == NULL ? 1 : 2;
+    ps->NR_DMRS_UplinkConfig ? (ps->NR_DMRS_UplinkConfig->maxLength == NULL ? 1 : 2) : 1;
   ps->ul_dmrs_symb_pos = get_l_prime(ps->nrOfSymbols,
                                             ps->mapping_type,
                                             additional_pos,
@@ -589,6 +599,7 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
 }
 
 void config_uldci(const NR_BWP_Uplink_t *ubwp,
+		              const NR_ServingCellConfigCommon_t *scc,
                   const nfapi_nr_pusch_pdu_t *pusch_pdu,
                   dci_pdu_rel15_t *dci_pdu_rel15,
                   int dci_format,
@@ -596,7 +607,9 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp,
                   uint8_t tpc,
                   int n_ubwp,
                   int bwp_id) {
-  const int bw = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  const int bw = NRRIV2BW(ubwp ?
+			  ubwp->bwp_Common->genericParameters.locationAndBandwidth :
+			  scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
   dci_pdu_rel15->frequency_domain_assignment.val =
       PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw);
   dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment;
@@ -606,8 +619,8 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp,
   dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index;
   dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id;
   dci_pdu_rel15->tpc = tpc;
-  AssertFatal(ubwp->bwp_Dedicated->pusch_Config->choice.setup->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1,
-              "Only frequency resource allocation type 1 is currently supported\n");
+  if (ubwp) AssertFatal(ubwp->bwp_Dedicated->pusch_Config->choice.setup->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1,
+			"Only frequency resource allocation type 1 is currently supported\n");
   switch (dci_format) {
     case NR_UL_DCI_FORMAT_0_0:
       dci_pdu_rel15->format_indicator = 0;
@@ -617,7 +630,11 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp,
       // bwp indicator as per table 7.3.1.1.2-1 in 38.212
       dci_pdu_rel15->bwp_indicator.val = n_ubwp < 4 ? bwp_id : bwp_id - 1;
       // SRS resource indicator
-      if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig != NULL) {
+      if (ubwp &&
+          ubwp->bwp_Dedicated &&
+          ubwp->bwp_Dedicated->pusch_Config &&
+          ubwp->bwp_Dedicated->pusch_Config->choice.setup &&
+          ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig != NULL) {
         AssertFatal(*ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig == NR_PUSCH_Config__txConfig_codebook,
                     "Non Codebook configuration non supported\n");
         dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS
@@ -631,8 +648,8 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp,
       AssertFatal(0, "Valid UL formats are 0_0 and 0_1\n");
   }
 
-  LOG_D(MAC,
-        "%s() ULDCI type 0 payload: freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d UL_BWP_ID %d\n",
+  LOG_D(NR_MAC,
+        "%s() ULDCI type 0 payload: freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n",
         __func__,
         dci_pdu_rel15->frequency_domain_assignment.val,
         dci_pdu_rel15->time_domain_assignment.val,
@@ -644,90 +661,93 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp,
         dci_pdu_rel15->bwp_indicator.val);
 }
 
+const int default_pucch_fmt[]       = {0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1};
+const int default_pucch_firstsymb[] = {12,12,12,10,10,10,10,4,4,4,4,0,0,0,0,0};
+const int default_pucch_numbsymb[]  = {2,2,2,2,4,4,4,4,10,10,10,10,14,14,14,14,14};
+const int default_pucch_prboffset[] = {0,0,3,0,0,2,4,0,0,2,4,0,0,2,4,-1};
+const int default_pucch_csset[]     = {2,3,3,2,4,4,4,2,4,4,4,2,4,4,4,4};
+
+int nr_get_default_pucch_res(int pucch_ResourceCommon) {
+
+  AssertFatal(pucch_ResourceCommon>=0 && pucch_ResourceCommon < 16, "illegal pucch_ResourceCommon %d\n",pucch_ResourceCommon);
+
+  return(default_pucch_csset[pucch_ResourceCommon]);
+}
 void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
                         NR_SearchSpace_t *ss,
                         NR_ControlResourceSet_t *coreset,
                         NR_ServingCellConfigCommon_t *scc,
                         NR_BWP_Downlink_t *bwp)
 {
-  int sps = 0;
+  NR_BWP_t *genericParameters = bwp ? &bwp->bwp_Common->genericParameters : &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
 
-  if (bwp) { // This is not the InitialBWP
-    pdcch_pdu->BWPSize  = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    pdcch_pdu->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
-    pdcch_pdu->CyclicPrefix = (bwp->bwp_Common->genericParameters.cyclicPrefix==NULL) ? 0 : *bwp->bwp_Common->genericParameters.cyclicPrefix;
+  pdcch_pdu->BWPSize  = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+  pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+  pdcch_pdu->SubcarrierSpacing = genericParameters->subcarrierSpacing;
+  pdcch_pdu->CyclicPrefix = genericParameters->cyclicPrefix ? *genericParameters->cyclicPrefix:0;
 
-    // first symbol
-    //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored");
-    sps = bwp->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
-  }
-  else { // this is for InitialBWP
-    pdcch_pdu->BWPSize  = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    pdcch_pdu->SubcarrierSpacing = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing;
-    pdcch_pdu->CyclicPrefix = (scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix==NULL) ? 0 : *scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix;
-
-    // first symbol
-    //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored");
-    sps = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12;
-  }
-    AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n");
-    AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n");
-    
-    // for SPS=14 8 MSBs in positions 13 downto 6
-    uint16_t monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) |
-      (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
-
-    for (int i=0; i<sps; i++) {
-      if ((monitoringSymbolsWithinSlot>>(sps-1-i))&1) {
-	pdcch_pdu->StartSymbolIndex=i;
-	break;
-      }
-    }
+  // first symbol
+  //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored");
+  int sps = genericParameters->cyclicPrefix == NULL ? 14 : 12;
 
-    pdcch_pdu->DurationSymbols  = coreset->duration;
-    
-    for (int i=0;i<6;i++)
-      pdcch_pdu->FreqDomainResource[i] = coreset->frequencyDomainResources.buf[i];
+  AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n");
+  AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n");
 
-    
-    //cce-REG-MappingType
-    pdcch_pdu->CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved?
-      NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED : NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED;
-
-    if (pdcch_pdu->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
-      pdcch_pdu->RegBundleSize = (coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize);
-      pdcch_pdu->InterleaverSize = (coreset->cce_REG_MappingType.choice.interleaved->interleaverSize==NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->interleaverSize);
-      AssertFatal(scc->physCellId != NULL,"scc->physCellId is null\n");
-      pdcch_pdu->ShiftIndex = coreset->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *coreset->cce_REG_MappingType.choice.interleaved->shiftIndex : *scc->physCellId;
-    }
-    else {
-      pdcch_pdu->RegBundleSize = 0;
-      pdcch_pdu->InterleaverSize = 0;
-      pdcch_pdu->ShiftIndex = 0;
-    }
+  // for SPS=14 8 MSBs in positions 13 downto 6
+  uint16_t monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) |
+    (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
 
-    if(coreset->controlResourceSetId == 0) {
-      pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
-    } else{
-      pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
+  for (int i=0; i<sps; i++) {
+    if ((monitoringSymbolsWithinSlot>>(sps-1-i))&1) {
+      pdcch_pdu->StartSymbolIndex=i;
+      break;
     }
+  }
 
-    //precoderGranularity
-    pdcch_pdu->precoderGranularity = coreset->precoderGranularity;
+  pdcch_pdu->DurationSymbols  = coreset->duration;
+
+  for (int i=0;i<6;i++)
+    pdcch_pdu->FreqDomainResource[i] = coreset->frequencyDomainResources.buf[i];
+
+
+  //cce-REG-MappingType
+  pdcch_pdu->CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved?
+    NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED : NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED;
+
+  if (pdcch_pdu->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
+    pdcch_pdu->RegBundleSize = (coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize);
+    pdcch_pdu->InterleaverSize = (coreset->cce_REG_MappingType.choice.interleaved->interleaverSize==NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->interleaverSize);
+    AssertFatal(scc->physCellId != NULL,"scc->physCellId is null\n");
+    pdcch_pdu->ShiftIndex = coreset->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *coreset->cce_REG_MappingType.choice.interleaved->shiftIndex : *scc->physCellId;
+  }
+  else {
+    pdcch_pdu->RegBundleSize = 0;
+    pdcch_pdu->InterleaverSize = 0;
+    pdcch_pdu->ShiftIndex = 0;
+  }
+
+  if(coreset->controlResourceSetId == 0) {
+    pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
+  } else{
+    pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
+  }
+
+  //precoderGranularity
+  pdcch_pdu->precoderGranularity = coreset->precoderGranularity;
 }
 
 
 // This function configures pucch pdu fapi structure
 void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
-			NR_ServingCellConfigCommon_t *scc,
-			NR_BWP_Uplink_t *bwp,
+			                  NR_ServingCellConfigCommon_t *scc,
+			                  NR_CellGroupConfig_t *CellGroup,
+			                  NR_BWP_Uplink_t *bwp,
                         uint16_t rnti,
                         uint8_t pucch_resource,
                         uint16_t O_csi,
                         uint16_t O_ack,
-                        uint8_t O_sr) {
+                        uint8_t O_sr,
+			                  int r_pucch) {
 
   NR_PUCCH_Config_t *pucch_Config;
   NR_PUCCH_Resource_t *pucchres;
@@ -745,208 +765,234 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
 
   uint16_t O_uci = O_csi + O_ack;
 
-  if (bwp) { // This is not the InitialBWP
-
-    NR_PUSCH_Config_t *pusch_Config = bwp->bwp_Dedicated->pusch_Config->choice.setup;
-    long *pusch_id = pusch_Config->dataScramblingIdentityPUSCH;
-
-    if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL)
-      id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->transformPrecodingDisabled->scramblingID0;
-    if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB != NULL)
-      id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->transformPrecodingDisabled->scramblingID0;
-
-    // hop flags and hopping id are valid for any BWP
-    switch (bwp->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_GroupHopping){
-      case 0 :
-        // if neither, both disabled
-        pucch_pdu->group_hop_flag = 0;
-        pucch_pdu->sequence_hop_flag = 0;
-        break;
-      case 1 :
-        // if enable, group enabled
-        pucch_pdu->group_hop_flag = 1;
-        pucch_pdu->sequence_hop_flag = 0;
-        break;
-      case 2 :
-        // if disable, sequence disabled
-        pucch_pdu->group_hop_flag = 0;
-        pucch_pdu->sequence_hop_flag = 1;
-        break;
-      default:
-        AssertFatal(1==0,"Group hopping flag %ld undefined (0,1,2) \n", bwp->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_GroupHopping);
-    }
+  NR_PUSCH_Config_t *pusch_Config = bwp ? bwp->bwp_Dedicated->pusch_Config->choice.setup : NULL;
+  long *pusch_id = bwp ? pusch_Config->dataScramblingIdentityPUSCH : NULL;
+
+  if (bwp && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL)
+    id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->transformPrecodingDisabled->scramblingID0;
+  else if (bwp && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB != NULL)
+    id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->transformPrecodingDisabled->scramblingID0;
+  else id0 = scc->physCellId;
+
+  NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon = bwp ?
+    bwp->bwp_Common->pucch_ConfigCommon->choice.setup :
+    scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup;
+  // hop flags and hopping id are valid for any BWP
+  switch (pucch_ConfigCommon->pucch_GroupHopping){
+  case 0 :
+    // if neither, both disabled
+    pucch_pdu->group_hop_flag = 0;
+    pucch_pdu->sequence_hop_flag = 0;
+    break;
+  case 1 :
+    // if enable, group enabled
+    pucch_pdu->group_hop_flag = 1;
+    pucch_pdu->sequence_hop_flag = 0;
+    break;
+  case 2 :
+    // if disable, sequence disabled
+    pucch_pdu->group_hop_flag = 0;
+    pucch_pdu->sequence_hop_flag = 1;
+    break;
+  default:
+    AssertFatal(1==0,"Group hopping flag %ld undefined (0,1,2) \n", bwp->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_GroupHopping);
+  }
 
-    if (bwp->bwp_Common->pucch_ConfigCommon->choice.setup->hoppingId != NULL)
-      pucch_pdu->hopping_id = *bwp->bwp_Common->pucch_ConfigCommon->choice.setup->hoppingId;
-    else
-      pucch_pdu->hopping_id = *scc->physCellId;
-
-    pucch_pdu->bwp_size  = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    pucch_pdu->bwp_start = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    pucch_pdu->subcarrier_spacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
-    pucch_pdu->cyclic_prefix = (bwp->bwp_Common->genericParameters.cyclicPrefix==NULL) ? 0 : *bwp->bwp_Common->genericParameters.cyclicPrefix;
-
-    pucch_Config = bwp->bwp_Dedicated->pucch_Config->choice.setup;
-
-    AssertFatal(pucch_Config->resourceSetToAddModList!=NULL,
-		"PUCCH resourceSetToAddModList is null\n");
-
-    n_set = pucch_Config->resourceSetToAddModList->list.count; 
-    AssertFatal(n_set>0,"PUCCH resourceSetToAddModList is empty\n");
-
-    LOG_D(MAC, "UCI n_set= %d\n", n_set);
-
-    N2 = 2;
-    // procedure to select pucch resource id from resource sets according to 
-    // number of uci bits and pucch resource indicator pucch_resource
-    // ( see table 9.2.3.2 in 38.213)
-    for (int i=0; i<n_set; i++) {
-      pucchresset = pucch_Config->resourceSetToAddModList->list.array[i];
-      n_list = pucchresset->resourceList.list.count;
-      if (pucchresset->pucch_ResourceSetId == 0 && O_uci<3) {
-        if (pucch_resource < n_list)
-          resource_id = pucchresset->resourceList.list.array[pucch_resource];
-        else 
-          AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci);
-      }
-      if (pucchresset->pucch_ResourceSetId == 1 && O_uci>2) {
+  if (pucch_ConfigCommon->hoppingId != NULL)
+    pucch_pdu->hopping_id = *pucch_ConfigCommon->hoppingId;
+  else
+    pucch_pdu->hopping_id = *scc->physCellId;
+  NR_BWP_t *genericParameters = bwp ?
+    &bwp->bwp_Common->genericParameters:
+    &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
+  pucch_pdu->bwp_size  = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+  pucch_pdu->bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
+  pucch_pdu->subcarrier_spacing = genericParameters->subcarrierSpacing;
+  pucch_pdu->cyclic_prefix = (genericParameters->cyclicPrefix==NULL) ? 0 : *genericParameters->cyclicPrefix;
+  if (r_pucch<0 || bwp){
+    // we have either a dedicated BWP or Dedicated PUCCH configuration on InitialBWP
+	pucch_Config = bwp ?
+	  bwp->bwp_Dedicated->pucch_Config->choice.setup:
+	  CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
+
+	AssertFatal(pucch_Config->resourceSetToAddModList!=NULL,
+		    "PUCCH resourceSetToAddModList is null\n");
+
+	n_set = pucch_Config->resourceSetToAddModList->list.count;
+	AssertFatal(n_set>0,"PUCCH resourceSetToAddModList is empty\n");
+
+	LOG_D(NR_MAC, "UCI n_set= %d\n", n_set);
+
+	N2 = 2;
+	// procedure to select pucch resource id from resource sets according to
+	// number of uci bits and pucch resource indicator pucch_resource
+	// ( see table 9.2.3.2 in 38.213)
+	for (int i=0; i<n_set; i++) {
+	  pucchresset = pucch_Config->resourceSetToAddModList->list.array[i];
+	  n_list = pucchresset->resourceList.list.count;
+	  if (pucchresset->pucch_ResourceSetId == 0 && O_uci<3) {
+	    if (pucch_resource < n_list)
+	      resource_id = pucchresset->resourceList.list.array[pucch_resource];
+	    else
+	      AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci);
+	  }
+	  if (pucchresset->pucch_ResourceSetId == 1 && O_uci>2) {
 #if (NR_RRC_VERSION >= MAKE_VERSION(16, 0, 0))
-        N3 = pucchresset->maxPayloadSize!= NULL ?  *pucchresset->maxPayloadSize : 1706;
+	    N3 = pucchresset->maxPayloadSize!= NULL ?  *pucchresset->maxPayloadSize : 1706;
 #else
-        N3 = pucchresset->maxPayloadMinus1!= NULL ?  *pucchresset->maxPayloadMinus1 : 1706;
+	    N3 = pucchresset->maxPayloadMinus1!= NULL ?  *pucchresset->maxPayloadMinus1 : 1706;
 #endif
-        if (N2<O_uci && N3>O_uci) {
-          if (pucch_resource < n_list)
-            resource_id = pucchresset->resourceList.list.array[pucch_resource];
-          else 
-            AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci);
-        }
-        else N2 = N3;
+	    if (N2<O_uci && N3>O_uci) {
+	      if (pucch_resource < n_list)
+		resource_id = pucchresset->resourceList.list.array[pucch_resource];
+	      else
+		AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci);
+	    }
+	    else N2 = N3;
+	  }
+	}
+
+	AssertFatal(resource_id!=NULL,"Couldn-t find any matching PUCCH resource in the PUCCH resource sets");
+
+	AssertFatal(pucch_Config->resourceToAddModList!=NULL,
+		    "PUCCH resourceToAddModList is null\n");
+
+	n_list = pucch_Config->resourceToAddModList->list.count;
+	AssertFatal(n_list>0,"PUCCH resourceToAddModList is empty\n");
+
+	// going through the list of PUCCH resources to find the one indexed by resource_id
+	for (int i=0; i<n_list; i++) {
+	  pucchres = pucch_Config->resourceToAddModList->list.array[i];
+	  if (pucchres->pucch_ResourceId == *resource_id) {
+	    res_found = 1;
+	    pucch_pdu->prb_start = pucchres->startingPRB;
+	    pucch_pdu->rnti = rnti;
+	    // FIXME why there is only one frequency hopping flag
+	    // what about inter slot frequency hopping?
+	    pucch_pdu->freq_hop_flag = pucchres->intraSlotFrequencyHopping!= NULL ?  1 : 0;
+	    pucch_pdu->second_hop_prb = pucchres->secondHopPRB!= NULL ?  *pucchres->secondHopPRB : 0;
+	    switch(pucchres->format.present) {
+	    case NR_PUCCH_Resource__format_PR_format0 :
+	      pucch_pdu->format_type = 0;
+	      pucch_pdu->initial_cyclic_shift = pucchres->format.choice.format0->initialCyclicShift;
+	      pucch_pdu->nr_of_symbols = pucchres->format.choice.format0->nrofSymbols;
+	      pucch_pdu->start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex;
+	      pucch_pdu->sr_flag = O_sr;
+	      break;
+	    case NR_PUCCH_Resource__format_PR_format1 :
+	      pucch_pdu->format_type = 1;
+	      pucch_pdu->initial_cyclic_shift = pucchres->format.choice.format1->initialCyclicShift;
+	      pucch_pdu->nr_of_symbols = pucchres->format.choice.format1->nrofSymbols;
+	      pucch_pdu->start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex;
+	      pucch_pdu->time_domain_occ_idx = pucchres->format.choice.format1->timeDomainOCC;
+	      pucch_pdu->sr_flag = O_sr;
+	      break;
+	    case NR_PUCCH_Resource__format_PR_format2 :
+	      pucch_pdu->format_type = 2;
+	      pucch_pdu->nr_of_symbols = pucchres->format.choice.format2->nrofSymbols;
+	      pucch_pdu->start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex;
+	      pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId;
+	      pucch_pdu->dmrs_scrambling_id = id0!= NULL ? *id0 : *scc->physCellId;
+	      pucch_pdu->prb_size = compute_pucch_prb_size(2,pucchres->format.choice.format2->nrofPRBs,
+							   O_uci+O_sr,O_csi,pucch_Config->format2->choice.setup->maxCodeRate,
+							   2,pucchres->format.choice.format2->nrofSymbols,8);
+	      pucch_pdu->bit_len_csi_part1 = O_csi;
+	      break;
+	    case NR_PUCCH_Resource__format_PR_format3 :
+	      pucch_pdu->format_type = 3;
+	      pucch_pdu->nr_of_symbols = pucchres->format.choice.format3->nrofSymbols;
+	      pucch_pdu->start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex;
+	      pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId;
+	      if (pucch_Config->format3 == NULL) {
+		pucch_pdu->pi_2bpsk = 0;
+		pucch_pdu->add_dmrs_flag = 0;
+	      }
+	      else {
+		pucchfmt = pucch_Config->format3->choice.setup;
+		pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ?  1 : 0;
+		pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ?  1 : 0;
+	      }
+	      int f3_dmrs_symbols;
+	      if (pucchres->format.choice.format3->nrofSymbols==4)
+		f3_dmrs_symbols = 1<<pucch_pdu->freq_hop_flag;
+	      else {
+		if(pucchres->format.choice.format3->nrofSymbols<10)
+		  f3_dmrs_symbols = 2;
+		else
+		  f3_dmrs_symbols = 2<<pucch_pdu->add_dmrs_flag;
+	      }
+	      pucch_pdu->prb_size = compute_pucch_prb_size(3,pucchres->format.choice.format3->nrofPRBs,
+							   O_uci+O_sr,O_csi,pucch_Config->format3->choice.setup->maxCodeRate,
+							   2-pucch_pdu->pi_2bpsk,pucchres->format.choice.format3->nrofSymbols-f3_dmrs_symbols,12);
+	      pucch_pdu->bit_len_csi_part1 = O_csi;
+	      break;
+	    case NR_PUCCH_Resource__format_PR_format4 :
+	      pucch_pdu->format_type = 4;
+	      pucch_pdu->nr_of_symbols = pucchres->format.choice.format4->nrofSymbols;
+	      pucch_pdu->start_symbol_index = pucchres->format.choice.format4->startingSymbolIndex;
+	      pucch_pdu->pre_dft_occ_len = pucchres->format.choice.format4->occ_Length;
+	      pucch_pdu->pre_dft_occ_idx = pucchres->format.choice.format4->occ_Index;
+	      pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId;
+	      if (pucch_Config->format3 == NULL) {
+		pucch_pdu->pi_2bpsk = 0;
+		pucch_pdu->add_dmrs_flag = 0;
+	      }
+	      else {
+		pucchfmt = pucch_Config->format3->choice.setup;
+		pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ?  1 : 0;
+		pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ?  1 : 0;
+	      }
+	      pucch_pdu->bit_len_csi_part1 = O_csi;
+	      break;
+	    default :
+	      AssertFatal(1==0,"Undefined PUCCH format \n");
+	    }
+	  }
+	}
+	AssertFatal(res_found==1,"No PUCCH resource found corresponding to id %ld\n",*resource_id);
       }
-    }
-
-    AssertFatal(resource_id!=NULL,"Couldn-t find any matching PUCCH resource in the PUCCH resource sets");
-
-    AssertFatal(pucch_Config->resourceToAddModList!=NULL,
-		"PUCCH resourceToAddModList is null\n");
-
-    n_list = pucch_Config->resourceToAddModList->list.count; 
-    AssertFatal(n_list>0,"PUCCH resourceToAddModList is empty\n");
-
-    // going through the list of PUCCH resources to find the one indexed by resource_id
-    for (int i=0; i<n_list; i++) {
-      pucchres = pucch_Config->resourceToAddModList->list.array[i];
-      if (pucchres->pucch_ResourceId == *resource_id) {
-        res_found = 1;
-        pucch_pdu->prb_start = pucchres->startingPRB;
-        pucch_pdu->rnti = rnti;
-        // FIXME why there is only one frequency hopping flag
-        // what about inter slot frequency hopping?
-        pucch_pdu->freq_hop_flag = pucchres->intraSlotFrequencyHopping!= NULL ?  1 : 0;
-        pucch_pdu->second_hop_prb = pucchres->secondHopPRB!= NULL ?  *pucchres->secondHopPRB : 0;
-        switch(pucchres->format.present) {
-          case NR_PUCCH_Resource__format_PR_format0 :
-            pucch_pdu->format_type = 0;
-            pucch_pdu->initial_cyclic_shift = pucchres->format.choice.format0->initialCyclicShift;
-            pucch_pdu->nr_of_symbols = pucchres->format.choice.format0->nrofSymbols;
-            pucch_pdu->start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex;
-            pucch_pdu->sr_flag = O_sr;
-            break;
-          case NR_PUCCH_Resource__format_PR_format1 :
-            pucch_pdu->format_type = 1;
-            pucch_pdu->initial_cyclic_shift = pucchres->format.choice.format1->initialCyclicShift;
-            pucch_pdu->nr_of_symbols = pucchres->format.choice.format1->nrofSymbols;
-            pucch_pdu->start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex;
-            pucch_pdu->time_domain_occ_idx = pucchres->format.choice.format1->timeDomainOCC;
-            pucch_pdu->sr_flag = O_sr;
-            break;
-          case NR_PUCCH_Resource__format_PR_format2 :
-            pucch_pdu->format_type = 2;
-            pucch_pdu->nr_of_symbols = pucchres->format.choice.format2->nrofSymbols;
-            pucch_pdu->start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex;
-            pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId;
-            pucch_pdu->dmrs_scrambling_id = id0!= NULL ? *id0 : *scc->physCellId;
-            pucch_pdu->prb_size = compute_pucch_prb_size(2,pucchres->format.choice.format2->nrofPRBs,
-                                                         O_uci+O_sr,O_csi,pucch_Config->format2->choice.setup->maxCodeRate,
-                                                         2,pucchres->format.choice.format2->nrofSymbols,8);
-            pucch_pdu->bit_len_csi_part1 = O_csi;
-            break;
-          case NR_PUCCH_Resource__format_PR_format3 :
-            pucch_pdu->format_type = 3;
-            pucch_pdu->nr_of_symbols = pucchres->format.choice.format3->nrofSymbols;
-            pucch_pdu->start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex;
-            pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId;
-            if (pucch_Config->format3 == NULL) {
-              pucch_pdu->pi_2bpsk = 0;
-              pucch_pdu->add_dmrs_flag = 0;
-            }
-            else {
-              pucchfmt = pucch_Config->format3->choice.setup;
-              pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ?  1 : 0;
-              pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ?  1 : 0;
-            }
-            int f3_dmrs_symbols;
-            if (pucchres->format.choice.format3->nrofSymbols==4)
-              f3_dmrs_symbols = 1<<pucch_pdu->freq_hop_flag;
-            else {
-              if(pucchres->format.choice.format3->nrofSymbols<10)
-                f3_dmrs_symbols = 2;
-              else
-                f3_dmrs_symbols = 2<<pucch_pdu->add_dmrs_flag;
-            }
-            pucch_pdu->prb_size = compute_pucch_prb_size(3,pucchres->format.choice.format3->nrofPRBs,
-                                                         O_uci+O_sr,O_csi,pucch_Config->format3->choice.setup->maxCodeRate,
-                                                         2-pucch_pdu->pi_2bpsk,pucchres->format.choice.format3->nrofSymbols-f3_dmrs_symbols,12);
-            pucch_pdu->bit_len_csi_part1 = O_csi;
-            break;
-          case NR_PUCCH_Resource__format_PR_format4 :
-            pucch_pdu->format_type = 4;
-            pucch_pdu->nr_of_symbols = pucchres->format.choice.format4->nrofSymbols;
-            pucch_pdu->start_symbol_index = pucchres->format.choice.format4->startingSymbolIndex;
-            pucch_pdu->pre_dft_occ_len = pucchres->format.choice.format4->occ_Length;
-            pucch_pdu->pre_dft_occ_idx = pucchres->format.choice.format4->occ_Index;
-            pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId;
-            if (pucch_Config->format3 == NULL) {
-              pucch_pdu->pi_2bpsk = 0;
-              pucch_pdu->add_dmrs_flag = 0;
-            }
-            else {
-              pucchfmt = pucch_Config->format3->choice.setup;
-              pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ?  1 : 0;
-              pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ?  1 : 0;
-            }
-            pucch_pdu->bit_len_csi_part1 = O_csi;
-            break;
-          default :
-            AssertFatal(1==0,"Undefined PUCCH format \n");
-        }
+      else { // this is the default PUCCH configuration, PUCCH format 0 or 1
+	int rsetindex = *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon;
+	int prboffset = r_pucch/default_pucch_csset[rsetindex];
+	int prboffsetm8 = (r_pucch-8)/default_pucch_csset[rsetindex];
+	pucch_pdu->prb_start = (r_pucch>>3)==0 ?
+	  default_pucch_prboffset[rsetindex] + prboffset:
+	  pucch_pdu->bwp_size-1-default_pucch_prboffset[rsetindex]-prboffsetm8;
+	pucch_pdu->rnti = rnti;
+	pucch_pdu->freq_hop_flag = 1;
+	pucch_pdu->second_hop_prb = (r_pucch>>3)==0?
+	  pucch_pdu->bwp_size-1-default_pucch_prboffset[rsetindex]-prboffset:
+	  default_pucch_prboffset[rsetindex] + prboffsetm8;
+	pucch_pdu->format_type = default_pucch_fmt[rsetindex];
+	pucch_pdu->initial_cyclic_shift = r_pucch%default_pucch_csset[rsetindex];
+	if (rsetindex==3||rsetindex==7||rsetindex==11) pucch_pdu->initial_cyclic_shift*=6;
+	else if (rsetindex==1||rsetindex==2) pucch_pdu->initial_cyclic_shift*=3;
+	else pucch_pdu->initial_cyclic_shift*=4;
+	pucch_pdu->nr_of_symbols = default_pucch_numbsymb[rsetindex];
+	pucch_pdu->start_symbol_index = default_pucch_firstsymb[rsetindex];
+	if (pucch_pdu->format_type == 1) pucch_pdu->time_domain_occ_idx = 0; // check this!!
+	pucch_pdu->sr_flag = O_sr;
       }
-    }
-    AssertFatal(res_found==1,"No PUCCH resource found corresponding to id %ld\n",*resource_id);
-  }  
-  else { // this is for InitialBWP
-    AssertFatal(1==0,"Fill in InitialBWP PUCCH configuration\n");
-  }
 
 }
 
 
-void prepare_dci(const NR_CellGroupConfig_t *secondaryCellGroup,
+void prepare_dci(const NR_CellGroupConfig_t *CellGroup,
                  dci_pdu_rel15_t *dci_pdu_rel15,
                  nr_dci_format_t format,
                  int bwp_id) {
 
-  NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
+  NR_BWP_Downlink_t *bwp=CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
 
   switch(format) {
     case NR_UL_DCI_FORMAT_0_1:
       // format indicator
       dci_pdu_rel15->format_indicator = 0;
       // carrier indicator
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL)
+      if (CellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL)
         AssertFatal(1==0,"Cross Carrier Scheduling Config currently not supported\n");
       // supplementary uplink
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->supplementaryUplink != NULL)
+      if (CellGroup->spCellConfig->spCellConfigDedicated->supplementaryUplink != NULL)
         AssertFatal(1==0,"Supplementary Uplink currently not supported\n");
       // SRS request
       dci_pdu_rel15->srs_request.val = 0;
@@ -956,7 +1002,7 @@ void prepare_dci(const NR_CellGroupConfig_t *secondaryCellGroup,
       // format indicator
       dci_pdu_rel15->format_indicator = 1;
       // carrier indicator
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL)
+      if (CellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL)
         AssertFatal(1==0,"Cross Carrier Scheduling Config currently not supported\n");
       //vrb to prb mapping
       if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->vrb_ToPRB_Interleaver==NULL)
@@ -978,8 +1024,8 @@ void prepare_dci(const NR_CellGroupConfig_t *secondaryCellGroup,
       if (bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[corset_id-1]->tci_PresentInDCI != NULL)
         AssertFatal(1==0,"TCI in DCI currently not supported\n");
       //srs resource set
-      if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->carrierSwitching!=NULL) {
-        NR_SRS_CarrierSwitching_t *cs = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->carrierSwitching->choice.setup;
+      if (CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->carrierSwitching!=NULL) {
+        NR_SRS_CarrierSwitching_t *cs = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->carrierSwitching->choice.setup;
         if (cs->srs_TPC_PDCCH_Group!=NULL){
           switch(cs->srs_TPC_PDCCH_Group->present) {
             case NR_SRS_CarrierSwitching__srs_TPC_PDCCH_Group_PR_NOTHING:
@@ -999,7 +1045,7 @@ void prepare_dci(const NR_CellGroupConfig_t *secondaryCellGroup,
       else
         dci_pdu_rel15->srs_request.val = 0;
     // CBGTI and CBGFI
-    if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL)
+    if (CellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL)
       AssertFatal(1==0,"CBG transmission currently not supported\n");
     break;
   default :
@@ -1009,7 +1055,7 @@ void prepare_dci(const NR_CellGroupConfig_t *secondaryCellGroup,
 
 
 void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
-                        const NR_CellGroupConfig_t *secondaryCellGroup,
+                        const NR_CellGroupConfig_t *CellGroup,
                         nfapi_nr_dl_dci_pdu_t *pdcch_dci_pdu,
                         dci_pdu_rel15_t *dci_pdu_rel15,
                         int dci_format,
@@ -1019,12 +1065,12 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
   uint8_t fsize = 0, pos = 0;
 
   uint64_t *dci_pdu = (uint64_t *)pdcch_dci_pdu->Payload;
-  int dci_size = nr_dci_size(scc, secondaryCellGroup, dci_pdu_rel15, dci_format, rnti_type, N_RB, bwp_id);
+  int dci_size = nr_dci_size(scc->uplinkConfigCommon->initialUplinkBWP, CellGroup, dci_pdu_rel15, dci_format, rnti_type, N_RB, bwp_id);
   pdcch_dci_pdu->PayloadSizeBits = dci_size;
   AssertFatal(dci_size <= 64, "DCI sizes above 64 bits not yet supported");
 
   if (dci_format == NR_DL_DCI_FORMAT_1_1 || dci_format == NR_UL_DCI_FORMAT_0_1)
-    prepare_dci(secondaryCellGroup, dci_pdu_rel15, dci_format, bwp_id);
+    prepare_dci(CellGroup, dci_pdu_rel15, dci_format, bwp_id);
 
   /// Payload generation
   switch (dci_format) {
@@ -1035,7 +1081,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
       fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1));
       pos = fsize;
       *dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val & ((1 << fsize) - 1)) << (dci_size - pos));
-      LOG_D(MAC,
+      LOG_D(NR_MAC,
             "frequency-domain assignment %d (%d bits) N_RB_BWP %d=> %d (0x%lx)\n",
             dci_pdu_rel15->frequency_domain_assignment.val,
             fsize,
@@ -1045,7 +1091,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
       // Time domain assignment
       pos += 4;
       *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment.val & 0xf) << (dci_size - pos));
-      LOG_D(MAC,
+      LOG_D(NR_MAC,
             "time-domain assignment %d  (3 bits)=> %d (0x%lx)\n",
             dci_pdu_rel15->time_domain_assignment.val,
             dci_size - pos,
@@ -1053,7 +1099,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
       // VRB to PRB mapping
       pos++;
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val & 0x1) << (dci_size - pos);
-      LOG_D(MAC,
+      LOG_D(NR_MAC,
             "vrb to prb mapping %d  (1 bits)=> %d (0x%lx)\n",
             dci_pdu_rel15->vrb_to_prb_mapping.val,
             dci_size - pos,
@@ -1062,21 +1108,21 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
       pos += 5;
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs & 0x1f) << (dci_size - pos);
 #ifdef DEBUG_FILL_DCI
-      LOG_I(MAC, "mcs %d  (5 bits)=> %d (0x%lx)\n", dci_pdu_rel15->mcs, dci_size - pos, *dci_pdu);
+      LOG_I(NR_MAC, "mcs %d  (5 bits)=> %d (0x%lx)\n", dci_pdu_rel15->mcs, dci_size - pos, *dci_pdu);
 #endif
       // TB scaling
       pos += 2;
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->tb_scaling & 0x3) << (dci_size - pos);
 #ifdef DEBUG_FILL_DCI
-      LOG_I(MAC, "tb_scaling %d  (2 bits)=> %d (0x%lx)\n", dci_pdu_rel15->tb_scaling, dci_size - pos, *dci_pdu);
+      LOG_I(NR_MAC, "tb_scaling %d  (2 bits)=> %d (0x%lx)\n", dci_pdu_rel15->tb_scaling, dci_size - pos, *dci_pdu);
 #endif
       break;
 
     case NR_RNTI_C:
       // indicating a DL DCI format 1bit
       pos++;
-      *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 1) << (dci_size - pos);
-      LOG_D(MAC,
+      *dci_pdu |= ((uint64_t)1) << (dci_size - pos);
+      LOG_D(NR_MAC,
             "Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",
             dci_pdu_rel15->format_indicator,
             1,
@@ -1087,7 +1133,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
       fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1));
       pos += fsize;
       *dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val & ((1 << fsize) - 1)) << (dci_size - pos));
-      LOG_D(MAC,
+      LOG_D(NR_MAC,
             "Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",
             dci_pdu_rel15->frequency_domain_assignment.val,
             fsize,
@@ -1117,7 +1163,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
         // Time domain assignment 4bit
         pos += 4;
         *dci_pdu |= ((dci_pdu_rel15->time_domain_assignment.val & 0xf) << (dci_size - pos));
-        LOG_D(MAC,
+        LOG_D(NR_MAC,
               "Time domain assignment %d (%d bits)=> %d (0x%lx)\n",
               dci_pdu_rel15->time_domain_assignment.val,
               4,
@@ -1126,7 +1172,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
         // VRB to PRB mapping  1bit
         pos++;
         *dci_pdu |= (dci_pdu_rel15->vrb_to_prb_mapping.val & 1) << (dci_size - pos);
-        LOG_D(MAC,
+        LOG_D(NR_MAC,
               "VRB to PRB %d (%d bits)=> %d (0x%lx)\n",
               dci_pdu_rel15->vrb_to_prb_mapping.val,
               1,
@@ -1135,31 +1181,31 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
         // MCS 5bit  //bit over 32, so dci_pdu ++
         pos += 5;
         *dci_pdu |= (dci_pdu_rel15->mcs & 0x1f) << (dci_size - pos);
-        LOG_D(MAC, "MCS %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->mcs, 5, dci_size - pos, *dci_pdu);
+        LOG_D(NR_MAC, "MCS %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->mcs, 5, dci_size - pos, *dci_pdu);
         // New data indicator 1bit
         pos++;
         *dci_pdu |= (dci_pdu_rel15->ndi & 1) << (dci_size - pos);
-        LOG_D(MAC, "NDI %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->ndi, 1, dci_size - pos, *dci_pdu);
+        LOG_D(NR_MAC, "NDI %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->ndi, 1, dci_size - pos, *dci_pdu);
         // Redundancy version  2bit
         pos += 2;
         *dci_pdu |= (dci_pdu_rel15->rv & 0x3) << (dci_size - pos);
-        LOG_D(MAC, "RV %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->rv, 2, dci_size - pos, *dci_pdu);
+        LOG_D(NR_MAC, "RV %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->rv, 2, dci_size - pos, *dci_pdu);
         // HARQ process number  4bit
         pos += 4;
         *dci_pdu |= ((dci_pdu_rel15->harq_pid & 0xf) << (dci_size - pos));
-        LOG_D(MAC, "HARQ_PID %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->harq_pid, 4, dci_size - pos, *dci_pdu);
+        LOG_D(NR_MAC, "HARQ_PID %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->harq_pid, 4, dci_size - pos, *dci_pdu);
         // Downlink assignment index  2bit
         pos += 2;
         *dci_pdu |= ((dci_pdu_rel15->dai[0].val & 3) << (dci_size - pos));
-        LOG_D(MAC, "DAI %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->dai[0].val, 2, dci_size - pos, *dci_pdu);
+        LOG_D(NR_MAC, "DAI %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->dai[0].val, 2, dci_size - pos, *dci_pdu);
         // TPC command for scheduled PUCCH  2bit
         pos += 2;
         *dci_pdu |= ((dci_pdu_rel15->tpc & 3) << (dci_size - pos));
-        LOG_D(MAC, "TPC %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->tpc, 2, dci_size - pos, *dci_pdu);
+        LOG_D(NR_MAC, "TPC %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->tpc, 2, dci_size - pos, *dci_pdu);
         // PUCCH resource indicator  3bit
         pos += 3;
         *dci_pdu |= ((dci_pdu_rel15->pucch_resource_indicator & 0x7) << (dci_size - pos));
-        LOG_D(MAC,
+        LOG_D(NR_MAC,
               "PUCCH RI %d (%d bits)=> %d (0x%lx)\n",
               dci_pdu_rel15->pucch_resource_indicator,
               3,
@@ -1168,7 +1214,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
         // PDSCH-to-HARQ_feedback timing indicator 3bit
         pos += 3;
         *dci_pdu |= ((dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val & 0x7) << (dci_size - pos));
-        LOG_D(MAC,
+        LOG_D(NR_MAC,
               "PDSCH to HARQ TI %d (%d bits)=> %d (0x%lx)\n",
               dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val,
               3,
@@ -1287,31 +1333,34 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
   case NR_UL_DCI_FORMAT_0_0:
     switch (rnti_type) {
     case NR_RNTI_C:
-      // indicating a DL DCI format 1bit
-      *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 1) << (dci_size - pos++);
+      // indicating a UL DCI format 1bit
+      pos=1;
+      *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 1) << (dci_size - pos);
       // Freq domain assignment  max 16 bit
       fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1));
-      for (int i = 0; i < fsize; i++)
-        *dci_pdu |= ((dci_pdu_rel15->frequency_domain_assignment.val >> (fsize - i - 1)) & 1) << (dci_size - pos++);
+      pos+=fsize;
+      *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val & ((1 << fsize) - 1)) << (dci_size - pos);
       // Time domain assignment 4bit
-      for (int i = 0; i < 4; i++)
-        *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment.val >> (3 - i)) & 1) << (dci_size - pos++);
+      pos += 4;
+      *dci_pdu |= ((uint64_t)dci_pdu_rel15->time_domain_assignment.val & ((1 << 4) - 1)) << (dci_size - pos);
       // Frequency hopping flag – 1 bit
-      *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val & 1) << (dci_size - pos++);
+      pos++;
+      *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val & 1) << (dci_size - pos);
       // MCS  5 bit
-      for (int i = 0; i < 5; i++)
-        *dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs >> (4 - i)) & 1) << (dci_size - pos++);
+      pos+=5;
+      *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs & 0x1f) << (dci_size - pos);
       // New data indicator 1bit
-      *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi & 1) << (dci_size - pos++);
+      pos++;
+      *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi & 1) << (dci_size - pos);
       // Redundancy version  2bit
-      for (int i = 0; i < 2; i++)
-        *dci_pdu |= (((uint64_t)dci_pdu_rel15->rv >> (1 - i)) & 1) << (dci_size - pos++);
+      pos+=2;
+      *dci_pdu |= ((uint64_t)dci_pdu_rel15->rv & 0x3) << (dci_size - pos);
       // HARQ process number  4bit
-      for (int i = 0; i < 4; i++)
-        *dci_pdu |= (((uint64_t)dci_pdu_rel15->harq_pid >> (3 - i)) & 1) << (dci_size - pos++);
+      pos+=4;
+      *dci_pdu |= ((uint64_t)dci_pdu_rel15->harq_pid & 0xf) << (dci_size - pos);
       // TPC command for scheduled PUSCH – 2 bits
-      for (int i = 0; i < 2; i++)
-        *dci_pdu |= (((uint64_t)dci_pdu_rel15->tpc >> (1 - i)) & 1) << (dci_size - pos++);
+      pos+=2;
+      *dci_pdu |= ((uint64_t)dci_pdu_rel15->tpc & 0x3) << (dci_size - pos);
       // Padding bits
       for (int a = pos; a < 32; a++)
         *dci_pdu |= ((uint64_t)dci_pdu_rel15->padding & 1) << (dci_size - pos++);
@@ -1321,6 +1370,19 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
         *dci_pdu |=
       ((uint64_t)dci_pdu_rel15->ul_sul_indicator.val&1)<<(dci_size-pos++);
         */
+
+        LOG_D(NR_MAC,"N_RB = %i\n", N_RB);
+        LOG_D(NR_MAC,"dci_size = %i\n", dci_size);
+        LOG_D(NR_MAC,"fsize = %i\n", fsize);
+        LOG_D(NR_MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val);
+        LOG_D(NR_MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val);
+        LOG_D(NR_MAC,"dci_pdu_rel15->frequency_hopping_flag.val = %i\n", dci_pdu_rel15->frequency_hopping_flag.val);
+        LOG_D(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs);
+        LOG_D(NR_MAC,"dci_pdu_rel15->ndi = %i\n", dci_pdu_rel15->ndi);
+        LOG_D(NR_MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv);
+        LOG_D(NR_MAC,"dci_pdu_rel15->harq_pid = %i\n", dci_pdu_rel15->harq_pid);
+        LOG_D(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc);
+        LOG_D(NR_MAC,"dci_pdu_rel15->padding = %i\n", dci_pdu_rel15->padding);
       break;
 
     case NFAPI_NR_RNTI_TC:
@@ -1524,7 +1586,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
     pos += 1;
     *dci_pdu |= ((uint64_t)dci_pdu_rel15->dmrs_sequence_initialization.val & 0x1) << (dci_size - pos);
   }
-  LOG_D(MAC, "DCI has %d bits and the payload is %lx\n", dci_size, *dci_pdu);
+  LOG_D(NR_MAC, "DCI has %d bits and the payload is %lx\n", dci_size, *dci_pdu);
 }
 
 int get_spf(nfapi_nr_config_request_scf_t *cfg) {
@@ -1563,7 +1625,7 @@ int extract_length(int startSymbolAndLength) {
 void dump_nr_list(NR_list_t *listP)
 {
   for (int j = listP->head; j >= 0; j = listP->next[j])
-    LOG_T(MAC, "NR list node %d => %d\n", j, listP->next[j]);
+    LOG_T(NR_MAC, "NR list node %d => %d\n", j, listP->next[j]);
 }
 
 /*
@@ -1699,7 +1761,7 @@ int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) {
   RA_t *ra = (RA_t *) &RC.nrmac[mod_idP]->common_channels[CC_idP].ra[0];
 
   for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) {
-    LOG_D(MAC, "Checking RA_id %d for %x : state %d\n",
+    LOG_D(NR_MAC, "Checking RA_id %d for %x : state %d\n",
           RA_id,
           rntiP,
           ra[RA_id].state);
@@ -1750,67 +1812,71 @@ int get_ul_bwp_id(const NR_ServingCellConfig_t *servingCellConfig)
 }
 
 //------------------------------------------------------------------------------
-int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secondaryCellGroup)
+int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup)
 {
+  NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_idP]->common_channels[0].ServingCellConfigCommon;
   NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info;
-  LOG_I(MAC, "[gNB %d] Adding UE with rnti %x (num_UEs %d)\n",
+  LOG_I(NR_MAC, "[gNB %d] Adding UE with rnti %x (num_UEs %d)\n",
         mod_idP,
         rntiP,
         UE_info->num_UEs);
   dump_nr_list(&UE_info->list);
 
   for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
-    if (UE_info->active[i])
+    if (UE_info->active[i]) {
+      LOG_D(NR_MAC,"UE %x is active, skipping\n",rntiP);
       continue;
-
+    }
     int UE_id = i;
     UE_info->num_UEs++;
     UE_info->active[UE_id] = true;
+    if (CellGroup) UE_info->Msg4_ACKed[UE_id] = true;
+    else           UE_info->Msg4_ACKed[UE_id] = false;
     UE_info->rnti[UE_id] = rntiP;
-    UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup;
+    UE_info->CellGroup[UE_id] = CellGroup;
     add_nr_list(&UE_info->list, UE_id);
     memset(&UE_info->mac_stats[UE_id], 0, sizeof(NR_mac_stats_t));
     set_Y(UE_info->Y[UE_id], rntiP);
-    compute_csi_bitlen (secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE_info, UE_id, mod_idP);
+    if (CellGroup && CellGroup->spCellConfig && CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated)
+      compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE_info, UE_id, mod_idP);
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
     memset(sched_ctrl, 0, sizeof(*sched_ctrl));
+    sched_ctrl->lcid_mask = 0;
     sched_ctrl->ta_frame = 0;
     sched_ctrl->ta_update = 31;
     sched_ctrl->ta_apply = false;
+    sched_ctrl->ul_rssi = 0;
+    sched_ctrl->pucch_consecutive_dtx_cnt = 0;
+    sched_ctrl->pusch_consecutive_dtx_cnt = 0;
+    sched_ctrl->ul_failure                = 0;
     /* set illegal time domain allocation to force recomputation of all fields */
     sched_ctrl->pdsch_semi_static.time_domain_allocation = -1;
     sched_ctrl->pusch_semi_static.time_domain_allocation = -1;
-    const NR_ServingCellConfig_t *servingCellConfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated;
+    const NR_ServingCellConfig_t *servingCellConfig = CellGroup ? CellGroup->spCellConfig->spCellConfigDedicated : NULL;
 
     /* Set default BWPs */
-    const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
-    const int bwp_id = get_dl_bwp_id(servingCellConfig);
-    AssertFatal(bwp_id > 0 && bwp_id <= bwpList->list.count,
-                "%s(): illegal bwp_id %d (max %d)!\n",
-                __func__,
-                bwp_id,
-                bwpList->list.count);
-    sched_ctrl->active_bwp = bwpList->list.array[bwp_id - 1];
-    const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
-    sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
-    sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
-
-    const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
-    const int ubwp_id = get_ul_bwp_id(servingCellConfig);
-    AssertFatal(ubwp_id > 0 && ubwp_id <= ubwpList->list.count,
-                "%s(): illegal ubwp_id %d (max %d)!\n",
-                __func__,
-                ubwp_id,
-                ubwpList->list.count);
-    sched_ctrl->active_ubwp = ubwpList->list.array[ubwp_id - 1];
+    const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig ? servingCellConfig->downlinkBWP_ToAddModList : NULL;
+    if (bwpList) AssertFatal(bwpList->list.count <= 4,
+			     "downlinkBWP_ToAddModList has %d BWP!\n",
+			     bwpList->list.count);
+    const int bwp_id = *servingCellConfig->firstActiveDownlinkBWP_Id;
+    sched_ctrl->active_bwp = bwpList ? bwpList->list.array[bwp_id - 1] : NULL;
+    const int target_ss = sched_ctrl->active_bwp ? NR_SearchSpace__searchSpaceType_PR_ue_Specific : NR_SearchSpace__searchSpaceType_PR_common;
+    sched_ctrl->search_space = get_searchspace(scc, sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, target_ss);
+    sched_ctrl->coreset = get_coreset(scc, sched_ctrl->active_bwp, sched_ctrl->search_space, target_ss);
+    const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL;
+    if (ubwpList) AssertFatal(ubwpList->list.count <= 4,
+			      "uplinkBWP_ToAddModList has %d BWP!\n",
+			      ubwpList->list.count);
+    sched_ctrl->active_ubwp = ubwpList ? ubwpList->list.array[bwp_id - 1] : NULL;
 
     /* get Number of HARQ processes for this UE */
-    AssertFatal(servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup,
-                "no pdsch-ServingCellConfig found for UE %d\n",
-                UE_id);
-    const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig->pdsch_ServingCellConfig->choice.setup;
-    const int nrofHARQ = pdsch->nrofHARQ_ProcessesForPDSCH ?
-        get_nrofHARQ_ProcessesForPDSCH(*pdsch->nrofHARQ_ProcessesForPDSCH) : 8;
+    if (servingCellConfig) AssertFatal(servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup,
+				       "no pdsch-ServingCellConfig found for UE %d\n",
+				       UE_id);
+    const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL;
+    const int nrofHARQ = pdsch ? (pdsch->nrofHARQ_ProcessesForPDSCH ?
+				  get_nrofHARQ_ProcessesForPDSCH(*pdsch->nrofHARQ_ProcessesForPDSCH) : 8) : 8;
     // add all available DL HARQ processes for this UE
     create_nr_list(&sched_ctrl->available_dl_harq, nrofHARQ);
     for (int harq = 0; harq < nrofHARQ; harq++)
@@ -1824,7 +1890,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secon
       add_tail_nr_list(&sched_ctrl->available_ul_harq, harq);
     create_nr_list(&sched_ctrl->feedback_ul_harq, 16);
     create_nr_list(&sched_ctrl->retrans_ul_harq, 16);
-    LOG_I(MAC, "[gNB %d] Add NR UE_id %d : rnti %x\n",
+    LOG_I(NR_MAC, "[gNB %d] Add NR UE_id %d : rnti %x\n",
           mod_idP,
           UE_id,
           rntiP);
@@ -1833,7 +1899,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secon
   }
 
   // printf("MAC: cannot add new UE for rnti %x\n", rntiP);
-  LOG_E(MAC, "error in add_new_ue(), could not find space in UE_info, Dumping UE list\n");
+  LOG_E(NR_MAC, "error in add_new_ue(), could not find space in UE_info, Dumping UE list\n");
   dump_nr_list(&UE_info->list);
   return -1;
 }
@@ -1871,7 +1937,7 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
     destroy_nr_list(&sched_ctrl->available_ul_harq);
     destroy_nr_list(&sched_ctrl->feedback_ul_harq);
     destroy_nr_list(&sched_ctrl->retrans_ul_harq);
-    LOG_I(MAC, "[gNB %d] Remove NR UE_id %d : rnti %x\n",
+    LOG_I(NR_MAC, "[gNB %d] Remove NR UE_id %d : rnti %x\n",
           mod_id,
           UE_id,
           rnti);
@@ -1890,7 +1956,7 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
     NR_COMMON_channels_t *cc = &RC.nrmac[mod_id]->common_channels[cc_id];
     for (i = 0; i < NR_NB_RA_PROC_MAX; i++) {
       if (cc->ra[i].rnti == rnti) {
-        LOG_D(MAC, "free RA process %d for rnti %d\n", i, rnti);
+        LOG_D(NR_MAC, "free RA process %d for rnti %d\n", i, rnti);
         /* is it enough? */
         cc->ra[i].cfra  = false;
         cc->ra[i].rnti  = 0;
@@ -1912,11 +1978,11 @@ void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti) {
 
 uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) {
   // al values passed to this function are x10
-
   int snrx10 = (cqi*5) - 640;
   if (snrx10 > target + incr) return 0; // decrease 1dB
   if (snrx10 < target - incr) return 2; // increase 1dB
   if (snrx10 < target - (3*incr)) return 3; // increase 3dB
+  LOG_D(NR_MAC,"tpc : target %d, snrx10 %d\n",target,snrx10);
   return 1; // no change
 }
 
@@ -1928,11 +1994,16 @@ void get_pdsch_to_harq_feedback(int Mod_idP,
 
   int bwp_id=1;
   NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
-  NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
-  NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
-  NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
+  NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id];
+  NR_BWP_Downlink_t *bwp=NULL;
+  NR_BWP_Uplink_t *ubwp=NULL;
+
+  if (CellGroup && CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList)
+    bwp = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
+  if (CellGroup && CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList)
+    ubwp = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
 
-  NR_SearchSpace_t *ss;
+  NR_SearchSpace_t *ss=NULL;
 
   // common search type uses DCI format 1_0
   if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) {
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
index f53f79ba499c661f840b40909b9ce1b4086149df..c7ee3fcff2039fac777a756ce05ffaca940e2b1a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
@@ -26,6 +26,7 @@
  * \company Eurecom
  */
 
+#include <softmodem-common.h>
 #include "LAYER2/MAC/mac.h"
 #include "NR_MAC_gNB/nr_mac_gNB.h"
 #include "NR_MAC_COMMON/nr_mac_extern.h"
@@ -72,12 +73,14 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
   NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
   nr_configure_pucch(pucch_pdu,
                      scc,
+                     UE_info->CellGroup[UE_id],
                      UE_info->UE_sched_ctrl[UE_id].active_ubwp,
                      UE_info->rnti[UE_id],
                      pucch->resource_indicator,
                      pucch->csi_bits,
                      pucch->dai_c,
-                     pucch->sr_flag);
+                     pucch->sr_flag,
+                     pucch->r_pucch);
 }
 
 #define MIN_RSRP_VALUE -141
@@ -129,6 +132,7 @@ void nr_schedule_pucch(int Mod_idP,
 
   for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+    if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
     const int n = sizeof(sched_ctrl->sched_pucch) / sizeof(*sched_ctrl->sched_pucch);
     for (int i = 0; i < n; i++) {
       NR_sched_pucch_t *curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[i];
@@ -139,7 +143,7 @@ void nr_schedule_pucch(int Mod_idP,
           || frameP != curr_pucch->frame
           || slotP != curr_pucch->ul_slot)
         continue;
-
+      LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %d in %d.%d O_ack %d\n",i,UE_id,curr_pucch->frame,curr_pucch->ul_slot,O_ack);
       nr_fill_nfapi_pucch(Mod_idP, frameP, slotP, curr_pucch, UE_id);
       memset(curr_pucch, 0, sizeof(*curr_pucch));
     }
@@ -476,9 +480,11 @@ void nr_csi_meas_reporting(int Mod_idP,
   NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
   NR_list_t *UE_list = &UE_info->list;
   for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-    const NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
+    const NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id];
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
-    const NR_CSI_MeasConfig_t *csi_measconfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
+    if (!CellGroup || !CellGroup->spCellConfig || !CellGroup->spCellConfig->spCellConfigDedicated ||
+	      !CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig) continue;
+    const NR_CSI_MeasConfig_t *csi_measconfig = CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
     AssertFatal(csi_measconfig->csi_ReportConfigToAddModList->list.count > 0,
                 "NO CSI report configuration available");
     NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
@@ -586,13 +592,13 @@ static void handle_dl_harq(module_id_t mod_id,
 
 int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, int Mod_idP, int UE_id) {
   NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
-  NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id] ;
-  int nb_tci_states = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count;
+  NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id] ;
+  int nb_tci_states = CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count;
   NR_TCI_State_t *tci =NULL;
   int i;
 
   for(i=0; i<nb_tci_states && i<64; i++) {
-    tci = (NR_TCI_State_t *)secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.array[i];
+    tci = (NR_TCI_State_t *)CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.array[i];
 
     if(tci != NULL) {
       if(tci->qcl_Type1.referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) {
@@ -613,19 +619,19 @@ int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, int Mod_idP, i
 
 int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, int Mod_idP, int UE_id) {
   NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
-  NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id] ;
-  int nb_tci_states = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count;
+  NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id] ;
+  int nb_tci_states = CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count;
   NR_TCI_State_t *tci =NULL;
   NR_TCI_StateId_t *tci_id = NULL;
   int bwp_id = 1;
-  NR_BWP_Downlink_t *bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
+  NR_BWP_Downlink_t *bwp = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
   NR_ControlResourceSet_t *coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[bwp_id-1];
   int i;
   int flag = 0;
   int tci_stateID = -1;
 
   for(i=0; i<nb_tci_states && i<128; i++) {
-    tci = (NR_TCI_State_t *)secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.array[i];
+    tci = (NR_TCI_State_t *)CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.array[i];
 
     if(tci != NULL && tci->qcl_Type1.referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) {
       if(tci->qcl_Type1.referenceSignal.choice.ssb == ssb_index_t) {
@@ -687,10 +693,10 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
   uint8_t idx = 0;
   int bwp_id  = 1;
   NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
-  NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
-  NR_BWP_Downlink_t *bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
+  NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id];
+  NR_BWP_Downlink_t *bwp = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
   //bwp indicator
-  int n_dl_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count;
+  int n_dl_bwp = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count;
   uint8_t nr_ssbri_cri = 0;
   uint8_t nb_of_csi_ssb_report = UE_info->csi_report_template[UE_id][cqi_idx].nb_of_csi_ssb_report;
   int better_rsrp_reported = -140-(-0); /*minimum_measured_RSRP_value - minimum_differntail_RSRP_value*///considering the minimum RSRP value as better RSRP initially
@@ -1049,7 +1055,12 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
     LOG_E(MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_234->rnti);
     return;
   }
-  NR_CSI_MeasConfig_t *csi_MeasConfig = RC.nrmac[mod_id]->UE_info.secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
+  AssertFatal(RC.nrmac[mod_id]->UE_info.CellGroup[UE_id],"Cellgroup is null for UE %d/%x\n",UE_id,uci_234->rnti);
+  AssertFatal(RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig, "Cellgroup->spCellConfig is null for UE %d/%x\n",UE_id,uci_234->rnti);
+  AssertFatal(RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated, "Cellgroup->spCellConfig->spCellConfigDedicated is null for UE %d/%x\n",UE_id,uci_234->rnti);
+  if ( RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->csi_MeasConfig==NULL) return;
+
+  NR_CSI_MeasConfig_t *csi_MeasConfig = RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
   NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
 
@@ -1092,7 +1103,8 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
 int nr_acknack_scheduling(int mod_id,
                           int UE_id,
                           frame_t frame,
-                          sub_frame_t slot)
+                          sub_frame_t slot,
+                          int r_pucch)
 {
   const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
   const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
@@ -1118,6 +1130,7 @@ int nr_acknack_scheduling(int mod_id,
    * * each UE has dedicated PUCCH Format 0 resources, and we use index 0! */
   NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id];
   NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0];
+  pucch->r_pucch=r_pucch;
   AssertFatal(pucch->csi_bits == 0,
               "%s(): csi_bits %d in sched_pucch[0]\n",
               __func__,
@@ -1136,6 +1149,7 @@ int nr_acknack_scheduling(int mod_id,
     csi_pucch = &sched_ctrl->sched_pucch[1];
     // skip the CSI PUCCH if it is present and if in the next frame/slot
     // and if we don't multiplex
+    csi_pucch->r_pucch=-1;
     if (csi_pucch->csi_bits > 0
         && csi_pucch->frame == pucch->frame
         && csi_pucch->ul_slot == pucch->ul_slot
@@ -1147,6 +1161,7 @@ int nr_acknack_scheduling(int mod_id,
     }
   }
 
+  LOG_D(MAC,"1. DL slot %d, UL_ACK %d\n",slot,pucch->ul_slot);
   /* if the UE's next PUCCH occasion is after the possible UL slots (within the
    * same frame) or wrapped around to the next frame, then we assume there is
    * no possible PUCCH allocation anymore */
@@ -1155,8 +1170,8 @@ int nr_acknack_scheduling(int mod_id,
       || (pucch->frame == frame + 1))
     return -1;
 
-  // this is hardcoded for now as ue specific
-  NR_SearchSpace__searchSpaceType_PR ss_type = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
+  // this is hardcoded for now as ue specific only if we are not on the initialBWP (to be fixed to allow ue_Specific also on initialBWP
+  NR_SearchSpace__searchSpaceType_PR ss_type = sched_ctrl->active_bwp ? NR_SearchSpace__searchSpaceType_PR_ue_Specific: NR_SearchSpace__searchSpaceType_PR_common;
   uint8_t pdsch_to_harq_feedback[8];
   get_pdsch_to_harq_feedback(mod_id, UE_id, ss_type, pdsch_to_harq_feedback);
 
@@ -1181,7 +1196,7 @@ int nr_acknack_scheduling(int mod_id,
       memset(pucch, 0, sizeof(*pucch));
       pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
       pucch->ul_slot = (s + 1) % n_slots_frame;
-      return nr_acknack_scheduling(mod_id, UE_id, frame, slot);
+      return nr_acknack_scheduling(mod_id, UE_id, frame, slot, pucch->r_pucch);
     }
 
     pucch->timing_indicator = i;
@@ -1213,6 +1228,8 @@ int nr_acknack_scheduling(int mod_id,
   // Find the right timing_indicator value.
   int i = 0;
   while (i < 8) {
+    LOG_D(MAC,"pdsch_to_harq_feedback[%d] = %d (pucch->ul_slot %d - slot %d)\n",
+	  i,pdsch_to_harq_feedback[i],pucch->ul_slot,slot);
     if (pdsch_to_harq_feedback[i] == pucch->ul_slot - slot)
       break;
     ++i;
@@ -1247,7 +1264,7 @@ int nr_acknack_scheduling(int mod_id,
       memset(pucch, 0, sizeof(*pucch));
       pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
       pucch->ul_slot = (s + 1) % n_slots_frame;
-      return nr_acknack_scheduling(mod_id, UE_id, frame, slot);
+      return nr_acknack_scheduling(mod_id, UE_id, frame, slot, -1);
     }
     // multiplexing harq and csi in a pucch
     else {
@@ -1259,13 +1276,26 @@ int nr_acknack_scheduling(int mod_id,
 
   pucch->timing_indicator = i; // index in the list of timing indicators
 
+  LOG_D(MAC,"2. DL slot %d, UL_ACK %d (index %d)\n",slot,pucch->ul_slot,i);
+
   pucch->dai_c++;
   pucch->resource_indicator = 0; // each UE has dedicated PUCCH resources
 
+  NR_PUCCH_Config_t *pucch_Config = NULL;
+  if (sched_ctrl->active_ubwp) {
+    pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
+  } else if (RC.nrmac[mod_id]->UE_info.CellGroup[UE_id] &&
+             RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig &&
+             RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated &&
+             RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+             RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
+             RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
+    pucch_Config = RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
+  }
+
   /* verify that at that slot and symbol, resources are free. We only do this
    * for initialCyclicShift 0 (we assume it always has that one), so other
    * initialCyclicShifts can overlap with ICS 0!*/
-  const NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
   const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[pucch->resource_indicator];
   DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0);
   if (resource->format.choice.format0->initialCyclicShift == 0) {
@@ -1417,7 +1447,19 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
   NR_list_t *UE_list = &UE_info->list;
   for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
-    NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
+
+    NR_PUCCH_Config_t *pucch_Config = NULL;
+    if (sched_ctrl->active_ubwp) {
+      pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
+    } else if (RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id] &&
+             RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig &&
+             RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated &&
+             RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+             RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
+             RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
+      pucch_Config = RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
+    }
+
     AssertFatal(pucch_Config->schedulingRequestResourceToAddModList->list.count>0,"NO SR configuration available");
 
     for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) {
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 323baa48a7b7b8a7fa60487398fc07efc6561929..3effe300abef5731eddc2198dc4b630e74f55aa8 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -32,6 +32,8 @@
 #include "LAYER2/NR_MAC_gNB/mac_proto.h"
 #include "executables/softmodem-common.h"
 #include "common/utils/nr/nr_common.h"
+#include <openair2/UTIL/OPT/opt.h>
+
 
 //38.321 Table 6.1.3.1-1
 const uint32_t NR_SHORT_BSR_TABLE[32] = {
@@ -69,7 +71,7 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
     return;
 
   /* there is a mixed slot only when in TDD */
-  const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
+  NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
   const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
   const NR_TDD_UL_DL_Pattern_t *tdd =
       scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
@@ -117,7 +119,7 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
   const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
   AssertFatal(tdaList->list.count >= 3, "need to have at least three TDAs for UL slots\n");
   const NR_PUSCH_TimeDomainResourceAllocation_t *tdaP_UL = tdaList->list.array[0];
-  const int k2 = get_K2(ubwp, /* tda = */ 0, mu);
+  const int k2 = get_K2(scc, (NR_BWP_Uplink_t*)ubwp,0, mu);
   int start, len;
   SLIV2SL(tdaP_UL->startSymbolAndLength, &start, &len);
   const uint16_t symb_tda = ((1 << len) - 1) << start;
@@ -129,10 +131,10 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
   // get largest time domain allocation (TDA) for UL slot and UL in mixed slot
   int tdaMi = -1;
   const NR_PUSCH_TimeDomainResourceAllocation_t *tdaP_Mi = tdaList->list.array[1];
-  AssertFatal(k2 == get_K2(ubwp, /* tda = */ 1, mu),
+  AssertFatal(k2 == get_K2(scc, (NR_BWP_Uplink_t*)ubwp, 1, mu),
               "scheduler cannot handle different k2 for UL slot (%d) and UL Mixed slot (%ld)\n",
               k2,
-              get_K2(ubwp, /* tda = */ 1, mu));
+              get_K2(scc, (NR_BWP_Uplink_t*)ubwp, 1, mu));
   SLIV2SL(tdaP_Mi->startSymbolAndLength, &start, &len);
   const uint16_t symb_tda_mi = ((1 << len) - 1) << start;
   // check whether PUCCH and TDA overlap: then, we cannot use it. Also, check
@@ -188,7 +190,6 @@ void nr_process_mac_pdu(module_id_t module_idP,
     int pdu_len = mac_pdu_len;
     uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len;
 
-
     NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
     //  For both DL/UL-SCH
@@ -222,7 +223,7 @@ void nr_process_mac_pdu(module_id_t module_idP,
         mac_sdu_len = 0;
         rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID;
 
-        LOG_D(MAC, "LCID received at gNB side: %d \n", rx_lcid);
+        LOG_D(NR_MAC, "LCID received at gNB side: %d \n", rx_lcid);
 
         unsigned char *ce_ptr;
         int n_Lcg = 0;
@@ -231,7 +232,7 @@ void nr_process_mac_pdu(module_id_t module_idP,
             //  MAC CE
 
             /*#ifdef DEBUG_HEADER_PARSING
-              LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len);
+              LOG_D(NR_MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len);
             #endif*/
         case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY:
               // 38.321 Ch6.1.3.20
@@ -251,7 +252,7 @@ void nr_process_mac_pdu(module_id_t module_idP,
                NR_BSR_SHORT *bsr_s = (NR_BSR_SHORT *) ce_ptr;
                sched_ctrl->estimated_ul_buffer = 0;
                sched_ctrl->estimated_ul_buffer = NR_SHORT_BSR_TABLE[bsr_s->Buffer_size];
-               LOG_D(MAC,
+               LOG_D(NR_MAC,
                      "SHORT BSR at %4d.%2d, LCG ID %d, BS Index %d, BS value < %d, est buf %d\n",
                      frameP,
                      slot,
@@ -279,10 +280,17 @@ void nr_process_mac_pdu(module_id_t module_idP,
                n_Lcg = bsr_l->LcgID7 + bsr_l->LcgID6 + bsr_l->LcgID5 + bsr_l->LcgID4 +
                        bsr_l->LcgID3 + bsr_l->LcgID2 + bsr_l->LcgID1 + bsr_l->LcgID0;
 
+               LOG_D(NR_MAC, "LONG BSR, LCG ID(7-0) %d/%d/%d/%d/%d/%d/%d/%d\n",
+                     bsr_l->LcgID7, bsr_l->LcgID6, bsr_l->LcgID5, bsr_l->LcgID4,
+                     bsr_l->LcgID3, bsr_l->LcgID2, bsr_l->LcgID1, bsr_l->LcgID0);
+
                for (int n = 0; n < n_Lcg; n++){
+                 LOG_D(NR_MAC, "LONG BSR, %d/%d (n/n_Lcg), BS Index %d, BS value < %d",
+                       n, n_Lcg, pdu_ptr[mac_subheader_len + 1 + n],
+                       NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]]);
                  sched_ctrl->estimated_ul_buffer +=
                        NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]];
-                 LOG_D(MAC,
+                 LOG_D(NR_MAC,
                        "LONG BSR at %4d.%2d, %d/%d (n/n_Lcg), BS Index %d, BS value < %d, total %d\n",
                        frameP,
                        slot,
@@ -307,19 +315,19 @@ void nr_process_mac_pdu(module_id_t module_idP,
         	//fixed length
         	mac_ce_len = 2;
         	/* Extract SINGLE ENTRY PHR elements for PHR calculation */
-                ce_ptr = &pdu_ptr[mac_subheader_len];
-                NR_SINGLE_ENTRY_PHR_MAC_CE *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr;
-                /* Save the phr info */
-                const int PH = phr->PH;
-                const int PCMAX = phr->PCMAX;
-                /* 38.133 Table10.1.17.1-1 */
-                if (PH < 55)
-                  sched_ctrl->ph = PH - 32;
-                else
-                  sched_ctrl->ph = PH - 32 + (PH - 54);
-                /* 38.133 Table10.1.18.1-1 */
-                sched_ctrl->pcmax = PCMAX - 29;
-                LOG_D(MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n",
+        	ce_ptr = &pdu_ptr[mac_subheader_len];
+        	NR_SINGLE_ENTRY_PHR_MAC_CE *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr;
+        	/* Save the phr info */
+        	const int PH = phr->PH;
+        	const int PCMAX = phr->PCMAX;
+        	/* 38.133 Table10.1.17.1-1 */
+        	if (PH < 55)
+        	  sched_ctrl->ph = PH - 32;
+        	else
+        	  sched_ctrl->ph = PH - 32 + (PH - 54);
+        	/* 38.133 Table10.1.18.1-1 */
+        	sched_ctrl->pcmax = PCMAX - 29;
+        	LOG_D(MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n",
                       phr->R1, PH, sched_ctrl->ph, phr->R2, PCMAX, sched_ctrl->pcmax);
         	break;
 
@@ -352,13 +360,30 @@ void nr_process_mac_pdu(module_id_t module_idP,
         	//  end of MAC PDU, can ignore the rest.
         	break;
 
-        // MAC SDUs
         case UL_SCH_LCID_SRB1:
-              // todo
-              break;
         case UL_SCH_LCID_SRB2:
-              // todo
-              break;
+          if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){
+            //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8;
+            mac_subheader_len = 3;
+            mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L1 & 0x7f) << 8)
+                | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L2 & 0xff);
+          } else {
+            mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L;
+            mac_subheader_len = 2;
+          }
+          LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: %d \n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len, *UE_info->rnti);
+          mac_rlc_data_ind(module_idP,
+                           UE_info->rnti[UE_id],
+                           module_idP,
+                           frameP,
+                           ENB_FLAG_YES,
+                           MBMS_FLAG_NO,
+                           rx_lcid,
+                           (char *) (pdu_ptr + mac_subheader_len),
+                           mac_sdu_len,
+                           1,
+                           NULL);
+          break;
         case UL_SCH_LCID_SRB3:
               // todo
               break;
@@ -414,16 +439,16 @@ void nr_process_mac_pdu(module_id_t module_idP,
             mac_subheader_len = 2;
           }
 
-          LOG_D(MAC,
-                "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n",
+          LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-%s %d (gNB %d, %d bytes)\n",
                 module_idP,
                 frameP,
+                rx_lcid<4?"DCCH":"DTCH",
                 rx_lcid,
                 module_idP,
                 mac_sdu_len);
           UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
 #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
-          log_dump(MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n");
+            log_dump(NR_MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n");
 #endif
 
           mac_rlc_data_ind(module_idP,
@@ -446,7 +471,7 @@ void nr_process_mac_pdu(module_id_t module_idP,
           break;
 
         default:
-          LOG_E(MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid);
+          LOG_E(NR_MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid);
           return;
           break;
         }
@@ -454,8 +479,8 @@ void nr_process_mac_pdu(module_id_t module_idP,
         pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
 
         if (pdu_len < 0) {
-          LOG_E(MAC, "%s() residual mac pdu length < 0!, pdu_len: %d\n", __func__, pdu_len);
-          LOG_E(MAC, "MAC PDU ");
+          LOG_E(NR_MAC, "%s() residual mac pdu length < 0!, pdu_len: %d\n", __func__, pdu_len);
+          LOG_E(NR_MAC, "MAC PDU ");
           for (int i = 0; i < 20; i++) // Only printf 1st - 20nd bytes
             printf("%02x ", pdu_ptr[i]);
           printf("\n");
@@ -489,7 +514,7 @@ void handle_nr_ul_harq(module_id_t mod_id,
 {
   int UE_id = find_nr_UE_id(mod_id, crc_pdu->rnti);
   if (UE_id < 0) {
-    LOG_E(MAC, "%s(): unknown RNTI %04x in PUSCH\n", __func__, crc_pdu->rnti);
+    LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUSCH\n", __func__, crc_pdu->rnti);
     return;
   }
   NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
@@ -497,7 +522,7 @@ void handle_nr_ul_harq(module_id_t mod_id,
 
   int8_t harq_pid = sched_ctrl->feedback_ul_harq.head;
   while (crc_pdu->harq_id != harq_pid || harq_pid < 0) {
-    LOG_W(MAC,
+    LOG_W(NR_MAC,
           "Unexpected ULSCH HARQ PID %d (have %d) for RNTI %04x (ignore this warning for RA)\n",
           crc_pdu->harq_id,
           harq_pid,
@@ -523,20 +548,20 @@ void handle_nr_ul_harq(module_id_t mod_id,
   if (!crc_pdu->tb_crc_status) {
     harq->ndi ^= 1;
     harq->round = 0;
-    LOG_D(MAC,
+    LOG_D(NR_MAC,
           "Ulharq id %d crc passed for RNTI %04x\n",
           harq_pid,
           crc_pdu->rnti);
     add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
   } else if (harq->round >= MAX_HARQ_ROUNDS - 1) {
     abort_nr_ul_harq(mod_id, UE_id, harq_pid);
-    LOG_D(MAC,
+    LOG_D(NR_MAC,
           "RNTI %04x: Ulharq id %d crc failed in all rounds\n",
           crc_pdu->rnti,
           harq_pid);
   } else {
     harq->round++;
-    LOG_D(MAC,
+    LOG_D(NR_MAC,
           "Ulharq id %d crc failed for RNTI %04x\n",
           harq_pid,
           crc_pdu->rnti);
@@ -563,6 +588,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
   const int current_rnti = rntiP;
   const int UE_id = find_nr_UE_id(gnb_mod_idP, current_rnti);
   const int target_snrx10 = gNB_mac->pusch_target_snrx10;
+  const int pusch_failure_thres = gNB_mac->pusch_failure_thres;
 
   if (UE_id != -1) {
     NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id];
@@ -574,7 +600,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
         T_BUFFER(sduP, sdu_lenP));
 
     UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP;
-    LOG_D(NR_MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d sduP %p\n",
+    LOG_D(NR_MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d TA %d sduP %p\n",
           gnb_mod_idP,
           harq_pid,
           CC_idP,
@@ -583,6 +609,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
           current_rnti,
           UE_id,
           ul_cqi,
+          timing_advance,
           sduP);
 
     // if not missed detection (10dB threshold for now)
@@ -600,7 +627,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
 
 #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
 
-    LOG_I(MAC, "Printing received UL MAC payload at gNB side: %d \n");
+    LOG_I(NR_MAC, "Printing received UL MAC payload at gNB side: %d \n");
     for (int i = 0; i < sdu_lenP ; i++) {
 	  //harq_process_ul_ue->a[i] = (unsigned char) rand();
 	  //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
@@ -613,6 +640,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
     if (sduP != NULL){
       LOG_D(NR_MAC, "Received PDU at MAC gNB \n");
 
+      UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt = 0;
       const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size;
       UE_scheduling_control->sched_ul_bytes -= tb_size;
       if (UE_scheduling_control->sched_ul_bytes < 0)
@@ -620,6 +648,24 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
 
       nr_process_mac_pdu(gnb_mod_idP, UE_id, CC_idP, frameP, slotP, sduP, sdu_lenP);
     }
+    else {
+      NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid];
+      /* reduce sched_ul_bytes when cur_harq->round == 3 */
+      if (cur_harq->round == 3){
+        const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size;
+        UE_scheduling_control->sched_ul_bytes -= tb_size;
+        if (UE_scheduling_control->sched_ul_bytes < 0)
+          UE_scheduling_control->sched_ul_bytes = 0;
+      }
+      if (ul_cqi <= 128) {
+        UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt++;
+        UE_info->mac_stats[UE_id].ulsch_DTX++;
+      }
+      if (UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt >= pusch_failure_thres) {
+         LOG_D(NR_MAC,"Detected UL Failure on PUSCH, stopping scheduling\n");
+         UE_info->UE_sched_ctrl[UE_id].ul_failure = 1;
+      }
+    }
   } else if(sduP) {
 
     bool no_sig = true;
@@ -647,7 +693,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
         continue;
 
       if(no_sig) {
-        LOG_W(NR_MAC, "Random Access %i failed at state %i\n", i, ra->state);
+        LOG_W(NR_MAC, "Random Access %i failed at state %i (no signal)\n", i, ra->state);
         nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
         nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
       } else {
@@ -660,7 +706,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
                 current_rnti);
 
           if( (frameP==ra->Msg3_frame) && (slotP==ra->Msg3_slot) ) {
-            LOG_W(NR_MAC, "Random Access %i failed at state %i\n", i, ra->state);
+            LOG_W(NR_MAC, "Random Access %i failed at state %i (TC_RNTI %04x RNTI %04x\n", i, ra->state,ra->rnti,current_rnti);
             nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
             nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
           }
@@ -668,7 +714,9 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
           continue;
         }
 
-        const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->secondaryCellGroup);
+        int UE_id=-1;
+
+        UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->CellGroup);
         UE_info->UE_beam_index[UE_id] = ra->beam_id;
 
         // re-initialize ta update variables after RA procedure completion
@@ -716,7 +764,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
 
         }
         return;
-
       }
     }
   } else {
@@ -725,16 +772,18 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
       if (ra->state != WAIT_Msg3)
         continue;
 
-      LOG_W(NR_MAC, "Random Access %i failed at state %i\n", i, ra->state);
+      LOG_W(NR_MAC, "Random Access %i failed at state %i (state is not WAIT_Msg3)\n", i, ra->state);
       nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
       nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
     }
   }
 }
 
-long get_K2(const NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
-  DevAssert(ubwp);
-  const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
+long get_K2(NR_ServingCellConfigCommon_t *scc,NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
+  DevAssert(scc);
+  const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp ?
+    ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]:
+    scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
   if (tda_list->k2)
     return *tda_list->k2;
   else if (mu < 2)
@@ -793,13 +842,23 @@ bool allocate_ul_retransmission(module_id_t module_id,
   NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
   NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch;
-  int rbStart =
-      NRRIV2PRBOFFSET(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-  const uint16_t bwpSize =
-      NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
+
+  // frame/slot in sched_pusch has been set previously. In the following, we
+  // overwrite the information in the retransmission information before storing
+  // as the new scheduling instruction
+  retInfo->frame = sched_ctrl->sched_pusch.frame;
+  retInfo->slot = sched_ctrl->sched_pusch.slot;
+
+  // Get previous PUSCH filed info
+  sched_ctrl->sched_pusch = *retInfo;
+
+  NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
+  int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0;
+  const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
 
-  const uint8_t num_dmrs_cdm_grps_no_data = 1;
-  const int tda = RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot];
+  const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_bwp ? 1 : 2;
+  const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
   if (tda == retInfo->time_domain_allocation) {
     /* Check the resource is enough for retransmission */
     while (rbStart < bwpSize && !rballoc_mask[rbStart])
@@ -812,7 +871,7 @@ bool allocate_ul_retransmission(module_id_t module_id,
      * (re-)transmission */
     NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
     const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
-    const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
+    const int dci_format = sched_ctrl->active_ubwp ? (f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : NR_UL_DCI_FORMAT_0_0;
     if (ps->time_domain_allocation != tda
         || ps->dci_format != dci_format
         || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
@@ -828,7 +887,7 @@ bool allocate_ul_retransmission(module_id_t module_id,
       rbSize++;
     NR_pusch_semi_static_t temp_ps;
     const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
-    const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
+    const int dci_format = sched_ctrl->active_ubwp ? (f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : NR_UL_DCI_FORMAT_0_0;
     nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, &temp_ps);
     uint32_t new_tbs;
     uint16_t new_rbSize;
@@ -860,14 +919,6 @@ bool allocate_ul_retransmission(module_id_t module_id,
     return false;
   }
 
-  /* frame/slot in sched_pusch has been set previously. In the following, we
-   * overwrite the information in the retransmission information before storing
-   * as the new scheduling instruction */
-  retInfo->frame = sched_ctrl->sched_pusch.frame;
-  retInfo->slot = sched_ctrl->sched_pusch.slot;
-  /* Get previous PSUCH field info */
-  sched_ctrl->sched_pusch = *retInfo;
-  NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
   LOG_D(MAC,
         "%4d.%2d Allocate UL retransmission UE %d/RNTI %04x sched %4d.%2d (%d RBs)\n",
         frame,
@@ -893,8 +944,8 @@ void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static
   const int mcs = sched_pusch->mcs;
   sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table);
   sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table);
-  if (ps->pusch_Config->tp_pi2BPSK
-      && ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) {
+
+  if (ps->pusch_Config && ps->pusch_Config->tp_pi2BPSK && ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) {
     sched_pusch->R >>= 1;
     sched_pusch->Qm <<= 1;
   }
@@ -911,7 +962,6 @@ void pf_ul(module_id_t module_id,
            uint8_t *rballoc_mask) {
 
   const int CC_id = 0;
-  const uint8_t num_dmrs_cdm_grps_no_data = 1;
   gNB_MAC_INST *nrmac = RC.nrmac[module_id];
   NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
   NR_UE_info_t *UE_info = &nrmac->UE_info;
@@ -923,10 +973,13 @@ void pf_ul(module_id_t module_id,
 
   /* Loop UE_list to calculate throughput and coeff */
   for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
+
+    if (UE_info->Msg4_ACKed[UE_id] != true) continue;
+
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
-    int rbStart =
-        NRRIV2PRBOFFSET(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
+    int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0;
+    const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
     NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
     NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
 
@@ -965,7 +1018,7 @@ void pf_ul(module_id_t module_id,
       /* if no data, pre-allocate 5RB */
       bool freeCCE = find_free_CCE(module_id, slot, UE_id);
       if (!freeCCE) {
-        LOG_D(MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE_info->rnti[UE_id]);
+        LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE_info->rnti[UE_id]);
         continue;
       }
       /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
@@ -973,20 +1026,22 @@ void pf_ul(module_id_t module_id,
       if (max_num_ue < 0)
         return;
 
+      LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d\n", min_rb,rbStart);
       while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
       if (rbStart + min_rb >= bwpSize) {
-        LOG_D(MAC, "cannot allocate continuous data for UE %d/RNTI %04x: no resources\n",
-              UE_id, UE_info->rnti[UE_id]);
-        continue;
+        LOG_W(NR_MAC, "cannot allocate continuous UL data for UE %d/RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n",
+              UE_id, UE_info->rnti[UE_id],rbStart,min_rb,bwpSize);
+        return;
       }
 
       /* Save PUSCH field */
       /* we want to avoid a lengthy deduction of DMRS and other parameters in
        * every TTI if we can save it, so check whether dci_format, TDA, or
        * num_dmrs_cdm_grps_no_data has changed and only then recompute */
+      const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_ubwp ? 1 : 2;
       const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
-      const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
-      const int tda = nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot];
+      const int dci_format = sched_ctrl->active_ubwp ? (f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : NR_UL_DCI_FORMAT_0_0;
+      const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
       if (ps->time_domain_allocation != tda
           || ps->dci_format != dci_format
           || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
@@ -1021,7 +1076,7 @@ void pf_ul(module_id_t module_id,
     sched_pusch->mcs = 9;
     const uint32_t tbs = ul_pf_tbs[ps->mcs_table][sched_pusch->mcs];
     coeff_ue[UE_id] = (float) tbs / ul_thr_ue[UE_id];
-    LOG_D(MAC,"b %d, ul_thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
+    LOG_D(NR_MAC,"b %d, ul_thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
           b, UE_id, ul_thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]);
   }
 
@@ -1047,7 +1102,7 @@ void pf_ul(module_id_t module_id,
 
     bool freeCCE = find_free_CCE(module_id, slot, UE_id);
     if (!freeCCE) {
-      LOG_D(MAC, "%4d.%2d no free CCE for UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
+      LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
       continue;
     }
 
@@ -1057,10 +1112,9 @@ void pf_ul(module_id_t module_id,
       return;
 
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
-    int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    /* for some reason, the UEs do not like when they are scheduled on the last
-     * RB. Hence, as a (hopefully temporary) fix, schedule one RB less. */
-    const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) - 1;
+    NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
+    int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0;
+    const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
     NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
     NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
 
@@ -1070,13 +1124,20 @@ void pf_ul(module_id_t module_id,
     while (rbStart + max_rbSize < bwpSize && rballoc_mask[rbStart + max_rbSize])
       max_rbSize++;
 
+    if (rbStart + min_rb >= bwpSize) {
+      LOG_W(NR_MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n",
+	    UE_id, UE_info->rnti[UE_id],rbStart,min_rb,bwpSize);
+      return;
+    }
+
     /* Save PUSCH field */
     /* we want to avoid a lengthy deduction of DMRS and other parameters in
      * every TTI if we can save it, so check whether dci_format, TDA, or
      * num_dmrs_cdm_grps_no_data has changed and only then recompute */
+    const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_ubwp ? 1 : 2;
     const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
-    const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
-    const int tda = nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot];
+    const int dci_format = sched_ctrl->active_ubwp ? (f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : NR_UL_DCI_FORMAT_0_0;
+    const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
     if (ps->time_domain_allocation != tda
         || ps->dci_format != dci_format
         || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
@@ -1126,10 +1187,10 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
    * schedule now (slot + k2 is not UL slot) */
   int UE_id = UE_info->list.head;
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
-  const int tda = nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot];
+  const int tda = sched_ctrl->active_ubwp ? nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
   if (tda < 0)
     return false;
-  int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu);
+  int K2 = get_K2(scc, sched_ctrl->active_ubwp, tda, mu);
   const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
   const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
   if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot))
@@ -1139,6 +1200,8 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
   sched_ctrl->sched_pusch.frame = sched_frame;
   for (UE_id = UE_info->list.next[UE_id]; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+    AssertFatal(K2 == get_K2(scc,sched_ctrl->active_ubwp, tda, mu),
+                "Different K2, %d(UE%d) != %ld(UE%d)\n", K2, 0, get_K2(scc,sched_ctrl->active_ubwp, tda, mu), UE_id);
     sched_ctrl->sched_pusch.slot = sched_slot;
     sched_ctrl->sched_pusch.frame = sched_frame;
   }
@@ -1148,13 +1211,18 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
    * Calculate largest contiguous RBs */
   uint16_t *vrb_map_UL =
       &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
-  const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-  const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
-    sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+  const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp ?
+                                    sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth:
+                                    scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
+                                    MAX_BWP_SIZE);
+  const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_ubwp ?
+    sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
+    scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
   const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
   int startSymbolIndex, nrOfSymbols;
   SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
   const uint16_t symb = ((1 << nrOfSymbols) - 1) << startSymbolIndex;
+
   int st = 0, e = 0, len = 0;
   for (int i = 0; i < bwpSize; i++) {
     while ((vrb_map_UL[i] & symb) != 0 && i < bwpSize)
@@ -1222,7 +1290,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
   /* Uplink data ONLY can be scheduled when the current slot is downlink slot,
    * because we have to schedule the DCI0 first before schedule uplink data */
   if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slot / 64], slot)) {
-    LOG_D(MAC, "Current slot %d is NOT DL slot, cannot schedule DCI0 for UL data\n", slot);
+    LOG_D(NR_MAC, "Current slot %d is NOT DL slot, cannot schedule DCI0 for UL data\n", slot);
     return;
   }
   bool do_sched = RC.nrmac[module_id]->pre_processor_ul(module_id, frame, slot);
@@ -1243,11 +1311,13 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
   const NR_list_t *UE_list = &UE_info->list;
   for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+    if (sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) continue;
     UE_info->mac_stats[UE_id].ulsch_current_bytes = 0;
 
     /* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in
      * every TTI are pre-populated by the preprocessor and used below */
     NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
+    LOG_D(NR_MAC,"UE %x : sched_pusch->rbSize %d\n",UE_info->rnti[UE_id],sched_pusch->rbSize);
     if (sched_pusch->rbSize <= 0)
       continue;
 
@@ -1297,7 +1367,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
       cur_harq->sched_pusch.time_domain_allocation = ps->time_domain_allocation;
       sched_ctrl->sched_ul_bytes += sched_pusch->tb_size;
     } else {
-      LOG_D(MAC,
+      LOG_D(NR_MAC,
             "%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n",
             frame,
             slot,
@@ -1312,7 +1382,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
     sched_ctrl->last_ul_frame = sched_pusch->frame;
     sched_ctrl->last_ul_slot = sched_pusch->slot;
 
-    LOG_D(MAC,
+    LOG_D(NR_MAC,
           "%4d.%2d RNTI %04x UL sched %4d.%2d start %2d RBS %3d startSymbol %2d nb_symbol %2d MCS %2d TBS %4d HARQ PID %2d round %d NDI %d est %6d sched %6d est BSR %6d\n",
           frame,
           slot,
@@ -1349,16 +1419,18 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
     memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
     future_ul_tti_req->n_pdus += 1;
 
-    LOG_D(MAC, "%4d.%2d Scheduling UE specific PUSCH\n", frame, slot);
+    LOG_D(NR_MAC, "%4d.%2d Scheduling UE specific PUSCH for sched %d.%d, ul_tto_req %d.%d\n", frame, slot,
+    sched_pusch->frame,sched_pusch->slot,future_ul_tti_req->SFN,future_ul_tti_req->Slot);
 
     pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
     pusch_pdu->rnti = rnti;
     pusch_pdu->handle = 0; //not yet used
 
     /* FAPI: BWP */
-    pusch_pdu->bwp_size  = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    pusch_pdu->bwp_start = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    pusch_pdu->subcarrier_spacing = sched_ctrl->active_ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+    NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters:&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
+    pusch_pdu->bwp_size  = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+    pusch_pdu->bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+    pusch_pdu->subcarrier_spacing = genericParameters->subcarrierSpacing;
     pusch_pdu->cyclic_prefix = 0;
 
     /* FAPI: PUSCH information always included */
@@ -1367,7 +1439,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
     pusch_pdu->mcs_index = sched_pusch->mcs;
     pusch_pdu->mcs_table = ps->mcs_table;
     pusch_pdu->transform_precoding = ps->transform_precoding;
-    if (ps->pusch_Config->dataScramblingIdentityPUSCH)
+    if (ps->pusch_Config &&
+	      ps->pusch_Config->dataScramblingIdentityPUSCH)
       pusch_pdu->data_scrambling_id = *ps->pusch_Config->dataScramblingIdentityPUSCH;
     else
       pusch_pdu->data_scrambling_id = *scc->physCellId;
@@ -1377,10 +1450,10 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
     pusch_pdu->ul_dmrs_symb_pos = ps->ul_dmrs_symb_pos;
     pusch_pdu->dmrs_config_type = ps->dmrs_config_type;
     if (pusch_pdu->transform_precoding) { // transform precoding disabled
-      long *scramblingid;
-      if (pusch_pdu->scid == 0)
+      long *scramblingid=NULL;
+      if (ps->NR_DMRS_UplinkConfig && pusch_pdu->scid == 0)
         scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0;
-      else
+      else if (ps->NR_DMRS_UplinkConfig)
         scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID1;
       if (scramblingid == NULL)
         pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
@@ -1389,9 +1462,9 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
     }
     else {
       pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
-      if (ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL)
+      if (ps->NR_DMRS_UplinkConfig && ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL)
         pusch_pdu->pusch_identity = *ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity;
-      else
+      else if (ps->NR_DMRS_UplinkConfig)
         pusch_pdu->pusch_identity = *scc->physCellId;
     }
     pusch_pdu->scid = 0;      // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]
@@ -1399,13 +1472,11 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
     pusch_pdu->dmrs_ports = 1;
 
     /* FAPI: Pusch Allocation in frequency domain */
-    AssertFatal(ps->pusch_Config->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1,
-                "Only frequency resource allocation type 1 is currently supported\n");
     pusch_pdu->resource_alloc = 1; //type 1
     pusch_pdu->rb_start = sched_pusch->rbStart;
     pusch_pdu->rb_size = sched_pusch->rbSize;
     pusch_pdu->vrb_to_prb_mapping = 0;
-    if (ps->pusch_Config->frequencyHopping==NULL)
+    if (ps->pusch_Config==NULL || ps->pusch_Config->frequencyHopping==NULL)
       pusch_pdu->frequency_hopping = 0;
     else
       pusch_pdu->frequency_hopping = 1;
@@ -1429,8 +1500,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
       pusch_pdu->dfts_ofdm.low_papr_group_number = pusch_pdu->pusch_identity % 30;
 
       // V as specified in section 6.4.1.1.1.2 in 38.211 V = 0 if sequence hopping and group hopping are disabled
-      if ((ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceGroupHopping == NULL) &&
-            (ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceHopping == NULL))
+      if ((ps->NR_DMRS_UplinkConfig==NULL) || ((ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceGroupHopping == NULL) &&
+					       (ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceHopping == NULL)))
         pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0;
       else
         AssertFatal(1==0,"SequenceGroupHopping or sequenceHopping are NOT Supported\n");
@@ -1441,7 +1512,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
     /*-----------------------------------------------------------------------------*/
 
     /* PUSCH PTRS */
-    if (ps->NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) {
+    if (ps->NR_DMRS_UplinkConfig && ps->NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) {
       bool valid_ptrs_setup = false;
       pusch_pdu->pusch_ptrs.ptrs_ports_list   = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
       valid_ptrs_setup = set_ul_ptrs_values(ps->NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup,
@@ -1459,8 +1530,10 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
 
     /* look up the PDCCH PDU for this BWP and CORESET. If it does not exist,
      * create it */
-    const int bwpid = sched_ctrl->active_bwp->bwp_Id;
-    const int coresetid = sched_ctrl->coreset->controlResourceSetId;
+    const int bwpid = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0;
+    NR_SearchSpace_t *ss = sched_ctrl->active_bwp ? sched_ctrl->search_space: RC.nrmac[module_id]->sched_ctrlCommon->search_space;
+    NR_ControlResourceSet_t *coreset = sched_ctrl->active_bwp? sched_ctrl->coreset: RC.nrmac[module_id]->sched_ctrlCommon->coreset;
+    const int coresetid = coreset->controlResourceSetId;
     nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = pdcch_pdu_bwp_coreset[bwpid][coresetid];
     if (!pdcch_pdu) {
       nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus];
@@ -1469,19 +1542,19 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
       ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
       pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
       ul_dci_req->numPdus += 1;
-      nr_configure_pdcch(pdcch_pdu, sched_ctrl->search_space, sched_ctrl->coreset, scc, sched_ctrl->active_bwp);
+      nr_configure_pdcch(pdcch_pdu, ss, coreset, scc, sched_ctrl->active_bwp);
       pdcch_pdu_bwp_coreset[bwpid][coresetid] = pdcch_pdu;
     }
 
-    LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frame,slot);
+    LOG_D(NR_MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frame,slot);
 
     /* Fill PDCCH DL DCI PDU */
     nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu->dci_pdu[pdcch_pdu->numDlDci];
     pdcch_pdu->numDlDci++;
     dci_pdu->RNTI = rnti;
-    if (sched_ctrl->coreset->pdcch_DMRS_ScramblingID &&
-        sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) {
-      dci_pdu->ScramblingId = *sched_ctrl->coreset->pdcch_DMRS_ScramblingID;
+    if (coreset->pdcch_DMRS_ScramblingID &&
+        ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) {
+      dci_pdu->ScramblingId = *coreset->pdcch_DMRS_ScramblingID;
       dci_pdu->ScramblingRNTI = rnti;
     } else {
       dci_pdu->ScramblingId = *scc->physCellId;
@@ -1494,24 +1567,30 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
 
     dci_pdu_rel15_t uldci_payload;
     memset(&uldci_payload, 0, sizeof(uldci_payload));
-    NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
-    const int n_ubwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
+    NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id];
+    int n_ubwp=1;
+    if (CellGroup && CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated &&
+        CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+        CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList)
+      n_ubwp = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
+
     config_uldci(sched_ctrl->active_ubwp,
+		             scc,
                  pusch_pdu,
                  &uldci_payload,
                  ps->dci_format,
                  ps->time_domain_allocation,
                  UE_info->UE_sched_ctrl[UE_id].tpc0,
                  n_ubwp,
-                 sched_ctrl->active_bwp->bwp_Id);
+                 bwpid);
     fill_dci_pdu_rel15(scc,
-                       secondaryCellGroup,
+                       CellGroup,
                        dci_pdu,
                        &uldci_payload,
                        ps->dci_format,
                        rnti_types[0],
                        pusch_pdu->bwp_size,
-                       sched_ctrl->active_bwp->bwp_Id);
+                       bwpid);
 
     memset(sched_pusch, 0, sizeof(*sched_pusch));
   }
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 1010ebafda335f12bfb37cd164ee0fc5de610418..ca12081a6ffe7279e91f8a8a38b470db81ad3021 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -51,12 +51,10 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
                            int ssb_SubcarrierOffset,
                            int pdsch_AntennaPorts,
                            int pusch_AntennaPorts,
-                           int pusch_tgt_snrx10,
-                           int pucch_tgt_snrx10,
                            NR_ServingCellConfigCommon_t *scc,
-			   int nsa_flag,
-			   uint32_t rnti,
-			   NR_CellGroupConfig_t *secondaryCellGroup
+		                  	   int nsa_flag,
+			                     uint32_t rnti,
+			                     NR_CellGroupConfig_t *CellGroup
                            );
 
 void clear_nr_nfapi_information(gNB_MAC_INST * gNB, 
@@ -167,6 +165,7 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
 
 
 void config_uldci(const NR_BWP_Uplink_t *ubwp,
+		              const NR_ServingCellConfigCommon_t *scc,
                   const nfapi_nr_pusch_pdu_t *pusch_pdu,
                   dci_pdu_rel15_t *dci_pdu_rel15,
                   int dci_format,
@@ -187,9 +186,10 @@ void nr_csi_meas_reporting(int Mod_idP,
                            sub_frame_t slotP);
 
 int nr_acknack_scheduling(int Mod_idP,
-                          int UE_id,
-                          frame_t frameP,
-                          sub_frame_t slotP);
+                           int UE_id,
+                           frame_t frameP,
+                           sub_frame_t slotP,
+                           int r_pucch);
 
 void get_pdsch_to_harq_feedback(int Mod_idP,
                                 int UE_id,
@@ -216,13 +216,15 @@ int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space,
 */
 
 void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
-			NR_ServingCellConfigCommon_t *scc,
-			NR_BWP_Uplink_t *bwp,
+                        NR_ServingCellConfigCommon_t *scc,
+                        NR_CellGroupConfig_t *CellGroup,
+                        NR_BWP_Uplink_t *bwp,
                         uint16_t rnti,
                         uint8_t pucch_resource,
                         uint16_t O_csi,
                         uint16_t O_ack,
-                        uint8_t O_sr);
+                        uint8_t O_sr,
+			                  int r_pucch);
 
 void find_search_space(int ss_type,
                        NR_BWP_Downlink_t *bwp,
@@ -235,7 +237,7 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
                         NR_BWP_Downlink_t *bwp);
 
 void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
-                        const NR_CellGroupConfig_t *secondaryCellGroup,
+                        const NR_CellGroupConfig_t *CellGroup,
                         nfapi_nr_dl_dci_pdu_t *pdcch_dci_pdu,
                         dci_pdu_rel15_t *dci_pdu_rel15,
                         int dci_formats,
@@ -243,18 +245,23 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
                         int N_RB,
                         int bwp_id);
 
-void prepare_dci(const NR_CellGroupConfig_t *secondaryCellGroup,
+void prepare_dci(const NR_CellGroupConfig_t *CellGroup,
                  dci_pdu_rel15_t *dci_pdu_rel15,
                  nr_dci_format_t format,
                  int bwp_id);
 
 /* find coreset within the search space */
-NR_ControlResourceSet_t *get_coreset(const NR_BWP_Downlink_t *bwp, const NR_SearchSpace_t *ss, int ss_type);
+NR_ControlResourceSet_t *get_coreset(NR_ServingCellConfigCommon_t *scc,
+                                     NR_BWP_Downlink_t *bwp,
+                                     NR_SearchSpace_t *ss,
+                                     NR_SearchSpace__searchSpaceType_PR ss_type);
 
 /* find a search space within a BWP */
-NR_SearchSpace_t *get_searchspace(const NR_BWP_Downlink_t *bwp, NR_SearchSpace__searchSpaceType_PR target_ss);
+NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc,
+                                  NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
+                                  NR_SearchSpace__searchSpaceType_PR target_ss);
 
-long get_K2(const NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu);
+long get_K2(NR_ServingCellConfigCommon_t *scc, NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu);
 
 void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
                               const NR_CellGroupConfig_t *secondaryCellGroup,
@@ -306,7 +313,7 @@ int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP);
 
 int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP);
 
-int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secondaryCellGroup);
+int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup);
 
 void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti);
 
@@ -329,6 +336,8 @@ uint16_t compute_pucch_prb_size(uint8_t format,
                                 uint8_t n_symb,
                                 uint8_t n_re_ctrl);
 
+int nr_get_default_pucch_res(int pucch_ResourceCommon);
+
 void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_info, int UE_id, module_id_t Mod_idP);
 
 int get_dlscs(nfapi_nr_config_request_t *cfg);
diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c
index 60b0cac21525ec5c41cfef67e3328080da785890..9974c08a18a94275dcda1bc52ecc9e80467b9a96 100644
--- a/openair2/LAYER2/NR_MAC_gNB/main.c
+++ b/openair2/LAYER2/NR_MAC_gNB/main.c
@@ -96,12 +96,12 @@ void mac_top_init_gNB(void)
     // These should be out of here later
     pdcp_layer_init();
 
-    if(IS_SOFTMODEM_NOS1 && !(get_softmodem_params()->do_ra || get_softmodem_params()->sa) )
+    if(IS_SOFTMODEM_NOS1 && get_softmodem_params()->phy_test)
       nr_DRB_preconfiguration(0x1234);
 
     rrc_init_nr_global_param();
 
-  }else {
+  } else {
     RC.nrmac = NULL;
   }
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index bd7304ad8f8df7dc872fbf7f31ddfe1f871204b0..1f9cfff1e8354e0e571fc1f1a5834bc520d1989e 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -160,8 +160,8 @@ typedef struct {
   NR_SearchSpace_t *ra_ss;
   // Beam index
   uint8_t beam_id;
-  /// secondaryCellGroup for UE in NSA that is to come
-  NR_CellGroupConfig_t *secondaryCellGroup;
+  /// CellGroup for UE that is to come (NSA is non-null, null for SA)
+  NR_CellGroupConfig_t *CellGroup;
   /// Preambles for contention-free access
   NR_preamble_ue_t preambles;
   /// NSA: the UEs C-RNTI to use
@@ -303,6 +303,7 @@ typedef struct NR_sched_pucch {
   uint8_t dai_c;
   uint8_t timing_indicator;
   uint8_t resource_indicator;
+  int r_pucch;
 } NR_sched_pucch_t;
 
 /* PUSCH semi-static configuration: as long as the TDA and DCI format remain
@@ -557,6 +558,7 @@ typedef struct {
   /// per-LC status data
   mac_rlc_status_resp_t rlc_status[MAX_NUM_LCID];
 
+  int lcid_mask;
   uint16_t ta_frame;
   int16_t ta_update;
   bool ta_apply;
@@ -565,7 +567,11 @@ typedef struct {
   int raw_rssi;
   int pusch_snrx10;
   int pucch_snrx10;
-
+  uint16_t ul_rssi;
+  uint8_t current_harq_pid;
+  int pusch_consecutive_dtx_cnt;
+  int pucch_consecutive_dtx_cnt;
+  int ul_failure;
   struct CSI_Report CSI_report[MAX_CSI_REPORTS];
   bool SR;
 
@@ -602,6 +608,7 @@ typedef struct {
   int dlsch_current_bytes;
   int ulsch_rounds[8];
   int ulsch_errors;
+  int ulsch_DTX;
   int ulsch_total_bytes_scheduled;
   int ulsch_total_bytes_rx;
   int ulsch_current_bytes;
@@ -622,13 +629,14 @@ typedef struct {
 
   bool active[MAX_MOBILES_PER_GNB];
   rnti_t rnti[MAX_MOBILES_PER_GNB];
-  NR_CellGroupConfig_t *secondaryCellGroup[MAX_MOBILES_PER_GNB];
+  NR_CellGroupConfig_t *CellGroup[MAX_MOBILES_PER_GNB];
   /// CCE indexing
   int Y[MAX_MOBILES_PER_GNB][3][160];
   int m[MAX_MOBILES_PER_GNB];
   int num_pdcch_cand[MAX_MOBILES_PER_GNB][MAX_NUM_CORESET];
   // UE selected beam index
   uint8_t UE_beam_index[MAX_MOBILES_PER_GNB];
+  bool Msg4_ACKed[MAX_MOBILES_PER_GNB];
 } NR_UE_info_t;
 
 typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
@@ -654,6 +662,10 @@ typedef struct gNB_MAC_INST_s {
   int                             pusch_target_snrx10;
   /// Pucch target SNR
   int                             pucch_target_snrx10;
+  /// PUCCH Failure threshold (compared to consecutive PUCCH DTX)
+  int                             pucch_failure_thres;
+  /// PUSCH Failure threshold (compared to consecutive PUSCH DTX)
+  int                             pusch_failure_thres;
   /// Subcarrier Offset
   int                             ssb_SubcarrierOffset;
   /// Common cell resources
@@ -733,7 +745,6 @@ typedef struct gNB_MAC_INST_s {
   nr_pp_impl_ul pre_processor_ul;
 
   NR_UE_sched_ctrl_t *sched_ctrlCommon;
-  NR_CellGroupConfig_t *secondaryCellGroupCommon;
   NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64];
 
 } gNB_MAC_INST;
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent.h b/openair2/LAYER2/PROTO_AGENT/proto_agent.h
index 6898c9e447421ab954a86a21dd3c6dd387da45bb..32bf5aa13c7793f07732c4af25d208f6133f45ec 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent.h
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent.h
@@ -30,6 +30,8 @@
 #define PROTO_AGENT_H_
 #include "ENB_APP/enb_config.h" // for enb properties
 #include "proto_agent_common.h"
+#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
+#include "RRC/NR/nr_rrc_defs.h"
 
 
 void *proto_agent_receive(void *args);
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c
index e0adfefa038f78cc305020d0bc738ae9bc8f3ba1..f19d7526fe3dc0467bb346ccd8d1a5ed36c4d263 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c
@@ -33,10 +33,9 @@
 #include "PHY/phy_extern.h"
 #include "proto_agent_common.h"
 #include "common/utils/LOG/log.h"
+#include "common/ran_context.h"
 
-#include "RRC/LTE/rrc_extern.h"
-#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
-#include "rrc_eNB_UE_context.h"
+extern RAN_CONTEXT_t RC;
 
 /*
  * message primitives
@@ -364,28 +363,23 @@ int proto_agent_pdcp_data_req_process(mod_id_t mod_id, const void *params, Proto
   pdcp_pdu_size = rlc_data->fsp_pdu->fsp_pdu_data.len;
   pdcp_pdu_p = get_free_mem_block(pdcp_pdu_size, __func__);
 
-  if (!pdcp_pdu_p) goto error;
+  if (!pdcp_pdu_p) {
+    LOG_E(PROTO_AGENT, "%s: an error occured\n", __FUNCTION__);
+    return -1;
+  }
 
   memcpy(pdcp_pdu_p->data, rlc_data->fsp_pdu->fsp_pdu_data.data, pdcp_pdu_size);
-  result = rlc_data_req(&ctxt_pP
-                        ,srb_flagP
-                        ,flag_MBMS
-                        ,rb_idP
-                        ,muiP
-                        ,confirmP
-                        ,pdcp_pdu_size
-                        ,pdcp_pdu_p
-                        ,NULL
-                        ,NULL
-                       );
+  if (RC.nrrrc) {
+    LOG_D(PROTO_AGENT, "proto_agent received pdcp_data_req \n");
+    // for (int i = 0; i < pdcp_pdu_size; i++)
+    //   printf(" %2.2x", (unsigned char)pdcp_pdu_p->data[i]);
+    // printf("\n");
+    du_rlc_data_req(&ctxt_pP, srb_flagP, flag_MBMS, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p);
+    result = 1;
+  } else {
+    result = rlc_data_req(&ctxt_pP, srb_flagP, flag_MBMS, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p, NULL, NULL);
+  }
   return result;
-error:
-
-  if (pdcp_pdu_p)
-    free_mem_block(pdcp_pdu_p, __func__);
-
-  LOG_E(PROTO_AGENT, "%s: an error occured\n", __FUNCTION__);
-  return -1;
 }
 
 int proto_agent_destroy_pdcp_data_ind(Protocol__FlexsplitMessage *msg) {
@@ -531,6 +525,8 @@ int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Proto
   ctxt_pP.rnti = ctxt->fsp_rnti;
   ctxt_pP.frame = ctxt->fsp_frame;
   ctxt_pP.subframe = ctxt->fsp_subframe;
+  ctxt_pP.configured = 1;
+  ctxt_pP.brOption = 0;
   ctxt_pP.eNB_index = ctxt->fsp_enb_index;
   srb_flagP = rlc_data->fsp_srb_flag;
   flag_MBMS = rlc_data->fsp_mbms_flag;
diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h
index ef5f824ba06d045c1ced611796b283b161a346dc..1e5b7947d7a384f209776fce7a9af2136e3eda04 100644
--- a/openair2/LAYER2/RLC/rlc.h
+++ b/openair2/LAYER2/RLC/rlc.h
@@ -624,6 +624,14 @@ rlc_op_status_t rlc_stat_req     (
 */
 int rlc_module_init(int enb_flag);
 
+void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
+                     const srb_flag_t   srb_flagP,
+                     const MBMS_flag_t  MBMS_flagP,
+                     const rb_id_t      rb_idP,
+                     const mui_t        muiP,
+                     confirm_t    confirmP,
+                     sdu_size_t   sdu_sizeP,
+                     mem_block_t *sdu_pP);
 /** @} */
 
 #define RLC_FG_COLOR_BLACK            "\e[0;30m"
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp.h b/openair2/LAYER2/nr_pdcp/nr_pdcp.h
new file mode 100644
index 0000000000000000000000000000000000000000..94939a0421751edd723bc3ae12f89e03c0880b99
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp.h
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#include <stdint.h>
+
+#ifndef _NR_PDCP_H_
+#define _NR_PDCP_H_
+
+void nr_pdcp_layer_init_ue(void);
+void nr_DRB_preconfiguration(uint16_t crnti);
+
+#endif /* _NR_PDCP_H_ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
index 748f1526eb2b2a8cb9290b387abb05346f0bce5e..0b5d0ad4866f8a89b190ea0cca5f424aa9fc9fe3 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
@@ -49,7 +49,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
     return;
   }
 
-  if (!(buffer[0] & 0x80)) {
+  if (entity->type != NR_PDCP_SRB && !(buffer[0] & 0x80)) {
     LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
     exit(1);
   }
@@ -65,7 +65,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
     header_size = 3;
   }
 
-  if (entity->has_integrity) {
+  /* SRBs always have MAC-I, even if integrity is not active */
+  if (entity->has_integrity || entity->type == NR_PDCP_SRB) {
     integrity_size = 4;
   } else {
     integrity_size = 0;
@@ -99,9 +100,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
     entity->integrity(entity->integrity_context, integrity,
                       buffer, size - integrity_size,
                       entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
-    if (memcmp(integrity, buffer, 4) != 0) {
+    if (memcmp(integrity, buffer + size - integrity_size, 4) != 0) {
       LOG_E(PDCP, "discard NR PDU, integrity failed\n");
-      return;
     }
   }
 
@@ -180,7 +180,8 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
     header_size = 3;
   }
 
-  if (entity->has_integrity) {
+  /* SRBs always have MAC-I, even if integrity is not active */
+  if (entity->has_integrity || entity->type == NR_PDCP_SRB) {
     integrity_size = 4;
   } else {
     integrity_size = 0;
@@ -194,6 +195,10 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
                       (unsigned char *)buf, header_size + size,
                       entity->rb_id, count, entity->is_gnb ? 1 : 0);
 
+  // set MAC-I to 0 for SRBs with integrity not active
+  else if (integrity_size == 4)
+    memset(buf + header_size + size, 0, 4);
+
   if (entity->has_ciphering)
     entity->cipher(entity->security_context,
                    (unsigned char *)buf + header_size, size + integrity_size,
@@ -205,12 +210,61 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
                       header_size + size + integrity_size, sdu_id);
 }
 
-static void nr_pdcp_entity_set_integrity_key(nr_pdcp_entity_t *entity,
-                                             char *key)
+/* may be called several times, take care to clean previous settings */
+static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity,
+                                        int integrity_algorithm,
+                                        char *integrity_key,
+                                        int ciphering_algorithm,
+                                        char *ciphering_key)
 {
-  LOG_E(PDCP, "%s: %d: %s: TODO? to remove?\n", __FILE__, __LINE__, __FUNCTION__);
-  exit(1);
-  //memcpy(entity->integrity_key, key, 16);
+  if (integrity_algorithm != -1)
+    entity->integrity_algorithm = integrity_algorithm;
+  if (ciphering_algorithm != -1)
+    entity->ciphering_algorithm = ciphering_algorithm;
+  if (integrity_key != NULL)
+    memcpy(entity->integrity_key, integrity_key, 16);
+  if (ciphering_key != NULL)
+    memcpy(entity->ciphering_key, ciphering_key, 16);
+
+  if (integrity_algorithm == 0) {
+    entity->has_integrity = 0;
+    if (entity->free_integrity != NULL)
+      entity->free_integrity(entity->integrity_context);
+    entity->free_integrity = NULL;
+  }
+
+  if (integrity_algorithm != 0 && integrity_algorithm != -1) {
+    if (integrity_algorithm != 2) {
+      LOG_E(PDCP, "FATAL: only nia2 supported for the moment\n");
+      exit(1);
+    }
+    entity->has_integrity = 1;
+    if (entity->free_integrity != NULL)
+      entity->free_integrity(entity->integrity_context);
+    entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key);
+    entity->integrity = nr_pdcp_integrity_nia2_integrity;
+    entity->free_integrity = nr_pdcp_integrity_nia2_free_integrity;
+  }
+
+  if (ciphering_algorithm == 0) {
+    entity->has_ciphering = 0;
+    if (entity->free_security != NULL)
+      entity->free_security(entity->security_context);
+    entity->free_security = NULL;
+  }
+
+  if (ciphering_algorithm != 0 && ciphering_algorithm != -1) {
+    if (ciphering_algorithm != 2) {
+      LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n");
+      exit(1);
+    }
+    entity->has_ciphering = 1;
+    if (entity->free_security != NULL)
+      entity->free_security(entity->security_context);
+    entity->security_context = nr_pdcp_security_nea2_init(entity->ciphering_key);
+    entity->cipher = nr_pdcp_security_nea2_cipher;
+    entity->free_security = nr_pdcp_security_nea2_free_security;
+  }
 }
 
 static void check_t_reordering(nr_pdcp_entity_t *entity)
@@ -282,7 +336,8 @@ void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity)
 
 nr_pdcp_entity_t *new_nr_pdcp_entity(
     nr_pdcp_entity_type_t type,
-    int is_gnb, int rb_id,
+    int is_gnb, int rb_id, int pdusession_id,int has_sdap,
+    int has_sdapULheader, int has_sdapDLheader,
     void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
                         char *buf, int size),
     void *deliver_sdu_data,
@@ -307,10 +362,10 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
 
   ret->type = type;
 
-  ret->recv_pdu          = nr_pdcp_entity_recv_pdu;
-  ret->recv_sdu          = nr_pdcp_entity_recv_sdu;
-  ret->set_integrity_key = nr_pdcp_entity_set_integrity_key;
-  ret->set_time          = nr_pdcp_entity_set_time;
+  ret->recv_pdu     = nr_pdcp_entity_recv_pdu;
+  ret->recv_sdu     = nr_pdcp_entity_recv_sdu;
+  ret->set_security = nr_pdcp_entity_set_security;
+  ret->set_time     = nr_pdcp_entity_set_time;
 
   ret->delete = nr_pdcp_entity_delete;
 
@@ -321,6 +376,10 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
   ret->deliver_pdu_data = deliver_pdu_data;
 
   ret->rb_id         = rb_id;
+  ret->pdusession_id = pdusession_id;
+  ret->has_sdap      = has_sdap;
+  ret->has_sdapULheader = has_sdapULheader;
+  ret->has_sdapDLheader = has_sdapDLheader;
   ret->sn_size       = sn_size;
   ret->t_reordering  = t_reordering;
   ret->discard_timer = discard_timer;
@@ -328,34 +387,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
   ret->sn_max        = (1 << sn_size) - 1;
   ret->window_size   = 1 << (sn_size - 1);
 
-  if (ciphering_key != NULL && ciphering_algorithm != 0) {
-    if (ciphering_algorithm != 2) {
-      LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n");
-      exit(1);
-    }
-    ret->has_ciphering = 1;
-    ret->ciphering_algorithm = ciphering_algorithm;
-    memcpy(ret->ciphering_key, ciphering_key, 16);
-
-    ret->security_context = nr_pdcp_security_nea2_init(ciphering_key);
-    ret->cipher = nr_pdcp_security_nea2_cipher;
-    ret->free_security = nr_pdcp_security_nea2_free_security;
-  }
   ret->is_gnb = is_gnb;
 
-  if (integrity_key != NULL && integrity_algorithm != 0) {
-    if (integrity_algorithm != 2) {
-      LOG_E(PDCP, "FATAL: only nia2 supported for the moment\n");
-      exit(1);
-    }
-    ret->has_integrity = 1;
-    ret->integrity_algorithm = integrity_algorithm;
-    memcpy(ret->integrity_key, integrity_key, 16);
-
-    ret->integrity_context = nr_pdcp_integrity_nia2_init(integrity_key);
-    ret->integrity = nr_pdcp_integrity_nia2_integrity;
-    ret->free_integrity = nr_pdcp_integrity_nia2_free_integrity;
-  }
+  nr_pdcp_entity_set_security(ret,
+                              integrity_algorithm, (char *)integrity_key,
+                              ciphering_algorithm, (char *)ciphering_key);
 
   return ret;
 }
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
index 2d391eb3e065e0e67e8aefdab601e58f572cbd03..fbcc2b96cd37d31cb35a02277721b4da6dee85d0 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
@@ -40,7 +40,18 @@ typedef struct nr_pdcp_entity_t {
   void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
                    int sdu_id);
   void (*delete)(struct nr_pdcp_entity_t *entity);
-  void (*set_integrity_key)(struct nr_pdcp_entity_t *entity, char *key);
+
+  /* set_security: pass -1 to integrity_algorithm / ciphering_algorithm
+   *               to keep the current algorithm
+   *               pass NULL to integrity_key / ciphering_key
+   *               to keep the current key
+   */
+  void (*set_security)(struct nr_pdcp_entity_t *entity,
+                       int integrity_algorithm,
+                       char *integrity_key,
+                       int ciphering_algorithm,
+                       char *ciphering_key);
+
   void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now);
 
   /* callbacks provided to the PDCP module */
@@ -53,7 +64,10 @@ typedef struct nr_pdcp_entity_t {
 
   /* configuration variables */
   int rb_id;
-
+  int pdusession_id;
+  int has_sdap;
+  int has_sdapULheader;
+  int has_sdapDLheader;
   int sn_size;                  /* SN size, in bits */
   int t_reordering;             /* unit: ms, -1 for infinity */
   int discard_timer;            /* unit: ms, -1 for infinity */
@@ -104,7 +118,8 @@ typedef struct nr_pdcp_entity_t {
 
 nr_pdcp_entity_t *new_nr_pdcp_entity(
     nr_pdcp_entity_type_t type,
-    int is_gnb, int rb_id,
+    int is_gnb, int rb_id, int pdusession_id,int has_sdap,
+    int has_sdapULheader,int has_sdapDLheader,
     void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
                         char *buf, int size),
     void *deliver_sdu_data,
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_srb.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_srb.c
new file mode 100644
index 0000000000000000000000000000000000000000..73840aeb0aae0da858d99c4bfd9cf2da841229ed
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_srb.c
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#include "nr_pdcp_entity_srb.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void nr_pdcp_entity_srb_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size)
+{
+  nr_pdcp_entity_srb_t *entity = (nr_pdcp_entity_srb_t *)_entity;
+
+  if (size < 2) abort();
+  entity->common.deliver_sdu(entity->common.deliver_sdu_data,
+                             (nr_pdcp_entity_t *)entity, buffer+2, size-6);
+}
+
+void nr_pdcp_entity_srb_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int size,
+                              int sdu_id)
+{
+  nr_pdcp_entity_srb_t *entity = (nr_pdcp_entity_srb_t *)_entity;
+  int sn;
+  char buf[size+6];
+
+  sn = entity->common.next_nr_pdcp_tx_sn;
+
+  entity->common.next_nr_pdcp_tx_sn++;
+  if (entity->common.next_nr_pdcp_tx_sn > entity->common.maximum_nr_pdcp_sn) {
+    entity->common.next_nr_pdcp_tx_sn = 0;
+    entity->common.tx_hfn++;
+  }
+
+  buf[0] = (sn >> 8) & 0x0f;
+  buf[1] = sn & 0xff;
+  memcpy(buf+2, buffer, size);
+
+  /* For now use padding for the MAC-I bytes (normally carrying message authentication code)
+   * which come after the data payload bytes (38.323, section 6.2.2.1) */
+  for (int i=size+2; i<size+6; i++)
+    buf[i] = 0x11*(i-size-1);
+
+  entity->common.deliver_pdu(entity->common.deliver_pdu_data,
+                             (nr_pdcp_entity_t *)entity, buf, size+6, sdu_id);
+}
+
+void nr_pdcp_entity_srb_set_integrity_key(nr_pdcp_entity_t *_entity, char *key)
+{
+  /* nothing to do */
+}
+
+void nr_pdcp_entity_srb_delete(nr_pdcp_entity_t *_entity)
+{
+  nr_pdcp_entity_srb_t *entity = (nr_pdcp_entity_srb_t *)_entity;
+  free(entity);
+}
+
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_srb.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_srb.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0f9d3e28f200c47e781064b3fb6fe22f750b33f
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_srb.h
@@ -0,0 +1,38 @@
+ /*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#ifndef _NR_PDCP_ENTITY_SRB_H_
+#define _NR_PDCP_ENTITY_SRB_H_
+
+#include "nr_pdcp_entity.h"
+
+typedef struct {
+  nr_pdcp_entity_t common;
+  int srb_id;
+} nr_pdcp_entity_srb_t;
+
+void nr_pdcp_entity_srb_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size);
+void nr_pdcp_entity_srb_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int size, int sdu_id);
+void nr_pdcp_entity_srb_set_integrity_key(nr_pdcp_entity_t *_entity, char *key);
+void nr_pdcp_entity_srb_delete(nr_pdcp_entity_t *_entity);
+
+
+#endif /* _NR_PDCP_ENTITY_SRB_H_ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
index 5553662ac524c2ee7ec9f01d80f152e920026df1..86f05586114e439201e9aee59ac57db2a9084025 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
@@ -45,7 +45,7 @@ static void compute_t(unsigned char *t, uint32_t count, int bearer,
   t[1] = (count >> 16) & 255;
   t[2] = (count >>  8) & 255;
   t[3] = (count      ) & 255;
-  t[4] = (bearer << 3) | (direction << 2);
+  t[4] = ((bearer-1) << 3) | (direction << 2);
   memset(&t[5], 0, 8-5);
 }
 
@@ -63,6 +63,7 @@ void nr_pdcp_integrity_nia2_integrity(void *integrity_context,
    * (which is identical to 128-NIA2, see 33.501 D.3.1.3) */
   compute_t(t, count, bearer, direction);
 
+  CMAC_Init(ctx, NULL, 0, NULL, NULL);
   CMAC_Update(ctx, t, 8);
   CMAC_Update(ctx, buffer, length);
   CMAC_Final(ctx, mac, &maclen);
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index c106d8e4fd02cf504633476083a6a6cb503cd143..1624c395efc3abc04d4a9604f8ffaf64314c109b 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -30,6 +30,7 @@
 #include "NR_RLC-Config.h"
 #include "NR_CellGroupConfig.h"
 #include "openair2/RRC/NR/nr_rrc_proto.h"
+#include <stdint.h>
 
 /* from OAI */
 #include "pdcp.h"
@@ -52,6 +53,9 @@ static int      nr_pdcp_current_time_last_subframe;
 hash_table_t  *pdcp_coll_p;
 static uint64_t pdcp_optmask;
 
+ngran_node_t node_type = ngran_gNB;
+uint8_t proto_agent_flag = 0;
+
 /****************************************************************************/
 /* rlc_data_req queue - begin                                               */
 /****************************************************************************/
@@ -186,6 +190,26 @@ static void enqueue_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
   if (pthread_mutex_unlock(&q.m) != 0) abort();
 }
 
+void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
+                     const srb_flag_t   srb_flagP,
+                     const MBMS_flag_t  MBMS_flagP,
+                     const rb_id_t      rb_idP,
+                     const mui_t        muiP,
+                     confirm_t    confirmP,
+                     sdu_size_t   sdu_sizeP,
+                     mem_block_t *sdu_pP)
+{
+  enqueue_rlc_data_req(ctxt_pP,
+                       srb_flagP,
+                       MBMS_flagP,
+                       rb_idP, muiP,
+                       confirmP,
+                       sdu_sizeP,
+                       sdu_pP,
+                       NULL,
+                       NULL);
+}
+
 /****************************************************************************/
 /* rlc_data_req queue - end                                                 */
 /****************************************************************************/
@@ -345,7 +369,10 @@ void pdcp_layer_init(void)
   if (pthread_mutex_unlock(&m) != 0) abort();
 
   nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1);
-  init_nr_rlc_data_req_queue();
+
+  if ((RC.nrrrc == NULL) || (!NODE_IS_CU(RC.nrrrc[0]->node_type))) {
+    init_nr_rlc_data_req_queue();
+  }
 
   nr_pdcp_init_timer_thread(nr_pdcp_ue_manager);
 }
@@ -437,22 +464,25 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
       exit(1);
 
     rb_found:
+    {
+      int offset=0;
+      if (entity->has_sdap == 1 && entity->has_sdapULheader == 1) offset = 1; // this is the offset of the SDAP header in bytes
+
       gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U,
-                                  size + GTPU_HEADER_OVERHEAD_MAX);
+                                  size + GTPU_HEADER_OVERHEAD_MAX - offset);
       AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY");
-      memcpy(&gtpu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], buf, size);
-      message_p = itti_alloc_new_message(TASK_PDCP_ENB, 0, GTPV1U_ENB_TUNNEL_DATA_REQ);
+      memcpy(&gtpu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], buf+offset, size-offset);
+      message_p = itti_alloc_new_message(TASK_PDCP_ENB, 0, GTPV1U_GNB_TUNNEL_DATA_REQ);
       AssertFatal(message_p != NULL, "OUT OF MEMORY");
-      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer       = gtpu_buffer_p;
-      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).length       = size;
-      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset       = GTPU_HEADER_OVERHEAD_MAX;
-      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti         = ue->rnti;
-      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id       = rb_id + 4;
-      LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size);
-      //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]);
-      //printf("\n");
+      GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).buffer              = gtpu_buffer_p;
+      GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).length              = size-offset;
+      GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).offset              = GTPU_HEADER_OVERHEAD_MAX;
+      GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).rnti                = ue->rnti;
+      GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).pdusession_id       = entity->pdusession_id;
+      if (offset==1) LOG_I(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]);
+      LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size-offset);
       itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p);
-
+   }
   }
 }
 
@@ -497,6 +527,105 @@ rb_found:
   enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock, NULL, NULL);
 }
 
+static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity,
+                            char *buf, int size)
+{
+  nr_pdcp_ue_t *ue = _ue;
+  int srb_id;
+  int i;
+
+  for (i = 0; i < 2; i++) {
+    if (entity == ue->srb[i]) {
+      srb_id = i+1;
+      goto srb_found;
+    }
+  }
+
+  LOG_E(PDCP, "%s:%d:%s: fatal, no SRB found for ue %d\n",
+	__FILE__, __LINE__, __FUNCTION__, ue->rnti);
+  exit(1);
+
+ srb_found:
+  {
+       uint8_t *rrc_buffer_p = entity->is_gnb ?
+					itti_malloc(TASK_PDCP_ENB, TASK_RRC_GNB, size):
+                                        itti_malloc(TASK_PDCP_UE, TASK_RRC_NRUE, size);
+       MessageDef  *message_p;
+
+       AssertFatal(rrc_buffer_p != NULL, "OUT OF MEMORY");
+       memcpy(rrc_buffer_p, buf, size);
+       message_p = entity->is_gnb ?
+                            itti_alloc_new_message(TASK_PDCP_ENB, 0, NR_RRC_DCCH_DATA_IND):
+                            itti_alloc_new_message(TASK_PDCP_UE, 0, NR_RRC_DCCH_DATA_IND);
+
+       AssertFatal(message_p != NULL, "OUT OF MEMORY");
+       NR_RRC_DCCH_DATA_IND(message_p).dcch_index = srb_id;
+       NR_RRC_DCCH_DATA_IND(message_p).sdu_p = rrc_buffer_p;
+       NR_RRC_DCCH_DATA_IND(message_p).sdu_size = size;
+       NR_RRC_DCCH_DATA_IND(message_p).rnti = ue->rnti;
+
+       itti_send_msg_to_task(entity->is_gnb ? TASK_RRC_GNB : TASK_RRC_NRUE, 0, message_p);
+    }
+}
+
+static void deliver_pdu_srb(void *_ue, nr_pdcp_entity_t *entity,
+                            char *buf, int size, int sdu_id)
+{
+  nr_pdcp_ue_t *ue = _ue;
+  int srb_id;
+  protocol_ctxt_t ctxt;
+  int i;
+  mem_block_t *memblock;
+
+  for (i = 0; i < 2; i++) {
+    if (entity == ue->srb[i]) {
+      srb_id = i+1;
+      goto srb_found;
+    }
+  }
+
+  LOG_E(PDCP, "%s:%d:%s: fatal, no SRB found for ue %d\n",
+        __FILE__, __LINE__, __FUNCTION__, ue->rnti);
+  exit(1);
+
+srb_found:
+
+
+  LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, srb_id, size);
+  //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
+  //printf("\n");
+  if ((RC.nrrrc == NULL) || (!NODE_IS_CU(RC.nrrrc[0]->node_type))) {
+    ctxt.module_id = 0;
+    ctxt.enb_flag = 1;
+    ctxt.instance = 0;
+    ctxt.frame = 0;
+    ctxt.subframe = 0;
+    ctxt.eNB_index = 0;
+    ctxt.configured = 1;
+    ctxt.brOption = 0;
+
+    ctxt.rnti = ue->rnti;
+
+    memblock = get_free_mem_block(size, __FUNCTION__);
+    memcpy(memblock->data, buf, size);
+    enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock, NULL, NULL);
+  }
+  else {
+    MessageDef  *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE);
+    F1AP_DL_RRC_MESSAGE (message_p).rrc_container        = (uint8_t*)buf;
+    F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = size;
+    F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id         = 0;
+    F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id         = 0;
+    F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id     = 0xFFFFFFFF; // unknown
+    F1AP_DL_RRC_MESSAGE (message_p).rnti                 = ue->rnti;
+    F1AP_DL_RRC_MESSAGE (message_p).srb_id               = srb_id;
+    F1AP_DL_RRC_MESSAGE (message_p).execute_duplication  = 1;
+    F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc = 0;
+    itti_send_msg_to_task (TASK_CU_F1, 0, message_p);
+    LOG_D(PDCP, "Send F1AP_DL_RRC_MESSAGE with ITTI\n");
+  }
+}
+
 boolean_t pdcp_data_ind(
   const protocol_ctxt_t *const  ctxt_pP,
   const srb_flag_t srb_flagP,
@@ -557,14 +686,26 @@ void pdcp_run(const protocol_ctxt_t *const  ctxt_pP)
 {
   MessageDef      *msg_p;
   int             result;
-  protocol_ctxt_t ctxt;
+  protocol_ctxt_t ctxt={.module_id=0,
+                        .enb_flag=1,
+                        .instance=0,
+                        .rnti=0,
+                        .frame=-1,
+                        .subframe=-1,
+                        .eNB_index=0,
+                        .configured=true,
+                        .brOption=false
+                       };
+
 
   while (1) {
     itti_poll_msg(ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, &msg_p);
-    if (msg_p == NULL)
-      break;
+    if (msg_p == NULL){
+     break;
+    }
     switch (ITTI_MSG_ID(msg_p)) {
     case RRC_DCCH_DATA_REQ:
+      LOG_D(PDCP, "Received RRC_DCCH_DATA_REQ type at PDCP task \n");
       PROTOCOL_CTXT_SET_BY_MODULE_ID(
           &ctxt,
           RRC_DCCH_DATA_REQ(msg_p).module_id,
@@ -595,9 +736,34 @@ void pdcp_run(const protocol_ctxt_t *const  ctxt_pP)
   }
 }
 
-static void add_srb(int rnti, struct NR_SRB_ToAddMod *s)
+static void add_srb(int is_gnb, int rnti, struct NR_SRB_ToAddMod *s)
 {
-  TODO;
+  nr_pdcp_entity_t *pdcp_srb;
+  nr_pdcp_ue_t *ue;
+  int t_Reordering=3000;
+
+  int srb_id = s->srb_Identity;
+  if (s->pdcp_Config == NULL ||
+      s->pdcp_Config->t_Reordering == NULL) t_Reordering = 3000;
+  else t_Reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering);
+
+  nr_pdcp_manager_lock(nr_pdcp_ue_manager);
+  ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
+  if (ue->srb[srb_id-1] != NULL) {
+    LOG_D(PDCP, "%s:%d:%s: warning SRB %d already exist for ue %d, do nothing\n",
+          __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
+  } else {
+    pdcp_srb = new_nr_pdcp_entity(NR_PDCP_SRB, is_gnb, srb_id,
+                                  0, 0, 0, 0, // sdap parameters
+                                  deliver_sdu_srb, ue, deliver_pdu_srb, ue,
+                                  12, t_Reordering, -1,
+                                  0, 0,
+                                  NULL, NULL);
+    nr_pdcp_ue_add_srb_pdcp_entity(ue, srb_id, pdcp_srb);
+
+    LOG_D(PDCP, "%s:%d:%s: added srb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
+  }
+  nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
 }
 
 static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
@@ -610,17 +776,41 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
   nr_pdcp_ue_t *ue;
 
   int drb_id = s->drb_Identity;
-  int t_reordering;
   int sn_size_ul = decode_sn_size_ul(*s->pdcp_Config->drb->pdcp_SN_SizeUL);
   int sn_size_dl = decode_sn_size_dl(*s->pdcp_Config->drb->pdcp_SN_SizeDL);
   int discard_timer = decode_discard_timer(*s->pdcp_Config->drb->discardTimer);
 
   /* if pdcp_Config->t_Reordering is not present, it means infinity (-1) */
-  if (s->pdcp_Config->t_Reordering != NULL)
+  int t_reordering = -1;
+  if (s->pdcp_Config->t_Reordering != NULL) {
     t_reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering);
-  else
-    t_reordering = -1;
+  }
 
+  if ((!s->cnAssociation) || s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_NOTHING) {
+    LOG_E(PDCP,"%s:%d:%s: fatal, cnAssociation is missing or present is NR_DRB_ToAddMod__cnAssociation_PR_NOTHING\n",__FILE__,__LINE__,__FUNCTION__);
+    exit(-1);
+  }
+
+  int pdusession_id;
+  int has_sdap = 0;
+  int has_sdapULheader=0;
+  int has_sdapDLheader=0;
+  if (s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity)
+     pdusession_id = s->cnAssociation->choice.eps_BearerIdentity;
+  else {
+    if (!s->cnAssociation->choice.sdap_Config) {
+      LOG_E(PDCP,"%s:%d:%s: fatal, sdap_Config is null",__FILE__,__LINE__,__FUNCTION__);
+      exit(-1);
+    }
+    pdusession_id = s->cnAssociation->choice.sdap_Config->pdu_Session;
+    has_sdap = 1;
+    has_sdapULheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present ? 1 : 0;
+    has_sdapDLheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present ? 1 : 0;
+    if (has_sdapDLheader==1) {
+      LOG_E(PDCP,"%s:%d:%s: fatal, no support for SDAP DL yet\n",__FILE__,__LINE__,__FUNCTION__);
+      exit(-1);
+    }
+  }
   /* TODO(?): accept different UL and DL SN sizes? */
   if (sn_size_ul != sn_size_dl) {
     LOG_E(PDCP, "%s:%d:%s: fatal, bad SN sizes, must be same. ul=%d, dl=%d\n",
@@ -640,7 +830,8 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
     LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
           __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
   } else {
-    pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id,
+    pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id,pdusession_id,has_sdap,
+                                  has_sdapULheader,has_sdapDLheader,
                                   deliver_sdu_drb, ue, deliver_pdu_drb, ue,
                                   sn_size_dl, t_reordering, discard_timer,
                                   ciphering_algorithm, integrity_algorithm,
@@ -717,7 +908,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
 
   if (srb2add_list != NULL) {
     for (i = 0; i < srb2add_list->list.count; i++) {
-      add_srb(rnti, srb2add_list->list.array[i]);
+      add_srb(ctxt_pP->enb_flag,rnti, srb2add_list->list.array[i]);
     }
   }
 
@@ -816,7 +1007,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
   }
 
   NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig));
-  nr_rlc_bearer_init(RLC_BearerConfig);
+  nr_rlc_bearer_init(RLC_BearerConfig,NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity);
   nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_um_Bi_Directional);
   nr_rlc_bearer_init_ul_spec(RLC_BearerConfig->mac_LogicalChannelConfig);
 
@@ -835,7 +1026,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
     (NR_SRB_ToAddModList_t *) NULL,
     rbconfig->drb_ToAddModList ,
     rbconfig->drb_ToReleaseList,
-    0xff,
+    0,
     NULL,
     NULL,
     NULL,
@@ -882,37 +1073,87 @@ void pdcp_config_set_security(
         uint8_t *const kRRCint_pP,
         uint8_t *const kUPenc_pP)
 {
-  DevAssert(pdcp_pP != NULL);
-
-  if ((security_modeP >= 0) && (security_modeP <= 0x77)) {
-    pdcp_pP->cipheringAlgorithm     = security_modeP & 0x0f;
-    pdcp_pP->integrityProtAlgorithm = (security_modeP>>4) & 0xf;
-    LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_SET_SECURITY_MODE: cipheringAlgorithm %d integrityProtAlgorithm %d\n",
-          PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP),
-          pdcp_pP->cipheringAlgorithm,
-          pdcp_pP->integrityProtAlgorithm);
-    pdcp_pP->kRRCenc = kRRCenc_pP;
-    pdcp_pP->kRRCint = kRRCint_pP;
-    pdcp_pP->kUPenc  = kUPenc_pP;
-    /* Activate security */
-    pdcp_pP->security_activated = 1;
-    MSC_LOG_EVENT(
-      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
-      "0 Set security ciph %X integ %x UE %"PRIx16" ",
-      pdcp_pP->cipheringAlgorithm,
-      pdcp_pP->integrityProtAlgorithm,
-      ctxt_pP->rnti);
+  nr_pdcp_ue_t *ue;
+  nr_pdcp_entity_t *rb;
+  int rnti = ctxt_pP->rnti;
+  int integrity_algorithm;
+  int ciphering_algorithm;
+
+  nr_pdcp_manager_lock(nr_pdcp_ue_manager);
+
+  ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
+
+  /* TODO: proper handling of DRBs, for the moment only SRBs are handled */
+
+  if (rb_id >= 1 && rb_id <= 2) {
+    rb = ue->srb[rb_id - 1];
+
+    if (rb == NULL) {
+      LOG_E(PDCP, "%s:%d:%s: no SRB found (rnti %d, rb_id %ld)\n",
+            __FILE__, __LINE__, __FUNCTION__, rnti, rb_id);
+      nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+      return;
+    }
+
+    integrity_algorithm = (security_modeP>>4) & 0xf;
+    ciphering_algorithm = security_modeP & 0x0f;
+    rb->set_security(rb, integrity_algorithm, (char *)kRRCint_pP,
+                     ciphering_algorithm, (char *)kRRCenc_pP);
   } else {
-    MSC_LOG_EVENT(
-      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
-      "0 Set security failed UE %"PRIx16" ",
-      ctxt_pP->rnti);
-    LOG_E(PDCP,PROTOCOL_PDCP_CTXT_FMT"  bad security mode %d",
-          PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP),
-          security_modeP);
+    LOG_E(PDCP, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
+    exit(1);
+  }
+
+  nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+}
+
+static boolean_t pdcp_data_req_srb(
+  protocol_ctxt_t  *ctxt_pP,
+  const rb_id_t rb_id,
+  const mui_t muiP,
+  const confirm_t confirmP,
+  const sdu_size_t sdu_buffer_size,
+  unsigned char *const sdu_buffer)
+{
+  LOG_D(PDCP, "%s() called, size %d\n", __func__, sdu_buffer_size);
+  nr_pdcp_ue_t *ue;
+  nr_pdcp_entity_t *rb;
+  int rnti = ctxt_pP->rnti;
+
+  if (ctxt_pP->module_id != 0 ||
+      //ctxt_pP->enb_flag != 1 ||
+      ctxt_pP->instance != 0 ||
+      ctxt_pP->eNB_index != 0 /*||
+      ctxt_pP->configured != 1 ||
+      ctxt_pP->brOption != 0*/) {
+    LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+    exit(1);
   }
+
+  nr_pdcp_manager_lock(nr_pdcp_ue_manager);
+
+  ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
+
+  if (rb_id < 1 || rb_id > 2)
+    rb = NULL;
+  else
+    rb = ue->srb[rb_id - 1];
+
+  if (rb == NULL) {
+    LOG_E(PDCP, "%s:%d:%s: no SRB found (rnti %d, rb_id %ld)\n",
+          __FILE__, __LINE__, __FUNCTION__, rnti, rb_id);
+    nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+    return 0;
+  }
+
+  rb->recv_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP);
+
+  nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+
+  return 1;
 }
 
+
 static boolean_t pdcp_data_req_drb(
   protocol_ctxt_t  *ctxt_pP,
   const rb_id_t rb_id,
@@ -973,9 +1214,12 @@ boolean_t pdcp_data_req(
 #endif
   )
 {
-  if (srb_flagP) { TODO; }
-  return pdcp_data_req_drb(ctxt_pP, rb_id, muiP, confirmP, sdu_buffer_size,
-                           sdu_buffer);
+  if (srb_flagP) {
+   return pdcp_data_req_srb(ctxt_pP, rb_id, muiP, confirmP, sdu_buffer_size, sdu_buffer);
+  }
+  else{
+    return pdcp_data_req_drb(ctxt_pP, rb_id, muiP, confirmP, sdu_buffer_size, sdu_buffer);
+  }
 }
 
 void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind)
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
index f89a18f94e4a00ebc6d9654fd40c9e1a83e3499a..160c5ebb22697c70ee2b16685a97bbdd71834fb5 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
@@ -85,7 +85,7 @@ nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *_m, int rnti)
     if (m->ue_list[i]->rnti == rnti)
       return m->ue_list[i];
 
-  LOG_D(PDCP, "%s:%d:%s: new UE %d\n", __FILE__, __LINE__, __FUNCTION__, rnti);
+  LOG_D(PDCP, "%s:%d:%s: new UE 0x%x\n", __FILE__, __LINE__, __FUNCTION__, rnti);
 
   m->ue_count++;
   m->ue_list = realloc(m->ue_list, sizeof(nr_pdcp_ue_t *) * m->ue_count);
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index 7cd1a87784338c7ab8a7fe764e70ed0e21c7ed3a..2a6bcf74aee97651a84b781483eb11269dd420f4 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -35,6 +35,15 @@
 #include "NR_DRB-ToReleaseList.h"
 #include "NR_CellGroupConfig.h"
 #include "NR_RLC-Config.h"
+#include "common/ran_context.h"
+#include "NR_UL-CCCH-Message.h"
+
+#undef C_RNTI // C_RNTI is used in F1AP generated code, prevent preprocessor replace
+#include "openair2/F1AP/f1ap_du_rrc_message_transfer.h"
+
+#include "openair2/LAYER2/PROTO_AGENT/proto_agent.h"
+
+extern RAN_CONTEXT_t RC;
 
 #include <stdint.h>
 
@@ -45,18 +54,25 @@ static uint64_t nr_rlc_current_time;
 static int      nr_rlc_current_time_last_frame;
 static int      nr_rlc_current_time_last_subframe;
 
-void nr_rlc_bearer_init(NR_RLC_BearerConfig_t *RLC_BearerConfig){
 
+void nr_rlc_bearer_init(NR_RLC_BearerConfig_t *RLC_BearerConfig, NR_RLC_BearerConfig__servedRadioBearer_PR rb_type){
 
   RLC_BearerConfig->servedRadioBearer                      = calloc(1, sizeof(*RLC_BearerConfig->servedRadioBearer));
   RLC_BearerConfig->reestablishRLC                         = calloc(1, sizeof(*RLC_BearerConfig->reestablishRLC));
   RLC_BearerConfig->rlc_Config                             = calloc(1, sizeof(*RLC_BearerConfig->rlc_Config));
   RLC_BearerConfig->mac_LogicalChannelConfig               = calloc(1, sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig));
 
-  RLC_BearerConfig->logicalChannelIdentity                 = 4;
-  RLC_BearerConfig->servedRadioBearer->present             = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity;
-  RLC_BearerConfig->servedRadioBearer->choice.drb_Identity = 1;
   *RLC_BearerConfig->reestablishRLC                        = NR_RLC_BearerConfig__reestablishRLC_true;
+  if(rb_type == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){
+    RLC_BearerConfig->logicalChannelIdentity                 = 4;
+    RLC_BearerConfig->servedRadioBearer->present             = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity;
+    RLC_BearerConfig->servedRadioBearer->choice.drb_Identity = 1;
+  }
+  else{
+    RLC_BearerConfig->logicalChannelIdentity                 = 1;
+    RLC_BearerConfig->servedRadioBearer->present             = NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity;
+    RLC_BearerConfig->servedRadioBearer->choice.srb_Identity = 1;
+  }
 
 }
 
@@ -160,7 +176,7 @@ void mac_rlc_data_ind     (
   } else {
     LOG_E(RLC, "%s:%d:%s: fatal: no RB found (channel ID %d)\n",
           __FILE__, __LINE__, __FUNCTION__, channel_idP);
-    exit(1);
+    // exit(1);
   }
 
   nr_rlc_manager_unlock(nr_rlc_ue_manager);
@@ -461,6 +477,27 @@ rb_found:
     T(T_ENB_RLC_UL,
       T_INT(0 /*ctxt_pP->module_id*/),
       T_INT(ue->rnti), T_INT(rb_id), T_INT(size));
+
+    const ngran_node_t type = RC.nrrrc[0 /*ctxt_pP->module_id*/]->node_type;
+    AssertFatal(type != ngran_eNB_CU && type != ngran_ng_eNB_CU && type != ngran_gNB_CU,
+                "Can't be CU, bad node type %d\n", type);
+
+    // if (NODE_IS_DU(type) && is_srb == 0) {
+    //   LOG_D(RLC, "call proto_agent_send_pdcp_data_ind() \n");
+    //   proto_agent_send_pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock);
+    //   return;
+    // }
+
+    if (NODE_IS_DU(type) && is_srb == 1) {
+      MessageDef *msg;
+      msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE);
+      F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti;
+      F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
+      F1AP_UL_RRC_MESSAGE(msg).rrc_container = (unsigned char *)buf;
+      F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
+      itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(0 /*ctxt_pP->module_id*/), msg);
+      return;
+    }
   }
 
   if (!pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock)) {
@@ -584,14 +621,15 @@ rb_found:
 #endif
 }
 
-static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s)
+static void add_rlc_srb(int rnti, struct NR_SRB_ToAddMod *s, NR_RLC_BearerConfig_t *rlc_BearerConfig)
 {
   nr_rlc_entity_t            *nr_rlc_am;
   nr_rlc_ue_t                *ue;
 
-  struct LTE_SRB_ToAddMod__rlc_Config *r = s->rlc_Config;
-  struct LTE_SRB_ToAddMod__logicalChannelConfig *l = s->logicalChannelConfig;
+  struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config;
+  struct NR_LogicalChannelConfig *l = rlc_BearerConfig->mac_LogicalChannelConfig;
   int srb_id = s->srb_Identity;
+  int channel_id = rlc_BearerConfig->logicalChannelIdentity;
   int logical_channel_group;
 
   int t_status_prohibit;
@@ -602,25 +640,21 @@ static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s)
   int t_reassembly;
   int sn_field_length;
 
+  LOG_D(RLC,"Trying to add SRB %d\n",srb_id);
   if (srb_id != 1 && srb_id != 2) {
     LOG_E(RLC, "%s:%d:%s: fatal, bad srb id %d\n",
-          __FILE__, __LINE__, __FUNCTION__, srb_id);
+        __FILE__, __LINE__, __FUNCTION__, srb_id);
     exit(1);
   }
 
-  switch (l->present) {
-  case LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue:
-    logical_channel_group = *l->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup;
-    break;
-  case LTE_SRB_ToAddMod__logicalChannelConfig_PR_defaultValue:
-    /* default value from 36.331 9.2.1 */
-    logical_channel_group = 0;
-    break;
-  default:
-    LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__);
+  if (channel_id != srb_id) {
+    LOG_E(RLC, "%s:%d:%s: todo, remove this limitation\n",
+          __FILE__, __LINE__, __FUNCTION__);
     exit(1);
   }
 
+  logical_channel_group = *l->ul_SpecificParameters->logicalChannelGroup;
+
   /* TODO: accept other values? */
   if (logical_channel_group != 0) {
     LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__);
@@ -628,29 +662,22 @@ static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s)
   }
 
   switch (r->present) {
-  case LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue: {
-    struct LTE_RLC_Config__am *am;
-    if (r->choice.explicitValue.present != LTE_RLC_Config_PR_am) {
-      LOG_E(RLC, "%s:%d:%s: fatal error, must be RLC AM\n",
-            __FILE__, __LINE__, __FUNCTION__);
-      exit(1);
-    }
-    am = &r->choice.explicitValue.choice.am;
+  case NR_RLC_Config_PR_am: {
+    struct NR_RLC_Config__am *am;
+    am = r->choice.am;
+    t_reassembly       = decode_t_reassembly(am->dl_AM_RLC.t_Reassembly);
     t_status_prohibit  = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit);
     t_poll_retransmit  = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit);
     poll_pdu           = decode_poll_pdu(am->ul_AM_RLC.pollPDU);
     poll_byte          = decode_poll_byte(am->ul_AM_RLC.pollByte);
     max_retx_threshold = decode_max_retx_threshold(am->ul_AM_RLC.maxRetxThreshold);
+    if (*am->dl_AM_RLC.sn_FieldLength != *am->ul_AM_RLC.sn_FieldLength) {
+      LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+      exit(1);
+    }
+    sn_field_length    = decode_sn_field_length_am(*am->dl_AM_RLC.sn_FieldLength);
     break;
   }
-  case LTE_SRB_ToAddMod__rlc_Config_PR_defaultValue:
-    /* default values from 36.331 9.2.1 */
-    t_status_prohibit  = 0;
-    t_poll_retransmit  = 45;
-    poll_pdu           = -1;
-    poll_byte          = -1;
-    max_retx_threshold = 4;
-    break;
   default:
     LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__);
     exit(1);
@@ -659,7 +686,7 @@ static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s)
   nr_rlc_manager_lock(nr_rlc_ue_manager);
   ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
   if (ue->srb[srb_id-1] != NULL) {
-    LOG_W(RLC, "%s:%d:%s: SRB %d already exists for UE with RNTI %x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
+    LOG_W(RLC, "%s:%d:%s: SRB %d already exists for UE with RNTI 0x%x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
   } else {
     /* hack: hardcode values for NR */
     t_poll_retransmit = 45;
@@ -680,8 +707,7 @@ static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s)
                                      sn_field_length);
     nr_rlc_ue_add_srb_rlc_entity(ue, srb_id, nr_rlc_am);
 
-    LOG_D(RLC, "%s:%d:%s: added srb %d to ue %d\n",
-          __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
+    LOG_D(RLC, "%s:%d:%s: added srb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
   }
   nr_rlc_manager_unlock(nr_rlc_ue_manager);
 }
@@ -722,7 +748,7 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_
   /* TODO: accept other values? */
   if (logical_channel_group != 1) {
     LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__);
-    exit(1);
+    //exit(1);
   }
 
   switch (r->present) {
@@ -763,7 +789,7 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_
                                      sn_field_length);
     nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_am);
 
-    LOG_D(RLC, "%s:%d:%s: added drb %d to UE with RNTI %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
+    LOG_D(RLC, "%s:%d:%s: added drb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
   }
   nr_rlc_manager_unlock(nr_rlc_ue_manager);
 }
@@ -831,7 +857,7 @@ static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_
                                      sn_field_length);
     nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_um);
 
-    LOG_D(RLC, "%s:%d:%s: added drb %d to UE with RNTI %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
+    LOG_D(RLC, "%s:%d:%s: added drb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
   }
   nr_rlc_manager_unlock(nr_rlc_ue_manager);
 }
@@ -850,7 +876,7 @@ static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, struct NR_RLC_BearerCon
           __FILE__, __LINE__, __FUNCTION__);
     exit(1);
   }
-  LOG_I(RLC, "%s:%s:%d: added DRB to UE with RNTI %x\n", __FILE__, __FUNCTION__, __LINE__, rnti);
+  LOG_I(RLC, "%s:%s:%d: added DRB to UE with RNTI 0x%x\n", __FILE__, __FUNCTION__, __LINE__, rnti);
 }
 
 /* Dummy function due to dependency from LTE libraries */
@@ -866,7 +892,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
 }
 
 rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP,
-    const LTE_SRB_ToAddModList_t   * const srb2add_listP,
+    const NR_SRB_ToAddModList_t   * const srb2add_listP,
     const NR_DRB_ToAddModList_t   * const drb2add_listP,
     const NR_DRB_ToReleaseList_t  * const drb2release_listP,
     const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
@@ -874,6 +900,7 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt
 {
   int rnti = ctxt_pP->rnti;
   int i;
+  int j;
 
   if (/*ctxt_pP->enb_flag != 1 ||*/ ctxt_pP->module_id != 0 /*||
       ctxt_pP->instance != 0 || ctxt_pP->eNB_index != 0 ||
@@ -896,13 +923,34 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt
 
   if (srb2add_listP != NULL) {
     for (i = 0; i < srb2add_listP->list.count; i++) {
-      add_srb(rnti, srb2add_listP->list.array[i]);
+      if (rlc_bearer2add_list != NULL) {
+        for(j = 0; j < rlc_bearer2add_list->list.count; j++){
+          if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){
+            if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity){
+              if(srb2add_listP->list.array[i]->srb_Identity == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.srb_Identity){
+                add_rlc_srb(rnti, srb2add_listP->list.array[i], rlc_bearer2add_list->list.array[j]);
+              }
+            }
+          }
+        }
+      }
+
     }
   }
 
-  if (drb2add_listP != NULL) {
+  if ((drb2add_listP != NULL) && (rlc_bearer2add_list != NULL)) {
     for (i = 0; i < drb2add_listP->list.count; i++) {
-      add_drb(rnti, drb2add_listP->list.array[i], rlc_bearer2add_list->list.array[i]);
+      if (rlc_bearer2add_list != NULL) {
+      for(j = 0; j < rlc_bearer2add_list->list.count; j++){
+        if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){
+          if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){
+            if(drb2add_listP->list.array[i]->drb_Identity == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){
+              add_drb(rnti, drb2add_listP->list.array[i], rlc_bearer2add_list->list.array[j]);
+            }
+          }  
+        }
+      }
+      }
     }
   }
 
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h
index 26dee0590b38ef030fae4251d74932178aa896cd..6b3c2281637d00454f7706fa61b562ebcf11abf5 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h
@@ -42,7 +42,7 @@
 struct NR_RLC_Config;
 struct NR_LogicalChannelConfig;
 
-void nr_rlc_bearer_init(NR_RLC_BearerConfig_t *RLC_BearerConfig);
+void nr_rlc_bearer_init(NR_RLC_BearerConfig_t *RLC_BearerConfig, NR_RLC_BearerConfig__servedRadioBearer_PR rb_type);
 
 void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config_pr);
 
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c
index 8c46628333d45dfec2d64cf6b3010e4a511e623e..dc2baa18391103fd14b10a8b5c08a5672fd764f1 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c
@@ -85,7 +85,7 @@ nr_rlc_ue_t *nr_rlc_manager_get_ue(nr_rlc_ue_manager_t *_m, int rnti)
     if (m->ue_list[i]->rnti == rnti)
       return m->ue_list[i];
 
-  LOG_D(RLC, "%s:%d:%s: new UE with RNTI %x\n", __FILE__, __LINE__, __FUNCTION__, rnti);
+  LOG_D(RLC, "%s:%d:%s: new UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, rnti);
 
   m->ue_count++;
   m->ue_list = realloc(m->ue_list, sizeof(nr_rlc_ue_t *) * m->ue_count);
diff --git a/openair2/LAYER2/rlc_v2/rlc_oai_api.c b/openair2/LAYER2/rlc_v2/rlc_oai_api.c
index 18285f65637ed4e4887014eef8ec1ab251b8b105..0cf4b85fa2cb98145cc1bc24f0a0a41f5eca793f 100644
--- a/openair2/LAYER2/rlc_v2/rlc_oai_api.c
+++ b/openair2/LAYER2/rlc_v2/rlc_oai_api.c
@@ -1031,3 +1031,14 @@ void rlc_tick(int frame, int subframe)
     rlc_current_time_last_subframe = subframe;
   }
 }
+
+void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
+                     const srb_flag_t   srb_flagP,
+                     const MBMS_flag_t  MBMS_flagP,
+                     const rb_id_t      rb_idP,
+                     const mui_t        muiP,
+                     confirm_t    confirmP,
+                     sdu_size_t   sdu_sizeP,
+                     mem_block_t *sdu_pP){
+
+}
\ No newline at end of file
diff --git a/openair2/NETWORK_DRIVER/MESH/mesh.c b/openair2/NETWORK_DRIVER/MESH/mesh.c
index ed87bc05f89ae52f100881aa742d70b2789ae60a..7e147feb684030835a7fa97f2620824bdc92aa84 100644
--- a/openair2/NETWORK_DRIVER/MESH/mesh.c
+++ b/openair2/NETWORK_DRIVER/MESH/mesh.c
@@ -886,6 +886,7 @@ int nas_mesh_DC_receive(struct cx_entity *cx,struct nas_priv *gpriv)
         switch (cx->state) {
         case NAS_CX_RELEASING_FAILURE:
           cx->retry=0;
+          /* fallthrough */
 
         case NAS_CX_DCH:
           nas_mesh_DC_decode_cx_loss_ind(cx,p);   // process message
diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
index 7bf738e04397a9b142143901912a9387c26e4954..982edf2f9de64482d0dab973c90520d310bfe35b 100644
--- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
@@ -108,7 +108,6 @@ void handle_nr_uci(NR_UL_IND_t *UL_info)
 
 }
 
-
 void handle_nr_ulsch(NR_UL_IND_t *UL_info)
 {
   if (UL_info->rx_ind.number_of_pdus > 0 && UL_info->crc_ind.number_crcs > 0) {
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index 51d279b7d1b5c8730a0dd4fa65b51d0cd27f1734..4576dbcc9bbc816ee46e72c86442f40cc979679a 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -47,7 +47,11 @@ const char *dl_indication_type[] = {"MIB", "SIB", "DLSCH", "DCI", "RAR"};
 static nr_ue_if_module_t *nr_ue_if_module_inst[MAX_IF_MODULES];
 
 //  L2 Abstraction Layer
-int handle_bcch_bch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint8_t *pduP, unsigned int additional_bits, uint32_t ssb_index, uint32_t ssb_length, uint16_t cell_id){
+int handle_bcch_bch(module_id_t module_id, int cc_id,
+                    unsigned int gNB_index, uint8_t *pduP,
+                    unsigned int additional_bits,
+                    uint32_t ssb_index, uint32_t ssb_length,
+                    uint16_t ssb_start_subcarrier, uint16_t cell_id){
 
   return nr_ue_decode_mib(module_id,
 			  cc_id,
@@ -55,7 +59,8 @@ int handle_bcch_bch(module_id_t module_id, int cc_id, unsigned int gNB_index, ui
 			  additional_bits,
 			  ssb_length,  //  Lssb = 64 is not support    
 			  ssb_index,
-			  pduP, 
+			  pduP,
+			  ssb_start_subcarrier,
 			  cell_id);
 
 }
@@ -90,7 +95,9 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
 
   ret = nr_ue_scheduler(NULL, ul_info);
 
-  if (is_nr_UL_slot(mac->scc, ul_info->slot_tx, mac->frame_type) && get_softmodem_params()->do_ra)
+  NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon = mac->scc != NULL ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon;
+
+  if (is_nr_UL_slot(tdd_UL_DL_ConfigurationCommon, ul_info->slot_tx, mac->frame_type) && !get_softmodem_params()->phy_test)
     nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->thread_id);
 
   switch(ret){
@@ -155,14 +162,15 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
 
         switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
 
-        case FAPI_NR_RX_PDU_TYPE_MIB:
+        case FAPI_NR_RX_PDU_TYPE_SSB:
 
           ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
-                      (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.pdu,
-                      (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.additional_bits,
-                      (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_index,
-                      (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_length,
-                      (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_MIB;
+                                       (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu,
+                                       (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.additional_bits,
+                                       (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_index,
+                                       (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_length,
+                                       (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_start_subcarrier,
+                                       (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_SSB;
 
           break;
 
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
index e78529d437de1871dcbd31234354184c3e6297a0..449c7bf890b8d55cee422033f69141326bb5e8ef 100755
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
@@ -221,7 +221,15 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq);
    \param ssb_index       SSB index within 0 - (L_ssb-1) corresponding to 38.331 ch.13 parameter i
    \param ssb_length      corresponding to L1 parameter L_ssb 
    \param cell_id         cell id */
-int handle_bcch_bch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint8_t *pduP, unsigned int additional_bits, uint32_t ssb_index, uint32_t ssb_length, uint16_t cell_id);
+int handle_bcch_bch(module_id_t module_id,
+                    int cc_id,
+                    unsigned int gNB_index,
+                    uint8_t *pduP,
+                    unsigned int additional_bits,
+                    uint32_t ssb_index,
+                    uint32_t ssb_length,
+                    uint16_t ssb_start_subcarrier,
+                    uint16_t cell_id);
 
 //  TODO check
 /**\brief handle BCCH-DL-SCH message from dl_indication
diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c
index 027a6299927abdb01014c431914c0e0fdfcefe50..f0279f0ef2a53b0ec6dbf9ebca5df7619aaa9f3e 100644
--- a/openair2/RRC/LITE/rrc_common.c
+++ b/openair2/RRC/LITE/rrc_common.c
@@ -392,7 +392,7 @@ rrc_rx_tx(
               current_timestamp_ms,
               ctxt_pP->frame,
               estimated_distance);
-        LOG_D(LOCALIZE, " RRC status %d\n", ue_context_p->ue_context.Status);
+        LOG_D(LOCALIZE, " RRC status %d\n", ue_context_p->ue_context.StatusRrc);
         push_front(&RC.rrc[ctxt_pP->module_id]->loc_list,
                    estimated_distance);
         RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms;
diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c
index 0bc63237b3737a1a2c1e90100fa767c45b9215ea..921c1f3bcb84c1bc7a75ec903d6f39da4c368c54 100644
--- a/openair2/RRC/LTE/L2_interface.c
+++ b/openair2/RRC/LTE/L2_interface.c
@@ -316,8 +316,9 @@ mac_rrc_data_ind(
       UE_id,
       rntiP,
       sduP,
-      sdu_lenP
-    );
+      sdu_lenP,
+      NULL,
+      0);
     return(0);
   }
 
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index f86b0ddbae81defa9452c2a4b63e3bf95710878f..006f03a63e175be8ca15d847c698356e0ef7a5e5 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -997,6 +997,7 @@ void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag) {
   free_list = &eNB_MAC->UE_free_list;
   free_list->UE_free_ctrl[free_list->tail_freelist].rnti = rnti;
   free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = removeFlag;
+  free_list->UE_free_ctrl[free_list->tail_freelist].raFlag = 0;
   free_list->num_UEs++;
   eNB_MAC->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = rnti;
   eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs++;
@@ -1046,12 +1047,12 @@ void release_UE_in_freeList(module_id_t mod_id) {
         eNB_PHY = RC.eNB[mod_id][CC_id];
         int id;
         // clean ULSCH entries for rnti
-        id = find_ulsch(rnti,eNB_PHY,SEARCH_EXIST);
+        id = find_ulsch(rnti,eNB_PHY,eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST);
 
         if (id>=0) clean_eNb_ulsch(eNB_PHY->ulsch[id]);
 
         // clean DLSCH entries for rnti
-        id = find_dlsch(rnti,eNB_PHY,SEARCH_EXIST);
+        id = find_dlsch(rnti,eNB_PHY,eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST);
 
         if (id>=0) clean_eNb_dlsch(eNB_PHY->dlsch[id][0]);
 
@@ -7613,7 +7614,7 @@ rrc_eNB_decode_ccch(
 
 #define NCE nonCriticalExtension
 
-static void 
+static void
 get_ue_Category(
   LTE_UE_EUTRA_Capability_t *c,
   long *catDL,
@@ -7649,7 +7650,7 @@ get_ue_Category(
                                       if (c125->ue_CategoryUL_r12) *catUL=*c125->ue_CategoryUL_r12;
                                       struct LTE_UE_EUTRA_Capability_v1260_IEs *c126=c125->NCE;
                                       if (c126 != NULL) { // v12.6
-                                         if (c126->ue_CategoryDL_v1260) *catDL=*c126->ue_CategoryDL_v1260; 
+                                         if (c126->ue_CategoryDL_v1260) *catDL=*c126->ue_CategoryDL_v1260;
                                          struct LTE_UE_EUTRA_Capability_v1270_IEs *c127=c126->NCE;
                                          if (c127 != NULL) { // v12.7
                                             struct LTE_UE_EUTRA_Capability_v1280_IEs *c128=c127->NCE;
@@ -7739,7 +7740,7 @@ is_ul_64QAM_supported(
          && c->NCE->NCE->NCE->NCE != NULL // R106
          && c->NCE->NCE->NCE->NCE->NCE != NULL // R109
          && c->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R113
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R117 
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R117
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R118
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R11a
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R125
@@ -7763,7 +7764,7 @@ is_dl_256QAM_supported(
          && c->NCE->NCE->NCE->NCE != NULL // R106
          && c->NCE->NCE->NCE->NCE->NCE != NULL // R109
          && c->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R113
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R117 
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R117
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R118
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R11a
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R125
@@ -7777,7 +7778,7 @@ is_dl_256QAM_supported(
 static int
 is_ul_256QAM_supported(
   LTE_UE_EUTRA_Capability_t *c
-) 
+)
 //-----------------------------------------------------------------------------
 {
   return c != NULL  // R8
@@ -7787,14 +7788,14 @@ is_ul_256QAM_supported(
          && c->NCE->NCE->NCE->NCE != NULL // R106
          && c->NCE->NCE->NCE->NCE->NCE != NULL // R109
          && c->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R113
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R117 
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R117
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R118
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R11a
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R125
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R126
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // 127
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // 128
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //131 
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //131
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //132
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //133
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //134
@@ -7803,7 +7804,7 @@ is_ul_256QAM_supported(
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //143
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430 != NULL
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430 != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430->list.array != NULL 
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430->list.array != NULL
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430->list.array[0]->bandParameterList_v1430 != NULL
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430->list.array[0]->bandParameterList_v1430->list.array != NULL
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430->list.array[0]->bandParameterList_v1430->list.array[0]->ul_256QAM_r14!=NULL
@@ -7826,14 +7827,14 @@ is_en_dc_supported(
          && c->NCE->NCE->NCE->NCE != NULL // R106
          && c->NCE->NCE->NCE->NCE->NCE != NULL // R109
          && c->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R113
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R117 
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R117
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R118
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R11a
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R125
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R126
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // 127
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // 128
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //131 
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //131
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //132
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //133
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //134
@@ -7841,7 +7842,7 @@ is_en_dc_supported(
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //136
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //143
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //144
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //145 
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //145
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //146
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //151
          && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15 != NULL
@@ -7868,7 +7869,7 @@ int to_nr_rsrpq(long rsrpq_result,int nr_band) {
        return((rsrpq_result*10)-1175);
       case 77:  // C
       case 78:
-      case 79: 
+      case 79:
        return((rsrpq_result*10)-1170);
       case 28:  // D
        return((rsrpq_result*10)-1165);
@@ -8836,23 +8837,23 @@ void handle_f1_setup_req(f1ap_setup_req_t *f1_setup_req) {
         }
 
         F1AP_SETUP_RESP (msg_p).gNB_CU_name                                = rrc->node_name;
-        F1AP_SETUP_RESP (msg_p).mcc[cu_cell_ind]                           = rrc->configuration.mcc[0];
-        F1AP_SETUP_RESP (msg_p).mnc[cu_cell_ind]                           = rrc->configuration.mnc[0];
-        F1AP_SETUP_RESP (msg_p).mnc_digit_length[cu_cell_ind]              = rrc->configuration.mnc_digit_length[0];
-        F1AP_SETUP_RESP (msg_p).nr_cellid[cu_cell_ind]                     = rrc->nr_cellid;
-        F1AP_SETUP_RESP (msg_p).nrpci[cu_cell_ind]                         = f1_setup_req->nr_pci[i];
+        F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].mcc                           = rrc->configuration.mcc[0];
+        F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].mnc                           = rrc->configuration.mnc[0];
+        F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].mnc_digit_length              = rrc->configuration.mnc_digit_length[0];
+        F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].nr_cellid                     = rrc->nr_cellid;
+        F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].nrpci                         = f1_setup_req->nr_pci[i];
         int num_SI= 0;
         if (rrc->carrier[0].SIB23) {
-          F1AP_SETUP_RESP (msg_p).SI_container[cu_cell_ind][2+num_SI]        = rrc->carrier[0].SIB23;
-          F1AP_SETUP_RESP (msg_p).SI_container_length[cu_cell_ind][2+num_SI] = rrc->carrier[0].sizeof_SIB23;
-          printf("SI %d size %d: ", 0, F1AP_SETUP_RESP(msg_p).SI_container_length[j][2+num_SI]);
-          for (int n = 0; n < F1AP_SETUP_RESP(msg_p).SI_container_length[j][2+num_SI]; n++)
-            printf("%02x ", F1AP_SETUP_RESP(msg_p).SI_container[0][2+num_SI][n]);
-          printf("\n");
+          F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].SI_container[2+num_SI]        = rrc->carrier[0].SIB23;
+          F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].SI_container_length[2+num_SI] = rrc->carrier[0].sizeof_SIB23;
+          //printf("SI %d size %d: ", 0, F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].SI_container_length[2+num_SI]);
+          //for (int n = 0; n < F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].SI_container_length[2+num_SI]; n++)
+          //  printf("%02x ", F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].SI_container[2+num_SI][n]);
+          //printf("\n");
           num_SI++;
         }
 
-        F1AP_SETUP_RESP (msg_p).num_SI[cu_cell_ind] = num_SI;
+        F1AP_SETUP_RESP (msg_p).cells_to_activate[cu_cell_ind].num_SI = num_SI;
         cu_cell_ind++;
         found_cell=1;
         F1AP_SETUP_RESP (msg_p).num_cells_to_activate = cu_cell_ind;
@@ -9059,7 +9060,7 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
 
   // check for UL failure or for UE to be released
   FILE *fd=NULL;
-  if ((ctxt_pP->frame&127) == 0 && ctxt_pP->subframe ==0) 
+  if ((ctxt_pP->frame&127) == 0 && ctxt_pP->subframe ==0)
     fd=fopen("RRC_stats.log","w+");
 
   RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
@@ -9091,15 +9092,15 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
         if (ue_context_p->ue_context.measResults) {
            fprintf(fd, "RRC PCell RSRP %ld, RSRQ %ld\n", ue_context_p->ue_context.measResults->measResultPCell.rsrpResult-140,
                                                          ue_context_p->ue_context.measResults->measResultPCell.rsrqResult/2 - 20);
-          if (ue_context_p->ue_context.measResults->measResultNeighCells && 
-              ue_context_p->ue_context.measResults->measResultNeighCells->present == LTE_MeasResults__measResultNeighCells_PR_measResultNeighCellListNR_r15) { 
+          if (ue_context_p->ue_context.measResults->measResultNeighCells &&
+              ue_context_p->ue_context.measResults->measResultNeighCells->present == LTE_MeasResults__measResultNeighCells_PR_measResultNeighCellListNR_r15) {
 
             fprintf(fd,"NR_pci %ld\n",ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->pci_r15);
             if(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultCell_r15.rsrpResult_r15)
               fprintf(fd,"NR_rsrp %f dB\n",to_nr_rsrpq(*ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultCell_r15.rsrpResult_r15,RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0])/10.0);
-            if (ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultCell_r15.rsrqResult_r15) 
+            if (ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultCell_r15.rsrqResult_r15)
               fprintf(fd,"NR_rsrq %f dB\n",to_nr_rsrpq(*ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultCell_r15.rsrqResult_r15,RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0])/10.0);
-            if (ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultRS_IndexList_r15) 
+            if (ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultRS_IndexList_r15)
               fprintf(fd,"NR_ssb_index %ld\n",ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->measResultRS_IndexList_r15->list.array[0]->ssb_Index_r15);
            }
         }
diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c
index c9ab3a3a97a4f1a741707c837ea69f4b1fb5bcc4..1f4af2a98eff5b81d3598d89868f424a3db1ab07 100644
--- a/openair2/RRC/NR/L2_nr_interface.c
+++ b/openair2/RRC/NR/L2_nr_interface.c
@@ -28,6 +28,7 @@
  * \email: raymond.knopp@eurecom.fr, kroempa@gmail.com
  */
 
+#include <f1ap_du_rrc_message_transfer.h>
 #include "platform_types.h"
 #include "nr_rrc_defs.h"
 #include "nr_rrc_extern.h"
@@ -43,6 +44,7 @@
 #include "NR_MIB.h"
 #include "NR_BCCH-BCH-Message.h"
 #include "rrc_gNB_UE_context.h"
+#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
 
 extern RAN_CONTEXT_t RC;
 
@@ -164,12 +166,12 @@ nr_rrc_data_req(
 //------------------------------------------------------------------------------
 {
   if(sdu_sizeP == 255) {
-    LOG_I(RRC,"sdu_sizeP == 255");
+    LOG_D(RRC,"sdu_sizeP == 255");
     return FALSE;
   }
 
   MSC_LOG_TX_MESSAGE(
-    ctxt_pP->enb_flag ? MSC_RRC_ENB : MSC_RRC_UE,
+    ctxt_pP->enb_flag ? MSC_RRC_GNB : MSC_RRC_UE,
     ctxt_pP->enb_flag ? MSC_PDCP_ENB : MSC_PDCP_UE,
     buffer_pP,
     sdu_sizeP,
@@ -182,11 +184,11 @@ nr_rrc_data_req(
   // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling).
   uint8_t *message_buffer;
   message_buffer = itti_malloc (
-                     ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE,
+                     ctxt_pP->enb_flag ? TASK_RRC_GNB : TASK_RRC_UE,
                      ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE,
                      sdu_sizeP);
   memcpy (message_buffer, buffer_pP, sdu_sizeP);
-  message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, 0, RRC_DCCH_DATA_REQ);
+  message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_GNB : TASK_RRC_UE, 0, RRC_DCCH_DATA_REQ);
   RRC_DCCH_DATA_REQ (message_p).frame     = ctxt_pP->frame;
   RRC_DCCH_DATA_REQ (message_p).enb_flag  = ctxt_pP->enb_flag;
   RRC_DCCH_DATA_REQ (message_p).rb_id     = rb_idP;
@@ -194,7 +196,7 @@ nr_rrc_data_req(
   RRC_DCCH_DATA_REQ (message_p).confirmp  = confirmP;
   RRC_DCCH_DATA_REQ (message_p).sdu_size  = sdu_sizeP;
   RRC_DCCH_DATA_REQ (message_p).sdu_p     = message_buffer;
-  //memcpy (RRC_DCCH_DATA_REQ (message_p).sdu_p, buffer_pP, sdu_sizeP);
+  //memcpy (NR_RRC_DCCH_DATA_REQ (message_p).sdu_p, buffer_pP, sdu_sizeP);
   RRC_DCCH_DATA_REQ (message_p).mode      = modeP;
   RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id;
   RRC_DCCH_DATA_REQ (message_p).rnti      = ctxt_pP->rnti;
@@ -203,12 +205,12 @@ nr_rrc_data_req(
     ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE,
     ctxt_pP->instance,
     message_p);
-  LOG_I(RRC,"sent RRC_DCCH_DATA_REQ to TASK_PDCP_ENB\n");
+  LOG_I(NR_RRC,"send RRC_DCCH_DATA_REQ to PDCP\n");
 
   /* Hack: only trigger PDCP if in CU, otherwise it is triggered by RU threads
    * Ideally, PDCP would not neet to be triggered like this but react to ITTI
    * messages automatically */
-  if (ctxt_pP->enb_flag && NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type))
+  if (ctxt_pP->enb_flag && NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type))
     pdcp_run(ctxt_pP);
 
   return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
@@ -281,6 +283,7 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
 
     LOG_D(NR_RRC,"[gNB %d] Frame %d CCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id);
 
+    AssertFatal(ue_context_p!=NULL,"failed to get ue_context\n");
     char payload_size = ue_context_p->ue_context.Srb0.Tx_buffer.payload_size;
 
     // check if data is there for MAC
@@ -310,6 +313,42 @@ int8_t nr_mac_rrc_data_ind(const module_id_t     module_idP,
                            const sdu_size_t      sdu_lenP,
                            const boolean_t   brOption) {
 
+  if (NODE_IS_DU(RC.nrrrc[module_idP]->node_type)) {
+    LOG_W(RRC,"[DU %d][RAPROC] Received SDU for CCCH on SRB %ld length %d for UE id %d RNTI %x \n",
+          module_idP, srb_idP, sdu_lenP, UE_id, rntiP);
+
+    // Generate DUtoCURRCContainer
+    // call do_RRCSetup like full procedure and extract masterCellGroup
+    NR_CellGroupConfig_t cellGroupConfig;
+    NR_ServingCellConfigCommon_t *scc=RC.nrrrc[module_idP]->carrier.servingcellconfigcommon;
+    uint8_t sdu2[100];
+    memset(&cellGroupConfig,0,sizeof(cellGroupConfig));
+    fill_initial_cellGroupConfig(rntiP,&cellGroupConfig,scc);
+    asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
+						    NULL,
+						    (void *)&cellGroupConfig,
+						    sdu2,
+						    100);
+
+    int sdu2_len = (enc_rval.encoded+7)/8;
+    if (enc_rval.encoded == -1) {
+      LOG_E(F1AP,"Could not encoded cellGroupConfig, failed element %s\n",enc_rval.failed_type->name);
+      exit(-1);
+    }
+    /* do ITTI message */
+    DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(
+      module_idP,
+      CC_id,
+      UE_id,
+      rntiP,
+      sduP,
+      sdu_lenP,
+      (const int8_t*)sdu2,
+      sdu2_len
+    );
+    return(0);
+  }
+
   protocol_ctxt_t ctxt;
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, GNB_FLAG_YES, rntiP, frameP, sub_frameP,0);
 
@@ -317,7 +356,7 @@ int8_t nr_mac_rrc_data_ind(const module_id_t     module_idP,
     LOG_D(NR_RRC, "[gNB %d] Received SDU for CCCH on SRB %ld\n", module_idP, srb_idP);
     ctxt.brOption = brOption;
     if (sdu_lenP > 0) {
-      nr_rrc_gNB_decode_ccch(&ctxt, sduP, sdu_lenP, CC_id);
+      nr_rrc_gNB_decode_ccch(&ctxt, sduP, sdu_lenP, NULL, CC_id);
     }
   }
 
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
old mode 100644
new mode 100755
index 39222f814dc8d1210fe712fdd745bb7f8e144f2a..789fb84a288e355543262196e2f87fdb373af88e
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -70,6 +70,7 @@
 #include "NR_RRCReconfigurationComplete-IEs.h"
 #include "NR_DLInformationTransfer.h"
 #include "NR_RRCReestablishmentRequest.h"
+#include "NR_UE-CapabilityRequestFilterNR.h"
 #include "PHY/defs_nr_common.h"
 #if defined(NR_Rel16)
   #include "NR_SCS-SpecificCarrier.h"
@@ -308,12 +309,12 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
 
   // TODO : Add support for more than one PLMN
   int num_plmn = 1; // int num_plmn = configuration->num_plmn;
-  struct NR_PLMN_Identity nr_plmn[num_plmn];
-  NR_MCC_MNC_Digit_t nr_mcc_digit[num_plmn][3];
-  NR_MCC_MNC_Digit_t nr_mnc_digit[num_plmn][3];
-  memset(nr_plmn,0,sizeof(nr_plmn));
-  memset(nr_mcc_digit,0,sizeof(nr_mcc_digit));
-  memset(nr_mnc_digit,0,sizeof(nr_mnc_digit));
+  struct NR_PLMN_Identity *nr_plmn = CALLOC(1, sizeof(struct NR_PLMN_Identity) * num_plmn);
+  NR_MCC_MNC_Digit_t (*nr_mcc_digit)[3] = (NR_MCC_MNC_Digit_t(*)[3])CALLOC(1, sizeof(NR_MCC_MNC_Digit_t)*num_plmn*3);
+  NR_MCC_MNC_Digit_t (*nr_mnc_digit)[3] = (NR_MCC_MNC_Digit_t(*)[3])CALLOC(1, sizeof(NR_MCC_MNC_Digit_t)*num_plmn*3);;
+  memset(nr_plmn,0,sizeof(struct NR_PLMN_Identity) * num_plmn);
+  memset(nr_mcc_digit,0,sizeof(NR_MCC_MNC_Digit_t)*num_plmn*3);
+  memset(nr_mnc_digit,0,sizeof(NR_MCC_MNC_Digit_t)*num_plmn*3);
 
   NR_BCCH_DL_SCH_Message_t *sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t));
   carrier->siblock1 = sib1_message;
@@ -444,7 +445,7 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
   ss1->nrofCandidates = calloc(1,sizeof(*ss1->nrofCandidates));
   ss1->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
   ss1->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
-  ss1->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
+  ss1->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n4;
   ss1->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
   ss1->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
   ss1->searchSpaceType = calloc(1,sizeof(*ss1->searchSpaceType));
@@ -658,6 +659,56 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
   return((enc_rval.encoded+7)/8);
 }
 
+uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier,
+                    gNB_RrcConfigurationReq *configuration) {
+  asn_enc_rval_t enc_rval;
+  SystemInformation_IEs__sib_TypeAndInfo__Member *sib2 = NULL;
+  SystemInformation_IEs__sib_TypeAndInfo__Member *sib3 = NULL;
+
+  NR_BCCH_DL_SCH_Message_t *sib_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t));
+  sib_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1;
+  sib_message->message.choice.c1 = CALLOC(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1));
+  sib_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation;
+  sib_message->message.choice.c1->choice.systemInformation = CALLOC(1,sizeof(struct NR_SystemInformation));
+  
+  struct NR_SystemInformation *sib = sib_message->message.choice.c1->choice.systemInformation;
+  sib->criticalExtensions.present = NR_SystemInformation__criticalExtensions_PR_systemInformation;
+  sib->criticalExtensions.choice.systemInformation = CALLOC(1, sizeof(struct NR_SystemInformation_IEs));
+
+  struct NR_SystemInformation_IEs *ies = sib->criticalExtensions.choice.systemInformation;
+  sib2 = CALLOC(1, sizeof(SystemInformation_IEs__sib_TypeAndInfo__Member));
+  sib2->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2;
+  sib2->choice.sib2 = CALLOC(1, sizeof(struct NR_SIB2));
+  sib2->choice.sib2->cellReselectionInfoCommon.q_Hyst = NR_SIB2__cellReselectionInfoCommon__q_Hyst_dB1;
+  sib2->choice.sib2->cellReselectionServingFreqInfo.threshServingLowP = 2; // INTEGER (0..31)
+  sib2->choice.sib2->cellReselectionServingFreqInfo.cellReselectionPriority =  2; // INTEGER (0..7)
+  sib2->choice.sib2->intraFreqCellReselectionInfo.q_RxLevMin = -50; // INTEGER (-70..-22)
+  sib2->choice.sib2->intraFreqCellReselectionInfo.s_IntraSearchP = 2; // INTEGER (0..31)
+  sib2->choice.sib2->intraFreqCellReselectionInfo.t_ReselectionNR = 2; // INTEGER (0..7)
+  sib2->choice.sib2->intraFreqCellReselectionInfo.deriveSSB_IndexFromCell = true;
+  ASN_SEQUENCE_ADD(&ies->sib_TypeAndInfo.list, sib2);
+
+  sib3 = CALLOC(1, sizeof(SystemInformation_IEs__sib_TypeAndInfo__Member));
+  sib3->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3;
+  sib3->choice.sib3 = CALLOC(1, sizeof(struct NR_SIB3));
+  ASN_SEQUENCE_ADD(&ies->sib_TypeAndInfo.list, sib3);
+
+  //encode SIB to data
+  // carrier->SIB23 = (uint8_t *) malloc16(128);
+  enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message,
+                                   NULL,
+                                   (void *)sib_message,
+                                   carrier->SIB23,
+                                   100);
+  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
+               enc_rval.failed_type->name, enc_rval.encoded);
+
+  if (enc_rval.encoded==-1) {
+    return(-1);
+  }
+
+  return((enc_rval.encoded+7)/8);
+}
 
 void  do_RLC_BEARER(uint8_t Mod_id,
                     int CC_id,
@@ -926,29 +977,360 @@ uint8_t do_RRCReject(uint8_t Mod_id,
     return((enc_rval.encoded+7)/8);
 }
 
+void fill_initial_SpCellConfig(rnti_t rnti,
+			       NR_SpCellConfig_t *SpCellConfig,
+			       NR_ServingCellConfigCommon_t *scc) {
+
+  SpCellConfig->servCellIndex = NULL;
+  SpCellConfig->reconfigurationWithSync = NULL;
+  SpCellConfig->rlmInSyncOutOfSyncThreshold = NULL;
+  SpCellConfig->rlf_TimersAndConstants = NULL;
+  SpCellConfig->spCellConfigDedicated = calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated));
+  SpCellConfig->spCellConfigDedicated->uplinkConfig = calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->uplinkConfig));
+  NR_BWP_UplinkDedicated_t *initialUplinkBWP = calloc(1,sizeof(*initialUplinkBWP));
+  SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP = initialUplinkBWP;
+  initialUplinkBWP->pucch_Config = calloc(1,sizeof(*initialUplinkBWP->pucch_Config));
+  initialUplinkBWP->pucch_Config->present = NR_SetupRelease_PUCCH_Config_PR_setup;
+  NR_PUCCH_Config_t *pucch_Config = calloc(1,sizeof(*pucch_Config));
+  initialUplinkBWP->pucch_Config->choice.setup=pucch_Config;
+  pucch_Config->resourceSetToAddModList = calloc(1,sizeof(*pucch_Config->resourceSetToAddModList));
+  pucch_Config->resourceSetToReleaseList = NULL;
+  NR_PUCCH_ResourceSet_t *pucchresset0=calloc(1,sizeof(*pucchresset0));
+  pucchresset0->pucch_ResourceSetId = 0;
+  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);
+  
+  pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList));
+  pucch_Config->resourceToReleaseList = NULL;
+  // configure one single PUCCH0 opportunity for initial connection procedure
+  // one symbol (13)
+  NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0));
+  pucchres0->pucch_ResourceId=0;
+  pucchres0->startingPRB=0;
+  pucchres0->intraSlotFrequencyHopping=NULL;
+  pucchres0->secondHopPRB=NULL;
+  pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0;
+  pucchres0->format.choice.format0=calloc(1,sizeof(*pucchres0->format.choice.format0));
+  pucchres0->format.choice.format0->initialCyclicShift=0;
+  pucchres0->format.choice.format0->nrofSymbols=1;
+  pucchres0->format.choice.format0->startingSymbolIndex=13;
+  ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0);
+  
+  // configure Scheduling request
+  // 40 slot period 
+  pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList));
+  NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig = calloc(1,sizeof(*schedulingRequestResourceConfig));
+  schedulingRequestResourceConfig->schedulingRequestResourceId = 1;
+  schedulingRequestResourceConfig->schedulingRequestID= 0;
+  schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset));
+  schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40;
+  // note: make sure that there is no issue here. Later choose the RNTI accordingly. 
+  //       Here we would be limited to 8 UEs on this resource (2 Frames 30 kHz SCS, 5 ms TDD periodicity => slots 8,9,18,19,28,29,38,39). 
+  //       This should be a temporary resource until the first RRCReconfiguration gives new pucch resources.
+  // Check for above configuration and exit for now if it is not the case
+  AssertFatal(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing==NR_SubcarrierSpacing_kHz30,
+	      "SCS != 30kHz\n");
+  AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity==NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5,
+	      "TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
+  
+  schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 10*((rnti>>1)&3) + (rnti&2);
+  schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource));
+  *schedulingRequestResourceConfig->resource = 0;
+  ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig);
+
+  SpCellConfig->spCellConfigDedicated->initialDownlinkBWP = calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->initialDownlinkBWP));
+  NR_BWP_DownlinkDedicated_t *bwp_Dedicated = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP;
+  bwp_Dedicated->pdcch_Config=calloc(1,sizeof(*bwp_Dedicated->pdcch_Config));
+  bwp_Dedicated->pdcch_Config->present = NR_SetupRelease_PDCCH_Config_PR_setup;
+  bwp_Dedicated->pdcch_Config->choice.setup = calloc(1,sizeof(*bwp_Dedicated->pdcch_Config->choice.setup));
+
+  bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList = calloc(1,sizeof(*bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList));
+  
+  NR_SearchSpace_t *ss2 = calloc(1,sizeof(*ss2));
+ 
+  ss2->searchSpaceId=2;
+  ss2->controlResourceSetId=calloc(1,sizeof(*ss2->controlResourceSetId));
+  *ss2->controlResourceSetId=0;
+  ss2->monitoringSlotPeriodicityAndOffset=calloc(1,sizeof(*ss2->monitoringSlotPeriodicityAndOffset));
+  ss2->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1;
+  ss2->monitoringSlotPeriodicityAndOffset->choice.sl1=(NULL_t)0;
+  ss2->duration=NULL;
+  ss2->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss2->monitoringSymbolsWithinSlot));
+  ss2->monitoringSymbolsWithinSlot->buf = calloc(1,2);
+  ss2->monitoringSymbolsWithinSlot->size = 2;
+  ss2->monitoringSymbolsWithinSlot->bits_unused = 2;
+  ss2->monitoringSymbolsWithinSlot->buf[0]=0x80;
+  ss2->monitoringSymbolsWithinSlot->buf[1]=0x0;
+  ss2->nrofCandidates=calloc(1,sizeof(*ss2->nrofCandidates));
+  ss2->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
+  ss2->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
+  ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
+  ss2->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
+  ss2->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
+  ss2->searchSpaceType=calloc(1,sizeof(*ss2->searchSpaceType));
+  ss2->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
+  ss2->searchSpaceType->choice.ue_Specific = calloc(1,sizeof(*ss2->searchSpaceType->choice.ue_Specific));
+  ss2->searchSpaceType->choice.ue_Specific->dci_Formats=NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_0_And_1_0;
+  
+  ASN_SEQUENCE_ADD(&bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list,
+                   ss2);
+  
+  SpCellConfig->spCellConfigDedicated->tag_Id=0;
+}
+
+void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup) {
+
+  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;
+  rlc_BearerConfig                                                 = calloc(1, sizeof(NR_RLC_BearerConfig_t));
+  rlc_BearerConfig->logicalChannelIdentity                         = 2;
+  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->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            = 3;
+  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));
+  *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;
+  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));
+  rlc_Config_drb->present                                          = NR_RLC_Config_PR_am;
+  rlc_Config_drb->choice.am                                        = calloc(1, sizeof(*rlc_Config_drb->choice.am));
+  rlc_Config_drb->choice.am->dl_AM_RLC.sn_FieldLength              = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
+  *(rlc_Config_drb->choice.am->dl_AM_RLC.sn_FieldLength)           = NR_SN_FieldLengthAM_size18;
+  rlc_Config_drb->choice.am->dl_AM_RLC.t_Reassembly                = NR_T_Reassembly_ms80;
+  rlc_Config_drb->choice.am->dl_AM_RLC.t_StatusProhibit            = NR_T_StatusProhibit_ms10;
+  rlc_Config_drb->choice.am->ul_AM_RLC.sn_FieldLength              = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
+  *(rlc_Config_drb->choice.am->ul_AM_RLC.sn_FieldLength)           = NR_SN_FieldLengthAM_size18;
+  rlc_Config_drb->choice.am->ul_AM_RLC.t_PollRetransmit            = NR_T_PollRetransmit_ms80;
+  rlc_Config_drb->choice.am->ul_AM_RLC.pollPDU                     = NR_PollPDU_p64;
+  rlc_Config_drb->choice.am->ul_AM_RLC.pollByte                    = NR_PollByte_kB125;
+  rlc_Config_drb->choice.am->ul_AM_RLC.maxRetxThreshold            = NR_UL_AM_RLC__maxRetxThreshold_t4;
+  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);
+}
+
+void fill_initial_cellGroupConfig(rnti_t rnti,
+				  NR_CellGroupConfig_t *cellGroupConfig,
+				  NR_ServingCellConfigCommon_t *scc) {
+
+  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;
+  ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
+
+  /*
+  // SRB2
+  NR_RLC_BearerConfig_t *rlc_BearerConfig2 = NULL;
+  NR_RLC_Config_t *rlc_Config2 = NULL;
+  NR_LogicalChannelConfig_t *logicalChannelConfig2= NULL;
+  long *logicalChannelGroup2 = NULL;
+  rlc_BearerConfig2                                                 = calloc(1, sizeof(NR_RLC_BearerConfig_t));
+  rlc_BearerConfig2->logicalChannelIdentity                         = 2;
+  rlc_BearerConfig2->servedRadioBearer                              = calloc(1, sizeof(*rlc_BearerConfig2->servedRadioBearer));
+  rlc_BearerConfig2->servedRadioBearer->present                     = NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity;
+  rlc_BearerConfig2->servedRadioBearer->choice.srb_Identity         = 2;
+  rlc_BearerConfig2->reestablishRLC                                 = NULL;
+  rlc_Config2 = calloc(1, sizeof(NR_RLC_Config_t));
+  rlc_Config2->present                                              = NR_RLC_Config_PR_am;
+  rlc_Config2->choice.am                                            = calloc(1, sizeof(*rlc_Config2->choice.am));
+  rlc_Config2->choice.am->dl_AM_RLC.sn_FieldLength                  = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
+  *(rlc_Config2->choice.am->dl_AM_RLC.sn_FieldLength)               = NR_SN_FieldLengthAM_size12;
+  rlc_Config2->choice.am->dl_AM_RLC.t_Reassembly                    = NR_T_Reassembly_ms35;
+  rlc_Config2->choice.am->dl_AM_RLC.t_StatusProhibit                = NR_T_StatusProhibit_ms0;
+  rlc_Config2->choice.am->ul_AM_RLC.sn_FieldLength                  = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
+  *(rlc_Config2->choice.am->ul_AM_RLC.sn_FieldLength)               = NR_SN_FieldLengthAM_size12;
+  rlc_Config2->choice.am->ul_AM_RLC.t_PollRetransmit                = NR_T_PollRetransmit_ms45;
+  rlc_Config2->choice.am->ul_AM_RLC.pollPDU                         = NR_PollPDU_infinity;
+  rlc_Config2->choice.am->ul_AM_RLC.pollByte                        = NR_PollByte_infinity;
+  rlc_Config2->choice.am->ul_AM_RLC.maxRetxThreshold                = NR_UL_AM_RLC__maxRetxThreshold_t8;
+  rlc_BearerConfig2->rlc_Config                                     = rlc_Config2;
+  logicalChannelConfig2                                             = calloc(1, sizeof(NR_LogicalChannelConfig_t));
+  logicalChannelConfig2->ul_SpecificParameters                      = calloc(1, sizeof(*logicalChannelConfig2->ul_SpecificParameters));
+  logicalChannelConfig2->ul_SpecificParameters->priority            = 1;
+  logicalChannelConfig2->ul_SpecificParameters->prioritisedBitRate  = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
+  logicalChannelGroup2                                              = CALLOC(1, sizeof(long));
+  *logicalChannelGroup2                                             = 0;
+  logicalChannelConfig2->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup2;
+  logicalChannelConfig2->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig2->ul_SpecificParameters->schedulingRequestID));
+  *logicalChannelConfig2->ul_SpecificParameters->schedulingRequestID = 0;
+  logicalChannelConfig2->ul_SpecificParameters->logicalChannelSR_Mask = 0;
+  logicalChannelConfig2->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0;
+  rlc_BearerConfig2->mac_LogicalChannelConfig                       = logicalChannelConfig2;
+  ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig2);
+  */
+  
+  cellGroupConfig->rlc_BearerToReleaseList = NULL;
+  
+  /* mac CellGroup Config */
+  if (1) {
+    mac_CellGroupConfig                                                     = calloc(1, sizeof(*mac_CellGroupConfig));
+    mac_CellGroupConfig->schedulingRequestConfig                            = calloc(1, sizeof(*mac_CellGroupConfig->schedulingRequestConfig));
+    mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = CALLOC(1,sizeof(*mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList));
+    struct NR_SchedulingRequestToAddMod *schedulingrequestlist;
+    schedulingrequestlist = CALLOC(1,sizeof(*schedulingrequestlist));
+    schedulingrequestlist->schedulingRequestId  = 0;
+    schedulingrequestlist->sr_ProhibitTimer = CALLOC(1,sizeof(*schedulingrequestlist->sr_ProhibitTimer));
+    *(schedulingrequestlist->sr_ProhibitTimer) = 0;
+    schedulingrequestlist->sr_TransMax      = 0;
+    ASN_SEQUENCE_ADD(&(mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list),schedulingrequestlist);
+    mac_CellGroupConfig->bsr_Config                                         = calloc(1, sizeof(*mac_CellGroupConfig->bsr_Config));
+    mac_CellGroupConfig->bsr_Config->periodicBSR_Timer                      = NR_BSR_Config__periodicBSR_Timer_sf10;
+    mac_CellGroupConfig->bsr_Config->retxBSR_Timer                          = NR_BSR_Config__retxBSR_Timer_sf80;
+    mac_CellGroupConfig->tag_Config                                         = calloc(1, sizeof(*mac_CellGroupConfig->tag_Config));
+    mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL;
+    mac_CellGroupConfig->tag_Config->tag_ToAddModList  = calloc(1,sizeof(*mac_CellGroupConfig->tag_Config->tag_ToAddModList));
+    struct NR_TAG *tag=calloc(1,sizeof(*tag));
+    tag->tag_Id             = 0;
+    tag->timeAlignmentTimer = NR_TimeAlignmentTimer_infinity;
+    ASN_SEQUENCE_ADD(&mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag);
+    mac_CellGroupConfig->phr_Config                                         = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config));
+    mac_CellGroupConfig->phr_Config->present                                = NR_SetupRelease_PHR_Config_PR_setup;
+    mac_CellGroupConfig->phr_Config->choice.setup                           = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config->choice.setup));
+    mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer        = NR_PHR_Config__phr_PeriodicTimer_sf10;
+    mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer        = NR_PHR_Config__phr_ProhibitTimer_sf10;
+    mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB1;
+  }
+  cellGroupConfig->mac_CellGroupConfig                                      = mac_CellGroupConfig;
+
+  physicalCellGroupConfig                                                   = calloc(1,sizeof(*physicalCellGroupConfig));
+  physicalCellGroupConfig->p_NR_FR1                                         = calloc(1,sizeof(*physicalCellGroupConfig->p_NR_FR1));
+  *physicalCellGroupConfig->p_NR_FR1                                        = 20;
+  physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook                          = NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic;
+  cellGroupConfig->physicalCellGroupConfig                                  = physicalCellGroupConfig;
+  
+  cellGroupConfig->spCellConfig                                             = calloc(1,sizeof(*cellGroupConfig->spCellConfig));
+  
+  fill_initial_SpCellConfig(rnti,cellGroupConfig->spCellConfig,scc);
+  
+  cellGroupConfig->sCellToAddModList                                        = NULL;
+  cellGroupConfig->sCellToReleaseList                                       = NULL;
+}
+
 //------------------------------------------------------------------------------
-uint8_t do_RRCSetup(const protocol_ctxt_t        *const ctxt_pP,
-                    rrc_gNB_ue_context_t         *const ue_context_pP,
-                    int                          CC_id,
+uint8_t do_RRCSetup(rrc_gNB_ue_context_t         *const ue_context_pP,
                     uint8_t                      *const buffer,
                     const uint8_t                transaction_id,
-                    NR_SRB_ToAddModList_t        **SRB_configList)
+		    OCTET_STRING_t               *masterCellGroup_from_DU,
+		    NR_ServingCellConfigCommon_t *scc)
 //------------------------------------------------------------------------------
 {
-    asn_enc_rval_t                                   enc_rval;;
+    asn_enc_rval_t                                   enc_rval;
     NR_DL_CCCH_Message_t                             dl_ccch_msg;
     NR_RRCSetup_t                                    *rrcSetup;
     NR_RRCSetup_IEs_t                                *ie;
     NR_SRB_ToAddMod_t                                *SRB1_config          = NULL;
     NR_PDCP_Config_t                                 *pdcp_Config          = NULL;
     NR_CellGroupConfig_t                             *cellGroupConfig      = NULL;
-    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;
-
     char masterCellGroup_buf[1000];
-    long *logicalChannelGroup = NULL;
+
+    AssertFatal(ue_context_pP != NULL,"ue_context_p is null\n");
+    gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
+    NR_SRB_ToAddModList_t        **SRB_configList = &ue_p->SRB_configList;
+
+
 
     memset((void *)&dl_ccch_msg, 0, sizeof(NR_DL_CCCH_Message_t));
     dl_ccch_msg.message.present            = NR_DL_CCCH_MessageType_PR_c1;
@@ -963,6 +1345,7 @@ uint8_t do_RRCSetup(const protocol_ctxt_t        *const ctxt_pP,
     ie = rrcSetup->criticalExtensions.choice.rrcSetup;
 
     /****************************** radioBearerConfig ******************************/
+
     /* Configure SRB1 */
     if (*SRB_configList) {
         free(*SRB_configList);
@@ -982,97 +1365,59 @@ uint8_t do_RRCSetup(const protocol_ctxt_t        *const ctxt_pP,
     ie->radioBearerConfig.drb_ToAddModList  = NULL;
     ie->radioBearerConfig.drb_ToReleaseList = NULL;
     ie->radioBearerConfig.securityConfig    = NULL;
-
+    
     /****************************** masterCellGroup ******************************/
     /* TODO */
-    cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
-    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;
-    rlc_BearerConfig->mac_LogicalChannelConfig                       = logicalChannelConfig;
-    ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
-
-    cellGroupConfig->rlc_BearerToReleaseList = NULL;
-    cellGroupConfig->sCellToAddModList       = NULL;
-    cellGroupConfig->sCellToReleaseList      = NULL;
-
-    /* mac CellGroup Config */
-    mac_CellGroupConfig                                                     = calloc(1, sizeof(NR_MAC_CellGroupConfig_t));
-    mac_CellGroupConfig->bsr_Config                                         = calloc(1, sizeof(*mac_CellGroupConfig->bsr_Config));
-    mac_CellGroupConfig->bsr_Config->periodicBSR_Timer                      = NR_BSR_Config__periodicBSR_Timer_sf10;
-    mac_CellGroupConfig->bsr_Config->retxBSR_Timer                          = NR_BSR_Config__retxBSR_Timer_sf80;
-    mac_CellGroupConfig->phr_Config                                         = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config));
-    mac_CellGroupConfig->phr_Config->present                                = NR_SetupRelease_PHR_Config_PR_setup;
-    mac_CellGroupConfig->phr_Config->choice.setup                           = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config->choice.setup));
-    mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer        = NR_PHR_Config__phr_PeriodicTimer_sf10;
-    mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer        = NR_PHR_Config__phr_ProhibitTimer_sf10;
-    mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB1;
-    cellGroupConfig->mac_CellGroupConfig                                     = mac_CellGroupConfig;
-
-    // cellGroupConfig.physicalCellGroupConfig;
-
-    enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
-                                    NULL,
-                                    (void *)cellGroupConfig,
-                                    masterCellGroup_buf,
-                                    100);
-
-    if(enc_rval.encoded == -1) {
+    if (masterCellGroup_from_DU) {
+      memcpy(&ie->masterCellGroup,masterCellGroup_from_DU,sizeof(*masterCellGroup_from_DU));
+      // decode masterCellGroup OCTET_STRING received from DU and place in ue context
+      uper_decode(NULL,
+		  &asn_DEF_NR_CellGroupConfig,   //might be added prefix later
+		  (void **)&cellGroupConfig,
+		  (uint8_t *)masterCellGroup_from_DU->buf,
+		  masterCellGroup_from_DU->size, 0, 0); 
+      
+      xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)cellGroupConfig);
+    }
+    else {
+      cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
+      fill_initial_cellGroupConfig(ue_context_pP->ue_context.rnti,cellGroupConfig,scc);
+
+      enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
+				       NULL,
+				       (void *)cellGroupConfig,
+				       masterCellGroup_buf,
+				       1000);
+      
+      if(enc_rval.encoded == -1) {
         LOG_E(NR_RRC, "ASN1 message CellGroupConfig encoding failed (%s, %lu)!\n",
-            enc_rval.failed_type->name, enc_rval.encoded);
+	      enc_rval.failed_type->name, enc_rval.encoded);
         return -1;
-    }
-
-    if (OCTET_STRING_fromBuf(&ie->masterCellGroup, masterCellGroup_buf, (enc_rval.encoded+7)/8) == -1) {
+      }
+      
+      if (OCTET_STRING_fromBuf(&ie->masterCellGroup, masterCellGroup_buf, (enc_rval.encoded+7)/8) == -1) {
         LOG_E(NR_RRC, "fatal: OCTET_STRING_fromBuf failed\n");
         return -1;
+      }
     }
 
+    ue_p->masterCellGroup = cellGroupConfig;
+
     if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
-        xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)&dl_ccch_msg);
+      xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)&dl_ccch_msg);
     }
-
     enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_CCCH_Message,
-                                    NULL,
-                                    (void *)&dl_ccch_msg,
-                                    buffer,
-                                    100);
-
+				     NULL,
+				     (void *)&dl_ccch_msg,
+				     buffer,
+				     1000);
+    
     if(enc_rval.encoded == -1) {
-        LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
-            enc_rval.failed_type->name, enc_rval.encoded);
-        return -1;
+      LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+	    enc_rval.failed_type->name, enc_rval.encoded);
+      return -1;
     }
-
+    
     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);
@@ -1146,6 +1491,11 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
                                    const uint8_t                Transaction_id)
 //------------------------------------------------------------------------------
 {
+  NR_UE_CapabilityRequestFilterNR_t *sa_band_filter;
+  NR_FreqBandList_t *sa_band_list;
+  NR_FreqBandInformation_t *sa_band_info;
+  NR_FreqBandInformationNR_t *sa_band_infoNR;
+
   NR_DL_DCCH_Message_t dl_dcch_msg;
   NR_UE_CapabilityRAT_Request_t *ue_capabilityrat_request;
 
@@ -1162,6 +1512,35 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
   memset(ue_capabilityrat_request,0,sizeof(NR_UE_CapabilityRAT_Request_t));
   ue_capabilityrat_request->rat_Type = NR_RAT_Type_nr;
 
+  sa_band_infoNR = (NR_FreqBandInformationNR_t*)calloc(1,sizeof(NR_FreqBandInformationNR_t));
+  sa_band_infoNR->bandNR = 78;
+  sa_band_info = (NR_FreqBandInformation_t*)calloc(1,sizeof(NR_FreqBandInformation_t));
+  sa_band_info->present = NR_FreqBandInformation_PR_bandInformationNR;
+  sa_band_info->choice.bandInformationNR = sa_band_infoNR;
+  
+  sa_band_list = (NR_FreqBandList_t *)calloc(1, sizeof(NR_FreqBandList_t));
+  ASN_SEQUENCE_ADD(&sa_band_list->list, sa_band_info);
+
+  sa_band_filter = (NR_UE_CapabilityRequestFilterNR_t*)calloc(1,sizeof(NR_UE_CapabilityRequestFilterNR_t));
+  sa_band_filter->frequencyBandListFilter = sa_band_list;
+
+  OCTET_STRING_t req_freq;
+  unsigned char req_freq_buf[1024];
+  enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_CapabilityRequestFilterNR,
+				   NULL,
+				   (void *)sa_band_filter,
+				   req_freq_buf,
+				   1024);
+
+  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+    xer_fprint(stdout, &asn_DEF_NR_UE_CapabilityRequestFilterNR, (void *)sa_band_filter);
+  }
+
+  req_freq.buf = req_freq_buf;
+  req_freq.size = (enc_rval.encoded+7)/8;
+
+  ue_capabilityrat_request->capabilityRequestFilter = &req_freq;
+
   ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1->choice.ueCapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityRAT_RequestList.list,
                    ue_capabilityrat_request);
 
@@ -1235,7 +1614,7 @@ uint8_t do_NR_RRCRelease(uint8_t                            *buffer,
 }
 
 //------------------------------------------------------------------------------
-uint16_t do_RRCReconfiguration(
+int16_t do_RRCReconfiguration(
     const protocol_ctxt_t        *const ctxt_pP,
     uint8_t                      *buffer,
     uint8_t                       Transaction_id,
@@ -1245,14 +1624,15 @@ uint16_t do_RRCReconfiguration(
     NR_SecurityConfig_t          *security_config,
     NR_SDAP_Config_t             *sdap_config,
     NR_MeasConfig_t              *meas_config,
-    struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
-                                 *dedicatedNAS_MessageList,
-    NR_MAC_CellGroupConfig_t     *mac_CellGroupConfig)
+    struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList,
+    NR_MAC_CellGroupConfig_t     *mac_CellGroupConfig,
+    NR_CellGroupConfig_t         *cellGroupConfig)
 //------------------------------------------------------------------------------
 {
     NR_DL_DCCH_Message_t                             dl_dcch_msg;
     asn_enc_rval_t                                   enc_rval;
     NR_RRCReconfiguration_IEs_t                      *ie;
+    unsigned char masterCellGroup_buf[1000];
 
     memset(&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t));
     dl_dcch_msg.message.present            = NR_DL_DCCH_MessageType_PR_c1;
@@ -1296,20 +1676,42 @@ uint16_t do_RRCReconfiguration(
     // lateNonCriticalExtension
     ie->lateNonCriticalExtension = NULL;
     // nonCriticalExtension
-    ie->nonCriticalExtension = calloc(1, sizeof(NR_RRCReconfiguration_v1530_IEs_t));
-    ie->nonCriticalExtension->dedicatedNAS_MessageList = dedicatedNAS_MessageList;
+
+    if (cellGroupConfig || dedicatedNAS_MessageList) {
+      ie->nonCriticalExtension = calloc(1, sizeof(NR_RRCReconfiguration_v1530_IEs_t));
+      if (dedicatedNAS_MessageList)
+        ie->nonCriticalExtension->dedicatedNAS_MessageList = dedicatedNAS_MessageList;
+    }
+
+    if(cellGroupConfig!=NULL){
+      enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
+          NULL,
+          (void *)cellGroupConfig,
+          masterCellGroup_buf,
+          1000);
+      if(enc_rval.encoded == -1) {
+        LOG_E(NR_RRC, "ASN1 message CellGroupConfig encoding failed (%s, %lu)!\n",
+            enc_rval.failed_type->name, enc_rval.encoded);
+        return -1;
+      }
+      xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)cellGroupConfig);
+      ie->nonCriticalExtension->masterCellGroup = calloc(1,sizeof(OCTET_STRING_t));
+
+      ie->nonCriticalExtension->masterCellGroup->buf = masterCellGroup_buf;
+      ie->nonCriticalExtension->masterCellGroup->size = (enc_rval.encoded+7)/8;
+    }
 
     dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration = ie;
 
-    if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+    //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
         xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
-    }
+    //}
 
     enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
                                     NULL,
                                     (void *)&dl_dcch_msg,
                                     buffer,
-                                    100);
+                                    1000);
 
     if(enc_rval.encoded == -1) {
         LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
@@ -1509,6 +1911,7 @@ do_NR_DLInformationTransfer(
     AssertFatal(encoded > 0,"ASN1 message encoding failed (%s, %ld)!\n",
                 "DLInformationTransfer", encoded);
     LOG_D(NR_RRC,"DLInformationTransfer Encoded %zd bytes\n", encoded);
+    //for (int i=0;i<encoded;i++) printf("%02x ",(*buffer)[i]);
     return encoded;
 }
 
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h
index bfc4942138ef96e11dbaa9a114b9fa4240369543..419352255ab1bb2e414e2f1632c175f57127bdf3 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h
@@ -65,6 +65,9 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
   gNB_RrcConfigurationReq *configuration
                   );
 
+uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier,
+                    gNB_RrcConfigurationReq *configuration);
+
 void do_RLC_BEARER(uint8_t Mod_id,
                     int CC_id,
                     struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_BearerToAddModList,
@@ -86,12 +89,22 @@ void do_SpCellConfig(gNB_RRC_INST *rrc,
 uint8_t do_RRCReject(uint8_t Mod_id,
                      uint8_t *const buffer);
 
-uint8_t do_RRCSetup(const protocol_ctxt_t        *const ctxt_pP,
-                    rrc_gNB_ue_context_t         *const ue_context_pP,
-                    int                          CC_id,
+void fill_initial_SpCellConfig(rnti_t rnti,
+			       NR_SpCellConfig_t *SpCellConfig,
+			       NR_ServingCellConfigCommon_t *scc);
+
+void fill_initial_cellGroupConfig(rnti_t rnti,
+				  NR_CellGroupConfig_t *cellGroupConfig,
+				  NR_ServingCellConfigCommon_t *scc);
+
+void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup);
+
+uint8_t do_RRCSetup(rrc_gNB_ue_context_t         *const ue_context_pP,
                     uint8_t                      *const buffer,
                     const uint8_t                transaction_id,
-                    NR_SRB_ToAddModList_t        **SRB_configList);
+                    OCTET_STRING_t               *masterCellGroup_from_DU,
+                    NR_ServingCellConfigCommon_t *scc);
+
 uint8_t do_NR_SecurityModeCommand(
                     const protocol_ctxt_t *const ctxt_pP,
                     uint8_t *const buffer,
@@ -105,7 +118,8 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
 
 uint8_t do_NR_RRCRelease(uint8_t *buffer,
                          uint8_t Transaction_id);
-uint16_t do_RRCReconfiguration(
+
+int16_t do_RRCReconfiguration(
     const protocol_ctxt_t        *const ctxt_pP,
     uint8_t                      *buffer,
     uint8_t                       Transaction_id,
@@ -115,9 +129,9 @@ uint16_t do_RRCReconfiguration(
     NR_SecurityConfig_t          *security_config,
     NR_SDAP_Config_t             *sdap_config,
     NR_MeasConfig_t              *meas_config,
-    struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
-                                 *dedicatedNAS_MessageList,
-    NR_MAC_CellGroupConfig_t     *mac_CellGroupConfig);
+    struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList,
+    NR_MAC_CellGroupConfig_t     *mac_CellGroupConfig,
+    NR_CellGroupConfig_t         *cellGroupConfig);
                     
 uint8_t do_RRCSetupComplete(uint8_t Mod_id, 
                             uint8_t *buffer, 
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index 7fd9e5d53a5bfe07f4d71d7ef71cbc8039f86937..5efb2e1e644edebd75fd9463680af8ff3aeee4f1 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -66,6 +66,7 @@
 #include "NR_CellGroupConfig.h"
 #include "NR_ServingCellConfigCommon.h"
 #include "NR_EstablishmentCause.h"
+#include "NR_SIB1.h"
 //-------------------
 
 #include "intertask_interface.h"
@@ -300,6 +301,7 @@ typedef struct gNB_RRC_UE_s {
   int                                UE_MRDC_Capability_size;
 
   NR_CellGroupConfig_t               *secondaryCellGroup;
+  NR_CellGroupConfig_t               *masterCellGroup;
   NR_RRCReconfiguration_t            *reconfig;
   NR_RadioBearerConfig_t             *rb_config;
 
@@ -315,7 +317,7 @@ typedef struct gNB_RRC_UE_s {
   NR_CipheringAlgorithm_t            ciphering_algorithm;
   e_NR_IntegrityProtAlgorithm        integrity_algorithm;
 
-  uint8_t                            status;
+  uint8_t                            StatusRrc;
   rnti_t                             rnti;
   uint64_t                           random_ue_identity;
 
@@ -425,10 +427,21 @@ typedef struct {
   uint8_t                                   *SIB1;
   uint8_t                                   sizeof_SIB1;
 
+  uint8_t                                   *SIB23;
+  uint8_t                                   sizeof_SIB23;
+
   uint8_t                                   *ServingCellConfigCommon;
   uint8_t                                   sizeof_servingcellconfigcommon;
 
+  int                                       physCellId;
+
   NR_BCCH_BCH_Message_t                     mib;
+  NR_BCCH_BCH_Message_t                    *mib_DU;
+  NR_BCCH_DL_SCH_Message_t                 *siblock1_DU;
+  NR_SIB1_t                                *sib1;
+  NR_SIB2_t                                *sib2;
+  NR_SIB3_t                                *sib3;
+  NR_BCCH_DL_SCH_Message_t                  systemInformation; // SIB23
   int ssb_SubcarrierOffset;                  
   int pdsch_AntennaPorts;
   int pusch_AntennaPorts;
@@ -441,7 +454,6 @@ typedef struct {
   NR_SRB_INFO                               SI;
   NR_SRB_INFO                               Srb0;
   int                                       initial_csi_index[MAX_NR_RRC_UE_CONTEXTS];
-  int                                       physCellId;
   int                                       p_gNB;
 
 } rrc_gNB_carrier_data_t;
@@ -461,6 +473,9 @@ typedef struct {
 //---NR---(completely change)---------------------
 typedef struct gNB_RRC_INST_s {
 
+  ngran_node_t                                        node_type;
+  uint32_t                                            node_id;
+  char                                               *node_name;
   int                                                 module_id;
   eth_params_t                                        eth_params_s;
   rrc_gNB_carrier_data_t                              carrier;
@@ -472,6 +487,12 @@ typedef struct gNB_RRC_INST_s {
   hash_table_t                                        *initial_id2_ngap_ids;
   hash_table_t                                        *ngap_id2_ngap_ids   ;
 
+  /// NR cell id
+  uint64_t nr_cellid;
+
+  // RRC configuration
+  gNB_RrcConfigurationReq configuration;
+
   // other PLMN parameters
   /// Mobile country code
   int mcc;
@@ -488,6 +509,10 @@ typedef struct gNB_RRC_INST_s {
   int srb1_timer_reordering;
   int srb1_timer_status_prohibit;
   int srs_enable[MAX_NUM_CCs];
+  uint16_t sctp_in_streams;
+  uint16_t sctp_out_streams;
+  int cell_info_configured;
+  pthread_mutex_t cell_info_mutex;
 
   // security configuration (preferred algorithms)
   nr_security_configuration_t security;
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index 7923cf6e05b1a50eb6df2b06773ed6f2fcea0c53..ff7547832e5bf28a1f66791eac1896e5dbe7fc0e 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -106,6 +106,14 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
 		       NR_RRCReconfiguration_t *reconfig,
 		       NR_RadioBearerConfig_t *rbconfig);
 
+void
+rrc_gNB_generate_RRCSetup(
+    const protocol_ctxt_t        *const ctxt_pP,
+    rrc_gNB_ue_context_t         *const ue_context_pP,
+    OCTET_STRING_t               *masterCellGroup_from_DU,
+    NR_ServingCellConfigCommon_t *scc,
+    const int                    CC_id);
+
 int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m);
 
 void
@@ -177,6 +185,7 @@ int8_t nr_mac_rrc_data_ind(
 int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
                            const uint8_t      *buffer,
                            int                buffer_length,
+                           OCTET_STRING_t     *du_to_cu_rrc_container,
                            const int          CC_id);
 
 void
@@ -186,3 +195,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
     uint8_t                  xid,
     uint32_t                 nas_length,
     uint8_t                 *nas_buffer);
+
+void 
+rrc_gNB_generate_dedicatedRRCReconfiguration(
+    const protocol_ctxt_t     *const ctxt_pP,
+    rrc_gNB_ue_context_t      *ue_context_pP);
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index bbaff81698ef30e6c631e5929a62b515d13604b3..23e3391c853b824e22e081770ede83baee7ba1d2 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -55,6 +55,7 @@
 #include "NR_RRCSetupRequest-IEs.h"
 #include "NR_RRCSetupComplete-IEs.h"
 #include "NR_RRCReestablishmentRequest-IEs.h"
+#include "NR_MIB.h"
 
 #include "rlc.h"
 #include "rrc_eNB_UE_context.h"
@@ -112,11 +113,11 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
     struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
 
 extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP,
-    const NR_SRB_ToAddModList_t   * const srb2add_listP,
-    const NR_DRB_ToAddModList_t   * const drb2add_listP,
-    const NR_DRB_ToReleaseList_t  * const drb2release_listP,
-    const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
-    struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
+                                                   const NR_SRB_ToAddModList_t   * const srb2add_listP,
+                                                   const NR_DRB_ToAddModList_t   * const drb2add_listP,
+                                                   const NR_DRB_ToReleaseList_t  * const drb2release_listP,
+                                                   const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
+                                                   struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
 
 static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn);
 
@@ -213,27 +214,44 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge(
 
 static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration) {
   LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__);
-  rrc->carrier.MIB             = (uint8_t *) malloc16(4);
-  rrc->carrier.sizeof_MIB      = do_MIB_NR(rrc,0);
+  if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
+    rrc->carrier.MIB             = (uint8_t *) malloc16(4);
+    rrc->carrier.sizeof_MIB      = do_MIB_NR(rrc,0);
+  }
 
-  if(get_softmodem_params()->sa) {
+    if((get_softmodem_params()->sa) && ( (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)))) {
     rrc->carrier.sizeof_SIB1 = do_SIB1_NR(&rrc->carrier,configuration);
   }
 
+  if (!NODE_IS_DU(rrc->node_type)) {
+    rrc->carrier.SIB23 = (uint8_t *) malloc16(100);
+    AssertFatal(rrc->carrier.SIB23 != NULL, "cannot allocate memory for SIB");
+    rrc->carrier.sizeof_SIB23 = do_SIB23_NR(&rrc->carrier, configuration);
+    LOG_I(NR_RRC,"do_SIB23_NR, size %d \n ", rrc->carrier.sizeof_SIB23);
+    AssertFatal(rrc->carrier.sizeof_SIB23 != 255,"FATAL, RC.nrrrc[mod].carrier[CC_id].sizeof_SIB23 == 255");
+  }
+
   LOG_I(NR_RRC,"Done init_NR_SI\n");
-  rrc_mac_config_req_gNB(rrc->module_id,
-                         rrc->carrier.ssb_SubcarrierOffset,
-                         rrc->carrier.pdsch_AntennaPorts,
-                         rrc->carrier.pusch_AntennaPorts,
-                         rrc->carrier.pusch_TargetSNRx10,
-                         rrc->carrier.pucch_TargetSNRx10,
-                         (NR_ServingCellConfigCommon_t *)rrc->carrier.servingcellconfigcommon,
-                         0,
-                         0, // WIP hardcoded rnti
-                         (NR_CellGroupConfig_t *)NULL
-                        );
 
-  if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0 || get_softmodem_params()->sa > 0) {
+  if (NODE_IS_MONOLITHIC(rrc->node_type)){
+    rrc_mac_config_req_gNB(rrc->module_id,
+			   rrc->carrier.ssb_SubcarrierOffset,
+			   rrc->carrier.pdsch_AntennaPorts,
+			   rrc->carrier.pusch_AntennaPorts,
+			   (NR_ServingCellConfigCommon_t *)rrc->carrier.servingcellconfigcommon,
+			   0,
+			   0, // WIP hardcoded rnti
+			   (NR_CellGroupConfig_t *)NULL
+			   );
+  }
+
+  /* set flag to indicate that cell information is configured. This is required
+   * in DU to trigger F1AP_SETUP procedure */
+  pthread_mutex_lock(&rrc->cell_info_mutex);
+  rrc->cell_info_configured=1;
+  pthread_mutex_unlock(&rrc->cell_info_mutex);
+
+  if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) {
     // This is for phytest only, emulate first X2 message if uecap.raw file is present
     FILE *fd;
     fd = fopen("uecap.raw","r");
@@ -281,12 +299,13 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
       ue_context_p->ue_context.spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig));
       ue_context_p->ue_context.spCellConfig->spCellConfigDedicated = configuration->scd;
       LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p);
-      rrc_add_nsa_user(rrc,ue_context_p,NULL);
+      if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) {
+        rrc_add_nsa_user(rrc,ue_context_p,NULL);
+      }
     }
   }
 }
 
-
 char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration) {
   protocol_ctxt_t      ctxt;
   gNB_RRC_INST         *rrc=RC.nrrrc[gnb_mod_idP];
@@ -311,9 +330,9 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
   rrc->carrier.ssb_SubcarrierOffset = configuration->ssb_SubcarrierOffset;
   rrc->carrier.pdsch_AntennaPorts = configuration->pdsch_AntennaPorts;
   rrc->carrier.pusch_AntennaPorts = configuration->pusch_AntennaPorts;
-  rrc->carrier.pusch_TargetSNRx10 = configuration->pusch_TargetSNRx10;
-  rrc->carrier.pucch_TargetSNRx10 = configuration->pucch_TargetSNRx10;
-  /// System Information INIT
+   /// System Information INIT
+  pthread_mutex_init(&rrc->cell_info_mutex,NULL);
+  rrc->cell_info_configured = 0;
   LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" Checking release \n",PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt));
   init_NR_SI(rrc, configuration);
   rrc_init_nr_global_param();
@@ -362,14 +381,16 @@ rrc_gNB_get_next_transaction_identifier(
 //-----------------------------------------------------------------------------
 void
 rrc_gNB_generate_RRCSetup(
-    const protocol_ctxt_t    *const ctxt_pP,
-    rrc_gNB_ue_context_t     *const ue_context_pP,
-    const int                CC_id
+    const protocol_ctxt_t        *const ctxt_pP,
+    rrc_gNB_ue_context_t         *const ue_context_pP,
+    OCTET_STRING_t               *masterCellGroup_from_DU,
+    NR_ServingCellConfigCommon_t *scc,
+    const int                    CC_id
 )
 //-----------------------------------------------------------------------------
 {
   LOG_I(NR_RRC, "rrc_gNB_generate_RRCSetup \n");
-  NR_SRB_ToAddModList_t        **SRB_configList = NULL;
+  MessageDef                    *message_p;
 
   // T(T_GNB_RRC_SETUP,
   //   T_INT(ctxt_pP->module_id),
@@ -377,55 +398,131 @@ rrc_gNB_generate_RRCSetup(
   //   T_INT(ctxt_pP->subframe),
   //   T_INT(ctxt_pP->rnti));
   gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
-  SRB_configList = &ue_p->SRB_configList;
-  ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ctxt_pP,
-              ue_context_pP,
-              CC_id,
-              (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
-              rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
-              SRB_configList);
+  ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ue_context_pP,
+						  (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
+						  rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
+						  masterCellGroup_from_DU,
+						  scc);
 
   LOG_DUMPMSG(NR_RRC, DEBUG_RRC,
               (char *)(ue_p->Srb0.Tx_buffer.Payload),
               ue_p->Srb0.Tx_buffer.payload_size,
               "[MSG] RRC Setup\n");
+  gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
+  switch (rrc->node_type) {
+    case ngran_gNB_CU:
+      // create an ITTI message
+      /* TODO: F1 IDs ar missing in RRC */
+      nr_rrc_pdcp_config_asn1_req(ctxt_pP,
+				  ue_context_pP->ue_context.SRB_configList,
+				  NULL,
+				  NULL,
+				  0xff,
+				  NULL,
+				  NULL,
+				  NULL,
+				  NULL,
+				  NULL,
+				  NULL,
+				  NULL);
+      message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE);
+      F1AP_DL_RRC_MESSAGE (message_p).rrc_container        =  (uint8_t *)ue_p->Srb0.Tx_buffer.Payload;
+      F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size;
+      F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id         = 0;
+      F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id         = 0;
+      F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id     = 0xFFFFFFFF; // unknown
+      F1AP_DL_RRC_MESSAGE (message_p).rnti                 = ue_p->rnti;
+      F1AP_DL_RRC_MESSAGE (message_p).srb_id               = CCCH;
+      F1AP_DL_RRC_MESSAGE (message_p).execute_duplication  = 1;
+      F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc = 0;
+      itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p);
+      LOG_D(NR_RRC, "Send F1AP_DL_RRC_MESSAGE with ITTI\n");
+
+    break;
+
+    case ngran_gNB_DU:
+      // nothing to do for DU
+      AssertFatal(1==0,"nothing to do for DU\n");
+      break;
 
-  LOG_D(NR_RRC,
-      PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ  (SRB1) ---> MAC_gNB\n",
-      PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
-
-  // rrc_mac_config_req_eNB
+    case ngran_gNB:
+    {
+      // rrc_mac_config_req_gNB
 
-  MSC_LOG_TX_MESSAGE(
-      MSC_RRC_GNB,
-      MSC_RRC_UE,
-      ue_p->Srb0.Tx_buffer.Header, // LG WARNING
-      ue_p->Srb0.Tx_buffer.payload_size,
-      MSC_AS_TIME_FMT" RRCSetup UE %x size %u",
-      MSC_AS_TIME_ARGS(ctxt_pP),
-      ue_context_pP->ue_context.rnti,
-      ue_p->Srb0.Tx_buffer.payload_size);
-  LOG_I(NR_RRC,
-      PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n",
-      PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
-      ue_p->Srb0.Tx_buffer.payload_size);
-  // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
-  ue_context_pP->ue_context.ue_release_timer = 1;
-  // remove UE after 10 frames after RRCConnectionRelease is triggered
-  ue_context_pP->ue_context.ue_release_timer_thres = 1000;
-  /* init timers */
-  //   ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0;
 #ifdef ITTI_SIM
-  MessageDef *message_p;
-  uint8_t *message_buffer;
-  message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM,
+      LOG_I(NR_RRC,
+            PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n",
+            PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
             ue_p->Srb0.Tx_buffer.payload_size);
-  memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size);
-  message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND);
-  GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
-  GNB_RRC_CCCH_DATA_IND (message_p).size  = ue_p->Srb0.Tx_buffer.payload_size;
-  itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
+      uint8_t *message_buffer;
+      message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM,
+                ue_p->Srb0.Tx_buffer.payload_size);
+      memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size);
+      message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND);
+      GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
+      GNB_RRC_CCCH_DATA_IND (message_p).size  = ue_p->Srb0.Tx_buffer.payload_size;
+      itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
+#else
+      LOG_D(NR_RRC,
+	    PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ  (SRB1) ---> MAC_gNB\n",
+	    PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
+      MSC_LOG_TX_MESSAGE(
+			 MSC_RRC_GNB,
+			 MSC_RRC_UE,
+			 ue_p->Srb0.Tx_buffer.Header, // LG WARNING
+			 ue_p->Srb0.Tx_buffer.payload_size,
+			 MSC_AS_TIME_FMT" RRCSetup UE %x size %u",
+			 MSC_AS_TIME_ARGS(ctxt_pP),
+			 ue_context_pP->ue_context.rnti,
+			 ue_p->Srb0.Tx_buffer.payload_size);
+      LOG_I(NR_RRC,
+	    PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n",
+	    PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
+	    ue_p->Srb0.Tx_buffer.payload_size);
+      // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
+      ue_context_pP->ue_context.ue_release_timer = 1;
+      // remove UE after 10 frames after RRCConnectionRelease is triggered
+      ue_context_pP->ue_context.ue_release_timer_thres = 1000;
+      /* init timers */
+      //   ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0;
+
+      // configure MAC
+      rrc_mac_config_req_gNB(rrc->module_id,
+                             rrc->carrier.ssb_SubcarrierOffset,
+                             rrc->carrier.pdsch_AntennaPorts,
+                             rrc->carrier.pusch_AntennaPorts,
+                             NULL,
+                             0,
+                             ue_context_pP->ue_context.rnti,
+                             get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : (NR_CellGroupConfig_t *)NULL);
+
+      nr_rrc_rlc_config_asn1_req(ctxt_pP,
+                                 ue_context_pP->ue_context.SRB_configList,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
+
+      nr_rrc_pdcp_config_asn1_req(ctxt_pP,
+                                  ue_context_pP->ue_context.SRB_configList,
+                                  NULL,
+                                  NULL,
+                                  0xff,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
 #endif
+    }
+    break;
+
+    default:
+      LOG_W(NR_RRC, "Unknown node type %d\n", rrc->node_type);
+      break;
+  }
 }
 
 //-----------------------------------------------------------------------------
@@ -437,20 +534,18 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
 //-----------------------------------------------------------------------------
 {
   LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n");
-  NR_SRB_ToAddModList_t        **SRB_configList = NULL;
   rrc_gNB_ue_context_t         *ue_context_pP   = NULL;
   gNB_RRC_INST                 *rrc_instance_p = RC.nrrrc[ctxt_pP->module_id];
+  NR_ServingCellConfigCommon_t *scc=rrc_instance_p->carrier.servingcellconfigcommon;
 
   ue_context_pP = rrc_gNB_get_next_free_ue_context(ctxt_pP, rrc_instance_p, 0);
 
   gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
-  SRB_configList = &ue_p->SRB_configList;
-  ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ctxt_pP,
-              ue_context_pP,
-              CC_id,
-              (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
-              rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
-              SRB_configList);
+  ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ue_context_pP,
+						  (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
+						  rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
+						  NULL,
+						  scc);
 
   LOG_DUMPMSG(NR_RRC, DEBUG_RRC,
               (char *)(ue_p->Srb0.Tx_buffer.Payload),
@@ -465,43 +560,41 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
                          rrc_instance_p->carrier.ssb_SubcarrierOffset,
                          rrc_instance_p->carrier.pdsch_AntennaPorts,
                          rrc_instance_p->carrier.pusch_AntennaPorts,
-                         rrc_instance_p->carrier.pusch_TargetSNRx10,
-                         rrc_instance_p->carrier.pucch_TargetSNRx10,
                          (NR_ServingCellConfigCommon_t *)rrc_instance_p->carrier.servingcellconfigcommon,
                          0,
                          ue_context_pP->ue_context.rnti,
                          (NR_CellGroupConfig_t *)NULL
-                        );
+			 );
 
-    MSC_LOG_TX_MESSAGE(
-        MSC_RRC_GNB,
-        MSC_RRC_UE,
-        ue_p->Srb0.Tx_buffer.Header, // LG WARNING
-        ue_p->Srb0.Tx_buffer.payload_size,
-        MSC_AS_TIME_FMT" RRCSetup UE %x size %u",
-        MSC_AS_TIME_ARGS(ctxt_pP),
-        ue_context_pP->ue_context.rnti,
-        ue_p->Srb0.Tx_buffer.payload_size);
-    LOG_I(NR_RRC,
+  MSC_LOG_TX_MESSAGE(
+		     MSC_RRC_GNB,
+		     MSC_RRC_UE,
+		     ue_p->Srb0.Tx_buffer.Header, // LG WARNING
+		     ue_p->Srb0.Tx_buffer.payload_size,
+		     MSC_AS_TIME_FMT" RRCSetup UE %x size %u",
+		     MSC_AS_TIME_ARGS(ctxt_pP),
+		     ue_context_pP->ue_context.rnti,
+		     ue_p->Srb0.Tx_buffer.payload_size);
+  LOG_I(NR_RRC,
         PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n",
         PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
         ue_p->Srb0.Tx_buffer.payload_size);
-    // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
-    ue_context_pP->ue_context.ue_release_timer = 1;
-    // remove UE after 10 frames after RRCConnectionRelease is triggered
-    ue_context_pP->ue_context.ue_release_timer_thres = 1000;
-    /* init timers */
-    //   ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0;
+  // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
+  ue_context_pP->ue_context.ue_release_timer = 1;
+  // remove UE after 10 frames after RRCConnectionRelease is triggered
+  ue_context_pP->ue_context.ue_release_timer_thres = 1000;
+  /* init timers */
+  //   ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0;
 #ifdef ITTI_SIM
-    MessageDef *message_p;
-    uint8_t *message_buffer;
-    message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM,
-              ue_p->Srb0.Tx_buffer.payload_size);
-    memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size);
-    message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND);
-    GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
-    GNB_RRC_CCCH_DATA_IND (message_p).size  = ue_p->Srb0.Tx_buffer.payload_size;
-    itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
+  MessageDef *message_p;
+  uint8_t *message_buffer;
+  message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM,
+				ue_p->Srb0.Tx_buffer.payload_size);
+  memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size);
+  message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND);
+  GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
+  GNB_RRC_CCCH_DATA_IND (message_p).size  = ue_p->Srb0.Tx_buffer.payload_size;
+  itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
 #endif
 }
 
@@ -515,6 +608,8 @@ rrc_gNB_generate_RRCReject(
 {
   LOG_I(NR_RRC, "rrc_gNB_generate_RRCReject \n");
   gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
+  MessageDef   *message_p;
+
   ue_p->Srb0.Tx_buffer.payload_size = do_RRCReject(ctxt_pP->module_id,
                                                   (uint8_t *)ue_p->Srb0.Tx_buffer.Payload);
   LOG_DUMPMSG(NR_RRC, DEBUG_RRC,
@@ -534,17 +629,47 @@ rrc_gNB_generate_RRCReject(
       PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
       ue_p->Srb0.Tx_buffer.payload_size);
 
+  switch (RC.nrrrc[ctxt_pP->module_id]->node_type) {
+    case ngran_gNB_CU:
+      // create an ITTI message
+      message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE);
+      F1AP_DL_RRC_MESSAGE (message_p).rrc_container        = (uint8_t *)ue_p->Srb0.Tx_buffer.Payload;
+      F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size;
+      F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id         = 0;
+      F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id         = 0;
+      F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id     = 0xFFFFFFFF; // unknown
+      F1AP_DL_RRC_MESSAGE (message_p).rnti                 = ue_p->rnti;
+      F1AP_DL_RRC_MESSAGE (message_p).srb_id               = CCCH;
+      F1AP_DL_RRC_MESSAGE (message_p).execute_duplication  = 1;
+      F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc = 0;
+      itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p);
+      LOG_D(NR_RRC, "Send F1AP_DL_RRC_MESSAGE with ITTI\n");
+      break;
+
+    case ngran_gNB_DU:
+      // nothing to do for DU
+      AssertFatal(1==0,"nothing to do for DU\n");
+      break;
+
+    case ngran_gNB:
+    {
 #ifdef ITTI_SIM
-  MessageDef *message_p;
-  uint8_t *message_buffer;
-  message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM,
-            ue_p->Srb0.Tx_buffer.payload_size);
-  memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size);
-  message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND);
-  GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
-  GNB_RRC_CCCH_DATA_IND (message_p).size  = ue_p->Srb0.Tx_buffer.payload_size;
-  itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
+      uint8_t *message_buffer;
+      message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM,
+                ue_p->Srb0.Tx_buffer.payload_size);
+      memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size);
+      message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND);
+      GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
+      GNB_RRC_CCCH_DATA_IND (message_p).size  = ue_p->Srb0.Tx_buffer.payload_size;
+      itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
 #endif
+      // rrc_mac_config_req_gNB
+    }
+      break;
+
+    default :
+      LOG_W(NR_RRC, "Unknown node type %d\n", RC.nrrrc[ctxt_pP->module_id]->node_type);
+  }
 }
 
 //-----------------------------------------------------------------------------
@@ -562,7 +687,8 @@ rrc_gNB_process_RRCSetupComplete(
   LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing NR_RRCSetupComplete from UE (SRB1 Active)\n",
       PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
   ue_context_pP->ue_context.Srb1.Active = 1;
-  ue_context_pP->ue_context.status = NR_RRC_CONNECTED;
+  ue_context_pP->ue_context.Srb1.Srb_info.Srb_id = 1;
+  ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED;
 
   if (AMF_MODE_ENABLED) {
     rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete);
@@ -581,13 +707,13 @@ rrc_gNB_generate_defaultRRCReconfiguration(
 {
   uint8_t                       buffer[RRC_BUF_SIZE];
   uint16_t                      size;
-  NR_SRB_ToAddModList_t        **SRB_configList2 = NULL;
+  /*NR_SRB_ToAddModList_t        **SRB_configList2 = NULL;
   NR_SRB_ToAddModList_t        *SRB_configList  = ue_context_pP->ue_context.SRB_configList;
   NR_DRB_ToAddModList_t        **DRB_configList  = NULL;
   NR_DRB_ToAddModList_t        **DRB_configList2 = NULL;
   NR_SRB_ToAddMod_t            *SRB2_config     = NULL;
   NR_DRB_ToAddMod_t            *DRB_config      = NULL;
-  NR_SDAP_Config_t             *sdap_config     = NULL;
+  NR_SDAP_Config_t             *sdap_config     = NULL;*/
   struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
                                *dedicatedNAS_MessageList = NULL;
   NR_DedicatedNAS_Message_t    *dedicatedNAS_Message = NULL;
@@ -596,7 +722,7 @@ rrc_gNB_generate_defaultRRCReconfiguration(
 
   /******************** Radio Bearer Config ********************/
   /* Configure SRB2 */
-  SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
+  /*SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
   if (*SRB_configList2) {
     free(*SRB_configList2);
   }
@@ -605,10 +731,10 @@ rrc_gNB_generate_defaultRRCReconfiguration(
   SRB2_config = CALLOC(1, sizeof(*SRB2_config));
   SRB2_config->srb_Identity = 2;
   ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
-  ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
+  ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);*/
 
   /* Configure DRB */
-  DRB_configList = &ue_context_pP->ue_context.DRB_configList;
+  /*DRB_configList = &ue_context_pP->ue_context.DRB_configList;
   if (*DRB_configList) {
       free(*DRB_configList);
   }
@@ -654,7 +780,7 @@ rrc_gNB_generate_defaultRRCReconfiguration(
   DRB_config->pdcp_Config->ext1 = NULL;
 
   ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config);
-  ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
+  ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);*/
 
   dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
 
@@ -676,13 +802,14 @@ rrc_gNB_generate_defaultRRCReconfiguration(
   memset(buffer, 0, RRC_BUF_SIZE);
   size = do_RRCReconfiguration(ctxt_pP, buffer,
                                 xid,
-                                *SRB_configList2,
-                                *DRB_configList,
+                                NULL, //*SRB_configList2,
+                                NULL, //*DRB_configList,
                                 NULL,
                                 NULL,
                                 NULL,
                                 NULL,
                                 dedicatedNAS_MessageList,
+                                NULL,
                                 NULL);
 
   free(ue_context_pP->ue_context.nas_pdu.buffer);
@@ -693,7 +820,38 @@ rrc_gNB_generate_defaultRRCReconfiguration(
           ctxt_pP->frame,
           size,
           ue_context_pP->ue_context.rnti);
-  LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
+  switch (RC.nrrrc[ctxt_pP->module_id]->node_type) {
+    case ngran_gNB_CU:
+      nr_rrc_data_req(ctxt_pP,
+                  DCCH,
+                  rrc_gNB_mui++,
+                  SDU_CONFIRM_NO,
+                  size,
+                  buffer,
+                  PDCP_TRANSMISSION_MODE_CONTROL);
+      // rrc_pdcp_config_asn1_req
+
+      break;
+
+    case ngran_gNB_DU:
+      // nothing to do for DU
+      AssertFatal(1==0,"nothing to do for DU\n");
+      break;
+
+    case ngran_gNB:
+    {
+#ifdef ITTI_SIM
+      MessageDef *message_p;
+      uint8_t *message_buffer;
+      message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size);
+      memcpy (message_buffer, buffer, size);
+      message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND);
+      GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
+      GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
+      GNB_RRC_DCCH_DATA_IND (message_p).size	= size;
+      itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
+#else
+      LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
           ctxt_pP->frame,
           ctxt_pP->module_id,
           size,
@@ -701,7 +859,7 @@ rrc_gNB_generate_defaultRRCReconfiguration(
           rrc_gNB_mui,
           ctxt_pP->module_id,
           DCCH);
-  MSC_LOG_TX_MESSAGE(MSC_RRC_GNB,
+      MSC_LOG_TX_MESSAGE(MSC_RRC_GNB,
           MSC_RRC_UE,
           buffer,
           size,
@@ -710,27 +868,247 @@ rrc_gNB_generate_defaultRRCReconfiguration(
           ue_context_pP->ue_context.rnti,
           rrc_gNB_mui,
           size);
+      nr_rrc_data_req(ctxt_pP,
+          DCCH,
+          rrc_gNB_mui++,
+          SDU_CONFIRM_NO,
+          size,
+          buffer,
+          PDCP_TRANSMISSION_MODE_CONTROL);
+      // rrc_pdcp_config_asn1_req
+#endif
+      // rrc_rlc_config_asn1_req
+    }
+    break;
+
+  default :
+    LOG_W(NR_RRC, "Unknown node type %d\n", RC.nrrrc[ctxt_pP->module_id]->node_type);
+  }
+}
+
+//-----------------------------------------------------------------------------
+void
+rrc_gNB_generate_dedicatedRRCReconfiguration(
+    const protocol_ctxt_t     *const ctxt_pP,
+    rrc_gNB_ue_context_t      *ue_context_pP
+)
+//-----------------------------------------------------------------------------
+{
+  NR_DRB_ToAddMod_t             *DRB_config           = NULL;
+  NR_SRB_ToAddMod_t             *SRB2_config          = NULL;
+  NR_SDAP_Config_t              *sdap_config          = NULL;
+  NR_DRB_ToAddModList_t        **DRB_configList  = NULL;
+  NR_DRB_ToAddModList_t        **DRB_configList2 = NULL;
+  NR_SRB_ToAddModList_t        **SRB_configList2 = NULL;
+  NR_SRB_ToAddModList_t        *SRB_configList  = ue_context_pP->ue_context.SRB_configList;
+  struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
+                                *dedicatedNAS_MessageList = NULL;
+  NR_DedicatedNAS_Message_t     *dedicatedNAS_Message = NULL;
+  uint8_t                        buffer[RRC_BUF_SIZE];
+  uint16_t                       size;
+  int                            qos_flow_index = 0;
+  NR_QFI_t                       qfi = 0;
+  int                            pdu_sessions_done = 0;
+  int i;
+  NR_CellGroupConfig_t *cellGroupConfig;
+
+  uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
+
+  /* Configure SRB2 */
+  SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
+  if (*SRB_configList2) {
+    free(*SRB_configList2);
+  }
+  *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
+  memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
+  SRB2_config = CALLOC(1, sizeof(*SRB2_config));
+  SRB2_config->srb_Identity = 2;
+  ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
+  ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
+
+  DRB_configList = &ue_context_pP->ue_context.DRB_configList;
+  if (*DRB_configList) {
+      free(*DRB_configList);
+  }
+  *DRB_configList = CALLOC(1, sizeof(**DRB_configList));
+  memset(*DRB_configList, 0, sizeof(**DRB_configList));
+
+  DRB_configList2 = &ue_context_pP->ue_context.DRB_configList2[xid];
+  if (*DRB_configList2) {
+      free(*DRB_configList2);
+  }
+  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
+  memset(*DRB_configList2, 0, sizeof(**DRB_configList2));
+
+  dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
+
+  for (i = 0; i < ue_context_pP->ue_context.setup_pdu_sessions; i++) {
+    if (pdu_sessions_done >= ue_context_pP->ue_context.nb_of_pdusessions) {
+      break;
+    }
+
+    if (ue_context_pP->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE) {
+      continue;
+    }
+
+    DRB_config = CALLOC(1, sizeof(*DRB_config));
+    DRB_config->drb_Identity = i+1;
+    DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation));
+    DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
+    // sdap_Config
+    sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
+    memset(sdap_config, 0, sizeof(NR_SDAP_Config_t));
+    sdap_config->pdu_Session = ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
+    sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
+    sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
+    sdap_config->defaultDRB = TRUE;
+    sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
+    memset(sdap_config->mappedQoS_FlowsToAdd, 0, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
+
+    for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pdusession[i].param.nb_qos; qos_flow_index++) {
+      qfi = ue_context_pP->ue_context.pdusession[i].param.qos[qos_flow_index].qfi;
+      ASN_SEQUENCE_ADD(&sdap_config->mappedQoS_FlowsToAdd->list, &qfi);
+    }
+    sdap_config->mappedQoS_FlowsToRelease = NULL;
+    DRB_config->cnAssociation->choice.sdap_Config = sdap_config;
+
+    // pdcp_Config
+    DRB_config->reestablishPDCP = NULL;
+    DRB_config->recoverPDCP = NULL;
+    DRB_config->pdcp_Config = calloc(1, sizeof(*DRB_config->pdcp_Config));
+    DRB_config->pdcp_Config->drb = calloc(1,sizeof(*DRB_config->pdcp_Config->drb));
+    DRB_config->pdcp_Config->drb->discardTimer = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->discardTimer));
+    *DRB_config->pdcp_Config->drb->discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
+    DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL));
+    *DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
+    DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL));
+    *DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
+    DRB_config->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
+    DRB_config->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
+
+    DRB_config->pdcp_Config->drb->integrityProtection = NULL;
+    DRB_config->pdcp_Config->drb->statusReportRequired = NULL;
+    DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL;
+    DRB_config->pdcp_Config->moreThanOneRLC = NULL;
+
+    DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering));
+    *DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms750;
+    DRB_config->pdcp_Config->ext1 = NULL;
+
+    // Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping
+    for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pdusession[i].param.nb_qos; qos_flow_index++) {
+      switch (ue_context_pP->ue_context.pdusession[i].param.qos[qos_flow_index].fiveQI) {
+        case 1: //100ms
+        case 2: //150ms
+        case 3: //50ms
+        case 4: //300ms
+        case 5: //100ms
+        case 6: //300ms
+        case 7: //100ms
+        case 8: //300ms
+        case 9: //300ms Video (Buffered Streaming)TCP-based (e.g., www, e-mail, chat, ftp, p2p file sharing, progressive video, etc.)
+          // TODO
+          break;
+
+        default:
+          LOG_E(NR_RRC,"not supported 5qi %lu\n", ue_context_pP->ue_context.pdusession[i].param.qos[qos_flow_index].fiveQI);
+          ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_FAILED;
+          ue_context_pP->ue_context.pdusession[i].xid = xid;
+          pdu_sessions_done++;
+          free(DRB_config);
+          continue;
+      }
+    }
+
+    ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config);
+    ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
+
+    ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_DONE;
+    ue_context_pP->ue_context.pdusession[i].xid = xid;
+
+    if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) {
+      dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
+      memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
+      OCTET_STRING_fromBuf(dedicatedNAS_Message,
+                            (char *)ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer,
+                            ue_context_pP->ue_context.pdusession[i].param.nas_pdu.length);
+      ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
+
+      LOG_I(NR_RRC,"add NAS info with size %d (pdusession id %d)\n",ue_context_pP->ue_context.pdusession[i].param.nas_pdu.length, i);
+    } else {
+      // TODO
+      LOG_E(NR_RRC,"no NAS info (pdusession id %d)\n", i);
+    }
+  }
+
+  /* If list is empty free the list and reset the address */
+  if (dedicatedNAS_MessageList->list.count == 0) {
+    free(dedicatedNAS_MessageList);
+    dedicatedNAS_MessageList = NULL;
+  }
+
+  memset(buffer, 0, RRC_BUF_SIZE);
+  cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
+  fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup);
+  size = do_RRCReconfiguration(ctxt_pP, buffer,
+                                xid,
+                                *SRB_configList2,
+                                *DRB_configList,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                dedicatedNAS_MessageList,
+                                NULL,
+                                cellGroupConfig);
+  LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Reconfiguration\n");
+
+  /* Free all NAS PDUs */
+  for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
+    if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) {
+      /* Free the NAS PDU buffer and invalidate it */
+      free(ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer);
+      ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer = NULL;
+    }
+  }
+
+  LOG_I(NR_RRC,
+        "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCReconfiguration (bytes %d, UE RNTI %x)\n",
+        ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
+  LOG_D(NR_RRC,
+        "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
+        ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH);
+  MSC_LOG_TX_MESSAGE(
+    MSC_RRC_GNB,
+    MSC_RRC_UE,
+    buffer,
+    size,
+    MSC_AS_TIME_FMT" dedicated RRCReconfiguration UE %x MUI %d size %u",
+    MSC_AS_TIME_ARGS(ctxt_pP),
+    ue_context_pP->ue_context.rnti,
+    rrc_gNB_mui,
+    size);
+
 #ifdef ITTI_SIM
-    MessageDef *message_p;
-    uint8_t *message_buffer;
-    message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size);
-    memcpy (message_buffer, buffer, size);
-    message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND);
-    GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
-    GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
-    GNB_RRC_DCCH_DATA_IND (message_p).size	= size;
-    itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
+  MessageDef *message_p;
+  uint8_t *message_buffer;
+  message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size);
+  memcpy (message_buffer, buffer, size);
+  message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, GNB_RRC_DCCH_DATA_IND);
+  GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
+  GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
+  GNB_RRC_DCCH_DATA_IND (message_p).size	= size;
+  itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
 #else
-  nr_rrc_data_req(ctxt_pP,
-              DCCH,
-              rrc_gNB_mui++,
-              SDU_CONFIRM_NO,
-              size,
-              buffer,
-              PDCP_TRANSMISSION_MODE_CONTROL);
+  nr_rrc_data_req(
+    ctxt_pP,
+    DCCH,
+    rrc_gNB_mui++,
+    SDU_CONFIRM_NO,
+    size,
+    buffer,
+    PDCP_TRANSMISSION_MODE_CONTROL);
 #endif
-  // rrc_pdcp_config_asn1_req
-  // rrc_rlc_config_asn1_req
 }
 
 //-----------------------------------------------------------------------------
@@ -789,6 +1167,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
                                NULL,
                                NULL,
                                dedicatedNAS_MessageList,
+                               NULL,
                                NULL);
 
   ue_context_pP->ue_context.pdu_session_release_command_flag = 1;
@@ -883,6 +1262,8 @@ rrc_gNB_process_RRCReconfigurationComplete(
                    ue_context_pP->ue_context.rnti);
 
 #ifndef ITTI_SIM
+  LOG_D(NR_RRC,"Configuring PDCP DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti);
+
   nr_rrc_pdcp_config_asn1_req(ctxt_pP,
                               SRB_configList, // NULL,
                               DRB_configList,
@@ -894,14 +1275,17 @@ rrc_gNB_process_RRCReconfigurationComplete(
                               NULL,
                               NULL,
                               NULL,
-                              NULL);
+                              get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
   /* Refresh SRBs/DRBs */
-  nr_rrc_rlc_config_asn1_req(ctxt_pP,
-                          SRB_configList, // NULL,
-                          DRB_configList,
-                          DRB_Release_configList2,
-                          NULL,
-                          NULL);
+  if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
+    LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti);
+    nr_rrc_rlc_config_asn1_req(ctxt_pP,
+                               SRB_configList, // NULL,
+                               DRB_configList,
+                               DRB_Release_configList2,
+                               NULL,
+                               get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
+  }
 #endif
 
   /* Set the SRB active in UE context */
@@ -909,6 +1293,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
     for (int i = 0; (i < SRB_configList->list.count) && (i < 3); i++) {
       if (SRB_configList->list.array[i]->srb_Identity == 1) {
         ue_context_pP->ue_context.Srb1.Active = 1;
+        ue_context_pP->ue_context.Srb1.Srb_info.Srb_id = 1;
       } else if (SRB_configList->list.array[i]->srb_Identity == 2) {
         ue_context_pP->ue_context.Srb2.Active = 1;
         ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2;
@@ -1111,7 +1496,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
 
   uint8_t next_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
   int ret = 0;
-  ue_context_pP->ue_context.status = NR_RRC_CONNECTED;
+  ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED;
   ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
   ue_context_pP->ue_context.reestablishment_xid = next_xid;
   SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
@@ -1290,6 +1675,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
                                 NULL,
                                 NULL, // MeasObj_list,
                                 NULL,
+                                NULL,
                                 NULL);
   LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,
               "[MSG] RRC Reconfiguration\n");
@@ -1324,15 +1710,15 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
       rrc_gNB_mui,
       size);
 #ifdef ITTI_SIM
-    MessageDef *message_p;
-    uint8_t *message_buffer;
-    message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size);
-    memcpy (message_buffer, buffer, size);
-    message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND);
-    GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
-    GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
-    GNB_RRC_DCCH_DATA_IND (message_p).size	= size;
-    itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
+  MessageDef *message_p;
+  uint8_t *message_buffer;
+  message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size);
+  memcpy (message_buffer, buffer, size);
+  message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND);
+  GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
+  GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
+  GNB_RRC_DCCH_DATA_IND (message_p).size	= size;
+  itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
 #else
     nr_rrc_data_req(
       ctxt_pP,
@@ -1351,6 +1737,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
 int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
                            const uint8_t      *buffer,
                            int                buffer_length,
+                           OCTET_STRING_t     *du_to_cu_rrc_container,
                            const int          CC_id)
 {
   module_id_t                                       Idx;
@@ -1475,9 +1862,9 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
                   LOG_E(RRC, "%s:%d:%s: rrc_gNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__);
               }
 
-       if (ue_context_p != NULL) {
-                  ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence = TRUE;
-                  ue_context_p->ue_context.ng_5G_S_TMSI_Part1 = s_tmsi_part1;
+              if (ue_context_p != NULL) {
+                ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence = TRUE;
+                ue_context_p->ue_context.ng_5G_S_TMSI_Part1 = s_tmsi_part1;
               }
             }
           } else {
@@ -1500,10 +1887,9 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
 
           rrc_gNB_generate_RRCSetup(ctxt_pP,
                                     rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti),
+                                    du_to_cu_rrc_container,
+                                    gnb_rrc_inst->carrier.servingcellconfigcommon,
                                     CC_id);
-
-          // FIXME: Check the best place to perform this DRB configuration
-          nr_DRB_preconfiguration(ctxt_pP->rnti);
         }
         break;
 
@@ -1602,7 +1988,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
           }
 #endif
           //c-plane not end
-          if((ue_context_p->ue_context.status != NR_RRC_RECONFIGURED) && (ue_context_p->ue_context.reestablishment_cause == NR_ReestablishmentCause_spare1)) {
+          if((ue_context_p->ue_context.StatusRrc != NR_RRC_RECONFIGURED) && (ue_context_p->ue_context.reestablishment_cause == NR_ReestablishmentCause_spare1)) {
             LOG_E(NR_RRC,
                   PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest (UE %x c-plane is not end), RRC establishment failed \n",
                   PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti);
@@ -1614,9 +2000,9 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
             LOG_E(NR_RRC,
                   PROTOCOL_NR_RRC_CTXT_UE_FMT" RRRCReconfigurationComplete(Previous) don't receive, delete the Previous UE,\nprevious Status %d, new Status NR_RRC_RECONFIGURED\n",
                   PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
-                  ue_context_p->ue_context.status
+                  ue_context_p->ue_context.StatusRrc
                   );
-            ue_context_p->ue_context.status = NR_RRC_RECONFIGURED;
+            ue_context_p->ue_context.StatusRrc = NR_RRC_RECONFIGURED;
             protocol_ctxt_t  ctxt_old_p;
             PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p,
                                           ctxt_pP->instance,
@@ -1791,6 +2177,10 @@ rrc_gNB_decode_dcch(
 
   LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Decoding UL-DCCH Message\n",
                   PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
+
+  //for (int i=0;i<sdu_sizeP;i++) printf("%02x ",Rx_sdu[i]);
+  //printf("\n");
+
   dec_rval = uper_decode(
                   NULL,
                   &asn_DEF_NR_UL_DCCH_Message,
@@ -1799,7 +2189,10 @@ rrc_gNB_decode_dcch(
                   sdu_sizeP,
                   0,
                   0);
-  // xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
+
+  if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
+    xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg);
+  }
 
   {
     for (i = 0; i < sdu_sizeP; i++) {
@@ -2253,6 +2646,119 @@ rrc_gNB_decode_dcch(
   return 0;
 }
 
+void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *f1_setup_req) {
+  LOG_I(NR_RRC,"Received F1 Setup Request from gNB_DU %llu (%s)\n",(unsigned long long int)f1_setup_req->gNB_DU_id,f1_setup_req->gNB_DU_name);
+  int cu_cell_ind = 0;
+  MessageDef *msg_p = NULL,*msg_p2=NULL;
+
+  for (int i = 0; i < f1_setup_req->num_cells_available; i++) {
+    int found_cell=0;
+    for (int j=0; j<RC.nb_nr_inst; j++) {
+      gNB_RRC_INST *rrc = RC.nrrrc[j];
+
+      if (rrc->configuration.mcc[0] == f1_setup_req->mcc[i] &&
+          rrc->configuration.mnc[0] == f1_setup_req->mnc[i] &&
+          rrc->nr_cellid == f1_setup_req->nr_cellid[i]) {
+        // check that CU rrc instance corresponds to mcc/mnc/cgi (normally cgi should be enough, but just in case)
+        rrc->carrier.MIB = malloc(f1_setup_req->mib_length[i]);
+        rrc->carrier.sizeof_MIB = f1_setup_req->mib_length[i];
+        LOG_W(NR_RRC, "instance %d mib length %d\n", i, f1_setup_req->mib_length[i]);
+        LOG_W(NR_RRC, "instance %d sib1 length %d\n", i, f1_setup_req->sib1_length[i]);
+        memcpy((void *)rrc->carrier.MIB,f1_setup_req->mib[i],f1_setup_req->mib_length[i]);
+        asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
+                                  &asn_DEF_NR_BCCH_BCH_Message,
+                                  (void **)&rrc->carrier.mib_DU,
+                                  f1_setup_req->mib[i],
+                                  f1_setup_req->mib_length[i]);
+        AssertFatal(dec_rval.code == RC_OK,
+                    "[gNB_DU %"PRIu8"] Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits)\n",
+                    j,
+                    dec_rval.consumed );
+        NR_BCCH_BCH_Message_t *mib = &rrc->carrier.mib;
+        NR_BCCH_BCH_Message_t *mib_DU = rrc->carrier.mib_DU;
+        mib->message.present = NR_BCCH_BCH_MessageType_PR_mib;
+        mib->message.choice.mib = CALLOC(1,sizeof(struct NR_MIB));
+        memset(mib->message.choice.mib,0,sizeof(struct NR_MIB));
+        memcpy(mib->message.choice.mib, mib_DU->message.choice.mib, sizeof(struct NR_MIB));
+
+        rrc->carrier.SIB1 = malloc(f1_setup_req->sib1_length[i]);
+        rrc->carrier.sizeof_SIB1 = f1_setup_req->sib1_length[i];
+        memcpy((void *)rrc->carrier.SIB1,f1_setup_req->sib1[i],f1_setup_req->sib1_length[i]);
+        dec_rval = uper_decode_complete(NULL,
+                                        &asn_DEF_NR_BCCH_DL_SCH_Message,
+                                        (void **)&rrc->carrier.siblock1_DU,
+                                        f1_setup_req->sib1[i],
+                                        f1_setup_req->sib1_length[i]);
+        AssertFatal(dec_rval.code == RC_OK,
+                    "[gNB_DU %"PRIu8"] Failed to decode NR_BCCH_DLSCH_MESSAGE (%zu bits)\n",
+                    j,
+                    dec_rval.consumed );
+
+        // Parse message and extract SystemInformationBlockType1 field
+        NR_BCCH_DL_SCH_Message_t *bcch_message = rrc->carrier.siblock1_DU;
+        AssertFatal(bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1,
+                    "bcch_message->message.present != NR_BCCH_DL_SCH_MessageType_PR_c1\n");
+        AssertFatal(bcch_message->message.choice.c1->present == NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1,
+                    "bcch_message->message.choice.c1->present != NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1\n");
+        rrc->carrier.sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
+        rrc->carrier.physCellId = f1_setup_req->nr_pci[i];
+	if (cu_cell_ind == 0) {
+	  // prepare F1_SETUP_RESPONSE + GNB_CU_CONFIGURATION_UPDATE
+	  if (msg_p == NULL) {
+	    msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_SETUP_RESP);
+	  }
+	  if (msg_p2 == NULL) {
+	    msg_p2 = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE);
+	  }
+
+	  F1AP_SETUP_RESP (msg_p).gNB_CU_name                                = rrc->node_name;
+	  F1AP_SETUP_RESP (msg_p).num_cells_to_activate = 0;
+
+	}
+
+	F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).gNB_CU_name                                = rrc->node_name;
+	F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).cells_to_activate[cu_cell_ind].mcc                           = rrc->configuration.mcc[0];
+	F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).cells_to_activate[cu_cell_ind].mnc                           = rrc->configuration.mnc[0];
+	F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).cells_to_activate[cu_cell_ind].mnc_digit_length              = rrc->configuration.mnc_digit_length[0];
+	F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).cells_to_activate[cu_cell_ind].nr_cellid                     = rrc->nr_cellid;
+	F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).cells_to_activate[cu_cell_ind].nrpci                         = f1_setup_req->nr_pci[i];
+        int num_SI= 0;
+
+        if (rrc->carrier.SIB23) {
+          F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).cells_to_activate[cu_cell_ind].SI_container[2]        = rrc->carrier.SIB23;
+          F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).cells_to_activate[cu_cell_ind].SI_container_length[2] = rrc->carrier.sizeof_SIB23;
+          num_SI++;
+        }
+
+        F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).cells_to_activate[cu_cell_ind].num_SI = num_SI;
+        cu_cell_ind++;
+        found_cell=1;
+	F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).num_cells_to_activate = cu_cell_ind;
+	// send
+        break;
+      } else {// setup_req mcc/mnc match rrc internal list element
+        LOG_W(NR_RRC,"[Inst %d] No matching MCC/MNC: rrc->mcc/f1_setup_req->mcc %d/%d rrc->mnc/f1_setup_req->mnc %d/%d rrc->nr_cellid/f1_setup_req->nr_cellid %ld/%ld \n",
+              j, rrc->configuration.mcc[0], f1_setup_req->mcc[i],
+                 rrc->configuration.mnc[0], f1_setup_req->mnc[i],
+                 rrc->nr_cellid, f1_setup_req->nr_cellid[i]);
+      }
+    }// for (int j=0;j<RC.nb_inst;j++)
+
+    if (found_cell == 0) {
+      AssertFatal(1 == 0, "No cell found\n");
+    }
+    else {
+      // send ITTI message to F1AP-CU task
+      itti_send_msg_to_task (TASK_CU_F1, 0, msg_p);
+
+      itti_send_msg_to_task (TASK_CU_F1, 0, msg_p2);
+
+    }
+
+    // handle other failure cases
+  }//for (int i=0;i<f1_setup_req->num_cells_available;i++)
+}
+
 void rrc_gNB_process_release_request(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_release_request_t *m)
 {
   gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP];
@@ -2284,7 +2790,18 @@ void *rrc_gnb_task(void *args_p) {
   int                                result;
   //SRB_INFO                           *srb_info_p;
   //int                                CC_id;
-  protocol_ctxt_t                    ctxt;
+
+  protocol_ctxt_t ctxt={.module_id=0,
+                        .enb_flag=1,
+                        .instance=0,
+                        .rnti=0,
+                        .frame=-1,
+                        .subframe=-1,
+                        .eNB_index=0,
+                        .configured=true,
+                        .brOption=false
+                       };
+
   itti_mark_task_ready(TASK_RRC_GNB);
   LOG_I(NR_RRC,"Entering main loop of NR_RRC message task\n");
 
@@ -2314,17 +2831,18 @@ void *rrc_gnb_task(void *args_p) {
 
       /* Messages from MAC */
       case NR_RRC_MAC_CCCH_DATA_IND:
-      PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
-                                    NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index,
-                                    GNB_FLAG_YES,
-                                    NR_RRC_MAC_CCCH_DATA_IND(msg_p).rnti,
-                                    msg_p->ittiMsgHeader.lte_time.frame,
-                                    msg_p->ittiMsgHeader.lte_time.slot);
-        LOG_I(NR_RRC,"Decoding CCCH : inst %ld, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n",
-                instance,
-                NR_RRC_MAC_CCCH_DATA_IND(msg_p).CC_id,
-                &ctxt,
-                NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
+        PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
+            NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index,
+            GNB_FLAG_YES,
+            NR_RRC_MAC_CCCH_DATA_IND(msg_p).rnti,
+            msg_p->ittiMsgHeader.lte_time.frame,
+            msg_p->ittiMsgHeader.lte_time.slot);
+        LOG_I(NR_RRC,"Decoding CCCH : ue %d, inst %ld, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n",
+            ctxt.rnti,
+            instance,
+            NR_RRC_MAC_CCCH_DATA_IND(msg_p).CC_id,
+            &ctxt,
+            NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
 
         if (NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= CCCH_SDU_SIZE) {
           LOG_I(NR_RRC, "CCCH message has size %d > %d\n",
@@ -2333,9 +2851,16 @@ void *rrc_gnb_task(void *args_p) {
       }
 
       nr_rrc_gNB_decode_ccch(&ctxt,
-                          (uint8_t *)NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu,
-                          NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,
-                          NR_RRC_MAC_CCCH_DATA_IND(msg_p).CC_id);
+                             (uint8_t *)NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu,
+                             NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,
+                             NR_RRC_MAC_CCCH_DATA_IND(msg_p).du_to_cu_rrc_container,
+                             NR_RRC_MAC_CCCH_DATA_IND(msg_p).CC_id);
+
+      if (NR_RRC_MAC_CCCH_DATA_IND(msg_p).du_to_cu_rrc_container) {
+        free(NR_RRC_MAC_CCCH_DATA_IND(msg_p).du_to_cu_rrc_container->buf);
+        free(NR_RRC_MAC_CCCH_DATA_IND(msg_p).du_to_cu_rrc_container);
+      }
+
       break;
 
       /* Messages from PDCP */
@@ -2346,6 +2871,11 @@ void *rrc_gnb_task(void *args_p) {
                                       NR_RRC_DCCH_DATA_IND(msg_p).rnti,
                                       msg_p->ittiMsgHeader.lte_time.frame,
                                       msg_p->ittiMsgHeader.lte_time.slot);
+        LOG_I(NR_RRC,"Decoding DCCH : ue %d, inst %ld, ctxt %p, size %d\n",
+                ctxt.rnti,
+                instance,
+                &ctxt,
+                NR_RRC_DCCH_DATA_IND(msg_p).sdu_size);
         LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received on DCCH %d %s\n",
                 PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt),
                 NR_RRC_DCCH_DATA_IND(msg_p).dcch_index,
@@ -2354,6 +2884,8 @@ void *rrc_gnb_task(void *args_p) {
                             NR_RRC_DCCH_DATA_IND(msg_p).dcch_index,
                             NR_RRC_DCCH_DATA_IND(msg_p).sdu_p,
                             NR_RRC_DCCH_DATA_IND(msg_p).sdu_size);
+        result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), NR_RRC_DCCH_DATA_IND(msg_p).sdu_p);
+
         break;
 
       case NGAP_DOWNLINK_NAS:
@@ -2417,11 +2949,7 @@ void *rrc_gnb_task(void *args_p) {
             ///Nothing to do. Apparently everything is done in S1AP processing
             //LOG_I(RRC, "[eNB %d] Received message %s, not processed because procedure not synched\n",
             //instance, msg_name_p);
-            if (rrc_eNB_get_ue_context(RC.nrrrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)
-                && rrc_eNB_get_ue_context(RC.nrrrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc > 0) {
-              rrc_eNB_get_ue_context(RC.nrrrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc =
-              rrc_eNB_get_ue_context(RC.nrrrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_thres_rrc;
-            }
+            AssertFatal(false, "Removed double mechanism for same feature: now delete_tunnel() function should be called\n");
             break;
 
       #endif
@@ -2432,6 +2960,14 @@ void *rrc_gnb_task(void *args_p) {
         openair_rrc_gNB_configuration(GNB_INSTANCE_TO_MODULE_ID(instance), &NRRRC_CONFIGURATION_REQ(msg_p));
         break;
 
+      /* Messages from F1AP task */
+      case F1AP_SETUP_REQ:
+        AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type),
+                    "should not receive F1AP_SETUP_REQUEST, need call by CU!\n");
+        LOG_I(NR_RRC,"[gNB %ld] Received %s : %p\n", instance, msg_name_p, &F1AP_SETUP_REQ(msg_p));
+        rrc_gNB_process_f1_setup_req(&F1AP_SETUP_REQ(msg_p));
+        break;
+
       /* Messages from X2AP */
       case X2AP_ENDC_SGNB_ADDITION_REQ:
         LOG_I(NR_RRC, "Received ENDC sgNB addition request from X2AP \n");
@@ -2483,12 +3019,13 @@ void *rrc_gnb_task(void *args_p) {
 void
 rrc_gNB_generate_SecurityModeCommand(
   const protocol_ctxt_t *const ctxt_pP,
-  rrc_gNB_ue_context_t          *const ue_context_pP
+  rrc_gNB_ue_context_t  *const ue_context_pP
 )
 //-----------------------------------------------------------------------------
 {
   uint8_t                             buffer[100];
   uint8_t                             size;
+
   T(T_ENB_RRC_SECURITY_MODE_COMMAND, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
     T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
   NR_IntegrityProtAlgorithm_t integrity_algorithm = (NR_IntegrityProtAlgorithm_t)ue_context_pP->ue_context.integrity_algorithm;
@@ -2503,24 +3040,45 @@ rrc_gNB_generate_SecurityModeCommand(
         PROTOCOL_NR_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n",
         PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
         size);
-  LOG_D(NR_RRC,
+
+  switch (RC.nrrrc[ctxt_pP->module_id]->node_type) {
+    case ngran_gNB_CU:
+      // create an ITTI message
+      memcpy(ue_context_pP->ue_context.Srb1.Srb_info.Tx_buffer.Payload, buffer, size);
+      ue_context_pP->ue_context.Srb1.Srb_info.Tx_buffer.payload_size = size;
+
+      LOG_I(NR_RRC,"calling rrc_data_req :securityModeCommand\n");
+      nr_rrc_data_req(ctxt_pP,
+                  DCCH,
+                  rrc_gNB_mui++,
+                  SDU_CONFIRM_NO,
+                  size,
+                  buffer,
+                  PDCP_TRANSMISSION_MODE_CONTROL);
+      break;
+
+    case ngran_gNB_DU:
+      // nothing to do for DU
+      AssertFatal(1==0,"nothing to do for DU\n");
+      break;
+
+    case ngran_gNB:
+      LOG_D(NR_RRC,
         PROTOCOL_NR_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (securityModeCommand to UE MUI %d) --->[PDCP][RB %02d]\n",
         PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
         size,
         rrc_gNB_mui,
         DCCH);
-  MSC_LOG_TX_MESSAGE(
-    MSC_RRC_GNB,
-    MSC_RRC_UE,
-    buffer,
-    size,
-    MSC_AS_TIME_FMT" securityModeCommand UE %x MUI %d size %u",
-    MSC_AS_TIME_ARGS(ctxt_pP),
-    ue_context_pP->ue_context.rnti,
-    rrc_gNB_mui,
-    size);
-
-  LOG_I(NR_RRC,"calling rrc_data_req :securityModeCommand\n");
+      MSC_LOG_TX_MESSAGE(
+        MSC_RRC_GNB,
+        MSC_RRC_UE,
+        buffer,
+        size,
+        MSC_AS_TIME_FMT" securityModeCommand UE %x MUI %d size %u",
+        MSC_AS_TIME_ARGS(ctxt_pP),
+        ue_context_pP->ue_context.rnti,
+        rrc_gNB_mui,
+        size);
 #ifdef ITTI_SIM
   MessageDef *message_p;
   uint8_t *message_buffer;
@@ -2532,15 +3090,20 @@ rrc_gNB_generate_SecurityModeCommand(
   GNB_RRC_DCCH_DATA_IND (message_p).size	= size;
   itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
 #else
+  LOG_D(NR_RRC,"calling rrc_data_req :securityModeCommand\n");
   nr_rrc_data_req(ctxt_pP,
-               DCCH,
-               rrc_gNB_mui++,
-               SDU_CONFIRM_NO,
-               size,
-               buffer,
-               PDCP_TRANSMISSION_MODE_CONTROL);
+                  DCCH,
+                  rrc_gNB_mui++,
+                  SDU_CONFIRM_NO,
+                  size,
+                  buffer,
+                  PDCP_TRANSMISSION_MODE_CONTROL);
 #endif
+      break;
 
+    default :
+        LOG_W(NR_RRC, "Unknown node type %d\n", RC.nrrrc[ctxt_pP->module_id]->node_type);
+  }
 }
 
 void
@@ -2552,32 +3115,52 @@ rrc_gNB_generate_UECapabilityEnquiry(
 {
   uint8_t                             buffer[100];
   uint8_t                             size;
+
   T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
     T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
   size = do_NR_SA_UECapabilityEnquiry(
            ctxt_pP,
            buffer,
            rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id));
-  LOG_I(RRC,
-        PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes %d)\n",
-        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
+  LOG_I(NR_RRC,
+        PROTOCOL_NR_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes %d)\n",
+        PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
         size);
-  LOG_D(RRC,
-        PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (NR UECapabilityEnquiry MUI %d) --->[PDCP][RB %02d]\n",
-        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
+  switch (RC.nrrrc[ctxt_pP->module_id]->node_type) {
+    case ngran_gNB_CU:
+      nr_rrc_data_req(
+        ctxt_pP,
+        DCCH,
+        rrc_gNB_mui++,
+        SDU_CONFIRM_NO,
+        size,
+        buffer,
+        PDCP_TRANSMISSION_MODE_CONTROL);
+      break;
+
+    case ngran_gNB_DU:
+      // nothing to do for DU
+      AssertFatal(1==0,"nothing to do for DU\n");
+      break;
+
+    case ngran_gNB:
+      // rrc_mac_config_req_gNB
+      LOG_D(NR_RRC,
+        PROTOCOL_NR_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (NR UECapabilityEnquiry MUI %d) --->[PDCP][RB %02d]\n",
+        PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
         size,
         rrc_gNB_mui,
         DCCH);
-  MSC_LOG_TX_MESSAGE(
-    MSC_RRC_GNB,
-    MSC_RRC_UE,
-    buffer,
-    size,
-    MSC_AS_TIME_FMT" rrcNRUECapabilityEnquiry UE %x MUI %d size %u",
-    MSC_AS_TIME_ARGS(ctxt_pP),
-    ue_context_pP->ue_context.rnti,
-    rrc_gNB_mui,
-    size);
+      MSC_LOG_TX_MESSAGE(
+        MSC_RRC_GNB,
+        MSC_RRC_UE,
+        buffer,
+        size,
+        MSC_AS_TIME_FMT" rrcNRUECapabilityEnquiry UE %x MUI %d size %u",
+        MSC_AS_TIME_ARGS(ctxt_pP),
+        ue_context_pP->ue_context.rnti,
+        rrc_gNB_mui,
+        size);
 #ifdef ITTI_SIM
   MessageDef *message_p;
   uint8_t *message_buffer;
@@ -2589,15 +3172,19 @@ rrc_gNB_generate_UECapabilityEnquiry(
   GNB_RRC_DCCH_DATA_IND (message_p).size  = size;
   itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
 #else
-  nr_rrc_data_req(
-    ctxt_pP,
-    DCCH,
-    rrc_gNB_mui++,
-    SDU_CONFIRM_NO,
-    size,
-    buffer,
-    PDCP_TRANSMISSION_MODE_CONTROL);
+  nr_rrc_data_req(ctxt_pP,
+                  DCCH,
+                  rrc_gNB_mui++,
+                  SDU_CONFIRM_NO,
+                  size,
+                  buffer,
+                  PDCP_TRANSMISSION_MODE_CONTROL);
 #endif
+  break;
+
+    default :
+        LOG_W(NR_RRC, "Unknown node type %d\n", RC.nrrrc[ctxt_pP->module_id]->node_type);
+  }
 }
 
 //-----------------------------------------------------------------------------
@@ -2620,6 +3207,8 @@ rrc_gNB_generate_RRCRelease(
   size = do_NR_RRCRelease(buffer,rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id));
   ue_context_pP->ue_context.ue_reestablishment_timer = 0;
   ue_context_pP->ue_context.ue_release_timer = 0;
+  ue_context_pP->ue_context.ul_failure_timer = 0;
+  ue_context_pP->ue_context.ue_release_timer_rrc = 0;
   LOG_I(NR_RRC,
         PROTOCOL_NR_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCRelease (bytes %d)\n",
         PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
@@ -2652,7 +3241,7 @@ rrc_gNB_generate_RRCRelease(
     GNB_RRC_DCCH_DATA_IND (message_p).size  = size;
     itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
 #else
-  if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+  if (NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
     MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
     F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti;
     F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK;
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index 5bb44205c466b0287b3a8178e0362c0452fae3e8..619880da59821a7eb364475715be46ed314b8b97 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -57,6 +57,7 @@
 #include "RRC/NR/MESSAGES/asn1_msg.h"
 #include "NR_UERadioAccessCapabilityInformation.h"
 #include "NR_UE-CapabilityRAT-ContainerList.h"
+#include "f1ap_messages_types.h"
 
 extern RAN_CONTEXT_t RC;
 
@@ -303,25 +304,44 @@ nr_rrc_pdcp_config_security(
   uint8_t                            *kRRCenc = NULL;
   uint8_t                            *kRRCint = NULL;
   uint8_t                            *kUPenc = NULL;
-  pdcp_t                             *pdcp_p   = NULL;
-  static int                          print_keys= 1;
-  hashtable_rc_t                      h_rc;
-  hash_key_t                          key;
+  static int                         print_keys= 1;
 
 #ifndef PHYSIM
-    /* Derive the keys from kgnb */
-    if (SRB_configList != NULL) {
-        nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
-                          ue_context_pP->ue_context.kgnb,
-                          &kUPenc);
-    }
 
-    nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
-                          ue_context_pP->ue_context.kgnb,
-                          &kRRCenc);
-    nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
-                          ue_context_pP->ue_context.kgnb,
-                          &kRRCint);
+  uint8_t *k_kdf = NULL;
+
+  /* Derive the keys from kgnb */
+  if (SRB_configList != NULL) {
+    k_kdf = NULL;
+    nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
+                         ue_context_pP->ue_context.kgnb,
+                         &k_kdf);
+    /* kUPenc: last 128 bits of key derivation function which returns 256 bits */
+    kUPenc = malloc(16);
+    if (kUPenc == NULL) exit(1);
+    memcpy(kUPenc, k_kdf+16, 16);
+    free(k_kdf);
+  }
+
+  k_kdf = NULL;
+  nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
+                        ue_context_pP->ue_context.kgnb,
+                        &k_kdf);
+  /* kRRCenc: last 128 bits of key derivation function which returns 256 bits */
+  kRRCenc = malloc(16);
+  if (kRRCenc == NULL) exit(1);
+  memcpy(kRRCenc, k_kdf+16, 16);
+  free(k_kdf);
+
+  k_kdf = NULL;
+  nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
+                        ue_context_pP->ue_context.kgnb,
+                        &k_kdf);
+  /* kRRCint: last 128 bits of key derivation function which returns 256 bits */
+  kRRCint = malloc(16);
+  if (kRRCint == NULL) exit(1);
+  memcpy(kRRCint, k_kdf+16, 16);
+  free(k_kdf);
 #endif
   if (!IS_SOFTMODEM_IQPLAYER) {
     SET_LOG_DUMP(DEBUG_SECURITY) ;
@@ -337,28 +357,18 @@ nr_rrc_pdcp_config_security(
     }
   }
 
-  key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES);
-  h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
-
-  if (h_rc == HASH_TABLE_OK) {
-    pdcp_config_set_security(
-        ctxt_pP,
-        pdcp_p,
-        DCCH,
-        DCCH+2,
-        (send_security_mode_command == TRUE)  ?
-        0 | (ue_context_pP->ue_context.integrity_algorithm << 4) :
-        (ue_context_pP->ue_context.ciphering_algorithm )         |
-        (ue_context_pP->ue_context.integrity_algorithm << 4),
-        kRRCenc,
-        kRRCint,
-        kUPenc);
-  } else {
-    LOG_E(NR_RRC,
-        PROTOCOL_NR_RRC_CTXT_UE_FMT"Could not get PDCP instance for SRB DCCH %u\n",
-        PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
-        DCCH);
-  }
+  pdcp_config_set_security(
+      ctxt_pP,
+      NULL,      /* pdcp_pP not used anymore in NR */
+      DCCH,
+      DCCH+2,
+      (send_security_mode_command == TRUE)  ?
+      0 | (ue_context_pP->ue_context.integrity_algorithm << 4) :
+      (ue_context_pP->ue_context.ciphering_algorithm )         |
+      (ue_context_pP->ue_context.integrity_algorithm << 4),
+      kRRCenc,
+      kRRCint,
+      kUPenc);
 }
 
 //------------------------------------------------------------------------------
@@ -424,57 +434,57 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ(
   NGAP_NAS_FIRST_REQ(message_p).selected_plmn_identity = selected_plmn_identity;
 
   if (rrcSetupComplete->registeredAMF != NULL) {
-    NR_RegisteredAMF_t *r_amf = rrcSetupComplete->registeredAMF;
-    NGAP_NAS_FIRST_REQ(message_p).ue_identity.presenceMask |= NGAP_UE_IDENTITIES_guami;
-
-    if (r_amf->plmn_Identity != NULL) {
-      if ((r_amf->plmn_Identity->mcc != NULL) && (r_amf->plmn_Identity->mcc->list.count > 0)) {
-        /* Use first indicated PLMN MCC if it is defined */
-        NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mcc = *r_amf->plmn_Identity->mcc->list.array[selected_plmn_identity];
-        LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n",
-            ctxt_pP->module_id,
-            NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.mcc,
-            ue_context_pP->ue_context.rnti);
+      NR_RegisteredAMF_t *r_amf = rrcSetupComplete->registeredAMF;
+      NGAP_NAS_FIRST_REQ(message_p).ue_identity.presenceMask |= NGAP_UE_IDENTITIES_guami;
+
+      if (r_amf->plmn_Identity != NULL) {
+          if ((r_amf->plmn_Identity->mcc != NULL) && (r_amf->plmn_Identity->mcc->list.count > 0)) {
+              /* Use first indicated PLMN MCC if it is defined */
+              NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mcc = *r_amf->plmn_Identity->mcc->list.array[selected_plmn_identity];
+              LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n",
+                  ctxt_pP->module_id,
+                  NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.mcc,
+                  ue_context_pP->ue_context.rnti);
+          }
+
+          if (r_amf->plmn_Identity->mnc.list.count > 0) {
+              /* Use first indicated PLMN MNC if it is defined */
+              NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc = *r_amf->plmn_Identity->mnc.list.array[selected_plmn_identity];
+              LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n",
+                  ctxt_pP->module_id,
+                  NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.mnc,
+                  ue_context_pP->ue_context.rnti);
+          }
+      } else {
+          /* TODO */
       }
 
-      if (r_amf->plmn_Identity->mnc.list.count > 0) {
-        /* Use first indicated PLMN MNC if it is defined */
-        NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc = *r_amf->plmn_Identity->mnc.list.array[selected_plmn_identity];
-        LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n",
+      /* amf_Identifier */
+      uint32_t amf_Id = BIT_STRING_to_uint32(&r_amf->amf_Identifier);
+      NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_region_id = amf_Id >> 16;
+      NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_set_id    = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id;
+      NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_pointer   = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer;
+
+      ue_context_pP->ue_context.ue_guami.mcc = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mcc;
+      ue_context_pP->ue_context.ue_guami.mnc = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc;
+      ue_context_pP->ue_context.ue_guami.mnc_len = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc_len;
+      ue_context_pP->ue_context.ue_guami.amf_region_id = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_region_id;
+      ue_context_pP->ue_context.ue_guami.amf_set_id = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_set_id;
+      ue_context_pP->ue_context.ue_guami.amf_pointer = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_pointer;
+
+      MSC_LOG_TX_MESSAGE(MSC_NGAP_GNB,
+                          MSC_NGAP_AMF,
+                          (const char *)&message_p->ittiMsg.ngap_nas_first_req,
+                          sizeof(ngap_nas_first_req_t),
+                          MSC_AS_TIME_FMT" NGAP_NAS_FIRST_REQ gNB %u UE %x",
+                          MSC_AS_TIME_ARGS(ctxt_pP),
+                          ctxt_pP->module_id,
+                          ctxt_pP->rnti);
+      LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUAMI amf_set_id %u amf_region_id %u ue %x\n",
             ctxt_pP->module_id,
-            NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.mnc,
+            NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.amf_set_id,
+            NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.amf_region_id,
             ue_context_pP->ue_context.rnti);
-      }
-    } else {
-      /* TODO */
-    }
-
-    /* amf_Identifier */
-    uint32_t amf_Id = BIT_STRING_to_uint32(&r_amf->amf_Identifier);
-    NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_region_id = amf_Id >> 16;
-    NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_set_id    = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id;
-    NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_pointer   = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer;
-
-    ue_context_pP->ue_context.ue_guami.mcc = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mcc;
-    ue_context_pP->ue_context.ue_guami.mnc = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc;
-    ue_context_pP->ue_context.ue_guami.mnc_len = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc_len;
-    ue_context_pP->ue_context.ue_guami.amf_region_id = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_region_id;
-    ue_context_pP->ue_context.ue_guami.amf_set_id = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_set_id;
-    ue_context_pP->ue_context.ue_guami.amf_pointer = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_pointer;
-
-    MSC_LOG_TX_MESSAGE(MSC_NGAP_GNB,
-                        MSC_NGAP_AMF,
-                        (const char *)&message_p->ittiMsg.ngap_nas_first_req,
-                        sizeof(ngap_nas_first_req_t),
-                        MSC_AS_TIME_FMT" NGAP_NAS_FIRST_REQ gNB %u UE %x",
-                        MSC_AS_TIME_ARGS(ctxt_pP),
-                        ctxt_pP->module_id,
-                        ctxt_pP->rnti);
-    LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUAMI amf_set_id %u amf_region_id %u ue %x\n",
-          ctxt_pP->module_id,
-          NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.amf_set_id,
-          NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.amf_region_id,
-          ue_context_pP->ue_context.rnti);
   }
 
   itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, message_p);
@@ -569,7 +579,7 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
       }
 
     // in case, send the S1SP initial context response if it is not sent with the attach complete message
-    if (ue_context_p->ue_context.status == NR_RRC_RECONFIGURED) {
+    if (ue_context_p->ue_context.StatusRrc == NR_RRC_RECONFIGURED) {
         LOG_I(NR_RRC, "Sending rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause);
         rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(&ctxt,ue_context_p);
     }
@@ -626,6 +636,10 @@ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(
 }
 
 static NR_CipheringAlgorithm_t rrc_gNB_select_ciphering(uint16_t algorithms) {
+
+  return NR_CipheringAlgorithm_nea0;
+
+
   if (algorithms & NGAP_ENCRYPTION_NEA3_MASK) {
     return NR_CipheringAlgorithm_nea3;
   }
@@ -638,10 +652,13 @@ static NR_CipheringAlgorithm_t rrc_gNB_select_ciphering(uint16_t algorithms) {
     return NR_CipheringAlgorithm_nea1;
   }
 
-  return NR_CipheringAlgorithm_nea0;
 }
 
 static e_NR_IntegrityProtAlgorithm rrc_gNB_select_integrity(uint16_t algorithms) {
+  
+  //only NIA2 supported for now
+  return NR_IntegrityProtAlgorithm_nia2;
+
   if (algorithms & NGAP_INTEGRITY_NIA3_MASK) {
     return NR_IntegrityProtAlgorithm_nia3;
   }
@@ -784,28 +801,54 @@ rrc_gNB_process_NGAP_DOWNLINK_NAS(
         /*
         * switch UL or DL NAS message without RRC piggybacked to SRB2 if active.
         */
+       switch (RC.nrrrc[ctxt.module_id]->node_type) {
+        case ngran_gNB_CU:
+          /* Transfer data to PDCP */
+          nr_rrc_data_req (
+              &ctxt,
+              ue_context_p->ue_context.Srb2.Active == 1 ? ue_context_p->ue_context.Srb2.Srb_info.Srb_id : ue_context_p->ue_context.Srb1.Srb_info.Srb_id,
+              (*rrc_gNB_mui)++,
+              SDU_CONFIRM_NO,
+              length,
+              buffer,
+              PDCP_TRANSMISSION_MODE_CONTROL);
+          break;
+
+        case ngran_gNB_DU:
+          // nothing to do for DU
+          AssertFatal(1==0,"nothing to do for DU\n");
+          break;
+
+        case ngran_gNB:
+        {
+          // rrc_mac_config_req_gNB
 #ifdef ITTI_SIM
-        MessageDef *message_p;
         uint8_t *message_buffer;
         message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, length);
         memcpy (message_buffer, buffer, length);
-        message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND);
+        MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND);
         GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
         GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
         GNB_RRC_DCCH_DATA_IND (message_p).size  = length;
         itti_send_msg_to_task (TASK_RRC_UE_SIM, instance, message_p);
         LOG_I(NR_RRC, "Send DL NAS message \n");
 #else
-        /* Transfer data to PDCP */
-        nr_rrc_data_req (
-            &ctxt,
-            ue_context_p->ue_context.Srb2.Srb_info.Srb_id,
-            (*rrc_gNB_mui)++,
-            SDU_CONFIRM_NO,
-            length,
-            buffer,
-            PDCP_TRANSMISSION_MODE_CONTROL);
+          /* Transfer data to PDCP */
+          nr_rrc_data_req (
+              &ctxt,
+              ue_context_p->ue_context.Srb2.Active == 1 ? ue_context_p->ue_context.Srb2.Srb_info.Srb_id : ue_context_p->ue_context.Srb1.Srb_info.Srb_id,
+              (*rrc_gNB_mui)++,
+              SDU_CONFIRM_NO,
+              length,
+              buffer,
+              PDCP_TRANSMISSION_MODE_CONTROL);
 #endif
+        }
+          break;
+
+        default :
+            LOG_W(NR_RRC, "Unknown node type %d\n", RC.nrrrc[ctxt.module_id]->node_type);
+      }
         return (0);
     }
 }
@@ -1015,8 +1058,9 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
     ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup;
 
     // TEST 
-    ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE;
-    rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0);
+    // ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE;
+    // rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0);
+    rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
     return(0);
   }
 }
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index 7861f2166c479b5e638bcd32ea19b56a7a34979f..f8cc951bc30b257c9911d2b3d47979ca711a292a 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -346,16 +346,25 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
 
   rrc->Nb_ue++;
   // configure MAC and RLC
-  rrc_mac_config_req_gNB(rrc->module_id,
-                         rrc->carrier.ssb_SubcarrierOffset,
-                         rrc->carrier.pdsch_AntennaPorts,
-                         rrc->carrier.pusch_AntennaPorts,
-                         rrc->carrier.pusch_TargetSNRx10,
-                         rrc->carrier.pucch_TargetSNRx10,
-                         NULL,
-                         1, // add_ue flag
-                         ue_context_p->ue_id_rnti,
-                         ue_context_p->ue_context.secondaryCellGroup);
+  if (NODE_IS_DU(rrc->node_type)) {
+    rrc_mac_config_req_gNB(rrc->module_id,
+                           rrc->carrier.ssb_SubcarrierOffset,
+                           rrc->carrier.pdsch_AntennaPorts,
+			                     rrc->carrier.pusch_AntennaPorts,
+                           rrc->carrier.servingcellconfigcommon,
+                           1, // add_ue flag
+                           ue_context_p->ue_id_rnti,
+                           ue_context_p->ue_context.secondaryCellGroup);
+  } else {
+    rrc_mac_config_req_gNB(rrc->module_id,
+                           rrc->carrier.ssb_SubcarrierOffset,
+                           rrc->carrier.pdsch_AntennaPorts,
+                           rrc->carrier.pusch_AntennaPorts,
+                           NULL,
+                           1, // add_ue flag
+                           ue_context_p->ue_id_rnti,
+                           ue_context_p->ue_context.secondaryCellGroup);
+  }
 
   if(m == NULL){
     LOG_W(RRC, "Calling RRC PDCP/RLC ASN1 request functions for protocol context %p with module_id %d, rnti %x, frame %d, subframe %d eNB_index %d \n", &ctxt,
@@ -366,26 +375,25 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
                                                                                                                                                         ctxt.eNB_index);
   }
 
-  nr_rrc_pdcp_config_asn1_req(
-    &ctxt,
-    (NR_SRB_ToAddModList_t *) NULL,
-    ue_context_p->ue_context.rb_config->drb_ToAddModList ,
-    ue_context_p->ue_context.rb_config->drb_ToReleaseList,
-    (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm,
-    NULL,          /* kRRCenc - unused */
-    NULL,          /* kRRCint - unused */
-    kUPenc,        /* kUPenc  */
-    NULL,          /* kUPint  - unused */
-    NULL,
-    NULL,
-    ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
+  nr_rrc_pdcp_config_asn1_req(&ctxt,
+                              get_softmodem_params()->sa ? ue_context_p->ue_context.rb_config->srb_ToAddModList : (NR_SRB_ToAddModList_t *) NULL,
+                              ue_context_p->ue_context.rb_config->drb_ToAddModList ,
+                              ue_context_p->ue_context.rb_config->drb_ToReleaseList,
+                              (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm,
+                              NULL,          /* kRRCenc - unused */
+                              NULL,          /* kRRCint - unused */
+                              kUPenc,        /* kUPenc  */
+                              NULL,          /* kUPint  - unused */
+                              NULL,
+                              NULL,
+                              ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
 
   nr_rrc_rlc_config_asn1_req (&ctxt,
-      (NR_SRB_ToAddModList_t *) NULL,
-      ue_context_p->ue_context.rb_config->drb_ToAddModList,
-      ue_context_p->ue_context.rb_config->drb_ToReleaseList,
-      (LTE_PMCH_InfoList_r9_t *) NULL,
-      ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
+                              get_softmodem_params()->sa ? ue_context_p->ue_context.rb_config->srb_ToAddModList : (NR_SRB_ToAddModList_t *) NULL,
+                              ue_context_p->ue_context.rb_config->drb_ToAddModList,
+                              ue_context_p->ue_context.rb_config->drb_ToReleaseList,
+                              (LTE_PMCH_InfoList_r9_t *) NULL,
+                              ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
 
   LOG_D(RRC, "%s:%d: done RRC PDCP/RLC ASN1 request for UE rnti %x\n", __FUNCTION__, __LINE__, ctxt.rnti);
 
@@ -394,7 +402,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
 void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
   protocol_ctxt_t      ctxt;
   rrc_gNB_ue_context_t *ue_context;
-  MessageDef           *msg_delete_tunnels_p;
   int                  e_rab;
 
   LOG_D(RRC, "calling rrc_remove_nsa_user rnti %d\n", rnti);
@@ -411,25 +418,18 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
   rrc_rlc_remove_ue(&ctxt);
 
   mac_remove_nr_ue(rrc->module_id, rnti);
-
-  /* delete gtp tunnel */
-  msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_GNB, 0, GTPV1U_ENB_DELETE_TUNNEL_REQ);
-  memset(&GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
-  GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = rnti;
-  GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 1;
-
-  LOG_D(RRC, "ue_context->ue_context.nb_of_e_rabs %d\n", ue_context->ue_context.nb_of_e_rabs);
+  gtpv1u_enb_delete_tunnel_req_t tmp={0};
+  tmp.rnti=rnti;
+  tmp.from_gnb=1;
+  LOG_D(RRC, "ue_context->ue_context.nb_of_e_rabs %d will be deleted for rnti %d\n", ue_context->ue_context.nb_of_e_rabs, rnti);
   for (e_rab = 0; e_rab < ue_context->ue_context.nb_of_e_rabs; e_rab++) {
-    GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
-      ue_context->ue_context.gnb_gtp_ebi[e_rab];
+    tmp.eps_bearer_id[tmp.num_erab++]= ue_context->ue_context.gnb_gtp_ebi[e_rab];
     // erase data
     ue_context->ue_context.gnb_gtp_teid[e_rab] = 0;
     memset(&ue_context->ue_context.gnb_gtp_addrs[e_rab], 0, sizeof(ue_context->ue_context.gnb_gtp_addrs[e_rab]));
     ue_context->ue_context.gnb_gtp_ebi[e_rab] = 0;
   }
-
-  itti_send_msg_to_task(TASK_VARIABLE, rrc->module_id, msg_delete_tunnels_p);
-
+  gtpv1u_delete_s1u_tunnel(rrc->module_id,  &tmp);
   /* remove context */
   rrc_gNB_remove_ue_context(&ctxt, rrc, ue_context);
 }
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index 72b0fd1d344756fb614fa56cf9097da299eb47af..3736ed52444b96d08cde297566d031aaf56b8aa8 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -50,29 +50,9 @@
 #define true 1
 
 void fill_default_initialDownlinkBWP(NR_BWP_Downlink_t *bwp, NR_ServingCellConfigCommon_t *servingcellconfigcommon) {
-
   bwp->bwp_Id = 0;
-
   bwp->bwp_Common=calloc(1,sizeof(*bwp->bwp_Common));
-  memcpy((void*)&bwp->bwp_Common,
-         &servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP,
-         sizeof(bwp->bwp_Common));
-
-  bwp->bwp_Dedicated=calloc(1,sizeof(*bwp->bwp_Dedicated));
-  bwp->bwp_Dedicated->pdsch_Config = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config));
-  bwp->bwp_Dedicated->pdsch_Config->present = NR_SetupRelease_PDSCH_Config_PR_setup;
-  bwp->bwp_Dedicated->pdsch_Config->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup));
-  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dataScramblingIdentityPDSCH = NULL;
-  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA));
-  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup;
-  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup));
-  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL;
-  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL;
-  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL;
-  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL;
-  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL;
-  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition));
-  *bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0;
+  *bwp->bwp_Common = *servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP;
 }
 
 void fill_default_coresetZero(NR_ControlResourceSet_t *coreset0, NR_ServingCellConfigCommon_t *servingcellconfigcommon) {
@@ -174,7 +154,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
   memset(secondaryCellGroup,0,sizeof(NR_CellGroupConfig_t));
   secondaryCellGroup->cellGroupId = scg_id;
   NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig));
-  nr_rlc_bearer_init(RLC_BearerConfig);
+  nr_rlc_bearer_init(RLC_BearerConfig, NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity);
   if (get_softmodem_params()->do_ra || get_softmodem_params()->sa)
     nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_um_Bi_Directional);
   else
@@ -183,9 +163,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
 
   secondaryCellGroup->rlc_BearerToAddModList = calloc(1,sizeof(*secondaryCellGroup->rlc_BearerToAddModList));
   ASN_SEQUENCE_ADD(&secondaryCellGroup->rlc_BearerToAddModList->list, RLC_BearerConfig);
+
   secondaryCellGroup->mac_CellGroupConfig=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig));
   secondaryCellGroup->mac_CellGroupConfig->drx_Config = NULL;
-
   secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig));
   secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList));
   NR_SchedulingRequestToAddMod_t *SchedulingRequestConf = calloc(1,sizeof(*SchedulingRequestConf));
@@ -1045,7 +1025,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  long *delay[8];
  for (int i=0;i<8;i++) {
    delay[i] = calloc(1,sizeof(*delay[i]));
-   *delay[i] = i+2;
+   *delay[i] = (i<6) ? (i+2) : 0;
    ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]);
  }
  pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList));
diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c
index c78a1caf37ec2fe81e2f0305ad439068b595bb4f..5c9293dcf9c0951a61251bbca17d51d917c7b540 100644
--- a/openair2/RRC/NR_UE/L2_interface_ue.c
+++ b/openair2/RRC/NR_UE/L2_interface_ue.c
@@ -162,12 +162,10 @@ rrc_data_req_ue(
     MessageDef *message_p;
     // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling).
     uint8_t *message_buffer;
-    message_buffer = itti_malloc (
-                       ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE,
-                       ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE,
-                       sdu_sizeP);
+    message_buffer = itti_malloc (TASK_RRC_UE, TASK_PDCP_UE, sdu_sizeP);
+    LOG_D(RRC,"Sending RRC message for SRB %ld, sdu_size %d\n",rb_idP, sdu_sizeP);
     memcpy (message_buffer, buffer_pP, sdu_sizeP);
-    message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, 0, RRC_DCCH_DATA_REQ);
+    message_p = itti_alloc_new_message ( TASK_RRC_UE, 0, RRC_DCCH_DATA_REQ);
     RRC_DCCH_DATA_REQ (message_p).frame     = ctxt_pP->frame;
     RRC_DCCH_DATA_REQ (message_p).enb_flag  = ctxt_pP->enb_flag;
     RRC_DCCH_DATA_REQ (message_p).rb_id     = rb_idP;
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index 86948230a589a2734ecefbf618c797129a2e224d..cb8eca950495ae383867e4c4a52796c0a0325664 100644
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -67,8 +67,9 @@
 #include "RRC/NAS/nas_config.h"
 #include "RRC/NAS/rb_config.h"
 #include "SIMULATION/TOOLS/sim.h" // for taus
+#include <executables/softmodem-common.h>
 
-#if ITTI_SIM
+#if defined(ITTI_SIM) || defined(RFSIM_NAS)
 #include "nr_nas_msg_sim.h"
 #endif
 
@@ -128,7 +129,6 @@ nr_rrc_ue_generate_rrcReestablishmentComplete(
 );
 
 mui_t nr_rrc_mui=0;
-uint8_t first_rrcreconfigurationcomplete = 0;
 
 static Rrc_State_NR_t nr_rrc_get_state (module_id_t ue_mod_idP) {
   return NR_UE_rrc_inst[ue_mod_idP].nrRrcState;
@@ -228,8 +228,8 @@ int8_t nr_rrc_ue_decode_secondary_cellgroup_config(
             return -1;
     }
 
-    if(NR_UE_rrc_inst[module_id].cell_group_config == NULL){
-        NR_UE_rrc_inst[module_id].cell_group_config = cell_group_config;
+    if(NR_UE_rrc_inst[module_id].scell_group_config == NULL){
+        NR_UE_rrc_inst[module_id].scell_group_config = cell_group_config;
         nr_rrc_ue_process_scg_config(module_id,cell_group_config);
     }else{
         nr_rrc_ue_process_scg_config(module_id,cell_group_config);
@@ -482,7 +482,7 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
       RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].CSI_ReportConfig_list, NR_maxNrofCSI_ReportConfigurations);
     }
 
-    if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1 || get_softmodem_params()->sa == 1) {
+    if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) {
       // read in files for RRCReconfiguration and RBconfig
       FILE *fd;
       char filename[1024];
@@ -553,45 +553,36 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(
     const uint8_t     gNB_index,
     uint8_t           *const bufferP,
     const uint8_t     buffer_len ){
-    int i;
     NR_BCCH_BCH_Message_t *bcch_message = NULL;
-    NR_MIB_t *mib = NR_UE_rrc_inst[module_id].mib;
-
-    if(mib != NULL){
-        SEQUENCE_free( &asn_DEF_NR_BCCH_BCH_Message, (void *)mib, 1 );
-    }
 
 
-    //for(i=0; i<buffer_len; ++i){
-    //    printf("[RRC] MIB PDU : %d\n", bufferP[i]);
-    //}
+    if (NR_UE_rrc_inst[module_id].mib != NULL)
+      SEQUENCE_free( &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message, 1 );
+    else LOG_I(NR_RRC,"Configuring MAC for first MIB reception\n");
 
-    asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
-                                                    &asn_DEF_NR_BCCH_BCH_Message,
+    asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
+                                                   &asn_DEF_NR_BCCH_BCH_Message,
                                                    (void **)&bcch_message,
                                                    (const void *)bufferP,
                                                    buffer_len );
 
     if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
-      printf("NR_BCCH_BCH decode error\n");
-      for (i=0; i<buffer_len; i++){
-    printf("%02x ",bufferP[i]);
-      }
-      printf("\n");
-      // free the memory
-      SEQUENCE_free( &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message, 1 );
-      return -1;
+       LOG_E(NR_RRC,"NR_BCCH_BCH decode error\n");
+       // free the memory
+       SEQUENCE_free( &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message, 1 );
+       return -1;
     }
     else {
       //  link to rrc instance
-      mib = bcch_message->message.choice.mib;
+       SEQUENCE_free( &asn_DEF_NR_MIB, (void *)NR_UE_rrc_inst[module_id].mib, 1 );
+       NR_UE_rrc_inst[module_id].mib = bcch_message->message.choice.mib;
       //memcpy( (void *)mib,
       //    (void *)&bcch_message->message.choice.mib,
       //    sizeof(NR_MIB_t) );
-      
-      nr_rrc_mac_config_req_ue( 0, 0, 0, mib, NULL);
-    }
-    
+
+       nr_rrc_mac_config_req_ue( 0, 0, 0, NR_UE_rrc_inst[module_id].mib, NULL, NULL, NULL);
+      }
+
     return 0;
 }
 
@@ -1148,7 +1139,7 @@ int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(
   NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index];
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN );
 
-  if (((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) &&  // SIB1 received
+  if (((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) && sib1->si_SchedulingInfo &&// SIB1 received
       (NR_UE_rrc_inst[module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)) {
     // to prevent memory bloating
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
@@ -1186,7 +1177,7 @@ int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(
           if(sib1 != NULL){
             SEQUENCE_free(&asn_DEF_NR_SIB1, (void *)sib1, 1 );
           }
-
+	        NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus|=1;
           sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
           if (*(int64_t*)sib1 != 1) {
             NR_UE_rrc_inst[module_id].sib1[gNB_index] = sib1;
@@ -1195,14 +1186,20 @@ int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(
             }
             LOG_I(NR_RRC, "SIB1 decoded\n");
 
+            ///	    dump_SIB1();
             // FIXME: improve condition for the RA trigger
             // Check for on-demand not broadcasted SI
             check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1);
-            if( nr_rrc_get_state(module_id) == RRC_STATE_IDLE_NR ) {
+            if( nr_rrc_get_state(module_id) <= RRC_STATE_IDLE_NR ) {
               NR_UE_rrc_inst[module_id].ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE;
               // TODO: remove flag after full RA procedures implemented
-              get_softmodem_params()->do_ra = 1;
+              //              get_softmodem_params()->do_ra = 1;
+              LOG_D(PHY,"Setting state to NR_RRC_SI_RECEIVED\n");
+              nr_rrc_set_state (module_id, NR_RRC_SI_RECEIVED);
             }
+            // take ServingCellConfigCommon and configure L1/L2
+            NR_UE_rrc_inst[module_id].servingCellConfigCommonSIB = sib1->servingCellConfigCommon;
+            nr_rrc_mac_config_req_ue(module_id,0,0,NULL,sib1->servingCellConfigCommon,NULL,NULL);
             nr_rrc_ue_generate_ra_msg(module_id,gNB_index);
           } else {
             LOG_E(NR_RRC, "SIB1 not decoded\n");
@@ -1256,10 +1253,18 @@ nr_rrc_ue_process_masterCellGroup(
 )
 //-----------------------------------------------------------------------------
 {
-  NR_CellGroupConfig_t *cellGroupConfig = (NR_CellGroupConfig_t *)masterCellGroup;
+  NR_CellGroupConfig_t *cellGroupConfig=NULL;
+  uper_decode(NULL,
+              &asn_DEF_NR_CellGroupConfig,   //might be added prefix later
+              (void **)&cellGroupConfig,
+              (uint8_t *)masterCellGroup->buf,
+              masterCellGroup->size, 0, 0);
+  xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)cellGroupConfig);
+
   if( cellGroupConfig->spCellConfig != NULL &&  cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL){
     //TODO (perform Reconfiguration with sync according to 5.3.5.5.2)
     //TODO (resume all suspended radio bearers and resume SCG transmission for all radio bearers, if suspended)
+    // NSA procedures
   }
 
   if( cellGroupConfig->rlc_BearerToReleaseList != NULL){
@@ -1279,12 +1284,18 @@ nr_rrc_ue_process_masterCellGroup(
   }
 
   if( cellGroupConfig->spCellConfig != NULL){
-    if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig) {
+    if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config &&
+	      NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig) {
       memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig,cellGroupConfig->spCellConfig,
              sizeof(struct NR_SpCellConfig));
     } else {
-      NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig = cellGroupConfig->spCellConfig;
+      if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config)
+	      NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig = cellGroupConfig->spCellConfig;
+      else
+	      NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = cellGroupConfig;
     }
+    LOG_D(RRC,"Sending CellGroupConfig to MAC\n");
+    nr_rrc_mac_config_req_ue(ctxt_pP->module_id,0,0,NULL,NULL,cellGroupConfig,NULL);
     //TODO (configure the SpCell as specified in 5.3.5.5.7)
   }
 
@@ -1312,8 +1323,16 @@ 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 ITTI_SIM
+#if defined(ITTI_SIM) || defined(RFSIM_NAS)
     as_nas_info_t initialNasMsg;
     generateRegistrationRequest(&initialNasMsg);
     nas_msg = (char*)initialNasMsg.data;
@@ -1329,18 +1348,22 @@ static void rrc_ue_generate_RRCSetupComplete(
   size = do_RRCSetupComplete(ctxt_pP->module_id,buffer,Transaction_id,sel_plmn_id,nas_msg_length,nas_msg);
   LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n",
    ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index);
-  LOG_D(RLC,
-       "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to gNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n",
+  LOG_D(NR_RRC,
+       "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCSetupComplete to gNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n",
        ctxt_pP->frame, ctxt_pP->module_id+NB_RN_INST, size, gNB_index, nr_rrc_mui, ctxt_pP->module_id+NB_eNB_INST, DCCH);
+
+  //for (int i=0;i<size;i++) printf("%02x ",buffer[i]);
+  //printf("\n");
+
    // ctxt_pP_local.rnti = ctxt_pP->rnti;
-  rrc_data_req_ue(
-      ctxt_pP,
-      DCCH,
-      nr_rrc_mui++,
-      SDU_CONFIRM_NO,
-      size,
-      buffer,
-      PDCP_TRANSMISSION_MODE_CONTROL);
+  rrc_data_req_ue(ctxt_pP,
+                  DCCH,
+                  nr_rrc_mui++,
+                  SDU_CONFIRM_NO,
+                  size,
+                  buffer,
+                  PDCP_TRANSMISSION_MODE_CONTROL);
+
 #ifdef ITTI_SIM
   MessageDef *message_p;
   uint8_t *message_buffer;
@@ -1355,382 +1378,392 @@ static void rrc_ue_generate_RRCSetupComplete(
 }
 
 int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB_INFO *const Srb_info, const uint8_t gNB_index ){
-    NR_DL_CCCH_Message_t *dl_ccch_msg=NULL;
-    asn_dec_rval_t dec_rval;
-    int rval=0;
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
-    //    LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",ue_mod_idP,Srb_info->Rx_buffer.payload_size,
-    //    NR_UE_rrc_inst[ue_mod_idP].Info[gNB_index].State);
-    dec_rval = uper_decode(NULL,
-                           &asn_DEF_NR_DL_CCCH_Message,
-                           (void **)&dl_ccch_msg,
-                           (uint8_t *)Srb_info->Rx_buffer.Payload,
-                           100,0,0);
-
-    if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
-      xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg);
-    }
-    
-    if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
-      LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed);
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
-      return -1;
-    }
-    
-    if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) {
-      if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_SI_RECEIVED) {
-        switch (dl_ccch_msg->message.choice.c1->present) {
-          case NR_DL_CCCH_MessageType__c1_PR_NOTHING:
-            LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",
-                  ctxt_pP->module_id,
-                  ctxt_pP->frame);
-            rval = 0;
-            break;
-    
-          case NR_DL_CCCH_MessageType__c1_PR_rrcReject:
-            LOG_I(NR_RRC,
-                  "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n",
-                  ctxt_pP->module_id,
-                  ctxt_pP->frame);
-            rval = 0;
-            break;
-    
-          case NR_DL_CCCH_MessageType__c1_PR_rrcSetup:
-            LOG_I(NR_RRC,
-                  "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n",
-                  ctxt_pP->module_id,
-                  ctxt_pP->frame,
-                  ctxt_pP->rnti);
-
-            // Get configuration
-            // Release T300 timer
-            NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T300_active = 0;
-            
-            nr_rrc_ue_process_masterCellGroup(
-              ctxt_pP,
-              gNB_index,
-              &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup);
-            nr_sa_rrc_ue_process_radioBearerConfig(
-              ctxt_pP,
-              gNB_index,
-              &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
-            nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED);
-            nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED);
-            NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti;
-            rrc_ue_generate_RRCSetupComplete(
-              ctxt_pP,
-              gNB_index,
-              dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier,
-              NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity);
-            rval = 0;
-            break;
-    
-          default:
-            LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n",
-                  ctxt_pP->module_id,
-                  ctxt_pP->frame);
-            rval = -1;
-            break;
-        }
-      }
-    }
-  
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
-  return rval;
-}
-
-// from NR SRB3
-int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(
-  const module_id_t module_id,
-  const uint8_t     gNB_index,
-  const uint8_t    *bufferP,
-  const uint32_t    buffer_len ){
-  //  uper_decode by nr R15 rrc_connection_reconfiguration
-  
-  int32_t i;
-  NR_DL_DCCH_Message_t *nr_dl_dcch_msg = NULL;
-  MessageDef *msg_p;
-
-  asn_dec_rval_t dec_rval = uper_decode(  NULL,
-                                          &asn_DEF_NR_DL_DCCH_Message,    
-                                          (void**)&nr_dl_dcch_msg,
-                                          (uint8_t *)bufferP,
-                                          buffer_len, 0, 0);
-
-  if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
-    for (i=0; i<buffer_len; i++)
-      printf("%02x ",bufferP[i]);
-    printf("\n");
-    // free the memory
-    SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 );
-    return -1;
-  }
-
-  if(nr_dl_dcch_msg != NULL){
-    switch(nr_dl_dcch_msg->message.present){            
-      case NR_DL_DCCH_MessageType_PR_c1:
-        switch(nr_dl_dcch_msg->message.choice.c1->present){
-          case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration:
-            nr_rrc_ue_process_rrcReconfiguration(module_id,nr_dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration);
-            break;
-
-          case NR_DL_DCCH_MessageType__c1_PR_NOTHING:
-          case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
-          case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
-            msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND);
-            if((nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) &&
-               (nr_dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){
-                nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer =
-                NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5;
-                nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType =
-                NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency;
-              }
-            itti_send_msg_to_task(TASK_RRC_NRUE,module_id,msg_p);
-            break;
-          
-          case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
-          case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
-          case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
-          case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
-          case NR_DL_DCCH_MessageType__c1_PR_counterCheck:
-          case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand:
-          case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16:
-          case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16:
-          case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16:
-          case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16:
-          case NR_DL_DCCH_MessageType__c1_PR_spare3:
-          case NR_DL_DCCH_MessageType__c1_PR_spare2:
-          case NR_DL_DCCH_MessageType__c1_PR_spare1:
-          default:
-            //  not supported or unused
-            break;
-        }
-        break;
-      case NR_DL_DCCH_MessageType_PR_NOTHING:
-      case NR_DL_DCCH_MessageType_PR_messageClassExtension:
-      default:
-        //  not supported or unused
-        break;
-    }
-    
-    //  release memory allocation
-    SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 );
-  }else{
-    //  log..
-  }
-
-  return 0;
-}
-
-
-//-----------------------------------------------------------------------------
-void
-nr_rrc_ue_process_securityModeCommand(
-  const protocol_ctxt_t *const ctxt_pP,
-  NR_SecurityModeCommand_t *const securityModeCommand,
-  const uint8_t                gNB_index
-)
-//-----------------------------------------------------------------------------
-{
-  asn_enc_rval_t enc_rval;
-  NR_UL_DCCH_Message_t ul_dcch_msg;
-  uint8_t buffer[200];
-  int i, securityMode;
-  LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n",
-        ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index);
-
-  switch (securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm) {
-    case NR_CipheringAlgorithm_nea0:
-      LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea0\n",
-            ctxt_pP->module_id);
-      securityMode= NR_CipheringAlgorithm_nea0;
-      break;
-
-    case NR_CipheringAlgorithm_nea1:
-      LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea1\n",ctxt_pP->module_id);
-      securityMode= NR_CipheringAlgorithm_nea1;
-      break;
-
-    case NR_CipheringAlgorithm_nea2:
-      LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea2\n",
-            ctxt_pP->module_id);
-      securityMode = NR_CipheringAlgorithm_nea2;
-      break;
 
-    default:
-      LOG_I(NR_RRC,"[UE %d] Security algorithm is set to none\n",ctxt_pP->module_id);
-      securityMode = NR_CipheringAlgorithm_spare1;
-      break;
-  }
+  NR_DL_CCCH_Message_t *dl_ccch_msg=NULL;
+  asn_dec_rval_t dec_rval;
+  int rval=0;
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
+  LOG_D(RRC,"[NR UE%d] Decoding DL-CCCH message (%d bytes), State %d\n",ctxt_pP->module_id,Srb_info->Rx_buffer.payload_size,
+      NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State);
+   dec_rval = uper_decode(NULL,
+			  &asn_DEF_NR_DL_CCCH_Message,
+			  (void **)&dl_ccch_msg,
+			  (uint8_t *)Srb_info->Rx_buffer.Payload,
+			  100,0,0);
+
+	 if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+     xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg);
+	 }
+
+   if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
+     LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed);
+     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
+     return -1;
+   }
 
-  switch (*securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm) {
-    case NR_IntegrityProtAlgorithm_nia1:
-      LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to nia1\n",ctxt_pP->module_id);
-      securityMode |= 1 << 5;
-      break;
+   if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) {
+     if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus > 0) {
+       switch (dl_ccch_msg->message.choice.c1->present) {
+       case NR_DL_CCCH_MessageType__c1_PR_NOTHING:
+	 LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",
+	       ctxt_pP->module_id,
+	       ctxt_pP->frame);
+	 rval = 0;
+	 break;
+
+       case NR_DL_CCCH_MessageType__c1_PR_rrcReject:
+	 LOG_I(NR_RRC,
+	       "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCReject \n",
+	       ctxt_pP->module_id,
+	       ctxt_pP->frame);
+	 rval = 0;
+	 break;
+
+       case NR_DL_CCCH_MessageType__c1_PR_rrcSetup:
+	 LOG_I(NR_RRC,
+	       "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n",
+	       ctxt_pP->module_id,
+	       ctxt_pP->frame,
+	       ctxt_pP->rnti);
+
+	 // Get configuration
+	 // Release T300 timer
+	 NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T300_active = 0;
+
+	 nr_rrc_ue_process_masterCellGroup(
+					   ctxt_pP,
+					   gNB_index,
+					   &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup);
+	 nr_sa_rrc_ue_process_radioBearerConfig(
+						ctxt_pP,
+						gNB_index,
+						&dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
+	 nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED);
+	 nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED);
+	 NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti;
+	 rrc_ue_generate_RRCSetupComplete(
+					  ctxt_pP,
+					  gNB_index,
+					  dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier,
+					  NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity);
+	 rval = 0;
+	 break;
+
+       default:
+	 LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n",
+	       ctxt_pP->module_id,
+	       ctxt_pP->frame);
+	 rval = -1;
+	 break;
+       }
+     }
+   }
 
-    case NR_IntegrityProtAlgorithm_nia2:
-      LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to nia2\n",ctxt_pP->module_id);
-      securityMode |= 1 << 6;
-      break;
+   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
+   return rval;
+ }
 
-    default:
-      LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to none\n",ctxt_pP->module_id);
-      securityMode |= 0x70 ;
-      break;
-  }
+ // from NR SRB3
+ int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(
+   const module_id_t module_id,
+   const uint8_t     gNB_index,
+   const uint8_t    *bufferP,
+   const uint32_t    buffer_len ){
+   //  uper_decode by nr R15 rrc_connection_reconfiguration
+
+   int32_t i;
+   NR_DL_DCCH_Message_t *nr_dl_dcch_msg = NULL;
+   MessageDef *msg_p;
+
+   asn_dec_rval_t dec_rval = uper_decode(  NULL,
+					   &asn_DEF_NR_DL_DCCH_Message,
+					   (void**)&nr_dl_dcch_msg,
+					   (uint8_t *)bufferP,
+					   buffer_len, 0, 0);
+
+   if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
+     for (i=0; i<buffer_len; i++)
+       printf("%02x ",bufferP[i]);
+     printf("\n");
+     // free the memory
+     SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 );
+     return -1;
+   }
 
-  LOG_D(NR_RRC,"[UE %d] security mode is %x \n",ctxt_pP->module_id, securityMode);
-  NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm =
-    securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm;
-  NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm =
-    *securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm;
-  memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
-  //memset((void *)&SecurityModeCommand,0,sizeof(SecurityModeCommand_t));
-  ul_dcch_msg.message.present           = NR_UL_DCCH_MessageType_PR_c1;
-  ul_dcch_msg.message.choice.c1         = calloc(1, sizeof(*ul_dcch_msg.message.choice.c1));
+   if(nr_dl_dcch_msg != NULL){
+     switch(nr_dl_dcch_msg->message.present){
+       case NR_DL_DCCH_MessageType_PR_c1:
+	 switch(nr_dl_dcch_msg->message.choice.c1->present){
+	   case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration:
+	     nr_rrc_ue_process_rrcReconfiguration(module_id,nr_dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration);
+	     break;
+
+	   case NR_DL_DCCH_MessageType__c1_PR_NOTHING:
+	   case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
+	   case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
+	     msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND);
+	     if((nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) &&
+		(nr_dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){
+		 nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer =
+		 NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5;
+		 nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType =
+		 NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency;
+	       }
+	     itti_send_msg_to_task(TASK_RRC_NRUE,module_id,msg_p);
+	     break;
+
+	   case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
+	   case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
+	   case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
+	   case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
+	   case NR_DL_DCCH_MessageType__c1_PR_counterCheck:
+	   case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand:
+	   case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16:
+	   case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16:
+	   case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16:
+	   case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16:
+	   case NR_DL_DCCH_MessageType__c1_PR_spare3:
+	   case NR_DL_DCCH_MessageType__c1_PR_spare2:
+	   case NR_DL_DCCH_MessageType__c1_PR_spare1:
+	   default:
+	     //  not supported or unused
+	     break;
+	 }
+	 break;
+       case NR_DL_DCCH_MessageType_PR_NOTHING:
+       case NR_DL_DCCH_MessageType_PR_messageClassExtension:
+       default:
+	 //  not supported or unused
+	 break;
+     }
+
+     //  release memory allocation
+     SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 );
+   }else{
+     //  log..
+   }
 
-  if (securityMode >= NO_SECURITY_MODE) {
-    LOG_I(NR_RRC, "rrc_ue_process_securityModeCommand, security mode complete case \n");
-    ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete;
-  } else {
-    LOG_I(NR_RRC, "rrc_ue_process_securityModeCommand, security mode failure case \n");
-    ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeFailure;
-  }
+   return 0;
+ }
 
-  uint8_t *kRRCenc = NULL;
-  uint8_t *kUPenc = NULL;
-  uint8_t *kRRCint = NULL;
-  pdcp_t *pdcp_p = NULL;
-  hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
-  hashtable_rc_t h_rc;
-  key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti,
-                            ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES);
-  h_rc = hashtable_get(pdcp_coll_p, key, (void **) &pdcp_p);
-
-  if (h_rc == HASH_TABLE_OK) {
-    LOG_D(NR_RRC, "PDCP_COLL_KEY_VALUE() returns valid key = %ld\n", key);
-    LOG_D(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB="
-          "%02x%02x%02x%02x"
-          "%02x%02x%02x%02x"
-          "%02x%02x%02x%02x"
-          "%02x%02x%02x%02x"
-          "%02x%02x%02x%02x"
-          "%02x%02x%02x%02x"
-          "%02x%02x%02x%02x"
-          "%02x%02x%02x%02x\n",
-          NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[0],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[1],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[2],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[3],
-          NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[4],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[5],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[6],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[7],
-          NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[8],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[9],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[10], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[11],
-          NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[12], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[13], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[14], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[15],
-          NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[16], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[17], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[18], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[19],
-          NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23],
-          NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27],
-          NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]);
-    derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc);
-    derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint);
-    derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc);
-
-    if (securityMode != 0xff) {
-      pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0,
-                               NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm
-                               | (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
-                               kRRCenc, kRRCint, kUPenc);
-    } else {
-      LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x",
-            securityMode);
-    }
-  } else {
-    LOG_I(NR_RRC, "Could not get PDCP instance where key=0x%ld\n", key);
-  }
 
-  if (securityModeCommand->criticalExtensions.present == NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand) {
-    ul_dcch_msg.message.choice.c1->choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_t));
-    ul_dcch_msg.message.choice.c1->choice.securityModeComplete->rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier;
-    ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.present = NR_SecurityModeComplete__criticalExtensions_PR_securityModeComplete;
-    ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_IEs_t));
-    ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete->nonCriticalExtension =NULL;
-    LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (gNB %d), rrc_TransactionIdentifier: %ld\n",
-          ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index, securityModeCommand->rrc_TransactionIdentifier);
-    enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
-                                     NULL,
-                                     (void *)&ul_dcch_msg,
-                                     buffer,
-                                     100);
-    AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
-                 enc_rval.failed_type->name, enc_rval.encoded);
-
-   if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
-      xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
+ //-----------------------------------------------------------------------------
+ void
+ nr_rrc_ue_process_securityModeCommand(
+   const protocol_ctxt_t *const ctxt_pP,
+   NR_SecurityModeCommand_t *const securityModeCommand,
+   const uint8_t                gNB_index
+ )
+ //-----------------------------------------------------------------------------
+ {
+   asn_enc_rval_t enc_rval;
+   NR_UL_DCCH_Message_t ul_dcch_msg;
+   uint8_t buffer[200];
+   int i, securityMode;
+   LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n",
+	 ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index);
+
+   switch (securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm) {
+     case NR_CipheringAlgorithm_nea0:
+       LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea0\n",
+	     ctxt_pP->module_id);
+       securityMode= NR_CipheringAlgorithm_nea0;
+       break;
+
+     case NR_CipheringAlgorithm_nea1:
+       LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea1\n",ctxt_pP->module_id);
+       securityMode= NR_CipheringAlgorithm_nea1;
+       break;
+
+     case NR_CipheringAlgorithm_nea2:
+       LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea2\n",
+	     ctxt_pP->module_id);
+       securityMode = NR_CipheringAlgorithm_nea2;
+       break;
+
+     default:
+       LOG_I(NR_RRC,"[UE %d] Security algorithm is set to none\n",ctxt_pP->module_id);
+       securityMode = NR_CipheringAlgorithm_spare1;
+       break;
    }
+   NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm =
+   securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm;
+
+   if (securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm != NULL)
+   {
+     switch (*securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm) {
+       case NR_IntegrityProtAlgorithm_nia1:
+         LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to nia1\n",ctxt_pP->module_id);
+         securityMode |= 1 << 5;
+         break;
+
+       case NR_IntegrityProtAlgorithm_nia2:
+         LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to nia2\n",ctxt_pP->module_id);
+         securityMode |= 1 << 6;
+         break;
+
+       default:
+         LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to none\n",ctxt_pP->module_id);
+         securityMode |= 0x70 ;
+         break;
+     }
+
+     NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm =
+     *securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm;
 
-    LOG_D(NR_RRC, "securityModeComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
+   }
 
-    for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) {
-      LOG_T(NR_RRC, "%02x.", buffer[i]);
-    }
+   LOG_D(NR_RRC,"[UE %d] security mode is %x \n",ctxt_pP->module_id, securityMode);
+   memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
+   //memset((void *)&SecurityModeCommand,0,sizeof(SecurityModeCommand_t));
+   ul_dcch_msg.message.present           = NR_UL_DCCH_MessageType_PR_c1;
+   ul_dcch_msg.message.choice.c1         = calloc(1, sizeof(*ul_dcch_msg.message.choice.c1));
+
+   if (securityMode >= NO_SECURITY_MODE) {
+     LOG_I(NR_RRC, "rrc_ue_process_securityModeCommand, security mode complete case \n");
+     ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete;
+   } else {
+     LOG_I(NR_RRC, "rrc_ue_process_securityModeCommand, security mode failure case \n");
+     ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeFailure;
+     ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete;
+   }
 
-    LOG_T(NR_RRC, "\n");
-#ifdef ITTI_SIM
-    MessageDef *message_p;
-    uint8_t *message_buffer;
-    message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
-                       (enc_rval.encoded + 7) / 8);
-    memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8);
+   uint8_t *kRRCenc = NULL;
+   uint8_t *kUPenc = NULL;
+   uint8_t *kRRCint = NULL;
+   pdcp_t *pdcp_p = NULL;
+   hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
+   hashtable_rc_t h_rc;
+   key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES);
+   h_rc = hashtable_get(pdcp_coll_p, key, (void **) &pdcp_p);
+
+   if (h_rc == HASH_TABLE_OK) {
+     LOG_D(NR_RRC, "PDCP_COLL_KEY_VALUE() returns valid key = %ld\n", key);
+     LOG_D(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB="
+	   "%02x%02x%02x%02x"
+	   "%02x%02x%02x%02x"
+	   "%02x%02x%02x%02x"
+	   "%02x%02x%02x%02x"
+	   "%02x%02x%02x%02x"
+	   "%02x%02x%02x%02x"
+	   "%02x%02x%02x%02x"
+	   "%02x%02x%02x%02x\n",
+	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[0],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[1],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[2],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[3],
+	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[4],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[5],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[6],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[7],
+	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[8],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[9],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[10], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[11],
+	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[12], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[13], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[14], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[15],
+	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[16], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[17], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[18], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[19],
+	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23],
+	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27],
+	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]);
+     derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc);
+     derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint);
+     derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc);
+
+     if (securityMode != 0xff) {
+       pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0,
+                                NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm
+                                | (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
+                                kRRCenc, kRRCint, kUPenc);
+     } else {
+       LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode);
+     }
+   } else {
+     LOG_I(NR_RRC, "Could not get PDCP instance where key=0x%ld\n", key);
+   }
 
-    message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
-    GNB_RRC_DCCH_DATA_IND (message_p).rbid  = DCCH;
-    GNB_RRC_DCCH_DATA_IND (message_p).sdu   = message_buffer;
-    GNB_RRC_DCCH_DATA_IND (message_p).size    = (enc_rval.encoded + 7) / 8;
-    itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
-#else
-    rrc_data_req (
-      ctxt_pP,
-      DCCH,
-      nr_rrc_mui++,
-      SDU_CONFIRM_NO,
-      (enc_rval.encoded + 7) / 8,
-      buffer,
-      PDCP_TRANSMISSION_MODE_CONTROL);
-#endif
-  } else
-    LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n",
-                 securityModeCommand->criticalExtensions.present);
-}
+   if (securityModeCommand->criticalExtensions.present == NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand) {
+     ul_dcch_msg.message.choice.c1->choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_t));
+     ul_dcch_msg.message.choice.c1->choice.securityModeComplete->rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier;
+     ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.present = NR_SecurityModeComplete__criticalExtensions_PR_securityModeComplete;
+     ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_IEs_t));
+     ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete->nonCriticalExtension =NULL;
+     LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (gNB %d), rrc_TransactionIdentifier: %ld\n",
+	   ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index, securityModeCommand->rrc_TransactionIdentifier);
+     enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
+                                      NULL,
+                                      (void *)&ul_dcch_msg,
+                                      buffer,
+                                      100);
+     AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
+		  enc_rval.failed_type->name, enc_rval.encoded);
 
-//-----------------------------------------------------------------------------
-void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) {
-  uint8_t i=0,rv[6];
-
-  if(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) {
-    // Get RRCConnectionRequest, fill random for now
-    // Generate random byte stream for contention resolution
-    for (i=0; i<6; i++) {
-#ifdef SMBV
-      // if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed
-      rv[i]=i;
-#else
-      rv[i]=taus()&0xff;
-#endif
-      LOG_T(NR_RRC,"%x.",rv[i]);
+    if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+      xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
     }
+     log_dump(MAC, buffer, 16, LOG_DUMP_CHAR, "securityModeComplete payload: ");
+     LOG_D(NR_RRC, "securityModeComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
+
+     for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) {
+       LOG_T(NR_RRC, "%02x.", buffer[i]);
+     }
+
+     LOG_T(NR_RRC, "\n");
+ #ifdef ITTI_SIM
+     MessageDef *message_p;
+     uint8_t *message_buffer;
+     message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
+			(enc_rval.encoded + 7) / 8);
+     memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8);
+
+     message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
+     GNB_RRC_DCCH_DATA_IND (message_p).rbid  = DCCH;
+     GNB_RRC_DCCH_DATA_IND (message_p).sdu   = message_buffer;
+     GNB_RRC_DCCH_DATA_IND (message_p).size    = (enc_rval.encoded + 7) / 8;
+     itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
+ #else
+     rrc_data_req_ue (ctxt_pP,
+                      DCCH,
+                      nr_rrc_mui++,
+                      SDU_CONFIRM_NO,
+                      (enc_rval.encoded + 7) / 8,
+                      buffer,
+                      PDCP_TRANSMISSION_MODE_CONTROL);
+ #endif
+   } else
+     LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n",
+		  securityModeCommand->criticalExtensions.present);
+ }
 
-    LOG_T(NR_RRC,"\n");
-    NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size =
-       do_RRCSetupRequest(
-         module_id,
-         (uint8_t *)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload,
-         rv);
-    LOG_I(NR_RRC,"[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n",
-          module_id, NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index);
-
-    for (i=0; i<NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) {
-      LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
-    }
+ //-----------------------------------------------------------------------------
+ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) {
+   uint8_t i=0,rv[6];
 
-    LOG_T(NR_RRC,"\n");
-    /*UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.Payload[i] = taus()&0xff;
-    UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.payload_size =i; */
+   if(get_softmodem_params()->sa) {
+     AMF_MODE_ENABLED = 1;
+   }
+   if(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) {
+     // Get RRCConnectionRequest, fill random for now
+     // Generate random byte stream for contention resolution
+     for (i=0; i<6; i++) {
+ #ifdef SMBV
+       // if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed
+       rv[i]=i;
+ #else
+       rv[i]=taus()&0xff;
+ #endif
+       LOG_T(NR_RRC,"%x.",rv[i]);
+     }
+
+     LOG_T(NR_RRC,"\n");
+     NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size =
+	do_RRCSetupRequest(
+	  module_id,
+	  (uint8_t *)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload,
+	  rv);
+     LOG_I(NR_RRC,"[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n",
+	   module_id, NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index);
+
+     for (i=0; i<NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) {
+       LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
+       //printf("%x.",NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
+
+     }
+
+     LOG_T(NR_RRC,"\n");
+     //printf("\n");
+     /*UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.Payload[i] = taus()&0xff;
+     UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.payload_size =i; */
 
 #ifdef ITTI_SIM
     MessageDef *message_p;
@@ -1783,722 +1816,619 @@ nr_rrc_ue_establish_srb2(
   return(0);
 }
 
-//-----------------------------------------------------------------------------
-int32_t
-nr_rrc_ue_establish_drb(
-    module_id_t       ue_mod_idP,
-    frame_t           frameP,
-    uint8_t           gNB_index,
-    NR_DRB_ToAddMod_t *DRB_config
-)
-//-----------------------------------------------------------------------------
-{
-  // add descriptor from RRC PDU
-  int oip_ifup = 0, ip_addr_offset3 = 0, ip_addr_offset4 = 0;
-  /* avoid gcc warnings */
-  (void)oip_ifup;
-  (void)ip_addr_offset3;
-  (void)ip_addr_offset4;
-  LOG_I(NR_RRC,"[UE %d] Frame %d: processing RRCReconfiguration: reconfiguring DRB %ld\n",
-        ue_mod_idP, frameP, DRB_config->drb_Identity);
-
- if(!AMF_MODE_ENABLED) {
-   ip_addr_offset3 = 0;
-   ip_addr_offset4 = 1;
-   LOG_I(OIP, "[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP,
-         ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1);
-   oip_ifup = nas_config(ip_addr_offset3+ue_mod_idP+1,   // interface_id
-                       UE_NAS_USE_TUN?1:(ip_addr_offset3+ue_mod_idP+1), // third_octet
-                       ip_addr_offset4+ue_mod_idP+1, // fourth_octet
-                       "oip");                        // interface suffix (when using kernel module)
-
-   if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB
-     LOG_I(OIP, "[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n",
-           ue_mod_idP,
-           ip_addr_offset3+ue_mod_idP,
-           (long int)((gNB_index * NR_maxDRB) + DRB_config->drb_Identity));
-     rb_conf_ipv4(0,//add
-                  ue_mod_idP,//cx align with the UE index
-                  ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index
-                  (gNB_index * NR_maxDRB) + DRB_config->drb_Identity,//rb
-                  0,//dscp
-                  ipv4_address(ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1),//saddr
-                  ipv4_address(ip_addr_offset3+ue_mod_idP+1, gNB_index+1));//daddr
-     LOG_D(NR_RRC,"[UE %d] State = Attached (gNB %d)\n",ue_mod_idP,gNB_index);
-   }
- }
-
-  return(0);
-}
-
-//-----------------------------------------------------------------------------
-void
-nr_rrc_ue_process_measConfig(
-    const protocol_ctxt_t *const       ctxt_pP,
-    const uint8_t                      gNB_index,
-    NR_MeasConfig_t *const             measConfig
-)
-//-----------------------------------------------------------------------------
-{
-  int i;
-  long ind;
-  NR_MeasObjectToAddMod_t   *measObj        = NULL;
-  NR_ReportConfigToAddMod_t *reportConfig   = NULL;
-
-  if (measConfig->measObjectToRemoveList != NULL) {
-    for (i = 0; i < measConfig->measObjectToRemoveList->list.count; i++) {
-        ind = *measConfig->measObjectToRemoveList->list.array[i];
-        free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]);
-    }
-  }
-
-  if (measConfig->measObjectToAddModList != NULL) {
-    LOG_I(NR_RRC, "Measurement Object List is present\n");
-    for (i = 0; i < measConfig->measObjectToAddModList->list.count; i++) {
-      measObj = measConfig->measObjectToAddModList->list.array[i];
-      ind     = measConfig->measObjectToAddModList->list.array[i]->measObjectId;
-
-      if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]) {
-        LOG_D(NR_RRC, "Modifying measurement object %ld\n",ind);
-        memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1],
-                (char *)measObj,
-                sizeof(NR_MeasObjectToAddMod_t));
-      } else {
-        LOG_I(NR_RRC, "Adding measurement object %ld\n", ind);
-
-        if (measObj->measObject.present == NR_MeasObjectToAddMod__measObject_PR_measObjectNR) {
-            NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]=measObj;
-        }
-      }
-    }
-
-    LOG_I(NR_RRC, "call rrc_mac_config_req \n");
-    // rrc_mac_config_req_ue
-  }
-
-  if (measConfig->reportConfigToRemoveList != NULL) {
-    for (i = 0; i < measConfig->reportConfigToRemoveList->list.count; i++) {
-        ind = *measConfig->reportConfigToRemoveList->list.array[i];
-        free(NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]);
-    }
-  }
-
-  if (measConfig->reportConfigToAddModList != NULL) {
-    LOG_I(NR_RRC,"Report Configuration List is present\n");
-    for (i = 0; i < measConfig->reportConfigToAddModList->list.count; i++) {
-      ind          = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId;
-      reportConfig = measConfig->reportConfigToAddModList->list.array[i];
-
-      if (NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]) {
-          LOG_I(NR_RRC, "Modifying Report Configuration %ld\n", ind-1);
-          memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1],
-                  (char *)measConfig->reportConfigToAddModList->list.array[i],
-                  sizeof(NR_ReportConfigToAddMod_t));
-      } else {
-        LOG_D(NR_RRC,"Adding Report Configuration %ld %p \n", ind-1, measConfig->reportConfigToAddModList->list.array[i]);
-        if (reportConfig->reportConfig.present == NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR) {
-            NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i];
-        }
-      }
-    }
-  }
-
-  if (measConfig->measIdToRemoveList != NULL) {
-    for (i = 0; i < measConfig->measIdToRemoveList->list.count; i++) {
-        ind = *measConfig->measIdToRemoveList->list.array[i];
-        free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]);
-    }
-  }
-
-  if (measConfig->measIdToAddModList != NULL) {
-    for (i = 0; i < measConfig->measIdToAddModList->list.count; i++) {
-      ind = measConfig->measIdToAddModList->list.array[i]->measId;
-
-      if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]) {
-        LOG_D(NR_RRC, "Modifying Measurement ID %ld\n",ind-1);
-        memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1],
-            (char *)measConfig->measIdToAddModList->list.array[i],
-            sizeof(NR_MeasIdToAddMod_t));
-      } else {
-        LOG_D(NR_RRC, "Adding Measurement ID %ld %p\n", ind-1, measConfig->measIdToAddModList->list.array[i]);
-        NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i];
-      }
-    }
-  }
-
-  if (measConfig->quantityConfig != NULL) {
-    if (NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index]) {
-      LOG_D(NR_RRC,"Modifying Quantity Configuration \n");
-      memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index],
-              (char *)measConfig->quantityConfig,
-              sizeof(NR_QuantityConfig_t));
-    } else {
-      LOG_D(NR_RRC, "Adding Quantity configuration\n");
-      NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index] = measConfig->quantityConfig;
-    }
-  }
-
-  if (measConfig->measGapConfig != NULL) {
-    if (NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index]) {
-      memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index],
-              (char *)measConfig->measGapConfig,
-              sizeof(NR_MeasGapConfig_t));
-    } else {
-      NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index] = measConfig->measGapConfig;
-    }
-  }
-
-  if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_ssb_RSRP) {
-    NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.ssb_RSRP;
-  } else if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_csi_RSRP) {
-    NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.csi_RSRP;
-  }
-}
-
-//-----------------------------------------------------------------------------
-void
-nr_sa_rrc_ue_process_radioBearerConfig(
-    const protocol_ctxt_t *const       ctxt_pP,
-    const uint8_t                      gNB_index,
-    NR_RadioBearerConfig_t *const      radioBearerConfig
-)
-//-----------------------------------------------------------------------------
-{
-  long SRB_id, DRB_id;
-  int i, cnt;
-
-  if( radioBearerConfig->srb3_ToRelease != NULL){
-    if( *radioBearerConfig->srb3_ToRelease == TRUE){
-      //TODO (release the PDCP entity and the srb-Identity of the SRB3.)
+ //-----------------------------------------------------------------------------
+ int32_t
+ nr_rrc_ue_establish_drb(
+     module_id_t       ue_mod_idP,
+     frame_t           frameP,
+     uint8_t           gNB_index,
+     NR_DRB_ToAddMod_t *DRB_config
+ )
+ //-----------------------------------------------------------------------------
+ {
+   // add descriptor from RRC PDU
+   int oip_ifup = 0, ip_addr_offset3 = 0, ip_addr_offset4 = 0;
+   /* avoid gcc warnings */
+   (void)oip_ifup;
+   (void)ip_addr_offset3;
+   (void)ip_addr_offset4;
+   LOG_I(NR_RRC,"[UE %d] Frame %d: processing RRCReconfiguration: reconfiguring DRB %ld\n",
+	 ue_mod_idP, frameP, DRB_config->drb_Identity);
+
+  if(!AMF_MODE_ENABLED) {
+    ip_addr_offset3 = 0;
+    ip_addr_offset4 = 1;
+    LOG_I(OIP, "[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP,
+	  ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1);
+    oip_ifup = nas_config(ip_addr_offset3+ue_mod_idP+1,   // interface_id
+			UE_NAS_USE_TUN?1:(ip_addr_offset3+ue_mod_idP+1), // third_octet
+			ip_addr_offset4+ue_mod_idP+1, // fourth_octet
+			"oip");                        // interface suffix (when using kernel module)
+
+    if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB
+      LOG_I(OIP, "[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n",
+	    ue_mod_idP,
+	    ip_addr_offset3+ue_mod_idP,
+	    (long int)((gNB_index * NR_maxDRB) + DRB_config->drb_Identity));
+      rb_conf_ipv4(0,//add
+		   ue_mod_idP,//cx align with the UE index
+		   ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index
+		   (gNB_index * NR_maxDRB) + DRB_config->drb_Identity,//rb
+		   0,//dscp
+		   ipv4_address(ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1),//saddr
+		   ipv4_address(ip_addr_offset3+ue_mod_idP+1, gNB_index+1));//daddr
+      LOG_D(NR_RRC,"[UE %d] State = Attached (gNB %d)\n",ue_mod_idP,gNB_index);
     }
   }
 
-  if (radioBearerConfig->srb_ToAddModList != NULL) {
-    if (radioBearerConfig->securityConfig != NULL) {
-      if (*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master) {
-        NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm =
-            radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm;
-        NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm =
-            *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm;
-      }
-    }
-
-    uint8_t *kRRCenc = NULL;
-    uint8_t *kRRCint = NULL;
-    derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
-                    NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc);
-    derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
-                    NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint);
-    // Refresh SRBs
-    // nr_rrc_pdcp_config_asn1_req(ctxt_pP,
-    //                             radioBearerConfig->srb_ToAddModList,
-    //                             NULL,
-    //                             NULL,
-    //                             NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm |
-    //                             (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
-    //                             kRRCenc,
-    //                             kRRCint,
-    //                             NULL,
-    //                             NULL,
-    //                             NULL,
-    //                             NULL,
-    //                             NULL);
-    // Refresh SRBs
-    // nr_rrc_rlc_config_asn1_req(ctxt_pP,
-    //                             radioBearerConfig->srb_ToAddModList,
-    //                             NULL,
-    //                             NULL,
-    //                             NULL,
-    //                             NULL
-    //                             );
-
-    for (cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) {
-      SRB_id = radioBearerConfig->srb_ToAddModList->list.array[cnt]->srb_Identity;
-      LOG_D(NR_RRC,"[UE %d]: Frame %d SRB config cnt %d (SRB%ld)\n", ctxt_pP->module_id, ctxt_pP->frame, cnt, SRB_id);
-      if (SRB_id == 1) {
-        if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index]) {
-          memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index],
-              radioBearerConfig->srb_ToAddModList->list.array[cnt], sizeof(NR_SRB_ToAddMod_t));
-        } else {
-          NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt];
-          nr_rrc_ue_establish_srb1(ctxt_pP->module_id,
-                                  ctxt_pP->frame,
-                                  gNB_index,
-                                  radioBearerConfig->srb_ToAddModList->list.array[cnt]);
-
-          LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB1 gNB %d) --->][MAC_UE][MOD %02d][]\n",
-              ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
-          // rrc_mac_config_req_ue
-        }
-      } else {
-        if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index]) {
-          memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index],
-              radioBearerConfig->srb_ToAddModList->list.array[cnt], sizeof(NR_SRB_ToAddMod_t));
-        } else {
-          NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt];
-          nr_rrc_ue_establish_srb2(ctxt_pP->module_id,
-                                  ctxt_pP->frame,
-                                  gNB_index,
-                                  radioBearerConfig->srb_ToAddModList->list.array[cnt]);
-
-          LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB2 gNB %d) --->][MAC_UE][MOD %02d][]\n",
-              ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
-          // rrc_mac_config_req_ue
-        }
-      } // srb2
-    }
-  } // srb_ToAddModList
-
-  // Establish DRBs if present
-  if (radioBearerConfig->drb_ToAddModList != NULL) {
-    if ((NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB == NULL) &&
-      (radioBearerConfig->drb_ToAddModList->list.count >= 1)) {
-      NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = malloc(sizeof(rb_id_t));
-      *NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = radioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity;
-    }
-
-    for (cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) {
-      DRB_id = radioBearerConfig->drb_ToAddModList->list.array[cnt]->drb_Identity;
-      if (NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]) {
-        memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1],
-                radioBearerConfig->drb_ToAddModList->list.array[cnt], sizeof(NR_DRB_ToAddMod_t));
-      } else {
-        LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]);
-        NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1] = radioBearerConfig->drb_ToAddModList->list.array[cnt];
-      }
-    }
-
-    uint8_t *kUPenc = NULL;
-    derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
-                    NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc);
-    MSC_LOG_TX_MESSAGE(
-        MSC_RRC_UE,
-        MSC_PDCP_UE,
-        NULL,
-        0,
-        MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security %X)",
-        MSC_AS_TIME_ARGS(ctxt_pP),
-        ctxt_pP->rnti,
-        NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm |
-        (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4));
-
-      // Refresh DRBs
-      // nr_rrc_pdcp_config_asn1_req(ctxt_pP,
-      //                             NULL,
-      //                             radioBearerConfig->drb_ToAddModList,
-      //                             NULL,
-      //                             NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm |
-      //                             (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
-      //                             NULL,
-      //                             NULL,
-      //                             kUPenc,
-      //                             NULL,
-      //                             NULL,
-      //                             NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB,
-      //                             NULL);
-      // Refresh DRBs
-      // nr_rrc_rlc_config_asn1_req(ctxt_pP,
-      //                             NULL,
-      //                             radioBearerConfig->drb_ToAddModList,
-      //                             NULL,
-      //                             NULL,
-      //                             NULL
-      //                             );
-  } // drb_ToAddModList
-
-  if (radioBearerConfig->drb_ToReleaseList != NULL) {
-    for (i = 0; i < radioBearerConfig->drb_ToReleaseList->list.count; i++) {
-      DRB_id = *radioBearerConfig->drb_ToReleaseList->list.array[i];
-      free(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]);
-    }
-  }
-
-  NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_CONNECTED;
-  LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index);
-}
-
-//-----------------------------------------------------------------------------
-void
-rrc_ue_process_rrcReconfiguration(
-  const protocol_ctxt_t *const  ctxt_pP,
-  NR_RRCReconfiguration_t       *rrcReconfiguration,
-  uint8_t                       gNB_index
-)
-//-----------------------------------------------------------------------------
-{
-  LOG_I(NR_RRC, "[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCReconfiguration (gNB %d)\n",
-      ctxt_pP->module_id, ctxt_pP->frame, gNB_index);
-
-  NR_RRCReconfiguration_IEs_t *ie = NULL;
+   return(0);
+ }
 
-  if (rrcReconfiguration->criticalExtensions.present
-                    == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration) {
-    ie = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration;
-    if (ie->measConfig != NULL) {
-      LOG_I(NR_RRC, "Measurement Configuration is present\n");
-      nr_rrc_ue_process_measConfig(ctxt_pP, gNB_index, ie->measConfig);
-    }
+ //-----------------------------------------------------------------------------
+ void
+ nr_rrc_ue_process_measConfig(
+     const protocol_ctxt_t *const       ctxt_pP,
+     const uint8_t                      gNB_index,
+     NR_MeasConfig_t *const             measConfig
+ )
+ //-----------------------------------------------------------------------------
+ {
+   int i;
+   long ind;
+   NR_MeasObjectToAddMod_t   *measObj        = NULL;
+   NR_ReportConfigToAddMod_t *reportConfig   = NULL;
+
+   if (measConfig->measObjectToRemoveList != NULL) {
+     for (i = 0; i < measConfig->measObjectToRemoveList->list.count; i++) {
+       ind = *measConfig->measObjectToRemoveList->list.array[i];
+       free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]);
+     }
+   }
 
-    if (ie->radioBearerConfig != NULL) {
-      LOG_I(NR_RRC, "radio Bearer Configuration is present\n");
-      nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig);
-    }
+   if (measConfig->measObjectToAddModList != NULL) {
+     LOG_I(NR_RRC, "Measurement Object List is present\n");
+     for (i = 0; i < measConfig->measObjectToAddModList->list.count; i++) {
+       measObj = measConfig->measObjectToAddModList->list.array[i];
+       ind     = measConfig->measObjectToAddModList->list.array[i]->measObjectId;
+
+       if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]) {
+         LOG_D(NR_RRC, "Modifying measurement object %ld\n",ind);
+         memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1],
+           (char *)measObj,
+           sizeof(NR_MeasObjectToAddMod_t));
+       } else {
+	 LOG_I(NR_RRC, "Adding measurement object %ld\n", ind);
+
+	 if (measObj->measObject.present == NR_MeasObjectToAddMod__measObject_PR_measObjectNR) {
+	     NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]=measObj;
+	 }
+       }
+     }
+
+     LOG_I(NR_RRC, "call rrc_mac_config_req \n");
+     // rrc_mac_config_req_ue
+   }
 
-    /* Check if there is dedicated NAS information to forward to NAS */
-    if (ie->nonCriticalExtension->dedicatedNAS_MessageList != NULL) {
-      int list_count;
-      uint32_t pdu_length;
-      uint8_t *pdu_buffer;
-      MessageDef *msg_p;
+   if (measConfig->reportConfigToRemoveList != NULL) {
+     for (i = 0; i < measConfig->reportConfigToRemoveList->list.count; i++) {
+       ind = *measConfig->reportConfigToRemoveList->list.array[i];
+       free(NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]);
+     }
+   }
 
-      for (list_count = 0; list_count < ie->nonCriticalExtension->dedicatedNAS_MessageList->list.count; list_count++) {
-        pdu_length = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->size;
-        pdu_buffer = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->buf;
-#ifdef ITTI_SIM
-        uint8_t msg_type = 0;
-        if((pdu_buffer + 1) != NULL){
-          if (*(pdu_buffer + 1) > 0 ) {
-            if((pdu_buffer + 9) != NULL){
-                msg_type = *(pdu_buffer + 9);
-            } else {
-              LOG_W(NR_RRC, "[UE] Received invalid downlink message\n");
-              return;
-            }
-          } else {
-            if((pdu_buffer + 2) != NULL){
-              msg_type = *(pdu_buffer + 2);
-            } else {
-                LOG_W(NR_RRC, "[UE] Received invalid downlink message\n");
-                return;
-            }
-          }
-        }
-        if(msg_type == REGISTRATION_ACCEPT){
-          LOG_I(NR_RRC, "[UE] Received REGISTRATION ACCEPT message\n");
-        }
-#endif
-        msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_ESTABLI_CNF);
-        NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS;
-        NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length;
-        NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer;
-        itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
-      }
+   if (measConfig->reportConfigToAddModList != NULL) {
+     LOG_I(NR_RRC,"Report Configuration List is present\n");
+     for (i = 0; i < measConfig->reportConfigToAddModList->list.count; i++) {
+       ind          = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId;
+       reportConfig = measConfig->reportConfigToAddModList->list.array[i];
+
+       if (NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]) {
+         LOG_I(NR_RRC, "Modifying Report Configuration %ld\n", ind-1);
+         memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1],
+                 (char *)measConfig->reportConfigToAddModList->list.array[i],
+                 sizeof(NR_ReportConfigToAddMod_t));
+       } else {
+         LOG_D(NR_RRC,"Adding Report Configuration %ld %p \n", ind-1, measConfig->reportConfigToAddModList->list.array[i]);
+         if (reportConfig->reportConfig.present == NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR) {
+             NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i];
+         }
+       }
+     }
+   }
 
-      free (ie->nonCriticalExtension->dedicatedNAS_MessageList);
-    }
-  }
-}
+   if (measConfig->measIdToRemoveList != NULL) {
+     for (i = 0; i < measConfig->measIdToRemoveList->list.count; i++) {
+       ind = *measConfig->measIdToRemoveList->list.array[i];
+       free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]);
+     }
+   }
 
-//-----------------------------------------------------------------------------
-void nr_rrc_ue_generate_RRCReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, const uint8_t Transaction_id ) {
-  uint8_t buffer[32], size;
-  size = do_NR_RRCReconfigurationComplete(ctxt_pP, buffer, Transaction_id);
-  LOG_I(NR_RRC,PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d, gNB_index %d)\n",
-        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size, gNB_index);
-  LOG_D(RLC,
-        "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfigurationComplete to gNB %d MUI %d) --->][PDCP][INST %02d][RB %02d]\n",
-        ctxt_pP->frame,
-        UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id),
-        size,
-        gNB_index,
-        nr_rrc_mui,
-        UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id),
-        DCCH);
-#ifdef ITTI_SIM
-  MessageDef *message_p;
-  uint8_t *message_buffer;
-  message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,size);
-  memcpy (message_buffer, buffer, size);
+   if (measConfig->measIdToAddModList != NULL) {
+     for (i = 0; i < measConfig->measIdToAddModList->list.count; i++) {
+       ind = measConfig->measIdToAddModList->list.array[i]->measId;
+
+       if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]) {
+         LOG_D(NR_RRC, "Modifying Measurement ID %ld\n",ind-1);
+         memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1],
+                 (char *)measConfig->measIdToAddModList->list.array[i],
+                 sizeof(NR_MeasIdToAddMod_t));
+       } else {
+         LOG_D(NR_RRC, "Adding Measurement ID %ld %p\n", ind-1, measConfig->measIdToAddModList->list.array[i]);
+         NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i];
+       }
+     }
+   }
 
-  message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
-  UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
-  UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
-  UE_RRC_DCCH_DATA_IND (message_p).size  = size;
-  itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
+   if (measConfig->quantityConfig != NULL) {
+     if (NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index]) {
+       LOG_D(NR_RRC,"Modifying Quantity Configuration \n");
+       memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index],
+	       (char *)measConfig->quantityConfig,
+	       sizeof(NR_QuantityConfig_t));
+     } else {
+       LOG_D(NR_RRC, "Adding Quantity configuration\n");
+       NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index] = measConfig->quantityConfig;
+     }
+   }
 
-#else
-  rrc_data_req_ue (
-    ctxt_pP,
-    DCCH,
-    nr_rrc_mui++,
-    SDU_CONFIRM_NO,
-    size,
-    buffer,
-    PDCP_TRANSMISSION_MODE_CONTROL);
-#endif
+   if (measConfig->measGapConfig != NULL) {
+     if (NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index]) {
+       memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index],
+	       (char *)measConfig->measGapConfig,
+	       sizeof(NR_MeasGapConfig_t));
+     } else {
+       NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index] = measConfig->measGapConfig;
+     }
+   }
 
-}
+   if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_ssb_RSRP) {
+     NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.ssb_RSRP;
+   } else if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_csi_RSRP) {
+     NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.csi_RSRP;
+   }
+ }
 
-// from NR SRB1
-//-----------------------------------------------------------------------------
-int
-nr_rrc_ue_decode_dcch(
-  const protocol_ctxt_t *const ctxt_pP,
-  const srb_id_t               Srb_id,
-  const uint8_t         *const Buffer,
-  const uint8_t                gNB_indexP
-)
-//-----------------------------------------------------------------------------
-{
-  asn_dec_rval_t                      dec_rval;
-  NR_DL_DCCH_Message_t                *dl_dcch_msg  = NULL;
-  MessageDef *msg_p;
+ //-----------------------------------------------------------------------------
+ void
+ nr_sa_rrc_ue_process_radioBearerConfig(
+     const protocol_ctxt_t *const       ctxt_pP,
+     const uint8_t                      gNB_index,
+     NR_RadioBearerConfig_t *const      radioBearerConfig
+ )
+ //-----------------------------------------------------------------------------
+ {
+   long SRB_id, DRB_id;
+   int i, cnt;
+
+   if( radioBearerConfig->srb3_ToRelease != NULL){
+     if( *radioBearerConfig->srb3_ToRelease == TRUE){
+       //TODO (release the PDCP entity and the srb-Identity of the SRB3.)
+     }
+   }
 
-  if (Srb_id != 1) {
-    LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n",
-        ctxt_pP->module_id, ctxt_pP->frame, Srb_id);
-    return -1;
-  } else {
-    LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id);
-  }
+   if (radioBearerConfig->srb_ToAddModList != NULL) {
+     if (radioBearerConfig->securityConfig != NULL) {
+       if (*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master) {
+	      NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm = radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm;
+	      NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm = *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm;
+       }
+     }
+
+     uint8_t *kRRCenc = NULL;
+     uint8_t *kRRCint = NULL;
+     derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
+		     NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc);
+     derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
+		     NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint);
+     // Refresh SRBs
+      nr_rrc_pdcp_config_asn1_req(ctxt_pP,
+                                  radioBearerConfig->srb_ToAddModList,
+                                  NULL,
+                                  NULL,
+                                  NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm |
+                                  (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
+                                  kRRCenc,
+                                  kRRCint,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList);
+     // Refresh SRBs
+      nr_rrc_rlc_config_asn1_req(ctxt_pP,
+                                  radioBearerConfig->srb_ToAddModList,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList
+                                  );
+
+     for (cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) {
+       SRB_id = radioBearerConfig->srb_ToAddModList->list.array[cnt]->srb_Identity;
+       LOG_D(NR_RRC,"[UE %d]: Frame %d SRB config cnt %d (SRB%ld)\n", ctxt_pP->module_id, ctxt_pP->frame, cnt, SRB_id);
+       if (SRB_id == 1) {
+	 if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index]) {
+	   memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index],
+		  radioBearerConfig->srb_ToAddModList->list.array[cnt],
+		  sizeof(NR_SRB_ToAddMod_t));
+	 } else {
+	   NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt];
+	   nr_rrc_ue_establish_srb1(ctxt_pP->module_id,
+				   ctxt_pP->frame,
+				   gNB_index,
+				   radioBearerConfig->srb_ToAddModList->list.array[cnt]);
+
+	   LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB1 gNB %d) --->][MAC_UE][MOD %02d][]\n",
+	       ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
+	   // rrc_mac_config_req_ue
+	 }
+       } else {
+	 if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index]) {
+	   memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index],
+	       radioBearerConfig->srb_ToAddModList->list.array[cnt], sizeof(NR_SRB_ToAddMod_t));
+	 } else {
+	   NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt];
+	   nr_rrc_ue_establish_srb2(ctxt_pP->module_id,
+				   ctxt_pP->frame,
+				   gNB_index,
+				   radioBearerConfig->srb_ToAddModList->list.array[cnt]);
+
+	   LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB2 gNB %d) --->][MAC_UE][MOD %02d][]\n",
+	       ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
+	   // rrc_mac_config_req_ue
+	 }
+       } // srb2
+     }
+   } // srb_ToAddModList
+
+   // Establish DRBs if present
+   if (radioBearerConfig->drb_ToAddModList != NULL) {
+     if ((NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB == NULL) &&
+       (radioBearerConfig->drb_ToAddModList->list.count >= 1)) {
+       NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = malloc(sizeof(rb_id_t));
+       *NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = radioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity;
+     }
+
+     for (cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) {
+       DRB_id = radioBearerConfig->drb_ToAddModList->list.array[cnt]->drb_Identity;
+       if (NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]) {
+	 memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1],
+		 radioBearerConfig->drb_ToAddModList->list.array[cnt], sizeof(NR_DRB_ToAddMod_t));
+       } else {
+	 LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]);
+	 NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1] = radioBearerConfig->drb_ToAddModList->list.array[cnt];
+       }
+     }
+
+     uint8_t *kUPenc = NULL;
+     derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
+		     NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc);
+     MSC_LOG_TX_MESSAGE(
+	 MSC_RRC_UE,
+	 MSC_PDCP_UE,
+	 NULL,
+	 0,
+	 MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security %X)",
+	 MSC_AS_TIME_ARGS(ctxt_pP),
+	 ctxt_pP->rnti,
+	 NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm |
+	 (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4));
+
+       // Refresh DRBs
+       // nr_rrc_pdcp_config_asn1_req(ctxt_pP,
+       //                             NULL,
+       //                             radioBearerConfig->drb_ToAddModList,
+       //                             NULL,
+       //                             NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm |
+       //                             (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
+       //                             NULL,
+       //                             NULL,
+       //                             kUPenc,
+       //                             NULL,
+       //                             NULL,
+       //                             NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB,
+       //                             NULL);
+       // Refresh DRBs
+       // nr_rrc_rlc_config_asn1_req(ctxt_pP,
+       //                             NULL,
+       //                             radioBearerConfig->drb_ToAddModList,
+       //                             NULL,
+       //                             NULL,
+       //                             NULL
+       //                             );
+   } // drb_ToAddModList
+
+   if (radioBearerConfig->drb_ToReleaseList != NULL) {
+     for (i = 0; i < radioBearerConfig->drb_ToReleaseList->list.count; i++) {
+       DRB_id = *radioBearerConfig->drb_ToReleaseList->list.array[i];
+       free(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]);
+     }
+   }
 
-  LOG_D(NR_RRC, "Decoding DL-DCCH Message\n");
-  dec_rval = uper_decode( NULL,
-                          &asn_DEF_NR_DL_DCCH_Message,
-                          (void **)&dl_dcch_msg,
-                          Buffer,
-                          RRC_BUF_SIZE,
-                          0,
-                          0);
+   NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_CONNECTED;
+   LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index);
+ }
 
-  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
-    LOG_E(NR_RRC, "Failed to decode DL-DCCH (%zu bytes)\n", dec_rval.consumed);
-    return -1;
-  }
+ //-----------------------------------------------------------------------------
+ void
+ rrc_ue_process_rrcReconfiguration(
+   const protocol_ctxt_t *const  ctxt_pP,
+   NR_RRCReconfiguration_t       *rrcReconfiguration,
+   uint8_t                       gNB_index
+ )
+ //-----------------------------------------------------------------------------
+ {
+   LOG_I(NR_RRC, "[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCReconfiguration (gNB %d)\n",
+       ctxt_pP->module_id, ctxt_pP->frame, gNB_index);
+
+   NR_RRCReconfiguration_IEs_t *ie = NULL;
+
+   if (rrcReconfiguration->criticalExtensions.present
+		     == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration) {
+     ie = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration;
+     if (ie->measConfig != NULL) {
+       LOG_I(NR_RRC, "Measurement Configuration is present\n");
+ //      nr_rrc_ue_process_measConfig(ctxt_pP, gNB_index, ie->measConfig);
+     }
+
+     if (ie->radioBearerConfig != NULL) {
+       LOG_I(NR_RRC, "radio Bearer Configuration is present\n");
+ //      nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig);
+     }
+
+     /* Check if there is dedicated NAS information to forward to NAS */
+     if (ie->nonCriticalExtension->dedicatedNAS_MessageList != NULL) {
+       int list_count;
+       uint32_t pdu_length;
+       uint8_t *pdu_buffer;
+       MessageDef *msg_p;
+
+       for (list_count = 0; list_count < ie->nonCriticalExtension->dedicatedNAS_MessageList->list.count; list_count++) {
+	 pdu_length = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->size;
+	 pdu_buffer = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->buf;
+	 msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_ESTABLI_CNF);
+	 NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS;
+	 NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length;
+	 NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer;
+	 itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p);
+       }
+
+       free (ie->nonCriticalExtension->dedicatedNAS_MessageList);
+     }
+   }
+ }
 
-  // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
-      xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message,(void *)dl_dcch_msg);
-  // }
-
-    if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) {
-        switch (dl_dcch_msg->message.choice.c1->present) {
-            case NR_DL_DCCH_MessageType__c1_PR_NOTHING:
-                LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n");
-                break;
-
-            case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration:
-            {
-                rrc_ue_process_rrcReconfiguration(ctxt_pP,
-                                                    dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration,
-                                                    gNB_indexP);
-                nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP,
-                                            gNB_indexP,
-                                            dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier);
-
-                if (first_rrcreconfigurationcomplete == 0) {
-                    first_rrcreconfigurationcomplete = 1;
-#ifdef ITTI_SIM
-                  if (AMF_MODE_ENABLED) {
-                    as_nas_info_t initialNasMsg;
-                    memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
-                    generateRegistrationComplete(&initialNasMsg, NULL);
-                    if(initialNasMsg.length > 0){
-                        MessageDef *message_p;
-                        message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_UPLINK_DATA_REQ);
-                        NAS_UPLINK_DATA_REQ(message_p).UEid          = ctxt_pP->module_id;
-                        NAS_UPLINK_DATA_REQ(message_p).nasMsg.data   = (uint8_t *)initialNasMsg.data;
-                        NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
-                        itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
-                        LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
-                    }
-                    as_nas_info_t pduEstablishMsg;
-                    memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
-                    generatePduSessionEstablishRequest(&pduEstablishMsg);
-                    if(initialNasMsg.length > 0){
-                        MessageDef *message_p;
-                        message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_UPLINK_DATA_REQ);
-                        NAS_UPLINK_DATA_REQ(message_p).UEid          = ctxt_pP->module_id;
-                        NAS_UPLINK_DATA_REQ(message_p).nasMsg.data   = (uint8_t *)pduEstablishMsg.data;
-                        NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length;
-                        itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
-                        LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
-                    }
-                  }
-#endif
-                }
-            }
-                break;
-
-            case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
-            case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
-              LOG_I(NR_RRC, "[UE %d] Received RRC Release (gNB %d)\n",
-                      ctxt_pP->module_id, gNB_indexP);
-
-              msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND);
-
-              if((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) &&
-                   (dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){
-                    dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer =
-                    NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5;
-                    dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType =
-                    NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency;
-                }
-
-                 itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
-                 break;
-            case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
-            	LOG_I(NR_RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n",
-            	      ctxt_pP->module_id,gNB_indexP);
-            	nr_rrc_ue_process_ueCapabilityEnquiry(
-            	  ctxt_pP,
-            	  dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry,
-            	  gNB_indexP);
-            	 break;
-            case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
-                LOG_I(NR_RRC,
-                    "[UE%d] Frame %d : Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n",
-                    ctxt_pP->module_id,
-                    ctxt_pP->frame);
-                nr_rrc_ue_generate_rrcReestablishmentComplete(
-                  ctxt_pP,
-                  dl_dcch_msg->message.choice.c1->choice.rrcReestablishment,
-                  gNB_indexP);
-                break;
-            case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
-            {
-                NR_DLInformationTransfer_t *dlInformationTransfer = dl_dcch_msg->message.choice.c1->choice.dlInformationTransfer;
-
-                if (dlInformationTransfer->criticalExtensions.present
-                      == NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) {
-                  /* This message hold a dedicated info NAS payload, forward it to NAS */
-                  NR_DedicatedNAS_Message_t *dedicatedNAS_Message =
-                      dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message;
-                  uint32_t pdu_length;
-                  uint8_t *pdu_buffer;
-                  pdu_length = dedicatedNAS_Message->size;
-                  pdu_buffer = dedicatedNAS_Message->buf;
-#ifdef ITTI_SIM
-                  LOG_I(NR_RRC, "[UE %d] Received %s: UEid %u, length %u , buffer %p\n", ctxt_pP->module_id,  messages_info[NAS_DOWNLINK_DATA_IND].name,
-                        ctxt_pP->module_id, pdu_length, pdu_buffer);
-                  as_nas_info_t initialNasMsg;
-                  uint8_t msg_type = 0;
-                  memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
-                  if((pdu_buffer + 1) != NULL){
-                    if (*(pdu_buffer + 1) > 0 ) {
-                      msg_type = *(pdu_buffer + 9);
-                    } else {
-                      msg_type = *(pdu_buffer + 2);
-                    }
-                  }
-                  if((pdu_buffer + 2) == NULL){
-                    LOG_W(NR_RRC, "[UE] Received invalid downlink message\n");
-                    return 0;
-                  }
-
-                  switch(msg_type){
-                    case FGS_IDENTITY_REQUEST:
-                       generateIdentityResponse(&initialNasMsg,*(pdu_buffer+3));
-                       break;
-                    case FGS_AUTHENTICATION_REQUEST:
-                       generateAuthenticationResp(&initialNasMsg, pdu_buffer);
-                       break;
-                    case FGS_SECURITY_MODE_COMMAND:
-                      generateSecurityModeComplete(&initialNasMsg);
-                      break;
-                    default:
-                       LOG_W(NR_RRC,"unknow message type %d\n",msg_type);
-                       break;
-                  }
-                  if(initialNasMsg.length > 0){
-                    MessageDef *message_p;
-                    message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_UPLINK_DATA_REQ);
-                    NAS_UPLINK_DATA_REQ(message_p).UEid          = ctxt_pP->module_id;
-                    NAS_UPLINK_DATA_REQ(message_p).nasMsg.data   = (uint8_t *)initialNasMsg.data;
-                    NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
-                    itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
-                    LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message\n");
-                  }
-#else
-                  MessageDef *msg_p;
-                  msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_DOWNLINK_DATA_IND);
-                  NAS_DOWNLINK_DATA_IND(msg_p).UEid = ctxt_pP->module_id; // TODO set the UEid to something else ?
-                  NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length = pdu_length;
-                  NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = pdu_buffer;
-                  itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
-#endif
-              }
-            }
+ //-----------------------------------------------------------------------------
+ void nr_rrc_ue_generate_RRCReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, const uint8_t Transaction_id ) {
+   uint8_t buffer[32], size;
+   size = do_NR_RRCReconfigurationComplete(ctxt_pP, buffer, Transaction_id);
+   LOG_I(NR_RRC,PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d, gNB_index %d)\n",
+	 PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size, gNB_index);
+   LOG_D(RLC,
+	 "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfigurationComplete to gNB %d MUI %d) --->][PDCP][INST %02d][RB %02d]\n",
+	 ctxt_pP->frame,
+	 UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id),
+	 size,
+	 gNB_index,
+	 nr_rrc_mui,
+	 UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id),
+	 DCCH);
+ #ifdef ITTI_SIM
+   MessageDef *message_p;
+   uint8_t *message_buffer;
+   message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,size);
+   memcpy (message_buffer, buffer, size);
+
+   message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
+   UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
+   UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
+   UE_RRC_DCCH_DATA_IND (message_p).size  = size;
+   itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
+
+ #else
+   rrc_data_req_ue (
+     ctxt_pP,
+     DCCH,
+     nr_rrc_mui++,
+     SDU_CONFIRM_NO,
+     size,
+     buffer,
+     PDCP_TRANSMISSION_MODE_CONTROL);
+ #endif
 
-              break;
-            case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand:
-            case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16:
-            case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16:
-            case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16:
-            case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16:
-            case NR_DL_DCCH_MessageType__c1_PR_spare3:
-            case NR_DL_DCCH_MessageType__c1_PR_spare2:
-            case NR_DL_DCCH_MessageType__c1_PR_spare1:
-            case NR_DL_DCCH_MessageType__c1_PR_counterCheck:
-                break;
-            case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
-                LOG_I(NR_RRC, "[UE %d] Received securityModeCommand (gNB %d)\n",
-                      ctxt_pP->module_id, gNB_indexP);
-                nr_rrc_ue_process_securityModeCommand(
-                    ctxt_pP,
-                    dl_dcch_msg->message.choice.c1->choice.securityModeCommand,
-                    gNB_indexP);
-
-                break;
-        }
-    }
-  return 0;
-}
+ }
 
-//-----------------------------------------------------------------------------
-void *rrc_nrue_task( void *args_p ) {
-  MessageDef   *msg_p;
-  instance_t    instance;
-  unsigned int  ue_mod_id;
-  int           result;
-  NR_SRB_INFO   *srb_info_p;
-  protocol_ctxt_t  ctxt;
-  itti_mark_task_ready (TASK_RRC_NRUE);
-
-  while(1) {
-    // Wait for a message
-    itti_receive_msg (TASK_RRC_NRUE, &msg_p);
-    instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p);
-    ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance);
-
-    switch (ITTI_MSG_ID(msg_p)) {
-      case TERMINATE_MESSAGE:
-        LOG_W(NR_RRC, " *** Exiting RRC thread\n");
-        itti_exit_task ();
-        break;
+ // from NR SRB1
+ //-----------------------------------------------------------------------------
+ int
+ nr_rrc_ue_decode_dcch(
+   const protocol_ctxt_t *const ctxt_pP,
+   const srb_id_t               Srb_id,
+   const uint8_t         *const Buffer,
+   const uint8_t                gNB_indexP
+ )
+ //-----------------------------------------------------------------------------
+ {
+   asn_dec_rval_t                      dec_rval;
+   NR_DL_DCCH_Message_t                *dl_dcch_msg  = NULL;
+   MessageDef *msg_p;
+
+   if (Srb_id != 1) {
+     LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n",
+	 ctxt_pP->module_id, ctxt_pP->frame, Srb_id);
+     return -1;
+   } else {
+     LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id);
+   }
 
-      case MESSAGE_TEST:
-        LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
-        break;
+   LOG_D(NR_RRC, "Decoding DL-DCCH Message\n");
+   dec_rval = uper_decode( NULL,
+			   &asn_DEF_NR_DL_DCCH_Message,
+			   (void **)&dl_dcch_msg,
+			   Buffer,
+			   RRC_BUF_SIZE,
+			   0,
+			   0);
+
+   if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
+     LOG_E(NR_RRC, "Failed to decode DL-DCCH (%zu bytes)\n", dec_rval.consumed);
+     return -1;
+   }
 
-      case NR_RRC_MAC_BCCH_DATA_IND:
-        LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p),
-              NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
-        PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
-        nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message (ctxt.module_id,
-                                   NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index,
-                                   NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu,
-                                   NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size,
-                                   NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrq,
-                                   NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrp);
-        break;
+   // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+       xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message,(void *)dl_dcch_msg);
+   // }
+
+     if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) {
+	 switch (dl_dcch_msg->message.choice.c1->present) {
+	     case NR_DL_DCCH_MessageType__c1_PR_NOTHING:
+		 LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n");
+		 break;
+
+	     case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration:
+	     {
+	       rrc_ue_process_rrcReconfiguration(ctxt_pP,
+						   dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration,
+						   gNB_indexP);
+	       nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP,
+					   gNB_indexP,
+					   dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier);
+	       break;
+	     }
+
+	     case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
+	     case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
+	       LOG_I(NR_RRC, "[UE %d] Received RRC Release (gNB %d)\n",
+		       ctxt_pP->module_id, gNB_indexP);
+
+	       msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND);
+
+	       if((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) &&
+		    (dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){
+		     dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer =
+		     NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5;
+		     dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType =
+		     NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency;
+		 }
+
+		  itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
+		  break;
+	     case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
+         LOG_I(NR_RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n", ctxt_pP->module_id,gNB_indexP);
+         nr_rrc_ue_process_ueCapabilityEnquiry(
+           ctxt_pP,
+           dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry,
+           gNB_indexP);
+         break;
+	     case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
+         LOG_I(NR_RRC,
+             "[UE%d] Frame %d : Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n",
+             ctxt_pP->module_id,
+             ctxt_pP->frame);
+         nr_rrc_ue_generate_rrcReestablishmentComplete(
+           ctxt_pP,
+           dl_dcch_msg->message.choice.c1->choice.rrcReestablishment,
+           gNB_indexP);
+		     break;
+	     case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
+	     {
+         NR_DLInformationTransfer_t *dlInformationTransfer = dl_dcch_msg->message.choice.c1->choice.dlInformationTransfer;
+
+         if (dlInformationTransfer->criticalExtensions.present
+               == NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) {
+               /* This message hold a dedicated info NAS payload, forward it to NAS */
+               NR_DedicatedNAS_Message_t *dedicatedNAS_Message =
+                   dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message;
+
+               MessageDef *msg_p;
+               msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_DOWNLINK_DATA_IND);
+               NAS_DOWNLINK_DATA_IND(msg_p).UEid = ctxt_pP->module_id; // TODO set the UEid to something else ?
+               NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length = dedicatedNAS_Message->size;
+               NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = dedicatedNAS_Message->buf;
+               itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p);
+             }
+	     }
+
+	       break;
+	     case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand:
+	     case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16:
+	     case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16:
+	     case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16:
+	     case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16:
+	     case NR_DL_DCCH_MessageType__c1_PR_spare3:
+	     case NR_DL_DCCH_MessageType__c1_PR_spare2:
+	     case NR_DL_DCCH_MessageType__c1_PR_spare1:
+	     case NR_DL_DCCH_MessageType__c1_PR_counterCheck:
+		 break;
+	     case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
+         LOG_I(NR_RRC, "[UE %d] Received securityModeCommand (gNB %d)\n",
+               ctxt_pP->module_id, gNB_indexP);
+         nr_rrc_ue_process_securityModeCommand(
+             ctxt_pP,
+             dl_dcch_msg->message.choice.c1->choice.securityModeCommand,
+             gNB_indexP);
+
+         break;
+	    }
+     }
+   return 0;
+ }
 
-      case NR_RRC_MAC_CCCH_DATA_IND:
-        LOG_D(NR_RRC, "[UE %d] RNTI %x Received %s: frameP %d, gNB %d\n",
-              ue_mod_id,
-              NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti,
-              ITTI_MSG_NAME (msg_p),
-              NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame,
-              NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
-        srb_info_p = &NR_UE_rrc_inst[ue_mod_id].Srb0[NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index];
-        memcpy (srb_info_p->Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu,
-                NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size);
-        srb_info_p->Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size;
-        PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0);
-        // PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
-        nr_rrc_ue_decode_ccch (&ctxt,
-                            srb_info_p,
-                            NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
-        break;
+ //-----------------------------------------------------------------------------
+ void *rrc_nrue_task( void *args_p ) {
+   MessageDef   *msg_p;
+   instance_t    instance;
+   unsigned int  ue_mod_id;
+   int           result;
+   NR_SRB_INFO   *srb_info_p;
+   protocol_ctxt_t  ctxt;
+   itti_mark_task_ready (TASK_RRC_NRUE);
+
+   while(1) {
+     // Wait for a message
+     itti_receive_msg (TASK_RRC_NRUE, &msg_p);
+     instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p);
+     ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance);
+
+     switch (ITTI_MSG_ID(msg_p)) {
+       case TERMINATE_MESSAGE:
+         LOG_W(NR_RRC, " *** Exiting RRC thread\n");
+         itti_exit_task ();
+         break;
+
+       case MESSAGE_TEST:
+         LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
+         break;
+
+       case NR_RRC_MAC_BCCH_DATA_IND:
+         LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p),
+               NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
+         PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
+         nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message (ctxt.module_id,
+                  NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index,
+                  NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu,
+                  NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size,
+                  NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrq,
+                  NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrp);
+         break;
+
+       case NR_RRC_MAC_CCCH_DATA_IND:
+         LOG_D(NR_RRC, "[UE %d] RNTI %x Received %s: frameP %d, gNB %d\n",
+               ue_mod_id,
+               NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti,
+               ITTI_MSG_NAME (msg_p),
+               NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame,
+               NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
+         srb_info_p = &NR_UE_rrc_inst[ue_mod_id].Srb0[NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index];
+         memcpy (srb_info_p->Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu,
+           NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size);
+         srb_info_p->Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size;
+         PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0);
+              // PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
+              nr_rrc_ue_decode_ccch (&ctxt,
+                                  srb_info_p,
+                                  NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
+         break;
 
       /* PDCP messages */
       case NR_RRC_DCCH_DATA_IND:
diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h
index f4ce4746573b5e7e93a0805b88ec269fd81c9fa5..e417b9f0b478130a8cfc78a57dcd680b7572b75f 100644
--- a/openair2/RRC/NR_UE/rrc_defs.h
+++ b/openair2/RRC/NR_UE/rrc_defs.h
@@ -105,6 +105,9 @@ typedef struct NR_UE_RRC_INST_s {
 
     NR_MeasConfig_t        *meas_config;
     NR_CellGroupConfig_t   *cell_group_config;
+    NR_CellGroupConfig_t   *scell_group_config;
+    NR_ServingCellConfigCommonSIB_t *servingCellConfigCommonSIB;
+
     NR_RadioBearerConfig_t *radio_bearer_config;
 
     NR_MeasObjectToAddMod_t        *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ];
@@ -123,7 +126,7 @@ typedef struct NR_UE_RRC_INST_s {
     NR_SRB_INFO_TABLE_ENTRY        Srb2[NB_CNX_UE];
 
     uint8_t                        MBMS_flag;
-	  OAI_NR_UECapability_t          *UECap;
+    OAI_NR_UECapability_t          *UECap;
     uint8_t 					             *UECapability;
     uint8_t                        UECapability_size;
 
@@ -209,7 +212,7 @@ typedef struct NR_UE_RRC_INST_s {
     long               selected_plmn_identity;
     Rrc_State_NR_t     nrRrcState;
     Rrc_Sub_State_NR_t nrRrcSubState;
-	as_nas_info_t      initialNasMsg;
+    as_nas_info_t      initialNasMsg;
 } NR_UE_RRC_INST_t;
 
 #endif
diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c
index 82906b45f867aff2a6fa4225ee071c487f26dee6..0cd022217db1a75d94ef2a67cfd333c58491c509 100644
--- a/openair2/SIMULATION/NR_RRC/itti_sim.c
+++ b/openair2/SIMULATION/NR_RRC/itti_sim.c
@@ -83,6 +83,9 @@ unsigned short config_frames[4] = {2,9,11,13};
 #include "openair3/NAS/UE/nas_ue_task.h"
 #include <executables/split_headers.h>
 #include <executables/nr-uesoftmodem.h>
+#if ITTI_SIM
+#include "nr_nas_msg_sim.h"
+#endif
 
 pthread_cond_t nfapi_sync_cond;
 pthread_mutex_t nfapi_sync_mutex;
@@ -412,6 +415,12 @@ int create_tasks_nrue(uint32_t ue_nb) {
       LOG_E(NR_RRC, "Create task for RRC UE failed\n");
       return -1;
     }
+
+    LOG_D(NR_RRC,"create TASK_NAS_NRUE\n");
+    if (itti_create_task (TASK_NAS_NRUE, nas_nrue_task, NULL) < 0) {
+      LOG_E(NR_RRC, "Create task for NAS UE failed\n");
+      return -1;
+    }
   }
 
 
@@ -579,8 +588,14 @@ int main( int argc, char **argv )
     init_pdcp();
 
   if (RC.nb_nr_inst > 0)  {
+    nr_read_config_and_init();
     // don't create if node doesn't connect to RRC/S1/GTP
     AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n");
+    for (int gnb_id = 0; gnb_id < RC.nb_nr_inst; gnb_id++) {
+      MessageDef *msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NRRRC_CONFIGURATION_REQ);
+      NRRRC_CONFIGURATION_REQ(msg_p) = RC.nrrrc[gnb_id]->configuration;
+      itti_send_msg_to_task (TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
+    }
   } else {
     printf("No ITTI, Initializing L1\n");
     return 0;
diff --git a/openair3/GTPV1-U/gtpv1u_gNB.c b/openair3/GTPV1-U/gtpv1u_gNB.c
index 19d2440a95f69c537c7810e65c21301652485098..d3f26aeff11dce59553b8457263ca1003bcf1c58 100644
--- a/openair3/GTPV1-U/gtpv1u_gNB.c
+++ b/openair3/GTPV1-U/gtpv1u_gNB.c
@@ -52,6 +52,9 @@
 
 #undef GTP_DUMP_SOCKET
 
+#undef GTPV1U_BEARER_OFFSET
+#define GTPV1U_BEARER_OFFSET 1
+
 extern unsigned char NB_eNB_INST;
 
 extern RAN_CONTEXT_t RC;
@@ -309,6 +312,106 @@ void *gtpv1u_gNB_task(void *args) {
   return NULL;
 }
 
+/* Callback called when a gtpv1u message arrived on UDP interface */
+NwGtpv1uRcT nr_gtpv1u_gNB_process_stack_req(
+  NwGtpv1uUlpHandleT hUlp,
+  NwGtpv1uUlpApiT   *pUlpApi) {
+  boolean_t              result             = FALSE;
+  teid_t                 teid               = 0;
+  hashtable_rc_t         hash_rc            = HASH_TABLE_KEY_NOT_EXISTS;
+  nr_gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
+  protocol_ctxt_t        ctxt;
+  NwGtpv1uRcT            rc;
+
+  switch(pUlpApi->apiType) {
+    /* Here there are two type of messages handled:
+     * - T-PDU
+     * - END-MARKER
+     */
+    case NW_GTPV1U_ULP_API_RECV_TPDU: {
+      uint8_t              buffer[4096];
+      uint32_t             buffer_len;
+      //uint16_t             msgType = NW_GTP_GPDU;
+      //NwGtpv1uMsgT     *pMsg = NULL;
+      /* Nw-gptv1u stack has processed a PDU. we can schedule it to PDCP
+       * for transmission.
+       */
+      teid = pUlpApi->apiInfo.recvMsgInfo.teid;
+      //pMsg = (NwGtpv1uMsgT *) pUlpApi->apiInfo.recvMsgInfo.hMsg;
+      //msgType = pMsg->msgType;
+
+      if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg,
+                                             buffer, &buffer_len)) {
+        LOG_E(GTPU, "Error while retrieving T-PDU");
+      }
+
+      itti_free(TASK_UDP, ((NwGtpv1uMsgT *)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBuf);
+#if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0
+      gtpv1u_eNB_write_dump_socket(buffer,buffer_len);
+#endif
+      rc = nwGtpv1uMsgDelete(RC.nr_gtpv1u_data_g->gtpv1u_stack,
+                             pUlpApi->apiInfo.recvMsgInfo.hMsg);
+
+      if (rc != NW_GTPV1U_OK) {
+        LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc);
+      }
+
+      hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->teid_mapping, teid, (void **)&gtpv1u_teid_data_p);
+
+      if (hash_rc == HASH_TABLE_OK) {
+// #if defined(LOG_GTPU) && LOG_GTPU > 0
+        LOG_D(GTPU, "Received T-PDU from gtpv1u stack teid  %u size %d -> gnb module id %u ue module id %u pdu session id %u\n",
+              teid,
+              buffer_len,
+              gtpv1u_teid_data_p->gnb_id,
+              gtpv1u_teid_data_p->ue_id,
+              gtpv1u_teid_data_p->pdu_session_id);
+// #endif
+        //warning "LG eps bearer mapping to DRB id to do (offset -4)"
+        PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, gtpv1u_teid_data_p->gnb_id, GNB_FLAG_YES,  gtpv1u_teid_data_p->ue_id, 0, 0,gtpv1u_teid_data_p->gnb_id);
+        // MSC_LOG_TX_MESSAGE(
+        //   MSC_GTPU_ENB,
+        //   MSC_PDCP_ENB,
+        //   NULL,0,
+        //   MSC_AS_TIME_FMT" DATA-REQ rb %u size %u",
+        //   0,0,
+        //   (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4,
+        //   buffer_len);
+
+        result = pdcp_data_req(
+                   &ctxt,
+                   SRB_FLAG_NO,
+                   1,
+                   0, // mui
+                   SDU_CONFIRM_NO, // confirm
+                   buffer_len,
+                   buffer,
+                   PDCP_TRANSMISSION_MODE_DATA,NULL, NULL
+                 );
+
+        if ( result == FALSE ) {
+          if (ctxt.configured == FALSE )
+            LOG_W(GTPU, "gNB node PDCP data request failed, cause: [UE:%x]RB is not configured!\n", ctxt.rnti) ;
+          else
+            LOG_W(GTPU, "PDCP data request failed\n");
+
+          return NW_GTPV1U_FAILURE;
+        }
+      } else {
+        LOG_W(GTPU, "Received T-PDU from gtpv1u stack teid %u unknown size %u", teid, buffer_len);
+      }
+    }
+    break;
+
+    default: {
+      LOG_E(GTPU, "Received undefined UlpApi (%02x) from gtpv1u stack!\n",
+            pUlpApi->apiType);
+    }
+  } // end of switch
+
+  return NW_GTPV1U_OK;
+}
+
 int nr_gtpv1u_gNB_init(void) {
   NwGtpv1uRcT             rc = NW_GTPV1U_FAILURE;
   NwGtpv1uUlpEntityT      ulp;
@@ -344,7 +447,7 @@ int nr_gtpv1u_gNB_init(void) {
   /* Set the ULP API callback. Called once message have been processed by the
    * nw-gtpv1u stack.
    */
-  ulp.ulpReqCallback = gtpv1u_gNB_process_stack_req;
+  ulp.ulpReqCallback = nr_gtpv1u_gNB_process_stack_req;
   memset((void *)&(ulp.hUlp), 0, sizeof(NwGtpv1uUlpHandleT));
 
   if ((rc = nwGtpv1uSetUlpEntity(RC.nr_gtpv1u_data_g->gtpv1u_stack, &ulp)) != NW_GTPV1U_OK) {
@@ -751,6 +854,81 @@ static int gtpv1u_ng_req(
   return 0;
 }
 
+static int gtpv1u_gnb_tunnel_data_req(gtpv1u_gnb_tunnel_data_req_t *gnb_tunnel_data_req) {
+  gtpv1u_gnb_tunnel_data_req_t *data_req_p           = NULL;
+  NwGtpv1uUlpApiT               stack_req;
+  NwGtpv1uRcT                   rc                   = NW_GTPV1U_FAILURE;
+  hashtable_rc_t                hash_rc              = HASH_TABLE_KEY_NOT_EXISTS;
+  nr_gtpv1u_ue_data_t          *gtpv1u_ue_data_p     = NULL;
+  teid_t                        gnb_ngu_teid         = 0;
+  teid_t                        upf_ngu_teid         = 0;
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_IN);
+  data_req_p = gnb_tunnel_data_req;
+
+  memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT));
+  hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->ue_mapping, (uint64_t)data_req_p->rnti, (void **)&gtpv1u_ue_data_p);
+
+  if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) {
+    LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: while getting ue rnti %x in hashtable ue_mapping\n", data_req_p->rnti);
+  } else {
+    if ((data_req_p->pdusession_id >= GTPV1U_BEARER_OFFSET) && (data_req_p->pdusession_id < max_val_NR_DRB_Identity)) {
+      gnb_ngu_teid                        = gtpv1u_ue_data_p->bearers[data_req_p->pdusession_id - GTPV1U_BEARER_OFFSET].teid_gNB;
+      upf_ngu_teid                        = gtpv1u_ue_data_p->bearers[data_req_p->pdusession_id - GTPV1U_BEARER_OFFSET].teid_upf;
+      stack_req.apiType                   = NW_GTPV1U_ULP_API_SEND_TPDU;
+      stack_req.apiInfo.sendtoInfo.teid   = upf_ngu_teid;
+      stack_req.apiInfo.sendtoInfo.ipAddr = gtpv1u_ue_data_p->bearers[data_req_p->pdusession_id - GTPV1U_BEARER_OFFSET].upf_ip_addr;
+      rc = nwGtpv1uGpduMsgNew(
+              RC.nr_gtpv1u_data_g->gtpv1u_stack,
+              upf_ngu_teid,
+              NW_FALSE,
+              RC.nr_gtpv1u_data_g->seq_num++,
+              data_req_p->buffer,
+              data_req_p->length,
+              data_req_p->offset,
+              &(stack_req.apiInfo.sendtoInfo.hMsg));
+
+      if (rc != NW_GTPV1U_OK) {
+        LOG_E(GTPU, "nwGtpv1uGpduMsgNew failed: 0x%x\n", rc);
+        MSC_LOG_EVENT(MSC_GTPU_GNB,"0 Failed send G-PDU ltid %u rtid %u size %u",
+                      gnb_ngu_teid,upf_ngu_teid,data_req_p->length);
+        (void)gnb_ngu_teid; /* avoid gcc warning "set but not used" */
+      } else {
+        rc = nwGtpv1uProcessUlpReq(RC.nr_gtpv1u_data_g->gtpv1u_stack, &stack_req);
+
+        if (rc != NW_GTPV1U_OK) {
+          LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: 0x%x\n", rc);
+          MSC_LOG_EVENT(MSC_GTPU_GNB,"0 Failed send G-PDU ltid %u rtid %u size %u",
+                        gnb_ngu_teid,upf_ngu_teid,data_req_p->length);
+        } else {
+          MSC_LOG_TX_MESSAGE(
+            MSC_GTPU_GNB,
+            MSC_GTPU_SGW,
+            NULL,
+            0,
+            MSC_AS_TIME_FMT" G-PDU ltid %u rtid %u size %u",
+            0,0,
+            gnb_ngu_teid,
+            upf_ngu_teid,
+            data_req_p->length);
+        }
+
+        rc = nwGtpv1uMsgDelete(RC.nr_gtpv1u_data_g->gtpv1u_stack,
+                                stack_req.apiInfo.sendtoInfo.hMsg);
+
+        if (rc != NW_GTPV1U_OK) {
+          LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc);
+        }
+      }
+    }
+  }
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_OUT);
+  /* Buffer still needed, do not free it */
+  //itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), data_req_p->buffer);
+
+  return 0;
+}
+
 //-----------------------------------------------------------------------------
 void *gtpv1u_gNB_process_itti_msg(void *notUsed) {
   /* Trying to fetch a message from the message queue.
@@ -774,6 +952,24 @@ void *gtpv1u_gNB_process_itti_msg(void *notUsed) {
       gtpv1u_delete_ngu_tunnel(instance, &received_message_p->ittiMsg.NRGtpv1uDeleteTunnelReq);
       break;
 
+    // DATA COMING FROM UDP
+    case UDP_DATA_IND: {
+      udp_data_ind_t *udp_data_ind_p;
+      udp_data_ind_p = &received_message_p->ittiMsg.udp_data_ind;
+      nwGtpv1uProcessUdpReq(RC.nr_gtpv1u_data_g->gtpv1u_stack,
+                            udp_data_ind_p->buffer,
+                            udp_data_ind_p->buffer_length,
+                            udp_data_ind_p->peer_port,
+                            udp_data_ind_p->peer_address);
+    }
+    break;
+
+    // DATA TO BE SENT TO UDP
+    case GTPV1U_GNB_TUNNEL_DATA_REQ:
+      LOG_I(GTPU, "Received message %s\n", ITTI_MSG_NAME(received_message_p));
+      gtpv1u_gnb_tunnel_data_req(&GTPV1U_GNB_TUNNEL_DATA_REQ(received_message_p));
+      break;
+
     case TERMINATE_MESSAGE: {
       if (RC.nr_gtpv1u_data_g->ue_mapping != NULL) {
         hashtable_destroy (&(RC.nr_gtpv1u_data_g->ue_mapping));
diff --git a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c
index 0c7663921b71dbd85c74323715c30ab19b316995..0d962cad7d5d1b11450939a87a67d3c3391f5f1b 100644
--- a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c
+++ b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c
@@ -59,6 +59,7 @@
 extern "C" {
 #endif
 
+//#define LOG_GTPU 1
 /*--------------------------------------------------------------------------*
  *                    P R I V A T E    F U N C T I O N S                    *
  *--------------------------------------------------------------------------*/
@@ -900,7 +901,7 @@ nwGtpv1uProcessUdpReq( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
   case NW_GTP_END_MARKER:
 #if defined(LOG_GTPU) && LOG_GTPU > 0
     for(int i =1; i<= udpDataLen; i++){
-      printf("%02x ", udpData[i-1]);
+      printf("%02x ", (uint8_t)udpData[i-1]);
       if(i % 20 == 0)printf("\n");
     }
 #endif  	
diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.c b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.c
index bc4d34d6503cf42d080e64f65f579fff508d3af1..1c9198b7204689cbc2288da98ec07628f4379362 100644
--- a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.c
+++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.c
@@ -54,6 +54,8 @@ int encode_pdu_session_establishment_request(pdu_session_establishment_request_m
   encoded++;
 
   IES_ENCODE_U16(buffer, encoded, pdusessionestablishrequest->maxdatarate);
+  *(buffer + encoded) = pdusessionestablishrequest->pdusessiontype;
+  encoded++;
 
   return encoded;
 }
diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.h b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.h
index ac5b250f66d5c158b5d457d5fea8b8b040e2599f..e2742ebc386c6e077531f259f0a34ee36d0dea9f 100644
--- a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.h
+++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.h
@@ -53,6 +53,7 @@ typedef struct pdu_session_establishment_request_msg_tag {
     uint8_t                                 pti;
     MessageType                             pdusessionestblishmsgtype;
     uint16_t                                maxdatarate;
+    uint8_t                                 pdusessiontype;
     /* Optional fields */
 } pdu_session_establishment_request_msg;
 
diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c
index 2c07de8dd5abfea1d460c0f0b09d5d672a724f80..55e21390bfe2f49f2e4e2de9276cc571a914a409 100644
--- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c
+++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c
@@ -38,12 +38,21 @@
 #include "aka_functions.h"
 #include "secu_defs.h"
 #include "PduSessionEstablishRequest.h"
-char netName[] = "5G:mnc093.mcc208.3gppnetwork.org";
+# include "intertask_interface.h"
+
+/*char netName[] = "5G:mnc093.mcc208.3gppnetwork.org";
 char imsi[] = "2089300007487";
 // USIM_API_K: 5122250214c33e723a5dd523fc145fc0
 uint8_t k[16] = {0x51, 0x22, 0x25, 0x02, 0x14,0xc3, 0x3e, 0x72, 0x3a, 0x5d, 0xd5, 0x23, 0xfc, 0x14, 0x5f, 0xc0};
 // OPC: 981d464c7c52eb6e5036234984ad0bcf
-const uint8_t opc[16] = {0x98, 0x1d, 0x46, 0x4c,0x7c,0x52,0xeb, 0x6e, 0x50, 0x36, 0x23, 0x49, 0x84, 0xad, 0x0b, 0xcf};
+const uint8_t opc[16] = {0x98, 0x1d, 0x46, 0x4c,0x7c,0x52,0xeb, 0x6e, 0x50, 0x36, 0x23, 0x49, 0x84, 0xad, 0x0b, 0xcf};*/
+
+char netName[] = "5G:mnc099.mcc208.3gppnetwork.org";
+char imsi[] = "2089900007487"; //"208990100001100";
+// USIM_API_K: fe c8 6b a6 eb 70 7e d0 89 05 75 7b 1b b4 4b 8f 
+uint8_t k[16] = {0xfe, 0xc8, 0x6b, 0xa6, 0xeb, 0x70, 0x7e, 0xd0, 0x89, 0x05, 0x75, 0x7b, 0x1b, 0xb4, 0x4b, 0x8f};
+// OPC: c4 24 49 36 3b ba d0 2b 66 d1 6b c9 75 d7 7c c1
+const uint8_t opc[16] = {0xc4, 0x24, 0x49, 0x36, 0x3b, 0xba, 0xd0, 0x2b, 0x66, 0xd1, 0x6b, 0xc9, 0x75, 0xd7, 0x7c, 0xc1};
 
 uint8_t  *registration_request_buf;
 uint32_t  registration_request_len;
@@ -273,14 +282,14 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
   mm_msg->registration_request.fgsregistrationtype = INITIAL_REGISTRATION;
   mm_msg->registration_request.naskeysetidentifier.naskeysetidentifier = 1;
   size += 1;
-  if(1){
+  if(0){
     mm_msg->registration_request.fgsmobileidentity.guti.typeofidentity = FGS_MOBILE_IDENTITY_5G_GUTI;
     mm_msg->registration_request.fgsmobileidentity.guti.amfregionid = 0xca;
     mm_msg->registration_request.fgsmobileidentity.guti.amfpointer = 0;
     mm_msg->registration_request.fgsmobileidentity.guti.amfsetid = 1016;
     mm_msg->registration_request.fgsmobileidentity.guti.tmsi = 10;
     mm_msg->registration_request.fgsmobileidentity.guti.mncdigit1 = 9;
-    mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 = 3;
+    mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 = 9;
     mm_msg->registration_request.fgsmobileidentity.guti.mncdigit3 = 0xf;
     mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = 2;
     mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = 0;
@@ -291,7 +300,7 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
   } else {
     mm_msg->registration_request.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI;
     mm_msg->registration_request.fgsmobileidentity.suci.mncdigit1 = 9;
-    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit2 = 3;
+    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit2 = 9;
     mm_msg->registration_request.fgsmobileidentity.suci.mncdigit3 = 0xf;
     mm_msg->registration_request.fgsmobileidentity.suci.mccdigit1 = 2;
     mm_msg->registration_request.fgsmobileidentity.suci.mccdigit2 = 0;
@@ -348,7 +357,7 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
   if(identitytype == FGS_MOBILE_IDENTITY_SUCI){
     mm_msg->fgs_identity_response.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI;
     mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit1 = 9;
-    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit2 = 3;
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit2 = 9;
     mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit3 = 0xf;
     mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit1 = 2;
     mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit2 = 0;
@@ -612,14 +621,15 @@ void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){
   memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
 
   // setup pdu session establishment request
-  uint16_t req_length = 6;
+  uint16_t req_length = 7;
   uint8_t *req_buffer = malloc(req_length);
   pdu_session_establishment_request_msg pdu_session_establish;
   pdu_session_establish.protocoldiscriminator = FGS_SESSION_MANAGEMENT_MESSAGE;
   pdu_session_establish.pdusessionid = 10;
-  pdu_session_establish.pti = 0;
+  pdu_session_establish.pti = 1;
   pdu_session_establish.pdusessionestblishmsgtype = FGS_PDU_SESSION_ESTABLISHMENT_REQ;
   pdu_session_establish.maxdatarate = 0xffff;
+  pdu_session_establish.pdusessiontype = 0x91;
   encode_pdu_session_establishment_request(&pdu_session_establish, req_buffer);
 
 
@@ -627,9 +637,8 @@ void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){
   MM_msg *mm_msg;
   nas_stream_cipher_t stream_cipher;
   uint8_t             mac[4];
-  uint8_t             nssai[]={1,1,2,3};
-  uint8_t             dnn[9]={0x8,0x69,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74};
-  // set security protected header
+  uint8_t             nssai[]={1,0,0,1}; //Corresponding to SST:1, SD:1
+  uint8_t            dnn[4]={0x4,0x6f,0x61,0x69}; //Corresponding to dnn:"oai"
   nas_msg.header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
   nas_msg.header.security_header_type = INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX;
   size += 7;
@@ -661,9 +670,9 @@ void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){
   mm_msg->uplink_nas_transport.snssai.length = 4;
   mm_msg->uplink_nas_transport.snssai.value = nssai;
   size += (1+1+4);
-  mm_msg->uplink_nas_transport.dnn.length = 9;
+  mm_msg->uplink_nas_transport.dnn.length = 4;
   mm_msg->uplink_nas_transport.dnn.value = dnn;
-  size += (1+1+9);
+  size += (1+1+4);
 
   // encode the message
   initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
@@ -690,3 +699,199 @@ void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){
      initialNasMsg->data[2+i] = mac[i];
   }
 }
+
+void *nas_nrue_task(void *args_p)
+{
+  MessageDef           *msg_p;
+  instance_t            instance;
+  unsigned int          Mod_id;
+  int                   result;
+  uint8_t               msg_type = 0;
+  uint8_t              *pdu_buffer = NULL;
+
+  itti_mark_task_ready (TASK_NAS_NRUE);
+  MSC_START_USE();
+  
+  while(1) {
+    // Wait for a message or an event
+    itti_receive_msg (TASK_NAS_NRUE, &msg_p);
+
+    if (msg_p != NULL) {
+      instance = msg_p->ittiMsgHeader.originInstance;
+      Mod_id = instance ;
+      if (instance == INSTANCE_DEFAULT) {
+        printf("%s:%d: FATAL: instance is INSTANCE_DEFAULT, should not happen.\n",
+               __FILE__, __LINE__);
+        exit_fun("exit... \n");
+      }
+
+      switch (ITTI_MSG_ID(msg_p)) {
+      case INITIALIZE_MESSAGE:
+        LOG_I(NAS, "[UE %d] Received %s\n", Mod_id,  ITTI_MSG_NAME (msg_p));
+
+        break;
+
+      case TERMINATE_MESSAGE:
+        itti_exit_task ();
+        break;
+
+      case MESSAGE_TEST:
+        LOG_I(NAS, "[UE %d] Received %s\n", Mod_id,  ITTI_MSG_NAME (msg_p));
+        break;
+
+      case NAS_CELL_SELECTION_CNF:
+        LOG_I(NAS, "[UE %d] Received %s: errCode %u, cellID %u, tac %u\n", Mod_id,  ITTI_MSG_NAME (msg_p),
+              NAS_CELL_SELECTION_CNF (msg_p).errCode, NAS_CELL_SELECTION_CNF (msg_p).cellID, NAS_CELL_SELECTION_CNF (msg_p).tac);
+        // as_stmsi_t s_tmsi={0, 0};
+        // as_nas_info_t nas_info;
+        // plmn_t plmnID={0, 0, 0, 0};
+        // generateRegistrationRequest(&nas_info);
+        // nr_nas_itti_nas_establish_req(0, AS_TYPE_ORIGINATING_SIGNAL, s_tmsi, plmnID, nas_info.data, nas_info.length, 0);
+        break;
+
+      case NAS_CELL_SELECTION_IND:
+        LOG_I(NAS, "[UE %d] Received %s: cellID %u, tac %u\n", Mod_id,  ITTI_MSG_NAME (msg_p),
+              NAS_CELL_SELECTION_IND (msg_p).cellID, NAS_CELL_SELECTION_IND (msg_p).tac);
+
+        /* TODO not processed by NAS currently */
+        break;
+
+      case NAS_PAGING_IND:
+        LOG_I(NAS, "[UE %d] Received %s: cause %u\n", Mod_id,  ITTI_MSG_NAME (msg_p),
+              NAS_PAGING_IND (msg_p).cause);
+
+        /* TODO not processed by NAS currently */
+        break;
+
+      case NAS_CONN_ESTABLI_CNF:
+      {
+        LOG_I(NAS, "[UE %d] Received %s: errCode %u, length %u\n", Mod_id,  ITTI_MSG_NAME (msg_p),
+              NAS_CONN_ESTABLI_CNF (msg_p).errCode, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length);
+
+        pdu_buffer = NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.data;
+        if((pdu_buffer + 1) != NULL){
+          if (*(pdu_buffer + 1) > 0 ) {
+            if((pdu_buffer + 9) != NULL){
+                msg_type = *(pdu_buffer + 9);
+            } else {
+              LOG_W(NAS, "[UE] Received invalid downlink message\n");
+              break;
+            }
+          } else {
+            if((pdu_buffer + 2) != NULL){
+              msg_type = *(pdu_buffer + 2);
+            } else {
+                LOG_W(NAS, "[UE] Received invalid downlink message\n");
+                break;
+            }
+          }
+        }
+        if(msg_type == REGISTRATION_ACCEPT){
+          LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n");
+
+          as_nas_info_t initialNasMsg;
+          memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
+          generateRegistrationComplete(&initialNasMsg, NULL);
+          if(initialNasMsg.length > 0){
+            MessageDef *message_p;
+            message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
+            NAS_UPLINK_DATA_REQ(message_p).UEid          = Mod_id;
+            NAS_UPLINK_DATA_REQ(message_p).nasMsg.data   = (uint8_t *)initialNasMsg.data;
+            NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
+            itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
+            LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
+          }
+
+          as_nas_info_t pduEstablishMsg;
+          memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
+          generatePduSessionEstablishRequest(&pduEstablishMsg);
+          if(pduEstablishMsg.length > 0){
+            MessageDef *message_p;
+            message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
+            NAS_UPLINK_DATA_REQ(message_p).UEid          = Mod_id;
+            NAS_UPLINK_DATA_REQ(message_p).nasMsg.data   = (uint8_t *)pduEstablishMsg.data;
+            NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length;
+            itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
+            LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
+          }
+        }
+
+        break;
+      }
+
+      case NAS_CONN_RELEASE_IND:
+        LOG_I(NAS, "[UE %d] Received %s: cause %u\n", Mod_id, ITTI_MSG_NAME (msg_p),
+              NAS_CONN_RELEASE_IND (msg_p).cause);
+
+        break;
+
+      case NAS_UPLINK_DATA_CNF:
+        LOG_I(NAS, "[UE %d] Received %s: UEid %u, errCode %u\n", Mod_id, ITTI_MSG_NAME (msg_p),
+              NAS_UPLINK_DATA_CNF (msg_p).UEid, NAS_UPLINK_DATA_CNF (msg_p).errCode);
+
+        break;
+
+      case NAS_DOWNLINK_DATA_IND:
+      {
+        LOG_I(NAS, "[UE %d] Received %s: UEid %u, length %u , buffer %p\n", Mod_id,
+                                                                            ITTI_MSG_NAME (msg_p),
+                                                                            Mod_id,
+                                                                            NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length,
+                                                                            NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data);
+        as_nas_info_t initialNasMsg;
+        memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
+
+        pdu_buffer = NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data;
+        if((pdu_buffer + 1) != NULL){
+          if (*(pdu_buffer + 1) > 0 ) {
+            msg_type = *(pdu_buffer + 9);
+          } else {
+            msg_type = *(pdu_buffer + 2);
+          }
+        }
+        if((pdu_buffer + 2) == NULL){
+          LOG_W(NAS, "[UE] Received invalid downlink message\n");
+          return 0;
+        }
+
+        switch(msg_type){
+          case FGS_IDENTITY_REQUEST:
+              generateIdentityResponse(&initialNasMsg,*(pdu_buffer+3));
+              break;
+          case FGS_AUTHENTICATION_REQUEST:
+              generateAuthenticationResp(&initialNasMsg, pdu_buffer);
+              break;
+          case FGS_SECURITY_MODE_COMMAND:
+            generateSecurityModeComplete(&initialNasMsg);
+            break;
+          default:
+              LOG_W(NR_RRC,"unknow message type %d\n",msg_type);
+              break;
+        }
+
+        if(initialNasMsg.length > 0){
+          MessageDef *message_p;
+          message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
+          NAS_UPLINK_DATA_REQ(message_p).UEid          = Mod_id;
+          NAS_UPLINK_DATA_REQ(message_p).nasMsg.data   = (uint8_t *)initialNasMsg.data;
+          NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
+          itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
+          LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message\n");
+        }
+
+        break;
+      }
+
+      default:
+        LOG_E(NAS, "[UE %d] Received unexpected message %s\n", Mod_id,  ITTI_MSG_NAME (msg_p));
+        break;
+      }
+
+      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
+      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+      msg_p = NULL;
+    }
+  }
+
+  return NULL;
+}
diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h
index fef4671f434706aae3f828c1111c828de93557ec..2f123a6f04822605d18b5d721947c164c9c80460 100644
--- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h
+++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h
@@ -120,6 +120,7 @@ void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf);
 void generateSecurityModeComplete(as_nas_info_t *initialNasMsg);
 void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer);
 void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg);
+void *nas_nrue_task(void *args_p);
 
 #endif /* __NR_NAS_MSG_SIM_H__*/
 
diff --git a/openair3/NGAP/ngap_common.h b/openair3/NGAP/ngap_common.h
index f0302a88c77a135fc94257940a9a9a1a749bbd65..6803adb0dda43fface7944d7d9ac93dd106df38f 100644
--- a/openair3/NGAP/ngap_common.h
+++ b/openair3/NGAP/ngap_common.h
@@ -144,7 +144,6 @@ extern int asn1_xer_print;
     if (ie == NULL ) { \
       NGAP_ERROR("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\
     } \
-    if (mandatory)  DevAssert(ie != NULL); \
   } while(0)
 /** \brief Function callback prototype.
  **/
diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c
index f143002537a723219a3dcf046734a39b3944ea62..e398f8fa3e1c39d0e5ac5a9d18ce57c766c794ef 100644
--- a/openair3/NGAP/ngap_gNB_handlers.c
+++ b/openair3/NGAP/ngap_gNB_handlers.c
@@ -1061,12 +1061,31 @@ int ngap_gNB_handle_initial_context_request(uint32_t   assoc_id,
   NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
                                NGAP_ProtocolIE_ID_id_AllowedNSSAI, true);
   
-  if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
+  //if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
     NGAP_AllowedNSSAI_Item_t *allow_nssai_item_p = NULL;
   
-    NGAP_DEBUG("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count);
-    DevAssert(ie->value.choice.AllowedNSSAI.list.count > 0);
-    DevAssert(ie->value.choice.AllowedNSSAI.list.count <= NGAP_maxnoofAllowedS_NSSAIs);
+    NGAP_WARN("AllowedNSSAI.list.count %d\n", ie != NULL ? ie->value.choice.AllowedNSSAI.list.count : 2);
+    //NGAP_DEBUG("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count);
+    //DevAssert(ie->value.choice.AllowedNSSAI.list.count > 0);
+    //DevAssert(ie->value.choice.AllowedNSSAI.list.count <= NGAP_maxnoofAllowedS_NSSAIs);
+
+    if (ie == NULL) {
+    	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_allowed_nssais = 2;
+
+    	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sST = 01;
+
+    	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sD_flag = 1;
+    	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sD[0] = 01;
+    	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sD[1] = 02;
+    	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sD[2] = 03;
+
+    	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sST = 01;
+ 
+    	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD_flag = 1;
+    	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[0] = 00;//11;
+    	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[1] = 00;//22;
+    	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[2] = 01;//33;
+    } else {
 
     NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_allowed_nssais = ie->value.choice.AllowedNSSAI.list.count;
     
@@ -1082,9 +1101,10 @@ int ngap_gNB_handle_initial_context_request(uint32_t   assoc_id,
         NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD[2] = allow_nssai_item_p->s_NSSAI.sD->buf[2];
       }
     }
-  } else {/* ie != NULL */
-    return -1;
-  }
+   }
+  //} else {/* ie != NULL */
+  //  return -1;
+  //}
 
   /* id-UESecurityCapabilities */
   NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c
index 37110726820c4a11ac10187cf068f9ff27e5d2a0..6b6164358837893ab60649259c40541eeb9c4ece 100644
--- a/openair3/NGAP/ngap_gNB_nas_procedures.c
+++ b/openair3/NGAP/ngap_gNB_nas_procedures.c
@@ -932,7 +932,7 @@ int ngap_gNB_ue_capabilities(instance_t instance,
   /* mandatory */
   ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t));
   ie->id = NGAP_ProtocolIE_ID_id_UERadioCapability;
-  ie->criticality = NGAP_Criticality_reject;
+  ie->criticality = NGAP_Criticality_ignore;
   ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_UERadioCapability;
   ie->value.choice.UERadioCapability.buf = ue_cap_info_ind_p->ue_radio_cap.buffer;
   ie->value.choice.UERadioCapability.size = ue_cap_info_ind_p->ue_radio_cap.length;
diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c
index 515dd9a17fae493dc9d10f29409de6485648fd9f..05729ba6b1e8666e4162e9f06a2aefeab5b36832 100644
--- a/openair3/UDP/udp_eNB_task.c
+++ b/openair3/UDP/udp_eNB_task.c
@@ -169,8 +169,8 @@ int udp_eNB_create_socket(int port, char *ip_addr, task_id_t task_id)
 
   if ((rc = bind(sd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in))) < 0) {
     close(sd);
-    AssertFatal(rc >= 0, "UDP: Failed to bind socket: (%s:%d) address %s port %d\n",
-                strerror(errno), errno, ip_addr, port);
+    LOG_E(UDP_, "Failed to bind socket: (%s:%d) address %s port %d\n", strerror(errno), errno, ip_addr, port);
+    return -1;
   }
 
   /* Create a new descriptor for this connection */
diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp
index 29633ba6ae0d3eeccbe2216c71996e841680b8ef..82a1d782ec5dc364a214763b95e6bffc58efdcd9 100644
--- a/openair3/ocp-gtpu/gtp_itf.cpp
+++ b/openair3/ocp-gtpu/gtp_itf.cpp
@@ -62,7 +62,7 @@ typedef struct {
 
 typedef struct {
   rnti_t rnti;
-  ebi_t rb_id;
+  ebi_t incoming_rb_id;
   gtpCallback callBack;
 } rntiData_t;
 
@@ -85,7 +85,7 @@ class gtpEndPoints {
 
 gtpEndPoints globGtp;
 
-  // note TEid 0 is reserved for specific usage: echo req/resp, error and supported extensions
+// note TEid 0 is reserved for specific usage: echo req/resp, error and supported extensions
 static  uint32_t gtpv1uNewTeid(void) {
 #ifdef GTPV1U_LINEAR_TEID_ALLOCATION
   g_gtpv1u_teid = g_gtpv1u_teid + 1;
@@ -154,14 +154,14 @@ static  int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, te
 static void gtpv1uSend(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req, bool seqNumFlag, bool npduNumFlag) {
   uint8_t *buffer=req->buffer+req->offset;
   size_t length=req->length;
-  uint64_t rnti=req->rnti;
+  rnti_t rnti=req->rnti;
   int  rab_id=req->rab_id;
   pthread_mutex_lock(&globGtp.gtp_lock);
   auto inst=&globGtp.instances[compatInst(instance)];
   auto ptrRnti=inst->ue2te_mapping.find(rnti);
 
   if (  ptrRnti==inst->ue2te_mapping.end() ) {
-    LOG_E(GTPU, "gtpv1uSend failed: while getting ue rnti %lx in hashtable ue_mapping\n", rnti);
+    LOG_E(GTPU, "gtpv1uSend failed: while getting ue rnti %x in hashtable ue_mapping\n", rnti);
     pthread_mutex_unlock(&globGtp.gtp_lock);
     return;
   }
@@ -169,11 +169,11 @@ static void gtpv1uSend(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req, b
   auto ptr=ptrRnti->second.bearers;
 
   if ( ptr.find(rab_id) == ptr.end() ) {
-    LOG_E(GTPU,"sending a packet to a non existant RNTI:RAB: %lx/%x\n", rnti, rab_id);
+    LOG_E(GTPU,"sending a packet to a non existant RNTI:RAB: %x/%x\n", rnti, rab_id);
     pthread_mutex_unlock(&globGtp.gtp_lock);
     return;
   } else
-    LOG_D(GTPU,"sending a packet to RNTI:RAB:teid %lx/%x/%x, len %lu, oldseq %d, oldnum %d\n",
+    LOG_D(GTPU,"sending a packet to RNTI:RAB:teid %x/%x/%x, len %lu, oldseq %d, oldnum %d\n",
           rnti, rab_id,ptr[rab_id].teid_outgoing,length,  ptr[rab_id].seqNum,ptr[rab_id].npduNum );
 
   if(seqNumFlag)
@@ -191,16 +191,57 @@ static void gtpv1uSend(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req, b
                          tmp.teid_outgoing,
                          buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0) ;
 }
-  
+
+static void gtpv1uSend2(instance_t instance, gtpv1u_gnb_tunnel_data_req_t *req, bool seqNumFlag, bool npduNumFlag) {
+  uint8_t *buffer=req->buffer+req->offset;
+  size_t length=req->length;
+  rnti_t rnti=req->rnti;
+  int  rab_id=req->pdusession_id;
+  pthread_mutex_lock(&globGtp.gtp_lock);
+  auto inst=&globGtp.instances[compatInst(instance)];
+  auto ptrRnti=inst->ue2te_mapping.find(rnti);
+
+  if (  ptrRnti==inst->ue2te_mapping.end() ) {
+    LOG_E(GTPU, "gtpv1uSend failed: while getting ue rnti %x in hashtable ue_mapping\n", rnti);
+    pthread_mutex_unlock(&globGtp.gtp_lock);
+    return;
+  }
+
+  auto ptr=ptrRnti->second.bearers;
+
+  if ( ptr.find(rab_id) == ptr.end() ) {
+    LOG_E(GTPU,"sending a packet to a non existant RNTI:RAB: %x/%x\n", rnti, rab_id);
+    pthread_mutex_unlock(&globGtp.gtp_lock);
+    return;
+  } else
+    LOG_D(GTPU,"sending a packet to RNTI:RAB:teid %x/%x/%x, len %lu, oldseq %d, oldnum %d\n",
+          rnti, rab_id,ptr[rab_id].teid_outgoing,length,  ptr[rab_id].seqNum,ptr[rab_id].npduNum );
+
+  if(seqNumFlag)
+    ptr[rab_id].seqNum++;
+
+  if(npduNumFlag)
+    ptr[rab_id].npduNum++;
+
+  // We will release the lock, let's copy data before
+  ocp_gtpv1u_bearer_t tmp=ptr[rab_id];
+  pthread_mutex_unlock(&globGtp.gtp_lock);
+  gtpv1uCreateAndSendMsg(compatInst(instance),
+                         tmp.outgoing_ip_addr,
+                         tmp.outgoing_port,
+                         tmp.teid_outgoing,
+                         buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0) ;
+}
+
 static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req) {
-  uint64_t rnti=req->rnti;
+  rnti_t rnti=req->rnti;
   int  rab_id=req->rab_id;
   pthread_mutex_lock(&globGtp.gtp_lock);
   auto inst=&globGtp.instances[compatInst(instance)];
   auto ptrRnti=inst->ue2te_mapping.find(rnti);
 
   if (  ptrRnti==inst->ue2te_mapping.end() ) {
-    LOG_E(GTPU, "gtpv1uSend failed: while getting ue rnti %lx in hashtable ue_mapping\n", rnti);
+    LOG_E(GTPU, "gtpv1uSend failed: while getting ue rnti %x in hashtable ue_mapping\n", rnti);
     pthread_mutex_unlock(&globGtp.gtp_lock);
     return;
   }
@@ -208,15 +249,15 @@ static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *r
   auto ptr=ptrRnti->second.bearers;
 
   if ( ptr.find(rab_id) == ptr.end() ) {
-    LOG_E(GTPU,"sending a packet to a non existant RNTI:RAB: %lx/%x\n", rnti, rab_id);
+    LOG_E(GTPU,"sending a packet to a non existant RNTI:RAB: %x/%x\n", rnti, rab_id);
     pthread_mutex_unlock(&globGtp.gtp_lock);
     return;
   } else
-    LOG_D(GTPU,"sending a end packet packet to RNTI:RAB:teid %lx/%x/%x\n",
+    LOG_D(GTPU,"sending a end packet packet to RNTI:RAB:teid %x/%x/%x\n",
           rnti, rab_id,ptr[rab_id].teid_outgoing);
+
   ocp_gtpv1u_bearer_t tmp=ptr[rab_id];
   pthread_mutex_unlock(&globGtp.gtp_lock);
-
   Gtpv1uMsgHeaderT  msgHdr;
   // N should be 0 for us (it was used only in 2G and 3G)
   msgHdr.PN=0;
@@ -229,7 +270,6 @@ static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *r
   msgHdr.msgType=GTP_END_MARKER;
   msgHdr.msgLength=htons(0);
   msgHdr.teid=htonl(tmp.teid_outgoing);
-
   // Fix me: add IPv6 support, using flag ipVersion
   static struct sockaddr_in to= {0};
   to.sin_family      = AF_INET;
@@ -243,7 +283,7 @@ static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *r
           compatInst(instance), IPV4_ADDR_FORMAT(tmp.outgoing_ip_addr), tmp.outgoing_port, sizeof(msgHdr));
   }
 }
-  
+
 static  int udpServerSocket(openAddr_s addr) {
   LOG_I(GTPU, "Initializing UDP for local address %s with port %s\n", addr.originHost, addr.originService);
   int status;
@@ -280,7 +320,7 @@ static  int udpServerSocket(openAddr_s addr) {
         memcpy(globGtp.instances[sockfd].foundAddr,
                &ipv4->sin_addr.s_addr, sizeof(ipv4->sin_addr.s_addr));
         globGtp.instances[sockfd].foundAddrLen=sizeof(ipv4->sin_addr.s_addr);
-	globGtp.instances[sockfd].ipVersion=4;
+        globGtp.instances[sockfd].ipVersion=4;
         break;
       } else if (p->ai_family == AF_INET6) {
         LOG_W(GTPU,"Local address is IP v6\n");
@@ -288,7 +328,7 @@ static  int udpServerSocket(openAddr_s addr) {
         memcpy(globGtp.instances[sockfd].foundAddr,
                &ipv6->sin6_addr.s6_addr, sizeof(ipv6->sin6_addr.s6_addr));
         globGtp.instances[sockfd].foundAddrLen=sizeof(ipv6->sin6_addr.s6_addr);
-	globGtp.instances[sockfd].ipVersion=6;
+        globGtp.instances[sockfd].ipVersion=6;
       } else
         AssertFatal(false,"Local address is not IPv4 or IPv6");
     }
@@ -344,7 +384,8 @@ instance_t ocp_gtpv1Init(openAddr_t context) {
   return id;
 }
 
-teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid_t teid, transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) {
+teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid,
+                           transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) {
   pthread_mutex_lock(&globGtp.gtp_lock);
   auto inst=&globGtp.instances[instance];
   auto it=inst->ue2te_mapping.find(rnti);
@@ -354,20 +395,20 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid
     inst->ue2te_mapping.erase(it);
   }
 
-  uint32_t s1u_teid=gtpv1uNewTeid();
+  uint32_t incoming_teid=gtpv1uNewTeid();
 
-  while ( inst->te2ue_mapping.find(s1u_teid) != inst->te2ue_mapping.end() ) {
-    LOG_W(GTPU, "generated a random Teid that exists, re-generating (%u)\n",s1u_teid);
-    s1u_teid=gtpv1uNewTeid();
+  while ( inst->te2ue_mapping.find(incoming_teid) != inst->te2ue_mapping.end() ) {
+    LOG_W(GTPU, "generated a random Teid that exists, re-generating (%x)\n",incoming_teid);
+    incoming_teid=gtpv1uNewTeid();
   };
 
-  inst->te2ue_mapping[s1u_teid].rnti=rnti;
+  inst->te2ue_mapping[incoming_teid].rnti=rnti;
 
-  inst->te2ue_mapping[s1u_teid].rb_id= teid;
+  inst->te2ue_mapping[incoming_teid].incoming_rb_id= incoming_bearer_id;
 
-  inst->te2ue_mapping[s1u_teid].callBack=callBack;
+  inst->te2ue_mapping[incoming_teid].callBack=callBack;
 
-  auto tmp=&inst->ue2te_mapping[rnti].bearers[bearer_id];
+  auto tmp=&inst->ue2te_mapping[rnti].bearers[outgoing_bearer_id];
 
   int addrs_length_in_bytes = remoteAddr.length / 8;
 
@@ -391,23 +432,38 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid
       AssertFatal(false, "SGW Address size impossible");
   }
 
-  tmp->teid_incoming = s1u_teid;
+  tmp->teid_incoming = incoming_teid;
   tmp->outgoing_port=port;
-  tmp->teid_outgoing= teid;
+  tmp->teid_outgoing= outgoing_teid;
   pthread_mutex_unlock(&globGtp.gtp_lock);
-  return s1u_teid;
+  char ip4[INET_ADDRSTRLEN];
+  char ip6[INET6_ADDRSTRLEN];
+
+  LOG_I(GTPU, "Created tunnel for RNTI %x, teid for DL: %d, teid for UL %d to remote IPv4: %s, IPv6 %s\n",
+        rnti,
+        tmp->teid_incoming,
+        tmp->teid_outgoing,
+        inet_ntop(AF_INET,(void*)&tmp->outgoing_ip_addr, ip4,INET_ADDRSTRLEN ),
+        inet_ntop(AF_INET6,(void*)&tmp->outgoing_ip6_addr.s6_addr, ip6, INET6_ADDRSTRLEN));
+
+  return incoming_teid;
 }
 
 int ocp_gtpv1u_create_s1u_tunnel(instance_t instance,
                                  const gtpv1u_enb_create_tunnel_req_t  *create_tunnel_req,
                                  gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp) {
-  LOG_D(GTPU, "Start create tunnels for RNTI %x, num_tunnels %d, sgw_S1u_teid %d\n",
+  LOG_D(GTPU, "Start create tunnels for RNTI %x, num_tunnels %d, sgw_S1u_teid %x\n",
         create_tunnel_req->rnti,
         create_tunnel_req->num_tunnels,
         create_tunnel_req->sgw_S1u_teid[0]);
 
   for (int i = 0; i < create_tunnel_req->num_tunnels; i++) {
+    AssertFatal(create_tunnel_req->eps_bearer_id[i] > 4,
+                "From legacy code not clear, seems impossible (bearer=%d)\n",
+                create_tunnel_req->eps_bearer_id[i]);
+    int incoming_rb_id=create_tunnel_req->eps_bearer_id[i]-4;
     teid_t teid=newGtpuCreateTunnel(compatInst(instance), create_tunnel_req->rnti,
+                                    incoming_rb_id,
                                     create_tunnel_req->eps_bearer_id[i],
                                     create_tunnel_req->sgw_S1u_teid[i],
                                     create_tunnel_req->sgw_addr[i], 2152,
@@ -430,7 +486,7 @@ int ocp_gtpv1u_update_s1u_tunnel(
   const gtpv1u_enb_create_tunnel_req_t *const  create_tunnel_req,
   const rnti_t                                  prior_rnti
 ) {
-  LOG_D(GTPU, "Start update tunnels for old RNTI %x, new RNTI %x, num_tunnels %d, sgw_S1u_teid %d, eps_bearer_id %d\n",
+  LOG_D(GTPU, "Start update tunnels for old RNTI %x, new RNTI %x, num_tunnels %d, sgw_S1u_teid %x, eps_bearer_id %x\n",
         prior_rnti,
         create_tunnel_req->rnti,
         create_tunnel_req->num_tunnels,
@@ -459,6 +515,41 @@ int ocp_gtpv1u_update_s1u_tunnel(
   return 0;
 }
 
+int gtpv1u_create_ngu_tunnel(  const instance_t instance,
+                               const gtpv1u_gnb_create_tunnel_req_t   *const create_tunnel_req,
+                               gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp) {
+  LOG_D(GTPU, "Start create tunnels for RNTI %x, num_tunnels %d, sgw_S1u_teid %x\n",
+        create_tunnel_req->rnti,
+        create_tunnel_req->num_tunnels,
+        create_tunnel_req->upf_NGu_teid[0]);
+
+  for (int i = 0; i < create_tunnel_req->num_tunnels; i++) {
+    teid_t teid=newGtpuCreateTunnel(compatInst(instance), create_tunnel_req->rnti,
+                                    create_tunnel_req->pdusession_id[i],
+                                    create_tunnel_req->pdusession_id[i],
+                                    create_tunnel_req->upf_NGu_teid[i],
+                                    create_tunnel_req->upf_addr[i], 2152,
+                                    pdcp_data_req);
+    create_tunnel_resp->status=0;
+    create_tunnel_resp->rnti=create_tunnel_req->rnti;
+    create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels;
+    create_tunnel_resp->gnb_NGu_teid[i]=teid;
+    memcpy(create_tunnel_resp->gnb_addr.buffer,globGtp.instances[compatInst(instance)].foundAddr,
+           globGtp.instances[compatInst(instance)].foundAddrLen);
+    create_tunnel_resp->gnb_addr.length= globGtp.instances[compatInst(instance)].foundAddrLen;
+  }
+
+  return !GTPNOK;
+}
+
+int gtpv1u_update_ngu_tunnel(
+  const instance_t instanceP,
+  const gtpv1u_gnb_create_tunnel_req_t *const  create_tunnel_req_pP,
+  const rnti_t prior_rnti
+) {
+  return GTPNOK;
+}
+
 int ocp_gtpv1u_create_x2u_tunnel(
   const instance_t instanceP,
   const gtpv1u_enb_create_x2u_tunnel_req_t   *const create_tunnel_req_pP,
@@ -479,13 +570,18 @@ int newGtpuDeleteTunnel(instance_t instance, rnti_t rnti) {
     return -1;
   }
 
+  int nb=0;
+
   for (auto j=it->second.bearers.begin();
        j!=it->second.bearers.end();
-       ++j)
+       ++j) {
     inst->te2ue_mapping.erase(j->second.teid_incoming);
+    nb++;
+  }
 
   inst->ue2te_mapping.erase(it);
   pthread_mutex_unlock(&globGtp.gtp_lock);
+  LOG_I(GTPU, "Deleted all tunnels for RNTI %d (%d tunnels deleted)\n", rnti, nb);
   return !GTPNOK;
 }
 
@@ -496,6 +592,12 @@ int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance,
   return  newGtpuDeleteTunnel(instance, req_pP->rnti);
 }
 
+int gtpv1u_delete_x2u_tunnel( const instance_t instanceP,
+                              const gtpv1u_enb_delete_tunnel_req_t *const req_pP,
+                              int enbflag) {
+  return 0;
+}
+
 static int Gtpv1uHandleEchoReq(int h,
                                uint8_t *msgBuf,
                                uint32_t msgBufLen,
@@ -526,15 +628,16 @@ static int Gtpv1uHandleSupportedExt(int h,
   return rc;
 }
 
-  // When end marker arrives, we notify the client with buffer size = 0
-  // The client will likely call "delete tunnel"
-  // nevertheless we don't take the initiative
+// When end marker arrives, we notify the client with buffer size = 0
+// The client will likely call "delete tunnel"
+// nevertheless we don't take the initiative
 static int Gtpv1uHandleEndMarker(int h,
                                  uint8_t *msgBuf,
                                  uint32_t msgBufLen,
                                  uint16_t peerPort,
                                  uint32_t peerIp) {
   Gtpv1uMsgHeaderT      *msgHdr = (Gtpv1uMsgHeaderT *) msgBuf;
+
   if ( msgHdr->version != 1 ||  msgHdr->PT != 1 ) {
     LOG_E(GTPU, "Received a packet that is not GTP header\n");
     return GTPNOK;
@@ -546,10 +649,11 @@ static int Gtpv1uHandleEndMarker(int h,
   auto tunnel=inst->te2ue_mapping.find(ntohl(msgHdr->teid));
 
   if ( tunnel == inst->te2ue_mapping.end() ) {
-    LOG_E(GTPU,"Received a incoming packet on unknown teid (%d) Dropping!\n", msgHdr->teid);
+    LOG_E(GTPU,"Received a incoming packet on unknown teid (%x) Dropping!\n", msgHdr->teid);
     pthread_mutex_unlock(&globGtp.gtp_lock);
     return GTPNOK;
   }
+
   // This context is not good for gtp
   // frame, ... has no meaning
   // manyother attributes may come from create tunnel
@@ -564,7 +668,7 @@ static int Gtpv1uHandleEndMarker(int h,
   ctxt.configured = 0;
   ctxt.brOption = 0;
   const srb_flag_t     srb_flag=SRB_FLAG_NO;
-  const rb_id_t        rb_id=tunnel->second.rb_id;
+  const rb_id_t        rb_id=tunnel->second.incoming_rb_id;
   const mui_t          mui=RLC_MUI_UNDEFINED;
   const confirm_t      confirm=RLC_SDU_CONFIRM_NO;
   const pdcp_transmission_mode_t mode=PDCP_TRANSMISSION_MODE_DATA;
@@ -587,7 +691,7 @@ static int Gtpv1uHandleEndMarker(int h,
   LOG_D(GTPU,"Received END marker packet for: teid:%x\n", ntohl(msgHdr->teid));
   return !GTPNOK;
 }
-  
+
 static int Gtpv1uHandleGpdu(int h,
                             uint8_t *msgBuf,
                             uint32_t msgBufLen,
@@ -606,7 +710,7 @@ static int Gtpv1uHandleGpdu(int h,
   auto tunnel=inst->te2ue_mapping.find(ntohl(msgHdr->teid));
 
   if ( tunnel == inst->te2ue_mapping.end() ) {
-    LOG_E(GTPU,"Received a incoming packet on unknown teid (%d) Dropping!\n", msgHdr->teid);
+    LOG_E(GTPU,"Received a incoming packet on unknown teid (%x) Dropping!\n", msgHdr->teid);
     pthread_mutex_unlock(&globGtp.gtp_lock);
     return GTPNOK;
   }
@@ -630,7 +734,7 @@ static int Gtpv1uHandleGpdu(int h,
   ctxt.configured = 0;
   ctxt.brOption = 0;
   const srb_flag_t     srb_flag=SRB_FLAG_NO;
-  const rb_id_t        rb_id=tunnel->second.rb_id;
+  const rb_id_t        rb_id=tunnel->second.incoming_rb_id;
   const mui_t          mui=RLC_MUI_UNDEFINED;
   const confirm_t      confirm=RLC_SDU_CONFIRM_NO;
   const sdu_size_t     sdu_buffer_size=msgBufLen-offset;
@@ -730,20 +834,27 @@ void *ocp_gtpv1uTask(void *args)  {
         }
         break;
 
+        case GTPV1U_GNB_TUNNEL_DATA_REQ: {
+          gtpv1uSend2(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)),
+                      &GTPV1U_GNB_TUNNEL_DATA_REQ(message_p), false, false);
+          itti_free(OCP_GTPV1_U, GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).buffer);
+        }
+        break;
+
         case TERMINATE_MESSAGE:
           break;
 
         case TIMER_HAS_EXPIRED:
           LOG_E(GTPU, "Received unexpected timer expired (no need of timers in this version) %s\n", ITTI_MSG_NAME(message_p));
           break;
-	  
-      case GTPV1U_ENB_END_MARKER_REQ:
-	gtpv1uEndTunnel(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)),
-			&GTPV1U_ENB_TUNNEL_DATA_REQ(message_p));
-	itti_free(OCP_GTPV1_U, GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer);
-	break;
-	
-      case GTPV1U_ENB_DATA_FORWARDING_REQ:
+
+        case GTPV1U_ENB_END_MARKER_REQ:
+          gtpv1uEndTunnel(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)),
+                          &GTPV1U_ENB_TUNNEL_DATA_REQ(message_p));
+          itti_free(OCP_GTPV1_U, GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer);
+          break;
+
+        case GTPV1U_ENB_DATA_FORWARDING_REQ:
         case GTPV1U_ENB_DATA_FORWARDING_IND:
         case GTPV1U_ENB_END_MARKER_IND:
           LOG_E(GTPU, "to be developped %s\n", ITTI_MSG_NAME(message_p));
@@ -757,6 +868,13 @@ void *ocp_gtpv1uTask(void *args)  {
           AssertFatal((legacyInstanceMapping=ocp_gtpv1Init(addr))!=0,"Instance 0 reserved for legacy\n");
           break;
 
+        case GTPV1U_GNB_NG_REQ:
+          // to be dev: should be removed, to use API
+          strcpy(addr.originHost, GTPV1U_ENB_S1_REQ(message_p).addrStr);
+          strcpy(addr.originService, GTPV1U_ENB_S1_REQ(message_p).portStr);
+          AssertFatal((legacyInstanceMapping=ocp_gtpv1Init(addr))!=0,"Instance 0 reserved for legacy\n");
+          break;
+
         default:
           LOG_E(GTPU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
           abort();
diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h
index 507aa1338e300d816e09555ca6282d06f15c3bd1..dd406e27cddc579eca574453c96b7ce2a2abd40b 100644
--- a/openair3/ocp-gtpu/gtp_itf.h
+++ b/openair3/ocp-gtpu/gtp_itf.h
@@ -14,7 +14,7 @@ extern "C" {
 #define gtpv1u_delete_s1u_tunnel ocp_gtpv1u_delete_s1u_tunnel
 #define gtpv1u_create_x2u_tunnel ocp_gtpv1u_create_x2u_tunnel
 #define gtpv1u_eNB_task          ocp_gtpv1uTask
-#define gtpv1u_gNB_task          ocp_gtpv1uTask
+#define nr_gtpv1u_gNB_task       ocp_gtpv1uTask
 #define TASK_VARIABLE            OCP_GTPV1_U
 #else
 #define TASK_VARIABLE            TASK_GTPV1_U
@@ -60,7 +60,7 @@ int ocp_gtpv1u_create_x2u_tunnel(
 
 
 // New API
-teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid_t teid,
+teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_rb_id, teid_t teid,
                            transport_layer_addr_t remoteAddr, int port, gtpCallback callBack);
 instance_t ocp_gtpv1Init(openAddr_t context);
 void *ocp_gtpv1uTask(void *args);
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index 83a6207eec8869d7082dc6a83a3f1aee803b2404..fd4a830a02bbce970bc140784ef9e332d95a1eca 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -949,8 +949,8 @@ int trx_usrp_reset_stats(openair0_device *device) {
 
 extern "C" {
   int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
-    LOG_D(HW, "openair0_cfg[0].sdr_addrs == '%s'\n", openair0_cfg[0].sdr_addrs);
-    LOG_D(HW, "openair0_cfg[0].clock_source == '%d'\n", openair0_cfg[0].clock_source);
+    LOG_I(HW, "openair0_cfg[0].sdr_addrs == '%s'\n", openair0_cfg[0].sdr_addrs);
+    LOG_I(HW, "openair0_cfg[0].clock_source == '%d' (internal = %d, external = %d)\n", openair0_cfg[0].clock_source,internal,external);
     usrp_state_t *s ;
 
     if ( device->priv == NULL) {
@@ -1041,15 +1041,15 @@ extern "C" {
     if (args.find("clock_source")==std::string::npos) {
 	if (openair0_cfg[0].clock_source == internal) {
 	  s->usrp->set_clock_source("internal");
-	  LOG_D(HW,"Setting clock source to internal\n");
+	  LOG_I(HW,"Setting clock source to internal\n");
 	}
 	else if (openair0_cfg[0].clock_source == external ) {
 	  s->usrp->set_clock_source("external");
-	  LOG_D(HW,"Setting clock source to external\n");
+	  LOG_I(HW,"Setting clock source to external\n");
 	}
 	else if (openair0_cfg[0].clock_source==gpsdo) {
 	  s->usrp->set_clock_source("gpsdo");
-	  LOG_D(HW,"Setting clock source to gpsdo\n");
+	  LOG_I(HW,"Setting clock source to gpsdo\n");
 	}
 	else {
 	  LOG_W(HW,"Clock source set neither in usrp_args nor on command line, using default!\n");
@@ -1064,15 +1064,15 @@ extern "C" {
     if (args.find("time_source")==std::string::npos) {
 	if (openair0_cfg[0].time_source == internal) {
 	  s->usrp->set_time_source("internal");
-	  LOG_D(HW,"Setting time source to internal\n");
+	  LOG_I(HW,"Setting time source to internal\n");
 	}
 	else if (openair0_cfg[0].time_source == external ) {
 	  s->usrp->set_time_source("external");
-	  LOG_D(HW,"Setting time source to external\n");
+	  LOG_I(HW,"Setting time source to external\n");
 	}
 	else if (openair0_cfg[0].time_source==gpsdo) {
 	  s->usrp->set_time_source("gpsdo");
-	  LOG_D(HW,"Setting time source to gpsdo\n");
+	  LOG_I(HW,"Setting time source to gpsdo\n");
 	}
 	else {
 	  LOG_W(HW,"Time source set neither in usrp_args nor on command line, using default!\n");
@@ -1265,10 +1265,14 @@ extern "C" {
       set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust);
       ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i);
       // limit to maximum gain
-      AssertFatal( openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] <= gain_range.stop(),
-                   "RX Gain too high, lower by %f dB\n",
-                   openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop());
-      s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i);
+      double gain=openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i];
+      if ( gain > gain_range.stop())  {
+                   LOG_E(HW,"RX Gain too high, lower by %f dB\n",
+                   gain - gain_range.stop());
+               gain=gain_range.stop();
+      }
+          
+      s->usrp->set_rx_gain(gain,i);
       LOG_I(HW,"RX Gain %d %f (%f) => %f (max %f)\n",i,
             openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i],
             openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop());
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_eNB_band13.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_eNB_band13.conf
index 1e32905733bec9c657c1149b4caea9a205be1589..1d8f61e442ba23af6a67ee6a21edbcea4c93fcc2 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_eNB_band13.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_eNB_band13.conf
@@ -240,7 +240,7 @@ MACRLCs = (
 THREAD_STRUCT = (
   {
     parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
-    worker_config = "ENABLE";
+    worker_config = "WORKER_ENABLE";
   }
 );
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_enb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_enb.conf
index d26ebcd590ca0a9c4524ac491b8823d308502d7d..7e9a55d924994bab675c75946ce4789e5e708fdf 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_enb.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_enb.conf
@@ -241,7 +241,7 @@ MACRLCs = (
 THREAD_STRUCT = (
   {
     parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
-    worker_config = "ENABLE";
+    worker_config = "WORKER_ENABLE";
   }
 );
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
index bdb8b8518aa6f070b64c192c18afb3534807020b..c7ffc1a29abc4669320e7ec44f79147e1989d1e0 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
@@ -188,7 +188,7 @@ gNBs =
 
 
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "192.168.18.99";
+    amf_ip_address      = ( { ipv4       = "192.168.69.131";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
@@ -211,10 +211,10 @@ gNBs =
     NETWORK_INTERFACES :
     {
 
-        GNB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
-        GNB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.18.198/24";
-        GNB_INTERFACE_NAME_FOR_S1U               = "eth0";
-        GNB_IPV4_ADDRESS_FOR_S1U                 = "192.168.18.198/24";
+        GNB_INTERFACE_NAME_FOR_NG_AMF            = "eth0";
+        GNB_IPV4_ADDRESS_FOR_NG_AMF              = "192.168.18.198/24";
+        GNB_INTERFACE_NAME_FOR_NGU               = "eth0";
+        GNB_IPV4_ADDRESS_FOR_NGU                 = "192.168.18.198/24";
         GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
         GNB_IPV4_ADDRESS_FOR_X2C                 = "192.168.18.198/24";
         GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
@@ -249,7 +249,7 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 114;
          eNB_instances  = [0];
-         clock_src = "external";
+         #clock_src = "external";
     }
 );  
 
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf
new file mode 100644
index 0000000000000000000000000000000000000000..483fd34f2a1e910ce7ff449e4ad0e3f3b4966a77
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf
@@ -0,0 +1,288 @@
+Active_gNBs = ( "gNB-CU-Eurecom-5GNRBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+Num_Threads_PUSCH = 8;
+
+gNBs =
+(
+ {
+    ////////// Identification parameters:
+    gNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_GNB";
+
+    gNB_name  =  "gNB-CU-Eurecom-5GNRBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  1;
+
+    plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
+
+    nr_cellid = 12345678L
+
+    tr_s_preference  = "f1"
+
+    local_s_if_name  = "lo";
+    remote_s_address = "127.0.0.3";
+    local_s_address  = "127.0.0.4";
+    local_s_portc    = 501;
+    remote_s_portc   = 500;
+    local_s_portd    = 601;
+    remote_s_portd   = 600; 
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 641032;
+      dl_frequencyBand                                                 = 78;
+      # this is 3600 MHz
+      dl_absoluteFrequencyPointA                                       = 640000;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        dl_subcarrierSpacing                                           = 1;
+        dl_carrierBandwidth                                            = 106;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=41,L=24 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6366;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 12;
+        initialDLBWPsearchSpaceZero                                             = 0;
+      #pdsch-ConfigCommon
+        #pdschTimeDomainAllocationList (up to 16 entries)
+             initialDLBWPk0_0                    = 0;
+             #initialULBWPmappingType
+	     #0=typeA,1=typeB
+             initialDLBWPmappingType_0           = 0;
+             #this is SS=1,L=13
+             initialDLBWPstartSymbolAndLength_0  = 40;
+
+             initialDLBWPk0_1                    = 0;
+             initialDLBWPmappingType_1           = 0;
+             #this is SS=2,L=12 
+             initialDLBWPstartSymbolAndLength_1  = 53;
+
+             initialDLBWPk0_2                    = 0;
+             initialDLBWPmappingType_2           = 0;
+             #this is SS=1,L=12 
+             initialDLBWPstartSymbolAndLength_2  = 54;
+
+             initialDLBWPk0_3                    = 0;
+             initialDLBWPmappingType_3           = 0;
+             #this is SS=1,L=5
+             initialDLBWPstartSymbolAndLength_3  = 57;
+
+  #uplinkConfigCommon 
+     #frequencyInfoUL
+      ul_frequencyBand                                                 = 78;
+      #scs-SpecificCarrierList
+      ul_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      ul_subcarrierSpacing                                           = 1;
+      ul_carrierBandwidth                                            = 106;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 6366;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialULBWPsubcarrierSpacing                                           = 1;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+          prach_msg1_FDM                                            = 0;
+          prach_msg1_FrequencyStart                                 = 0;
+          zeroCorrelationZoneConfig                                 = 13;
+          preambleReceivedTargetPower                               = -118;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+          preambleTransMax                                          = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+        powerRampingStep                                            = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+        ra_ResponseWindow                                           = 4;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 15;
+#ra_ContentionResolutionTimer
+#(0..7) 8,16,24,32,40,48,56,64
+        ra_ContentionResolutionTimer                                = 7;
+        rsrp_ThresholdSSB                                           = 19;
+#prach-RootSequenceIndex_PR
+#1 = 839, 2 = 139
+        prach_RootSequenceIndex_PR                                  = 2;
+        prach_RootSequenceIndex                                     = 1;
+        # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
+        #  
+        msg1_SubcarrierSpacing                                      = 1,
+# restrictedSetConfig
+# 0=unrestricted, 1=restricted type A, 2=restricted type B
+        restrictedSetConfig                                         = 0,
+
+      # pusch-ConfigCommon (up to 16 elements)
+        initialULBWPk2_0                      = 6;
+        initialULBWPmappingType_0             = 1
+        # this is SS=0 L=11
+        initialULBWPstartSymbolAndLength_0    = 55;
+
+        initialULBWPk2_1                      = 6;
+        initialULBWPmappingType_1             = 1;
+        # this is SS=0 L=12
+        initialULBWPstartSymbolAndLength_1    = 69;
+
+        initialULBWPk2_2                      = 7;
+        initialULBWPmappingType_2             = 1;
+        # this is SS=10 L=4
+        initialULBWPstartSymbolAndLength_2    = 52;
+
+        msg3_DeltaPreamble                                          = 1;
+        p0_NominalWithGrant                                         =-90;
+
+# pucch-ConfigCommon setup :
+# pucchGroupHopping
+# 0 = neither, 1= group hopping, 2=sequence hopping
+        pucchGroupHopping                                           = 0;
+        hoppingId                                                   = 40;
+        p0_nominal                                                  = -90;
+# ssb_PositionsInBurs_BitmapPR
+# 1=short, 2=medium, 3=long
+      ssb_PositionsInBurst_PR                                       = 2;
+      ssb_PositionsInBurst_Bitmap                                   = 1;
+
+# ssb_periodicityServingCell
+# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 
+      ssb_periodicityServingCell                                    = 2;
+
+# dmrs_TypeA_position
+# 0 = pos2, 1 = pos3
+      dmrs_TypeA_Position                                           = 0;
+
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      subcarrierSpacing                                             = 1;
+
+
+  #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      referenceSubcarrierSpacing                                    = 1;
+      # pattern1 
+      # dl_UL_TransmissionPeriodicity
+      # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+      dl_UL_TransmissionPeriodicity                                 = 6;
+      nrofDownlinkSlots                                             = 7;
+      nrofDownlinkSymbols                                           = 6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4;
+
+  ssPBCH_BlockPower                                             = 10;
+  }
+
+  );
+
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "192.168.12.26";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+
+        GNB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
+        GNB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.111/24";
+        GNB_INTERFACE_NAME_FOR_S1U               = "eth0";
+        GNB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.111/24";
+        GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+  }
+);
+
+# RUs = (
+#     {		  
+#        local_rf       = "yes"
+#          nb_tx          = 1
+#          nb_rx          = 1
+#          att_tx         = 0
+#          att_rx         = 0;
+#          bands          = [7];
+#          max_pdschReferenceSignalPower = -27;
+#          max_rxgain                    = 75;
+#          eNB_instances  = [0];
+#          ##beamforming 1x2 matrix: 1 layer x 2 antennas
+#          bf_weights = [0x00007fff, 0x0000];
+#          ##beamforming 1x4 matrix: 1 layer x 4 antennas
+#          #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
+#          ## beamforming 2x2 matrix:
+#          # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
+#          ## beamforming 4x4 matrix:
+#          #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
+
+#          sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
+#          clock_src = "external";
+#     }
+# );  
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="debug";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="debug";
+       rrc_log_verbosity                     ="medium";
+       f1ap_log_level                        ="info";
+       f1ap_log_verbosity                    ="medium";
+    };
+
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf
new file mode 100644
index 0000000000000000000000000000000000000000..dcb3010f20386b2fc13f7bdbc8c00a72270a87d0
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf
@@ -0,0 +1,302 @@
+Active_gNBs = ( "gNB-Eurecom-DU");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+Num_Threads_PUSCH = 8;
+
+gNBs =
+(
+ {
+    ////////// Identification parameters:
+    gNB_CU_ID = 0xe00;
+
+#     cell_type =  "CELL_MACRO_GNB";
+
+    gNB_name  =  "gNB-Eurecom-DU";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  1;
+
+    plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});	
+
+    nr_cellid = 12345678L 
+
+#     tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 641032;
+      dl_frequencyBand                                                 = 78;
+      # this is 3600 MHz
+      dl_absoluteFrequencyPointA                                       = 640000;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        dl_subcarrierSpacing                                           = 1;
+        dl_carrierBandwidth                                            = 106;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=41,L=24 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6366;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 12;
+        initialDLBWPsearchSpaceZero                                             = 0;
+      #pdsch-ConfigCommon
+        #pdschTimeDomainAllocationList (up to 16 entries)
+             initialDLBWPk0_0                    = 0;
+             #initialULBWPmappingType
+	     #0=typeA,1=typeB
+             initialDLBWPmappingType_0           = 0;
+             #this is SS=1,L=13
+             initialDLBWPstartSymbolAndLength_0  = 40;
+
+             initialDLBWPk0_1                    = 0;
+             initialDLBWPmappingType_1           = 0;
+             #this is SS=2,L=12 
+             initialDLBWPstartSymbolAndLength_1  = 53;
+
+             initialDLBWPk0_2                    = 0;
+             initialDLBWPmappingType_2           = 0;
+             #this is SS=1,L=12 
+             initialDLBWPstartSymbolAndLength_2  = 54;
+
+             initialDLBWPk0_3                    = 0;
+             initialDLBWPmappingType_3           = 0;
+             #this is SS=1,L=5
+             initialDLBWPstartSymbolAndLength_3  = 57;
+
+  #uplinkConfigCommon 
+     #frequencyInfoUL
+      ul_frequencyBand                                                 = 78;
+      #scs-SpecificCarrierList
+      ul_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      ul_subcarrierSpacing                                           = 1;
+      ul_carrierBandwidth                                            = 106;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 6366;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialULBWPsubcarrierSpacing                                           = 1;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+          prach_msg1_FDM                                            = 0;
+          prach_msg1_FrequencyStart                                 = 0;
+          zeroCorrelationZoneConfig                                 = 13;
+          preambleReceivedTargetPower                               = -118;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+          preambleTransMax                                          = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+        powerRampingStep                                            = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+        ra_ResponseWindow                                           = 4;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 15;
+#ra_ContentionResolutionTimer
+#(0..7) 8,16,24,32,40,48,56,64
+        ra_ContentionResolutionTimer                                = 7;
+        rsrp_ThresholdSSB                                           = 19;
+#prach-RootSequenceIndex_PR
+#1 = 839, 2 = 139
+        prach_RootSequenceIndex_PR                                  = 2;
+        prach_RootSequenceIndex                                     = 1;
+        # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
+        #  
+        msg1_SubcarrierSpacing                                      = 1,
+# restrictedSetConfig
+# 0=unrestricted, 1=restricted type A, 2=restricted type B
+        restrictedSetConfig                                         = 0,
+
+      # pusch-ConfigCommon (up to 16 elements)
+        initialULBWPk2_0                      = 6;
+        initialULBWPmappingType_0             = 1
+        # this is SS=0 L=11
+        initialULBWPstartSymbolAndLength_0    = 55;
+
+        initialULBWPk2_1                      = 6;
+        initialULBWPmappingType_1             = 1;
+        # this is SS=0 L=12
+        initialULBWPstartSymbolAndLength_1    = 69;
+
+        initialULBWPk2_2                      = 7;
+        initialULBWPmappingType_2             = 1;
+        # this is SS=10 L=4
+        initialULBWPstartSymbolAndLength_2    = 52;
+
+        msg3_DeltaPreamble                                          = 1;
+        p0_NominalWithGrant                                         =-90;
+
+# pucch-ConfigCommon setup :
+# pucchGroupHopping
+# 0 = neither, 1= group hopping, 2=sequence hopping
+        pucchGroupHopping                                           = 0;
+        hoppingId                                                   = 40;
+        p0_nominal                                                  = -90;
+# ssb_PositionsInBurs_BitmapPR
+# 1=short, 2=medium, 3=long
+      ssb_PositionsInBurst_PR                                       = 2;
+      ssb_PositionsInBurst_Bitmap                                   = 1;
+
+# ssb_periodicityServingCell
+# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 
+      ssb_periodicityServingCell                                    = 2;
+
+# dmrs_TypeA_position
+# 0 = pos2, 1 = pos3
+      dmrs_TypeA_Position                                           = 0;
+
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      subcarrierSpacing                                             = 1;
+
+
+  #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      referenceSubcarrierSpacing                                    = 1;
+      # pattern1 
+      # dl_UL_TransmissionPeriodicity
+      # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+      dl_UL_TransmissionPeriodicity                                 = 6;
+      nrofDownlinkSlots                                             = 7;
+      nrofDownlinkSymbols                                           = 6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4;
+
+  ssPBCH_BlockPower                                             = 10;
+  }
+
+  );
+
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "192.168.12.26";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+
+        GNB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
+        GNB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.111/24";
+        GNB_INTERFACE_NAME_FOR_S1U               = "eth0";
+        GNB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.111/24";
+        GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+  }
+);
+
+MACRLCs = (
+  {
+    num_cc           = 1;
+    tr_s_preference  = "local_L1";
+    tr_n_preference  = "f1";
+    local_n_if_name  = "lo";
+    remote_n_address = "127.0.0.4";
+    local_n_address  = "127.0.0.3";
+    local_n_portc    = 500;
+    remote_n_portc   = 501;
+    local_n_portd    = 600;
+    remote_n_portd   = 601;
+  }
+);
+
+L1s = (
+    	{
+	num_cc = 1;
+	tr_n_preference = "local_mac";
+        }  
+);
+
+RUs = (
+    {		  
+       local_rf       = "yes"
+         nb_tx          = 1
+         nb_rx          = 1
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 75;
+         eNB_instances  = [0];
+         ##beamforming 1x2 matrix: 1 layer x 2 antennas
+         bf_weights = [0x00007fff, 0x0000];
+         ##beamforming 1x4 matrix: 1 layer x 4 antennas
+         #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
+         ## beamforming 2x2 matrix:
+         # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
+         ## beamforming 4x4 matrix:
+         #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
+
+         sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
+         clock_src = "external";
+    }
+);  
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_SINGLE_THREAD";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="debug";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+       f1ap_log_level                         ="debug";
+       f1ap_log_verbosity                     ="medium";
+    };
+
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf
new file mode 100644
index 0000000000000000000000000000000000000000..753bd0bed3ef58dac322a104f5bc70c7ecfae2a3
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf
@@ -0,0 +1,304 @@
+Active_gNBs = ( "gNB-Eurecom-5GNRBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+gNBs =
+(
+ {
+    ////////// Identification parameters:
+    gNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_GNB";
+
+    gNB_name  =  "gNB-Eurecom-5GNRBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  100;
+												
+    plmn_list = ({			
+			mcc = 208;		
+			mnc = 93;		
+			mnc_length = 2;		
+			snssaiList = (		
+				{	
+					sst = 1;
+					sd  = 0x010203; // 0 false, else true
+				},	
+				{	
+					sst = 1;
+					sd  = 0x112233; // 0 false, else true
+				}	
+			);		
+												
+			});		
+												
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+	
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 641032;
+      dl_frequencyBand                                                 = 78;
+      # this is 3600 MHz
+      dl_absoluteFrequencyPointA                                       = 640000;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        dl_subcarrierSpacing                                           = 1;
+        dl_carrierBandwidth                                            = 106;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=41,L=24 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6366;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 12;
+        initialDLBWPsearchSpaceZero                                             = 0;
+      #pdsch-ConfigCommon
+        #pdschTimeDomainAllocationList (up to 16 entries)
+             initialDLBWPk0_0                    = 0;
+             #initialULBWPmappingType
+	     #0=typeA,1=typeB
+             initialDLBWPmappingType_0           = 0;
+             #this is SS=1,L=13
+             initialDLBWPstartSymbolAndLength_0  = 40;
+
+             initialDLBWPk0_1                    = 0;
+             initialDLBWPmappingType_1           = 0;
+             #this is SS=2,L=12 
+             initialDLBWPstartSymbolAndLength_1  = 53;
+
+             initialDLBWPk0_2                    = 0;
+             initialDLBWPmappingType_2           = 0;
+             #this is SS=1,L=12 
+             initialDLBWPstartSymbolAndLength_2  = 54;
+
+             initialDLBWPk0_3                    = 0;
+             initialDLBWPmappingType_3           = 0;
+             #this is SS=1,L=5
+             initialDLBWPstartSymbolAndLength_3  = 57;
+
+  #uplinkConfigCommon 
+     #frequencyInfoUL
+      ul_frequencyBand                                                 = 78;
+      #scs-SpecificCarrierList
+      ul_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      ul_subcarrierSpacing                                           = 1;
+      ul_carrierBandwidth                                            = 106;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 6366;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialULBWPsubcarrierSpacing                                           = 1;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+          prach_msg1_FDM                                            = 0;
+          prach_msg1_FrequencyStart                                 = 0;
+          zeroCorrelationZoneConfig                                 = 13;
+          preambleReceivedTargetPower                               = -118;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+          preambleTransMax                                          = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+        powerRampingStep                                            = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+        ra_ResponseWindow                                           = 4;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 15;
+#ra_ContentionResolutionTimer
+#(0..7) 8,16,24,32,40,48,56,64
+        ra_ContentionResolutionTimer                                = 7;
+        rsrp_ThresholdSSB                                           = 19;
+#prach-RootSequenceIndex_PR
+#1 = 839, 2 = 139
+        prach_RootSequenceIndex_PR                                  = 2;
+        prach_RootSequenceIndex                                     = 1;
+        # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
+        #  
+        msg1_SubcarrierSpacing                                      = 1,
+
+# restrictedSetConfig
+# 0=unrestricted, 1=restricted type A, 2=restricted type B
+        restrictedSetConfig                                         = 0,
+      # pusch-ConfigCommon (up to 16 elements)
+        initialULBWPk2_0                      = 6;
+        initialULBWPmappingType_0             = 1
+        # this is SS=0 L=11
+        initialULBWPstartSymbolAndLength_0    = 55;
+
+        initialULBWPk2_1                      = 6;
+        initialULBWPmappingType_1             = 1;
+        # this is SS=0 L=12
+        initialULBWPstartSymbolAndLength_1    = 69;
+
+        initialULBWPk2_2                      = 7;
+        initialULBWPmappingType_2             = 1;
+        # this is SS=10 L=4
+        initialULBWPstartSymbolAndLength_2    = 52;
+
+        msg3_DeltaPreamble                                          = 1;
+        p0_NominalWithGrant                                         =-90;
+
+# pucch-ConfigCommon setup :
+# pucchGroupHopping
+# 0 = neither, 1= group hopping, 2=sequence hopping
+        pucchGroupHopping                                           = 0;
+        hoppingId                                                   = 40;
+        p0_nominal                                                  = -90;
+# ssb_PositionsInBurs_BitmapPR
+# 1=short, 2=medium, 3=long
+      ssb_PositionsInBurst_PR                                       = 2;
+      ssb_PositionsInBurst_Bitmap                                   = 1;
+
+# ssb_periodicityServingCell
+# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 
+      ssb_periodicityServingCell                                    = 2;
+
+# dmrs_TypeA_position
+# 0 = pos2, 1 = pos3
+      dmrs_TypeA_Position                                           = 0;
+
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      subcarrierSpacing                                             = 1;
+
+
+  #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      referenceSubcarrierSpacing                                    = 1;
+      # pattern1 
+      # dl_UL_TransmissionPeriodicity
+      # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+      dl_UL_TransmissionPeriodicity                                 = 6;
+      nrofDownlinkSlots                                             = 7;
+      nrofDownlinkSymbols                                           = 6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4;
+
+  ssPBCH_BlockPower                                             = 10;
+  }
+
+  );
+
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+												
+    ////////// AMF parameters:												
+    amf_ip_address      = ( { ipv4       = "192.168.199.223";												
+                              ipv6       = "192:168:199::223";												
+                              active     = "yes";												
+                              preference = "ipv4";												
+                            }												
+                          );												
+												
+						
+												
+    NETWORK_INTERFACES :												
+    {												
+												
+        GNB_INTERFACE_NAME_FOR_NG_AMF            = "eno1";												
+        GNB_IPV4_ADDRESS_FOR_NG_AMF              = "192.168.199.222/24";												
+        GNB_INTERFACE_NAME_FOR_NGU               = "enx000ec6c0a3ac";												
+        GNB_IPV4_ADDRESS_FOR_NGU                 = "192.168.10.100/24";												
+        GNB_PORT_FOR_NGU                         = 2152; # Spec 2152												
+        GNB_IPV4_ADDRESS_FOR_X2C                 = "192.168.20.20/24";												
+        GNB_PORT_FOR_X2C                         = 36422; # Spec 36422												
+    };												
+  }												
+);												
+
+MACRLCs = (
+	{
+	num_cc = 1;
+	tr_s_preference = "local_L1";
+	tr_n_preference = "local_RRC";
+        }  
+);
+
+L1s = (
+    	{
+	num_cc = 1;
+	tr_n_preference = "local_mac";
+        }  
+);
+
+RUs = (
+    {		  
+       local_rf       = "yes"
+         nb_tx          = 1
+         nb_rx          = 1
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 75;
+         eNB_instances  = [0];
+         #beamforming 1x4 matrix:
+         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+         sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
+         clock_src = "external";
+    }
+);  
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+       ngap_log_level                         ="info";												
+       ngap_log_verbosity                    ="medium";												
+    };
+
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 0f66d2fb92bf1b85d403acc1675cf854ba5b55d1..00c92d75a224f124aa43268f6701cbb49cd3f5b8 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
@@ -1,4 +1,4 @@
-Active_gNBs = ( "gNB-Eurecom-5GNRBox");
+Active_gNBs = ( "gNB-Eurecom-DU");
 # Asn1_verbosity, choice in: none, info, annoying
 Asn1_verbosity = "none";
 
@@ -7,15 +7,28 @@ gNBs =
  {
     ////////// Identification parameters:
     gNB_ID    =  0xe00;
-
-    cell_type =  "CELL_MACRO_GNB";
-    gNB_name  =  "gNB-Eurecom-5GNRBox";
+    gNB_name  =  "gNB-Eurecom-DU";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
     tracking_area_code  =  1;
-    plmn_list = ({mcc = 208; mnc = 92; mnc_length = 2;});
-
-    tr_s_preference     = "local_mac"
+    plmn_list = ({
+                  mcc = 208;
+                  mnc = 99;
+                  mnc_length = 2;
+                  snssaiList = (
+                    {
+                      sst = 1;
+                      sd  = 0x1; // 0 false, else true
+                    },
+                    {
+                      sst = 1;
+                      sd  = 0x112233; // 0 false, else true
+                    }
+                  );
+
+                  });
+
+    nr_cellid = 12345678L;
 
     ////////// Physical parameters:
 
@@ -51,8 +64,8 @@ gNBs =
         dl_carrierBandwidth                                            = 106;
      #initialDownlinkBWP
       #genericParameters
-        # this is RBstart=41,L=24 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                               = 12952; # 6366 12925 12956 28875
+        # this is RBstart=27,L=48 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                               = 12952; # 6366 12925 12956 28875 12952
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
         initialDLBWPsubcarrierSpacing                                   = 1;
@@ -191,35 +204,21 @@ gNBs =
 
 
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "192.168.12.26";
+    amf_ip_address      = ( { ipv4       = "192.168.70.132";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
                             }
                           );
 
-    ///X2
-    enable_x2 = "no";
-    t_reloc_prep      = 1000;      /* unit: millisecond */
-    tx2_reloc_overall = 2000;      /* unit: millisecond */
-    t_dc_prep         = 1000;      /* unit: millisecond */
-    t_dc_overall      = 2000;      /* unit: millisecond */
-    target_enb_x2_ip_address      = (
-                                     { ipv4       = "CI_FR1_CTL_ENB_IP_ADDR";
-                                       ipv6       = "192:168:30::17";
-                                       preference = "ipv4";
-                                     }
-                                    );
 
     NETWORK_INTERFACES :
     {
-        GNB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
-        GNB_IPV4_ADDRESS_FOR_S1_MME              = "CI_GNB_IP_ADDR";
-        GNB_INTERFACE_NAME_FOR_S1U               = "eth0";
-        GNB_IPV4_ADDRESS_FOR_S1U                 = "CI_GNB_IP_ADDR";
+        GNB_INTERFACE_NAME_FOR_NG_AMF            = "demo-oai";
+        GNB_IPV4_ADDRESS_FOR_NG_AMF              = "192.168.70.129/24";
+        GNB_INTERFACE_NAME_FOR_NGU               = "demo-oai";
+        GNB_IPV4_ADDRESS_FOR_NGU                 = "192.168.70.129/24";
         GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
-        GNB_IPV4_ADDRESS_FOR_X2C                 = "CI_GNB_IP_ADDR";
-        GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
     };
 
   }
@@ -238,7 +237,7 @@ L1s = (
 	num_cc = 1;
 	tr_n_preference = "local_mac";
 	pusch_proc_threads = 8;
-	}
+    }
 );
 
 RUs = (
@@ -292,5 +291,7 @@ rfsimulator :
        pdcp_log_verbosity                    ="medium";
        rrc_log_level                         ="info";
        rrc_log_verbosity                     ="medium";
+       ngap_log_level                         ="debug";
+       ngap_log_verbosity                     ="medium";
     };
 
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 52805981b8f8b3a2fea394d156d3048b81575023..bd0678e344c5e37d7fb9ed4a711ff053af8c0bff 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
@@ -1,4 +1,4 @@
-Active_gNBs = ( "gNB-Eurecom-5GNRBox");
+Active_gNBs = ( "gNB-Eurecom-DU");
 # Asn1_verbosity, choice in: none, info, annoying
 Asn1_verbosity = "none";
 
@@ -7,15 +7,28 @@ gNBs =
  {
     ////////// Identification parameters:
     gNB_ID    =  0xe00;
-
-    cell_type =  "CELL_MACRO_GNB";
-    gNB_name  =  "gNB-Eurecom-5GNRBox";
+    gNB_name  =  "gNB-Eurecom-DU";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
     tracking_area_code  =  1;
-    plmn_list = ({mcc = 208; mnc = 92; mnc_length = 2;});
-
-    tr_s_preference     = "local_mac"
+    plmn_list = ({
+                  mcc = 208;
+                  mnc = 99;
+                  mnc_length = 2;
+                  snssaiList = (
+                    {
+                      sst = 1;
+                      sd  = 0x1; // 0 false, else true
+                    },
+                    {
+                      sst = 1;
+                      sd  = 0x112233; // 0 false, else true
+                    }
+                  );
+
+                  });
+
+    nr_cellid = 12345678L;
 
     ////////// Physical parameters:
 
@@ -191,35 +204,21 @@ gNBs =
 
 
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "192.168.12.26";
+    amf_ip_address      = ( { ipv4       = "192.168.70.132";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
                             }
                           );
 
-    ///X2
-    enable_x2 = "no";
-    t_reloc_prep      = 1000;      /* unit: millisecond */
-    tx2_reloc_overall = 2000;      /* unit: millisecond */
-    t_dc_prep         = 1000;      /* unit: millisecond */
-    t_dc_overall      = 2000;      /* unit: millisecond */
-    target_enb_x2_ip_address      = (
-                                     { ipv4       = "CI_FR1_CTL_ENB_IP_ADDR";
-                                       ipv6       = "192:168:30::17";
-                                       preference = "ipv4";
-                                     }
-                                    );
 
     NETWORK_INTERFACES :
     {
-        GNB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
-        GNB_IPV4_ADDRESS_FOR_S1_MME              = "CI_GNB_IP_ADDR";
-        GNB_INTERFACE_NAME_FOR_S1U               = "eth0";
-        GNB_IPV4_ADDRESS_FOR_S1U                 = "CI_GNB_IP_ADDR";
+        GNB_INTERFACE_NAME_FOR_NG_AMF            = "demo-oai";
+        GNB_IPV4_ADDRESS_FOR_NG_AMF              = "192.168.70.129/24";
+        GNB_INTERFACE_NAME_FOR_NGU               = "demo-oai";
+        GNB_IPV4_ADDRESS_FOR_NGU                 = "192.168.70.129/24";
         GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
-        GNB_IPV4_ADDRESS_FOR_X2C                 = "CI_GNB_IP_ADDR";
-        GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
     };
 
   }
@@ -292,5 +291,7 @@ rfsimulator :
        pdcp_log_verbosity                    ="medium";
        rrc_log_level                         ="info";
        rrc_log_verbosity                     ="medium";
+       ngap_log_level                         ="debug";
+       ngap_log_verbosity                     ="medium";
     };
 
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index c21c04ba054c593e5bcb14aa86f82764953490d3..424a1390014a812d4725af72ff1122086ac14765 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -103,9 +103,6 @@ pthread_cond_t nfapi_sync_cond;
 pthread_mutex_t nfapi_sync_mutex;
 int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
 
-msc_interface_t msc_interface;
-
-
 uint16_t sf_ahead=4;
 
 pthread_cond_t sync_cond;
@@ -187,6 +184,7 @@ eth_params_t *eth_params;
 double cpuf;
 
 int oaisim_flag=0;
+uint8_t proto_agent_flag = 0;
 
 
 /* forward declarations */
diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c
index 1079f89c3fd52c83dc008f97d40ac76e9cf7f874..026e6d4a6061afc262b2a9f31d9c45c0ce371902 100644
--- a/targets/RT/USER/lte-uesoftmodem.c
+++ b/targets/RT/USER/lte-uesoftmodem.c
@@ -86,7 +86,6 @@
 #include "lte-softmodem.h"
 
 
-msc_interface_t msc_interface;
 /* temporary compilation wokaround (UE/eNB split */
 uint16_t sf_ahead;