diff --git a/CHANGELOG.md b/CHANGELOG.md
old mode 100644
new mode 100755
diff --git a/LICENSE b/LICENSE
old mode 100644
new mode 100755
diff --git a/charts/physims/Chart.yaml b/charts/physims/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..bef28aac2759f35d9e8a1963fb93450f4c4c2d61
--- /dev/null
+++ b/charts/physims/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-physim
+description: A Helm chart for physical simulators network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulators
+  - RAN
+  - 4G
+  - 5G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/dlsim/Chart.yaml b/charts/physims/charts/dlsim/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..de7f5958b2f967d70adeeca94e171a50775a31b8
--- /dev/null
+++ b/charts/physims/charts/dlsim/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-dlsim
+description: A Helm subchart for dlsim network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulator
+  - dlsim
+  - RAN
+  - 4G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/dlsim/templates/NOTES.txt b/charts/physims/charts/dlsim/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..75b79e3dd4d4a30be484fb6ff6b980eef9f56f22
--- /dev/null
+++ b/charts/physims/charts/dlsim/templates/NOTES.txt
@@ -0,0 +1,15 @@
+1. Get the application URL by running these commands:
+{{- if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-dlsim.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-dlsim.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-dlsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-dlsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/charts/physims/charts/dlsim/templates/_helpers.tpl b/charts/physims/charts/dlsim/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..7ae142b6719dca78536d59d81d459dcf8c353a1c
--- /dev/null
+++ b/charts/physims/charts/dlsim/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "oai-dlsim.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "oai-dlsim.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "oai-dlsim.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "oai-dlsim.labels" -}}
+helm.sh/chart: {{ include "oai-dlsim.chart" . }}
+{{ include "oai-dlsim.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "oai-dlsim.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "oai-dlsim.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "oai-dlsim.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "oai-dlsim.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/physims/charts/dlsim/templates/deployment.yaml b/charts/physims/charts/dlsim/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9cbdd383b35dcc1f19e7a0c02ccd6db658dda2ea
--- /dev/null
+++ b/charts/physims/charts/dlsim/templates/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-dlsim.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "oai-dlsim.selectorLabels" . | nindent 6 }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "oai-dlsim.selectorLabels" . | nindent 8 }}
+    spec:
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      containers:
+      - name: physim
+        image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        securityContext:
+          {{- toYaml .Values.securityContext | nindent 12 }}
+        ports:
+        - containerPort: 80
+          name: oai-dlsim
+        # volumeMounts:
+        # - mountPath: /opt/oai-dlsim/certs
+        #   name: certs
+        command: ["/bin/sh", "-c"]
+        args:
+        - >  
+          export OPENAIR_DIR=/opt/oai-physim &&
+          cd cmake_targets/autotests &&
+          ./run_exec_autotests.bash -g "015100" -q -np -b &&
+          echo "FINISHED" &&
+          sleep infinity
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      schedulerName: default-scheduler
+      serviceAccountName: {{ .Values.global.serviceAccountName }}
+      terminationGracePeriodSeconds: 30
diff --git a/charts/physims/charts/dlsim/templates/service.yaml b/charts/physims/charts/dlsim/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6aeb0dbf530981d9c209cdb7f766d00f1267cd23
--- /dev/null
+++ b/charts/physims/charts/dlsim/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-dlsim.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if  contains "ClusterIP" .Values.service.type }}
+  clusterIP: None
+{{- end }}
+  ports:
+    - name: oai-dlsim
+      # Port accessible outside cluster
+      port: {{ .Values.service.port }}
+      # Port to forward to inside the pod
+      targetPort: {{ .Values.service.Port }}
+      protocol: TCP
+  selector:
+    {{- include "oai-dlsim.selectorLabels" . | nindent 4 }}
diff --git a/charts/physims/charts/dlsim/values.yaml b/charts/physims/charts/dlsim/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c0142b50ae1704d9a0717c47891fb9f090549991
--- /dev/null
+++ b/charts/physims/charts/dlsim/values.yaml
@@ -0,0 +1,63 @@
+# Default values for oai-dlsim.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+namespace: "oaicicd-ran-tmp"
+
+image:
+  registry: local
+  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  version: temp
+  # pullPolicy: IfNotPresent or Never or Always
+  pullPolicy: Always
+
+imagePullSecrets: []
+
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: "oai-dlsim-sa"
+
+podSecurityContext:
+  runAsUser: 0
+  runAsGroup: 0
+
+securityContext:
+  privileged: true
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 80
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/charts/physims/charts/ldpctest/Chart.yaml b/charts/physims/charts/ldpctest/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..667bd3d8aa196ea9af9938a77e3f399c43016898
--- /dev/null
+++ b/charts/physims/charts/ldpctest/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-ldpctest
+description: A Helm subchart for ldpctest network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulator
+  - ldpctest
+  - RAN
+  - 5G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/ldpctest/templates/NOTES.txt b/charts/physims/charts/ldpctest/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bda83c2f9e732b8affd1131d0f33724ed3f0cd87
--- /dev/null
+++ b/charts/physims/charts/ldpctest/templates/NOTES.txt
@@ -0,0 +1,15 @@
+1. Get the application URL by running these commands:
+{{- if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-ldpctest.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-ldpctest.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-ldpctest.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-ldpctest.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/charts/physims/charts/ldpctest/templates/_helpers.tpl b/charts/physims/charts/ldpctest/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..018eaa5af5d6cd42c95f2d88fe2680b2f054b2c3
--- /dev/null
+++ b/charts/physims/charts/ldpctest/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "oai-ldpctest.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "oai-ldpctest.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "oai-ldpctest.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "oai-ldpctest.labels" -}}
+helm.sh/chart: {{ include "oai-ldpctest.chart" . }}
+{{ include "oai-ldpctest.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "oai-ldpctest.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "oai-ldpctest.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "oai-ldpctest.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "oai-ldpctest.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/physims/charts/ldpctest/templates/deployment.yaml b/charts/physims/charts/ldpctest/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ef30d9c08ad335dc4611d5798ae3edac560dbac6
--- /dev/null
+++ b/charts/physims/charts/ldpctest/templates/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-ldpctest.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "oai-ldpctest.selectorLabels" . | nindent 6 }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "oai-ldpctest.selectorLabels" . | nindent 8 }}
+    spec:
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      containers:
+      - name: physim
+        image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        securityContext:
+          {{- toYaml .Values.securityContext | nindent 12 }}
+        ports:
+        - containerPort: 80
+          name: oai-ldpctest
+        # volumeMounts:
+        # - mountPath: /opt/oai-ldpctest/certs
+        #   name: certs
+        command: ["/bin/sh", "-c"]
+        args:
+        - >  
+          export OPENAIR_DIR=/opt/oai-physim &&
+          cd cmake_targets/autotests &&
+          ./run_exec_autotests.bash -g "015102" -q -np -b &&
+          echo "FINISHED" &&
+          sleep infinity
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      schedulerName: default-scheduler
+      serviceAccountName: {{ .Values.global.serviceAccountName }}
+      terminationGracePeriodSeconds: 30
diff --git a/charts/physims/charts/ldpctest/templates/service.yaml b/charts/physims/charts/ldpctest/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..eb0db8ce00678d5d2610d8c765aa7231c74434eb
--- /dev/null
+++ b/charts/physims/charts/ldpctest/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-ldpctest.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if  contains "ClusterIP" .Values.service.type }}
+  clusterIP: None
+{{- end }}
+  ports:
+    - name: oai-ldpctest
+      # Port accessible outside cluster
+      port: {{ .Values.service.port }}
+      # Port to forward to inside the pod
+      targetPort: {{ .Values.service.Port }}
+      protocol: TCP
+  selector:
+    {{- include "oai-ldpctest.selectorLabels" . | nindent 4 }}
diff --git a/charts/physims/charts/ldpctest/values.yaml b/charts/physims/charts/ldpctest/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..91eab91af5418bd248a169d9e8d677a2852f866b
--- /dev/null
+++ b/charts/physims/charts/ldpctest/values.yaml
@@ -0,0 +1,63 @@
+# Default values for oai-ldpctest.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+namespace: "oaicicd-ran-tmp"
+
+image:
+  registry: local
+  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  version: temp
+  # pullPolicy: IfNotPresent or Never or Always
+  pullPolicy: Always
+
+imagePullSecrets: []
+
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: "oai-ldpctest-sa"
+
+podSecurityContext:
+  runAsUser: 0
+  runAsGroup: 0
+
+securityContext:
+  privileged: true
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 80
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/charts/physims/charts/nr-dlschsim/Chart.yaml b/charts/physims/charts/nr-dlschsim/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3837f0cd2ba60ccccfcfaeaa4764250d85dea995
--- /dev/null
+++ b/charts/physims/charts/nr-dlschsim/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-nr-dlschsim
+description: A Helm subchart for nr-dlschsim network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulator
+  - nr-dlschsim
+  - RAN
+  - 5G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/nr-dlschsim/templates/NOTES.txt b/charts/physims/charts/nr-dlschsim/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1f88d6497664fd9d3d18ad1504526673fce16077
--- /dev/null
+++ b/charts/physims/charts/nr-dlschsim/templates/NOTES.txt
@@ -0,0 +1,15 @@
+1. Get the application URL by running these commands:
+{{- if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-dlschsim.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-dlschsim.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-dlschsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-dlschsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/charts/physims/charts/nr-dlschsim/templates/_helpers.tpl b/charts/physims/charts/nr-dlschsim/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..6b6a5181e9da5557644dad51cc22303922457235
--- /dev/null
+++ b/charts/physims/charts/nr-dlschsim/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "oai-nr-dlschsim.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "oai-nr-dlschsim.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "oai-nr-dlschsim.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "oai-nr-dlschsim.labels" -}}
+helm.sh/chart: {{ include "oai-nr-dlschsim.chart" . }}
+{{ include "oai-nr-dlschsim.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "oai-nr-dlschsim.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "oai-nr-dlschsim.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "oai-nr-dlschsim.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "oai-nr-dlschsim.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/physims/charts/nr-dlschsim/templates/deployment.yaml b/charts/physims/charts/nr-dlschsim/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..06f01a0f0baeaa38a61bc85a0d6878302becb578
--- /dev/null
+++ b/charts/physims/charts/nr-dlschsim/templates/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-dlschsim.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "oai-nr-dlschsim.selectorLabels" . | nindent 6 }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "oai-nr-dlschsim.selectorLabels" . | nindent 8 }}
+    spec:
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      containers:
+      - name: physim
+        image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        securityContext:
+          {{- toYaml .Values.securityContext | nindent 12 }}
+        ports:
+        - containerPort: 80
+          name: oai-nr-dlschsim
+        # volumeMounts:
+        # - mountPath: /opt/oai-nr-dlschsim/certs
+        #   name: certs
+        command: ["/bin/sh", "-c"]
+        args:
+        - >  
+          export OPENAIR_DIR=/opt/oai-physim &&
+          cd cmake_targets/autotests &&
+          ./run_exec_autotests.bash -g "015106" -q -np -b &&
+          echo "FINISHED" &&
+          sleep infinity
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      schedulerName: default-scheduler
+      serviceAccountName: {{ .Values.global.serviceAccountName }}
+      terminationGracePeriodSeconds: 30
diff --git a/charts/physims/charts/nr-dlschsim/templates/service.yaml b/charts/physims/charts/nr-dlschsim/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0dd065c9e0a3d24cf5d499f3f0cc3f28b95f0391
--- /dev/null
+++ b/charts/physims/charts/nr-dlschsim/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-dlschsim.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if  contains "ClusterIP" .Values.service.type }}
+  clusterIP: None
+{{- end }}
+  ports:
+    - name: oai-nr-dlschsim
+      # Port accessible outside cluster
+      port: {{ .Values.service.port }}
+      # Port to forward to inside the pod
+      targetPort: {{ .Values.service.Port }}
+      protocol: TCP
+  selector:
+    {{- include "oai-nr-dlschsim.selectorLabels" . | nindent 4 }}
diff --git a/charts/physims/charts/nr-dlschsim/values.yaml b/charts/physims/charts/nr-dlschsim/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e96541102c4f30792350ec3a8aeacc9808bfe6e1
--- /dev/null
+++ b/charts/physims/charts/nr-dlschsim/values.yaml
@@ -0,0 +1,63 @@
+# Default values for oai-nr-dlschsim.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+namespace: "oaicicd-ran-tmp"
+
+image:
+  registry: local
+  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  version: temp
+  # pullPolicy: IfNotPresent or Never or Always
+  pullPolicy: Always
+
+imagePullSecrets: []
+
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: "oai-nr-dlschsim-sa"
+
+podSecurityContext:
+  runAsUser: 0
+  runAsGroup: 0
+
+securityContext:
+  privileged: true
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 80
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/charts/physims/charts/nr-dlsim/Chart.yaml b/charts/physims/charts/nr-dlsim/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2ec4b7eabdfbb97e2dbc71428c500f7ee42cc4e4
--- /dev/null
+++ b/charts/physims/charts/nr-dlsim/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-nr-dlsim
+description: A Helm subchart for nr-dlsim network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulator
+  - nr-dlsim
+  - RAN
+  - 5G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/nr-dlsim/templates/NOTES.txt b/charts/physims/charts/nr-dlsim/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..79027454cfbd9411a7cc6722e4e2fbe05beb039a
--- /dev/null
+++ b/charts/physims/charts/nr-dlsim/templates/NOTES.txt
@@ -0,0 +1,15 @@
+1. Get the application URL by running these commands:
+{{- if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-dlsim.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-dlsim.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-dlsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-dlsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/charts/physims/charts/nr-dlsim/templates/_helpers.tpl b/charts/physims/charts/nr-dlsim/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..1dd7fbd3fd5a7addca9d7969c9589a1b9d7e6302
--- /dev/null
+++ b/charts/physims/charts/nr-dlsim/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "oai-nr-dlsim.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "oai-nr-dlsim.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "oai-nr-dlsim.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "oai-nr-dlsim.labels" -}}
+helm.sh/chart: {{ include "oai-nr-dlsim.chart" . }}
+{{ include "oai-nr-dlsim.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "oai-nr-dlsim.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "oai-nr-dlsim.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "oai-nr-dlsim.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "oai-nr-dlsim.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/physims/charts/nr-dlsim/templates/deployment.yaml b/charts/physims/charts/nr-dlsim/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4c38664e61b14c8a473f1193b5686725a93089bc
--- /dev/null
+++ b/charts/physims/charts/nr-dlsim/templates/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-dlsim.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "oai-nr-dlsim.selectorLabels" . | nindent 6 }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "oai-nr-dlsim.selectorLabels" . | nindent 8 }}
+    spec:
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      containers:
+      - name: physim
+        image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        securityContext:
+          {{- toYaml .Values.securityContext | nindent 12 }}
+        ports:
+        - containerPort: 80
+          name: oai-nr-dlsim
+        # volumeMounts:
+        # - mountPath: /opt/oai-nr-dlsim/certs
+        #   name: certs
+        command: ["/bin/sh", "-c"]
+        args:
+        - >  
+          export OPENAIR_DIR=/opt/oai-physim &&
+          cd cmake_targets/autotests &&
+          ./run_exec_autotests.bash -g "015105" -q -np -b &&
+          echo "FINISHED" &&
+          sleep infinity
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      schedulerName: default-scheduler
+      serviceAccountName: {{ .Values.global.serviceAccountName }}
+      terminationGracePeriodSeconds: 30
diff --git a/charts/physims/charts/nr-dlsim/templates/service.yaml b/charts/physims/charts/nr-dlsim/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c58433f3b26f6a0a0b3c35620de392426c07381e
--- /dev/null
+++ b/charts/physims/charts/nr-dlsim/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-dlsim.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if  contains "ClusterIP" .Values.service.type }}
+  clusterIP: None
+{{- end }}
+  ports:
+    - name: oai-nr-dlsim
+      # Port accessible outside cluster
+      port: {{ .Values.service.port }}
+      # Port to forward to inside the pod
+      targetPort: {{ .Values.service.Port }}
+      protocol: TCP
+  selector:
+    {{- include "oai-nr-dlsim.selectorLabels" . | nindent 4 }}
diff --git a/charts/physims/charts/nr-dlsim/values.yaml b/charts/physims/charts/nr-dlsim/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c86fc96cff29c8b9b3cf83594aaa58711c4f0650
--- /dev/null
+++ b/charts/physims/charts/nr-dlsim/values.yaml
@@ -0,0 +1,63 @@
+# Default values for oai-nr-dlsim.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+namespace: "oaicicd-ran-tmp"
+
+image:
+  registry: local
+  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  version: temp
+  # pullPolicy: IfNotPresent or Never or Always
+  pullPolicy: Always
+
+imagePullSecrets: []
+
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: "oai-nr-dlsim-sa"
+
+podSecurityContext:
+  runAsUser: 0
+  runAsGroup: 0
+
+securityContext:
+  privileged: true
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 80
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/charts/physims/charts/nr-pbchsim/Chart.yaml b/charts/physims/charts/nr-pbchsim/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6d8359598d5f7ed1d155793817d8b7c408a9fa6a
--- /dev/null
+++ b/charts/physims/charts/nr-pbchsim/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-nr-pbchsim
+description: A Helm subchart for nr-pbchsim network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulator
+  - nr-pbchsim
+  - RAN
+  - 5G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/nr-pbchsim/templates/NOTES.txt b/charts/physims/charts/nr-pbchsim/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cee233d4f36c3380af3a4cb42af3b3b500243619
--- /dev/null
+++ b/charts/physims/charts/nr-pbchsim/templates/NOTES.txt
@@ -0,0 +1,15 @@
+1. Get the application URL by running these commands:
+{{- if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-pbchsim.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-pbchsim.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-pbchsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-pbchsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/charts/physims/charts/nr-pbchsim/templates/_helpers.tpl b/charts/physims/charts/nr-pbchsim/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..0e3103334384493a08e2c883f1cd9964fa1f400a
--- /dev/null
+++ b/charts/physims/charts/nr-pbchsim/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "oai-nr-pbchsim.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "oai-nr-pbchsim.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "oai-nr-pbchsim.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "oai-nr-pbchsim.labels" -}}
+helm.sh/chart: {{ include "oai-nr-pbchsim.chart" . }}
+{{ include "oai-nr-pbchsim.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "oai-nr-pbchsim.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "oai-nr-pbchsim.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "oai-nr-pbchsim.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "oai-nr-pbchsim.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/physims/charts/nr-pbchsim/templates/deployment.yaml b/charts/physims/charts/nr-pbchsim/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..551785abc0ddf08998599cef769a34ccc09f93f4
--- /dev/null
+++ b/charts/physims/charts/nr-pbchsim/templates/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-pbchsim.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "oai-nr-pbchsim.selectorLabels" . | nindent 6 }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "oai-nr-pbchsim.selectorLabels" . | nindent 8 }}
+    spec:
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      containers:
+      - name: physim
+        image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        securityContext:
+          {{- toYaml .Values.securityContext | nindent 12 }}
+        ports:
+        - containerPort: 80
+          name: oai-nr-pbchsim
+        # volumeMounts:
+        # - mountPath: /opt/oai-nr-pbchsim/certs
+        #   name: certs
+        command: ["/bin/sh", "-c"]
+        args:
+        - >  
+          export OPENAIR_DIR=/opt/oai-physim &&
+          cd cmake_targets/autotests &&
+          ./run_exec_autotests.bash -g "015104" -q -np -b &&
+          echo "FINISHED" &&
+          sleep infinity
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      schedulerName: default-scheduler
+      serviceAccountName: {{ .Values.global.serviceAccountName }}
+      terminationGracePeriodSeconds: 30
diff --git a/charts/physims/charts/nr-pbchsim/templates/service.yaml b/charts/physims/charts/nr-pbchsim/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..35faf3c33dae49955f814387c99a9c31c46871d2
--- /dev/null
+++ b/charts/physims/charts/nr-pbchsim/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-pbchsim.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if  contains "ClusterIP" .Values.service.type }}
+  clusterIP: None
+{{- end }}
+  ports:
+    - name: oai-nr-pbchsim
+      # Port accessible outside cluster
+      port: {{ .Values.service.port }}
+      # Port to forward to inside the pod
+      targetPort: {{ .Values.service.Port }}
+      protocol: TCP
+  selector:
+    {{- include "oai-nr-pbchsim.selectorLabels" . | nindent 4 }}
diff --git a/charts/physims/charts/nr-pbchsim/values.yaml b/charts/physims/charts/nr-pbchsim/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..62d89f9632c286708ff45fbc99ae387e66f753b3
--- /dev/null
+++ b/charts/physims/charts/nr-pbchsim/values.yaml
@@ -0,0 +1,63 @@
+# Default values for oai-nr-pbchsim.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+namespace: "oaicicd-ran-tmp"
+
+image:
+  registry: local
+  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  version: temp
+  # pullPolicy: IfNotPresent or Never or Always
+  pullPolicy: Always
+
+imagePullSecrets: []
+
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: "oai-nr-pbchsim-sa"
+
+podSecurityContext:
+  runAsUser: 0
+  runAsGroup: 0
+
+securityContext:
+  privileged: true
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 80
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/charts/physims/charts/nr-prachsim/Chart.yaml b/charts/physims/charts/nr-prachsim/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8c88587a7fd999914a6a4be755e56bf6e9136cde
--- /dev/null
+++ b/charts/physims/charts/nr-prachsim/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-nr-prachsim
+description: A Helm subchart for nr-prachsim network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulator
+  - nr-prachsim
+  - RAN
+  - 5G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/nr-prachsim/templates/NOTES.txt b/charts/physims/charts/nr-prachsim/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..376694e7e464ee2fe5996d0982e993485947ac55
--- /dev/null
+++ b/charts/physims/charts/nr-prachsim/templates/NOTES.txt
@@ -0,0 +1,15 @@
+1. Get the application URL by running these commands:
+{{- if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-prachsim.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-prachsim.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-prachsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-prachsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/charts/physims/charts/nr-prachsim/templates/_helpers.tpl b/charts/physims/charts/nr-prachsim/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..6362c72b2a6e89a79257a0d8f2b91caa84970ac9
--- /dev/null
+++ b/charts/physims/charts/nr-prachsim/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "oai-nr-prachsim.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "oai-nr-prachsim.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "oai-nr-prachsim.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "oai-nr-prachsim.labels" -}}
+helm.sh/chart: {{ include "oai-nr-prachsim.chart" . }}
+{{ include "oai-nr-prachsim.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "oai-nr-prachsim.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "oai-nr-prachsim.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "oai-nr-prachsim.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "oai-nr-prachsim.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/physims/charts/nr-prachsim/templates/deployment.yaml b/charts/physims/charts/nr-prachsim/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..52bc030c4591ba8ed74d424021cd91406087c5de
--- /dev/null
+++ b/charts/physims/charts/nr-prachsim/templates/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-prachsim.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "oai-nr-prachsim.selectorLabels" . | nindent 6 }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "oai-nr-prachsim.selectorLabels" . | nindent 8 }}
+    spec:
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      containers:
+      - name: physim
+        image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        securityContext:
+          {{- toYaml .Values.securityContext | nindent 12 }}
+        ports:
+        - containerPort: 80
+          name: oai-nr-prachsim
+        # volumeMounts:
+        # - mountPath: /opt/oai-nr-prachsim/certs
+        #   name: certs
+        command: ["/bin/sh", "-c"]
+        args:
+        - >  
+          export OPENAIR_DIR=/opt/oai-physim &&
+          cd cmake_targets/autotests &&
+          ./run_exec_autotests.bash -g "015112" -q -np -b &&
+          echo "FINISHED" &&
+          sleep infinity
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      schedulerName: default-scheduler
+      serviceAccountName: {{ .Values.global.serviceAccountName }}
+      terminationGracePeriodSeconds: 30
diff --git a/charts/physims/charts/nr-prachsim/templates/service.yaml b/charts/physims/charts/nr-prachsim/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..71bfe7b9feb524cf1ba1542b13d28ec93fa915c4
--- /dev/null
+++ b/charts/physims/charts/nr-prachsim/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-prachsim.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if  contains "ClusterIP" .Values.service.type }}
+  clusterIP: None
+{{- end }}
+  ports:
+    - name: oai-nr-prachsim
+      # Port accessible outside cluster
+      port: {{ .Values.service.port }}
+      # Port to forward to inside the pod
+      targetPort: {{ .Values.service.Port }}
+      protocol: TCP
+  selector:
+    {{- include "oai-nr-prachsim.selectorLabels" . | nindent 4 }}
diff --git a/charts/physims/charts/nr-prachsim/values.yaml b/charts/physims/charts/nr-prachsim/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3ea9787f7ab5cf660cfd98e7e61adddb1aa9b47e
--- /dev/null
+++ b/charts/physims/charts/nr-prachsim/values.yaml
@@ -0,0 +1,63 @@
+# Default values for oai-nr-prachsim.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+namespace: "oaicicd-ran-tmp"
+
+image:
+  registry: local
+  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  version: temp
+  # pullPolicy: IfNotPresent or Never or Always
+  pullPolicy: Always
+
+imagePullSecrets: []
+
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: "oai-nr-prachsim-sa"
+
+podSecurityContext:
+  runAsUser: 0
+  runAsGroup: 0
+
+securityContext:
+  privileged: true
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 80
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/charts/physims/charts/nr-pucchsim/Chart.yaml b/charts/physims/charts/nr-pucchsim/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..bb0033175f43bd73dd46f8474f19acd12e1b895d
--- /dev/null
+++ b/charts/physims/charts/nr-pucchsim/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-nr-pucchsim
+description: A Helm subchart for nr-pucchsim network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulator
+  - nr-pucchsim
+  - RAN
+  - 5G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/nr-pucchsim/templates/NOTES.txt b/charts/physims/charts/nr-pucchsim/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7c2cfa9155eff91c08bfeec4eb14b36c7f49cde4
--- /dev/null
+++ b/charts/physims/charts/nr-pucchsim/templates/NOTES.txt
@@ -0,0 +1,15 @@
+1. Get the application URL by running these commands:
+{{- if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-pucchsim.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-pucchsim.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-pucchsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-pucchsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/charts/physims/charts/nr-pucchsim/templates/_helpers.tpl b/charts/physims/charts/nr-pucchsim/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..210ba26db2f3e7e6aa07b36563c26792de3d5082
--- /dev/null
+++ b/charts/physims/charts/nr-pucchsim/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "oai-nr-pucchsim.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "oai-nr-pucchsim.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "oai-nr-pucchsim.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "oai-nr-pucchsim.labels" -}}
+helm.sh/chart: {{ include "oai-nr-pucchsim.chart" . }}
+{{ include "oai-nr-pucchsim.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "oai-nr-pucchsim.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "oai-nr-pucchsim.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "oai-nr-pucchsim.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "oai-nr-pucchsim.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/physims/charts/nr-pucchsim/templates/deployment.yaml b/charts/physims/charts/nr-pucchsim/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d783991e0b4a3f572b82ca2665c8443cd4465dde
--- /dev/null
+++ b/charts/physims/charts/nr-pucchsim/templates/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-pucchsim.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "oai-nr-pucchsim.selectorLabels" . | nindent 6 }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "oai-nr-pucchsim.selectorLabels" . | nindent 8 }}
+    spec:
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      containers:
+      - name: physim
+        image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        securityContext:
+          {{- toYaml .Values.securityContext | nindent 12 }}
+        ports:
+        - containerPort: 80
+          name: oai-nr-pucchsim
+        # volumeMounts:
+        # - mountPath: /opt/oai-nr-pucchsim/certs
+        #   name: certs
+        command: ["/bin/sh", "-c"]
+        args:
+        - >  
+          export OPENAIR_DIR=/opt/oai-physim &&
+          cd cmake_targets/autotests &&
+          ./run_exec_autotests.bash -g "015109" -q -np -b &&
+          echo "FINISHED" &&
+          sleep infinity
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      schedulerName: default-scheduler
+      serviceAccountName: {{ .Values.global.serviceAccountName }}
+      terminationGracePeriodSeconds: 30
diff --git a/charts/physims/charts/nr-pucchsim/templates/service.yaml b/charts/physims/charts/nr-pucchsim/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9e8760e76b68834a00451cd1d3e71ec72e2cd719
--- /dev/null
+++ b/charts/physims/charts/nr-pucchsim/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-pucchsim.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if  contains "ClusterIP" .Values.service.type }}
+  clusterIP: None
+{{- end }}
+  ports:
+    - name: oai-nr-pucchsim
+      # Port accessible outside cluster
+      port: {{ .Values.service.port }}
+      # Port to forward to inside the pod
+      targetPort: {{ .Values.service.Port }}
+      protocol: TCP
+  selector:
+    {{- include "oai-nr-pucchsim.selectorLabels" . | nindent 4 }}
diff --git a/charts/physims/charts/nr-pucchsim/values.yaml b/charts/physims/charts/nr-pucchsim/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cf50c0bd3cf8a82feaef6911203e6422b39858ad
--- /dev/null
+++ b/charts/physims/charts/nr-pucchsim/values.yaml
@@ -0,0 +1,63 @@
+# Default values for oai-nr-pucchsim.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+namespace: "oaicicd-ran-tmp"
+
+image:
+  registry: local
+  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  version: temp
+  # pullPolicy: IfNotPresent or Never or Always
+  pullPolicy: Always
+
+imagePullSecrets: []
+
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: "oai-nr-pucchsim-sa"
+
+podSecurityContext:
+  runAsUser: 0
+  runAsGroup: 0
+
+securityContext:
+  privileged: true
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 80
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/charts/physims/charts/nr-ulschsim/Chart.yaml b/charts/physims/charts/nr-ulschsim/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e2525f0032b35ab32188cae55d43b49664da5804
--- /dev/null
+++ b/charts/physims/charts/nr-ulschsim/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-nr-ulschsim
+description: A Helm subchart for nr-ulschsim network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulator
+  - nr-ulschsim
+  - RAN
+  - 5G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/nr-ulschsim/templates/NOTES.txt b/charts/physims/charts/nr-ulschsim/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..65566932cd7c96f2951ac2f9a445492e852d0e21
--- /dev/null
+++ b/charts/physims/charts/nr-ulschsim/templates/NOTES.txt
@@ -0,0 +1,15 @@
+1. Get the application URL by running these commands:
+{{- if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-ulschsim.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-ulschsim.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-ulschsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-ulschsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/charts/physims/charts/nr-ulschsim/templates/_helpers.tpl b/charts/physims/charts/nr-ulschsim/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..9aa13a81f062e3d0a610fc2434e850d77baf634f
--- /dev/null
+++ b/charts/physims/charts/nr-ulschsim/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "oai-nr-ulschsim.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "oai-nr-ulschsim.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "oai-nr-ulschsim.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "oai-nr-ulschsim.labels" -}}
+helm.sh/chart: {{ include "oai-nr-ulschsim.chart" . }}
+{{ include "oai-nr-ulschsim.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "oai-nr-ulschsim.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "oai-nr-ulschsim.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "oai-nr-ulschsim.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "oai-nr-ulschsim.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/physims/charts/nr-ulschsim/templates/deployment.yaml b/charts/physims/charts/nr-ulschsim/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..56fb0de5b878954ca95179d0c49a60d10a0af102
--- /dev/null
+++ b/charts/physims/charts/nr-ulschsim/templates/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-ulschsim.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "oai-nr-ulschsim.selectorLabels" . | nindent 6 }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "oai-nr-ulschsim.selectorLabels" . | nindent 8 }}
+    spec:
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      containers:
+      - name: physim
+        image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        securityContext:
+          {{- toYaml .Values.securityContext | nindent 12 }}
+        ports:
+        - containerPort: 80
+          name: oai-nr-ulschsim
+        # volumeMounts:
+        # - mountPath: /opt/oai-nr-ulschsim/certs
+        #   name: certs
+        command: ["/bin/sh", "-c"]
+        args:
+        - >  
+          export OPENAIR_DIR=/opt/oai-physim &&
+          cd cmake_targets/autotests &&
+          ./run_exec_autotests.bash -g "015108" -q -np -b &&
+          echo "FINISHED" &&
+          sleep infinity
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      schedulerName: default-scheduler
+      serviceAccountName: {{ .Values.global.serviceAccountName }}
+      terminationGracePeriodSeconds: 30
diff --git a/charts/physims/charts/nr-ulschsim/templates/service.yaml b/charts/physims/charts/nr-ulschsim/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d34882700e1b84e8bef58187701c2eb89276011c
--- /dev/null
+++ b/charts/physims/charts/nr-ulschsim/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-ulschsim.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if  contains "ClusterIP" .Values.service.type }}
+  clusterIP: None
+{{- end }}
+  ports:
+    - name: oai-nr-ulschsim
+      # Port accessible outside cluster
+      port: {{ .Values.service.port }}
+      # Port to forward to inside the pod
+      targetPort: {{ .Values.service.Port }}
+      protocol: TCP
+  selector:
+    {{- include "oai-nr-ulschsim.selectorLabels" . | nindent 4 }}
diff --git a/charts/physims/charts/nr-ulschsim/values.yaml b/charts/physims/charts/nr-ulschsim/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..420b15459655986e89640e20ca2a23b747816528
--- /dev/null
+++ b/charts/physims/charts/nr-ulschsim/values.yaml
@@ -0,0 +1,63 @@
+# Default values for oai-nr-ulschsim.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+namespace: "oaicicd-ran-tmp"
+
+image:
+  registry: local
+  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  version: temp
+  # pullPolicy: IfNotPresent or Never or Always
+  pullPolicy: Always
+
+imagePullSecrets: []
+
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: "oai-nr-ulschsim-sa"
+
+podSecurityContext:
+  runAsUser: 0
+  runAsGroup: 0
+
+securityContext:
+  privileged: true
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 80
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/charts/physims/charts/nr-ulsim/Chart.yaml b/charts/physims/charts/nr-ulsim/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ede87ea7e487e3e1ccbec9e04fb77e1d168143bc
--- /dev/null
+++ b/charts/physims/charts/nr-ulsim/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-nr-ulsim
+description: A Helm subchart for nr-ulsim network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulator
+  - nr-ulsim
+  - RAN
+  - 5G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/nr-ulsim/templates/NOTES.txt b/charts/physims/charts/nr-ulsim/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6865eeaedf096ad070079aec1d024a9bf2358145
--- /dev/null
+++ b/charts/physims/charts/nr-ulsim/templates/NOTES.txt
@@ -0,0 +1,15 @@
+1. Get the application URL by running these commands:
+{{- if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-nr-ulsim.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-nr-ulsim.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-nr-ulsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-nr-ulsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/charts/physims/charts/nr-ulsim/templates/_helpers.tpl b/charts/physims/charts/nr-ulsim/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..90f0bd0e363db238d832517cc87b56011ddb3986
--- /dev/null
+++ b/charts/physims/charts/nr-ulsim/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "oai-nr-ulsim.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "oai-nr-ulsim.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "oai-nr-ulsim.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "oai-nr-ulsim.labels" -}}
+helm.sh/chart: {{ include "oai-nr-ulsim.chart" . }}
+{{ include "oai-nr-ulsim.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "oai-nr-ulsim.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "oai-nr-ulsim.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "oai-nr-ulsim.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "oai-nr-ulsim.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/physims/charts/nr-ulsim/templates/deployment.yaml b/charts/physims/charts/nr-ulsim/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c0fa5ceb3b1b28c578c4cf6b1be3623574b15a68
--- /dev/null
+++ b/charts/physims/charts/nr-ulsim/templates/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-ulsim.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "oai-nr-ulsim.selectorLabels" . | nindent 6 }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "oai-nr-ulsim.selectorLabels" . | nindent 8 }}
+    spec:
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      containers:
+      - name: physim
+        image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        securityContext:
+          {{- toYaml .Values.securityContext | nindent 12 }}
+        ports:
+        - containerPort: 80
+          name: oai-nr-ulsim
+        # volumeMounts:
+        # - mountPath: /opt/oai-nr-ulsim/certs
+        #   name: certs
+        command: ["/bin/sh", "-c"]
+        args:
+        - >  
+          export OPENAIR_DIR=/opt/oai-physim &&
+          cd cmake_targets/autotests &&
+          ./run_exec_autotests.bash -g "015111" -q -np -b &&
+          echo "FINISHED" &&
+          sleep infinity
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      schedulerName: default-scheduler
+      serviceAccountName: {{ .Values.global.serviceAccountName }}
+      terminationGracePeriodSeconds: 30
diff --git a/charts/physims/charts/nr-ulsim/templates/service.yaml b/charts/physims/charts/nr-ulsim/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..95f198d1b123ca859866da0a76c050905e0202cd
--- /dev/null
+++ b/charts/physims/charts/nr-ulsim/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-nr-ulsim.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if  contains "ClusterIP" .Values.service.type }}
+  clusterIP: None
+{{- end }}
+  ports:
+    - name: oai-nr-ulsim
+      # Port accessible outside cluster
+      port: {{ .Values.service.port }}
+      # Port to forward to inside the pod
+      targetPort: {{ .Values.service.Port }}
+      protocol: TCP
+  selector:
+    {{- include "oai-nr-ulsim.selectorLabels" . | nindent 4 }}
diff --git a/charts/physims/charts/nr-ulsim/values.yaml b/charts/physims/charts/nr-ulsim/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7eb8e33fcbcab2c83442fe5b024034bfe2753970
--- /dev/null
+++ b/charts/physims/charts/nr-ulsim/values.yaml
@@ -0,0 +1,63 @@
+# Default values for oai-nr-ulsim.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+namespace: "oaicicd-ran-tmp"
+
+image:
+  registry: local
+  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  version: temp
+  # pullPolicy: IfNotPresent or Never or Always
+  pullPolicy: Always
+
+imagePullSecrets: []
+
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: "oai-nr-ulsim-sa"
+
+podSecurityContext:
+  runAsUser: 0
+  runAsGroup: 0
+
+securityContext:
+  privileged: true
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 80
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/charts/physims/charts/polartest/Chart.yaml b/charts/physims/charts/polartest/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ae5f5ca2631bbb94472c14d0f91672ceb2f970b9
--- /dev/null
+++ b/charts/physims/charts/polartest/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-polartest
+description: A Helm subchart for polartest network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulator
+  - polartest
+  - RAN
+  - 4G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/polartest/templates/NOTES.txt b/charts/physims/charts/polartest/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9c2c978de0ddf27df5f59b0a04345ee455abeb21
--- /dev/null
+++ b/charts/physims/charts/polartest/templates/NOTES.txt
@@ -0,0 +1,15 @@
+1. Get the application URL by running these commands:
+{{- if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-polartest.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-polartest.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-polartest.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-polartest.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/charts/physims/charts/polartest/templates/_helpers.tpl b/charts/physims/charts/polartest/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..ce81dbe525587d8abf510f6de73bde4bfb5484bd
--- /dev/null
+++ b/charts/physims/charts/polartest/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "oai-polartest.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "oai-polartest.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "oai-polartest.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "oai-polartest.labels" -}}
+helm.sh/chart: {{ include "oai-polartest.chart" . }}
+{{ include "oai-polartest.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "oai-polartest.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "oai-polartest.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "oai-polartest.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "oai-polartest.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/physims/charts/polartest/templates/deployment.yaml b/charts/physims/charts/polartest/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..01a6efc815b7cba88f777b4fc0c495960845f582
--- /dev/null
+++ b/charts/physims/charts/polartest/templates/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-polartest.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "oai-polartest.selectorLabels" . | nindent 6 }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "oai-polartest.selectorLabels" . | nindent 8 }}
+    spec:
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      containers:
+      - name: physim
+        image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        securityContext:
+          {{- toYaml .Values.securityContext | nindent 12 }}
+        ports:
+        - containerPort: 80
+          name: oai-polartest
+        # volumeMounts:
+        # - mountPath: /opt/oai-polartest/certs
+        #   name: certs
+        command: ["/bin/sh", "-c"]
+        args:
+        - >  
+          export OPENAIR_DIR=/opt/oai-physim &&
+          cd cmake_targets/autotests &&
+          ./run_exec_autotests.bash -g "015103" -q -np -b &&
+          echo "FINISHED" &&
+          sleep infinity
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      schedulerName: default-scheduler
+      serviceAccountName: {{ .Values.global.serviceAccountName }}
+      terminationGracePeriodSeconds: 30
diff --git a/charts/physims/charts/polartest/templates/service.yaml b/charts/physims/charts/polartest/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..40abb6769eb3128366b2658326c13a5e8069d7e0
--- /dev/null
+++ b/charts/physims/charts/polartest/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-polartest.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if  contains "ClusterIP" .Values.service.type }}
+  clusterIP: None
+{{- end }}
+  ports:
+    - name: oai-polartest
+      # Port accessible outside cluster
+      port: {{ .Values.service.port }}
+      # Port to forward to inside the pod
+      targetPort: {{ .Values.service.Port }}
+      protocol: TCP
+  selector:
+    {{- include "oai-polartest.selectorLabels" . | nindent 4 }}
diff --git a/charts/physims/charts/polartest/values.yaml b/charts/physims/charts/polartest/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..496dc8afba245c7c8204618cd01dc4509bf27897
--- /dev/null
+++ b/charts/physims/charts/polartest/values.yaml
@@ -0,0 +1,63 @@
+# Default values for oai-polartest.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+namespace: "oaicicd-ran-tmp"
+
+image:
+  registry: local
+  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  version: temp
+  # pullPolicy: IfNotPresent or Never or Always
+  pullPolicy: Always
+
+imagePullSecrets: []
+
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: "oai-polartest-sa"
+
+podSecurityContext:
+  runAsUser: 0
+  runAsGroup: 0
+
+securityContext:
+  privileged: true
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 80
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/charts/physims/charts/smallblocktest/Chart.yaml b/charts/physims/charts/smallblocktest/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..74092783aec9c3f36cf0d286368b709b843736b2
--- /dev/null
+++ b/charts/physims/charts/smallblocktest/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-smallblocktest
+description: A Helm subchart for smallblocktest network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulator
+  - smallblocktest
+  - RAN
+  - 4G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/smallblocktest/templates/NOTES.txt b/charts/physims/charts/smallblocktest/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c593dbfe223177cfe73ae6b911aeff0cdb3ac54d
--- /dev/null
+++ b/charts/physims/charts/smallblocktest/templates/NOTES.txt
@@ -0,0 +1,15 @@
+1. Get the application URL by running these commands:
+{{- if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-smallblocktest.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-smallblocktest.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-smallblocktest.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-smallblocktest.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/charts/physims/charts/smallblocktest/templates/_helpers.tpl b/charts/physims/charts/smallblocktest/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..a3c264b33ebf817d52f0319a03512403d342713e
--- /dev/null
+++ b/charts/physims/charts/smallblocktest/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "oai-smallblocktest.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "oai-smallblocktest.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "oai-smallblocktest.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "oai-smallblocktest.labels" -}}
+helm.sh/chart: {{ include "oai-smallblocktest.chart" . }}
+{{ include "oai-smallblocktest.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "oai-smallblocktest.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "oai-smallblocktest.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "oai-smallblocktest.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "oai-smallblocktest.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/physims/charts/smallblocktest/templates/deployment.yaml b/charts/physims/charts/smallblocktest/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3439c2597ed787be2d53102c8ce4c719314fddeb
--- /dev/null
+++ b/charts/physims/charts/smallblocktest/templates/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-smallblocktest.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "oai-smallblocktest.selectorLabels" . | nindent 6 }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "oai-smallblocktest.selectorLabels" . | nindent 8 }}
+    spec:
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      containers:
+      - name: physim
+        image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        securityContext:
+          {{- toYaml .Values.securityContext | nindent 12 }}
+        ports:
+        - containerPort: 80
+          name: oai-smallblock
+        # volumeMounts:
+        # - mountPath: /opt/oai-smallblocktest/certs
+        #   name: certs
+        command: ["/bin/sh", "-c"]
+        args:
+        - >  
+          export OPENAIR_DIR=/opt/oai-physim &&
+          cd cmake_targets/autotests &&
+          ./run_exec_autotests.bash -g "015107" -q -np -b &&
+          echo "FINISHED" &&
+          sleep infinity
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      schedulerName: default-scheduler
+      serviceAccountName: {{ .Values.global.serviceAccountName }}
+      terminationGracePeriodSeconds: 30
diff --git a/charts/physims/charts/smallblocktest/templates/service.yaml b/charts/physims/charts/smallblocktest/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d51bf21ce4c1dcc45031c00fb18894dbf0218f84
--- /dev/null
+++ b/charts/physims/charts/smallblocktest/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-smallblocktest.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if  contains "ClusterIP" .Values.service.type }}
+  clusterIP: None
+{{- end }}
+  ports:
+    - name: oai-smallblocktest
+      # Port accessible outside cluster
+      port: {{ .Values.service.port }}
+      # Port to forward to inside the pod
+      targetPort: {{ .Values.service.Port }}
+      protocol: TCP
+  selector:
+    {{- include "oai-smallblocktest.selectorLabels" . | nindent 4 }}
diff --git a/charts/physims/charts/smallblocktest/values.yaml b/charts/physims/charts/smallblocktest/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9dd791265f2416098e2a2406286337a10ca88a46
--- /dev/null
+++ b/charts/physims/charts/smallblocktest/values.yaml
@@ -0,0 +1,63 @@
+# Default values for oai-smallblocktest.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+namespace: "oaicicd-ran-tmp"
+
+image:
+  registry: local
+  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  version: temp
+  # pullPolicy: IfNotPresent or Never or Always
+  pullPolicy: Always
+
+imagePullSecrets: []
+
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: "oai-smallblocktest-sa"
+
+podSecurityContext:
+  runAsUser: 0
+  runAsGroup: 0
+
+securityContext:
+  privileged: true
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 80
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/charts/physims/charts/ulsim/Chart.yaml b/charts/physims/charts/ulsim/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2311d729b4c3aad7ae49641baf5f62778efd5d0b
--- /dev/null
+++ b/charts/physims/charts/ulsim/Chart.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+name: oai-ulsim
+description: A Helm subchart for ulsim network function
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+version: 0.1.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application.
+appVersion: v1
+
+keywords:
+  - Physical Simulator
+  - ulsim
+  - RAN
+  - 4G
+
+sources:
+  - https://gitlab.eurecom.fr/oai/openairinterface5g
+
+maintainers:
+  - name:  OPENAIRINTERFACE
+    email: contact@openairinterface.org
diff --git a/charts/physims/charts/ulsim/templates/NOTES.txt b/charts/physims/charts/ulsim/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..91ab3ce0b7a523af4cdb8d9829cd982362ee8651
--- /dev/null
+++ b/charts/physims/charts/ulsim/templates/NOTES.txt
@@ -0,0 +1,15 @@
+1. Get the application URL by running these commands:
+{{- if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oai-ulsim.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oai-ulsim.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oai-ulsim.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oai-ulsim.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/charts/physims/charts/ulsim/templates/_helpers.tpl b/charts/physims/charts/ulsim/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..67b65004791cfa3231dffacac4232b4f9dbd4a6d
--- /dev/null
+++ b/charts/physims/charts/ulsim/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "oai-ulsim.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "oai-ulsim.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "oai-ulsim.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "oai-ulsim.labels" -}}
+helm.sh/chart: {{ include "oai-ulsim.chart" . }}
+{{ include "oai-ulsim.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "oai-ulsim.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "oai-ulsim.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "oai-ulsim.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "oai-ulsim.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/physims/charts/ulsim/templates/deployment.yaml b/charts/physims/charts/ulsim/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e8c90dabc1857c673d8a6a51d8c1da40d799ea2d
--- /dev/null
+++ b/charts/physims/charts/ulsim/templates/deployment.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-ulsim.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "oai-ulsim.selectorLabels" . | nindent 6 }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "oai-ulsim.selectorLabels" . | nindent 8 }}
+    spec:
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      containers:
+      - name: physim
+        image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        securityContext:
+          {{- toYaml .Values.securityContext | nindent 12 }}
+        ports:
+        - containerPort: 80
+          name: oai-ulsim
+        # volumeMounts:
+        # - mountPath: /opt/oai-ulsim/certs
+        #   name: certs
+        command: ["/bin/sh", "-c"]
+        args:
+        - >  
+          export OPENAIR_DIR=/opt/oai-physim &&
+          cd cmake_targets/autotests &&
+          ./run_exec_autotests.bash -g "015101" -q -np -b &&
+          echo "FINISHED" &&
+          sleep infinity
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      schedulerName: default-scheduler
+      serviceAccountName: {{ .Values.global.serviceAccountName }}
+      terminationGracePeriodSeconds: 30
diff --git a/charts/physims/charts/ulsim/templates/service.yaml b/charts/physims/charts/ulsim/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..dcc37d6299461562d9ecfc7776cbb1b0f7fd10c8
--- /dev/null
+++ b/charts/physims/charts/ulsim/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Chart.Name }}
+  labels:
+    {{- include "oai-ulsim.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if  contains "ClusterIP" .Values.service.type }}
+  clusterIP: None
+{{- end }}
+  ports:
+    - name: oai-ulsim
+      # Port accessible outside cluster
+      port: {{ .Values.service.port }}
+      # Port to forward to inside the pod
+      targetPort: {{ .Values.service.Port }}
+      protocol: TCP
+  selector:
+    {{- include "oai-ulsim.selectorLabels" . | nindent 4 }}
diff --git a/charts/physims/charts/ulsim/values.yaml b/charts/physims/charts/ulsim/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f5110989d86bb5db489151e88202256f0e57c54e
--- /dev/null
+++ b/charts/physims/charts/ulsim/values.yaml
@@ -0,0 +1,63 @@
+# Default values for oai-ulsim.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+namespace: "oaicicd-ran-tmp"
+
+image:
+  registry: local
+  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  version: temp
+  # pullPolicy: IfNotPresent or Never or Always
+  pullPolicy: Always
+
+imagePullSecrets: []
+
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: "oai-ulsim-sa"
+
+podSecurityContext:
+  runAsUser: 0
+  runAsGroup: 0
+
+securityContext:
+  privileged: true
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 80
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/charts/physims/templates/rbac.yaml b/charts/physims/templates/rbac.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..35f956a203beaf004b75369e524147dc0afabf1b
--- /dev/null
+++ b/charts/physims/templates/rbac.yaml
@@ -0,0 +1,12 @@
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+  name: {{ .Chart.Name }}-{{ .Values.global.namespace }}-rbac
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: cluster-admin
+subjects:
+- kind: ServiceAccount
+  name: {{ .Values.global.serviceAccountName }}
+  namespace: {{ .Values.global.namespace }}
diff --git a/charts/physims/templates/serviceaccount.yaml b/charts/physims/templates/serviceaccount.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..21d094ad38b154cfba02982fad63b7ab3cb61936
--- /dev/null
+++ b/charts/physims/templates/serviceaccount.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ .Values.global.serviceAccountName }}
diff --git a/charts/physims/values.yaml b/charts/physims/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b348e822bb0e2e64ed7ae2f2c1c6e737f0afd5ec
--- /dev/null
+++ b/charts/physims/values.yaml
@@ -0,0 +1,84 @@
+# Default values for oai-physim.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+global:
+  serviceAccountName: oai-physim-sa
+  namespace: "oaicicd-ran-tmp"
+  image:
+    repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+    version: TAG
+
+## Declaring values specific to coressponding physim to overwrite
+
+dlsim:
+  replicaCount: 1
+  service:
+    type: ClusterIP
+    port: 80
+
+ulsim:
+  replicaCount: 1
+  service:
+    type: ClusterIP
+    port: 80
+
+ldpctest:
+  replicaCount: 1
+  service:
+    type: ClusterIP
+    port: 80
+
+polartest:
+  replicaCount: 1
+  service:
+    type: ClusterIP
+    port: 80
+
+nr-pbchsim:
+  replicaCount: 1
+  service:
+    type: ClusterIP
+    port: 80
+
+nr-dlsim:
+  replicaCount: 1
+  service:
+    type: ClusterIP
+    port: 80
+
+nr-dlschsim:
+  replicaCount: 1
+  service:
+    type: ClusterIP
+    port: 80
+
+smallblocktest:
+  replicaCount: 1
+  service:
+    type: ClusterIP
+    port: 80
+
+nr-ulschsim:
+  replicaCount: 1
+  service:
+    type: ClusterIP
+    port: 80
+
+nr-pucchsim:
+  replicaCount: 1
+  service:
+    type: ClusterIP
+    port: 80
+
+nr-ulsim:
+  replicaCount: 1
+  service:
+    type: ClusterIP
+    port: 80
+
+nr-prachsim:
+  replicaCount: 1
+  service:
+    type: ClusterIP
+    port: 80
diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container
new file mode 100644
index 0000000000000000000000000000000000000000..f4b99e7f9246928a38d555b585aaab75bd9201d0
--- /dev/null
+++ b/ci-scripts/Jenkinsfile-GitLab-Container
@@ -0,0 +1,327 @@
+#!/bin/groovy
+/*
+ * 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
+ */
+
+// Location of the executor node
+def nodeExecutor = params.nodeExecutor
+
+// Tags to shorten pipeline duration
+def doMandatoryTests = false
+def doFullTestsuite = false
+
+//
+def gitCommitAuthorEmailAddr
+
+pipeline {
+  agent {
+    label nodeExecutor
+  }
+  options {
+    disableConcurrentBuilds()
+    timestamps()
+    gitLabConnection('OAI GitLab')
+    ansiColor('xterm')
+  }
+
+  stages {
+    stage ("Verify Parameters") {
+      steps {
+        script {
+          JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"'
+          JOB_TIMESTAMP = JOB_TIMESTAMP.trim()
+
+          echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
+          def allParametersPresent = true
+
+          echo '\u2705 \u001B[32mVerify Labels\u001B[0m'
+          if ("MERGE".equals(env.gitlabActionType)) {
+            LABEL_CHECK = sh returnStdout: true, script: 'ci-scripts/checkGitLabMergeRequestLabels.sh --mr-id ' + env.gitlabMergeRequestIid
+            LABEL_CHECK = LABEL_CHECK.trim()
+            if (LABEL_CHECK == 'NONE') {
+              def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Your merge request has none of the mandatory labels:\n\n"
+              message += " - BUILD-ONLY\n"
+              message += " - 4G-LTE\n"
+              message += " - 5G-NR\n"
+              message += " - CI\n\n"
+              message += "Not performing CI due to lack of labels"
+              addGitLabMRComment comment: message
+              error('Not performing CI due to lack of labels')
+            } else if (LABEL_CHECK == 'FULL') {
+              doMandatoryTests = true
+              doFullTestsuite = true
+            } else if (LABEL_CHECK == 'SHORTEN-5G') {
+              doMandatoryTests = true
+            } else {
+              def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): We will perform only build stages on your Merge Request"
+              addGitLabMRComment comment: message
+            }
+          } else {
+            doMandatoryTests = true
+            doFullTestsuite = true
+          }
+        }
+      }
+    }
+    stage ("Verify Guidelines") {
+      steps {
+        echo "Git URL     is ${GIT_URL}"
+        echo "GitLab Act    is ${env.gitlabActionType}"
+        script {
+          if ("MERGE".equals(env.gitlabActionType)) {
+            // since a bit, in push events, gitlabUserEmail is not populated
+            gitCommitAuthorEmailAddr = env.gitlabUserEmail
+            echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}"
+            // GitLab-Jenkins plugin integration is lacking to perform the merge by itself
+            // Doing it manually --> it may have merge conflicts
+            sh "./ci-scripts/doGitLabMerge.sh --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
+          } else {
+            echo "Git Branch    is ${GIT_BRANCH}"
+            echo "Git Commit    is ${GIT_COMMIT}"
+            // since a bit, in push events, gitlabUserEmail is not populated
+            gitCommitAuthorEmailAddr = sh returnStdout: true, script: 'git log -n1 --pretty=format:%ae ${GIT_COMMIT}'
+            gitCommitAuthorEmailAddr = gitCommitAuthorEmailAddr.trim()
+            echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}"
+            sh "git log -n1 --pretty=format:\"%s\" > .git/CI_COMMIT_MSG"
+          }
+        }
+      }
+      post {
+        failure {
+          script {
+            def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Merge Conflicts -- Cannot perform CI"
+            addGitLabMRComment comment: message
+            currentBuild.result = 'FAILURE'
+          }
+        }
+      }
+    }
+    // Build Stages are Mandatory
+    // Later we will add a Ubuntu20 build
+    stage ("Image Building Processes") {
+      parallel {
+        stage ("Ubuntu18 Build") {
+          steps {
+            script {
+              triggerSlaveJob ('RAN-Ubuntu18-Image-Builder', 'Ubuntu18-Images-Build')
+            }
+          }
+          post {
+            always {
+              script {
+                finalizeSlaveJob('RAN-Ubuntu18-Image-Builder')
+              }
+            }
+            failure {
+              script {
+                currentBuild.result = 'FAILURE'
+              }
+            }
+          }
+        }
+        stage ("RHEL8 Build") {
+          steps {
+            script {
+              triggerSlaveJob ('RAN-RHEL8-Image-Builder', 'RHEL8-Images-Build')
+            }
+          }
+          post {
+            always {
+              script {
+                finalizeSlaveJob('RAN-RHEL8-Image-Builder')
+              }
+            }
+            failure {
+              script {
+                currentBuild.result = 'FAILURE'
+              }
+            }
+          }
+        }
+        stage ("CppCheck Analysis") {
+          steps {
+            script {
+              triggerSlaveJob ('RAN-cppcheck', 'CppCheck Analysis')
+            }
+          }
+          post {
+            always {
+              script {
+                finalizeSlaveJob('RAN-cppcheck')
+              }
+            }
+            failure {
+              script {
+                currentBuild.result = 'FAILURE'
+              }
+            }
+          }
+        }
+      }
+    }
+    stage ("Image Test Processes") {
+      parallel {
+        stage ("Physical Simulators") {
+          when { expression {doMandatoryTests} }
+          steps {
+            script {
+              triggerSlaveJob ('RAN-PhySim-Cluster', 'Test-Physim-Cluster')
+            }
+          }
+          post {
+            always {
+              script {
+                finalizeSlaveJob('RAN-PhySim-Cluster')
+              }
+            }
+            failure {
+              script {
+                currentBuild.result = 'FAILURE'
+              }
+            }
+          }
+        }
+        stage ("RF Simulators") {
+          when { expression {doMandatoryTests} }
+          steps {
+            script {
+              triggerSlaveJob ('RAN-RF-Sim-Test', 'Test-RF-Sim-Container')
+            }
+          }
+          post {
+            always {
+              script {
+                finalizeSlaveJob('RAN-RF-Sim-Test')
+              }
+            }
+            failure {
+              script {
+                currentBuild.result = 'FAILURE'
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  post {
+    always {
+      script {
+        def eSubject = JOB_NAME + ' - Build # ' + BUILD_ID + ' - ' + currentBuild.result + '!'
+        def eBody = "Hi,\n\n"
+        eBody += "Here are attached HTML report files for " + JOB_NAME + "  - Build # " + BUILD_ID + " - " + currentBuild.result + "!\n\n"
+        eBody += "Regards,\n"
+        eBody += "OAI CI Team"
+        emailext attachmentsPattern: '*results*.html',
+           body: eBody,
+           replyTo: 'no-reply@openairinterface.org',
+           subject: eSubject,
+           to: gitCommitAuthorEmailAddr
+
+        if (fileExists('.git/CI_COMMIT_MSG')) {
+          sh "rm -f .git/CI_COMMIT_MSG"
+        }
+      }
+    }
+    success {
+      script {
+        def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ")"
+        if ("MERGE".equals(env.gitlabActionType)) {
+          echo "This is a MERGE event"
+          addGitLabMRComment comment: message
+        }
+      }
+    }
+    failure {
+      script {
+        def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ")"
+        if ("MERGE".equals(env.gitlabActionType)) {
+          echo "This is a MERGE event"
+          addGitLabMRComment comment: message
+        }
+      }
+    }
+  }
+}
+
+// ----  Slave Job functions
+
+def triggerSlaveJob (jobName, gitlabStatusName) {
+  // Workaround for the "cancelled" GitLab pipeline notification
+  // The slave job is triggered with the propagate false so the following commands are executed
+  // Its status is now PASS/SUCCESS from a stage pipeline point of view
+  // localStatus variable MUST be analyzed to properly assess the status
+  localStatus = build job: jobName,
+    parameters: [
+      string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)),
+      string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)),
+      string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)),
+      booleanParam(name: 'eNB_mergeRequest', value: "MERGE".equals(env.gitlabActionType)),
+      string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch))
+    ], propagate: false
+  localResult = localStatus.getResult()
+  echo "${jobName} Slave Job status is ${localResult}"
+  gitlabCommitStatus(name: gitlabStatusName) {
+    if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) {
+       echo "${jobName} Slave Job is OK"
+    } else {
+       echo "${jobName} Slave Job is KO"
+       sh "ci-scripts/fail.sh"
+    }
+  }
+}
+
+def triggerSlaveJobNoGitLab (jobName) {
+  // Workaround for the "cancelled" GitLab pipeline notification
+  // The slave job is triggered with the propagate false so the following commands are executed
+  // Its status is now PASS/SUCCESS from a stage pipeline point of view
+  // localStatus variable MUST be analyzed to properly assess the status
+  localStatus = build job: jobName,
+    parameters: [
+      string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)),
+      string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)),
+      string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)),
+      booleanParam(name: 'eNB_mergeRequest', value: "MERGE".equals(env.gitlabActionType)),
+      string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch))
+    ], propagate: false
+  localResult = localStatus.getResult()
+  echo "${jobName} Slave Job status is ${localResult}"
+  if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) {
+     echo "${jobName} Slave Job is OK"
+  } else {
+     echo "${jobName} Slave Job is KO"
+     sh "ci-scripts/fail.sh"
+  }
+}
+
+def finalizeSlaveJob(jobName) {
+  // In case of any non-success, we are retrieving the HTML report of the last completed
+  // slave job. The only drop-back is that we may retrieve the HTML report of a previous build
+  fileName = "test_results-${jobName}.html"
+  if (!fileExists(fileName)) {
+    copyArtifacts(projectName: jobName,
+      filter: 'test_results*.html',
+      selector: lastCompleted())
+    if (fileExists(fileName)) {
+      sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' ${fileName}"
+      archiveArtifacts artifacts: fileName
+    }
+  }
+}
diff --git a/openair2/UTIL/TRACE/fifo_printf_proto_extern.h b/ci-scripts/Jenkinsfile-git-dashboard
similarity index 60%
rename from openair2/UTIL/TRACE/fifo_printf_proto_extern.h
rename to ci-scripts/Jenkinsfile-git-dashboard
index 0855a8da93fae86ab950db4df8722a9f3f72ea29..6ebd46bc762410647c059ad02af2272ac679c0e9 100644
--- a/openair2/UTIL/TRACE/fifo_printf_proto_extern.h
+++ b/ci-scripts/Jenkinsfile-git-dashboard
@@ -1,3 +1,4 @@
+#!/bin/groovy
 /*
  * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -19,23 +20,26 @@
  *      contact@openairinterface.org
  */
 
-/***************************************************************************
-                          fifo_printf_proto_extern.h  -  description
-                             -------------------
-  AUTHOR  : Lionel GAUTHIER
-  COMPANY : EURECOM
-  EMAIL   : Lionel.Gauthier@eurecom.fr
+// Template Jenkins Declarative Pipeline script to run Test w/ RF HW
 
+// Location of the python executor node shall be in the same subnet as the others servers
+def pythonExecutor = params.pythonExecutor
+
+
+pipeline {
+    agent {
+        label pythonExecutor
+    }
+    stages {
+        stage ("gDashboard") {
+            steps {
+                script {     
+                    //retrieve MR data from gitlab and export to gSheet            
+                    sh returnStdout: true, script: 'python3 ci-scripts/ran_dashboard.py'
+                }                                  
+            }   
+        }
+    }
+}
 
 
- ***************************************************************************/
-#ifndef __FIFO_PRINTF_PROTO_EXTERN_H__
-#    define __FIFO_PRINTF_PROTO_EXTERN_H__
-#ifdef FIFO_PRINTF
-extern void     fifo_printf_init (void);
-extern void     fifo_printf_clean_up (void);
-extern int      fifo_printf (const char *fmt, ...);
-#else
-extern int      fifo_printf_null (const char *fmt, ...);
-#endif
-#endif
diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab
index ff661543c0001279b5f81203ed82383fd5ed0241..6b53230c097981053140ba424a42b600d1e7218e 100644
--- a/ci-scripts/Jenkinsfile-gitlab
+++ b/ci-scripts/Jenkinsfile-gitlab
@@ -30,8 +30,6 @@ def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) {
     }
 }
 
-def doFlexranCtrlTest = false
-
 // Location of the executor node
 def nodeExecutor = params.nodeExecutor
 
@@ -66,9 +64,6 @@ pipeline {
                         echo "Platform is ${env.TESTPLATFORM_OWNER}"
                     }
 
-                    if (params.FlexRanRtcGitLabRepository_Credentials != null) {
-                        doFlexranCtrlTest = true
-                    }
                     if (fileExists("flexran")) {
                         sh "rm -Rf flexran > /dev/null 2>&1"
                     }
@@ -141,15 +136,13 @@ pipeline {
                         // For the moment, there is no fail criteria. Just a notification of number of files that do not follow
                         sh "./ci-scripts/checkCodingFormattingRules.sh"
                     }
-                    if (doFlexranCtrlTest && doMandatoryTests) {
+                    // With Mosaic 5G being part of OSA and making all it's repositories public
+                    // No need to pass credentials to clone flexran-rtc
+                    if (doMandatoryTests) {
                         sh "mkdir flexran"
                         dir ('flexran') {
-                            withCredentials([
-                                [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.FlexRanRtcGitLabRepository_Credentials}", usernameVariable: 'git_username', passwordVariable: 'git_password']
-                                ]) {
-                                sh "git clone https://${git_username}:${git_password}@gitlab.eurecom.fr/flexran/flexran-rtc.git . > ../git_clone.log 2>&1"
-                                sh "git checkout develop >> ../git_clone.log 2>&1"
-                            }
+                            sh "git clone https://gitlab.eurecom.fr/flexran/flexran-rtc.git . > ../git_clone.log 2>&1"
+                            sh "git checkout develop >> ../git_clone.log 2>&1"
                             sh "zip -r -qq flexran.zip ."
                         }
                     }
@@ -196,26 +189,6 @@ pipeline {
             }
         }
 
-        stage ("Start VM -- enb-usrp") {
-            steps {
-              lock (vmResource) {
-                timeout (time: 5, unit: 'MINUTES') {
-                    sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
-                }
-              }
-            }
-        }
-
-        stage ("Start VM -- phy-sim") {
-            steps {
-              lock (vmResource) {
-                timeout (time: 5, unit: 'MINUTES') {
-                    sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
-                }
-              }
-            }
-        }
-        
         stage ("Start VM -- enb-ethernet") {
             steps {
               lock (vmResource) {
@@ -234,33 +207,14 @@ pipeline {
                 }
               }
             }
-        }
+   }
         
-        stage ("Start VM -- cppcheck") {
-            steps {
-              lock (vmResource) {
-                timeout (time: 7, unit: 'MINUTES') {
-                    sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
-                }
-              }
-            }
-        }
-
         stage ("Variant Builds") {
             parallel {
-                stage ("Analysis with cppcheck") {
-                    steps {
-                        gitlabCommitStatus(name: "Analysis with cppcheck") {
-                            timeout (time: 20, unit: 'MINUTES') {
-                                sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
-                            }
-                        }
-                    }
-                }
                 stage ("Build basic simulator") {
                     steps {
                         gitlabCommitStatus(name: "Build basic-sim") {
-                            timeout (time: 20, unit: 'MINUTES') {
+                            timeout (time: 45, unit: 'MINUTES') {
                                 sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
                             }
                         }
@@ -269,7 +223,7 @@ pipeline {
                 stage ("Build 5G gNB-USRP") {
                     steps {
                         gitlabCommitStatus(name: "Build gNB-USRP") {
-                            timeout (time: 20, unit: 'MINUTES') {
+                            timeout (time: 45, unit: 'MINUTES') {
                                 sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
                             }
                         }
@@ -278,34 +232,16 @@ pipeline {
                 stage ("Build 5G NR-UE-USRP") {
                     steps {
                         gitlabCommitStatus(name: "Build nr-UE-USRP") {
-                            timeout (time: 20, unit: 'MINUTES') {
+                            timeout (time: 45, unit: 'MINUTES') {
                                 sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
                             }
                         }
                     }
                 }
-                stage ("Build eNB-USRP") {
-                    steps {
-                        gitlabCommitStatus(name: "Build eNB-USRP") {
-                            timeout (time: 20, unit: 'MINUTES') {
-                                sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
-                            }
-                        }
-                    }
-                }
-                stage ("Build physical simulators") {
-                    steps {
-                        gitlabCommitStatus(name: "Build phy-sim") {
-                            timeout (time: 20, unit: 'MINUTES') {
-                               sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
-                            }
-                        }
-                    }
-                }
                 stage ("Build eNB-ethernet") {
                     steps {
                         gitlabCommitStatus(name: "Build eNB-ethernet") {
-                            timeout (time: 20, unit: 'MINUTES') {
+                            timeout (time: 45, unit: 'MINUTES') {
                                 sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
                             }
                         }
@@ -316,7 +252,7 @@ pipeline {
                       // This is typically the last one to finish.
                       lock (vmResource) {
                         gitlabCommitStatus(name: "Build UE-ethernet") {
-                            timeout (time: 20, unit: 'MINUTES') {
+                            timeout (time: 45, unit: 'MINUTES') {
                                 sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
                             }
                         }
@@ -334,9 +270,9 @@ pipeline {
                     script {
                         dir ('archives') {
                             if (fileExists('red_hat')) {
-                                sh "zip -r -qq vm_build_logs.zip basic_sim enb_usrp phy_sim cppcheck enb_eth ue_eth gnb_usrp nr_ue_usrp red_hat"
+                                sh "zip -r -qq vm_build_logs.zip basic_sim enb_eth ue_eth gnb_usrp nr_ue_usrp red_hat"
                             } else {
-                                sh "zip -r -qq vm_build_logs.zip basic_sim enb_usrp phy_sim cppcheck enb_eth ue_eth gnb_usrp nr_ue_usrp"
+                                sh "zip -r -qq vm_build_logs.zip basic_sim enb_eth ue_eth gnb_usrp nr_ue_usrp"
                             }
                         }
                         if(fileExists('archives/vm_build_logs.zip')) {
@@ -344,16 +280,6 @@ pipeline {
                         }
                         if ("MERGE".equals(env.gitlabActionType)) {
                             sh "./ci-scripts/oai-ci-vm-tool report-build --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
-                            // If the merge request has introduced more CPPCHECK errors or warnings, notifications in GitLab
-                            if (fileExists('oai_cppcheck_added_errors.txt')) {
-                                def ret=readFile('./oai_cppcheck_added_errors.txt').trim();
-                                if ("0".equals(ret)) {
-                                    echo "No added cppcheck warnings/errors in this merge request"
-                                } else {
-                                    def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Some modified files in Merge Request MAY have INTRODUCED up to " + ret + " CPPCHECK errors/warnings"
-                                    addGitLabMRComment comment: message
-                                }
-                            }
                             // If the merge request has introduced compilation warnings, notifications in GitLab
                             sh "./ci-scripts/checkAddedWarnings.sh --src-branch ${env.gitlabSourceBranch} --target-branch ${env.gitlabTargetBranch}"
                             def res=readFile('./oai_warning_files.txt').trim();
@@ -380,18 +306,16 @@ pipeline {
             parallel {
                 stage ("VM-based tests") {
                     stages {
-                        stage ("Test physical simulators") {
+                        stage ("Build Flexran Controller") {
                             when {
                                 expression {doMandatoryTests}
                             }
                             steps {
                               lock (vmResource) {
                                 script {
-                                    timeout (time: 90, unit: 'MINUTES') {
+                                    timeout (time: 20, unit: 'MINUTES') {
                                         try {
-                                            gitlabCommitStatus(name: "Test phy-sim") {
-                                                sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
-                                            }
+                                            sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant flexran-rtc --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
                                         } catch (Exception e) {
                                           currentBuild.result = 'FAILURE'
                                         }
@@ -400,16 +324,18 @@ pipeline {
                               }
                             }
                         }
-                        stage ("Build Flexran Controller") {
+                        stage ("Test basic simulator") {
                             when {
-                                expression {doFlexranCtrlTest && doMandatoryTests}
+                                expression {doMandatoryTests}
                             }
                             steps {
                               lock (vmResource) {
                                 script {
-                                    timeout (time: 20, unit: 'MINUTES') {
+                                    timeout (time: 30, unit: 'MINUTES') {
                                         try {
-                                            sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant flexran-rtc --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
+                                            gitlabCommitStatus(name: "Test basic-sim") {
+                                                sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
+                                            }
                                         } catch (Exception e) {
                                           currentBuild.result = 'FAILURE'
                                         }
@@ -418,7 +344,7 @@ pipeline {
                               }
                             }
                         }
-                        stage ("Test basic simulator") {
+                        stage ("Test L1 simulator") {
                             when {
                                 expression {doMandatoryTests}
                             }
@@ -427,28 +353,28 @@ pipeline {
                                 script {
                                     timeout (time: 30, unit: 'MINUTES') {
                                         try {
-                                            gitlabCommitStatus(name: "Test basic-sim") {
-                                                sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
+                                            gitlabCommitStatus(name: "Test L1-sim") {
+                                                sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l1-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
                                             }
                                         } catch (Exception e) {
-                                          currentBuild.result = 'FAILURE'
+                                            currentBuild.result = 'FAILURE'
                                         }
                                     }
                                 }
                               }
                             }
                         }
-                        stage ("Test L1 simulator") {
+                        stage ("Test RF simulator") {
                             when {
                                 expression {doMandatoryTests}
                             }
                             steps {
                               lock (vmResource) {
                                 script {
-                                    timeout (time: 30, unit: 'MINUTES') {
+                                    timeout (time: 40, unit: 'MINUTES') {
                                         try {
-                                            gitlabCommitStatus(name: "Test L1-sim") {
-                                                sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l1-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
+                                            gitlabCommitStatus(name: "Test RF-sim") {
+                                                sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant rf-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
                                             }
                                         } catch (Exception e) {
                                             currentBuild.result = 'FAILURE'
@@ -458,7 +384,7 @@ pipeline {
                               }
                             }
                         }
-                        stage ("Test RF simulator") {
+                        stage ("Test 5G RF simulator") {
                             when {
                                 expression {doMandatoryTests}
                             }
@@ -467,8 +393,8 @@ pipeline {
                                 script {
                                     timeout (time: 40, unit: 'MINUTES') {
                                         try {
-                                            gitlabCommitStatus(name: "Test RF-sim") {
-                                                sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant rf-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
+                                            gitlabCommitStatus(name: "Test 5G RF-sim") {
+                                                sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant rf5g-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
                                             }
                                         } catch (Exception e) {
                                             currentBuild.result = 'FAILURE'
@@ -764,7 +690,7 @@ pipeline {
                     script {
                       if (doMandatoryTests) {
                         dir ('archives') {
-                            sh "if [ -d basic_sim/test ] || [ -d phy_sim/test ] || [ -d l2_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi"
+                            sh "if [ -d basic_sim/test ] || [ -d rf_sim/test ] || [ -d l2_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi"
                         }
                         if(fileExists('archives/vm_tests_logs.zip')) {
                             archiveArtifacts artifacts: 'archives/vm_tests_logs.zip'
diff --git a/ci-scripts/Jenkinsfile-physim-deploy b/ci-scripts/Jenkinsfile-physim-deploy
new file mode 100644
index 0000000000000000000000000000000000000000..eac572e6cdcb12bc06af68e7905d8b97218445af
--- /dev/null
+++ b/ci-scripts/Jenkinsfile-physim-deploy
@@ -0,0 +1,233 @@
+#!/bin/groovy
+/*
+ * 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
+ */
+
+// Location of the executor node
+def pythonExecutor = params.pythonExecutor
+
+// Location of the test XML file to be run
+def testXMLFile = params.pythonTestXmlFile
+def mainPythonAllXmlFiles = ""
+def buildStageStatus = true
+
+// Name of the test stage
+def testStageName = params.pipelineTestStageName
+
+// Name of the resource
+def ciEpcResource = params.epcResource
+
+// Global Parameters. Normally they should be populated when the master job
+// triggers the slave job with parameters
+def eNB_Repository
+def eNB_Branch
+def eNB_CommitID
+def eNB_AllowMergeRequestProcess = false
+def eNB_TargetBranch
+
+// Flags
+def scmEvent = false
+def upstreamEvent = false
+
+//-------------------------------------------------------------------------------
+// Pipeline start
+pipeline {
+  agent {
+    label pythonExecutor
+  }
+  options {
+    disableConcurrentBuilds()
+    timestamps()
+    ansiColor('xterm')
+    lock(ciEpcResource)
+  }
+
+  stages {
+    stage ('Verify Parameters') {
+      steps {
+        script {
+          echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
+
+          JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"'
+          JOB_TIMESTAMP = JOB_TIMESTAMP.trim()
+
+          def allParametersPresent = true
+
+          // It is already to late to check it
+          if (params.pythonExecutor != null) {
+            echo "eNB CI executor node  :   ${pythonExecutor}"
+          }
+          // If not present picking a default Stage Name
+          if (params.pipelineTestStageName == null) {
+            // picking default
+            testStageName = 'Template Test Stage'
+          }
+
+          if (params.smartphonesResource == null) {
+            allParametersPresent = false
+          }
+          if (params.eNB_IPAddress == null) {
+            allParametersPresent = false
+          }
+          if (params.eNB_SourceCodePath == null) {
+            allParametersPresent = false
+          }
+          if (params.eNB_Credentials == null) {
+            allParametersPresent = false
+          }
+          // the following 4 parameters should be pushed by the master trigger
+          // if not present, take the job GIT variables (used for developing)
+          if (params.eNB_Repository == null) {
+            eNB_Repository = env.GIT_URL
+          } else {
+            eNB_Repository = params.eNB_Repository
+          }
+          echo "eNB_Repository        :   ${eNB_Repository}"
+          if (params.eNB_Branch == null) {
+            eNB_Branch = env.GIT_BRANCH
+          } else {
+            eNB_Branch = params.eNB_Branch
+          }
+          echo "eNB_Branch            :   ${eNB_Branch}"
+          if (params.eNB_CommitID == null) {
+            eNB_CommitID = env.GIT_COMMIT
+          } else {
+            eNB_CommitID = params.eNB_CommitID
+          }
+          echo "eNB_CommitID          :   ${eNB_CommitID}"
+          if (params.eNB_mergeRequest != null) {
+            eNB_AllowMergeRequestProcess = params.eNB_mergeRequest
+            if (eNB_AllowMergeRequestProcess) {
+              if (params.eNB_TargetBranch != null) {
+                eNB_TargetBranch = params.eNB_TargetBranch
+              } else {
+                eNB_TargetBranch = 'develop'
+              }
+              echo "eNB_TargetBranch      :   ${eNB_TargetBranch}"
+            }
+          }
+
+          if (params.EPC_IPAddress == null) {
+            allParametersPresent = false
+          }
+          if (params.EPC_Type == null) {
+            allParametersPresent = false
+          }
+          if (params.EPC_SourceCodePath == null) {
+            allParametersPresent = false
+          }
+          if (params.EPC_Credentials == null) {
+            allParametersPresent = false
+          }
+
+          if (params.ADB_IPAddress == null) {
+            allParametersPresent = false
+          }
+          if (params.ADB_Credentials == null) {
+            allParametersPresent = false
+          }
+          if (params.OC_Credentials == null) {
+            allParametersPresent = false
+          }
+          if (params.OC_ProjectName == null) {
+            allParametersPresent = false
+          }
+          if (allParametersPresent) {
+            echo "All parameters are present"
+            if (eNB_AllowMergeRequestProcess) {
+              sh "git fetch"
+              sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest"
+            } else {
+              sh "git fetch"
+              sh "git checkout -f ${eNB_CommitID}"
+            }
+          } else {
+            echo "Some parameters are missing"
+            sh "./ci-scripts/fail.sh"
+          }
+        }
+      }
+    }
+
+    stage ("Deploy and Test") {
+      steps {
+        script {
+          dir ('ci-scripts') {
+            echo "\u2705 \u001B[32m${testStageName}\u001B[0m"
+            // If not present picking a default XML file
+            if (params.pythonTestXmlFile == null) {
+              // picking default
+              testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml'
+              echo "Test XML file(default):   ${testXMLFile}"
+              mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " "
+            } else {
+              String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
+              for (xmlFile in myXmlTestSuite) {
+                if (fileExists(xmlFile)) {
+                  mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " "
+                  echo "Test XML file         :   ${xmlFile}"
+                }
+              }
+            }
+            withCredentials([
+              [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
+              [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
+              [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'],
+              [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password']
+            ]) {
+              sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
+              String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
+              for (xmlFile in myXmlTestSuite) {
+                if (fileExists(xmlFile)) {
+                  try {
+                    sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}"
+                  } catch (Exception e) {
+                    currentBuild.result = 'FAILURE'
+                    buildStageStatus = false
+                  }
+                }
+              }
+              sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
+            }
+          }
+        } 
+      }
+    }
+    stage ("Log Collection") {
+      steps {
+        script {
+          dir ('ci-scripts') {
+            // Zipping all archived log files
+            sh "zip -r -qq physim_deploytest_logs_${env.BUILD_ID}.zip physim_test_logs_*/*"
+            sh "rm -rf physim_test_logs_*/"
+            if (fileExists("physim_deploytest_logs_${env.BUILD_ID}.zip")) {
+              archiveArtifacts artifacts: "physim_deploytest_logs_${env.BUILD_ID}.zip"
+            }
+            if (fileExists("test_results.html")) {
+              sh "mv test_results.html test_results-${env.JOB_NAME}.html"
+              sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
+              archiveArtifacts artifacts: "test_results-${env.JOB_NAME}.html"
+            }
+          }
+        }
+      }
+    }
+  }  
+}  
diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb-benetel b/ci-scripts/Jenkinsfile-tmp-multi-enb-benetel
new file mode 100644
index 0000000000000000000000000000000000000000..8ac2e6adffa3a5d5d3f434e8f936b6de33da667f
--- /dev/null
+++ b/ci-scripts/Jenkinsfile-tmp-multi-enb-benetel
@@ -0,0 +1,293 @@
+#!/bin/groovy
+/*
+ * 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
+ */
+
+// Template Jenkins Declarative Pipeline script to run Test w/ RF HW
+
+// Location of the python executor node shall be in the same subnet as the others servers
+def pythonExecutor = params.pythonExecutor
+
+// Location of the test XML file to be run
+def testXMLFile = params.pythonTestXmlFile
+def mainPythonAllXmlFiles = ""
+def buildStageStatus = true
+
+// Name of the test stage
+def testStageName = params.pipelineTestStageName
+
+// Name of the phone resource
+def ciSmartPhonesResource1 = params.SmartPhonesResource1
+def ciSmartPhonesResource2 = params.SmartPhonesResource2
+
+// Global Parameters. Normally they should be populated when the master job
+// triggers the slave job with parameters
+def eNB_Repository
+def eNB_Branch
+def eNB_CommitID
+def eNB_AllowMergeRequestProcess
+def eNB_TargetBranch
+
+pipeline {
+    agent {
+        label pythonExecutor
+    }
+    options {
+        disableConcurrentBuilds()
+        ansiColor('xterm')
+        lock(extra: [[resource: ciSmartPhonesResource2]], resource: ciSmartPhonesResource1)
+    }
+    stages {
+        stage("Build Init") {
+            steps {
+                // update the build name and description
+                buildName "${params.eNB_MR}"
+                buildDescription "Branch : ${params.eNB_Branch}"
+            }
+        }
+        stage ("Verify Parameters") {
+            steps {
+                script {
+                    echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
+                    def allParametersPresent = true
+
+                    // It is already to late to check it
+                    if (params.pythonExecutor != null) {
+                        echo "eNB CI executor node  :   ${pythonExecutor}"
+                    }
+                    // If not present picking a default Stage Name
+                    if (params.pipelineTestStageName == null) {
+                        // picking default
+                        testStageName = 'Template Test Stage'
+                    }
+
+                    if (params.SmartPhonesResource1 == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.SmartPhonesResource2 == null) {
+                        allParametersPresent = false
+                    }
+                    // 1st eNB parameters
+                    if (params.eNB_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB_Credentials == null) {
+                        allParametersPresent = false
+                    }
+                    // 2nd eNB parameters
+                    if (params.eNB1_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB1_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB1_Credentials == null) {
+                        allParametersPresent = false
+                    }
+                    // 3rd eNB parameters
+                    if (params.eNB2_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB2_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB2_Credentials == null) {
+                        allParametersPresent = false
+                    }
+                    // the following 4 parameters should be pushed by the master trigger
+                    // if not present, take the job GIT variables (used for developing)
+                    if (params.eNB_Repository == null) {
+                        eNB_Repository = env.GIT_URL
+                    } else {
+                        eNB_Repository = params.eNB_Repository
+                    }
+                    echo "eNB_Repository        :   ${eNB_Repository}"
+                    if (params.eNB_Branch == null) {
+                        eNB_Branch = env.GIT_BRANCH
+                    } else {
+                        eNB_Branch = params.eNB_Branch
+                    }
+                    echo "eNB_Branch            :   ${eNB_Branch}"
+                    if (params.eNB_CommitID == null) {
+                        eNB_CommitID = env.GIT_COMMIT
+                    } else {
+                        eNB_CommitID = params.eNB_CommitID
+                    }
+                    echo "eNB_CommitID          :   ${eNB_CommitID}"
+                    if (params.eNB_AllowMergeRequestProcess!= null) {
+                        eNB_AllowMergeRequestProcess = params.eNB_AllowMergeRequestProcess
+                        if (eNB_AllowMergeRequestProcess) {
+                            if (params.eNB_TargetBranch != null) {
+                                eNB_TargetBranch = params.eNB_TargetBranch
+                            } else {
+                                eNB_TargetBranch = 'develop'
+                            }
+                            echo "eNB_TargetBranch      :   ${eNB_TargetBranch}"
+                        }
+                    }
+
+                    if (params.EPC_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.EPC_Type == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.EPC_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.EPC_Credentials == null) {
+                        allParametersPresent = false
+                    }
+
+                    if (params.ADB_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.ADB_Credentials == null) {
+                        allParametersPresent = false
+                    }
+
+                    if (allParametersPresent) {
+                        echo "All parameters are present"
+                        if (eNB_AllowMergeRequestProcess) {
+                            sh "git fetch"
+                            sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest"
+                        } else {
+                            sh "git fetch"
+                            sh "git checkout -f ${eNB_CommitID}"
+                        }
+                    } else {
+                        echo "Some parameters are missing"
+                        sh "./ci-scripts/fail.sh"
+                    }
+                }
+            }
+        }
+        stage ("Build and Test") {
+            steps {
+                script {
+                    dir ('ci-scripts') {
+                        echo "\u2705 \u001B[32m${testStageName}\u001B[0m"
+                        // If not present picking a default XML file
+                        if (params.pythonTestXmlFile == null) {
+                            // picking default
+                            testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml'
+                            echo "Test XML file(default):   ${testXMLFile}"
+                            mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " "
+                        } else {
+                            String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
+                            for (xmlFile in myXmlTestSuite) {
+                                if (fileExists(xmlFile)) {
+                                    mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " "
+                                    echo "Test XML file         :   ${xmlFile}"
+                                }
+                            }
+                        }
+                        withCredentials([
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB2_Credentials}", usernameVariable: 'eNB2_Username', passwordVariable: 'eNB2_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
+                        ]) {
+                            sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
+                            String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
+                            for (xmlFile in myXmlTestSuite) {
+                                if (fileExists(xmlFile)) {
+                                    try {
+                                        sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}"
+                                    } catch (Exception e) {
+                                        currentBuild.result = 'FAILURE'
+                                        buildStageStatus = false
+                                    }
+                                }
+                            }
+                            sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
+                        }
+                    }
+                }
+            }
+        }
+        stage('Log Collection') {
+            parallel {
+                stage('Log Collection (eNB - Build)') {
+                    steps {
+                        withCredentials([
+                             [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
+                        ]) {
+                            echo '\u2705 \u001B[32mLog Collection (eNB - Build)\u001B[0m'
+                            sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
+
+                            echo '\u2705 \u001B[32mLog Transfer (eNB - Build)\u001B[0m'
+                            sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true"
+                        }
+                        script {
+                            if(fileExists("build.log.${env.BUILD_ID}.zip")) {
+                                archiveArtifacts "build.log.${env.BUILD_ID}.zip"
+                            }
+                        }
+                    }
+                }
+                stage('Log Collection (eNB - Run)') {
+                    steps {
+                        withCredentials([
+                             [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
+                        ]) {
+                            echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
+                            sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
+
+                            echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m'
+                            sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true"
+                        }
+                        script {
+                            if(fileExists("enb.log.${env.BUILD_ID}.zip")) {
+                                archiveArtifacts "enb.log.${env.BUILD_ID}.zip"
+                            }
+                            if(fileExists("ci-scripts/test_results.html")) {
+                                sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html"
+                                sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
+                                archiveArtifacts "test_results-${JOB_NAME}.html"
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    post {
+        always {
+            script {
+                if (params.pipelineZipsConsoleLog != null) {
+                    if (params.pipelineZipsConsoleLog) {
+                        echo "Archiving Jenkins console log"
+                        sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true"
+                        sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true"
+                        if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) {
+                            archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip"
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb-benetel-long b/ci-scripts/Jenkinsfile-tmp-multi-enb-benetel-long
new file mode 100644
index 0000000000000000000000000000000000000000..fb7f3738d2a763bdf2e204ab53f3c0dbdc8da125
--- /dev/null
+++ b/ci-scripts/Jenkinsfile-tmp-multi-enb-benetel-long
@@ -0,0 +1,304 @@
+#!/bin/groovy
+/*
+ * 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
+ */
+
+// Template Jenkins Declarative Pipeline script to run Test w/ RF HW
+
+// Location of the python executor node shall be in the same subnet as the others servers
+def pythonExecutor = params.pythonExecutor
+
+// Location of the test XML file to be run
+def testXMLFile = params.pythonTestXmlFile
+def mainPythonAllXmlFiles = ""
+def buildStageStatus = true
+
+// Name of the test stage
+def testStageName = params.pipelineTestStageName
+
+// Name of the phone resource
+def ciSmartPhonesResource1 = params.SmartPhonesResource1
+def ciSmartPhonesResource2 = params.SmartPhonesResource2
+
+// Global Parameters. Populated when the master job
+// triggers the slave job with parameters
+def eNB_Repository = "https://gitlab.eurecom.fr/oai/openairinterface5g.git"
+def eNB_Branch = "develop"
+def eNB_CommitID
+def eNB_AllowMergeRequestProcess = false
+def eNB_TargetBranch = "develop"
+def eNB_MR = "develop"
+
+pipeline {
+    agent {
+        label pythonExecutor
+    }
+    options {
+        disableConcurrentBuilds()
+        ansiColor('xterm')
+        lock(extra: [[resource: ciSmartPhonesResource2]], resource: ciSmartPhonesResource1)
+    }
+    stages {
+        stage("Build Init") {
+            steps {
+                script {
+                    //retrieve latest commit ID from branch
+                    latest_commit_from_branch= sh returnStdout: true, script: 'git log -1 origin/${eNB_Branch} | grep commit'
+                    echo "Branch ${eNB_Branch}"
+                    echo "${latest_commit_from_branch}"
+                    tmp=latest_commit_from_branch.split()
+                    echo "${tmp}"
+                    eNB_CommitID = tmp[1]
+                    echo "eNB_CommitID ${eNB_CommitID}"
+                    // update the build name and description
+                    buildName "${params.eNB_MR}"
+                    buildDescription "Commit : ${eNB_CommitID}"
+                }
+            }
+        }
+        stage ("Verify Parameters") {
+            steps {
+                script {
+                    echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
+                    def allParametersPresent = true
+
+                    // It is already to late to check it
+                    if (params.pythonExecutor != null) {
+                        echo "eNB CI executor node  :   ${pythonExecutor}"
+                    }
+                    // If not present picking a default Stage Name
+                    if (params.pipelineTestStageName == null) {
+                        // picking default
+                        testStageName = 'Template Test Stage'
+                    }
+
+                    if (params.SmartPhonesResource1 == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.SmartPhonesResource2 == null) {
+                        allParametersPresent = false
+                    }
+                    // 1st eNB parameters
+                    if (params.eNB_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB_Credentials == null) {
+                        allParametersPresent = false
+                    }
+                    // 2nd eNB parameters
+                    if (params.eNB1_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB1_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB1_Credentials == null) {
+                        allParametersPresent = false
+                    }
+                    // 3rd eNB parameters
+                    if (params.eNB2_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB2_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB2_Credentials == null) {
+                        allParametersPresent = false
+                    }
+                    // the following 4 parameters should be pushed by the master trigger
+                    // if not present, take the job GIT variables (used for developing)
+                    if (params.eNB_Repository == null) {
+                        eNB_Repository = env.GIT_URL
+                    } else {
+                        eNB_Repository = params.eNB_Repository
+                    }
+                    echo "eNB_Repository        :   ${eNB_Repository}"
+                    if (params.eNB_Branch == null) {
+                        eNB_Branch = env.GIT_BRANCH
+                    } else {
+                        eNB_Branch = params.eNB_Branch
+                    }
+                    echo "eNB_Branch            :   ${eNB_Branch}"
+                    //if (params.eNB_CommitID == null) {
+                    //    eNB_CommitID = env.GIT_COMMIT
+                    //} else {
+                    //    eNB_CommitID = params.eNB_CommitID
+                    //}
+                    echo "eNB_CommitID          :   ${eNB_CommitID}"
+                    if (params.eNB_AllowMergeRequestProcess!= null) {
+                        eNB_AllowMergeRequestProcess = params.eNB_AllowMergeRequestProcess
+                        if (eNB_AllowMergeRequestProcess) {
+                            if (params.eNB_TargetBranch != null) {
+                                eNB_TargetBranch = params.eNB_TargetBranch
+                            } else {
+                                eNB_TargetBranch = 'develop'
+                            }
+                            echo "eNB_TargetBranch      :   ${eNB_TargetBranch}"
+                        }
+                    }
+
+                    if (params.EPC_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.EPC_Type == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.EPC_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.EPC_Credentials == null) {
+                        allParametersPresent = false
+                    }
+
+                    if (params.ADB_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.ADB_Credentials == null) {
+                        allParametersPresent = false
+                    }
+
+                    if (allParametersPresent) {
+                        echo "All parameters are present"
+                        if (eNB_AllowMergeRequestProcess) {
+                            sh "git fetch"
+                            sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest"
+                        } else {
+                            sh "git fetch"
+                            sh "git checkout -f ${eNB_CommitID}"
+                        }
+                    } else {
+                        echo "Some parameters are missing"
+                        sh "./ci-scripts/fail.sh"
+                    }
+                }
+            }
+        }
+        stage ("Build and Test") {
+            steps {
+                script {
+                    dir ('ci-scripts') {
+                        echo "\u2705 \u001B[32m${testStageName}\u001B[0m"
+                        // If not present picking a default XML file
+                        if (params.pythonTestXmlFile == null) {
+                            // picking default
+                            testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml'
+                            echo "Test XML file(default):   ${testXMLFile}"
+                            mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " "
+                        } else {
+                            String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
+                            for (xmlFile in myXmlTestSuite) {
+                                if (fileExists(xmlFile)) {
+                                    mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " "
+                                    echo "Test XML file         :   ${xmlFile}"
+                                }
+                            }
+                        }
+                        withCredentials([
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB2_Credentials}", usernameVariable: 'eNB2_Username', passwordVariable: 'eNB2_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
+                        ]) {
+                            sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
+                            String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
+                            for (xmlFile in myXmlTestSuite) {
+                                if (fileExists(xmlFile)) {
+                                    try {
+                                        sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}"
+                                    } catch (Exception e) {
+                                        currentBuild.result = 'FAILURE'
+                                        buildStageStatus = false
+                                    }
+                                }
+                            }
+                            sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
+                        }
+                    }
+                }
+            }
+        }
+        stage('Log Collection') {
+            parallel {
+                stage('Log Collection (eNB - Build)') {
+                    steps {
+                        withCredentials([
+                             [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
+                        ]) {
+                            echo '\u2705 \u001B[32mLog Collection (eNB - Build)\u001B[0m'
+                            sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
+
+                            echo '\u2705 \u001B[32mLog Transfer (eNB - Build)\u001B[0m'
+                            sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true"
+                        }
+                        script {
+                            if(fileExists("build.log.${env.BUILD_ID}.zip")) {
+                                archiveArtifacts "build.log.${env.BUILD_ID}.zip"
+                            }
+                        }
+                    }
+                }
+                stage('Log Collection (eNB - Run)') {
+                    steps {
+                        withCredentials([
+                             [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
+                        ]) {
+                            echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
+                            sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
+
+                            echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m'
+                            sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true"
+                        }
+                        script {
+                            if(fileExists("enb.log.${env.BUILD_ID}.zip")) {
+                                archiveArtifacts "enb.log.${env.BUILD_ID}.zip"
+                            }
+                            if(fileExists("ci-scripts/test_results.html")) {
+                                sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html"
+                                sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
+                                archiveArtifacts "test_results-${JOB_NAME}.html"
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    post {
+        always {
+            script {
+                if (params.pipelineZipsConsoleLog != null) {
+                    if (params.pipelineZipsConsoleLog) {
+                        echo "Archiving Jenkins console log"
+                        sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true"
+                        sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true"
+                        if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) {
+                            archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip"
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa b/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa
new file mode 100644
index 0000000000000000000000000000000000000000..1e4933838b907817f767386dacbe2b10c2799694
--- /dev/null
+++ b/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa
@@ -0,0 +1,293 @@
+#!/bin/groovy
+/*
+ * 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
+ */
+
+// Template Jenkins Declarative Pipeline script to run Test w/ RF HW
+
+// Location of the python executor node shall be in the same subnet as the others servers
+def pythonExecutor = params.pythonExecutor
+
+// Location of the test XML file to be run
+def testXMLFile = params.pythonTestXmlFile
+def mainPythonAllXmlFiles = ""
+def buildStageStatus = true
+
+// Name of the test stage
+def testStageName = params.pipelineTestStageName
+
+// Name of the phone/server resource
+def ciSmartPhonesResource1 = params.SmartPhonesResource1
+def ciSmartPhonesResource2 = params.SmartPhonesResource2
+
+// Global Parameters. Normally they should be populated when the master job
+// triggers the slave job with parameters
+def eNB_Repository
+def eNB_Branch
+def eNB_CommitID
+def eNB_AllowMergeRequestProcess
+def eNB_TargetBranch
+
+pipeline {
+    agent {
+        label pythonExecutor
+    }
+    options {
+        disableConcurrentBuilds()
+        ansiColor('xterm')
+        lock(extra: [[resource: ciSmartPhonesResource2]], resource: ciSmartPhonesResource1)
+    }
+    stages {
+        stage("Build Init") {
+            steps {
+                // update the build name and description
+                buildName "${params.eNB_MR}"
+                buildDescription "Branch : ${params.eNB_Branch}"
+            }
+        }
+        stage ("Verify Parameters") {
+            steps {
+                script {
+                    echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
+                    def allParametersPresent = true
+
+                    // It is already to late to check it
+                    if (params.pythonExecutor != null) {
+                        echo "eNB CI executor node  :   ${pythonExecutor}"
+                    }
+                    // If not present picking a default Stage Name
+                    if (params.pipelineTestStageName == null) {
+                        // picking default
+                        testStageName = 'Template Test Stage'
+                    }
+
+                    if (params.SmartPhonesResource1 == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.SmartPhonesResource2 == null) {
+                        allParametersPresent = false
+                    }
+                    // 1st eNB parameters
+                    if (params.eNB_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB_Credentials == null) {
+                        allParametersPresent = false
+                    }
+                    // 2nd eNB parameters
+                    if (params.eNB1_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB1_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB1_Credentials == null) {
+                        allParametersPresent = false
+                    }
+                    // 3rd eNB parameters
+                    if (params.eNB2_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB2_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.eNB2_Credentials == null) {
+                        allParametersPresent = false
+                    }
+                    // the following 4 parameters should be pushed by the master trigger
+                    // if not present, take the job GIT variables (used for developing)
+                    if (params.eNB_Repository == null) {
+                        eNB_Repository = env.GIT_URL
+                    } else {
+                        eNB_Repository = params.eNB_Repository
+                    }
+                    echo "eNB_Repository        :   ${eNB_Repository}"
+                    if (params.eNB_Branch == null) {
+                        eNB_Branch = env.GIT_BRANCH
+                    } else {
+                        eNB_Branch = params.eNB_Branch
+                    }
+                    echo "eNB_Branch            :   ${eNB_Branch}"
+                    if (params.eNB_CommitID == null) {
+                        eNB_CommitID = env.GIT_COMMIT
+                    } else {
+                        eNB_CommitID = params.eNB_CommitID
+                    }
+                    echo "eNB_CommitID          :   ${eNB_CommitID}"
+                    if (params.eNB_AllowMergeRequestProcess!= null) {
+                        eNB_AllowMergeRequestProcess = params.eNB_AllowMergeRequestProcess
+                        if (eNB_AllowMergeRequestProcess) {
+                            if (params.eNB_TargetBranch != null) {
+                                eNB_TargetBranch = params.eNB_TargetBranch
+                            } else {
+                                eNB_TargetBranch = 'develop'
+                            }
+                            echo "eNB_TargetBranch      :   ${eNB_TargetBranch}"
+                        }
+                    }
+
+                    if (params.EPC_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.EPC_Type == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.EPC_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.EPC_Credentials == null) {
+                        allParametersPresent = false
+                    }
+
+                    if (params.ADB_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.ADB_Credentials == null) {
+                        allParametersPresent = false
+                    }
+
+                    if (allParametersPresent) {
+                        echo "All parameters are present"
+                        if (eNB_AllowMergeRequestProcess) {
+                            sh "git fetch"
+                            sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest"
+                        } else {
+                            sh "git fetch"
+                            sh "git checkout -f ${eNB_CommitID}"
+                        }
+                    } else {
+                        echo "Some parameters are missing"
+                        sh "./ci-scripts/fail.sh"
+                    }
+                }
+            }
+        }
+        stage ("Build and Test") {
+            steps {
+                script {
+                    dir ('ci-scripts') {
+                        echo "\u2705 \u001B[32m${testStageName}\u001B[0m"
+                        // If not present picking a default XML file
+                        if (params.pythonTestXmlFile == null) {
+                            // picking default
+                            testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml'
+                            echo "Test XML file(default):   ${testXMLFile}"
+                            mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " "
+                        } else {
+                            String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
+                            for (xmlFile in myXmlTestSuite) {
+                                if (fileExists(xmlFile)) {
+                                    mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " "
+                                    echo "Test XML file         :   ${xmlFile}"
+                                }
+                            }
+                        }
+                        withCredentials([
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB2_Credentials}", usernameVariable: 'eNB2_Username', passwordVariable: 'eNB2_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
+                        ]) {
+                            sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
+                            String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
+                            for (xmlFile in myXmlTestSuite) {
+                                if (fileExists(xmlFile)) {
+                                    try {
+                                        sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}"
+                                    } catch (Exception e) {
+                                        currentBuild.result = 'FAILURE'
+                                        buildStageStatus = false
+                                    }
+                                }
+                            }
+                            sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
+                        }
+                    }
+                }
+            }
+        }
+        stage('Log Collection') {
+            parallel {
+                stage('Log Collection (eNB - Build)') {
+                    steps {
+                        withCredentials([
+                             [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
+                        ]) {
+                            echo '\u2705 \u001B[32mLog Collection (eNB - Build)\u001B[0m'
+                            sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
+
+                            echo '\u2705 \u001B[32mLog Transfer (eNB - Build)\u001B[0m'
+                            sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true"
+                        }
+                        script {
+                            if(fileExists("build.log.${env.BUILD_ID}.zip")) {
+                                archiveArtifacts "build.log.${env.BUILD_ID}.zip"
+                            }
+                        }
+                    }
+                }
+                stage('Log Collection (eNB - Run)') {
+                    steps {
+                        withCredentials([
+                             [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
+                        ]) {
+                            echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
+                            sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
+
+                            echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m'
+                            sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true"
+                        }
+                        script {
+                            if(fileExists("enb.log.${env.BUILD_ID}.zip")) {
+                                archiveArtifacts "enb.log.${env.BUILD_ID}.zip"
+                            }
+                            if(fileExists("ci-scripts/test_results.html")) {
+                                sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html"
+                                sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
+                                archiveArtifacts "test_results-${JOB_NAME}.html"
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    post {
+        always {
+            script {
+                if (params.pipelineZipsConsoleLog != null) {
+                    if (params.pipelineZipsConsoleLog) {
+                        echo "Archiving Jenkins console log"
+                        sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true"
+                        sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true"
+                        if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) {
+                            archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip"
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran
index ab1573de7fc374d040e22e353e1641cca4b70edf..a0d0f13871ac21770dd9f971d6e1c28c989aecd0 100644
--- a/ci-scripts/Jenkinsfile-tmp-ran
+++ b/ci-scripts/Jenkinsfile-tmp-ran
@@ -241,6 +241,10 @@ pipeline {
         stage ("Terminate") {
             parallel {
                 stage('Terminate UE') {
+                    // Bypassing this stage if there are no abd server defined
+                    when {
+                      expression { params.ADB_IPAddress != "none" }
+                    }
                     steps {
                         echo '\u2705 \u001B[32mTerminate UE\u001B[0m'
                         withCredentials([
@@ -275,6 +279,10 @@ pipeline {
                     }
                 }
                 stage('Terminate SPGW') {
+                    // Bypassing this stage if EPC server is not defined
+                    when {
+                      expression { params.EPC_IPAddress != "none" }
+                    }
                     steps {
                         echo '\u2705 \u001B[32mTerminate SPGW\u001B[0m'
                         withCredentials([
@@ -292,6 +300,10 @@ pipeline {
                     }
                 }
                 stage('Terminate MME') {
+                    // Bypassing this stage if EPC server is not defined
+                    when {
+                      expression { params.EPC_IPAddress != "none" }
+                    }
                     steps {
                         echo '\u2705 \u001B[32mTerminate MME\u001B[0m'
                         withCredentials([
@@ -309,6 +321,10 @@ pipeline {
                     }
                 }
                 stage('Terminate HSS') {
+                    // Bypassing this stage if EPC server is not defined
+                    when {
+                      expression { params.EPC_IPAddress != "none" }
+                    }
                     steps {
                         echo '\u2705 \u001B[32mTerminate HSS\u001B[0m'
                         withCredentials([
@@ -353,7 +369,7 @@ pipeline {
                              [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
                         ]) {
                             echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
-                            sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
+                            sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}"
 
                             echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m'
                             sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true"
@@ -371,6 +387,10 @@ pipeline {
                     }
                 }
                 stage('Log Collection (SPGW)') {
+                    // Bypassing this stage if EPC server is not defined
+                    when {
+                      expression { params.EPC_IPAddress != "none" }
+                    }
                     steps {
                         withCredentials([
                              [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
@@ -389,6 +409,10 @@ pipeline {
                     }
                 }
                 stage('Log Collection (MME)') {
+                    // Bypassing this stage if EPC server is not defined
+                    when {
+                      expression { params.EPC_IPAddress != "none" }
+                    }
                     steps {
                         withCredentials([
                              [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
@@ -407,6 +431,10 @@ pipeline {
                     }
                 }
                 stage('Log Collection (HSS)') {
+                    // Bypassing this stage if EPC server is not defined
+                    when {
+                      expression { params.EPC_IPAddress != "none" }
+                    }
                     steps {
                         withCredentials([
                              [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
@@ -425,6 +453,10 @@ pipeline {
                     }
                 }
                 stage('Log Collection (Ping)') {
+                    // Bypassing this stage if EPC server is not defined
+                    when {
+                      expression { params.EPC_IPAddress != "none" }
+                    }
                     steps {
                         withCredentials([
                              [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
@@ -443,6 +475,10 @@ pipeline {
                     }
                 }
                 stage('Log Collection (Iperf)') {
+                    // Bypassing this stage if EPC server is not defined
+                    when {
+                      expression { params.EPC_IPAddress != "none" }
+                    }
                     steps {
                         withCredentials([
                              [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
@@ -482,7 +518,7 @@ pipeline {
         // Making sure that we really shutdown every thing before leaving
         failure {
             script {
-                if (!termStatusArray[termUE]) {
+                if ((!termStatusArray[termUE]) && (params.ADB_IPAddress != "none")) {
                     withCredentials([
                         [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
                     ]) {
@@ -496,21 +532,21 @@ pipeline {
                         sh "python3 ci-scripts/main.py --mode=TerminateeNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
                     }
                 }
-                if (!termStatusArray[termSPGW]) {
+                if ((!termStatusArray[termSPGW]) && (params.EPC_IPAddress != "none")) {
                     withCredentials([
                         [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
                     ]) {
                         sh "python3 ci-scripts/main.py --mode=TerminateSPGW --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}"
                     }
                 }
-                if (!termStatusArray[termMME]) {
+                if ((!termStatusArray[termMME]) && (params.EPC_IPAddress != "none")) {
                     withCredentials([
                         [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
                     ]) {
                         sh "python3 ci-scripts/main.py --mode=TerminateMME --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}"
                     }
                 }
-                if (!termStatusArray[termHSS]) {
+                if ((!termStatusArray[termHSS]) && (params.EPC_IPAddress != "none")) {
                     withCredentials([
                         [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
                     ]) {
diff --git a/ci-scripts/Jenkinsfile-trig-nsa b/ci-scripts/Jenkinsfile-trig-nsa
new file mode 100644
index 0000000000000000000000000000000000000000..2dcaf1a04fef5fa7eac155d0e9098d4eaef547bd
--- /dev/null
+++ b/ci-scripts/Jenkinsfile-trig-nsa
@@ -0,0 +1,82 @@
+#!/bin/groovy
+/*
+ * 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
+ */
+
+// Template Jenkins Declarative Pipeline script to run Test w/ RF HW
+
+// Location of the python executor node shall be in the same subnet as the others servers
+def pythonExecutor = params.pythonExecutor
+
+def TARGET_BRANCH = "develop"
+def ALLOW_MERGE = true
+
+pipeline {
+    agent {
+        label pythonExecutor
+    }
+    stages {
+        stage ("Launcher") {
+            steps {
+                script {     
+                    //retrieve MR that are opened nd with tag NSA             
+                    MR_LIST= sh returnStdout: true, script: 'curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100&labels=NSA" | jq ".[].iid" || true '
+                    echo "List of selected MR:\n${MR_LIST}" 
+                    def MR_ARRAY = MR_LIST.split('\n') 
+                    //for every selected MR, retrieve the branch name and the latest commit              
+                    for (MR in MR_ARRAY) {
+                        SRC_BRANCH=sh returnStdout: true, script: """curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/${MR}" | jq ".source_branch" || true """
+                        SRC_BRANCH=SRC_BRANCH.trim()
+                        COMMIT_ID=sh returnStdout: true, script:  """curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/${MR}" | jq ".sha" || true """
+                        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 : 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 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/args_parse.py b/ci-scripts/args_parse.py
index 248e873cdd66845490ee2fbd5a74a6edd3a26e66..c0203a4c98abf4ccd1a0c91907d311a0cfcc17bc 100644
--- a/ci-scripts/args_parse.py
+++ b/ci-scripts/args_parse.py
@@ -41,7 +41,7 @@ import constants as CONST
 #-----------------------------------------------------------
 
 
-def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
+def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA,PHYSIM):
 
 
     py_param_file_present = False
@@ -80,6 +80,8 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
             HTML.ranRepository=matchReg.group(1)
             ldpc.ranRepository=matchReg.group(1)
             CONTAINERS.ranRepository=matchReg.group(1)
+            SCA.ranRepository=matchReg.group(1)
+            PHYSIM.ranRepository=matchReg.group(1)
         elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE):
             if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
                 matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE)
@@ -92,6 +94,8 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
                 RAN.ranAllowMerge=True
                 HTML.ranAllowMerge=True
                 CONTAINERS.ranAllowMerge=True
+                SCA.ranAllowMerge=True
+                PHYSIM.ranAllowMerge=True
         elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
             if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
                 matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE)
@@ -102,6 +106,8 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
             HTML.ranBranch=matchReg.group(1)
             ldpc.ranBranch=matchReg.group(1)
             CONTAINERS.ranBranch=matchReg.group(1)
+            SCA.ranBranch=matchReg.group(1)
+            PHYSIM.ranBranch=matchReg.group(1)
         elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
             if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
                 matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE)
@@ -112,6 +118,8 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
             HTML.ranCommitID=matchReg.group(1)
             ldpc.ranCommitID=matchReg.group(1)
             CONTAINERS.ranCommitID=matchReg.group(1)
+            SCA.ranCommitID=matchReg.group(1)
+            PHYSIM.ranCommitID=matchReg.group(1)
         elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
             if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
                 matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE)
@@ -122,12 +130,16 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
             HTML.ranTargetBranch=matchReg.group(1)
             ldpc.ranTargetBranch=matchReg.group(1)
             CONTAINERS.ranTargetBranch=matchReg.group(1)
+            SCA.ranTargetBranch=matchReg.group(1)
+            PHYSIM.ranTargetBranch=matchReg.group(1)
         elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
             if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
                 matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
                 RAN.eNBIPAddress=matchReg.group(1)
                 ldpc.eNBIpAddr=matchReg.group(1)
                 CONTAINERS.eNBIPAddress=matchReg.group(1)
+                SCA.eNBIPAddress=matchReg.group(1)
+                PHYSIM.eNBIPAddress=matchReg.group(1)
             elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE):
                 matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE)
                 RAN.eNB1IPAddress=matchReg.group(1)
@@ -142,6 +154,8 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
                 RAN.eNBUserName=matchReg.group(1)
                 ldpc.eNBUserName=matchReg.group(1)
                 CONTAINERS.eNBUserName=matchReg.group(1)
+                SCA.eNBUserName=matchReg.group(1)
+                PHYSIM.eNBUserName=matchReg.group(1)
             elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE):
                 matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE)
                 RAN.eNB1UserName=matchReg.group(1)
@@ -156,6 +170,8 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
                 RAN.eNBPassword=matchReg.group(1)
                 ldpc.eNBPassWord=matchReg.group(1)
                 CONTAINERS.eNBPassword=matchReg.group(1)
+                SCA.eNBPassword=matchReg.group(1)
+                PHYSIM.eNBPassword=matchReg.group(1)
             elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE):
                 matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE)
                 RAN.eNB1Password=matchReg.group(1)
@@ -170,6 +186,8 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
                 RAN.eNBSourceCodePath=matchReg.group(1)
                 ldpc.eNBSourceCodePath=matchReg.group(1)
                 CONTAINERS.eNBSourceCodePath=matchReg.group(1)
+                SCA.eNBSourceCodePath=matchReg.group(1)
+                PHYSIM.eNBSourceCodePath=matchReg.group(1)
             elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
                 matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
                 RAN.eNB1SourceCodePath=matchReg.group(1)
@@ -239,6 +257,18 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP):
             finalStatus = matchReg.group(1)
             if ((finalStatus == 'true') or (finalStatus == 'True')):
                 CiTestObj.finalStatus = True
+        elif re.match('^\-\-OCUserName=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-OCUserName=(.+)$', myArgv, re.IGNORECASE)
+            PHYSIM.OCUserName = matchReg.group(1)
+        elif re.match('^\-\-OCPassword=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-OCPassword=(.+)$', myArgv, re.IGNORECASE)
+            PHYSIM.OCPassword = matchReg.group(1)
+        elif re.match('^\-\-OCProjectName=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-OCProjectName=(.+)$', myArgv, re.IGNORECASE)
+            PHYSIM.OCProjectName = matchReg.group(1)
+        elif re.match('^\-\-BuildId=(.+)$', myArgv, re.IGNORECASE):
+            matchReg = re.match('^\-\-BuildId=(.+)$', myArgv, re.IGNORECASE)
+            RAN.BuildId = matchReg.group(1)
         else:
             HELP.GenericHelp(CONST.Version)
             sys.exit('Invalid Parameter: ' + myArgv)
diff --git a/ci-scripts/auto_start_gnb.sh b/ci-scripts/auto_start_gnb.sh
new file mode 100644
index 0000000000000000000000000000000000000000..86ffc66d184269ad34937d6bab02161fd6261208
--- /dev/null
+++ b/ci-scripts/auto_start_gnb.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+while true
+do
+  echo "gNB will be started automatically..."
+  sleep 1
+  sudo .././cmake_targets/ran_build/build/nr-softmodem -E -O ../targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
+done
diff --git a/ci-scripts/buildOnRH.sh b/ci-scripts/buildOnRH.sh
deleted file mode 100755
index eaff097c885ad1d219ba502bd58cbde245020955..0000000000000000000000000000000000000000
--- a/ci-scripts/buildOnRH.sh
+++ /dev/null
@@ -1,216 +0,0 @@
-#!/bin/bash
-#/*
-# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
-# * contributor license agreements.  See the NOTICE file distributed with
-# * this work for additional information regarding copyright ownership.
-# * The OpenAirInterface Software Alliance licenses this file to You under
-# * the OAI Public License, Version 1.1  (the "License"); you may not use this file
-# * except in compliance with the License.
-# * You may obtain a copy of the License at
-# *
-# *      http://www.openairinterface.org/?page_id=698
-# *
-# * Unless required by applicable law or agreed to in writing, software
-# * distributed under the License is distributed on an "AS IS" BASIS,
-# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# * See the License for the specific language governing permissions and
-# * limitations under the License.
-# *-------------------------------------------------------------------------------
-# * For more information about the OpenAirInterface (OAI) Software Alliance:
-# *      contact@openairinterface.org
-# */
-
-function usage {
-    echo "OAI RedHat Build Check script"
-    echo "   Original Author: Raphael Defosseux"
-
-    echo ""
-    echo "Usage:"
-    echo "------"
-    echo "    buildOnRH.sh [OPTIONS]"
-    echo ""
-    echo "Options:"
-    echo "--------"
-    echo "    --job-name #### OR -jn ####"
-    echo "    Specify the name of the Jenkins job."
-    echo ""
-    echo "    --build-id #### OR -id ####"
-    echo "    Specify the build ID of the Jenkins job."
-    echo ""
-    echo "    --workspace #### OR -ws ####"
-    echo "    Specify the workspace."
-    echo ""
-    echo "    --remote-host #### OR -rh ####"
-    echo "    Specify the RedHat remote server."
-    echo ""
-    echo "    --remote-user-name #### OR -ru ####"
-    echo "    Specify the RedHat remote server username."
-    echo ""
-    echo "    --remote-password #### OR -rp ####"
-    echo "    Specify the RedHat remote server password."
-    echo ""
-    echo "    --remote-path #### OR -ra ####"
-    echo "    Specify the RedHat remote server path to work on."
-    echo ""
-}
-
-if [ $# -lt 1 ] || [ $# -gt 14 ]
-then
-    echo "Syntax Error: not the correct number of arguments"
-    echo ""
-    usage
-    exit 1
-fi
-
-RH_HOST=XX
-RH_USER=XX
-RH_PASSWD=XX
-RH_PATH=XX
-JOB_NAME=XX
-BUILD_ID=XX
-
-while [[ $# -gt 0 ]]
-do
-key="$1"
-
-case $key in
-    -h|--help)
-    shift
-    usage
-    exit 0
-    ;;
-    -jn|--job-name)
-    JOB_NAME="$2"
-    shift
-    shift
-    ;;
-    -id|--build-id)
-    BUILD_ID="$2"
-    shift
-    shift
-    ;;
-    -ws|--workspace)
-    JENKINS_WKSP="$2"
-    shift
-    shift
-    ;;
-    -rh|--remote-host)
-    RH_HOST="$2"
-    shift
-    shift
-    ;;
-    -ru|--remote-user-name)
-    RH_USER="$2"
-    shift
-    shift
-    ;;
-    -rp|--remote-password)
-    RH_PASSWD="$2"
-    shift
-    shift
-    ;;
-    -ra|--remote-path)
-    RH_PATH="$2"
-    shift
-    shift
-    ;;
-    *)
-    echo "Syntax Error: unknown option: $key"
-    echo ""
-    usage
-    exit 1
-esac
-done
-
-if [ ! -f $JENKINS_WKSP/localZip.zip ]
-then
-    echo "Missing localZip.zip file!"
-    exit 1
-fi
-
-if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ] || [ "$RH_HOST" == "XX" ] || [ "$RH_USER" == "XX" ] || [ "$RH_PASSWD" == "XX" ] || [ "$RH_PATH" == "XX" ]
-then
-    echo "Missing options"
-    usage
-    exit 1
-fi
-
-echo "############################################################"
-echo "Copying GIT repo into RedHat Server" 
-echo "############################################################"
-echo "rm -Rf ${RH_PATH}" >> rh-cmd.txt
-echo "mkdir -p ${RH_PATH}" >> rh-cmd.txt
-
-sshpass -p ${RH_PASSWD} ssh -o 'StrictHostKeyChecking no' ${RH_USER}@${RH_HOST} < rh-cmd.txt
-rm -f rh-cmd.txt
-
-echo "############################################################"
-echo "Running install and build script on RedHat Server"
-echo "############################################################"
-sshpass -p ${RH_PASSWD} scp -o 'StrictHostKeyChecking no' $JENKINS_WKSP/localZip.zip ${RH_USER}@${RH_HOST}:${RH_PATH}
-
-echo "cd ${RH_PATH}" > rh-cmd.txt
-echo "unzip -qq localZip.zip" >> rh-cmd.txt
-echo "source oaienv" >> rh-cmd.txt
-echo "cd cmake_targets" >> rh-cmd.txt
-echo "mkdir -p log" >> rh-cmd.txt
-echo "./build_oai -I -w USRP --eNB > log/install-build.txt 2>&1" >> rh-cmd.txt
-sshpass -p ${RH_PASSWD} ssh -o 'StrictHostKeyChecking no' ${RH_USER}@${RH_HOST} < rh-cmd.txt
-
-rm -f rh-cmd.txt
-
-echo "############################################################"
-echo "Creating a tmp folder to store results and artifacts"
-echo "############################################################"
-if [ ! -d $JENKINS_WKSP/archives ]
-then
-    mkdir -p $JENKINS_WKSP/archives
-fi
-
-ARCHIVES_LOC=$JENKINS_WKSP/archives/red_hat
-if [ ! -d $ARCHIVES_LOC ]
-then
-    mkdir -p $ARCHIVES_LOC
-fi
-
-sshpass -p ${RH_PASSWD} scp -o 'StrictHostKeyChecking no' ${RH_USER}@${RH_HOST}:${RH_PATH}/cmake_targets/log/*.txt $ARCHIVES_LOC
-
-echo "############################################################"
-echo "Checking build status" 
-echo "############################################################"
-
-LOG_PATTERN=.Rel15.txt
-NB_PATTERN_FILES=7
-
-LOG_FILES=`ls $ARCHIVES_LOC/*.txt`
-STATUS=0
-NB_FOUND_FILES=0
-
-for FULLFILE in $LOG_FILES
-do
-    if [[ $FULLFILE == *"$LOG_PATTERN"* ]]
-    then
-        filename=$(basename -- "$FULLFILE")
-        PASS_PATTERN=`echo $filename | sed -e "s#$LOG_PATTERN##"`
-        LOCAL_STAT=`egrep -c "Built target $PASS_PATTERN" $FULLFILE`
-        if [ $LOCAL_STAT -eq 0 ]; then STATUS=-1; fi
-        NB_FOUND_FILES=$((NB_FOUND_FILES + 1))
-    fi
-done
-
-if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]
-then
-    echo "Expecting $NB_PATTERN_FILES log files and found $NB_FOUND_FILES"
-    STATUS=-1
-fi
-
-echo "COMMAND: build_oai -I -w USRP --eNB" > $ARCHIVES_LOC/build_final_status.log
-if [ $STATUS -eq 0 ]
-then
-    echo "BUILD_OK" >> $ARCHIVES_LOC/build_final_status.log
-    echo "STATUS seems OK"
-else
-    echo "BUILD_KO" >> $ARCHIVES_LOC/build_final_status.log
-    echo "STATUS failed?"
-fi
-exit $STATUS
diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh
index 861cab0782d1ebb5f189f5fea225df243da9cc27..f4cf3931dd327827dc36731ce8d45855059f3c00 100755
--- a/ci-scripts/buildOnVM.sh
+++ b/ci-scripts/buildOnVM.sh
@@ -62,6 +62,12 @@ function build_on_vm {
     echo "ARCHIVES_LOC        = $ARCHIVES_LOC"
     echo "BUILD_OPTIONS       = $BUILD_OPTIONS"
 
+    if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]]
+    then
+        echo "This VM type is no longer supported in the pipeline framework"
+        return
+    fi
+
     IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME`
 
     if [ $IS_VM_ALIVE -eq 0 ]
@@ -158,6 +164,9 @@ function build_on_vm {
     echo "cd tmp" >> $VM_CMDS
     echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $VM_CMDS
     echo "unzip -qq -DD ../localZip.zip" >> $VM_CMDS
+    # Trying to make some room on filesystem before building
+    echo "rm ../localZip.zip" >> $VM_CMDS
+    echo "export CI_ENV=True" >> $VM_CMDS
     if [[ "$VM_NAME" == *"-cppcheck"* ]]
     then
         echo "mkdir cmake_targets/log" >> $VM_CMDS
@@ -208,7 +217,15 @@ function build_on_vm {
             echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS
             echo "./build_oai -I $BUILD_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS
         else
-            echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
+            if [[ "$VM_NAME" == *"-enb-ethernet"* ]]
+            then
+                echo "echo \"sleep 170 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
+            elif [[ "$VM_NAME" == *"-ue-ethernet"* ]]
+            then
+                echo "echo \"sleep 60 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
+            else
+                echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
+            fi
             echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS
             echo "echo \"sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh\"" >> $VM_CMDS
             echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh" >> $VM_CMDS
diff --git a/ci-scripts/build_fr1_template.yaml b/ci-scripts/build_fr1_template.yaml
index 2a8f9cc6a02a3e7a798f90c6d0a9f02c292fbf7f..02e49bc4b59b303ee3a1cd36136a34d3796ce0ad 100755
--- a/ci-scripts/build_fr1_template.yaml
+++ b/ci-scripts/build_fr1_template.yaml
@@ -1,15 +1,15 @@
 
 ranRepository : https://gitlab.eurecom.fr/oai/openairinterface5g.git
-ranBranch : BRANCH_NAME 
-ranCommitID : COMMIT_ID 
-ranAllowMerge : 'true' 
+ranBranch : integration_2021_wk13_a  
+ranCommitID : 104aa7eed5d6702c1b9da663414079ef698da206     
+ranAllowMerge : 'yes' 
 ranTargetBranch : develop
 
 steps:
   - InitiateHtml,none
   - TesteNB,xml_files/fr1_multi_node_build.xml
   - TesteNB,xml_files/fr1_epc_start.xml
-  - TesteNB,xml_files/fr1_ran_ue_base.xml #ue toggle, nodes initialize, ue toggle, ping, nodes terminate
+  - TesteNB,xml_files/fr1_nsa_base_next.xml #ue toggle, nodes initialize, ue toggle, ping, nodes terminate
   - TesteNB,xml_files/fr1_epc_closure.xml
 
 
diff --git a/ci-scripts/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh
index 3a2fcbb02cbba3692c65b0c597fde6edbc39d4b2..45cf08aa9afeec3a78b761b2ee5f075810601476 100755
--- a/ci-scripts/checkCodingFormattingRules.sh
+++ b/ci-scripts/checkCodingFormattingRules.sh
@@ -76,8 +76,8 @@ then
     do
        IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true`
        IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE || true`
-       IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FILE || true`
-       IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair3/NAS/COMMON/milenage.h" || true`
+       IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence|License-Identifier: BSD-2-Clause" $FILE || true`
+       IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair2/UTIL/OPT/packet-rohc.h|openair3/NAS/COMMON/milenage.h" || true`
        if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ]
        then
            if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ]
@@ -197,8 +197,8 @@ do
         then
             IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true`
             IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE || true`
-            IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FULLFILE || true`
-            IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair3/NAS/COMMON/milenage.h" || true`
+            IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence|License-Identifier: BSD-2-Clause" $FULLFILE || true`
+            IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair2/UTIL/OPT/packet-rohc.h|openair3/NAS/COMMON/milenage.h" || true`
             if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ]
             then
                 if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ]
diff --git a/ci-scripts/ci_ctl_qtel.py b/ci-scripts/ci_ctl_qtel.py
new file mode 100644
index 0000000000000000000000000000000000000000..3785d7ee89a6b66fe884d957087680d4b26c6730
--- /dev/null
+++ b/ci-scripts/ci_ctl_qtel.py
@@ -0,0 +1,86 @@
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+#   Required Python Version
+#     Python 3.x
+#
+#---------------------------------------------------------------------
+
+#usage example:
+#sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 wup
+#sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 detach
+
+
+import sys
+import time
+import serial
+
+
+class qtel_ctl:
+	#---------------
+	#private methods
+	#---------------
+    def __init__(self, usb_port_at):
+        self.QUECTEL_USB_PORT_AT = usb_port_at #ex : '/dev/ttyUSB2'
+        self.modem = serial.Serial(self.QUECTEL_USB_PORT_AT, timeout=1)
+        self.cmd_dict= {"wup": self.wup,"detach":self.detach}#dictionary of function pointers
+
+    def __set_modem_state(self,ser,state):
+	    self.__send_command(ser,"AT+CFUN={}\r".format(state))
+
+    def __send_command(self,ser,com):
+        ser.write(com.encode())
+        time.sleep(0.1)
+        ret=[]
+        while ser.inWaiting()>0:
+            print("waiting")
+            msg=ser.readline()
+            msg=msg.decode("utf-8")
+            msg=msg.replace("\r","")
+            msg=msg.replace("\n","")
+            print(msg)
+            if msg!="":
+                ret.append(msg)
+            else:
+                print("msg empty")
+        return ret
+
+	#--------------
+	#public methods
+	#--------------
+    def wup(self):#sending AT+CFUN=0, then AT+CFUN=1
+        self.__set_modem_state(self.modem,'0')
+        time.sleep(3)
+        self.__set_modem_state(self.modem,'1')
+
+    def detach(self):#sending AT+CFUN=0
+        self.__set_modem_state(self.modem,'0')
+
+
+
+
+if __name__ == "__main__":
+    #argv[1] : usb port
+    #argv[2] : qtel command (see function pointers dict "wup", "detach" etc ...)
+    command = sys.argv[2]
+    Module=qtel_ctl(sys.argv[1])
+    #calling the function to be applied
+    Module.cmd_dict[command]()
diff --git a/ci-scripts/ci_ueinfra.yaml b/ci-scripts/ci_ueinfra.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..619e8fba15bfeaae26831327696a9ff600d1d73c
--- /dev/null
+++ b/ci-scripts/ci_ueinfra.yaml
@@ -0,0 +1,49 @@
+idefix:
+  ID: idefix
+  State : enabled
+  Kind : quectel
+  Process : 
+    Name : quectel-CM
+    Cmd : /home/oaicicd/quectel-CM/quectel-CM -s oai.ipv4 -4
+  WakeupScript : ci_ctl_qtel.py /dev/ttyUSB2 wup
+  DetachScript : ci_ctl_qtel.py /dev/ttyUSB2 detach
+  LogStore : /media/usb-drive/ci_qlogs
+  PLMN : 22201
+  UENetwork : wwan0 
+  HostIPAddress : 192.168.18.188
+  HostUsername : oaicicd
+  HostPassword : oaicicd
+  HostSourceCodePath : none
+nrmodule2_quectel:
+  ID: nrmodule2_quectel
+  State : enabled
+  Kind : quectel
+  Process :
+    Name : quectel-CM
+    Cmd : /home/nrmodule2/quectel-CM/quectel-CM -s oai.ipv4 -4
+  WakeupScript : ci_ctl_qtel.py /dev/ttyUSB7 wup
+  DetachScript : ci_ctl_qtel.py /dev/ttyUSB7 detach
+  LogStore : /media/ci_qlogs  
+  PLMN : 20899 
+  UENetwork : wwan1
+  HostIPAddress : 192.168.18.189
+  HostUsername : nrmodule2 
+  HostPassword : linux 
+  HostSourceCodePath : none
+dummy:
+  ID: ''
+  State : ''
+  Kind : ''
+  Process : 
+    Name : ''
+    Cmd : ''
+  WakeupScript : ''
+  DetachScript : ''
+  PLMN : 22201
+  UENetwork : wwan0
+  HostIPAddress : 192.168.18.188
+  HostUsername : oaicicd
+  HostPassword : oaicicd
+  HostSourceCodePath : none
+
+
diff --git a/ci-scripts/cls_ci_ueinfra.py b/ci-scripts/cls_ci_ueinfra.py
new file mode 100644
index 0000000000000000000000000000000000000000..0326a92a4f4ca9434093b87b633352d4477dd857
--- /dev/null
+++ b/ci-scripts/cls_ci_ueinfra.py
@@ -0,0 +1,57 @@
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+#   Required Python Version
+#     Python 3.x
+#
+#---------------------------------------------------------------------
+
+#to use isfile
+import os
+import sys
+import logging
+#to create a SSH object locally in the methods
+import sshconnection
+#time.sleep
+import time
+#to load ue infrastructure dictionary
+import yaml
+
+class InfraUE:
+	def __init__(self):
+		self.ci_ue_infra ={}
+
+
+#-----------------$
+#PUBLIC Methods$
+#-----------------$
+
+	#This method reads the yaml file describing the multi-UE infrastructure
+	#and stores the infra permanently in the related class attribute self.ci_ue_infra
+	def Get_UE_Infra(self,ue_infra_filename):
+		f_yaml=ue_infra_filename
+		with open(f_yaml,'r') as file:
+			logging.debug('Loading UE infrastructure from file '+f_yaml)
+			#load it permanently in the class attribute
+			self.ci_ue_infra = yaml.load(file,Loader=yaml.FullLoader)
+
+
+
diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py
index 0c07dfe91fe24f044f5b52915ea12ad57944aa90..63b707aa748a79db8c90eb049b9672f7e70cbe99 100644
--- a/ci-scripts/cls_containerize.py
+++ b/ci-scripts/cls_containerize.py
@@ -35,6 +35,8 @@ import sys              # arg
 import re               # reg
 import logging
 import os
+import shutil
+import subprocess
 import time
 from multiprocessing import Process, Lock, SimpleQueue
 from zipfile import ZipFile
@@ -75,6 +77,9 @@ class Containerize():
 		self.eNB_instance = 0
 		self.eNB_serverId = ['', '', '']
 		self.yamlPath = ['', '', '']
+		self.services = ['', '', '']
+		self.nb_healthy = [0, 0, 0]
+		self.exitStatus = 0
 		self.eNB_logFile = ['', '', '']
 
 		self.testCase_id = ''
@@ -82,10 +87,20 @@ class Containerize():
 		self.flexranCtrlDeployed = False
 		self.flexranCtrlIpAddress = ''
 		self.cli = ''
+		self.cliBuildOptions = ''
 		self.dockerfileprefix = ''
 		self.host = ''
 		self.allImagesSize = {}
 		self.collectInfo = {}
+
+		self.pingContName = ''
+		self.pingOptions = ''
+		self.pingLossThreshold = ''
+		self.svrContName = ''
+		self.svrOptions = ''
+		self.cliContName = ''
+		self.cliOptions = ''
+
 #-----------------------------------------------------------
 # Container management functions
 #-----------------------------------------------------------
@@ -123,9 +138,11 @@ class Containerize():
 		if self.host == 'Ubuntu':
 			self.cli = 'docker'
 			self.dockerfileprefix = '.ubuntu18'
+			self.cliBuildOptions = '--no-cache'
 		elif self.host == 'Red Hat':
-			self.cli = 'podman'
+			self.cli = 'sudo podman'
 			self.dockerfileprefix = '.rhel8.2'
+			self.cliBuildOptions = '--no-cache --disable-compression'
 
 		imageNames = []
 		result = re.search('eNB', self.imageKind)
@@ -143,6 +160,10 @@ class Containerize():
 					imageNames.append(('oai-gnb', 'gNB'))
 					imageNames.append(('oai-lte-ue', 'lteUE'))
 					imageNames.append(('oai-nr-ue', 'nrUE'))
+					if self.host == 'Red Hat':
+						imageNames.append(('oai-physim', 'phySim'))
+					if self.host == 'Ubuntu':
+						imageNames.append(('oai-lte-ru', 'lteRU'))
 		if len(imageNames) == 0:
 			imageNames.append(('oai-enb', 'eNB'))
 		
@@ -155,7 +176,7 @@ class Containerize():
 		# on RedHat/CentOS .git extension is mandatory
 		result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
 		if result is not None:
-			full_ran_repo_name = self.ranRepository
+			full_ran_repo_name = self.ranRepository.replace('git/', 'git')
 		else:
 			full_ran_repo_name = self.ranRepository + '.git'
 		mySSH.command('mkdir -p ' + lSourcePath, '\$', 5)
@@ -169,10 +190,11 @@ class Containerize():
 		mySSH.command('mkdir -p cmake_targets/log', '\$', 5)
 		# if the commit ID is provided use it to point to it
 		if self.ranCommitID != '':
-			mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 5)
+			mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
 		# if the branch is not develop, then it is a merge request and we need to do 
 		# the potential merge. Note that merge conflicts should already been checked earlier
 		imageTag = 'develop'
+		sharedTag = 'develop'
 		if (self.ranAllowMerge):
 			imageTag = 'ci-temp'
 			if self.ranTargetBranch == '':
@@ -188,38 +210,23 @@ class Containerize():
 			mySSH.command('mkdir -p tmp/entitlement/', '\$', 5) 
 			mySSH.command('sudo cp /etc/rhsm/ca/redhat-uep.pem tmp/ca/', '\$', 5)
 			mySSH.command('sudo cp /etc/pki/entitlement/*.pem tmp/entitlement/', '\$', 5)
-			
-		#mySSH.close()
-		#return 0
+
 		sharedimage = 'ran-build'
 		# Let's remove any previous run artifacts if still there
-		mySSH.command(self.cli + ' image prune --force', '\$', 5)
-		mySSH.command(self.cli + ' image rm ' + sharedimage + ':' + imageTag, '\$', 5)
+		mySSH.command(self.cli + ' image prune --force', '\$', 30)
+		if (not self.ranAllowMerge):
+			mySSH.command(self.cli + ' image rm ' + sharedimage + ':' + sharedTag, '\$', 30)
 		for image,pattern in imageNames:
-			mySSH.command(self.cli + ' image rm ' + image + ':' + imageTag, '\$', 5)
-		# Build the shared image
-		mySSH.command(self.cli + ' build --target ' + sharedimage + ' --tag ' + sharedimage + ':' + imageTag + ' --file docker/Dockerfile.ran' + self.dockerfileprefix + ' --build-arg NEEDED_GIT_PROXY="http://proxy.eurecom.fr:8080" . > cmake_targets/log/ran-build.log 2>&1', '\$', 1600)
-		# Build the target image(s)
-		previousImage = sharedimage + ':' + imageTag
-		danglingShaOnes=[]
-		for image,pattern in imageNames:
-			# the archived Dockerfiles have "ran-build:latest" as base image
-			# we need to update them with proper tag
-			mySSH.command('sed -i -e "s#' + sharedimage + ':latest#' + sharedimage + ':' + imageTag + '#" docker/Dockerfile.' + pattern + self.dockerfileprefix, '\$', 5)
-			mySSH.command(self.cli + ' build --target ' + image + ' --tag ' + image + ':' + imageTag + ' --file docker/Dockerfile.' + pattern + self.dockerfileprefix + ' . > cmake_targets/log/' + image + '.log 2>&1', '\$', 1200)
-			# Retrieving the dangling image(s) for the log collection
-			mySSH.command(self.cli + ' images --filter "dangling=true" --filter "since=' + previousImage + '" -q | sed -e "s#^#sha=#"', '\$', 5)
-			result = re.search('sha=(?P<imageShaOne>[a-zA-Z0-9\-\_]+)', mySSH.getBefore())
-			if result is not None:
-				danglingShaOnes.append((image, result.group('imageShaOne')))
-			previousImage = image + ':' + imageTag
+			mySSH.command(self.cli + ' image rm ' + image + ':' + imageTag, '\$', 30)
 
-		imageTag = 'ci-temp'
-		# First verify if images were properly created.
+		# Build the shared image only on Push Events (not on Merge Requests)
+		if (not self.ranAllowMerge):
+			mySSH.command(self.cli + ' build ' + self.cliBuildOptions + ' --target ' + sharedimage + ' --tag ' + sharedimage + ':' + sharedTag + ' --file docker/Dockerfile.ran' + self.dockerfileprefix + ' --build-arg NEEDED_GIT_PROXY="http://proxy.eurecom.fr:8080" . > cmake_targets/log/ran-build.log 2>&1', '\$', 1600)
+		# First verify if the shared image was properly created.
 		status = True
-		mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' ' + sharedimage + ':' + imageTag, '\$', 5)
-		if mySSH.getBefore().count('No such object') != 0:
-			logging.error('Could not build properly ran-build')
+		mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' ' + sharedimage + ':' + sharedTag, '\$', 5)
+		if mySSH.getBefore().count('o such image') != 0:
+			logging.error('\u001B[1m Could not build properly ran-build\u001B[0m')
 			status = False
 		else:
 			result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', mySSH.getBefore())
@@ -240,11 +247,40 @@ class Containerize():
 						self.allImagesSize['ran-build'] = str(round(imageSize,1)) + ' Gbytes'
 			else:
 				logging.debug('ran-build size is unknown')
+		# If the shared image failed, no need to continue
+		if not status:
+			# Recover the name of the failed container?
+			mySSH.command(self.cli + ' ps --quiet --filter "status=exited" -n1 | xargs ' + self.cli + ' rm -f', '\$', 5)
+			mySSH.command(self.cli + ' image prune --force', '\$', 30)
+			mySSH.close()
+			logging.error('\u001B[1m Building OAI Images Failed\u001B[0m')
+			HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK)
+			HTML.CreateHtmlTabFooter(False)
+			sys.exit(1)
+		else:
+			# Recover build logs, for the moment only possible when build is successful
+			mySSH.command(self.cli + ' create --name test ' + sharedimage + ':' + sharedTag, '\$', 5)
+			mySSH.command('mkdir -p cmake_targets/log/ran-build', '\$', 5)
+			mySSH.command(self.cli + ' cp test:/oai-ran/cmake_targets/log/. cmake_targets/log/ran-build', '\$', 5)
+			mySSH.command(self.cli + ' rm -f test', '\$', 5)
+
+		# Build the target image(s)
 		for image,pattern in imageNames:
+			# the archived Dockerfiles have "ran-build:latest" as base image
+			# we need to update them with proper tag
+			mySSH.command('sed -i -e "s#' + sharedimage + ':latest#' + sharedimage + ':' + sharedTag + '#" docker/Dockerfile.' + pattern + self.dockerfileprefix, '\$', 5)
+			mySSH.command(self.cli + ' build ' + self.cliBuildOptions + ' --target ' + image + ' --tag ' + image + ':' + imageTag + ' --file docker/Dockerfile.' + pattern + self.dockerfileprefix + ' . > cmake_targets/log/' + image + '.log 2>&1', '\$', 1200)
+			# split the log
+			mySSH.command('mkdir -p cmake_targets/log/' + image, '\$', 5)
+			mySSH.command('python3 ci-scripts/docker_log_split.py --logfilename=cmake_targets/log/' + image + '.log', '\$', 5)
+			# checking the status of the build
 			mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' ' + image + ':' + imageTag, '\$', 5)
-			if mySSH.getBefore().count('No such object') != 0:
-				logging.error('Could not build properly ' + image)
+			if mySSH.getBefore().count('o such image') != 0:
+				logging.error('\u001B[1m Could not build properly ' + image + '\u001B[0m')
 				status = False
+				# Here we should check if the last container corresponds to a failed command and destroy it
+				mySSH.command(self.cli + ' ps --quiet --filter "status=exited" -n1 | xargs ' + self.cli + ' rm -f', '\$', 5)
+				self.allImagesSize[image] = 'N/A -- Build Failed'
 			else:
 				result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', mySSH.getBefore())
 				if result is not None:
@@ -264,39 +300,27 @@ class Containerize():
 							self.allImagesSize[image] = str(round(imageSize,1)) + ' Gbytes'
 				else:
 					logging.debug('ran-build size is unknown')
-		if not status:
-			mySSH.close()
-			logging.error('\u001B[1m Building OAI Images Failed\u001B[0m')
-			HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK)
-			#HTML.CreateHtmlNextTabHeaderTestRow(self.collectInfo, self.allImagesSize)
-			HTML.CreateHtmlTabFooter(False)
-			sys.exit(1)
+					self.allImagesSize[image] = 'unknown'
+			# Now pruning dangling images in between target builds
+			mySSH.command(self.cli + ' image prune --force', '\$', 30)
 
-		# Recover build logs, for the moment only possible when build is successful
-		mySSH.command(self.cli + ' create --name test ' + sharedimage + ':' + imageTag, '\$', 5)
-		mySSH.command('mkdir -p cmake_targets/log/ran-build', '\$', 5)
-		mySSH.command(self.cli + ' cp test:/oai-ran/cmake_targets/log/. cmake_targets/log/ran-build', '\$', 5)
-		mySSH.command(self.cli + ' rm -f test', '\$', 5)
-		for image,shaone in danglingShaOnes:
-			mySSH.command('mkdir -p cmake_targets/log/' + image, '\$', 5)
-			mySSH.command(self.cli + ' create --name test ' + shaone, '\$', 5)
-			mySSH.command(self.cli + ' cp test:/oai-ran/cmake_targets/log/. cmake_targets/log/' + image, '\$', 5)
-			mySSH.command(self.cli + ' rm -f test', '\$', 5)
-		mySSH.command(self.cli + ' image prune --force', '\$', 5)
-		mySSH.command('cd cmake_targets', '\$', 5)
+		# Analyzing the logs
+		mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
 		mySSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5)
 		mySSH.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5)
-		#mySSH.close()
-	
-		mySSH.command('cd /tmp/CI-eNB/cmake_targets', '\$', 5)
+
+		mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
+		mySSH.command('rm -f build_log_' + self.testCase_id + '.zip || true', '\$', 5)
 		if (os.path.isfile('./build_log_' + self.testCase_id + '.zip')):
 			os.remove('./build_log_' + self.testCase_id + '.zip')
+		if (os.path.isdir('./build_log_' + self.testCase_id)):
+			shutil.rmtree('./build_log_' + self.testCase_id)
 		mySSH.command('zip -r -qq build_log_' + self.testCase_id + '.zip build_log_' + self.testCase_id, '\$', 5)
 		mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/build_log_' + self.testCase_id + '.zip', '.')
-		#mySSH.command('rm -f build_log_' + self.testCase_id + '.zip','\$', 5)
+		mySSH.command('rm -f build_log_' + self.testCase_id + '.zip','\$', 5)
 		mySSH.close()
 		ZipFile('build_log_' + self.testCase_id + '.zip').extractall('.')
-	
+
 		#Trying to identify the errors and warnings for each built images
 		imageNames1 = imageNames
 		shared = ('ran-build','ran')
@@ -326,11 +350,43 @@ class Containerize():
 					errorandwarnings['warnings'] = warningsNo
 					errorandwarnings['status'] = status
 				files[fil] = errorandwarnings
+			# Let analyze the target image creation part
+			if os.path.isfile('build_log_{}/{}.log'.format(self.testCase_id,image)):
+				errorandwarnings = {}
+				with open('build_log_{}/{}.log'.format(self.testCase_id,image), mode='r') as inputfile:
+					startOfTargetImageCreation = False
+					buildStatus = False
+					for line in inputfile:
+						result = re.search('FROM .* [aA][sS] ' + image + '$', str(line))
+						if result is not None:
+							startOfTargetImageCreation = True
+						if startOfTargetImageCreation:
+							result = re.search('Successfully tagged ' + image + ':', str(line))
+							if result is not None:
+								buildStatus = True
+							result = re.search('COMMIT ' + image + ':', str(line))
+							if result is not None:
+								buildStatus = True
+					inputfile.close()
+					if buildStatus:
+						errorandwarnings['errors'] = 0
+					else:
+						errorandwarnings['errors'] = 1
+					errorandwarnings['warnings'] = 0
+					errorandwarnings['status'] = buildStatus
+					files['Target Image Creation'] = errorandwarnings
 			self.collectInfo[image] = files
 		
-		logging.info('\u001B[1m Building OAI Image(s) Pass\u001B[0m')
-		HTML.CreateHtmlTestRow(self.imageKind, 'OK', CONST.ALL_PROCESSES_OK)
-		HTML.CreateHtmlNextTabHeaderTestRow(self.collectInfo, self.allImagesSize)
+		if status:
+			logging.info('\u001B[1m Building OAI Image(s) Pass\u001B[0m')
+			HTML.CreateHtmlTestRow(self.imageKind, 'OK', CONST.ALL_PROCESSES_OK)
+			HTML.CreateHtmlNextTabHeaderTestRow(self.collectInfo, self.allImagesSize)
+		else:
+			logging.error('\u001B[1m Building OAI Images Failed\u001B[0m')
+			HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK)
+			HTML.CreateHtmlNextTabHeaderTestRow(self.collectInfo, self.allImagesSize)
+			HTML.CreateHtmlTabFooter(False)
+			sys.exit(1)
 
 	def DeployObject(self, HTML, EPC):
 		if self.eNB_serverId[self.eNB_instance] == '0':
@@ -432,7 +488,6 @@ class Containerize():
 			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
 
 	def UndeployObject(self, HTML, RAN):
-		logging.info('\u001B[1m Undeploying OAI Object Pass\u001B[0m')
 		if self.eNB_serverId[self.eNB_instance] == '0':
 			lIpAddr = self.eNBIPAddress
 			lUserName = self.eNBUserName
@@ -485,4 +540,307 @@ class Containerize():
 				HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus)
 			else:
 				HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
+		logging.info('\u001B[1m Undeploying OAI Object Pass\u001B[0m')
+
+	def DeployGenObject(self, HTML):
+		self.exitStatus = 0
+		logging.info('\u001B[1m Checking Services to deploy\u001B[0m')
+		cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose config --services'
+		logging.debug(cmd)
+		try:
+			listServices = subprocess.check_output(cmd, shell=True, universal_newlines=True)
+		except Exception as e:
+			self.exitStatus = 1
+			HTML.CreateHtmlTestRow('SVC not Found', 'KO', CONST.ALL_PROCESSES_OK)
+			return
+		for reqSvc in self.services[0].split(' '):
+			res = re.search(reqSvc, listServices)
+			if res is None:
+				logging.error(reqSvc + ' not found in specified docker-compose')
+				self.exitStatus = 1
+		if (self.exitStatus == 1):
+			HTML.CreateHtmlTestRow('SVC not Found', 'KO', CONST.ALL_PROCESSES_OK)
+			return
 
+		if (self.ranAllowMerge):
+			cmd = 'cd ' + self.yamlPath[0] + ' && sed -e "s@develop@ci-temp@" docker-compose.y*ml > docker-compose-ci.yml'
+		else:
+			cmd = 'cd ' + self.yamlPath[0] + ' && sed -e "s@develop@develop@" docker-compose.y*ml > docker-compose-ci.yml'
+		logging.debug(cmd)
+		subprocess.run(cmd, shell=True)
+
+		cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml up -d ' + self.services[0]
+		logging.debug(cmd)
+		try:
+			deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=30)
+		except Exception as e:
+			self.exitStatus = 1
+			logging.error('Could not deploy')
+			HTML.CreateHtmlTestRow('Could not deploy', 'KO', CONST.ALL_PROCESSES_OK)
+			return
+
+		logging.info('\u001B[1m Checking if all deployed healthy\u001B[0m')
+		cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml ps -a'
+		count = 0
+		healthy = 0
+		while (count < 10):
+			count += 1
+			deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
+			healthy = 0
+			for state in deployStatus.split('\n'):
+				res = re.search('Up \(healthy\)', state)
+				if res is not None:
+					healthy += 1
+			if healthy == self.nb_healthy[0]:
+				count = 100
+			else:
+				time.sleep(10)
+
+		#  HACK TO REMOVE LATER WHEN FIX
+		res = re.search('oai-nr-ue', self.services[0])
+		if res is not None:
+			cmd = 'docker exec rfsim5g-oai-nr-ue /bin/bash -c "ip route del default"'
+			logging.debug(cmd)
+			deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
+			cmd = 'docker exec rfsim5g-oai-nr-ue /bin/bash -c "ip route del 12.1.1.0/24"'
+			logging.debug(cmd)
+			deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
+			cmd = 'docker exec rfsim5g-oai-nr-ue /bin/bash -c "ip route add default via 12.1.1.2 dev oaitun_ue1"'
+			logging.debug(cmd)
+			deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
+		#  END OF HACK TO REMOVE LATER WHEN FIX
+
+		if count == 100 and healthy == self.nb_healthy[0]:
+			HTML.CreateHtmlTestRow('n/a', 'OK', CONST.ALL_PROCESSES_OK)
+			logging.info('\u001B[1m Deploying OAI Object(s) PASS\u001B[0m')
+		else:
+			self.exitStatus = 1
+			HTML.CreateHtmlTestRow('Could not deploy in time', 'KO', CONST.ALL_PROCESSES_OK)
+			logging.error('\u001B[1m Deploying OAI Object(s) FAILED\u001B[0m')
+
+	def UndeployGenObject(self, HTML):
+		self.exitStatus = 0
+
+		if (self.ranAllowMerge):
+			cmd = 'cd ' + self.yamlPath[0] + ' && sed -e "s@develop@ci-temp@" docker-compose.y*ml > docker-compose-ci.yml'
+		else:
+			cmd = 'cd ' + self.yamlPath[0] + ' && sed -e "s@develop@develop@" docker-compose.y*ml > docker-compose-ci.yml'
+		logging.debug(cmd)
+		subprocess.run(cmd, shell=True)
+
+# if the containers are running, recover the logs!
+		cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml ps --all'
+		logging.debug(cmd)
+		deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
+		anyLogs = False
+		for state in deployStatus.split('\n'):
+			res = re.search('Name|----------', state)
+			if res is not None:
+				continue
+			if len(state) == 0:
+				continue
+			res = re.search('^(?P<container_name>[a-zA-Z0-9\-\_]+) ', state)
+			if res is not None:
+				anyLogs = True
+				cName = res.group('container_name')
+				cmd = 'cd ' + self.yamlPath[0] + ' && docker logs ' + cName + ' > ' + cName + '.log 2>&1'
+				logging.debug(cmd)
+				deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
+		if anyLogs:
+			cmd = 'mkdir -p ../cmake_targets/log && mv ' + self.yamlPath[0] + '/*.log ../cmake_targets/log'
+			logging.debug(cmd)
+			deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
+
+		cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml down'
+		logging.debug(cmd)
+		try:
+			deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100)
+		except Exception as e:
+			self.exitStatus = 1
+			logging.error('Could not undeploy')
+			HTML.CreateHtmlTestRow('Could not undeploy', 'KO', CONST.ALL_PROCESSES_OK)
+			logging.error('\u001B[1m Undeploying OAI Object(s) FAILED\u001B[0m')
+			return
+
+		HTML.CreateHtmlTestRow('n/a', 'OK', CONST.ALL_PROCESSES_OK)
+		logging.info('\u001B[1m Undeploying OAI Object(s) PASS\u001B[0m')
+
+	def PingFromContainer(self, HTML):
+		self.exitStatus = 0
+		cmd = 'mkdir -p ../cmake_targets/log'
+		deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
+
+		cmd = 'docker exec ' + self.pingContName + ' /bin/bash -c "ping ' + self.pingOptions + '" 2>&1 | tee ../cmake_targets/log/ping_' + HTML.testCase_id + '.log'
+		logging.debug(cmd)
+		deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100)
+
+		result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', deployStatus)
+		if result is None:
+			self.PingExit(HTML, False, 'Packet Loss Not Found')
+			return
+
+		packetloss = result.group('packetloss')
+		if float(packetloss) == 100:
+			self.PingExit(HTML, False, 'Packet Loss is 100%')
+			return
+
+		result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', deployStatus)
+		if result is None:
+			self.PingExit(HTML, False, 'Ping RTT_Min RTT_Avg RTT_Max Not Found!')
+			return
+
+		rtt_min = result.group('rtt_min')
+		rtt_avg = result.group('rtt_avg')
+		rtt_max = result.group('rtt_max')
+		pal_msg = 'Packet Loss : ' + packetloss + '%'
+		min_msg = 'RTT(Min)    : ' + rtt_min + ' ms'
+		avg_msg = 'RTT(Avg)    : ' + rtt_avg + ' ms'
+		max_msg = 'RTT(Max)    : ' + rtt_max + ' ms'
+
+		message = 'ping result\n'
+		message += '    ' + pal_msg + '\n'
+		message += '    ' + min_msg + '\n'
+		message += '    ' + avg_msg + '\n'
+		message += '    ' + max_msg + '\n'
+		packetLossOK = True
+		if float(packetloss) > float(self.pingLossThreshold):
+			message += '\nPacket Loss too high'
+			packetLossOK = False
+		elif float(packetloss) > 0:
+			message += '\nPacket Loss is not 0%'
+		self.PingExit(HTML, packetLossOK, message)
+
+		if packetLossOK:
+			logging.debug('\u001B[1;37;44m ping result \u001B[0m')
+			logging.debug('\u001B[1;34m    ' + pal_msg + '\u001B[0m')
+			logging.debug('\u001B[1;34m    ' + min_msg + '\u001B[0m')
+			logging.debug('\u001B[1;34m    ' + avg_msg + '\u001B[0m')
+			logging.debug('\u001B[1;34m    ' + max_msg + '\u001B[0m')
+			logging.info('\u001B[1m Ping Test PASS\u001B[0m')
+
+	def PingExit(self, HTML, status, message):
+		html_queue = SimpleQueue()
+		html_cell = '<pre style="background-color:white">UE\n' + message + '</pre>'
+		html_queue.put(html_cell)
+		if status:
+			HTML.CreateHtmlTestRowQueue(self.pingOptions, 'OK', 1, html_queue)
+		else:
+			self.exitStatus = 1
+			logging.error('\u001B[1;37;41m ' + message + ' \u001B[0m')
+			HTML.CreateHtmlTestRowQueue(self.pingOptions, 'KO', 1, html_queue)
+
+	def IperfFromContainer(self, HTML):
+		self.exitStatus = 0
+
+		cmd = 'mkdir -p ../cmake_targets/log'
+		logStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
+
+		# Start the server process
+		cmd = 'docker exec -d ' + self.svrContName + ' /bin/bash -c "nohup iperf ' + self.svrOptions + ' > /tmp/iperf_server.log 2>&1"'
+		logging.debug(cmd)
+		serverStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
+		time.sleep(5)
+
+		# Start the client process
+		cmd = 'docker exec ' + self.cliContName + ' /bin/bash -c "iperf ' + self.cliOptions + '" 2>&1 | tee ../cmake_targets/log/iperf_client_' + HTML.testCase_id + '.log'
+		logging.debug(cmd)
+		clientStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100)
+
+		# Stop the server process
+		cmd = 'docker exec ' + self.svrContName + ' /bin/bash -c "pkill iperf"'
+		logging.debug(cmd)
+		serverStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
+		time.sleep(5)
+		cmd = 'docker cp ' + self.svrContName + ':/tmp/iperf_server.log ../cmake_targets/log/iperf_server_' + HTML.testCase_id + '.log'
+		logging.debug(cmd)
+		serverStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
+
+		# Analyze client output
+		result = re.search('Server Report:', clientStatus)
+		if result is None:
+			result = re.search('read failed: Connection refused', clientStatus)
+			if result is not None:
+				message = 'Could not connect to iperf server!'
+			else:
+				message = 'Server Report and Connection refused Not Found!'
+			self.IperfExit(HTML, False, message)
+			return
+
+		# Computing the requested bandwidth in float
+		result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', self.cliOptions)
+		if result is not None:
+			req_bandwidth = result.group('iperf_bandwidth')
+			req_bw = float(req_bandwidth)
+			result = re.search('-b [0-9\.]+K', self.cliOptions)
+			if result is not None:
+				req_bandwidth = '%.1f Kbits/sec' % req_bw
+				req_bw = req_bw * 1000
+			result = re.search('-b [0-9\.]+M', self.cliOptions)
+			if result is not None:
+				req_bandwidth = '%.1f Mbits/sec' % req_bw
+				req_bw = req_bw * 1000000
+
+		reportLine = None
+		reportLineFound = False
+		for iLine in clientStatus.split('\n'):
+			if reportLineFound:
+				reportLine = iLine
+				reportLineFound = False
+			res = re.search('Server Report:', iLine)
+			if res is not None:
+				reportLineFound = True
+		result = None
+		if reportLine is not None:
+			result = re.search('(?:|\[ *\d+\].*) (?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(\d+\/ ..\d+) +(\((?P<packetloss>[0-9\.]+)%\))', reportLine)
+		iperfStatus = True
+		if result is not None:
+			bitrate = result.group('bitrate')
+			packetloss = result.group('packetloss')
+			jitter = result.group('jitter')
+			logging.debug('\u001B[1;37;44m iperf result \u001B[0m')
+			iperfStatus = True
+			msg = 'Req Bitrate : ' + req_bandwidth + '\n'
+			logging.debug('\u001B[1;34m    Req Bitrate : ' + req_bandwidth + '\u001B[0m')
+			if bitrate is not None:
+				msg += 'Bitrate     : ' + bitrate + '\n'
+				logging.debug('\u001B[1;34m    Bitrate     : ' + bitrate + '\u001B[0m')
+				result = re.search('(?P<real_bw>[0-9\.]+) [KMG]bits/sec', str(bitrate))
+				if result is not None:
+					actual_bw = float(str(result.group('real_bw')))
+					result = re.search('[0-9\.]+ K', bitrate)
+					if result is not None:
+						actual_bw = actual_bw * 1000
+					result = re.search('[0-9\.]+ M', bitrate)
+					if result is not None:
+						actual_bw = actual_bw * 1000000
+					br_loss = 100 * actual_bw / req_bw
+					if br_loss < 90:
+						iperfStatus = False
+					bitperf = '%.2f ' % br_loss
+					msg += 'Bitrate Perf: ' + bitperf + '%\n'
+					logging.debug('\u001B[1;34m    Bitrate Perf: ' + bitperf + '%\u001B[0m')
+			if packetloss is not None:
+				msg += 'Packet Loss : ' + packetloss + '%\n'
+				logging.debug('\u001B[1;34m    Packet Loss : ' + packetloss + '%\u001B[0m')
+				if float(packetloss) > float(5):
+					msg += 'Packet Loss too high!\n'
+					logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m')
+					iperfStatus = False
+			if jitter is not None:
+				msg += 'Jitter      : ' + jitter + '\n'
+				logging.debug('\u001B[1;34m    Jitter      : ' + jitter + '\u001B[0m')
+			self.IperfExit(HTML, iperfStatus, msg)
+		else:
+			logging.error('problem?')
+		if iperfStatus:
+			logging.info('\u001B[1m Iperf Test PASS\u001B[0m')
+
+	def IperfExit(self, HTML, status, message):
+		html_queue = SimpleQueue()
+		html_cell = '<pre style="background-color:white">UE\n' + message + '</pre>'
+		html_queue.put(html_cell)
+		if status:
+			HTML.CreateHtmlTestRowQueue(self.cliOptions, 'OK', 1, html_queue)
+		else:
+			self.exitStatus = 1
+			HTML.CreateHtmlTestRowQueue(self.cliOptions, 'KO', 1, html_queue)
diff --git a/ci-scripts/cls_log_mgt.py b/ci-scripts/cls_log_mgt.py
new file mode 100644
index 0000000000000000000000000000000000000000..7fb45ed3ea0f83bdb648c1b5dfe726793f03cca8
--- /dev/null
+++ b/ci-scripts/cls_log_mgt.py
@@ -0,0 +1,107 @@
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+#   Required Python Version
+#     Python 3.x
+#
+#---------------------------------------------------------------------
+
+#USAGE: 
+#	log=Log_Mgt(Username,IPAddress,Password,Path)
+#	log.LogRotation()
+
+
+
+
+import re
+import subprocess
+import logging
+import math
+
+class Log_Mgt:
+
+	def __init__(self,Username, IPAddress,Password,Path):
+		self.Username=Username
+		self.IPAddress=IPAddress
+		self.Password=Password
+		self.path=Path
+
+#-----------------$
+#PRIVATE# Methods$
+#-----------------$
+
+
+	def __CheckAvailSpace(self):
+		HOST=self.Username+'@'+self.IPAddress
+		COMMAND="df "+ self.path
+		ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+		result = ssh.stdout.readlines()
+		s=result[1].decode('utf-8').rstrip()#result[1] is the second line with the results we are looking for
+		tmp=s.split()
+		return tmp[3] #return avail space from the line
+
+	def __GetOldestFile(self):
+		HOST=self.Username+'@'+self.IPAddress
+		COMMAND="ls -rtl "+ self.path #-rtl will bring oldest file on top
+		ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+		result = ssh.stdout.readlines()
+		s=result[1].decode('utf-8').rstrip()
+		tmp=s.split()
+		return tmp[8]#return filename from the line
+
+
+	def __AvgSize(self):
+		HOST=self.Username+'@'+self.IPAddress
+		COMMAND="ls -rtl "+ self.path
+		ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+		result = ssh.stdout.readlines()
+		if len(result)>1: #at least 1 file present
+			total_size=0
+			for i in range(1,len(result)):
+				s=result[i].decode('utf-8').rstrip()
+				tmp=s.split()
+				total_size+=int(tmp[4]) #get filesize
+			return math.floor(total_size/(len(result)-1)) #compute average file/artifact size
+		else:#empty,no files
+			return 0
+
+
+#-----------------$
+#PUBLIC Methods$
+#-----------------$
+
+
+	def LogRotation(self):
+		avail_space =int(self.__CheckAvailSpace())*1000 #avail space in target folder, initially displayed in Gb
+		avg_size=self.__AvgSize() #average size of artifacts in the target folder
+		logging.debug("Avail Space : " + str(avail_space) + " / Artifact Avg Size : " + str(avg_size))
+		if avail_space < 2*avg_size: #reserved space is 2x artifact file ; oldest file will be deleted
+			oldestfile=self.__GetOldestFile()
+			HOST=self.Username+'@'+self.IPAddress
+			COMMAND="echo " + self.Password + " | sudo -S rm "+ self.path + "/" + oldestfile
+			logging.debug(COMMAND)
+			ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+		else:
+			logging.debug("Still some space left for artifacts storage")
+			
+
+
+
diff --git a/ci-scripts/cls_module_ue.py b/ci-scripts/cls_module_ue.py
new file mode 100644
index 0000000000000000000000000000000000000000..96d4e0310ef99bae7be74ca607be4cd91f008554
--- /dev/null
+++ b/ci-scripts/cls_module_ue.py
@@ -0,0 +1,175 @@
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+#   Required Python Version
+#     Python 3.x
+#
+#---------------------------------------------------------------------
+
+#to use isfile
+import os
+import sys
+import logging
+#to create a SSH object locally in the methods
+import sshconnection
+#time.sleep
+import time
+
+
+import re
+import subprocess
+
+from datetime import datetime
+
+#for log rotation mgt
+import cls_log_mgt
+
+class Module_UE:
+
+	def __init__(self,Module):
+		#create attributes as in the Module dictionary
+		for k, v in Module.items():
+			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.ue_trace=''		
+
+
+
+#-----------------$
+#PUBLIC Methods$
+#-----------------$
+
+	#this method checks if the specified Process is running on the server hosting the module
+	#if not it will be started
+	def CheckCMProcess(self):
+		HOST=self.HostUsername+'@'+self.HostIPAddress
+		COMMAND="ps aux | grep " + self.Process['Name'] + " | grep -v grep "
+		logging.debug(COMMAND)
+		ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+		result = ssh.stdout.readlines()
+		if len(result)!=0:
+			logging.debug(self.Process['Name'] + " process found")
+			return True 
+		else:#start process and check again  
+			logging.debug(self.Process['Name'] + " process NOT found")
+			#starting the process
+			logging.debug('Starting ' + self.Process['Name'])
+			mySSH = sshconnection.SSHConnection()
+			mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
+			mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S ' + self.Process['Cmd'] + ' &','\$',5)
+			mySSH.close()
+			#checking the process
+			time.sleep(5)
+			HOST=self.HostUsername+'@'+self.HostIPAddress
+			COMMAND="ps aux | grep " + self.Process['Name'] + " | grep -v grep "
+			logging.debug(COMMAND)
+			ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+			result = ssh.stdout.readlines()
+			if len(result)!=0:
+				logging.debug(self.Process['Name'] + " process found")
+				return True
+			else:
+				logging.debug(self.Process['Name'] + " process NOT found")
+				return False 
+
+	#Generic command function, using function pointers dictionary
+	def Command(self,cmd):
+		mySSH = sshconnection.SSHConnection()
+		mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
+		mySSH.command('echo ' + self.HostPassword + ' | sudo -S python3 ' + self.cmd_dict[cmd],'\$',10)
+		time.sleep(5)
+		logging.debug("Module "+ cmd)
+		mySSH.close()
+
+
+	#this method retrieves the Module IP address (not the Host IP address) 
+	def GetModuleIPAddress(self):
+		HOST=self.HostUsername+'@'+self.HostIPAddress
+		response= []
+		tentative = 3 
+		while (len(response)==0) and (tentative>0):
+			COMMAND="ip a show dev " + self.UENetwork + " | grep inet | grep " + self.UENetwork
+			logging.debug(COMMAND)
+			ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+			response = ssh.stdout.readlines()
+			tentative-=1
+			time.sleep(10)
+		if (tentative==0) and (len(response)==0):
+			logging.debug('\u001B[1;37;41m Module IP Address Not Found! Time expired \u001B[0m')
+			return -1
+		else: #check response
+			result = re.search('inet (?P<moduleipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', response[0].decode("utf-8") )
+			if result is not None: 
+				if result.group('moduleipaddress') is not None: 
+					self.UEIPAddress = result.group('moduleipaddress')
+					logging.debug('\u001B[1mUE Module IP Address is ' + self.UEIPAddress + '\u001B[0m')
+					return 0
+				else:
+					logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m')
+					return -1
+			else:
+				logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m')
+				return -1
+
+	def EnableTrace(self):
+		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()
+		mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
+		mySSH.command('echo ' + self.HostPassword + ' | sudo -S killall --signal=SIGINT *QLog*', '\$',5)
+		mySSH.close()
+
+
+	def DisableCM(self):
+		mySSH = sshconnection.SSHConnection()
+		mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
+		mySSH.command('echo ' + self.HostPassword + ' | sudo -S killall --signal SIGKILL *'+self.Process['Name']+'*', '\$', 5)
+		mySSH.close()
+
+
+	def LogCollect(self):
+		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= self.LogStore + '/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.HostUsername,self.HostIPAddress, self.HostPassword, self.LogStore)
+			Log_Mgt.LogRotation()
+		else:
+			destination=""
+		return destination
diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py
index 7da829b7f7dc401fb423875b1cfd6f0af08fced0..15b28cbe996d7e3f289a5625be41e68311313e81 100644
--- a/ci-scripts/cls_oaicitest.py
+++ b/ci-scripts/cls_oaicitest.py
@@ -54,7 +54,8 @@ import helpreadme as HELP
 import constants as CONST
 import sshconnection
 
-
+import cls_module_ue
+import cls_ci_ueinfra		#class defining the multi Ue infrastrucure
 
 
 #-----------------------------------------------------------
@@ -129,6 +130,7 @@ class OaiCiTest():
 		self.iperf_packetloss_threshold = ''
 		self.iperf_profile = ''
 		self.iperf_options = ''
+		self.iperf_direction = ''
 		self.nbMaxUEtoAttach = -1
 		self.UEDevices = []
 		self.UEDevicesStatus = []
@@ -157,6 +159,8 @@ class OaiCiTest():
 		self.clean_repository = True
 		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):
@@ -174,7 +178,7 @@ class OaiCiTest():
 			ue_prefix = ''
 		result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
 		if result is not None:
-			full_ran_repo_name = self.ranRepository
+			full_ran_repo_name = self.ranRepository.replace('git/', 'git')
 		else:
 			full_ran_repo_name = self.ranRepository + '.git'
 		SSH.command('mkdir -p ' + self.UESourceCodePath, '\$', 5)
@@ -217,7 +221,7 @@ class OaiCiTest():
 
 		# if the commit ID is provided use it to point to it
 		if self.ranCommitID != '':
-			SSH.command('git checkout -f ' + self.ranCommitID, '\$', 5)
+			SSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
 		# if the branch is not develop, then it is a merge request and we need to do 
 		# the potential merge. Note that merge conflicts should already been checked earlier
 		if self.ranAllowMerge:
@@ -364,29 +368,50 @@ class OaiCiTest():
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
-	def InitializeUE(self,HTML,COTS_UE):
-		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			HELP.GenericHelp(CONST.Version)
-			sys.exit('Insufficient Parameter')
-		multi_jobs = []
-		i = 0
-		for device_id in self.UEDevices:
-			p = Process(target = self.InitializeUE_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 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)
+				sys.exit('Insufficient Parameter')
+			multi_jobs = []
+			i = 0
+			for device_id in self.UEDevices:
+				p = Process(target = self.InitializeUE_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
+			#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()
+				time.sleep(5)
+				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 InitializeOAIUE(self,HTML,RAN,EPC,COTS_UE):
+	def InitializeOAIUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
 		if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
 			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
+
+			
 		if self.air_interface == 'lte-uesoftmodem':
 			result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args))
 			if result is None:
@@ -403,13 +428,13 @@ class OaiCiTest():
 		SSH = sshconnection.SSHConnection()
 		SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
 		# b2xx_fx3_utils reset procedure
-		SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60)
+		SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 90)
 		result = re.search('type: b200', SSH.getBefore())
 		if result is not None:
 			logging.debug('Found a B2xx device --> resetting it')
 			SSH.command('echo ' + self.UEPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10)
 			# Reloading FGPA bin firmware
-			SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60)
+			SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 90)
 		result = re.search('type: n3xx', str(SSH.getBefore()))
 		if result is not None:
 			logging.debug('Found a N3xx device --> resetting it')
@@ -563,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
@@ -605,7 +630,7 @@ class OaiCiTest():
 				HTML.htmlUEFailureMsg='nr-uesoftmodem did NOT synced'
 				HTML.CreateHtmlTestRow(self.air_interface + ' ' +  self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE')
 			logging.error('\033[91mInitialize OAI UE Failed! \033[0m')
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 
 	def checkDevTTYisUnlocked(self):
 		SSH = sshconnection.SSHConnection()
@@ -683,7 +708,7 @@ class OaiCiTest():
 		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 		self.checkDevTTYisUnlocked()
 
-	def AttachCatM(self,HTML,RAN,COTS_UE,EPC):
+	def AttachCatM(self,HTML,RAN,COTS_UE,EPC,InfraUE):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
 			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
@@ -756,9 +781,9 @@ class OaiCiTest():
 			html_cell = '<pre style="background-color:white">CAT-M module Attachment Failed</pre>'
 			html_queue.put(html_cell)
 			HTML.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 
-	def PingCatM(self,HTML,RAN,EPC,COTS_UE):
+	def PingCatM(self,HTML,RAN,EPC,COTS_UE,InfraUE):
 		if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '':
 			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
@@ -767,7 +792,7 @@ class OaiCiTest():
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
 		if (pStatus < 0):
 			HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 			return
 		try:
 			statusQueue = SimpleQueue()
@@ -788,7 +813,7 @@ class OaiCiTest():
 					moduleIPAddr = result.group('ipaddr')
 				else:
 					HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
-					self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+					self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 					return
 			ping_time = re.findall("-c (\d+)",str(self.ping_args))
 			device_id = 'catm'
@@ -852,7 +877,7 @@ class OaiCiTest():
 				HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue)
 			else:
 				HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue)
-				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
@@ -944,64 +969,82 @@ class OaiCiTest():
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
-	def AttachUE(self,HTML,RAN,EPC,COTS_UE):
-		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			HELP.GenericHelp(CONST.Version)
-			sys.exit('Insufficient Parameter')
-		check_eNB = True
-		check_OAI_UE = False
-		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
-		if (pStatus < 0):
-			HTML.CreateHtmlTestRow('N/A', 'KO', pStatus)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
-			return
-		multi_jobs = []
-		status_queue = SimpleQueue()
-		lock = Lock()
-		nb_ue_to_connect = 0
-		for device_id in self.UEDevices:
-			if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach):
-				self.UEDevicesStatus[nb_ue_to_connect] = CONST.UE_STATUS_ATTACHING
-				p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,nb_ue_to_connect,COTS_UE,))
-				p.daemon = True
-				p.start()
-				multi_jobs.append(p)
-			nb_ue_to_connect = nb_ue_to_connect + 1
-		for job in multi_jobs:
-			job.join()
-
-		if (status_queue.empty()):
-			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
-			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)
+	def AttachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
+		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)
+				sys.exit('Insufficient Parameter')
+			check_eNB = True
+			check_OAI_UE = False
+			pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
+			if (pStatus < 0):
+				HTML.CreateHtmlTestRow('N/A', 'KO', pStatus)
+				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
+				return
+			multi_jobs = []
+			status_queue = SimpleQueue()
+			lock = Lock()
+			nb_ue_to_connect = 0
+			for device_id in self.UEDevices:
+				if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach):
+					self.UEDevicesStatus[nb_ue_to_connect] = CONST.UE_STATUS_ATTACHING
+					p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,nb_ue_to_connect,COTS_UE,))
+					p.daemon = True
+					p.start()
+					multi_jobs.append(p)
+				nb_ue_to_connect = nb_ue_to_connect + 1
+			for job in multi_jobs:
+				job.join()
+
+			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)
-				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+				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:
@@ -1025,37 +1068,44 @@ class OaiCiTest():
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
-	def DetachUE(self,HTML,RAN,EPC,COTS_UE):
-		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			HELP.GenericHelp(CONST.Version)
-			sys.exit('Insufficient Parameter')
-		check_eNB = True
-		check_OAI_UE = False
-		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
-		if (pStatus < 0):
-			HTML.CreateHtmlTestRow('N/A', 'KO', pStatus)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
-			return
-		multi_jobs = []
-		cnt = 0
-		for device_id in self.UEDevices:
-			self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHING
-			p = Process(target = self.DetachUE_common, args = (device_id,cnt,COTS_UE,))
-			p.daemon = True
-			p.start()
-			multi_jobs.append(p)
-			cnt += 1
-		for job in multi_jobs:
-			job.join()
-		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
-		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)
-		cnt = 0
-		while cnt < len(self.UEDevices):
-			self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHED
-			cnt += 1
+	def DetachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
+		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)
+				sys.exit('Insufficient Parameter')
+			check_eNB = True
+			check_OAI_UE = False
+			pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
+			if (pStatus < 0):
+				HTML.CreateHtmlTestRow('N/A', 'KO', pStatus)
+				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
+				return
+			multi_jobs = []
+			cnt = 0
+			for device_id in self.UEDevices:
+				self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHING
+				p = Process(target = self.DetachUE_common, args = (device_id,cnt,COTS_UE,))
+				p.daemon = True
+				p.start()
+				multi_jobs.append(p)
+				cnt += 1
+			for job in multi_jobs:
+				job.join()
+			HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+			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)
+			cnt = 0
+			while cnt < len(self.UEDevices):
+				self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHED
+				cnt += 1
+		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")
+			HTML.CreateHtmlTestRow('NA', 'OK', CONST.ALL_PROCESSES_OK)	
+				
+							
 
 	def RebootUE_common(self, device_id):
 		try:
@@ -1303,7 +1353,7 @@ class OaiCiTest():
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
-	def CheckStatusUE(self,HTML,RAN,EPC,COTS_UE):
+	def CheckStatusUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
 			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
@@ -1350,7 +1400,7 @@ class OaiCiTest():
 
 		if (status_queue.empty()):
 			HTML.CreateHtmlTestRow(htmlOptions, 'KO', CONST.ALL_PROCESSES_OK)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 		else:
 			check_status = True
 			html_queue = SimpleQueue()
@@ -1366,7 +1416,7 @@ class OaiCiTest():
 				HTML.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue)
 			else:
 				HTML.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue)
-				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 
 	def GetAllUEIPAddresses(self):
 		SSH = sshconnection.SSHConnection()
@@ -1437,14 +1487,20 @@ class OaiCiTest():
 		statusQueue.put(message)
 		lock.release()
 
-	def Ping_common(self, lock, UE_IPAddress, device_id, statusQueue,EPC):
+	def Ping_common(self, lock, UE_IPAddress, device_id, statusQueue,EPC, Module_UE):
 		try:
 			SSH = sshconnection.SSHConnection()
 			# Launch ping on the EPC side (true for ltebox and old open-air-cn)
 			# But for OAI-Rel14-CUPS, we launch from python executor
 			launchFromEpc = True
+			launchFromModule = False
 			if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE):
 				launchFromEpc = False
+			#if module, ping from module to EPC
+			if self.ue_id!='':
+				launchFromEpc = False
+				launchfromModule = True
+
 			ping_time = re.findall("-c (\d+)",str(self.ping_args))
 
 			if launchFromEpc:
@@ -1462,21 +1518,39 @@ class OaiCiTest():
 				#copy the ping log file to have it locally for analysis (ping stats)
 				SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '.')				
 			else:
-				#ping log file is on the python executor
-				cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' 
-				message = cmd + '\n'
-				logging.debug(cmd)
-				ret = subprocess.run(cmd, shell=True)
-				ping_status = ret.returncode
-				#copy the ping log file to an other folder for log collection (source and destination are EPC)
-				SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
-                #copy the ping log file to have it locally for analysis (ping stats)
-				logging.debug(EPC.SourceCodePath + 'ping_' + self.testCase_id + '_' + device_id + '.log')
-				SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath  +'/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '.')
+				if launchfromModule == False:
+					#ping log file is on the python executor
+					cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' 
+					message = cmd + '\n'
+					logging.debug(cmd)
+					ret = subprocess.run(cmd, shell=True)
+					ping_status = ret.returncode
+					#copy the ping log file to an other folder for log collection (source and destination are EPC)
+					SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
+                	#copy the ping log file to have it locally for analysis (ping stats)
+					logging.debug(EPC.SourceCodePath + 'ping_' + self.testCase_id + '_' + device_id + '.log')
+					SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath  +'/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '.')
+
+					SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+					#cat is executed on EPC
+					SSH.command('cat ' + EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+				else: #launch from Module
+					SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
+					#target address is different depending on EPC type
+					if re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE):
+						Target = EPC.MmeIPAddress
+					else:
+						Target = EPC.IPAddress
+					#ping from module NIC rather than IP address to make sure round trip is over the air	
+					cmd = 'ping -I ' + Module_UE.UENetwork  + ' ' + self.ping_args + ' ' +  Target  + ' 2>&1 > ping_' + self.testCase_id + '_' + self.ue_id + '.log' 
+					SSH.command(cmd,'\$',int(ping_time[0])*1.5)
+					#copy the ping log file to have it locally for analysis (ping stats)
+					SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'ping_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
+
+					#cat is executed locally 
+					SSH.command('cat ping_' + self.testCase_id + '_' + self.ue_id + '.log', '\$', 5)
+					ping_status=0
 
-				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
-				#cat is executed on EPC
-				SSH.command('cat ' + EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 			# TIMEOUT CASE
 			if ping_status < 0:
 				message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!'
@@ -1567,14 +1641,14 @@ class OaiCiTest():
 		html_queue.put(html_cell)
 		HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
 
-	def PingNoS1(self,HTML,RAN,EPC,COTS_UE):
+	def PingNoS1(self,HTML,RAN,EPC,COTS_UE,InfraUE):
 		SSH=sshconnection.SSHConnection()
 		check_eNB = True
 		check_OAI_UE = True
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
 		if (pStatus < 0):
 			HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 			return
 		ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args))
 		if ping_from_eNB is not None:
@@ -1660,10 +1734,10 @@ class OaiCiTest():
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
-	def Ping(self,HTML,RAN,EPC,COTS_UE):
+	def Ping(self,HTML,RAN,EPC,COTS_UE, InfraUE):
 		result = re.search('noS1', str(RAN.Initialize_eNB_args))
 		if result is not None:
-			self.PingNoS1(HTML,RAN,EPC,COTS_UE)
+			self.PingNoS1(HTML,RAN,EPC,COTS_UE,InfraUE)
 			return
 		if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '':
 			HELP.GenericHelp(CONST.Version)
@@ -1676,20 +1750,32 @@ class OaiCiTest():
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
 		if (pStatus < 0):
 			HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
-			return
-		ueIpStatus = self.GetAllUEIPAddresses()
-		if (ueIpStatus < 0):
-			HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 			return
+
+		if self.ue_id=="":
+			Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra['dummy']) #RH, temporary, we need a dummy Module_UE object to pass to Ping_common
+			ueIpStatus = self.GetAllUEIPAddresses()
+			if (ueIpStatus < 0):
+				HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
+				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
+				return
+		else:
+			self.UEIPAddresses=[]
+			Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
+			Module_UE.GetModuleIPAddress()
+			self.UEIPAddresses.append(Module_UE.UEIPAddress)
+		logging.debug(self.UEIPAddresses)
 		multi_jobs = []
 		i = 0
 		lock = Lock()
 		status_queue = SimpleQueue()
 		for UE_IPAddress in self.UEIPAddresses:
-			device_id = self.UEDevices[i]
-			p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,EPC,))
+			if self.ue_id=="":
+				device_id = self.UEDevices[i]
+			else:
+				device_id = Module_UE.ID + "-" + Module_UE.Kind 
+			p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,EPC,Module_UE,))
 			p.daemon = True
 			p.start()
 			multi_jobs.append(p)
@@ -1699,7 +1785,7 @@ class OaiCiTest():
 
 		if (status_queue.empty()):
 			HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.ALL_PROCESSES_OK)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 		else:
 			ping_status = True
 			html_queue = SimpleQueue()
@@ -1716,7 +1802,7 @@ class OaiCiTest():
 				HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue)
 			else:
 				HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
-				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 
 	def Iperf_ComputeTime(self):
 		result = re.search('-t (?P<iperf_time>\d+)', str(self.iperf_args))
@@ -1864,8 +1950,8 @@ class OaiCiTest():
 		else:
 			return -2
 
-	def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options):
-		if (not os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')):
+	def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options, filename,type):
+		if (not os.path.isfile(filename)):
 			self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log')
 			return
 		# Computing the requested bandwidth in float
@@ -1890,14 +1976,18 @@ class OaiCiTest():
 				req_bandwidth = '%.1f Gbits/sec' % req_bw
 				req_bw = req_bw * 1000000000
 
-		server_file = open('iperf_server_' + self.testCase_id + '_' + device_id + '.log', 'r')
+		server_file = open(filename, 'r')
 		br_sum = 0.0
 		ji_sum = 0.0
 		pl_sum = 0
 		ps_sum = 0
 		row_idx = 0
 		for line in server_file.readlines():
-			result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(?P<lostPack>[0-9]+)/ +(?P<sentPack>[0-9]+)', str(line))
+			if type==0:
+				result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(?P<lostPack>[0-9]+)/ +(?P<sentPack>[0-9]+)', str(line))
+			else:
+				result = re.search('^\[  \d\].+ +(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(?P<lostPack>[0-9]+)\/(?P<sentPack>[0-9]+)', str(line))
+
 			if result is not None:
 				bitrate = result.group('bitrate')
 				jitter = result.group('jitter')
@@ -2127,12 +2217,95 @@ class OaiCiTest():
 					SSH.command('docker cp prod-trf-gen:/iperf-2.0.5/iperf_server_' + self.testCase_id + '_' + device_id + '.log ' + EPC.SourceCodePath + '/scripts', '\$', 5)
 					SSH.close()
 				SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath+ '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
-			self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options)
+			filename='iperf_server_' + self.testCase_id + '_' + device_id + '.log'
+			self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options,filename,0)
 		# in case of OAI-UE 
 		if (device_id == 'OAI-UE'):
 			SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.')
 			SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
 
+
+	def Iperf_Module(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC, Module_UE):
+		SSH = sshconnection.SSHConnection()
+		#RH temporary quick n dirty for test
+		SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+		cmd = 'echo ' + EPC.Password + ' | sudo -S ip link set dev tun5 mtu 1358'
+		SSH.command(cmd,'\$',5)	
+		SSH.close()
+			
+
+		#kill iperf processes before (in case there are still some remaining)
+		SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
+		cmd = 'killall --signal=SIGKILL iperf'
+		SSH.command(cmd,'\$',5)
+		SSH.close()
+		SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+		cmd = 'killall --signal=SIGKILL iperf'
+		SSH.command(cmd,'\$',5)
+		SSH.close()
+
+
+		iperf_time = self.Iperf_ComputeTime()	
+		if self.iperf_direction=="DL":
+			logging.debug("Iperf for Module in DL mode detected")
+			#server side UE
+			SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
+			cmd = 'rm iperf_server_' +  self.testCase_id + '_' + self.ue_id + '.log'
+			SSH.command(cmd,'\$',5)
+			cmd = 'echo $USER; nohup /opt/iperf-2.0.10/iperf -s -B ' + UE_IPAddress + ' -u  2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log' 
+			SSH.command(cmd,'\$',5)
+			SSH.close()
+			#client side EPC
+			SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+			cmd = 'rm iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
+			SSH.command(cmd,'\$',5)
+			cmd = 'iperf -c ' + UE_IPAddress + ' ' + self.iperf_args + ' 2>&1 > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log' 
+			SSH.command(cmd,'\$',int(iperf_time)*5.0)
+			SSH.close()
+			#copy the 2 resulting files locally
+			SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
+			SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
+			#send for analysis
+			filename='iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
+			self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, self.iperf_args,filename,1)	
+
+		elif self.iperf_direction=="UL":#does not work at the moment
+			logging.debug("Iperf for Module in UL mode detected")
+			#server side EPC
+			SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+			cmd = 'rm iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
+			SSH.command(cmd,'\$',5)
+			cmd = 'echo $USER; nohup iperf -s -u 2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
+			SSH.command(cmd,'\$',5)
+			SSH.close()
+
+			#client side UE
+			SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
+			cmd = 'rm iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
+			SSH.command(cmd,'\$',5)
+			SSH.command('/opt/iperf-2.0.10/iperf -c 192.172.0.1 ' + self.iperf_args + ' 2>&1 > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '\$', int(iperf_time)*5.0)
+			SSH.close()
+
+			#copy the 2 resulting files locally
+			SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
+			SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
+			#send for analysis
+			filename='iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
+			self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, self.iperf_args,filename,1)
+		else :
+			logging.debug("Incorrect or missing IPERF direction in XML")
+
+		#kill iperf processes after to be clean
+		SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
+		cmd = 'killall --signal=SIGKILL iperf'
+		SSH.command(cmd,'\$',5)
+		SSH.close()
+		SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+		cmd = 'killall --signal=SIGKILL iperf'
+		SSH.command(cmd,'\$',5)
+		SSH.close()
+		return
+
 	def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC):
 		try:
 			SSH = sshconnection.SSHConnection()
@@ -2229,8 +2402,13 @@ class OaiCiTest():
 			# Launch the IPERF client on the EPC side for DL (true for ltebox and old open-air-cn
 			# But for OAI-Rel14-CUPS, we launch from python executor
 			launchFromEpc = True
+			launchFromModule = False
 			if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE):
 				launchFromEpc = False
+			#if module
+			if self.ue_id!='' and self.iperf :
+				launchFromEpc = False
+				launchfromModule = True
 			# When using a docker-based deployment, IPERF client shall be launched from trf container
 			launchFromTrfContainer = False
 			if re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE):
@@ -2334,7 +2512,8 @@ class OaiCiTest():
 					subprocess.run(cmd, shell=True)
 				except:
 					pass
-				self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options)
+				filename='iperf_server_' + self.testCase_id + '_' + device_id + '.log'
+				self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options,filename,0)
 
 			# in case of OAI UE: 
 			if (device_id == 'OAI-UE'):
@@ -2347,7 +2526,7 @@ class OaiCiTest():
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
-	def IperfNoS1(self,HTML,RAN,EPC,COTS_UE):
+	def IperfNoS1(self,HTML,RAN,EPC,COTS_UE,InfraUE):
 		SSH = sshconnection.SSHConnection()
 		if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '':
 			HELP.GenericHelp(CONST.Version)
@@ -2357,7 +2536,7 @@ class OaiCiTest():
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
 		if (pStatus < 0):
 			HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 			return
 		server_on_enb = re.search('-R', str(self.iperf_args))
 		if server_on_enb is not None:
@@ -2422,7 +2601,8 @@ class OaiCiTest():
 			if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')):
 				os.remove('iperf_server_' + self.testCase_id + '.log')
 			SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log')
-			self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options)
+			filename='iperf_server_' + self.testCase_id + '_OAI-UE.log'
+			self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options,filename,0)
 
 		# copying on the EPC server for logCollection
 		if (clientStatus == -1):
@@ -2455,12 +2635,12 @@ class OaiCiTest():
 			HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue)
 		else:
 			HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 
-	def Iperf(self,HTML,RAN,EPC,COTS_UE):
+	def Iperf(self,HTML,RAN,EPC,COTS_UE, InfraUE):
 		result = re.search('noS1', str(RAN.Initialize_eNB_args))
 		if result is not None:
-			self.IperfNoS1(HTML,RAN,EPC,COTS_UE)
+			self.IperfNoS1(HTML,RAN,EPC,COTS_UE,InfraUE)
 			return
 		if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
 			HELP.GenericHelp(CONST.Version)
@@ -2473,15 +2653,24 @@ class OaiCiTest():
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
 		if (pStatus < 0):
 			HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
-			return
-		ueIpStatus = self.GetAllUEIPAddresses()
-		if (ueIpStatus < 0):
-			logging.debug('going here')
-			HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 			return
 
+		if self.ue_id=="":#is not a module, follow legacy code
+			ueIpStatus = self.GetAllUEIPAddresses()
+			if (ueIpStatus < 0):
+				HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
+				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
+				return
+		else: #is a module
+			self.UEIPAddresses=[]
+			Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
+			Module_UE.GetModuleIPAddress()
+			self.UEIPAddresses.append(Module_UE.UEIPAddress)
+
+
+
+
 		self.dummyIperfVersion = '2.0.10'
 		#cmd = 'iperf --version'
 		#logging.debug(cmd + '\n')
@@ -2498,9 +2687,15 @@ class OaiCiTest():
 		ue_num = len(self.UEIPAddresses)
 		lock = Lock()
 		status_queue = SimpleQueue()
+		logging.debug(self.UEIPAddresses)
 		for UE_IPAddress in self.UEIPAddresses:
 			device_id = self.UEDevices[i]
-			p = Process(target = self.Iperf_common, args = (lock,UE_IPAddress,device_id,i,ue_num,status_queue,EPC,))
+        	#special quick and dirty treatment for modules, iperf to be restructured
+			if self.ue_id!="": #is module
+				device_id = Module_UE.ID + "-" + Module_UE.Kind
+				p = Process(target = self.Iperf_Module ,args = (lock, UE_IPAddress, device_id, i, ue_num, status_queue, EPC, Module_UE,))
+			else: #legacy code
+				p = Process(target = self.Iperf_common, args = (lock, UE_IPAddress, device_id, i, ue_num, status_queue, EPC, ))
 			p.daemon = True
 			p.start()
 			multi_jobs.append(p)
@@ -2510,7 +2705,7 @@ class OaiCiTest():
 
 		if (status_queue.empty()):
 			HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.ALL_PROCESSES_OK)
-			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+			self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfaUE)
 		else:
 			iperf_status = True
 			iperf_noperf = False
@@ -2532,7 +2727,7 @@ class OaiCiTest():
 				HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue)
 			else:
 				HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue)
-				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 
 	def CheckProcessExist(self, check_eNB, check_OAI_UE,RAN,EPC):
 		multi_jobs = []
@@ -2937,22 +3132,34 @@ 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):
+	def TerminateOAIUE(self,HTML,RAN,COTS_UE,EPC, InfraUE):
 		SSH = sshconnection.SSHConnection()
 		SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
 		SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5)
@@ -2993,11 +3200,11 @@ class OaiCiTest():
 					# Not an error then
 					if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'):
 						self.Initialize_OAI_UE_args = ''
-						self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+						self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 				else:
 					if (logStatus == CONST.OAI_UE_PROCESS_COULD_NOT_SYNC):
 						self.Initialize_OAI_UE_args = ''
-						self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
+						self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE)
 			else:
 				logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m')
 				HTML.htmlUEFailureMsg='<b>' + ueAction + ' Completed</b>\n' + HTML.htmlUEFailureMsg
@@ -3006,21 +3213,21 @@ class OaiCiTest():
 		else:
 			HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
-	def AutoTerminateUEandeNB(self,HTML,RAN,COTS_UE,EPC):
+	def AutoTerminateUEandeNB(self,HTML,RAN,COTS_UE,EPC,InfraUE):
 		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
 			self.desc = 'Automatic Termination of OAI-UE'
 			HTML.desc='Automatic Termination of OAI-UE'
 			self.ShowTestID()
-			self.TerminateOAIUE(HTML,RAN,COTS_UE,EPC)
+			self.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE)
 		if (RAN.Initialize_eNB_args != ''):
 			self.testCase_id = 'AUTO-KILL-RAN'
 			HTML.testCase_id=self.testCase_id
@@ -3273,7 +3480,7 @@ class OaiCiTest():
 				UhdVersion = result.group('uhd_version')
 				logging.debug('UHD Version is: ' + UhdVersion)
 				HTML.UhdVersion[idx]=UhdVersion
-		SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 60)
+		SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 90)
 		usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', SSH.getBefore())
 		count = 0
 		for board in usrp_boards:
diff --git a/ci-scripts/cls_physim.py b/ci-scripts/cls_physim.py
index 4ca36b8cf0f6c485b31cb025349e3a693531d1ca..e825b2f7bd694b3abdeb3d7c7c69024ebf65ada5 100644
--- a/ci-scripts/cls_physim.py
+++ b/ci-scripts/cls_physim.py
@@ -1,191 +1,191 @@
-# * 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
-# */
-#---------------------------------------------------------------------
-# Python for CI of OAI-eNB + COTS-UE
-#
-#   Required Python Version
-#     Python 3.x
-#
-#   Required Python Package
-#     pexpect
-#---------------------------------------------------------------------
-
-#to use logging.info()
-import logging
-#to create a SSH object locally in the methods
-import sshconnection
-#to update the HTML object
-import html
-from multiprocessing import SimpleQueue
-#for log folder maintenance
-import os
-
-class PhySim:
-	def __init__(self):
-		self.buildargs = ""
-		self.runargs = ""
-		self.eNBIpAddr = ""
-		self.eNBUserName = ""
-		self.eNBPassWord = ""
-		self.eNBSourceCodePath = ""
-		self.ranRepository = ""
-		self.ranBranch = ""
-		self.ranCommitID= ""
-		self.ranAllowMerge= ""
-		self.ranTargetBranch= ""
-		self.exitStatus=0
-		self.forced_workspace_cleanup=False
-		#private attributes
-		self.__workSpacePath=''
-		self.__buildLogFile='compile_phy_sim.log'
-		self.__runLogFile=''
-		self.__runResults=[]
-		self.__runLogPath='phy_sim_logs'
-
-
-#-----------------
-#PRIVATE Methods
-#-----------------
-
-	def __CheckResults_PhySim(self,HTML,CONST,testcase_id):
-		mySSH = sshconnection.SSHConnection()
-		mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
-		#retrieve run log file and store it locally$
-		mySSH.copyin(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord, self.__workSpacePath+self.__runLogFile, '.')
-		mySSH.close()
-		#parse results looking for Encoding and Decoding mean values
-		self.__runResults=[]
-		with open(self.__runLogFile) as f:
-			for line in f:
-				if 'mean' in line:
-					self.__runResults.append(line)
-		#the values are appended for each mean value (2), so we take these 2 values from the list
-		info=self.__runResults[0]+self.__runResults[1]
-
-		#once parsed move the local logfile to its folder for tidiness
-		os.system('mv '+self.__runLogFile+' '+ self.__runLogPath+'/.')
-
-		#updating the HTML with results
-		html_cell = '<pre style="background-color:white">' + info  + '</pre>'
-		html_queue=SimpleQueue()
-		html_queue.put(html_cell)
-		HTML.CreateHtmlTestRowQueue(self.runargs, 'OK', 1, html_queue)
-		return HTML
-
-
-	def __CheckBuild_PhySim(self, HTML, CONST):
-		self.__workSpacePath=self.eNBSourceCodePath+'/cmake_targets/'
-		mySSH = sshconnection.SSHConnection()
-		mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
-		#retrieve compile log file and store it locally
-		mySSH.copyin(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord, self.__workSpacePath+self.__buildLogFile, '.')
-		#delete older run log file
-		mySSH.command('rm ' + self.__workSpacePath+self.__runLogFile, '\$', 5)
-		mySSH.close()
-		#check build result from local compile log file
-		buildStatus=False
-		with open(self.__buildLogFile) as f:
-		#nr_prachsim is the last compile step
-			if 'nr_prachsim compiled' in f.read():
-				buildStatus=True
-		#update HTML based on build status
-		if buildStatus:
-			HTML.CreateHtmlTestRow(self.buildargs, 'OK', CONST.ALL_PROCESSES_OK, 'LDPC')
-			self.exitStatus=0
-		else:
-			logging.error('\u001B[1m Building Physical Simulators Failed\u001B[0m')
-			HTML.CreateHtmlTestRow(self.buildargs, 'KO', CONST.ALL_PROCESSES_OK, 'LDPC')
-			HTML.CreateHtmlTabFooter(False)
-			#exitStatus=1 will do a sys.exit in main
-			self.exitStatus=1
-		return HTML
-
-
-#-----------------$
-#PUBLIC Methods$
-#-----------------$
-
-	def Build_PhySim(self,htmlObj,constObj):
-		mySSH = sshconnection.SSHConnection()    
-		mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
-
-		#create working dir    
-		mySSH.command('mkdir -p ' + self.eNBSourceCodePath, '\$', 5)
-		mySSH.command('cd ' + self.eNBSourceCodePath, '\$', 5)
-
-		if not self.ranRepository.lower().endswith('.git'):
-			self.ranRepository+='.git'
-
-		#git clone
-		mySSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone '  + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600)
-		#git config 
-		mySSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
-		mySSH.command('git config user.name "OAI Jenkins"', '\$', 5) 
-
-		#git clean depending on self.forced_workspace_cleanup captured in xml
-		if self.forced_workspace_cleanup==True:
-			logging.info('Cleaning workspace ...')
-			mySSH.command('echo ' + self.eNBPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30)
-		else:
-			logging.info('Workspace cleaning was disabled')
-
-		# if the commit ID is provided, use it to point to it
-		if self.ranCommitID != '':
-			mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 5)
-		# if the branch is not develop, then it is a merge request and we need to do 
-		# the potential merge. Note that merge conflicts should have already been checked earlier
-		if (self.ranAllowMerge):
-			if self.ranTargetBranch == '':
-				if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'):
-					mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5)
-			else:
-				logging.info('Merging with the target branch: ' + self.ranTargetBranch)
-				mySSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
-
-		#build
-		mySSH.command('source oaienv', '\$', 5)
-		mySSH.command('cd cmake_targets', '\$', 5)
-		mySSH.command('mkdir -p log', '\$', 5)
-		mySSH.command('chmod 777 log', '\$', 5)
-		mySSH.command('stdbuf -o0 ./build_oai ' + self.buildargs + ' 2>&1 | stdbuf -o0 tee ' + self.__buildLogFile, 'Bypassing the Tests|build have failed', 1500) 
-
-		mySSH.close()
-		#check build status and update HTML object
-		lHTML = html.HTMLManagement()
-		lHTML=self.__CheckBuild_PhySim(htmlObj,constObj)
-		return lHTML
-
-
-	def Run_PhySim(self,htmlObj,constObj,testcase_id):
-		#create run logs folder locally
-		os.system('mkdir -p ./'+self.__runLogPath)
-		#log file is tc_<testcase_id>.log remotely
-		self.__runLogFile='physim_'+str(testcase_id)+'.log'
-		#open a session for test run
-		mySSH = sshconnection.SSHConnection()
-		mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
-		mySSH.command('cd '+self.__workSpacePath,'\$',5)
-		#run and redirect the results to a log file
-		mySSH.command(self.__workSpacePath+'phy_simulators/build/ldpctest ' + self.runargs + ' >> '+self.__runLogFile, '\$', 30)   
-		mySSH.close()
-		#return updated HTML to main
-		lHTML = html.HTMLManagement()
-		lHTML=self.__CheckResults_PhySim(htmlObj,constObj,testcase_id)
-		return lHTML
+# * 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
+# */
+#---------------------------------------------------------------------
+# Python for CI of OAI-eNB + COTS-UE
+#
+#   Required Python Version
+#     Python 3.x
+#
+#   Required Python Package
+#     pexpect
+#---------------------------------------------------------------------
+
+#to use logging.info()
+import logging
+#to create a SSH object locally in the methods
+import sshconnection
+#to update the HTML object
+import html
+from multiprocessing import SimpleQueue
+#for log folder maintenance
+import os
+
+class PhySim:
+	def __init__(self):
+		self.buildargs = ""
+		self.runargs = ""
+		self.eNBIpAddr = ""
+		self.eNBUserName = ""
+		self.eNBPassWord = ""
+		self.eNBSourceCodePath = ""
+		self.ranRepository = ""
+		self.ranBranch = ""
+		self.ranCommitID= ""
+		self.ranAllowMerge= ""
+		self.ranTargetBranch= ""
+		self.exitStatus=0
+		self.forced_workspace_cleanup=False
+		#private attributes
+		self.__workSpacePath=''
+		self.__buildLogFile='compile_phy_sim.log'
+		self.__runLogFile=''
+		self.__runResults=[]
+		self.__runLogPath='phy_sim_logs'
+
+
+#-----------------
+#PRIVATE Methods
+#-----------------
+
+	def __CheckResults_PhySim(self,HTML,CONST,testcase_id):
+		mySSH = sshconnection.SSHConnection()
+		mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
+		#retrieve run log file and store it locally$
+		mySSH.copyin(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord, self.__workSpacePath+self.__runLogFile, '.')
+		mySSH.close()
+		#parse results looking for Encoding and Decoding mean values
+		self.__runResults=[]
+		with open(self.__runLogFile) as f:
+			for line in f:
+				if 'mean' in line:
+					self.__runResults.append(line)
+		#the values are appended for each mean value (2), so we take these 2 values from the list
+		info=self.__runResults[0]+self.__runResults[1]
+
+		#once parsed move the local logfile to its folder for tidiness
+		os.system('mv '+self.__runLogFile+' '+ self.__runLogPath+'/.')
+
+		#updating the HTML with results
+		html_cell = '<pre style="background-color:white">' + info  + '</pre>'
+		html_queue=SimpleQueue()
+		html_queue.put(html_cell)
+		HTML.CreateHtmlTestRowQueue(self.runargs, 'OK', 1, html_queue)
+		return HTML
+
+
+	def __CheckBuild_PhySim(self, HTML, CONST):
+		self.__workSpacePath=self.eNBSourceCodePath+'/cmake_targets/'
+		mySSH = sshconnection.SSHConnection()
+		mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
+		#retrieve compile log file and store it locally
+		mySSH.copyin(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord, self.__workSpacePath+self.__buildLogFile, '.')
+		#delete older run log file
+		mySSH.command('rm ' + self.__workSpacePath+self.__runLogFile, '\$', 5)
+		mySSH.close()
+		#check build result from local compile log file
+		buildStatus=False
+		with open(self.__buildLogFile) as f:
+		#nr_prachsim is the last compile step
+			if 'nr_prachsim compiled' in f.read():
+				buildStatus=True
+		#update HTML based on build status
+		if buildStatus:
+			HTML.CreateHtmlTestRow(self.buildargs, 'OK', CONST.ALL_PROCESSES_OK, 'LDPC')
+			self.exitStatus=0
+		else:
+			logging.error('\u001B[1m Building Physical Simulators Failed\u001B[0m')
+			HTML.CreateHtmlTestRow(self.buildargs, 'KO', CONST.ALL_PROCESSES_OK, 'LDPC')
+			HTML.CreateHtmlTabFooter(False)
+			#exitStatus=1 will do a sys.exit in main
+			self.exitStatus=1
+		return HTML
+
+
+#-----------------$
+#PUBLIC Methods$
+#-----------------$
+
+	def Build_PhySim(self,htmlObj,constObj):
+		mySSH = sshconnection.SSHConnection()
+		mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
+
+		#create working dir
+		mySSH.command('mkdir -p ' + self.eNBSourceCodePath, '\$', 5)
+		mySSH.command('cd ' + self.eNBSourceCodePath, '\$', 5)
+
+		if not self.ranRepository.lower().endswith('.git'):
+			self.ranRepository+='.git'
+
+		#git clone
+		mySSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone '  + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600)
+		#git config
+		mySSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
+		mySSH.command('git config user.name "OAI Jenkins"', '\$', 5)
+
+		#git clean depending on self.forced_workspace_cleanup captured in xml
+		if self.forced_workspace_cleanup==True:
+			logging.info('Cleaning workspace ...')
+			mySSH.command('echo ' + self.eNBPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30)
+		else:
+			logging.info('Workspace cleaning was disabled')
+
+		# if the commit ID is provided, use it to point to it
+		if self.ranCommitID != '':
+			mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
+		# if the branch is not develop, then it is a merge request and we need to do
+		# the potential merge. Note that merge conflicts should have already been checked earlier
+		if (self.ranAllowMerge):
+			if self.ranTargetBranch == '':
+				if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'):
+					mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5)
+			else:
+				logging.info('Merging with the target branch: ' + self.ranTargetBranch)
+				mySSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
+
+		#build
+		mySSH.command('source oaienv', '\$', 5)
+		mySSH.command('cd cmake_targets', '\$', 5)
+		mySSH.command('mkdir -p log', '\$', 5)
+		mySSH.command('chmod 777 log', '\$', 5)
+		mySSH.command('stdbuf -o0 ./build_oai ' + self.buildargs + ' 2>&1 | stdbuf -o0 tee ' + self.__buildLogFile, 'Bypassing the Tests|build have failed', 1500)
+
+		mySSH.close()
+		#check build status and update HTML object
+		lHTML = html.HTMLManagement()
+		lHTML=self.__CheckBuild_PhySim(htmlObj,constObj)
+		return lHTML
+
+
+	def Run_PhySim(self,htmlObj,constObj,testcase_id):
+		#create run logs folder locally
+		os.system('mkdir -p ./'+self.__runLogPath)
+		#log file is tc_<testcase_id>.log remotely
+		self.__runLogFile='physim_'+str(testcase_id)+'.log'
+		#open a session for test run
+		mySSH = sshconnection.SSHConnection()
+		mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
+		mySSH.command('cd '+self.__workSpacePath,'\$',5)
+		#run and redirect the results to a log file
+		mySSH.command(self.__workSpacePath+'phy_simulators/build/ldpctest ' + self.runargs + ' >> '+self.__runLogFile, '\$', 30)
+		mySSH.close()
+		#return updated HTML to main
+		lHTML = html.HTMLManagement()
+		lHTML=self.__CheckResults_PhySim(htmlObj,constObj,testcase_id)
+		return lHTML
diff --git a/ci-scripts/cls_physim1.py b/ci-scripts/cls_physim1.py
new file mode 100644
index 0000000000000000000000000000000000000000..131aa01c4c90babbf9af457c6dabd443843d4326
--- /dev/null
+++ b/ci-scripts/cls_physim1.py
@@ -0,0 +1,342 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+# Python for CI of OAI-eNB + COTS-UE
+#
+#   Required Python Version
+#     Python 3.x
+#
+#   Required Python Package
+#     pexpect
+#---------------------------------------------------------------------
+
+#-----------------------------------------------------------
+# Import
+#-----------------------------------------------------------
+import logging
+import sshconnection as SSH
+import html
+import os
+import re
+import time
+import sys
+import constants as CONST
+import helpreadme as HELP
+
+class PhySim:
+	def __init__(self):
+		self.eNBIpAddr = ""
+		self.eNBUserName = ""
+		self.eNBPassword = ""
+		self.OCUserName = ""
+		self.OCPassword = ""
+		self.OCProjectName = ""
+		self.eNBSourceCodePath = ""
+		self.ranRepository = ""
+		self.ranBranch = ""
+		self.ranCommitID= ""
+		self.ranAllowMerge= False
+		self.ranTargetBranch= ""
+		self.testResult = {}
+		self.testCount = [0,0,0]
+		self.testSummary = {}
+		self.testStatus = False
+
+#-----------------$
+#PUBLIC Methods$
+#-----------------$
+
+	def Deploy_PhySim(self, HTML, RAN):
+		if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
+			HELP.GenericHelp(CONST.Version)
+			sys.exit('Insufficient Parameter')
+		lIpAddr = self.eNBIPAddress
+		lUserName = self.eNBUserName
+		lPassWord = self.eNBPassword
+		lSourcePath = self.eNBSourceCodePath
+		ocUserName = self.OCUserName
+		ocPassword = self.OCPassword
+		ocProjectName = self.OCProjectName
+
+		if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '' or ocUserName == '' or ocPassword == '' or ocProjectName == '':
+			HELP.GenericHelp(CONST.Version)
+			sys.exit('Insufficient Parameter')
+		logging.debug('Building on server: ' + lIpAddr)
+		mySSH = SSH.SSHConnection()
+		mySSH.open(lIpAddr, lUserName, lPassWord)
+
+		self.testCase_id = HTML.testCase_id
+
+		# on RedHat/CentOS .git extension is mandatory
+		result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
+		if result is not None:
+			full_ran_repo_name = self.ranRepository.replace('git/', 'git')
+		else:
+			full_ran_repo_name = self.ranRepository + '.git'
+		mySSH.command('echo ' + lPassWord + ' | sudo rm -Rf ' + lSourcePath, '\$', 30)
+		mySSH.command('mkdir -p ' + lSourcePath, '\$', 5)
+		mySSH.command('cd ' + lSourcePath, '\$', 5)
+		mySSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600)
+		# Raphael: here add a check if git clone or git fetch went smoothly
+		mySSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
+		mySSH.command('git config user.name "OAI Jenkins"', '\$', 5)
+
+		mySSH.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30)
+		mySSH.command('mkdir -p cmake_targets/log', '\$', 5)
+		# if the commit ID is provided use it to point to it
+		if self.ranCommitID != '':
+			mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
+		if self.ranAllowMerge:
+			imageTag = "ci-temp"
+			if self.ranTargetBranch == '':
+				if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'):
+					mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5)
+			else:
+				logging.debug('Merging with the target branch: ' + self.ranTargetBranch)
+				mySSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
+		else:
+			imageTag = "develop"
+		# Check if image is exist on the Red Hat server, before pushing it to OC cluster
+		mySSH.command("sudo podman image inspect --format='Size = {{.Size}} bytes' oai-physim:" + imageTag, '\$', 60)
+		if mySSH.getBefore().count('no such image') != 0:
+			logging.error('\u001B[1m No such image oai-physim\u001B[0m')
+			mySSH.close()
+			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.PHYSIM_IMAGE_ABSENT)
+			RAN.prematureExit = True
+			return
+		else:
+			result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', mySSH.getBefore())
+			if result is not None:
+				imageSize = float(result.group('size'))
+				imageSize = imageSize / 1000
+				if imageSize < 1000:
+					logging.debug('\u001B[1m   oai-physim size is ' + ('%.0f' % imageSize) + ' kbytes\u001B[0m')
+				else:
+					imageSize = imageSize / 1000
+					if imageSize < 1000:
+						logging.debug('\u001B[1m   oai-physim size is ' + ('%.0f' % imageSize) + ' Mbytes\u001B[0m')
+					else:
+						imageSize = imageSize / 1000
+						logging.debug('\u001B[1m   oai-physim is ' + ('%.3f' % imageSize) + ' Gbytes\u001B[0m')
+			else:
+				logging.debug('oai-physim size is unknown')
+
+		# logging to OC Cluster and then switch to corresponding project
+		mySSH.command(f'oc login -u {ocUserName} -p {ocPassword}', '\$', 6)
+		if mySSH.getBefore().count('Login successful.') == 0:
+			logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m')
+			mySSH.close()
+			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL)
+			RAN.prematureExit = True
+			return
+		else:
+			logging.debug('\u001B[1m   Login to OC Cluster Successfully\u001B[0m')
+		mySSH.command(f'oc project {ocProjectName}', '\$', 6)
+		if mySSH.getBefore().count(f'Already on project "{ocProjectName}"') == 0 and mySSH.getBefore().count(f'Now using project "{self.OCProjectName}"') == 0:
+			logging.error(f'\u001B[1m Unable to access OC project {ocProjectName}\u001B[0m')
+			mySSH.close()
+			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_PROJECT_FAIL)
+			RAN.prematureExit = True
+			return
+		else:
+			logging.debug(f'\u001B[1m   Now using project {ocProjectName}\u001B[0m')
+
+		# Tag the image and push to the OC cluster
+		mySSH.command('oc whoami -t | sudo podman login -u ' + ocUserName + ' --password-stdin https://default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/ --tls-verify=false', '\$', 6)
+		if mySSH.getBefore().count('Login Succeeded!') == 0:
+			logging.error('\u001B[1m Podman Login to OC Cluster Registry Failed\u001B[0m')
+			mySSH.close()
+			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL)
+			RAN.prematureExit = True
+			return
+		else:
+			logging.debug('\u001B[1m Podman Login to OC Cluster Registry Successfully\u001B[0m')
+		time.sleep(2)
+		mySSH.command('oc create -f openshift/oai-physim-image-stream.yml', '\$', 6)
+		if mySSH.getBefore().count('(AlreadyExists):') == 0 and mySSH.getBefore().count('created') == 0:
+			logging.error(f'\u001B[1m Image Stream "oai-physim" Creation Failed on OC Cluster {ocProjectName}\u001B[0m')
+			mySSH.close()
+			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_IS_FAIL)
+			RAN.prematureExit = True
+			return
+		else:
+			logging.debug(f'\u001B[1m   Image Stream "oai-physim" created on OC project {ocProjectName}\u001B[0m')
+		time.sleep(2)
+		mySSH.command(f'sudo podman tag oai-physim:{imageTag} default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
+		time.sleep(2)
+		mySSH.command(f'sudo podman push default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag} --tls-verify=false', '\$', 30)
+		if mySSH.getBefore().count('Storing signatures') == 0:
+			logging.error('\u001B[1m Image "oai-physim" push to OC Cluster Registry Failed\u001B[0m')
+			mySSH.close()
+			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_IS_FAIL)
+			RAN.prematureExit = True
+			return
+		else:
+			logging.debug('\u001B[1m Image "oai-physim" push to OC Cluster Registry Successfully\u001B[0m')
+
+		# Using helm charts deployment
+		time.sleep(5)
+		mySSH.command(f'sed -i -e "s#TAG#{imageTag}#g" ./charts/physims/values.yaml', '\$', 6)
+		mySSH.command('helm install physim ./charts/physims/ | tee -a cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
+		if mySSH.getBefore().count('STATUS: deployed') == 0:
+			logging.error('\u001B[1m Deploying PhySim Failed using helm chart on OC Cluster\u001B[0m')
+			mySSH.command('helm uninstall physim >> cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
+			isFinished1 = False
+			while(isFinished1 == False):
+				time.sleep(20)
+				mySSH.command('oc get pods -l app.kubernetes.io/instance=physim', '\$', 6, resync=True)
+				if re.search('No resources found', mySSH.getBefore()):
+					isFinished1 = True
+			mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
+			mySSH.command('oc delete is oai-physim', '\$', 6)
+			mySSH.close()
+			self.AnalyzeLogFile_phySim(HTML)
+			RAN.prematureExit = True
+			return
+		else:
+			logging.debug('\u001B[1m   Deployed PhySim Successfully using helm chart\u001B[0m')
+		isRunning = False
+		count = 0
+		while(count < 2 and isRunning == False):
+			time.sleep(60)
+			mySSH.command('oc get pods -o wide -l app.kubernetes.io/instance=physim | tee -a cmake_targets/log/physim_pods_summary.txt', '\$', 6, resync=True)
+			if mySSH.getBefore().count('Running') == 12:
+				logging.debug('\u001B[1m Running the physim test Scenarios\u001B[0m')
+				isRunning = True
+				podNames = re.findall('oai-[\S\d\w]+', mySSH.getBefore())
+			count +=1
+		if isRunning == False:
+			logging.error('\u001B[1m Some PODS Running FAILED \u001B[0m')
+			mySSH.command('oc get pods -l app.kubernetes.io/instance=physim 2>&1 | tee -a cmake_targets/log/physim_pods_summary.txt', '\$', 6)
+			mySSH.command('helm uninstall physim >> cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
+			self.AnalyzeLogFile_phySim(HTML)
+			isFinished1 = False
+			while(isFinished1 == False):
+				time.sleep(20)
+				mySSH.command('oc get pods -l app.kubernetes.io/instance=physim', '\$', 6, resync=True)
+				if re.search('No resources found', mySSH.getBefore()):
+					isFinished1 = True
+			mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
+			mySSH.command('oc delete is oai-physim', '\$', 6)
+			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_PHYSIM_DEPLOY_FAIL)
+			HTML.CreateHtmlTestRowPhySimTestResult(self.testSummary,self.testResult)
+			RAN.prematureExit = True
+			return
+		# Waiting to complete the running test
+		count = 0
+		isFinished = False
+		# doing a deep copy!
+		tmpPodNames = podNames.copy()
+		while(count < 32 and isFinished == False):
+			time.sleep(60)
+			for podName in tmpPodNames:
+				mySSH.command2(f'oc logs --tail=1 {podName} 2>&1', 6, silent=True)
+				if mySSH.cmd2Results.count('FINISHED') != 0:
+					logging.debug(podName + ' is finished')
+					tmpPodNames.remove(podName)
+			if not tmpPodNames:
+				isFinished = True
+			count += 1
+		if isFinished:
+			logging.debug('\u001B[1m PhySim test is Complete\u001B[0m')
+		else:
+			logging.error('\u001B[1m PhySim test Timed-out!\u001B[0m')
+
+		# Getting the logs of each executables running in individual pods
+		for podName in podNames:
+			mySSH.command(f'oc logs {podName} >> cmake_targets/log/physim_test.txt 2>&1', '\$', 15, resync=True)
+		time.sleep(30)
+
+		# UnDeploy the physical simulator pods
+		mySSH.command('helm uninstall physim | tee -a cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
+		isFinished1 = False
+		while(isFinished1 == False):
+			time.sleep(20)
+			mySSH.command('oc get pods -l app.kubernetes.io/instance=physim', '\$', 6, resync=True)
+			if re.search('No resources found', mySSH.getBefore()):
+				isFinished1 = True
+		if isFinished1 == True:
+			logging.debug('\u001B[1m UnDeployed PhySim Successfully on OC Cluster\u001B[0m')
+		mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
+		mySSH.command('oc delete is oai-physim', '\$', 6)
+		logging.debug('\u001B[1m Deleted the Image and ImageStream\u001B[0m')
+		mySSH.command('oc logout', '\$', 6)
+		mySSH.close()
+		self.AnalyzeLogFile_phySim(HTML)
+		if self.testStatus and isFinished:
+			HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+			HTML.CreateHtmlTestRowPhySimTestResult(self.testSummary,self.testResult)
+			logging.info('\u001B[1m Physical Simulator Pass\u001B[0m')
+		else:
+			RAN.prematureExit = True
+			if isFinished:
+				HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
+			else:
+				HTML.CreateHtmlTestRow('Some test(s) timed-out!', 'KO', CONST.ALL_PROCESSES_OK)
+			HTML.CreateHtmlTestRowPhySimTestResult(self.testSummary,self.testResult)
+			logging.error('\u001B[1m Physical Simulator Fail\u001B[0m')
+
+	def AnalyzeLogFile_phySim(self, HTML):
+		lIpAddr = self.eNBIPAddress
+		lUserName = self.eNBUserName
+		lPassWord = self.eNBPassword
+		lSourcePath = self.eNBSourceCodePath
+		mySSH = SSH.SSHConnection()
+		mySSH.open(lIpAddr, lUserName, lPassWord)
+		mySSH.command('cd ' + lSourcePath, '\$', 5)
+		mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
+		mySSH.command('mkdir -p physim_test_log_' + self.testCase_id, '\$', 5)
+		mySSH.command('cp log/physim_* ' + 'physim_test_log_' + self.testCase_id, '\$', 5)
+		if not os.path.exists(f'./physim_test_logs_{self.testCase_id}'):
+			os.mkdir(f'./physim_test_logs_{self.testCase_id}')
+		mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/physim_test_log_' + self.testCase_id + '/*', './physim_test_logs_' + self.testCase_id)
+		mySSH.command('rm -rf ./physim_test_log_'+ self.testCase_id, '\$', 5)
+		mySSH.close()
+		# physim test log analysis
+		nextt = 0
+		if (os.path.isfile(f'./physim_test_logs_{self.testCase_id}/physim_test.txt')):
+			with open(f'./physim_test_logs_{self.testCase_id}/physim_test.txt', 'r') as logfile:
+				for line in logfile:
+					if re.search('execution 015', str(line)) or re.search('Bypassing compilation', str(line)):
+						nextt = 1
+					elif nextt == 1:
+						if not re.search('Test Results', str(line)):
+							nextt = 0
+							ret2 = re.search('T[^\n]*', str(line))
+							if ret2 is not None:
+								ret3 = ret2.group()
+								ret3 = ret3.replace("", "")
+					if re.search('execution 015', str(line)):
+						self.testCount[0] += 1
+						testName = line.split()
+						ret1 = re.search('Result = PASS', str(line))
+						if ret1 is not None:
+							self.testResult[testName[1]] = [ret3, 'PASS']
+							self.testCount[1] += 1
+						else:
+							self.testResult[testName[1]] = [ret3, 'FAIL']
+							self.testCount[2] += 1
+		self.testSummary['Nbtests'] = self.testCount[0]
+		self.testSummary['Nbpass'] =  self.testCount[1]
+		self.testSummary['Nbfail'] =  self.testCount[2]
+		if self.testSummary['Nbfail'] == 0:
+			self.testStatus = True
+		return 0
diff --git a/ci-scripts/cls_static_code_analysis.py b/ci-scripts/cls_static_code_analysis.py
new file mode 100644
index 0000000000000000000000000000000000000000..1680f3e560340c8cbe9a7946e77f04269b3ef9ff
--- /dev/null
+++ b/ci-scripts/cls_static_code_analysis.py
@@ -0,0 +1,192 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+# Python for CI of OAI-eNB + COTS-UE
+#
+#   Required Python Version
+#     Python 3.x
+#
+#   Required Python Package
+#     pexpect
+#---------------------------------------------------------------------
+
+#-----------------------------------------------------------
+# Import
+#-----------------------------------------------------------
+import sys              # arg
+import re               # reg
+import logging
+import os
+import time
+
+#-----------------------------------------------------------
+# OAI Testing modules
+#-----------------------------------------------------------
+import sshconnection as SSH
+import helpreadme as HELP
+import constants as CONST
+
+#-----------------------------------------------------------
+# Class Declaration
+#-----------------------------------------------------------
+class CppCheckResults():
+
+	def __init__(self):
+
+		self.variants = ['xenial', 'bionic']
+		self.versions = ['','']
+		self.nbErrors = [0,0]
+		self.nbWarnings = [0,0]
+		self.nbNullPtrs = [0,0]
+		self.nbMemLeaks = [0,0]
+		self.nbUninitVars = [0,0]
+		self.nbInvalidPrintf = [0,0]
+		self.nbModuloAlways = [0,0]
+		self.nbTooManyBitsShift = [0,0]
+		self.nbIntegerOverflow = [0,0]
+		self.nbWrongScanfArg = [0,0]
+		self.nbPtrAddNotNull = [0,0]
+		self.nbOppoInnerCondition = [0,0]
+
+class StaticCodeAnalysis():
+
+	def __init__(self):
+
+		self.ranRepository = ''
+		self.ranBranch = ''
+		self.ranAllowMerge = False
+		self.ranCommitID = ''
+		self.ranTargetBranch = ''
+		self.eNBIPAddress = ''
+		self.eNBUserName = ''
+		self.eNBPassword = ''
+		self.eNBSourceCodePath = ''
+
+	def CppCheckAnalysis(self, HTML):
+		if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
+			HELP.GenericHelp(CONST.Version)
+			sys.exit('Insufficient Parameter')
+		lIpAddr = self.eNBIPAddress
+		lUserName = self.eNBUserName
+		lPassWord = self.eNBPassword
+		lSourcePath = self.eNBSourceCodePath
+
+		if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
+			HELP.GenericHelp(CONST.Version)
+			sys.exit('Insufficient Parameter')
+		logging.debug('Building on server: ' + lIpAddr)
+		mySSH = SSH.SSHConnection()
+		mySSH.open(lIpAddr, lUserName, lPassWord)
+
+		self.testCase_id = HTML.testCase_id
+
+		# on RedHat/CentOS .git extension is mandatory
+		result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
+		if result is not None:
+			full_ran_repo_name = self.ranRepository.replace('git/', 'git')
+		else:
+			full_ran_repo_name = self.ranRepository + '.git'
+		mySSH.command('mkdir -p ' + lSourcePath, '\$', 5)
+		mySSH.command('cd ' + lSourcePath, '\$', 5)
+		mySSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600)
+		# Raphael: here add a check if git clone or git fetch went smoothly
+		mySSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
+		mySSH.command('git config user.name "OAI Jenkins"', '\$', 5)
+
+		mySSH.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30)
+		mySSH.command('mkdir -p cmake_targets/log', '\$', 5)
+		# if the commit ID is provided use it to point to it
+		if self.ranCommitID != '':
+			mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
+
+		mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:xenial || true', '\$', 60)
+		mySSH.command('docker build --tag oai-cppcheck:xenial --file ci-scripts/docker/Dockerfile.cppcheck.xenial . > cmake_targets/log/cppcheck-xenial.txt 2>&1', '\$', 600)
+		mySSH.command('sed -e "s@xenial@bionic@" ci-scripts/docker/Dockerfile.cppcheck.xenial > ci-scripts/docker/Dockerfile.cppcheck.bionic', '\$', 6)
+		mySSH.command('docker build --tag oai-cppcheck:bionic --file ci-scripts/docker/Dockerfile.cppcheck.bionic . > cmake_targets/log/cppcheck-bionic.txt 2>&1', '\$', 600)
+		mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:xenial || true', '\$', 60)
+
+		# Analyzing the logs
+		mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
+		mySSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5)
+		mySSH.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5)
+		mySSH.close()
+
+		mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/build_log_' + self.testCase_id + '/*', '.')
+		CCR = CppCheckResults()
+		vId = 0
+		for variant in CCR.variants:
+			if (os.path.isfile('./cppcheck-'+ variant + '.txt')):
+				xmlStart = False
+				with open('./cppcheck-'+ variant + '.txt', 'r') as logfile:
+					for line in logfile:
+						ret = re.search('Unpacking cppcheck \((?P<version>[0-9\.]+)', str(line))
+						if ret is not None:
+						   CCR.versions[vId] = ret.group('version')
+						if re.search('RUN cat cmake_targets/log/cppcheck.xml', str(line)) is not None:
+							xmlStart = True
+						if xmlStart:
+							if re.search('severity="error"', str(line)) is not None:
+								CCR.nbErrors[vId] += 1
+							if re.search('severity="warning"', str(line)) is not None:
+								CCR.nbWarnings[vId] += 1
+							if re.search('id="memleak"', str(line)) is not None:
+								CCR.nbMemLeaks[vId] += 1
+							if re.search('id="nullPointer"', str(line)) is not None:
+								CCR.nbNullPtrs[vId] += 1
+							if re.search('id="uninitvar"', str(line)) is not None:
+								CCR.nbUninitVars[vId] += 1
+							if re.search('id="invalidPrintfArgType_sint"|id="invalidPrintfArgType_uint"', str(line)) is not None:
+								CCR.nbInvalidPrintf[vId] += 1
+							if re.search('id="moduloAlwaysTrueFalse"', str(line)) is not None:
+								CCR.nbModuloAlways[vId] += 1
+							if re.search('id="shiftTooManyBitsSigned"', str(line)) is not None:
+								CCR.nbTooManyBitsShift[vId] += 1
+							if re.search('id="integerOverflow"', str(line)) is not None:
+								CCR.nbIntegerOverflow[vId] += 1
+							if re.search('id="wrongPrintfScanfArgNum"|id="invalidScanfArgType_int"', str(line)) is not None:
+								CCR.nbWrongScanfArg[vId] += 1
+							if re.search('id="pointerAdditionResultNotNull"', str(line)) is not None:
+								CCR.nbPtrAddNotNull[vId] += 1
+							if re.search('id="oppositeInnerCondition"', str(line)) is not None:
+								CCR.nbOppoInnerCondition[vId] += 1
+			logging.debug('========  Variant ' + variant + ' - ' + CCR.versions[vId] + ' ========')
+			logging.debug('   ' + str(CCR.nbErrors[vId]) + ' errors')
+			logging.debug('   ' + str(CCR.nbWarnings[vId]) + ' warnings')
+			logging.debug('  -- Details --')
+			logging.debug('   Memory leak:                     ' + str(CCR.nbMemLeaks[vId]))
+			logging.debug('   Possible null pointer deference: ' + str(CCR.nbNullPtrs[vId]))
+			logging.debug('   Uninitialized variable:          ' + str(CCR.nbUninitVars[vId]))
+			logging.debug('   Undefined behaviour shifting:    ' + str(CCR.nbTooManyBitsShift[vId]))
+			logging.debug('   Signed integer overflow:         ' + str(CCR.nbIntegerOverflow[vId]))
+			logging.debug('')
+			logging.debug('   Printf formatting issue:         ' + str(CCR.nbInvalidPrintf[vId]))
+			logging.debug('   Modulo result is predetermined:  ' + str(CCR.nbModuloAlways[vId]))
+			logging.debug('   Opposite Condition -> dead code: ' + str(CCR.nbOppoInnerCondition[vId]))
+			logging.debug('   Wrong Scanf Nb Args:             ' + str(CCR.nbWrongScanfArg[vId]))
+			logging.debug('')
+			vId += 1
+
+		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+		HTML.CreateHtmlTestRowCppCheckResults(CCR)
+		logging.info('\u001B[1m Static Code Analysis Pass\u001B[0m')
+
+		return 0
+
diff --git a/ci-scripts/conf_files/benetel-4g.conf b/ci-scripts/conf_files/benetel-4g.conf
new file mode 100644
index 0000000000000000000000000000000000000000..9423ebe56ecb84c5b2559abf057ce8f1fde8bad3
--- /dev/null
+++ b/ci-scripts/conf_files/benetel-4g.conf
@@ -0,0 +1,285 @@
+Active_eNBs = ( "eNB-Eurecom-LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+    # real_time choice in {hard, rt-preempt, no}
+    real_time       =  "no";
+
+    ////////// Identification parameters:
+    eNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_ENB";
+
+    eNB_name  =  "eNB-Eurecom-LTEBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 222; mnc = 01; mnc_length = 2; } );
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    component_carriers = (
+      {
+      node_function             = "NGFI_RCC_IF4p5";
+      node_timing               = "synch_to_ext_device";
+      node_synch_ref            = 0;
+      frame_type					      = "FDD";
+      tdd_config 					      = 3;
+      tdd_config_s            			      = 0;
+      prefix_type             			      = "NORMAL";
+      eutra_band              			      = 7;
+      downlink_frequency      			      = 2655000000L;
+      uplink_frequency_offset 			      = -120000000;
+      Nid_cell					      = 0;
+      N_RB_DL                 			      = 100;
+      Nid_cell_mbsfn          			      = 0;
+      nb_antenna_ports                                = 1;
+      nb_antennas_tx          			      = 1;
+      nb_antennas_rx          			      = 1;
+      tx_gain                                            = 90;
+      rx_gain                                            = 125;
+      pbch_repetition                                 = "FALSE";
+      prach_root              			      = 0;
+      prach_config_index      			      = 0;
+      prach_high_speed        			      = "DISABLE";
+      prach_zero_correlation  			      = 1;
+      prach_freq_offset       			      = 90;
+      pucch_delta_shift       			      = 1;
+      pucch_nRB_CQI           			      = 0;
+      pucch_nCS_AN            			      = 0;
+      pucch_n1_AN             			      = 0;
+      pdsch_referenceSignalPower 			      = -10;
+      pdsch_p_b                  			      = 0;
+      pusch_n_SB                 			      = 1;
+      pusch_enable64QAM          			      = "DISABLE";
+      pusch_hoppingMode                                  = "interSubFrame";
+      pusch_hoppingOffset                                = 0;
+      pusch_groupHoppingEnabled  			      = "ENABLE";
+      pusch_groupAssignment      			      = 0;
+      pusch_sequenceHoppingEnabled		   	      = "DISABLE";
+      pusch_nDMRS1                                       = 1;
+      phich_duration                                     = "NORMAL";
+      phich_resource                                     = "ONESIXTH";
+      srs_enable                                         = "DISABLE";
+      /*  srs_BandwidthConfig                                =;
+      srs_SubframeConfig                                 =;
+      srs_ackNackST                                      =;
+      srs_MaxUpPts                                       =;*/
+
+      pusch_p0_Nominal                                   = -96;
+      pusch_alpha                                        = "AL1";
+      pucch_p0_Nominal                                   = -104;
+      msg3_delta_Preamble                                = 6;
+      pucch_deltaF_Format1                               = "deltaF2";
+      pucch_deltaF_Format1b                              = "deltaF3";
+      pucch_deltaF_Format2                               = "deltaF0";
+      pucch_deltaF_Format2a                              = "deltaF0";
+      pucch_deltaF_Format2b		    	      = "deltaF0";
+
+      rach_numberOfRA_Preambles                          = 64;
+      rach_preamblesGroupAConfig                         = "DISABLE";
+      /*
+      rach_sizeOfRA_PreamblesGroupA                      = ;
+      rach_messageSizeGroupA                             = ;
+      rach_messagePowerOffsetGroupB                      = ;
+      */
+      rach_powerRampingStep                              = 4;
+      rach_preambleInitialReceivedTargetPower            = -108;
+      rach_preambleTransMax                              = 10;
+      rach_raResponseWindowSize                          = 10;
+      rach_macContentionResolutionTimer                  = 48;
+      rach_maxHARQ_Msg3Tx                                = 4;
+
+      pcch_default_PagingCycle                           = 128;
+      pcch_nB                                            = "oneT";
+      bcch_modificationPeriodCoeff			      = 2;
+      ue_TimersAndConstants_t300			      = 1000;
+      ue_TimersAndConstants_t301			      = 1000;
+      ue_TimersAndConstants_t310			      = 1000;
+      ue_TimersAndConstants_t311			      = 10000;
+      ue_TimersAndConstants_n310			      = 20;
+      ue_TimersAndConstants_n311			      = 1;
+      ue_TransmissionMode                                    = 1;
+
+      //Parameters for SIB18
+      rxPool_sc_CP_Len                                       = "normal";
+      rxPool_sc_Period                                       = "sf40";
+      rxPool_data_CP_Len                                     = "normal";
+      rxPool_ResourceConfig_prb_Num                          = 20;
+      rxPool_ResourceConfig_prb_Start                        = 5;
+      rxPool_ResourceConfig_prb_End                          = 44;
+      rxPool_ResourceConfig_offsetIndicator_present          = "prSmall";
+      rxPool_ResourceConfig_offsetIndicator_choice           = 0;
+      rxPool_ResourceConfig_subframeBitmap_present           = "prBs40";
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_buf              = "00000000000000000000";
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_size             = 5;
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused      = 0;
+/*    rxPool_dataHoppingConfig_hoppingParameter                       = 0;
+      rxPool_dataHoppingConfig_numSubbands                            = "ns1";
+      rxPool_dataHoppingConfig_rbOffset                               = 0;
+      rxPool_commTxResourceUC-ReqAllowed                              = "TRUE";
+*/
+      // Parameters for SIB19
+      discRxPool_cp_Len                                               = "normal"
+      discRxPool_discPeriod                                           = "rf32"
+      discRxPool_numRetx                                              = 1;
+      discRxPool_numRepetition                                        = 2;
+      discRxPool_ResourceConfig_prb_Num                               = 5;
+      discRxPool_ResourceConfig_prb_Start                             = 3;
+      discRxPool_ResourceConfig_prb_End                               = 21;
+      discRxPool_ResourceConfig_offsetIndicator_present               = "prSmall";
+      discRxPool_ResourceConfig_offsetIndicator_choice                = 0;
+      discRxPool_ResourceConfig_subframeBitmap_present                = "prBs40";
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf          = "f0ffffffff";
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_size         = 5;
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused  = 0;
+
+      //SSB central frequency of NR secondary cell group (for ENDC NSA) 
+      nr_scg_ssb_freq	      	    	      	   	      	      = 640000;	
+      }
+    );
+
+
+    srb1_parameters :
+    {
+        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
+        timer_poll_retransmit    = 80;
+
+        # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
+        timer_reordering         = 35;
+
+        # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
+        timer_status_prohibit    = 0;
+
+        # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
+        poll_pdu                 =  4;
+
+        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
+        poll_byte                =  99999;
+
+        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
+        max_retx_threshold       =  4;
+    }
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    enable_measurement_reports = "yes";
+
+    ///X2
+    enable_x2 = "yes";
+    t_reloc_prep      = 1000;      /* unit: millisecond */
+    tx2_reloc_overall = 2000;      /* unit: millisecond */
+    t_dc_prep         = 1000;      /* unit: millisecond */
+    t_dc_overall      = 2000;      /* unit: millisecond */
+
+    NETWORK_INTERFACES :
+    {
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "CI_ENB_IP_ADDR";
+        ENB_INTERFACE_NAME_FOR_S1U               = "eth0";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "CI_ENB_IP_ADDR";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+        ENB_IPV4_ADDRESS_FOR_X2C                 = "127.0.0.1";
+        ENB_PORT_FOR_X2C                         = 36422; # Spec 36422
+    };
+  }
+);
+
+MACRLCs = (
+	{
+	num_cc = 1;
+	tr_s_preference = "local_L1";
+	tr_n_preference = "local_RRC";
+	phy_test_mode = 0;
+        puSch10xSnr     =  160;
+        puCch10xSnr     =  160;
+        }
+);
+
+L1s = (
+      {
+	num_cc = 1;
+	tr_n_preference = "local_mac";
+        prach_dtx_threshold = 150;
+      }
+);
+
+RUs = (
+    {
+        //local_if_name  = "enp129s0f0";
+        local_if_name  = "dpdk";
+        sdr_addrs      = "softmodem -m 2048 -l 35 -n 2 -b 0000:81:00.3 --proc-type auto --file-prefix ggg -- -p 0x1";
+        #sdr_addrs      = "softmodem -l 8 -n 2 -- -p 0x2";
+        #remote_address = "127.0.0.2";
+        #local_address  = "127.0.0.1";
+        #local_portc    = 50000;
+        #remote_portc   = 50000;
+        #local_portd    = 50001;
+        #remote_portd   = 50001;
+        local_rf       = "no"
+        tr_preference  = "raw_if4p5"
+        nb_tx          = 1
+        nb_rx          = 1
+        att_tx         = 0
+        att_rx         = 0;
+        eNB_instances  = [0];
+    }
+);
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    #parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    parallel_config    = "PARALLEL_SINGLE_THREAD";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+NETWORK_CONTROLLER :
+{
+    FLEXRAN_ENABLED        = "no";
+    FLEXRAN_INTERFACE_NAME = "lo";
+    FLEXRAN_IPV4_ADDRESS   = "127.0.0.1";
+    FLEXRAN_PORT           = 2210;
+    FLEXRAN_CACHE          = "/mnt/oai_agent_cache";
+    FLEXRAN_AWAIT_RECONF   = "no";
+};
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+    };
diff --git a/ci-scripts/conf_files/benetel-5g.conf b/ci-scripts/conf_files/benetel-5g.conf
new file mode 100644
index 0000000000000000000000000000000000000000..47898aad155b77a35fc1e692688430bda0ec980a
--- /dev/null
+++ b/ci-scripts/conf_files/benetel-5g.conf
@@ -0,0 +1,301 @@
+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  =  1;
+
+    plmn_list = ({mcc = 222; mnc = 01; mnc_length = 2;});	 
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 31; //0;
+    pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
+	
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is is the central frequency of SSB 
+      absoluteFrequencySSB                                          = 640000; //641272
+      dl_frequencyBand                                                 = 78;
+      # the carrier frequency is assumed to be in the middle of the carrier, i.e. dl_absoluteFrequencyPointA_kHz + dl_carrierBandwidth*12*SCS_kHz/2
+      dl_absoluteFrequencyPointA                                       = 638728; //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=84,L=13 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6368; 
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 0;
+        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                                        = 6368; 
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialULBWPsubcarrierSpacing                                           = 1;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 4;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+          prach_msg1_FDM                                            = 0;
+          prach_msg1_FrequencyStart                                 = 74;
+          zeroCorrelationZoneConfig                                 = 13;
+          #preambleReceivedTargetPower                               = -118;
+          #preambleReceivedTargetPower                               = -104;
+          preambleReceivedTargetPower                               = -108;
+#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                                            = 2;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+        ra_ResponseWindow                                           = 5;
+#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; //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                                  = 1;
+        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                      = 2;  # used for UL slot
+        initialULBWPmappingType_0             = 1
+        initialULBWPstartSymbolAndLength_0    = 55; # this is SS=0 L=12
+
+        initialULBWPk2_1                      = 2;  # used for mixed slot
+        initialULBWPmappingType_1             = 1;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
+
+        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;
+        p0_NominalWithGrant                                         =-118;
+
+# pucch-ConfigCommon setup :
+# pucchGroupHopping
+# 0 = neither, 1= group hopping, 2=sequence hopping
+        pucchGroupHopping                                           = 0;
+        hoppingId                                                   = 40;
+        #p0_nominal                                                  = -90;
+        p0_nominal                                                  = -118;
+# ssb_PositionsInBurs_BitmapPR
+# 1=short, 2=medium, 3=long
+      ssb_PositionsInBurst_PR                                       = 2;
+      ssb_PositionsInBurst_Bitmap                                   = 1; #0x80;
+
+# 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; //8; //7;
+      nrofDownlinkSymbols                                           = 6; //0; //6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4; //0; //4;
+
+  #ssPBCH_BlockPower                                             = 10;
+  ssPBCH_BlockPower                                             = -35;
+  }
+
+  );
+
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    ///X2
+    enable_x2 = "yes";
+    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       = "127.0.0.1";
+                                       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_PORT_FOR_S1U                         = 2152; # Spec 2152
+        GNB_IPV4_ADDRESS_FOR_X2C                 = "127.0.0.2/24";
+        GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
+    };
+  }
+);
+
+MACRLCs = (
+	{
+	    num_cc              = 1;
+	    tr_s_preference     = "local_L1";
+	    tr_n_preference     = "local_RRC";
+	    pusch_TargetSNRx10  = 200;
+        pucch_TargetSNRx10  = 200;
+    }
+);
+
+L1s = (
+    	{
+	num_cc = 1;
+	tr_n_preference = "local_mac";
+	pusch_proc_threads = 8;
+        }  
+);
+
+RUs = (
+    {		  
+       local_rf       = "no"
+         nb_tx          = 1
+         nb_rx          = 1
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 114;
+         eNB_instances  = [0];
+         //clock_src = "internal";
+         clock_src = "external";
+
+        local_if_name  = "dpdk";
+        sdr_addrs      = "softmodem -m 2048 -l 34  -n 3 -b 0000:81:00.2 --proc-type auto --file-prefix hhh -- -p 0x1";
+        remote_address = "127.0.0.2";
+        local_address  = "127.0.0.1";
+        local_portc    = 50000;
+        remote_portc   = 50000;
+        local_portd    = 50001;
+        remote_portd   = 50001;
+        tr_preference  = "raw_if4p5"
+
+    }
+);  
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    //parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    parallel_config    = "PARALLEL_SINGLE_THREAD";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_DISABLE";
+  }
+);
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+    };
+
diff --git a/ci-scripts/conf_files/channelmod_rfsimu.conf b/ci-scripts/conf_files/channelmod_rfsimu.conf
new file mode 100644
index 0000000000000000000000000000000000000000..9a6ded24f11dbc8b5131872284c43b5e96a3846b
--- /dev/null
+++ b/ci-scripts/conf_files/channelmod_rfsimu.conf
@@ -0,0 +1,57 @@
+#/* configuration for channel modelisation */
+#/* To be included in main config file when */
+#/* channel modelisation is used (rfsimulator with chanmod options enabled) */
+channelmod = { 
+  max_chan=10;
+  modellist="modellist_rfsimu_1";
+  modellist_rfsimu_1 = (
+    {
+        model_name                       = "rfsimu_channel_enB0"
+      	type                             = "AWGN";			  
+      	ploss_dB                         = 0;
+        noise_power_dB                   = -10; 
+        forgetfact                       = 0;  
+        offset                           = 0;      
+        ds_tdl                           = 0;      
+    },
+    {
+        model_name                       = "rfsimu_channel_ue1"
+      	type                             = "AWGN";			  
+      	ploss_dB                         = 0;
+        noise_power_dB                   = 0; 
+        forgetfact                       = 0;  
+        offset                           = 0;      
+        ds_tdl                           = 0;      
+    }    
+  );
+  modellist_rfsimu_2 = (
+    {
+        model_name                       = "rfsimu_channel_ue0"
+      	type                             = "AWGN";			  
+      	ploss_dB                         = 0;
+        noise_power_dB                   = 0; 
+        forgetfact                       = 0;  
+        offset                           = 0;      
+        ds_tdl                           = 0;      
+    },
+    {
+        model_name                       = "rfsimu_channel_ue1"
+      	type                             = "AWGN";			  
+      	ploss_dB                         = 0;
+        noise_power_dB                   = 0; 
+        forgetfact                       = 0;  
+        offset                           = 0;      
+        ds_tdl                           = 0;      
+    },
+    {
+        model_name                       = "rfsimu_channel_ue2"
+      	type                             = "AWGN";			  
+      	ploss_dB                         = 0;
+        noise_power_dB                   = 0; 
+        forgetfact                       = 0;  
+        offset                           = 0;      
+        ds_tdl                           = 0;      
+    }    
+  );  
+};
+
diff --git a/ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf b/ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf
new file mode 100644
index 0000000000000000000000000000000000000000..db0802fdd7fcac457580b53bb54c8b02cad0b113
--- /dev/null
+++ b/ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf
@@ -0,0 +1,280 @@
+Active_eNBs = ( "eNB-Eurecom-B38");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+    ////////// Identification parameters:
+    eNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_ENB";
+
+    eNB_name  =  "eNB-Eurecom-B38";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 99; mnc_length = 2; } );
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    component_carriers = (
+      {
+      node_function             = "3GPP_eNODEB";
+      node_timing               = "synch_to_ext_device";
+      node_synch_ref            = 0;
+      frame_type					      = "TDD";
+      tdd_config 					      = 1;
+      tdd_config_s            			      = 0;
+      prefix_type             			      = "NORMAL";
+      eutra_band              			      = 38;
+      downlink_frequency      			      = 2605000000L;
+      uplink_frequency_offset 			      = 0;
+      Nid_cell					      = 0;
+      N_RB_DL                 			      = 100;
+      Nid_cell_mbsfn          			      = 0;
+      nb_antenna_ports                                = 1;
+      nb_antennas_tx          			      = 2;
+      nb_antennas_rx          			      = 2;
+      tx_gain                                            = 90;
+      rx_gain                                            = 125;
+      pbch_repetition                                 = "FALSE";
+      prach_root              			      = 0;
+      prach_config_index      			      = 0;
+      prach_high_speed        			      = "DISABLE";
+      prach_zero_correlation  			      = 1;
+      prach_freq_offset       			      = 2;
+      pucch_delta_shift       			      = 1;
+      pucch_nRB_CQI           			      = 0;
+      pucch_nCS_AN            			      = 0;
+      pucch_n1_AN             			      = 0;
+      pdsch_referenceSignalPower 			      = -29;
+      pdsch_p_b                  			      = 0;
+      pusch_n_SB                 			      = 1;
+      pusch_enable64QAM          			      = "DISABLE";
+      pusch_hoppingMode                                  = "interSubFrame";
+      pusch_hoppingOffset                                = 0;
+      pusch_groupHoppingEnabled  			      = "ENABLE";
+      pusch_groupAssignment      			      = 0;
+      pusch_sequenceHoppingEnabled		   	      = "DISABLE";
+      pusch_nDMRS1                                       = 1;
+      phich_duration                                     = "NORMAL";
+      phich_resource                                     = "ONESIXTH";
+      srs_enable                                         = "DISABLE";
+      /*  srs_BandwidthConfig                                =;
+      srs_SubframeConfig                                 =;
+      srs_ackNackST                                      =;
+      srs_MaxUpPts                                       =;*/
+
+      pusch_p0_Nominal                                   = -96;
+      pusch_alpha                                        = "AL1";
+      pucch_p0_Nominal                                   = -104;
+      msg3_delta_Preamble                                = 6;
+      pucch_deltaF_Format1                               = "deltaF2";
+      pucch_deltaF_Format1b                              = "deltaF3";
+      pucch_deltaF_Format2                               = "deltaF0";
+      pucch_deltaF_Format2a                              = "deltaF0";
+      pucch_deltaF_Format2b		    	      = "deltaF0";
+
+      rach_numberOfRA_Preambles                          = 64;
+      rach_preamblesGroupAConfig                         = "DISABLE";
+      /*
+      rach_sizeOfRA_PreamblesGroupA                      = ;
+      rach_messageSizeGroupA                             = ;
+      rach_messagePowerOffsetGroupB                      = ;
+      */
+      rach_powerRampingStep                              = 4;
+      rach_preambleInitialReceivedTargetPower            = -108;
+      rach_preambleTransMax                              = 10;
+      rach_raResponseWindowSize                          = 10;
+      rach_macContentionResolutionTimer                  = 48;
+      rach_maxHARQ_Msg3Tx                                = 4;
+
+      pcch_default_PagingCycle                           = 128;
+      pcch_nB                                            = "oneT";
+      bcch_modificationPeriodCoeff			      = 2;
+      ue_TimersAndConstants_t300			      = 1000;
+      ue_TimersAndConstants_t301			      = 1000;
+      ue_TimersAndConstants_t310			      = 1000;
+      ue_TimersAndConstants_t311			      = 10000;
+      ue_TimersAndConstants_n310			      = 20;
+      ue_TimersAndConstants_n311			      = 1;
+      ue_TransmissionMode                                    = 1;
+
+      //Parameters for SIB18
+      rxPool_sc_CP_Len                                       = "normal";
+      rxPool_sc_Period                                       = "sf40";
+      rxPool_data_CP_Len                                     = "normal";
+      rxPool_ResourceConfig_prb_Num                          = 20;
+      rxPool_ResourceConfig_prb_Start                        = 5;
+      rxPool_ResourceConfig_prb_End                          = 44;
+      rxPool_ResourceConfig_offsetIndicator_present          = "prSmall";
+      rxPool_ResourceConfig_offsetIndicator_choice           = 0;
+      rxPool_ResourceConfig_subframeBitmap_present           = "prBs40";
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_buf              = "00000000000000000000";
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_size             = 5;
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused      = 0;
+/*    rxPool_dataHoppingConfig_hoppingParameter                       = 0;
+      rxPool_dataHoppingConfig_numSubbands                            = "ns1";
+      rxPool_dataHoppingConfig_rbOffset                               = 0;
+      rxPool_commTxResourceUC-ReqAllowed                              = "TRUE";
+*/
+      // Parameters for SIB19
+      discRxPool_cp_Len                                               = "normal"
+      discRxPool_discPeriod                                           = "rf32"
+      discRxPool_numRetx                                              = 1;
+      discRxPool_numRepetition                                        = 2;
+      discRxPool_ResourceConfig_prb_Num                               = 5;
+      discRxPool_ResourceConfig_prb_Start                             = 3;
+      discRxPool_ResourceConfig_prb_End                               = 21;
+      discRxPool_ResourceConfig_offsetIndicator_present               = "prSmall";
+      discRxPool_ResourceConfig_offsetIndicator_choice                = 0;
+      discRxPool_ResourceConfig_subframeBitmap_present                = "prBs40";
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf          = "f0ffffffff";
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_size         = 5;
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused  = 0;
+
+      }
+    );
+
+
+    srb1_parameters :
+    {
+        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
+        timer_poll_retransmit    = 80;
+
+        # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
+        timer_reordering         = 35;
+
+        # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
+        timer_status_prohibit    = 0;
+
+        # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
+        poll_pdu                 =  4;
+
+        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
+        poll_byte                =  99999;
+
+        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
+        max_retx_threshold       =  4;
+    }
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    enable_measurement_reports = "no";
+
+    ///X2
+    enable_x2 = "yes";
+    t_reloc_prep      = 1000;      /* unit: millisecond */
+    tx2_reloc_overall = 2000;      /* unit: millisecond */
+    t_dc_prep         = 1000;      /* unit: millisecond */
+    t_dc_overall      = 2000;      /* unit: millisecond */
+
+    NETWORK_INTERFACES :
+    {
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eno1";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "CI_ENB_IP_ADDR";
+        ENB_INTERFACE_NAME_FOR_S1U               = "eno1";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "CI_ENB_IP_ADDR";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+        ENB_IPV4_ADDRESS_FOR_X2C                 = "CI_ENB_IP_ADDR";
+        ENB_PORT_FOR_X2C                         = 36422; # Spec 36422
+    };
+  }
+);
+
+MACRLCs = (
+	{
+	num_cc = 1;
+	tr_s_preference = "local_L1";
+	tr_n_preference = "local_RRC";
+	phy_test_mode = 0;
+        scheduler_mode = "fairRR";
+        bler_target_upper = 20.0;
+        bler_target_lower = 10.0;
+        max_ul_rb_index   = 24;
+        puSch10xSnr     =  100;
+        puCch10xSnr     =  150;
+        }  
+);
+
+L1s = (
+    	{
+	num_cc = 1;
+	tr_n_preference = "local_mac";
+        prach_dtx_threshold = 200;
+        pucch1_dtx_threshold = 5
+        pucch1ab_dtx_threshold =0;
+        }  
+);
+
+RUs = (
+    {		  
+       local_rf       = "yes"
+         nb_tx          = 2
+         nb_rx          = 2
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [38];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 75;
+         eNB_instances  = [0];
+         sdr_addrs      = "mgmt_addr=192.168.18.241,addr=192.168.20.2,second_addr=192.168.10.2";
+
+    }
+);  
+
+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";
+  }
+);
+
+NETWORK_CONTROLLER :
+{
+    FLEXRAN_ENABLED        = "no";
+    FLEXRAN_INTERFACE_NAME = "lo";
+    FLEXRAN_IPV4_ADDRESS   = "127.0.0.1";
+    FLEXRAN_PORT           = 2210;
+    FLEXRAN_CACHE          = "/mnt/oai_agent_cache";
+    FLEXRAN_AWAIT_RECONF   = "no";
+};
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+    };
+
diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf
index f29fc163b3d0459df1e633c397f3b67fb0711575..6fc84012361a0c9c59d0b7a456f04f2b304525f4 100644
--- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf
@@ -6,10 +6,8 @@ eNBs =
 (
  {
     ////////// Identification parameters:
-    eNB_ID    =  0xe00;
-
+    eNB_ID    =  0xe01;
     cell_type =  "CELL_MACRO_ENB";
-
     eNB_name  =  "eNB-Eurecom-LTEBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
@@ -128,24 +126,25 @@ eNBs =
       rxPool_commTxResourceUC-ReqAllowed                     = "TRUE";
 */
       // Parameters for SIB19
-      discRxPool_cp_Len                                      = "normal"
-      discRxPool_discPeriod                                  = "rf32"
-      discRxPool_numRetx                                     = 1;
-      discRxPool_numRepetition                               = 2;
-      discRxPool_ResourceConfig_prb_Num                      = 5;
-      discRxPool_ResourceConfig_prb_Start                    = 3;
-      discRxPool_ResourceConfig_prb_End                      = 21;
-      discRxPool_ResourceConfig_offsetIndicator_present      = "prSmall";
-      discRxPool_ResourceConfig_offsetIndicator_choice       = 0;
-      discRxPool_ResourceConfig_subframeBitmap_present       = "prBs40";
-      discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff";
-      discRxPool_ResourceConfig_subframeBitmap_choice_bs_size= 5;
+      discRxPool_cp_Len                                               = "normal"
+      discRxPool_discPeriod                                           = "rf32"
+      discRxPool_numRetx                                              = 1;
+      discRxPool_numRepetition                                        = 2;
+      discRxPool_ResourceConfig_prb_Num                               = 5;
+      discRxPool_ResourceConfig_prb_Start                             = 3;
+      discRxPool_ResourceConfig_prb_End                               = 21;
+      discRxPool_ResourceConfig_offsetIndicator_present               = "prSmall";
+      discRxPool_ResourceConfig_offsetIndicator_choice                = 0;
+      discRxPool_ResourceConfig_subframeBitmap_present                = "prBs40";
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf          = "f0ffffffff";
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_size         = 5;
       discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused  = 0;
 
+      //SSB central frequency of NR secondary cell group (for ENDC NSA)
+      nr_scg_ssb_freq = 641272;
       }
     );
 
-
     srb1_parameters :
     {
         # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
@@ -175,6 +174,7 @@ eNBs =
         SCTP_OUTSTREAMS = 2;
     };
 
+    enable_measurement_reports = "no";
 
     ////////// MME parameters:
     mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR";
@@ -185,10 +185,8 @@ eNBs =
                             }
                           );
 
-    enable_measurement_reports = "no";
-
     ///X2
-    enable_x2 = "no";
+    enable_x2         = "no";
     t_reloc_prep      = 1000;      /* unit: millisecond */
     tx2_reloc_overall = 2000;      /* unit: millisecond */
     t_dc_prep         = 1000;      /* unit: millisecond */
diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
index 4d89ad96daa3708d0e67b8bb12ca163870f472f1..087ee37f01b961d7f09ce997ae14d1bddf626288 100644
--- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
@@ -260,7 +260,6 @@ NETWORK_CONTROLLER :
     FLEXRAN_CACHE          = "/mnt/oai_agent_cache";
     FLEXRAN_AWAIT_RECONF   = "no";
 };
-
      log_config :
      {
        global_log_level                      ="info";
@@ -279,3 +278,4 @@ NETWORK_CONTROLLER :
        rrc_log_verbosity                     ="medium";
     };
 
+@include "channelmod_rfsimu.conf"
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 33aae14dac1cb781a814f5d90e0626cbe3e7f000..454649f20d4b858c8abcf280882603e0d7cfa901 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
@@ -5,110 +5,106 @@ Asn1_verbosity = "none";
 eNBs =
 (
  {
-    # real_time choice in {hard, rt-preempt, no}
-    real_time       =  "no";
     ////////// Identification parameters:
     eNB_ID    =  0xe01;
     cell_type =  "CELL_MACRO_ENB";
     eNB_name  =  "eNB-Eurecom-LTEBox";
     
     // Tracking area code, 0x0000 and 0xfffe are reserved values
-    tracking_area_code  =  1;
-    plmn_list = (
-      { mcc = 222; mnc = 01; mnc_length = 2; }
-    );
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 222; mnc = 01; mnc_length = 2; } );
     
     tr_s_preference     = "local_mac"
 
+    // In seconds
+    rrc_inactivity_threshold = 0;
+
     ////////// Physical parameters:
   
     component_carriers = (
       {
-        node_function                    = "eNodeB_3GPP";
-        node_timing                      = "synch_to_ext_device";
-        node_synch_ref                   = 0;
-        nb_antenna_ports                 = 1;
-        ue_TransmissionMode              = 1;
-        frame_type                       = "FDD"; 
-        tdd_config                       = 3;
-        tdd_config_s                     = 0;
-        prefix_type                      = "NORMAL";
-        eutra_band                       = 7;
-        downlink_frequency               = 2680000000L;
-        uplink_frequency_offset          = -120000000;
-  
-        Nid_cell                         = 0;
-        N_RB_DL                          = 25;
-        Nid_cell_mbsfn                   = 0;
-        nb_antennas_tx                   = 1;
-        nb_antennas_rx                   = 1; 
-        prach_root                       = 0;
-        tx_gain                          = 90;
-        rx_gain                          = 115;
-        pbch_repetition                  = "FALSE";
-
-        prach_config_index               = 0;
-        prach_high_speed                 = "DISABLE";
-        prach_zero_correlation           = 1;
-        prach_freq_offset                = 2;
-
-        pucch_delta_shift                = 1;
-        pucch_nRB_CQI                    = 0;
-        pucch_nCS_AN                     = 0;
-        pucch_n1_AN                      = 0;
-        pdsch_referenceSignalPower       = -29;
-        pdsch_p_b                        = 0;
-        pusch_n_SB                       = 1; 
-        pusch_enable64QAM                = "DISABLE";
-        pusch_hoppingMode                = "interSubFrame";
-        pusch_hoppingOffset              = 0;
-        pusch_groupHoppingEnabled        = "ENABLE";
-        pusch_groupAssignment            = 0;
-        pusch_sequenceHoppingEnabled     = "DISABLE";
-        pusch_nDMRS1                     = 1;
-        phich_duration                   = "NORMAL";
-        phich_resource                   = "ONESIXTH";
-        srs_enable                       = "DISABLE";
+      node_function             = "3GPP_eNODEB";
+      node_timing               = "synch_to_ext_device";
+      node_synch_ref            = 0;
+      frame_type                = "FDD";
+      tdd_config                = 3;
+      tdd_config_s              = 0;
+      prefix_type               = "NORMAL";
+      eutra_band                = 7;
+      downlink_frequency        = 2680000000L;
+      uplink_frequency_offset   = -120000000;
+      Nid_cell                  = 0;
+      N_RB_DL                   = 25;
+      Nid_cell_mbsfn            = 0;
+      nb_antenna_ports          = 1;
+      nb_antennas_tx            = 1;
+      nb_antennas_rx            = 1;
+      tx_gain                   = 90;
+      rx_gain                   = 115;
+      pbch_repetition           = "FALSE";
+      prach_root                = 0;
+      prach_config_index        = 0;
+      prach_high_speed          = "DISABLE";
+      prach_zero_correlation    = 1;
+      prach_freq_offset         = 2;
+      pucch_delta_shift         = 1;
+      pucch_nRB_CQI             = 0;
+      pucch_nCS_AN              = 0;
+      pucch_n1_AN               = 0;
+      pdsch_referenceSignalPower= -29;
+      pdsch_p_b                 = 0;
+      pusch_n_SB                = 1;
+      pusch_enable64QAM         = "DISABLE";
+      pusch_hoppingMode         = "interSubFrame";
+      pusch_hoppingOffset       = 0;
+      pusch_groupHoppingEnabled = "ENABLE";
+      pusch_groupAssignment     = 0;
+      pusch_sequenceHoppingEnabled = "DISABLE";
+      pusch_nDMRS1              = 1;
+      phich_duration            = "NORMAL";
+      phich_resource            = "ONESIXTH";
+      srs_enable                = "DISABLE";
 /*
-        srs_BandwidthConfig              =;
-        srs_SubframeConfig               =;
-        srs_ackNackST                    =;
-        srs_MaxUpPts                     =;
+      srs_BandwidthConfig       =;
+      srs_SubframeConfig        =;
+      srs_ackNackST             =;
+      srs_MaxUpPts              =;
 */
 
-        pusch_p0_Nominal                 = -96;
-        pusch_alpha                      = "AL1";
-        pucch_p0_Nominal                 = -96;
-        msg3_delta_Preamble              = 6;
-        pucch_deltaF_Format1             = "deltaF2";
-        pucch_deltaF_Format1b            = "deltaF3";
-        pucch_deltaF_Format2             = "deltaF0";
-        pucch_deltaF_Format2a            = "deltaF0";
-        pucch_deltaF_Format2b            = "deltaF0";
+      pusch_p0_Nominal          = -96;
+      pusch_alpha               = "AL1";
+      pucch_p0_Nominal          = -96;
+      msg3_delta_Preamble       = 6;
+      pucch_deltaF_Format1      = "deltaF2";
+      pucch_deltaF_Format1b     = "deltaF3";
+      pucch_deltaF_Format2      = "deltaF0";
+      pucch_deltaF_Format2a     = "deltaF0";
+      pucch_deltaF_Format2b     = "deltaF0";
  
-        rach_numberOfRA_Preambles        = 64;
-        rach_preamblesGroupAConfig       = "DISABLE";
+      rach_numberOfRA_Preambles                = 64;
+      rach_preamblesGroupAConfig               = "DISABLE";
 /*
-        rach_sizeOfRA_PreamblesGroupA    = ;
-        rach_messageSizeGroupA           = ;
-        rach_messagePowerOffsetGroupB    = ; 
+      rach_sizeOfRA_PreamblesGroupA            = ;
+      rach_messageSizeGroupA                   = ;
+      rach_messagePowerOffsetGroupB            = ;
 */
-        rach_powerRampingStep                   = 4;
-        rach_preambleInitialReceivedTargetPower = -108;
-        rach_preambleTransMax                   = 10;
-        rach_raResponseWindowSize               = 10;
-        rach_macContentionResolutionTimer       = 48;
-        rach_maxHARQ_Msg3Tx                     = 4;
+      rach_powerRampingStep                    = 4;
+      rach_preambleInitialReceivedTargetPower  = -108;
+      rach_preambleTransMax                    = 10;
+      rach_raResponseWindowSize                = 10;
+      rach_macContentionResolutionTimer        = 48;
+      rach_maxHARQ_Msg3Tx                      = 4;
 
-      pcch_default_PagingCycle           = 128;
-      pcch_nB                            = "oneT";
-      bcch_modificationPeriodCoeff       = 2;
-      ue_TimersAndConstants_t300         = 1000;
-      ue_TimersAndConstants_t301         = 1000;
-      ue_TimersAndConstants_t310         = 1000;
-      ue_TimersAndConstants_t311         = 10000;
-      ue_TimersAndConstants_n310         = 20;
-      ue_TimersAndConstants_n311         = 1;
+      pcch_default_PagingCycle                 = 128;
+      pcch_nB                                  = "oneT";
+      bcch_modificationPeriodCoeff             = 2;
+      ue_TimersAndConstants_t300               = 1000;
+      ue_TimersAndConstants_t301               = 1000;
+      ue_TimersAndConstants_t310               = 1000;
+      ue_TimersAndConstants_t311               = 10000;
+      ue_TimersAndConstants_n310               = 20;
+      ue_TimersAndConstants_n311               = 1;
+      ue_TransmissionMode                      = 1;
 
       //Parameters for SIB18
       rxPool_sc_CP_Len                                       = "normal"; 
@@ -120,25 +116,25 @@ eNBs =
       rxPool_ResourceConfig_offsetIndicator_present          = "prSmall";
       rxPool_ResourceConfig_offsetIndicator_choice           = 0;      
       rxPool_ResourceConfig_subframeBitmap_present           = "prBs40";
-      rxPool_ResourceConfig_subframeBitmap_choice_bs_buf              = "00000000000000000000";
-      rxPool_ResourceConfig_subframeBitmap_choice_bs_size             = 5;
-      rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused      = 0;
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_buf     = "00000000000000000000";
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_size    = 5;
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
 /*
-      rxPool_dataHoppingConfig_hoppingParameter                       = 0;
-      rxPool_dataHoppingConfig_numSubbands                            = "ns1";
-      rxPool_dataHoppingConfig_rbOffset                               = 0;
-      rxPool_commTxResourceUC-ReqAllowed                              = "TRUE";
+      rxPool_dataHoppingConfig_hoppingParameter              = 0;
+      rxPool_dataHoppingConfig_numSubbands                   = "ns1";
+      rxPool_dataHoppingConfig_rbOffset                      = 0;
+      rxPool_commTxResourceUC-ReqAllowed                     = "TRUE";
 */    
       // Parameters for SIB19
       discRxPool_cp_Len                                               = "normal"
       discRxPool_discPeriod                                           = "rf32"
-      discRxPool_numRetx                                              = 1;   
+      discRxPool_numRetx                                              = 1;
       discRxPool_numRepetition                                        = 2;
-      discRxPool_ResourceConfig_prb_Num                               = 5;  
+      discRxPool_ResourceConfig_prb_Num                               = 5;
       discRxPool_ResourceConfig_prb_Start                             = 3;
       discRxPool_ResourceConfig_prb_End                               = 21;
       discRxPool_ResourceConfig_offsetIndicator_present               = "prSmall";
-      discRxPool_ResourceConfig_offsetIndicator_choice                = 0;      
+      discRxPool_ResourceConfig_offsetIndicator_choice                = 0;
       discRxPool_ResourceConfig_subframeBitmap_present                = "prBs40";
       discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf          = "f0ffffffff";
       discRxPool_ResourceConfig_subframeBitmap_choice_bs_size         = 5;
@@ -190,7 +186,7 @@ eNBs =
                           );
 
     ///X2
-    enable_x2 = "yes";
+    enable_x2         = "yes";
     t_reloc_prep      = 1000;      /* unit: millisecond */
     tx2_reloc_overall = 2000;      /* unit: millisecond */
     t_dc_prep         = 1000;      /* unit: millisecond */
@@ -198,39 +194,19 @@ eNBs =
 
     NETWORK_INTERFACES : 
     {
-        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth1";
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
         ENB_IPV4_ADDRESS_FOR_S1_MME              = "CI_ENB_IP_ADDR";
-
-        ENB_INTERFACE_NAME_FOR_S1U               = "eth1";
+        ENB_INTERFACE_NAME_FOR_S1U               = "eth0";
         ENB_IPV4_ADDRESS_FOR_S1U                 = "CI_ENB_IP_ADDR";
         ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
-
         ENB_IPV4_ADDRESS_FOR_X2C                 = "CI_ENB_IP_ADDR";
         ENB_PORT_FOR_X2C                         = 36422; # Spec 36422
     };
-    
-    log_config : 
-    {
-     global_log_level                      ="info"; 
-     global_log_verbosity                  ="high";
-     hw_log_level                          ="info"; 
-     hw_log_verbosity                      ="medium";
-     phy_log_level                         ="info"; 
-     phy_log_verbosity                     ="medium";
-     mac_log_level                         ="info"; 
-     mac_log_verbosity                     ="high";
-     rlc_log_level                         ="debug"; 
-     rlc_log_verbosity                     ="high";
-     pdcp_log_level                        ="info"; 
-     pdcp_log_verbosity                    ="high";
-     rrc_log_level                         ="info"; 
-     rrc_log_verbosity                     ="medium";
-   }; 
-   
   }
 );
 
-MACRLCs = (
+MACRLCs =
+(
   {
     num_cc          = 1;
     tr_s_preference = "local_L1";
@@ -238,37 +214,52 @@ MACRLCs = (
     phy_test_mode   = 0;
     puSch10xSnr     =  160;
     puCch10xSnr     =  160;
-  }  
+  }
 );
 
-THREAD_STRUCT = (
+L1s =
+(
   {
-    parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
-    worker_config   = "ENABLE";
+    num_cc = 1;
+    tr_n_preference = "local_mac";
   }
 );
 
-L1s = (
+RUs =
+(
   {
-    num_cc          = 1;
-    tr_n_preference = "local_mac";
-  }  
+    local_rf                      = "yes"
+    nb_tx                         = 1
+    nb_rx                         = 1
+    att_tx                        = 3
+    att_rx                        = 0;
+    bands                         = [7];
+    max_pdschReferenceSignalPower = -27;
+    max_rxgain                    = 115;
+    eNB_instances                 = [0];
+#    clock_src                     = "external";
+  }
 );
 
-RUs = (
-  {             
-    local_rf       = "yes"
-    nb_tx          = 1
-    nb_rx          = 1
-    att_tx         = 0
-    att_rx         = 0;
-    bands          = [7];
-    max_pdschReferenceSignalPower = -27;
-    max_rxgain                    = 118;
-    eNB_instances  = [0];
-#    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";
   }
-);  
+);
+
+NETWORK_CONTROLLER :
+{
+    FLEXRAN_ENABLED        = "no";
+    FLEXRAN_INTERFACE_NAME = "eth0";
+    FLEXRAN_IPV4_ADDRESS   = "CI_FLEXRAN_CTL_IP_ADDR";
+    FLEXRAN_PORT           = 2210;
+    FLEXRAN_CACHE          = "/mnt/oai_agent_cache";
+    FLEXRAN_AWAIT_RECONF   = "no";
+};
 
 log_config : 
   {
@@ -286,4 +277,5 @@ log_config :
      pdcp_log_verbosity                    ="high";
      rrc_log_level                         ="info"; 
      rrc_log_verbosity                     ="medium";
-  }; 
+};
+
diff --git a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
new file mode 100644
index 0000000000000000000000000000000000000000..a4d9985dcafa05dfa89b6b3f547b636cf3eeaff2
--- /dev/null
+++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
@@ -0,0 +1,289 @@
+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  =  1;
+
+    plmn_list = ({mcc = 311; mnc = 480; mnc_length = 3;});	 
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
+	
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is pointA + 23 PRBs@120kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 2071241;
+      dl_frequencyBand                                                 = 261;
+      # this is 27.900 GHz
+      dl_absoluteFrequencyPointA                                       = 2070833;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        dl_subcarrierSpacing                                           = 3;
+        dl_carrierBandwidth                                            = 32;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=0,L=32 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 8525;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 3;
+      #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_3                    = 0;  #for mixed slot
+        initialDLBWPmappingType_3           = 0;
+        initialDLBWPstartSymbolAndLength_3  = 57; #this is SS=1,L=5
+
+  #uplinkConfigCommon 
+     #frequencyInfoUL
+      ul_frequencyBand                                                 = 261;
+      #scs-SpecificCarrierList
+      ul_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      ul_subcarrierSpacing                                           = 3;
+      ul_carrierBandwidth                                            = 32;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 8525;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialULBWPsubcarrierSpacing                                           = 3;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 52;
+#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                                           = 7;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 7;
+#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                                      = 3,
+
+# 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    = 41;
+
+        initialULBWPk2_1                      = 6;
+        initialULBWPmappingType_1             = 1;
+        # this is SS=0 L=12
+        initialULBWPstartSymbolAndLength_1    = 69;
+
+        initialULBWPk2_2                      = 14;
+        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                                       = 3;
+      ssb_PositionsInBurst_Bitmap                                   = 0x0001000100010001L;
+
+# 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                                             = 3;
+
+
+  #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      referenceSubcarrierSpacing                                    = 3;
+      # pattern1 
+      # dl_UL_TransmissionPeriodicity
+      # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+      dl_UL_TransmissionPeriodicity                                 = 3;
+      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.18.99";
+                              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       = "192.168.18.199";
+                                       ipv6       = "192:168:30::17";
+                                       preference = "ipv4";
+                                     }
+                                    );
+
+    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_PORT_FOR_S1U                         = 2152; # Spec 2152
+        GNB_IPV4_ADDRESS_FOR_X2C                 = "192.168.18.198/24";
+        GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
+    };
+  }
+);
+
+MACRLCs = (
+	{
+	    num_cc                      = 1;
+	    tr_s_preference             = "local_L1";
+	    tr_n_preference             = "local_RRC";
+	    ulsch_max_slots_inactivity  = 1;
+	    pusch_TargetSNRx10          = 200;
+        pucch_TargetSNRx10          = 200;
+    }
+);
+
+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                    = 75;
+         eNB_instances  = [0];
+	 sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2";
+         if_freq = 5124520000L;
+	 clock_src = "external";
+	 time_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";
+    };
+
diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
new file mode 100644
index 0000000000000000000000000000000000000000..1209a6f227f77167d113ae752e892bafbc3ae0f8
--- /dev/null
+++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
@@ -0,0 +1,278 @@
+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  =  1;
+
+    plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 2150 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 433096;
+      dl_frequencyBand                                                 = 66;
+      # this is 2150 MHz
+      dl_absoluteFrequencyPointA                                       = 430000;
+      #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=0,L=50 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 13475;
+# 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_3                    = 0;  #for mixed slot
+        initialDLBWPmappingType_3           = 0;
+        initialDLBWPstartSymbolAndLength_3  = 57; #this is SS=1,L=5
+
+  #uplinkConfigCommon
+     #frequencyInfoUL
+      ul_frequencyBand                                                 = 66;
+      ul_absoluteFrequencyPointA                                       = 350000;
+      #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                                        = 13475;
+# 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;  # 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=10 L=2
+
+        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:
+    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 = "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                    = 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";
+         # if_freq = 3700000000L;
+         # if_offset = 1000000;
+    }
+);
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+    };
+
diff --git a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf
new file mode 100644
index 0000000000000000000000000000000000000000..24dbdbd74b74c25e9bb357af2d2c68d09c4156d1
--- /dev/null
+++ b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf
@@ -0,0 +1,296 @@
+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  =  1;
+    plmn_list = ({mcc = 208; mnc = 99; mnc_length = 2;});	 
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 31; //0;
+    pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 2;
+    pusch_TargetSNRx10                                        = 200;
+    pucch_TargetSNRx10                                        = 200;
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 641272; //641032;      #641968; 641968=start of ssb at 3600MHz + 82 RBs    641032=center of SSB at center of cell
+      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=84,L=13 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6368;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 0;
+        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                                        = 6368;
+# 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                               = -100;
+#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                                           = 5;
+#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; //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                      = 2;  # used for UL slot
+        initialULBWPmappingType_0             = 1
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 2;  # used for mixed slot
+        initialULBWPmappingType_1             = 1;
+        initialULBWPstartSymbolAndLength_1    = 24; # this is SS=10 L=2
+
+        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; #0x80;
+
+# 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; //8; //7;
+      nrofDownlinkSymbols                                           = 6; //0; //6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4; //0; //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";
+                            }
+                          );
+
+    ///X2
+    enable_x2 = "yes";
+    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_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
+        GNB_IPV4_ADDRESS_FOR_X2C                 = "CI_GNB_IP_ADDR";
+        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";
+	pusch_proc_threads = 8;
+        prach_dtx_threshold = 100;
+        }  
+);
+
+RUs = (
+    {		  
+       local_rf       = "yes"
+         nb_tx          = 2
+         nb_rx          = 2
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 75;
+         eNB_instances  = [0];
+         bf_weights = [0x00007fff, 0x00007fff];
+         #clock_src = "external";
+         sdr_addrs = "mgmt_addr=192.168.18.240,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=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_RU_L1_TRX_SPLIT";
+    //parallel_config    = "PARALLEL_SINGLE_THREAD";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+security = {
+  # preferred ciphering algorithms
+  # the first one of the list that an UE supports in chosen
+  # valid values: nea0, nea1, nea2, nea3
+  ciphering_algorithms = ( "nea0", "nea2" );
+
+  # preferred integrity algorithms
+  # the first one of the list that an UE supports in chosen
+  # valid values: nia0, nia1, nia2, nia3
+  integrity_algorithms = ( "nia0" );
+};
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+    };
+
diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf
new file mode 100644
index 0000000000000000000000000000000000000000..db190f177d2452f804e17a5d1be19aa66170ad17
--- /dev/null
+++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf
@@ -0,0 +1,301 @@
+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 = 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:
+
+    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    = 52; # this is SS=10 L=4
+
+        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";
+        ulsch_max_slots_inactivity  = 100;
+        pusch_TargetSNRx10          = 200;
+        pucch_TargetSNRx10          = 200;
+    }
+);
+
+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                    = 81;
+         eNB_instances  = [0];
+         #beamforming 1x4 matrix:
+         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+         #clock_src = "external";
+         sdr_addrs = "mgmt_addr=192.168.18.240,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=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.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
index aeba400cad73ace17cb920bb5a2802b74dfa37af..8d32e8b792e793a9e1a3291f6153e407374c03d3 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -23,7 +23,8 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
-	
+    pusch_AntennaPorts                                        = 1;
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
@@ -46,7 +47,7 @@ gNBs =
      #initialDownlinkBWP
       #genericParameters
         # this is RBstart=41,L=24 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 6366;
+        initialDLBWPlocationAndBandwidth                                        = 6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
@@ -55,27 +56,13 @@ gNBs =
         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;
+        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
@@ -89,7 +76,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 6366;
+        initialULBWPlocationAndBandwidth                                        = 6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -131,20 +118,17 @@ gNBs =
         restrictedSetConfig                                         = 0,
 
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;
+        initialULBWPk2_0                      = 6;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
 
-        initialULBWPk2_1                      = 6;
+        initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
-        initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
@@ -186,7 +170,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
@@ -227,30 +211,39 @@ MACRLCs = (
 	num_cc = 1;
 	tr_s_preference = "local_L1";
 	tr_n_preference = "local_RRC";
-        }  
+	ulsch_max_slots_inactivity = 1;
+	}
 );
 
 L1s = (
-    	{
+	{
 	num_cc = 1;
 	tr_n_preference = "local_mac";
-        }  
+	pusch_proc_threads = 8;
+	}
 );
 
 RUs = (
     {		  
-       local_rf       = "yes"
+         local_rf       = "yes"
          nb_tx          = 1
          nb_rx          = 1
          att_tx         = 0
          att_rx         = 0;
          bands          = [7];
          max_pdschReferenceSignalPower = -27;
-         max_rxgain                    = 75;
+         max_rxgain                    = 50;
          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";
+         ## 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.30.2,mgmt_addr=192.168.30.2,second_addr=192.168.50.2";
          clock_src = "external";
     }
 );  
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 258618e7f0644e9e8a983350b9d9b93099b8b8aa..33855f2c0eb10c2d4301b57919ed9ea43e0c76d1 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
@@ -8,7 +8,6 @@ gNBs =
  {
     ////////// Identification parameters:
     gNB_ID    =  0xe00;
-
     cell_type =  "CELL_MACRO_GNB";
     gNB_name  =  "gNB-Eurecom-5GNRBox";
 
@@ -22,9 +21,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 31; //0;
     pdsch_AntennaPorts                                        = 1;
-    pusch_TargetSNRx10                                        = 200; 
-    pucch_TargetSNRx10                                        = 200;
-
+    pusch_AntennaPorts                                        = 1;
  
     servingCellConfigCommon = (
     {
@@ -48,7 +45,7 @@ gNBs =
      #initialDownlinkBWP
       #genericParameters
         # this is RBstart=84,L=13 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 6366; //28875; //6366; #6407; #3384;
+        initialDLBWPlocationAndBandwidth                                        = 6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
@@ -57,27 +54,14 @@ gNBs =
         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=4 //5 (4 is for 43, 5 is for 57)
-             initialDLBWPstartSymbolAndLength_3  = 57; //43; //57;
+        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;
@@ -90,7 +74,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 6366; //28875; //6366; #6407; #3384;
+        initialULBWPlocationAndBandwidth                                        = 6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -132,20 +116,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 2;
+        initialULBWPk2_0                      = 6;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
-   
-  initialULBWPk2_1                      = 2;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 52; # this is SS=10 L=4
 
-        initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
@@ -203,100 +184,101 @@ gNBs =
 
 
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR";
-                              ipv6       = "192:168:30::17";
-                              port       = 36412 ;
-                              active     = "yes";
-                              preference = "ipv4";
-                            }
-                          );
+#    mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR";
+#                              ipv6       = "192:168:30::17";
+#                              port       = 36412 ;
+#                              active     = "yes";
+#                              preference = "ipv4";
+#                            }
+#                          );
 
     ///X2
-    enable_x2 = "yes";
+    enable_x2         = "yes";
     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";
-                                     }
-                                    );
+
+    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_PORT_FOR_S1U                         = 2152; # Spec 2152
-        GNB_IPV4_ADDRESS_FOR_X2C                 = "CI_GNB_IP_ADDR";
-        GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
+      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_PORT_FOR_S1U               = 2152; # Spec 2152
+      GNB_IPV4_ADDRESS_FOR_X2C       = "CI_GNB_IP_ADDR";
+      GNB_PORT_FOR_X2C               = 36422; # Spec 36422
     };
+
   }
 );
 
 MACRLCs = (
   {
-  num_cc = 1;
-  tr_s_preference = "local_L1";
-  tr_n_preference = "local_RRC";
-        }  
+    num_cc              = 1;
+    tr_s_preference     = "local_L1";
+    tr_n_preference     = "local_RRC";
+    pusch_TargetSNRx10  = 200;
+    pucch_TargetSNRx10  = 200;
+  }
 );
 
 L1s = (
-      {
-  num_cc = 1;
-  tr_n_preference = "local_mac";
-  pusch_proc_threads = 8;
-        }  
+  {
+    num_cc             = 1;
+    tr_n_preference    = "local_mac";
+    pusch_proc_threads = 6;
+  }
 );
 
 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];
-#         clock_src = "external";
-    }
+  {
+    local_rf       = "yes"
+    nb_tx          = 1
+    nb_rx          = 1
+    att_tx         = 3
+    att_rx         = 0;
+    bands          = [7];
+    max_pdschReferenceSignalPower = -27;
+    max_rxgain     = 111;
+    eNB_instances  = [0];
+#    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";
-    //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                         ="info";
-       rlc_log_verbosity                     ="medium";
-       pdcp_log_level                        ="info";
-       pdcp_log_verbosity                    ="medium";
-       rrc_log_level                         ="info";
-       rrc_log_verbosity                     ="medium";
-    };
+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";
+};
 
 uicc: {
-opc = "testopc";
+  opc = "testopc";
 };
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf
new file mode 100644
index 0000000000000000000000000000000000000000..b981b27f53cc6ebba59d6bbdd71142cb1266fe33
--- /dev/null
+++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf
@@ -0,0 +1,295 @@
+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  =  1;
+    plmn_list = ({mcc = 222; mnc = 01; mnc_length = 2;});   
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 31; //0;
+    pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
+ 
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 641272; //641032;      #641968; 641968=start of ssb at 3600MHz + 82 RBs    641032=center of SSB at center of cell
+      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=84,L=13 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6368;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 0;
+        initialDLBWPsearchSpaceZero                                             = 0;
+      #pdsch-ConfigCommon
+        #pdschTimeDomainAllocationList (up to 16 entries)
+             initialDLBWPk0_0                    = 0;
+             #initialULBWPmappingType
+       #0=typeA,1=typeB
+             initialDLBWPmappingType_0           = 0;#for DL slot
+             #this is SS=1,L=13
+             initialDLBWPstartSymbolAndLength_0  = 40;
+
+             initialDLBWPk0_1                    = 0;#for mixed slot
+             initialDLBWPmappingType_1           = 0;
+             #this is SS=1,L=5 
+             initialDLBWPstartSymbolAndLength_1  = 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                                        = 6368;
+# 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                               = -90;
+#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                                           = 5;
+#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; //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                      = 2;
+        initialULBWPmappingType_0             = 1
+        # this is SS=0 L=11
+        initialULBWPstartSymbolAndLength_0    = 41;
+   
+  initialULBWPk2_1                      = 2;
+        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; #0x80;
+
+# 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; //8; //7;
+      nrofDownlinkSymbols                                           = 6; //0; //6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4; //0; //4;
+
+  ssPBCH_BlockPower                                             = -15;
+  }
+
+  );
+
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR";
+                              ipv6       = "192:168:30::17";
+                              port       = 36412 ;
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    ///X2
+    enable_x2 = "yes";
+    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_PORT_FOR_S1U                         = 2152; # Spec 2152
+        GNB_IPV4_ADDRESS_FOR_X2C                 = "CI_GNB_IP_ADDR";
+        GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
+    };
+  }
+);
+
+MACRLCs = (
+    {
+        num_cc              = 1;
+        tr_s_preference     = "local_L1";
+        tr_n_preference     = "local_RRC";
+        pusch_TargetSNRx10  = 200;
+        pucch_TargetSNRx10  = 200;
+    }
+);
+
+L1s = (
+      {
+  num_cc = 1;
+  tr_n_preference = "local_mac";
+  pusch_proc_threads = 6;
+        }  
+);
+
+RUs = (
+    {      
+       local_rf       = "yes"
+         nb_tx          = 1
+         nb_rx          = 1
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 75; #114
+         eNB_instances  = [0];
+         sdr_addrs = "addr=192.168.80.50"
+         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_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                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+    };
+
+uicc: {
+opc = "testopc";
+};
diff --git a/ci-scripts/conf_files/nr-ue-sim.conf b/ci-scripts/conf_files/nr-ue-sim.conf
new file mode 100644
index 0000000000000000000000000000000000000000..05ac825db418ab46f02b6a73d5a8f40bb8acb51d
--- /dev/null
+++ b/ci-scripts/conf_files/nr-ue-sim.conf
@@ -0,0 +1,8 @@
+uicc0 = {
+  imsi = "@FULL_IMSI@";
+  key = "@FULL_KEY@";
+  opc= "@OPC@";
+  dnn= "@DNN@";
+  nssai_sst=@NSSAI_SST@;
+  nssai_sd=@NSSAI_SD@;
+}
diff --git a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf
index 419598647b123e8d151037127fea63f3fbc6393e..7f6bff304d6d3fe9d52fed202369256d2a66e25a 100644
--- a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf
+++ b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf
@@ -19,54 +19,54 @@ eNBs =
     tracking_area_code = 1;
     plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
-       ////////// Physical parameters:
+    ////////// Physical parameters:
 
     component_carriers = (
       {
-        node_function                                         = "NGFI_RCC_IF4p5";
-        node_timing                                           = "synch_to_ext_device";
-        node_synch_ref                                        = 0;
-        frame_type					      = "TDD";
-        tdd_config 					      = 1;
-        tdd_config_s            			      = 0;
-        prefix_type             			      = "NORMAL";
-        eutra_band              			      = 40;
-        downlink_frequency      			      = 2350000000L;
-        uplink_frequency_offset 			      = 0;
-        Nid_cell					      = 0;
-        N_RB_DL                 			      = 25;
-        Nid_cell_mbsfn          			      = 0;
-        nb_antenna_ports          			      = 1;
-        nb_antennas_tx          			      = 1;
-        nb_antennas_rx          			      = 1;
-        tx_gain                                            = 90;
-        rx_gain                                            = 125;
-        prach_root              			      = 0;
-        prach_config_index      			      = 0;
-        prach_high_speed        			      = "DISABLE";
-        prach_zero_correlation  			      = 1;
-        prach_freq_offset       			      = 2;
-        pucch_delta_shift       			      = 1;
-        pucch_nRB_CQI           			      = 1;
-        pucch_nCS_AN            			      = 0;
-        pucch_n1_AN             			      = 0;
-        pdsch_referenceSignalPower 			      =-27;
-        pdsch_p_b                  			      = 0;
-        pusch_n_SB                 			      = 1;
-        pusch_enable64QAM          			      = "DISABLE";
-        pusch_hoppingMode                                  = "interSubFrame";
-        pusch_hoppingOffset                                = 0;
-        pusch_groupHoppingEnabled  			      = "ENABLE";
-        pusch_groupAssignment      			      = 0;
-        pusch_sequenceHoppingEnabled		   	      = "DISABLE";
-        pusch_nDMRS1                                       = 1;
-        phich_duration                                     = "NORMAL";
-        phich_resource                                     = "ONESIXTH";
-        srs_enable                                         = "DISABLE";
-      /*  srs_BandwidthConfig                                =;
-        srs_SubframeConfig                                 =;
-        srs_ackNackST                                      =;
-        srs_MaxUpPts                                       =;*/
+        node_function                             = "NGFI_RCC_IF4p5";
+        node_timing                               = "synch_to_ext_device";
+        node_synch_ref                            = 0;
+        frame_type                                = "TDD";
+        tdd_config                                = 1;
+        tdd_config_s                              = 0;
+        prefix_type                               = "NORMAL";
+        eutra_band                                = 40;
+        downlink_frequency                        = 2350000000L;
+        uplink_frequency_offset                   = 0;
+        Nid_cell                                  = 0;
+        N_RB_DL                                   = 25;
+        Nid_cell_mbsfn                            = 0;
+        nb_antenna_ports                          = 1;
+        nb_antennas_tx                            = 1;
+        nb_antennas_rx                            = 1;
+        tx_gain                                   = 90;
+        rx_gain                                   = 125;
+        prach_root                                = 0;
+        prach_config_index                        = 0;
+        prach_high_speed                          = "DISABLE";
+        prach_zero_correlation                    = 1;
+        prach_freq_offset                         = 2;
+        pucch_delta_shift                         = 1;
+        pucch_nRB_CQI                             = 1;
+        pucch_nCS_AN                              = 0;
+        pucch_n1_AN                               = 0;
+        pdsch_referenceSignalPower                =-27;
+        pdsch_p_b                                 = 0;
+        pusch_n_SB                                = 1;
+        pusch_enable64QAM                         = "DISABLE";
+        pusch_hoppingMode                         = "interSubFrame";
+        pusch_hoppingOffset                       = 0;
+        pusch_groupHoppingEnabled                 = "ENABLE";
+        pusch_groupAssignment                     = 0;
+        pusch_sequenceHoppingEnabled              = "DISABLE";
+        pusch_nDMRS1                              = 1;
+        phich_duration                            = "NORMAL";
+        phich_resource                            = "ONESIXTH";
+        srs_enable                                = "DISABLE";
+      /*  srs_BandwidthConfig                     =;
+        srs_SubframeConfig                        =;
+        srs_ackNackST                             =;
+        srs_MaxUpPts                              =;*/
 
         pusch_p0_Nominal                                   = -96;
         pusch_alpha                                        = "AL1";
@@ -76,7 +76,7 @@ eNBs =
         pucch_deltaF_Format1b                              = "deltaF3";
         pucch_deltaF_Format2                               = "deltaF0";
         pucch_deltaF_Format2a                              = "deltaF0";
-        pucch_deltaF_Format2b		    	      = "deltaF0";
+        pucch_deltaF_Format2b                              = "deltaF0";
 
         rach_numberOfRA_Preambles                          = 64;
         rach_preamblesGroupAConfig                         = "DISABLE";
@@ -92,17 +92,17 @@ eNBs =
         rach_macContentionResolutionTimer                  = 48;
         rach_maxHARQ_Msg3Tx                                = 4;
 
-        pcch_default_PagingCycle                           = 128;
-        pcch_nB                                            = "oneT";
-        bcch_modificationPeriodCoeff			      = 2;
-        ue_TimersAndConstants_t300			      = 1000;
-        ue_TimersAndConstants_t301			      = 1000;
-        ue_TimersAndConstants_t310			      = 1000;
-        ue_TimersAndConstants_t311			      = 10000;
-        ue_TimersAndConstants_n310			      = 20;
-        ue_TimersAndConstants_n311			      = 1;
-
-	ue_TransmissionMode				      = 1;
+        pcch_default_PagingCycle                    = 128;
+        pcch_nB                                     = "oneT";
+        bcch_modificationPeriodCoeff                = 2;
+        ue_TimersAndConstants_t300                  = 1000;
+        ue_TimersAndConstants_t301                  = 1000;
+        ue_TimersAndConstants_t310                  = 1000;
+        ue_TimersAndConstants_t311                  = 10000;
+        ue_TimersAndConstants_n310                  = 20;
+        ue_TimersAndConstants_n311                  = 1;
+
+        ue_TransmissionMode                         = 1;
       }
     );
 
@@ -148,7 +148,7 @@ eNBs =
     enable_measurement_reports = "no";
 
     ///X2
-    enable_x2 = "no";
+    enable_x2         = "no";
     t_reloc_prep      = 1000;      /* unit: millisecond */
     tx2_reloc_overall = 2000;      /* unit: millisecond */
     t_dc_prep         = 1000;      /* unit: millisecond */
@@ -186,41 +186,41 @@ eNBs =
   }
 );
 MACRLCs = (
-	{
-        num_cc = 1;
-        tr_s_preference = "local_L1";
-        tr_n_preference = "local_RRC";
-        scheduler_mode = "fairRR";
-        puSch10xSnr     =  200;
-        puCch10xSnr     =  200;
-        }  
+  {
+    num_cc          = 1;
+    tr_s_preference = "local_L1";
+    tr_n_preference = "local_RRC";
+    scheduler_mode  = "fairRR";
+    puSch10xSnr     =  200;
+    puCch10xSnr     =  200;
+  }
 );
 
 L1s = (
-    	{
-	num_cc = 1;
-	tr_n_preference = "local_mac";
-        }  
+  {
+    num_cc          = 1;
+    tr_n_preference = "local_mac";
+  }
 );
 
 RUs = (
-    {		  
-        local_if_name  = "lo";
-        remote_address = "127.0.0.2";
-        local_address  = "127.0.0.1";
-        local_portc    = 50000;
-        remote_portc   = 50000;
-        local_portd    = 50001;
-        remote_portd   = 50001;
-        local_rf       = "no"
-        tr_preference  = "udp_if4p5"
-        nb_tx          = 1
-        nb_rx          = 1
-        att_tx         = 0
-        att_rx         = 0;
-        eNB_instances  = [0];
-    }
-);  
+  {
+    local_if_name  = "lo";
+    remote_address = "127.0.0.2";
+    local_address  = "127.0.0.1";
+    local_portc    = 50000;
+    remote_portc   = 50000;
+    local_portd    = 50001;
+    remote_portd   = 50001;
+    local_rf       = "no"
+    tr_preference  = "udp_if4p5"
+    nb_tx          = 1
+    nb_rx          = 1
+    att_tx         = 0
+    att_rx         = 0;
+    eNB_instances  = [0];
+  }
+);
 
 THREAD_STRUCT = (
   {
diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf
index 2c3c11b84f287cc237922114166ecf9809863331..574c8b25456d5ce7d8f9d72f4a2c379e64143798 100644
--- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf
@@ -25,51 +25,51 @@ eNBs =
 
     component_carriers = (
       {
-      node_function             = "NGFI_RCC_IF4p5";
-      node_timing               = "synch_to_ext_device";
-      node_synch_ref            = 0;
-      frame_type					      = "FDD";
-      tdd_config 					      = 3;
-      tdd_config_s            			      = 0;
-      prefix_type             			      = "NORMAL";
-      eutra_band              			      = 7;
-      downlink_frequency      			      = 2680000000L;
-      uplink_frequency_offset 			      = -120000000;
-      Nid_cell					      = 0;
-      N_RB_DL                 			      = 25;
-      Nid_cell_mbsfn          			      = 0;
-      nb_antenna_ports                                = 1;
-      nb_antennas_tx          			      = 1;
-      nb_antennas_rx          			      = 1;
-      tx_gain                                            = 90;
-      rx_gain                                            = 125;
-      pbch_repetition                                 = "FALSE";
-      prach_root              			      = 0;
-      prach_config_index      			      = 0;
-      prach_high_speed        			      = "DISABLE";
-      prach_zero_correlation  			      = 1;
-      prach_freq_offset       			      = 2;
-      pucch_delta_shift       			      = 1;
-      pucch_nRB_CQI           			      = 0;
-      pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 0;
-      pdsch_referenceSignalPower 			      = -25;
-      pdsch_p_b                  			      = 0;
-      pusch_n_SB                 			      = 1;
-      pusch_enable64QAM          			      = "DISABLE";
-      pusch_hoppingMode                                  = "interSubFrame";
-      pusch_hoppingOffset                                = 0;
-      pusch_groupHoppingEnabled  			      = "ENABLE";
-      pusch_groupAssignment      			      = 0;
-      pusch_sequenceHoppingEnabled		   	      = "DISABLE";
-      pusch_nDMRS1                                       = 1;
-      phich_duration                                     = "NORMAL";
-      phich_resource                                     = "ONESIXTH";
-      srs_enable                                         = "DISABLE";
-      /*  srs_BandwidthConfig                                =;
-      srs_SubframeConfig                                 =;
-      srs_ackNackST                                      =;
-      srs_MaxUpPts                                       =;*/
+      node_function                             = "NGFI_RCC_IF4p5";
+      node_timing                               = "synch_to_ext_device";
+      node_synch_ref                            = 0;
+      frame_type                                = "FDD";
+      tdd_config                                = 3;
+      tdd_config_s                              = 0;
+      prefix_type                               = "NORMAL";
+      eutra_band                                = 7;
+      downlink_frequency                        = 2680000000L;
+      uplink_frequency_offset                   = -120000000;
+      Nid_cell                                  = 0;
+      N_RB_DL                                   = 25;
+      Nid_cell_mbsfn                            = 0;
+      nb_antenna_ports                          = 1;
+      nb_antennas_tx                            = 1;
+      nb_antennas_rx                            = 1;
+      tx_gain                                   = 90;
+      rx_gain                                   = 125;
+      pbch_repetition                           = "FALSE";
+      prach_root                                = 0;
+      prach_config_index                        = 0;
+      prach_high_speed                          = "DISABLE";
+      prach_zero_correlation                    = 1;
+      prach_freq_offset                         = 2;
+      pucch_delta_shift                         = 1;
+      pucch_nRB_CQI                             = 0;
+      pucch_nCS_AN                              = 0;
+      pucch_n1_AN                               = 0;
+      pdsch_referenceSignalPower                = -25;
+      pdsch_p_b                                 = 0;
+      pusch_n_SB                                = 1;
+      pusch_enable64QAM                         = "DISABLE";
+      pusch_hoppingMode                         = "interSubFrame";
+      pusch_hoppingOffset                       = 0;
+      pusch_groupHoppingEnabled                 = "ENABLE";
+      pusch_groupAssignment                     = 0;
+      pusch_sequenceHoppingEnabled              = "DISABLE";
+      pusch_nDMRS1                              = 1;
+      phich_duration                            = "NORMAL";
+      phich_resource                            = "ONESIXTH";
+      srs_enable                                = "DISABLE";
+      /*  srs_BandwidthConfig                   =;
+      srs_SubframeConfig                        =;
+      srs_ackNackST                             =;
+      srs_MaxUpPts                              =;*/
 
       pusch_p0_Nominal                                   = -96;
       pusch_alpha                                        = "AL1";
@@ -79,7 +79,7 @@ eNBs =
       pucch_deltaF_Format1b                              = "deltaF3";
       pucch_deltaF_Format2                               = "deltaF0";
       pucch_deltaF_Format2a                              = "deltaF0";
-      pucch_deltaF_Format2b		    	      = "deltaF0";
+      pucch_deltaF_Format2b                              = "deltaF0";
 
       rach_numberOfRA_Preambles                          = 64;
       rach_preamblesGroupAConfig                         = "DISABLE";
@@ -97,25 +97,25 @@ eNBs =
 
       pcch_default_PagingCycle                           = 128;
       pcch_nB                                            = "oneT";
-      bcch_modificationPeriodCoeff			      = 2;
-      ue_TimersAndConstants_t300			      = 1000;
-      ue_TimersAndConstants_t301			      = 1000;
-      ue_TimersAndConstants_t310			      = 1000;
-      ue_TimersAndConstants_t311			      = 10000;
-      ue_TimersAndConstants_n310			      = 20;
-      ue_TimersAndConstants_n311			      = 1;
-      ue_TransmissionMode                                    = 1;
+      bcch_modificationPeriodCoeff                       = 2;
+      ue_TimersAndConstants_t300                         = 1000;
+      ue_TimersAndConstants_t301                         = 1000;
+      ue_TimersAndConstants_t310                         = 1000;
+      ue_TimersAndConstants_t311                         = 10000;
+      ue_TimersAndConstants_n310                         = 20;
+      ue_TimersAndConstants_n311                         = 1;
+      ue_TransmissionMode                                = 1;
 
       //Parameters for SIB18
-      rxPool_sc_CP_Len                                       = "normal";
-      rxPool_sc_Period                                       = "sf40";
-      rxPool_data_CP_Len                                     = "normal";
-      rxPool_ResourceConfig_prb_Num                          = 20;
-      rxPool_ResourceConfig_prb_Start                        = 5;
-      rxPool_ResourceConfig_prb_End                          = 44;
-      rxPool_ResourceConfig_offsetIndicator_present          = "prSmall";
-      rxPool_ResourceConfig_offsetIndicator_choice           = 0;
-      rxPool_ResourceConfig_subframeBitmap_present           = "prBs40";
+      rxPool_sc_CP_Len                                                = "normal";
+      rxPool_sc_Period                                                = "sf40";
+      rxPool_data_CP_Len                                              = "normal";
+      rxPool_ResourceConfig_prb_Num                                   = 20;
+      rxPool_ResourceConfig_prb_Start                                 = 5;
+      rxPool_ResourceConfig_prb_End                                   = 44;
+      rxPool_ResourceConfig_offsetIndicator_present                   = "prSmall";
+      rxPool_ResourceConfig_offsetIndicator_choice                    = 0;
+      rxPool_ResourceConfig_subframeBitmap_present                    = "prBs40";
       rxPool_ResourceConfig_subframeBitmap_choice_bs_buf              = "00000000000000000000";
       rxPool_ResourceConfig_subframeBitmap_choice_bs_size             = 5;
       rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused      = 0;
@@ -185,7 +185,7 @@ eNBs =
     enable_measurement_reports = "no";
 
     ///X2
-    enable_x2 = "no";
+    enable_x2         = "no";
     t_reloc_prep      = 1000;      /* unit: millisecond */
     tx2_reloc_overall = 2000;      /* unit: millisecond */
     t_dc_prep         = 1000;      /* unit: millisecond */
@@ -205,21 +205,21 @@ eNBs =
 );
 
 MACRLCs = (
-	{
-	num_cc = 1;
-	tr_s_preference = "local_L1";
-	tr_n_preference = "local_RRC";
-	phy_test_mode = 0;
-        puSch10xSnr     =  160;
-        puCch10xSnr     =  160;
-        }
+  {
+    num_cc = 1;
+    tr_s_preference = "local_L1";
+    tr_n_preference = "local_RRC";
+    phy_test_mode   = 0;
+    puSch10xSnr     =  160;
+    puCch10xSnr     =  160;
+  }
 );
 
 L1s = (
-      {
-	num_cc = 1;
-	tr_n_preference = "local_mac";
-      }
+  {
+    num_cc          = 1;
+    tr_n_preference = "local_mac";
+  }
 );
 
 RUs = (
@@ -260,20 +260,20 @@ NETWORK_CONTROLLER :
     FLEXRAN_AWAIT_RECONF   = "no";
 };
 
-     log_config :
-     {
-       global_log_level                      ="info";
-       global_log_verbosity                  ="medium";
-       hw_log_level                          ="info";
-       hw_log_verbosity                      ="medium";
-       phy_log_level                         ="info";
-       phy_log_verbosity                     ="medium";
-       mac_log_level                         ="info";
-       mac_log_verbosity                     ="high";
-       rlc_log_level                         ="info";
-       rlc_log_verbosity                     ="medium";
-       pdcp_log_level                        ="info";
-       pdcp_log_verbosity                    ="medium";
-       rrc_log_level                         ="info";
-       rrc_log_verbosity                     ="medium";
-    };
+log_config :
+{
+  global_log_level         ="info";
+  global_log_verbosity     ="medium";
+  hw_log_level             ="info";
+  hw_log_verbosity         ="medium";
+  phy_log_level            ="info";
+  phy_log_verbosity        ="medium";
+  mac_log_level            ="info";
+  mac_log_verbosity        ="high";
+  rlc_log_level            ="info";
+  rlc_log_verbosity        ="medium";
+  pdcp_log_level           ="info";
+  pdcp_log_verbosity       ="medium";
+  rrc_log_level            ="info";
+  rrc_log_verbosity        ="medium";
+};
diff --git a/ci-scripts/constants.py b/ci-scripts/constants.py
index a0e1ac5c45c57490db5edf3115e39e25098d667f..bb110bc0e87b149cc999222bfa2d0567b0b305c4 100644
--- a/ci-scripts/constants.py
+++ b/ci-scripts/constants.py
@@ -60,6 +60,11 @@ OAI_UE_PROCESS_SEG_FAULT = -25
 OAI_UE_PROCESS_NO_MBMS_MSGS = -26
 OAI_UE_PROCESS_OK = +6
 INVALID_PARAMETER = -50
+PHYSIM_IMAGE_ABSENT = -60
+OC_LOGIN_FAIL = -61
+OC_PROJECT_FAIL = -62
+OC_IS_FAIL = -63
+OC_PHYSIM_DEPLOY_FAIL = -64
 
 UE_STATUS_DETACHED = 0
 UE_STATUS_DETACHING = 1
diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh
index 237a1a5d5e4521197c51a2f69433a38340f1c6e3..f3f8ddaca28641ddf5b465001661170c11739b58 100755
--- a/ci-scripts/createVM.sh
+++ b/ci-scripts/createVM.sh
@@ -87,6 +87,12 @@ function create_vm {
     echo "VM_CPU              = $VM_CPU"
     echo "VM_DISK             = $VM_DISK GBytes"
 
+    if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]]
+    then
+        echo "This VM type is no longer supported in the pipeline framework"
+        return
+    fi
+
     echo "############################################################"
     echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base"
     echo "############################################################"
diff --git a/ci-scripts/datalog_rt_stats.yaml b/ci-scripts/datalog_rt_stats.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..548caa0bddbb201fc14fdf6c6f66a142d40a5ace
--- /dev/null
+++ b/ci-scripts/datalog_rt_stats.yaml
@@ -0,0 +1,33 @@
+#this is a configuration file
+#used to build real time processing statistics 
+#for 5G NR phy test (gNB terminate)
+Title : Processing Time (us)
+ColNames :
+  - Metric
+  - Average
+  - Max
+  - Average vs Reference Deviation (Reference Value ; Acceptability Threshold)
+Ref : 
+  feprx : 60.0
+  feptx_prec : 8.0
+  feptx_ofdm : 50.0
+  feptx_total : 75.0
+  L1 Tx processing : 300.0
+  DLSCH encoding : 230.0
+  L1 Rx processing : 175.0
+  PUSCH inner-receiver : 100.0
+  PUSCH decoding : 140.0 
+  DL & UL scheduling timing stats : 37.0
+  UL Indication : 38.0
+Threshold :
+  feprx : 1.25
+  feptx_prec : 1.25
+  feptx_ofdm : 1.25
+  feptx_total : 1.25
+  L1 Tx processing : 1.25
+  DLSCH encoding : 1.25
+  L1 Rx processing : 1.25
+  PUSCH inner-receiver : 1.25
+  PUSCH decoding : 1.25
+  DL & UL scheduling timing stats : 1.25
+  UL Indication : 1.25
diff --git a/ci-scripts/docker/Dockerfile.cppcheck.xenial b/ci-scripts/docker/Dockerfile.cppcheck.xenial
new file mode 100644
index 0000000000000000000000000000000000000000..0aecc62037e6a2bdfb849f02e2618dd04bd4eb7e
--- /dev/null
+++ b/ci-scripts/docker/Dockerfile.cppcheck.xenial
@@ -0,0 +1,31 @@
+FROM ubuntu:xenial AS oai-cppcheck
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update && \
+    DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
+    DEBIAN_FRONTEND=noninteractive apt-get install --yes \
+       build-essential \
+       vim \
+       cppcheck
+
+WORKDIR /oai-ran
+COPY . .
+
+WORKDIR /oai-ran/common/utils/T
+RUN make
+
+WORKDIR /oai-ran
+RUN mkdir -p cmake_targets/log && \
+    cppcheck --enable=warning --force --xml --xml-version=2 \
+        -i openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c \
+        --suppressions-list=ci-scripts/cppcheck_suppressions.list \
+        -I common/utils \
+        -I openair3/NAS/COMMON/UTIL \
+        -j`nproc` . 2> cmake_targets/log/cppcheck.xml 1> cmake_targets/log/cppcheck_build.txt
+
+RUN egrep -c 'severity="error' cmake_targets/log/cppcheck.xml
+
+RUN egrep -c 'severity="warning' cmake_targets/log/cppcheck.xml
+
+RUN cat cmake_targets/log/cppcheck.xml
diff --git a/ci-scripts/docker_log_split.py b/ci-scripts/docker_log_split.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c3c9e41dcac79f2b527fc980da803b7b33465fc
--- /dev/null
+++ b/ci-scripts/docker_log_split.py
@@ -0,0 +1,92 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+# Python for CI of OAI-eNB + COTS-UE
+#
+#   Required Python Version
+#     Python 3.x
+#
+#   Required Python Package
+#     pexpect
+#---------------------------------------------------------------------
+
+
+#-----------------------------------------------------------
+# Import Libs
+#-----------------------------------------------------------
+import sys		# arg
+import re		# reg
+import os
+import subprocess
+
+
+class SplitReport():
+	def __init__(self):
+		self.logfilename = ''
+		self.destinationFolder = ''
+
+	def split(self):
+		self.destinationFolder = self.logfilename.replace(".log","")
+		if os.path.isfile(self.logfilename):
+			newImageLog = open(self.logfilename + '.new', 'w')
+			copyFlag = True
+			with open(self.logfilename, 'r') as imageLog:
+				for line in imageLog:
+					header = False
+					ret = re.search('====== Start of log for ([0-9\.A-Za-z\-\_]+) ======', line)
+					if ret is not None:
+						copyFlag = False
+						header = True
+						detailedLogFile = open(self.destinationFolder + '/' + ret.group(1), 'w')
+					if copyFlag:
+						newImageLog.write(line)
+					ret = re.search('====== End of log for ([0-9\.A-Za-z\-\_]+) ======', line)
+					if ret is not None:
+						copyFlag = True
+						detailedLogFile.close()
+					elif not copyFlag and not header:
+						detailedLogFile.write(line)
+			imageLog.close()
+			newImageLog.close()
+			os.rename(self.logfilename + '.new', self.logfilename)
+		else:
+			print('Cannot split unfound file')
+
+#--------------------------------------------------------------------------------------------------------
+#
+# Start of main
+#
+#--------------------------------------------------------------------------------------------------------
+
+argvs = sys.argv
+argc = len(argvs)
+
+SP = SplitReport()
+
+while len(argvs) > 1:
+	myArgv = argvs.pop(1)
+	if re.match('^\-\-logfilename=(.+)$', myArgv, re.IGNORECASE):
+		matchReg = re.match('^\-\-logfilename=(.+)$', myArgv, re.IGNORECASE)
+		SP.logfilename = matchReg.group(1)
+
+SP.split()
+
+sys.exit(0)
diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py
index cd5a74765435065df2b8643b47e17b7917a5f86c..1c202438d2a3f337bab4e2207a53cea6ca7ce868 100644
--- a/ci-scripts/epc.py
+++ b/ci-scripts/epc.py
@@ -62,6 +62,7 @@ class EPCManagement():
 		self.PcapFileName = ''
 		self.testCase_id = ''
 		self.MmeIPAddress = ''
+		self.AmfIPAddress = ''
 		self.containerPrefix = 'prod'
 		self.mmeConfFile = 'mme.conf'
 		self.yamlPath = ''
@@ -76,7 +77,7 @@ class EPCManagement():
 			HELP.GenericHelp(CONST.Version)
 			HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type)
 			sys.exit('Insufficient EPC Parameters')
-		mySSH = SSH.SSHConnection() 
+		mySSH = SSH.SSHConnection()
 		mySSH.open(self.IPAddress, self.UserName, self.Password)
 		if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
 			logging.debug('Using the OAI EPC Release 14 Cassandra-based HSS in Docker')
@@ -120,7 +121,7 @@ class EPCManagement():
 			HELP.GenericHelp(CONST.Version)
 			HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type)
 			sys.exit('Insufficient EPC Parameters')
-		mySSH = SSH.SSHConnection() 
+		mySSH = SSH.SSHConnection()
 		mySSH.open(self.IPAddress, self.UserName, self.Password)
 		if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
 			logging.debug('Using the OAI EPC Release 14 MME in Docker')
@@ -161,7 +162,7 @@ class EPCManagement():
 			return
 		# Only in case of Docker containers, MME IP address is not the EPC HOST IP address
 		if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
-			mySSH = SSH.SSHConnection() 
+			mySSH = SSH.SSHConnection()
 			mySSH.open(self.IPAddress, self.UserName, self.Password)
 			mySSH.command('docker inspect --format="MME_IP_ADDR = {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" ' + self.containerPrefix + '-oai-mme', '\$', 5)
 			result = re.search('MME_IP_ADDR = (?P<mme_ip_addr>[0-9\.]+)', mySSH.getBefore())
@@ -177,7 +178,7 @@ class EPCManagement():
 			HELP.GenericHelp(CONST.Version)
 			HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type)
 			sys.exit('Insufficient EPC Parameters')
-		mySSH = SSH.SSHConnection() 
+		mySSH = SSH.SSHConnection()
 		mySSH.open(self.IPAddress, self.UserName, self.Password)
 		if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
 			logging.debug('Using the OAI EPC Release 14 SPGW-CUPS in Docker')
@@ -211,9 +212,40 @@ class EPCManagement():
 		mySSH.close()
 		HTML.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK)
 
+	def Initialize5GCN(self, HTML):
+		if self.IPAddress == '' or self.UserName == '' or self.Password == '' or self.SourceCodePath == '' or self.Type == '':
+			HELP.GenericHelp(CONST.Version)
+			HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type)
+			sys.exit('Insufficient EPC Parameters')
+		mySSH = SSH.SSHConnection()
+		mySSH.open(self.IPAddress, self.UserName, self.Password)
+		if re.match('ltebox', self.Type, re.IGNORECASE):
+			logging.debug('Using the sabox simulated HSS')
+			mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
+			mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5)
+			mySSH.command('cd /opt/hss_sim0609', '\$', 5)
+			mySSH.command('echo ' + self.Password + ' | sudo -S rm -f hss.log', '\$', 5)
+			mySSH.command('echo ' + self.Password + ' | sudo -S echo "Starting sudo session" && sudo su -c "screen -dm -S simulated_5g_hss ./start_5g_hss"', '\$', 5)
+			logging.debug('Using the sabox')
+			mySSH.command('cd /opt/ltebox/tools', '\$', 5)
+			mySSH.command('echo ' + self.Password + ' | sudo -S ./start_sabox', '\$', 5)
+		else:
+			logging.error('This option should not occur!')
+		mySSH.close()
+		HTML.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK)
+
+	def SetAmfIPAddress(self):
+		# Not an error if we don't need an 5GCN
+		if self.IPAddress == '' or self.UserName == '' or self.Password == '' or self.SourceCodePath == '' or self.Type == '':
+			return
+		if self.IPAddress == 'none':
+			return
+		if re.match('ltebox', self.Type, re.IGNORECASE):
+			self.MmeIPAddress = self.IPAddress
+
 	def CheckHSSProcess(self, status_queue):
 		try:
-			mySSH = SSH.SSHConnection() 
+			mySSH = SSH.SSHConnection()
 			mySSH.open(self.IPAddress, self.UserName, self.Password)
 			if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
 				mySSH.command('docker top ' + self.containerPrefix + '-oai-hss', '\$', 5)
@@ -238,7 +270,7 @@ class EPCManagement():
 
 	def CheckMMEProcess(self, status_queue):
 		try:
-			mySSH = SSH.SSHConnection() 
+			mySSH = SSH.SSHConnection()
 			mySSH.open(self.IPAddress, self.UserName, self.Password)
 			if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
 				mySSH.command('docker top ' + self.containerPrefix + '-oai-mme', '\$', 5)
@@ -251,11 +283,11 @@ class EPCManagement():
 			elif re.match('OAI', self.Type, re.IGNORECASE):
 				result = re.search('\/bin\/bash .\/run_', mySSH.getBefore())
 			elif re.match('ltebox', self.Type, re.IGNORECASE):
-				result = re.search('mme', mySSH.getBefore())
+				result = re.search('mme|amf', mySSH.getBefore())
 			else:
 				logging.error('This should not happen!')
 			if result is None:
-				logging.debug('\u001B[1;37;41m MME Process Not Found! \u001B[0m')
+				logging.debug('\u001B[1;37;41m MME|AMF Process Not Found! \u001B[0m')
 				status_queue.put(CONST.MME_PROCESS_FAILED)
 			else:
 				status_queue.put(CONST.MME_PROCESS_OK)
@@ -265,7 +297,7 @@ class EPCManagement():
 
 	def CheckSPGWProcess(self, status_queue):
 		try:
-			mySSH = SSH.SSHConnection() 
+			mySSH = SSH.SSHConnection()
 			mySSH.open(self.IPAddress, self.UserName, self.Password)
 			if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
 				mySSH.command('docker top ' + self.containerPrefix + '-oai-spgwc', '\$', 5)
@@ -281,11 +313,11 @@ class EPCManagement():
 				result = re.search('\/bin\/bash .\/run_', mySSH.getBefore())
 			elif re.match('ltebox', self.Type, re.IGNORECASE):
 				mySSH.command('stdbuf -o0 ps -aux | grep --color=never xGw | grep -v grep', '\$', 5)
-				result = re.search('xGw', mySSH.getBefore())
+				result = re.search('xGw|upf', mySSH.getBefore())
 			else:
 				logging.error('This should not happen!')
 			if result is None:
-				logging.debug('\u001B[1;37;41m SPGW Process Not Found! \u001B[0m')
+				logging.debug('\u001B[1;37;41m SPGW|UPF Process Not Found! \u001B[0m')
 				status_queue.put(CONST.SPGW_PROCESS_FAILED)
 			else:
 				status_queue.put(CONST.SPGW_PROCESS_OK)
@@ -294,7 +326,7 @@ class EPCManagement():
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def TerminateHSS(self, HTML):
-		mySSH = SSH.SSHConnection() 
+		mySSH = SSH.SSHConnection()
 		mySSH.open(self.IPAddress, self.UserName, self.Password)
 		if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
 			mySSH.command('docker exec -it ' + self.containerPrefix + '-oai-hss /bin/bash -c "killall --signal SIGINT oai_hss tshark"', '\$', 5)
@@ -322,14 +354,14 @@ class EPCManagement():
 			mySSH.command('cd ' + self.SourceCodePath, '\$', 5)
 			mySSH.command('cd scripts', '\$', 5)
 			time.sleep(1)
-			mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGKILL hss_sim', '\$', 5)
+			mySSH.command('echo ' + self.Password + ' | sudo -S screen -S simulated_hss -X quit', '\$', 5)
 		else:
 			logging.error('This should not happen!')
 		mySSH.close()
 		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def TerminateMME(self, HTML):
-		mySSH = SSH.SSHConnection() 
+		mySSH = SSH.SSHConnection()
 		mySSH.open(self.IPAddress, self.UserName, self.Password)
 		if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
 			mySSH.command('docker exec -it ' + self.containerPrefix + '-oai-mme /bin/bash -c "killall --signal SIGINT oai_mme tshark"', '\$', 5)
@@ -355,7 +387,7 @@ class EPCManagement():
 		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def TerminateSPGW(self, HTML):
-		mySSH = SSH.SSHConnection() 
+		mySSH = SSH.SSHConnection()
 		mySSH.open(self.IPAddress, self.UserName, self.Password)
 		if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
 			mySSH.command('docker exec -it ' + self.containerPrefix + '-oai-spgwc /bin/bash -c "killall --signal SIGINT oai_spgwc tshark"', '\$', 5)
@@ -397,6 +429,22 @@ class EPCManagement():
 		mySSH.close()
 		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
+	def Terminate5GCN(self, HTML):
+		mySSH = SSH.SSHConnection()
+		mySSH.open(self.IPAddress, self.UserName, self.Password)
+		if re.match('ltebox', self.Type, re.IGNORECASE):
+			mySSH.command('cd /opt/ltebox/tools', '\$', 5)
+			mySSH.command('echo ' + self.Password + ' | sudo -S ./stop_sabox', '\$', 5)
+			time.sleep(1)
+			mySSH.command('cd ' + self.SourceCodePath, '\$', 5)
+			mySSH.command('cd scripts', '\$', 5)
+			time.sleep(1)
+			mySSH.command('echo ' + self.Password + ' | sudo -S screen -S simulated_5g_hss -X quit', '\$', 5)
+		else:
+			logging.error('This should not happen!')
+		mySSH.close()
+		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+
 	def DeployEpc(self, HTML):
 		logging.debug('Trying to deploy')
 		if not re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
@@ -408,7 +456,7 @@ class EPCManagement():
 			HELP.GenericHelp(CONST.Version)
 			HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type)
 			sys.exit('Insufficient EPC Parameters')
-		mySSH = SSH.SSHConnection() 
+		mySSH = SSH.SSHConnection()
 		mySSH.open(self.IPAddress, self.UserName, self.Password)
 		mySSH.command('docker-compose --version', '\$', 5)
 		result = re.search('docker-compose version 1', mySSH.getBefore())
@@ -502,7 +550,7 @@ class EPCManagement():
 		logging.debug('Trying to undeploy')
 		# No check down, we suppose everything done before.
 
-		mySSH = SSH.SSHConnection() 
+		mySSH = SSH.SSHConnection()
 		mySSH.open(self.IPAddress, self.UserName, self.Password)
 		# Recovering logs and pcap files
 		mySSH.command('cd ' + self.SourceCodePath + '/logs', '\$', 5)
@@ -546,7 +594,7 @@ class EPCManagement():
 			HTML.CreateHtmlTestRow(self.Type, 'KO', CONST.INVALID_PARAMETER)
 
 	def LogCollectHSS(self):
-		mySSH = SSH.SSHConnection() 
+		mySSH = SSH.SSHConnection()
 		mySSH.open(self.IPAddress, self.UserName, self.Password)
 		mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5)
 		mySSH.command('rm -f hss.log.zip', '\$', 5)
@@ -576,7 +624,7 @@ class EPCManagement():
 		mySSH.close()
 
 	def LogCollectMME(self):
-		mySSH = SSH.SSHConnection() 
+		mySSH = SSH.SSHConnection()
 		mySSH.open(self.IPAddress, self.UserName, self.Password)
 		mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5)
 		mySSH.command('rm -f mme.log.zip', '\$', 5)
@@ -597,13 +645,13 @@ class EPCManagement():
 			mySSH.command('echo ' + self.Password + ' | sudo -S rm mme*.log', '\$', 5)
 		elif re.match('ltebox', self.Type, re.IGNORECASE):
 			mySSH.command('cp /opt/ltebox/var/log/*Log.0 .', '\$', 5)
-			mySSH.command('zip mme.log.zip mmeLog.0 s1apcLog.0 s1apsLog.0 s11cLog.0 libLog.0 s1apCodecLog.0', '\$', 60)
+			mySSH.command('zip mme.log.zip mmeLog.0 s1apcLog.0 s1apsLog.0 s11cLog.0 libLog.0 s1apCodecLog.0 amfLog.0 ngapcLog.0 ngapcommonLog.0 ngapsLog.0', '\$', 60)
 		else:
 			logging.error('This option should not occur!')
 		mySSH.close()
 
 	def LogCollectSPGW(self):
-		mySSH = SSH.SSHConnection() 
+		mySSH = SSH.SSHConnection()
 		mySSH.open(self.IPAddress, self.UserName, self.Password)
 		mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5)
 		mySSH.command('rm -f spgw.log.zip', '\$', 5)
@@ -625,8 +673,8 @@ class EPCManagement():
 			mySSH.command('zip spgw.log.zip spgw*.log', '\$', 60)
 			mySSH.command('echo ' + self.Password + ' | sudo -S rm spgw*.log', '\$', 5)
 		elif re.match('ltebox', self.Type, re.IGNORECASE):
-			mySSH.command('cp /opt/ltebox/var/log/xGwLog.0 .', '\$', 5)
-			mySSH.command('zip spgw.log.zip xGwLog.0', '\$', 60)
+			mySSH.command('cp /opt/ltebox/var/log/*Log.0 .', '\$', 5)
+			mySSH.command('zip spgw.log.zip xGwLog.0 upfLog.0', '\$', 60)
 		else:
 			logging.error('This option should not occur!')
 		mySSH.close()
diff --git a/ci-scripts/html.py b/ci-scripts/html.py
index b3ee00e7dc5253133431803ff7f9a2f3b8d647dd..b172ffb71113b74dedbdf933545623933a85ed38 100644
--- a/ci-scripts/html.py
+++ b/ci-scripts/html.py
@@ -47,7 +47,7 @@ import constants as CONST
 class HTMLManagement():
 
 	def __init__(self):
-	
+
 		self.htmlFile = ''
 		self.htmlHeaderCreated = False
 		self.htmlFooterCreated = False
@@ -86,13 +86,13 @@ class HTMLManagement():
 #-----------------------------------------------------------
 # Setters and Getters
 #-----------------------------------------------------------
-	
+
 	def SethtmlUEConnected(self, nbUEs):
 		if nbUEs > 0:
 			self.htmlUEConnected = nbUEs
 		else:
 			self.htmlUEConnected = 1
-	
+
 
 
 #-----------------------------------------------------------
@@ -182,9 +182,12 @@ class HTMLManagement():
 				self.htmlFile.write('     </tr>\n')
 			self.htmlFile.write('  </table>\n')
 
-			if (ADBIPAddress != 'none'):
+			if (ADBIPAddress != 'none') and (ADBIPAddress != 'modules'):
 				self.htmlFile.write('  <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(self.htmlNb_Smartphones) + ' UE(s) is(are) connected to ADB bench server</h2>\n')
 				self.htmlFile.write('  <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(self.htmlNb_CATM_Modules) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n')
+			elif (ADBIPAddress == 'modules'):
+				self.htmlUEConnected = 1
+				self.htmlFile.write('  <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> 1 commercial module is connected to CI bench</h2>\n')
 			else:
 				self.htmlUEConnected = 1
 				self.htmlFile.write('  <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> 1 OAI UE(s) is(are) connected to CI bench</h2>\n')
@@ -365,6 +368,16 @@ class HTMLManagement():
 				self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - SPGW process not found</td>\n')
 			elif (processesStatus == CONST.UE_IP_ADDRESS_ISSUE):
 				self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - Could not retrieve UE IP address</td>\n')
+			elif (processesStatus == CONST.PHYSIM_IMAGE_ABSENT):
+				self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - No such image oai-physim</td>\n')
+			elif (processesStatus == CONST.OC_LOGIN_FAIL):
+				self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - Could not log onto cluster</td>\n')
+			elif (processesStatus == CONST.OC_PROJECT_FAIL):
+				self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - Could not register into cluster project</td>\n')
+			elif (processesStatus == CONST.OC_IS_FAIL):
+				self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - Could not create Image Stream</td>\n')
+			elif (processesStatus == CONST.OC_PHYSIM_DEPLOY_FAIL):
+				self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - Could not properly deploy physim on cluster</td>\n')
 			else:
 				self.htmlFile.write('        <td bgcolor = "lightcoral" >' + str(status)  + '</td>\n')
 		else:
@@ -412,7 +425,12 @@ class HTMLManagement():
 			for image in collectInfo:
 				files = collectInfo[image]
         		# TabHeader for image logs on built shared and target images
-				self.htmlFile.write('      <tr bgcolor = "#F0F0F0" >\n')
+				if allImagesSize[image].count('unknown') > 0:
+					self.htmlFile.write('      <tr bgcolor = "orange" >\n')
+				elif allImagesSize[image].count('Build Failed') > 0:
+					self.htmlFile.write('      <tr bgcolor = "red" >\n')
+				else:
+					self.htmlFile.write('      <tr bgcolor = "#F0F0F0" >\n')
 				self.htmlFile.write('        <td colspan=' + str(5+self.htmlUEConnected) + '><b> ---- ' + image  + ' IMAGE STATUS ----> Size ' + allImagesSize[image] + ' </b></td>\n')
 				self.htmlFile.write('      </tr>\n')
 				self.htmlFile.write('      <tr bgcolor = "#33CCFF" >\n')
@@ -431,21 +449,54 @@ class HTMLManagement():
 						self.htmlFile.write('        <td bgcolor = "green" >' + str(parameters['errors'])  + '</td>\n')
 					else:
 						self.htmlFile.write('        <td bgcolor = "red" >' + str(parameters['errors'])  + '</td>\n')
-					if (parameters['warnings'] == 0):
+					if (parameters['errors'] > 0):
+						self.htmlFile.write('        <td bgcolor = "red" >' + str(parameters['warnings'])  + '</td>\n')
+					elif (parameters['warnings'] == 0):
 						self.htmlFile.write('        <td bgcolor = "green" >' + str(parameters['warnings'])  + '</td>\n')
 					elif ((parameters['warnings'] > 0) and (parameters['warnings'] <= 20)):
 						self.htmlFile.write('        <td bgcolor = "orange" >' + str(parameters['warnings'])  + '</td>\n')
 					else:
-						self.htmlFile.write('        <td bgcolor = "red" >' + str(parameters['warnings'])  + '</td>\n')	
+						self.htmlFile.write('        <td bgcolor = "red" >' + str(parameters['warnings'])  + '</td>\n')
 					if (parameters['errors'] == 0) and (parameters['warnings'] == 0):
 						self.htmlFile.write('        <th colspan=' + str(1+self.htmlUEConnected) + ' bgcolor = "green" ><font color="white">OK </font></th>\n')
 					elif (parameters['errors'] == 0) and ((parameters['warnings'] > 0) and (parameters['warnings'] <= 20)):
 						self.htmlFile.write('        <th colspan=' + str(1+self.htmlUEConnected) + ' bgcolor = "orange" ><font color="white">OK </font></th>\n')
 					else:
-						self.htmlFile.write('        <th colspan=' + str(1+self.htmlUEConnected) + ' bgcolor = "red" > NOT OK  </th>\n')	
+						self.htmlFile.write('        <th colspan=' + str(1+self.htmlUEConnected) + ' bgcolor = "red" > NOT OK  </th>\n')
 					self.htmlFile.write('      </tr>\n')
 		self.htmlFile.close()
 
+	#for the moment it is limited to 4 columns, to be made generic later
+	def CreateHtmlDataLogTable(self, DataLog):
+		if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
+			return
+		self.htmlFile = open('test_results.html', 'a')
+		
+        # TabHeader 
+		self.htmlFile.write('      <tr bgcolor = "#F0F0F0" >\n')
+		self.htmlFile.write('        <td colspan=' + str(5+self.htmlUEConnected) + '><b> ---- ' + DataLog['Title'] + ' ---- </b></td>\n')
+		self.htmlFile.write('      </tr>\n')
+		self.htmlFile.write('      <tr bgcolor = "#33CCFF" >\n')
+		self.htmlFile.write('        <th colspan="3">'+ DataLog['ColNames'][0] +'</th>\n')
+		self.htmlFile.write('        <th>' + DataLog['ColNames'][1] + '</th>\n')
+		self.htmlFile.write('        <th>' + DataLog['ColNames'][2] + '</th>\n')
+		self.htmlFile.write('        <th colspan=' + str(1+self.htmlUEConnected) + '>'+ DataLog['ColNames'][3] +'</th>\n')
+		self.htmlFile.write('      </tr>\n')
+
+		for k in DataLog['Data']:
+			# TestRow 
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td colspan="3" bgcolor = "lightcyan" >' + k  + ' </td>\n')				
+			self.htmlFile.write('        <td bgcolor = "lightcyan" >' + DataLog['Data'][k][0]  + ' </td>\n')
+			self.htmlFile.write('        <td bgcolor = "lightcyan" >' + DataLog['Data'][k][1]  + ' </td>\n')
+			if float(DataLog['Data'][k][2])> DataLog['Threshold'][k]:
+				self.htmlFile.write('        <th bgcolor = "red" >' + DataLog['Data'][k][2]  + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = '   +str(DataLog['Threshold'][k])+') ' + '</th>\n')
+			else:
+				self.htmlFile.write('        <th bgcolor = "green" ><font color="white">' + DataLog['Data'][k][2]  + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = '   +str(DataLog['Threshold'][k])+') ' + '</th>\n')					
+			self.htmlFile.write('      </tr>\n')
+		self.htmlFile.close()
+
+
 	def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue):
 		if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
 			self.htmlFile = open('test_results.html', 'a')
@@ -479,3 +530,140 @@ class HTMLManagement():
 			self.htmlFile.write('      </tr>\n')
 			self.htmlFile.close()
 
+	def CreateHtmlTestRowCppCheckResults(self, CCR):
+		if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
+			return
+		self.htmlFile = open('test_results.html', 'a')
+		vId = 0
+		for version in CCR.versions:
+			self.htmlFile.write('      <tr bgcolor = "#F0F0F0" >\n')
+			self.htmlFile.write('        <td colspan=' + str(5+self.htmlUEConnected) + '><b> Results for cppcheck v ' + version + ' </b></td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td></td>\n')
+			self.htmlFile.write('        <td colspan=2 bgcolor = "lightcyan" ><b> NB ERRORS</b></td>\n')
+			if CCR.nbErrors[vId] == 0:
+				myColor = 'lightgreen'
+			elif CCR.nbErrors[vId] < 20:
+				myColor = 'orange'
+			else:
+				myColor = 'lightcoral'
+			self.htmlFile.write('        <td colspan=' + str(2+self.htmlUEConnected) + ' bgcolor = "' + myColor + '"><b>' + str(CCR.nbErrors[vId]) + '</b></td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td></td>\n')
+			self.htmlFile.write('        <td colspan=2 bgcolor = "lightcyan" ><b> NB WARNINGS</b></td>\n')
+			if CCR.nbWarnings[vId] == 0:
+				myColor = 'lightgreen'
+			elif CCR.nbWarnings[vId] < 20:
+				myColor = 'orange'
+			else:
+				myColor = 'lightcoral'
+			self.htmlFile.write('        <td colspan=' + str(2+self.htmlUEConnected) + ' bgcolor = "' + myColor + '"><b>' + str(CCR.nbWarnings[vId]) + '</b></td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr bgcolor = "#F0F0F0" >\n')
+			self.htmlFile.write('        <td colspan=' + str(5+self.htmlUEConnected) + '> ----------------- </td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td></td>\n')
+			self.htmlFile.write('        <td colspan=2 bgcolor = "lightcyan" ><b> Memory leak</b></td>\n')
+			self.htmlFile.write('        <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbMemLeaks[vId]) + '</td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td></td>\n')
+			self.htmlFile.write('        <td colspan=2 bgcolor = "lightcyan" ><b> Possible null pointer deference</b></td>\n')
+			self.htmlFile.write('        <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbNullPtrs[vId]) + '</td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td></td>\n')
+			self.htmlFile.write('        <td colspan=2 bgcolor = "lightcyan" ><b> Uninitialized variable</b></td>\n')
+			self.htmlFile.write('        <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbUninitVars[vId]) + '</td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td></td>\n')
+			self.htmlFile.write('        <td colspan=2 bgcolor = "lightcyan" ><b> Undefined behaviour shifting</b></td>\n')
+			self.htmlFile.write('        <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbTooManyBitsShift[vId]) + '</td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td></td>\n')
+			self.htmlFile.write('        <td colspan=2 bgcolor = "lightcyan" ><b> Signed integer overflow</b></td>\n')
+			self.htmlFile.write('        <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbIntegerOverflow[vId]) + '</td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr bgcolor = "#F0F0F0" >\n')
+			self.htmlFile.write('        <td colspan=' + str(5+self.htmlUEConnected) + '> </td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td></td>\n')
+			self.htmlFile.write('        <td colspan=2 bgcolor = "lightcyan" ><b> Printf formatting issues</b></td>\n')
+			self.htmlFile.write('        <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbInvalidPrintf[vId]) + '</td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td></td>\n')
+			self.htmlFile.write('        <td colspan=2 bgcolor = "lightcyan" ><b> Modulo result is predetermined</b></td>\n')
+			self.htmlFile.write('        <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbModuloAlways[vId]) + '</td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td></td>\n')
+			self.htmlFile.write('        <td colspan=2 bgcolor = "lightcyan" ><b> Opposite Condition -> dead code</b></td>\n')
+			self.htmlFile.write('        <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbOppoInnerCondition[vId]) + '</td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td></td>\n')
+			self.htmlFile.write('        <td colspan=2 bgcolor = "lightcyan" ><b> Wrong Scanf Nb Args</b></td>\n')
+			self.htmlFile.write('        <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbWrongScanfArg[vId]) + '</td>\n')
+			self.htmlFile.write('      </tr>\n')
+			vId += 1
+
+	def CreateHtmlTestRowPhySimTestResult(self, testSummary, testResult):
+		if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
+			return
+		self.htmlFile = open('test_results.html', 'a')
+		if bool(testResult) == False and bool(testSummary) == False:
+			self.htmlFile.write('      <tr bgcolor = "red" >\n')
+			self.htmlFile.write('        <td colspan=' + str(5+self.htmlUEConnected) + '><b> ----PHYSIM TESTING FAILED - Unable to recover the test logs ---- </b></td>\n')
+			self.htmlFile.write('      </tr>\n')
+		else:
+		# Tab header
+			self.htmlFile.write('      <tr bgcolor = "#F0F0F0" >\n')
+			self.htmlFile.write('        <td colspan=' + str(5+self.htmlUEConnected) + '><b> ---- PHYSIM TEST SUMMARY---- </b></td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr bgcolor = "#33CCFF" >\n')
+			self.htmlFile.write('        <th colspan="2">LogFile Name</th>\n')
+			self.htmlFile.write('        <th colspan="2">Nb Tests</th>\n')
+			self.htmlFile.write('        <th>Nb Failure</th>\n')
+			self.htmlFile.write('        <th>Nb Pass</th>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr>\n')
+			self.htmlFile.write('        <td colspan="2" bgcolor = "lightcyan" > physim_test.txt  </td>\n')
+			self.htmlFile.write('        <td colspan="2" bgcolor = "lightcyan" >' + str(testSummary['Nbtests']) + ' </td>\n')
+			if testSummary['Nbfail'] == 0:
+				self.htmlFile.write('        <td bgcolor = "lightcyan" >' + str(testSummary['Nbfail']) + ' </td>\n')
+			else:
+				self.htmlFile.write('        <td bgcolor = "red" >' + str(testSummary['Nbfail']) + ' </td>\n')
+			self.htmlFile.write('        <td gcolor = "lightcyan" >' + str(testSummary['Nbpass']) + ' </td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr bgcolor = "#F0F0F0" >\n')
+			self.htmlFile.write('        <td colspan=' + str(5+self.htmlUEConnected) + '><b> ---- PHYSIM TEST DETAIL INFO---- </b></td>\n')
+			self.htmlFile.write('      </tr>\n')
+			self.htmlFile.write('      <tr bgcolor = "#33CCFF" >\n')
+			self.htmlFile.write('        <th colspan="2">Test Name</th>\n')
+			self.htmlFile.write('        <th colspan="2">Test Description</th>\n')
+			self.htmlFile.write('        <th colspan=' + str(1+self.htmlUEConnected) + '>Result</th>\n')
+			self.htmlFile.write('      </tr>\n')
+			y = ''
+			for key, value in testResult.items():
+				x = key.split(".")
+				if x[0] != y:
+					self.htmlFile.write('      <tr bgcolor = "lightgreen" >\n')
+					self.htmlFile.write('        <td style="text-align: center;" colspan=' + str(5+self.htmlUEConnected) + '><b>"' + x[0] + '" series </b></td>\n')
+					self.htmlFile.write('      </tr>\n')
+					y = x[0]
+				self.htmlFile.write('      <tr>\n')
+				self.htmlFile.write('        <td colspan="2" bgcolor = "lightcyan" >' + key  + ' </td>\n')
+				self.htmlFile.write('        <td colspan="2" bgcolor = "lightcyan" >' + value[0]  + '</td>\n')
+				if 'PASS' in value:
+					self.htmlFile.write('        <td colspan=' + str(1+self.htmlUEConnected) + ' bgcolor = "green" >' + value[1]  + '</td>\n')
+				else:
+					self.htmlFile.write('        <td colspan=' + str(1+self.htmlUEConnected) + ' bgcolor = "red" >' + value[1]  + '</td>\n')
+
+		self.htmlFile.close()
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index 3094197c542f8bbf6a7ca90a91dff1dfe656d287..d66c0c630578310bff402a62f525ab5ebf1e059b 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -38,11 +38,13 @@ import helpreadme as HELP
 import constants as CONST
 
 
-import cls_oaicitest		#main class for OAI CI test framework
-import cls_physim           #class PhySim for physical simulators build and test
-import cls_cots_ue			#class CotsUe for Airplane mode control
-import cls_containerize     #class Containerize for all container-based operations on RAN/UE objects
-
+import cls_oaicitest            #main class for OAI CI test framework
+import cls_physim               #class PhySim for physical simulators build and test
+import cls_cots_ue              #class CotsUe for Airplane mode control
+import cls_containerize         #class Containerize for all container-based operations on RAN/UE objects
+import cls_static_code_analysis #class for static code analysis
+import cls_ci_ueinfra			#class defining the multi Ue infrastrucure
+import cls_physim1          #class PhySim for physical simulators deploy and run
 
 import sshconnection 
 import epc
@@ -63,6 +65,7 @@ import xml.etree.ElementTree as ET
 import logging
 import datetime
 import signal
+import subprocess
 from multiprocessing import Process, Lock, SimpleQueue
 logging.basicConfig(
 	level=logging.DEBUG,
@@ -150,8 +153,14 @@ def GetParametersFromXML(action):
 			RAN.eNB_serverId[RAN.eNB_instance]=eNB_serverId
 
 	elif action == 'Initialize_eNB':
+		RAN.eNB_Trace=test.findtext('eNB_Trace')
 		RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args')
 		eNB_instance=test.findtext('eNB_instance')
+		USRPIPAddress=test.findtext('USRP_IPAddress')
+		if USRPIPAddress is None:
+			RAN.USRPIPAddress=''
+		else:
+			RAN.USRPIPAddress=USRPIPAddress
 		if (eNB_instance is None):
 			RAN.eNB_instance=0
 		else:
@@ -192,13 +201,41 @@ def GetParametersFromXML(action):
 		else :
 			RAN.air_interface[RAN.eNB_instance] = 'ocp-enb'
 
+	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:
+			CiTestObj.ue_id = ue_id
+
+	elif action == 'Detach_UE':
+		ue_id = test.findtext('id')
+		if (ue_id is None):
+			CiTestObj.ue_id = ""
+		else:
+			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):
@@ -252,9 +289,20 @@ def GetParametersFromXML(action):
 	elif (action == 'Ping') or (action == 'Ping_CatM_module'):
 		CiTestObj.ping_args = test.findtext('ping_args')
 		CiTestObj.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold')
+		ue_id = test.findtext('id')
+		if (ue_id is None):
+			CiTestObj.ue_id = ""
+		else:
+			CiTestObj.ue_id = ue_id
 
 	elif action == 'Iperf':
 		CiTestObj.iperf_args = test.findtext('iperf_args')
+		ue_id = test.findtext('id')
+		if (ue_id is None):
+			CiTestObj.ue_id = ""
+		else:
+			CiTestObj.ue_id = ue_id
+		CiTestObj.iperf_direction = test.findtext('direction')#used for modules only	
 		CiTestObj.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold')
 		CiTestObj.iperf_profile = test.findtext('iperf_profile')
 		if (CiTestObj.iperf_profile is None):
@@ -325,6 +373,41 @@ def GetParametersFromXML(action):
 		if (string_field is not None):
 			CONTAINERS.yamlPath[CONTAINERS.eNB_instance] = string_field
 
+	elif action == 'DeployGenObject' or action == 'UndeployGenObject':
+		string_field=test.findtext('yaml_path')
+		if (string_field is not None):
+			CONTAINERS.yamlPath[0] = string_field
+		string_field=test.findtext('services')
+		if (string_field is not None):
+			CONTAINERS.services[0] = string_field
+		string_field=test.findtext('nb_healthy')
+		if (string_field is not None):
+			CONTAINERS.nb_healthy[0] = int(string_field)
+
+	elif action == 'PingFromContainer':
+		string_field = test.findtext('container_name')
+		if (string_field is not None):
+			CONTAINERS.pingContName = string_field
+		string_field = test.findtext('options')
+		if (string_field is not None):
+			CONTAINERS.pingOptions = string_field
+		string_field = test.findtext('loss_threshold')
+		if (string_field is not None):
+			CONTAINERS.pingLossThreshold = string_field
+
+	elif action == 'IperfFromContainer':
+		string_field = test.findtext('server_container_name')
+		if (string_field is not None):
+			CONTAINERS.svrContName = string_field
+		string_field = test.findtext('server_options')
+		if (string_field is not None):
+			CONTAINERS.svrOptions = string_field
+		string_field = test.findtext('client_container_name')
+		if (string_field is not None):
+			CONTAINERS.cliContName = string_field
+		string_field = test.findtext('client_options')
+		if (string_field is not None):
+			CONTAINERS.cliOptions = string_field
 
 	else: # ie action == 'Run_PhySim':
 		ldpc.runargs = test.findtext('physim_run_args')
@@ -369,6 +452,20 @@ with open(yaml_file,'r') as f:
 
 
 
+#loading UE infrastructure from yaml
+ue_infra_file='ci_ueinfra.yaml'
+if (os.path.isfile(ue_infra_file)):
+	yaml_file=ue_infra_file
+elif (os.path.isfile('ci-scripts/'+ue_infra_file)):
+	yaml_file='ci-scripts/'+ue_infra_file
+else:
+	logging.error("UE infrastructure yaml file cannot be found")
+	sys.exit("UE infrastructure file cannot be found")
+InfraUE=cls_ci_ueinfra.InfraUE() #initialize UE infrastructure class
+InfraUE.Get_UE_Infra(yaml_file) #read the UE infra, filename is hardcoded and unique for the moment but should be passed as parameter from the test suite
+
+
+
 mode = ''
 
 CiTestObj = cls_oaicitest.OaiCiTest()
@@ -378,17 +475,18 @@ EPC = epc.EPCManagement()
 RAN = ran.RANManagement()
 HTML = html.HTMLManagement()
 CONTAINERS = cls_containerize.Containerize()
+SCA = cls_static_code_analysis.StaticCodeAnalysis()
+PHYSIM = cls_physim1.PhySim()
 
 ldpc=cls_physim.PhySim()    #create an instance for LDPC test using GPU or CPU build
 
 
-
 #-----------------------------------------------------------
 # Parsing Command Line Arguments
 #-----------------------------------------------------------
 
 import args_parse
-py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP)
+py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA,PHYSIM)
 
 
 
@@ -417,6 +515,8 @@ if re.match('^TerminateeNB$', mode, re.IGNORECASE):
 	if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '':
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
+	if RAN.eNBIPAddress == 'none':
+		sys.exit(0)
 	RAN.eNB_instance=0
 	RAN.eNB_serverId[0]='0'
 	RAN.eNBSourceCodePath='/tmp/'
@@ -426,13 +526,13 @@ 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)
 		sys.exit('Insufficient Parameter')
 	signal.signal(signal.SIGUSR1, receive_signal)
-	CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC)
+	CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE)
 elif re.match('^TerminateHSS$', mode, re.IGNORECASE):
 	if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '':
 		HELP.GenericHelp(CONST.Version)
@@ -452,11 +552,18 @@ elif re.match('^LogCollectBuild$', mode, re.IGNORECASE):
 	if (RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '') and (CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == ''):
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
+	if RAN.eNBIPAddress == 'none':
+		sys.exit(0)
 	CiTestObj.LogCollectBuild(RAN)
 elif re.match('^LogCollecteNB$', mode, re.IGNORECASE):
 	if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '':
 		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
+	if RAN.eNBIPAddress == 'none':
+		cmd = 'zip -r enb.log.' + RAN.BuildId + '.zip cmake_targets/log'
+		logging.debug(cmd)
+		zipStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=60)
+		sys.exit(0)
 	RAN.LogCollecteNB()
 elif re.match('^LogCollectHSS$', mode, re.IGNORECASE):
 	if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '':
@@ -511,7 +618,7 @@ elif re.match('^InitiateHtml$', mode, re.IGNORECASE):
 	if foundCount != HTML.nbTestXMLfiles:
 		HTML.nbTestXMLfiles=foundCount
 	
-	if (CiTestObj.ADBIPAddress != 'none'):
+	if (CiTestObj.ADBIPAddress != 'none') and (CiTestObj.ADBIPAddress != 'modules'):
 		terminate_ue_flag = False
 		CiTestObj.GetAllUEDevices(terminate_ue_flag)
 		CiTestObj.GetAllCatMDevices(terminate_ue_flag)
@@ -602,6 +709,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 	if (EPC.IPAddress != '') and (EPC.IPAddress != 'none'):
 		CiTestObj.CheckFlexranCtrlInstallation(RAN,EPC,CONTAINERS)
 		EPC.SetMmeIPAddress()
+		EPC.SetAmfIPAddress()
 
 	#get the list of tests to be done
 	todo_tests=[]
@@ -614,10 +722,12 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 
 	signal.signal(signal.SIGUSR1, receive_signal)
 
-	if (CiTestObj.ADBIPAddress != 'none'):
+	if (CiTestObj.ADBIPAddress != 'none') and (CiTestObj.ADBIPAddress != 'modules'):
 		terminate_ue_flag = False
 		CiTestObj.GetAllUEDevices(terminate_ue_flag)
 		CiTestObj.GetAllCatMDevices(terminate_ue_flag)
+	elif (CiTestObj.ADBIPAddress == 'modules'):
+		CiTestObj.UEDevices.append('COTS-Module')
 	else:
 		CiTestObj.UEDevices.append('OAI-UE')
 	HTML.SethtmlUEConnected(len(CiTestObj.UEDevices) + len(CiTestObj.CatMDevices))
@@ -651,7 +761,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 				CiTestObj.ShowTestID()
 				GetParametersFromXML(action)
 				if action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Ping' or action == 'Iperf' or action == 'Reboot_UE' or action == 'DataDisable_UE' or action == 'DataEnable_UE' or action == 'CheckStatusUE':
-					if (CiTestObj.ADBIPAddress != 'none'):
+					if (CiTestObj.ADBIPAddress != 'none') and (CiTestObj.ADBIPAddress != 'modules'):
 						#in these cases, having no devices is critical, GetAllUEDevices function has to manage it as a critical error, reason why terminate_ue_flag is set to True
 						terminate_ue_flag = True 
 						# Now we stop properly the test-suite --> clean reporting
@@ -671,39 +781,39 @@ 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,COTS_UE)
+					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)
+					CiTestObj.AttachUE(HTML,RAN,EPC,COTS_UE,InfraUE)
 				elif action == 'Detach_UE':
-					CiTestObj.DetachUE(HTML,RAN,EPC,COTS_UE)
+					CiTestObj.DetachUE(HTML,RAN,EPC,COTS_UE,InfraUE)
 				elif action == 'DataDisable_UE':
 					CiTestObj.DataDisableUE(HTML)
 				elif action == 'DataEnable_UE':
 					CiTestObj.DataEnableUE(HTML)
 				elif action == 'CheckStatusUE':
-					CiTestObj.CheckStatusUE(HTML,RAN,EPC,COTS_UE)
+					CiTestObj.CheckStatusUE(HTML,RAN,EPC,COTS_UE,InfraUE)
 				elif action == 'Build_OAI_UE':
 					CiTestObj.BuildOAIUE(HTML)
 				elif action == 'Initialize_OAI_UE':
-					CiTestObj.InitializeOAIUE(HTML,RAN,EPC,COTS_UE)
+					CiTestObj.InitializeOAIUE(HTML,RAN,EPC,COTS_UE,InfraUE)
 				elif action == 'Terminate_OAI_UE':
-					CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC)
+					CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE)
 				elif action == 'Initialize_CatM_module':
 					CiTestObj.InitializeCatM(HTML)
 				elif action == 'Terminate_CatM_module':
 					CiTestObj.TerminateCatM(HTML)
 				elif action == 'Attach_CatM_module':
-					CiTestObj.AttachCatM(HTML,RAN,COTS_UE,EPC)
+					CiTestObj.AttachCatM(HTML,RAN,COTS_UE,EPC,InfraUE)
 				elif action == 'Detach_CatM_module':
 					CiTestObj.TerminateCatM(HTML)
 				elif action == 'Ping_CatM_module':
-					CiTestObj.PingCatM(HTML,RAN,EPC,COTS_UE,EPC)
+					CiTestObj.PingCatM(HTML,RAN,EPC,COTS_UE,EPC,InfraUE)
 				elif action == 'Ping':
-					CiTestObj.Ping(HTML,RAN,EPC,COTS_UE)
+					CiTestObj.Ping(HTML,RAN,EPC,COTS_UE, InfraUE)
 				elif action == 'Iperf':
-					CiTestObj.Iperf(HTML,RAN,EPC,COTS_UE)
+					CiTestObj.Iperf(HTML,RAN,EPC,COTS_UE, InfraUE)
 				elif action == 'Reboot_UE':
 					CiTestObj.RebootUE(HTML,RAN,EPC)
 				elif action == 'Initialize_HSS':
@@ -718,6 +828,10 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 					EPC.InitializeSPGW(HTML)
 				elif action == 'Terminate_SPGW':
 					EPC.TerminateSPGW(HTML)
+				elif action == 'Initialize_5GCN':
+					EPC.Initialize5GCN(HTML)
+				elif action == 'Terminate_5GCN':
+					EPC.Terminate5GCN(HTML)
 				elif action == 'Deploy_EPC':
 					EPC.DeployEpc(HTML)
 				elif action == 'Undeploy_EPC':
@@ -732,7 +846,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 					CiTestObj.Perform_X2_Handover(HTML,RAN,EPC)
 				elif action == 'Build_PhySim':
 					HTML=ldpc.Build_PhySim(HTML,CONST)
-					if ldpc.exitStatus==1:sys.exit()
+					if ldpc.exitStatus==1:
+						RAN.prematureExit = True
 				elif action == 'Run_PhySim':
 					HTML=ldpc.Run_PhySim(HTML,CONST,id)
 				elif action == 'Build_Image':
@@ -741,9 +856,29 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 					CONTAINERS.DeployObject(HTML, EPC)
 				elif action == 'Undeploy_Object':
 					CONTAINERS.UndeployObject(HTML, RAN)
+				elif action == 'Cppcheck_Analysis':
+					SCA.CppCheckAnalysis(HTML)
+				elif action == 'Deploy_Run_PhySim':
+					PHYSIM.Deploy_PhySim(HTML, RAN)
+				elif action == 'DeployGenObject':
+					CONTAINERS.DeployGenObject(HTML)
+					if CONTAINERS.exitStatus==1:
+						RAN.prematureExit = True
+				elif action == 'UndeployGenObject':
+					CONTAINERS.UndeployGenObject(HTML)
+					if CONTAINERS.exitStatus==1:
+						RAN.prematureExit = True
+				elif action == 'PingFromContainer':
+					CONTAINERS.PingFromContainer(HTML)
+					if CONTAINERS.exitStatus==1:
+						RAN.prematureExit = True
+				elif action == 'IperfFromContainer':
+					CONTAINERS.IperfFromContainer(HTML)
+					if CONTAINERS.exitStatus==1:
+						RAN.prematureExit = True
 				else:
 					sys.exit('Invalid class (action) from xml')
-				if not RAN.prematureExit:
+				if RAN.prematureExit:
 					if CiTestObj.testCase_id == CiTestObj.testMinStableId:
 						logging.debug('Scenario has reached minimal stability point')
 						CiTestObj.testStabilityPointReached = True
diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool
index 9b9fe462f15d07200b316cedb3b8273451b91807..5ee653c8e15768303ff5a67d505c13ce95157bb1 100755
--- a/ci-scripts/oai-ci-vm-tool
+++ b/ci-scripts/oai-ci-vm-tool
@@ -170,19 +170,20 @@ function setvar_usage {
 # for compatibility reasons  
 
 function variant__v1__enb_usrp {
-    NB_PATTERN_FILES=9
+    NB_PATTERN_FILES=7
     BUILD_OPTIONS="--eNB -w USRP --mu"
+    VM_MEMORY=3072
 }
     
 function variant__v2__basic_sim {
-    NB_PATTERN_FILES=13
+    NB_PATTERN_FILES=11
     BUILD_OPTIONS="--eNB --UE"
     VM_MEMORY=8192
     RUN_OPTIONS="complex"
 }
 
 function variant__v3__phy_sim {
-    NB_PATTERN_FILES=13
+    NB_PATTERN_FILES=11
     BUILD_OPTIONS="--phy_simulators"
     VM_MEMORY=8192
     VM_DISK=20
@@ -199,29 +200,29 @@ function variant__v4__cppcheck {
 function variant__v5__gnb_usrp {
     VM_MEMORY=10240
     VM_CPU=8
-    NB_PATTERN_FILES=9
+    NB_PATTERN_FILES=7
     BUILD_OPTIONS="--gNB -w USRP"
 }
 
 function variant__v6__nr_ue_usrp {
     VM_MEMORY=4096
     VM_CPU=4
-    NB_PATTERN_FILES=9
+    NB_PATTERN_FILES=7
     BUILD_OPTIONS="--nrUE -w USRP"
 }
 
 function variant__v7__enb_ethernet {
     VM_MEMORY=4096
     ARCHIVES_LOC=enb_eth
-    NB_PATTERN_FILES=8
-    BUILD_OPTIONS="--eNB"
+    NB_PATTERN_FILES=7
+    BUILD_OPTIONS="--eNB -w USRP"
 }
 
 function variant__v8__ue_ethernet {
     VM_MEMORY=4096
     ARCHIVES_LOC=ue_eth
-    NB_PATTERN_FILES=12
-    BUILD_OPTIONS="--UE"
+    NB_PATTERN_FILES=11
+    BUILD_OPTIONS="--UE -w USRP"
 }
 
 function variant__v10__flexran_rtc {
@@ -246,6 +247,11 @@ function variant__v22__l2_sim {
     RUN_OPTIONS="complex"
 }
 
+function variant__v23__rf5g_sim {
+    ARCHIVES_LOC=rf5g_sim
+    RUN_OPTIONS="complex"
+}
+
 # Following function lists all variant__v<n>__<variant name> functions
 # and set the VARIANTS_SHORT and VARIANTS_LONG arrays from
 # the function names
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index 774d7f19c6a4f240ca36409aa2418a8b0005c57f..5e3d8e388f8feca72c0aadbf3613554f9c90970e 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -37,6 +37,8 @@ import logging
 import os
 import time
 from multiprocessing import Process, Lock, SimpleQueue
+import yaml
+
 
 #-----------------------------------------------------------
 # OAI Testing modules
@@ -90,6 +92,9 @@ class RANManagement():
 		self.testCase_id = ''
 		self.epcPcapFile = ''
 		self.runtime_stats= ''
+		self.datalog_rt_stats={}
+		self.eNB_Trace = '' #if 'yes', Tshark will be launched at initialization
+		self.USRPIPAddress = ''
 
 
 
@@ -127,12 +132,16 @@ class RANManagement():
 		result = re.search('--eNBocp', self.Build_eNB_args)
 		if result is not None:
 			self.air_interface[self.eNB_instance] = 'ocp-enb'
-		else:	
-			result = re.search('--gNB', self.Build_eNB_args)
+		else:
+			result = re.search('--RU', self.Build_eNB_args)
 			if result is not None:
-				self.air_interface[self.eNB_instance] = 'nr-softmodem'
+				self.air_interface[self.eNB_instance] = 'oairu'
 			else:
-				self.air_interface[self.eNB_instance] = 'lte-softmodem'
+				result = re.search('--gNB', self.Build_eNB_args)
+				if result is not None:
+					self.air_interface[self.eNB_instance] = 'nr-softmodem'
+				else:
+					self.air_interface[self.eNB_instance] = 'lte-softmodem'
 		
 		# Worakround for some servers, we need to erase completely the workspace
 		if self.Build_eNB_forced_workspace_cleanup:
@@ -141,7 +150,7 @@ class RANManagement():
 		# on RedHat/CentOS .git extension is mandatory
 		result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
 		if result is not None:
-			full_ran_repo_name = self.ranRepository
+			full_ran_repo_name = self.ranRepository.replace('git/', 'git')
 		else:
 			full_ran_repo_name = self.ranRepository + '.git'
 		mySSH.command('mkdir -p ' + lSourcePath, '\$', 5)
@@ -184,7 +193,7 @@ class RANManagement():
 		mySSH.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30)
 		# if the commit ID is provided use it to point to it
 		if self.ranCommitID != '':
-			mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 5)
+			mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
 		# if the branch is not develop, then it is a merge request and we need to do 
 		# the potential merge. Note that merge conflicts should already been checked earlier
 		if (self.ranAllowMerge):
@@ -293,7 +302,7 @@ class RANManagement():
 				mySSH.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
 				mySSH.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5)
 				#-qq quiet / -u update orcreate files
-				mySSH.command('unzip -u -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5)
+				mySSH.command('unzip -o -u -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5)
 				mySSH.command('rm -f tmp_build' + testcaseId + '.zip', '\$', 5)
 				mySSH.close()
 		else:
@@ -333,10 +342,41 @@ class RANManagement():
 		self.testCase_id = HTML.testCase_id
 		mySSH = SSH.SSHConnection()
 		
+		#reboot USRP if requested in xml
+		if self.USRPIPAddress!='':
+			logging.debug('USRP '+ self.USRPIPAddress +'reboot request')
+			mySSH.open(lIpAddr, lUserName, lPassWord)
+			cmd2usrp='ssh root@'+self.USRPIPAddress+' reboot'
+			mySSH.command2(cmd2usrp,1)
+			mySSH.close()
+			logging.debug('Waiting for USRP to be ready')
+			time.sleep(120)
+
+
 		if (self.pStatus < 0):
 			HTML.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' ' + self.Initialize_eNB_args, 'KO', self.pStatus)
 			HTML.CreateHtmlTabFooter(False)
 			sys.exit(1)
+
+		#Get pcap on enb and/or gnb if enabled in the xml 
+		if self.eNB_Trace=='yes':
+			if ((self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb')):
+				pcapfile_prefix="enb_"
+			else:
+				pcapfile_prefix="gnb_"
+			mySSH.open(lIpAddr, lUserName, lPassWord)
+			mySSH.command('ip addr show | awk -f /tmp/active_net_interfaces.awk | egrep -v "lo|tun"', '\$', 5)
+			result = re.search('interfaceToUse=(?P<eth_interface>[a-zA-Z0-9\-\_]+)done', mySSH.getBefore())
+			if result is not None:
+				eth_interface = result.group('eth_interface')
+				logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + '\u001B[0m')
+				pcapfile = pcapfile_prefix + self.testCase_id + '_log.pcap'
+				mySSH.command('echo ' + lPassWord + ' | sudo -S rm -f /tmp/' + pcapfile , '\$', 5)
+				mySSH.command('echo $USER; nohup sudo -E tshark  -i ' + eth_interface + ' -w /tmp/' + pcapfile + ' 2>&1 &','\$', 5)
+			mySSH.close()
+			
+
+
 		# If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB
 		result = re.search('T_stdout', str(self.Initialize_eNB_args))
 		if (result is not None):
@@ -381,13 +421,13 @@ class RANManagement():
 		# do not reset board twice in IF4.5 case
 		result = re.search('^rru|^enb|^du.band', str(config_file))
 		if result is not None:
-			mySSH.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 60)
+			mySSH.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 90)
 			result = re.search('type: b200', mySSH.getBefore())
 			if result is not None:
 				logging.debug('Found a B2xx device --> resetting it')
 				mySSH.command('echo ' + lPassWord + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10)
 				# Reloading FGPA bin firmware
-				mySSH.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 60)
+				mySSH.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 90)
 		# Make a copy and adapt to EPC / eNB IP addresses
 		mySSH.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5)
 		localMmeIpAddr = EPC.MmeIPAddress
@@ -464,7 +504,7 @@ class RANManagement():
 				self.prematureExit = True
 				return
 			else:
-				mySSH.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Starting"', '\$', 4)
+				mySSH.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Starting|Started"', '\$', 4)
 				if rruCheck:
 					result = re.search('wait RUs', mySSH.getBefore())
 				else:
@@ -572,6 +612,10 @@ class RANManagement():
 				mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem ocp-enb || true', '\$', 5)
 				time.sleep(5)
 		mySSH.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
+		#stopping tshark (valid if eNB and enabled in xml, will not harm otherwise)
+		logging.debug('\u001B[1m Stopping tshark \u001B[0m')
+		mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
+		time.sleep(1)
 		mySSH.close()
 		# If tracer options is on, stopping tshark on EPC side
 		result = re.search('T_stdout', str(self.Initialize_eNB_args))
@@ -590,6 +634,7 @@ class RANManagement():
 			mySSH.close()
 			logging.debug('\u001B[1m Replaying RAW record file\u001B[0m')
 			mySSH.open(lIpAddr, lUserName, lPassWord)
+			mySSH.command('killall --signal SIGKILL record', '\$', 5)
 			mySSH.command('cd ' + lSourcePath + '/common/utils/T/tracer/', '\$', 5)
 			enbLogFile = self.eNBLogFiles[int(self.eNB_instance)]
 			raw_record_file = enbLogFile.replace('.log', '_record.raw')
@@ -632,6 +677,9 @@ class RANManagement():
 					HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
 			else:
 				HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
+		#display rt stats for gNB only
+		if len(self.datalog_rt_stats)!=0 and nodeB_prefix == 'g':
+			HTML.CreateHtmlDataLogTable(self.datalog_rt_stats)
 		self.eNBmbmsEnables[int(self.eNB_instance)] = False
 		self.eNBstatuses[int(self.eNB_instance)] = -1
 
@@ -640,9 +688,11 @@ class RANManagement():
 		mySSH.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
 		mySSH.command('cd ' + self.eNBSourceCodePath, '\$', 5)
 		mySSH.command('cd cmake_targets', '\$', 5)
+		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/enb_*.pcap .','\$',20)
+		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/gnb_*.pcap .','\$',20)
 		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5)
-		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap enb_*txt physim_*.log', '\$', 60)
-		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 5)
+		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log', '\$', 60)
+		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log', '\$', 5)
 		mySSH.close()
 
 	def AnalyzeLogFile_eNB(self, eNBlogFile, HTML):
@@ -693,12 +743,32 @@ class RANManagement():
 		NSA_RAPROC_PUSCH_check = 0
 		#dlsch and ulsch statistics (dictionary)
 		dlsch_ulsch_stats = {}
-		#count "L1 thread not ready" msg 	
-		L1_thread_not_ready_cnt = 0
+		#real time statistics (dictionary)
+		real_time_stats = {}
 		#count "problem receiving samples" msg
 		pb_receiving_samples_cnt = 0
+		#count "removing UE" msg
+		removing_ue = 0
+		#NSA specific log markers
+		nsa_markers ={'SgNBReleaseRequestAcknowledge': [],'FAILURE': [], 'scgFailureInformationNR-r15': [], 'SgNBReleaseRequest': []}
 	
+		#the datalog config file has to be loaded
+		datalog_rt_stats_file='datalog_rt_stats.yaml'
+		if (os.path.isfile(datalog_rt_stats_file)):
+			yaml_file=datalog_rt_stats_file
+		elif (os.path.isfile('ci-scripts/'+datalog_rt_stats_file)):
+			yaml_file='ci-scripts/'+datalog_rt_stats_file
+		else:
+			logging.error("Datalog RT stats yaml file cannot be found")
+			sys.exit("Datalog RT stats yaml file cannot be found")
+
+		with open(yaml_file,'r') as f:
+			datalog_rt_stats = yaml.load(f,Loader=yaml.FullLoader)
+		rt_keys = datalog_rt_stats['Ref'] #we use the keys from the Ref field  
+
+		line_cnt=0 #log file line counter
 		for line in enb_log_file.readlines():
+			line_cnt+=1
 			# Runtime statistics
 			result = re.search('Run time:' ,str(line))
 			if result is not None:
@@ -856,20 +926,36 @@ class RANManagement():
 			#keys below are the markers we are loooking for, loop over this keys list
 			#everytime these markers are found in the log file, the previous ones are overwritten in the dict
 			#eventually we record and print only the last occurence 
-			keys = {'dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled'}
+			keys = {'UE ID','dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled'}
 			for k in keys:
 				result = re.search(k, line)
 				if result is not None:
 					#remove 1- all useless char before relevant info (ulsch or dlsch) 2- trailing char
 					dlsch_ulsch_stats[k]=re.sub(r'^.*\]\s+', r'' , line.rstrip())
-			#count "L1 thread not ready" msg
-			result = re.search('\[PHY\]\s+L1_thread isn\'t ready', str(line))
-			if result is not None:
-				L1_thread_not_ready_cnt += 1	
+			#real time statistics for gNB
+			for k in rt_keys:
+				result = re.search(k, line)     
+				if result is not None:
+					#remove 1- all useless char before relevant info  2- trailing char
+					line=line.replace('[0m','')
+					tmp=re.match(rf'^.*?(\b{k}\b.*)',line.rstrip()) #from python 3.6 we can use literal string interpolation for the variable k, using rf' in the regex
+					if tmp!=None: #with ULULULUULULULLLL at the head of the line, we skip it
+						real_time_stats[k]=tmp.group(1)
+
 			#count "problem receiving samples" msg
 			result = re.search('\[PHY\]\s+problem receiving samples', str(line))
 			if result is not None:
-				pb_receiving_samples_cnt += 1				
+				pb_receiving_samples_cnt += 1
+			#count "Removing UE" msg
+			result = re.search('\[MAC\]\s+Removing UE', str(line))
+			if result is not None:
+				removing_ue += 1
+
+			#nsa markers logging
+			for k in nsa_markers:
+				result = re.search(k, line)
+				if result is not None:
+					nsa_markers[k].append(line_cnt)					
 
 		enb_log_file.close()
 		logging.debug('   File analysis completed')
@@ -878,7 +964,7 @@ class RANManagement():
 		else:
 			nodeB_prefix = 'g'
 
-		if self.air_interface[self.eNB_instance] == 'nr-softmodem':
+		if nodeB_prefix == 'g':
 			if ulschReceiveOK > 0:
 				statMsg = nodeB_prefix + 'NB showed ' + str(ulschReceiveOK) + ' "ULSCH received ok" message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
@@ -896,17 +982,28 @@ class RANManagement():
 				statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : PASS '
 				htmlMsg = statMsg+'\n'
 			else:
-				statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : FAIL '
+				statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : FAIL or not relevant'
 				htmlMsg = statMsg+'\n'
 			logging.debug(statMsg)
 			htmleNBFailureMsg += htmlMsg
-			#L1 thread not ready log
-			statMsg = '[PHY] L1 thread is not ready msg count =  '+str(L1_thread_not_ready_cnt)
+			#problem receiving samples log
+			statMsg = '[PHY] problem receiving samples msg count =  '+str(pb_receiving_samples_cnt)
 			htmlMsg = statMsg+'\n'
 			logging.debug(statMsg)
 			htmleNBFailureMsg += htmlMsg
-			#problem receiving samples log
-			statMsg = '[PHY] problem receiving samples msg count =  '+str(pb_receiving_samples_cnt)
+			#nsa markers
+			statMsg = 'logfile line count = ' + str(line_cnt)			
+			htmlMsg = statMsg+'\n'
+			logging.debug(statMsg)
+			htmleNBFailureMsg += htmlMsg
+			if len(nsa_markers['SgNBReleaseRequestAcknowledge'])!=0:
+				statMsg = 'SgNBReleaseRequestAcknowledge = ' + str(len(nsa_markers['SgNBReleaseRequestAcknowledge'])) + ' occurences , starting line ' + str(nsa_markers['SgNBReleaseRequestAcknowledge'][0])
+			else:
+				statMsg = 'SgNBReleaseRequestAcknowledge = ' + str(len(nsa_markers['SgNBReleaseRequestAcknowledge'])) + ' occurences' 
+			htmlMsg = statMsg+'\n'
+			logging.debug(statMsg)
+			htmleNBFailureMsg += htmlMsg
+			statMsg = 'FAILURE = ' + str(len(nsa_markers['FAILURE'])) + ' occurences'
 			htmlMsg = statMsg+'\n'
 			logging.debug(statMsg)
 			htmleNBFailureMsg += htmlMsg
@@ -919,6 +1016,52 @@ class RANManagement():
 					logging.debug(dlsch_ulsch_stats[key])
 				htmleNBFailureMsg += statMsg
 
+			#real time statistics
+			datalog_rt_stats['Data']={}
+			if len(real_time_stats)!=0: #check if dictionary is not empty
+				for k in real_time_stats:
+					tmp=re.match(r'^(?P<metric>.*):\s+(?P<avg>\d+\.\d+) us;\s+\d+;\s+(?P<max>\d+\.\d+) us;',real_time_stats[k])
+					if tmp is not None:
+						metric=tmp.group('metric')
+						avg=float(tmp.group('avg'))
+						max=float(tmp.group('max'))
+						datalog_rt_stats['Data'][metric]=["{:.0f}".format(avg),"{:.0f}".format(max),"{:.2f}".format(avg/datalog_rt_stats['Ref'][metric])]
+				#once all metrics are collected, store the data as a class attribute to build a dedicated HTML table afterward
+				self.datalog_rt_stats=datalog_rt_stats
+				#check if there is a fail => will render the test as failed
+				for k in datalog_rt_stats['Data']:
+					if float(datalog_rt_stats['Data'][k][2])> datalog_rt_stats['Threshold'][k]: #condition for fail : avg/ref is greater than the fixed threshold
+						#setting prematureExit is ok although not the best option
+						self.prematureExit=True
+			else:
+				statMsg = 'No real time stats found in the log file\n'
+				logging.debug('No real time stats found in the log file')
+				htmleNBFailureMsg += statMsg
+
+		else:
+			#Removing UE log
+			statMsg = '[MAC] Removing UE msg count =  '+str(removing_ue)
+			htmlMsg = statMsg+'\n'
+			logging.debug(statMsg)
+			htmleNBFailureMsg += htmlMsg
+			#nsa markers
+			statMsg = 'logfile line count = ' + str(line_cnt)			
+			htmlMsg = statMsg+'\n'
+			logging.debug(statMsg)
+			htmleNBFailureMsg += htmlMsg
+			if len(nsa_markers['SgNBReleaseRequest'])!=0:
+				statMsg = 'SgNBReleaseRequest = ' + str(len(nsa_markers['SgNBReleaseRequest'])) + ' occurences , starting line ' + str(nsa_markers['SgNBReleaseRequest'][0])
+			else:
+				statMsg = 'SgNBReleaseRequest = ' + str(len(nsa_markers['SgNBReleaseRequest'])) + ' occurences'
+			htmlMsg = statMsg+'\n'
+			logging.debug(statMsg)
+			htmleNBFailureMsg += htmlMsg
+			statMsg = 'scgFailureInformationNR-r15 = ' + str(len(nsa_markers['scgFailureInformationNR-r15'])) + ' occurences'
+			htmlMsg = statMsg+'\n'
+			logging.debug(statMsg)
+			htmleNBFailureMsg += htmlMsg			
+
+
 		if uciStatMsgCount > 0:
 			statMsg = nodeB_prefix + 'NB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
diff --git a/ci-scripts/ran_dashboard.py b/ci-scripts/ran_dashboard.py
new file mode 100644
index 0000000000000000000000000000000000000000..4f18638e682c7cf6fd8fd31f4afe28d9d9ed189d
--- /dev/null
+++ b/ci-scripts/ran_dashboard.py
@@ -0,0 +1,299 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+# Merge Requests Dashboard for RAN on googleSheet 
+#
+#   Required Python Version
+#     Python 3.x
+#
+#---------------------------------------------------------------------
+
+#-----------------------------------------------------------
+# Import
+#-----------------------------------------------------------
+
+#import google spreadsheet API
+import gspread
+from oauth2client.service_account import ServiceAccountCredentials
+
+
+import subprocess
+import shlex      #lexical analysis
+import json       #json structures
+import datetime   #now() and date formating
+from datetime import datetime
+import re
+import gitlab
+
+#-----------------------------------------------------------
+# Class Declaration
+#-----------------------------------------------------------
+
+class gDashboard:
+    def __init__(self, creds_file, spreadsheet, worksheet): #"creds.json", 'OAI RAN Dashboard', 'MR Status'
+        self.scope = ["https://spreadsheets.google.com/feeds",'https://www.googleapis.com/auth/spreadsheets',"https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/drive"]
+        self.creds = ServiceAccountCredentials.from_json_keyfile_name(creds_file, self.scope)
+        self.client = gspread.authorize(self.creds)
+        #spreadsheet
+        self.ss = self.client.open(spreadsheet)
+        #worksheet
+        self.sheet = self.ss.worksheet(worksheet)
+        self.ss.del_worksheet(self.sheet) #start by deleting the old sheet
+        self.sheet = self.ss.add_worksheet(title=worksheet, rows="100", cols="20") #create a new one
+        
+        self.d = {} #data dictionary
+
+
+    def fetchData(self,cmd):
+        #cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """
+        process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
+        output = process.stdout.readline()
+        tmp=output.decode("utf-8") 
+        self.d = json.loads(tmp)
+
+
+    def gBuild(self, destinationSheetName):
+
+        #line 1 : update date/time, format dd/mm/YY H:M:S
+        now = datetime.now()
+        dt_string = "Update : " + now.strftime("%d/%m/%Y %H:%M")	
+        row =[dt_string]
+        self.sheet.insert_row(row, index=1, value_input_option='RAW')
+
+        #line 2 empty
+        #line 3 is for the column names
+        i=3
+        row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","Review Form","OK MERGE","Merge conflicts"]
+        self.sheet.insert_row(row, index=i, value_input_option='RAW')
+
+        #line 4 onward, MR data lines
+        for x in range(len(self.d)):
+            i=i+1                        
+            date_time_str = self.d[x]['created_at']
+            date_time_obj = datetime.strptime(date_time_str, '%Y-%m-%dT%H:%M:%S.%fZ')
+    
+            milestone1=milestone2=milestone3=milestone4=""
+            if self.d[x]['milestone']!=None:
+                if self.d[x]['milestone']['title']=="REVIEW_CAN_START":
+                    milestone1="X"
+                elif self.d[x]['milestone']['title']=="REVIEW_IN_PROGRESS":
+                    milestone2="X"
+                elif self.d[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED":
+                    milestone3="X"
+                elif self.d[x]['milestone']['title']=="OK_TO_BE_MERGED": 
+                    milestone4="X" 
+                else:
+                    pass
+            else:
+                pass
+
+            #check if empty or not
+            if self.d[x]['assignee']!=None:
+                assignee = str(self.d[x]['assignee']['name'])
+            else:
+                assignee = ""
+ 
+            #check if empty or not       
+            if len(self.d[x]['reviewers'])!=0:
+                reviewer = str(self.d[x]['reviewers'][0]['name'])
+            else:
+                reviewer = ""
+
+            if self.d[x]['has_conflicts']==True:
+                conflicts = "YES"
+            else:
+                conflicts = ""
+
+
+            #add a column flagging that the review form is present
+            #we use gitlab API to parse the MR notes
+            gl = gitlab.Gitlab.from_config('OAI')
+            project_id = 223
+            project = gl.projects.get(project_id)
+            #get the opened MR in the project
+            mrs = project.mergerequests.list(state='opened')
+            for m in range (0,len(mrs)):
+                if mrs[m].iid==self.d[x]['iid']:#check the iid is the one we are on
+                    mr_notes = mrs[m].notes.list(all=True)
+                    n=0
+                    found=False
+                    review_form=""
+                    while found==False and n<len(mr_notes):
+                        res=re.search('Code Review by',mr_notes[n].body)#this is the marker we are looking for in all notes
+                        if res!=None:
+                            review_form = "X"
+                            found=True
+                        n+=1
+
+
+            #build final row to be inserted, the first column is left empty for now, will be filled afterward with hyperlinks to gitlab MR
+            row =["", str(date_time_obj.date()),str(self.d[x]['author']['name']),str(self.d[x]['title']),\
+            assignee, reviewer,\
+            milestone1,milestone2,milestone3,review_form,milestone4,conflicts]
+            
+            #insert the row to worksheet
+            self.sheet.insert_row(row, index=i, value_input_option='RAW')
+        
+        
+        #add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas) 
+        i=3
+        requests=[]
+        for x in range(len(self.d)):              
+            rowIndex=i
+            colIndex=0
+            hyperlink= '\"'+"https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/"+ str(self.d[x]['iid']) +'\"'
+            text= '\"'+str(self.d[x]['iid'])+'"'
+            requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex))
+            i=i+1
+        body = {"requests": requests}    
+        self.ss.batch_update(body)        
+            
+
+    
+    def addHyperlink(self, hyperlink, text, destinationSheetName, rowIndex, colIndex):
+        sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
+        request =\
+                {
+                "updateCells": {
+                        "rows": [
+                            {
+                            "values": [
+                                {
+                                "userEnteredValue": {
+                                "formulaValue":"=HYPERLINK({},{})".format(hyperlink, text) 
+                                }
+                                }
+                            ]
+                            }
+                        ],
+                        "fields": "userEnteredValue",
+                        "start": {
+                            "sheetId": sheetId,
+                            "rowIndex": rowIndex,
+                            "columnIndex": colIndex
+                        }
+                }
+              }
+        return request
+
+
+    
+    def gFormat(self,sourceSheetName,destinationSheetName):  # "Formating" , "MR Status"
+        #the requests are appended in a list of requests to be sent as one update batch; this to save API calls (quotas) 
+        #copy formating template
+        sourceSheetId = self.ss.worksheet(sourceSheetName)._properties['sheetId']
+        destinationSheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
+        requests=[]
+        requests.append(
+                {
+                    "copyPaste": {
+                        "source": {
+                            "sheetId": sourceSheetId,
+                            "startRowIndex": 0,
+                            "endRowIndex": 40,
+                            "startColumnIndex": 0,
+                            "endColumnIndex": 12
+                        },
+                        "destination": {
+                            "sheetId": destinationSheetId,
+                            "startRowIndex": 0,
+                            "endRowIndex": 40,
+                            "startColumnIndex": 0,
+                            "endColumnIndex": 12
+                        },
+                        "pasteType": "PASTE_FORMAT"
+                    }
+                }
+        )
+        
+
+        #resize columns fit to data, except col 0
+        sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
+        requests.append(
+                {
+                'autoResizeDimensions': {
+                    'dimensions': {
+                        'sheetId': sheetId, 
+                        'dimension': 'COLUMNS', 
+                        'startIndex': 1, 
+                        'endIndex': 12
+                        }
+                    }
+                }   
+        )
+
+
+        #resize col 0					
+        sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
+        requests.append(
+                {
+                    "updateDimensionProperties": {
+                        "range": {
+                            "sheetId": sheetId,
+                            "dimension": "COLUMNS",
+                            "startIndex": 0,
+                            "endIndex": 1
+                        },
+                        "properties": {
+                            "pixelSize": 100
+                        },
+                        "fields": "pixelSize"
+                    }
+                }
+        )
+
+
+        #resize milestones to be cleaner
+        sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
+        requests.append(
+                {
+                    "updateDimensionProperties": {
+                        "range": {
+                            "sheetId": sheetId,
+                            "dimension": "COLUMNS",
+                            "startIndex": 6,
+                            "endIndex": 11
+                        },
+                        "properties": {
+                            "pixelSize": 120
+                        },
+                        "fields": "pixelSize"
+                    }
+                }
+        )
+    
+        body = {"requests": requests}    
+        self.ss.batch_update(body)
+  
+
+
+def main():
+    my_gDashboard=gDashboard("/home/oaicicd/remi/creds.json", 'OAI RAN Dashboard', 'MR Status')
+    cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """ 
+    my_gDashboard.fetchData(cmd)
+    my_gDashboard.gBuild("MR Status")
+    my_gDashboard.gFormat("Formating" , "MR Status")
+
+      
+        
+if __name__ == "__main__":
+    # execute only if run as a script
+    main()      
diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh
index 44d200c3b6419b1c0fe354fdb33db882c9bcb1f2..8b6db9261a57945d5c2621d7ef5a7229dddb83f6 100755
--- a/ci-scripts/reportBuildLocally.sh
+++ b/ci-scripts/reportBuildLocally.sh
@@ -568,28 +568,28 @@ function report_build {
 
     echo "   <h2>Ubuntu 16.04 LTS -- Summary</h2>" >> ./build_results.html
 
-    sca_summary_table_header ./archives/cppcheck/cppcheck.xml "OAI Static Code Analysis with CPPCHECK"
-    sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized variable" uninitvar
-    sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized struct member" uninitStructMember
-    sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory leak" memleak
-    sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory is freed twice" doubleFree
-    sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Resource leak" resourceLeak
-    sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Possible null pointer dereference" nullPointer
-    sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Array access  out of bounds" arrayIndexOutOfBounds
-    sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Buffer is accessed out of bounds" bufferAccessOutOfBounds
-    sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder
-    sca_summary_table_footer ./archives/cppcheck/cppcheck.xml
+    summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_eth
+    summary_table_row "LTE SoftModem - Release 15" ./archives/enb_eth/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_eth_row1.html
+    summary_table_row "Coding - Release 15" ./archives/enb_eth/coding.Rel15.txt "Built target coding" ./enb_eth_row2.html
+    summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_eth_row3.html
+    summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_eth_row4.html
+    summary_table_row "RF Simulator - Release 15" ./archives/enb_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_eth_row5.html
+    summary_table_row "TCP OAI Bridge - Release 15" ./archives/enb_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_eth_row6.html
+    summary_table_row "OAI USRP device if - Release 15" ./archives/enb_eth/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_eth_row7.html
+    summary_table_footer
 
-    summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_usrp
-    summary_table_row "LTE SoftModem - Release 15" ./archives/enb_usrp/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_row1.html
-    summary_table_row "Coding - Release 15" ./archives/enb_usrp/coding.Rel15.txt "Built target coding" ./enb_usrp_row2.html
-    summary_table_row "OAI USRP device if - Release 15" ./archives/enb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html
-    summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_usrp_row4.html
-    summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_usrp_row5.html
-    summary_table_row "NASMESH - Release 15" ./archives/enb_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./enb_usrp_row6.html
-    summary_table_row "RB Tool - Release 15" ./archives/enb_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./enb_usrp_row7.html
-    summary_table_row "RF Simulator - Release 15" ./archives/enb_usrp/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_usrp_row8.html
-    summary_table_row "TCP Bridge - Release 15" ./archives/enb_usrp/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_usrp_row9.html
+    summary_table_header "OAI Build: 4G LTE UE -- USRP option" ./archives/ue_eth
+    summary_table_row "LTE UE SoftModem - Release 15" ./archives/ue_eth/lte-uesoftmodem.Rel15.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html
+    summary_table_row "Coding - Release 15" ./archives/ue_eth/coding.Rel15.txt "Built target coding" ./ue_eth_row2.html
+    summary_table_row "OAI ETHERNET transport - Release 15" ./archives/ue_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./ue_eth_row3.html
+    summary_table_row "Parameters Lib Config - Release 15" ./archives/ue_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./ue_eth_row4.html
+    summary_table_row "RF Simulator - Release 15" ./archives/ue_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./ue_eth_row5.html
+    summary_table_row "TCP OAI Bridge - Release 15" ./archives/ue_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./ue_eth_row6.html
+    summary_table_row "Conf 2 UE Data - Release 15" ./archives/ue_eth/conf2uedata.Rel15.txt "Built target conf2uedata" ./ue_eth_row7.html
+    summary_table_row "NVRAM - Release 15" ./archives/ue_eth/nvram.Rel15.txt "Built target nvram" ./ue_eth_row8.html
+    summary_table_row "UE IP - Release 15" ./archives/ue_eth/ue_ip.Rel15.txt "Built target ue_ip" ./ue_eth_row9.html
+    summary_table_row "USIM - Release 15" ./archives/ue_eth/usim.Rel15.txt "Built target usim" ./ue_eth_row9a.html
+    summary_table_row "OAI USRP device if - Release 15" ./archives/ue_eth/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./ue_eth_row9b.html
     summary_table_footer
 
     summary_table_header "OAI Build: 4G LTE basic simulator option" ./archives/basic_sim
@@ -598,9 +598,7 @@ function report_build {
     summary_table_row "Coding - Release 15" ./archives/basic_sim/coding.Rel15.txt "Built target coding" ./basic_sim_row3.html
     summary_table_row "Conf 2 UE data - Release 15" ./archives/basic_sim/conf2uedata.Rel15.txt "Built target conf2uedata" ./basic_sim_row4.html
     summary_table_row "OAI ETHERNET transport - Release 15" ./archives/basic_sim/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./basic_sim_row5.html
-    summary_table_row "NASMESH - Release 15" ./archives/basic_sim/nasmesh.Rel15.txt "Built target nasmesh" ./basic_sim_row6.html
     summary_table_row "Parameters Lib Config - Release 15" ./archives/basic_sim/params_libconfig.Rel15.txt "Built target params_libconfig" ./basic_sim_row7.html
-    summary_table_row "RB Tool - Release 15" ./archives/basic_sim/rb_tool.Rel15.txt "Built target rb_tool" ./basic_sim_row8.html
     summary_table_row "RF Simulator - Release 15" ./archives/basic_sim/rfsimulator.Rel15.txt "Built target rfsimulator" ./basic_sim_row9.html
     summary_table_row "TCP Bridge - Release 15" ./archives/basic_sim/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./basic_sim_row10.html
     summary_table_row "UE IP - Release 15" ./archives/basic_sim/ue_ip.Rel15.txt "Built target ue_ip" ./basic_sim_row11.html
@@ -608,48 +606,6 @@ function report_build {
     summary_table_row "NVRAM - Release 15" ./archives/basic_sim/nvram.Rel15.txt "Built target nvram" ./basic_sim_row13.html
     summary_table_footer
 
-    summary_table_header "OAI Build: 4G LTE / 5G NR Physical simulators option" ./archives/phy_sim
-    summary_table_row "LTE DL Simulator - Release 15" ./archives/phy_sim/dlsim.Rel15.txt "Built target dlsim" ./phy_sim_row1.html
-    summary_table_row "LTE UL Simulator - Release 15" ./archives/phy_sim/ulsim.Rel15.txt "Built target ulsim" ./phy_sim_row2.html
-    summary_table_row "Coding - Release 15" ./archives/phy_sim/coding.Rel15.txt "Built target coding" ./phy_sim_row3.html
-    if [ -f ./archives/phy_sim/ldpctest.Rel15.txt ]
-    then
-        summary_table_row "NR LDPC Test - Release 15" ./archives/phy_sim/ldpctest.Rel15.txt "Built target ldpctest" ./phy_sim_row4.html
-    fi
-    if [ -f ./archives/phy_sim/polartest.Rel15.txt ]
-    then
-        summary_table_row "NR Polar Test - Release 15" ./archives/phy_sim/polartest.Rel15.txt "Built target polartest" ./phy_sim_row5.html
-    fi
-    if [ -f ./archives/phy_sim/nr_pbchsim.Rel15.txt ]
-    then
-        summary_table_row "NR PBCH Test - Release 15" ./archives/phy_sim/nr_pbchsim.Rel15.txt "Built target nr_pbchsim" ./phy_sim_row6.html
-    fi
-    if [ -f ./archives/phy_sim/nr_dlschsim.Rel15.txt ]
-    then
-        summary_table_row "NR DLSCH Test - Release 15" ./archives/phy_sim/nr_dlschsim.Rel15.txt "Built target nr_dlschsim" ./phy_sim_row7.html
-    fi
-    if [ -f ./archives/phy_sim/nr_pucchsim.Rel15.txt ]
-    then
-        summary_table_row "NR PUCCH Test - Release 15" ./archives/phy_sim/nr_pucchsim.Rel15.txt "Built target nr_pucchsim" ./phy_sim_row8.html
-    fi
-    if [ -f ./archives/phy_sim/smallblocktest.Rel15.txt ]
-    then
-        summary_table_row "NR Small Block Test - Release 15" ./archives/phy_sim/smallblocktest.Rel15.txt "Built target smallblocktest" ./phy_sim_row9.html
-    fi
-    if [ -f ./archives/phy_sim/nr_dlsim.Rel15.txt ]
-    then
-        summary_table_row "NR DL Sim Test - Release 15" ./archives/phy_sim/nr_dlsim.Rel15.txt "Built target nr_dlsim" ./phy_sim_row10.html
-    fi
-    if [ -f ./archives/phy_sim/nr_ulschsim.Rel15.txt ]
-    then
-        summary_table_row "NR ULSCH Test - Release 15" ./archives/phy_sim/nr_ulschsim.Rel15.txt "Built target nr_ulschsim" ./phy_sim_row11.html
-    fi
-    if [ -f ./archives/phy_sim/nr_ulsim.Rel15.txt ]
-    then
-        summary_table_row "NR UL Sim Test - Release 15" ./archives/phy_sim/nr_ulsim.Rel15.txt "Built target nr_ulsim" ./phy_sim_row12.html
-    fi
-    summary_table_footer
-
     if [ -f archives/gnb_usrp/nr-softmodem.Rel15.txt ]
     then
         summary_table_header "OAI Build: 5G NR gNB -- USRP option" ./archives/gnb_usrp
@@ -657,9 +613,7 @@ function report_build {
         summary_table_row "Coding - Release 15" ./archives/gnb_usrp/coding.Rel15.txt "Built target coding" ./gnb_usrp_row2.html
         summary_table_row "OAI USRP device if - Release 15" ./archives/gnb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./gnb_usrp_row3.html
         summary_table_row "OAI ETHERNET transport - Release 15" ./archives/gnb_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./gnb_usrp_row4.html
-        summary_table_row "NASMESH - Release 15" ./archives/gnb_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./gnb_usrp_row5.html
         summary_table_row "Parameters Lib Config - Release 15" ./archives/gnb_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./gnb_usrp_row6.html
-        summary_table_row "RB Tool - Release 15" ./archives/gnb_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./gnb_usrp_row7.html
         summary_table_footer
     fi
 
@@ -670,34 +624,10 @@ function report_build {
         summary_table_row "Coding - Release 15" ./archives/nr_ue_usrp/coding.Rel15.txt "Built target coding" ./nr_ue_usrp_row2.html
         summary_table_row "OAI USRP device if - Release 15" ./archives/nr_ue_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./nr_ue_usrp_row3.html
         summary_table_row "OAI ETHERNET transport - Release 15" ./archives/nr_ue_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./nr_ue_usrp_row4.html
-        summary_table_row "NASMESH - Release 15" ./archives/nr_ue_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./nr_ue_usrp_row5.html
         summary_table_row "Parameters Lib Config - Release 15" ./archives/nr_ue_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./nr_ue_usrp_row6.html
-        summary_table_row "RB Tool - Release 15" ./archives/nr_ue_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./nr_ue_usrp_row7.html
         summary_table_footer
     fi
 
-    summary_table_header "OAI Build: 4G LTE eNB -- ETHERNET transport option" ./archives/enb_eth
-    summary_table_row "LTE SoftModem - Release 15" ./archives/enb_eth/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_eth_row1.html
-    summary_table_row "Coding - Release 15" ./archives/enb_eth/coding.Rel15.txt "Built target coding" ./enb_eth_row2.html
-    summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_eth_row3.html
-    summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_eth_row4.html
-    summary_table_row "RF Simulator - Release 15" ./archives/enb_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_eth_row5.html
-    summary_table_row "TCP OAI Bridge - Release 15" ./archives/enb_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_eth_row6.html
-    summary_table_footer
-
-    summary_table_header "OAI Build: 4G LTE UE -- ETHERNET transport option" ./archives/ue_eth
-    summary_table_row "LTE UE SoftModem - Release 15" ./archives/ue_eth/lte-uesoftmodem.Rel15.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html
-    summary_table_row "Coding - Release 15" ./archives/ue_eth/coding.Rel15.txt "Built target coding" ./ue_eth_row2.html
-    summary_table_row "OAI ETHERNET transport - Release 15" ./archives/ue_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./ue_eth_row3.html
-    summary_table_row "Parameters Lib Config - Release 15" ./archives/ue_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./ue_eth_row4.html
-    summary_table_row "RF Simulator - Release 15" ./archives/ue_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./ue_eth_row5.html
-    summary_table_row "TCP OAI Bridge - Release 15" ./archives/ue_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./ue_eth_row6.html
-    summary_table_row "Conf 2 UE Data - Release 15" ./archives/ue_eth/conf2uedata.Rel15.txt "Built target conf2uedata" ./ue_eth_row7.html
-    summary_table_row "NVRAM - Release 15" ./archives/ue_eth/nvram.Rel15.txt "Built target nvram" ./ue_eth_row8.html
-    summary_table_row "UE IP - Release 15" ./archives/ue_eth/ue_ip.Rel15.txt "Built target ue_ip" ./ue_eth_row9.html
-    summary_table_row "USIM - Release 15" ./archives/ue_eth/usim.Rel15.txt "Built target usim" ./ue_eth_row9a.html
-    summary_table_footer
-
     if [ -e ./archives/red_hat ]
     then
         echo "   <h2>Red Hat Enterprise Linux Server release 7.6) -- Summary</h2>" >> ./build_results.html
@@ -714,23 +644,23 @@ function report_build {
     echo "   <button data-toggle=\"collapse\" data-target=\"#oai-compilation-details\">Details for Compilation Errors and Warnings </button>" >> ./build_results.html
     echo "   <div id=\"oai-compilation-details\" class=\"collapse\">" >> ./build_results.html
 
-    if [ -f ./enb_usrp_row1.html ] || [ -f ./enb_usrp_row2.html ] || [ -f ./enb_usrp_row3.html ] || [ -f ./enb_usrp_row4.html ]
+    if [ -f ./enb_eth_row1.html ] || [ -f ./enb_eth_row2.html ] || [ -f ./enb_eth_row3.html ] || [ -f ./enb_eth_row4.html ] || [ -f ./enb_eth_row5.html ] || [ -f ./enb_eth_row6.html ] || [ -f ./enb_eth_row7.html ]
     then
-        for DETAILS_TABLE in `ls ./enb_usrp_row*.html`
+        for DETAILS_TABLE in `ls ./enb_eth_row*.html`
         do
             cat $DETAILS_TABLE >> ./build_results.html
         done
     fi
-    if [ -f ./basic_sim_row1.html ] || [ -f ./basic_sim_row2.html ] || [ -f ./basic_sim_row3.html ] || [ -f ./basic_sim_row4.html ] || [ -f ./basic_sim_row5.html ]
+    if [ -f ./ue_eth_row1.html ] || [ -f ./ue_eth_row2.html ] || [ -f ./ue_eth_row3.html ] || [ -f ./ue_eth_row4.html ] || [ -f ./ue_eth_row5.html ] || [ -f ./ue_eth_row6.html ] || [ -f ./ue_eth_row7.html ] || [ -f ./ue_eth_row8.html ] || [ -f ./ue_eth_row9.html ] || [ -f ./ue_eth_row9a.html ] || [ -f ./ue_eth_row9b.html ]
     then
-        for DETAILS_TABLE in `ls ./basic_sim_row*.html`
+        for DETAILS_TABLE in `ls ./ue_eth_row*.html`
         do
             cat $DETAILS_TABLE >> ./build_results.html
         done
     fi
-    if [ -f ./phy_sim_row1.html ] || [ -f ./phy_sim_row2.html ] || [ -f ./phy_sim_row3.html ] || [ -f ./phy_sim_row4.html ] || [ -f ./phy_sim_row5.html ] || [ -f ./phy_sim_row6.html ] || [ -f ./phy_sim_row7.html ] || [ -f ./phy_sim_row8.html ]
+    if [ -f ./basic_sim_row1.html ] || [ -f ./basic_sim_row2.html ] || [ -f ./basic_sim_row3.html ] || [ -f ./basic_sim_row4.html ] || [ -f ./basic_sim_row5.html ]
     then
-        for DETAILS_TABLE in `ls ./phy_sim_row*.html`
+        for DETAILS_TABLE in `ls ./basic_sim_row*.html`
         do
             cat $DETAILS_TABLE >> ./build_results.html
         done
@@ -749,27 +679,6 @@ function report_build {
             cat $DETAILS_TABLE >> ./build_results.html
         done
     fi
-    if [ -f ./enb_eth_row1.html ] || [ -f ./enb_eth_row2.html ] || [ -f ./enb_eth_row3.html ] || [ -f ./enb_eth_row4.html ] || [ -f ./enb_eth_row5.html ] || [ -f ./enb_eth_row6.html ]
-    then
-        for DETAILS_TABLE in `ls ./enb_eth_row*.html`
-        do
-            cat $DETAILS_TABLE >> ./build_results.html
-        done
-    fi
-    if [ -f ./ue_eth_row1.html ] || [ -f ./ue_eth_row2.html ] || [ -f ./ue_eth_row3.html ] || [ -f ./ue_eth_row4.html ] || [ -f ./ue_eth_row5.html ] || [ -f ./ue_eth_row6.html ]
-    then
-        for DETAILS_TABLE in `ls ./ue_eth_row*.html`
-        do
-            cat $DETAILS_TABLE >> ./build_results.html
-        done
-    fi
-    if [ -f ./enb_usrp_rh_row1.html ] || [ -f ./enb_usrp_rh_row2.html ] || [ -f ./enb_usrp_rh_row3.html ] || [ -f ./enb_usrp_rh_row4.html ]
-    then
-        for DETAILS_TABLE in `ls ./enb_usrp_rh_row*.html`
-        do
-            cat $DETAILS_TABLE >> ./build_results.html
-        done
-    fi
     rm -f ./*_row*.html
 
     echo "   </div>" >> ./build_results.html
diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh
index 8562f4b2de49411b922b4f8f39fda765ecebe3c9..19fac7fd781827e8d83b5bf470772eb03bcbaa9f 100755
--- a/ci-scripts/reportTestLocally.sh
+++ b/ci-scripts/reportTestLocally.sh
@@ -309,14 +309,14 @@ function report_test {
                     NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG`
                     NB_UE_GOT_SYNC=`egrep -c "got sync" $UE_LOG`
                     NB_ENB_SYNCED_WITH_UE=`egrep -c "got UE capabilities for UE" $ENB_LOG`
-                    if [ $NB_ENB_GOT_SYNC -eq 1 ] && [ $NB_UE_GOT_SYNC -eq 2 ] && [ $NB_ENB_SYNCED_WITH_UE -eq 1 ]
+                    if [ $NB_ENB_GOT_SYNC -gt 0 ] && [ $NB_UE_GOT_SYNC -eq 2 ] && [ $NB_ENB_SYNCED_WITH_UE -eq 1 ]
                     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 [ $NB_ENB_GOT_SYNC -eq 1 ]
+                    if [ $NB_ENB_GOT_SYNC -gt 0 ]
                     then
                         echo "<font color = \"blue\">- eNB --> got sync</font>" >> ./test_simulator_results.html
                     else
@@ -717,7 +717,11 @@ function report_test {
         done
         echo "   </table>" >> ./test_simulator_results.html
         echo "   </div>" >> ./test_simulator_results.html
+    fi
 
+    ARCHIVES_LOC=archives/rf5g_sim/test
+    if [ -d $ARCHIVES_LOC ]
+    then
         echo "   <h3>5G NR RF Simulator Check</h3>" >> ./test_simulator_results.html
 
         if [ -f $ARCHIVES_LOC/test_final_status.log ]
@@ -748,8 +752,155 @@ 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 CN5G : ${TMODE} -- ${BW}PRB -- ${FR_MODE}</td>" >> ./test_simulator_results.html
+                else
+                    echo "          <td align = \"center\" colspan = 4 >Test without CN5G : ${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")
+        BW_CASES=(32)
+        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 CN5G : ${TMODE} -- ${BW}PRB -- ${FR_MODE}</td>" >> ./test_simulator_results.html
+                else
+                    echo "          <td align = \"center\" colspan = 4 >Test without CN5G : ${TMODE} -- ${BW}PRB -- ${FR_MODE}</td>" >> ./test_simulator_results.html
+                fi
+                echo "      </tr>" >> ./test_simulator_results.html
+
+
+                #FR2 RA test (--do-ra option)
+
+                #build log files names tdd_${PRB}prb_${CN_CONFIG}_gnb_ra_fr2_test.log
+
+                RA_ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb_ra_fr2_test.log
+                RA_UE_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_ue_ra_fr2_test.log
+                if [ -f $RA_ENB_LOG ] && [ -f $RA_UE_LOG ]
+                then
+                    #get rid of full path
+                    NAME_ENB=`echo $RA_ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"`
+                    NAME_UE=`echo $RA_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 FR2 RA proc succeeded</td>" >> ./test_simulator_results.html
+
+                    #gNB RA check
+                    GNB_RECEIVED=`egrep -c "\[RAPROC\] PUSCH with TC_RNTI (.+) received correctly" $RA_ENB_LOG`
+                    #UE RA check
+                    UE_RA_PROC_OK=`egrep -c "\[RAPROC\] RA procedure succeeded" $RA_UE_LOG`
+
+
+                    if [ $GNB_RECEIVED -gt 0 ] && [ $UE_RA_PROC_OK -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 [ $GNB_RECEIVED -gt 0 ]
+                    then
+                        echo "<font color = \"blue\">- gNB --> RA received</font>" >> ./test_simulator_results.html
+                    else
+                        echo "<font color = \"red\"><b>- gNB RA NOT RECEIVED</b></font>" >> ./test_simulator_results.html
+                    fi
+                    if [ $UE_RA_PROC_OK -gt 0 ]
+                    then
+                        echo "<font color = \"blue\">- NR UE  --> RA procedure succeded</font>" >> ./test_simulator_results.html
+                    else
+                        echo "<font color = \"red\"><b>- NR UE RA procedure failed</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")
+        FR_MODE=("FR1")
+        TRANS_MODES=("fdd" "tdd")
         BW_CASES=(106)
         for CN_CONFIG in ${EPC_CONFIGS[@]}
         do
@@ -760,13 +911,14 @@ function report_test {
                 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 </td>" >> ./test_simulator_results.html
+                    echo "          <td align = \"center\" colspan = 4 >Test with CN5G : ${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 </td>" >> ./test_simulator_results.html
+                    echo "          <td align = \"center\" colspan = 4 >Test without CN5G : ${TMODE} -- ${BW}PRB -- ${FR_MODE}</td>" >> ./test_simulator_results.html
                 fi
                 echo "      </tr>" >> ./test_simulator_results.html
 
-                #RA test (--do-ra option)
+
+                #FR1 RA test (--do-ra option)
 
                 #build log files names
                 RA_ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb_ra_test.log
@@ -778,7 +930,7 @@ function report_test {
                     NAME_UE=`echo $RA_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 RA proc succeeded</td>" >> ./test_simulator_results.html
+                    echo "        <td>Check if FR1 RA proc succeeded</td>" >> ./test_simulator_results.html
 
                     #gNB RA check
                     GNB_RECEIVED=`egrep -c "\[RAPROC\] PUSCH with TC_RNTI (.+) received correctly" $RA_ENB_LOG`
diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 70eabb7b695ecc4218c2d80143e47f3ff8124b0b..de696cdc64b77cb03be90a6d91080fd05e5f837e 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
@@ -379,7 +419,7 @@ function check_iperf {
     local LOC_IS_DL=`echo $LOC_BASE_LOG | grep -c _dl`
     local LOC_IS_BASIC_SIM=`echo $LOC_BASE_LOG | grep -c basic_sim`
     local LOC_IS_RF_SIM=`echo $LOC_BASE_LOG | grep -c rf_sim`
-    local LOC_IS_NR=`echo $LOC_BASE_LOG | grep -c tdd_106prb`
+    local LOC_IS_NR=`echo $LOC_BASE_LOG | grep -c _106prb`
     if [ -f ${LOC_BASE_LOG}_client.txt ]
     then
         local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt`
@@ -964,6 +1004,12 @@ function start_l2_sim_ue {
         echo "ifconfig" > $1
         ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1
         rm $1
+    else
+        echo "Setting Routes for all UEs"
+        echo "cd /home/ubuntu/tmp/cmake_targets/tools" > $1
+        echo "./setup_routes.sh $LOC_NB_UES" >> $1
+        ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1
+        rm $1
     fi
 }
 
@@ -1209,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
@@ -1233,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
+        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 --noS1 --nokrnmod 1 --rfsim --phy-test\" > ./my-nr-softmodem-run.sh " >> $1
-        else #RA test => use --do-ra 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 --do-ra\" > ./my-nr-softmodem-run.sh " >> $1
+            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
@@ -1273,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
@@ -1306,8 +1355,11 @@ function start_rf_sim_gnb {
     ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1
     rm $1
     # Copy the RAW files from the gNB run for the NR-UE
-    scp -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/ran_build/build/rbconfig.raw .
-    scp -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/ran_build/build/reconfig.raw .
+    if [ $LOC_RA_SA_TEST -ne 2 ]
+    then
+        scp -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/ran_build/build/rbconfig.raw .
+        scp -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/ran_build/build/reconfig.raw .
+    fi
 }
 
 function start_rf_sim_nr_ue {
@@ -1318,12 +1370,15 @@ 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
-    scp -o StrictHostKeyChecking=no reconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp
+    if [ $LOC_RA_SA_TEST -ne 2 ]
+    then
+        scp -o StrictHostKeyChecking=no rbconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp
+        scp -o StrictHostKeyChecking=no reconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp
+    fi
 
     echo "echo \"sudo apt-get --yes --quiet install daemon \"" > $1
     echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1
@@ -1331,16 +1386,23 @@ function start_rf_sim_nr_ue {
     echo "export RFSIMULATOR=${LOC_GNB_VM_IP_ADDR}" >> $1
     echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1
     echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
-    echo "sudo cp /home/ubuntu/tmp/r*config.raw /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
-    echo "sudo chmod 666 /home/ubuntu/tmp/cmake_targets/ran_build/build/r*config.raw" >> $1
+    echo "sudo rm -f /home/ubuntu/tmp/cmake_targets/ran_build/build/r*config.raw" >> $1
+    if [ $LOC_RA_SA_TEST -ne 2 ]
+    then
+        echo "sudo cp /home/ubuntu/tmp/r*config.raw /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
+        echo "sudo chmod 666 /home/ubuntu/tmp/cmake_targets/ran_build/build/r*config.raw" >> $1
+    fi
     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
@@ -1375,7 +1437,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
@@ -1420,11 +1482,13 @@ function run_test_on_vm {
         UE_VM_CMDS=${UE_VM_NAME}_cmds.txt
         echo "UE_VM_NAME          = $UE_VM_NAME"
         echo "UE_VM_CMD_FILE      = $UE_VM_CMDS"
-        GNB_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#gnb-usrp#" -e "s#rf-sim#gnb-usrp#"`
+    elif [[ (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-rf5g-sim.* ))  ]]
+    then
+        GNB_VM_NAME=`echo $VM_NAME | sed -e "s#rf5g-sim#gnb-usrp#"`
         GNB_VM_CMDS=${GNB_VM_NAME}_cmds.txt
         echo "GNB_VM_NAME         = $GNB_VM_NAME"
         echo "GNB_VM_CMD_FILE     = $GNB_VM_CMDS"
-        NR_UE_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#nr-ue-usrp#" -e "s#rf-sim#nr-ue-usrp#"`
+        NR_UE_VM_NAME=`echo $VM_NAME | sed -e "s#rf5g-sim#nr-ue-usrp#"`
         NR_UE_VM_CMDS=${UE_VM_NAME}_cmds.txt
         echo "NR_UE_VM_NAME       = $NR_UE_VM_NAME"
         echo "NR_UE_VM_CMD_FILE   = $NR_UE_VM_CMDS"
@@ -1453,6 +1517,8 @@ function run_test_on_vm {
         UE_VM_IP_ADDR=`uvt-kvm ip $UE_VM_NAME`
         echo "$UE_VM_NAME has for IP addr = $UE_VM_IP_ADDR"
 
+    elif [[ (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-rf5g-sim.* ))  ]]
+    then
         echo "############################################################"
         echo "Waiting for GNB VM to be started"
         echo "############################################################"
@@ -1478,13 +1544,13 @@ function run_test_on_vm {
         echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
     fi
 
-    if [ "$RUN_OPTIONS" == "none" ]
+    if [ "$RUN_OPTIONS" == "none" ] || [[ $RUN_OPTIONS =~ .*run_exec_autotests.* ]]
     then
         echo "No run on VM testing for this variant currently"
         return
     fi
 
-    if [[ $RUN_OPTIONS =~ .*run_exec_autotests.* ]]
+    if [[ $RUN_OPTIONS =~ .*run_XXXX_autotests.* ]]
     then
         echo "############################################################"
         echo "Running test script on VM ($VM_NAME)"
@@ -2187,10 +2253,23 @@ function run_test_on_vm {
 
     fi
 
-    if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]]
+    if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf5g-sim.* ]]
     then
+        PING_STATUS=0
+        IPERF_STATUS=0
+        NR_STATUS=0
+        if [ -d $ARCHIVES_LOC ]
+        then
+            rm -Rf $ARCHIVES_LOC
+        fi
+        mkdir --parents $ARCHIVES_LOC
+
+        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.tm1.106PRB.usrpn300.conf
+        CONF_FILE=gnb.band78.sa.fr1.106PRB.usrpn310.conf
         S1_NOS1_CFG=0
         PRB=106
         FREQUENCY=3510
@@ -2201,27 +2280,109 @@ function run_test_on_vm {
         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
+                echo "SA test OK"
+                try_cnt=$((try_cnt+10))
+            fi
+        done
+        ########### end SA test
+
+        sleep 30
+
+
+
+        echo "############################################################"
+        echo "RA TEST FR2"
+        echo "############################################################"
+        #RA FR2 test, attention : has a different config file from the rest of the test
+        CN_CONFIG="noS1"
+        CONF_FILE=gnb.band261.tm1.32PRB.usrpn300.conf
+        S1_NOS1_CFG=0
+        PRB=32
+        FREQUENCY=28000 #28GHz
+
+        if [ ! -d $ARCHIVES_LOC ]
+        then
+            mkdir --parents $ARCHIVES_LOC
+        fi
+
+        local try_cnt=0
 
         ######### start of RA TEST loop
+        RA_FR2_STATUS=0
         while [ $try_cnt -lt 5 ] #5 because it hardly succeed within CI
         do
 
             SYNC_STATUS=0
             RA_STATUS=0
-            rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}*ra_test.log
+            rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}*ra_fr2_test.log
 
             echo "############################################################"
             echo "${CN_CONFIG} : Starting the gNB"
             echo "############################################################"
-            CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb_ra_test.log
+            CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb_ra_fr2_test.log
             #last argument = 1 is to enable --do-ra for RA test
             start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 1
 
             echo "############################################################"
             echo "${CN_CONFIG} : Starting the NR-UE"
             echo "############################################################"
-            CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue_ra_test.log
+            CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue_ra_fr2_test.log
             #last argument = 1 is to enable --do-ra for RA 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 1
             if [ $NR_UE_SYNC -eq 0 ]
@@ -2247,48 +2408,165 @@ function run_test_on_vm {
 
             #check RA markers in gNB and NR UE log files
             echo "############################################################"
-            echo "${CN_CONFIG} : Checking RA on gNB / NR-UE"
+            echo "${CN_CONFIG} : Checking FR2 RA on gNB / NR-UE"
             echo "############################################################"
 
             # Proper check to be done when RA test is working!
             check_ra_result $ARCHIVES_LOC/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC/$CURRENT_NR_UE_LOG_FILE
             if [ $RA_STATUS -ne 0 ]
             then
-                echo "RA test NOT OK"
+                echo "RA FR2 test NOT OK"
                 echo "try_cnt = " $try_cnt
                 try_cnt=$((try_cnt+1))
+                RA_FR2_STATUS=-1
             else
+                echo "RA FR2 test OK"
+                RA_FR2_STATUS=0
                 try_cnt=$((try_cnt+10))
             fi
         done
-        ########### end RA test
-        
+        ########### end RA FR2 test
+
         sleep 30
 
 
-        ######### start of PHY TEST loop
-        try_cnt=0
-        while [ $try_cnt -lt 4 ]
+        echo "############################################################"
+        echo "RA TEST FR1"
+        echo "############################################################"
+        ######### redefine config for the rest of the test
+
+        CN_CONFIG="noS1"
+        CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf
+        S1_NOS1_CFG=0
+        PRB=106
+        FREQUENCY=3510
+
+        if [ ! -d $ARCHIVES_LOC ]
+        then
+            mkdir --parents $ARCHIVES_LOC
+        fi
+
+        CN_CONFIG="noS1"
+        S1_NOS1_CFG=0
+
+        ######### start of RA TEST loop
+        # for the moment only TDD
+        TRANS_MODES=("tdd")
+        for TMODE in ${TRANS_MODES[@]}
         do
+          if [[ $TMODE =~ .*fdd.* ]]
+          then
+            CONF_FILE=gnb.band66.tm1.106PRB.usrpn300.conf
+            PRB=106
+            FREQUENCY=37000
+          else
+            CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf
+            PRB=106
+            FREQUENCY=3510
+          fi
 
+          RA_FR1_STATUS=0
+          local try_cnt=0
+          while [ $try_cnt -lt 5 ] #5 because it hardly succeed within CI
 
+          do
             SYNC_STATUS=0
-            PING_STATUS=0
-            IPERF_STATUS=0
-            rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_gnb.log $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ue.log 
-            rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log
-            rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_iperf_dl*txt $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_iperf_ul*txt
+            RA_STATUS=0
+            rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}*ra_test.log
 
             echo "############################################################"
-            echo "${CN_CONFIG} : Starting the gNB"
+            echo "${CN_CONFIG} : Starting the gNB in ${TMODE} mode (RA TEST)"
             echo "############################################################"
-            CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb.log
+            CURRENT_GNB_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_gnb_ra_test.log
+            #last argument = 1 is to enable --do-ra for RA test
+            start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 1
+
+            echo "############################################################"
+            echo "${CN_CONFIG} : Starting the NR-UE in ${TMODE} mode (RA TEST)"
+            echo "############################################################"
+            CURRENT_NR_UE_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ue_ra_test.log
+            #last argument = 1 is to enable --do-ra for RA 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 1
+            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 RA markers in gNB and NR UE log files
+            echo "############################################################"
+            echo "${CN_CONFIG} : Checking FR1 RA on gNB / NR-UE"
+            echo "############################################################"
+
+            # Proper check to be done when RA test is working!
+            check_ra_result $ARCHIVES_LOC/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC/$CURRENT_NR_UE_LOG_FILE
+            if [ $RA_STATUS -ne 0 ]
+            then
+                echo "RA FR1 test NOT OK"
+                echo "try_cnt = " $try_cnt
+                RA_FR1_STATUS=-1
+                try_cnt=$((try_cnt+1))
+            else
+                echo "RA FR1 test OK"
+                RA_FR1_STATUS=0
+                try_cnt=$((try_cnt+10))
+            fi
+          done
+        done
+        ########### end RA test
+        
+        sleep 30
+
+        ######### start of PHY TEST loop
+        SYNC_STATUS=0
+        PING_STATUS=0
+        IPERF_STATUS=0
+        TRANS_MODES=("fdd tdd")
+        for TMODE in ${TRANS_MODES[@]}
+        do
+          if [[ $TMODE =~ .*fdd.* ]]
+          then
+            CONF_FILE=gnb.band66.tm1.106PRB.usrpn300.conf
+            PRB=106
+            FREQUENCY=37000
+          else
+            CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf
+            PRB=106
+            FREQUENCY=3510
+          fi
+
+          try_cnt=0
+          while [ $try_cnt -lt 4 ]
+          do
+            rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_gnb.log $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ue.log
+            rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log
+            rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_dl*txt $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_ul*txt
+
+            echo "############################################################"
+            echo "${CN_CONFIG} : Starting the gNB in ${TMODE} mode (PHY TEST)"
+            echo "############################################################"
+            CURRENT_GNB_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_gnb.log
             start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 0
 
             echo "############################################################"
-            echo "${CN_CONFIG} : Starting the NR-UE"
+            echo "${CN_CONFIG} : Starting the NR-UE in ${TMODE} mode (PHY TEST)"
             echo "############################################################"
-            CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue.log
+            CURRENT_NR_UE_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ue.log
             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 0
             if [ $NR_UE_SYNC -eq 0 ]
             then
@@ -2306,7 +2584,7 @@ function run_test_on_vm {
             echo "${CN_CONFIG} : Pinging the gNB from NR-UE"
             echo "############################################################"
             get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR
-            PING_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log
+            PING_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log
             ping_epc_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $ENB_IP_ADDR $PING_LOG_FILE 1 0
             scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
             check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
@@ -2315,7 +2593,7 @@ function run_test_on_vm {
             echo "${CN_CONFIG} : Pinging the NR-UE from gNB"
             echo "############################################################"
             get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1
-            PING_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log
+            PING_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log
             ping_enb_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0
             scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
             check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
@@ -2324,7 +2602,7 @@ function run_test_on_vm {
             echo "${CN_CONFIG} : iperf DL -- NR-UE is server and gNB is client"
             echo "############################################################"
             THROUGHPUT="30K"
-            CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_dl
+            CURR_IPERF_LOG_BASE=${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_dl
             get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR
             get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1
             generic_iperf $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0 
@@ -2346,7 +2624,7 @@ function run_test_on_vm {
             echo "${CN_CONFIG} : iperf UL -- gNB is server and NR-UE is client"
             echo "############################################################"
             THROUGHPUT="30K"
-            CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_ul
+            CURR_IPERF_LOG_BASE=${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_ul
             get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR
             get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1
             generic_iperf $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0
@@ -2368,6 +2646,7 @@ function run_test_on_vm {
             else
                 try_cnt=$((try_cnt+10))
             fi
+          done
         done
         ######### end of loop
         full_l2_sim_destroy
@@ -2377,17 +2656,19 @@ function run_test_on_vm {
         echo "Checking run status"
         echo "############################################################"
 
-        if [ $RA_STATUS -ne 0 ]; then NR_STATUS=-1; fi
+        if [ $SA_STATUS -ne 0 ]; then NR_STATUS=-1; fi     
+        if [ $RA_FR2_STATUS -ne 0 ]; then NR_STATUS=-1; fi        
+        if [ $RA_FR1_STATUS -ne 0 ]; then NR_STATUS=-1; fi
         if [ $SYNC_STATUS -ne 0 ]; then NR_STATUS=-1; fi
         if [ $PING_STATUS -ne 0 ]; then NR_STATUS=-1; fi
         if [ $IPERF_STATUS -ne 0 ]; then NR_STATUS=-1; fi
         if [ $NR_STATUS -eq 0 ]
         then
             echo "5G-NR RFSIM seems OK"
-            echo "5G-NR: TEST_OK" >> $ARCHIVES_LOC/test_final_status.log
+            echo "5G-NR: TEST_OK" > $ARCHIVES_LOC/test_final_status.log
         else
             echo "5G-NR RFSIM seems to FAIL"
-            echo "5G-NR: TEST_KO" >> $ARCHIVES_LOC/test_final_status.log
+            echo "5G-NR: TEST_KO" > $ARCHIVES_LOC/test_final_status.log
             STATUS=-1
         fi
     fi
diff --git a/ci-scripts/sshconnection.py b/ci-scripts/sshconnection.py
index 5bfe5da70f94b3abf104957514158eaa482ec369..b4087c9695900422b107227c3bc60b0fae23c1f4 100644
--- a/ci-scripts/sshconnection.py
+++ b/ci-scripts/sshconnection.py
@@ -35,6 +35,7 @@ import pexpect          # pexpect
 import logging
 import time             # sleep
 import re
+import subprocess
 import sys
 
 #-----------------------------------------------------------
@@ -44,6 +45,9 @@ class SSHConnection():
 	def __init__(self):
 		self.ssh = ''
 		self.picocom_closure = False
+		self.ipaddress = ''
+		self.username = ''
+		self.cmd2Results = ''
 
 	def disablePicocomClosure(self):
 		self.picocom_closure = False
@@ -98,6 +102,8 @@ class SSHConnection():
 			pass
 		else:
 			sys.exit('SSH Connection Failed')
+		self.ipaddress = ipaddress
+		self.username = username
 
 
 
@@ -111,11 +117,20 @@ class SSHConnection():
 		self.sshresponse = self.ssh.expect(expected)
 		return self.sshresponse
 
-	def command(self, commandline, expectedline, timeout):
-		logging.debug(commandline)
+	def command(self, commandline, expectedline, timeout, silent=False, resync=False):
+		if not silent:
+			logging.debug(commandline)
 		self.ssh.timeout = timeout
-		self.ssh.sendline(commandline)
-		self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT])
+		# Nasty patch when pexpect output is out of sync.
+		# Much pronounced when running back-to-back-back oc commands
+		if resync:
+			self.ssh.send(commandline)
+			self.ssh.expect([commandline, pexpect.TIMEOUT])
+			self.ssh.send('\r\n')
+			self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT])
+		else:
+			self.ssh.sendline(commandline)
+			self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT])
 		if self.sshresponse == 0:
 			return 0
 		elif self.sshresponse == 1:
@@ -137,10 +152,23 @@ class SSHConnection():
 			logging.debug('Expected Line : ' + expectedline)
 			sys.exit(self.sshresponse)
 
+	def command2(self, commandline, timeout, silent=False):
+		if not silent:
+			logging.debug(commandline)
+		self.cmd2Results = ''
+		myHost = self.username + '@' + self.ipaddress
+		# CAUTION: THIS METHOD IMPLIES THAT THERE ARE VALID SSH KEYS
+		# BETWEEN THE PYTHON EXECUTOR NODE AND THE REMOTE HOST
+		# OTHERWISE IT WON'T WORK
+		lSsh = subprocess.Popen(["ssh", "%s" % myHost, commandline],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+		self.cmd2Results = str(lSsh.stdout.readlines())
+
 	def close(self):
 		self.ssh.timeout = 5
 		self.ssh.sendline('exit')
 		self.sshresponse = self.ssh.expect([pexpect.EOF, pexpect.TIMEOUT])
+		self.ipaddress = ''
+		self.username = ''
 		if self.sshresponse == 0:
 			pass
 		elif self.sshresponse == 1:
diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh
index f066dacd8123abb5ccff3c1eff3a0f6ed5df5663..4a604a1fe94d8d1c466608a76fc6a174e0f18583 100755
--- a/ci-scripts/waitBuildOnVM.sh
+++ b/ci-scripts/waitBuildOnVM.sh
@@ -47,6 +47,12 @@ function wait_on_vm_build {
     echo "ARCHIVES_LOC        = $ARCHIVES_LOC"
     echo "BUILD_OPTIONS       = $BUILD_OPTIONS"
 
+    if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]]
+    then
+        echo "This VM type is no longer supported in the pipeline framework"
+        return
+    fi
+
     IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME`
 
     if [ $IS_VM_ALIVE -eq 0 ]
@@ -67,6 +73,9 @@ function wait_on_vm_build {
     echo "############################################################"
     echo "Waiting build process to end on VM ($VM_NAME)"
     echo "############################################################"
+    # Since the last VM was cppcheck and is removed
+    # we are going too fast in wait and the build_oai is not yet started
+    sleep 120
 
     if [[ "$VM_NAME" == *"-cppcheck"* ]]
     then
@@ -84,6 +93,12 @@ function wait_on_vm_build {
 }
 
 function check_on_vm_build {
+    if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]]
+    then
+        echo "This VM type is no longer supported in the pipeline framework"
+        return
+    fi
+
     echo "############################################################"
     echo "Creating a tmp folder to store results and artifacts"
     echo "############################################################"
diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml
index 0e00a2e7d413da5784e7c88210335bfa335406ec..d8e1b26a215ddabafbea38471a0c6f0b34e71f86 100755
--- a/ci-scripts/xml_class_list.yml
+++ b/ci-scripts/xml_class_list.yml
@@ -27,6 +27,8 @@
   - Terminate_MME
   - Initialize_SPGW
   - Terminate_SPGW
+  - Initialize_5GCN
+  - Terminate_5GCN
   - Initialize_CatM_module
   - Terminate_CatM_module
   - Attach_CatM_module
@@ -37,3 +39,9 @@
   - Build_Image
   - Deploy_Object
   - Undeploy_Object
+  - Cppcheck_Analysis
+  - Deploy_Run_PhySim
+  - DeployGenObject
+  - UndeployGenObject
+  - PingFromContainer
+  - IperfFromContainer
diff --git a/ci-scripts/xml_files/benetel_multi_node_build.xml b/ci-scripts/xml_files/benetel_multi_node_build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5ac28951b4ad308f078402f0cebd117ba01e4112
--- /dev/null
+++ b/ci-scripts/xml_files/benetel_multi_node_build.xml
@@ -0,0 +1,54 @@
+<!--
+
+ 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>build-tab</htmlTabRef>
+	<htmlTabName>Build</htmlTabName>
+	<htmlTabIcon>wrench</htmlTabIcon>
+	<TestCaseRequestedList>
+ 000001 000002
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="000001">
+		<class>Build_eNB</class>
+		<desc>Build eNB</desc>
+		<Build_eNB_args>--eNB -t benetel4g -w None</Build_eNB_args>
+		<forced_workspace_cleanup>True</forced_workspace_cleanup>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+	</testCase>
+
+
+	<testCase id="000002">
+		<class>Build_eNB</class>
+		<desc>Build gNB</desc>
+		<Build_eNB_args>--gNB -t benetel5g -w None</Build_eNB_args>
+		<forced_workspace_cleanup>True</forced_workspace_cleanup>
+		<eNB_instance>1</eNB_instance>
+		<eNB_serverId>1</eNB_serverId>
+	</testCase>
+
+
+
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/benetel_nsa_quectel.xml b/ci-scripts/xml_files/benetel_nsa_quectel.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ed93f59e81cefff0d0b410c38f0636c5cd939452
--- /dev/null
+++ b/ci-scripts/xml_files/benetel_nsa_quectel.xml
@@ -0,0 +1,147 @@
+<!--
+
+ 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</htmlTabName>
+	<htmlTabIcon>tasks</htmlTabIcon>
+	<repeatCount>3</repeatCount>
+	<TestCaseRequestedList>
+ 030000
+ 040000
+ 000002
+ 010000
+ 050000
+ 050001
+ 000001
+ 070000
+ 000001
+ 070001
+ 000001
+ 010002
+ 000001
+ 080001
+ 080000
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="010000">
+		<class>Initialize_UE</class>
+		<desc>Initialize Quectel</desc>
+		<id>idefix</id>
+	</testCase>
+
+
+	<testCase id="010002">
+		<class>Detach_UE</class>
+		<desc>Detach UE</desc>
+		<id>idefix</id>
+	</testCase>
+
+
+	<testCase id="030000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize eNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/benetel-4g.conf</Initialize_eNB_args>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<air_interface>lte</air_interface>
+	</testCase>
+
+
+	<testCase id="040000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize gNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/benetel-5g.conf -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 -i 1</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 -i 1</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/benetel_nsa_quectel_longrun.xml b/ci-scripts/xml_files/benetel_nsa_quectel_longrun.xml
new file mode 100644
index 0000000000000000000000000000000000000000..93c0c5a00a209659092d47b39787086b48dc30da
--- /dev/null
+++ b/ci-scripts/xml_files/benetel_nsa_quectel_longrun.xml
@@ -0,0 +1,149 @@
+<!--
+
+ 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</htmlTabName>
+	<htmlTabIcon>tasks</htmlTabIcon>
+	<repeatCount>3</repeatCount>
+	<TestCaseRequestedList>
+ 030000
+ 040000
+ 000002
+ 010000
+ 000001
+ 050000
+ 050001
+ 000001
+ 070000
+ 000001
+ 070001
+ 000001
+ 010002
+ 000001
+ 080001
+ 080000
+  
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="010000">
+		<class>Initialize_UE</class>
+		<desc>Initialize Quectel</desc>
+		<id>idefix</id>
+	</testCase>
+
+
+	<testCase id="010002">
+		<class>Detach_UE</class>
+		<desc>Detach UE</desc>
+		<id>idefix</id>
+	</testCase>
+
+
+	<testCase id="030000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize eNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/benetel-4g.conf</Initialize_eNB_args>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<air_interface>lte</air_interface>
+	</testCase>
+
+
+	<testCase id="040000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize gNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/benetel-5g.conf -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>10</idle_sleep_time_in_sec>
+	</testCase>
+
+	<testCase id="000002">
+		<class>IdleSleep</class>
+		<desc>Sleep</desc>
+		<idle_sleep_time_in_sec>30</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)(20 min)(single-ue profile)</desc>
+		<iperf_args>-u -b 20M -t 1200 -i 1</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)(20 min)(single-ue profile)</desc>
+		<iperf_args>-u -b 2M -t 1200 -i 1</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/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8847c1189429ec8acc3f9f18d71a5d064a2a141e
--- /dev/null
+++ b/ci-scripts/xml_files/container_5g_rfsim.xml
@@ -0,0 +1,103 @@
+<!--
+
+ 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>rfsim-5gnr</htmlTabRef>
+        <htmlTabName>Testing 5G NR RF sim in containers</htmlTabName>
+        <htmlTabIcon>wrench</htmlTabIcon>
+        <TestCaseRequestedList>
+ 000001
+ 000002
+ 000003
+ 020001
+ 020002
+ 030001
+ 030002
+ 100001
+        </TestCaseRequestedList>
+        <TestCaseExclusionList></TestCaseExclusionList>
+
+        <testCase id="000001">
+                <class>DeployGenObject</class>
+                <desc>Deploy OAI 5G CoreNetwork</desc>
+                <yaml_path>yaml_files/5g_rfsimulator</yaml_path>
+                <services>mysql oai-nrf oai-amf oai-smf oai-spgwu oai-ext-dn</services>
+                <nb_healthy>6</nb_healthy>
+        </testCase>
+
+        <testCase id="000002">
+                <class>DeployGenObject</class>
+                <desc>Deploy OAI 5G gNB RF sim SA</desc>
+                <yaml_path>yaml_files/5g_rfsimulator</yaml_path>
+                <services>oai-gnb</services>
+                <nb_healthy>7</nb_healthy>
+        </testCase>
+
+        <testCase id="000003">
+                <class>DeployGenObject</class>
+                <desc>Deploy OAI 5G NR-UE RF sim SA</desc>
+                <yaml_path>yaml_files/5g_rfsimulator</yaml_path>
+                <services>oai-nr-ue</services>
+                <nb_healthy>8</nb_healthy>
+        </testCase>
+
+        <testCase id="020001">
+                <class>PingFromContainer</class>
+                <desc>Ping ext-dn from NR-UE</desc>
+                <container_name>rfsim5g-oai-nr-ue</container_name>
+                <options>-I oaitun_ue1 -c 20 192.168.72.135</options>
+                <loss_threshold>5</loss_threshold>
+        </testCase>
+
+        <testCase id="020002">
+                <class>PingFromContainer</class>
+                <desc>Ping NR-UE from ext-dn</desc>
+		<container_name>rfsim5g-oai-ext-dn</container_name>
+                <options>-c 20 12.1.1.2</options>
+                <loss_threshold>5</loss_threshold>
+        </testCase>
+
+        <testCase id="030001">
+                <class>IperfFromContainer</class>
+                <desc>Iperf UDP Downlink</desc>
+                <server_container_name>rfsim5g-oai-nr-ue</server_container_name>
+                <client_container_name>rfsim5g-oai-ext-dn</client_container_name>
+                <server_options>-B 12.1.1.2 -u -i 1 -s</server_options>
+                <client_options>-c 12.1.1.2 -u -i 1 -t 30 -b 400K</client_options>
+        </testCase>
+
+        <testCase id="030002">
+                <class>IperfFromContainer</class>
+                <desc>Iperf UDP Uplink</desc>
+                <server_container_name>rfsim5g-oai-ext-dn</server_container_name>
+                <client_container_name>rfsim5g-oai-nr-ue</client_container_name>
+                <server_options>-u -i 1 -s</server_options>
+                <client_options>-B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 30 -b 20K</client_options>
+        </testCase>
+
+        <testCase id="100001">
+                <class>UndeployGenObject</class>
+                <desc>Undeploy all OAI 5G stack</desc>
+                <yaml_path>yaml_files/5g_rfsimulator</yaml_path>
+        </testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/container_5g_rfsim_down.xml b/ci-scripts/xml_files/container_5g_rfsim_down.xml
new file mode 100644
index 0000000000000000000000000000000000000000..57b0f67a214c297fe86648559e29aaf04012c1f7
--- /dev/null
+++ b/ci-scripts/xml_files/container_5g_rfsim_down.xml
@@ -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
+
+-->
+<testCaseList>
+        <htmlTabRef>rfsim-5gnr-down</htmlTabRef>
+        <htmlTabName>CleanUp 5G RF</htmlTabName>
+        <htmlTabIcon>trash</htmlTabIcon>
+        <TestCaseRequestedList>
+ 100002
+        </TestCaseRequestedList>
+        <TestCaseExclusionList></TestCaseExclusionList>
+
+        <testCase id="100002">
+                <class>UndeployGenObject</class>
+                <desc>Undeploy all OAI 5G stack</desc>
+                <yaml_path>yaml_files/5g_rfsimulator</yaml_path>
+        </testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/fr1_image_build.xml b/ci-scripts/xml_files/container_image_build.xml
similarity index 90%
rename from ci-scripts/xml_files/fr1_image_build.xml
rename to ci-scripts/xml_files/container_image_build.xml
index 9dd386b646cd6e1975882e62f49852700efd5cf8..e7eabc0794c44ebbd6186b7d55f4b0a2c7b69fbc 100644
--- a/ci-scripts/xml_files/fr1_image_build.xml
+++ b/ci-scripts/xml_files/container_image_build.xml
@@ -22,7 +22,7 @@
 -->
 <testCaseList>
 	<htmlTabRef>build-tab</htmlTabRef>
-	<htmlTabName>Build</htmlTabName>
+	<htmlTabName>Build Container Images</htmlTabName>
 	<htmlTabIcon>wrench</htmlTabIcon>
 	<TestCaseRequestedList>
  000001
@@ -31,10 +31,11 @@
 
 	<testCase id="000001">
 		<class>Build_Image</class>
-		<desc>Build eNB Image</desc>
+		<desc>Build all Images</desc>
 		<kind>all</kind>
 		<eNB_instance>0</eNB_instance>
 		<eNB_serverId>0</eNB_serverId>
+		<forced_workspace_cleanup>True</forced_workspace_cleanup>
 	</testCase>
 
 </testCaseList>
diff --git a/ci-scripts/xml_files/cppcheck.xml b/ci-scripts/xml_files/cppcheck.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dd90d88f7e289cba5e35ac56df3c6f409bd08960
--- /dev/null
+++ b/ci-scripts/xml_files/cppcheck.xml
@@ -0,0 +1,37 @@
+<!--
+
+ 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>build-tab</htmlTabRef>
+	<htmlTabName>CPPCHECK Analysis</htmlTabName>
+	<htmlTabIcon>wrench</htmlTabIcon>
+	<TestCaseRequestedList>
+ 000001
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="000001">
+		<class>Cppcheck_Analysis</class>
+		<desc>Static Code Analysis with cppcheck</desc>
+	</testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_build.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_build.xml
index 64c35171669e48444e5f67beda0690ad03103b05..bfaaceaa2d91b54925bdbd914032cbcdae5f7bed 100644
--- a/ci-scripts/xml_files/enb_ue_usrp210_band7_build.xml
+++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_build.xml
@@ -32,7 +32,7 @@
 	<testCase id="010101">
 		<class>Build_eNB</class>
 		<desc>Build eNB (USRP)</desc>
-		<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
+		<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
 	</testCase>
 
 </testCaseList>
diff --git a/ci-scripts/xml_files/enb_usrp210_band13_build.xml b/ci-scripts/xml_files/enb_usrp210_band13_build.xml
index 888a1230ae23aabc95f9ec8dd25a8681eeacde03..53066573c89a6dee1aeaae1eeebd49243e608cce 100644
--- a/ci-scripts/xml_files/enb_usrp210_band13_build.xml
+++ b/ci-scripts/xml_files/enb_usrp210_band13_build.xml
@@ -33,7 +33,7 @@
 	<testCase id="010101">
 		<class>Build_eNB</class>
 		<desc>Build eNB (USRP)</desc>
-		<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
+		<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
 	</testCase>
 
 </testCaseList>
diff --git a/ci-scripts/xml_files/enb_usrp210_band40_build.xml b/ci-scripts/xml_files/enb_usrp210_band40_build.xml
index 64c35171669e48444e5f67beda0690ad03103b05..bfaaceaa2d91b54925bdbd914032cbcdae5f7bed 100644
--- a/ci-scripts/xml_files/enb_usrp210_band40_build.xml
+++ b/ci-scripts/xml_files/enb_usrp210_band40_build.xml
@@ -32,7 +32,7 @@
 	<testCase id="010101">
 		<class>Build_eNB</class>
 		<desc>Build eNB (USRP)</desc>
-		<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
+		<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
 	</testCase>
 
 </testCaseList>
diff --git a/ci-scripts/xml_files/enb_usrp210_band7_build.xml b/ci-scripts/xml_files/enb_usrp210_band7_build.xml
index 64c35171669e48444e5f67beda0690ad03103b05..bfaaceaa2d91b54925bdbd914032cbcdae5f7bed 100644
--- a/ci-scripts/xml_files/enb_usrp210_band7_build.xml
+++ b/ci-scripts/xml_files/enb_usrp210_band7_build.xml
@@ -32,7 +32,7 @@
 	<testCase id="010101">
 		<class>Build_eNB</class>
 		<desc>Build eNB (USRP)</desc>
-		<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
+		<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
 	</testCase>
 
 </testCaseList>
diff --git a/ci-scripts/xml_files/fr1_gnb_build.xml b/ci-scripts/xml_files/fr1_gnb_build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d0c91f407df41d8d58543ade502653440e31dba1
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_gnb_build.xml
@@ -0,0 +1,50 @@
+<!--
+
+ 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>build-tab</htmlTabRef>
+	<htmlTabName>Build</htmlTabName>
+	<htmlTabIcon>wrench</htmlTabIcon>
+	<TestCaseRequestedList>
+ 000001
+ 000002
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="000001">
+		<class>Build_eNB</class>
+		<desc>Build gNB</desc>
+		<Build_eNB_args>-w USRP -c --gNB --ninja</Build_eNB_args>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<backgroundBuild>True</backgroundBuild>
+		<forced_workspace_cleanup>True</forced_workspace_cleanup>
+	</testCase>
+
+	<testCase id="000002">
+		<class>WaitEndBuild_eNB</class>
+		<desc>Wait for end of Build gNB</desc>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+	</testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/fr1_multi_node_build.xml b/ci-scripts/xml_files/fr1_multi_node_build.xml
index 7b4eacef3a3d091e7397bfc89a7f8422c459998c..57c4685341c9cda60734c02cdbcbd2435f5e5c84 100644
--- a/ci-scripts/xml_files/fr1_multi_node_build.xml
+++ b/ci-scripts/xml_files/fr1_multi_node_build.xml
@@ -37,6 +37,7 @@
 		<eNB_instance>0</eNB_instance>
 		<eNB_serverId>0</eNB_serverId>
 		<backgroundBuild>True</backgroundBuild>
+		<forced_workspace_cleanup>True</forced_workspace_cleanup>
 	</testCase>
 
 	<testCase id="000004">
@@ -53,6 +54,7 @@
 		<eNB_instance>1</eNB_instance>
 		<eNB_serverId>1</eNB_serverId>
 		<backgroundBuild>True</backgroundBuild>
+		<forced_workspace_cleanup>True</forced_workspace_cleanup>
 	</testCase>
 
 	<testCase id="000003">
diff --git a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a8e385b854120a2451253e4fd42c9c4aff314b11
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml
@@ -0,0 +1,146 @@
+<!--
+
+ 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</htmlTabName>
+	<htmlTabIcon>tasks</htmlTabIcon>
+	<repeatCount>1</repeatCount>
+	<TestCaseRequestedList>
+ 030000
+ 040000
+ 000002
+ 010000
+ 000001
+ 050000
+ 000001
+ 010002
+ 080001
+ 080000
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="010000">
+		<class>Initialize_UE</class>
+		<desc>Initialize Quectel</desc>
+		<id>nrmodule2_quectel</id>
+		<UE_Trace>yes</UE_Trace>
+	</testCase>
+
+
+	<testCase id="010002">
+		<class>Terminate_UE</class>
+		<desc>Terminate Quectel</desc>
+		<id>nrmodule2_quectel</id>
+	</testCase>
+
+
+	<testCase id="030000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize eNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf</Initialize_eNB_args>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<air_interface>lte</air_interface>
+		<eNB_Trace>yes</eNB_Trace>
+		<USRP_IPAddress>192.168.18.241</USRP_IPAddress>
+	</testCase>
+
+
+	<testCase id="040000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize gNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf -q</Initialize_eNB_args>
+		<eNB_instance>1</eNB_instance>
+		<eNB_serverId>1</eNB_serverId>
+		<air_interface>nr</air_interface>
+		<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
+	</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>nrmodule2_quectel</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>nrmodule2_quectel</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>nrmodule2_quectel</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>nrmodule2_quectel</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_ran_ue_iperf.xml b/ci-scripts/xml_files/fr1_nsa_base.xml
similarity index 80%
rename from ci-scripts/xml_files/fr1_ran_ue_iperf.xml
rename to ci-scripts/xml_files/fr1_nsa_base.xml
index 8ead3afc62ee152e39cc03bc389c53b4409b3be9..96bdc79f0f9138e2d43597237575014f28700c04 100644
--- a/ci-scripts/xml_files/fr1_ran_ue_iperf.xml
+++ b/ci-scripts/xml_files/fr1_nsa_base.xml
@@ -21,8 +21,8 @@
 
 -->
 <testCaseList>
-	<htmlTabRef>TEST-FR1-TM1</htmlTabRef>
-	<htmlTabName>FR1</htmlTabName>
+	<htmlTabRef>TEST-NSA-FR1-TM1</htmlTabRef>
+	<htmlTabName>NSA FULL</htmlTabName>
 	<htmlTabIcon>tasks</htmlTabIcon>
 	<TestCaseRequestedList>
  010000
@@ -31,14 +31,17 @@
  010001
  000001
  050000
+ 050001
  000001
  060000
  060001
  000001
+ 070000
+ 070001
  010002
  000001
- 070001
- 070000
+ 080001
+ 080000
  010003
 	</TestCaseRequestedList>
 	<TestCaseExclusionList></TestCaseExclusionList>
@@ -96,6 +99,13 @@
 		<ping_packetloss_threshold>50</ping_packetloss_threshold>
 	</testCase>
 
+	<testCase id="050001">
+		<class>Ping</class>
+		<desc>Ping: 100pings in 20sec</desc>
+		<ping_args>-c 100 -i 0.2</ping_args>
+		<ping_packetloss_threshold>50</ping_packetloss_threshold>
+	</testCase>
+
 
 	<testCase id="060000">
 		<class>Iperf</class>
@@ -113,7 +123,26 @@
 		<iperf_profile>single-ue</iperf_profile>
 	</testCase>
 
+
 	<testCase id="070000">
+		<class>Iperf</class>
+		<desc>iperf (DL/20Mbps/UDP)(20 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 20M -t 20 -i 1</iperf_args>
+		<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)(20 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 3M -t 20 -i 1 -R</iperf_args>
+		<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>
@@ -121,7 +150,7 @@
 		<air_interface>lte</air_interface>
 	</testCase>
 
-	<testCase id="070001">
+	<testCase id="080001">
 		<class>Terminate_eNB</class>
 		<desc>Terminate gNB</desc>
 		<eNB_instance>1</eNB_instance>
diff --git a/ci-scripts/xml_files/fr1_multi_node_test.xml b/ci-scripts/xml_files/fr1_nsa_quectel.xml
similarity index 51%
rename from ci-scripts/xml_files/fr1_multi_node_test.xml
rename to ci-scripts/xml_files/fr1_nsa_quectel.xml
index 8c56f0bcec9354394dc622d86675e30ff1281dff..7ec3a5f1402ceb1d6365c731b6d467235a01ceda 100644
--- a/ci-scripts/xml_files/fr1_multi_node_test.xml
+++ b/ci-scripts/xml_files/fr1_nsa_quectel.xml
@@ -21,19 +21,43 @@
 
 -->
 <testCaseList>
-	<htmlTabRef>test-fr1-tm1</htmlTabRef>
-	<htmlTabName>Test-FR1-TM1</htmlTabName>
+	<htmlTabRef>TEST-NSA-FR1-TM1</htmlTabRef>
+	<htmlTabName>NSA Ping DL UL with QUECTEL</htmlTabName>
 	<htmlTabIcon>tasks</htmlTabIcon>
 	<repeatCount>1</repeatCount>
 	<TestCaseRequestedList>
  030000
  040000
+ 000002
+ 010000
+ 000001
+ 050000
+ 050001
  000001
- 070001
  070000
+ 000001
+ 070001
+ 000001
+ 010002
+ 080001
+ 080000
 	</TestCaseRequestedList>
-	<TestCaseExclusionList>
-	</TestCaseExclusionList>
+	<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="030000">
 		<class>Initialize_eNB</class>
@@ -42,12 +66,14 @@
 		<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 (3/4 sampling rate)</desc>
-		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E</Initialize_eNB_args>
+		<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>
@@ -56,21 +82,67 @@
 	<testCase id="000001">
 		<class>IdleSleep</class>
 		<desc>Sleep</desc>
-		<idle_sleep_time_in_sec>30</idle_sleep_time_in_sec>
+		<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="070001">
+	<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_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_ran_ue_base.xml b/ci-scripts/xml_files/fr1_nsa_quectel_long.xml
similarity index 78%
rename from ci-scripts/xml_files/fr1_ran_ue_base.xml
rename to ci-scripts/xml_files/fr1_nsa_quectel_long.xml
index 847967f81e9f9808d982f89615eed1c1be9a079d..21ff7a63c5b3dfbc4712dd036233b6fdb66f61e1 100644
--- a/ci-scripts/xml_files/fr1_ran_ue_base.xml
+++ b/ci-scripts/xml_files/fr1_nsa_quectel_long.xml
@@ -21,49 +21,40 @@
 
 -->
 <testCaseList>
-	<htmlTabRef>TEST-FR1-TM1</htmlTabRef>
-	<htmlTabName>FR1</htmlTabName>
+	<htmlTabRef>TEST-NSA-FR1-TM1</htmlTabRef>
+	<htmlTabName>NSA Ping DL UL with QUECTEL (Longer)</htmlTabName>
 	<htmlTabIcon>tasks</htmlTabIcon>
+	<repeatCount>1</repeatCount>
 	<TestCaseRequestedList>
- 010000
  030000
  040000
- 010001
+ 000002
+ 010000
  000001
  050000
  050001
- 050002
- 050002
  000001
- 060000
- 060001
- 000001
- 010002
+ 070000
  000001
  070001
- 070000
- 010003
+ 000001
+ 010002
+ 080001
+ 080000
 	</TestCaseRequestedList>
 	<TestCaseExclusionList></TestCaseExclusionList>
 
 	<testCase id="010000">
 		<class>Initialize_UE</class>
-		<desc>Initialize UE</desc>
+		<desc>Initialize Quectel</desc>
+		<id>idefix</id>
 	</testCase>
 
-	<testCase id="010003">
-		<class>Terminate_UE</class>
-		<desc>Terminate UE</desc>
-	</testCase>
-
-	<testCase id="010001">
-		<class>Attach_UE</class>
-		<desc>Attach UE</desc>
-	</testCase>
 
 	<testCase id="010002">
-		<class>Detach_UE</class>
-		<desc>Detach UE</desc>
+		<class>Terminate_UE</class>
+		<desc>Terminate Quectel</desc>
+		<id>idefix</id>
 	</testCase>
 
 
@@ -74,63 +65,70 @@
 		<eNB_instance>0</eNB_instance>
 		<eNB_serverId>0</eNB_serverId>
 		<air_interface>lte</air_interface>
-   </testCase>
+		<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</Initialize_eNB_args>
+		<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: 5pings in 1sec</desc>
-		<ping_args>-c 5 -i 0.2</ping_args>
-		<ping_packetloss_threshold>50</ping_packetloss_threshold>
-	</testCase>
-
-	<testCase id="050002">
 		<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="060000">
+	<testCase id="070000">
 		<class>Iperf</class>
-		<desc>iperf (DL/1Mbps/UDP)(30 sec)(single-ue profile)</desc>
-		<iperf_args>-u -b 1M -t 30 -i 1</iperf_args>
+		<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="060001">
+	<testCase id="070001">
 		<class>Iperf</class>
-		<desc>iperf (UL/1Mbps/UDP)(30 sec)(single-ue profile)</desc>
-		<iperf_args>-u -b 1M -t 30 -i 1 -R</iperf_args>
+		<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="070000">
+
+	<testCase id="080000">
 		<class>Terminate_eNB</class>
 		<desc>Terminate eNB</desc>
 		<eNB_instance>0</eNB_instance>
@@ -138,7 +136,7 @@
 		<air_interface>lte</air_interface>
 	</testCase>
 
-	<testCase id="070001">
+	<testCase id="080001">
 		<class>Terminate_eNB</class>
 		<desc>Terminate gNB</desc>
 		<eNB_instance>1</eNB_instance>
diff --git a/ci-scripts/xml_files/fr1_sa_quectel.xml b/ci-scripts/xml_files/fr1_sa_quectel.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4c8fba0611be738bc6732ad12c2804e40fcf87ed
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_sa_quectel.xml
@@ -0,0 +1,125 @@
+<!--
+
+ 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-SA-FR1-TM1</htmlTabRef>
+	<htmlTabName>SA Ping DL UL with QUECTEL</htmlTabName>
+	<htmlTabIcon>tasks</htmlTabIcon>
+	<repeatCount>1</repeatCount>
+	<TestCaseRequestedList>
+ 040000
+ 000002
+ 010000
+ 000001
+ 050000
+ 000001
+ 010002
+ 080000
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="010000">
+		<class>Initialize_UE</class>
+		<desc>Initialize Quectel</desc>
+		<id>nrmodule2_quectel</id>
+		<UE_Trace>yes</UE_Trace>
+	</testCase>
+
+
+	<testCase id="010002">
+		<class>Terminate_UE</class>
+		<desc>Terminate Quectel</desc>
+		<id>nrmodule2_quectel</id>
+	</testCase>
+
+
+	<testCase id="040000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize gNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf --sa -q</Initialize_eNB_args>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<air_interface>nr</air_interface>
+		<eNB_Trace>yes</eNB_Trace>
+		<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
+	</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>nrmodule2_quectel</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>nrmodule2_quectel</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>nrmodule2_quectel</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>nrmodule2_quectel</id>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
+		<iperf_profile>single-ue</iperf_profile>
+	</testCase>
+
+
+	<testCase id="080000">
+		<class>Terminate_eNB</class>
+		<desc>Terminate gNB</desc>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<air_interface>nr</air_interface>
+	</testCase>
+
+</testCaseList>
+
diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9e798afdc488ca4d13b4c88d7cd4d1976fbbdfb7
--- /dev/null
+++ b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml
@@ -0,0 +1,53 @@
+<!--
+
+ 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>gNB-PHY-Test</htmlTabRef>
+        <htmlTabName>Run-gNB-PHY-Test</htmlTabName>
+        <htmlTabIcon>tasks</htmlTabIcon>	
+	<repeatCount>3</repeatCount>
+	<TestCaseRequestedList>
+090101 000001 090109
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+	
+        <testCase id="090101">
+                <class>Initialize_eNB</class>
+                <desc>Initialize gNB USRP</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test -q -U 787200 -T 106 -t 28 -D 130175 -m 28 -M 106</Initialize_eNB_args>
+		<air_interface>NR</air_interface>
+        </testCase>
+
+	<testCase id="000001">
+		<class>IdleSleep</class>
+		<desc>Sleep</desc>
+		<idle_sleep_time_in_sec>300</idle_sleep_time_in_sec>
+	</testCase>
+
+
+        <testCase id="090109">
+                <class>Terminate_eNB</class>
+                <desc>Terminate gNB</desc>
+		<air_interface>NR</air_interface>
+        </testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_build.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_build.xml
index ab221c918d50ac74a7832b3b6b7f2ba9933a6d1b..d383dbb61b50e8b019ff3e4d31747c50f1485057 100644
--- a/ci-scripts/xml_files/if4p5_usrp210_band40_build.xml
+++ b/ci-scripts/xml_files/if4p5_usrp210_band40_build.xml
@@ -33,7 +33,7 @@
 	<testCase id="010101">
 		<class>Build_eNB</class>
 		<desc>Build eNB (USRP -- Ethernet Fronthaul)</desc>
-		<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
+		<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
 	</testCase>
 
 </testCaseList>
diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml
index ab221c918d50ac74a7832b3b6b7f2ba9933a6d1b..d383dbb61b50e8b019ff3e4d31747c50f1485057 100644
--- a/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml
+++ b/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml
@@ -33,7 +33,7 @@
 	<testCase id="010101">
 		<class>Build_eNB</class>
 		<desc>Build eNB (USRP -- Ethernet Fronthaul)</desc>
-		<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
+		<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
 	</testCase>
 
 </testCaseList>
diff --git a/ci-scripts/xml_files/multi_rru_band38_build.xml b/ci-scripts/xml_files/multi_rru_band38_build.xml
index ba45eab10a35e8db259457d7578f3a1e694761ad..1370a3a3962e435e802d2e3118f98d2439971d90 100644
--- a/ci-scripts/xml_files/multi_rru_band38_build.xml
+++ b/ci-scripts/xml_files/multi_rru_band38_build.xml
@@ -26,7 +26,7 @@
 	<htmlTabIcon>wrench</htmlTabIcon>
 	<TestCaseRequestedList>
  010101 010102 010103
- 000101 000102 000103
+ 000102 000103 000101
 	</TestCaseRequestedList>
 	<TestCaseExclusionList></TestCaseExclusionList>
 
@@ -50,7 +50,7 @@
 	<testCase id="010102">
 		<class>Build_eNB</class>
 		<desc>Build Master RRU</desc>
-		<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
+		<Build_eNB_args>-w USRP -c --RU --ninja</Build_eNB_args>
 		<eNB_instance>1</eNB_instance>
 		<eNB_serverId>1</eNB_serverId>
 		<backgroundBuild>True</backgroundBuild>
@@ -59,7 +59,7 @@
 	<testCase id="000102">
 		<class>WaitEndBuild_eNB</class>
 		<desc>Wait for end of Build Master RRU</desc>
-		<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
+		<Build_eNB_args>-w USRP -c --RU --ninja</Build_eNB_args>
 		<eNB_instance>1</eNB_instance>
 		<eNB_serverId>1</eNB_serverId>
 	</testCase>
@@ -67,7 +67,7 @@
 	<testCase id="010103">
 		<class>Build_eNB</class>
 		<desc>Build Slave RRU</desc>
-		<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
+		<Build_eNB_args>-w USRP -c --RU --ninja</Build_eNB_args>
 		<eNB_instance>2</eNB_instance>
 		<eNB_serverId>2</eNB_serverId>
 		<backgroundBuild>True</backgroundBuild>
@@ -76,7 +76,7 @@
 	<testCase id="000103">
 		<class>WaitEndBuild_eNB</class>
 		<desc>Wait for end of Build Slave RRU</desc>
-		<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
+		<Build_eNB_args>-w USRP -c --RU --ninja</Build_eNB_args>
 		<eNB_instance>2</eNB_instance>
 		<eNB_serverId>2</eNB_serverId>
 	</testCase>
diff --git a/ci-scripts/xml_files/physim_deploy_run.xml b/ci-scripts/xml_files/physim_deploy_run.xml
new file mode 100644
index 0000000000000000000000000000000000000000..63152c1fb55808c2169b62b09bf4a0162d2b91ca
--- /dev/null
+++ b/ci-scripts/xml_files/physim_deploy_run.xml
@@ -0,0 +1,37 @@
+<!--
+
+ 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>build-tab</htmlTabRef>
+	<htmlTabName>Physical Simulators Check</htmlTabName>
+	<htmlTabIcon>wrench</htmlTabIcon>
+	<TestCaseRequestedList>
+ 010201
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="010201">
+		<class>Deploy_Run_PhySim</class>
+		<desc>Deploy and run physical simulator on openshift</desc>
+	</testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/sa_cn5g_closure.xml b/ci-scripts/xml_files/sa_cn5g_closure.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7174da3b7bb28d8125ce465d0f8ebacdc140cce2
--- /dev/null
+++ b/ci-scripts/xml_files/sa_cn5g_closure.xml
@@ -0,0 +1,37 @@
+<!--
+
+ 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>cn5g-closure</htmlTabRef>
+	<htmlTabName>CN5G-Closure</htmlTabName>
+	<htmlTabIcon>log-out</htmlTabIcon>
+	<TestCaseRequestedList>
+060000
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="060000">
+		<class>Terminate_5GCN</class>
+		<desc>Terminate 5G Core</desc>
+	</testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/sa_cn5g_start.xml b/ci-scripts/xml_files/sa_cn5g_start.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a524610569e80fd2cf659969d558b4d20cf263d6
--- /dev/null
+++ b/ci-scripts/xml_files/sa_cn5g_start.xml
@@ -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
+
+-->
+<testCaseList>
+	<htmlTabRef>cn5g-start-tab</htmlTabRef>
+	<htmlTabName>CN5G-Start</htmlTabName>
+	<htmlTabIcon>log-in</htmlTabIcon>
+	<TestCaseRequestedList>
+ 000100
+	</TestCaseRequestedList>
+	<TestCaseExclusionList>
+	</TestCaseExclusionList>
+
+	<testCase id="000100">
+		<class>Initialize_5GCN</class>
+		<desc>Initialize 5G Core</desc>
+	</testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml
index c5a912a33d9a112c4ea4b0a07ee5dd5c406fcdbd..0ac6bfcc0d4f0c1cc7295f19d8a4adbabeb6cbc8 100644
--- a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml
+++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml
@@ -42,7 +42,7 @@
 	<testCase id="010102">
 		<class>Build_eNB</class>
 		<desc>Build Slave eNB (USRP)</desc>
-		<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
+		<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
 		<eNB_instance>1</eNB_instance>
 		<eNB_serverId>1</eNB_serverId>
 	</testCase>
diff --git a/ci-scripts/yaml_files/4g_rfsimulator/README.md b/ci-scripts/yaml_files/4g_rfsimulator/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..b2a7f8e30cc74622d02435986513aa01863c04da
--- /dev/null
+++ b/ci-scripts/yaml_files/4g_rfsimulator/README.md
@@ -0,0 +1,504 @@
+<table style="border-collapse: collapse; border: none;">
+  <tr style="border-collapse: collapse; border: none;">
+    <td style="border-collapse: collapse; border: none;">
+      <a href="http://www.openairinterface.org/">
+         <img src="../../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
+         </img>
+      </a>
+    </td>
+    <td style="border-collapse: collapse; border: none; vertical-align: center;">
+      <b><font size = "5">OAI Full Stack 4G-LTE RF simulation with containers</font></b>
+    </td>
+  </tr>
+</table>
+
+This page is only valid for an `Ubuntu18` host.
+
+**TABLE OF CONTENTS**
+
+1. [Retrieving the images on Docker-Hub](#1-retrieving-the-images-on-docker-hub)
+2. [Deploy containers](#2-deploy-containers)
+   1. [Deploy and Configure Cassandra Database](#21-deploy-and-configure-cassandra-database)
+   2. [Deploy OAI CN4G containers](#22-deploy-oai-cn4g-containers)
+   3. [Deploy OAI eNB in RF simulator mode](#23-deploy-oai-enb-in-rf-simulator-mode)
+   4. [Deploy OAI LTE UE in RF simulator mode](#24-deploy-oai-lte-ue-in-rf-simulator-mode)
+3. [Check traffic](#3-check-traffic)
+4. [Un-deployment](#4-un-deployment)
+5. [Explanation on the configuration](#5-explanation-on-the-configuration)
+   1. [UE IMSI and Keys](#51-ue-imsi-and-keys)
+   2. [PLMN and TAI](#52-plmn-and-tai)
+   3. [Access to Internet](#53-access-to-internet)
+
+# 1. Retrieving the images on Docker-Hub #
+
+Currently the images are hosted under the user account `rdefosseoai`.
+
+This may change in the future.
+
+Once again you may need to log on [docker-hub](https://hub.docker.com/) if your organization has reached pulling limit as `anonymous`.
+
+```bash
+$ docker login
+Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
+Username:
+Password:
+```
+
+Now pull images.
+
+```bash
+$ docker pull cassandra:2.1
+$ docker pull rdefosseoai/oai-hss:latest
+$ docker pull rdefosseoai/oai-mme:latest
+$ docker pull rdefosseoai/oai-spgwc:latest
+$ docker pull rdefosseoai/oai-spgwu-tiny:latest
+
+$ docker pull rdefosseoai/oai-enb:develop
+$ docker pull rdefosseoai/oai-lte-ue:develop
+```
+
+And **re-tag** them for tutorials' docker-compose file to work.
+
+```bash
+$ docker image tag rdefosseoai/oai-spgwc:latest oai-spgwc:latest
+$ docker image tag rdefosseoai/oai-hss:latest oai-hss:latest
+$ docker image tag rdefosseoai/oai-spgwu-tiny:latest oai-spgwu-tiny:latest 
+$ docker image tag rdefosseoai/oai-mme:latest oai-mme:latest
+
+$ docker image tag rdefosseoai/oai-enb:develop oai-enb:develop
+$ docker image tag rdefosseoai/oai-lte-ue:develop oai-lte-ue:develop
+```
+
+```bash
+$ docker logout
+```
+
+How to build the Traffic-Generator image is explained [here](https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master/docs/GENERATE_TRAFFIC.md#1-build-a-traffic-generator-image).
+
+# 2. Deploy containers #
+
+**CAUTION: this SHALL be done in multiple steps.**
+
+**Just `docker-compose up -d` WILL NOT WORK!**
+
+All the following commands **SHALL** be run from the `ci-scripts/yaml_files/4g_rfsimulator` folder.
+
+## 2.1. Deploy and Configure Cassandra Database ##
+
+It is very crutial that the Cassandra DB is fully configured before you do anything else!
+
+```bash
+$ cd ci-scripts/yaml_files/4g_rfsimulator
+$ docker-compose up -d db_init
+Creating network "rfsim4g-oai-private-net" with the default driver
+Creating network "rfsim4g-oai-public-net" with the default driver
+Creating rfsim4g-cassandra ... done
+Creating rfsim4g-db-init   ... done
+
+$ docker logs rfsim4g-db-init --follow
+Connection error: ('Unable to connect to any servers', {'192.168.68.2': error(111, "Tried connecting to [('192.168.68.2', 9042)]. Last error: Connection refused")})
+...
+Connection error: ('Unable to connect to any servers', {'192.168.68.2': error(111, "Tried connecting to [('192.168.68.2', 9042)]. Last error: Connection refused")})
+OK
+```
+
+**You SHALL wait until you HAVE the `OK` message in the logs!**
+
+```bash
+$ docker rm rfsim4g-db-init
+```
+
+At this point, you can prepare a capture on the newly-created public docker bridge:
+
+```bash
+$ ifconfig rfsim4g-public
+        inet 192.168.61.1  netmask 255.255.255.192  broadcast 192.168.61.63
+        ether 02:42:8f:dd:ba:5a  txqueuelen 0  (Ethernet)
+        RX packets 0  bytes 0 (0.0 B)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 0  bytes 0 (0.0 B)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+$ sudo tshark -i rfsim4g-public -f 'port 3868 or port 2123 or port 36412 or port 36422 or port 46520 or port 8805' -w /tmp/my-oai-control-plane.pcap
+```
+
+**BE CAREFUL: please use that filter or you will also capture the data-plane with IQ samples between `eNB` and `LTE-UE`.**
+
+**and your capture WILL become huge (10s of Gbytes).**
+
+## 2.2. Deploy OAI CN4G containers ##
+
+```bash
+$ docker-compose up -d oai_mme oai_spgwu trf_gen
+rfsim4g-cassandra is up-to-date
+Creating rfsim4g-trf-gen   ... done
+Creating rfsim4g-oai-hss ... done
+Creating rfsim4g-oai-mme ... done
+Creating rfsim4g-oai-spgwc ... done
+Creating rfsim4g-oai-spgwu-tiny ... done
+```
+
+You shall wait until all containers are `healthy`. About 10 seconds!
+
+```bash
+$ docker-compose ps -a
+         Name                       Command                  State                            Ports                      
+-------------------------------------------------------------------------------------------------------------------------
+rfsim4g-cassandra        docker-entrypoint.sh cassa ...   Up (healthy)   7000/tcp, 7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp
+rfsim4g-oai-hss          /openair-hss/bin/entrypoin ...   Up (healthy)   5868/tcp, 9042/tcp, 9080/tcp, 9081/tcp          
+rfsim4g-oai-mme          /openair-mme/bin/entrypoin ...   Up (healthy)   2123/udp, 3870/tcp, 5870/tcp                    
+rfsim4g-oai-spgwc        /openair-spgwc/bin/entrypo ...   Up (healthy)   2123/udp, 8805/udp                              
+rfsim4g-oai-spgwu-tiny   /openair-spgwu-tiny/bin/en ...   Up (healthy)   2152/udp, 8805/udp                              
+rfsim4g-trf-gen          /bin/bash -c ip route add  ...   Up (healthy)                                                   
+```
+
+## 2.3. Deploy OAI eNB in RF simulator mode ##
+
+```bash
+$ docker-compose up -d enb
+Creating rfsim4g-oai-enb ... done
+```
+
+Again wait for the healthy state:
+
+```bash
+$ docker-compose ps -a
+         Name                       Command                  State                            Ports                      
+-------------------------------------------------------------------------------------------------------------------------
+rfsim4g-cassandra        docker-entrypoint.sh cassa ...   Up (healthy)   7000/tcp, 7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp
+rfsim4g-oai-enb          /opt/oai-enb/bin/entrypoin ...   Up (healthy)   2152/udp, 36412/udp, 36422/udp                  
+rfsim4g-oai-hss          /openair-hss/bin/entrypoin ...   Up (healthy)   5868/tcp, 9042/tcp, 9080/tcp, 9081/tcp          
+rfsim4g-oai-mme          /openair-mme/bin/entrypoin ...   Up (healthy)   2123/udp, 3870/tcp, 5870/tcp                    
+rfsim4g-oai-spgwc        /openair-spgwc/bin/entrypo ...   Up (healthy)   2123/udp, 8805/udp                              
+rfsim4g-oai-spgwu-tiny   /openair-spgwu-tiny/bin/en ...   Up (healthy)   2152/udp, 8805/udp                              
+rfsim4g-trf-gen          /bin/bash -c ip route add  ...   Up (healthy)                                    
+```
+
+Check if the eNB connected to MME:
+
+```bash
+$ docker logs rfsim4g-oai-mme
+...
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0039    ======================================= STATISTICS ============================================
+
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0042                   |   Current Status| Added since last display|  Removed since last display |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0048    Connected eNBs |          0      |              0              |             0               |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0054    Attached UEs   |          0      |              0              |             0               |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0060    Connected UEs  |          0      |              0              |             0               |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0066    Default Bearers|          0      |              0              |             0               |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0072    S1-U Bearers   |          0      |              0              |             0               |
+
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0075    ======================================= STATISTICS ============================================
+
+DEBUG SCTP   rc/sctp/sctp_primitives_server.c:0469    Client association changed: 0
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0101    ----------------------
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0102    SCTP Status:
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0103    assoc id .....: 675
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0104    state ........: 4
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0105    instrms ......: 2
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0106    outstrms .....: 2
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0108    fragmentation : 1452
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0109    pending data .: 0
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0110    unack data ...: 0
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0111    rwnd .........: 106496
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0112    peer info     :
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0114        state ....: 2
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0116        cwnd .....: 4380
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0118        srtt .....: 0
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0120        rto ......: 3000
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0122        mtu ......: 1500
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0123    ----------------------
+DEBUG SCTP   rc/sctp/sctp_primitives_server.c:0479    New connection
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0205    ----------------------
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0206    Local addresses:
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0217        - [192.168.61.3]
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0234    ----------------------
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0151    ----------------------
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0152    Peer addresses:
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0163        - [192.168.61.20]
+DEBUG SCTP   enair-mme/src/sctp/sctp_common.c:0178    ----------------------
+DEBUG SCTP   rc/sctp/sctp_primitives_server.c:0554    SCTP RETURNING!!
+DEBUG SCTP   rc/sctp/sctp_primitives_server.c:0547    [675][44] Msg of length 51 received from port 36412, on stream 0, PPID 18
+DEBUG SCTP   rc/sctp/sctp_primitives_server.c:0554    SCTP RETURNING!!
+DEBUG S1AP   mme/src/s1ap/s1ap_mme_handlers.c:2826    Create eNB context for assoc_id: 675
+DEBUG S1AP   mme/src/s1ap/s1ap_mme_handlers.c:0361    S1-Setup-Request macroENB_ID.size 3 (should be 20)
+DEBUG S1AP   mme/src/s1ap/s1ap_mme_handlers.c:0321    New s1 setup request incoming from macro eNB id: 00e01
+DEBUG S1AP   mme/src/s1ap/s1ap_mme_handlers.c:0423    Adding eNB to the list of served eNBs
+DEBUG S1AP   mme/src/s1ap/s1ap_mme_handlers.c:0438    Adding eNB id 3585 to the list of served eNBs
+DEBUG SCTP   rc/sctp/sctp_primitives_server.c:0283    [44][675] Sending buffer 0x7f9394009f90 of 27 bytes on stream 0 with ppid 18
+DEBUG SCTP   rc/sctp/sctp_primitives_server.c:0296    Successfully sent 27 bytes on stream 0
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0039    ======================================= STATISTICS ============================================
+
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0042                   |   Current Status| Added since last display|  Removed since last display |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0048    Connected eNBs |          1      |              1              |             0               |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0054    Attached UEs   |          0      |              0              |             0               |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0060    Connected UEs  |          0      |              0              |             0               |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0066    Default Bearers|          0      |              0              |             0               |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0072    S1-U Bearers   |          0      |              0              |             0               |
+
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0075    ======================================= STATISTICS ============================================
+...
+```
+
+## 2.4. Deploy OAI LTE UE in RF simulator mode ##
+
+```bash
+$ docker-compose up -d oai_ue0
+Creating rfsim4g-oai-lte-ue0 ... done
+```
+
+Again a bit of patience:
+
+```bash
+$ docker-compose ps -a
+         Name                       Command                  State                            Ports                      
+-------------------------------------------------------------------------------------------------------------------------
+rfsim4g-cassandra        docker-entrypoint.sh cassa ...   Up (healthy)   7000/tcp, 7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp
+rfsim4g-oai-enb          /opt/oai-enb/bin/entrypoin ...   Up (healthy)   2152/udp, 36412/udp, 36422/udp                  
+rfsim4g-oai-hss          /openair-hss/bin/entrypoin ...   Up (healthy)   5868/tcp, 9042/tcp, 9080/tcp, 9081/tcp          
+rfsim4g-oai-lte-ue0      /opt/oai-lte-ue/bin/entryp ...   Up (healthy)   10000/tcp                                       
+rfsim4g-oai-mme          /openair-mme/bin/entrypoin ...   Up (healthy)   2123/udp, 3870/tcp, 5870/tcp                    
+rfsim4g-oai-spgwc        /openair-spgwc/bin/entrypo ...   Up (healthy)   2123/udp, 8805/udp                              
+rfsim4g-oai-spgwu-tiny   /openair-spgwu-tiny/bin/en ...   Up (healthy)   2152/udp, 8805/udp                              
+rfsim4g-trf-gen          /bin/bash -c ip route add  ...   Up (healthy)                                             
+Creating rfsim4g-oai-enb ... done
+```
+
+Making sure the OAI UE is connected:
+
+```bash
+$ docker logs rfsim4g-oai-enb
+...
+[RRC]   RRCConnectionReconfiguration Encoded 1098 bits (138 bytes)
+[RRC]   [eNB 0] Frame 0, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes 138, UE id 617b)
+[RRC]   sent RRC_DCCH_DATA_REQ to TASK_PDCP_ENB
+[PDCP]   [FRAME 00000][eNB][MOD 00][RNTI 617b][SRB 02]  Action ADD  LCID 2 (SRB id 2) configured with SN size 5 bits and RLC AM
+[PDCP]   [FRAME 00000][eNB][MOD 00][RNTI 617b][DRB 01]  Action ADD  LCID 3 (DRB id 1) configured with SN size 12 bits and RLC AM
+[SCTP]   Successfully sent 46 bytes on stream 1 for assoc_id 676
+[RRC]   [FRAME 00000][eNB][MOD 00][RNTI 617b] UE State = RRC_RECONFIGURED (default DRB, xid 0)
+[PDCP]   [FRAME 00000][eNB][MOD 00][RNTI 617b][SRB 02]  Action MODIFY LCID 2 RB id 2 reconfigured with SN size 5 and RLC AM 
+[PDCP]   [FRAME 00000][eNB][MOD 00][RNTI 617b][DRB 01]  Action MODIFY LCID 3 RB id 1 reconfigured with SN size 1 and RLC AM 
+[RRC]   [eNB 0] Frame  0 CC 0 : SRB2 is now active
+[RRC]   [eNB 0] Frame  0 : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE rnti 617b, reconfiguring DRB 1/LCID 3
+[RRC]   [eNB 0] Frame  0 : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete, reconfiguring DRB 1/LCID 3
+[MAC]   UE 0 RNTI 617b adding LC 3 idx 2 to scheduling control (total 3)
+[MAC]   Added physicalConfigDedicated 0x7f98e0004950 for 0.0
+[S1AP]   initial_ctxt_resp_p: e_rab ID 5, enb_addr 192.168.61.20, SIZE 4 
+[SCTP]   Successfully sent 40 bytes on stream 1 for assoc_id 676
+[SCTP]   Successfully sent 61 bytes on stream 1 for assoc_id 676
+...
+```
+
+On the MME:
+
+```bash
+$ docker logs rfsim4g-oai-mme
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0039    ======================================= STATISTICS ============================================
+
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0042                   |   Current Status| Added since last display|  Removed since last display |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0048    Connected eNBs |          1      |              0              |             0               |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0054    Attached UEs   |          1      |              0              |             0               |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0060    Connected UEs  |          1      |              0              |             0               |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0066    Default Bearers|          0      |              0              |             0               |
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0072    S1-U Bearers   |          0      |              0              |             0               |
+
+DEBUG MME-AP src/mme_app/mme_app_statistics.c:0075    ======================================= STATISTICS ============================================
+```
+
+On the LTE UE:
+
+```bash
+$ docker exec rfsim4g-oai-lte-ue0 /bin/bash -c "ifconfig"
+eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
+        inet 192.168.61.30  netmask 255.255.255.192  broadcast 192.168.61.63
+        ether 02:42:c0:a8:3d:1e  txqueuelen 0  (Ethernet)
+        RX packets 1109931  bytes 8078031934 (8.0 GB)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 1232068  bytes 7798928848 (7.7 GB)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+
+lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
+        inet 127.0.0.1  netmask 255.0.0.0
+        loop  txqueuelen 1000  (Local Loopback)
+        RX packets 0  bytes 0 (0.0 B)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 0  bytes 0 (0.0 B)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+
+oaitun_ue1: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
+        inet 12.0.0.2  netmask 255.0.0.0  destination 12.0.0.2
+        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
+        RX packets 0  bytes 0 (0.0 B)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 0  bytes 0 (0.0 B)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+
+oaitun_uem1: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
+        inet 10.0.2.2  netmask 255.255.255.0  destination 10.0.2.2
+        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
+        RX packets 0  bytes 0 (0.0 B)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 0  bytes 0 (0.0 B)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+```
+
+The tunnel `oaitun_ue1` SHALL be mounted and with an IP address in the `12.0.0.xxx` range.
+
+# 3. Check traffic #
+
+```bash
+$ docker exec rfsim4g-oai-lte-ue0 /bin/bash -c "ping -c 2 www.lemonde.fr"
+PING s2.shared.global.fastly.net (151.101.122.217) 56(84) bytes of data.
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=1 ttl=54 time=12.9 ms
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=2 ttl=54 time=12.9 ms
+
+--- s2.shared.global.fastly.net ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1001ms
+rtt min/avg/max/mdev = 12.940/12.965/12.990/0.025 ms
+
+$ docker exec rfsim4g-oai-lte-ue0 /bin/bash -c "ping -I oaitun_ue1 -c 2 www.lemonde.fr"
+PING s2.shared.global.fastly.net (151.101.122.217) from 12.0.0.2 oaitun_ue1: 56(84) bytes of data.
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=1 ttl=53 time=23.6 ms
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=2 ttl=53 time=29.5 ms
+
+--- s2.shared.global.fastly.net ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1001ms
+rtt min/avg/max/mdev = 23.659/26.626/29.593/2.967 ms
+```
+
+The 1st ping command is NOT using the OAI stack. My network infrastructure has a response of `13 ms` to reach this website.
+
+The 2nd ping command is using the OAI stack. So the stack takes `26.6 - 12.9 = 13.7 ms`.
+
+# 4. Un-deployment #
+
+```bash
+$ docker-compose down
+Stopping rfsim4g-oai-lte-ue0    ... done
+Stopping rfsim4g-oai-enb        ... done
+Stopping rfsim4g-oai-spgwu-tiny ... done
+Stopping rfsim4g-oai-spgwc      ... done
+Stopping rfsim4g-oai-mme        ... done
+Stopping rfsim4g-oai-hss        ... done
+Stopping rfsim4g-trf-gen        ... done
+Stopping rfsim4g-cassandra      ... done
+Removing rfsim4g-oai-lte-ue0    ... done
+Removing rfsim4g-oai-enb        ... done
+Removing rfsim4g-oai-spgwu-tiny ... done
+Removing rfsim4g-oai-spgwc      ... done
+Removing rfsim4g-oai-mme        ... done
+Removing rfsim4g-oai-hss        ... done
+Removing rfsim4g-trf-gen        ... done
+Removing rfsim4g-cassandra      ... done
+Removing network rfsim4g-oai-private-net
+Removing network rfsim4g-oai-public-net
+```
+
+# 5. Explanation on the configuration #
+
+With a single `docker-compose.yml` file, it is easier to explain how I made the full connection.
+
+Try to modify as little as possible. And if you don't understand a field/value, you'd better NOT modify it.
+
+## 5.1. UE IMSI and Keys ##
+
+in HSS config:
+
+```yaml
+            OP_KEY: 1006020f0a478bf6b699f15c062e42b3
+            LTE_K: fec86ba6eb707ed08905757b1bb44b8f
+            APN1: oai.ipv4
+            APN2: internet
+            FIRST_IMSI: 208960100000001
+            NB_USERS: 10
+```
+
+in UE config:
+
+```yaml
+            MCC: '208'
+            MNC: '96'
+            SHORT_IMSI: '0100000001'
+            LTE_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
+            OPC: 'c42449363bbad02b66d16bc975d77cc1'
+            MSISDN: '001011234561010'
+            HPLMN: 20896
+```
+
+As you can see: `LTE_K` and `LTE_KEY` are the same value. And `OP_KEY` and `OPC` can be deduced from each other. Look in HSS logs.
+
+```bash
+$ docker logs rfsim4g-oai-hss
+...
+Compute opc:
+	K:  FEC86BA6EB707ED08905757B1BB44B8F           <== `LTE_K`
+	In: 1006020F0A478BF6B699F15C062E42B3           <== `OP_KEY`
+	Rinj:   D4224B3931FD5BDDD0489A9573F93E72
+	Out:    C42449363BBAD02B66D16BC975D77CC1       <== `OPC`
+...
+```
+
+In HSS, I've provisioned 10 users starting at `208960100000001` (`FIRST_IMSI` and `NB_USERS`).
+
+My 1st UE IMSI is an aggregation of `MCC`, `MNC`, `SHORT_IMSI`.
+
+## 5.2. PLMN and TAI ##
+
+in MME config:
+
+```yaml
+            REALM: openairinterface.org
+..
+            MCC: '208'
+            MNC: '96'
+            MME_GID: 32768
+            MME_CODE: 3
+            TAC_0: 1
+            TAC_1: 2
+            TAC_2: 3
+            MME_FQDN: mme.openairinterface.org
+```
+
+in SPGW-C/-U configs:
+
+```yaml
+            MCC: '208'
+            MNC: '96'
+            MNC03: '096'
+            TAC: 1
+            GW_ID: 1
+            REALM: openairinterface.org
+```
+
+in eNB config:
+
+```yaml
+            MCC: '208'
+            MNC: '96'
+            MNC_LENGTH: 2
+            TAC: 1
+```
+
+The values SHALL match, and `TAC` shall match `TAC_0` from MME.
+
+## 5.3. Access to Internet ##
+
+In my traffic test, I was able to ping outside of my local network.
+
+in SPGW-C config:
+
+```yaml
+            DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
+            DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
+            PUSH_PROTOCOL_OPTION: 'true'
+```
+
+in SPGW-U config:
+
+```yaml
+            NETWORK_UE_NAT_OPTION: 'yes'
+```
+
+Please put your own DNS server IP adress.
+
+And you may have to play with `PUSH_PROTOCOL_OPTION` and `NETWORK_UE_NAT_OPTION` depending on your network.
+
diff --git a/ci-scripts/yaml_files/4g_rfsimulator/docker-compose.yml b/ci-scripts/yaml_files/4g_rfsimulator/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..32e4bd41e8146f4b6e52a16324948d2b18f66e9c
--- /dev/null
+++ b/ci-scripts/yaml_files/4g_rfsimulator/docker-compose.yml
@@ -0,0 +1,272 @@
+version: '3.8'
+
+services:
+    cassandra:
+        image: cassandra:2.1
+        container_name: rfsim4g-cassandra
+        networks:
+            private_net:
+                ipv4_address: 192.168.68.2
+        environment:
+            CASSANDRA_CLUSTER_NAME: "OAI HSS Cluster"
+            CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch
+        healthcheck:
+            test: /bin/bash -c "nodetool status"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    db_init:
+        image: cassandra:2.1
+        container_name: rfsim4g-db-init
+        depends_on: [cassandra]
+        deploy:
+            restart_policy:
+                condition: on-failure
+                max_attempts: 10
+        networks:
+            private_net:
+                ipv4_address: 192.168.68.4
+        volumes:
+            - ./oai_db.cql:/home/oai_db.cql
+        entrypoint: /bin/bash -c "cqlsh --file /home/oai_db.cql 192.168.68.2 && echo 'OK'"
+
+    oai_hss:
+        image: oai-hss:latest
+        container_name: rfsim4g-oai-hss
+        privileged: true
+        depends_on: [cassandra]
+        networks:
+            private_net:
+                ipv4_address: 192.168.68.3
+            public_net:
+                ipv4_address: 192.168.61.2
+        environment:
+            REALM: openairinterface.org
+            HSS_FQDN: hss.openairinterface.org
+            PREFIX: /openair-hss/etc
+            cassandra_Server_IP: 192.168.68.2
+            OP_KEY: 1006020f0a478bf6b699f15c062e42b3
+            LTE_K: fec86ba6eb707ed08905757b1bb44b8f
+            APN1: oai.ipv4
+            APN2: internet
+            FIRST_IMSI: 208960100000001
+            NB_USERS: 10
+        healthcheck:
+            test: /bin/bash -c "pgrep oai_hss"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    oai_mme:
+        image: oai-mme:latest
+        container_name: rfsim4g-oai-mme
+        privileged: true
+        depends_on: [oai_hss]
+        networks:
+            public_net:
+                ipv4_address: 192.168.61.3
+        environment:
+            REALM: openairinterface.org
+            PREFIX: /openair-mme/etc
+            INSTANCE: 1
+            PID_DIRECTORY: /var/run
+            HSS_IP_ADDR: 192.168.61.2
+            HSS_HOSTNAME: hss
+            HSS_FQDN: hss.openairinterface.org
+            HSS_REALM: openairinterface.org
+            MCC: '208'
+            MNC: '96'
+            MME_GID: 32768
+            MME_CODE: 3
+            TAC_0: 1
+            TAC_1: 2
+            TAC_2: 3
+            MME_FQDN: mme.openairinterface.org
+            MME_S6A_IP_ADDR: 192.168.61.3
+            MME_INTERFACE_NAME_FOR_S1_MME: eth0
+            MME_IPV4_ADDRESS_FOR_S1_MME: 192.168.61.3
+            MME_INTERFACE_NAME_FOR_S11: eth0
+            MME_IPV4_ADDRESS_FOR_S11: 192.168.61.3
+            MME_INTERFACE_NAME_FOR_S10: lo
+            MME_IPV4_ADDRESS_FOR_S10: 127.0.0.10
+            OUTPUT: CONSOLE
+            SGW_IPV4_ADDRESS_FOR_S11_0: 192.168.61.4
+            PEER_MME_IPV4_ADDRESS_FOR_S10_0: 0.0.0.0
+            PEER_MME_IPV4_ADDRESS_FOR_S10_1: 0.0.0.0
+            MCC_SGW_0: '208'
+            MNC3_SGW_0: '096'
+            TAC_LB_SGW_0: '01'
+            TAC_HB_SGW_0: '00'
+            MCC_MME_0: '208'
+            MNC3_MME_0: '096'
+            TAC_LB_MME_0: '02'
+            TAC_HB_MME_0: '00'
+            MCC_MME_1: '208'
+            MNC3_MME_1: '096'
+            TAC_LB_MME_1: '03'
+            TAC_HB_MME_1: '00'
+            TAC_LB_SGW_TEST_0: '03'
+            TAC_HB_SGW_TEST_0: '00'
+            SGW_IPV4_ADDRESS_FOR_S11_TEST_0: 0.0.0.0
+        healthcheck:
+            test: /bin/bash -c "pgrep oai_mme"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    oai_spgwc:
+        image: oai-spgwc:latest
+        privileged: true
+        depends_on: [oai_mme]
+        container_name: rfsim4g-oai-spgwc
+        networks:
+            public_net:
+                ipv4_address: 192.168.61.4
+        environment:
+            TZ: Europe/Paris
+            SGW_INTERFACE_NAME_FOR_S11: eth0
+            PGW_INTERFACE_NAME_FOR_SX: eth0
+            DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
+            DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
+            PUSH_PROTOCOL_OPTION: 'true'
+            APN_NI_1: oai.ipv4
+            APN_NI_2: oai.ipv4_2
+            DEFAULT_APN_NI_1: oai.ipv4
+            UE_IP_ADDRESS_POOL_1: '12.0.0.2 - 12.0.0.254'
+            UE_IP_ADDRESS_POOL_2: '12.1.1.2 - 12.1.1.254'
+            MCC: '208'
+            MNC: '96'
+            MNC03: '096'
+            TAC: 1
+            GW_ID: 1
+            REALM: openairinterface.org
+        healthcheck:
+            test: /bin/bash -c "pgrep oai_spgwc"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    oai_spgwu:
+        image: oai-spgwu-tiny:latest
+        privileged: true
+        container_name: rfsim4g-oai-spgwu-tiny
+        depends_on: [oai_spgwc]
+        networks:
+            public_net:
+                ipv4_address: 192.168.61.5
+        environment:
+            TZ: Europe/Paris
+            PID_DIRECTORY: /var/run
+            INSTANCE: 1
+            SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP: eth0
+            PGW_INTERFACE_NAME_FOR_SGI: eth0
+            SGW_INTERFACE_NAME_FOR_SX: eth0
+            SPGWC0_IP_ADDRESS: 192.168.61.4
+            NETWORK_UE_IP: '12.0.0.0/24'
+            NETWORK_UE_NAT_OPTION: 'yes'
+            MCC: '208'
+            MNC: '96'
+            MNC03: '096'
+            TAC: 1
+            GW_ID: 1
+            REALM: openairinterface.org
+        healthcheck:
+            test: /bin/bash -c "pgrep oai_spgwu"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    trf_gen:
+        image: trf-gen:production
+        privileged: true
+        container_name: rfsim4g-trf-gen
+        networks:
+            public_net:
+                ipv4_address: 192.168.61.11
+        entrypoint: /bin/bash -c "ip route add 12.0.0.0/24 via 192.168.61.5 dev eth0; sleep infinity"
+        healthcheck:
+            test: /bin/bash -c "ping -c 2 192.168.61.5"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    enb:
+        image: oai-enb:develop
+        privileged: true
+        container_name: rfsim4g-oai-enb
+        networks:
+            public_net:
+                ipv4_address: 192.168.61.20
+        environment:
+            TZ: Europe/Paris
+            USE_FDD_MONO: 'yes'
+            RFSIMULATOR: enb
+            ENB_NAME: eNB-rf-sim
+            MCC: '208'
+            MNC: '96'
+            MNC_LENGTH: 2
+            TAC: 1
+            UTRA_BAND_ID: 7
+            DL_FREQUENCY_IN_MHZ: 2680
+            UL_FREQUENCY_OFFSET_IN_MHZ: 120
+            NID_CELL: 10
+            NB_PRB: 25
+            MME_S1C_IP_ADDRESS: 192.168.61.3
+            ENB_S1C_IF_NAME: eth0
+            ENB_S1C_IP_ADDRESS: 192.168.61.20
+            ENB_S1U_IF_NAME: eth0
+            ENB_S1U_IP_ADDRESS: 192.168.61.20
+            ENB_X2_IP_ADDRESS: 192.168.61.20
+            FLEXRAN_ENABLED: 'no'
+            FLEXRAN_INTERFACE_NAME: eth0
+            FLEXRAN_IPV4_ADDRESS: 192.168.61.10
+            USE_ADDITIONAL_OPTIONS: --rfsim
+        healthcheck:
+            test: /bin/bash -c "pgrep lte-softmodem"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    oai_ue0:
+        image: oai-lte-ue:develop
+        privileged: true
+        container_name: rfsim4g-oai-lte-ue0
+        networks:
+            public_net:
+                ipv4_address: 192.168.61.30
+        expose:
+            - "10000"
+        environment:
+            TZ: Europe/Paris
+            HOSTNAME: oai_ue0
+            RFSIMULATOR: 192.168.61.20
+            MCC: '208'
+            MNC: '96'
+            SHORT_IMSI: '0100000001'
+            LTE_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
+            OPC: 'c42449363bbad02b66d16bc975d77cc1'
+            MSISDN: '001011234561010'
+            HPLMN: 20896
+            USE_ADDITIONAL_OPTIONS: --rfsim -C 2680000000 -r 25 --ue-rxgain 140 --ue-txgain 120 --nokrnmod 1
+        healthcheck:
+            test: /bin/bash -c "pgrep lte-uesoftmodem"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+networks:
+    private_net:
+        name: rfsim4g-oai-private-net
+        ipam:
+            config:
+                - subnet: 192.168.68.0/26
+        driver_opts:
+            com.docker.network.bridge.name: "rfsim4g-private"
+    public_net:
+        name: rfsim4g-oai-public-net
+        ipam:
+            config:
+                - subnet: 192.168.61.0/26
+        driver_opts:
+            com.docker.network.bridge.name: "rfsim4g-public"
diff --git a/ci-scripts/yaml_files/4g_rfsimulator/oai_db.cql b/ci-scripts/yaml_files/4g_rfsimulator/oai_db.cql
new file mode 100644
index 0000000000000000000000000000000000000000..2be0a8e2e95a604801c47b7e39d4e39487273edf
--- /dev/null
+++ b/ci-scripts/yaml_files/4g_rfsimulator/oai_db.cql
@@ -0,0 +1,93 @@
+CREATE KEYSPACE IF NOT EXISTS vhss WITH replication = {'class': 'NetworkTopologyStrategy', 'DC1': '1'};
+
+CREATE TABLE IF NOT EXISTS vhss.users_imsi (
+    imsi text PRIMARY KEY,
+    access_restriction int,
+    idmmeidentity int,
+    imei text,
+    imei_sv text,
+    key text,
+    lipa_permissions text,
+    mme_cap int,
+    mmehost text,
+    mmeidentity_idmmeidentity int,
+    mmerealm text,
+    ms_ps_status text,
+    msisdn bigint,
+    niddvalidity text,
+    nir_dest_host text,
+    nir_dest_realm text,
+    opc text,
+    pgw_id int,
+    rand text,
+    rfsp_index varint,
+    sqn bigint,
+    subscription_data text,
+    ue_reachability varint,
+    urrp_mme varint,
+    user_identifier text,
+    visited_plmnid text);
+
+CREATE TABLE IF NOT EXISTS vhss.msisdn_imsi (
+	msisdn bigint PRIMARY KEY,
+	imsi text
+);
+
+CREATE TABLE IF NOT EXISTS vhss.global_ids (
+    table_name text PRIMARY KEY,
+    id counter);
+
+CREATE TABLE IF NOT EXISTS vhss.mmeidentity_host (
+    mmehost text PRIMARY KEY,
+    idmmeidentity int,
+    mmerealm text,
+    ue_reachability varint,
+    mmeisdn text);
+
+CREATE TABLE IF NOT EXISTS vhss.mmeidentity (
+    idmmeidentity int PRIMARY KEY,
+    mmehost text,
+    mmerealm text,
+    ue_reachability varint,
+    mmeisdn text);
+
+CREATE TABLE IF NOT EXISTS vhss.events (
+    scef_id text,
+    scef_ref_id bigint,
+    extid text,
+    monitoring_event_configuration text,
+    monitoring_type int,
+    msisdn bigint,
+    user_identifier text,
+    primary key (scef_id, scef_ref_id)
+);
+
+CREATE TABLE IF NOT EXISTS vhss.events_msisdn (
+    msisdn bigint,
+    scef_id text,
+    scef_ref_id bigint,
+    primary key (msisdn, scef_id, scef_ref_id)
+);
+
+CREATE TABLE IF NOT EXISTS vhss.events_extid (
+    extid text,
+    scef_id text,
+    scef_ref_id bigint,
+    primary key (extid, scef_id, scef_ref_id)
+);
+
+CREATE TABLE IF NOT EXISTS vhss.extid (
+    extid text primary key
+);
+
+CREATE TABLE IF NOT EXISTS vhss.extid_imsi (
+    extid text,
+    imsi text,
+    primary key (extid, imsi)
+);
+
+CREATE TABLE IF NOT EXISTS vhss.extid_imsi_xref (
+    imsi text,
+    extid text,
+    primary key (imsi, extid)
+);
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/README.md b/ci-scripts/yaml_files/5g_rfsimulator/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..807f1b47c55c6e6cd92632288076d83d08e2f093
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_rfsimulator/README.md
@@ -0,0 +1,396 @@
+<table style="border-collapse: collapse; border: none;">
+  <tr style="border-collapse: collapse; border: none;">
+    <td style="border-collapse: collapse; border: none;">
+      <a href="http://www.openairinterface.org/">
+         <img src="../../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
+         </img>
+      </a>
+    </td>
+    <td style="border-collapse: collapse; border: none; vertical-align: center;">
+      <b><font size = "5">OAI Full Stack 5G-NR RF simulation with containers</font></b>
+    </td>
+  </tr>
+</table>
+
+This page is only valid for an `Ubuntu18` host.
+
+**TABLE OF CONTENTS**
+
+1. [Retrieving the images on Docker-Hub](#1-retrieving-the-images-on-docker-hub)
+2. [Deploy containers](#2-deploy-containers)
+   1. [Deploy OAI 5G Core Network](#21-deploy-oai-5g-core-network)
+   2. [Deploy OAI gNB in RF simulator mode and in Standalone Mode](#22-deploy-oai-gnb-in-rf-simulator-mode-and-in-standalone-mode)
+   3. [Deploy OAI NR-UE in RF simulator mode and in Standalone Mode](#23-deploy-oai-nr-ue-in-rf-simulator-mode-and-in-standalone-mode)
+3. [Check traffic](#3-check-traffic)
+   1. [Check your Internet connectivity](#31-check-your-internet-connectivity)
+   2. [Start the iperf server inside the NR-UE container](#32-start-the-iperf-server-inside-the-nr-ue-container)
+   3. [Start the iperf client inside the ext-dn container](#33-start-the-iperf-client-inside-the-ext-dn-container)
+4. [Un-deployment](#4-un-deployment)
+
+# 1. Retrieving the images on Docker-Hub #
+
+Currently the images are hosted under the user account `rdefosseoai`.
+
+This may change in the future.
+
+Once again you may need to log on [docker-hub](https://hub.docker.com/) if your organization has reached pulling limit as `anonymous`.
+
+```bash
+$ docker login
+Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
+Username:
+Password:
+```
+
+Now pull images.
+
+```bash
+$ docker pull mysql:5.7
+$ docker pull rdefosseoai/oai-amf:latest
+$ docker pull rdefosseoai/oai-nrf:latest
+$ docker pull rdefosseoai/oai-smf:latest
+$ docker pull rdefosseoai/oai-spgwu-tiny:latest
+
+$ docker pull rdefosseoai/oai-gnb:develop
+$ docker pull rdefosseoai/oai-nr-ue:develop
+```
+
+And **re-tag** them for tutorials' docker-compose file to work.
+
+```bash
+$ docker image tag rdefosseoai/oai-amf:latest oai-amf:latest
+$ docker image tag rdefosseoai/oai-nrf:latest oai-nrf:latest
+$ docker image tag rdefosseoai/oai-smf:latest oai-smf:latest
+$ docker image tag rdefosseoai/oai-spgwu-tiny:latest oai-spgwu-tiny:latest
+
+$ docker image tag rdefosseoai/oai-gnb:develop oai-gnb:develop
+$ docker image tag rdefosseoai/oai-nr-ue:develop oai-nr-ue:develop
+```
+
+```bash
+$ docker logout
+```
+
+# 2. Deploy containers #
+
+![Deployment](./oai-end-to-end.jpg)
+
+**CAUTION: this SHALL be done in multiple steps.**
+
+**Just `docker-compose up -d` WILL NOT WORK!**
+
+All the following commands **SHALL** be run from the `ci-scripts/yaml_files/5g_rfsimulator` folder.
+
+## 2.1. Deploy OAI 5G Core Network ##
+
+```bash
+$ cd ci-scripts/yaml_files/5g_rfsimulator
+$ docker-compose up -d mysql oai-nrf oai-amf oai-smf oai-spgwu oai-ext-dn
+Creating network "rfsim5g-oai-public-net" with driver "bridge"
+Creating network "rfsim5g-oai-traffic_net-net" with driver "bridge"
+Creating rfsim5g-oai-nrf ... done
+Creating rfsim5g-mysql      ... done
+Creating rfsim5g-oai-spgwu ... done
+Creating rfsim5g-oai-amf   ... done
+Creating rfsim5g-oai-smf   ... done
+Creating rfsim5g-oai-ext-dn ... done
+```
+
+Wait for a bit.
+
+```bash
+$ docker-compose ps -a
+       Name                     Command                  State                  Ports            
+-------------------------------------------------------------------------------------------------
+rfsim5g-mysql        docker-entrypoint.sh mysqld      Up (healthy)   3306/tcp, 33060/tcp         
+rfsim5g-oai-amf      /bin/bash /openair-amf/bin ...   Up (healthy)   38412/sctp, 80/tcp, 9090/tcp
+rfsim5g-oai-ext-dn   /bin/bash -c  apt update;  ...   Up (healthy)                               
+rfsim5g-oai-nrf      /bin/bash /openair-nrf/bin ...   Up (healthy)   80/tcp, 9090/tcp            
+rfsim5g-oai-smf      /bin/bash -c /openair-smf/ ...   Up (healthy)   80/tcp, 8805/udp, 9090/tcp  
+rfsim5g-oai-spgwu    /openair-spgwu-tiny/bin/en ...   Up (healthy)   2152/udp, 8805/udp          
+```
+
+At this point, you can prepare a capture on the newly-created public docker bridges:
+
+```bash
+$ ifconfig 
+...
+rfsim5g-public: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
+        inet 192.168.71.129  netmask 255.255.255.192  broadcast 192.168.71.191
+        inet6 fe80::42:c4ff:fe2b:3d38  prefixlen 64  scopeid 0x20<link>
+        ether 02:42:c4:2b:3d:38  txqueuelen 0  (Ethernet)
+        RX packets 4  bytes 112 (112.0 B)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 7  bytes 626 (626.0 B)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+
+rfsim5g-traffic: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
+        inet 192.168.72.129  netmask 255.255.255.192  broadcast 192.168.72.191
+        inet6 fe80::42:b5ff:fed3:e732  prefixlen 64  scopeid 0x20<link>
+        ether 02:42:b5:d3:e7:32  txqueuelen 0  (Ethernet)
+        RX packets 2652  bytes 142335 (142.3 KB)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 3999  bytes 23367972 (23.3 MB)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+...
+```
+
+## 2.2. Deploy OAI gNB in RF simulator mode and in Standalone Mode ##
+
+```bash
+$ docker-compose up -d oai-gnb
+rfsim5g-oai-nrf is up-to-date
+rfsim5g-oai-spgwu is up-to-date
+rfsim5g-oai-ext-dn is up-to-date
+Creating rfsim5g-oai-gnb ... done
+```
+
+Wait for a bit.
+
+```bash
+$ docker-compose ps -a
+       Name                     Command                  State                  Ports            
+-------------------------------------------------------------------------------------------------
+rfsim5g-mysql        docker-entrypoint.sh mysqld      Up (healthy)   3306/tcp, 33060/tcp         
+rfsim5g-oai-amf      /bin/bash /openair-amf/bin ...   Up (healthy)   38412/sctp, 80/tcp, 9090/tcp
+rfsim5g-oai-ext-dn   /bin/bash -c  apt update;  ...   Up (healthy)                               
+rfsim5g-oai-gnb      /opt/oai-gnb/bin/entrypoin ...   Up (healthy)                               
+rfsim5g-oai-nrf      /bin/bash /openair-nrf/bin ...   Up (healthy)   80/tcp, 9090/tcp            
+rfsim5g-oai-smf      /bin/bash -c /openair-smf/ ...   Up (healthy)   80/tcp, 8805/udp, 9090/tcp  
+rfsim5g-oai-spgwu    /openair-spgwu-tiny/bin/en ...   Up (healthy)   2152/udp, 8805/udp          
+```
+
+## 2.3. Deploy OAI NR-UE in RF simulator mode and in Standalone Mode ##
+
+```bash
+$ docker-compose up -d oai-nr-ue
+rfsim5g-mysql is up-to-date
+rfsim5g-oai-nrf is up-to-date
+rfsim5g-oai-spgwu is up-to-date
+rfsim5g-oai-ext-dn is up-to-date
+rfsim5g-oai-gnb is up-to-date
+Creating rfsim5g-oai-nr-ue ... done
+```
+
+Wait for a bit.
+
+```bash
+$ docker-compose ps -a
+       Name                     Command                  State                  Ports            
+-------------------------------------------------------------------------------------------------
+rfsim5g-mysql        docker-entrypoint.sh mysqld      Up (healthy)   3306/tcp, 33060/tcp         
+rfsim5g-oai-amf      /bin/bash /openair-amf/bin ...   Up (healthy)   38412/sctp, 80/tcp, 9090/tcp
+rfsim5g-oai-ext-dn   /bin/bash -c  apt update;  ...   Up (healthy)                               
+rfsim5g-oai-gnb      /opt/oai-gnb/bin/entrypoin ...   Up (healthy)                               
+rfsim5g-oai-nr-ue    /opt/oai-nr-ue/bin/entrypo ...   Up (healthy)                               
+rfsim5g-oai-nrf      /bin/bash /openair-nrf/bin ...   Up (healthy)   80/tcp, 9090/tcp            
+rfsim5g-oai-smf      /bin/bash -c /openair-smf/ ...   Up (healthy)   80/tcp, 8805/udp, 9090/tcp  
+rfsim5g-oai-spgwu    /openair-spgwu-tiny/bin/en ...   Up (healthy)   2152/udp, 8805/udp          
+```
+
+Making sure the OAI UE is connected:
+
+```bash
+$ docker exec -it rfsim5g-oai-nr-ue /bin/bash
+root@bb4d400a832d:/opt/oai-nr-ue# ifconfig 
+eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
+        inet 192.168.71.137  netmask 255.255.255.192  broadcast 192.168.71.191
+        ether 02:42:c0:a8:47:89  txqueuelen 0  (Ethernet)
+        RX packets 224259  bytes 5821372018 (5.8 GB)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 235916  bytes 7848786376 (7.8 GB)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+
+lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
+        inet 127.0.0.1  netmask 255.0.0.0
+        loop  txqueuelen 1000  (Local Loopback)
+        RX packets 0  bytes 0 (0.0 B)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 0  bytes 0 (0.0 B)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+
+oaitun_ue1: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
+        inet 12.1.1.2  netmask 255.255.255.0  destination 12.1.1.2
+        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
+        RX packets 0  bytes 0 (0.0 B)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 0  bytes 0 (0.0 B)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+```
+
+**CAUTION: THESE NEXT FEW COMMANDS ARE A HACK. RAN developers SHALL FIX THIS!**
+
+```bash
+$ docker exec -it rfsim5g-oai-nr-ue /bin/bash
+
+# Check the current routes
+
+root@bb4d400a832d:/opt/oai-nr-ue# ip route
+default via 192.168.71.129 dev eth0 
+12.1.1.0/24 dev oaitun_ue1 proto kernel scope link src 12.1.1.2 
+192.168.71.128/26 dev eth0 proto kernel scope link src 192.168.71.137 
+
+# Remove the default and PDN routes
+
+root@bb4d400a832d:/opt/oai-nr-ue# ip route del default
+root@bb4d400a832d:/opt/oai-nr-ue# ip route del 12.1.1.0/24
+
+# Force the default route through oaitun_ue1 tunnel
+
+root@bb4d400a832d:/opt/oai-nr-ue# ip route add default via 12.1.1.2 dev oaitun_ue1
+
+# Check the new routes
+
+root@bb4d400a832d:/opt/oai-nr-ue# ip route
+default via 12.1.1.2 dev oaitun_ue1 
+192.168.71.128/26 dev eth0 proto kernel scope link src 192.168.71.137 
+```
+
+# 3. Check traffic #
+
+## 3.1. Check your Internet connectivity ##
+
+```bash
+$ docker exec -it rfsim5g-oai-nr-ue /bin/bash
+root@bb4d400a832d:/opt/oai-nr-ue# ping -I oaitun_ue1 -c 10 www.lemonde.fr
+PING s2.shared.global.fastly.net (151.101.122.217) from 12.1.1.2 oaitun_ue1: 56(84) bytes of data.
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=1 ttl=53 time=64.5 ms
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=2 ttl=53 time=37.0 ms
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=3 ttl=53 time=43.2 ms
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=4 ttl=53 time=43.2 ms
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=5 ttl=53 time=54.3 ms
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=6 ttl=53 time=24.0 ms
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=7 ttl=53 time=32.5 ms
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=8 ttl=53 time=37.0 ms
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=9 ttl=53 time=41.2 ms
+64 bytes from 151.101.122.217 (151.101.122.217): icmp_seq=10 ttl=53 time=50.3 ms
+
+--- s2.shared.global.fastly.net ping statistics ---
+10 packets transmitted, 10 received, 0% packet loss, time 9011ms
+rtt min/avg/max/mdev = 24.035/42.765/64.557/10.904 ms
+```
+
+If it does not work, certainly you need to modify the DNS values in the docker-compose.
+
+But you can also check with the `ext-dn` container (IP address is `192.168.72.135` in docker-compose)
+
+```bash
+$ docker exec -it rfsim5g-oai-nr-ue /bin/bash
+root@bb4d400a832d# ping -I oaitun_ue1 -c 2 192.168.72.135
+PING 192.168.72.135 (192.168.72.135) from 12.1.1.2 oaitun_ue1: 56(84) bytes of data.
+64 bytes from 192.168.72.135: icmp_seq=1 ttl=63 time=10.9 ms
+64 bytes from 192.168.72.135: icmp_seq=2 ttl=63 time=16.5 ms
+
+--- 192.168.72.135 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1001ms
+rtt min/avg/max/mdev = 10.939/13.747/16.556/2.810 ms
+```
+
+Let now try to check UDP traffic in Downlink.
+
+You will need 2 terminals: one in the NR-UE container, one in the ext-dn container.
+
+## 3.2. Start the `iperf` server inside the NR-UE container ##
+
+```bash
+$ docker exec -it rfsim5g-oai-nr-ue /bin/bash
+root@bb4d400a832d:/opt/oai-nr-ue# iperf -B 12.1.1.2 -u -i 1 -s
+------------------------------------------------------------
+Server listening on UDP port 5001
+Binding to local address 12.1.1.2
+Receiving 1470 byte datagrams
+UDP buffer size:  208 KByte (default)
+------------------------------------------------------------
+```
+
+## 3.3. Start the `iperf` client inside the ext-dn container ##
+
+```bash
+$ docker exec -it rfsim5g-oai-ext-dn /bin/bash
+root@f239e31a0bd0:/# iperf -c 12.1.1.2 -u -i 1 -t 20 -b 500K
+------------------------------------------------------------
+Client connecting to 12.1.1.2, UDP port 5001
+Sending 1470 byte datagrams, IPG target: 22968.75 us (kalman adjust)
+UDP buffer size:  208 KByte (default)
+------------------------------------------------------------
+[  3] local 192.168.72.135 port 58800 connected with 12.1.1.2 port 5001
+[ ID] Interval       Transfer     Bandwidth
+[  3]  0.0- 1.0 sec  64.6 KBytes   529 Kbits/sec
+[  3]  1.0- 2.0 sec  63.2 KBytes   517 Kbits/sec
+[  3]  2.0- 3.0 sec  61.7 KBytes   506 Kbits/sec
+[  3]  3.0- 4.0 sec  63.2 KBytes   517 Kbits/sec
+[  3]  4.0- 5.0 sec  61.7 KBytes   506 Kbits/sec
+[  3]  5.0- 6.0 sec  63.2 KBytes   517 Kbits/sec
+[  3]  6.0- 7.0 sec  61.7 KBytes   506 Kbits/sec
+[  3]  7.0- 8.0 sec  63.2 KBytes   517 Kbits/sec
+[  3]  8.0- 9.0 sec  61.7 KBytes   506 Kbits/sec
+[  3]  9.0-10.0 sec  63.2 KBytes   517 Kbits/sec
+[  3] 10.0-11.0 sec  61.7 KBytes   506 Kbits/sec
+[  3] 11.0-12.0 sec  63.2 KBytes   517 Kbits/sec
+[  3] 12.0-13.0 sec  61.7 KBytes   506 Kbits/sec
+[  3] 13.0-14.0 sec  63.2 KBytes   517 Kbits/sec
+[  3] 14.0-15.0 sec  63.2 KBytes   517 Kbits/sec
+[  3] 15.0-16.0 sec  61.7 KBytes   506 Kbits/sec
+[  3] 16.0-17.0 sec  63.2 KBytes   517 Kbits/sec
+[  3] 17.0-18.0 sec  61.7 KBytes   506 Kbits/sec
+[  3] 18.0-19.0 sec  63.2 KBytes   517 Kbits/sec
+[  3] 19.0-20.0 sec  61.7 KBytes   506 Kbits/sec
+[  3]  0.0-20.0 sec  1.22 MBytes   512 Kbits/sec
+[  3] Sent 872 datagrams
+[  3] Server Report:
+[  3]  0.0-20.0 sec  1.22 MBytes   510 Kbits/sec   0.000 ms    3/  872 (0%)
+```
+
+Back on your NR-UE terminal you shall see:
+
+```bash
+[  3] local 12.1.1.2 port 5001 connected with 192.168.72.135 port 58800
+[ ID] Interval       Transfer     Bandwidth        Jitter   Lost/Total Datagrams
+[  3]  0.0- 1.0 sec  63.2 KBytes   517 Kbits/sec   1.113 ms    0/   44 (0%)
+[  3]  1.0- 2.0 sec  61.7 KBytes   506 Kbits/sec   1.466 ms    0/   43 (0%)
+[  3]  2.0- 3.0 sec  63.2 KBytes   517 Kbits/sec   1.770 ms    0/   44 (0%)
+[  3]  3.0- 4.0 sec  61.7 KBytes   506 Kbits/sec   1.378 ms    0/   43 (0%)
+[  3]  4.0- 5.0 sec  63.2 KBytes   517 Kbits/sec   1.614 ms    0/   44 (0%)
+[  3]  5.0- 6.0 sec  63.2 KBytes   517 Kbits/sec   1.427 ms    0/   44 (0%)
+[  3]  6.0- 7.0 sec  60.3 KBytes   494 Kbits/sec   1.507 ms    1/   43 (2.3%)
+[  3]  7.0- 8.0 sec  63.2 KBytes   517 Kbits/sec   1.409 ms    0/   44 (0%)
+[  3]  8.0- 9.0 sec  61.7 KBytes   506 Kbits/sec   1.525 ms    0/   43 (0%)
+[  3]  9.0-10.0 sec  63.2 KBytes   517 Kbits/sec   1.393 ms    0/   44 (0%)
+[  3] 10.0-11.0 sec  61.7 KBytes   506 Kbits/sec   1.377 ms    0/   43 (0%)
+[  3] 11.0-12.0 sec  63.2 KBytes   517 Kbits/sec   1.501 ms    0/   44 (0%)
+[  3] 12.0-13.0 sec  61.7 KBytes   506 Kbits/sec   1.788 ms    0/   43 (0%)
+[  3] 13.0-14.0 sec  63.2 KBytes   517 Kbits/sec   1.466 ms    0/   44 (0%)
+[  3] 14.0-15.0 sec  61.7 KBytes   506 Kbits/sec   1.381 ms    0/   43 (0%)
+[  3] 15.0-16.0 sec  61.7 KBytes   506 Kbits/sec   1.417 ms    1/   44 (2.3%)
+[  3] 16.0-17.0 sec  61.7 KBytes   506 Kbits/sec   1.569 ms    0/   43 (0%)
+[  3] 17.0-18.0 sec  63.2 KBytes   517 Kbits/sec   1.492 ms    1/   45 (2.2%)
+[  3] 18.0-19.0 sec  61.7 KBytes   506 Kbits/sec   1.376 ms    0/   43 (0%)
+[  3] 19.0-20.0 sec  61.7 KBytes   506 Kbits/sec   1.589 ms    0/   43 (0%)
+[  3]  0.0-20.0 sec  1.22 MBytes   510 Kbits/sec   1.551 ms    3/  872 (0.34%)
+```
+
+The `500 Kbits/sec` value may change depending on your CPU power!
+
+# 4. Un-deployment #
+
+```bash
+$ docker-compose down
+Stopping rfsim5g-oai-nr-ue  ... done
+Stopping rfsim5g-oai-gnb    ... done
+Stopping rfsim5g-oai-ext-dn ... done
+Stopping rfsim5g-oai-smf    ... done
+Stopping rfsim5g-oai-amf    ... done
+Stopping rfsim5g-oai-spgwu  ... done
+Stopping rfsim5g-oai-nrf    ... done
+Stopping rfsim5g-mysql      ... done
+Removing rfsim5g-oai-nr-ue  ... done
+Removing rfsim5g-oai-gnb    ... done
+Removing rfsim5g-oai-ext-dn ... done
+Removing rfsim5g-oai-smf    ... done
+Removing rfsim5g-oai-amf    ... done
+Removing rfsim5g-oai-spgwu  ... done
+Removing rfsim5g-oai-nrf    ... done
+Removing rfsim5g-mysql      ... done
+Removing network rfsim5g-oai-public-net
+Removing network rfsim5g-oai-traffic_net-net
+```
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/amf-healthcheck.sh b/ci-scripts/yaml_files/5g_rfsimulator/amf-healthcheck.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8bfdee2aac6150b50240f7af4fa15a5eb105e9bc
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_rfsimulator/amf-healthcheck.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+set -eo pipefail
+
+STATUS=0
+AMF_PORT_FOR_NGAP=38412
+AMF_PORT_FOR_N11_HTTP=80
+AMF_IP_NGAP_INTERFACE=$(ifconfig $AMF_INTERFACE_NAME_FOR_NGAP | grep inet | awk {'print $2'})
+AMF_IP_N11_INTERFACE=$(ifconfig $AMF_INTERFACE_NAME_FOR_N11 | grep inet | awk {'print $2'})
+N2_PORT_STATUS=$(netstat -Snpl | grep -o "$AMF_IP_NGAP_INTERFACE:$AMF_PORT_FOR_NGAP")
+N11_PORT_STATUS=$(netstat -tnpl | grep -o "$AMF_IP_N11_INTERFACE:$AMF_PORT_FOR_N11_HTTP")
+#Check if entrypoint properly configured the conf file and no parameter is unset (optional)
+NB_UNREPLACED_AT=`cat /openair-amf/etc/*.conf | grep -v contact@openairinterface.org | grep -c @ || true`
+
+if [ $NB_UNREPLACED_AT -ne 0 ]; then
+	STATUS=1
+	echo "Healthcheck error: configuration file is not configured properly"
+fi
+
+if [[ -z $N2_PORT_STATUS ]]; then
+	STATUS=1
+	echo "Healthcheck error: N2 SCTP port $AMF_PORT_FOR_NGAP is not listening"
+fi
+
+if [[ -z $N11_PORT_STATUS ]]; then
+	STATUS=1
+	echo "Healthcheck error: N11/SBI TCP/HTTP port $AMF_PORT_FOR_N11_HTTP is not listening"
+fi
+
+#host="${MYSQL_SERVER}"
+#user="${MYSQL_USER:-root}"
+#export MYSQL_PWD="${MYSQL_PASS}"
+
+#args=(
+#	-h"$host"
+#	-u"$user"
+#	--silent
+#)
+
+#if ! command -v mysql &> /dev/null; then
+#	echo "Installing mysql command"
+#	apt update
+#	apt-get -y install mysql-client
+#else
+#	if select="$(echo 'SELECT 1' | mysql "${args[@]}")" && [ "$select" = '1' ]; then
+#		database_check=$(mysql -h$host -u$user -D oai_db --silent -e "SELECT * FROM users;")
+#		if [[ -z $database_check ]]; then
+#			echo "Healthcheck error: oai_db not populated"
+#			STATUS=1
+#		fi
+#		STATUS=0
+#	else
+#		echo "Healthcheck error: Mysql port inactive"
+#		STATUS=1
+#	fi
+#fi
+
+exit $STATUS
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5da7a353ab3ccc373d9d7830c85775be06fb5dea
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
@@ -0,0 +1,293 @@
+version: '3.8'
+services:
+    oai-nrf:
+        container_name: "rfsim5g-oai-nrf"
+        image: oai-nrf:latest
+        environment:
+            - NRF_INTERFACE_NAME_FOR_SBI=eth0
+            - NRF_INTERFACE_PORT_FOR_SBI=80
+            - NRF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
+            - NRF_API_VERSION=v1
+            - INSTANCE=0
+            - PID_DIRECTORY=/var/run
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.130
+        volumes:
+            - ./nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh
+        healthcheck:
+            test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+    mysql:
+        container_name: "rfsim5g-mysql"
+        image: mysql:5.7
+        volumes:
+            - ./oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
+            - ./mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
+        environment:
+            - TZ=Europe/Paris
+            - MYSQL_DATABASE=oai_db
+            - MYSQL_USER=test
+            - MYSQL_PASSWORD=test
+            - MYSQL_ROOT_PASSWORD=linux
+        healthcheck:
+            test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.131
+    oai-amf:
+        container_name: "rfsim5g-oai-amf"
+        image: oai-amf:latest
+        environment:
+            - TZ=Europe/paris
+            - INSTANCE=0
+            - PID_DIRECTORY=/var/run
+            - MCC=208
+            - MNC=99
+            - REGION_ID=128
+            - AMF_SET_ID=1
+            - SERVED_GUAMI_MCC_0=208
+            - SERVED_GUAMI_MNC_0=99
+            - SERVED_GUAMI_REGION_ID_0=128
+            - SERVED_GUAMI_AMF_SET_ID_0=1
+            - SERVED_GUAMI_MCC_1=460
+            - SERVED_GUAMI_MNC_1=11
+            - SERVED_GUAMI_REGION_ID_1=10
+            - SERVED_GUAMI_AMF_SET_ID_1=1
+            - PLMN_SUPPORT_MCC=208
+            - PLMN_SUPPORT_MNC=99
+            - PLMN_SUPPORT_TAC=0x0001
+            - SST_0=1
+            - SD_0=1
+            - SST_1=1
+            - SD_1=12
+            - AMF_INTERFACE_NAME_FOR_NGAP=eth0
+            - AMF_INTERFACE_NAME_FOR_N11=eth0
+            - SMF_INSTANCE_ID_0=1
+            - SMF_FQDN_0=oai-smf
+            - SMF_IPV4_ADDR_0=0.0.0.0
+            - SMF_HTTP_VERSION_0=v1
+            - SELECTED_0=true
+            - SMF_INSTANCE_ID_1=2
+            - SMF_FQDN_1=oai-smf
+            - SMF_IPV4_ADDR_1=0.0.0.0
+            - SMF_HTTP_VERSION_1=v1
+            - SELECTED_1=false
+            - MYSQL_SERVER=192.168.71.131
+            - MYSQL_USER=root
+            - MYSQL_PASS=linux
+            - MYSQL_DB=oai_db
+            - OPERATOR_KEY=c42449363bbad02b66d16bc975d77cc1
+            - NRF_IPV4_ADDRESS=192.168.71.130
+            - NRF_PORT=80
+            - NF_REGISTRATION=yes
+            - SMF_SELECTION=yes
+            - USE_FQDN_DNS=yes
+            - NRF_API_VERSION=v1
+            - NRF_FQDN=oai-nrf
+            - AUSF_IPV4_ADDRESS=127.0.0.1
+            - AUSF_PORT=80
+            - AUSF_API_VERSION=v1
+        depends_on:
+            - oai-nrf
+        volumes:
+            - ./amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh
+        healthcheck:
+            test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh"
+            interval: 10s
+            timeout: 15s
+            retries: 5
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.132
+    oai-smf:
+        container_name: "rfsim5g-oai-smf"
+        image: oai-smf:latest
+        entrypoint: /bin/bash -c "/openair-smf/bin/oai_smf -c /openair-smf/bin/oai-smf.conf -o"
+        environment:
+            - TZ=Europe/Paris
+            - INSTANCE=0
+            - PID_DIRECTORY=/var/run
+            - SMF_INTERFACE_NAME_FOR_N4=eth0
+            - SMF_INTERFACE_NAME_FOR_SBI=eth0
+            - SMF_INTERFACE_PORT_FOR_SBI=80
+            - SMF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
+            - SMF_API_VERSION=v1
+            - DEFAULT_DNS_IPV4_ADDRESS=192.168.18.129
+            - DEFAULT_DNS_SEC_IPV4_ADDRESS=4.4.4.4
+            - AMF_IPV4_ADDRESS=0.0.0.0
+            - AMF_PORT=80
+            - AMF_API_VERSION=v1
+            - AMF_FQDN=oai-amf
+            - UDM_IPV4_ADDRESS=127.0.0.1
+            - UDM_PORT=80
+            - UDM_API_VERSION=v1
+            - UDM_FQDN=localhost
+            - UPF_IPV4_ADDRESS=192.168.71.134
+            - UPF_FQDN_0=oai-spgwu
+            - NRF_IPV4_ADDRESS=192.168.71.130
+            - NRF_PORT=80
+            - NRF_API_VERSION=v1
+            - NRF_FQDN=oai-nrf
+            - REGISTER_NRF=yes
+            - DISCOVER_UPF=yes
+            - USE_FQDN_DNS=yes
+        depends_on:
+            - oai-nrf
+        volumes:
+            - ./smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh
+            - ./oai-smf.conf:/openair-smf/bin/oai-smf.conf
+        healthcheck:
+            test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.133
+    oai-spgwu:
+        container_name: "rfsim5g-oai-spgwu"
+        image: oai-spgwu-tiny:latest
+        environment:
+            - TZ=Europe/Paris
+            - PID_DIRECTORY=/var/run
+            - SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP=eth0
+            - SGW_INTERFACE_NAME_FOR_SX=eth0
+            - PGW_INTERFACE_NAME_FOR_SGI=eth0
+            - NETWORK_UE_NAT_OPTION=yes
+            - NETWORK_UE_IP=12.1.1.0/24
+            - SPGWC0_IP_ADDRESS=192.168.71.133
+            - BYPASS_UL_PFCP_RULES=no
+            - MCC=208
+            - MNC=99
+            - MNC03=099
+            - TAC=1
+            - GTP_EXTENSION_HEADER_PRESENT=yes
+            - GW_ID=1
+            - REALM=openairinterface.org
+            - ENABLE_5G_FEATURES=yes
+            - REGISTER_NRF=yes
+            - USE_FQDN_NRF=yes
+            - UPF_FQDN_5G=oai-spgwu
+            - NRF_IPV4_ADDRESS=192.168.71.130
+            - NRF_PORT=80
+            - NRF_API_VERSION=v1
+            - NRF_FQDN=oai-nrf
+            - NSSAI_SST_0=1
+            - NSSAI_SD_0=1
+            - DNN_0=oai
+        depends_on:
+            - oai-nrf
+        cap_add:
+            - NET_ADMIN
+            - SYS_ADMIN
+        cap_drop:
+            - ALL
+        privileged: true
+        volumes:
+            - ./spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh
+        healthcheck:
+            test: /bin/bash -c "/openair-spgwu-tiny/bin/spgwu-healthcheck.sh"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.134
+            traffic_net:
+                ipv4_address: 192.168.72.134
+    oai-ext-dn:
+        image: ubuntu:bionic
+        privileged: true
+        container_name: rfsim5g-oai-ext-dn
+        entrypoint: /bin/bash -c \
+              "apt update; apt install -y procps iptables iproute2 iperf iputils-ping;"\
+              "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
+              "ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
+        depends_on:
+            - oai-spgwu
+        networks:
+            traffic_net:
+                ipv4_address: 192.168.72.135
+        healthcheck:
+            test: /bin/bash -c "ping -c 2 192.168.72.134"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+    oai-gnb:
+        image: oai-gnb:develop
+        privileged: true
+        container_name: rfsim5g-oai-gnb
+        environment: 
+            RFSIMULATOR: server
+            USE_SA_TDD_MONO: 'yes'
+            GNB_NAME: gnb-rfsim
+            TAC: 1
+            MCC: '208'
+            MNC: '99'
+            MNC_LENGTH: 2
+            NSSAI_SST: 1
+            NSSAI_SD0: 1
+            NSSAI_SD1: 112233
+            AMF_IP_ADDRESS: 192.168.71.132
+            GNB_NGA_IF_NAME: eth0
+            GNB_NGA_IP_ADDRESS: 192.168.71.136
+            GNB_NGU_IF_NAME: eth0
+            GNB_NGU_IP_ADDRESS: 192.168.71.136
+            USE_ADDITIONAL_OPTIONS: --sa -E --rfsim
+        depends_on:
+            - oai-ext-dn
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.136
+        healthcheck:
+            test: /bin/bash -c "pgrep nr-softmodem"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+    oai-nr-ue:
+        image: oai-nr-ue:develop
+        privileged: true
+        container_name: rfsim5g-oai-nr-ue
+        environment: 
+            RFSIMULATOR: 192.168.71.136
+            FULL_IMSI: '208990100001100'
+            FULL_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
+            OPC: 'C42449363BBAD02B66D16BC975D77CC1'
+            DNN: oai
+            NSSAI_SST: 1
+            NSSAI_SD: 1
+            USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 -C 3619200000 --nokrnmod
+        depends_on:
+            - oai-gnb
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.137
+        healthcheck:
+            test: /bin/bash -c "pgrep nr-uesoftmodem"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+networks:
+    public_net:
+        driver: bridge
+        name: rfsim5g-oai-public-net
+        ipam:
+            config:
+                - subnet: 192.168.71.128/26
+        driver_opts:
+            com.docker.network.bridge.name: "rfsim5g-public"
+    traffic_net:
+        driver: bridge
+        name: rfsim5g-oai-traffic_net-net
+        ipam:
+            config:
+                - subnet: 192.168.72.128/26
+        driver_opts:
+            com.docker.network.bridge.name: "rfsim5g-traffic"
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/mysql-healthcheck.sh b/ci-scripts/yaml_files/5g_rfsimulator/mysql-healthcheck.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c92efb9f00a1f69e36dbc8bd410c163bb5d37a97
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_rfsimulator/mysql-healthcheck.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+set -eo pipefail
+
+if [ "$MYSQL_ROOT_PASSWORD" ] && [ -z "$MYSQL_USER" ] && [ -z "$MYSQL_PASSWORD" ]; then
+	echo >&2 'Healthcheck error: cannot determine root password (and MYSQL_USER and MYSQL_PASSWORD were not set)'
+	exit 0
+fi
+
+host="$(hostname --ip-address || echo '127.0.0.1')"
+user="${MYSQL_USER:-root}"
+export MYSQL_PWD="${MYSQL_PASSWORD:-$MYSQL_ROOT_PASSWORD}"
+
+args=(
+	# force mysql to not use the local "mysqld.sock" (test "external" connectivity)
+	-h"$host"
+	-u"$user"
+	--silent
+)
+
+STATUS=0
+if command -v mysqladmin &> /dev/null; then
+	if mysqladmin "${args[@]}" ping > /dev/null; then
+		database_check=$(mysql -u$user -D oai_db --silent -e "SELECT * FROM users;")
+		if [[ -z $database_check ]]; then
+			echo "Healthcheck error: oai_db not populated"
+			STATUS=1
+		fi
+		STATUS=0
+	else
+		echo "Healthcheck error: Mysql port inactive"
+		STATUS=1
+	fi
+else
+	if select="$(echo 'SELECT 1' | mysql "${args[@]}")" && [ "$select" = '1' ]; then
+		database_check=$(mysql -u$user -D oai_db --silent -e "SELECT * FROM users;")
+		if [[ -z $database_check ]]; then
+			echo "Healthcheck error: oai_db not populated"
+			STATUS=1
+		fi
+		STATUS=0
+	else
+		echo "Healthcheck error: Mysql port inactive"
+		STATUS=1
+	fi
+fi
+exit $STATUS
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/nrf-healthcheck.sh b/ci-scripts/yaml_files/5g_rfsimulator/nrf-healthcheck.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3479c092e8805bf45007d1a4635ee43149786401
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_rfsimulator/nrf-healthcheck.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+set -eo pipefail
+
+STATUS=0
+NRF_IP_SBI_INTERFACE=$(ifconfig $NRF_INTERFACE_NAME_FOR_SBI | grep inet | awk {'print $2'})
+NRF_SBI_PORT_STATUS=$(netstat -tnpl | grep -o "$NRF_IP_SBI_INTERFACE:$NRF_INTERFACE_PORT_FOR_SBI")
+#Check if entrypoint properly configured the conf file and no parameter is unset(optional)
+NB_UNREPLACED_AT=`cat /openair-nrf/etc/*.conf | grep -v contact@openairinterface.org | grep -c @ || true`
+
+if [ $NB_UNREPLACED_AT -ne 0 ]; then
+	STATUS=1
+	echo "Healthcheck error: UNHEALTHY configuration file is not configured properly"
+fi
+
+if [[ -z $NRF_SBI_PORT_STATUS ]]; then
+	STATUS=1
+	echo "Healthcheck error: UNHEALTHY SBI TCP/HTTP port $NRF_INTERFACE_PORT_FOR_SBI is not listening."
+fi
+
+exit $STATUS
\ No newline at end of file
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/oai-end-to-end.jpg b/ci-scripts/yaml_files/5g_rfsimulator/oai-end-to-end.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f454a016f624196c87baa431f5974d148ec677be
Binary files /dev/null and b/ci-scripts/yaml_files/5g_rfsimulator/oai-end-to-end.jpg differ
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/oai-smf.conf b/ci-scripts/yaml_files/5g_rfsimulator/oai-smf.conf
new file mode 100644
index 0000000000000000000000000000000000000000..0c83ab8be937cee03a6b1dc0931473e162c952df
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_rfsimulator/oai-smf.conf
@@ -0,0 +1,133 @@
+################################################################################
+# 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
+################################################################################
+
+SMF =
+{
+    FQDN = "oai-smf-svc";               
+    INSTANCE      = 0;         # 0 is the default
+    PID_DIRECTORY = "/var/run";  # /var/run is the default
+
+    INTERFACES :
+    {
+        N4 :
+        {
+            # SMF binded interface for N4 communication (UPF)
+            INTERFACE_NAME = "eth0"; # YOUR NETWORK CONFIG HERE
+            IPV4_ADDRESS   = "read";                        
+         };
+
+        SBI :
+        {
+            # SMF binded interface for SBI interface (e.g., communication with AMF, UDM)
+            INTERFACE_NAME = "eth0";     # YOUR NETWORK CONFIG HERE
+            IPV4_ADDRESS   = "read";
+            PORT           = 80;       # YOUR NETWORK CONFIG HERE (default: 80)
+            HTTP2_PORT     = 9090; # YOUR NETWORK CONFIG HERE
+            API_VERSION    = "v1";                # YOUR SMF API VERSION CONFIG HERE
+         };                 
+
+    };
+
+
+    # Pool of UE assigned IP addresses
+    # Do not make IP pools overlap
+    # first IPv4 address X.Y.Z.1 is reserved for GTP network device on UPF
+    IP_ADDRESS_POOL :
+    {
+        IPV4_LIST = (
+                      {RANGE = "12.1.1.2 - 12.1.1.128";},         # STRING, IPv4 RANGE IP_start - IP_end, YOUR NETWORK CONFIG HERE.
+                      {RANGE = "12.1.1.129 - 12.1.1.224";},       # STRING, IPv4 RANGE IP_start - IP_end, YOUR NETWORK CONFIG HERE.
+                      {RANGE = "10.10.10.2 - 10.10.10.253";}  # STRING, IPv4 RANGE IP_start - IP_end, YOUR NETWORK CONFIG HERE.
+
+                    );
+        IPV6_LIST = (
+                      {PREFIX = "2001:1:2::/64";},                # STRING, IPv6 prefix, YOUR NETWORK CONFIG HERE.
+                      {PREFIX = "3001:1:2::/64";},                # STRING, IPv6 prefix, YOUR NETWORK CONFIG HERE.
+                      {PREFIX = "4001:1:2::/64";}                 # STRING, IPv6 prefix, YOUR NETWORK CONFIG HERE.
+                    );
+    };
+
+    DNN_LIST = (
+       # IPV4_POOL, IPV6_POOL are index in IPV4_LIST, IPV6_LIST, PDU_SESSION_TYPE choice in {IPv4, IPv6, IPv4v6}
+      {DNN_NI = "default"; PDU_SESSION_TYPE = "IPv4"; IPV4_POOL  = 2; IPV6_POOL = -1},
+      {DNN_NI = "carrier.com"; PDU_SESSION_TYPE = "IPv4"; IPV4_POOL = 1; IPV6_POOL = -1},
+      {DNN_NI = "oai"; PDU_SESSION_TYPE = "IPv4"; IPV4_POOL = 0; IPV6_POOL = -1}
+    );
+
+    # DNS address communicated to UEs
+    DEFAULT_DNS_IPV4_ADDRESS     = "192.168.18.129";      # YOUR DNS CONFIG HERE
+    DEFAULT_DNS_SEC_IPV4_ADDRESS = "192.168.18.129";  # YOUR DNS CONFIG HERE
+    DEFAULT_DNS_IPV6_ADDRESS     = "2001:4860:4860::8888";            # YOUR DNS CONFIG HERE
+    DEFAULT_DNS_SEC_IPV6_ADDRESS = "2001:4860:4860::8844";            # YOUR DNS CONFIG HERE
+ 
+    SUPPORT_FEATURES: 
+    {
+      # STRING, {"yes", "no"}, 
+      REGISTER_NRF = "yes";  # Set to yes if SMF resgisters to an NRF
+      DISCOVER_UPF = "yes";  # Set to yes to enable UPF discovery and selection
+      FORCE_PUSH_PROTOCOL_CONFIGURATION_OPTIONS = "no"; # Non standard feature, normally should be set to "no", 
+                                                        # but you may need to set to yes for UE that do not explicitly request a PDN address through NAS signalling
+      USE_LOCAL_SUBSCRIPTION_INFO = "yes";  # Set to yes if SMF uses local subscription information instead of from an UDM
+      USE_FQDN_DNS = "yes";                  # Set to yes if AMF/UDM/NRF/UPF will relying on a DNS to resolve FQDN
+    }  
+  
+    AMF :
+    {
+      IPV4_ADDRESS = "0.0.0.0";  # YOUR AMF CONFIG HERE
+      PORT         = 80;            # YOUR AMF CONFIG HERE (default: 80)
+      API_VERSION  = "v1";   # YOUR AMF API VERSION FOR SBI CONFIG HERE
+      FQDN         = "oai-amf"               # YOUR AMF FQDN CONFIG HERE
+    };
+    
+    UDM :
+    {
+      IPV4_ADDRESS = "127.0.0.1";  # YOUR UDM CONFIG HERE
+      PORT         = 80;            # YOUR UDM CONFIG HERE (default: 80)
+      API_VERSION  = "v1";   # YOUR UDM API VERSION FOR SBI CONFIG HERE
+      FQDN         = "localhost"      # YOUR UDM FQDN CONFIG HERE
+    };    
+
+    NRF :
+    {
+      IPV4_ADDRESS = "192.168.71.130";  # YOUR NRF CONFIG HERE
+      PORT         = 80;            # YOUR NRF CONFIG HERE (default: 80)
+      API_VERSION  = "v1";   # YOUR NRF API VERSION FOR SBI CONFIG HERE
+      FQDN         = "oai-nrf"      # YOUR NRF FQDN CONFIG HERE
+    };
+        
+    UPF_LIST = (
+         {IPV4_ADDRESS = "192.168.71.134" ; FQDN = "oai-spgwu"}   # YOUR UPF CONFIG HERE
+    );   
+   
+    LOCAL_CONFIGURATION :
+    {
+      SESSION_MANAGEMENT_SUBSCRIPTION_LIST = (
+         { NSSAI_SST = 222, NSSAI_SD = "123", DNN = "default", DEFAULT_SESSION_TYPE = "IPV4", DEFAULT_SSC_MODE = 1, 
+           QOS_PROFILE_5QI = 7, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT", 
+           QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "20Mbps", SESSION_AMBR_DL = "22Mbps"},
+         { NSSAI_SST = 1; NSSAI_SD = "1", DNN = "oai", DEFAULT_SESSION_TYPE = "IPV4", DEFAULT_SSC_MODE = 1, 
+           QOS_PROFILE_5QI = 6, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT", 
+           QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "20Mbps", SESSION_AMBR_DL = "22Mbps"}
+        );                 
+    };   
+    
+};
+
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/oai_db.sql b/ci-scripts/yaml_files/5g_rfsimulator/oai_db.sql
new file mode 100755
index 0000000000000000000000000000000000000000..fbd7907a71edd41cc32016f91176b270b8b5bd11
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_rfsimulator/oai_db.sql
@@ -0,0 +1,217 @@
+-- MySQL dump 10.13  Distrib 5.5.46, for debian-linux-gnu (x86_64)
+--
+-- Host: localhost    Database: oai_db
+-- ------------------------------------------------------
+-- Server version	5.5.46-0ubuntu0.14.04.2
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `apn`
+--
+
+DROP TABLE IF EXISTS `apn`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `apn` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `apn-name` varchar(60) NOT NULL,
+  `pdn-type` enum('IPv4','IPv6','IPv4v6','IPv4_or_IPv6') NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `apn-name` (`apn-name`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `apn`
+--
+
+LOCK TABLES `apn` WRITE;
+/*!40000 ALTER TABLE `apn` DISABLE KEYS */;
+/*!40000 ALTER TABLE `apn` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `mmeidentity`
+--
+
+DROP TABLE IF EXISTS `mmeidentity`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `mmeidentity` (
+  `idmmeidentity` int(11) NOT NULL AUTO_INCREMENT,
+  `mmehost` varchar(255) DEFAULT NULL,
+  `mmerealm` varchar(200) DEFAULT NULL,
+  `UE-Reachability` tinyint(1) NOT NULL COMMENT 'Indicates whether the MME supports UE Reachability Notifcation',
+  PRIMARY KEY (`idmmeidentity`)
+) ENGINE=MyISAM AUTO_INCREMENT=46 DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `mmeidentity`
+--
+
+LOCK TABLES `mmeidentity` WRITE;
+/*!40000 ALTER TABLE `mmeidentity` DISABLE KEYS */;
+INSERT INTO `mmeidentity` VALUES (2,'mme2.openair4G.eur','openair4G.eur',0),(1,'nano.openair4G.eur','openair4G.eur',0),(5,'abeille.openair4G.eur','openair4G.eur',0),(4,'yang.openair4G.eur','openair4G.eur',0),(3,'mme3.openair4G.eur','openair4G.eur',0),(6,'calisson.openair4G.eur','openair4G.eur',0);
+/*!40000 ALTER TABLE `mmeidentity` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `pdn`
+--
+
+DROP TABLE IF EXISTS `pdn`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `pdn` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `apn` varchar(60) NOT NULL,
+  `pdn_type` enum('IPv4','IPv6','IPv4v6','IPv4_or_IPv6') NOT NULL DEFAULT 'IPv4',
+  `pdn_ipv4` varchar(15) DEFAULT '0.0.0.0',
+  `pdn_ipv6` varchar(45) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT '0:0:0:0:0:0:0:0',
+  `aggregate_ambr_ul` int(10) unsigned DEFAULT '50000000',
+  `aggregate_ambr_dl` int(10) unsigned DEFAULT '100000000',
+  `pgw_id` int(11) NOT NULL,
+  `users_imsi` varchar(15) NOT NULL,
+  `qci` tinyint(3) unsigned NOT NULL DEFAULT '9',
+  `priority_level` tinyint(3) unsigned NOT NULL DEFAULT '15',
+  `pre_emp_cap` enum('ENABLED','DISABLED') DEFAULT 'DISABLED',
+  `pre_emp_vul` enum('ENABLED','DISABLED') DEFAULT 'DISABLED',
+  `LIPA-Permissions` enum('LIPA-prohibited','LIPA-only','LIPA-conditional') NOT NULL DEFAULT 'LIPA-only',
+  PRIMARY KEY (`id`,`pgw_id`,`users_imsi`),
+  KEY `fk_pdn_pgw1_idx` (`pgw_id`),
+  KEY `fk_pdn_users1_idx` (`users_imsi`)
+) ENGINE=MyISAM AUTO_INCREMENT=60 DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `pdn`
+--
+
+LOCK TABLES `pdn` WRITE;
+/*!40000 ALTER TABLE `pdn` DISABLE KEYS */;
+INSERT INTO `pdn` VALUES (1,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930000000001',9,15,'DISABLED','ENABLED','LIPA-only'),(41,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'20834123456789',9,15,'DISABLED','ENABLED','LIPA-only'),(40,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'20810000001234',9,15,'DISABLED','ENABLED','LIPA-only'),(42,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'31002890832150',9,15,'DISABLED','ENABLED','LIPA-only'),(16,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000002',9,15,'DISABLED','ENABLED','LIPA-only'),(43,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'001010123456789',9,15,'DISABLED','ENABLED','LIPA-only'),(2,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930000000002',9,15,'DISABLED','ENABLED','LIPA-only'),(3,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930000000003',9,15,'DISABLED','ENABLED','LIPA-only'),(4,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930000000004',9,15,'DISABLED','ENABLED','LIPA-only'),(5,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930000000005',9,15,'DISABLED','ENABLED','LIPA-only'),(6,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930000000006',9,15,'DISABLED','ENABLED','LIPA-only'),(7,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930000000007',9,15,'DISABLED','ENABLED','LIPA-only'),(8,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208940000000001',9,15,'DISABLED','ENABLED','LIPA-only'),(9,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208940000000002',9,15,'DISABLED','ENABLED','LIPA-only'),(10,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208940000000003',9,15,'DISABLED','ENABLED','LIPA-only'),(11,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208940000000004',9,15,'DISABLED','ENABLED','LIPA-only'),(12,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208940000000005',9,15,'DISABLED','ENABLED','LIPA-only'),(13,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208940000000006',9,15,'DISABLED','ENABLED','LIPA-only'),(14,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208940000000007',9,15,'DISABLED','ENABLED','LIPA-only'),(15,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000001',9,15,'DISABLED','ENABLED','LIPA-only'),(17,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000003',9,15,'DISABLED','ENABLED','LIPA-only'),(18,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000004',9,15,'DISABLED','ENABLED','LIPA-only'),(19,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000005',9,15,'DISABLED','ENABLED','LIPA-only'),(20,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000006',9,15,'DISABLED','ENABLED','LIPA-only'),(21,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000007',9,15,'DISABLED','ENABLED','LIPA-only'),(22,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001100',9,15,'DISABLED','ENABLED','LIPA-only'),(23,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001101',9,15,'DISABLED','ENABLED','LIPA-only'),(24,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001102',9,15,'DISABLED','ENABLED','LIPA-only'),(25,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001103',9,15,'DISABLED','ENABLED','LIPA-only'),(26,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001104',9,15,'DISABLED','ENABLED','LIPA-only'),(27,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001105',9,15,'DISABLED','ENABLED','LIPA-only'),(28,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001106',9,15,'DISABLED','ENABLED','LIPA-only'),(29,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001107',9,15,'DISABLED','ENABLED','LIPA-only'),(30,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001108',9,15,'DISABLED','ENABLED','LIPA-only'),(31,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001109',9,15,'DISABLED','ENABLED','LIPA-only'),(32,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001110',9,15,'DISABLED','ENABLED','LIPA-only'),(33,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930100001111',9,15,'DISABLED','ENABLED','LIPA-only'),(34,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930100001112',9,15,'DISABLED','ENABLED','LIPA-only'),(35,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930100001113',9,15,'DISABLED','ENABLED','LIPA-only'),(44,'operator','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930100001113',9,15,'DISABLED','ENABLED','LIPA-only'),(45,'operator','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930100001112',9,15,'DISABLED','ENABLED','LIPA-only'),(46,'operator','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208930100001111',9,15,'DISABLED','ENABLED','LIPA-only'),(47,'operator','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000002',9,15,'DISABLED','ENABLED','LIPA-only'),(48,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000008',9,15,'DISABLED','ENABLED','LIPA-only'),(49,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000009',9,15,'DISABLED','ENABLED','LIPA-only'),(50,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000010',9,15,'DISABLED','ENABLED','LIPA-only'),(51,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000011',9,15,'DISABLED','ENABLED','LIPA-only'),(52,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000012',9,15,'DISABLED','ENABLED','LIPA-only'),(53,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000013',9,15,'DISABLED','ENABLED','LIPA-only'),(54,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000014',9,15,'DISABLED','ENABLED','LIPA-only'),(55,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208950000000015',9,15,'DISABLED','ENABLED','LIPA-only'),(56,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001118',9,15,'DISABLED','ENABLED','LIPA-only'),(57,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001121',9,15,'DISABLED','ENABLED','LIPA-only'),(58,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001120',9,15,'DISABLED','ENABLED','LIPA-only'),(59,'oai.ipv4','IPv4','0.0.0.0','0:0:0:0:0:0:0:0',50000000,100000000,3,'208920100001119',9,15,'DISABLED','ENABLED','LIPA-only');
+/*!40000 ALTER TABLE `pdn` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `pgw`
+--
+
+DROP TABLE IF EXISTS `pgw`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `pgw` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `ipv4` varchar(15) NOT NULL,
+  `ipv6` varchar(39) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `ipv4` (`ipv4`),
+  UNIQUE KEY `ipv6` (`ipv6`)
+) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `pgw`
+--
+
+LOCK TABLES `pgw` WRITE;
+/*!40000 ALTER TABLE `pgw` DISABLE KEYS */;
+INSERT INTO `pgw` VALUES (1,'127.0.0.1','0:0:0:0:0:0:0:1'),(2,'192.168.56.101',''),(3,'10.0.0.2','0');
+/*!40000 ALTER TABLE `pgw` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `terminal-info`
+--
+
+DROP TABLE IF EXISTS `terminal-info`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `terminal-info` (
+  `imei` varchar(15) NOT NULL,
+  `sv` varchar(2) NOT NULL,
+  UNIQUE KEY `imei` (`imei`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `terminal-info`
+--
+
+LOCK TABLES `terminal-info` WRITE;
+/*!40000 ALTER TABLE `terminal-info` DISABLE KEYS */;
+/*!40000 ALTER TABLE `terminal-info` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `users`
+--
+
+DROP TABLE IF EXISTS `users`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `users` (
+  `imsi` varchar(15) NOT NULL COMMENT 'IMSI is the main reference key.',
+  `msisdn` varchar(46) DEFAULT NULL COMMENT 'The basic MSISDN of the UE (Presence of MSISDN is optional).',
+  `imei` varchar(15) DEFAULT NULL COMMENT 'International Mobile Equipment Identity',
+  `imei_sv` varchar(2) DEFAULT NULL COMMENT 'International Mobile Equipment Identity Software Version Number',
+  `ms_ps_status` enum('PURGED','NOT_PURGED') DEFAULT 'PURGED' COMMENT 'Indicates that ESM and EMM status are purged from MME',
+  `rau_tau_timer` int(10) unsigned DEFAULT '120',
+  `ue_ambr_ul` bigint(20) unsigned DEFAULT '50000000' COMMENT 'The Maximum Aggregated uplink MBRs to be shared across all Non-GBR bearers according to the subscription of the user.',
+  `ue_ambr_dl` bigint(20) unsigned DEFAULT '100000000' COMMENT 'The Maximum Aggregated downlink MBRs to be shared across all Non-GBR bearers according to the subscription of the user.',
+  `access_restriction` int(10) unsigned DEFAULT '60' COMMENT 'Indicates the access restriction subscription information. 3GPP TS.29272 #7.3.31',
+  `mme_cap` int(10) unsigned zerofill DEFAULT NULL COMMENT 'Indicates the capabilities of the MME with respect to core functionality e.g. regional access restrictions.',
+  `mmeidentity_idmmeidentity` int(11) NOT NULL DEFAULT '0',
+  `key` varbinary(16) NOT NULL DEFAULT '0' COMMENT 'UE security key',
+  `RFSP-Index` smallint(5) unsigned NOT NULL DEFAULT '1' COMMENT 'An index to specific RRM configuration in the E-UTRAN. Possible values from 1 to 256',
+  `urrp_mme` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'UE Reachability Request Parameter indicating that UE activity notification from MME has been requested by the HSS.',
+  `sqn` bigint(20) unsigned zerofill NOT NULL,
+  `rand` varbinary(16) NOT NULL,
+  `OPc` varbinary(16) DEFAULT NULL COMMENT 'Can be computed by HSS',
+  PRIMARY KEY (`imsi`,`mmeidentity_idmmeidentity`),
+  KEY `fk_users_mmeidentity_idx1` (`mmeidentity_idmmeidentity`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `users`
+--
+
+LOCK TABLES `users` WRITE;
+/*!40000 ALTER TABLE `users` DISABLE KEYS */;
+INSERT INTO `users` VALUES ('20834123456789','380561234567','35609204079300',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,'+�E��ų\0�,IH��H',0,0,00000000000000000096,'Px�X \Z1��x��','^��K�����FeU���'),('20810000001234','33611123456','35609204079299',NULL,'PURGED',120,40000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000281454575616225,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0','�4�s@���z��~�'),('31002890832150','33638060059','35611302209414',NULL,'PURGED',120,40000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012416,'`�F�݆��D��ϛ���','�4�s@���z��~�'),('001010123456789','33600101789','35609204079298',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'\0	\n\r',1,0,00000000000000000351,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0','L�*\\�����^��]� '),('208930000000001','33638030001','35609204079301',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208950000000002','33638050002','35609204079502',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000020471,'\0	\n\r','�4�s@���z��~�'),('208950000000003','33638050003','35609204079503',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012343,'\0	\n\r','�4�s@���z��~�'),('208950000000004','33638050004','35609204079504',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000005','33638050005','35609204079505',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000001','33638050001','35609204079501',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208950000000006','33638050006','35609204079506',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000007','33638050007','35609204079507',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208930000000002','33638030002','35609204079302',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000003','33638030003','35609204079303',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000004','33638030004','35609204079304',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000005','33638030005','35609204079305',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000006','33638030006','35609204079306',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000007','33638030007','35609204079307',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000007','33638040007','35609204079407',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000006','33638040006','35609204079406',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000005','33638040005','35609204079405',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000004','33638040004','35609204079404',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000003','33638040003','35609204079403',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000002','33638040002','35609204079402',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000001','33638040001','35609204079401',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208920100001100','33638020001','35609204079201',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001101','33638020001','35609204079201',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204937234,'\0	\n\r','�$I6;��+f�k�u�|�'),('208920100001102','33638020002','35609204079202',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001103','33638020003','35609204079203',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001104','33638020004','35609204079204',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001105','33638020005','35609204079205',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001106','33638020006','35609204079206',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000000000000006103,'ebd07771ace8677a','�$I6;��+f�k�u�|�'),('208920100001107','33638020007','35609204079207',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001108','33638020008','35609204079208',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001109','33638020009','35609204079209',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001110','33638020010','35609204079210',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001111','33638030011','35609304079211',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001112','33638030012','35609304079212',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001113','33638030013','35609304079213',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006263,'�SNܒ�Iv��e�6','�4�s@���z��~�'),('208950000000008','33638050008','35609204079508',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000009','33638050009','35609204079509',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000010','33638050010','35609204079510',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000011','33638050011','35609204079511',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000012','33638050012','35609204079512',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000013','33638050013','35609204079513',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000014','33638050014','35609204079514',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000015','33638050015','35609204079515',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000000000,'3536663032363164','�4�s@���z��~�'),('208920100001118','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204934762,'~?03�u-%�ey�y�','�$I6;��+f�k�u�|�'),('208920100001121','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'&��@xg�]���\n��Vp','�$I6;��+f�k�u�|�'),('208920100001119','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'269482407867805d','�$I6;��+f�k�u�|�'),('208920100001120','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'3236393438323430','�$I6;��+f�k�u�|�');
+INSERT INTO `users` VALUES ('208990100001100','1','55000000000000',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0xfec86ba6eb707ed08905757b1bb44b8f,0,0,0x40,'ebd07771ace8677a',0xc42449363bbad02b66d16bc975d77cc1);
+INSERT INTO `users` VALUES ('208950000000031','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
+INSERT INTO `users` VALUES ('208950000000032','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
+INSERT INTO `users` VALUES ('208950000000033','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
+INSERT INTO `users` VALUES ('208950000000034','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
+INSERT INTO `users` VALUES ('208950000000035','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
+INSERT INTO `users` VALUES ('208950000000036','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
+INSERT INTO `users` VALUES ('208950000000037','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
+INSERT INTO `users` VALUES ('208950000000038','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
+INSERT INTO `users` VALUES ('208950000000039','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
+INSERT INTO `users` VALUES ('208950000000040','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
+/*!40000 ALTER TABLE `users` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2016-06-28 11:41:40
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/smf-healthcheck.sh b/ci-scripts/yaml_files/5g_rfsimulator/smf-healthcheck.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d9ff7608e80d8ec5e840e94bcf074d27759c702d
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_rfsimulator/smf-healthcheck.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+set -eo pipefail
+
+STATUS=0
+SMF_IP_SBI_INTERFACE=$(ifconfig $SMF_INTERFACE_NAME_FOR_SBI | grep inet | awk {'print $2'})
+SMF_SBI_PORT_STATUS=$(netstat -tnpl | grep -o "$SMF_IP_SBI_INTERFACE:$SMF_INTERFACE_PORT_FOR_SBI")
+
+#Check if entrypoint properly configured the conf file and no parameter is unset(optional)
+#NB_UNREPLACED_AT=`cat /openair-smf/etc/*.conf | grep -v contact@openairinterface.org | grep -c @ || true`
+
+#if [ $NB_UNREPLACED_AT -ne 0 ]; then
+#	STATUS=-1
+#	echo "Healthcheck error: UNHEALTHY configuration file is not configured properly"
+#fi
+#
+if [[ -z $SMF_SBI_PORT_STATUS ]]; then
+	STATUS=-1
+	echo "Healthcheck error: UNHEALTHY SBI TCP/HTTP port $SMF_INTERFACE_PORT_FOR_SBI is not listening."
+fi
+
+exit $STATUS
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/spgwu-healthcheck.sh b/ci-scripts/yaml_files/5g_rfsimulator/spgwu-healthcheck.sh
new file mode 100755
index 0000000000000000000000000000000000000000..0e3b67ee7e5653a19552ceae70abd36b04a223a7
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_rfsimulator/spgwu-healthcheck.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+set -eo pipefail
+
+STATUS=0
+SGW_PORT_FOR_S1U_S12_S4_UP=2152
+SGW_PORT_FOR_SX=8805
+SGW_IP_S1U_INTERFACE=$(ifconfig $SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP | grep inet | awk {'print $2'})
+SGW_IP_SX_INTERFACE=$(ifconfig $SGW_INTERFACE_NAME_FOR_SX | grep inet | awk {'print $2'})
+S1U_S12_S4_UP_PORT_STATUS=$(netstat -unpl | grep -o "$SGW_IP_S1U_INTERFACE:$SGW_PORT_FOR_S1U_S12_S4_UP")
+SX_PORT_STATUS=$(netstat -unpl | grep -o "$SGW_IP_SX_INTERFACE:$SGW_PORT_FOR_SX")
+#Check if entrypoint properly configured the conf file and no parameter is unset (optional)
+NB_UNREPLACED_AT=`cat /openair-spgwu/etc/*.conf | grep -v contact@openairinterface.org | grep -c @ || true`
+if [ $NB_UNREPLACED_AT -ne 0 ]; then
+	STATUS=1
+	echo "Healthcheck error: UNHEALTHY configuration file is not configured properly"
+fi
+
+if [[ -z $S1U_S12_S4_UP_PORT_STATUS ]]; then
+	STATUS=1
+	echo "Healthcheck error: UNHEALTHY S1U port $SGW_PORT_FOR_S1U_S12_S4_UP is not listening."
+fi
+
+if [[ -z $SX_PORT_STATUS ]]; then
+	STATUS=1
+	echo "Healthcheck error: UNHEALTHY SX port $SGW_PORT_FOR_SX is not listening."
+fi
+
+exit $STATUS
\ No newline at end of file
diff --git a/ci-scripts/yaml_files/fr1_epc_tim/docker-compose.yml b/ci-scripts/yaml_files/fr1_epc_tim/docker-compose.yml
index 28ae154838aed5b750eb9954ef7467f05318198d..73a6b3a1fff2b10258d0ed3dbcb21a4878c86681 100644
--- a/ci-scripts/yaml_files/fr1_epc_tim/docker-compose.yml
+++ b/ci-scripts/yaml_files/fr1_epc_tim/docker-compose.yml
@@ -40,18 +40,19 @@ services:
             private_net:
                 ipv4_address: 192.168.68.3
             public_net:
-                ipv4_address: 192.168.61.2
+                ipv4_address: 192.168.61.194
         environment:
+            TZ: Europe/Paris
             REALM: openairinterface.org
             HSS_FQDN: hss.openairinterface.org
             PREFIX: /openair-hss/etc
             cassandra_Server_IP: 192.168.68.2
             OP_KEY: 1006020f0a478bf6b699f15c062e42b3
-            LTE_K: fec86ba6eb707ed08905757b1bb44b8f
+            LTE_K: FEC86BA6EB707ED08905757B1BB44B8F 
             APN1: oai.ipv4
-            APN2: internet
-            FIRST_IMSI: 222010100001120
-            NB_USERS: 10
+            APN2: oai2.ipv4
+            FIRST_IMSI: 208990100001127 
+            NB_USERS: 5
         healthcheck:
             test: /bin/bash -c "pgrep oai_hss"
             interval: 10s
@@ -65,45 +66,46 @@ services:
         depends_on: [oai_hss]
         networks:
             public_net:
-                ipv4_address: 192.168.61.3
+                ipv4_address: 192.168.61.195
         environment:
+            TZ: Europe/Paris
             REALM: openairinterface.org
             PREFIX: /openair-mme/etc
             INSTANCE: 1
             PID_DIRECTORY: /var/run
-            HSS_IP_ADDR: 192.168.61.2
+            HSS_IP_ADDR: 192.168.61.194
             HSS_HOSTNAME: hss
             HSS_FQDN: hss.openairinterface.org
             HSS_REALM: openairinterface.org
-            MCC: '222'
-            MNC: '01'
+            MCC: '208'
+            MNC: '99'
             MME_GID: 32768
             MME_CODE: 3
             TAC_0: 1
             TAC_1: 2
             TAC_2: 3
             MME_FQDN: mme.openairinterface.org
-            MME_S6A_IP_ADDR: 192.168.61.3
+            MME_S6A_IP_ADDR: 192.168.61.195
             MME_INTERFACE_NAME_FOR_S1_MME: eth0
-            MME_IPV4_ADDRESS_FOR_S1_MME: 192.168.61.3
+            MME_IPV4_ADDRESS_FOR_S1_MME: 192.168.61.195
             MME_INTERFACE_NAME_FOR_S11: eth0
-            MME_IPV4_ADDRESS_FOR_S11: 192.168.61.3
+            MME_IPV4_ADDRESS_FOR_S11: 192.168.61.195
             MME_INTERFACE_NAME_FOR_S10: lo
             MME_IPV4_ADDRESS_FOR_S10: 127.0.0.10
             OUTPUT: CONSOLE
-            SGW_IPV4_ADDRESS_FOR_S11_0: 192.168.61.4
+            SGW_IPV4_ADDRESS_FOR_S11_0: 192.168.61.196
             PEER_MME_IPV4_ADDRESS_FOR_S10_0: 0.0.0.0
             PEER_MME_IPV4_ADDRESS_FOR_S10_1: 0.0.0.0
-            MCC_SGW_0: '222'
-            MNC3_SGW_0: '001'
+            MCC_SGW_0: '208'
+            MNC3_SGW_0: '099'
             TAC_LB_SGW_0: '01'
             TAC_HB_SGW_0: '00'
-            MCC_MME_0: '222'
-            MNC3_MME_0: '001'
+            MCC_MME_0: '208'
+            MNC3_MME_0: '099'
             TAC_LB_MME_0: '02'
             TAC_HB_MME_0: '00'
-            MCC_MME_1: '222'
-            MNC3_MME_1: '001'
+            MCC_MME_1: '208'
+            MNC3_MME_1: '099'
             TAC_LB_MME_1: '03'
             TAC_HB_MME_1: '00'
             TAC_LB_SGW_TEST_0: '03'
@@ -122,18 +124,25 @@ services:
         container_name: prod-oai-spgwc
         networks:
             public_net:
-                ipv4_address: 192.168.61.4
+                ipv4_address: 192.168.61.196
         environment:
-            PID_DIRECTORY: /var/run
+            TZ: Europe/Paris
             SGW_INTERFACE_NAME_FOR_S11: eth0
-            SGW_IP_FOR_S5_S8_CP: 127.0.0.11/8
-            PGW_IP_FOR_S5_S8_CP: 127.0.0.12/8
             PGW_INTERFACE_NAME_FOR_SX: eth0
-            DEFAULT_APN: oai.ipv4
             DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
             DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
-            UE_IP_ADDRESS_POOL: '12.1.1.2 - 12.1.1.254'
-            PUSH_PROTOCOL_OPTION: 'yes'
+            PUSH_PROTOCOL_OPTION: 'true'
+            APN_NI_1: oai.ipv4
+            APN_NI_2: oai2.ipv4
+            DEFAULT_APN_NI_1: oai.ipv4
+            UE_IP_ADDRESS_POOL_1: '12.1.1.2 - 12.1.1.254'
+            UE_IP_ADDRESS_POOL_2: '12.0.0.2 - 12.0.0.254'
+            MCC: '208'
+            MNC: '99'
+            MNC03: '099'
+            TAC: 1
+            GW_ID: 1
+            REALM: openairinterface.org
         healthcheck:
             test: /bin/bash -c "pgrep oai_spgwc"
             interval: 10s
@@ -147,45 +156,39 @@ services:
         depends_on: [oai_spgwc]
         networks:
             public_net:
-                ipv4_address: 192.168.61.5
+                ipv4_address: 192.168.61.197
         environment:
+            TZ: Europe/Paris
             PID_DIRECTORY: /var/run
             INSTANCE: 1
             SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP: eth0
             PGW_INTERFACE_NAME_FOR_SGI: eth0
             SGW_INTERFACE_NAME_FOR_SX: eth0
-            SPGWC0_IP_ADDRESS: 192.168.61.4
+            SPGWC0_IP_ADDRESS: 192.168.61.196
             NETWORK_UE_IP: '12.1.1.0/24'
             NETWORK_UE_NAT_OPTION: 'yes'
+            MCC: '208'
+            MNC: '99'
+            MNC03: '099'
+            TAC: 1
+            GW_ID: 1
+            REALM: openairinterface.org
         healthcheck:
             test: /bin/bash -c "pgrep oai_spgwu"
             interval: 10s
             timeout: 5s
             retries: 5
 
-    flexran_rtc:
-        image: flexran-rtc:production
-        privileged: true
-        container_name: prod-flexran-rtc
-        networks:
-            public_net:
-                ipv4_address: 192.168.61.10
-        healthcheck:
-            test: /bin/bash -c "pgrep rt_controller"
-            interval: 10s
-            timeout: 5s
-            retries: 5
-
     trf_gen:
         image: trf-gen:production
         privileged: true
         container_name: prod-trf-gen
         networks:
             public_net:
-                ipv4_address: 192.168.61.11
-        entrypoint: /bin/bash -c "ip route add 12.1.1.0/24 via 192.168.61.5 dev eth0; sleep infinity"
+                ipv4_address: 192.168.61.200
+        entrypoint: /bin/bash -c "ip route add 12.1.1.0/24 via 192.168.61.197 dev eth0; sleep infinity"
         healthcheck:
-            test: /bin/bash -c "ping -c 2 192.168.61.5"
+            test: /bin/bash -c "ping -c 2 192.168.61.197"
             interval: 10s
             timeout: 5s
             retries: 5
@@ -200,4 +203,4 @@ networks:
         name: prod-oai-public-net
         ipam:
             config:
-                - subnet: 192.168.61.0/26
+                - subnet: 192.168.61.192/26
diff --git a/ci-scripts/yaml_files/fr1_epc_tim/docker-compose.yml.orig b/ci-scripts/yaml_files/fr1_epc_tim/docker-compose.yml.orig
new file mode 100644
index 0000000000000000000000000000000000000000..28ae154838aed5b750eb9954ef7467f05318198d
--- /dev/null
+++ b/ci-scripts/yaml_files/fr1_epc_tim/docker-compose.yml.orig
@@ -0,0 +1,203 @@
+version: '3.8'
+
+services:
+    cassandra:
+        image: cassandra:2.1
+        container_name: prod-cassandra
+        networks:
+            private_net:
+                ipv4_address: 192.168.68.2
+        environment:
+            CASSANDRA_CLUSTER_NAME: "OAI HSS Cluster"
+            CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch
+        healthcheck:
+            test: /bin/bash -c "nodetool status"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    db_init:
+        image: cassandra:2.1
+        container_name: prod-db-init
+        depends_on: [cassandra]
+        deploy:
+            restart_policy:
+                condition: on-failure
+                max_attempts: 10
+        networks:
+            private_net:
+                ipv4_address: 192.168.68.4
+        volumes:
+            - ./oai_db.cql:/home/oai_db.cql
+        entrypoint: /bin/bash -c "cqlsh --file /home/oai_db.cql 192.168.68.2 && echo 'OK'"
+
+    oai_hss:
+        image: oai-hss:production
+        container_name: prod-oai-hss
+        privileged: true
+        depends_on: [cassandra]
+        networks:
+            private_net:
+                ipv4_address: 192.168.68.3
+            public_net:
+                ipv4_address: 192.168.61.2
+        environment:
+            REALM: openairinterface.org
+            HSS_FQDN: hss.openairinterface.org
+            PREFIX: /openair-hss/etc
+            cassandra_Server_IP: 192.168.68.2
+            OP_KEY: 1006020f0a478bf6b699f15c062e42b3
+            LTE_K: fec86ba6eb707ed08905757b1bb44b8f
+            APN1: oai.ipv4
+            APN2: internet
+            FIRST_IMSI: 222010100001120
+            NB_USERS: 10
+        healthcheck:
+            test: /bin/bash -c "pgrep oai_hss"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    oai_mme:
+        image: oai-mme:production
+        container_name: prod-oai-mme
+        privileged: true
+        depends_on: [oai_hss]
+        networks:
+            public_net:
+                ipv4_address: 192.168.61.3
+        environment:
+            REALM: openairinterface.org
+            PREFIX: /openair-mme/etc
+            INSTANCE: 1
+            PID_DIRECTORY: /var/run
+            HSS_IP_ADDR: 192.168.61.2
+            HSS_HOSTNAME: hss
+            HSS_FQDN: hss.openairinterface.org
+            HSS_REALM: openairinterface.org
+            MCC: '222'
+            MNC: '01'
+            MME_GID: 32768
+            MME_CODE: 3
+            TAC_0: 1
+            TAC_1: 2
+            TAC_2: 3
+            MME_FQDN: mme.openairinterface.org
+            MME_S6A_IP_ADDR: 192.168.61.3
+            MME_INTERFACE_NAME_FOR_S1_MME: eth0
+            MME_IPV4_ADDRESS_FOR_S1_MME: 192.168.61.3
+            MME_INTERFACE_NAME_FOR_S11: eth0
+            MME_IPV4_ADDRESS_FOR_S11: 192.168.61.3
+            MME_INTERFACE_NAME_FOR_S10: lo
+            MME_IPV4_ADDRESS_FOR_S10: 127.0.0.10
+            OUTPUT: CONSOLE
+            SGW_IPV4_ADDRESS_FOR_S11_0: 192.168.61.4
+            PEER_MME_IPV4_ADDRESS_FOR_S10_0: 0.0.0.0
+            PEER_MME_IPV4_ADDRESS_FOR_S10_1: 0.0.0.0
+            MCC_SGW_0: '222'
+            MNC3_SGW_0: '001'
+            TAC_LB_SGW_0: '01'
+            TAC_HB_SGW_0: '00'
+            MCC_MME_0: '222'
+            MNC3_MME_0: '001'
+            TAC_LB_MME_0: '02'
+            TAC_HB_MME_0: '00'
+            MCC_MME_1: '222'
+            MNC3_MME_1: '001'
+            TAC_LB_MME_1: '03'
+            TAC_HB_MME_1: '00'
+            TAC_LB_SGW_TEST_0: '03'
+            TAC_HB_SGW_TEST_0: '00'
+            SGW_IPV4_ADDRESS_FOR_S11_TEST_0: 0.0.0.0
+        healthcheck:
+            test: /bin/bash -c "pgrep oai_mme"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    oai_spgwc:
+        image: oai-spgwc:production
+        privileged: true
+        depends_on: [oai_mme]
+        container_name: prod-oai-spgwc
+        networks:
+            public_net:
+                ipv4_address: 192.168.61.4
+        environment:
+            PID_DIRECTORY: /var/run
+            SGW_INTERFACE_NAME_FOR_S11: eth0
+            SGW_IP_FOR_S5_S8_CP: 127.0.0.11/8
+            PGW_IP_FOR_S5_S8_CP: 127.0.0.12/8
+            PGW_INTERFACE_NAME_FOR_SX: eth0
+            DEFAULT_APN: oai.ipv4
+            DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
+            DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
+            UE_IP_ADDRESS_POOL: '12.1.1.2 - 12.1.1.254'
+            PUSH_PROTOCOL_OPTION: 'yes'
+        healthcheck:
+            test: /bin/bash -c "pgrep oai_spgwc"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    oai_spgwu:
+        image: oai-spgwu-tiny:production
+        privileged: true
+        container_name: prod-oai-spgwu-tiny
+        depends_on: [oai_spgwc]
+        networks:
+            public_net:
+                ipv4_address: 192.168.61.5
+        environment:
+            PID_DIRECTORY: /var/run
+            INSTANCE: 1
+            SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP: eth0
+            PGW_INTERFACE_NAME_FOR_SGI: eth0
+            SGW_INTERFACE_NAME_FOR_SX: eth0
+            SPGWC0_IP_ADDRESS: 192.168.61.4
+            NETWORK_UE_IP: '12.1.1.0/24'
+            NETWORK_UE_NAT_OPTION: 'yes'
+        healthcheck:
+            test: /bin/bash -c "pgrep oai_spgwu"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    flexran_rtc:
+        image: flexran-rtc:production
+        privileged: true
+        container_name: prod-flexran-rtc
+        networks:
+            public_net:
+                ipv4_address: 192.168.61.10
+        healthcheck:
+            test: /bin/bash -c "pgrep rt_controller"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    trf_gen:
+        image: trf-gen:production
+        privileged: true
+        container_name: prod-trf-gen
+        networks:
+            public_net:
+                ipv4_address: 192.168.61.11
+        entrypoint: /bin/bash -c "ip route add 12.1.1.0/24 via 192.168.61.5 dev eth0; sleep infinity"
+        healthcheck:
+            test: /bin/bash -c "ping -c 2 192.168.61.5"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+networks:
+    private_net:
+        name: prod-oai-private-net
+        ipam:
+            config:
+                - subnet: 192.168.68.0/26
+    public_net:
+        name: prod-oai-public-net
+        ipam:
+            config:
+                - subnet: 192.168.61.0/26
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index e11c850b8e732a85c262062b531160a2ffc3b5b8..44678b4c91855f3faa41354a1360cb09041c5405 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -45,6 +45,8 @@ include_directories(${CONFIG_INCLUDE_DIRS})
 pkg_search_module(CRYPTO libcrypto REQUIRED)
 include_directories(${CRYPTO_INCLUDE_DIRS})
 
+#uhd 4.0 and iris installs by default in /usr/local
+include_directories("/usr/local/include/")
 #use native cmake method as this package is not in pkg-config
 if (${RF_BOARD} STREQUAL "OAI_USRP")
   find_package(Boost REQUIRED)
@@ -52,7 +54,7 @@ if (${RF_BOARD} STREQUAL "OAI_USRP")
 
 elseif (${RF_BOARD} STREQUAL "OAI_IRIS")
     include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/")
-    include_directories("/usr/local/include/")
+
     set(HW_SOURCE ${HW_SOURCE}
             ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp)
     LINK_DIRECTORIES("/usr/local/lib")
@@ -60,6 +62,8 @@ elseif (${RF_BOARD} STREQUAL "OAI_IRIS")
 
 endif (${RF_BOARD} STREQUAL "OAI_USRP")
 
+message("RU=${RU}")
+
 pkg_search_module(OPENPGM openpgm-5.1 openpgm-5.2)
 if(NOT ${OPENPGM_FOUND})
   message("PACKAGE openpgm-5.1 is required by binaries such as oaisim: will fail later if this target is built")
@@ -120,13 +124,13 @@ if(EXISTS "/usr/include/atlas/cblas.h" OR EXISTS "/usr/include/cblas.h")
 
 # for ubuntu 17.10, directories are different
 elseif(EXISTS "/usr/include/x86_64-linux-gnu/cblas.h")
-
+  
   include_directories("/usr/include/x86_64-linux-gnu")
   LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu")
   list(APPEND ATLAS_LIBRARIES cblas)
   list(APPEND ATLAS_LIBRARIES atlas)
   list(APPEND ATLAS_LIBRARIES lapack)
-
+  
 else()
   message("No Blas/Atlas libs found, some targets will fail")
 endif()
@@ -151,8 +155,6 @@ set (OPENAIR_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY})
 
 project (OpenAirInterface)
 
-
-
 ##############################################
 # Base CUDA setting
 ##############################################
@@ -253,6 +255,7 @@ macro(add_list_string_option name val helpstr)
   endif()
 endmacro(add_list_string_option)
 
+# this function should produce the same value as the macro MAKE_VERSION defined in the C code (file types.h)
 function(make_version VERSION_VALUE)
   math(EXPR RESULT "0")
   foreach (ARG ${ARGN})
@@ -305,44 +308,38 @@ if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86")
 endif()
 
 #
-set(CMAKE_C_FLAGS
-  "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -pipe -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC")
 # add autotools definitions that were maybe used!
+add_definitions("-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")
+
+set(commonOpts "-pipe -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic")
+
+set(CMAKE_C_FLAGS
+  "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} ${commonOpts} -std=gnu99 -funroll-loops")
+set(CMAKE_CXX_FLAGS
+  "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR}  ${commonOpts} -std=c++11")
+
+# cuda compiler bug (limitation) on complex macro definition
 if (CUDA_FOUND)
-	set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'")
-    set(CUDA_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 CUDA_FLAG"
-    )
-    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"
-    )
-    set(CMAKE_CXX_FLAGS
-	"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -std=c++11 -D${MKVER} -D CUDA_FLAG"
-    )
-else (CUDA_FOUND)
-    set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'")
-    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}"
-    )
-    set(CMAKE_CXX_FLAGS
-	"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -std=c++11 -D${MKVER}"
-    )
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DCUDA_FLAG")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCUDA_FLAG")
+endif()
+
+if (SANITIZE_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")
 
 #########################
-set(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${CMAKE_CURRENT_BINARY_DIR}")
+set(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} -ggdb3 -Wl,-rpath -Wl,${CMAKE_CURRENT_BINARY_DIR}")
 #########################
 # 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_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3 -O2 -fno-delete-null-pointer-checks")
-set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS}  -O3")
+set(debugOpt "-ggdb3 -DMALLOC_CHECK_=3 -fno-delete-null-pointer-checks")
+set(CMAKE_C_FLAGS_DEBUG "${debugOpt} -O0")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO "${debugOpt} -O2")
+set(CMAKE_C_FLAGS_RELEASE "-O3")
 
 set(GIT_BRANCH        "UNKNOWN")
 set(GIT_COMMIT_HASH   "UNKNOWN")
@@ -376,7 +373,6 @@ if(GIT_FOUND)
   )
 endif()
 
-
 # Below is a hard-coded info
 set (FIRMWARE_VERSION "No svn information")
 add_definitions("-DFIRMWARE_VERSION=\"${FIRMWARE_VERSION}\"")
@@ -397,14 +393,12 @@ add_boolean_option(PDCP_MSG_PRINT      False "print PDCP messages to /tmp/pdcp.l
 add_boolean_option(DEBUG_PDCP_PAYLOAD  False "print PDCP PDU to stdout")  # if true, make sure that global and PDCP log levels are trace
 add_boolean_option(DEBUG_MAC_INTERFACE False "print MAC-RLC PDU exchange to stdout") # if true, make sure that global and PDCP log levels are trace
 add_boolean_option(TRACE_RLC_PAYLOAD   False "print RLC PDU to stdout") # if true, make sure that global and PDCP log levels are trace
-add_boolean_option(TEST_OMG            False "???")
-add_boolean_option(DEBUG_OMG           False "???")
 add_boolean_option(PRINT_STATS         False "This adds the possibility to see the status")
 add_boolean_option(T_TRACER            True  "Activate the T tracer, a debugging/monitoring framework" )
 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(DEBUG_CONSOLE       False "disables stdout/stderr buffering")
 
 set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti)
 add_library(ITTI
@@ -412,9 +406,6 @@ add_library(ITTI
   ${OPENAIR_DIR}/common/utils/backtrace.c
   )
 add_dependencies(ITTI rrc_flag)
-  set(ITTI_LIB ITTI)
-  set(GTPU_need_ITTI ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_eNB.c)
-
 
 ##################################################
 # ASN.1 grammar C code generation & dependencies #
@@ -430,7 +421,6 @@ set(asn1_generated_dir ${OPENAIR_BIN_DIR})
 set(protoc_call "${OPENAIR_CMAKE}/tools/generate_protobuf")
 set(protobuf_generated_dir ${OPENAIR_BIN_DIR})
 
-
 # RRC
 ######
 set (RRC_ASN1_VERSION "Rel15")
@@ -441,15 +431,18 @@ add_definitions(-DLTE_RRC_VERSION=${LTE_RRC_VERSION})
 set (RRC_FULL_DIR ${asn1_generated_dir}/RRC_${RRC_ASN1_VERSION})
 
 # Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
-execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${RRC_FULL_DIR}" "${RRC_GRAMMAR}" "LTE_"
-                RESULT_VARIABLE ret)
+if (${RU} STREQUAL 0)
+  execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh  "LTE_" " " "${RRC_FULL_DIR}" "${RRC_GRAMMAR}"
+                  RESULT_VARIABLE ret)
+endif (${RU} STREQUAL 0)
+
 if (NOT ${ret} STREQUAL 0)
   message(FATAL_ERROR "${ret}: error")
 endif (NOT ${ret} STREQUAL 0)
 file(GLOB rrc_source ${RRC_FULL_DIR}/*.c)
 add_custom_target (
   rrc_flag ALL
-  ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${RRC_FULL_DIR}" "${RRC_GRAMMAR}" "LTE_"
+  ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "LTE_" " " "${RRC_FULL_DIR}" "${RRC_GRAMMAR}"
   DEPENDS ${RRC_GRAMMAR}
   )
 
@@ -470,20 +463,22 @@ add_definitions(-DNR_RRC_VERSION=${NR_RRC_VERSION})
 set (NR_RRC_FULL_DIR ${asn1_generated_dir}/RRC_${NR_RRC_ASN1_VERSION})
 
 # 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 "${NR_RRC_FULL_DIR}" "${NR_RRC_GRAMMAR}" "NR_" "-findirect-choice"
-                RESULT_VARIABLE ret)
+  execute_process(
+    COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "NR_" "-findirect-choice" "${NR_RRC_FULL_DIR}" "${NR_RRC_GRAMMAR}"
+    RESULT_VARIABLE ret)
 if (NOT ${ret} STREQUAL 0)
   message(FATAL_ERROR "${ret}: error")
 endif ()
 file(GLOB nr_rrc_source ${NR_RRC_FULL_DIR}/*.c)
 file(GLOB nr_rrc_h ${NR_RRC_FULL_DIR}/*.h)
+
 add_custom_target (
   nr_rrc_flag ALL
-  ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${NR_RRC_FULL_DIR}" "${NR_RRC_GRAMMAR}" "NR_" "-findirect-choice"
+  ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh  "NR_" "-findirect-choice" "${NR_RRC_FULL_DIR}" "${NR_RRC_GRAMMAR}"
   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)
@@ -504,18 +499,21 @@ set(S1AP_ASN_DIR ${S1AP_DIR}/MESSAGES/ASN1/${S1AP_RELEASE})
 set(S1AP_C_DIR ${asn1_generated_dir}/S1AP_${S1AP_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 "${S1AP_C_DIR}" "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" "S1AP_" -fno-include-deps
-                RESULT_VARIABLE ret)
-if (NOT ${ret} STREQUAL 0)
-  message(FATAL_ERROR "${ret}: error")
-endif (NOT ${ret} STREQUAL 0)
-file(GLOB S1AP_source ${S1AP_C_DIR}/*.c)
+if (${RU} STREQUAL 0)
+  execute_process(
+    COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh  "S1AP_" -fno-include-deps "${S1AP_C_DIR}" "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}"
+    RESULT_VARIABLE ret)
+  if (NOT ${ret} STREQUAL 0)
+    message(FATAL_ERROR "${ret}: error")
+  endif (NOT ${ret} STREQUAL 0)
+  file(GLOB S1AP_source ${S1AP_C_DIR}/*.c)
+endif (${RU} STREQUAL 0)
 
-add_custom_target (
-  s1ap_flag ALL
-  ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${S1AP_C_DIR}" "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" "S1AP_" -fno-include-deps
-  DEPENDS  "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" 
-)
+  add_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}"
+  )
 
 add_library(S1AP_LIB
   ${S1AP_source}
@@ -558,8 +556,9 @@ set(NGAP_ASN_DIR ${NGAP_DIR}/MESSAGES/ASN1/ASN1_files)
 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_C_DIR}" "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}" "NGAP_" -fno-include-deps -findirect-choice
-                RESULT_VARIABLE ret)
+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}"
+  RESULT_VARIABLE ret)
 if (NOT ${ret} STREQUAL 0)
   message(FATAL_ERROR "${ret}: error")
 endif (NOT ${ret} STREQUAL 0)
@@ -567,8 +566,8 @@ file(GLOB NGAP_source ${NGAP_C_DIR}/*.c)
 
 add_custom_target (
   ngap_flag ALL
-  ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${NGAP_C_DIR}" "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}" "NGAP_" -fno-include-deps
-  DEPENDS  "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}" 
+  ${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}"
 )
 
 add_library(NGAP_LIB
@@ -624,17 +623,20 @@ set(M2AP_ASN_DIR ${M2AP_DIR}/MESSAGES/ASN1/${M2AP_RELEASE})
 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
-execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${M2AP_C_DIR}" "${M2AP_ASN_DIR}/${M2AP_ASN_FILES}"  "M2AP_" -fno-include-deps -DEMIT_ASN_DEBUG=1
-                RESULT_VARIABLE ret)
-if (NOT ${ret} STREQUAL 0)
-  message(FATAL_ERROR "${ret}: error")
-endif (NOT ${ret} STREQUAL 0)
+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}"
+    RESULT_VARIABLE ret)
+  if (NOT ${ret} STREQUAL 0)
+    message(FATAL_ERROR "${ret}: error")
+  endif (NOT ${ret} STREQUAL 0)
+endif (${RU} STREQUAL 0)
 
 file(GLOB M2AP_source ${M2AP_C_DIR}/*.c)
 
 add_custom_target (
   m2_flag ALL
-  COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${M2AP_C_DIR}" "${M2AP_ASN_DIR}/${M2AP_ASN_FILES}"  "M2AP_" -fno-include-deps
+  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}"
   DEPENDS ${M2AP_ASN_DIR}/${M2AP_ASN_FILES}
   )
 
@@ -694,17 +696,20 @@ set(M3AP_ASN_DIR ${M3AP_DIR}/MESSAGES/ASN1/${M3AP_RELEASE})
 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
-execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${M3AP_C_DIR}" "${M3AP_ASN_DIR}/${M3AP_ASN_FILES}"  "M3AP_" -fno-include-deps
-                RESULT_VARIABLE ret)
-if (NOT ${ret} STREQUAL 0)
-  message(FATAL_ERROR "${ret}: error")
-endif (NOT ${ret} STREQUAL 0)
+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}"
+    RESULT_VARIABLE ret)
+  if (NOT ${ret} STREQUAL 0)
+    message(FATAL_ERROR "${ret}: error")
+  endif (NOT ${ret} STREQUAL 0)
+endif (${RU} STREQUAL 0)
 
 file(GLOB M3AP_source ${M3AP_C_DIR}/*.c)
 
 add_custom_target (
   m3_flag ALL
-  COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${M3AP_C_DIR}" "${M3AP_ASN_DIR}/${M3AP_ASN_FILES}"  "M3AP_" -fno-include-deps
+  COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh  "M3AP_" -fno-include-deps "${M3AP_C_DIR}" "${M3AP_ASN_DIR}/${M3AP_ASN_FILES}"
   DEPENDS ${M3AP_ASN_DIR}/${M3AP_ASN_FILES}
   )
 
@@ -748,17 +753,20 @@ add_definitions(-DX2AP_VERSION=${X2AP_VERSION})
 set(X2AP_ASN_DIR ${X2AP_DIR}/MESSAGES/ASN1/${X2AP_RELEASE})
 set(X2AP_C_DIR ${asn1_generated_dir}/X2AP_${X2AP_RELEASE})
 # Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
-execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${X2AP_C_DIR}" "${X2AP_ASN_DIR}/${X2AP_ASN_FILES}"  "X2AP_" -fno-include-deps
-                RESULT_VARIABLE ret)
-if (NOT ${ret} STREQUAL 0)
-  message(FATAL_ERROR "${ret}: error")
-endif (NOT ${ret} STREQUAL 0)
+if (${RU} STREQUAL 0)
+  execute_process(
+    COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "X2AP_" -fno-include-deps "${X2AP_C_DIR}" "${X2AP_ASN_DIR}/${X2AP_ASN_FILES}"
+    RESULT_VARIABLE ret)
+  if (NOT ${ret} STREQUAL 0)
+    message(FATAL_ERROR "${ret}: error")
+  endif (NOT ${ret} STREQUAL 0)
+endif (${RU} STREQUAL 0)
 
 file(GLOB X2AP_source ${X2AP_C_DIR}/*.c)
 
 add_custom_target (
   x2_flag ALL
-  COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${X2AP_C_DIR}" "${X2AP_ASN_DIR}/${X2AP_ASN_FILES}"  "X2AP_" -fno-include-deps
+  COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "X2AP_" -fno-include-deps "${X2AP_C_DIR}" "${X2AP_ASN_DIR}/${X2AP_ASN_FILES}"
   DEPENDS ${X2AP_ASN_DIR}/${X2AP_ASN_FILES}
   )
 
@@ -787,12 +795,13 @@ add_dependencies(X2AP_ENB X2AP_LIB rrc_flag x2_flag)
 
 # F1AP
 ##############
-add_list1_option(F1AP_RELEASE R15 "F1AP ASN.1 grammar version" R15)
+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 "R15")
-  make_version(F1AP_VERSION 15 2 1)
-  set (ASN1RELDIR R15.2.1)
-endif(${F1AP_RELEASE} STREQUAL "R15")
+if (${F1AP_RELEASE} STREQUAL "R16")
+  make_version(F1AP_VERSION 16 3 1)
+  set (ASN1RELDIR R16.3.1)
+endif(${F1AP_RELEASE} STREQUAL "R16")
 add_definitions(-DF1AP_VERSION=${F1AP_VERSION})
 set(F1AP_ASN_DIR ${F1AP_DIR}/MESSAGES/ASN1/${ASN1RELDIR})
 set(F1AP_ASN_FILES
@@ -804,60 +813,63 @@ set(F1AP_ASN_FILES
   ${F1AP_ASN_DIR}/F1AP-Containers.asn
   )
 
-set(F1AP_ASN_GENERATED_C_DIR ${asn1_generated_dir}/F1AP_${ASN1RELDIR})
-message("calling ASN1C_PREFIX=F1AP_ asn1c -gen-PER -no-gen-OER -fcompound-names -no-gen-example -findirect-choice -fno-include-deps -D ${F1AP_ASN_GENERATED_C_DIR} ${F1AP_ASN_FILES}")
-execute_process(COMMAND mkdir -p ${F1AP_ASN_GENERATED_C_DIR}
-   COMMAND env "ASN1C_PREFIX=F1AP_" asn1c -gen-PER -no-gen-OER -fcompound-names -no-gen-example -findirect-choice -fno-include-deps -D ${F1AP_ASN_GENERATED_C_DIR} ${F1AP_ASN_FILES}
-                RESULT_VARIABLE ret
-                OUTPUT_QUIET
-                ERROR_QUIET)
-
-if (NOT ${ret} STREQUAL 0)
-  message(FATAL_ERROR "asn1c: error")
-endif (NOT ${ret} STREQUAL 0)
-
-file(GLOB F1AP_ASN_GENERATED_C_FILES ${F1AP_ASN_GENERATED_C_DIR}/*.c)
-add_library(F1AP_LIB
-  ${F1AP_ASN_GENERATED_C_FILES}
-)
-
-include_directories ("${F1AP_ASN_GENERATED_C_DIR}")
-include_directories ("${F1AP_DIR}")
-
-file(GLOB F1AP_C_FILES ${F1AP_DIR}/*.c)
-add_library(F1AP
-  ${F1AP_C_FILES}
-)
-
+if (${RU} STREQUAL 0)
+  set(F1AP_ASN_GENERATED_C_DIR ${asn1_generated_dir}/F1AP_${ASN1RELDIR})
+  message("calling ASN1C_PREFIX=F1AP_ asn1c -gen-PER -no-gen-OER -fcompound-names -no-gen-example -findirect-choice -fno-include-deps -D ${F1AP_ASN_GENERATED_C_DIR} ${F1AP_ASN_FILES}")
+  execute_process(
+    COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "F1AP_" "-findirect-choice -fno-include-deps" ${F1AP_ASN_GENERATED_C_DIR} ${F1AP_ASN_FILES}
+    RESULT_VARIABLE ret
+    )
+  
+  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}
+    DEPENDS ${F1AP_ASN_FILES}
+    )
+  file(GLOB F1AP_ASN_GENERATED_C_FILES ${F1AP_ASN_GENERATED_C_DIR}/*.c)
+  add_library(F1AP_LIB
+    ${F1AP_ASN_GENERATED_C_FILES}
+    )
+  add_dependencies (F1AP_LIB  f1_flag)
+  
+  include_directories ("${F1AP_ASN_GENERATED_C_DIR}")
+  include_directories ("${F1AP_DIR}")
+  
+  file(GLOB F1AP_C_FILES ${F1AP_DIR}/*.c)
+  add_library(F1AP ${F1AP_C_FILES} )
+  
+endif (${RU} STREQUAL 0)
 
 # Hardware dependant options
 ###################################
-add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4")
+add_list1_option(NB_ANTENNAS_RX "4" "Number of antennas in reception" "1" "2" "4")
 add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4")
 
 add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "OAI_USRP" "OAI_BLADERF" "OAI_LMSSDR" "OAI_SIMU")
 
-
-
 add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET")
 #NOKIA config enhancement
 set (CONFIG_ROOTDIR
-    ${OPENAIR_DIR}/common/config
-   )
+  ${OPENAIR_DIR}/common/config
+  )
 set (CONFIG_SOURCES
-    ${CONFIG_ROOTDIR}/config_load_configmodule.c
-    ${CONFIG_ROOTDIR}/config_userapi.c
-    ${CONFIG_ROOTDIR}/config_cmdline.c
-   )
+  ${CONFIG_ROOTDIR}/config_load_configmodule.c
+  ${CONFIG_ROOTDIR}/config_userapi.c
+  ${CONFIG_ROOTDIR}/config_cmdline.c
+  )
 set (CONFIG_LIBCONFIG_SOURCES
-    ${CONFIG_ROOTDIR}/libconfig/config_libconfig.c
-    )
+  ${CONFIG_ROOTDIR}/libconfig/config_libconfig.c
+  )
 add_library(CONFIG_LIB ${CONFIG_SOURCES})
 add_library(params_libconfig MODULE ${CONFIG_LIBCONFIG_SOURCES} )
 target_link_libraries(params_libconfig config)
 # shared library loader
 set (SHLIB_LOADER_SOURCES
-    ${OPENAIR_DIR}/common/utils/load_module_shlib.c
+  ${OPENAIR_DIR}/common/utils/load_module_shlib.c
 )
 # include RF devices / transport protocols library modules
 ######################################################################
@@ -896,8 +908,8 @@ add_library(oai_eth_transpro MODULE ${TPLIB_ETHERNET_SOURCE} )
 include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/")
 set(option_HWIRISLIB_lib "-l SoapySDR")
 set(HWLIB_IRIS_SOURCE
-        ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp
-        )
+  ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp
+  )
 add_library(oai_irisdevif MODULE ${HWLIB_IRIS_SOURCE})
 target_include_directories(oai_irisdevif PRIVATE /usr/local/lib/SoapySDR/modules0.7/)
 target_link_libraries(oai_irisdevif SoapySDR)
@@ -926,6 +938,9 @@ set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidd
 # Benetel 4G library
 ######################################################################
 
+
+include_directories ("/usr/include/dpdk")
+
 set(HWLIB_BENETEL_4G_SOURCE
   ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/benetel.c
   ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/shared_buffers.c
@@ -1001,7 +1016,6 @@ add_boolean_option(ENABLE_VCD              False  "always true now, time measure
 add_boolean_option(ENABLE_VCD_FIFO         False  "time measurements of proc calls and var displays sent to FIFO (one more thread)")
 add_boolean_option(LINUX                   False "used in weird memcpy() in pdcp.c ???")
 add_boolean_option(LINUX_LIST              False "used only in lists.c: either use OAI implementation of lists or Linux one (should be True, but it is False")
-add_boolean_option(OPENAIR_LTE             True "Seems legacy: keep it to true")
 
 ##########################
 # PHY options
@@ -1010,10 +1024,7 @@ add_boolean_option(DRIVER2013              True "only relevant for EXMIMO")
 add_boolean_option(EXMIMO_IOT              True "????")
 add_boolean_option(LOCALIZATION            False "???")
 add_integer_option(MAX_NUM_CCs             1     "????")
-add_boolean_option(MU_RECEIVER             False "????")
 add_boolean_option(PHYSIM                  False  "for L1 simulators (dlsim, ulsim, ...)")
-add_boolean_option(PHY_CONTEXT             True "not clear: must remain False for dlsim")
-add_boolean_option(PHY_EMUL                False "not clear: must remain False for dlsim")
 add_boolean_option(SMBV                    False "Rohde&Schwarz SMBV100A vector signal generator")
 add_boolean_option(DEBUG_PHY               False "Enable PHY layer debugging options")
 add_boolean_option(DEBUG_PHY_PROC          False "Enable debugging of PHY layer procedures")
@@ -1355,42 +1366,42 @@ target_link_libraries (msc LFDS)
 include_directories(${OPENAIR_DIR}/common/utils/msc)
 
 set(UTIL_SRC
-#  ${OPENAIR2_DIR}/UTIL/CLI/cli.c
-#  ${OPENAIR2_DIR}/UTIL/CLI/cli_cmd.c
-#  ${OPENAIR2_DIR}/UTIL/CLI/cli_server.c
+  #  ${OPENAIR2_DIR}/UTIL/CLI/cli.c
+  #  ${OPENAIR2_DIR}/UTIL/CLI/cli_cmd.c
+  #  ${OPENAIR2_DIR}/UTIL/CLI/cli_server.c
   ${OPENAIR2_DIR}/UTIL/FIFO/pad_list.c
   ${OPENAIR2_DIR}/UTIL/LISTS/list.c
   ${OPENAIR2_DIR}/UTIL/LISTS/list2.c
   ${OPENAIR_DIR}/common/utils/LOG/log.c
   ${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.c
   ${OPENAIR2_DIR}/UTIL/MATH/oml.c
-#  ${OPENAIR2_DIR}/UTIL/MEM/mem_block.c
-#  ${OPENAIR2_DIR}/UTIL/OCG/OCG.c
-#  ${OPENAIR2_DIR}/UTIL/OCG/OCG_create_dir.c
-#  ${OPENAIR2_DIR}/UTIL/OCG/OCG_detect_file.c
-#  ${OPENAIR2_DIR}/UTIL/OCG/OCG_generate_report.c
-#  ${OPENAIR2_DIR}/UTIL/OCG/OCG_parse_filename.c
-#  ${OPENAIR2_DIR}/UTIL/OCG/OCG_parse_XML.c
-#  ${OPENAIR2_DIR}/UTIL/OCG/OCG_save_XML.c
-#  ${OPENAIR2_DIR}/UTIL/OMG/common.c
-#  ${OPENAIR2_DIR}/UTIL/OMG/grid.c
-#  ${OPENAIR2_DIR}/UTIL/OMG/job.c
-#  ${OPENAIR2_DIR}/UTIL/OMG/mobility_parser.c
-#  ${OPENAIR2_DIR}/UTIL/OMG/omg.c
-#  ${OPENAIR2_DIR}/UTIL/OMG/omg_hashtable.c
-#  ${OPENAIR2_DIR}/UTIL/OMG/rwalk.c
-#  ${OPENAIR2_DIR}/UTIL/OMG/rwp.c
-#  ${OPENAIR2_DIR}/UTIL/OMG/static.c
-#  ${OPENAIR2_DIR}/UTIL/OMG/steadystaterwp.c
-#  ${OPENAIR2_DIR}/UTIL/OMG/trace.c
-#  ${OPENAIR2_DIR}/UTIL/OMG/trace_hashtable.c
+  #  ${OPENAIR2_DIR}/UTIL/MEM/mem_block.c
+  #  ${OPENAIR2_DIR}/UTIL/OCG/OCG.c
+  #  ${OPENAIR2_DIR}/UTIL/OCG/OCG_create_dir.c
+  #  ${OPENAIR2_DIR}/UTIL/OCG/OCG_detect_file.c
+  #  ${OPENAIR2_DIR}/UTIL/OCG/OCG_generate_report.c
+  #  ${OPENAIR2_DIR}/UTIL/OCG/OCG_parse_filename.c
+  #  ${OPENAIR2_DIR}/UTIL/OCG/OCG_parse_XML.c
+  #  ${OPENAIR2_DIR}/UTIL/OCG/OCG_save_XML.c
+  #  ${OPENAIR2_DIR}/UTIL/OMG/common.c
+  #  ${OPENAIR2_DIR}/UTIL/OMG/grid.c
+  #  ${OPENAIR2_DIR}/UTIL/OMG/job.c
+  #  ${OPENAIR2_DIR}/UTIL/OMG/mobility_parser.c
+  #  ${OPENAIR2_DIR}/UTIL/OMG/omg.c
+  #  ${OPENAIR2_DIR}/UTIL/OMG/omg_hashtable.c
+  #  ${OPENAIR2_DIR}/UTIL/OMG/rwalk.c
+  #  ${OPENAIR2_DIR}/UTIL/OMG/rwp.c
+  #  ${OPENAIR2_DIR}/UTIL/OMG/static.c
+  #  ${OPENAIR2_DIR}/UTIL/OMG/steadystaterwp.c
+  #  ${OPENAIR2_DIR}/UTIL/OMG/trace.c
+  #  ${OPENAIR2_DIR}/UTIL/OMG/trace_hashtable.c
   ${OPENAIR2_DIR}/UTIL/OPT/probe.c
-#  ${OPENAIR2_DIR}/UTIL/OTG/otg_tx.c
-#  ${OPENAIR2_DIR}/UTIL/OTG/otg.c
-#  ${OPENAIR2_DIR}/UTIL/OTG/otg_kpi.c
-#  ${OPENAIR2_DIR}/UTIL/OTG/otg_models.c
-#  ${OPENAIR2_DIR}/UTIL/OTG/otg_form.c
-#  ${OPENAIR2_DIR}/UTIL/OTG/otg_rx.c
+  #  ${OPENAIR2_DIR}/UTIL/OTG/otg_tx.c
+  #  ${OPENAIR2_DIR}/UTIL/OTG/otg.c
+  #  ${OPENAIR2_DIR}/UTIL/OTG/otg_kpi.c
+  #  ${OPENAIR2_DIR}/UTIL/OTG/otg_models.c
+  #  ${OPENAIR2_DIR}/UTIL/OTG/otg_form.c
+  #  ${OPENAIR2_DIR}/UTIL/OTG/otg_rx.c
   )
 add_library(UTIL ${UTIL_SRC})
 add_dependencies(UTIL rrc_flag)
@@ -1468,11 +1479,10 @@ 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 
 )
 add_library(SCHED_NR_UE_LIB ${SCHED_SRC_NR_UE})
 
@@ -1481,7 +1491,7 @@ add_library(SCHED_NR_UE_LIB ${SCHED_SRC_NR_UE})
 #################################
 set(NFAPI_COMMON_SRC
   ${NFAPI_DIR}/common/src/debug.c
-)
+  )
 add_library(NFAPI_COMMON_LIB ${NFAPI_COMMON_SRC})
 
 include_directories(${NFAPI_DIR}/common/public_inc)
@@ -1632,7 +1642,6 @@ set(PHY_SRC_COMMON
   ${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c
   ${OPENAIR1_DIR}/PHY/INIT/init_top.c
   ${OPENAIR1_DIR}/PHY/INIT/lte_parms.c
-  ${OPENAIR1_DIR}/PHY/INIT/lte_param_init.c
   ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
   ${OPENAIR1_DIR}/PHY/TOOLS/dfts_load.c
   ${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c
@@ -1783,7 +1792,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
@@ -1962,13 +1971,15 @@ 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
   ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c
-  ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
+  ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_sdu.c
+  ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c
   ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
+  ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
   ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
   )
 
@@ -1987,12 +1998,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
@@ -2038,14 +2050,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}
@@ -2103,7 +2115,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
@@ -2137,7 +2149,6 @@ set (MISC_NFAPI_LTE
  ${OPENAIR1_DIR}/SCHED/nfapi_lte_dummy.c
  )
 
-
 add_library(MISC_NFAPI_LTE_LIB
   ${MISC_NFAPI_LTE}
  )
@@ -2146,7 +2157,6 @@ set (MISC_NFAPI_NR
  ${OPENAIR1_DIR}/SCHED/nfapi_nr_dummy.c
  )
 
-
 add_library(MISC_NFAPI_NR_LIB
   ${MISC_NFAPI_NR}
  )
@@ -2175,6 +2185,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}
@@ -2182,7 +2193,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
@@ -2223,32 +2235,28 @@ add_library(CN_UTILS
   )
 
 set(GTPV1U_DIR ${OPENAIR3_DIR}/GTPV1-U)
-set (GTPV1U_SRC
-  ${RRC_DIR}/rrc_eNB_GTPV1U.c
-  ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTunnelEndPoint.c
-  ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTrxn.c
-  ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uMsg.c
-  ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1u.c
-  ${GTPV1U_DIR}/gtpv1u_teid_pool.c
-)
-add_library(GTPV1U ${GTPV1U_SRC})
-add_dependencies(GTPV1U rrc_flag)
 
-#add_library (GTPV1U_OCP
-#${OPENAIR3_DIR}/ocp-gtp/gtp_itf.cpp
-#)
-#include_directories(${OPENAIR3_DIR}/ocp-gtp)
+add_library (GTPV1U_OCP
+  ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c
+  ${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)
 
 #NR case
 set (NR_GTPV1U_SRC
   ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c
   ${RRC_DIR}/rrc_eNB_GTPV1U.c
+  ${GTPV1U_DIR}/gtpv1u_eNB.c
+  ${GTPV1U_DIR}/gtpv1u_gNB.c
   ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTunnelEndPoint.c
   ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTrxn.c
   ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uMsg.c
   ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1u.c
   ${GTPV1U_DIR}/gtpv1u_teid_pool.c
-)
+  )
 add_library(NR_GTPV1U ${NR_GTPV1U_SRC})
 add_dependencies(NR_GTPV1U rrc_flag)
 
@@ -2270,7 +2278,6 @@ add_dependencies(SCTP_CLIENT rrc_flag)
 add_library(UDP ${OPENAIR3_DIR}/UDP/udp_eNB_task.c)
 add_dependencies(UDP rrc_flag)
 
-
 set(NAS_SRC ${OPENAIR3_DIR}/NAS/)
 set(libnas_api_OBJS
   ${NAS_SRC}COMMON/API/NETWORK/as_message.c
@@ -2429,253 +2436,171 @@ set (libnas_utils_OBJS
   ${NAS_SRC}COMMON/UTIL/OctetString.c
 )
 
-if(NAS_UE)
-  set(libnas_ue_api_OBJS
-    ${NAS_SRC}UE/API/USER/at_command.c
-    ${NAS_SRC}UE/API/USER/at_error.c
-    ${NAS_SRC}UE/API/USER/at_response.c
-    ${NAS_SRC}UE/API/USER/user_api.c
-    ${NAS_SRC}UE/API/USER/user_indication.c
-    ${NAS_SRC}UE/API/USIM/aka_functions.c
-    ${NAS_SRC}UE/API/USIM/usim_api.c
-  )
-  set(libnas_ue_emm_OBJS
-    ${NAS_SRC}UE/EMM/Attach.c
-    ${NAS_SRC}UE/EMM/Authentication.c
-    ${NAS_SRC}UE/EMM/Detach.c
-    ${NAS_SRC}UE/EMM/emm_main.c
-    ${NAS_SRC}UE/EMM/EmmStatusHdl.c
-    ${NAS_SRC}UE/EMM/Identification.c
-    ${NAS_SRC}UE/EMM/IdleMode.c
-    ${NAS_SRC}UE/EMM/LowerLayer.c
-    ${NAS_SRC}UE/EMM/SecurityModeControl.c
-    ${NAS_SRC}UE/EMM/ServiceRequestHdl.c
-    ${NAS_SRC}UE/EMM/TrackingAreaUpdate.c
-  )
-  set(libnas_ue_emm_sap_OBJS
-    ${NAS_SRC}UE/EMM/SAP/emm_as.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredAttachNeeded.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregistered.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredInitiated.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredLimitedService.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNoImsi.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNormalService.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredPlmnSearch.c
-    ${NAS_SRC}UE/EMM/SAP/emm_esm.c
-    ${NAS_SRC}UE/EMM/SAP/emm_fsm.c
-    ${NAS_SRC}UE/EMM/SAP/EmmNull.c
-    ${NAS_SRC}UE/EMM/SAP/emm_recv.c
-    ${NAS_SRC}UE/EMM/SAP/emm_reg.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegistered.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredInitiated.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredLimitedService.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredNoCellAvailable.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredNormalService.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredPlmnSearch.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredUpdateNeeded.c
-    ${NAS_SRC}UE/EMM/SAP/emm_sap.c
-    ${NAS_SRC}UE/EMM/SAP/emm_send.c
-    ${NAS_SRC}UE/EMM/SAP/EmmServiceRequestInitiated.c
-    ${NAS_SRC}UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c
-  )
-  set (libnas_ue_esm_OBJS
-    ${NAS_SRC}UE/ESM/DedicatedEpsBearerContextActivation.c
-    ${NAS_SRC}UE/ESM/DefaultEpsBearerContextActivation.c
-    ${NAS_SRC}UE/ESM/EpsBearerContextDeactivation.c
-    ${NAS_SRC}UE/ESM/esm_ebr.c
-    ${NAS_SRC}UE/ESM/esm_ebr_context.c
-    ${NAS_SRC}UE/ESM/esm_ip.c
-    ${NAS_SRC}UE/ESM/esm_main.c
-    ${NAS_SRC}UE/ESM/esm_pt.c
-    ${NAS_SRC}UE/ESM/EsmStatusHdl.c
-    ${NAS_SRC}UE/ESM/PdnConnectivity.c
-    ${NAS_SRC}UE/ESM/PdnDisconnect.c
-  )
-  set(libnas_ue_esm_sap_OBJS
-    ${NAS_SRC}UE/ESM/SAP/esm_recv.c
-    ${NAS_SRC}UE/ESM/SAP/esm_send.c
-    ${NAS_SRC}UE/ESM/SAP/esm_sap.c
-  )
-  add_library(LIB_NAS_UE
-    ${NAS_SRC}UE/nas_itti_messaging.c
-    ${NAS_SRC}UE/nas_network.c
-    ${NAS_SRC}UE/nas_parser.c
-    ${NAS_SRC}UE/nas_proc.c
-    ${NAS_SRC}UE/nas_user.c
-    ${libnas_api_OBJS}
-    ${libnas_ue_api_OBJS}
-    ${libnas_emm_msg_OBJS}
-    ${libnas_esm_msg_OBJS}
-    ${libnas_ies_OBJS}
-    ${libnas_utils_OBJS}
-    ${libnas_ue_emm_OBJS}
-    ${libnas_ue_emm_sap_OBJS}
-    ${libnas_ue_esm_OBJS}
-    ${libnas_ue_esm_sap_OBJS}
-  )
-  add_dependencies(LIB_NAS_UE rrc_flag)
-  set(NAS_UE_LIB LIB_NAS_UE)
-
-  include_directories(${NAS_SRC}UE)
-  include_directories(${NAS_SRC}UE/API/USER)
-  include_directories(${NAS_SRC}UE/API/USIM)
-  include_directories(${NAS_SRC}UE/EMM)
-  include_directories(${NAS_SRC}UE/EMM/SAP)
-  include_directories(${NAS_SRC}UE/ESM)
-  include_directories(${NAS_SRC}UE/ESM/SAP)
-endif()
-
-
-if(ITTI_SIM)
-  set(libnas_ue_api_OBJS
-    ${NAS_SRC}UE/API/USER/at_command.c
-    ${NAS_SRC}UE/API/USER/at_error.c
-    ${NAS_SRC}UE/API/USER/at_response.c
-    ${NAS_SRC}UE/API/USER/user_api.c
-    ${NAS_SRC}UE/API/USER/user_indication.c
-    ${NAS_SRC}UE/API/USIM/aka_functions.c
-    ${NAS_SRC}UE/API/USIM/usim_api.c
-  )
-  set(libnas_ue_emm_OBJS
-    ${NAS_SRC}UE/EMM/Attach.c
-    ${NAS_SRC}UE/EMM/Authentication.c
-    ${NAS_SRC}UE/EMM/Detach.c
-    ${NAS_SRC}UE/EMM/emm_main.c
-    ${NAS_SRC}UE/EMM/EmmStatusHdl.c
-    ${NAS_SRC}UE/EMM/Identification.c
-    ${NAS_SRC}UE/EMM/IdleMode.c
-    ${NAS_SRC}UE/EMM/LowerLayer.c
-    ${NAS_SRC}UE/EMM/SecurityModeControl.c
-    ${NAS_SRC}UE/EMM/ServiceRequestHdl.c
-    ${NAS_SRC}UE/EMM/TrackingAreaUpdate.c
-  )
-  set(libnas_ue_emm_sap_OBJS
-    ${NAS_SRC}UE/EMM/SAP/emm_as.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredAttachNeeded.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregistered.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredInitiated.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredLimitedService.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNoImsi.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNormalService.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredPlmnSearch.c
-    ${NAS_SRC}UE/EMM/SAP/emm_esm.c
-    ${NAS_SRC}UE/EMM/SAP/emm_fsm.c
-    ${NAS_SRC}UE/EMM/SAP/EmmNull.c
-    ${NAS_SRC}UE/EMM/SAP/emm_recv.c
-    ${NAS_SRC}UE/EMM/SAP/emm_reg.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegistered.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredInitiated.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredLimitedService.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredNoCellAvailable.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredNormalService.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredPlmnSearch.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredUpdateNeeded.c
-    ${NAS_SRC}UE/EMM/SAP/emm_sap.c
-    ${NAS_SRC}UE/EMM/SAP/emm_send.c
-    ${NAS_SRC}UE/EMM/SAP/EmmServiceRequestInitiated.c
-    ${NAS_SRC}UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c
-  )
-  set (libnas_ue_esm_OBJS
-    ${NAS_SRC}UE/ESM/DedicatedEpsBearerContextActivation.c
-    ${NAS_SRC}UE/ESM/DefaultEpsBearerContextActivation.c
-    ${NAS_SRC}UE/ESM/EpsBearerContextDeactivation.c
-    ${NAS_SRC}UE/ESM/esm_ebr.c
-    ${NAS_SRC}UE/ESM/esm_ebr_context.c
-    ${NAS_SRC}UE/ESM/esm_ip.c
-    ${NAS_SRC}UE/ESM/esm_main.c
-    ${NAS_SRC}UE/ESM/esm_pt.c
-    ${NAS_SRC}UE/ESM/EsmStatusHdl.c
-    ${NAS_SRC}UE/ESM/PdnConnectivity.c
-    ${NAS_SRC}UE/ESM/PdnDisconnect.c
-  )
-  set(libnas_ue_esm_sap_OBJS
-    ${NAS_SRC}UE/ESM/SAP/esm_recv.c
-    ${NAS_SRC}UE/ESM/SAP/esm_send.c
-    ${NAS_SRC}UE/ESM/SAP/esm_sap.c
-  )
-
-  set(libnrnas_emm_msg_OBJS
-    ${NAS_SRC}COMMON/EMM/MSG/RegistrationRequest.c
-    ${NAS_SRC}COMMON/EMM/MSG/RegistrationAccept.c
-    ${NAS_SRC}COMMON/EMM/MSG/FGSIdentityResponse.c
-    ${NAS_SRC}COMMON/EMM/MSG/FGSAuthenticationResponse.c
-    ${NAS_SRC}COMMON/EMM/MSG/FGSNASSecurityModeComplete.c
-    ${NAS_SRC}COMMON/EMM/MSG/RegistrationComplete.c
-    ${NAS_SRC}COMMON/EMM/MSG/FGSUplinkNasTransport.c
-    ${NAS_SRC}COMMON/ESM/MSG/PduSessionEstablishRequest.c
-  )
-
-  set(libnrnas_ies_OBJS
-    ${NAS_SRC}COMMON/IES/ExtendedProtocolDiscriminator.c
-    ${NAS_SRC}COMMON/IES/FGSMobileIdentity.c
-    ${NAS_SRC}COMMON/IES/FGSRegistrationType.c
-    ${NAS_SRC}COMMON/IES/SpareHalfOctet.c
-    ${NAS_SRC}COMMON/IES/FGSRegistrationResult.c
-    ${NAS_SRC}COMMON/IES/FGMMCapability.c
-    ${NAS_SRC}COMMON/IES/NrUESecurityCapability.c
-    ${NAS_SRC}COMMON/IES/FGCNasMessageContainer.c
-    ${NAS_SRC}COMMON/IES/SORTransparentContainer.c
-  )
-
-  add_library(LIB_NAS_SIMUE
-    ${NAS_SRC}UE/nas_itti_messaging.c
-    ${NAS_SRC}UE/nas_network.c
-    ${NAS_SRC}UE/nas_parser.c
-    ${NAS_SRC}UE/nas_proc.c
-    ${NAS_SRC}UE/nas_user.c
-    ${NAS_SRC}NR_UE/nr_nas_msg_sim.c
-    ${libnas_api_OBJS}
-    ${libnas_ue_api_OBJS}
-    ${libnas_emm_msg_OBJS}
-    ${libnas_esm_msg_OBJS}
-    ${libnas_ies_OBJS}
-    ${libnas_utils_OBJS}
-    ${libnas_ue_emm_OBJS}
-    ${libnas_ue_emm_sap_OBJS}
-    ${libnas_ue_esm_OBJS}
-    ${libnas_ue_esm_sap_OBJS}
-    ${libnrnas_emm_msg_OBJS}
-    ${libnrnas_ies_OBJS}
-  )
-  add_dependencies(LIB_NAS_SIMUE rrc_flag)
-  set(NAS_SIM_LIB LIB_NAS_SIMUE)
-
-  include_directories(${NAS_SRC}NR_UE)
-  include_directories(${NAS_SRC}UE)
-  include_directories(${NAS_SRC}UE/API/USER)
-  include_directories(${NAS_SRC}UE/API/USIM)
-  include_directories(${NAS_SRC}UE/EMM)
-  include_directories(${NAS_SRC}UE/EMM/SAP)
-  include_directories(${NAS_SRC}UE/ESM)
-  include_directories(${NAS_SRC}UE/ESM/SAP)
-endif()
+set(libnas_ue_api_OBJS
+  ${NAS_SRC}UE/API/USER/at_command.c
+  ${NAS_SRC}UE/API/USER/at_error.c
+  ${NAS_SRC}UE/API/USER/at_response.c
+  ${NAS_SRC}UE/API/USER/user_api.c
+  ${NAS_SRC}UE/API/USER/user_indication.c
+  ${NAS_SRC}UE/API/USIM/aka_functions.c
+  ${NAS_SRC}UE/API/USIM/usim_api.c
+  )
+set(libnas_ue_emm_OBJS
+  ${NAS_SRC}UE/EMM/Attach.c
+  ${NAS_SRC}UE/EMM/Authentication.c
+  ${NAS_SRC}UE/EMM/Detach.c
+  ${NAS_SRC}UE/EMM/emm_main.c
+  ${NAS_SRC}UE/EMM/EmmStatusHdl.c
+  ${NAS_SRC}UE/EMM/Identification.c
+  ${NAS_SRC}UE/EMM/IdleMode.c
+  ${NAS_SRC}UE/EMM/LowerLayer.c
+  ${NAS_SRC}UE/EMM/SecurityModeControl.c
+  ${NAS_SRC}UE/EMM/ServiceRequestHdl.c
+  ${NAS_SRC}UE/EMM/TrackingAreaUpdate.c
+  )
+set(libnas_ue_emm_sap_OBJS
+  ${NAS_SRC}UE/EMM/SAP/emm_as.c
+  ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredAttachNeeded.c
+  ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c
+  ${NAS_SRC}UE/EMM/SAP/EmmDeregistered.c
+  ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredInitiated.c
+  ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredLimitedService.c
+  ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c
+  ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNoImsi.c
+  ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNormalService.c
+  ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredPlmnSearch.c
+  ${NAS_SRC}UE/EMM/SAP/emm_esm.c
+  ${NAS_SRC}UE/EMM/SAP/emm_fsm.c
+  ${NAS_SRC}UE/EMM/SAP/EmmNull.c
+  ${NAS_SRC}UE/EMM/SAP/emm_recv.c
+  ${NAS_SRC}UE/EMM/SAP/emm_reg.c
+  ${NAS_SRC}UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c
+  ${NAS_SRC}UE/EMM/SAP/EmmRegistered.c
+  ${NAS_SRC}UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c
+  ${NAS_SRC}UE/EMM/SAP/EmmRegisteredInitiated.c
+  ${NAS_SRC}UE/EMM/SAP/EmmRegisteredLimitedService.c
+  ${NAS_SRC}UE/EMM/SAP/EmmRegisteredNoCellAvailable.c
+  ${NAS_SRC}UE/EMM/SAP/EmmRegisteredNormalService.c
+  ${NAS_SRC}UE/EMM/SAP/EmmRegisteredPlmnSearch.c
+  ${NAS_SRC}UE/EMM/SAP/EmmRegisteredUpdateNeeded.c
+  ${NAS_SRC}UE/EMM/SAP/emm_sap.c
+  ${NAS_SRC}UE/EMM/SAP/emm_send.c
+  ${NAS_SRC}UE/EMM/SAP/EmmServiceRequestInitiated.c
+  ${NAS_SRC}UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c
+  )
+set (libnas_ue_esm_OBJS
+  ${NAS_SRC}UE/ESM/DedicatedEpsBearerContextActivation.c
+  ${NAS_SRC}UE/ESM/DefaultEpsBearerContextActivation.c
+  ${NAS_SRC}UE/ESM/EpsBearerContextDeactivation.c
+  ${NAS_SRC}UE/ESM/esm_ebr.c
+  ${NAS_SRC}UE/ESM/esm_ebr_context.c
+  ${NAS_SRC}UE/ESM/esm_ip.c
+  ${NAS_SRC}UE/ESM/esm_main.c
+  ${NAS_SRC}UE/ESM/esm_pt.c
+  ${NAS_SRC}UE/ESM/EsmStatusHdl.c
+  ${NAS_SRC}UE/ESM/PdnConnectivity.c
+  ${NAS_SRC}UE/ESM/PdnDisconnect.c
+  )
+set(libnas_ue_esm_sap_OBJS
+  ${NAS_SRC}UE/ESM/SAP/esm_recv.c
+  ${NAS_SRC}UE/ESM/SAP/esm_send.c
+  ${NAS_SRC}UE/ESM/SAP/esm_sap.c
+  )
+
+set(libnrnas_emm_msg_OBJS
+  ${NAS_SRC}COMMON/EMM/MSG/RegistrationRequest.c
+  ${NAS_SRC}COMMON/EMM/MSG/RegistrationAccept.c
+  ${NAS_SRC}COMMON/EMM/MSG/FGSIdentityResponse.c
+  ${NAS_SRC}COMMON/EMM/MSG/FGSAuthenticationResponse.c
+  ${NAS_SRC}COMMON/EMM/MSG/FGSNASSecurityModeComplete.c
+  ${NAS_SRC}COMMON/EMM/MSG/RegistrationComplete.c
+  ${NAS_SRC}COMMON/EMM/MSG/FGSUplinkNasTransport.c
+  ${NAS_SRC}COMMON/ESM/MSG/PduSessionEstablishRequest.c
+  )
+
+set(libnrnas_ies_OBJS
+  ${NAS_SRC}COMMON/IES/ExtendedProtocolDiscriminator.c
+  ${NAS_SRC}COMMON/IES/FGSMobileIdentity.c
+  ${NAS_SRC}COMMON/IES/FGSRegistrationType.c
+  ${NAS_SRC}COMMON/IES/SpareHalfOctet.c
+  ${NAS_SRC}COMMON/IES/FGSRegistrationResult.c
+  ${NAS_SRC}COMMON/IES/FGMMCapability.c
+  ${NAS_SRC}COMMON/IES/NrUESecurityCapability.c
+  ${NAS_SRC}COMMON/IES/FGCNasMessageContainer.c
+  ${NAS_SRC}COMMON/IES/SORTransparentContainer.c
+  )
+
+add_library(LIB_NAS_SIMUE
+  ${NAS_SRC}UE/nas_itti_messaging.c
+  ${NAS_SRC}UE/nas_network.c
+  ${NAS_SRC}UE/nas_parser.c
+  ${NAS_SRC}UE/nas_proc.c
+  ${NAS_SRC}UE/nas_user.c
+  ${NAS_SRC}NR_UE/nr_nas_msg_sim.c
+  ${libnas_api_OBJS}
+  ${libnas_ue_api_OBJS}
+  ${libnas_emm_msg_OBJS}
+  ${libnas_esm_msg_OBJS}
+  ${libnas_ies_OBJS}
+  ${libnas_utils_OBJS}
+  ${libnas_ue_emm_OBJS}
+  ${libnas_ue_emm_sap_OBJS}
+  ${libnas_ue_esm_OBJS}
+  ${libnas_ue_esm_sap_OBJS}
+  ${libnrnas_emm_msg_OBJS}
+  ${libnrnas_ies_OBJS}
+  )
+add_dependencies(LIB_NAS_SIMUE rrc_flag)
+set(NAS_SIM_LIB LIB_NAS_SIMUE)
+
+add_library(LIB_NAS_UE
+  ${NAS_SRC}UE/nas_itti_messaging.c
+  ${NAS_SRC}UE/nas_network.c
+  ${NAS_SRC}UE/nas_parser.c
+  ${NAS_SRC}UE/nas_proc.c
+  ${NAS_SRC}UE/nas_user.c
+  ${libnas_api_OBJS}
+  ${libnas_ue_api_OBJS}
+  ${libnas_emm_msg_OBJS}
+  ${libnas_esm_msg_OBJS}
+  ${libnas_ies_OBJS}
+  ${libnas_utils_OBJS}
+  ${libnas_ue_emm_OBJS}
+  ${libnas_ue_emm_sap_OBJS}
+  ${libnas_ue_esm_OBJS}
+  ${libnas_ue_esm_sap_OBJS}
+  )
+add_dependencies(LIB_NAS_UE rrc_flag)
+set(NAS_UE_LIB LIB_NAS_UE)
+
+
+include_directories(${NAS_SRC}NR_UE)
+include_directories(${NAS_SRC}UE)
+include_directories(${NAS_SRC}UE/API/USER)
+include_directories(${NAS_SRC}UE/API/USIM)
+include_directories(${NAS_SRC}UE/EMM)
+include_directories(${NAS_SRC}UE/EMM/SAP)
+include_directories(${NAS_SRC}UE/ESM)
+include_directories(${NAS_SRC}UE/ESM/SAP)
 
 # nbiot
 add_definitions("-DNUMBER_OF_UE_MAX_NB_IoT=16")
 set (NBIOT_SOURCES
-    ${OPENAIR2_DIR}/ENB_APP/NB_IoT_config.c
-)
+  ${OPENAIR2_DIR}/ENB_APP/NB_IoT_config.c
+  )
 add_library(NB_IoT MODULE ${NBIOT_SOURCES} )
 
 # shared library loader
 set (SHLIB_LOADER_SOURCES
-    ${OPENAIR_DIR}/common/utils/load_module_shlib.c
-)
+  ${OPENAIR_DIR}/common/utils/load_module_shlib.c
+  )
 
 add_library(LIB_5GNAS_GNB
-	${NAS_SRC}/COMMON/nr_common.c
-	${NAS_SRC}/gNB/network_process_nas.c
-	${NAS_SRC}/NR_UE/ue_process_nas.c
-	${OPENAIR3_DIR}//UICC/usim_interface.c
-	)
+  ${NAS_SRC}/COMMON/nr_common.c
+  ${NAS_SRC}/gNB/network_process_nas.c
+  ${NAS_SRC}/NR_UE/ue_process_nas.c
+  ${OPENAIR3_DIR}//UICC/usim_interface.c
+  )
 target_link_libraries(LIB_5GNAS_GNB SECU_CN ${CRYPTO_LIBRARIES})
 
 # Make lfds as a own source code (even if it is a outside library)
@@ -2723,7 +2648,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
@@ -2786,14 +2711,15 @@ 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
+  ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
 	)
 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}")
@@ -2804,6 +2730,7 @@ include_directories("${OPENAIR_DIR}/common/utils/T")
 
 if (${T_TRACER})
   set(T_SOURCE
+      ${OPENAIR_DIR}/common/utils/T/T_IDs.h
       ${OPENAIR_DIR}/common/utils/T/T.c
       ${OPENAIR_DIR}/common/utils/T/local_tracer.c)
   set(T_LIB "rt")
@@ -2813,8 +2740,6 @@ endif (${T_TRACER})
 #This rule and the following deal with it.
 add_custom_command (
   OUTPUT ${OPENAIR_DIR}/common/utils/T/T_IDs.h
-  COMMAND make clean
-  COMMAND make -j2
   COMMAND make check_vcd
   WORKING_DIRECTORY ${OPENAIR_DIR}/common/utils/T
   DEPENDS ${OPENAIR_DIR}/common/utils/T/T_messages.txt
@@ -2822,6 +2747,10 @@ add_custom_command (
           ${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.h
   )
 
+execute_process (
+  COMMAND make check_vcd
+  WORKING_DIRECTORY ${OPENAIR_DIR}/common/utils/T
+)
 #This rule is specifically needed to generate T files
 #before anything else in a project that uses the T.
 #See below, there are some 'add_dependencies' showing that.
@@ -2860,7 +2789,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 )
@@ -2885,13 +2814,15 @@ 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
   ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
   ${OPENAIR_DIR}/common/utils/utils.c
   ${OPENAIR_DIR}/common/utils/system.c
-  ${GTPU_need_ITTI}
+  ${OPENAIR_DIR}/common/utils/lte/ue_power.c
+  ${OPENAIR_DIR}/common/utils/lte/prach_utils.c
   ${XFORMSINTERFACE_SOURCE}
   ${T_SOURCE}
   ${CONFIG_SOURCES}
@@ -2901,11 +2832,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}
+  ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ITTI ${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})
@@ -2932,7 +2863,8 @@ add_executable(ocp-enb
   ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
   ${OPENAIR_DIR}/common/utils/utils.c
   ${OPENAIR_DIR}/common/utils/system.c
-  ${GTPU_need_ITTI}
+  ${OPENAIR_DIR}/common/utils/lte/ue_power.c
+  ${OPENAIR_DIR}/common/utils/lte/prach_utils.c
   ${XFORMSINTERFACE_SOURCE}
   ${T_SOURCE}
   ${CONFIG_SOURCES}
@@ -2942,9 +2874,10 @@ 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}
+  ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ITTI ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
   -Wl,--end-group z dl)
 target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB}  ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB})
 
@@ -2959,7 +2892,7 @@ add_executable(cu_test
 )
 target_link_libraries(cu_test
   ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FSPT_MSG_LIB} ${PROTOBUF_LIB}
-  ${PROTO_AGENT_LIB} pthread UTIL ${T_LIB} dl ${ITTI_LIB}
+  ${PROTO_AGENT_LIB} pthread UTIL ${T_LIB} dl ITTI
 )
 
 add_executable(du_test
@@ -2973,8 +2906,35 @@ add_executable(du_test
 )
 target_link_libraries(du_test
   ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FSPT_MSG_LIB} ${PROTOBUF_LIB}
-  ${PROTO_AGENT_LIB} pthread UTIL ${T_LIB} dl ${ITTI_LIB}
+  ${PROTO_AGENT_LIB} pthread UTIL ${T_LIB} dl ITTI
+)
+
+add_executable(oairu
+  ${OPENAIR_TARGETS}/RT/USER/lte-ru.c
+  ${OPENAIR_TARGETS}/RT/USER/ru_control.c
+  ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
+  ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
+  ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
+  ${OPENAIR_DIR}/executables/softmodem-common.c
+  ${OPENAIR_DIR}/openair1/SCHED/phy_procedures_lte_common.c
+  ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
+  ${OPENAIR_DIR}/executables/main_ru.c
+  ${T_SOURCE}
+  ${OPENAIR_DIR}/common/utils/LOG/log.c
+  ${CONFIG_SOURCES}
+  ${OPENAIR_DIR}/common/utils/utils.c
+  ${OPENAIR_DIR}/common/utils/system.c
+  ${OPENAIR_DIR}/common/utils/lte/prach_utils.c
+  ${SHLIB_LOADER_SOURCES}
 )
+target_link_libraries (oairu
+  -Wl,--start-group
+  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})
+
 
 # lte-uesoftmodem is  UE implementation
 #######################################
@@ -2984,9 +2944,6 @@ add_executable(lte-uesoftmodem
   ${OPENAIR_TARGETS}/RT/USER/lte-ue.c
   ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c
   ${OPENAIR_DIR}/executables/softmodem-common.c
-  ${OPENAIR_TARGETS}/RT/USER/lte-ru.c
-  ${OPENAIR_TARGETS}/RT/USER/ru_control.c
-  ${OPENAIR_TARGETS}/RT/USER/rfsim.c
   ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
   ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
   ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
@@ -2998,6 +2955,8 @@ add_executable(lte-uesoftmodem
   ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
   ${OPENAIR_DIR}/common/utils/utils.c
   ${OPENAIR_DIR}/common/utils/system.c
+  ${OPENAIR_DIR}/common/utils/lte/ue_power.c
+  ${OPENAIR_DIR}/common/utils/lte/prach_utils.c
   ${XFORMSINTERFACE_SOURCE}
   ${T_SOURCE}
   ${CONFIG_SOURCES}
@@ -3012,9 +2971,10 @@ endif()
 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}
+  ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ITTI ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${ATLAS_LIBRARIES}
   -Wl,--end-group z dl)
 
 target_link_libraries (lte-uesoftmodem ${LIBXML2_LIBRARIES})
@@ -3040,22 +3000,24 @@ add_executable(nr-softmodem
   ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
   ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
   ${OPENAIR2_DIR}/RRC/NAS/rb_config.c
-  ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_gNB.c
   ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
   ${OPENAIR_DIR}/common/utils/utils.c
   ${OPENAIR_DIR}/common/utils/system.c
+  ${OPENAIR_DIR}/common/utils/lte/ue_power.c
+  ${OPENAIR_DIR}/common/utils/lte/prach_utils.c
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
-  ${GTPU_need_ITTI}
   ${XFORMSINTERFACE_SOURCE}
   ${T_SOURCE}
   ${CONFIG_SOURCES}
   ${SHLIB_LOADER_SOURCES}
+  ${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 NR_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 ${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)
@@ -3084,7 +3046,6 @@ add_executable(ocp-gnb
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
   ${OPENAIR_DIR}/common/utils/utils.c
   ${OPENAIR_DIR}/common/utils/system.c
-  ${GTPU_need_ITTI}
   ${XFORMS_SOURCE_NR}
   ${T_SOURCE}
   ${CONFIG_SOURCES}
@@ -3094,8 +3055,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 NR_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 ${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)
@@ -3141,9 +3102,9 @@ target_link_libraries (nr-uesoftmodem
   RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
   PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
   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} 
+  ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ITTI ${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
+  ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ITTI ${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})
@@ -3169,11 +3130,22 @@ add_executable(dlsim_tm4
   ${T_SOURCE}
   )
 target_link_libraries (dlsim_tm4
-  -Wl,--start-group SIMU_COMMON SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY LFDS ${ITTI_LIB} -Wl,--end-group
+  -Wl,--start-group SIMU_COMMON SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY LFDS ITTI -Wl,--end-group
   pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${T_LIB}
   )
 
-add_executable(polartest 
+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
+  ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
+  ${OPENAIR_DIR}/executables/softmodem-common.c
+  ${CONFIG_SOURCES}
+  ${SHLIB_LOADER_SOURCES}
+)
+target_link_libraries(rftest minimal_lib PHY_NR_COMMON pthread dl m forms ${T_LIB} )
+
+add_executable(polartest
   ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c
   ${OPENAIR_DIR}/common/utils/backtrace.c
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
@@ -3186,7 +3158,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
@@ -3201,20 +3173,12 @@ target_link_libraries(smallblocktest
   m pthread ${ATLAS_LIBRARIES} dl
   )
 
-
-# temp_C_flag = CMAKE_C_FLAGS
-#set(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 (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)
@@ -3224,14 +3188,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}
@@ -3239,25 +3203,23 @@ else (CUDA_FOUND)
        )
 
 endif ()
-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
@@ -3266,13 +3228,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
+  m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI 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
@@ -3283,12 +3245,12 @@ add_executable(nr_pbchsim
   )
 target_link_libraries(nr_pbchsim
   -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
+  m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI dl
   )
 
 #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
@@ -3300,7 +3262,7 @@ add_executable(nr_pucchsim
   )
 target_link_libraries(nr_pucchsim
   -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
+  m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI dl
   )
 
 add_executable(nr_dlsim
@@ -3316,15 +3278,15 @@ 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} dl
+  m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl
   )
 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
@@ -3336,9 +3298,9 @@ 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} dl)
+  m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl)
 
 add_executable(nr_ulschsim
   ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
@@ -3352,7 +3314,7 @@ add_executable(nr_ulschsim
   )
 target_link_libraries(nr_ulschsim
   -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
+  m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI dl
   )
 
 add_executable(nr_ulsim
@@ -3371,18 +3333,21 @@ add_executable(nr_ulsim
   )
 target_link_libraries(nr_ulsim
   -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} dl
+  m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl
   )
 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
     ${OPENAIR_DIR}/common/utils/backtrace.c
     ${OPENAIR_DIR}/common/utils/system.c
     ${OPENAIR_DIR}/common/utils/utils.c
+    ${OPENAIR_DIR}/common/utils/lte/ue_power.c
+    ${OPENAIR_DIR}/common/utils/lte/prach_utils.c
+    ${OPENAIR1_DIR}/PHY/INIT/lte_param_init.c
     ${XFORMS_SOURCE}
     ${T_SOURCE}
     ${CONFIG_SOURCES}
@@ -3390,10 +3355,10 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
     ${NFAPI_USER_DIR}/nfapi.c
     )
   target_link_libraries (${myExe}
-    -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
+    -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 LFDS7 -Wl,--end-group
     pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES}  ${XFORMS_LIBRARIES} ${T_LIB} dl
     )
-   
+
 endforeach(myExe)
 
 add_executable(test_epc_generate_scenario
@@ -3405,7 +3370,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 ${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
@@ -3424,7 +3389,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 ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB}
   )
 
 
@@ -3456,13 +3421,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
@@ -3470,7 +3435,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 NR_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)
@@ -3526,7 +3491,7 @@ endfunction(make_driver name dir src)
 # nashmesh module
 ################
 list(APPEND nasmesh_src device.c common.c ioctl.c classifier.c tool.c mesh.c)
-set(module_cc_opt "${module_cc_opt} -DNAS_NETLINK -DPDCP_USE_NETLINK -D${MKVER}")
+set(module_cc_opt "${module_cc_opt} -DNAS_NETLINK -DPDCP_USE_NETLINK")
 # legacy Makefile was using NAS_NETLINK flag, but other drivers the hereafter flag
 # so, this cmake use OAI_NW_DRIVER_USE_NETLINK everywhere
 if (OAI_NW_DRIVER_USE_NETLINK)
@@ -3561,24 +3526,26 @@ add_executable(nr-ittisim
   ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
   ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
   ${OPENAIR2_DIR}/RRC/NAS/rb_config.c
-  ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_gNB.c
   ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
   ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
   ${OPENAIR_DIR}/common/utils/utils.c
   ${OPENAIR_DIR}/common/utils/system.c
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
   ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
-  ${GTPU_need_ITTI}
+  ${OPENAIR_DIR}/common/utils/lte/ue_power.c
+  ${OPENAIR_DIR}/common/utils/lte/prach_utils.c
+  ${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api_to_fix.c
   ${XFORMSINTERFACE_SOURCE}
   ${T_SOURCE}
   ${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 NR_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 ${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
diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/core.py b/cmake_targets/autotests/core.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/log.py b/cmake_targets/autotests/log.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/openair.py b/cmake_targets/autotests/openair.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/templates/index.html b/cmake_targets/autotests/templates/index.html
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/templates/testcase_report.html b/cmake_targets/autotests/templates/testcase_report.html
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
old mode 100644
new mode 100755
index 089d0503fdf02a7b0726223adec38c78e343a7c5..3472b14efcf09695f156d57ee6cbd69cc89ff1b3
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1099,8 +1099,11 @@
                                  (Test14: 3 PTRS, 8 Interpolated Symbols),
                                  (Test15: 6 PTRS, 5 Interpolated Symbols),
                                  (Test16: 11 PTRS, 0 Interpolated Symbols),
-                                 (Test17: 2 DMRS Symbols),
-                                 (Test18: 3 DMRS Symbols)</desc>
+                                 (Test17: Mapping type A, 2 DMRS Symbols),
+                                 (Test18: Mapping type A, 3 DMRS Symbols),
+                                 (Test19: Mapping type B, 4 DMRS Symbols),
+                                 (Test20: 4x4 MIMO, 1 Layer),
+                                 (Test21: 4x4 MIMO, 2 Layers)</desc>
       <pre_compile_prog></pre_compile_prog>
       <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
       <compile_prog_args> --phy_simulators  -c </compile_prog_args>
@@ -1124,8 +1127,11 @@
                   -n100 -s5 -T 2 1 2
                   -n100 -s5 -T 2 0 4
                   -n100 -s2 -U 2 0 1
-                  -n100 -s2 -U 2 0 2</main_exec_args>
-      <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18</tags>
+                  -n100 -s2 -U 2 0 2
+                  -n100 -s2 -U 2 1 3
+                  -n10 -s20 -U 3 0 0 2 -gR -x1 -y4 -z4
+                  -n10 -s20 -U 3 0 0 2 -gR -x2 -y4 -z4</main_exec_args>
+      <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21</tags>
       <search_expr_true>PDSCH test OK</search_expr_true>
       <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
       <nruns>3</nruns>
@@ -1287,14 +1293,16 @@
                                  (Test3: MCS 28 50 PRBs),
                                  (Test4: MCS 9 217 PRBs),
                                  (Test5: MCS 9 273 PRBs),
-                                 (Test6: DMRS Type A, 3 DMRS, 4 PTRS, 5 Interpolated Symbols),
-                                 (Test7: DMRS Type B, 3 DMRS, 2 PTRS, 7 Interpolated Symbols),
-                                 (Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols),
-                                 (Test9: SC-FDMA, 50 PRBs),
-                                 (Test10: SC-FDMA, 75 PRBs),
-                                 (Test11: SC-FDMA, 216 PRBs),
-                                 (Test12: SC-FDMA, 273 PRBs),
-                                 (Test13: SC-FDMA, 3 DMRS)</desc>
+                                 (Test6: DMRS Type A, 2 DMRS Symbols),
+                                 (Test7: DMRS Type A, 3 DMRS, 4 PTRS, 5 Interpolated Symbols),
+                                 (Test8: DMRS Type B, 3 DMRS, 2 PTRS, 7 Interpolated Symbols),
+                                 (Test9: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols),
+                                 (Test10: SC-FDMA, 50 PRBs),
+                                 (Test11: SC-FDMA, 75 PRBs),
+                                 (Test12: SC-FDMA, 216 PRBs),
+                                 (Test13: SC-FDMA, 273 PRBs),
+                                 (Test14: SC-FDMA, 3 DMRS),
+                                 (Test15: MCS 16 50 PRBs 2 RX_Antenna)</desc>
       <pre_compile_prog></pre_compile_prog>
       <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
       <compile_prog_args> --phy_simulators  -c </compile_prog_args>
@@ -1306,16 +1314,18 @@
                       -n100 -m28 -s20
                       -n100 -m9 -R217 -r217 -s5
                       -n100 -m9 -R273 -r273 -s5
+                      -n100 -s5 -U 2 0 1
                       -n100 -s5 -T 2 1 2 -U 2 0 2
                       -n100 -s5 -T 2 2 2 -U 2 1 2
                       -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3
-                      -n100 -s2 -Z
-                      -n100 -s2 -Z -r75
-                      -n100 -s2 -Z -r216 -R217
-                      -n100 -s2 -Z -r270 -R273
-                      -n100 -s2 -Z -U 2 0 2</main_exec_args>
-
-      <tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13</tags>
+                      -n100 -s5 -Z
+                      -n100 -s5 -Z -r75
+                      -n50 -s5 -Z -r216 -R217
+                      -n50 -s5 -Z -r270 -R273
+                      -n100 -s5 -Z -U 2 0 2
+                      -n100 -m16 -s10 -z2</main_exec_args>
+
+      <tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15</tags>
       <search_expr_true>PUSCH test OK</search_expr_true>
       <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
       <nruns>3</nruns>
@@ -1328,7 +1338,8 @@
                                     (Test3: 30kHz SCS, 273 PRBs, Prach format A2),
 				    (Test4: 30kHz SCS, 106 PRBs, Prach format 0),
                                     (Test5: 120kHz SCS, 32 PRBs, Prach format A2),
-                                    (Test6: 120kHz SCS, 66 PRBs, Prach format A2)</desc>
+                                    (Test6: 120kHz SCS, 66 PRBs, Prach format A2),
+                                    (Test7: 120kHz SCS, 66 PRBs, High Speed Enabled)</desc>
       <pre_compile_prog></pre_compile_prog>
       <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
       <compile_prog_args> --phy_simulators -c </compile_prog_args>
@@ -1340,8 +1351,9 @@
                       -a -s -30 -n 100 -p 63 -R 273
 		      -a -s -30 -n 100 -p 63 -R 106 -c 4
 		      -a -s -30 -n 100 -p 32 -R 32 -m 3 -c52 
-		      -a -s -30 -n 100 -p 32 -R 66 -m 3 -c52</main_exec_args>
-      <tags>nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6</tags>
+		      -a -s -30 -n 100 -p 32 -R 66 -m 3 -c52
+          -a -s -30 -n 100 -R 66 -m 3 -c52 -H</main_exec_args>
+      <tags>nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6 nr_prachsim.test7</tags>
       <search_expr_true>PRACH test OK</search_expr_true>
       <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
       <nruns>3</nruns>
diff --git a/cmake_targets/autotests/testsuite_ue_noS1.xml b/cmake_targets/autotests/testsuite_ue_noS1.xml
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/testsuite_ue_noS1_TCL.xml b/cmake_targets/autotests/testsuite_ue_noS1_TCL.xml
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/tools/lib_autotest.py b/cmake_targets/autotests/tools/lib_autotest.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/tools/lib_autotest_analyser.py b/cmake_targets/autotests/tools/lib_autotest_analyser.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/tools/wdial.bandrich.conf b/cmake_targets/autotests/tools/wdial.bandrich.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/3276.txt b/cmake_targets/autotests/v2/actions/3276.txt
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/alu_epc.bash b/cmake_targets/autotests/v2/actions/alu_epc.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/alu_epc_stop.bash b/cmake_targets/autotests/v2/actions/alu_epc_stop.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/alu_hss.bash b/cmake_targets/autotests/v2/actions/alu_hss.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/bandrich.txt b/cmake_targets/autotests/v2/actions/bandrich.txt
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/client_tcp.bash b/cmake_targets/autotests/v2/actions/client_tcp.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/client_udp.bash b/cmake_targets/autotests/v2/actions/client_udp.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/clone_repository.bash b/cmake_targets/autotests/v2/actions/clone_repository.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/compilation.bash b/cmake_targets/autotests/v2/actions/compilation.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/execution.bash b/cmake_targets/autotests/v2/actions/execution.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/execution_compile.bash b/cmake_targets/autotests/v2/actions/execution_compile.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/modem.py b/cmake_targets/autotests/v2/actions/modem.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/run_enb.bash b/cmake_targets/autotests/v2/actions/run_enb.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/server_tcp.bash b/cmake_targets/autotests/v2/actions/server_tcp.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/server_udp.bash b/cmake_targets/autotests/v2/actions/server_udp.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/start_3276.bash b/cmake_targets/autotests/v2/actions/start_3276.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/start_3276.py b/cmake_targets/autotests/v2/actions/start_3276.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/start_bandrich.bash b/cmake_targets/autotests/v2/actions/start_bandrich.bash
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/start_bandrich.py b/cmake_targets/autotests/v2/actions/start_bandrich.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/stop_3276.py b/cmake_targets/autotests/v2/actions/stop_3276.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/stop_bandrich.py b/cmake_targets/autotests/v2/actions/stop_bandrich.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/wvdial.3276.conf b/cmake_targets/autotests/v2/actions/wvdial.3276.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/actions/wvdial.bandrich.conf b/cmake_targets/autotests/v2/actions/wvdial.bandrich.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/alu_test.py b/cmake_targets/autotests/v2/alu_test.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/connection.py b/cmake_targets/autotests/v2/connection.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/machine_list.py b/cmake_targets/autotests/v2/machine_list.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/main.py b/cmake_targets/autotests/v2/main.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/task.py b/cmake_targets/autotests/v2/task.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/autotests/v2/utils.py b/cmake_targets/autotests/v2/utils.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 960b24104773b4ce6816c6c90920389eb4b98b5c..c9390d67ce5202478b4951746a58505aef22c5c8 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -48,8 +48,9 @@ DEADLINE_SCHEDULER_FLAG_USER=""
 CPU_AFFINITY_FLAG_USER="False" #Only valid when low-latency flag is set to False
 REL="Rel15"
 HW="None"
-TP="None"
+TP="Ethernet"
 EPC=0
+VERBOSE_CI=0
 VERBOSE_COMPILE=0
 CFLAGS_PROCESSOR_USER=""
 RUN_GROUP=0
@@ -67,7 +68,9 @@ USRP_REC_PLAY="False"
 BUILD_ECLIPSE=0
 NR="False"
 ITTI_SIM="False"
+SANITIZE_ADDRESS="False"
 OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc"
+RU=0
 trap handle_ctrl_c INT
 
 function print_help() {
@@ -102,6 +105,8 @@ Options
   Makes the NR softmodem
 --nrUE
   Makes the NR UE softmodem
+--RU
+  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]
@@ -239,26 +244,36 @@ function main() {
             shift;;
        --eNB)
             eNB=1
+            RU=0
             echo_info "Will compile eNB"
             shift;;
        --eNBocp)
             eNBocp=1
+            RU=0
             echo_info "Will compile OCP eNB"
             shift;;
       --gNB)
             gNB=1
+            RU=0
             NR="True"
             echo_info "Will compile gNB"
             shift;;
+       --RU)
+	          RU=1
+            echo_info "Will compile RRU"
+	    shift;;
        -a | --agent)
             echo_info "FlexRAN support is always compiled into the eNB"
             shift;;
        --UE)
+            RU=0
             UE=1
             echo_info "Will compile UE"
             shift;;
        --nrUE)
+            RU=0
             nrUE=1
+            rfsimNas=1
             NR="True"
             echo_info "Will compile NR UE"
             shift;;
@@ -289,8 +304,12 @@ function main() {
             esac
 			echo_info "Setting hardware to: $HW"
             shift 2;;
+       -t | --transport)
+	    TP=$2
+            shift 2;;
        -P | --phy_simulators)
             SIMUS_PHY=1
+	          RU=0
             echo_info "Will compile dlsim, ulsim, ..."
             shift;;
        -S | --core_simulators)
@@ -324,6 +343,10 @@ function main() {
             HWLAT_TEST=1
             echo_info "Will compile hw latency test program"
             shift;;
+       --verbose-ci)
+	        VERBOSE_CI=1
+            echo_info "Will compile with verbose instructions in CI Docker env"
+            shift;;
        --verbose-compile)
 	        VERBOSE_COMPILE=1
             echo_info "Will compile with verbose instructions"
@@ -416,6 +439,9 @@ function main() {
         CMAKE_CMD="$CMAKE_CMD -GNinja"
 	MAKE_CMD=ninja
 	shift;;
+    --sanitize-address | -fsanitize=address)
+        SANITIZE_ADDRESS=True
+        shift;;
       --ittiSIM)
             ittiSIM=1
             ITTI_SIM="True"
@@ -452,7 +478,7 @@ function main() {
   ########################################################
   # to be discussed
   
-  if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$gNB" = "1" ] ; then
+  if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$gNB" = "1" -o "$RU" = "1" ] ; then
       if [ "$HW" = "None" -a  "$TP" = "None" ] ; then
 	      echo_info "No local radio head and no transport protocol selected"
       fi
@@ -579,7 +605,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 "$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
 
@@ -603,7 +629,9 @@ function main() {
     echo "set ( UE_TIMING_TRACE $UE_TIMING_TRACE )"                       >> $cmake_file
     echo "set ( USRP_REC_PLAY $USRP_REC_PLAY )"                           >> $cmake_file
     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 ( SANITIZE_ADDRESS $SANITIZE_ADDRESS )"                     >> $cmake_file
     echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)'         >> $cmake_file
     cd  $DIR/$build_dir/build
     eval $CMAKE_CMD
@@ -618,6 +646,9 @@ function main() {
     if [ "$gNB" = "1" ] ; then
       execlist="$execlist nr-softmodem"
     fi
+    if [ "$RU" = "1" ] ; then
+      execlist="$execlist oairu"
+    fi
     if [ "$UE" = 1 ] ; then
       execlist="$execlist lte-uesoftmodem"
     fi
@@ -646,28 +677,15 @@ function main() {
         $build_dir $config_libconfig_shlib \
         lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so
 
-      compilations \
-        $build_dir coding \
-        libcoding.so $dbin/libcoding.so
-
+      if [ "$RU" = "0" ] ; then
 
-      #check if we run inside a container or not
-      #IS_CONTAINER variable is defined in build_helper file
-      #compile  nasmesh and rb_tool only if NOT running in a container
-      if [ $IS_CONTAINER -eq 0 ]
-      then
         compilations \
-          $build_dir nasmesh \
-          CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
+          $build_dir coding \
+          libcoding.so $dbin/libcoding.so
 
-        compilations \
-          $build_dir rb_tool \
-          rb_tool $dbin/rb_tool
 
-        cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin
-      fi #IS_CONTAINER
+      fi
     fi
-
   fi
 
   if [ "$UE" = 1 ] ; then
@@ -849,7 +867,7 @@ function main() {
   ####################################################
   # Build RF device and transport protocol libraries #
   ####################################################
-  if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HWLAT" = "1" ] ; then
+  if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$RU" = "1"  -o "$nrUE" = "1" -o "$HWLAT" = "1" ] ; then
 
       # build RF device libraries
       if [ "$HW" != "None" ] ; then
@@ -936,12 +954,30 @@ function main() {
           echo_info "Building transport protocol libraries"
           rm -f liboai_transpro.so
           rm -f $dbin/liboai_transpro.so
-          compilations \
-              $build_dir oai_eth_transpro \
-              liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL
-          ln -sf liboai_eth_transpro.so liboai_transpro.so
-          ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
-          echo_info "liboai_transpro.so is linked to ETHERNET transport"
+	  if [ "$TP" == "Ethernet" ]; then
+              compilations \
+		  $build_dir oai_eth_transpro \
+		  liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL
+              ln -sf liboai_eth_transpro.so liboai_transpro.so
+              ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
+              echo_info "liboai_transpro.so is linked to ETHERNET transport"
+	  fi
+	  if [ "$TP" == "benetel4g" ]; then
+              compilations \
+		  $build_dir benetel_4g \
+		  libbenetel_4g.so $dbin/libbenetel_4g.$REL
+              ln -sf libbenetel_4g.so liboai_transpro.so
+              ln -sf $dbin/libbenetel_4g.so.$REL $dbin/liboai_transpro.so
+              echo_info "liboai_transpro.so is linked to BENETEL4G transport"
+	  fi
+	  if [ "$TP" == "benetel5g" ]; then
+              compilations \
+		  $build_dir benetel_5g \
+		  libbenetel_5g.so $dbin/libbenetel_5g.$REL
+              ln -sf libbenetel_5g.so liboai_transpro.so
+              ln -sf $dbin/libbenetel_5g.so.$REL $dbin/liboai_transpro.so
+              echo_info "liboai_transpro.so is linked to BENETEL4G transport"
+	  fi
       fi
   fi
 
diff --git a/cmake_targets/doxygen/CMakeLists.txt b/cmake_targets/doxygen/CMakeLists.txt
old mode 100644
new mode 100755
diff --git a/cmake_targets/epc_test/CMakeLists.template b/cmake_targets/epc_test/CMakeLists.template
old mode 100644
new mode 100755
diff --git a/cmake_targets/install_external_packages.ubuntu20 b/cmake_targets/install_external_packages.ubuntu20
index 9ef79be9c2d74cdb65c5e4dd115caeeab1925f8d..f0314ca575eb32faf6776aa3027b58b8f2f2e6fd 100755
--- a/cmake_targets/install_external_packages.ubuntu20
+++ b/cmake_targets/install_external_packages.ubuntu20
@@ -83,6 +83,8 @@ get_distribution_release() {
 check_supported_distribution() {
     case $(get_distribution_release) in
         "ubuntu20.04") return 0 ;;
+        "ubuntu20.10") return 0 ;;
+        "ubuntu21.04") return 0 ;;
     esac
     return 1
 }
@@ -152,11 +154,11 @@ install_protobuf_from_source(){
 	cd /tmp || exit
 	echo "Downloading protobuf"
 	#rm -rf /tmp/protobuf-2.6.1.tar.gz* /tmp/protobuf-2.6.1
-	#wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
+	#wget https://github.com/protocolbuffers/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
 	#tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner
 	#cd protobuf-2.6.1/
 	rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0
-	wget --tries=3 --retry-connrefused https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
+	wget --tries=3 --retry-connrefused https://github.com/protocolbuffers/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
 	tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner "$USER" --group "$(groups | cut -d" " -f1)" --no-same-owner
 	cd protobuf-3.3.0/ || exit
 	./configure
@@ -198,15 +200,15 @@ install_usrp_uhd_driver_from_source(){
 	rm -rf /tmp/uhd
 	git clone https://github.com/EttusResearch/uhd.git
 	cd uhd || exit
-	git checkout tags/v3.13.0.2
+	git checkout UHD-3.15.LTS
 	mkdir -p host/build
 	cd host/build || exit
-	$CMAKE ../
+	$CMAKE ../ -GNinja
 	echo "Compiling UHD"
-	make -j"$(nproc)"
-	make test
-	$SUDO make install
+	ninja
+	$SUDO ninja install
 	$SUDO ldconfig
+        $SUDO /usr/lib/uhd/utils/uhd_images_downloader.py
     ) >& "$uhd_install_log"
 }
 
@@ -333,6 +335,11 @@ check_install_ubuntu_packages() {
 		LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu"
 		LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so"
 		;;
+            "ubuntu21.04")
+		specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev"
+		LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu"
+		LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so"
+		;;
 	esac
 	$SUDO $INSTALLER install -y \
 	      $specific_packages \
@@ -345,7 +352,6 @@ check_install_ubuntu_packages() {
               openvpn \
               pkg-config \
               python3-dev  \
-              python-pexpect \
               sshfs \
               swig  \
               tshark \
@@ -358,7 +364,6 @@ check_install_ubuntu_packages() {
               iperf3 \
               android-tools-adb \
               wvdial \
-              python-numpy \
               sshpass \
               nscd \
               bc \
@@ -379,7 +384,6 @@ check_install_ubuntu_packages() {
 	      git \
 	      graphviz \
 	      gtkwave \
-	      guile-2.0-dev  \
 	      iperf \
 	      iptables \
 	      libxtables-dev \
@@ -419,7 +423,8 @@ check_install_ubuntu_packages() {
 	      libxpm-dev \
               libboost-all-dev \
 	      nettle-dev \
-	      nettle-bin
+	      nettle-bin \
+              libreadline-dev
     fi
     
     $SUDO update-alternatives --set "$LAPACK_LIBNAME" "$LAPACK_TARGET"
diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt
old mode 100644
new mode 100755
diff --git a/cmake_targets/phy_simulators/CMakeLists.txt b/cmake_targets/phy_simulators/CMakeLists.txt
old mode 100644
new mode 100755
index 447e90bcab1190b6aa03720898e8d8cf4175e1f2..f8c659959f36a6558a2cf76f3c8a6ac1676a9be0
--- a/cmake_targets/phy_simulators/CMakeLists.txt
+++ b/cmake_targets/phy_simulators/CMakeLists.txt
@@ -17,4 +17,5 @@ set ( UE_TIMING_TRACE False )
 set ( USRP_REC_PLAY False )
 set ( SKIP_SHARED_LIB_FLAG False )
 set ( PHYSIM True)
+set ( RU 0)
 include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)
diff --git a/cmake_targets/s1c_mme_test/CMakeLists.template b/cmake_targets/s1c_mme_test/CMakeLists.template
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/Kbuild.cmake b/cmake_targets/tools/Kbuild.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/CMakeParseArguments.cmake b/cmake_targets/tools/MODULES/CMakeParseArguments.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/CMakeUserFindMySQL.cmake b/cmake_targets/tools/MODULES/CMakeUserFindMySQL.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/CMakeUserUseBison.cmake b/cmake_targets/tools/MODULES/CMakeUserUseBison.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/CMakeUserUseFlex.cmake b/cmake_targets/tools/MODULES/CMakeUserUseFlex.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/FindFreeDiameter.cmake b/cmake_targets/tools/MODULES/FindFreeDiameter.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/FindGCCXML.cmake b/cmake_targets/tools/MODULES/FindGCCXML.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/FindGcrypt.cmake b/cmake_targets/tools/MODULES/FindGcrypt.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/FindGnuTLS.cmake b/cmake_targets/tools/MODULES/FindGnuTLS.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/FindKbuild.cmake b/cmake_targets/tools/MODULES/FindKbuild.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/FindLibXml2.cmake b/cmake_targets/tools/MODULES/FindLibXml2.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/FindMySQL.cmake b/cmake_targets/tools/MODULES/FindMySQL.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/FindNettle.cmake b/cmake_targets/tools/MODULES/FindNettle.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/FindPostgreSQL.cmake b/cmake_targets/tools/MODULES/FindPostgreSQL.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/FindSCTP.cmake b/cmake_targets/tools/MODULES/FindSCTP.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/Kbuild.cmake b/cmake_targets/tools/MODULES/Kbuild.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/cmake_useful.cmake b/cmake_targets/tools/MODULES/cmake_useful.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/kbuild_system.cmake b/cmake_targets/tools/MODULES/kbuild_system.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/kmodule.cmake b/cmake_targets/tools/MODULES/kmodule.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/MODULES/path_prefixes.cmake b/cmake_targets/tools/MODULES/path_prefixes.cmake
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/asn1tostruct.py b/cmake_targets/tools/asn1tostruct.py
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 674d4a0cacf5312336a5df55376ba7e2af3aec30..d3fcf615e220140d9c21e7b266a2248651a95e5b 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -41,7 +41,7 @@ KERNEL_VERSION=$(uname -r | cut -d '.' -f1)
 KERNEL_MAJOR=$(uname -r | cut -d '.' -f2)
 
 #check if we run inside a container
-IS_CONTAINER=`egrep -c "docker|podman|kubepods" /proc/self/cgroup || true`
+IS_CONTAINER=`egrep -c "docker|podman|kubepods|libpod|buildah" /proc/self/cgroup || true`
 #sudo is not needed when we are root
 if [ "$UID" = 0 ]
 then
@@ -113,6 +113,7 @@ check_supported_distribution() {
         "rhel7.6")     return 0 ;;
         "rhel7.7")     return 0 ;;
         "rhel7.8")     return 0 ;;
+        "rhel7.9")     return 0 ;;
         "rhel8.2")     return 0 ;;
         "rhel8.3")     return 0 ;;
         "rhel8.4")     return 0 ;;
@@ -221,6 +222,11 @@ compilations() {
     ret=$?
   } > $dlog/$2.$REL.txt 2>&1
   set -e
+  if [ "$VERBOSE_CI" == "1" ]; then
+     echo_info "====== Start of log for $2.$REL.txt ======"
+     cat $dlog/$2.$REL.txt
+     echo_info "====== End of log for $2.$REL.txt ======"
+  fi
   if [[ $ret -ne 0 ]]; then
      check_warnings "$dlog/$2.$REL.txt"
      check_errors "$dlog/$2.$REL.txt"
@@ -250,14 +256,14 @@ install_protobuf_from_source(){
     cd /tmp
     echo "Downloading protobuf"
     #rm -rf /tmp/protobuf-2.6.1.tar.gz* /tmp/protobuf-2.6.1
-    #wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
+    #wget https://github.com/protocolbuffers/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
     #tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner
     #cd protobuf-2.6.1/
 
     if [ $IS_CONTAINER -eq 0 ]
     then
       rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0
-      wget --tries=3 --retry-connrefused https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
+      wget --tries=3 --retry-connrefused https://github.com/protocolbuffers/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
       tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $(id -u) --group $(id -g) --no-same-owner
       cd protobuf-3.3.0/
     else
@@ -273,6 +279,10 @@ install_protobuf_from_source(){
     make -j`nproc`
     $SUDO make install
     $SUDO ldconfig
+    if [[ -v CI_ENV ]]; then
+        cd /tmp
+        $SUDO rm -rf protobuf*
+    fi
     ) >& $protobuf_install_log
 }
 
@@ -295,6 +305,10 @@ install_protobuf_c_from_source(){
     make -j`nproc`
     $SUDO make install
     $SUDO ldconfig
+    if [[ -v CI_ENV ]]; then
+        cd /tmp
+        $SUDO rm -rf protobuf*
+    fi
     ) >& $protobuf_c_install_log
 }
 
@@ -351,10 +365,10 @@ check_install_usrp_uhd_driver(){
     elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
         if [ $IS_CONTAINER -eq 0 ]
         then
-            $SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils cmake
+            $SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils $CMAKE
             $SUDO -H pip install requests
         else
-            $SUDO $INSTALLER -y install boost boost-devel cmake3
+            $SUDO $INSTALLER -y install boost boost-devel $CMAKE
             $SUDO pip3 install mako requests
         fi
         if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
@@ -480,7 +494,7 @@ install_soapy_from_source(){
     #git checkout tags/release_003_010_001_001
     mkdir -p build
     cd build
-    cmake ../
+    $CMAKE ../
     echo "Compiling SoapyRemote"
     make -j`nproc`
     $SUDO make install
@@ -499,7 +513,7 @@ install_soapy_iris_from_source(){
     cd sklk-soapyiris
     mkdir -p build
     cd build
-    cmake ../
+    $CMAKE ../
     echo "Compiling SoapyIris"
     make -j`nproc`
     $SUDO make install
@@ -676,7 +690,7 @@ check_install_oai_software() {
 	automake  \
 	bison  \
 	build-essential \
-	cmake \
+	$CMAKE \
 	cmake-curses-gui  \
         ninja-build \
 	doxygen \
@@ -831,6 +845,9 @@ install_asn1c_from_source(){
     $SUDO make install
     cd -
     $SUDO ldconfig
+    if [[ -v CI_ENV ]]; then
+        $SUDO rm -rf /tmp/asn1c
+    fi
     ) > $asn1_install_log 2>&1
 }
 
diff --git a/cmake_targets/tools/example_enb_exmimo_mme_hss.txt b/cmake_targets/tools/example_enb_exmimo_mme_hss.txt
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/example_oaisim_enb_ue_mme_virtual.txt b/cmake_targets/tools/example_oaisim_enb_ue_mme_virtual.txt
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/exmimo2_2arxg.lime b/cmake_targets/tools/exmimo2_2arxg.lime
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/exmimo2_2brxg.lime b/cmake_targets/tools/exmimo2_2brxg.lime
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/exmimo_stop_octave.m b/cmake_targets/tools/exmimo_stop_octave.m
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/fix_asn1.data/RRC.rel10/SystemInformation-r8-IEs.h.diff b/cmake_targets/tools/fix_asn1.data/RRC.rel10/SystemInformation-r8-IEs.h.diff
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff b/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff b/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/fix_asn1.data/X2AP.rel11.2/X2ap-CriticalityDiagnostics-IE-List.h.diff b/cmake_targets/tools/fix_asn1.data/X2AP.rel11.2/X2ap-CriticalityDiagnostics-IE-List.h.diff
old mode 100644
new mode 100755
diff --git a/cmake_targets/tools/make_asn1c_includes.sh b/cmake_targets/tools/make_asn1c_includes.sh
index 1598678a73521b9811939542fbd95ae8c1f2738a..00c88d64977390178c0e79a9af4d2313460476f9 100755
--- a/cmake_targets/tools/make_asn1c_includes.sh
+++ b/cmake_targets/tools/make_asn1c_includes.sh
@@ -1,13 +1,19 @@
 #!/bin/bash
-GENERATED_FULL_DIR=$1
+export ASN1C_PREFIX=$1
 shift
-ASN1_SOURCE_DIR=$1
+options=$1
 shift
-export ASN1C_PREFIX=$1
+GENERATED_FULL_DIR=$1
 shift
-options=$*
+ASN1_SOURCE_DIR=$*
 done_flag="$GENERATED_FULL_DIR"/done
-if [ "$done_flag" -ot $ASN1_SOURCE_DIR ] ; then
+rebuild=0
+for f in $ASN1_SOURCE_DIR ; do
+   if [ "$done_flag" -ot "$f" ] ; then
+      rebuild=1
+   fi
+done
+if [ $rebuild -eq 1 ] ; then
    rm -f "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}*.c "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}*.h
    mkdir -p "$GENERATED_FULL_DIR"
    asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example $options -D $GENERATED_FULL_DIR $ASN1_SOURCE_DIR |& egrep -v "^Copied|^Compiled" | sort -u
diff --git a/cmake_targets/tools/run_enb_s1_usrp b/cmake_targets/tools/run_enb_s1_usrp
index e11912668303a3c441e44350f4f50939e265d3cd..1a4c6b10b8381a367762e8032ae5235aa68e8a6a 100755
--- a/cmake_targets/tools/run_enb_s1_usrp
+++ b/cmake_targets/tools/run_enb_s1_usrp
@@ -101,7 +101,6 @@ function main()
   local -i run_gdb=0
   local -i show_stdout=0
   local    exe_arguments=""
-  local    itti_dump_file=""
   
   until [ -z "$1" ]
     do
@@ -154,18 +153,6 @@ function main()
             exe_arguments="$exe_arguments --rf-config-file=$rf_config_file"
 	fi 
         ;;      
-     -K | --itti-dump-file)
-        itti_dump_file=$2
-        # can omit file name if last arg on the line
-        if [ "x$itti_dump_file" = "x" ]; then
-          itti_dump_file="/tmp/enb_s1_usrp_itti.log"
-          shift 1;
-        else
-          shift 2;
-        fi
-        echo "setting ITTI dump file to: $itti_dump_file"
-        exe_arguments="$exe_arguments -K $itti_dump_file"
-        ;;      
       -m | --mscgen)
         g_msc_dir=$2
         # can omit file name if last arg on the line
diff --git a/cmake_targets/tools/setup_routes.sh b/cmake_targets/tools/setup_routes.sh
new file mode 100755
index 0000000000000000000000000000000000000000..67fe250be7706dd90108b64afce6979f891dc808
--- /dev/null
+++ b/cmake_targets/tools/setup_routes.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+for i in $(seq 1 $1);
+do
+    let table=1000+$i
+    echo "sudo ip route add 10.0.1.0/24 dev oaitun_ue$i table $table"
+    sudo ip route add 10.0.1.0/24 dev oaitun_ue$i table $table
+    echo "sudo ip route add default via 10.0.1.1 dev oaitun_ue$i table $table"
+    sudo ip route add default via 10.0.1.1 dev oaitun_ue$i table $table
+    let octet=$i+1
+    echo "sudo ip rule add from 10.0.1.$octet table $table"
+    sudo ip rule add from 10.0.1.$octet table $table
+done
diff --git a/cmake_targets/tools/test_helper b/cmake_targets/tools/test_helper
old mode 100644
new mode 100755
diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c
index 6d01d98c65b328496e80f5d34014472db4fcaee7..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;
@@ -255,7 +255,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
         if ( ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgpath) == 0))  || /* short option, one "-" */
              ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) || /* long option beginning with "--" */
              ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgoptions[n].optname) == 0) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ||
-             ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 ) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ) {
+             ((strlen(oneargv) > 2) && (strcmp(oneargv + 2, cfgoptions[n].optname) == 0 ) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ) {
           char *valptr=NULL;
           int ret;
           config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED;
diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h
index 8baaa99bb8074f90e9fa42aac5d18506c65a2f40..0688f6531f5d34dbdcf9e46f9a3b8219c7673fc1 100644
--- a/common/config/config_load_configmodule.h
+++ b/common/config/config_load_configmodule.h
@@ -82,10 +82,12 @@ typedef struct configmodule_interface {
 #ifdef CONFIG_LOADCONFIG_MAIN
 configmodule_interface_t *cfgptr=NULL;
 
-static char config_helpstr [] = "\n lte-softmodem -O [config mode]<:dbgl[debugflags]> \n \
-          debugflags can also be defined in the config_libconfig section of the config file\n \
+static char config_helpstr [] = "\n lte-softmodem -O [config mode]<:dbgl[debugflags]><:incp[path]>\n \
+          debugflags can also be defined in the config section of the config file\n \
           debugflags: mask,    1->print parameters, 2->print memory allocations debug messages\n \
-                               4->print command line processing debug messages\n ";
+                               4->print command line processing debug messages\n \
+          incp parameter can be used to define the include path used for config files (@include directive)\n \
+                         defaults is set to the path of the main config file.\n";
 
 #define CONFIG_SECTIONNAME "config"
 #define CONFIGPARAM_DEBUGFLAGS_IDX        0
diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c
index af70cae71eccf889a3618ed152f5f1138ac28627..462299b8939fcdb19316d1efc7cace4157d1dbcb 100644
--- a/common/config/config_userapi.c
+++ b/common/config/config_userapi.c
@@ -83,9 +83,14 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) {
   }
 
   if (*ptr == NULL) {
-    *ptr = malloc(length>40?length:40);
     // LTS: dummy fix, waiting Francois full fix in 4G branch
     // the issue is we don't know at this point the size we will get
+    // for parmeters on the command line, 
+    // The length sould probably managed, in a later version
+    // 100 is a very large value for a string parameter of today OAI
+    if (length<100)
+       length=100;
+    *ptr = malloc(length);
 
     if ( *ptr != NULL) {
       memset(*ptr,0,length);
diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c
index eb08a70183f5f699253450d460be22e607938c59..17266246f0c24e9b9178ebb62171ed5ff3dd0fc6 100644
--- a/common/config/libconfig/config_libconfig.c
+++ b/common/config/libconfig/config_libconfig.c
@@ -33,8 +33,9 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <unistd.h>
+ #include <libgen.h>
 
-#include <arpa/inet.h>
 
 #include "config_libconfig.h"
 #include "config_libconfig_private.h"
@@ -347,17 +348,35 @@ int config_libconfig_init(char *cfgP[], int numP) {
   config_get_if()->numptrs=0;
   memset(config_get_if()->ptrs,0,sizeof(void *) * CONFIG_MAX_ALLOCATEDPTRS);
   memset(config_get_if()->ptrsAllocated, 0, sizeof(config_get_if()->ptrsAllocated));
-
+  /* search for include path parameter and set config file include path accordingly */
+  for (int i=0; i<numP; i++) {
+  	  if (strncmp(cfgP[i],"incp",4) == 0) {
+  	  	  config_set_include_dir (&(libconfig_privdata.cfg),cfgP[i]+4);
+  	  break;
+  	  }
+  }
+  /* dirname may modify the input path and returned ptr may points to part of input path */
+  char *tmppath = strdup(libconfig_privdata.configfile);
+  if ( config_get_include_dir (&(libconfig_privdata.cfg)) == NULL) {
+  	 config_set_include_dir (&(libconfig_privdata.cfg),dirname( tmppath )); 	 
+  }
+  
+  const char *incp = config_get_include_dir (&(libconfig_privdata.cfg)) ;
+ 
+  printf("[LIBCONFIG] Path for include directive set to: %s\n", (incp!=NULL)?incp:"libconfig defaults");
+  /* set convertion option to allow integer to float conversion*/
+   config_set_auto_convert (&(libconfig_privdata.cfg), CONFIG_TRUE);
   /* Read the file. If there is an error, report it and exit. */
-  if(! config_read_file(&(libconfig_privdata.cfg), libconfig_privdata.configfile)) {
-    fprintf(stderr,"[LIBCONFIG] %s %d file %s - %d - %s\n",__FILE__, __LINE__,
+  if( config_read_file(&(libconfig_privdata.cfg), libconfig_privdata.configfile) == CONFIG_FALSE) {
+    fprintf(stderr,"[LIBCONFIG] %s %d file %s - line %d: %s\n",__FILE__, __LINE__,
             libconfig_privdata.configfile, config_error_line(&(libconfig_privdata.cfg)),
             config_error_text(&(libconfig_privdata.cfg)));
     config_destroy(&(libconfig_privdata.cfg));
     printf( "\n");
+    free(tmppath);
     return -1;
   }
-
+  free(tmppath);
   return 0;
 }
 
diff --git a/common/ran_context.h b/common/ran_context.h
index 3f57c000a097f0e3c816f06e140e5b510f84c182..db981e9182f31405019a5a9ffc767b54dd0d3c48 100644
--- a/common/ran_context.h
+++ b/common/ran_context.h
@@ -39,7 +39,7 @@
 #include "PHY/types.h"
 #include "PHY/impl_defs_top.h"
 
-#include "ENB_APP/enb_config.h"
+//#include "ENB_APP/enb_config.h"
 #include "flexran_agent_defs.h"
 
 #include "gtpv1u.h"
@@ -122,5 +122,5 @@ typedef struct {
   pthread_cond_t ru_cond;
 } RAN_CONTEXT_t;
 
-
+extern RAN_CONTEXT_t RC;
 #endif
diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c
index 9fd67a6dbb9cf6a0f3f385b4df81788c465601b9..d0a53a755b27ca807f5df975aa0f9f5c597446a0 100644
--- a/common/utils/LOG/log.c
+++ b/common/utils/LOG/log.c
@@ -88,7 +88,8 @@ int write_file_matlab(const char *fname,
 					  void *data,
 					  int length,
 					  int dec,
-					  unsigned int format)
+					  unsigned int format,
+            int multiVec)
 {
   FILE *fp=NULL;
   int i;
@@ -100,8 +101,7 @@ int write_file_matlab(const char *fname,
 
   //printf("Writing %d elements of type %d to %s\n",length,format,fname);
 
-
-  if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14) {
+  if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14 || multiVec) {
     fp = fopen(fname,"a+");
   } else if (format != 10 && format !=11  && format != 12 && format != 13 && format != 14) {
     fp = fopen(fname,"w+");
@@ -137,8 +137,7 @@ int write_file_matlab(const char *fname,
     return(0);	
   }
 
-
-  if (format != 10 && format !=11  && format != 12 && format != 13 && format != 14)
+  if ((format != 10 && format !=11  && format != 12 && format != 13 && format != 14) || multiVec)
     fprintf(fp,"%s = [",vname);
 
   switch (format) {
@@ -244,10 +243,10 @@ int write_file_matlab(const char *fname,
       fprintf(fp,"%d \n",((unsigned char *)&data)[0]);
       break;
   default:
-    AssertFatal(false, "unknown dump format: %d\n", format);
+    AssertFatal(false, "unknown dump format: %u\n", format);
   }
 
-  if (format != 10 && format !=11 && format !=12 && format != 13 && format != 15) {
+  if ((format != 10 && format !=11 && format !=12 && format != 13 && format != 15) || multiVec) {
     fprintf(fp,"];\n");
     fclose(fp);
     return(0);
@@ -461,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/LOG/log.h b/common/utils/LOG/log.h
index 49c6bdfd4c32bf696995dd66192fef781125b7f2..fa95d5a6fee9436755a6c42207cf1a598985742b 100644
--- a/common/utils/LOG/log.h
+++ b/common/utils/LOG/log.h
@@ -335,6 +335,7 @@ typedef struct {
 @param length length of data vector to output
 @param dec    decimation level
 @param format data format (0 = real 16-bit, 1 = complex 16-bit,2 real 32-bit, 3 complex 32-bit,4 = real 8-bit, 5 = complex 8-bit)
+@param multiVec create new file or append to existing (useful for writing multiple vectors to same file. Just call the function multiple times with same file name and with this parameter set to 1)
 */
 #define MATLAB_RAW (1<<31)
 #define MATLAB_SHORT 0
@@ -354,7 +355,7 @@ typedef struct {
 #define MATLAB_CSHORT_BRACKET2 14
 #define MATLAB_CSHORT_BRACKET3 15
   
-int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, unsigned int format);
+int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, unsigned int format, int multiVec);
 
 /*----------------macro definitions for reading log configuration from the config module */
 #define CONFIG_STRING_LOG_PREFIX                           "log_config"
@@ -414,7 +415,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
 
 /* bitmask dependent macros, to generate debug file such as matlab file or message dump */
 #    define LOG_DUMPFLAG(D) (g_log->dump_mask & D)
-#    define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)/* */
+#    define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0)/* */
 /* define variable only used in LOG macro's */
 #    define LOG_VAR(A,B) A B
 #  else /* T_TRACER: remove all debugging and tracing messages, except errors */
@@ -431,17 +432,19 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
 #    define LOG_DUMPFLAG(D) (g_log->debug_mask & D)
 #    define LOG_DUMPMSG(c, f, b, s, x...) do {  if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x)  ;}   while (0)  /* */
 
-#    define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)
+#    define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0)
 #    define LOG_VAR(A,B) A B
+#    define T_ACTIVE(a) (0) 
 #  endif /* T_TRACER */
 /* avoid warnings for variables only used in LOG macro's but set outside debug section */
 #define GCC_NOTUSED   __attribute__((unused))
 #define LOG_USEDINLOG_VAR(A,B) GCC_NOTUSED A B
 
 /* unfiltered macros, useful for simulators or messages at init time, before log is configured */
-#define LOG_UM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)
+#define LOG_UM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0)
 #define LOG_UI(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ; } while(0)
 #define LOG_UDUMPMSG(c, b, s, f, x...) do { log_dump(c, b, s, f, x)  ;}   while (0)  /* */
+#    define LOG_MM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 1);} while(0)
 /* @}*/
 
 
diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c
index bd598b48dab7ba97d7cdb2b7e0aa21c15bf14e64..5bf97599338f0e1d673bfcc973e065b498c2d950 100644
--- a/common/utils/LOG/vcd_signal_dumper.c
+++ b/common/utils/LOG/vcd_signal_dumper.c
@@ -302,6 +302,9 @@ const char* eurecomFunctionsNames[] = {
   /* PHY signals  */
   "ue_synch",
   "ue_slot_fep",
+  "ue_slot_fep_pdcch",
+  "ue_slot_fep_pbch",
+  "ue_slot_fep_pdsch",
   "ue_slot_fep_mbsfn",
   "ue_slot_fep_mbsfn_khz_1dot25",
   "ue_rrc_measurements",
@@ -390,6 +393,8 @@ const char* eurecomFunctionsNames[] = {
   "rx_pmch",
   "rx_pmch_khz_1dot25",
   "pdsch_procedures",
+  "pdsch_procedures_crnti",
+  //"dlsch_procedures_crnti",
   "pdsch_procedures_si",
   "pdsch_procedures_p",
   "pdsch_procedures_ra",
diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h
index f9f5868260fce048470531405b303bff5dd945a5..fb27c19973ad84105ca878ae0c6a0a60abf1c318 100644
--- a/common/utils/LOG/vcd_signal_dumper.h
+++ b/common/utils/LOG/vcd_signal_dumper.h
@@ -283,6 +283,9 @@ typedef enum {
   /* PHY signals  */
   VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SYNCH,
   VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH,
   VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN,
   VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN_KHZ_1DOT25,
   VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS,
@@ -371,9 +374,11 @@ typedef enum {
   VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH,
   VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH_KHZ_1DOT25,
   VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C,
   VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI,
   VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P,
   VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA,
+  //VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PROC_C,
   VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2,
   VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_CONFIG_SIB1_ENB,
   VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_CONFIG_SIB2_ENB,
diff --git a/common/utils/T/.gitignore b/common/utils/T/.gitignore
index d754ff7c38730801afa6f6629ef45b9c9d4dcc03..6a6e5817c5d20da48e684ae4401878124d30b812 100644
--- a/common/utils/T/.gitignore
+++ b/common/utils/T/.gitignore
@@ -4,6 +4,7 @@ T_IDs.h
 T_messages.txt.h
 genids
 tracer/enb
+tracer/gnb
 tracer/extract_config
 tracer/record
 tracer/replay
diff --git a/common/utils/T/Makefile b/common/utils/T/Makefile
index 0588c88a456c4d54965c73f4caee0e060d8b4852..d76ab93cb8d0a735f79031571ae3140d7fe85c28 100644
--- a/common/utils/T/Makefile
+++ b/common/utils/T/Makefile
@@ -18,7 +18,7 @@ T_messages.txt.h: T_messages.txt
 T_IDs.h: $(GENIDS) T_messages.txt
 	./$(GENIDS) T_messages.txt T_IDs.h
 
-check_vcd:
+check_vcd: T_IDs.h T_messages.txt.h
 	gcc -Wall -I. -I.. -I../itti -I../../../openair2/COMMON -Itracer -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread
 	./_check_vcd || (rm -f ./_check_vcd ./T_IDs.h ./T_messages.txt.h && false)
 	rm -f ./_check_vcd
diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h
index 11c816f002a409c8befb42ff7381126a5e3b00a9..b74c0567ce7333544d8a29f95419b1f08eb57f85 100644
--- a/common/utils/T/T_defs.h
+++ b/common/utils/T/T_defs.h
@@ -42,9 +42,9 @@
 /* maximum size of a message - increase if needed */
 #if BASIC_SIMULATOR
    /* let's have 100 RBs functional for the basic simulator */
-#  define T_BUFFER_MAX (1024*64*2)
+#  define T_BUFFER_MAX (1024*64*4)
 #else
-#  define T_BUFFER_MAX (1024*64*2)
+#  define T_BUFFER_MAX (1024*64*4)
 #endif
 
 /* size of the local cache for messages (must be pow(2,something)) */
@@ -73,7 +73,7 @@ typedef struct {
 } T_cache_t;
 
 /* number of VCD functions (to be kept up to date! see in T_messages.txt) */
-#define VCD_NUM_FUNCTIONS (269)
+#define VCD_NUM_FUNCTIONS (273)
 
 /* number of VCD variables (to be kept up to date! see in T_messages.txt) */
 #define VCD_NUM_VARIABLES (187)
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
index bad6444e1303d385c9808608a599cf6e43330bab..ca5690497dc05140dc918e8b47254ec94f0ab26f 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -1,7 +1,3 @@
-ID = BENETEL
-  GROUP = ALL
-  FORMAT = int,frame : int,slot : buffer,rxdataF
-
 #general logs
 ID = ENB_MASTER_TICK
     DESC = eNodeB master tick - one tick per ms, to be used as "reference clock", mostly for ticktime view
@@ -93,6 +89,14 @@ ID = GNB_PHY_MIB
     DESC = NR MIB data
     GROUP = ALL:PHY:GNB:WIRESHARK
     FORMAT = int,gNB_ID : int,frame : int,slot : buffer,data
+ID = GNB_PHY_PUCCH_PUSCH_IQ
+    DESC = gNodeB input data in the frequency domain for a slot where some PUCCH or PUSCH detection was done
+    GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
+    FORMAT = int,frame : int,slot : buffer,rxdataF
+ID = GNB_PHY_PRACH_INPUT_SIGNAL
+    DESC = gNodeB input data in the time domain for slots with PRACH detection
+    GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
+    FORMAT = int,frame : int,slot : int,antenna : buffer,rxdata
 
 #MAC logs
 ID = ENB_MAC_UE_DL_SDU
@@ -2407,6 +2411,21 @@ ID = VCD_FUNCTION_UE_SLOT_FEP
     GROUP = ALL:VCD:UE:VCD_FUNCTION
     FORMAT = int,value
     VCD_NAME = ue_slot_fep
+ID = VCD_FUNCTION_UE_SLOT_FEP_PDCCH
+    DESC = VCD function UE_SLOT_FEP_PDCCH
+    GROUP = ALL:VCD:UE:VCD_FUNCTION
+    FORMAT = int,value
+    VCD_NAME = ue_slot_fep_pdcch
+ID = VCD_FUNCTION_UE_SLOT_FEP_PBCH
+    DESC = VCD function UE_SLOT_FEP_PBCH
+    GROUP = ALL:VCD:UE:VCD_FUNCTION
+    FORMAT = int,value
+    VCD_NAME = ue_slot_fep_pbch
+ID = VCD_FUNCTION_UE_SLOT_FEP_PDSCH
+    DESC = VCD function UE_SLOT_FEP_PDSCH
+    GROUP = ALL:VCD:UE:VCD_FUNCTION
+    FORMAT = int,value
+    VCD_NAME = ue_slot_fep_pdsch
 ID = VCD_FUNCTION_UE_SLOT_FEP_MBSFN
     DESC = VCD function UE_SLOT_FEP_MBSFN
     GROUP = ALL:VCD:UE:VCD_FUNCTION
@@ -2847,6 +2866,11 @@ ID = VCD_FUNCTION_PDSCH_PROC
     GROUP = ALL:VCD:UE:VCD_FUNCTION
     FORMAT = int,value
     VCD_NAME = pdsch_procedures
+ID = VCD_FUNCTION_PDSCH_PROC_C
+    DESC = VCD function PDSCH_PROC_C
+    GROUP = ALL:VCD:UE:VCD_FUNCTION
+    FORMAT = int,value
+    VCD_NAME = pdsch_procedures_crnti
 ID = VCD_FUNCTION_PDSCH_PROC_SI
     DESC = VCD function PDSCH_PROC_SI
     GROUP = ALL:VCD:UE:VCD_FUNCTION
diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile
index 792c2a407c1ce1233ad8930396a86996020c2001..0713d9a3df9f0233baee15abbe92aad211654b24 100644
--- a/common/utils/T/tracer/Makefile
+++ b/common/utils/T/tracer/Makefile
@@ -7,7 +7,8 @@ LIBS=-lm
 XLIBS=-lX11 -lpng -lXft
 
 all: record replay extract_config textlog enb ue vcd macpdu2wireshark \
-     extract_input_subframe extract_output_subframe to_vcd extract multi
+     extract_input_subframe extract_output_subframe to_vcd extract multi \
+     gnb
 
 record: utils.o record.o database.o config.o
 	$(CC) $(CFLAGS) -o record $^ $(LIBS)
@@ -60,6 +61,11 @@ macpdu2wireshark: macpdu2wireshark.o database.o utils.o handler.o event.o \
 multi: multi.o utils.o database.o config.o
 	$(CC) $(CFLAGS) -o multi $^ $(LIBS)
 
+gnb: utils.o gnb.o database.o event.o handler.o config.o \
+         view/view.a gui/gui.a logger/logger.a \
+         filter/filter.a
+	$(CC) $(CFLAGS) -o gnb $^ $(LIBS) $(XLIBS)
+
 multi.o: ../T_IDs.h
 
 ../T_IDs.h:
@@ -85,7 +91,7 @@ filter/filter.a:
 clean:
 	rm -f *.o core tracer_remote textlog enb ue vcd record replay
 	rm -f extract_config macpdu2wireshark extract_input_subframe
-	rm -f extract_output_subframe to_vcd extract multi
+	rm -f extract_output_subframe to_vcd extract multi gnb
 	cd gui && $(MAKE) clean
 	cd view && $(MAKE) clean
 	cd logger && $(MAKE) clean
diff --git a/common/utils/T/tracer/gnb.c b/common/utils/T/tracer/gnb.c
new file mode 100644
index 0000000000000000000000000000000000000000..4aaa4898a1fcc7902c189d8732f3a481c9562634
--- /dev/null
+++ b/common/utils/T/tracer/gnb.c
@@ -0,0 +1,172 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+#include "database.h"
+#include "handler.h"
+#include "config.h"
+#include "logger/logger.h"
+#include "view/view.h"
+#include "gui/gui.h"
+
+typedef struct {
+  widget *pucch_pusch_iq_plot;
+  logger *pucch_pusch_iq_logger;
+} gnb_gui;
+
+typedef struct {
+  int socket;
+  int *is_on;
+  int nevents;
+  pthread_mutex_t lock;
+  gnb_gui *e;
+  void *database;
+} gnb_data;
+
+void is_on_changed(void *_d)
+{
+  gnb_data *d = _d;
+  char t;
+
+  if (pthread_mutex_lock(&d->lock)) abort();
+
+  if (d->socket == -1) goto no_connection;
+
+  t = 1;
+  if (socket_send(d->socket, &t, 1) == -1 ||
+      socket_send(d->socket, &d->nevents, sizeof(int)) == -1 ||
+      socket_send(d->socket, d->is_on, d->nevents * sizeof(int)) == -1)
+    goto connection_dies;
+
+no_connection:
+  if (pthread_mutex_unlock(&d->lock)) abort();
+  return;
+
+connection_dies:
+  close(d->socket);
+  d->socket = -1;
+  if (pthread_mutex_unlock(&d->lock)) abort();
+}
+
+void usage(void)
+{
+  printf(
+"options:\n"
+"    -d   <database file>      this option is mandatory\n"
+"    -ip <host>                connect to given IP address (default %s)\n"
+"    -p  <port>                connect to given port (default %d)\n",
+  DEFAULT_REMOTE_IP,
+  DEFAULT_REMOTE_PORT
+  );
+  exit(1);
+}
+
+static void *gui_thread(void *_g)
+{
+  gui *g = _g;
+  gui_loop(g);
+  return NULL;
+}
+
+static void gnb_main_gui(gnb_gui *e, gui *g, event_handler *h, void *database,
+    gnb_data *ed)
+{
+  widget *main_window;
+  widget *top_container;
+  widget *line;
+  widget *w;
+  logger *l;
+  view *v;
+
+  main_window = new_toplevel_window(g, 500, 300, "gNB tracer");
+
+  top_container = new_container(g, VERTICAL);
+  widget_add_child(g, main_window, top_container, -1);
+
+  line = new_container(g, HORIZONTAL);
+  widget_add_child(g, top_container, line, -1);
+
+  /* PUCCH/PUSCH IQ data */
+  w = new_xy_plot(g, 55, 55, "", 50);
+  e->pucch_pusch_iq_plot = w;
+  widget_add_child(g, line, w, -1);
+  xy_plot_set_range(g, w, -1000, 1000, -1000, 1000);
+  xy_plot_set_title(g, w, "rxdataF");
+  l = new_iqlog_full(h, database, "GNB_PHY_PUCCH_PUSCH_IQ", "rxdataF");
+  v = new_view_xy(300*12*14,10,g,w,new_color(g,"#000"),XY_FORCED_MODE);
+  logger_add_view(l, v);
+  e->pucch_pusch_iq_logger = l;
+}
+
+int main(int n, char **v)
+{
+  char *database_filename = NULL;
+  void *database;
+  char *ip = DEFAULT_REMOTE_IP;
+  int port = DEFAULT_REMOTE_PORT;
+  int *is_on;
+  int number_of_events;
+  int i;
+  event_handler *h;
+  gnb_data gnb_data;
+  gui *g;
+  gnb_gui eg;
+
+  for (i = 1; i < n; i++) {
+    if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
+    if (!strcmp(v[i], "-d"))
+      { if (i > n-2) usage(); database_filename = v[++i]; continue; }
+    usage();
+  }
+
+  if (database_filename == NULL) {
+    printf("ERROR: provide a database file (-d)\n");
+    exit(1);
+  }
+
+  database = parse_database(database_filename);
+
+  load_config_file(database_filename);
+
+  number_of_events = number_of_ids(database);
+  is_on = calloc(number_of_events, sizeof(int));
+  if (is_on == NULL) abort();
+
+  h = new_handler(database);
+
+  on_off(database, "GNB_PHY_PUCCH_PUSCH_IQ", is_on, 1);
+
+  gnb_data.database = database;
+  gnb_data.socket = -1;
+  gnb_data.is_on = is_on;
+  gnb_data.nevents = number_of_events;
+  if (pthread_mutex_init(&gnb_data.lock, NULL)) abort();
+
+  g = gui_init();
+  new_thread(gui_thread, g);
+
+  gnb_main_gui(&eg, g, h, database, &gnb_data);
+
+  OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
+
+restart:
+  clear_remote_config();
+  if (gnb_data.socket != -1) close(gnb_data.socket);
+  gnb_data.socket = connect_to(ip, port);
+
+  /* send the first message - activate selected traces */
+  is_on_changed(&gnb_data);
+
+  /* read messages */
+  while (1) {
+    event e;
+    e = get_event(gnb_data.socket, &ebuf, database);
+    if (e.type == -1) goto restart;
+    if (pthread_mutex_lock(&gnb_data.lock)) abort();
+    handle_event(h, e);
+    if (pthread_mutex_unlock(&gnb_data.lock)) abort();
+  }
+
+  return 0;
+}
diff --git a/common/utils/T/tracer/logger/iqlog.c b/common/utils/T/tracer/logger/iqlog.c
index 168c50e39b0978be0409769acf42fcfd9bbbcb33..1947de2bca4c3bfee863ffe73023b8f12bba160d 100644
--- a/common/utils/T/tracer/logger/iqlog.c
+++ b/common/utils/T/tracer/logger/iqlog.c
@@ -74,6 +74,44 @@ static void _event(void *p, event e)
     l->common.v[i]->append(l->common.v[i], l->i, l->q, count);
 }
 
+static void _event_full(void *p, event e)
+{
+  struct iqlog *l = p;
+  int i;
+  void *buffer;
+  int bsize;
+  int nsamples;
+  float *idst, *qdst;
+
+  if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0)
+    return;
+
+  buffer = e.e[l->buffer_arg].b;
+  bsize = e.e[l->buffer_arg].bsize;
+
+  nsamples = bsize / 4;
+
+  if (nsamples > l->max_length) {
+    l->i = realloc(l->i, nsamples * sizeof(float));
+    if (l->i == NULL) abort();
+    l->q = realloc(l->q, nsamples * sizeof(float));
+    if (l->q == NULL) abort();
+    l->max_length = nsamples;
+  }
+
+  idst = l->i;
+  qdst = l->q;
+  for (i = 0; i < nsamples; i++) {
+    *idst = ((int16_t *)buffer)[i * 2];
+    *qdst = ((int16_t *)buffer)[i * 2 + 1];
+    idst++;
+    qdst++;
+  }
+
+  for (i = 0; i < l->common.vsize; i++)
+    l->common.v[i]->append(l->common.v[i], l->i, l->q, nsamples);
+}
+
 logger *new_iqlog(event_handler *h, void *database,
     char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti,
     char *buffer_varname)
@@ -149,3 +187,43 @@ logger *new_iqlog(event_handler *h, void *database,
 
   return ret;
 }
+
+logger *new_iqlog_full(event_handler *h, void *database, char *event_name,
+    char *buffer_varname)
+{
+  struct iqlog *ret;
+  int event_id;
+  database_event_format f;
+  int i;
+
+  ret = calloc(1, sizeof(struct iqlog)); if (ret == NULL) abort();
+
+  ret->common.event_name = strdup(event_name);
+  if (ret->common.event_name == NULL) abort();
+  ret->database = database;
+
+  event_id = event_id_from_name(database, event_name);
+
+  ret->common.handler_id = register_handler_function(h, event_id, _event_full,
+                                                     ret);
+
+  f = get_format(database, event_id);
+
+  /* look for args */
+  ret->buffer_arg = -1;
+  for (i = 0; i < f.count; i++) {
+    if (!strcmp(f.name[i], buffer_varname)) ret->buffer_arg = i;
+  }
+  if (ret->buffer_arg == -1) {
+    printf("%s:%d: buffer argument '%s' not found in event '%s'\n",
+        __FILE__, __LINE__, buffer_varname, event_name);
+    abort();
+  }
+  if (strcmp(f.type[ret->buffer_arg], "buffer") != 0) {
+    printf("%s:%d: argument '%s' has wrong type (should be 'buffer')\n",
+        __FILE__, __LINE__, buffer_varname);
+    abort();
+  }
+
+  return ret;
+}
diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h
index 7c019b4797244b5edc4a8120cc551392f52b09fb..d746161e7061907ae5783acf170c64716f98b039 100644
--- a/common/utils/T/tracer/logger/logger.h
+++ b/common/utils/T/tracer/logger/logger.h
@@ -23,6 +23,8 @@ logger *new_ticklog(void *event_handler, void *database,
 logger *new_iqlog(void *event_handler, void *database,
     char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti,
     char *buffer_varname);
+logger *new_iqlog_full(void *event_handler, void *database, char *event_name,
+    char *buffer_varname);
 logger *new_iqdotlog(void *event_handler, void *database,
     char *event_name, char *I, char *Q);
 
diff --git a/common/utils/assertions.h b/common/utils/assertions.h
index 48d8df401cec155027bec18dacc056ef3f70d7fe..06d43bdbfa05c26dc08ac292aae9af8dd15a6364 100644
--- a/common/utils/assertions.h
+++ b/common/utils/assertions.h
@@ -39,7 +39,7 @@ void output_log_mem(void);
     display_backtrace();                        \
     fflush(stdout);                             \
     fflush(stderr);                             \
-    exit(EXIT_FAILURE);                         \
+    abort();
 
 #define _Assert_(cOND, aCTION, fORMAT, aRGS...)             \
 do {                                                        \
diff --git a/common/utils/backtrace.c b/common/utils/backtrace.c
index f6de74f156ce1bc04ddb58aeb65c3097c8c1ba47..f61cf0349ac5d9a64fcad36a6b235e9c8071768d 100644
--- a/common/utils/backtrace.c
+++ b/common/utils/backtrace.c
@@ -38,7 +38,7 @@ void display_backtrace(void) {
   size_t i;
   char *test=getenv("NO_BACKTRACE");
 
-  if (test!=0) *((int *)0)=0;
+  if (test!=0) abort();
 
   size = backtrace(array, 10);
   strings = backtrace_symbols(array, size);
diff --git a/common/utils/lte/prach_utils.c b/common/utils/lte/prach_utils.c
new file mode 100644
index 0000000000000000000000000000000000000000..9ef29e55a5ef5c467ffae8b616a75761356ac7c1
--- /dev/null
+++ b/common/utils/lte/prach_utils.c
@@ -0,0 +1,425 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file common/utils/lte/prach_utils.c
+ * \brief utils for PRACH  common to both PHY and MAC
+ * \author R. Knopp
+ * \date 2020
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include <stdint.h>
+
+
+#include "PHY/LTE_TRANSPORT/transport_common.h"
+
+// This is table 5.7.1-4 from 36.211
+PRACH_TDD_PREAMBLE_MAP tdd_preamble_map[64][7] = {
+  // TDD Configuration Index 0
+  { {1,{{0,1,0,2}}},{1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {1,{{0,1,0,2}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {1,{{0,1,0,2}}}},
+  // TDD Configuration Index 1
+  { {1,{{0,2,0,2}}},{1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {1,{{0,2,0,2}}}, {1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {1,{{0,2,0,2}}}},
+  // TDD Configuration Index 2
+  { {1,{{0,1,1,2}}},{1,{{0,1,1,1}}}, {1,{{0,1,1,0}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,1,1}}}},
+  // TDD Configuration Index 3
+  { {1,{{0,0,0,2}}},{1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {1,{{0,0,0,2}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {1,{{0,0,0,2}}}},
+  // TDD Configuration Index 4
+  { {1,{{0,0,1,2}}},{1,{{0,0,1,1}}}, {1,{{0,0,1,0}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,1,1}}}},
+  // TDD Configuration Index 5
+  { {1,{{0,0,0,1}}},{1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}},
+  // TDD Configuration Index 6
+  { {2,{{0,0,0,2},{0,0,1,2}}}, {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {2,{{0,0,0,1},{0,0,0,2}}}, {2,{{0,0,0,0},{0,0,0,1}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {2,{{0,0,0,2},{0,0,1,1}}}},
+  // TDD Configuration Index 7
+  { {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{0,0,0,2}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{0,0,1,0}}}},
+  // TDD Configuration Index 8
+  { {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{0,0,0,1}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{0,0,1,1}}}},
+  // TDD Configuration Index 9
+  { {3,{{0,0,0,1},{0,0,0,2},{0,0,1,2}}}, {3,{{0,0,0,0},{0,0,0,1},{0,0,1,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,1},{0,0,0,2}}}, {3,{{0,0,0,0},{0,0,0,1},{1,0,0,1}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {3,{{0,0,0,1},{0,0,0,2},{0,0,1,1}}}},
+  // TDD Configuration Index 10
+  { {3,{{0,0,0,0},{0,0,1,0},{0,0,1,1}}}, {3,{{0,0,0,1},{0,0,1,0},{0,0,1,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,1},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,2},{0,0,1,0}}}},
+  // TDD Configuration Index 11
+  { {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,1},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{0,0,1,0},{0,0,1,1}}}},
+  // TDD Configuration Index 12
+  { {4,{{0,0,0,1},{0,0,0,2},{0,0,1,1},{0,0,1,2}}}, {4,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1}}},
+    {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}},
+    {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,2}}},
+    {4,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1}}},
+    {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}},
+    {4,{{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1}}}
+  },
+  // TDD Configuration Index 13
+  { {4,{{0,0,0,0},{0,0,0,2},{0,0,1,0},{0,0,1,2}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,1}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,1}}}
+  },
+  // TDD Configuration Index 14
+  { {4,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {4,{{0,0,0,0},{0,0,0,2},{0,0,1,0},{0,0,1,1}}}
+  },
+  // TDD Configuration Index 15
+  { {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,1},{0,0,1,2}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,1}}},
+    {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,1},{1,0,0,2}}},
+    {5,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1},{2,0,0,1}}}, {5,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0}}},
+    {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1}}}
+  },
+  // TDD Configuration Index 16
+  { {5,{{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{0,0,1,2}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,1,1}}},
+    {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,1,0}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0},{1,0,0,2}}},
+    {5,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}
+  },
+  // TDD Configuration Index 17
+  { {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,2}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0},{1,0,0,1}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}
+  },
+  // TDD Configuration Index 18
+  { {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{0,0,1,2}}},
+    {6,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,1},{1,0,1,1}}},
+    {6,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0},{2,0,1,0}}},
+    {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0},{1,0,0,1},{1,0,0,2}}},
+    {6,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1},{2,0,0,0},{2,0,0,1}}},
+    {6,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0},{5,0,0,0}}},
+    {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{1,0,0,2}}}
+  },
+  // TDD Configuration Index 19
+  { {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {6,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,0},{1,0,1,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{1,0,1,1}}}
+  },
+  // TDD Configuration Index 20
+  { {1,{{0,1,0,1}}},{1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}},
+  // TDD Configuration Index 21
+  { {1,{{0,2,0,1}}},{1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}},
+
+  // TDD Configuration Index 22
+  { {1,{{0,1,1,1}}},{1,{{0,1,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,1,0}}}},
+
+  // TDD Configuration Index 23
+  { {1,{{0,0,0,1}}},{1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}},
+
+  // TDD Configuration Index 24
+  { {1,{{0,0,1,1}}},{1,{{0,0,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,1,0}}}},
+
+  // TDD Configuration Index 25
+  { {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{1,0,0,1}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{0,0,1,0}}}},
+
+  // TDD Configuration Index 26
+  { {3,{{0,0,0,1},{0,0,1,1},{1,0,0,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{1,0,0,1},{2,0,0,1}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{0,0,1,0},{1,0,0,1}}}},
+
+  // TDD Configuration Index 27
+  { {4,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1}}}, {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {4,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1}}},
+    {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {4,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0}}}
+  },
+
+  // TDD Configuration Index 28
+  { {5,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1}}}, {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {5,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1}}},
+    {5,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {5,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1}}}
+  },
+
+  // TDD Configuration Index 29
+  { {6,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1},{2,0,1,1}}},
+    {6,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0},{2,0,1,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {6,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1},{5,0,0,1}}},
+    {6,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0},{5,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {6,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1},{2,0,1,0}}}
+  },
+
+
+  // TDD Configuration Index 30
+  { {1,{{0,1,0,1}}},{1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}},
+
+  // TDD Configuration Index 31
+  { {1,{{0,2,0,1}}},{1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}},
+
+  // TDD Configuration Index 32
+  { {1,{{0,1,1,1}}},{1,{{0,1,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,1,0}}}},
+
+  // TDD Configuration Index 33
+  { {1,{{0,0,0,1}}},{1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}},
+
+  // TDD Configuration Index 34
+  { {1,{{0,0,1,1}}},{1,{{0,0,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,1,0}}}},
+
+  // TDD Configuration Index 35
+  { {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{1,0,0,1}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{0,0,1,0}}}},
+
+  // TDD Configuration Index 36
+  { {3,{{0,0,0,1},{0,0,1,1},{1,0,0,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{1,0,0,1},{2,0,0,1}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{0,0,1,0},{1,0,0,1}}}},
+
+  // TDD Configuration Index 37
+  { {4,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1}}}, {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {4,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1}}},
+    {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {4,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0}}}
+  },
+
+  // TDD Configuration Index 38
+  { {5,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1}}}, {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {5,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1}}},
+    {5,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {5,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1}}}
+  },
+
+  // TDD Configuration Index 39
+  { {6,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1},{2,0,1,1}}},
+    {6,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0},{2,0,1,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {6,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1},{5,0,0,1}}},
+    {6,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0},{5,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {6,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1},{2,0,1,0}}}
+  },
+
+  // TDD Configuration Index 40
+  { {1,{{0,1,0,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,0}}}},
+  // TDD Configuration Index 41
+  { {1,{{0,2,0,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,0}}}},
+
+  // TDD Configuration Index 42
+  { {1,{{0,1,1,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}},
+
+  // TDD Configuration Index 43
+  { {1,{{0,0,0,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,0}}}},
+
+  // TDD Configuration Index 44
+  { {1,{{0,0,1,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}},
+
+  // TDD Configuration Index 45
+  { {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{1,0,0,0}}}},
+
+  // TDD Configuration Index 46
+  { {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}},
+
+  // TDD Configuration Index 47
+  { {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}},
+    {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}
+  }
+};
+
+
+uint8_t get_prach_fmt(int prach_ConfigIndex,int frame_type) {
+  if (frame_type == FDD) // FDD
+    return(prach_ConfigIndex>>4);
+  else {
+    if (prach_ConfigIndex < 20)
+      return (0);
+
+    if (prach_ConfigIndex < 30)
+      return (1);
+
+    if (prach_ConfigIndex < 40)
+      return (2);
+
+    if (prach_ConfigIndex < 48)
+      return (3);
+    else
+      return (4);
+  }
+}
+
+uint8_t get_prach_prb_offset(int frame_type,
+			     int tdd_config,
+                             int N_RB_UL,
+                             uint8_t prach_ConfigIndex,
+                             uint8_t n_ra_prboffset,
+                             uint8_t tdd_mapindex, uint16_t Nf) {
+  uint8_t n_ra_prb;
+  uint8_t f_ra,t1_ra;
+  uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
+  uint8_t Nsp=2;
+
+  if (frame_type == TDD) { // TDD
+    if (tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach==0) {
+      LOG_E(PHY, "Illegal prach_ConfigIndex %"PRIu8"", prach_ConfigIndex);
+      return(-1);
+    }
+
+    // adjust n_ra_prboffset for frequency multiplexing (p.36 36.211)
+    f_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[tdd_mapindex].f_ra;
+
+    if (prach_fmt < 4) {
+      if ((f_ra&1) == 0) {
+        n_ra_prb = n_ra_prboffset + 6*(f_ra>>1);
+      } else {
+        n_ra_prb = N_RB_UL - 6 - n_ra_prboffset + 6*(f_ra>>1);
+      }
+    } else {
+      if ((tdd_config >2) && (tdd_config<6))
+        Nsp = 2;
+
+      t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra;
+
+      if ((((Nf&1)*(2-Nsp)+t1_ra)&1) == 0) {
+        n_ra_prb = 6*f_ra;
+      } else {
+        n_ra_prb = N_RB_UL - 6*(f_ra+1);
+      }
+    }
+  } else { //FDD
+    n_ra_prb = n_ra_prboffset;
+  }
+
+  return(n_ra_prb);
+}
+
+int is_prach_subframe0(int tdd_config,int frame_type,uint8_t prach_ConfigIndex,uint32_t frame, uint8_t subframe) {
+  uint8_t t0_ra;
+  uint8_t t1_ra;
+  uint8_t t2_ra;
+  int prach_mask = 0;
+
+  if (frame_type == FDD) { //FDD
+    //implement Table 5.7.1-2 from 36.211 (Rel-10, p.41)
+    if ((((frame&1) == 1) && (subframe < 9)) ||
+        (((frame&1) == 0) && (subframe == 9)))  // This is an odd frame, ignore even-only PRACH frames
+      if (((prach_ConfigIndex&0xf)<3) || // 0,1,2,16,17,18,32,33,34,48,49,50
+          ((prach_ConfigIndex&0x1f)==18) || // 18,50
+          ((prach_ConfigIndex&0xf)==15))   // 15,47
+        return(0);
+
+    switch (prach_ConfigIndex&0x1f) {
+      case 0:
+      case 3:
+        if (subframe==1) prach_mask = 1;
+
+        break;
+
+      case 1:
+      case 4:
+        if (subframe==4) prach_mask = 1;
+
+        break;
+
+      case 2:
+      case 5:
+        if (subframe==7) prach_mask = 1;
+
+        break;
+
+      case 6:
+        if ((subframe==1) || (subframe==6)) prach_mask=1;
+
+        break;
+
+      case 7:
+        if ((subframe==2) || (subframe==7)) prach_mask=1;
+
+        break;
+
+      case 8:
+        if ((subframe==3) || (subframe==8)) prach_mask=1;
+
+        break;
+
+      case 9:
+        if ((subframe==1) || (subframe==4) || (subframe==7)) prach_mask=1;
+
+        break;
+
+      case 10:
+        if ((subframe==2) || (subframe==5) || (subframe==8)) prach_mask=1;
+
+        break;
+
+      case 11:
+        if ((subframe==3) || (subframe==6) || (subframe==9)) prach_mask=1;
+
+        break;
+
+      case 12:
+        if ((subframe&1)==0) prach_mask=1;
+
+        break;
+
+      case 13:
+        if ((subframe&1)==1) prach_mask=1;
+
+        break;
+
+      case 14:
+        prach_mask=1;
+        break;
+
+      case 15:
+        if (subframe==9) prach_mask=1;
+
+        break;
+    }
+  } else { // TDD
+    AssertFatal(prach_ConfigIndex<64,
+                "Illegal prach_ConfigIndex %d for ",prach_ConfigIndex);
+    AssertFatal(tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach>0,
+                "Illegal prach_ConfigIndex %d for ",prach_ConfigIndex);
+    t0_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t0_ra;
+    t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra;
+    t2_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t2_ra;
+#ifdef PRACH_DEBUG
+    LOG_I(PHY,"[PRACH] Checking for PRACH format (ConfigIndex %d) in TDD subframe %d (%d,%d,%d)\n",
+          prach_ConfigIndex,
+          subframe,
+          t0_ra,t1_ra,t2_ra);
+#endif
+
+    if ((((t0_ra == 1) && ((frame &1)==0))||  // frame is even and PRACH is in even frames
+         ((t0_ra == 2) && ((frame &1)==1))||  // frame is odd and PRACH is in odd frames
+         (t0_ra == 0)) &&                                // PRACH is in all frames
+        (((subframe<5)&&(t1_ra==0)) ||                   // PRACH is in 1st half-frame
+         (((subframe>4)&&(t1_ra==1))))) {                // PRACH is in 2nd half-frame
+      if ((prach_ConfigIndex<48) &&                          // PRACH only in normal UL subframe
+          (((subframe%5)-2)==t2_ra)) prach_mask=1;
+      else if ((prach_ConfigIndex>47) && (((subframe%5)-1)==t2_ra)) prach_mask=1;      // PRACH can be in UpPTS
+    }
+  }
+
+  return(prach_mask);
+}
+
diff --git a/common/utils/lte/prach_utils.h b/common/utils/lte/prach_utils.h
new file mode 100644
index 0000000000000000000000000000000000000000..995805fbd2f0547956966e9580f517f6e1fea168
--- /dev/null
+++ b/common/utils/lte/prach_utils.h
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file common/utils/prach_utils.h
+* \brief computation of some PRACH variables used in both MAC and PHY 
+* \author R. Knopp
+* \date 2020
+* \version 0.1
+* \company Eurecom
+* \email: raymond.knopp@eurecom.fr, florian.kaltenberger@eurecom.fr, oscar.tonelli@yahoo.it
+* \note
+* \warning
+*/
+uint8_t get_prach_fmt(int prach_ConfigIndex,int frame_type);
+
+uint8_t get_prach_prb_offset(int frame_type,
+                             int tdd_config,
+                             int N_RB_UL,
+                             uint8_t prach_ConfigIndex,
+                             uint8_t n_ra_prboffset,
+                             uint8_t tdd_mapindex, uint16_t Nf);
+int is_prach_subframe0(int tdd_config,int frame_type,uint8_t prach_ConfigIndex,uint32_t frame, uint8_t subframe);
diff --git a/common/utils/lte/ue_power.c b/common/utils/lte/ue_power.c
new file mode 100644
index 0000000000000000000000000000000000000000..b377abf2ff91719f1d4107902c4ce5ba6912fe8a
--- /dev/null
+++ b/common/utils/lte/ue_power.c
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file ue_power.c
+* \brief Routines to compute UE TX power according to 36.213
+* \author R. Knopp, F. Kaltenberger
+* \date 2020
+* \version 0.1
+* \company Eurecom
+* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
+* \note
+* \warning
+*/
+
+#include <stdint.h>
+#include <stdio.h>
+#include "PHY/defs_eNB.h"
+#include "PHY/TOOLS/dB_routines.h"
+
+extern int16_t hundred_times_delta_TF[100];
+extern uint16_t hundred_times_log10_NPRB[100];
+
+int16_t estimate_ue_tx_power(int norm,uint32_t tbs, uint32_t nb_rb, uint8_t control_only, int ncp, uint8_t use_srs)
+{
+
+  /// The payload + CRC size in bits, "B"
+  uint32_t B;
+  /// Number of code segments
+  uint32_t C;
+  /// Number of "small" code segments
+  uint32_t Cminus;
+  /// Number of "large" code segments
+  uint32_t Cplus;
+  /// Number of bits in "small" code segments (<6144)
+  uint32_t Kminus;
+  /// Number of bits in "large" code segments (<6144)
+  uint32_t Kplus;
+  /// Total number of bits across all segments
+  uint32_t sumKr;
+  /// Number of "Filler" bits
+  uint32_t F;
+  // num resource elements
+  uint32_t num_re=0.0;
+  // num symbols
+  uint32_t num_symb=0.0;
+  /// effective spectral efficiency of the PUSCH
+  uint32_t MPR_x100=0;
+  /// beta_offset
+  uint16_t beta_offset_pusch_x8=8;
+  /// delta mcs
+  float delta_mcs=0.0;
+  /// bandwidth factor
+  float bw_factor=0.0;
+
+  B= tbs+24;
+  lte_segmentation(NULL,
+                   NULL,
+                   B,
+                   &C,
+                   &Cplus,
+                   &Cminus,
+                   &Kplus,
+                   &Kminus,
+                   &F);
+
+
+  sumKr = Cminus*Kminus + Cplus*Kplus;
+  num_symb = 12-(ncp<<1)-(use_srs==0?0:1);
+  num_re = num_symb * nb_rb * 12;
+
+  if (num_re == 0)
+    return(0);
+
+  MPR_x100 = 100*sumKr/num_re;
+
+  if (control_only == 1 )
+    beta_offset_pusch_x8=8; // fixme
+
+  //(beta_offset_pusch_x8=ue->ulsch[eNB_id]->harq_processes[harq_pid]->control_only == 1) ? ue->ulsch[eNB_id]->beta_offset_cqi_times8:8;
+
+  // if deltamcs_enabledm
+  delta_mcs = ((hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch_x8)>>3))/100.0);
+                                                                                                                 
+  bw_factor = (norm!=0) ? 0 : (hundred_times_log10_NPRB[nb_rb-1]/100.0);
+  LOG_D(PHY,"estimated ue tx power %d (num_re %d, sumKr %d, mpr_x100 %d, delta_mcs %f, bw_factor %f)\n",
+         (int16_t)ceil(delta_mcs + bw_factor), num_re, sumKr, MPR_x100, delta_mcs, bw_factor);
+  return (int16_t)ceil(delta_mcs + bw_factor);
+
+}
+    
diff --git a/openair2/UTIL/TRACE/print.h b/common/utils/lte/ue_power.h
similarity index 71%
rename from openair2/UTIL/TRACE/print.h
rename to common/utils/lte/ue_power.h
index 72c43f20d473d51b20a842aa38ec3b3a80d2ae2b..caeebec2c8f01fabfb4362313e44649835f6a492 100644
--- a/openair2/UTIL/TRACE/print.h
+++ b/common/utils/lte/ue_power.h
@@ -19,14 +19,16 @@
  *      contact@openairinterface.org
  */
 
-/***************************************************************************
-                          print.h  -  description
-                             -------------------
-  AUTHOR  : Lionel GAUTHIER
-  COMPANY : EURECOM
-  EMAIL   : Lionel.Gauthier@eurecom.fr
- ***************************************************************************/
-#ifndef __PRINT_H__
-#    define __PRINT_H__
-#    define msg printf
-#endif
+/*! \file ue_power.h
+* \brief support routines used in MAC and PHY 
+* \author R. Knopp, F. Kaltenberger
+* \date 2020
+* \version 0.1
+* \company Eurecom
+* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
+* \note
+* \warning
+*/
+
+int16_t estimate_ue_tx_power(int norm,uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs);
+
diff --git a/common/utils/minimal_stub.c b/common/utils/minimal_stub.c
index 86454fe53f87dad750a11d7c0a1f07d67b5e5379..79e35bf7a6f8cef12bd29cb156711f5f67a884d6 100644
--- a/common/utils/minimal_stub.c
+++ b/common/utils/minimal_stub.c
@@ -1,4 +1,6 @@
+#ifndef T_TRACER
 int T_stdout;
+#endif
 
 void exit_function(const char *file, const char *function, const int line, const char *s) {
 }
diff --git a/common/utils/msc/msc.c b/common/utils/msc/msc.c
index 7cc5f79f90ef18e07dde08b626c2d3f8d50d4515..84b723b02286694f0837f7ac817c592e5e98f72c 100644
--- a/common/utils/msc/msc.c
+++ b/common/utils/msc/msc.c
@@ -52,6 +52,7 @@
 FILE    *g_msc_fd;
 char     g_msc_proto2str[MAX_MSC_PROTOS][MSC_MAX_PROTO_NAME_LENGTH];
 
+msc_interface_t msc_interface;
 
 typedef unsigned long msc_message_number_t;
 typedef struct msc_queue_item_s {
diff --git a/common/utils/msc/msc.h b/common/utils/msc/msc.h
index aab872cfe150607a06f6f19b2a23c435d57f82e3..adb0d9e657e5ef7a54ad433938d9c372ef225ec3 100644
--- a/common/utils/msc/msc.h
+++ b/common/utils/msc/msc.h
@@ -117,7 +117,7 @@ void msc_log_message(
 
 #define MESSAGE_CHART_GENERATOR  msc_interface.msc_loaded
 
-msc_interface_t msc_interface;
+extern msc_interface_t msc_interface;
 #define MSC_INIT(arg1,arg2)                                     if(msc_interface.msc_loaded) msc_interface.msc_init(arg1,arg2)
 #define MSC_START_USE                                           if(msc_interface.msc_loaded) msc_interface.msc_start_use
 #define MSC_END                                                 if(msc_interface.msc_loaded) msc_interface.msc_end
diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c
index 5f07fc00aa7ca7905552d5881b92a0ff39e1669b..9e4869035ab371acf483359bbbac6ae8832f0178 100644
--- a/common/utils/nr/nr_common.c
+++ b/common/utils/nr/nr_common.c
@@ -32,12 +32,85 @@
 
 #include <stdint.h>
 #include "assertions.h"
+#include "nr_common.h"
+
+// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101)
+// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
+// Notes:
+// - N_OFFs for bands from 80 to 89 and band 95 is referred to UL
+// - Frequencies are expressed in KHz
+// - col: NR_band ul_min  ul_max  dl_min  dl_max  step  N_OFFs_DL  deltaf_raster
+nr_bandentry_t nr_bandtable[] = {
+  {1,   1920000, 1980000, 2110000, 2170000, 20, 422000, 100},
+  {2,   1850000, 1910000, 1930000, 1990000, 20, 386000, 100},
+  {3,   1710000, 1785000, 1805000, 1880000, 20, 361000, 100},
+  {5,    824000,  849000,  869000,  894000, 20, 173800, 100},
+  {7,   2500000, 2570000, 2620000, 2690000, 20, 524000, 100},
+  {8,    880000,  915000,  925000,  960000, 20, 185000, 100},
+  {12,   698000,  716000,  729000,  746000, 20, 145800, 100},
+  {14,   788000,  798000,  758000,  768000, 20, 151600, 100},
+  {18,   815000,  830000,  860000,  875000, 20, 172000, 100},
+  {20,   832000,  862000,  791000,  821000, 20, 158200, 100},
+  {25,  1850000, 1915000, 1930000, 1995000, 20, 386000, 100},
+  {26,   814000,  849000,  859000,  894000, 20, 171800, 100},
+  {28,   703000,  758000,  758000,  813000, 20, 151600, 100},
+  {29,      000,     000,  717000,  728000, 20, 143400, 100},
+  {30,  2305000, 2315000, 2350000, 2360000, 20, 470000, 100},
+  {34,  2010000, 2025000, 2010000, 2025000, 20, 402000, 100},
+  {38,  2570000, 2620000, 2570000, 2630000, 20, 514000, 100},
+  {39,  1880000, 1920000, 1880000, 1920000, 20, 376000, 100},
+  {40,  2300000, 2400000, 2300000, 2400000, 20, 460000, 100},
+  {41,  2496000, 2690000, 2496000, 2690000,  3, 499200,  15},
+  {41,  2496000, 2690000, 2496000, 2690000,  6, 499200,  30},
+  {47,  5855000, 5925000, 5855000, 5925000,  1, 790334,  15},
+  //{48,  3550000, 3700000, 3550000, 3700000,  1, 636667,  15},
+  //{48,  3550000, 3700000, 3550000, 3700000,  2, 636668,  30},
+  {50,  1432000, 1517000, 1432000, 1517000, 20, 286400, 100},
+  {51,  1427000, 1432000, 1427000, 1432000, 20, 285400, 100},
+  {53,  2483500, 2495000, 2483500, 2495000, 20, 496700, 100},
+  {65,  1920000, 2010000, 2110000, 2200000, 20, 422000, 100},
+  {66,  1710000, 1780000, 2110000, 2200000, 20, 422000, 100},
+  {70,  1695000, 1710000, 1995000, 2020000, 20, 399000, 100},
+  {71,   663000,  698000,  617000,  652000, 20, 123400, 100},
+  {74,  1427000, 1470000, 1475000, 1518000, 20, 295000, 100},
+  {75,      000,     000, 1432000, 1517000, 20, 286400, 100},
+  {76,      000,     000, 1427000, 1432000, 20, 285400, 100},
+  {77,  3300000, 4200000, 3300000, 4200000,  1, 620000,  15},
+  {77,  3300000, 4200000, 3300000, 4200000,  2, 620000,  30},
+  {78,  3300000, 3800000, 3300000, 3800000,  1, 620000,  15},
+  {78,  3300000, 3800000, 3300000, 3800000,  2, 620000,  30},
+  {79,  4400010, 5000000, 4400010, 5000000,  1, 693334,  15},
+  {79,  4400010, 5000000, 4400010, 5000000,  2, 693334,  30},
+  {80,  1710000, 1785000,     000,     000, 20, 342000, 100},
+  {81,   880000,  915000,     000,     000, 20, 176000, 100},
+  {82,   832000,  862000,     000,     000, 20, 166400, 100},
+  {83,   703000,  748000,     000,     000, 20, 140600, 100},
+  {84,  1920000, 1980000,     000,     000, 20, 384000, 100},
+  {86,  1710000, 1785000,     000,     000, 20, 342000, 100},
+  {89,   824000,  849000,     000,     000, 20, 342000, 100},
+  {90,  2496000, 2690000, 2496000, 2690000, 3,  499200,  15},
+  {90,  2496000, 2690000, 2496000, 2690000, 6,  499200,  30},
+  {90,  2496000, 2690000, 2496000, 2690000, 20, 499200, 100},
+  {91,   832000,  862000, 1427000, 1432000, 20, 285400, 100},
+  {92,   832000,  862000, 1432000, 1517000, 20, 286400, 100},
+  {93,   880000,  915000, 1427000, 1432000, 20, 285400, 100},
+  {94,   880000,  915000, 1432000, 1517000, 20, 286400, 100},
+  {95,  2010000, 2025000,     000,     000, 20, 402000, 100},
+  {257,26500020,29500000,26500020,29500000,  1,2054166,  60},
+  {257,26500080,29500000,26500080,29500000,  2,2054167, 120},
+  {258,24250080,27500000,24250080,27500000,  1,2016667,  60},
+  {258,24250080,27500000,24250080,27500000,  2,2016667, 120},
+  {260,37000020,40000000,37000020,40000000,  1,2229166,  60},
+  {260,37000080,40000000,37000080,40000000,  2,2229167, 120},
+  {261,27500040,28350000,27500040,28350000,  1,2070833,  60},
+  {261,27500040,28350000,27500040,28350000,  2,2070833, 120}
+};
+
+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);
 
@@ -46,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);
 }
@@ -125,6 +196,26 @@ uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) {
   }
 }
 
+
+int get_dmrs_port(int nl, uint16_t dmrs_ports) {
+
+  if (dmrs_ports == 0) return 0; // dci 1_0
+  int p = -1;
+  int found = -1;
+  for (int i=0; i<12; i++) { // loop over dmrs ports
+    if((dmrs_ports>>i)&0x01) { // check if current bit is 1
+      found++;
+      if (found == nl) { // found antenna port number corresponding to current layer
+        p = i;
+        break;
+      }
+    }
+  }
+  AssertFatal(p>-1,"No dmrs port corresponding to layer %d found\n",nl);
+  return p;
+}
+
+
 int get_subband_size(int NPRB,int size) {
   // implements table  5.2.1.4-2 from 36.214
   //
diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h
index 5601c0fcbf8f5755b42fc484db8bbbd8ccdf6aa9..b95fdd50463fc450d518282ee9a8a757ebd1e693 100644
--- a/common/utils/nr/nr_common.h
+++ b/common/utils/nr/nr_common.h
@@ -36,6 +36,20 @@
 #include <stdint.h>
 #include "assertions.h"
 
+typedef struct nr_bandentry_s {
+  int16_t band;
+  uint64_t ul_min;
+  uint64_t ul_max;
+  uint64_t dl_min;
+  uint64_t dl_max;
+  uint64_t step_size;
+  uint64_t N_OFFs_DL;
+  uint8_t deltaf_raster;
+} nr_bandentry_t;
+
+extern const size_t nr_bandtable_size;
+extern nr_bandentry_t nr_bandtable[];
+
 int NRRIV2BW(int locationAndBandwidth,int N_RB);
 int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
 int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize);
@@ -48,7 +62,7 @@ uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx);
 uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx);
 int get_subband_size(int NPRB,int size);
 void SLIV2SL(int SLIV,int *S,int *L);
-
+int get_dmrs_port(int nl, uint16_t dmrs_ports);
 
 #define CEILIDIV(a,b) ((a+b-1)/b)
 #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp
index 2189be9fe8bfe34cdef4d6495fd0076ebc548d94..4e5323aec98c85d0c807ad195bbfa6ed4f022c8e 100644
--- a/common/utils/ocp_itti/intertask_interface.cpp
+++ b/common/utils/ocp_itti/intertask_interface.cpp
@@ -136,7 +136,7 @@ extern "C" {
       LOG_E(TMR,"Queue for %s task contains %ld messages\n", itti_get_task_name(destination_task_id), s );
 
     if ( s > 50 )
-      LOG_I(TMR,"Queue for %s task size: %ld\n",itti_get_task_name(destination_task_id), s+1);
+      LOG_I(TMR,"Queue for %s task size: %ld (last message %s)\n",itti_get_task_name(destination_task_id), s+1,ITTI_MSG_NAME(message));
 
     t->message_queue.insert(t->message_queue.begin(), message);
     eventfd_t sem_counter = 1;
@@ -339,7 +339,9 @@ extern "C" {
   int itti_create_queue(const task_info_t *taskInfo) {
     pthread_mutex_lock (&lock_nb_queues);
     int newQueue=nb_queues++;
-    AssertFatal(tasks=(task_list_t **) realloc(tasks, nb_queues * sizeof(*tasks)),"");
+    task_list_t **new_tasks = (task_list_t **)realloc(tasks, nb_queues * sizeof(*tasks));
+    AssertFatal(new_tasks != NULL, "could not realloc() tasks list");
+    tasks = new_tasks;
     tasks[newQueue]= new task_list_t;
     pthread_mutex_unlock (&lock_nb_queues);
     LOG_I(TMR,"Starting itti queue: %s as task %d\n", taskInfo->name, newQueue);
diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h
index 18a8f7868c29f48b08e55f9aa16a6b690c311e18..7c17a6f3b12fe9d060b8fb3a9053d7c922ead83f 100644
--- a/common/utils/ocp_itti/intertask_interface.h
+++ b/common/utils/ocp_itti/intertask_interface.h
@@ -340,11 +340,13 @@ void *rrc_enb_process_msg(void *);
   TASK_DEF(TASK_RAL_UE,   TASK_PRIORITY_MED,  200, NULL, NULL)  \
   TASK_DEF(TASK_MSC,      TASK_PRIORITY_MED,  200, NULL, NULL)\
   TASK_DEF(TASK_GTPV1_U,  TASK_PRIORITY_MED,  1000,NULL, NULL)\
+  TASK_DEF(OCP_GTPV1_U,  TASK_PRIORITY_MED,  1000,NULL, NULL)\
   TASK_DEF(TASK_UDP,      TASK_PRIORITY_MED,  1000, NULL, NULL)\
   TASK_DEF(TASK_CU_F1,    TASK_PRIORITY_MED,  200, NULL, NULL) \
   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 },
@@ -471,6 +473,9 @@ void itti_subscribe_event_fd(task_id_t task_id, int fd);
 void itti_unsubscribe_event_fd(task_id_t task_id, int fd);
 
 /** \brief Return the list of events excluding the fd associated with itti
+    \the fd associated with itti can return, but it is marked events[i].events &= ~EPOLLIN
+    \as it is not EPOLLIN, the reader should ignore this fd
+    \or it can manage the list of fd's in his interest, so ignore the other ones
     \param task_id Task ID of the task
     \param events events list
     @returns number of events to handle
diff --git a/common/utils/system.c b/common/utils/system.c
index 1bd5c7d39bc500d979bd8d258c8fa7dd16a52b95..d8b66c51d3210287bfe95fa8f6165d0a23539937 100644
--- a/common/utils/system.c
+++ b/common/utils/system.c
@@ -96,6 +96,54 @@ static void read_pipe(int p, char *b, int size) {
   }
 }
 
+static int baseRunTimeCommand(char* cmd, size_t cmdSize) {
+  FILE *fp;
+  size_t retSize = 0;
+
+  fp = popen(cmd, "r");
+  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;
+  }
+  return atoi(cmd);
+}
+
+int checkIfFedoraDistribution(void) {
+  char cmd[200];
+
+  memset(cmd, 0, 200);
+  sprintf(cmd, "cat /etc/os-release | grep ID_LIKE | grep -ic fedora || true");
+  return baseRunTimeCommand(cmd, 200);
+}
+
+int checkIfGenericKernelOnFedora(void) {
+  char cmd[200];
+
+  memset(cmd, 0, 200);
+  sprintf(cmd, "uname -a | grep -c rt || true");
+  return (1 - baseRunTimeCommand(cmd, 200));
+}
+
+int checkIfInsideContainer(void) {
+  char cmd[200];
+  int res = 0;
+
+  memset(cmd, 0, 200);
+  sprintf(cmd, "cat /proc/self/cgroup | egrep -c 'libpod|podman|kubepods' || true");
+  res = baseRunTimeCommand(cmd, 200);
+  if (res > 0)
+    return 1;
+  else
+    return 0;
+}
+
 /********************************************************************/
 /* background process                                               */
 /********************************************************************/
@@ -199,15 +247,41 @@ void start_background_system(void) {
 
 void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority){
   pthread_attr_t attr;
-  pthread_attr_init(&attr);
-  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-  pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
-  pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
-  struct sched_param sparam={0};
-  sparam.sched_priority = priority;
-  pthread_attr_setschedparam(&attr, &sparam);
+  int ret;
+  int settingPriority = 1;
+  ret=pthread_attr_init(&attr);
+  AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
+  ret=pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+  AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
+  ret=pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+  AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
+  if (checkIfFedoraDistribution())
+    if (checkIfGenericKernelOnFedora())
+      if (checkIfInsideContainer())
+        settingPriority = 0;
+
+  if (settingPriority) {
+    ret=pthread_attr_setschedpolicy(&attr, SCHED_OAI);
+    AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
+    if(priority<sched_get_priority_min(SCHED_OAI) || priority>sched_get_priority_max(SCHED_FIFO)) {
+      LOG_E(TMR,"Prio not possible: %d, min is %d, max: %d, forced in the range\n",
+                priority,
+                sched_get_priority_min(SCHED_OAI),
+                sched_get_priority_max(SCHED_OAI));
+      if(priority<sched_get_priority_min(SCHED_OAI))
+        priority=sched_get_priority_min(SCHED_OAI);
+      if(priority>sched_get_priority_max(SCHED_OAI))
+        priority=sched_get_priority_max(SCHED_OAI);
+    }
+    AssertFatal(priority<=sched_get_priority_max(SCHED_OAI),"");
+    struct sched_param sparam={0};
+    sparam.sched_priority = priority;
+    ret=pthread_attr_setschedparam(&attr, &sparam);
+    AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
+  }
 
-  pthread_create(t, &attr, func, param);
+  ret=pthread_create(t, &attr, func, param);
+  AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
 
   pthread_setname_np(*t, name);
   if (affinity != -1 ) {
@@ -216,7 +290,6 @@ void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name,
     CPU_SET(affinity, &cpuset);
     AssertFatal( pthread_setaffinity_np(*t, sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity");
   }
-
   pthread_attr_destroy(&attr);
 }
 
diff --git a/common/utils/system.h b/common/utils/system.h
index a89a6c5b1729f0b968fbfd4baed9cfd3cce85b10..c76fef9144a7c9cf64e78015046a020df416faf5 100644
--- a/common/utils/system.h
+++ b/common/utils/system.h
@@ -46,9 +46,11 @@ void set_latency_target(void);
 void configure_linux(void);
 
 void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority);
-#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_FIFO)
-#define OAI_PRIORITY_RT sched_get_priority_max(SCHED_FIFO)-10
-#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_FIFO)
+ 
+#define SCHED_OAI SCHED_RR
+#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_OAI)
+#define OAI_PRIORITY_RT ((sched_get_priority_min(SCHED_OAI)+sched_get_priority_max(SCHED_OAI))/2)
+#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_OAI)-2
 
 void thread_top_init(char *thread_name,
                      int affinity,
@@ -56,6 +58,14 @@ void thread_top_init(char *thread_name,
                      uint64_t deadline,
                      uint64_t period);
 
+/****************************************************
+ * Functions to check system at runtime.
+ ****************************************************/
+
+int checkIfFedoraDistribution(void);
+int checkIfGenericKernelOnFedora(void);
+int checkIfInsideContainer(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c
index 03f7af99bc2ca9cc8d81c7f834f7ad8dd2a2c7ce..734126721ad03a9141e87eb5eff10b79db202f4c 100644
--- a/common/utils/telnetsrv/telnetsrv.c
+++ b/common/utils/telnetsrv/telnetsrv.c
@@ -461,12 +461,12 @@ int process_command(char *buf) {
   int i,j,k;
   char modulename[TELNET_CMD_MAXSIZE];
   char cmd[TELNET_CMD_MAXSIZE];
-  char cmdb[TELNET_MAX_MSGLENGTH];
+  char *cmdb=NULL;
   char *bufbck;
   int rt;
   memset(modulename,0,sizeof(modulename));
   memset(cmd,0,sizeof(cmd));
-  memset(cmdb,0,sizeof(cmdb));
+  
 
   if (strncasecmp(buf,"ex",2) == 0)
     return CMDSTATUS_EXIT;
@@ -490,12 +490,10 @@ int process_command(char *buf) {
     return CMDSTATUS_FOUND;
   }
 
-  memset(modulename,0,sizeof(modulename));
-  memset(cmd,0,sizeof(cmd));
-  memset(cmdb,0,sizeof(cmdb));
+  
   bufbck=strdup(buf);
   rt=CMDSTATUS_NOTFOUND;
-  j = sscanf(buf,"%19s %19s %19[^\t\n]",modulename,cmd,cmdb);
+  j = sscanf(buf,"%19s %19s %m[^\t\n]",modulename,cmd,&cmdb);
 
   if (telnetparams.telnetdbg > 0)
     printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb);
@@ -562,7 +560,7 @@ int process_command(char *buf) {
       rt= CMDSTATUS_FOUND;
     } /* loop */
   } /* for i */
-
+  free(cmdb);
   free(bufbck);
   return rt;
 }
@@ -702,7 +700,7 @@ void poll_telnetcmdq(void *qid, void *arg) {
 */
 void exec_moduleinit(char *modname) {
   void (*fptr)(void);
-  char initfunc[TELNET_CMD_MAXSIZE+9];
+  char initfunc[TELNET_CMD_MAXSIZE+10];
 
   if (strlen(modname) > TELNET_CMD_MAXSIZE) {
     fprintf(stderr,"[TELNETSRV] module %s not loaded, name exceeds the %i size limit\n",
diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h
index b66641d5c8b9588b8699c93b31326b5a418f5252..59655501d3ed15f26037f18a649303e92141df1b 100644
--- a/common/utils/telnetsrv/telnetsrv.h
+++ b/common/utils/telnetsrv/telnetsrv.h
@@ -31,6 +31,7 @@
 #ifndef TELNETSRV_H
 #define TELNETSRV_H
 
+#include <common/ran_context.h> 
 #define TELNETSRV_MODNAME  "telnetsrv"
 
 #define TELNET_PORT               9090
diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h
index 5db1a5e34e6ca58a1b439977b26c9d1267ec867c..a32b7c38595bbfe83ce446d2eddf81de87e4d995 100644
--- a/common/utils/threadPool/thread-pool.h
+++ b/common/utils/threadPool/thread-pool.h
@@ -37,14 +37,21 @@
 #else
   #define THREADINIT   PTHREAD_MUTEX_INITIALIZER
 #endif
-#define mutexinit(mutex)   AssertFatal(pthread_mutex_init(&mutex,NULL)==0,"");
-#define condinit(signal)   AssertFatal(pthread_cond_init(&signal,NULL)==0,"");
-#define mutexlock(mutex)   AssertFatal(pthread_mutex_lock(&mutex)==0,"");
+#define mutexinit(mutex)   {int ret=pthread_mutex_init(&mutex,NULL); \
+                            AssertFatal(ret==0,"ret=%d\n",ret);}
+#define condinit(signal)   {int ret=pthread_cond_init(&signal,NULL); \
+                            AssertFatal(ret==0,"ret=%d\n",ret);}
+#define mutexlock(mutex)   {int ret=pthread_mutex_lock(&mutex); \
+                            AssertFatal(ret==0,"ret=%d\n",ret);}
 #define mutextrylock(mutex)   pthread_mutex_trylock(&mutex)
-#define mutexunlock(mutex) AssertFatal(pthread_mutex_unlock(&mutex)==0,"");
-#define condwait(condition, mutex) AssertFatal(pthread_cond_wait(&condition, &mutex)==0,"");
-#define condbroadcast(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,"");
-#define condsignal(signal)    AssertFatal(pthread_cond_broadcast(&signal)==0,"");
+#define mutexunlock(mutex) {int ret=pthread_mutex_unlock(&mutex); \
+                            AssertFatal(ret==0,"ret=%d\n",ret);}
+#define condwait(condition, mutex) {int ret=pthread_cond_wait(&condition, &mutex); \
+                                    AssertFatal(ret==0,"ret=%d\n",ret);}
+#define condbroadcast(signal) {int ret=pthread_cond_broadcast(&signal); \
+                               AssertFatal(ret==0,"ret=%d\n",ret);}
+#define condsignal(signal)    {int ret=pthread_cond_broadcast(&signal); \
+                               AssertFatal(ret==0,"ret=%d\n",ret);}
 #define tpool_nbthreads(tpool)   (tpool.nbThreads)
 typedef struct notifiedFIFO_elt_s {
   struct notifiedFIFO_elt_s *next;
@@ -78,7 +85,7 @@ static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size,
   ret->reponseFifo=reponseFifo;
   ret->processingFunc=processingFunc;
   // We set user data piece aligend 32 bytes to be able to process it with SIMD
-  ret->msgData=(void *)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32;
+  ret->msgData=(void *)((uint8_t*)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32);
   ret->malloced=true;
   return ret;
 }
diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md
index a087b989faddba2b8374721ea34d609d589444a7..f2422d98225c5d5e4ea9d2f4a84dbcfa6e93ccb1 100644
--- a/common/utils/threadPool/thread-pool.md
+++ b/common/utils/threadPool/thread-pool.md
@@ -210,8 +210,8 @@ time the worker finished the job
 time the client reads the result
 
 if you set the environement variable:
-thread-pool-measurements to a valid file name
+threadPoolMeasurements to a valid file name
 These measurements will be wrote to this Linux pipe.
 
-A tool to read the linux fifo and display it in ascii is provided:
-see the local directory Makefile for this tool and to compile the thread pool unitary tests.
+A tool to read the linux fifo and display it in ascii is provided; compute the binay:
+in cmake building directory: make/ninja measurement_display
diff --git a/common/utils/utils.h b/common/utils/utils.h
index da7c453b0375d25165350b0bb4bcd474e14a7579..16631586c413ec7532812da13f28ecd79dd7a9c1 100644
--- a/common/utils/utils.h
+++ b/common/utils/utils.h
@@ -7,6 +7,7 @@
 extern "C" {
 #endif
 
+#define sizeofArray(a) (sizeof(a)/sizeof(*(a)))
 void *calloc_or_fail(size_t size);
 void *malloc_or_fail(size_t size);
 
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/FEATURE_SET.md b/doc/FEATURE_SET.md
index 2171fc2f1fd567a655701ea92fa468d9f7c43919..c2f38332039e17d83739e815687fef28ff4593f2 100644
--- a/doc/FEATURE_SET.md
+++ b/doc/FEATURE_SET.md
@@ -257,7 +257,7 @@ The following features are valid for the gNB and the 5G-NR UE.
 *  FDD
 *  Normal CP
 *  30 kHz subcarrier spacing
-*  Bandwidths up to 80MHz (217 Physical Resource Blocks)
+*  Bandwidths: 10, 20, 40, 80, 100MHz (273 Physical Resource Blocks)
 *  Intermediate downlink and uplink frequencies to interface with IF equipment
 *  Single antenna port (single beam)
 *  Slot format: 14 OFDM symbols in UL or DL
@@ -277,10 +277,20 @@ The following features are valid for the gNB and the 5G-NR UE.
    - user-specific search space configured by RRC
    - DCI formats: 00, 10 (01 and 11 **under integration**)
 *  Generation of NR-PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
-   - Single symbol DMRS, DMRS-TypeA-Position Pos2,  DMRS configuration type 1
-   - PDSCH mapping type A
-*  NR-CSI Generation of sequence at PHY (**under integration**)
+   - PDSCH mapping type A and B
+   - DMRS configuration type 1 and 2
+   - Single and multiple DMRS symbols
+   - PTRS support
+   - Support for 1, 2 and 4 TX antennas
+   - Support for up to 2 layers (currently limited to DMRS configuration type 2)
+*  NR-CSIRS Generation of sequence at PHY
 *  NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
+   - PUSCH mapping type A and B
+   - DMRS configuration type 1 and 2
+   - Single and multiple DMRS symbols
+   - PTRS support
+   - Support for 1 RX antenna
+   - Support for 1 layer
 *  NR-PUCCH 
    - Format 0 (2 bits, mainly for ACK/NACK)
    - Format 2 (up to 64 bits, mainly for CSI feedback)
@@ -309,6 +319,7 @@ The following features are valid for the gNB and the 5G-NR UE.
 - MAC <-> PHY data interface using FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU
 - Scheduler procedures for SIB1
 - Scheduler procedures for RA
+- Scheduler procedures for CSI-RS
 - MAC downlink scheduler (fixed allocations)
 - MAC header generation (including timing advance)
 - ACK / NACK handling and HARQ procedures for downlink
@@ -320,27 +331,32 @@ The following features are valid for the gNB and the 5G-NR UE.
 - Creates TUN interface to PDCP to inject and receive user-place traffic
 - Will only work with OAI gNB configured in the same mode
 
-##  UE PHY Layer ##
+##  NR UE PHY Layer ##
 
 *  Initial synchronization
 *  Time tracking based on PBCH DMRS
-*  Time tracking based on PBCH DMRS
 *  Frequency offset estimation
-*  PBCH RX
-*  PDCCH RX
-*  PDSCH RX, including a first version of dual stream receiver for PDSCH  
 *  30KHz SCS for FR1 and 120 KHz SCS for FR2
-*  Generation of NR-PSS/NR-SSS
+*  Reception of NR-PSS/NR-SSS
 *  NR-PBCH supports multiple SSBs and flexible periodicity
-*  Generation of NR-PDCCH for SIB1 (including generation of DCI, polar encoding, scrambling, modulation, RB mapping, etc)
+*  Reception of NR-PDCCH for SIB1 (including reception of DCI, polar decoding, de-scrambling, de-modulation, RB de-mapping, etc)
    - common search space configured by MIB
    - user-specific search space configured by RRC
    - DCI formats: 00, 10 (01 and 11 **under integration**)
-*  Generation of NR-PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
-   - Single symbol DMRS, DMRS-TypeA-Position Pos2,  DMRS configuration type 1
-   - PDSCH mapping type A
-*  NR-CSI Generation of sequence at PHY (**under integration**)
+*  Reception of NR-PDSCH (including Segmentation, LDPC decoding, rate de-matching, de-scrambling, de-modulation, RB de-mapping, etc).
+   - PDSCH mapping type A and B
+   - DMRS configuration type 1 and 2
+   - Single and multiple DMRS symbols
+   - PTRS support
+   - Support for 1, 2 and 4 RX antennas
+   - Support for up to 2 layers (currently limited to DMRS configuration type 2)
 *  NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
+   - PUSCH mapping type A and B
+   - DMRS configuration type 1 and 2
+   - Single and multiple DMRS symbols
+   - PTRS support
+   - Support for 1 TX antenna
+   - Support for 1 layer
 *  NR-PUCCH 
    - Format 0 (2 bits, mainly for ACK/NACK)
    - Format 2 (up to 64 bits, mainly for CSI feedback)
@@ -351,7 +367,7 @@ The following features are valid for the gNB and the 5G-NR UE.
 *  Encoder and decoder for short block
 
 
-## UE Higher Layers ##
+## NR UE Higher Layers ##
 
 **UE MAC**
 *  Minimum system information (MSI)
diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md
index d13b193ff96fb7afc62a9ce7df8f7a9a26e9c9e0..dc7a982310bf1f0c4c929c7d1d9f79afc7409b68 100644
--- a/doc/RUNMODEM.md
+++ b/doc/RUNMODEM.md
@@ -132,23 +132,26 @@ With the RF simulator (on the same machine):
 
 `sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --do-ra --rfsim --parallel-config PARALLEL_SINGLE_THREAD`
 
-## sa setup with OAI
+## 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.
+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:
+- The RRC encodes SIB1 according to the configuration file and transmits it through NR-BCCH-DL-SCH.
 
-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 UE the --sa flag will:
+- 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
 
-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.
+### Run OAI in SA mode
 
 From the `cmake_targets/ran_build/build` folder:
 
@@ -158,17 +161,17 @@ 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
 
-The -C and -CO flags can be used together at UE side to set custom downlink and uplink FR1 intermediate frequencies for the IF equipment.
+The -C and --CO flags can be used together at UE side to set custom downlink and uplink FR1 arbitrary frequencies for the IF equipment.
 
 In order to run this setup, the following flags are needed at the UE side:
 
@@ -182,9 +185,11 @@ and the following parameters must be configured in the RUs section of the gNB co
 
 `if_offset`
 
-### Run OAI with custom DL/UL intermediate frequencies
+The values must be given in Hz.
 
-The following example uses DL frequency 2169.080 MHz and UL frequency offset -400 MHz, with a configuration file for band 66 at gNB side.
+### Run OAI with custom DL/UL arbitrary frequencies
+
+The following example uses DL frequency 2169.080 MHz and UL frequency offset -400 MHz, with a configuration file for band 66 (FDD) at gNB side.
 
 From the `cmake_targets/ran_build/build` folder:
 
diff --git a/doc/SW_archi.md b/doc/SW_archi.md
index d92f8021488fb30b6a2b3fb7d209fc733b92347d..e5856d63bc73ac1486b807236d9eea2aca66e34f 100644
--- a/doc/SW_archi.md
+++ b/doc/SW_archi.md
@@ -171,24 +171,31 @@ NR_sched_pusch_t (for values changing every TTI, e.g., frequency domain
 allocation) and NR_sched_pusch_save_t (for values changing less frequently, at
 least in FR1 [to my understanding], e.g., DMRS fields when the time domain
 allocation stays between TTIs) structures. Furthermore, the preprocessor is an
-exchangeable module that might schedule differently, e.g., one user for
-phytest, multiple users in FR1, or maybe FR2: phytest is in
-nr_ul_preprocessor_phytest(), for FR1 is nr_simple_ulsch_preprocessor() [under
-development], for FR2 does not exist yet.
+exchangeable module that schedules differently based on a particular
+use-case/deployment type, e.g., one user for phytest [in
+nr_ul_preprocessor_phytest()], multiple users in FR1
+[nr_fr1_ulsch_preprocessor()], or maybe FR2 [does not exist yet]:
 * calls preprocessor via pre_processor_ul(): the preprocessor is responsible
-  for allocating CCEs (using allocate_nr_CCEs()). Note that we do not yet have
-  scheduling requests or buffer status reports, and only one UE. E.g.,
-  nr_simple_ulsch_preprocessor():
+  for allocating CCEs (using allocate_nr_CCEs()) and deciding on resource
+  allocation for the UEs including TB size. Note that we do not yet have
+  scheduling requests. What it typically does:
   1)  check whether the current frame/slot plus K2 is an UL slot, and return if
       not.
   2)  Find first free start RB in vrb_map_UL, and as many free consecutive RBs
       as possible.
-  3)  allocate a CCE for the UE (and return if it is not possible)
-  4)  Calculate DMRS stuff (nr_save_pusch_fields()) and the TBS.
-  5)  Mark used resources in vrb_map_UL.
-* loop through all users: get a free HARQ PID and
-  update statistics. Fill nFAPI structures directly for PUSCH, and call
-  config_uldci() and fill_dci_pdu_rel15() for DCI filling and PDCCH messages.
+  3)  Either set up resource allocation directly (e.g., for a single UE,
+      phytest), or call into a function to perform actual resource allocation.
+      Currently, this is done using pf_ul() which implements a basic
+      proportional fair scheduler:
+      * for every UE, check for retransmission and allocate as necessary
+      * Calculate DMRS stuff (nr_set_pusch_semi_static())
+      * Calculate the PF coefficient and put eligible UEs into a list
+      * Allocate resources to the UE(s) with the highest coefficient
+  4)  Mark used resources in vrb_map_UL.
+* loop through all users: get a HARQ process as indicated through the
+  preprocessor, update statistics, fill nFAPI structures directly for PUSCH,
+  and call config_uldci() and fill_dci_pdu_rel15() for DCI filling and PDCCH
+  messages.
 
 Calls nr_schedule_ue_spec(). It is divided into the "preprocessor" and the
 "postprocessor": the first makes the scheduling decisions, the second fills
@@ -196,29 +203,28 @@ nFAPI structures to indicate to the PHY what it is supposed to do. To signal
 which users have how many resources, the preprocessor populates the
 NR_UE_sched_ctrl_t structure of affected users. In particular, the field rbSize
 decides whether a user is to be allocated. Furthermore, the preprocessor is an
-exchangeable module that might schedule differently, e.g., one user for
-phytest, multiple users in FR1, or maybe FR2: phytest is in
-nr_preprocessor_phytest(), for FR1 is nr_simple_dlsch_preprocessor() [under
-development], for FR2 does not exist yet.
+exchangeable module that schedules differently based on a particular
+use-case/deployment type, e.g., one user for phytest [in
+nr_preprocessor_phytest()], multiple users in FR1
+[nr_fr1_dlsch_preprocessor()], or maybe FR2 [does not exist yet].
 * calls preprocessor via pre_processor_dl(): the preprocessor is responsible
   for allocating CCEs and PUCCH (using allocate_nr_CCEs() and
   nr_acknack_scheduling()) and deciding on the frequency/time domain
-  allocation. E.g., nr_simple_dlsch_preprocessor():
-  1)  mac_rlc_status_ind() locks and checks directly inside rlc data the
-      quantity of waiting data.
-  2)  return from the preprocessor if there is no data and no timing advance to
-      send,
-  3)  otherwise, allocate a CCE for the UE (and return if it is not possible)
-  4)  find a PUCCH occasion for HARQ
-  5a) check if there is a retransmission: if yes, find free resources to
-      transmit using the same resources, else
-  5b) calculate the necessary RBs needed to get a TBS large enough to hold all
-      data, or until no more resources are available
-  6)  Mark taken resources in the vrb_map
+  allocation including the TB size. What it typically does:
+  1)  Check available resources in the vrb_map
+  2)  Checks the quantity of waiting data in RLC
+  3)  Either set up resource allocation directly (e.g., for a single UE,
+      phytest), or call into a function to perform actual resource allocation.
+      Currently, this is done using pf_dl() which implements a basic
+      proportional fair scheduler:
+      * for every UE, check for retransmission and allocate as necessary
+      * Calculate the PF coefficient and put eligible UEs into a list
+      * Allocate resources to the UE(s) with the highest coefficient
+  4)  Mark taken resources in the vrb_map
 * loop through all users: check if a new TA is necessary. Then, if a user has
-  allocated resources, compute its TBS, and fill nFAPI structures
-  (nr_fill_nfapi_dl_pdu() to populate what should be done by the lower layers
-  to make the Tx subframe). Update statistics (round, sent bytes).
+  allocated resources, update statistics (round, sent bytes), update HARQ
+  process information, and fill nFAPI structures (allocate a DCI and PDCCH
+  messages, TX_req, ...)
 
 # RRC
 RRC is a regular thread with itti loop on queue: TASK_RRC_GNB
@@ -296,6 +302,28 @@ gtp thread calls directly pdcp_data_req(), so it runs inside it's context intern
 ## inside other threads
 gtpv1u_create_s1u_tunnel(), delete tunnel, ... functions are called inside the other threads, without mutex.
 
+# New GTP
+## initialization
+Coexistance until full merge with legacy GTP
+cmake new option: NEW_GTPU to use the new implementation (it changes for the entire executable)
+It is possible to use both old and new GTP in same executable because the itti task and all functions names are different 
+Current status of new implementation: not tested, X2 not developped, 5G new GTP option not developped, remain issues on data coming from void: muid, enb_flag, ...
+
+ocp_gtpv1uTask(): this creates only the thread, doesn't configure anything
+gtpv1Init(): creates a listening socket to Linux for a given reception and select a local IP address
+
+newGtpuCreateTunnel() this function will replace the xxx_create_tunnel_xxx() for various cases
+This creates a outgoing context for a teid (in input), it computes and return the incoming teid that will be used for incoming packets
+These teids and in a "instance", so in a Linux socket: same teid can co-exist for different sockets
+ Remain here a lack to fill: the information given in the legacy funtions is not enough to fullfil the data needed by the callback
+stuff like enb_flag, but also mui and more important data are not given explicitly by any legacy function (gtpv1u_create_s1u_tunnel), but the legacy and the new interface to lower layer (like pdcp) require this data.
+The datamodel is still not fully understood, so this data source remain unknown
+A new parameter is the callback function: will be pdpcp_data_req() and gtpv_data_req() (x2 case) for existing implementation and later other call backs like the F1-U implementation.
+
+incoming packets
+the gtp layer retrieves the data, the teid, find out the related data: rnti, bearer and quite a lot of other parameters (not clear why, because it looks like all is statefull, so the lower layer should have the context) 
+if lower layers can be stateless, it is a good idea to keep the context in the gtp layer and pass it to the callback, but the design remain obfuscated.
+
 # NGAP
 NGAP would be a itti thread as is S1AP (+twin thread SCTP that is almost void processing)?  
 About all messages are exchanged with RRC thread  
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.md b/doc/TESTING_GNB_W_COTS_UE.md
index 73ae18351f2f1458a687ea41408321c3cc36180f..84f43bfc27d04123a9f49ca2c18d574ddc5fadc7 100644
--- a/doc/TESTING_GNB_W_COTS_UE.md
+++ b/doc/TESTING_GNB_W_COTS_UE.md
@@ -44,10 +44,12 @@ Our code might not work with all 5G phones yet, but we are constantly improving
 
 *  Oppo Reno 5G
 *  Samsung A90 5G
-*  Google Pixel 5G
+*  Samsung A42 5G
+*  Google Pixel 5G (note1)
 *  Simcom SIMCOM8200EA 
 *  Quectel RM500Q-GL
 
+Note1: In the version we have at Eurecom, you need to set the PLMN to 50501, and you also need to change the firmware to "11.0.0 (RD1A.201105.003.B1, Nov 2020, EU carriers)" (see https://developers.google.com/android/images)
 
 ## Repository
 
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/docker/Dockerfile.eNB.rhel8.2 b/docker/Dockerfile.eNB.rhel8.2
index 5fcd5a7b9f07d041f66d3aa92dca8a3c72c57c83..90c807fc0e3b0719ed52daad370d465e3a84d7e7 100644
--- a/docker/Dockerfile.eNB.rhel8.2
+++ b/docker/Dockerfile.eNB.rhel8.2
@@ -25,21 +25,19 @@
 #
 #---------------------------------------------------------------------
 
-FROM localhost/ran-build:latest AS enb-build 
+FROM ran-build:latest AS enb-build
 
+RUN rm -Rf /oai-ran
 WORKDIR /oai-ran
+COPY . .
 
 #run build_oai to build the target image
 RUN /bin/sh oaienv && \ 
     cd cmake_targets && \
-    rm -Rf log && \
     mkdir -p log && \
-    ./build_oai --eNB --ninja -w USRP
+    ./build_oai --eNB --ninja -w USRP --verbose-ci
 
-# debug
-#RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-softmodem.Rel15
-#RUN ls -ls /oai-ran/targets/bin
-#RUN ls -ls /oai-ran/cmake_targets/ran_build/build/*.so
+RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/enb_parameters.yaml
 
 #start from scratch for target executable
 FROM registry.access.redhat.com/ubi8/ubi:latest as oai-enb
@@ -48,6 +46,7 @@ RUN yum update -y && \
     yum install -y --enablerepo="ubi-8-codeready-builder" \
         lksctp-tools \
         nettle \
+        procps-ng \
         atlas \
         net-tools \
         iputils \
@@ -58,6 +57,7 @@ RUN yum update -y && \
 
 WORKDIR /opt/oai-enb/bin
 COPY --from=enb-build /oai-ran/targets/bin/lte-softmodem.Rel15 .
+COPY --from=enb-build /oai-ran/docker/scripts/enb_entrypoint.sh entrypoint.sh
 
 WORKDIR /usr/local/lib/
 COPY --from=enb-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 .
@@ -92,34 +92,16 @@ COPY --from=enb-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64
 
 RUN ldconfig
 
-#debug
-#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15
-#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15
-#RUN ldd /usr/local/lib/librfsimulator.so.Rel15
-#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15
-#RUN ldd /usr/local/lib/libcoding.so
-#RUN ldd /usr/local/lib/libparams_libconfig.so
-#RUN ldd /usr/local/lib/libdfts.so
-#RUN ldd /usr/local/lib/liboai_iqplayer.so
-#RUN ldd /opt/oai-enb/bin/lte-softmodem.Rel15
-
 # Copy the relevant configuration files for eNB
 WORKDIR /opt/oai-enb/etc
-COPY --from=enb-build /oai-ran/ci-scripts/conf_files/enb.* .
-COPY --from=enb-build /oai-ran/ci-scripts/conf_files/rcc.* .
-COPY --from=enb-build /oai-ran/ci-scripts/conf_files/cu.* .
-COPY --from=enb-build /oai-ran/ci-scripts/conf_files/du.* .
-COPY --from=enb-build /oai-ran/ci-scripts/conf_files/rru.* .
+COPY --from=enb-build /oai-ran/docker/etc .
 
 WORKDIR /opt/oai-enb
 
-#EXPOSE 2152/udp  # S1U, GTP/UDP
-#EXPOSE 22100/tcp # ?
-#EXPOSE 36412/udp # S1C, SCTP/UDP
-#EXPOSE 36422/udp # X2C, SCTP/UDP
-#EXPOSE 50000/udp # IF5 / ORI (control)
-#EXPOSE 50001/udp # IF5 / ECPRI (data)
+# 2152 --> S1U, GTP/UDP
+# 36412 --> S1C, SCTP/UDP
+# 36422 --> X2C, SCTP/UDP
+EXPOSE 2152/udp 36412/udp 36422/udp
 
-#CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"]
-#ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"]
-CMD ["sleep", "infinity"]
+ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"]
+CMD ["/opt/oai-enb/bin/lte-softmodem.Rel15", "-O", "/opt/oai-enb/etc/enb.conf"]
diff --git a/docker/Dockerfile.eNB.ubuntu18 b/docker/Dockerfile.eNB.ubuntu18
index cdfb37ebfc343637e2bfbdce2ff3d2f0f147a09c..c4393dc78e6b16f027d9d760bfb3821d388eed52 100644
--- a/docker/Dockerfile.eNB.ubuntu18
+++ b/docker/Dockerfile.eNB.ubuntu18
@@ -27,23 +27,17 @@
 
 FROM ran-build:latest AS enb-build 
 
+RUN rm -Rf /oai-ran
 WORKDIR /oai-ran
+COPY . .
 
 #run build_oai to build the target image
 RUN /bin/sh oaienv && \ 
     cd cmake_targets && \
-    rm -Rf log && \
     mkdir -p log && \
-    ./build_oai --eNB --ninja -w USRP
+    ./build_oai --eNB --ninja -w USRP --verbose-ci
 
-RUN apt-get install -y python3-pip && \
-    pip3 install --ignore-installed pyyaml && \
-    python3 ./docker/scripts/generateTemplate.py ./docker/scripts/enb_parameters.yaml
-
-# debug
-#RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-softmodem.Rel15
-#RUN ls -ls /oai-ran/targets/bin
-#RUN ls -ls /oai-ran/cmake_targets/ran_build/build/*.so
+RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/enb_parameters.yaml
 
 #start from scratch for target executable
 FROM ubuntu:bionic as oai-enb
@@ -55,6 +49,7 @@ RUN apt-get update && \
     DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
     DEBIAN_FRONTEND=noninteractive apt-get install --yes \
         software-properties-common \
+        procps \
         libsctp1 \
         libnettle6 \
         libblas3 \
@@ -64,6 +59,7 @@ RUN apt-get update && \
         net-tools \
         iputils-ping \
         iproute2 \
+        iperf \
         libyaml-0-2 && \
     # Install UHD driver from ettus ppa 
     # At time of writing, it is 3.14
@@ -97,17 +93,6 @@ COPY --from=enb-build /usr/local/lib/libprotobuf-c.so.1 .
 
 RUN ldconfig
 
-#debug
-#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15
-#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15
-#RUN ldd /usr/local/lib/librfsimulator.so.Rel15
-#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15
-#RUN ldd /usr/local/lib/libcoding.so
-#RUN ldd /usr/local/lib/libparams_libconfig.so
-#RUN ldd /usr/local/lib/libdfts.so
-#RUN ldd /usr/local/lib/liboai_iqplayer.so
-#RUN ldd /opt/oai-enb/bin/lte-softmodem.Rel15
-
 # Copy the relevant configuration files for eNB
 WORKDIR /opt/oai-enb/etc
 COPY --from=enb-build /oai-ran/docker/etc .
diff --git a/docker/Dockerfile.gNB.rhel8.2 b/docker/Dockerfile.gNB.rhel8.2
index fb9ade927f8db1a1c7d559b3ddb26db4cb6af8df..9ee0bf9ae9d52683895b6940909858c0b0df8696 100644
--- a/docker/Dockerfile.gNB.rhel8.2
+++ b/docker/Dockerfile.gNB.rhel8.2
@@ -25,22 +25,19 @@
 #
 #---------------------------------------------------------------------
 
-FROM localhost/ran-build:latest AS gnb-build 
+FROM ran-build:latest AS gnb-build
 
+RUN rm -Rf /oai-ran
 WORKDIR /oai-ran
+COPY . .
 
 #run build_oai to build the target image
 RUN /bin/sh oaienv && \ 
     cd cmake_targets && \
-    rm -Rf log && \
     mkdir -p log && \
-    ./build_oai --gNB --ninja -w USRP
+    ./build_oai --gNB --ninja -w USRP --verbose-ci
 
-#debug
-#RUN ldconfig -v
-#RUN ldd /oai-ran/targets/bin/nr-softmodem.Rel15
-#RUN ls -lst /oai-ran/targets/bin
-#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so
+RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/gnb_parameters.yaml
 
 #start from scratch for target executable
 FROM registry.access.redhat.com/ubi8/ubi:latest as oai-gnb
@@ -48,6 +45,7 @@ FROM registry.access.redhat.com/ubi8/ubi:latest as oai-gnb
 RUN yum repolist --disablerepo=* && \
     yum update -y && \
     yum install -y --enablerepo="ubi-8-codeready-builder" \
+        procps-ng \
         libXpm \
         libX11 \
         atlas \
@@ -61,6 +59,7 @@ RUN yum repolist --disablerepo=* && \
 
 WORKDIR /opt/oai-gnb/bin
 COPY --from=gnb-build /oai-ran/targets/bin/nr-softmodem.Rel15 .
+COPY --from=gnb-build /oai-ran/docker/scripts/gnb_entrypoint.sh entrypoint.sh
 
 WORKDIR /usr/local/lib/
 COPY --from=gnb-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 .
@@ -98,23 +97,10 @@ COPY --from=gnb-build /lib64/libboost_timer.so.1.66.0 /lib64
 COPY --from=gnb-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64
 
 RUN ldconfig
-#debug
-#RUN ldd /opt/oai-gnb/bin/nr-softmodem.Rel15
-#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15
-#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15
-#RUN ldd /usr/local/lib/librfsimulator.so.Rel15
-#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15
-#RUN ldd /usr/local/lib/libcoding.so
-#RUN ldd /usr/local/lib/libparams_libconfig.so
-#RUN ldd /usr/local/lib/libdfts.so
-#RUN ldd /usr/local/lib/libldpc.so
-#RUN ldd /usr/local/lib/libldpc_optim.so
-#RUN ldd /usr/local/lib/libldpc_optim8seg.so
-#RUN ldd /usr/local/lib/libldpc_orig.so
 
 # Copy the relevant configuration files for gNB
 WORKDIR /opt/oai-gnb/etc
-COPY --from=gnb-build /oai-ran/ci-scripts/conf_files/gnb.* .
+COPY --from=gnb-build /oai-ran/docker/etc .
 
 WORKDIR /opt/oai-gnb
 #EXPOSE 2152/udp  # S1U, GTP/UDP
@@ -124,6 +110,5 @@ WORKDIR /opt/oai-gnb
 #EXPOSE 50000/udp # IF5 / ORI (control)
 #EXPOSE 50001/udp # IF5 / ECPRI (data)
 
-#CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"]
-#ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"]
-CMD ["sleep", "infinity"]
+ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"]
+CMD ["/opt/oai-gnb/bin/nr-softmodem.Rel15", "-O", "/opt/oai-gnb/etc/gnb.conf"]
diff --git a/docker/Dockerfile.gNB.ubuntu18 b/docker/Dockerfile.gNB.ubuntu18
index d43ad4709dbedcef7c76861cc2677a38c95dc8d4..990c4363e5b98aad04ee852826937807b8883487 100644
--- a/docker/Dockerfile.gNB.ubuntu18
+++ b/docker/Dockerfile.gNB.ubuntu18
@@ -25,34 +25,32 @@
 #
 #---------------------------------------------------------------------
 
-FROM ran-build:latest AS gnb-build 
+FROM ran-build:latest AS gnb-build
 
+RUN rm -Rf /oai-ran
 WORKDIR /oai-ran
+COPY . .
 
 #run build_oai to build the target image
 RUN /bin/sh oaienv && \ 
     cd cmake_targets && \
-    rm -Rf log && \
     mkdir -p log && \
-    ./build_oai --gNB --ninja -w USRP
+    ./build_oai --gNB --ninja -w USRP --verbose-ci
 
-#debug
-RUN ldconfig -v
-RUN ldd /oai-ran/targets/bin/nr-softmodem.Rel15
-RUN ls -lst /oai-ran/targets/bin
-RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so
+RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/gnb_parameters.yaml
 
 #start from scratch for target executable
 FROM ubuntu:bionic as oai-gnb
 ENV DEBIAN_FRONTEND=noninteractive
 ENV TZ=Europe
-RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
 
 RUN apt-get update && \
     DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
     DEBIAN_FRONTEND=noninteractive apt-get install --yes \
         software-properties-common \
+        procps \
         libsctp1 \
+        tzdata \
         libnettle6 \
         libblas3 \
         libatlas3-base \
@@ -75,6 +73,7 @@ RUN apt-get update && \
 
 WORKDIR /opt/oai-gnb/bin
 COPY --from=gnb-build /oai-ran/targets/bin/nr-softmodem.Rel15 .
+COPY --from=gnb-build /oai-ran/docker/scripts/gnb_entrypoint.sh entrypoint.sh
 
 WORKDIR /usr/local/lib/
 COPY --from=gnb-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 .
@@ -95,23 +94,10 @@ RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/li
 COPY --from=gnb-build /usr/local/lib/libprotobuf-c.so.1 .
 
 RUN ldconfig
-#debug
-#RUN ldd /opt/oai-gnb/bin/nr-softmodem.Rel15
-#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15
-#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15
-#RUN ldd /usr/local/lib/librfsimulator.so.Rel15
-#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15
-#RUN ldd /usr/local/lib/libcoding.so
-#RUN ldd /usr/local/lib/libparams_libconfig.so
-#RUN ldd /usr/local/lib/libdfts.so
-#RUN ldd /usr/local/lib/libldpc.so
-#RUN ldd /usr/local/lib/libldpc_optim.so
-#RUN ldd /usr/local/lib/libldpc_optim8seg.so
-#RUN ldd /usr/local/lib/libldpc_orig.so
 
 # Copy the relevant configuration files for gNB
 WORKDIR /opt/oai-gnb/etc
-COPY --from=gnb-build /oai-ran/ci-scripts/conf_files/gnb.* ./
+COPY --from=gnb-build /oai-ran/docker/etc .
 
 WORKDIR /opt/oai-gnb
 #EXPOSE 2152/udp  # S1U, GTP/UDP
@@ -121,6 +107,5 @@ WORKDIR /opt/oai-gnb
 #EXPOSE 50000/udp # IF5 / ORI (control)
 #EXPOSE 50001/udp # IF5 / ECPRI (data)
 
-#CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"]
-#ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"]
-CMD ["sleep", "infinity"]
+ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"]
+CMD ["/opt/oai-gnb/bin/nr-softmodem.Rel15", "-O", "/opt/oai-gnb/etc/gnb.conf"]
diff --git a/docker/Dockerfile.lteRU.rhel8.2 b/docker/Dockerfile.lteRU.rhel8.2
new file mode 100644
index 0000000000000000000000000000000000000000..314c01dff39eb3d46014216ad947929172915bd3
--- /dev/null
+++ b/docker/Dockerfile.lteRU.rhel8.2
@@ -0,0 +1,98 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+# Dockerfile for the Open-Air-Interface BUILD service
+#   Valid for RHEL8
+#
+#---------------------------------------------------------------------
+
+FROM ran-build:latest AS ru-build
+
+RUN rm -Rf /oai-ran
+WORKDIR /oai-ran
+COPY . .
+
+#run build_oai to build the target image
+RUN /bin/sh oaienv && \
+    cd cmake_targets && \
+    mkdir -p log && \
+    ./build_oai --RU --ninja -w USRP --verbose-ci
+
+RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/enb_parameters.yaml
+
+#start from scratch for target executable
+FROM registry.access.redhat.com/ubi8/ubi:latest as oai-lte-ru
+ENV TZ=Europe/Paris
+
+RUN yum update -y && \
+    yum install -y --enablerepo="ubi-8-codeready-builder" \
+        tzdata \
+        procps-ng \
+        atlas \
+        net-tools \
+        iputils \
+        iproute && \
+    echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \
+    echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf
+
+WORKDIR /opt/oai-lte-ru/bin
+COPY --from=ru-build /oai-ran/targets/bin/oairu.Rel15 .
+COPY --from=ru-build /oai-ran/docker/scripts/lte_ru_entrypoint.sh entrypoint.sh
+
+WORKDIR /usr/local/lib/
+COPY --from=ru-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 .
+COPY --from=ru-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 .
+COPY --from=ru-build /oai-ran/targets/bin/librfsimulator.so.Rel15 .
+COPY --from=ru-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 .
+COPY --from=ru-build /oai-ran/targets/bin/libparams_libconfig.so .
+COPY --from=ru-build /oai-ran/cmake_targets/ran_build/build/libdfts.so .
+
+# Copying from the ran-build image the USRP needed packages
+COPY --from=ru-build /lib64/libconfig.so.9 /lib64
+COPY --from=ru-build /lib64/libblas.so.3 /lib64
+COPY --from=ru-build /lib64/liblapack.so.3 /lib64
+COPY --from=ru-build /lib64/liblapacke.so.3 /lib64
+COPY --from=ru-build /lib64/libboost_chrono.so.1.66.0 /lib64
+COPY --from=ru-build /lib64/libboost_date_time.so.1.66.0 /lib64
+COPY --from=ru-build /lib64/libboost_filesystem.so.1.66.0 /lib64
+COPY --from=ru-build /lib64/libboost_program_options.so.1.66.0 /lib64
+COPY --from=ru-build /lib64/libboost_serialization.so.1.66.0 /lib64
+COPY --from=ru-build /lib64/libboost_thread.so.1.66.0 /lib64
+COPY --from=ru-build /lib64/libboost_system.so.1.66.0 /lib64
+COPY --from=ru-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64
+COPY --from=ru-build /lib64/libboost_atomic.so.1.66.0 /lib64
+COPY --from=ru-build /lib64/libboost_timer.so.1.66.0 /lib64
+COPY --from=ru-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64
+
+RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" && \
+    /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" && \
+    /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" && \
+    ldconfig
+
+# Copy the relevant configuration files for RRU
+WORKDIR /opt/oai-lte-ru/etc
+COPY --from=ru-build /oai-ran/docker/etc/rru* ./
+
+WORKDIR /opt/oai-lte-ru
+
+ENTRYPOINT ["/opt/oai-lte-ru/bin/entrypoint.sh"]
+CMD ["/opt/oai-lte-ru/bin/oairu.Rel15", "-O", "/opt/oai-lte-ru/etc/rru.conf"]
diff --git a/docker/Dockerfile.lteRU.ubuntu18 b/docker/Dockerfile.lteRU.ubuntu18
new file mode 100644
index 0000000000000000000000000000000000000000..fa99827d942ca3e9e5e566acbb75860fd14f5554
--- /dev/null
+++ b/docker/Dockerfile.lteRU.ubuntu18
@@ -0,0 +1,93 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+# Dockerfile for the Open-Air-Interface BUILD service
+#   Valid for Ubuntu 18.04
+#
+#---------------------------------------------------------------------
+
+FROM ran-build:latest AS ru-build
+
+RUN rm -Rf /oai-ran
+WORKDIR /oai-ran
+COPY . .
+
+#run build_oai to build the target image
+RUN /bin/sh oaienv && \
+    cd cmake_targets && \
+    mkdir -p log && \
+    ./build_oai --RU --ninja -w USRP --verbose-ci
+
+RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/enb_parameters.yaml
+
+#start from scratch for target executable
+FROM ubuntu:bionic as oai-lte-ru
+ENV DEBIAN_FRONTEND=noninteractive
+ENV TZ=Europe/Paris
+
+RUN apt-get update && \
+    DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
+    DEBIAN_FRONTEND=noninteractive apt-get install --yes \
+        tzdata \
+        procps \
+        software-properties-common \
+        libblas3 \
+        libatlas3-base \
+        libconfig9 \
+        net-tools \
+        iputils-ping \
+        iproute2 && \
+    # Install UHD driver from ettus ppa
+    # At time of writing, it is 3.14
+    add-apt-repository ppa:ettusresearch/uhd --yes && \
+    apt-get update && \
+    DEBIAN_FRONTEND=noninteractive apt-get install --yes \
+        python \
+        libusb-1.0-0 \
+        libuhd003 \
+        uhd-host && \
+    rm -rf /var/lib/apt/lists/*
+
+WORKDIR /opt/oai-lte-ru/bin
+COPY --from=ru-build /oai-ran/targets/bin/oairu.Rel15 .
+COPY --from=ru-build /oai-ran/docker/scripts/lte_ru_entrypoint.sh entrypoint.sh
+
+WORKDIR /usr/local/lib/
+COPY --from=ru-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 .
+COPY --from=ru-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 .
+COPY --from=ru-build /oai-ran/targets/bin/librfsimulator.so.Rel15 .
+COPY --from=ru-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 .
+COPY --from=ru-build /oai-ran/targets/bin/libparams_libconfig.so .
+COPY --from=ru-build /oai-ran/cmake_targets/ran_build/build/libdfts.so .
+RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" && \
+    /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" && \
+    /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" && \
+    ldconfig
+
+# Copy the relevant configuration files for RRU
+WORKDIR /opt/oai-lte-ru/etc
+COPY --from=ru-build /oai-ran/docker/etc/rru* ./
+
+WORKDIR /opt/oai-lte-ru
+
+ENTRYPOINT ["/opt/oai-lte-ru/bin/entrypoint.sh"]
+CMD ["/opt/oai-lte-ru/bin/oairu.Rel15", "-O", "/opt/oai-lte-ru/etc/rru.conf"]
diff --git a/docker/Dockerfile.lteUE.rhel8.2 b/docker/Dockerfile.lteUE.rhel8.2
index 0a853dcd6b5dc211a730cf0a82f074e9118eea61..2d540876e34961e57414535b9784f8ebb1e64822 100644
--- a/docker/Dockerfile.lteUE.rhel8.2
+++ b/docker/Dockerfile.lteUE.rhel8.2
@@ -25,22 +25,22 @@
 #
 #---------------------------------------------------------------------
 
-FROM localhost/ran-build:latest AS lte-ue-build 
-
+FROM ran-build:latest AS lte-ue-build
 
+RUN rm -Rf /oai-ran
 WORKDIR /oai-ran
+COPY . .
 
 #run build_oai to build the target image
 RUN /bin/sh oaienv && \ 
     cd cmake_targets && \
-    rm -Rf log && \
     mkdir -p log && \
-    ./build_oai --UE --ninja -w USRP
+    ./build_oai --UE --ninja -w USRP --verbose-ci
 
-# debug
-#RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-uesoftmodem.Rel15
-#RUN ls -lst /oai-ran/targets/bin
-#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so
+RUN yum install -y python3-pip && \
+    pip3 install --ignore-installed pyyaml && \
+    python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_parameters.yaml && \
+    python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_sim_parameters.yaml
 
 #start from scratch for target executable
 FROM registry.access.redhat.com/ubi8/ubi:latest as oai-lte-ue
@@ -48,6 +48,7 @@ FROM registry.access.redhat.com/ubi8/ubi:latest as oai-lte-ue
 RUN yum update -y && \
     yum install -y --enablerepo="ubi-8-codeready-builder" \
         lksctp-tools \
+        procps-ng \
         nettle \
         atlas \
         iproute \
@@ -59,12 +60,10 @@ RUN yum update -y && \
 
 WORKDIR /opt/oai-lte-ue/bin
 COPY --from=lte-ue-build /oai-ran/targets/bin/lte-uesoftmodem.Rel15 .
+COPY --from=lte-ue-build /oai-ran/docker/scripts/lte_ue_entrypoint.sh entrypoint.sh
 COPY --from=lte-ue-build /oai-ran/targets/bin/conf2uedata .
 COPY --from=lte-ue-build /oai-ran/targets/bin/nvram .
 COPY --from=lte-ue-build /oai-ran/targets/bin/usim .
-COPY --from=lte-ue-build /oai-ran/targets/bin/.ue_emm.nvram0 .
-COPY --from=lte-ue-build /oai-ran/targets/bin/.ue.nvram0 .
-COPY --from=lte-ue-build /oai-ran/targets/bin/.usim.nvram0 .
 
 WORKDIR /usr/local/lib/
 COPY --from=lte-ue-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 .
@@ -99,26 +98,10 @@ COPY --from=lte-ue-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64
 
 RUN ldconfig
 
-#debug
-#RUN ldd /opt/oai-lte-ue/bin/lte-uesoftmodem.Rel15
-#RUN ldd /opt/oai-lte-ue/bin/conf2uedata
-#RUN ldd /opt/oai-lte-ue/bin/nvram
-#RUN ldd /opt/oai-lte-ue/bin/usim
-#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15
-#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15
-#RUN ldd /usr/local/lib/librfsimulator.so.Rel15
-#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15
-#RUN ldd /usr/local/lib/libcoding.so
-#RUN ldd /usr/local/lib/libparams_libconfig.so
-#RUN ldd /usr/local/lib/libSIMU.so
-#RUN ldd /usr/local/lib/libdfts.so
-
-# Copy the relevant configuration files for eNB
+# Copy the relevant configuration files for UE
 WORKDIR /opt/oai-lte-ue/etc
-COPY --from=lte-ue-build /oai-ran/ci-scripts/conf_files/ue.* .
-COPY --from=lte-ue-build /oai-ran/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf ./ue_usim.conf
+COPY --from=lte-ue-build /oai-ran/docker/etc .
 
 WORKDIR /opt/oai-lte-ue
-#CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem", "-O", "/opt/oai-lte-ue/etc/enb.conf"]
-#ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"]
-CMD ["sleep", "infinity"]
+CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem.Rel15"]
+ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"]
diff --git a/docker/Dockerfile.lteUE.ubuntu18 b/docker/Dockerfile.lteUE.ubuntu18
index 8793cc54f79d87e470a46a4520b7f2ee519d1865..c6a70a0b503c9c9e03d1f9c57f41fc63b699d123 100644
--- a/docker/Dockerfile.lteUE.ubuntu18
+++ b/docker/Dockerfile.lteUE.ubuntu18
@@ -27,20 +27,20 @@
 
 FROM ran-build:latest AS lte-ue-build 
 
+RUN rm -Rf /oai-ran
 WORKDIR /oai-ran
+COPY . .
 
 #run build_oai to build the target image
 RUN /bin/sh oaienv && \ 
     cd cmake_targets && \
-    rm -Rf log && \
     mkdir -p log && \
-    ./build_oai --UE --ninja -w USRP
+    ./build_oai --UE --ninja -w USRP --verbose-ci
 
-# debug
-#RUN ldconfig -v
-#RUN ldd /oai-ran/targets/bin/lte-uesoftmodem.Rel15
-#RUN ls -lst /oai-ran/targets/bin
-#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so
+RUN apt-get install -y python3-pip && \
+    pip3 install --ignore-installed pyyaml && \
+    python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_parameters.yaml && \
+    python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_sim_parameters.yaml
 
 #start from scratch for target executable
 FROM ubuntu:bionic as oai-lte-ue
@@ -52,6 +52,7 @@ RUN apt-get update && \
     DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
     DEBIAN_FRONTEND=noninteractive apt-get install --yes \
         software-properties-common \
+        procps \
         libsctp1 \
         libnettle6 \
         liblapacke \
@@ -61,6 +62,7 @@ RUN apt-get update && \
         net-tools \
         iputils-ping \
         iproute2 \
+        iperf \
         libyaml-0-2 && \
     # Install UHD driver from ettus ppa 
     # At time of writing, it is 3.14
@@ -75,12 +77,10 @@ RUN apt-get update && \
 
 WORKDIR /opt/oai-lte-ue/bin
 COPY --from=lte-ue-build /oai-ran/targets/bin/lte-uesoftmodem.Rel15 .
+COPY --from=lte-ue-build /oai-ran/docker/scripts/lte_ue_entrypoint.sh entrypoint.sh
 COPY --from=lte-ue-build /oai-ran/targets/bin/conf2uedata .
 COPY --from=lte-ue-build /oai-ran/targets/bin/nvram .
 COPY --from=lte-ue-build /oai-ran/targets/bin/usim .
-COPY --from=lte-ue-build /oai-ran/targets/bin/.ue_emm.nvram0 .
-COPY --from=lte-ue-build /oai-ran/targets/bin/.ue.nvram0 .
-COPY --from=lte-ue-build /oai-ran/targets/bin/.usim.nvram0 .
 
 WORKDIR /usr/local/lib/
 COPY --from=lte-ue-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 .
@@ -99,26 +99,10 @@ COPY --from=lte-ue-build /usr/local/lib/libprotobuf-c.so.1 .
 
 RUN ldconfig
 
-#debug
-#RUN ldd /opt/oai-lte-ue/bin/lte-uesoftmodem.Rel15
-#RUN ldd /opt/oai-lte-ue/bin/conf2uedata
-#RUN ldd /opt/oai-lte-ue/bin/nvram
-#RUN ldd /opt/oai-lte-ue/bin/usim
-#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15
-#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15
-#RUN ldd /usr/local/lib/librfsimulator.so.Rel15
-#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15
-#RUN ldd /usr/local/lib/libcoding.so
-#RUN ldd /usr/local/lib/libparams_libconfig.so
-#RUN ldd /usr/local/lib/libSIMU.so
-#RUN ldd /usr/local/lib/libdfts.so
-
-# Copy the relevant configuration files for eNB
+# Copy the relevant configuration files for UE
 WORKDIR /opt/oai-lte-ue/etc
-COPY --from=lte-ue-build /oai-ran/ci-scripts/conf_files/ue.* ./
-COPY --from=lte-ue-build /oai-ran/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf ./ue_usim.conf
+COPY --from=lte-ue-build /oai-ran/docker/etc .
 
 WORKDIR /opt/oai-lte-ue
-#CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem", "-O", "/opt/oai-lte-ue/etc/enb.conf"]
-#ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"]
-CMD ["sleep", "infinity"]
+CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem.Rel15"]
+ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"]
diff --git a/docker/Dockerfile.nrUE.rhel8.2 b/docker/Dockerfile.nrUE.rhel8.2
index f9f3f8e4bfcdfd4e95d3d8ae10ed206788f7af53..f036c1148343710587585d42490924077b0d19d0 100644
--- a/docker/Dockerfile.nrUE.rhel8.2
+++ b/docker/Dockerfile.nrUE.rhel8.2
@@ -25,29 +25,27 @@
 #
 #---------------------------------------------------------------------
 
-FROM localhost/ran-build:latest AS nr-ue-build 
+FROM ran-build:latest AS nr-ue-build 
 
+RUN rm -Rf /oai-ran
 WORKDIR /oai-ran
+COPY . .
 
 #run build_oai to build the target image
 RUN /bin/sh oaienv && \ 
     cd cmake_targets && \
-    rm -Rf log && \
     mkdir -p log && \
-    ./build_oai --nrUE --ninja -w USRP
-
-# debug
-#RUN ldconfig -v
-#RUN ldd /oai-ran/targets/bin/nr-uesoftmodem.Rel15
-#RUN ls -lst /oai-ran/targets/bin
-#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so
+    ./build_oai --nrUE --ninja -w USRP --verbose-ci
 
 #start from scratch for target executable
 FROM registry.access.redhat.com/ubi8/ubi:latest as oai-nr-ue
+ENV TZ=Europe/Paris
 
 RUN yum update -y && \
     yum install -y --enablerepo="ubi-8-codeready-builder" \
         lksctp-tools \
+        procps-ng \
+        tzdata \
         nettle \
         net-tools \
         iputils \
@@ -60,6 +58,10 @@ RUN yum update -y && \
 
 WORKDIR /opt/oai-nr-ue/bin
 COPY --from=nr-ue-build /oai-ran/targets/bin/nr-uesoftmodem.Rel15 .
+COPY --from=nr-ue-build /oai-ran/docker/scripts/nr_ue_entrypoint.sh entrypoint.sh
+
+WORKDIR /opt/oai-nr-ue/etc
+COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/nr-ue-sim.conf .
 
 WORKDIR /usr/local/lib/
 COPY --from=nr-ue-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 .
@@ -97,24 +99,11 @@ COPY --from=nr-ue-build /lib64/libboost_timer.so.1.66.0 /lib64
 COPY --from=nr-ue-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64
 
 RUN ldconfig
-#RUN ldd /opt/oai-nr-ue/bin/nr-uesoftmodem.Rel15
-#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15
-#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15
-#RUN ldd /usr/local/lib/librfsimulator.so.Rel15
-#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15
-#RUN ldd /usr/local/lib/libcoding.so
-#RUN ldd /usr/local/lib/libparams_libconfig.so
-#RUN ldd /usr/local/lib/libdfts.so
-#RUN ldd /usr/local/lib/libldpc.so
-#RUN ldd /usr/local/lib/libldpc_optim.so
-#RUN ldd /usr/local/lib/libldpc_optim8seg.so
-#RUN ldd /usr/local/lib/libldpc_orig.so
 
 # Copy the relevant configuration files for eNB
 WORKDIR /opt/oai-nr-ue/etc
 COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/ue.* .
 
 WORKDIR /opt/oai-nr-ue
-#CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem", "-O", "/opt/oai-nr-ue/etc/enb.conf"]
-#ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"]
-CMD ["sleep", "infinity"]
+CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem.Rel15", "-O", "/opt/oai-nr-ue/etc/nr-ue-sim.conf"]
+ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"]
diff --git a/docker/Dockerfile.nrUE.ubuntu18 b/docker/Dockerfile.nrUE.ubuntu18
index 5450194f3539ad83663017e31e53e10185dc9a37..fc30af7286f9f93af74f2762fba9ad7fac164d28 100644
--- a/docker/Dockerfile.nrUE.ubuntu18
+++ b/docker/Dockerfile.nrUE.ubuntu18
@@ -25,34 +25,30 @@
 #
 #---------------------------------------------------------------------
 
-FROM ran-build:latest AS nr-ue-build 
+FROM ran-build:latest AS nr-ue-build
 
+RUN rm -Rf /oai-ran
 WORKDIR /oai-ran
+COPY . .
 
 #run build_oai to build the target image
 RUN /bin/sh oaienv && \ 
     cd cmake_targets && \
-    rm -Rf log && \
     mkdir -p log && \
-    ./build_oai --nrUE --ninja -w USRP
-
-# debug
-#RUN ldconfig -v
-#RUN ldd /oai-ran/targets/bin/nr-uesoftmodem.Rel15
-#RUN ls -lst /oai-ran/targets/bin
-#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so
+    ./build_oai --nrUE --ninja -w USRP --verbose-ci
 
 #start from scratch for target executable
 FROM ubuntu:bionic as oai-nr-ue
 ENV DEBIAN_FRONTEND=noninteractive
-ENV TZ=Europe
-RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+ENV TZ=Europe/Paris
 
 RUN apt-get update && \
     DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
     DEBIAN_FRONTEND=noninteractive apt-get install --yes \
         software-properties-common \
         libsctp1 \
+        procps \
+        tzdata \
         libnettle6 \
         liblapacke \
         libatlas3-base \
@@ -61,6 +57,7 @@ RUN apt-get update && \
         net-tools \
         iputils-ping \
         iproute2 \
+        iperf \
         libyaml-0-2 && \
     # Install UHD driver from ettus ppa 
     # At time of writing, it is 3.14
@@ -75,6 +72,10 @@ RUN apt-get update && \
 
 WORKDIR /opt/oai-nr-ue/bin
 COPY --from=nr-ue-build /oai-ran/targets/bin/nr-uesoftmodem.Rel15 .
+COPY --from=nr-ue-build /oai-ran/docker/scripts/nr_ue_entrypoint.sh entrypoint.sh
+
+WORKDIR /opt/oai-nr-ue/etc
+COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/nr-ue-sim.conf .
 
 WORKDIR /usr/local/lib/
 COPY --from=nr-ue-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 .
@@ -95,25 +96,7 @@ RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/li
 COPY --from=nr-ue-build /usr/local/lib/libprotobuf-c.so.1 .
 
 RUN ldconfig
-#debug
-#RUN ldd /opt/oai-nr-ue/bin/nr-uesoftmodem.Rel15
-#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15
-#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15
-#RUN ldd /usr/local/lib/librfsimulator.so.Rel15
-#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15
-#RUN ldd /usr/local/lib/libcoding.so
-#RUN ldd /usr/local/lib/libparams_libconfig.so
-#RUN ldd /usr/local/lib/libdfts.so
-#RUN ldd /usr/local/lib/libldpc.so
-#RUN ldd /usr/local/lib/libldpc_optim.so
-#RUN ldd /usr/local/lib/libldpc_optim8seg.so
-#RUN ldd /usr/local/lib/libldpc_orig.so
-
-# Copy the relevant configuration files for eNB
-WORKDIR /opt/oai-nr-ue/etc
-COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/ue.* .
 
 WORKDIR /opt/oai-nr-ue
-#CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem", "-O", "/opt/oai-nr-ue/etc/enb.conf"]
-#ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"]
-CMD ["sleep", "infinity"]
+CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem.Rel15", "-O", "/opt/oai-nr-ue/etc/nr-ue-sim.conf"]
+ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"]
diff --git a/docker/Dockerfile.phySim.rhel8.2 b/docker/Dockerfile.phySim.rhel8.2
new file mode 100644
index 0000000000000000000000000000000000000000..2333098bd715a4b44c3ec3e07f00395c96f383dd
--- /dev/null
+++ b/docker/Dockerfile.phySim.rhel8.2
@@ -0,0 +1,123 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+# Dockerfile for the Open-Air-Interface BUILD service
+#   Valid for RHEL8
+#
+#---------------------------------------------------------------------
+
+FROM ran-build:develop AS phy-sim-build
+
+RUN rm -Rf /oai-ran
+WORKDIR /oai-ran
+COPY . .
+
+#run build_oai to build the target image
+RUN /bin/sh oaienv && \ 
+    cd cmake_targets && \
+    mkdir -p log && \
+    ./build_oai --phy_simulators --ninja --verbose-ci
+
+
+#start from scratch for target executable
+FROM registry.access.redhat.com/ubi8/ubi:latest as oai-physim
+
+RUN yum update -y && \
+    yum install -y --enablerepo="ubi-8-codeready-builder" \
+        lksctp-tools \
+        nettle \
+        atlas \
+        hostname \
+        sudo \
+        procps-ng \
+        net-tools \
+        iputils \
+        bc \
+        iproute \
+        libyaml && \
+    echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \
+    echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf
+
+WORKDIR /opt/oai-physim/targets/bin
+COPY --from=phy-sim-build /oai-ran/targets/bin/dlsim.Rel15 .
+COPY --from=phy-sim-build /oai-ran/targets/bin/nr_dlsim.Rel15 .
+COPY --from=phy-sim-build /oai-ran/targets/bin/nr_prachsim.Rel15 .
+COPY --from=phy-sim-build /oai-ran/targets/bin/nr_ulschsim.Rel15 .
+COPY --from=phy-sim-build /oai-ran/targets/bin/polartest.Rel15 .
+COPY --from=phy-sim-build /oai-ran/targets/bin/ulsim.Rel15 .
+COPY --from=phy-sim-build /oai-ran/targets/bin/ldpctest.Rel15 .
+COPY --from=phy-sim-build /oai-ran/targets/bin/nr_dlschsim.Rel15 .
+COPY --from=phy-sim-build /oai-ran/targets/bin/nr_pbchsim.Rel15 .
+COPY --from=phy-sim-build /oai-ran/targets/bin/nr_pucchsim.Rel15 .
+COPY --from=phy-sim-build /oai-ran/targets/bin/nr_ulsim.Rel15 .
+COPY --from=phy-sim-build /oai-ran/targets/bin/smallblocktest.Rel15 .
+
+WORKDIR /usr/local/lib/
+COPY --from=phy-sim-build /oai-ran/targets/bin/libcoding.so .
+COPY --from=phy-sim-build /lib64/liblapacke.so.3 .
+COPY --from=phy-sim-build /lib64/libX11.so.6 .
+COPY --from=phy-sim-build /lib64/libXpm.so.4 .
+COPY --from=phy-sim-build /lib64/libxcb.so.1 .
+COPY --from=phy-sim-build /lib64/libXau.so.6 .
+COPY --from=phy-sim-build /lib64/libforms.so.2 .
+COPY --from=phy-sim-build /lib64/libblas.so.3 .
+COPY --from=phy-sim-build /lib64/liblapack.so.3 .
+COPY --from=phy-sim-build /lib64/libexslt.so.0 .
+COPY --from=phy-sim-build /lib64/libxslt.so.1 .
+COPY --from=phy-sim-build /oai-ran/cmake_targets/phy_simulators/build/libdfts.so .
+COPY --from=phy-sim-build /oai-ran/cmake_targets/phy_simulators/build/libSIMU.so .
+COPY --from=phy-sim-build /oai-ran/cmake_targets/phy_simulators/build/libldpc.so .
+COPY --from=phy-sim-build /oai-ran/cmake_targets/phy_simulators/build/libldpc_orig.so .
+
+RUN ldconfig
+
+#debug
+#RUN ldd /opt/oai-physim/targets/bin/dlsim.Rel15
+#RUN ldd /opt/oai-physim/targets/bin/nr_dlsim.Rel15
+#RUN ldd /opt/oai-physim/targets/bin/nr_prachsim.Rel15
+#RUN ldd /opt/oai-physim/targets/bin/nr_ulschsim.Rel15
+#RUN ldd /opt/oai-physim/targets/bin/polartest.Rel15
+#RUN ldd /opt/oai-physim/targets/bin/ulsim.Rel15
+#RUN ldd /opt/oai-physim/targets/bin/ldpctest.Rel15
+#RUN ldd /opt/oai-physim/targets/bin/nr_dlschsim.Rel15
+#RUN ldd /opt/oai-physim/targets/bin/nr_pbchsim.Rel15
+#RUN ldd /opt/oai-physim/targets/bin/nr_pucchsim.Rel15
+#RUN ldd /opt/oai-physim/targets/bin/nr_ulsim.Rel15
+#RUN ldd /opt/oai-physim/targets/bin/smallblocktest.Rel15
+
+# Copy some executables
+WORKDIR /usr/bin/
+
+COPY --from=phy-sim-build /usr/bin/killall .
+COPY --from=phy-sim-build /usr/bin/xmlstarlet .
+COPY --from=phy-sim-build /usr/bin/svn .
+
+# Copy the relevant configuration files for phySim
+WORKDIR /opt/oai-physim/
+
+COPY --from=phy-sim-build /oai-ran/cmake_targets/autotests/run_exec_autotests.bash /opt/oai-physim/cmake_targets/autotests/
+COPY --from=phy-sim-build /oai-ran/cmake_targets/autotests/test_case_list.xml /opt/oai-physim/cmake_targets/autotests/
+COPY --from=phy-sim-build /oai-ran/cmake_targets/autotests/tools/free_mem.bash /opt/oai-physim/cmake_targets/autotests/tools/
+COPY --from=phy-sim-build /oai-ran/cmake_targets/tools/build_helper /opt/oai-physim/cmake_targets/tools/
+COPY --from=phy-sim-build /oai-ran/cmake_targets/tools/test_helper /opt/oai-physim/cmake_targets/tools/
+
+#CMD ["sleep", "infinity"]
diff --git a/docker/Dockerfile.ran.rhel8.2 b/docker/Dockerfile.ran.rhel8.2
index 2e4bd586bfdc19de44b3470e63b8a274672cdbd5..3972fd0c35ffb054a5af11a9479753d68f077368 100644
--- a/docker/Dockerfile.ran.rhel8.2
+++ b/docker/Dockerfile.ran.rhel8.2
@@ -44,8 +44,11 @@ RUN rm -f /etc/rhsm-host && \
        file \
        psmisc \
        git \
+       # python3-pip and pyyaml are used for conf template generation
+       python3-pip \
        #unzip is needed for protobuf
        unzip && \
+    pip3 install --ignore-installed pyyaml && \
     echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \
     echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf
 
diff --git a/docker/Dockerfile.ran.ubuntu18 b/docker/Dockerfile.ran.ubuntu18
index 730366da74cc008a761589199a8b65a3bda4450d..4b296408fd8d5747533e02e55ca13ebd2308290f 100644
--- a/docker/Dockerfile.ran.ubuntu18
+++ b/docker/Dockerfile.ran.ubuntu18
@@ -42,7 +42,10 @@ RUN apt-get update && \
        git \
        xxd \
        #unzip is needed for protobuf
-       unzip
+       unzip \
+       # python3-pip for conf template generation
+       python3-pip && \
+    pip3 install --ignore-installed pyyaml
 
 # In some network environments, GIT proxy is required
 RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi"
@@ -56,4 +59,3 @@ RUN /bin/sh oaienv && \
     cd cmake_targets && \
     mkdir -p log && \
     ./build_oai -I -w USRP
-
diff --git a/docker/scripts/enb_entrypoint.sh b/docker/scripts/enb_entrypoint.sh
index 31d99b2a676e2393ee16d4107fbd902943d145b2..4ac86ef1b705b04d4e6e31166bec79cb48b32a30 100755
--- a/docker/scripts/enb_entrypoint.sh
+++ b/docker/scripts/enb_entrypoint.sh
@@ -2,17 +2,24 @@
 
 set -euo pipefail
 
+PREFIX=/opt/oai-enb
+RRC_INACTIVITY_THRESHOLD=${RRC_INACTIVITY_THRESHOLD:-0}
+ENABLE_MEASUREMENT_REPORTS=${ENABLE_MEASUREMENT_REPORTS:-no}
+ENABLE_X2=${ENABLE_X2:-no}
+
 # Based another env var, pick one template to use
-if [[ -v USE_FDD_CU ]]; then ln -s /opt/oai-enb/etc/cu.fdd.conf /opt/oai-enb/etc/enb.conf; fi
-if [[ -v USE_FDD_DU ]]; then ln -s /opt/oai-enb/etc/du.fdd.conf /opt/oai-enb/etc/enb.conf; fi
-if [[ -v USE_FDD_MONO ]]; then ln -s /opt/oai-enb/etc/enb.fdd.conf /opt/oai-enb/etc/enb.conf; fi
-if [[ -v USE_TDD_MONO ]]; then ln -s /opt/oai-enb/etc/enb.tdd.conf /opt/oai-enb/etc/enb.conf; fi
-if [[ -v USE_FDD_RCC ]]; then ln -s /opt/oai-enb/etc/rcc.if4p5.enb.fdd.conf /opt/oai-enb/etc/enb.conf; fi
-if [[ -v USE_FDD_RRU ]]; then ln -s /opt/oai-enb/etc/rru.fdd.conf /opt/oai-enb/etc/enb.conf; fi
-if [[ -v USE_TDD_RRU ]]; then ln -s /opt/oai-enb/etc/rru.tdd.conf /opt/oai-enb/etc/enb.conf; fi
+if [[ -v USE_FDD_CU ]]; then ln -s $PREFIX/etc/cu.fdd.conf $PREFIX/etc/enb.conf; fi
+if [[ -v USE_FDD_DU ]]; then ln -s $PREFIX/etc/du.fdd.conf $PREFIX/etc/enb.conf; fi
+if [[ -v USE_FDD_MONO ]]; then ln -s $PREFIX/etc/enb.fdd.conf $PREFIX/etc/enb.conf; fi
+if [[ -v USE_TDD_MONO ]]; then ln -s $PREFIX/etc/enb.tdd.conf $PREFIX/etc/enb.conf; fi
+if [[ -v USE_FDD_FAPI_RCC ]]; then ln -s $PREFIX/etc/rcc.nfapi.fdd.conf $PREFIX/etc/enb.conf; fi
+if [[ -v USE_FDD_IF4P5_RCC ]]; then ln -s $PREFIX/etc/rcc.if4p5.fdd.conf $PREFIX/etc/enb.conf; fi
+if [[ -v USE_TDD_IF4P5_RCC ]]; then ln -s $PREFIX/etc/rcc.if4p5.tdd.conf $PREFIX/etc/enb.conf; fi
+if [[ -v USE_FDD_RRU ]]; then ln -s $PREFIX/etc/rru.fdd.conf $PREFIX/etc/enb.conf; fi
+if [[ -v USE_TDD_RRU ]]; then ln -s $PREFIX/etc/rru.tdd.conf $PREFIX/etc/enb.conf; fi
 
 # Only this template will be manipulated
-CONFIG_FILES=`ls /opt/oai-enb/etc/enb.conf`
+CONFIG_FILES=`ls $PREFIX/etc/enb.conf || true`
 
 for c in ${CONFIG_FILES}; do
     # grep variable names (format: ${VAR}) from template to be rendered
diff --git a/docker/scripts/enb_parameters.yaml b/docker/scripts/enb_parameters.yaml
index a60fc20e29434725379d3fbe8172dd33c22e2f3f..58715a71527fbc5574cffa224391a2e5c1dec7db 100644
--- a/docker/scripts/enb_parameters.yaml
+++ b/docker/scripts/enb_parameters.yaml
@@ -25,7 +25,7 @@
     dest_dir: docker/etc
     
 - configurations:
-  - filePrefix: cu
+  - filePrefix: cu.band7.tm1.25PRB
     outputfilename: "cu.fdd.conf"
     config:
     - key: Active_eNBs
@@ -68,7 +68,7 @@
     - key: ENB_IPV4_ADDRESS_FOR_X2C
       env: "@F1_CU_IP_ADDRESS@"
       
-  - filePrefix: du
+  - filePrefix: du.band7.tm1.25PRB
     outputfilename: "du.fdd.conf"
     config:
     - key: Active_eNBs
@@ -123,7 +123,7 @@
     - key: bands
       env: "@UTRA_BAND_ID@"
       
-  - filePrefix: enb.band7.tm1.25PRB.usrpb210
+  - filePrefix: enb.band7.tm1.fr1.25PRB.usrpb210.conf
     outputfilename: "enb.fdd.conf"
     config:
     - key: Active_eNBs
@@ -147,6 +147,10 @@
       env: "@NID_CELL@"
     - key: N_RB_DL
       env: "@NB_PRB@"
+    - key: enable_measurement_reports
+      env: "@ENABLE_MEASUREMENT_REPORTS@"
+    - key: enable_x2
+      env: "@ENABLE_X2@"
     - key: ipv4
       env: "@MME_S1C_IP_ADDRESS@"
     - key: ENB_INTERFACE_NAME_FOR_S1_MME
@@ -159,6 +163,8 @@
       env: "@ENB_S1U_IP_ADDRESS@"
     - key: ENB_IPV4_ADDRESS_FOR_X2C
       env: "@ENB_X2_IP_ADDRESS@"
+    - key: rrc_inactivity_threshold
+      env: "@RRC_INACTIVITY_THRESHOLD@"
     - key: FLEXRAN_ENABLED
       env: "@FLEXRAN_ENABLED@"
     - key: FLEXRAN_INTERFACE_NAME
@@ -204,7 +210,7 @@
       env: "@F1_CU_IP_ADDRESS@"
       
   - filePrefix: "rcc.band7.tm1.nfapi"
-    outputfilename: "rcc.if4p5.enb.fdd.conf"
+    outputfilename: "rcc.nfapi.fdd.conf"
     config:
     - key: Active_eNBs
       env: "@ENB_NAME@"
@@ -246,3 +252,89 @@
     - key: ENB_IPV4_ADDRESS_FOR_X2C
       env: "@F1_CU_IP_ADDRESS@"
 
+  - filePrefix: "rcc.band7.tm1.if4p5.lo.25PRB"
+    outputfilename: "rcc.if4p5.fdd.conf"
+    config:
+    - key: Active_eNBs
+      env: "@ENB_NAME@"
+    - key: eNB_name
+      env: "@ENB_NAME@"
+    - key: plmn_list
+      env:
+        mcc: "@MCC@"
+        mnc: "@MNC@"
+        mnc_length: "@MNC_LENGTH@"
+    - key: tracking_area_code
+      env: "@TAC@"
+    - key: eutra_band
+      env: "@UTRA_BAND_ID@"
+    - key: downlink_frequency
+      env: "@DL_FREQUENCY_IN_MHZ@000000"
+    - key: uplink_frequency_offset
+      env: "@UL_FREQUENCY_OFFSET_IN_MHZ@000000"
+    - key: Nid_cell
+      env: "@NID_CELL@"
+    - key: N_RB_DL
+      env: "@NB_PRB@"
+    - key: ipv4
+      env: "@MME_S1C_IP_ADDRESS@"
+    - key: ENB_INTERFACE_NAME_FOR_S1_MME
+      env: "@RCC_IF_NAME@"
+    - key: ENB_IPV4_ADDRESS_FOR_S1_MME
+      env: "@RCC_S1C_IP_ADDRESS@"
+    - key: ENB_INTERFACE_NAME_FOR_S1U
+      env: "@RCC_IF_NAME@"
+    - key: ENB_IPV4_ADDRESS_FOR_S1U
+      env: "@RCC_IP_ADDRESS@"
+    - key: ENB_IPV4_ADDRESS_FOR_X2C
+      env: "@RCC_IP_ADDRESS@"
+    - key: local_if_name
+      env: "@IF4P5_IF_NAME@"
+    - key: remote_address
+      env: "@IF4P5_RRU_IP_ADDRESS@"
+    - key: local_address
+      env: "@IF4P5_RCC_IP_ADDRESS@"
+
+  - filePrefix: "rcc.band40.tm1.25PRB"
+    outputfilename: "rcc.if4p5.tdd.conf"
+    config:
+    - key: Active_eNBs
+      env: "@ENB_NAME@"
+    - key: eNB_name
+      env: "@ENB_NAME@"
+    - key: plmn_list
+      env:
+        mcc: "@MCC@"
+        mnc: "@MNC@"
+        mnc_length: "@MNC_LENGTH@"
+    - key: tracking_area_code
+      env: "@TAC@"
+    - key: eutra_band
+      env: "@UTRA_BAND_ID@"
+    - key: downlink_frequency
+      env: "@DL_FREQUENCY_IN_MHZ@000000"
+    - key: uplink_frequency_offset
+      env: "@UL_FREQUENCY_OFFSET_IN_MHZ@000000"
+    - key: Nid_cell
+      env: "@NID_CELL@"
+    - key: N_RB_DL
+      env: "@NB_PRB@"
+    - key: ipv4
+      env: "@MME_S1C_IP_ADDRESS@"
+    - key: ENB_INTERFACE_NAME_FOR_S1_MME
+      env: "@RCC_IF_NAME@"
+    - key: ENB_IPV4_ADDRESS_FOR_S1_MME
+      env: "@RCC_S1C_IP_ADDRESS@"
+    - key: ENB_INTERFACE_NAME_FOR_S1U
+      env: "@RCC_IF_NAME@"
+    - key: ENB_IPV4_ADDRESS_FOR_S1U
+      env: "@RCC_IP_ADDRESS@"
+    - key: ENB_IPV4_ADDRESS_FOR_X2C
+      env: "@RCC_IP_ADDRESS@"
+    - key: local_if_name
+      env: "@IF4P5_IF_NAME@"
+    - key: remote_address
+      env: "@IF4P5_RRU_IP_ADDRESS@"
+    - key: local_address
+      env: "@IF4P5_RCC_IP_ADDRESS@"
+
diff --git a/docker/scripts/generateTemplate.py b/docker/scripts/generateTemplate.py
index 4949e9cf21531849fd3fa72d4adb18d8fa0c950a..cc4b72a7035159ebbae7e77767cfc150bfeb106b 100644
--- a/docker/scripts/generateTemplate.py
+++ b/docker/scripts/generateTemplate.py
@@ -35,24 +35,33 @@ def main():
   data = yaml.full_load(f)
   dir = os.listdir(f'{data[0]["paths"]["source_dir"]}')
 
-
   #identify configs, read and replace corresponding values
   for config in data[1]["configurations"]:
     filePrefix = config["filePrefix"]
     outputfilename = config["outputfilename"]
+    print('================================================')
+    print('filePrefix = ' + filePrefix)
+    print('outputfilename = ' + outputfilename)
     for inputfile in dir:
       if inputfile.find(filePrefix) >=0:
-        prefix_outputfile = {"cu": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', 
-                             "du": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+        prefix_outputfile = {"cu.band7.tm1.25PRB": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', 
+                             "du.band7.tm1.25PRB": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
                              "rru.fdd": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
                              "rru.tdd": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
-                             "enb.band7.tm1.25PRB.usrpb210": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+                             "enb.band7.tm1.fr1.25PRB.usrpb210.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
                              "enb.band40.tm1.25PRB.FairScheduler.usrpb210": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
-                             "rcc.band7.tm1.nfapi": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}'
+                             "rcc.band7.tm1.nfapi": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+                             "rcc.band7.tm1.if4p5.lo.25PRB": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+                             "rcc.band40.tm1.25PRB": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+                             "gnb.band78.tm1.fr1.106PRB.usrpb210.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+                             "gnb.band78.sa.fr1.106PRB.usrpn310.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+                             "ue.nfapi": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+                             "ue_sim_ci": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}'
                              }
+        print('inputfile = ' + inputfile)
         if filePrefix in prefix_outputfile:
           outputfile1 = prefix_outputfile[filePrefix]  
-      
+
         directory = f'{data[0]["paths"]["dest_dir"]}'
         if not os.path.exists(directory):
           os.makedirs(directory, exist_ok=True)
@@ -61,11 +70,24 @@ def main():
              open(outputfile1, mode='w') as outputfile:
           for line in inputfile:
             count = 0
+            if re.search(r'EHPLMN_LIST', line):
+              outputfile.write(line)
+              continue
+            if re.search(r'sd  = 0x1;', line):
+              templine = re.sub(r'sd  = 0x1;', 'sd  = 0x@NSSAI_SD0@;', line)
+              outputfile.write(templine)
+              continue
+            if re.search(r'sd  = 0x112233;', line):
+              templine = re.sub(r'sd  = 0x112233;', 'sd  = 0x@NSSAI_SD1@;', line)
+              outputfile.write(templine)
+              continue
             for key in config["config"]:
               if line.find(key["key"]) >= 0:
                 count += 1
                 if re.search(r'preference', line):
                   templine = line
+                elif re.search(r'mnc_length', line) and key["key"] == "mnc":
+                  continue
                 elif re.search(r'plmn_list', line):
                   templine = re.sub(r'[0-9]+', '""', line)
                   templine = re.sub(r'\"\"', key["env"]["mcc"], templine, 1)
diff --git a/docker/scripts/gnb_entrypoint.sh b/docker/scripts/gnb_entrypoint.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6d3d63629ff07ce858d4ab946a4fea64beda3902
--- /dev/null
+++ b/docker/scripts/gnb_entrypoint.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+set -euo pipefail
+
+PREFIX=/opt/oai-gnb
+ENABLE_X2=${ENABLE_X2:-yes}
+
+# Based another env var, pick one template to use
+if [[ -v USE_NSA_TDD_MONO ]]; then ln -s $PREFIX/etc/gnb.nsa.tdd.conf $PREFIX/etc/gnb.conf; fi
+if [[ -v USE_SA_TDD_MONO ]]; then ln -s $PREFIX/etc/gnb.sa.tdd.conf $PREFIX/etc/gnb.conf; fi
+
+# Only this template will be manipulated
+CONFIG_FILES=`ls $PREFIX/etc/gnb.conf || true`
+
+for c in ${CONFIG_FILES}; do
+    # grep variable names (format: ${VAR}) from template to be rendered
+    VARS=$(grep -oP '@[a-zA-Z0-9_]+@' ${c} | sort | uniq | xargs)
+
+    # create sed expressions for substituting each occurrence of ${VAR}
+    # with the value of the environment variable "VAR"
+    EXPRESSIONS=""
+    for v in ${VARS}; do
+        NEW_VAR=`echo $v | sed -e "s#@##g"`
+        if [[ "${!NEW_VAR}x" == "x" ]]; then
+            echo "Error: Environment variable '${NEW_VAR}' is not set." \
+                "Config file '$(basename $c)' requires all of $VARS."
+            exit 1
+        fi
+        EXPRESSIONS="${EXPRESSIONS};s|${v}|${!NEW_VAR}|g"
+    done
+    EXPRESSIONS="${EXPRESSIONS#';'}"
+
+    # render template and inline replace config file
+    sed -i "${EXPRESSIONS}" ${c}
+done
+
+# Load the USRP binaries
+if [[ -v USE_B2XX ]]; then
+    /usr/lib/uhd/utils/uhd_images_downloader.py -t b2xx
+elif [[ -v USE_X3XX ]]; then
+    /usr/lib/uhd/utils/uhd_images_downloader.py -t x3xx
+elif [[ -v USE_N3XX ]]; then
+    /usr/lib/uhd/utils/uhd_images_downloader.py -t n3xx
+fi
+
+echo "=================================="
+echo "== Starting gNB soft modem"
+if [[ -v USE_ADDITIONAL_OPTIONS ]]; then
+    echo "Additional option(s): ${USE_ADDITIONAL_OPTIONS}"
+    new_args=()
+    while [[ $# -gt 0 ]]; do
+        new_args+=("$1")
+        shift
+    done
+    for word in ${USE_ADDITIONAL_OPTIONS}; do
+        new_args+=("$word")
+    done
+    echo "${new_args[@]}"
+    exec "${new_args[@]}"
+else
+    echo "$@"
+    exec "$@"
+fi
diff --git a/docker/scripts/gnb_parameters.yaml b/docker/scripts/gnb_parameters.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a13d0d3677dded433610069e7b2db1358c8c3016
--- /dev/null
+++ b/docker/scripts/gnb_parameters.yaml
@@ -0,0 +1,92 @@
+#/*
+# * 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
+# */
+
+---
+- paths:
+    source_dir: "ci-scripts/conf_files/"
+    dest_dir: docker/etc
+
+- configurations:
+  - filePrefix: gnb.band78.tm1.fr1.106PRB.usrpb210.conf
+    outputfilename: "gnb.nsa.tdd.conf"
+    config:
+    - key: Active_gNBs
+      env: "@GNB_NAME@"
+    - key: gNB_name
+      env: "@GNB_NAME@"
+    - key: plmn_list
+      env:
+        mcc: "@MCC@"
+        mnc: "@MNC@"
+        mnc_length: "@MNC_LENGTH@"
+    - key: tracking_area_code
+      env: "@TAC@"
+    - key: enable_x2
+      env: "@ENABLE_X2@"
+    - key: ipv4
+      env: "@ENB_X2_IP_ADDRESS@"
+    - key: GNB_INTERFACE_NAME_FOR_S1_MME
+      env: "@GNB_S1C_IF_NAME@"
+    - key: GNB_IPV4_ADDRESS_FOR_S1_MME
+      env: "@GNB_S1C_IP_ADDRESS@"
+    - key: GNB_INTERFACE_NAME_FOR_S1U
+      env: "@GNB_S1U_IF_NAME@"
+    - key: GNB_IPV4_ADDRESS_FOR_S1U
+      env: "@GNB_S1U_IP_ADDRESS@"
+    - key: GNB_IPV4_ADDRESS_FOR_X2C
+      env: "@GNB_X2_IP_ADDRESS@"
+    - key: rrc_inactivity_threshold
+      env: "@RRC_INACTIVITY_THRESHOLD@"
+    - key: FLEXRAN_ENABLED
+      env: "@FLEXRAN_ENABLED@"
+    - key: FLEXRAN_INTERFACE_NAME
+      env: "@FLEXRAN_INTERFACE_NAME@"
+    - key: FLEXRAN_IPV4_ADDRESS
+      env: "@FLEXRAN_IPV4_ADDRESS@"
+
+  - filePrefix: gnb.band78.sa.fr1.106PRB.usrpn310.conf
+    outputfilename: "gnb.sa.tdd.conf"
+    config:
+    - key: Active_gNBs
+      env: "@GNB_NAME@"
+    - key: gNB_name
+      env: "@GNB_NAME@"
+    - key: mcc
+      env: "@MCC@"
+    - key: mnc
+      env: "@MNC@"
+    - key: mnc_length
+      env: "@MNC_LENGTH@"
+    - key: tracking_area_code
+      env: "@TAC@"
+    - key: sst
+      env: "@NSSAI_SST@"
+    - key: ipv4
+      env: "@AMF_IP_ADDRESS@"
+    - key: GNB_INTERFACE_NAME_FOR_NG_AMF
+      env: "@GNB_NGA_IF_NAME@"
+    - key: GNB_IPV4_ADDRESS_FOR_NG_AMF
+      env: "@GNB_NGA_IP_ADDRESS@"
+    - key: GNB_INTERFACE_NAME_FOR_NGU
+      env: "@GNB_NGU_IF_NAME@"
+    - key: GNB_IPV4_ADDRESS_FOR_NGU
+      env: "@GNB_NGU_IP_ADDRESS@"
+
diff --git a/docker/scripts/lte_ru_entrypoint.sh b/docker/scripts/lte_ru_entrypoint.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f466e25ec28a30acad6af2d4bea9a5743859e7a5
--- /dev/null
+++ b/docker/scripts/lte_ru_entrypoint.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+set -euo pipefail
+
+PREFIX=/opt/oai-lte-ru
+
+# Based another env var, pick one template to use
+if [[ -v USE_FDD_RRU ]]; then ln -s $PREFIX/etc/rru.fdd.conf $PREFIX/etc/rru.conf; fi
+if [[ -v USE_TDD_RRU ]]; then ln -s $PREFIX/etc/rru.tdd.conf $PREFIX/etc/rru.conf; fi
+
+# Only this template will be manipulated
+CONFIG_FILES=`ls $PREFIX/etc/rru.conf || true`
+
+for c in ${CONFIG_FILES}; do
+    # grep variable names (format: ${VAR}) from template to be rendered
+    VARS=$(grep -oP '@[a-zA-Z0-9_]+@' ${c} | sort | uniq | xargs)
+
+    # create sed expressions for substituting each occurrence of ${VAR}
+    # with the value of the environment variable "VAR"
+    EXPRESSIONS=""
+    for v in ${VARS}; do
+        NEW_VAR=`echo $v | sed -e "s#@##g"`
+        if [[ "${!NEW_VAR}x" == "x" ]]; then
+            echo "Error: Environment variable '${NEW_VAR}' is not set." \
+                "Config file '$(basename $c)' requires all of $VARS."
+            exit 1
+        fi
+        EXPRESSIONS="${EXPRESSIONS};s|${v}|${!NEW_VAR}|g"
+    done
+    EXPRESSIONS="${EXPRESSIONS#';'}"
+
+    # render template and inline replace config file
+    sed -i "${EXPRESSIONS}" ${c}
+done
+
+# Load the USRP binaries
+if [[ -v USE_B2XX ]]; then
+    /usr/lib/uhd/utils/uhd_images_downloader.py -t b2xx
+elif [[ -v USE_X3XX ]]; then
+    /usr/lib/uhd/utils/uhd_images_downloader.py -t x3xx
+elif [[ -v USE_N3XX ]]; then
+    /usr/lib/uhd/utils/uhd_images_downloader.py -t n3xx
+fi
+
+echo "=================================="
+echo "== Starting eNB soft modem"
+if [[ -v USE_ADDITIONAL_OPTIONS ]]; then
+    echo "Additional option(s): ${USE_ADDITIONAL_OPTIONS}"
+    new_args=()
+    while [[ $# -gt 0 ]]; do
+        new_args+=("$1")
+        shift
+    done
+    for word in ${USE_ADDITIONAL_OPTIONS}; do
+        new_args+=("$word")
+    done
+    echo "${new_args[@]}"
+    exec "${new_args[@]}"
+else
+    echo "$@"
+    exec "$@"
+fi
diff --git a/docker/scripts/lte_ue_entrypoint.sh b/docker/scripts/lte_ue_entrypoint.sh
new file mode 100755
index 0000000000000000000000000000000000000000..235128f73855aea4452d89940ea64d640e844e6d
--- /dev/null
+++ b/docker/scripts/lte_ue_entrypoint.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+
+set -euo pipefail
+
+PREFIX=/opt/oai-lte-ue
+
+# Based another env var, pick one template to use
+if [[ -v USE_NFAPI ]]; then ln -s $PREFIX/etc/ue.nfapi.conf $PREFIX/etc/ue.conf; fi
+
+# Only this template will be manipulated and the USIM one!
+CONFIG_FILES=`ls $PREFIX/etc/ue.conf $PREFIX/etc/ue_usim.conf || true`
+
+for c in ${CONFIG_FILES}; do
+    # grep variable names (format: ${VAR}) from template to be rendered
+    VARS=$(grep -oP '@[a-zA-Z0-9_]+@' ${c} | sort | uniq | xargs)
+
+    # create sed expressions for substituting each occurrence of ${VAR}
+    # with the value of the environment variable "VAR"
+    EXPRESSIONS=""
+    for v in ${VARS}; do
+        NEW_VAR=`echo $v | sed -e "s#@##g"`
+        if [[ "${!NEW_VAR}x" == "x" ]]; then
+            echo "Error: Environment variable '${NEW_VAR}' is not set." \
+                "Config file '$(basename $c)' requires all of $VARS."
+            exit 1
+        fi
+        EXPRESSIONS="${EXPRESSIONS};s|${v}|${!NEW_VAR}|g"
+    done
+    EXPRESSIONS="${EXPRESSIONS#';'}"
+
+    # render template and inline replace config file
+    sed -i "${EXPRESSIONS}" ${c}
+done
+
+#now generate USIM files
+# At this point all operations will be run from $PREFIX!
+cd $PREFIX
+$PREFIX/bin/conf2uedata -c $PREFIX/etc/ue_usim.conf -o $PREFIX
+
+# Load the USRP binaries
+if [[ -v USE_B2XX ]]; then
+    /usr/lib/uhd/utils/uhd_images_downloader.py -t b2xx
+elif [[ -v USE_X3XX ]]; then
+    /usr/lib/uhd/utils/uhd_images_downloader.py -t x3xx
+elif [[ -v USE_N3XX ]]; then
+    /usr/lib/uhd/utils/uhd_images_downloader.py -t n3xx
+fi
+
+# in case we have conf file, append
+new_args=()
+while [[ $# -gt 0 ]]; do
+  new_args+=("$1")
+  shift
+done
+if [[ -v USE_NFAPI ]]; then
+  new_args+=("-O")
+  new_args+=("$PREFIX/etc/ue.conf")
+fi
+
+echo "=================================="
+echo "== Starting LTE UE soft modem"
+if [[ -v USE_ADDITIONAL_OPTIONS ]]; then
+    echo "Additional option(s): ${USE_ADDITIONAL_OPTIONS}"
+    for word in ${USE_ADDITIONAL_OPTIONS}; do
+        new_args+=("$word")
+    done
+    echo "${new_args[@]}"
+    exec "${new_args[@]}"
+else
+    echo "${new_args[@]}"
+    exec "${new_args[@]}"
+fi
diff --git a/docker/scripts/lte_ue_parameters.yaml b/docker/scripts/lte_ue_parameters.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..977659bb54c280d53c86179c5f674673069b31b8
--- /dev/null
+++ b/docker/scripts/lte_ue_parameters.yaml
@@ -0,0 +1,37 @@
+#/*
+# * 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
+# */
+
+---
+- paths:
+    source_dir: "ci-scripts/conf_files/"
+    dest_dir: docker/etc
+    
+- configurations:
+  - filePrefix: ue.nfapi
+    outputfilename: "ue.nfapi.conf"
+    config:
+    - key: remote_n_address
+      env: "@ENB_IP_ADDRESS@"
+    - key: local_n_address
+      env: "@LTE_UE_IP_ADDRESS@"
+    - key: local_n_if_name
+      env: "@UE_NFAPI_IF_NAME@"
+
diff --git a/docker/scripts/lte_ue_sim_parameters.yaml b/docker/scripts/lte_ue_sim_parameters.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a339ed7504ea16d105f342d46700f5e852e540e9
--- /dev/null
+++ b/docker/scripts/lte_ue_sim_parameters.yaml
@@ -0,0 +1,47 @@
+#/*
+# * 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
+# */
+
+---
+- paths:
+    source_dir: "openair3/NAS/TOOLS/"
+    dest_dir: docker/etc
+    
+- configurations:
+  - filePrefix: ue_sim_ci
+    outputfilename: "ue_usim.conf"
+    config:
+    - key: MNC
+      env: "@MNC@"
+    - key: MCC
+      env: "@MCC@"
+    - key: MSIN
+      env: "@SHORT_IMSI@"
+    - key: USIM_API_K
+      env: "@LTE_KEY@"
+    - key: OPC
+      env: "@OPC@"
+    - key: MSISDN
+      env: "@MSISDN@"
+    - key: HPLMN
+      env: "@HPLMN@"
+    - key: OPLMN_LIST
+      env: "@HPLMN@"
+
diff --git a/docker/scripts/nr_ue_entrypoint.sh b/docker/scripts/nr_ue_entrypoint.sh
new file mode 100755
index 0000000000000000000000000000000000000000..691258b8fa9e30a732a1c6904a4404cd82934913
--- /dev/null
+++ b/docker/scripts/nr_ue_entrypoint.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+set -euo pipefail
+
+PREFIX=/opt/oai-nr-ue
+
+# Based another env var, pick one template to use
+#if [[ -v USE_NFAPI ]]; then ln -s $PREFIX/etc/ue.nfapi.conf $PREFIX/etc/ue.conf; fi
+
+# Only this template will be manipulated and the USIM one!
+CONFIG_FILES=`ls $PREFIX/etc/ue.conf $PREFIX/etc/nr-ue-sim.conf || true`
+
+for c in ${CONFIG_FILES}; do
+    # grep variable names (format: ${VAR}) from template to be rendered
+    VARS=$(grep -oP '@[a-zA-Z0-9_]+@' ${c} | sort | uniq | xargs)
+
+    # create sed expressions for substituting each occurrence of ${VAR}
+    # with the value of the environment variable "VAR"
+    EXPRESSIONS=""
+    for v in ${VARS}; do
+        NEW_VAR=`echo $v | sed -e "s#@##g"`
+        if [[ "${!NEW_VAR}x" == "x" ]]; then
+            echo "Error: Environment variable '${NEW_VAR}' is not set." \
+                "Config file '$(basename $c)' requires all of $VARS."
+            exit 1
+        fi
+        EXPRESSIONS="${EXPRESSIONS};s|${v}|${!NEW_VAR}|g"
+    done
+    EXPRESSIONS="${EXPRESSIONS#';'}"
+
+    # render template and inline replace config file
+    sed -i "${EXPRESSIONS}" ${c}
+done
+
+# Load the USRP binaries
+if [[ -v USE_B2XX ]]; then
+    /usr/lib/uhd/utils/uhd_images_downloader.py -t b2xx
+elif [[ -v USE_X3XX ]]; then
+    /usr/lib/uhd/utils/uhd_images_downloader.py -t x3xx
+elif [[ -v USE_N3XX ]]; then
+    /usr/lib/uhd/utils/uhd_images_downloader.py -t n3xx
+fi
+
+# in case we have conf file, append
+new_args=()
+while [[ $# -gt 0 ]]; do
+  new_args+=("$1")
+  shift
+done
+
+echo "=================================="
+echo "== Starting NR UE soft modem"
+if [[ -v USE_ADDITIONAL_OPTIONS ]]; then
+    echo "Additional option(s): ${USE_ADDITIONAL_OPTIONS}"
+    for word in ${USE_ADDITIONAL_OPTIONS}; do
+        new_args+=("$word")
+    done
+    echo "${new_args[@]}"
+    exec "${new_args[@]}"
+else
+    echo "${new_args[@]}"
+    exec "${new_args[@]}"
+fi
diff --git a/executables/main-fs6.c b/executables/main-fs6.c
index 5283ce5eaa1cf1b3b3dbd25543c15af7475b7637..438edb4044dd02dc766029406697c6094c4e300c 100644
--- a/executables/main-fs6.c
+++ b/executables/main-fs6.c
@@ -750,7 +750,7 @@ void phy_procedures_eNB_uespec_RX_fromsplit(uint8_t *bufferZone, int nbBlocks,PH
   recvFs6Ul(bufferZone, nbBlocks, eNB, ul_propa);
 
   // dirty memory allocation in OAI...
-  for (int i = 0; i < NUMBER_OF_UCI_VARS_MAX; i++)
+  for (int i = 0; i < NUMBER_OF_UCI_MAX; i++)
     if ( eNB->uci_vars[i].frame == proc->frame_rx &&
          eNB->uci_vars[i].subframe == proc->subframe_rx )
       eNB->uci_vars[i].active=0;
@@ -1145,7 +1145,7 @@ void appendFs6DLUEcch(uint8_t *bufferZone, PHY_VARS_eNB *eNB, int frame, int sub
   commonUDP_t *newUDPheader=(commonUDP_t *) firstFreeByte;
   bool first_UE=true;
 
-  for (int i = 0; i < NUMBER_OF_UCI_VARS_MAX; i++) {
+  for (int i = 0; i < NUMBER_OF_UCI_MAX; i++) {
     LTE_eNB_UCI *uci = &(eNB->uci_vars[i]);
 
     if ((uci->active == 1) && (uci->frame == frame) && (uci->subframe == subframe)) {
diff --git a/executables/main-ocp.c b/executables/main-ocp.c
index ae1db7195bc6e2fb6add1059efc0ee5343d8213c..0355582b2b4e76848588cd22a580dd4577569ab0 100644
--- a/executables/main-ocp.c
+++ b/executables/main-ocp.c
@@ -73,17 +73,19 @@ int sync_var=-1; //!< protected by mutex \ref sync_mutex.
 int config_sync_var=-1;
 volatile int oai_exit = 0;
 double cpuf;
+THREAD_STRUCT thread_struct;
+
 uint16_t sf_ahead=4;
 //uint16_t slot_ahead=6;
 int otg_enabled;
 uint64_t  downlink_frequency[MAX_NUM_CCs][4];
 int32_t   uplink_frequency_offset[MAX_NUM_CCs][4];
 int split73;
-int usrp_tx_thread = 0;
 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){
@@ -202,7 +204,6 @@ void init_eNB_afterRU(void) {
   for (int inst=0; inst<RC.nb_inst; inst++) {
     for (int CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
       PHY_VARS_eNB *eNB = RC.eNB[inst][CC_id];
-      phy_init_lte_eNB(eNB,0,0);
       eNB->frame_parms.nb_antennas_rx       = 0;
       eNB->frame_parms.nb_antennas_tx       = 0;
       eNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *));
@@ -228,12 +229,26 @@ void init_eNB_afterRU(void) {
           for (int ce_level=0; ce_level<4; ce_level++)
             eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i];
 
-          eNB->common_vars.rxdataF[aa]     =  eNB->RU_list[ru_id]->common.rxdataF[i];
         }
       }
 
-      AssertFatal( eNB->frame_parms.nb_antennas_rx > 0 && eNB->frame_parms.nb_antennas_rx < 4, "");
-      AssertFatal( eNB->frame_parms.nb_antennas_tx > 0 && eNB->frame_parms.nb_antennas_rx < 4, "");
+
+      AssertFatal( eNB->frame_parms.nb_antennas_rx > 0 && eNB->frame_parms.nb_antennas_rx < 5, "");
+      AssertFatal( eNB->frame_parms.nb_antennas_tx > 0 && eNB->frame_parms.nb_antennas_rx < 5, "");
+
+      phy_init_lte_eNB(eNB,0,0);
+
+      // need to copy rxdataF after L1 variables are allocated
+      for (int inst=0; inst<RC.nb_inst; inst++) {
+         for (int CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
+           PHY_VARS_eNB *eNB = RC.eNB[inst][CC_id];
+           for (int ru_id=0,aa=0; ru_id<eNB->num_RU; ru_id++) {
+              for (int i=0; i<eNB->RU_list[ru_id]->nb_rx; aa++,i++) 
+                eNB->common_vars.rxdataF[aa]     =  eNB->RU_list[ru_id]->common.rxdataF[i];
+           }
+         }
+      }
+
       LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx);
       init_transport(eNB);
       //init_precoding_weights(RC.eNB[inst][CC_id]);
@@ -800,7 +815,7 @@ int init_rf(RU_t *ru) {
   pthread_setname_np(pthread_self(),name);
   return ret;
 }
-
+ 
 void ocp_init_RU(RU_t *ru, char *rf_config_file, int send_dmrssync) {
   PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL;
   int i;
@@ -1318,7 +1333,7 @@ int main ( int argc, char **argv ) {
 
   // end of CI modifications
   //getchar();
-  if(IS_SOFTMODEM_DOFORMS)
+  if(IS_SOFTMODEM_DOSCOPE)
     load_softscope("enb", NULL);
 
   itti_wait_tasks_end();
@@ -1327,7 +1342,7 @@ int main ( int argc, char **argv ) {
   // stop threads
 
   if (RC.nb_inst == 0 || !NODE_IS_CU(node_type)) {
-    if(IS_SOFTMODEM_DOFORMS)
+    if(IS_SOFTMODEM_DOSCOPE)
       end_forms();
 
     LOG_I(ENB_APP,"stopping MODEM threads\n");
diff --git a/executables/main_ru.c b/executables/main_ru.c
new file mode 100644
index 0000000000000000000000000000000000000000..93a580560e34122ee7ed258aa1d8b34a8a2a7903
--- /dev/null
+++ b/executables/main_ru.c
@@ -0,0 +1,382 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file oairu.c
+ * \brief Top-level threads for radio-unit
+ * \author R. Knopp
+ * \date 2020
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr
+ * \note
+ * \warning
+ */
+
+
+#define _GNU_SOURCE             /* See feature_test_macros(7) */
+#include <sched.h>
+
+
+
+
+#include "assertions.h"
+#include "PHY/types.h"
+
+#include "PHY/defs_RU.h"
+#include "common/config/config_userapi.h"
+#include "common/utils/load_module_shlib.h"
+
+
+#include "../../ARCH/COMMON/common_lib.h"
+#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
+
+
+#include "PHY/phy_vars.h"
+#include "SCHED/sched_common_vars.h"
+#include "PHY/TOOLS/phy_scope_interface.h"
+#include "common/utils/LOG/log.h"
+#include "common/utils/LOG/vcd_signal_dumper.h"
+#include "PHY/INIT/phy_init.h"
+#include "openair2/ENB_APP/enb_paramdef.h"
+#include "system.h"
+
+#include <executables/split_headers.h>
+#include <executables/softmodem-common.h>
+#include <executables/thread-common.h>
+
+static int DEFBANDS[] = {7};
+static int DEFENBS[] = {0};
+static int DEFBFW[] = {0x00007fff};
+
+THREAD_STRUCT thread_struct;
+
+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;
+
+volatile int             oai_exit = 0;
+uint16_t sf_ahead = 4;
+RU_t ru_m;
+
+
+extern void init_RU0(RU_t *ru,int ru_id,char *rf_config_file, int send_dmrssync);
+extern void init_RU_proc(RU_t *ru);
+extern void kill_RU_proc(RU_t *ru);
+extern void set_function_spec_param(RU_t *ru);
+
+int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+
+
+void nfapi_setmode(nfapi_mode_t nfapi_mode) { return; }
+void exit_function(const char *file, const char *function, const int line, const char *s) {
+
+  if (s != NULL) {
+    printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s);
+  }
+  close_log_mem();
+  oai_exit = 1;
+
+  if (ru_m.rfdevice.trx_end_func) {
+    ru_m.rfdevice.trx_end_func(&ru_m.rfdevice);
+    ru_m.rfdevice.trx_end_func = NULL;
+  }
+
+  if (ru_m.ifdevice.trx_end_func) {
+    ru_m.ifdevice.trx_end_func(&ru_m.ifdevice);
+    ru_m.ifdevice.trx_end_func = NULL;
+  }
+ 
+  pthread_mutex_destroy(ru_m.ru_mutex);
+  pthread_cond_destroy(ru_m.ru_cond); 
+  sleep(1); //allow lte-softmodem threads to exit first
+  exit(1);
+}
+
+
+static void get_options(void) {
+  CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
+  get_common_options(SOFTMODEM_ENB_BIT );
+  CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
+
+  //RCConfig();
+  
+}
+
+
+
+
+
+extern void  phy_free_RU(RU_t *);
+
+nfapi_mode_t nfapi_getmode(void) {
+  return(NFAPI_MODE_PNF);
+}
+
+void oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {
+
+  AssertFatal(1==0,"This is bad ... please check why we get here\n");
+}
+
+void wait_eNBs(void){ return; }
+
+uint64_t                 downlink_frequency[MAX_NUM_CCs][4];
+
+
+int main ( int argc, char **argv )
+{
+
+  if ( load_configmodule(argc,argv,0) == NULL) {
+    exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
+  }
+
+  logInit();
+  printf("Reading in command-line options\n");
+  get_options ();
+
+  if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) {
+    fprintf(stderr,"Getting configuration failed\n");
+    exit(-1);
+  }
+
+#if T_TRACER
+  T_Config_Init();
+#endif
+  printf("configuring for RRU\n");
+
+#ifndef PACKAGE_VERSION
+#  define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
+#endif
+  LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
+
+  /* Read configuration */
+
+  printf("About to Init RU threads\n");
+  
+
+  RU_t *ru=&ru_m;
+
+  paramdef_t RUParams[] = RUPARAMS_DESC;
+  paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0};
+  config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL);
+
+  int j=0;
+  uint64_t ru_mask=1;
+  pthread_mutex_t ru_mutex; pthread_mutex_init(&ru_mutex,NULL);
+  pthread_cond_t ru_cond; pthread_cond_init(&ru_cond,NULL);
+
+  ru->ru_mask= &ru_mask;
+  ru->ru_mutex = &ru_mutex;
+  ru->ru_cond = &ru_cond;
+
+  ru->if_timing = synch_to_ext_device;
+  ru->num_eNB = 0;
+  ru->has_ctrl_prt = 1;
+  if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) {
+    ru->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr));
+  }
+
+  if (config_isparamset(RUParamList.paramarray[j], RU_SDR_CLK_SRC)) {
+    if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "internal") == 0) {
+      ru->openair0_cfg.clock_source = internal;
+      LOG_D(PHY, "RU clock source set as internal\n");
+    } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "external") == 0) {
+      ru->openair0_cfg.clock_source = external;
+      LOG_D(PHY, "RU clock source set as external\n");
+    } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "gpsdo") == 0) {
+      ru->openair0_cfg.clock_source = gpsdo;
+      LOG_D(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 {
+    ru->openair0_cfg.clock_source = unset;
+  }
+
+  if (config_isparamset(RUParamList.paramarray[j], RU_SDR_TME_SRC)) {
+    if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "internal") == 0) {
+      ru->openair0_cfg.time_source = internal;
+      LOG_D(PHY, "RU time source set as internal\n");
+    } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "external") == 0) {
+      ru->openair0_cfg.time_source = external;
+      LOG_D(PHY, "RU time source set as external\n");
+    } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "gpsdo") == 0) {
+      ru->openair0_cfg.time_source = gpsdo;
+      LOG_D(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 {
+    ru->openair0_cfg.time_source = unset;
+  }      
+
+  if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) {
+    if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) {
+      AssertFatal(1==0,"IF_NAME is required\n");
+    } else {
+      ru->eth_params.local_if_name            = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
+      ru->eth_params.my_addr                  = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
+      ru->eth_params.remote_addr              = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
+      ru->eth_params.my_portd                 = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
+      ru->eth_params.remote_portd             = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
+
+      // Check if control port set
+      if  (!(config_isparamset(RUParamList.paramarray[j],RU_REMOTE_PORTC_IDX)) ) {
+	printf("Removing control port for RU %d\n",j);
+	ru->has_ctrl_prt            = 0;
+      } else {
+	ru->eth_params.my_portc                 = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
+	ru->eth_params.remote_portc             = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
+	printf(" Control port %u \n",ru->eth_params.my_portc);
+      }
+
+      if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
+	ru->if_south                        = LOCAL_RF;
+	ru->function                        = NGFI_RRU_IF5;
+	ru->eth_params.transp_preference    = ETH_UDP_MODE;
+	printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j);
+      } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
+	ru->if_south                        = LOCAL_RF;
+	ru->function                        = NGFI_RRU_IF5;
+	ru->eth_params.transp_preference    = ETH_RAW_MODE;
+	printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j);
+      } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
+	ru->if_south                        = LOCAL_RF;
+	ru->function                        = NGFI_RRU_IF4p5;
+	ru->eth_params.transp_preference    = ETH_UDP_IF4p5_MODE;
+	printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j);
+      } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
+	ru->if_south                        = LOCAL_RF;
+	ru->function                        = NGFI_RRU_IF4p5;
+	ru->eth_params.transp_preference    = ETH_RAW_IF4p5_MODE;
+	printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j);
+      }
+
+      printf("RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr));
+
+      if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) ru->is_slave=1;
+      else ru->is_slave=0;
+
+      printf("RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr));
+
+      if (strcmp(*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr), "yes") == 0) ru->ota_sync_enable=1;
+      else ru->ota_sync_enable=0;
+    }
+
+    ru->max_pdschReferenceSignalPower     = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);;
+    ru->max_rxgain                        = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr);
+    ru->num_bands                         = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt;
+    /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */
+    ru->sf_extension                      = *(RUParamList.paramarray[j][RU_SF_EXTENSION_IDX].uptr);
+
+    for (int i=0; i<ru->num_bands; i++) ru->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
+  } //strcmp(local_rf, "yes") == 0
+  else {
+    printf("RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr));
+    ru->eth_params.local_if_name      = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
+    ru->eth_params.my_addr            = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
+    ru->eth_params.remote_addr        = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
+    ru->eth_params.my_portc           = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
+    ru->eth_params.remote_portc       = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
+    ru->eth_params.my_portd           = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
+    ru->eth_params.remote_portd       = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
+
+    if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
+      ru->if_south                     = REMOTE_IF5;
+      ru->function                     = NGFI_RAU_IF5;
+      ru->eth_params.transp_preference = ETH_UDP_MODE;
+    } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
+      ru->if_south                     = REMOTE_IF5;
+      ru->function                     = NGFI_RAU_IF5;
+      ru->eth_params.transp_preference = ETH_RAW_MODE;
+    } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
+      ru->if_south                     = REMOTE_IF4p5;
+      ru->function                     = NGFI_RAU_IF4p5;
+      ru->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
+    } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
+      ru->if_south                     = REMOTE_IF4p5;
+      ru->function                     = NGFI_RAU_IF4p5;
+      ru->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
+    }
+
+    if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) ru->is_slave=1;
+    else ru->is_slave=0;
+  }  /* strcmp(local_rf, "yes") != 0 */
+      
+  ru->nb_tx                             = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr);
+  ru->nb_rx                             = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr);
+  ru->att_tx                            = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr);
+  ru->att_rx                            = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr);
+
+
+  set_worker_conf("WORKER_ENABLE");
+
+  mlockall(MCL_CURRENT | MCL_FUTURE);
+  pthread_cond_init(&sync_cond,NULL);
+  pthread_mutex_init(&sync_mutex, NULL);
+ 
+  init_RU0(ru,0,get_softmodem_params()->rf_config_file,get_softmodem_params()->send_dmrs_sync);
+  ru->rf_map.card=0;
+  ru->rf_map.chain=(get_softmodem_params()->chain_offset);
+
+  LOG_I(PHY, "Initializing RRU descriptor : (%s,%s,%d)\n", ru_if_types[ru->if_south], NB_timing[ru->if_timing], ru->function);
+  set_function_spec_param(ru);
+  LOG_I(PHY, "Starting ru_thread , is_slave %d, send_dmrs %d\n", ru->is_slave, ru->generate_dmrs_sync);
+  init_RU_proc(ru);
+
+  pthread_mutex_lock(&ru_mutex);
+  while (ru_mask>0) 
+    pthread_cond_wait(&ru_cond,&ru_mutex);
+  pthread_mutex_unlock(&ru_mutex);
+  LOG_I(PHY,"RU configured, unlocking threads\n"); 
+  config_sync_var=0;
+  pthread_mutex_lock(&sync_mutex);
+  sync_var=0;
+  pthread_cond_broadcast(&sync_cond);
+  pthread_mutex_unlock(&sync_mutex);
+ 
+  while (oai_exit==0) sleep(1);
+  // stop threads
+      
+  kill_RU_proc(ru);
+  phy_free_RU(ru);
+      
+  free_lte_top();
+  end_configmodule();
+      
+  if (ru->rfdevice.trx_end_func) {
+    ru->rfdevice.trx_end_func(&ru->rfdevice);
+    ru->rfdevice.trx_end_func = NULL;
+  }
+      
+  if (ru->ifdevice.trx_end_func) {
+    ru->ifdevice.trx_end_func(&ru->ifdevice);
+    ru->ifdevice.trx_end_func = NULL;
+  }
+      
+  
+      
+  logClean();
+  printf("Bye.\n");
+  return 0;
+}
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index 71996cfd2989eb113a32acdae7ab2f0603f49d6c..e9319f9d3c1070bc604662e481e352d26d4800f3 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -81,10 +81,13 @@
 
 #include "s1ap_eNB.h"
 #include "SIMULATION/ETH_TRANSPORT/proto.h"
-
+#include <executables/softmodem-common.h>
 
 #include "T.h"
 #include "nfapi/oai_integration/vendor_ext.h"
+#include <nfapi/oai_integration/nfapi_pnf.h>
+#include <openair1/PHY/NR_TRANSPORT/nr_ulsch.h>
+#include <PHY/NR_ESTIMATION/nr_ul_estimation.h>
 //#define DEBUG_THREADS 1
 
 //#define USRP_DEBUG 1
@@ -92,17 +95,6 @@
 // extern openair0_device openair0;
 
 
-extern volatile int start_gNB;
-extern volatile int start_UE;
-extern volatile int oai_exit;
-
-extern openair0_config_t openair0_cfg[MAX_CARDS];
-
-extern int transmission_mode;
-
-extern uint16_t sf_ahead;
-extern uint16_t sl_ahead;
-
 //pthread_t                       main_gNB_thread;
 
 time_stats_t softmodem_stats_mt; // main thread
@@ -111,40 +103,43 @@ time_stats_t softmodem_stats_rxtx_sf; // total tx time
 time_stats_t nfapi_meas; // total tx time
 time_stats_t softmodem_stats_rx_sf; // total rx time
 
-/* mutex, cond and variable to serialize phy proc TX calls
- * (this mechanism may be relaxed in the future for better
- * performances)
- */
-static struct {
-  pthread_mutex_t  mutex_phy_proc_tx;
-  pthread_cond_t   cond_phy_proc_tx;
-  volatile uint8_t phy_proc_CC_id;
-} sync_phy_proc;
 
-extern double cpuf;
+#include "executables/thread-common.h"
+
 
-void init_gNB(int,int);
-void stop_gNB(int nb_inst);
+//#define TICK_TO_US(ts) (ts.diff)
+#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
 
-int wakeup_txfh(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int frame_tx, int slot_tx, uint64_t timestamp_tx);
-int wakeup_tx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, uint64_t timestamp_tx);
-#include "executables/thread-common.h"
-//extern PARALLEL_CONF_t get_thread_parallel_conf(void);
-//extern WORKER_CONF_t   get_thread_worker_conf(void);
 
+void tx_func(void *param) {
 
-void wakeup_prach_gNB(PHY_VARS_gNB *gNB, RU_t *ru, int frame, int subframe);
+  processingData_L1_t *info = (processingData_L1_t *) param;
+  PHY_VARS_gNB *gNB = info->gNB;
+  int frame_tx = info->frame_tx;
+  int slot_tx = info->slot_tx;
 
-extern uint8_t nfapi_mode;
-extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
-extern void oai_slot_ind(uint16_t sfn, uint16_t slot);
-extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
+  phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
 
-//#define TICK_TO_US(ts) (ts.diff)
-#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
+  // start FH TX processing
+  notifiedFIFO_elt_t *res; 
+  res = pullTpool(gNB->resp_RU_tx, gNB->threadPool);
+  processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(res);
+  syncMsg->frame_tx = frame_tx;
+  syncMsg->slot_tx = slot_tx;
+  syncMsg->timestamp_tx = info->timestamp_tx;
+  syncMsg->ru = gNB->RU_list[0];
+  res->key = slot_tx;
+  pushTpool(gNB->threadPool, res);
+}
 
-static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) {
+void rx_func(void *param) {
 
+  processingData_L1_t *info = (processingData_L1_t *) param;
+  PHY_VARS_gNB *gNB = info->gNB;
+  int frame_rx = info->frame_rx;
+  int slot_rx = info->slot_rx;
+  int frame_tx = info->frame_tx;
+  int slot_tx = info->slot_tx;
   sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe;
   nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
 
@@ -235,22 +230,6 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
   rnti_to_remove_count = 0;
   if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
 
-  /*
-  // if this is IF5 or 3GPP_gNB
-  if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
-    wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
-  }
-  */
-  // Call the scheduler
-
-  pthread_mutex_lock(&gNB->UL_INFO_mutex);
-  gNB->UL_INFO.frame     = frame_rx;
-  gNB->UL_INFO.slot      = slot_rx;
-  gNB->UL_INFO.module_id = gNB->Mod_id;
-  gNB->UL_INFO.CC_id     = gNB->CC_id;
-  gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
-  pthread_mutex_unlock(&gNB->UL_INFO_mutex);
-  
   // RX processing
   int tx_slot_type         = nr_slot_select(cfg,frame_tx,slot_tx);
   int rx_slot_type         = nr_slot_select(cfg,frame_rx,slot_rx);
@@ -263,33 +242,47 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
     L1_nr_prach_procedures(gNB,frame_rx,slot_rx);
 
     //apply the rx signal rotation here
-    apply_nr_rotation_ul(&gNB->frame_parms,
-			 gNB->common_vars.rxdataF[0],
-			 slot_rx,
-			 0,
-			 gNB->frame_parms.Ncp==EXTENDED?12:14,
-			 gNB->frame_parms.ofdm_symbol_size);
-    
+    for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
+      apply_nr_rotation_ul(&gNB->frame_parms,
+                           gNB->common_vars.rxdataF[aa],
+                           slot_rx,
+                           0,
+                           gNB->frame_parms.Ncp==EXTENDED?12:14,
+                           gNB->frame_parms.ofdm_symbol_size);
+    }
     phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
   }
 
-  if (oai_exit) return(-1);
+  stop_meas( &softmodem_stats_rxtx_sf );
+  LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
 
-  // *****************************************
-  // TX processing for subframe n+sf_ahead
-  // run PHY TX procedures the one after the other for all CCs to avoid race conditions
-  // (may be relaxed in the future for performance reasons)
-  // *****************************************
+  // Call the scheduler
 
-  if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
+  start_meas(&gNB->ul_indication_stats);
+  pthread_mutex_lock(&gNB->UL_INFO_mutex);
+  gNB->UL_INFO.frame     = frame_rx;
+  gNB->UL_INFO.slot      = slot_rx;
+  gNB->UL_INFO.module_id = gNB->Mod_id;
+  gNB->UL_INFO.CC_id     = gNB->CC_id;
+  gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
+  pthread_mutex_unlock(&gNB->UL_INFO_mutex);
+  stop_meas(&gNB->ul_indication_stats);
+  
+  notifiedFIFO_elt_t *res; 
 
-    if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) {
-      phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
-    }
+  if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
+    res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
+    processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(res);
+    syncMsg->gNB = gNB;
+    syncMsg->frame_rx = frame_rx;
+    syncMsg->slot_rx = slot_rx;
+    syncMsg->frame_tx = frame_tx;
+    syncMsg->slot_tx = slot_tx;
+    syncMsg->timestamp_tx = info->timestamp_tx;
+    res->key = slot_tx;
+    pushTpool(gNB->threadPool, res);
   }
-
-  stop_meas( &softmodem_stats_rxtx_sf );
-  LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
+    
 #if 0
   LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
         softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now,
@@ -329,553 +322,60 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
         TICK_TO_US(gNB->ulsch_tc_intl2_stats)
        );
 #endif
-  return(0);
-}
-
-static void *gNB_L1_thread_tx(void *param) {
-  PHY_VARS_gNB *gNB        = (PHY_VARS_gNB *)param;
-  gNB_L1_proc_t *gNB_proc  = &gNB->proc;
-  gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB_proc->L1_proc_tx;
-  //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
-  char thread_name[100];
-
-  sprintf(thread_name,"gNB_L1_thread_tx\n");
-
-  while (!oai_exit) {
-    if (wait_on_condition(&L1_proc_tx->mutex,&L1_proc_tx->cond,&L1_proc_tx->instance_cnt,thread_name)<0) break;
-
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 1 );
-
-    if (oai_exit) break;
-
-    // *****************************************
-    // TX processing for subframe n+4
-    // run PHY TX procedures the one after the other for all CCs to avoid race conditions
-    // (may be relaxed in the future for performance reasons)
-    // *****************************************
-    int      frame_tx = L1_proc_tx->frame_tx;
-    int      slot_tx = L1_proc_tx->slot_tx;
-    uint64_t timestamp_tx = L1_proc_tx->timestamp_tx;
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx);
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx);
-    phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
-
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 1 );
-    pthread_mutex_lock( &L1_proc_tx->mutex );
-    L1_proc_tx->instance_cnt = -1;
-
-    // the thread can now be woken up
-    if (pthread_cond_signal(&L1_proc_tx->cond) != 0) {
-      LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
-      exit_fun( "ERROR pthread_cond_signal" );
-    }
-    pthread_mutex_unlock(&L1_proc_tx->mutex);
-
-    wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx);
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 0 );
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 );
-  }
-
-  return 0;
-}
-
-/*!
- * \brief The RX UE-specific and TX thread of gNB.
- * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-
-static void *gNB_L1_thread( void *param ) {
-  static int gNB_thread_rxtx_status;
-  PHY_VARS_gNB *gNB        = (PHY_VARS_gNB *)param;
-  gNB_L1_proc_t *gNB_proc  = &gNB->proc;
-  gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc;
-  //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
-  char thread_name[100];
-  // set default return value
-  // set default return value
-  gNB_thread_rxtx_status = 0;
-
-  sprintf(thread_name,"gNB_L1_thread");
-
-
-  while (!oai_exit) {
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 0 );
-    if (wait_on_condition(&L1_proc->mutex,&L1_proc->cond,&L1_proc->instance_cnt,thread_name)<0) break;
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 );
-
-    int frame_rx          = L1_proc->frame_rx;
-    int slot_rx           = L1_proc->slot_rx;
-    int frame_tx          = L1_proc->frame_tx;
-    int slot_tx           = L1_proc->slot_tx;
-    uint64_t timestamp_tx = L1_proc->timestamp_tx;
-
-
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,slot_tx);
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,slot_rx);
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,frame_tx);
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,frame_rx);
-
-    if (oai_exit) break;
-
-    if (gNB->CC_id==0) {
-      if (rxtx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,thread_name) < 0) break;
-    }
-
-    if (release_thread(&L1_proc->mutex,&L1_proc->instance_cnt,thread_name)<0) break;
-
-    if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)  wakeup_tx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,timestamp_tx);
-    else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(gNB,L1_proc,frame_tx,slot_tx,timestamp_tx);
-  } // while !oai_exit
-
-  LOG_D(PHY, " *** Exiting gNB thread RXn_TXnp4\n");
-  gNB_thread_rxtx_status = 0;
-  return &gNB_thread_rxtx_status;
-}
-
-
-#if 0 
-// Wait for gNB application initialization to be complete (gNB registration to MME)
-static void wait_system_ready (char *message, volatile int *start_flag) {
-  static char *indicator[] = {".    ", "..   ", "...  ", ".... ", ".....",
-                              " ....", "  ...", "   ..", "    .", "     "
-                             };
-  int i = 0;
-
-  while ((!oai_exit) && (*start_flag == 0)) {
-    LOG_N(EMU, message, indicator[i]);
-    fflush(stdout);
-    i = (i + 1) % (sizeof(indicator) / sizeof(indicator[0]));
-    usleep(200000);
-  }
-
-  LOG_D(EMU,"\n");
-}
-#endif
-
-
-
-
-
-void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct RU_t_s *ru) {
-  gNB_L1_proc_t *proc           = &gNB->proc;
-  gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
-  NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
-  RU_proc_t *ru_proc=&ru->proc;
-  proc->frame_rx    = frame_rx;
-  proc->slot_rx = slot_rx;
-  sl_ahead = sf_ahead*fp->slots_per_subframe;
-
-  if (!oai_exit) {
-    T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->slot_rx));
-    L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe);
-    L1_proc->frame_rx     = ru_proc->frame_rx;
-    L1_proc->slot_rx      = ru_proc->tti_rx;
-    L1_proc->frame_tx     = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
-    L1_proc->slot_tx      = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame;
-
-    if (rxtx(gNB,L1_proc->frame_rx,L1_proc->slot_rx,L1_proc->frame_tx,L1_proc->slot_tx,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id);
-
-    ru_proc->timestamp_tx = L1_proc->timestamp_tx;
-    ru_proc->tti_tx       = L1_proc->slot_tx;
-    ru_proc->frame_tx     = L1_proc->frame_tx;
-  }
-}
-
-int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx) {
-
-  RU_t *ru;
-  RU_proc_t *ru_proc;
-
-  int waitret = 0, ret = 0, time_ns = 1000*1000;
-  struct timespec now, abstime;
-  // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
-  // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1);
-  time_ns = time_ns/gNB->frame_parms.slots_per_subframe;
-  AssertFatal((ret = pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret);
-  while (proc->instance_cnt_RUs < 0) {
-    clock_gettime(CLOCK_REALTIME, &now);
-    abstime.tv_sec = now.tv_sec;
-    abstime.tv_nsec = now.tv_nsec + time_ns;
-
-    if (abstime.tv_nsec >= 1000*1000*1000) {
-      abstime.tv_nsec -= 1000*1000*1000;
-      abstime.tv_sec  += 1;
-    }
-    if((waitret = pthread_cond_timedwait(&proc->cond_RUs,&proc->mutex_RUs_tx,&abstime)) == 0) break; // this unlocks mutex_rxtx while waiting and then locks it again
-  }
-  proc->instance_cnt_RUs = -1;
-  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
-  AssertFatal((ret = pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret);
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0);
-
-  if (waitret == ETIMEDOUT) {
-    LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 1 slot times (500us)\n",frame_tx,slot_tx);
-
-    AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
-    gNB->proc.RU_mask_tx = 0;
-    AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
-    AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret);
-    proc->instance_cnt_RUs = 0;
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
-    AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret);
-
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1);
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0);
-
-    return(-1);
-  }
-
-  for(int i=0; i<gNB->num_RU; i++)
-  {
-    ru      = gNB->RU_list[i];
-    ru_proc = &ru->proc;
-
-
-    if (ru_proc->instance_cnt_gNBs == 0) {
-      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1);
-      LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->tti_tx, proc->frame_rx, proc->slot_rx);
-      AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
-      gNB->proc.RU_mask_tx = 0;
-      AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
-
-      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0);
-      return(-1);
-    }
-    AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret);
-
-    ru_proc->instance_cnt_gNBs = 0;
-    ru_proc->timestamp_tx = timestamp_tx;
-    ru_proc->tti_tx       = slot_tx;
-    ru_proc->frame_tx     = frame_tx;
-
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, ru_proc->instance_cnt_gNBs);
-
-    LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_tx);
-    // the thread can now be woken up
-    AssertFatal(pthread_cond_signal(&ru_proc->cond_gNBs) == 0,
-                "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
-    AssertFatal((ret=pthread_mutex_unlock(&ru_proc->mutex_gNBs))==0,"mutex_unlock returned %d\n",ret);
-
-  }
-  return(0);
 }
-
-int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx) {
-
-
-  gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx;
-
-  int ret;
- 
-  
-  AssertFatal((ret = pthread_mutex_lock(&L1_proc_tx->mutex))==0,"mutex_lock returns %d\n",ret);
-
-
-  while(L1_proc_tx->instance_cnt == 0) {
-    pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex);
-  }
-
-  L1_proc_tx->instance_cnt = 0;
-
-  
-  L1_proc_tx->slot_rx       = slot_rx;
-  L1_proc_tx->frame_rx      = frame_rx;
-  L1_proc_tx->slot_tx       = slot_tx;
-  L1_proc_tx->frame_tx      = frame_tx;
-  L1_proc_tx->timestamp_tx  = timestamp_tx;
-
- 
-  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1);
-  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0);
-  // the thread can now be woken up
-  // the thread can now be woken up
-  AssertFatal(pthread_cond_signal(&L1_proc_tx->cond) == 0, "ERROR pthread_cond_signal for gNB L1 thread\n");
-  
-  AssertFatal((ret=pthread_mutex_unlock(&L1_proc_tx->mutex))==0,"mutex_unlock returns %d\n",ret);
-
-  return(0);
-}
-
-int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
-  gNB_L1_proc_t *proc=&gNB->proc;
-  gNB_L1_rxtx_proc_t *L1_proc=&proc->L1_proc;
-  NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
-  RU_proc_t *ru_proc=&ru->proc;
-  int ret;
-  int i;
-  struct timespec abstime;
-  int time_ns = 50000;
-  int wait_timer = 0;
-  bool do_last_check = 1;
-  
-  AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret);
-  for (i=0; i<gNB->num_RU; i++) {
-    if (ru == gNB->RU_list[i]) {
-      if ((proc->RU_mask&(1<<i)) > 0)
-        LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
-              gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask);
-      proc->RU_mask |= (1<<i);
-    }
-  }
-  if (proc->RU_mask != (1<<gNB->num_RU)-1) {  // not all RUs have provided their information so return
-    LOG_E(PHY,"Not all RUs have provided their info\n");
-    AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"mutex_unlock returns %d\n",ret);
-    return(0);
-  }
-  else { // all RUs have provided their information so continue on and wakeup gNB processing
-    proc->RU_mask = 0;
-    AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret);
-  }
-
-  // wake up TX for subframe n+sf_ahead
-  // lock the TX mutex and make sure the thread is ready
-  while (wait_timer < 200) {
-    clock_gettime(CLOCK_REALTIME, &abstime);
-    abstime.tv_nsec = abstime.tv_nsec + time_ns;
-
-    if (abstime.tv_nsec >= 1000*1000*1000) {
-      abstime.tv_nsec -= 1000*1000*1000;
-      abstime.tv_sec  += 1;
-    }
-
-    AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
-
-    if (L1_proc->instance_cnt == 0) { // L1_thread is busy so wait for a bit
-      AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
-      wait_timer += 50;
-      usleep(50);
-    }
-    else {
-      do_last_check = 0;
-      break;
-    }
-  }
-  if (do_last_check) {
-    AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
-    if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe
-      AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
-      LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
-      return (-1);
-    }
-  }
-
-  ++L1_proc->instance_cnt;
-  // We have just received and processed the common part of a subframe, say n.
-  // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
-  // transmitted timestamp of the next TX slot (first).
-
-  // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, 
-  // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti,
-  // and proc->slot_tx = proc->slot_rx+sf_ahead
-  L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe);
-  L1_proc->frame_rx     = ru_proc->frame_rx;
-  L1_proc->slot_rx  = ru_proc->tti_rx;
-  L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
-  L1_proc->slot_tx  = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame;
-
-  LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sf_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sf_ahead);
-
-  pthread_mutex_unlock( &L1_proc->mutex );
-
-  // the thread can now be woken up
-  if (pthread_cond_signal(&L1_proc->cond) != 0) {
-    LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n");
-    exit_fun( "ERROR pthread_cond_signal" );
-    return(-1);
-  }
-
-  return(0);
-}
-/*
-void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe) {
-
-  gNB_L1_proc_t *proc = &gNB->proc;
-  LTE_DL_FRAME_PARMS *fp=&gNB->frame_parms;
-  int i;
-
-  if (ru!=NULL) {
-    pthread_mutex_lock(&proc->mutex_RU_PRACH);
-    for (i=0;i<gNB->num_RU;i++) {
-      if (ru == gNB->RU_list[i]) {
-  LOG_D(PHY,"frame %d, subframe %d: RU %d for gNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,gNB->Mod_id,proc->RU_mask_prach,gNB->num_RU);
-  if ((proc->RU_mask_prach&(1<<i)) > 0)
-    LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n",
-    gNB->Mod_id,frame,subframe,ru->idx,gNB->num_RU,proc->RU_mask_prach);
-  proc->RU_mask_prach |= (1<<i);
-      }
-    }
-    if (proc->RU_mask_prach != (1<<gNB->num_RU)-1) {  // not all RUs have provided their information so return
-      pthread_mutex_unlock(&proc->mutex_RU_PRACH);
-      return;
-    }
-    else { // all RUs have provided their information so continue on and wakeup gNB processing
-      proc->RU_mask_prach = 0;
-      pthread_mutex_unlock(&proc->mutex_RU_PRACH);
-    }
-  }
-
-  // check if we have to detect PRACH first
-  if (is_prach_subframe(fp,frame,subframe)>0) {
-    LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe);
-    if (proc->instance_cnt_prach == 0) {
-      LOG_W(PHY,"[gNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe);
-      return;
-    }
-
-    // wake up thread for PRACH RX
-    if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
-      LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach);
-      exit_fun( "error locking mutex_prach" );
-      return;
-    }
-
-    ++proc->instance_cnt_prach;
-    // set timing for prach thread
-    proc->frame_prach = frame;
-    proc->subframe_prach = subframe;
-
-    // the thread can now be woken up
-    if (pthread_cond_signal(&proc->cond_prach) != 0) {
-      LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB PRACH thread %d\n", proc->thread_index);
-      exit_fun( "ERROR pthread_cond_signal" );
-      return;
-    }
-
-    pthread_mutex_unlock( &proc->mutex_prach );
-  }
-
-}*/
-
-/*!
- * \brief The prach receive thread of gNB.
- * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-/*
-static void* gNB_thread_prach( void* param ) {
- static int gNB_thread_prach_status;
-
-
- PHY_VARS_gNB *gNB= (PHY_VARS_gNB *)param;
- gNB_L1_proc_t *proc = &gNB->proc;
-
- // set default return value
- gNB_thread_prach_status = 0;
-
-
-
- while (!oai_exit) {
-
-   if (oai_exit) break;
-
-
-   if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break;
-
-   LOG_D(PHY,"Running gNB prach procedures\n");
-   prach_procedures(gNB ,0);
-
-   if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break;
- }
-
- LOG_I(PHY, "Exiting gNB thread PRACH\n");
-
- gNB_thread_prach_status = 0;
- return &gNB_thread_prach_status;
-}
-*/
-
-extern void init_td_thread(PHY_VARS_gNB *);
-extern void init_te_thread(PHY_VARS_gNB *);
-
 static void *process_stats_thread(void *param) {
 
   PHY_VARS_gNB *gNB  = (PHY_VARS_gNB *)param;
 
+  reset_meas(&gNB->phy_proc_tx);
   reset_meas(&gNB->dlsch_encoding_stats);
-  reset_meas(&gNB->dlsch_scrambling_stats);
-  reset_meas(&gNB->dlsch_modulation_stats);
+  reset_meas(&gNB->phy_proc_rx);
+  reset_meas(&gNB->ul_indication_stats);
+  reset_meas(&gNB->rx_pusch_stats);
+  reset_meas(&gNB->ulsch_decoding_stats);
 
   wait_sync("process_stats_thread");
 
   while(!oai_exit)
   {
     sleep(1);
-    print_meas(&gNB->dlsch_encoding_stats, "pdsch_encoding", NULL, NULL);
-    print_meas(&gNB->dlsch_scrambling_stats, "pdsch_scrambling", NULL, NULL);
-    print_meas(&gNB->dlsch_modulation_stats, "pdsch_modulation", NULL, NULL);
+    print_meas(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL);
+    print_meas(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL);
+    print_meas(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL);
+    print_meas(&gNB->ul_indication_stats, "UL Indication", NULL, NULL);
+    print_meas(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL);
+    print_meas(&gNB->ulsch_decoding_stats, "PUSCH decoding", NULL, NULL);
   }
   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 nrL1_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_proc(int inst) {
-  int i=0;
-  int CC_id = 0;
+void init_gNB_Tpool(int inst) {
   PHY_VARS_gNB *gNB;
-  gNB_L1_proc_t *proc;
-  gNB_L1_rxtx_proc_t *L1_proc,*L1_proc_tx;
-//  LOG_I(PHY,"%s(inst:%d) RC.nb_nr_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_nr_CC[inst]);
   gNB = RC.gNB[inst];
-  LOG_I(PHY,"Initializing gNB processes instance:%d CC_id %d \n",inst,CC_id);
-  
-  proc = &gNB->proc;
-  L1_proc                        = &proc->L1_proc;
-  L1_proc_tx                     = &proc->L1_proc_tx;
-  L1_proc->instance_cnt          = -1;
-  L1_proc_tx->instance_cnt       = -1;
-  L1_proc->instance_cnt_RUs      = 0;
-  L1_proc_tx->instance_cnt_RUs   = 0;
-  proc->instance_cnt_prach       = -1;
-  proc->instance_cnt_asynch_rxtx = -1;
-  proc->CC_id                    = CC_id;
-  proc->first_rx                 =1;
-  proc->first_tx                 =1;
-  proc->RU_mask                  =0;
-  proc->RU_mask_tx               = (1<<gNB->num_RU)-1;
-  proc->RU_mask_prach            =0;
-  pthread_mutex_init( &gNB->UL_INFO_mutex, NULL);
-  pthread_mutex_init( &L1_proc->mutex, NULL);
-  pthread_mutex_init( &L1_proc_tx->mutex, NULL);
-  pthread_cond_init( &L1_proc->cond, NULL);
-  pthread_cond_init( &L1_proc_tx->cond, NULL);
-  pthread_mutex_init( &proc->mutex_prach, NULL);
-  pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
-  pthread_mutex_init( &proc->mutex_RU,NULL);
-  pthread_mutex_init( &proc->mutex_RU_tx,NULL);
-  pthread_mutex_init( &proc->mutex_RU_PRACH,NULL);
-  pthread_cond_init( &proc->cond_prach, NULL);
-  pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
-  LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag);
-  
-  if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
-    threadCreate( &L1_proc->pthread, gNB_L1_thread, gNB, "L1_proc", -1, OAI_PRIORITY_RT );
-    threadCreate( &L1_proc_tx->pthread, gNB_L1_thread_tx, gNB,"L1_proc_tx", -1, OAI_PRIORITY_RT);
-  }
-  
-  if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
-  //pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB );
-  char name[16];
-  
-  if (gNB->single_thread_flag==0) {
-    snprintf( name, sizeof(name), "L1 %d", i );
-    pthread_setname_np( L1_proc->pthread, name );
-    snprintf( name, sizeof(name), "L1TX %d", i );
-    pthread_setname_np( L1_proc_tx->pthread, name );
-  }
-  
-  AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);
-
-  /* setup PHY proc TX sync mechanism */
-  pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
-  pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
-  sync_phy_proc.phy_proc_CC_id = 0;
+  gNB_L1_proc_t *proc = &gNB->proc;
 
+  // ULSCH decoding threadpool
   gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
-  gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
   int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
+  LOG_I(PHY,"Number of threads requested in config file: %d, Number of threads available on this machine: %d\n",gNB->pusch_proc_threads,numCPU);
   int threadCnt = min(numCPU, gNB->pusch_proc_threads);
+  if (threadCnt < 2) LOG_E(PHY,"Number of threads for gNB should be more than 1. Allocated only %d\n",threadCnt);
   char ul_pool[80];
   sprintf(ul_pool,"-1");
   int s_offset = 0;
@@ -883,71 +383,44 @@ void init_gNB_proc(int inst) {
     sprintf(ul_pool+2+s_offset,",-1");
     s_offset += 3;
   }
+  if (getenv("noThreads")) strcpy(ul_pool, "n");
   initTpool(ul_pool, gNB->threadPool, false);
+  // ULSCH decoder result FIFO
+  gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
   initNotifiedFIFO(gNB->respDecode);
-}
 
+  // L1 RX result FIFO 
+  gNB->resp_L1 = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
+  initNotifiedFIFO(gNB->resp_L1);
+
+  // L1 TX result FIFO 
+  gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
+  initNotifiedFIFO(gNB->resp_L1_tx);
+
+  // RU TX result FIFO 
+  gNB->resp_RU_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
+  initNotifiedFIFO(gNB->resp_RU_tx);
+
+  // Stats measurement thread
+  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);
+
+}
 
 
 /*!
  * \brief Terminate gNB TX and RX threads.
  */
 void kill_gNB_proc(int inst) {
-  int *status;
   PHY_VARS_gNB *gNB;
-  gNB_L1_proc_t *proc;
-  gNB_L1_rxtx_proc_t *L1_proc, *L1_proc_tx;
 
   gNB=RC.gNB[inst];
-  proc = &gNB->proc;
-  L1_proc     = &proc->L1_proc;
-  L1_proc_tx  = &proc->L1_proc_tx;
-  LOG_I(PHY, "Killing TX inst %d\n",inst );
-  
-  if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
-    pthread_mutex_lock(&L1_proc->mutex);
-    L1_proc->instance_cnt = 0;
-    pthread_cond_signal(&L1_proc->cond);
-    pthread_mutex_unlock(&L1_proc->mutex);
-    pthread_mutex_lock(&L1_proc_tx->mutex);
-    L1_proc_tx->instance_cnt = 0;
-    pthread_cond_signal(&L1_proc_tx->cond);
-    pthread_mutex_unlock(&L1_proc_tx->mutex);
-  }
   
-  proc->instance_cnt_prach = 0;
-  pthread_cond_signal( &proc->cond_prach );
-  pthread_cond_signal( &proc->cond_asynch_rxtx );
-  pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
-  //    LOG_D(PHY, "joining pthread_prach\n");
-  //    pthread_join( proc->pthread_prach, (void**)&status );
-  LOG_I(PHY, "Destroying prach mutex/cond\n");
-  pthread_mutex_destroy( &proc->mutex_prach );
-  pthread_cond_destroy( &proc->cond_prach );
   LOG_I(PHY, "Destroying UL_INFO mutex\n");
   pthread_mutex_destroy(&gNB->UL_INFO_mutex);
   
-  if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
-    LOG_I(PHY, "Joining L1_proc mutex/cond\n");
-    pthread_join( L1_proc->pthread, (void **)&status );
-    LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n");
-    pthread_join( L1_proc_tx->pthread, (void **)&status );
-  }
-  
-  LOG_I(PHY, "Destroying L1_proc mutex/cond\n");
-  pthread_mutex_destroy( &L1_proc->mutex );
-  pthread_cond_destroy( &L1_proc->cond );
-  LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n");
-  pthread_mutex_destroy( &L1_proc_tx->mutex );
-  pthread_cond_destroy( &L1_proc_tx->cond );
-  pthread_mutex_destroy( &proc->mutex_RU );
-  pthread_mutex_destroy( &proc->mutex_RU_tx );
-  
 }
 
-
-
-
 void reset_opp_meas(void) {
   int sfn;
   reset_meas(&softmodem_stats_mt);
@@ -1015,15 +488,9 @@ printf("after %p\n", gNB->common_vars.rxdataF[aa]);
      * (not tested in other modes).
      */
     //init_precoding_weights(RC.gNB[inst]);
-    init_gNB_proc(inst);
+    init_gNB_Tpool(inst);
   }
 
-  for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
-    AssertFatal(RC.ru[ru_id]!=NULL,"ru_id %d is null\n",ru_id);
-    RC.ru[ru_id]->nr_wakeup_rxtx         = wakeup_rxtx;
-    //    RC.ru[ru_id]->wakeup_prach_eNB    = wakeup_prach_gNB;
-    RC.ru[ru_id]->gNB_top             = gNB_top;
-  }
 }
 
 void init_gNB(int single_thread_flag,int wait_for_sync) {
@@ -1032,18 +499,16 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
   PHY_VARS_gNB *gNB;
 
   if (RC.gNB == NULL) {
-    RC.gNB = (PHY_VARS_gNB **) malloc((1+RC.nb_nr_L1_inst)*sizeof(PHY_VARS_gNB *));
-    for (inst=0; inst<RC.nb_nr_L1_inst; inst++) {
-      RC.gNB[inst] = (PHY_VARS_gNB *) malloc(sizeof(PHY_VARS_gNB));
-      memset((void*)RC.gNB[inst],0,sizeof(PHY_VARS_gNB));
-    }
+    RC.gNB = (PHY_VARS_gNB **) calloc(1+RC.nb_nr_L1_inst, sizeof(PHY_VARS_gNB *));
+    LOG_I(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB);
   }
 
-  LOG_I(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB);
-
   for (inst=0; inst<RC.nb_nr_L1_inst; inst++) {
 
-    LOG_I(PHY,"[lte-softmodem.c] gNB structure RC.gNB[%d] allocated @ %p\n",inst,RC.gNB[inst]);
+    if (RC.gNB[inst] == NULL) {
+      RC.gNB[inst] = (PHY_VARS_gNB *) calloc(1, sizeof(PHY_VARS_gNB));
+      LOG_I(PHY,"[nr-gnb.c] gNB structure RC.gNB[%d] allocated @ %p\n",inst,RC.gNB[inst]);
+    }
     gNB                     = RC.gNB[inst];
     gNB->abstraction_flag   = 0;
     gNB->single_thread_flag = single_thread_flag;
@@ -1073,7 +538,7 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
   }
   
 
-  LOG_I(PHY,"[nr-softmodem.c] gNB structure allocated\n");
+  LOG_I(PHY,"[nr-gnb.c] gNB structure allocated\n");
 }
 
 
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 73421d8ed7c71fa9249bfff51cbc1afcd8bf9416..2de04f4e7fc9035e005892d43322a72cc3569b49 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
@@ -89,7 +77,7 @@ static int DEFBFW[] = {0x00007fff};
 
 #include "s1ap_eNB.h"
 #include "SIMULATION/ETH_TRANSPORT/proto.h"
-
+#include <openair1/PHY/TOOLS/phy_scope_interface.h>
 
 
 #include "T.h"
@@ -112,6 +100,7 @@ void configure_ru(int idx, void *arg);
 void configure_rru(int idx, void *arg);
 int attach_rru(RU_t *ru);
 int connect_rau(RU_t *ru);
+static void NRRCconfig_RU(void);
 
 uint16_t sf_ahead;
 uint16_t slot_ahead;
@@ -119,15 +108,13 @@ uint16_t sl_ahead;
 
 extern int emulate_rf;
 extern int numerology;
-extern int usrp_tx_thread;
 
 /*************************************************************/
 /* Functions to attach and configure RRU                     */
 
 extern void wait_gNBs(void);
 
-int attach_rru(RU_t *ru)
-{
+int attach_rru(RU_t *ru) {
   ssize_t      msg_len,len;
   RRU_CONFIG_msg_t rru_config_msg;
   int received_capabilities=0;
@@ -195,8 +182,7 @@ int attach_rru(RU_t *ru)
   return 0;
 }
 
-int connect_rau(RU_t *ru)
-{
+int connect_rau(RU_t *ru) {
   RRU_CONFIG_msg_t   rru_config_msg;
   ssize_t            msg_len;
   int                tick_received          = 0;
@@ -293,22 +279,20 @@ int connect_rau(RU_t *ru)
 /* Southbound Fronthaul functions, RCC/RAU                   */
 
 // southbound IF5 fronthaul for 16-bit OAI format
-void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
-{
+void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) {
   if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
 
   send_IF5(ru, timestamp, slot, &ru->seqno, IF5_RRH_GW_DL);
 }
 
 // southbound IF4p5 fronthaul
-void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
-{
+void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) {
   nfapi_nr_config_request_scf_t *cfg = &ru->config;
+
   if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
 
   LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx);
 
-
   if ((nr_slot_select(cfg,ru->proc.frame_tx,ru->proc.tti_tx)&NR_DOWNLINK_SLOT) > 0)
     send_IF4p5(ru,frame, slot, IF4p5_PDLFFT);
 }
@@ -319,8 +303,7 @@ void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
 // Synchronous if5 from south
 void fh_if5_south_in(RU_t *ru,
                      int *frame,
-                     int *tti)
-{
+                     int *tti) {
   NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
   RU_proc_t *proc = &ru->proc;
   recv_IF5(ru, &proc->timestamp_rx, *tti, IF5_RRH_GW_UL);
@@ -350,8 +333,7 @@ void fh_if5_south_in(RU_t *ru,
 // Synchronous if4p5 from south
 void fh_if4p5_south_in(RU_t *ru,
                        int *frame,
-                       int *slot)
-{
+                       int *slot) {
   NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
   RU_proc_t *proc = &ru->proc;
   int f,sl;
@@ -648,7 +630,6 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
                                      ru->nb_rx);
   }
 
-
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
   proc->timestamp_rx = ts-ru->ts_offset;
 
@@ -661,6 +642,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
     proc->timestamp_rx = 0;
   } else {
     samples_per_slot_prev = fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp);
+
     if (proc->timestamp_rx - old_ts != samples_per_slot_prev) {
       LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - samples_per_slot_prev,ru->ts_offset);
       ru->ts_offset += (proc->timestamp_rx - old_ts - samples_per_slot_prev);
@@ -690,7 +672,8 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
     }
 
     if (proc->frame_rx != *frame) {
-      LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, proc->tti_rx %d, slot %d)\n",(long long unsigned int)proc->timestamp_rx,proc->frame_rx,*frame,proc->tti_rx,*slot);
+      LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, proc->tti_rx %d, slot %d)\n",(long long unsigned int)proc->timestamp_rx,proc->frame_rx,
+            *frame,proc->tti_rx,*slot);
       exit_fun("Exiting");
     }
   } else {
@@ -718,7 +701,6 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
   int i,txsymb;
   T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot),
     T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp,0)], fp->samples_per_subframe * 4));
-
   int slot_type         = nr_slot_select(cfg,frame,slot%fp->slots_per_frame);
   int prevslot_type     = nr_slot_select(cfg,frame,(slot+(fp->slots_per_frame-1))%fp->slots_per_frame);
   int nextslot_type     = nr_slot_select(cfg,frame,(slot+1)%fp->slots_per_frame);
@@ -728,20 +710,23 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
 
   //nr_subframe_t SF_type     = nr_slot_select(cfg,slot%fp->slots_per_frame);
   if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT || IS_SOFTMODEM_RFSIM) {
-
-    if (cfg->cell_config.frame_duplex_type.value == TDD){
+    if (cfg->cell_config.frame_duplex_type.value == TDD) {
       if(slot_type == NR_MIXED_SLOT) {
         txsymb = 0;
+
         for(int symbol_count = 0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
           if (cfg->tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value == 0)
             txsymb++;
         }
+
         AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb);
+
         if(slot%(fp->slots_per_subframe/2))
           siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
         else
           siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
-                 //+ ru->end_of_burst_delay;
+
+        //+ ru->end_of_burst_delay;
         flags = 3; // end of burst
       }
 
@@ -755,341 +740,150 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
     if (fp->freq_range==nr_FR2) {
       // the beam index is written in bits 8-10 of the flags
       // bit 11 enables the gpio programming
+      // currently we switch beams every 10 slots (should = 1 TDD period in FR2) and we take the beam index of the first symbol of the first slot of this period
       int beam=0;
-      //if (slot==0) beam = 11; //3 for boresight & 8 to enable
+
+      if (slot%10==0) {
+        if ( ru->common.beam_id && (ru->common.beam_id[0][slot*fp->symbols_per_slot] < 8)) {
+          beam = ru->common.beam_id[0][slot*fp->symbols_per_slot] | 8;
+        }
+      }
+
       /*
-      if (slot==0 || slot==40) beam=0&8;
-      if (slot==10 || slot==50) beam=1&8;
-      if (slot==20 || slot==60) beam=2&8;
-      if (slot==30 || slot==70) beam=3&8;
+      if (slot==0 || slot==40) beam=0|8;
+      if (slot==10 || slot==50) beam=1|8;
+      if (slot==20 || slot==60) beam=2|8;
+      if (slot==30 || slot==70) beam=3|8;
       */
       flags |= beam<<8;
+      LOG_D(HW,"slot %d, beam %d\n",slot,ru->common.beam_id[0][slot*fp->symbols_per_slot]);
     }
 
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags ); 
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags );
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame );
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot );
+
     for (i=0; i<ru->nb_tx; i++)
       txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot,fp,0)-sf_extension];
-    
-      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
-      // prepare tx buffer pointers
-      txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
-					timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
-					txp,
-					siglen+sf_extension,
-					ru->nb_tx,
-					flags);
-      LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, slot %di, returned %d\n",ru->idx,
-	    (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot, txs);
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
-      //AssertFatal(txs == 0,"trx write function error %d\n", txs);
-  }
-}
-
-
-
-/*!
- * \brief The Asynchronous RX/TX FH thread of RAU/RCC/gNB/RRU.
- * This handles the RX FH for an asynchronous RRU/UE
- * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-void *ru_thread_asynch_rxtx( void *param ) {
-  static int ru_thread_asynch_rxtx_status;
-  RU_t *ru         = (RU_t *)param;
-  RU_proc_t *proc  = &ru->proc;
-  nfapi_nr_config_request_scf_t *cfg = &ru->config;
-  int slot=0, frame=0;
-  // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
-  wait_sync("ru_thread_asynch_rxtx");
-  // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
-  printf( "waiting for devices (ru_thread_asynch_rx)\n");
-  wait_on_condition(&proc->mutex_asynch_rxtx,&proc->cond_asynch_rxtx,&proc->instance_cnt_asynch_rxtx,"thread_asynch");
-  printf( "devices ok (ru_thread_asynch_rx)\n");
-
-  while (!oai_exit) {
-
-    if (slot==ru->nr_frame_parms->slots_per_frame) {
-      slot=0;
-      frame++;
-      frame&=1023;
-    } else {
-      slot++;
-    }
-
-    LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n");
-
-    // asynchronous receive from north (RRU IF4/IF5)
-    if (ru->fh_north_asynch_in) {
-      if ((nr_slot_select(cfg,frame,slot) & NR_DOWNLINK_SLOT)>0)
-        ru->fh_north_asynch_in(ru,&frame,&slot);
-    } else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n");
-  }
-
-  ru_thread_asynch_rxtx_status=0;
-  return(&ru_thread_asynch_rxtx_status);
-}
-
 
-
-
-/*!
- * \brief The prach receive thread of RU.
- * \param param is a \ref RU_proc_t structure which contains the info what to process.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-void *ru_thread_prach( void *param ) {
-  static int ru_thread_prach_status;
-  RU_t *ru        = (RU_t *)param;
-  RU_proc_t *proc = (RU_proc_t *)&ru->proc;
-  // set default return value
-  ru_thread_prach_status = 0;
-
-  while (RC.ru_mask>0) {
-    usleep(1e6);
-    LOG_I(PHY,"%s() RACH waiting for RU to be configured\n", __FUNCTION__);
-  }
-
-  LOG_I(PHY,"%s() RU configured - RACH processing thread running\n", __FUNCTION__);
-
-  while (!oai_exit) {
-    
-
-    if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break;
-
-    /*VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 );
-
-    if (ru->gNB_list[0]){
-      prach_procedures(
-        ru->gNB_list[0],0
-        );
-    }
-    else {
-       rx_prach(NULL,
-            ru,
-          NULL,
-                NULL,
-                NULL,
-                proc->frame_prach,
-                0,0
-          );
-    }
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );*/
-    if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break;
-  }
-
-  LOG_I(PHY, "Exiting RU thread PRACH\n");
-  ru_thread_prach_status = 0;
-  return &ru_thread_prach_status;
-}
-
-
-int wakeup_synch(RU_t *ru) {
-  struct timespec wait;
-  wait.tv_sec=0;
-  wait.tv_nsec=5000000L;
-
-  // wake up synch thread
-  // lock the synch mutex and make sure the thread is ready
-  if (pthread_mutex_timedlock(&ru->proc.mutex_synch,&wait) != 0) {
-    LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for RU synch thread (IC %d)\n", ru->proc.instance_cnt_synch );
-    exit_fun( "error locking mutex_synch" );
-    return(-1);
-  }
-
-  ++ru->proc.instance_cnt_synch;
-
-  // the thread can now be woken up
-  if (pthread_cond_signal(&ru->proc.cond_synch) != 0) {
-    LOG_E( PHY, "[RU] ERROR pthread_cond_signal for RU synch thread\n");
-    exit_fun( "ERROR pthread_cond_signal" );
-    return(-1);
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
+    // prepare tx buffer pointers
+    txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
+                                      timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
+                                      txp,
+                                      siglen+sf_extension,
+                                      ru->nb_tx,
+                                      flags);
+    LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, slot %di, returned %d\n",ru->idx,
+          (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot, txs);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
+    //AssertFatal(txs == 0,"trx write function error %d\n", txs);
   }
-
-  pthread_mutex_unlock( &ru->proc.mutex_synch );
-  return(0);
 }
 
-void do_ru_synch(RU_t *ru) {
-  NR_DL_FRAME_PARMS *fp  = ru->nr_frame_parms;
-  RU_proc_t *proc         = &ru->proc;
+// this is for RU with local RF unit
+void fill_rf_config(RU_t *ru, char *rf_config_file) {
   int i;
-  void *rxp[2],*rxp2[2];
-  int32_t dummy_rx[ru->nb_rx][fp->samples_per_subframe] __attribute__((aligned(32)));
-  int rxs;
-  int ic;
-
-  // initialize the synchronization buffer to the common_vars.rxdata
-  for (int i=0; i<ru->nb_rx; i++)
-    rxp[i] = &ru->common.rxdata[i][0];
-
-  double temp_freq1 = ru->rfdevice.openair0_cfg->rx_freq[0];
-  double temp_freq2 = ru->rfdevice.openair0_cfg->tx_freq[0];
-
-  for (i=0; i<4; i++) {
-    ru->rfdevice.openair0_cfg->rx_freq[i] = ru->rfdevice.openair0_cfg->tx_freq[i];
-    ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq1;
-  }
-
-  ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0);
-
-  while ((ru->in_synch ==0)&&(!oai_exit)) {
-    // read in frame
-    rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
-                                     &(proc->timestamp_rx),
-                                     rxp,
-                                     fp->samples_per_subframe*10,
-                                     ru->nb_rx);
-
-    if (rxs != fp->samples_per_subframe*10) LOG_E(PHY,"requested %d samples, got %d\n",fp->samples_per_subframe*10,rxs);
-
-    // wakeup synchronization processing thread
-    wakeup_synch(ru);
-    ic=0;
-
-    while ((ic>=0)&&(!oai_exit)) {
-      // continuously read in frames, 1ms at a time,
-      // until we are done with the synchronization procedure
-      for (i=0; i<ru->nb_rx; i++)
-        rxp2[i] = (void *)&dummy_rx[i][0];
-
-      for (i=0; i<10; i++)
-        rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
-                                         &(proc->timestamp_rx),
-                                         rxp2,
-                                         fp->samples_per_subframe,
-                                         ru->nb_rx);
-
-      pthread_mutex_lock(&ru->proc.mutex_synch);
-      ic = ru->proc.instance_cnt_synch;
-      pthread_mutex_unlock(&ru->proc.mutex_synch);
-    } // ic>=0
-  } // in_synch==0
-
-  // read in rx_offset samples
-  LOG_I(PHY,"Resynchronizing by %d samples\n",ru->rx_offset);
-  rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
-                                   &(proc->timestamp_rx),
-                                   rxp,
-                                   ru->rx_offset,
-                                   ru->nb_rx);
-
-  for (i=0; i<4; i++) {
-    ru->rfdevice.openair0_cfg->rx_freq[i] = temp_freq1;
-    ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq2;
-  }
-
-  ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0);
-}
+  NR_DL_FRAME_PARMS *fp   = ru->nr_frame_parms;
+  nfapi_nr_config_request_scf_t *config = &ru->config; //tmp index
+  openair0_config_t *cfg   = &ru->openair0_cfg;
+  int mu = config->ssb_config.scs_common.value;
+  int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value;
 
+  if (mu == NR_MU_0) {
+    switch(N_RB) {
+      case 270:
+        if (fp->threequarter_fs) {
+          cfg->sample_rate=92.16e6;
+          cfg->samples_per_frame = 921600;
+          cfg->tx_bw = 50e6;
+          cfg->rx_bw = 50e6;
+        } else {
+          cfg->sample_rate=61.44e6;
+          cfg->samples_per_frame = 614400;
+          cfg->tx_bw = 50e6;
+          cfg->rx_bw = 50e6;
+        }
 
+      case 216:
+        if (fp->threequarter_fs) {
+          cfg->sample_rate=46.08e6;
+          cfg->samples_per_frame = 460800;
+          cfg->tx_bw = 40e6;
+          cfg->rx_bw = 40e6;
+        } else {
+          cfg->sample_rate=61.44e6;
+          cfg->samples_per_frame = 614400;
+          cfg->tx_bw = 40e6;
+          cfg->rx_bw = 40e6;
+        }
 
-void wakeup_gNB_L1s(RU_t *ru) {
-  int i;
-  PHY_VARS_gNB **gNB_list = ru->gNB_list;
-  LOG_D(PHY,"wakeup_gNB_L1s (num %d) for RU %d ru->gNB_top:%p\n",ru->num_gNB,ru->idx, ru->gNB_top);
-
-  if (ru->num_gNB==1 && ru->gNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) {
-    // call gNB function directly
-    char string[20];
-    sprintf(string,"Incoming RU %u",ru->idx);
-    LOG_D(PHY,"RU %d Call gNB_top\n",ru->idx);
-    ru->gNB_top(gNB_list[0],ru->proc.frame_rx,ru->proc.tti_rx,string,ru);
-  } else {
-    LOG_D(PHY,"ru->num_gNB:%d\n", ru->num_gNB);
+        break;
 
-    for (i=0; i<ru->num_gNB; i++) {
-      LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->nr_wakeup_rxtx);
+      case 106:
+        if (fp->threequarter_fs) {
+          cfg->sample_rate=23.04e6;
+          cfg->samples_per_frame = 230400;
+          cfg->tx_bw = 20e6;
+          cfg->rx_bw = 20e6;
+        } else {
+          cfg->sample_rate=30.72e6;
+          cfg->samples_per_frame = 307200;
+          cfg->tx_bw = 20e6;
+          cfg->rx_bw = 20e6;
+        }
 
-      if (ru->nr_wakeup_rxtx!=0 && ru->nr_wakeup_rxtx(gNB_list[i],ru) < 0) {
-        LOG_E(PHY,"could not wakeup gNB rxtx process for subframe %d\n", ru->proc.tti_rx);
-      }
-    }
-  }
-}
+        break;
 
-int wakeup_prach_ru(RU_t *ru) {
-  struct timespec wait;
-  wait.tv_sec=0;
-  wait.tv_nsec=5000000L;
+      case 52:
+        if (fp->threequarter_fs) {
+          cfg->sample_rate=11.52e6;
+          cfg->samples_per_frame = 115200;
+          cfg->tx_bw = 10e6;
+          cfg->rx_bw = 10e6;
+        } else {
+          cfg->sample_rate=15.36e6;
+          cfg->samples_per_frame = 153600;
+          cfg->tx_bw = 10e6;
+          cfg->rx_bw = 10e6;
+        }
 
-  if (pthread_mutex_timedlock(&ru->proc.mutex_prach,&wait) !=0) {
-    LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for RU prach thread (IC %d)\n", ru->proc.instance_cnt_prach);
-    exit_fun( "error locking mutex_rxtx" );
-    return(-1);
-  }
+      case 25:
+        if (fp->threequarter_fs) {
+          cfg->sample_rate=5.76e6;
+          cfg->samples_per_frame = 57600;
+          cfg->tx_bw = 5e6;
+          cfg->rx_bw = 5e6;
+        } else {
+          cfg->sample_rate=7.68e6;
+          cfg->samples_per_frame = 76800;
+          cfg->tx_bw = 5e6;
+          cfg->rx_bw = 5e6;
+        }
 
-  if (ru->proc.instance_cnt_prach==-1) {
-    ++ru->proc.instance_cnt_prach;
-    ru->proc.frame_prach    = ru->proc.frame_rx;
-    ru->proc.subframe_prach = ru->proc.tti_rx;
+        break;
 
-    // DJP - think prach_procedures() is looking at gNB frame_prach
-    if (ru->gNB_list[0]) {
-      ru->gNB_list[0]->proc.frame_prach = ru->proc.frame_rx;
-      ru->gNB_list[0]->proc.slot_prach = ru->proc.tti_rx;
+      default:
+        AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu);
     }
-
-    LOG_I(PHY,"RU %d: waking up PRACH thread\n",ru->idx);
-    // the thread can now be woken up
-    AssertFatal(pthread_cond_signal(&ru->proc.cond_prach) == 0, "ERROR pthread_cond_signal for RU prach thread\n");
-  } else LOG_W(PHY,"RU prach thread busy, skipping\n");
-
-  pthread_mutex_unlock( &ru->proc.mutex_prach );
-  return(0);
-}
-
-// this is for RU with local RF unit
-void fill_rf_config(RU_t *ru, char *rf_config_file) {
-  int i;
-  NR_DL_FRAME_PARMS *fp   = ru->nr_frame_parms;
-  nfapi_nr_config_request_scf_t *config = &ru->config; //tmp index
-  openair0_config_t *cfg   = &ru->openair0_cfg;
-  int mu = config->ssb_config.scs_common.value;
-  int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value;
-
-  if (mu == NR_MU_0) { //or if LTE
-    if(N_RB == 100) {
-      if (fp->threequarter_fs) {
-        cfg->sample_rate=23.04e6;
-        cfg->samples_per_frame = 230400;
-        cfg->tx_bw = 10e6;
-        cfg->rx_bw = 10e6;
-      } else {
-        cfg->sample_rate=30.72e6;
-        cfg->samples_per_frame = 307200;
-        cfg->tx_bw = 10e6;
-        cfg->rx_bw = 10e6;
-      }
-    } else if(N_RB == 50) {
-      cfg->sample_rate=15.36e6;
-      cfg->samples_per_frame = 153600;
-      cfg->tx_bw = 5e6;
-      cfg->rx_bw = 5e6;
-    } else if (N_RB == 25) {
-      cfg->sample_rate=7.68e6;
-      cfg->samples_per_frame = 76800;
-      cfg->tx_bw = 2.5e6;
-      cfg->rx_bw = 2.5e6;
-    } else if (N_RB == 6) {
-      cfg->sample_rate=1.92e6;
-      cfg->samples_per_frame = 19200;
-      cfg->tx_bw = 1.5e6;
-      cfg->rx_bw = 1.5e6;
-    } else AssertFatal(1==0,"Unknown N_RB %d\n",N_RB);
   } else if (mu == NR_MU_1) {
-    if(N_RB == 273) {
+    switch(N_RB) {
+
+    case 273:
       if (fp->threequarter_fs) {
-        AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n");
+        cfg->sample_rate=184.32e6;
+        cfg->samples_per_frame = 1843200;
+        cfg->tx_bw = 100e6;
+        cfg->rx_bw = 100e6;
       } else {
         cfg->sample_rate=122.88e6;
         cfg->samples_per_frame = 1228800;
         cfg->tx_bw = 100e6;
         cfg->rx_bw = 100e6;
       }
-    } else if(N_RB == 217) {
+      break;
+    case 217:
       if (fp->threequarter_fs) {
         cfg->sample_rate=92.16e6;
         cfg->samples_per_frame = 921600;
@@ -1101,7 +895,20 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
         cfg->tx_bw = 80e6;
         cfg->rx_bw = 80e6;
       }
-    } else if(N_RB == 106) {
+      break;
+    case 133 :
+      if (fp->threequarter_fs) {
+	AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",N_RB);
+      }
+      else {
+        cfg->sample_rate=61.44e6;
+        cfg->samples_per_frame = 614400;
+        cfg->tx_bw = 50e6;
+        cfg->rx_bw = 50e6;
+      }
+
+      break;
+    case 106:
       if (fp->threequarter_fs) {
         cfg->sample_rate=46.08e6;
         cfg->samples_per_frame = 460800;
@@ -1114,20 +921,72 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
         cfg->tx_bw = 40e6;
         cfg->rx_bw = 40e6;
       }
-    } else {
+     break;
+    case 51:
+      if (fp->threequarter_fs) {
+        cfg->sample_rate=23.04e6;
+        cfg->samples_per_frame = 230400;
+        cfg->tx_bw = 20e6;
+        cfg->rx_bw = 20e6;
+      }
+      else {
+        cfg->sample_rate=30.72e6;
+        cfg->samples_per_frame = 307200;
+        cfg->tx_bw = 20e6;
+        cfg->rx_bw = 20e6;
+      }
+      break;
+    case 24:
+      if (fp->threequarter_fs) {
+        cfg->sample_rate=11.52e6;
+        cfg->samples_per_frame = 115200;
+        cfg->tx_bw = 10e6;
+        cfg->rx_bw = 10e6;
+      }
+      else {
+        cfg->sample_rate=15.36e6;
+        cfg->samples_per_frame = 153600;
+        cfg->tx_bw = 10e6;
+        cfg->rx_bw = 10e6;
+      }
+      break;
+    default:
       AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu);
     }
   } else if (mu == NR_MU_3) {
-    if (N_RB == 66) {
-      cfg->sample_rate = 122.88e6;
-      cfg->samples_per_frame = 1228800;
-      cfg->tx_bw = 100e6;
-      cfg->rx_bw = 100e6;
-    } else if(N_RB == 32) {
-      cfg->sample_rate=61.44e6;
-      cfg->samples_per_frame = 614400;
-      cfg->tx_bw = 50e6;
-      cfg->rx_bw = 50e6;
+    switch(N_RB) {
+      case 66:
+        if (fp->threequarter_fs) {
+          cfg->sample_rate=184.32e6;
+          cfg->samples_per_frame = 1843200;
+          cfg->tx_bw = 100e6;
+          cfg->rx_bw = 100e6;
+        } else {
+          cfg->sample_rate = 122.88e6;
+          cfg->samples_per_frame = 1228800;
+          cfg->tx_bw = 100e6;
+          cfg->rx_bw = 100e6;
+        }
+
+        break;
+
+      case 32:
+        if (fp->threequarter_fs) {
+          cfg->sample_rate=92.16e6;
+          cfg->samples_per_frame = 921600;
+          cfg->tx_bw = 50e6;
+          cfg->rx_bw = 50e6;
+        } else {
+          cfg->sample_rate=61.44e6;
+          cfg->samples_per_frame = 614400;
+          cfg->tx_bw = 50e6;
+          cfg->rx_bw = 50e6;
+        }
+
+        break;
+
+      default:
+        AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu);
     }
   } else {
     AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu);
@@ -1147,7 +1006,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
     if (ru->if_frequency == 0) {
       cfg->tx_freq[i] = (double)fp->dl_CarrierFreq;
       cfg->rx_freq[i] = (double)fp->ul_CarrierFreq;
-    } else if (ru->if_freq_offset){
+    } else if (ru->if_freq_offset) {
       cfg->tx_freq[i] = (double)(ru->if_frequency);
       cfg->rx_freq[i] = (double)(ru->if_frequency + ru->if_freq_offset);
       LOG_I(PHY, "Setting IF TX frequency to %lu Hz with IF RX frequency offset %d Hz\n", ru->if_frequency, ru->if_freq_offset);
@@ -1155,14 +1014,15 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
       cfg->tx_freq[i] = (double)ru->if_frequency;
       cfg->rx_freq[i] = (double)(ru->if_frequency+fp->ul_CarrierFreq-fp->dl_CarrierFreq);
     }
+
     cfg->tx_gain[i] = ru->att_tx;
     cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx;
     cfg->configFilename = rf_config_file;
     LOG_I(PHY, "Channel %d: setting tx_gain offset %f, rx_gain offset %f, tx_freq %lu Hz, rx_freq %lu Hz\n",
-           i, cfg->tx_gain[i],
-           cfg->rx_gain[i],
-           (unsigned long)cfg->tx_freq[i],
-           (unsigned long)cfg->rx_freq[i]);
+          i, cfg->tx_gain[i],
+          cfg->rx_gain[i],
+          (unsigned long)cfg->tx_freq[i],
+          (unsigned long)cfg->rx_freq[i]);
   }
 }
 
@@ -1174,64 +1034,58 @@ int setup_RU_buffers(RU_t *ru) {
   int i,j;
   int card,ant;
   //uint16_t N_TA_offset = 0;
-  NR_DL_FRAME_PARMS *frame_parms;
+  NR_DL_FRAME_PARMS *fp;
   nfapi_nr_config_request_scf_t *config = &ru->config;
 
   if (ru) {
-    frame_parms = ru->nr_frame_parms;
-    printf("setup_RU_buffers: frame_parms = %p\n",frame_parms);
+    fp = ru->nr_frame_parms;
+    printf("setup_RU_buffers: frame_parms = %p\n",fp);
   } else {
     printf("ru pointer is NULL\n");
     return(-1);
   }
+
   int mu = config->ssb_config.scs_common.value;
   int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value;
 
-
   if (config->cell_config.frame_duplex_type.value == TDD) {
     int N_TA_offset =  config->carrier_config.uplink_frequency.value < 6000000 ? 400 : 431; // reference samples  for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2
-
     double factor=1;
 
     switch (mu) {
-    case 0: //15 kHz scs
-      AssertFatal(N_TA_offset == 400,"scs_common 15kHz only for FR1\n");
-      if (N_RB <= 25) factor = .25;      // 7.68 Ms/s
-      else if (N_RB <=50) factor = .5;   // 15.36 Ms/s
-      else if (N_RB <=75) factor = 1.0;  // 30.72 Ms/s
-      else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s
-      else AssertFatal(1==0,"Too many PRBS for mu=0\n");
-      break;
-    case 1: //30 kHz sc
-      AssertFatal(N_TA_offset == 400,"scs_common 30kHz only for FR1\n");
-      if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s
-      else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s
-      break;
-    case 2: //60 kHz scs
-      AssertFatal(1==0,"scs_common should not be 60 kHz\n");
-      break;
-    case 3: //120 kHz scs
-      AssertFatal(N_TA_offset == 431,"scs_common 120kHz only for FR2\n");
-      break;
-    case 4: //240 kHz scs
-      AssertFatal(1==0,"scs_common should not be 60 kHz\n");
-      if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s
-      else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s
-      else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB);
-      break;
-
-      if      (N_RB == 100) ru->N_TA_offset = 624;
-      else if (N_RB == 50)  ru->N_TA_offset = 624/2;
-      else if (N_RB == 25)  ru->N_TA_offset = 624/4;
+      case 0: //15 kHz scs
+        AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n");
+        factor = fp->samples_per_subframe / 30720.0;
+        break;
+
+      case 1: //30 kHz sc
+        AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n");
+        factor = fp->samples_per_subframe / 30720.0;
+        break;
+
+      case 2: //60 kHz scs
+        AssertFatal(1==0, "scs_common should not be 60 kHz\n");
+        break;
+
+      case 3: //120 kHz scs
+        AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n");
+        factor = fp->samples_per_subframe / 61440.0;
+        break;
+
+      case 4: //240 kHz scs
+        AssertFatal(N_TA_offset == 431, "scs_common 240kHz only for FR2\n");
+        factor = fp->samples_per_subframe / 61440.0;
+        break;
+
+      default:
+        AssertFatal(1==0, "Invalid scs_common!\n");
     }
-    if (frame_parms->threequarter_fs == 1) factor = factor*.75;
+
     ru->N_TA_offset = (int)(N_TA_offset * factor);
-    LOG_I(PHY,"RU %d Setting N_TA_offset to %d samples (factor %f, UL Freq %d, N_RB %d)\n",ru->idx,ru->N_TA_offset,factor,
-	  config->carrier_config.uplink_frequency.value, N_RB);
-  }
-  else ru->N_TA_offset = 0;
+    LOG_I(PHY,"RU %d Setting N_TA_offset to %d samples (factor %f, UL Freq %d, N_RB %d, mu %d)\n",ru->idx,ru->N_TA_offset,factor,
+          config->carrier_config.uplink_frequency.value, N_RB, mu);
+  } else ru->N_TA_offset = 0;
 
-  
   if (ru->openair0_cfg.mmapped_dma == 1) {
     // replace RX signal buffers with mmaped HW versions
     for (i=0; i<ru->nb_rx; i++) {
@@ -1276,7 +1130,6 @@ void *ru_stats_thread(void *param) {
     sleep(1);
 
     if (opp_enabled == 1) {
-
       if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL);
 
       if (ru->feptx_ofdm) {
@@ -1289,6 +1142,7 @@ void *ru_stats_thread(void *param) {
       if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL);
 
       print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL);
+
       if (ru->fh_north_out) {
         print_meas(&ru->compression,"compression",NULL,NULL);
         print_meas(&ru->transport,"transport",NULL,NULL);
@@ -1299,136 +1153,57 @@ void *ru_stats_thread(void *param) {
   return(NULL);
 }
 
-void *ru_thread_tx( void *param ) {
-  RU_t               *ru      = (RU_t *)param;
-  RU_proc_t          *proc    = &ru->proc;
-  NR_DL_FRAME_PARMS  *fp      = ru->nr_frame_parms;
-  PHY_VARS_gNB       *gNB;
-  gNB_L1_proc_t      *gNB_proc;
-  gNB_L1_rxtx_proc_t *L1_proc;
-  char               filename[40];
-  int                print_frame = 8;
-  int                i = 0;
-  int                ret;
-  
-
-  wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
-  printf( "ru_thread_tx ready\n");
-
-  while (!oai_exit) {
-
-    LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n");
-    // wait until eNBs are finished subframe RX n and TX n+4
-
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, 1 );
-    wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx");
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, 0 );
-
-    ret = pthread_mutex_lock(&proc->mutex_gNBs);
-    AssertFatal(ret == 0,"mutex_lock return %d\n",ret);
-    int frame_tx=proc->frame_tx;
-    int tti_tx  =proc->tti_tx;
-    uint64_t timestamp_tx = proc->timestamp_tx;
-
-    ret = pthread_mutex_unlock(&proc->mutex_gNBs);
-    AssertFatal(ret == 0,"mutex_lock returns %d\n",ret);
-
-    if (oai_exit) break;
-
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx );
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx );
-
-    // do TX front-end processing if needed (precoding and/or IDFTs)
-    if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx);
-
-    // do OFDM with/without TX front-end processing  if needed
-    if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx);
-
-    if(!emulate_rf) {
-      // do outgoing fronthaul (south) if needed
-      if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,tti_tx,timestamp_tx);
-
-      if (ru->fh_north_out) ru->fh_north_out(ru);
-    } else {
-      if(proc->frame_tx == print_frame) {
-        for (i=0; i<ru->nb_tx; i++) {
+void ru_tx_func(void *param) {
+  processingData_RU_t *info = (processingData_RU_t *) param;
+  RU_t *ru = info->ru;
+  NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
+  int frame_tx = info->frame_tx;
+  int slot_tx = info->slot_tx;
+  int print_frame = 8;
+  char filename[40];
 
-          if(proc->tti_tx == 0) {
-            sprintf(filename,"gNBdataF_frame%d_sl%d.m", print_frame, proc->tti_tx);
-            LOG_M(filename,"txdataF_frame",&ru->gNB_list[0]->common_vars.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1);
+  // do TX front-end processing if needed (precoding and/or IDFTs)
+  if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,slot_tx);
 
-            sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx);
-            LOG_M(filename,"txdataF_frame",&ru->common.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1);
+  // do OFDM with/without TX front-end processing  if needed
+  if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,slot_tx);
 
-            sprintf(filename,"tx%ddataF_BF_frame%d_sl%d.m", i, print_frame, proc->tti_tx);
-            LOG_M(filename,"txdataF_BF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1);
-          }
+  if(!emulate_rf) {
+    // do outgoing fronthaul (south) if needed
+    if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,slot_tx,info->timestamp_tx);
 
-          if(proc->tti_tx == 9) {
-            sprintf(filename,"tx%ddata_frame%d.m", i, print_frame);
-            LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1);
-            sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame);
-            FILE *output_fd = fopen(filename,"w");
-
-            if (output_fd) {
-              fwrite(&ru->common.txdata[i][0],
-                     sizeof(int32_t),
-                     fp->samples_per_frame,
-                     output_fd);
-              fclose(output_fd);
-            } else {
-              LOG_E(PHY,"Cannot write to file %s\n",filename);
-            }
-          }//if(proc->tti_tx == 9)
-        }//for (i=0; i<ru->nb_tx; i++)
-      }//if(proc->frame_tx == print_frame)
-    }//else  emulate_rf
-
-    release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx");
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, proc->instance_cnt_gNBs);
-
-    for(i = 0; i<ru->num_gNB; i++) {
-      gNB       = ru->gNB_list[i];
-      gNB_proc  = &gNB->proc;
-      L1_proc   = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &gNB_proc->L1_proc_tx : &gNB_proc->L1_proc;
-      ret = pthread_mutex_lock(&gNB_proc->mutex_RU_tx);
-      AssertFatal(ret == 0,"mutex_lock returns %d\n",ret);
-
-      for (int j=0; j<gNB->num_RU; j++) {
-        if (ru == gNB->RU_list[j]) {
-          if ((gNB_proc->RU_mask_tx&(1<<j)) > 0)
-            LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n",
-                  gNB->Mod_id,gNB_proc->frame_rx,gNB_proc->slot_rx,ru->idx,gNB->num_RU,gNB_proc->RU_mask_tx);
-
-          gNB_proc->RU_mask_tx |= (1<<j);
+    if (ru->fh_north_out) ru->fh_north_out(ru);
+  } else {
+    if(frame_tx == print_frame) {
+      for (int i=0; i<ru->nb_tx; i++) {
+        if(slot_tx == 0) {
+          sprintf(filename,"gNBdataF_frame%d_sl%d.m", print_frame, slot_tx);
+          LOG_M(filename,"txdataF_frame",&ru->gNB_list[0]->common_vars.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1);
+          sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, slot_tx);
+          LOG_M(filename,"txdataF_frame",&ru->common.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1);
+          sprintf(filename,"tx%ddataF_BF_frame%d_sl%d.m", i, print_frame, slot_tx);
+          LOG_M(filename,"txdataF_BF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1);
         }
-      }
-
-      if (gNB_proc->RU_mask_tx != (1<<gNB->num_RU)-1) {  // not all RUs have provided their information so return
-        ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx);
-        AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret);
-      } else { // all RUs TX are finished so send the ready signal to gNB processing
-        gNB_proc->RU_mask_tx = 0;
-        ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx);
-        AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret);
-
-        ret = pthread_mutex_lock(&L1_proc->mutex_RUs_tx);
-        AssertFatal(ret == 0,"mutex_lock returns %d\n",ret);
-        // the thread can now be woken up
-        if (L1_proc->instance_cnt_RUs == -1) {
-          L1_proc->instance_cnt_RUs = 0;
-          VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs);
-          AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0,
-                      "ERROR pthread_cond_signal for gNB_L1_thread\n");
-        } //else AssertFatal(1==0,"gNB TX thread is not ready\n");
-        ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx);
-        AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret);
-      }
-    }
-  }
 
-  release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
-  return 0;
+        if(slot_tx == 9) {
+          sprintf(filename,"tx%ddata_frame%d.m", i, print_frame);
+          LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1);
+          sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame);
+          FILE *output_fd = fopen(filename,"w");
+
+          if (output_fd) {
+            fwrite(&ru->common.txdata[i][0],
+                   sizeof(int32_t),
+                   fp->samples_per_frame,
+                   output_fd);
+            fclose(output_fd);
+          } else {
+            LOG_E(PHY,"Cannot write to file %s\n",filename);
+          }
+        }//if(slot_tx == 9)
+      }//for (i=0; i<ru->nb_tx; i++)
+    }//if(frame_tx == print_frame)
+  }//else  emulate_rf
 }
 
 void *ru_thread( void *param ) {
@@ -1436,25 +1211,19 @@ void *ru_thread( void *param ) {
   RU_t               *ru      = (RU_t *)param;
   RU_proc_t          *proc    = &ru->proc;
   NR_DL_FRAME_PARMS  *fp      = ru->nr_frame_parms;
+  PHY_VARS_gNB       *gNB     = RC.gNB[0];
   int                ret;
   int                slot     = fp->slots_per_frame-1;
   int                frame    = 1023;
-  char               filename[40], threadname[40];
-  int                print_frame = 8;
-  int                i = 0;
+  char               threadname[40];
   int                aa;
-
   nfapi_nr_config_request_scf_t *cfg = &ru->config;
-  
   // set default return value
   ru_thread_status = 0;
   // set default return value
   sprintf(threadname,"ru_thread %u",ru->idx);
-
-
   LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]);
-
-  memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
+  memcpy((void *)&ru->config,(void *)&RC.gNB[0]->gNB_config,sizeof(ru->config));
 
   if(emulate_rf) {
     fill_rf_config(ru,ru->rf_config_file);
@@ -1500,6 +1269,14 @@ void *ru_thread( void *param ) {
   pthread_cond_signal(&RC.ru_cond);
   pthread_mutex_unlock(&RC.ru_mutex);
   wait_sync("ru_thread");
+  notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1,rx_func);
+  notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1_tx,tx_func);
+  notifiedFIFO_elt_t *msgRUTx = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_RU_tx,ru_tx_func);
+  processingData_L1_t *syncMsg;
+  notifiedFIFO_elt_t *res;
+  pushNotifiedFIFO(gNB->resp_L1,msg); // to unblock the process in the beginning
+  pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning
+  pushNotifiedFIFO(gNB->resp_RU_tx,msgRUTx); // to unblock the process in the beginning
 
   if(!emulate_rf) {
     // Start RF device if any
@@ -1509,37 +1286,18 @@ void *ru_thread( void *param ) {
       else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
     } else LOG_I(PHY,"RU %d no rf device\n",ru->idx);
 
-    // if an asnych_rxtx thread exists
-    // wakeup the thread because the devices are ready at this point
-
-    if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) {
-      pthread_mutex_lock(&proc->mutex_asynch_rxtx);
-      proc->instance_cnt_asynch_rxtx=0;
-      pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
-      pthread_cond_signal(&proc->cond_asynch_rxtx);
-    } else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx);
-
-    // if this is a slave RRU, try to synchronize on the DL frequency
-    if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
-
     // start trx write thread
-    if(usrp_tx_thread == 1){
-      if (ru->start_write_thread){
-        if(ru->start_write_thread(ru) != 0){
+    if(usrp_tx_thread == 1) {
+      if (ru->start_write_thread) {
+        if(ru->start_write_thread(ru) != 0) {
           LOG_E(HW,"Could not start tx write thread\n");
-        }
-        else{
+        } else {
           LOG_I(PHY,"tx write thread ready\n");
         }
       }
     }
   }
 
-  pthread_mutex_lock(&proc->mutex_FH1);
-  proc->instance_cnt_FH1 = 0;
-  pthread_mutex_unlock(&proc->mutex_FH1);
-  pthread_cond_signal(&proc->cond_FH1);
-
   // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
   while (!oai_exit) {
     // these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
@@ -1554,127 +1312,89 @@ void *ru_thread( void *param ) {
 
     // synchronization on input FH interface, acquire signals/data and block
     LOG_D(PHY,"[RU_thread] read data: frame_rx = %d, tti_rx = %d\n", frame, slot);
+
     if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot);
     else AssertFatal(1==0, "No fronthaul interface at south port");
 
+    proc->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe);
+    proc->frame_tx     = (proc->tti_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
+    proc->tti_tx      = (proc->tti_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame;
     LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0]:[RX:%d%d TX(SFN):%d]\n",
           frame,slot,
           proc->frame_rx,proc->tti_rx,
           proc->frame_tx,proc->tti_tx,
           RC.gNB[0]->proc.frame_rx,RC.gNB[0]->proc.slot_rx,
-	  RC.gNB[0]->proc.frame_tx);
-    /*
-          LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n",
-              ru->do_prach,
-              is_prach_subframe(fp, proc->frame_rx, proc->tti_rx),
-              proc->frame_rx,proc->tti_rx);
+          RC.gNB[0]->proc.frame_tx);
 
-        if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->tti_rx)==1)) {
-          wakeup_prach_ru(ru);
-        }*/
-
-    // adjust for timing offset between RU
-    //printf("~~~~~~~~~~~~~~~~~~~~~~~~~~%d.%d in ru_thread is in process\n", proc->frame_rx, proc->tti_rx);
     if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023;
 
     // do RX front-end processing (frequency-shift, dft) if needed
-
     int slot_type = nr_slot_select(cfg,proc->frame_rx,proc->tti_rx);
-    if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
-    //if (proc->tti_rx==8) {
 
+    if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
       if (ru->feprx) {
-      ru->feprx(ru,proc->tti_rx);
-      //LOG_M("rxdata.m","rxs",ru->common.rxdata[0],1228800,1,1);
-
-      LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx);
-      LOG_D(PHY,"Copying rxdataF from RU to gNB\n");
-      
-      for (aa=0;aa<ru->nb_rx;aa++)
-	memcpy((void*)RC.gNB[0]->common_vars.rxdataF[aa],
-	       (void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
-
-      // Do PRACH RU processing
-
-      int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST);
-      uint8_t prachStartSymbol,N_dur;
-      if (prach_id>=0) {
-	N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt);
-	/*
-	get_nr_prach_info_from_index(ru->config.prach_config.prach_ConfigurationIndex.value,
-				     proc->frame_rx,proc->tti_rx,
-				     ru->config.carrier_config.dl_frequency.value,
-				     fp->numerology_index,
-				     fp->frame_type,
-				     &format,
-				     &start_symbol,
-				     &N_t_slot,
-				     &N_dur,
-				     &RA_sfn_index,
-				     &N_RA_slot,
-				     &config_period);
-	*/			     
-	for (int prach_oc = 0; prach_oc<ru->prach_list[prach_id].num_prach_ocas; prach_oc++) {
-	  prachStartSymbol = ru->prach_list[prach_id].prachStartSymbol+prach_oc*N_dur;
-	  //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. 
-
-	  rx_nr_prach_ru(ru,
-			 ru->prach_list[prach_id].fmt, //could also use format
-			 ru->prach_list[prach_id].numRA,
-			 prachStartSymbol,
-			 prach_oc,
-			 proc->frame_rx,proc->tti_rx);
-	}
-	free_nr_ru_prach_entry(ru,prach_id);
-      }
+        ru->feprx(ru,proc->tti_rx);
+        //LOG_M("rxdata.m","rxs",ru->common.rxdata[0],1228800,1,1);
+        LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx);
+        LOG_D(PHY,"Copying rxdataF from RU to gNB\n");
+
+        for (aa=0; aa<ru->nb_rx; aa++)
+          memcpy((void *)RC.gNB[0]->common_vars.rxdataF[aa],
+                 (void *)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
+
+        if (IS_SOFTMODEM_DOSCOPE && RC.gNB[0]->scopeData)
+          ((scopeData_t *)RC.gNB[0]->scopeData)->slotFunc(ru->common.rxdataF[0],proc->tti_rx, RC.gNB[0]->scopeData);
+
+        // Do PRACH RU processing
+        int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST);
+        uint8_t prachStartSymbol,N_dur;
+
+        if (prach_id>=0) {
+          T(T_GNB_PHY_PRACH_INPUT_SIGNAL, T_INT(proc->frame_rx), T_INT(proc->tti_rx), T_INT(0),
+            T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx-1,fp,0)]/*-ru->N_TA_offset*/, fp->get_samples_per_slot(proc->tti_rx,fp)*4*2));
+          N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt);
+
+          /*
+          get_nr_prach_info_from_index(ru->config.prach_config.prach_ConfigurationIndex.value,
+                     proc->frame_rx,proc->tti_rx,
+                     ru->config.carrier_config.dl_frequency.value,
+                     fp->numerology_index,
+                     fp->frame_type,
+                     &format,
+                     &start_symbol,
+                     &N_t_slot,
+                     &N_dur,
+                     &RA_sfn_index,
+                     &N_RA_slot,
+                     &config_period);
+          */
+          for (int prach_oc = 0; prach_oc<ru->prach_list[prach_id].num_prach_ocas; prach_oc++) {
+            prachStartSymbol = ru->prach_list[prach_id].prachStartSymbol+prach_oc*N_dur;
+            //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}.
+            rx_nr_prach_ru(ru,
+                           ru->prach_list[prach_id].fmt, //could also use format
+                           ru->prach_list[prach_id].numRA,
+                           prachStartSymbol,
+                           prach_oc,
+                           proc->frame_rx,proc->tti_rx);
+          }
+
+          free_nr_ru_prach_entry(ru,prach_id);
+        }
       }
     }
 
     // At this point, all information for subframe has been received on FH interface
-
-    // wakeup all gNB processes waiting for this RU
-    if (ru->num_gNB>0) wakeup_gNB_L1s(ru);
-
-    if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_gNB==0) {
-      // do TX front-end processing if needed (precoding and/or IDFTs)
-      if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx);
-
-      // do OFDM with/without TX front-end processing  if needed
-      if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx);
-
-      if(!emulate_rf) {
-        // do outgoing fronthaul (south) if needed
-        if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx);
-
-        if (ru->fh_north_out) ru->fh_north_out(ru);
-      } else {
-        if(proc->frame_tx == print_frame) {
-          for (i=0; i<ru->nb_tx; i++) {
-            sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx);
-            LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_slot_wCP, 1, 1);
-
-            if(proc->tti_tx == 9) {
-              sprintf(filename,"tx%ddata_frame%d.m", i, print_frame);
-              LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1);
-              sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame);
-              FILE *output_fd = fopen(filename,"w");
-
-              if (output_fd) {
-                fwrite(&ru->common.txdata[i][0],
-                       sizeof(int32_t),
-                       fp->samples_per_frame,
-                       output_fd);
-                fclose(output_fd);
-              } else {
-                LOG_E(PHY,"Cannot write to file %s\n",filename);
-              }
-            }//if(proc->tti_tx == 9)
-          }//for (i=0; i<ru->nb_tx; i++)
-        }//if(proc->frame_tx == print_frame)
-      }//else  emulate_rf
-
-      proc->emulate_rf_busy = 0;
-    }//if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD)
+    res = pullTpool(gNB->resp_L1, gNB->threadPool);
+    syncMsg = (processingData_L1_t *)NotifiedFifoData(res);
+    syncMsg->gNB = gNB;
+    syncMsg->frame_rx = proc->frame_rx;
+    syncMsg->slot_rx = proc->tti_rx;
+    syncMsg->frame_tx = proc->frame_tx;
+    syncMsg->slot_tx = proc->tti_tx;
+    syncMsg->timestamp_tx = proc->timestamp_tx;
+    res->key = proc->tti_rx;
+    pushTpool(gNB->threadPool, res);
   }
 
   printf( "Exiting ru_thread \n");
@@ -1685,85 +1405,12 @@ void *ru_thread( void *param ) {
     else LOG_I(PHY,"RU %d rf device stopped\n",ru->idx);
   }
 
+  delNotifiedFIFO_elt(msg);
+  delNotifiedFIFO_elt(msgL1Tx);
+  delNotifiedFIFO_elt(msgRUTx);
   ru_thread_status = 0;
   return &ru_thread_status;
 }
-/*
-// This thread run the initial synchronization like a UE
-void *ru_thread_synch(void *arg) {
-
-  RU_t *ru = (RU_t*)arg;
-  NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms;
-  int32_t sync_pos,sync_pos2;
-  uint32_t peak_val;
-  uint32_t sync_corr[307200] __attribute__((aligned(32)));
-  static int ru_thread_synch_status;
-
-
-
-  wait_sync("ru_thread_synch");
-
-  // initialize variables for PSS detection
-  lte_sync_time_init(ru->nr_frame_parms);
-
-  while (!oai_exit) {
-
-    // wait to be woken up
-    if (wait_on_condition(&ru->proc.mutex_synch,&ru->proc.cond_synch,&ru->proc.instance_cnt_synch,"ru_thread_synch")<0) break;
-
-    // if we're not in synch, then run initial synch
-    if (ru->in_synch == 0) {
-      // run intial synch like UE
-      LOG_I(PHY,"Running initial synchronization\n");
-
-      sync_pos = lte_sync_time_gNB(ru->common.rxdata,
-           fp,
-           fp->samples_per_subframe*5,
-           &peak_val,
-           sync_corr);
-      LOG_I(PHY,"RU synch: %d, val %d\n",sync_pos,peak_val);
-
-      if (sync_pos >= 0) {
-  if (sync_pos >= fp->nb_prefix_samples)
-    sync_pos2 = sync_pos - fp->nb_prefix_samples;
-  else
-    sync_pos2 = sync_pos + (fp->samples_per_subframe*10) - fp->nb_prefix_samples;
-
-  if (fp->frame_type == FDD) {
-
-    // PSS is hypothesized in last symbol of first slot in Frame
-    int sync_pos_slot = (fp->samples_per_subframe>>1) - fp->ofdm_symbol_size - fp->nb_prefix_samples;
-
-    if (sync_pos2 >= sync_pos_slot)
-      ru->rx_offset = sync_pos2 - sync_pos_slot;
-    else
-      ru->rx_offset = (fp->samples_per_subframe*10) + sync_pos2 - sync_pos_slot;
-  }
-  else {
-
-  }
-
-  LOG_I(PHY,"Estimated sync_pos %d, peak_val %d => timing offset %d\n",sync_pos,peak_val,ru->rx_offset);
-
-  if ((peak_val > 300000) && (sync_pos > 0)) {
-  //      if (sync_pos++ > 3) {
-  write_output("ru_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_subframe*5,1,2);
-  write_output("ru_rx.m","rxs",(void*)ru->ru_time.rxdata[0][0],fp->samples_per_subframe*10,1,1);
-  exit(-1);
-  }
-
-  ru->in_synch=1;
-      }
-    }
-
-    if (release_thread(&ru->proc.mutex_synch,&ru->proc.instance_cnt_synch,"ru_synch_thread") < 0) break;
-  } // oai_exit
-
-  ru_thread_synch_status = 0;
-  return &ru_thread_synch_status;
-
-}
-*/
 
 int nr_start_if(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB) {
   return(ru->ifdevice.trx_start_func(&ru->ifdevice));
@@ -1785,17 +1432,10 @@ int start_write_thread(RU_t *ru) {
 void init_RU_proc(RU_t *ru) {
   int i=0;
   RU_proc_t *proc;
-  char name[100];
   LOG_I(PHY,"Initializing RU proc %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]);
   proc = &ru->proc;
   memset((void *)proc,0,sizeof(RU_proc_t));
   proc->ru = ru;
-  proc->instance_cnt_prach       = -1;
-  proc->instance_cnt_synch       = -1;
-  proc->instance_cnt_FH          = -1;
-  proc->instance_cnt_FH1         = -1;
-  proc->instance_cnt_gNBs        = -1;
-  proc->instance_cnt_asynch_rxtx = -1;
   proc->instance_cnt_emulateRF   = -1;
   proc->first_rx                 = 1;
   proc->first_tx                 = 1;
@@ -1806,44 +1446,13 @@ void init_RU_proc(RU_t *ru) {
 
   for (i=0; i<10; i++) proc->symbol_mask[i]=0;
 
-  pthread_mutex_init( &proc->mutex_prach, NULL);
-  pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
-  pthread_mutex_init( &proc->mutex_synch,NULL);
-  pthread_mutex_init( &proc->mutex_FH,NULL);
-  pthread_mutex_init( &proc->mutex_FH1,NULL);
   pthread_mutex_init( &proc->mutex_emulateRF,NULL);
-  pthread_mutex_init( &proc->mutex_gNBs, NULL);
-  pthread_cond_init( &proc->cond_prach, NULL);
-  pthread_cond_init( &proc->cond_FH, NULL);
-  pthread_cond_init( &proc->cond_FH1, NULL);
   pthread_cond_init( &proc->cond_emulateRF, NULL);
-  pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
-  pthread_cond_init( &proc->cond_synch,NULL);
-  pthread_cond_init( &proc->cond_gNBs, NULL);
   threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "thread_FH", -1, OAI_PRIORITY_RT_MAX );
 
-  if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)
-    threadCreate( &proc->pthread_FH1, ru_thread_tx, (void *)ru, "thread_FH1", -1, OAI_PRIORITY_RT );
-
   if(emulate_rf)
     threadCreate( &proc->pthread_emulateRF, emulatedRF_thread, (void *)proc, "emulateRF", -1, OAI_PRIORITY_RT );
 
-  if (ru->function == NGFI_RRU_IF4p5) {
-    threadCreate( &proc->pthread_prach, ru_thread_prach, (void *)ru, "RACH", -1, OAI_PRIORITY_RT );
-    ///tmp deactivation of synch thread
-    //    if (ru->is_slave == 1) pthread_create( &proc->pthread_synch, attr_synch, ru_thread_synch, (void*)ru);
-
-    if ((ru->if_timing == synch_to_other) ||
-        (ru->function == NGFI_RRU_IF5) ||
-        (ru->function == NGFI_RRU_IF4p5)) threadCreate( &proc->pthread_asynch_rxtx, ru_thread_asynch_rxtx, (void *)ru, "asynch_rxtx", -1, OAI_PRIORITY_RT );
-
-    snprintf( name, sizeof(name), "ru_thread_FH %d", ru->idx );
-    pthread_setname_np( proc->pthread_FH, name );
-  } else if (ru->function == gNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF
-    LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__);
-    threadCreate( &proc->pthread_prach, ru_thread_prach, (void *)ru,"RACH", -1, OAI_PRIORITY_RT );
-  }
-
   if (get_thread_worker_conf() == WORKER_ENABLE) {
     if (ru->feprx) nr_init_feprx_thread(ru);
 
@@ -1856,46 +1465,9 @@ void init_RU_proc(RU_t *ru) {
 void kill_NR_RU_proc(int inst) {
   RU_t *ru = RC.ru[inst];
   RU_proc_t *proc = &ru->proc;
-  pthread_mutex_lock(&proc->mutex_FH);
-  proc->instance_cnt_FH = 0;
-  pthread_mutex_unlock(&proc->mutex_FH);
-  pthread_cond_signal(&proc->cond_FH);
-  pthread_mutex_lock(&proc->mutex_prach);
-  proc->instance_cnt_prach = 0;
-  pthread_mutex_unlock(&proc->mutex_prach);
-  pthread_cond_signal(&proc->cond_prach);
-  pthread_mutex_lock(&proc->mutex_synch);
-  proc->instance_cnt_synch = 0;
-  pthread_mutex_unlock(&proc->mutex_synch);
-  pthread_cond_signal(&proc->cond_synch);
-  pthread_mutex_lock(&proc->mutex_gNBs);
-  proc->instance_cnt_gNBs = 0;
-  pthread_mutex_unlock(&proc->mutex_gNBs);
-  pthread_cond_signal(&proc->cond_gNBs);
-  pthread_mutex_lock(&proc->mutex_asynch_rxtx);
-  proc->instance_cnt_asynch_rxtx = 0;
-  pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
-  pthread_cond_signal(&proc->cond_asynch_rxtx);
   LOG_D(PHY, "Joining pthread_FH\n");
   pthread_join(proc->pthread_FH, NULL);
 
-  if (ru->function == NGFI_RRU_IF4p5) {
-    LOG_D(PHY, "Joining pthread_prach\n");
-    pthread_join(proc->pthread_prach, NULL);
-
-    if (ru->is_slave) {
-      LOG_D(PHY, "Joining pthread_\n");
-      pthread_join(proc->pthread_synch, NULL);
-    }
-
-    if ((ru->if_timing == synch_to_other) ||
-        (ru->function == NGFI_RRU_IF5) ||
-        (ru->function == NGFI_RRU_IF4p5)) {
-      LOG_D(PHY, "Joining pthread_asynch_rxtx\n");
-      pthread_join(proc->pthread_asynch_rxtx, NULL);
-    }
-  }
-
   if (get_nprocs() >= 2) {
     if (ru->feprx) {
       pthread_mutex_lock(&proc->mutex_fep);
@@ -1924,21 +1496,9 @@ void kill_NR_RU_proc(int inst) {
     LOG_D(PHY, "Joining ru_stats_thread\n");
     pthread_join(ru->ru_stats_thread, NULL);
   }
-
-  pthread_mutex_destroy(&proc->mutex_prach);
-  pthread_mutex_destroy(&proc->mutex_asynch_rxtx);
-  pthread_mutex_destroy(&proc->mutex_synch);
-  pthread_mutex_destroy(&proc->mutex_FH);
-  pthread_mutex_destroy(&proc->mutex_gNBs);
-  pthread_cond_destroy(&proc->cond_prach);
-  pthread_cond_destroy(&proc->cond_FH);
-  pthread_cond_destroy(&proc->cond_asynch_rxtx);
-  pthread_cond_destroy(&proc->cond_synch);
-  pthread_cond_destroy(&proc->cond_gNBs);
 }
 
-int check_capabilities(RU_t *ru,RRU_capabilities_t *cap)
-{
+int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) {
   FH_fmt_options_t fmt = cap->FH_fmt;
   int i;
   int found_band=0;
@@ -1994,8 +1554,7 @@ char rru_formats[3][20] = {"OAI_IF5","MBP_IF5","OAI_IF4p5"};
 char ru_if_formats[4][20] = {"LOCAL_RF","REMOTE_OAI_IF5","REMOTE_MBP_IF5","REMOTE_OAI_IF4p5"};
 
 void configure_ru(int idx,
-                  void *arg)
-{
+                  void *arg) {
   RU_t               *ru           = RC.ru[idx];
   RRU_config_t       *config       = (RRU_config_t *)arg;
   RRU_capabilities_t *capabilities = (RRU_capabilities_t *)arg;
@@ -2168,28 +1727,25 @@ void set_function_spec_param(RU_t *ru) {
         ru->fh_north_out         = NULL;                    // no outgoing fronthaul to north
         ru->nr_start_if          = NULL;                    // no if interface
         ru->rfdevice.host_type   = RAU_HOST;
-
-	// FK this here looks messed up. The following lines should be part of the  if (ru->function == gNodeB_3GPP), shouldn't they?
-
-	ru->fh_south_in            = rx_rf;                               // local synchronous RF RX
-	ru->fh_south_out           = tx_rf;                               // local synchronous RF TX
-	ru->start_rf               = start_rf;                            // need to start the local RF interface
-	ru->stop_rf                = stop_rf;
-	ru->start_write_thread     = start_write_thread;                  // starting RF TX in different thread
-	printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf);
+        ru->fh_south_in            = rx_rf;                 // local synchronous RF RX
+        ru->fh_south_out           = tx_rf;                 // local synchronous RF TX
+        ru->start_rf               = start_rf;              // need to start the local RF interface
+        ru->stop_rf                = stop_rf;
+        ru->start_write_thread     = start_write_thread;                  // starting RF TX in different thread
+        printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf);
       }
 
       /*
-	printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf);
-	fill_rf_config(ru,rf_config_file);
-	init_frame_parms(&ru->frame_parms,1);
-	nr_phy_init_RU(ru);
-
-	ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
-	if (setup_RU_buffers(ru)!=0) {
-	   printf("Exiting, cannot initialize RU Buffers\n");
-	   exit(-1);
-	}
+      printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf);
+      fill_rf_config(ru,rf_config_file);
+      init_frame_parms(&ru->frame_parms,1);
+      nr_phy_init_RU(ru);
+
+      ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
+      if (setup_RU_buffers(ru)!=0) {
+      printf("Exiting, cannot initialize RU Buffers\n");
+      exit(-1);
+      }
       */
       break;
 
@@ -2245,9 +1801,12 @@ void set_function_spec_param(RU_t *ru) {
 
       if (ru->ifdevice.get_internal_parameter != NULL) {
         void *t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_in");
+
         if (t != NULL)
           ru->fh_south_in = t;
+
         t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_out");
+
         if (t != NULL)
           ru->fh_south_out = t;
       }
@@ -2261,8 +1820,7 @@ void set_function_spec_param(RU_t *ru) {
   } // switch on interface type
 }
 
-void init_NR_RU(char *rf_config_file)
-{
+void init_NR_RU(char *rf_config_file) {
   int ru_id;
   RU_t *ru;
   PHY_VARS_gNB *gNB_RC;
@@ -2275,9 +1833,8 @@ void init_NR_RU(char *rf_config_file)
   pthread_cond_init(&RC.ru_cond,NULL);
   // read in configuration file)
   printf("configuring RU from file\n");
-  RCconfig_RU();
+  NRRCconfig_RU();
   LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_nr_L1_inst,RC.nb_RU,get_nprocs());
-
   LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU);
 
   for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
@@ -2339,8 +1896,7 @@ void init_NR_RU(char *rf_config_file)
 }
 
 
-void stop_RU(int nb_ru)
-{
+void stop_RU(int nb_ru) {
   for (int inst = 0; inst < nb_ru; inst++) {
     LOG_I(PHY, "Stopping RU %d processing threads\n", inst);
     kill_NR_RU_proc(inst);
@@ -2350,8 +1906,7 @@ void stop_RU(int nb_ru)
 
 /* --------------------------------------------------------*/
 /* from here function to use configuration module          */
-void RCconfig_RU(void)
-{
+static void NRRCconfig_RU(void) {
   int i = 0, j = 0;
   paramdef_t RUParams[] = RUPARAMS_DESC;
   paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0};
@@ -2385,39 +1940,39 @@ void RCconfig_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;
+      } else {
+        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 {
+        LOG_I(PHY,"Setting time source to internal\n");
+        RC.ru[j]->openair0_cfg.time_source = internal;
       }
-      else {
-	RC.ru[j]->openair0_cfg.time_source = unset;
-      }
-      
+
       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;
@@ -2487,7 +2042,7 @@ void RCconfig_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);
@@ -2496,11 +2051,14 @@ void RCconfig_RU(void)
       RC.ru[j]->att_rx                            = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr);
       RC.ru[j]->if_frequency                      = *(RUParamList.paramarray[j][RU_IF_FREQUENCY].u64ptr);
       RC.ru[j]->if_freq_offset                    = *(RUParamList.paramarray[j][RU_IF_FREQ_OFFSET].iptr);
+      RC.ru[j]->do_precoding                      = *(RUParamList.paramarray[j][RU_DO_PRECODING].iptr);
 
       if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) {
         RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt;
+
         for (i=0; i<RC.ru[j]->num_gNB; i++)  {
           RC.ru[j]->bw_list[i] = (int32_t *)malloc16_clear((RC.ru[j]->nb_bfw)*sizeof(int32_t));
+
           for (int b=0; b<RC.ru[j]->nb_bfw; b++) RC.ru[j]->bw_list[i][b] = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].iptr[b];
         }
       }
diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h
index 500819e6844016ea2829d7b0472a8358fff9f70b..101b1a2bf9775d98632ff50e5fdd89d38f125783 100644
--- a/executables/nr-softmodem-common.h
+++ b/executables/nr-softmodem-common.h
@@ -68,11 +68,16 @@
 #define CONFIG_HLP_SOFTS         "Enable soft scope and L1 and L2 stats (Xforms)\n"
 #define CONFIG_HLP_EXMCAL        "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
 #define CONFIG_HLP_ITTIL         "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
-#define CONFIG_HLP_DLMCS         "Set the maximum downlink MCS\n"
+#define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n"
+#define CONFIG_HLP_DLNL_PHYTEST "Set the downlink nrOfLayers for PHYTEST mode\n"
 #define CONFIG_HLP_STMON         "Enable processing timing measurement of lte softmodem on per subframe basis \n"
 #define CONFIG_HLP_PRB           "Set the PRB, valid values: 6, 25, 50, 100  \n"
 #define CONFIG_HLP_MSLOTS        "Skip the missed slots/subframes \n"
-#define CONFIG_HLP_ULMCS         "Set the maximum uplink MCS\n"
+#define CONFIG_HLP_ULMCS_PHYTEST "Set the uplink MCS for PHYTEST mode\n"
+#define CONFIG_HLP_DLBW_PHYTEST  "Set the number of PRBs used for DLSCH in PHYTEST mode\n"
+#define CONFIG_HLP_ULBW_PHYTEST  "Set the number of PRBs used for ULSCH in PHYTEST mode\n"
+#define CONFIG_HLP_DLBM_PHYTEST  "Bitmap for DLSCH slots (slot 0 starts at LSB)\n"
+#define CONFIG_HLP_ULBM_PHYTEST  "Bitmap for ULSCH slots (slot 0 starts at LSB)\n"
 #define CONFIG_HLP_TDD           "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
 #define CONFIG_HLP_UE            "Set the lte softmodem as a UE\n"
 #define CONFIG_HLP_L2MONW        "Enable L2 wireshark messages on localhost \n"
@@ -150,7 +155,4 @@ extern int emulate_rf;
 extern int numerology;
 extern int usrp_tx_thread;
 
-extern volatile int start_eNB;
-extern volatile int start_UE;
-
 #endif
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index 924c32b8a7cddc7d09f06b68f811b1b315ad6f65..b855418d649674b6337ede00b9c1a123c629d282 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -53,6 +53,7 @@
 #include "PHY_INTERFACE/phy_interface_vars.h"
 #include "gnb_config.h"
 #include "SIMULATION/TOOLS/sim.h"
+#include <targets/RT/USER/lte-softmodem.h>
 
 #ifdef SMBV
 #include "PHY/TOOLS/smbv.h"
@@ -85,6 +86,7 @@ unsigned short config_frames[4] = {2,9,11,13};
 #include "x2ap_eNB.h"
 #include "ngap_gNB.h"
 #include "gnb_paramdef.h"
+#include <openair3/ocp-gtpu/gtp_itf.h>
 #include "nfapi/oai_integration/vendor_ext.h"
 
 pthread_cond_t nfapi_sync_cond;
@@ -92,7 +94,7 @@ pthread_mutex_t nfapi_sync_mutex;
 int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
 
 extern uint8_t nfapi_mode; // Default to monolithic mode
-
+THREAD_STRUCT thread_struct;
 pthread_cond_t sync_cond;
 pthread_mutex_t sync_mutex;
 int sync_var=-1; //!< protected by mutex \ref sync_mutex.
@@ -114,7 +116,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
 //Temp fix for inexistent NR upper layer
 unsigned char NB_gNB_INST = 1;
 
-static char                    *itti_dump_file = NULL;
 
 int UE_scan = 1;
 int UE_scan_carrier = 0;
@@ -136,9 +137,6 @@ double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}};
 
 double rx_gain_off = 0.0;
 
-double sample_rate=30.72e6;
-double bw = 10.0e6;
-
 static int tx_max_power[MAX_NUM_CCs]; /* =  {0,0}*/;
 
 
@@ -163,26 +161,30 @@ int otg_enabled;
 
 //static NR_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
 //static nfapi_nr_config_request_t *config[MAX_NUM_CCs];
-uint32_t target_dl_mcs = 28; //maximum allowed mcs
-uint32_t target_ul_mcs = 20;
 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");
 }
+void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask,
+                   uint16_t rnti, int32_t stat) {
+  AssertFatal(false, "Must not be called in this context\n");
+}
+
 
 extern void reset_opp_meas(void);
 extern void print_opp_meas(void);
 
-extern void init_eNB_afterRU(void);
 extern void *udp_eNB_task(void *args_p);
 
 int transmission_mode=1;
 int emulate_rf = 0;
 int numerology = 0;
-int usrp_tx_thread = 0;
 
 
 static char *parallel_config = NULL;
@@ -306,45 +308,41 @@ int create_gNB_tasks(uint32_t gnb_nb) {
   LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb);
   itti_wait_ready(1);
 
-
   if (gnb_nb > 0) {
     /* Last task to create, others task must be ready before its start */
     /*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;
     }*/
-    if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){
+    if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0) {
       LOG_E(SCTP, "Create task for SCTP failed\n");
       return -1;
     }
+
     if (is_x2ap_enabled()) {
-    if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0){
-      LOG_E(X2AP, "Create task for X2AP failed\n");
-    }
-    }
-    else {
+      if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0) {
+        LOG_E(X2AP, "Create task for X2AP failed\n");
+      }
+    } else {
       LOG_I(X2AP, "X2AP is disabled.\n");
     }
   }
-  
+
   paramdef_t NETParams[]  =  GNBNETPARAMS_DESC;
   char aprefix[MAX_OPTNAME_SIZE*2 + 8];
   sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
-  config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); 
+  config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix);
 
-  for(int i = GNB_INTERFACE_NAME_FOR_NG_AMF_IDX; i <= GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX; i++){
-    if( NETParams[i].strptr == NULL){
+  for(int i = GNB_INTERFACE_NAME_FOR_NG_AMF_IDX; i <= GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX; i++) {
+    if( NETParams[i].strptr == NULL) {
       LOG_E(NGAP, "No configuration in the file.\n");
-	  NGAP_CONF_MODE = 0;
-	}
-    else {
+      NGAP_CONF_MODE = 0;
+    } else {
       LOG_D(NGAP, "Configuration in the file: %s.\n",*NETParams[i].strptr);
     }
-  
   }
 
-
-  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) {
@@ -352,42 +350,49 @@ int create_gNB_tasks(uint32_t gnb_nb) {
         return -1;
       }
       */
-      if(NGAP_CONF_MODE){
+      if(NGAP_CONF_MODE) {
         if (itti_create_task (TASK_NGAP, ngap_gNB_task, NULL) < 0) {
           LOG_E(NGAP, "Create task for NGAP failed\n");
           return -1;
         }
       } else {
-          LOG_E(NGAP, "Ngap task not created\n");
+        LOG_E(NGAP, "Ngap task not created\n");
       }
 
-
-      if(!emulate_rf){
+      if(!emulate_rf) {
         if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
           LOG_E(UDP_, "Create task for UDP failed\n");
           return -1;
         }
       }
 
-      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");
 
     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;
@@ -395,18 +400,12 @@ int create_gNB_tasks(uint32_t gnb_nb) {
 
 
 static void get_options(void) {
-
-
   paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ;
-
   CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
   get_common_options(SOFTMODEM_GNB_BIT );
   config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
   CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
 
-
-
-
   if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) {
     memset((void *)&RC,0,sizeof(RC));
     /* Read RC configuration file */
@@ -419,13 +418,11 @@ static void get_options(void) {
   if(parallel_config != NULL) set_parallel_conf(parallel_config);
 
   if(worker_config != NULL) set_worker_conf(worker_config);
-
 }
 
 
 void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs],
-		             NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs])
-{
+                             NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
   for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     frame_parms[CC_id] = (NR_DL_FRAME_PARMS *) malloc(sizeof(NR_DL_FRAME_PARMS));
     config[CC_id] = (nfapi_nr_config_request_scf_t *) malloc(sizeof(nfapi_nr_config_request_scf_t));
@@ -476,93 +473,6 @@ void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs],
   }
 }
 
-/*
-void init_openair0(void) {
-
-  int card;
-  int i;
-
-  for (card=0; card<MAX_CARDS; card++) {
-
-    openair0_cfg[card].mmapped_dma=mmapped_dma;
-    openair0_cfg[card].configFilename = NULL;
-
-    if(config[0]->rf_config.dl_carrier_bandwidth.value == 100) {
-      if (frame_parms[0]->threequarter_fs) {
-  openair0_cfg[card].sample_rate=23.04e6;
-  openair0_cfg[card].samples_per_frame = 230400;
-  openair0_cfg[card].tx_bw = 10e6;
-  openair0_cfg[card].rx_bw = 10e6;
-      } else {
-  openair0_cfg[card].sample_rate=30.72e6;
-  openair0_cfg[card].samples_per_frame = 307200;
-  openair0_cfg[card].tx_bw = 10e6;
-  openair0_cfg[card].rx_bw = 10e6;
-      }
-    } else if(config[0]->rf_config.dl_carrier_bandwidth.value == 50) {
-      openair0_cfg[card].sample_rate=15.36e6;
-      openair0_cfg[card].samples_per_frame = 153600;
-      openair0_cfg[card].tx_bw = 5e6;
-      openair0_cfg[card].rx_bw = 5e6;
-    } else if (config[0]->rf_config.dl_carrier_bandwidth.value == 25) {
-      openair0_cfg[card].sample_rate=7.68e6;
-      openair0_cfg[card].samples_per_frame = 76800;
-      openair0_cfg[card].tx_bw = 2.5e6;
-      openair0_cfg[card].rx_bw = 2.5e6;
-    } else if (config[0]->rf_config.dl_carrier_bandwidth.value == 6) {
-      openair0_cfg[card].sample_rate=1.92e6;
-      openair0_cfg[card].samples_per_frame = 19200;
-      openair0_cfg[card].tx_bw = 1.5e6;
-      openair0_cfg[card].rx_bw = 1.5e6;
-    }
-
-
-    if (config[0]->subframe_config.duplex_mode.value==TDD)
-      openair0_cfg[card].duplex_mode = duplex_mode_TDD;
-    else //FDD
-      openair0_cfg[card].duplex_mode = duplex_mode_FDD;
-
-    printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
-     RC.gNB[0]->gNB_config.rf_config.tx_antenna_ports.value,
-     RC.gNB[0]->gNB_config.rf_config.tx_antenna_ports.value );
-    openair0_cfg[card].Mod_id = 0;
-
-    openair0_cfg[card].num_rb_dl=config[0]->rf_config.dl_carrier_bandwidth.value;
-
-    openair0_cfg[card].clock_source = clock_source;
-
-
-    openair0_cfg[card].tx_num_channels=min(2,RC.gNB[0]->gNB_config.rf_config.tx_antenna_ports.value );
-    openair0_cfg[card].rx_num_channels=min(2,RC.gNB[0]->gNB_config.rf_config.tx_antenna_ports.value );
-
-    for (i=0; i<4; i++) {
-
-      if (i<openair0_cfg[card].tx_num_channels)
-  openair0_cfg[card].tx_freq[i] = downlink_frequency[0][i] ;
-      else
-  openair0_cfg[card].tx_freq[i]=0.0;
-
-      if (i<openair0_cfg[card].rx_num_channels)
-  openair0_cfg[card].rx_freq[i] =downlink_frequency[0][i] + uplink_frequency_offset[0][i] ;
-      else
-  openair0_cfg[card].rx_freq[i]=0.0;
-
-      openair0_cfg[card].autocal[i] = 1;
-      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
-      openair0_cfg[card].rx_gain[i] = RC.gNB[0]->rx_total_gain_dB;
-
-
-      openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file;
-      printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
-       card,i, openair0_cfg[card].tx_gain[i],
-       openair0_cfg[card].rx_gain[i],
-       openair0_cfg[card].tx_freq[i],
-       openair0_cfg[card].rx_freq[i]);
-    }
-  } // for loop on cards
-}
-*/
-
 void wait_RUs(void) {
   LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask);
   // wait for all RUs to be configured over fronthaul
@@ -587,10 +497,9 @@ void wait_gNBs(void) {
     waiting=0;
 
     for (i=0; i<RC.nb_nr_L1_inst; i++) {
-
       if (RC.gNB[i]->configured==0) {
-	waiting=1;
-	break;
+        waiting=1;
+        break;
       }
     }
   }
@@ -647,11 +556,8 @@ int stop_L1L2(module_id_t gnb_id) {
   LOG_I(GNB_APP, "calling kill_NR_RU_proc() for instance %d\n", gnb_id);
   kill_NR_RU_proc(gnb_id);
   oai_exit = 0;
-
-    //free_transport(RC.gNB[gnb_id]);
+  //free_transport(RC.gNB[gnb_id]);
   phy_free_nr_gNB(RC.gNB[gnb_id]);
-
-
   nr_phy_free_RU(RC.ru[gnb_id]);
   free_lte_top();
   return 0;
@@ -666,17 +572,13 @@ int restart_L1L2(module_id_t gnb_id) {
   LOG_W(GNB_APP, "restarting nr-softmodem\n");
   /* block threads */
   sync_var = -1;
-
   RC.gNB[gnb_id]->configured = 0;
-  
-
   RC.ru_mask |= (1 << ru->idx);
   set_function_spec_param(RC.ru[gnb_id]);
   LOG_I(GNB_APP, "attempting to create ITTI tasks\n");
   // No more rrc thread, as many race conditions are hidden behind
   rrc_enb_init();
   itti_mark_task_ready(TASK_RRC_ENB);
-
   /* pass a reconfiguration request which will configure everything down to
    * RC.eNB[i][j]->frame_parms, too */
   msg_p = itti_alloc_new_message(TASK_ENB_APP, 0, RRC_CONFIGURATION_REQ);
@@ -710,32 +612,34 @@ 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 main( int argc, char **argv ) {
   int ru_id, CC_id = 0;
   start_background_system();
 
@@ -743,6 +647,7 @@ int main( int argc, char **argv )
   if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) {
     exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
   }
+
   set_softmodem_sighandler();
 #ifdef DEBUG_CONSOLE
   setvbuf(stdout, NULL, _IONBF, 0);
@@ -762,8 +667,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");
@@ -786,35 +691,26 @@ int main( int argc, char **argv )
   itti_init(TASK_MAX, tasks_info);
   // initialize mscgen log after ITTI
   MSC_INIT(MSC_E_UTRAN, ADDED_QUEUES_MAX+TASK_MAX);
-
-
   init_opt();
+#ifdef PDCP_USE_NETLINK
 
+  if(!IS_SOFTMODEM_NOS1)
+    netlink_init();
 
-#ifdef PDCP_USE_NETLINK
-if(!IS_SOFTMODEM_NOS1)
-  netlink_init();
 #if defined(PDCP_USE_NETLINK_QUEUES)
   pdcp_netlink_init();
 #endif
 #endif
-
 #ifndef PACKAGE_VERSION
 #  define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
 #endif
   LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
 
-  if(IS_SOFTMODEM_NOS1)
-    init_pdcp();
-
-  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");
-  } else {
-    printf("No ITTI, Initializing L1\n");
+  if (RC.nb_nr_L1_inst > 0)
     RCconfig_NR_L1();
-  }
 
+  // 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 */
   /*
   RCconfig_nr_flexran();
@@ -822,15 +718,13 @@ if(!IS_SOFTMODEM_NOS1)
   for (i = 0; i < RC.nb_nr_L1_inst; i++) {
     flexran_agent_start(i);
   }
-*/
-
+  */
   // init UE_PF_PO and mutex lock
   pthread_mutex_init(&ue_pf_po_mutex, NULL);
   memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
   mlockall(MCL_CURRENT | MCL_FUTURE);
   pthread_cond_init(&sync_cond,NULL);
   pthread_mutex_init(&sync_mutex, NULL);
-
   usleep(1000);
 
   if (NFAPI_MODE) {
@@ -894,36 +788,40 @@ 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_DOFORMS) {
-    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__);
@@ -935,7 +833,6 @@ if(!IS_SOFTMODEM_NOS1)
   printf("Returned from ITTI signal handler\n");
   oai_exit=1;
   printf("oai_exit=%d\n",oai_exit);
-
   // stop threads
   /*#ifdef XFORMS
 
@@ -961,13 +858,16 @@ 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) */
   for (int inst = 0; inst < NB_gNB_INST; inst++) {
-      //free_transport(RC.gNB[inst]);
-      phy_free_nr_gNB(RC.gNB[inst]);
+    //free_transport(RC.gNB[inst]);
+    phy_free_nr_gNB(RC.gNB[inst]);
   }
 
   for (int inst = 0; inst < NB_RU; inst++) {
@@ -991,7 +891,6 @@ if(!IS_SOFTMODEM_NOS1)
       RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);
   }
 
-
   logClean();
   printf("Bye.\n");
   return 0;
diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h
index d6cfe6b906acef4026dcf08d7b03433b32fd1986..896c363cbf15ed17d06d6ea242d8c912f9e9b4a1 100644
--- a/executables/nr-softmodem.h
+++ b/executables/nr-softmodem.h
@@ -18,19 +18,29 @@
 /*   optname                helpstr                 paramflags        XXXptr                              defXXXval                   type         numelt               */
 /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define CMDLINE_PARAMS_DESC_GNB {  \
-    {"mmapped-dma",           CONFIG_HLP_DMAMAP,      PARAMFLAG_BOOL,   uptr:&mmapped_dma,                  defintval:0,                   TYPE_INT,    0},        \
     {"single-thread-disable", CONFIG_HLP_NOSNGLT,     PARAMFLAG_BOOL,   iptr:&single_thread_flag,           defintval:1,                   TYPE_INT,    0},        \
     {"A" ,                    CONFIG_HLP_TADV,        0,                uptr:&timing_advance,               defintval:0,                   TYPE_UINT,   0},        \
     {"E" ,                    CONFIG_HLP_TQFS,        PARAMFLAG_BOOL,   i8ptr:&threequarter_fs,             defintval:0,                   TYPE_INT8,   0},        \
-    {"K" ,                    CONFIG_HLP_ITTIL,       PARAMFLAG_NOFREE, strptr:&itti_dump_file,             defstrval:"/tmp/itti.dump",    TYPE_STRING, 0},        \
-    {"m" ,                    CONFIG_HLP_DLMCS,       0,                uptr:&target_dl_mcs,                defintval:0,                   TYPE_UINT,   0},        \
-    {"t" ,                    CONFIG_HLP_ULMCS,       0,                uptr:&target_ul_mcs,                defintval:0,                   TYPE_UINT,   0},        \
+    {"m" ,                    CONFIG_HLP_DLMCS_PHYTEST,0,               uptr:&target_dl_mcs,                defintval:0,                   TYPE_UINT,   0},        \
+    {"l" ,                    CONFIG_HLP_DLNL_PHYTEST,0,                uptr:&target_dl_Nl,                 defintval:0,                   TYPE_UINT,   0},        \
+    {"t" ,                    CONFIG_HLP_ULMCS_PHYTEST,0,               uptr:&target_ul_mcs,                defintval:0,                   TYPE_UINT,   0},        \
+    {"M" ,                    CONFIG_HLP_DLBW_PHYTEST,0,                uptr:&target_dl_bw,                 defintval:0,                   TYPE_UINT,   0},        \
+    {"T" ,                    CONFIG_HLP_ULBW_PHYTEST,0,                uptr:&target_ul_bw,                 defintval:0,                   TYPE_UINT,   0},        \
+    {"D" ,                    CONFIG_HLP_DLBM_PHYTEST,0,                u64ptr:&dlsch_slot_bitmap,          defintval:0,                   TYPE_UINT64, 0},        \
+    {"U" ,                    CONFIG_HLP_ULBM_PHYTEST,0,                u64ptr:&ulsch_slot_bitmap,          defintval:0,                   TYPE_UINT64, 0},        \
     {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0,                iptr:&usrp_tx_thread,               defstrval:0,                   TYPE_INT,    0},        \
     {"s" ,                    CONFIG_HLP_SNR,         0,                dblptr:&snr_dB,                     defdblval:25,                  TYPE_DOUBLE, 0},        \
   }
 
 #include "threads_t.h"
 extern threads_t threads;
+extern uint32_t target_dl_mcs;
+extern uint32_t target_dl_Nl;
+extern uint32_t target_ul_mcs;
+extern uint32_t target_dl_bw;
+extern uint32_t target_ul_bw;
+extern uint64_t dlsch_slot_bitmap;
+extern uint64_t ulsch_slot_bitmap;
 
 // In nr-gnb.c
 extern void init_gNB(int single_thread_flag,int wait_for_sync);
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 6be23582b18983c76ef2bc954bb8dd6eb01e1000..82b11f9b7fd29c464b4ffdef9b0525b572ffea90 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -27,6 +27,8 @@
 #include "SCHED_NR_UE/phy_frame_config_nr.h"
 #include "SCHED_NR_UE/defs.h"
 #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
+#include "executables/softmodem-common.h"
+#include "SCHED_NR_UE/pucch_uci_ue_nr.h"
 
 /*
  *  NR SLOT PROCESSING SEQUENCE
@@ -90,6 +92,8 @@
 #else
   #define DURATION_RX_TO_TX           (6)   /* For LTE, this duration is fixed to 4 and it is linked to LTE standard for both modes FDD/TDD */
 #endif
+#define RX_JOB_ID 0x1010
+#define TX_JOB_ID 100
 
 typedef enum {
   pss = 0,
@@ -107,6 +111,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
   ue->Mod_id      = UE_id;
   ue->mac_enabled = 1;
   ue->if_inst     = nr_ue_if_module_init(0);
+  ue->dci_thres   = 0;
 
   // Setting UE mode to NOT_SYNCHED by default
   for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){
@@ -129,10 +134,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
  * \param arg is a pointer to a \ref PHY_VARS_NR_UE structure.
  */
 
-typedef struct syncData_s {
-  UE_nr_rxtx_proc_t proc;
-  PHY_VARS_NR_UE *UE;
-} syncData_t;
+typedef nr_rxtx_thread_data_t syncData_t;
 
 static void UE_synch(void *arg) {
   syncData_t *syncD=(syncData_t *) arg;
@@ -218,7 +220,6 @@ static void UE_synch(void *arg) {
       LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
 
       uint64_t dl_carrier, ul_carrier;
-      double rx_gain_off = 0;
       nr_get_carrier_frequencies(&UE->frame_parms, &dl_carrier, &ul_carrier);
 
       if (nr_initial_sync(&syncD->proc, UE, 2) == 0) {
@@ -228,7 +229,7 @@ static void UE_synch(void *arg) {
 
         // rerun with new cell parameters and frequency-offset
         // todo: the freq_offset computed on DL shall be scaled before being applied to UL
-        nr_rf_card_config(&openair0_cfg[UE->rf_map.card], rx_gain_off, ul_carrier, dl_carrier, freq_offset);
+        nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_carrier, dl_carrier, freq_offset);
 
         LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n",
               hw_slot_offset,
@@ -237,43 +238,6 @@ static void UE_synch(void *arg) {
               openair0_cfg[UE->rf_map.card].rx_freq[0],
               openair0_cfg[UE->rf_map.card].tx_freq[0]);
 
-        // reconfigure for potentially different bandwidth
-        switch(UE->frame_parms.N_RB_DL) {
-          case 6:
-            openair0_cfg[UE->rf_map.card].sample_rate =1.92e6;
-            openair0_cfg[UE->rf_map.card].rx_bw          =.96e6;
-            openair0_cfg[UE->rf_map.card].tx_bw          =.96e6;
-            //            openair0_cfg[0].rx_gain[0] -= 12;
-            break;
-
-          case 25:
-            openair0_cfg[UE->rf_map.card].sample_rate =7.68e6;
-            openair0_cfg[UE->rf_map.card].rx_bw          =2.5e6;
-            openair0_cfg[UE->rf_map.card].tx_bw          =2.5e6;
-            //            openair0_cfg[0].rx_gain[0] -= 6;
-            break;
-
-          case 50:
-            openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
-            openair0_cfg[UE->rf_map.card].rx_bw          =5.0e6;
-            openair0_cfg[UE->rf_map.card].tx_bw          =5.0e6;
-            //            openair0_cfg[0].rx_gain[0] -= 3;
-            break;
-
-          case 100:
-            openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
-            openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
-            openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
-            //            openair0_cfg[0].rx_gain[0] -= 0;
-            break;
-
-          case 66:
-            openair0_cfg[UE->rf_map.card].sample_rate=122.88e6;
-            openair0_cfg[UE->rf_map.card].rx_bw=100.e6;
-            openair0_cfg[UE->rf_map.card].tx_bw=100.e6;
-            break;
-        }
-
         if (UE->mode != loop_through_memory) {
           UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
           //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
@@ -299,7 +263,7 @@ static void UE_synch(void *arg) {
 
           freq_offset *= -1;
 
-          nr_rf_card_config(&openair0_cfg[UE->rf_map.card], rx_gain_off, ul_carrier, dl_carrier, freq_offset);
+          nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_carrier, dl_carrier, freq_offset);
 
           LOG_I(PHY, "Initial sync failed: trying carrier off %d Hz\n", freq_offset);
 
@@ -316,11 +280,16 @@ static void UE_synch(void *arg) {
   }
 }
 
-void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
+void processSlotTX(void *arg) {
+
+  nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg;
+  UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
+  PHY_VARS_NR_UE    *UE   = rxtxD->UE;
   fapi_nr_config_request_t *cfg = &UE->nrUE_config;
   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
@@ -337,20 +306,25 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
       ul_indication.frame_tx  = proc->frame_tx;
       ul_indication.slot_tx   = proc->nr_slot_tx;
       ul_indication.thread_id = proc->thread_id;
+      ul_indication.ue_sched_mode = rxtxD->ue_sched_mode;
 
       UE->if_inst->ul_indication(&ul_indication);
     }
 
-    if (UE->mode != loop_through_memory) {
+    if ((UE->mode != loop_through_memory) && (rxtxD->ue_sched_mode != NOT_PUSCH)) {
       phy_procedures_nrUE_TX(UE,proc,0);
     }
   }
 }
 
-void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
+void processSlotRX(void *arg) {
 
+  nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg;
+  UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
+  PHY_VARS_NR_UE    *UE   = rxtxD->UE;
   fapi_nr_config_request_t *cfg = &UE->nrUE_config;
   int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_slot_rx);
+  int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx);
   uint8_t gNB_id = 0;
 
   if (rx_slot_type == NR_DOWNLINK_SLOT || rx_slot_type == NR_MIXED_SLOT){
@@ -366,44 +340,59 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
     phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL );
 #else
     uint64_t a=rdtsc();
-    phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel);
+    phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel, &rxtxD->txFifo);
     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);
       pdcp_run(&ctxt);
+
+      /* send tick to RLC and PDCP every ms */
+      if (proc->nr_slot_rx % UE->frame_parms.slots_per_subframe == 0) {
+        void nr_rlc_tick(int frame, int subframe);
+        void nr_pdcp_tick(int frame, int subframe);
+        nr_rlc_tick(proc->frame_rx, proc->nr_slot_rx / UE->frame_parms.slots_per_subframe);
+        nr_pdcp_tick(proc->frame_rx, proc->nr_slot_rx / UE->frame_parms.slots_per_subframe);
+      }
     }
-  }
+    // calling UL_indication to schedule things other than PUSCH (eg, PUCCH)
+    rxtxD->ue_sched_mode = NOT_PUSCH;
+    processSlotTX(rxtxD);
 
-}
+    // Wait for PUSCH processing to finish
+    notifiedFIFO_elt_t *res;
+    res = pullTpool(&rxtxD->txFifo,&(get_nrUE_params()->Tpool));
+    delNotifiedFIFO_elt(res);
 
-/*!
- * \brief This is the UE thread for RX subframe n and TX subframe n+4.
- * This thread performs the phy_procedures_UE_RX() on every received slot.
- * then, if TX is enabled it performs TX for n+4.
- * \param arg is a pointer to a \ref PHY_VARS_NR_UE structure.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
+  } else {
+    rxtxD->ue_sched_mode = SCHED_ALL;
+    processSlotTX(rxtxD);
+  }
 
-typedef struct processingData_s {
-  UE_nr_rxtx_proc_t proc;
-  PHY_VARS_NR_UE    *UE;
-}  processingData_t;
+  if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){
+    if (UE->UE_mode[gNB_id] <= PUSCH) {
+      if (get_softmodem_params()->usim_test==0) {
+        pucch_procedures_ue_nr(UE,
+                               gNB_id,
+                               proc);
+      }
 
-void UE_processing(void *arg) {
-  processingData_t *rxtxD = (processingData_t *) arg;
-  UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
-  PHY_VARS_NR_UE    *UE   = rxtxD->UE;
-  int slot_tx = proc->nr_slot_tx;
-  int frame_tx = proc->frame_tx;
+      LOG_D(PHY, "Sending Uplink data \n");
+      nr_ue_pusch_common_procedures(UE,
+                                    proc->nr_slot_tx,
+                                    &UE->frame_parms,1);
+    }
 
-  processSlotRX(UE, proc);
-  processSlotTX(UE, proc);
-  ue_ta_procedures(UE, slot_tx, frame_tx);
+    if (UE->UE_mode[gNB_id] > NOT_SYNCHED && UE->UE_mode[gNB_id] < PUSCH) {
+      nr_ue_prach_procedures(UE, proc, gNB_id);
+    }
+    LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", proc->frame_tx, proc->nr_slot_tx);
+  }
 
+  ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx);
 }
 
 void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
@@ -520,25 +509,44 @@ void *UE_thread(void *arg) {
   int start_rx_stream = 0;
   AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), "");
   UE->rfdevice.host_type = RAU_HOST;
+  UE->lost_sync = 0;
+  UE->is_synchronized = 0;
   AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n");
+
   notifiedFIFO_t nf;
   initNotifiedFIFO(&nf);
-  int nbSlotProcessing=0;
-  int thread_idx=0;
+
   notifiedFIFO_t freeBlocks;
   initNotifiedFIFO_nothreadSafe(&freeBlocks);
+
+  int nbSlotProcessing=0;
+  int thread_idx=0;
   NR_UE_MAC_INST_t *mac = get_mac_inst(0);
   int timing_advance = UE->timing_advance;
 
-  for (int i=0; i<RX_NB_TH+1; i++)  // RX_NB_TH working + 1 we are making to be pushed
-    pushNotifiedFIFO_nothreadSafe(&freeBlocks,
-                                  newNotifiedFIFO_elt(sizeof(processingData_t), 0,&nf,UE_processing));
-
   bool syncRunning=false;
   const int nb_slot_frame = UE->frame_parms.slots_per_frame;
   int absolute_slot=0, decoded_frame_rx=INT_MAX, trashed_frames=0;
 
+  for (int i=0; i<NR_RX_NB_TH+1; i++) {// NR_RX_NB_TH working + 1 we are making to be pushed
+    notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), RX_JOB_ID,&nf,processSlotRX);
+    nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(newElt);
+    initNotifiedFIFO(&curMsg->txFifo);
+    pushNotifiedFIFO_nothreadSafe(&freeBlocks, newElt);
+  }
+
   while (!oai_exit) {
+    if (UE->lost_sync) {
+      int nb = abortTpool(&(get_nrUE_params()->Tpool),RX_JOB_ID);
+      nb += abortNotifiedFIFO(&nf, RX_JOB_ID);
+      LOG_I(PHY,"Number of aborted slots %d\n",nb);
+      for (int i=0; i<nb; i++)
+        pushNotifiedFIFO_nothreadSafe(&freeBlocks, newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), RX_JOB_ID,&nf,processSlotRX));
+      nbSlotProcessing = 0;
+      UE->is_synchronized = 0;
+      UE->lost_sync = 0;
+    }
+
     if (syncRunning) {
       notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool));
 
@@ -548,9 +556,10 @@ void *UE_thread(void *arg) {
         if (UE->is_synchronized) {
           decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
           // shift the frame index with all the frames we trashed meanwhile we perform the synch search
-          decoded_frame_rx=(decoded_frame_rx + (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
+          decoded_frame_rx=(decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER;
         }
         delNotifiedFIFO_elt(res);
+        start_rx_stream=0;
       } else {
         readFrame(UE, &timestamp, true);
         trashed_frames+=2;
@@ -597,13 +606,13 @@ void *UE_thread(void *arg) {
 
     // whatever means thread_idx
     // Fix me: will be wrong when slot 1 is slow, as slot 2 finishes
-    // Slot 3 will overlap if RX_NB_TH is 2
+    // Slot 3 will overlap if NR_RX_NB_TH is 2
     // this is general failure in UE !!!
-    thread_idx = absolute_slot % RX_NB_TH;
+    thread_idx = absolute_slot % NR_RX_NB_TH;
     int slot_nr = absolute_slot % nb_slot_frame;
     notifiedFIFO_elt_t *msgToPush;
     AssertFatal((msgToPush=pullNotifiedFIFO_nothreadSafe(&freeBlocks)) != NULL,"chained list failure");
-    processingData_t *curMsg=(processingData_t *)NotifiedFifoData(msgToPush);
+    nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(msgToPush);
     curMsg->UE=UE;
     // update thread index for received subframe
     curMsg->proc.thread_id   = thread_idx;
@@ -631,18 +640,18 @@ void *UE_thread(void *arg) {
 
     for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
       txp[i] = (void *)&UE->common_vars.txdata[i][UE->frame_parms.get_samples_slot_timestamp(
-               ((slot_nr + DURATION_RX_TO_TX - RX_NB_TH)%nb_slot_frame),&UE->frame_parms,0)];
+               ((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH)%nb_slot_frame),&UE->frame_parms,0)];
 
     int readBlockSize, writeBlockSize;
 
     if (slot_nr<(nb_slot_frame - 1)) {
       readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms);
-      writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - RX_NB_TH) % nb_slot_frame, &UE->frame_parms);
+      writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH) % nb_slot_frame, &UE->frame_parms);
     } else {
       UE->rx_offset_diff = computeSamplesShift(UE);
       readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) -
                     UE->rx_offset_diff;
-      writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - RX_NB_TH) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff;
+      writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff;
     }
 
     AssertFatal(readBlockSize ==
@@ -669,31 +678,33 @@ void *UE_thread(void *arg) {
     }
 
     curMsg->proc.timestamp_tx = timestamp+
-                                UE->frame_parms.get_samples_slot_timestamp(slot_nr,
-                                &UE->frame_parms,DURATION_RX_TO_TX) - firstSymSamp;
+      UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX) 
+      - firstSymSamp;
 
     notifiedFIFO_elt_t *res;
 
-    while (nbSlotProcessing >= RX_NB_TH) {
+    while (nbSlotProcessing >= NR_RX_NB_TH) {
       res=pullTpool(&nf, &(get_nrUE_params()->Tpool));
       nbSlotProcessing--;
-      processingData_t *tmp=(processingData_t *)res->msgData;
+      nr_rxtx_thread_data_t *tmp=(nr_rxtx_thread_data_t *)res->msgData;
 
       if (tmp->proc.decoded_frame_rx != -1)
         decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
-      else 
+      else
          decoded_frame_rx=-1;
 
       pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
     }
 
-    if (  decoded_frame_rx>0 && decoded_frame_rx != curMsg->proc.frame_rx)
+    if (decoded_frame_rx>0 && decoded_frame_rx != curMsg->proc.frame_rx)
       LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n",
-            decoded_frame_rx, curMsg->proc.frame_rx  );
+            decoded_frame_rx, curMsg->proc.frame_rx);
 
     // use previous timing_advance value to compute writeTimestamp
-    writeTimestamp = timestamp + UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms,DURATION_RX_TO_TX - RX_NB_TH) -
-                     firstSymSamp - openair0_cfg[0].tx_sample_advance - UE->N_TA_offset - timing_advance;
+    writeTimestamp = timestamp+
+      UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX
+      - NR_RX_NB_TH) - firstSymSamp - openair0_cfg[0].tx_sample_advance -
+      UE->N_TA_offset - timing_advance;
 
     // but use current UE->timing_advance value to compute writeBlockSize
     if (UE->timing_advance != timing_advance) {
@@ -702,51 +713,47 @@ void *UE_thread(void *arg) {
     }
 
     int flags = 0;
-    int slot_tx_usrp = slot_nr + DURATION_RX_TO_TX - RX_NB_TH;
-    uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots;
-    uint8_t num_UL_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots +
-                           (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0);
-    uint8_t first_tx_slot = tdd_period - num_UL_slots;
-    if (slot_tx_usrp%tdd_period==first_tx_slot)
-      flags=2;
-    else     if (slot_tx_usrp%tdd_period==first_tx_slot+num_UL_slots-1)
-      flags = 3;
-    else     if (slot_tx_usrp%tdd_period>first_tx_slot)
+    int slot_tx_usrp = slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH;
+
+    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 = 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;
+
+      if (slot_tx_usrp % tdd_period == first_tx_slot)
+        flags = 2;
+      else if (slot_tx_usrp % tdd_period == first_tx_slot + num_UL_slots - 1)
+        flags = 3;
+      else if (slot_tx_usrp % tdd_period > first_tx_slot)
+        flags = 1;
+    } else {
       flags = 1;
+    }
 
     if (flags || IS_SOFTMODEM_RFSIM)
-      AssertFatal( writeBlockSize ==
-                 UE->rfdevice.trx_write_func(&UE->rfdevice,
-					       writeTimestamp,
-					       txp,
-					       writeBlockSize,
-					       UE->frame_parms.nb_antennas_tx,
-					       flags),"");
+      AssertFatal(writeBlockSize ==
+                  UE->rfdevice.trx_write_func(&UE->rfdevice,
+                                              writeTimestamp,
+                                              txp,
+                                              writeBlockSize,
+                                              UE->frame_parms.nb_antennas_tx,
+                                              flags),"");
     
     for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
       memset(txp[i], 0, writeBlockSize);
 
     nbSlotProcessing++;
-    msgToPush->key=slot_nr;
+    LOG_D(PHY,"Number of slots being processed at the moment: %d\n",nbSlotProcessing);
     pushTpool(&(get_nrUE_params()->Tpool), msgToPush);
 
-    if (IS_SOFTMODEM_RFSIM) {  //getenv("RFSIMULATOR")
-      // FixMe: Wait previous thread is done, because race conditions seems too bad
-      // in case of actual RF board, the overlap between threads mitigate the issue
-      // We must receive one message, that proves the slot processing is done
-      res=pullTpool(&nf, &(get_nrUE_params()->Tpool));
-      nbSlotProcessing--;
-      processingData_t *tmp=(processingData_t *)res->msgData;
-
-      if (tmp->proc.decoded_frame_rx != -1)
-        decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
-      else 
-        decoded_frame_rx=-1;
-        //decoded_frame_rx=tmp->proc.decoded_frame_rx;
-
-      pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
-    }
-
   } // while !oai_exit
 
   return NULL;
@@ -761,23 +768,6 @@ void init_NR_UE(int nb_inst, char* rrc_config_path) {
     AssertFatal((rrc_inst = nr_l3_init_ue(rrc_config_path)) != NULL, "can not initialize RRC module\n");
     AssertFatal((mac_inst = nr_l2_init_ue(rrc_inst)) != NULL, "can not initialize L2 module\n");
     AssertFatal((mac_inst->if_module = nr_ue_if_module_init(inst)) != NULL, "can not initialize IF module\n");
-
-    NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
-    if (mac_inst->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
-      pusch_TimeDomainAllocationList = mac_inst->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
-    }
-    else if (mac_inst->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
-      pusch_TimeDomainAllocationList = mac_inst->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
-    }
-    	
-    if (pusch_TimeDomainAllocationList) {
-      for(int i = 0; i < pusch_TimeDomainAllocationList->list.count; i++) {
-        AssertFatal(*pusch_TimeDomainAllocationList->list.array[i]->k2 >= DURATION_RX_TO_TX, 
-                    "Slot offset K2 (%ld) cannot be less than DURATION_RX_TO_TX (%d)\n", 
-                    *pusch_TimeDomainAllocationList->list.array[i]->k2,
-                    DURATION_RX_TO_TX);
-      }
-    }
   }
 }
 
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 5d651344d608e606bb6d7d76512c9fe730edd99d..9475cc8657c879366ab1537aaa1fef09b9fe08ec 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -82,12 +82,15 @@ unsigned short config_frames[4] = {2,9,11,13};
 // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
 #include "PHY/TOOLS/phy_scope_interface.h"
 #include "PHY/TOOLS/nr_phy_scope.h"
-#define NRUE_MAIN
 #include <executables/nr-uesoftmodem.h>
 #include "executables/softmodem-common.h"
 #include "executables/thread-common.h"
 
+#include "nr_nas_msg_sim.h"
+
 extern const char *duplex_mode[];
+THREAD_STRUCT thread_struct;
+nrUE_params_t nrUE_params;
 
 // Thread variables
 pthread_cond_t nfapi_sync_cond;
@@ -102,8 +105,6 @@ int config_sync_var=-1;
 
 
 RAN_CONTEXT_t RC;
-volatile int             start_eNB = 0;
-volatile int             start_UE = 0;
 volatile int             oai_exit = 0;
 
 
@@ -146,11 +147,11 @@ int           card_offset = 0;
 uint64_t num_missed_slots = 0; // counter for the number of missed slots
 int     transmission_mode = 1;
 int            numerology = 0;
-int        usrp_tx_thread = 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
@@ -180,6 +181,26 @@ void print_difftimes(void) {
   LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
 }
 
+int create_tasks_nrue(uint32_t ue_nb) {
+  LOG_D(NR_RRC, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb);
+  itti_wait_ready(1);
+
+  if (ue_nb > 0) {
+    LOG_I(NR_RRC,"create TASK_RRC_NRUE \n");
+    if (itti_create_task (TASK_RRC_NRUE, rrc_nrue_task, NULL) < 0) {
+      LOG_E(NR_RRC, "Create task for RRC UE failed\n");
+      return -1;
+    }
+  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;
+  }
+  }
+
+  itti_wait_ready(0);
+  return 0;
+}
+
 void exit_function(const char *file, const char *function, const int line, const char *s) {
   int CC_id;
 
@@ -214,9 +235,16 @@ nrUE_params_t *get_nrUE_params(void) {
 }
 /* initialie thread pools used for NRUE processing paralleliation */ 
 void init_tpools(uint8_t nun_dlsch_threads) {
-  char *params=calloc(1,(RX_NB_TH*3)+1);
-  for (int i=0; i<RX_NB_TH; i++) {
-    memcpy(params+(i*3),"-1,",3);
+  char *params = NULL;
+  if (IS_SOFTMODEM_RFSIM) {
+    params = calloc(1,2);
+    memcpy(params,"N",1);
+  }
+  else {
+    params = calloc(1,(NR_RX_NB_TH*NR_NB_TH_SLOT*3)+1);
+    for (int i=0; i<NR_RX_NB_TH*NR_NB_TH_SLOT; i++) {
+      memcpy(params+(i*3),"-1,",3);
+    }
   }
   initTpool(params, &(nrUE_params.Tpool), false);
   free(params);
@@ -240,7 +268,6 @@ static void get_options(void) {
     printf("%s\n",uecap_xer);
     uecap_xer_in=1;
   } /* UE with config file  */
-    init_tpools(nrUE_params.nr_dlsch_parallel);
 }
 
 // set PHY vars from command line
@@ -303,8 +330,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);
 
 }
@@ -316,92 +344,10 @@ void init_openair0(void) {
 
   for (card=0; card<MAX_CARDS; card++) {
     uint64_t dl_carrier, ul_carrier;
-    openair0_cfg[card].configFilename = NULL;
-    openair0_cfg[card].threequarter_fs = frame_parms->threequarter_fs;
-    numerology = frame_parms->numerology_index;
-
-    if(frame_parms->N_RB_DL == 66) {
-      if (numerology==3) {
-          openair0_cfg[card].sample_rate=122.88e6;
-          openair0_cfg[card].samples_per_frame = 1228800;
-        } else {
-          LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n");
-          exit(-1);
-        }
-    }else if(frame_parms->N_RB_DL == 32) {
-      if (numerology==3) {
-          openair0_cfg[card].sample_rate=61.44e6;
-          openair0_cfg[card].samples_per_frame = 614400;
-        } else {
-          LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n");
-          exit(-1);
-        }
-    }else if(frame_parms->N_RB_DL == 217) {
-      if (numerology==1) {
-        if (frame_parms->threequarter_fs) {
-          openair0_cfg[card].sample_rate=92.16e6;
-          openair0_cfg[card].samples_per_frame = 921600;
-        }
-        else {
-          openair0_cfg[card].sample_rate=122.88e6;
-          openair0_cfg[card].samples_per_frame = 1228800;
-        }
-      } else {
-        LOG_E(PHY,"Unsupported numerology!\n");
-        exit(-1);
-      }
-    } else if(frame_parms->N_RB_DL == 273) {
-      if (numerology==1) {
-        if (frame_parms->threequarter_fs) {
-          AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n");
-        }
-        else {
-          openair0_cfg[card].sample_rate=122.88e6;
-          openair0_cfg[card].samples_per_frame = 1228800;
-        }
-      } else {
-        LOG_E(PHY,"Unsupported numerology!\n");
-        exit(-1);
-      }
-    } else if(frame_parms->N_RB_DL == 106) {
-      if (numerology==0) {
-        if (frame_parms->threequarter_fs) {
-          openair0_cfg[card].sample_rate=23.04e6;
-          openair0_cfg[card].samples_per_frame = 230400;
-        } else {
-          openair0_cfg[card].sample_rate=30.72e6;
-          openair0_cfg[card].samples_per_frame = 307200;
-        }
-      } else if (numerology==1) {
-        if (frame_parms->threequarter_fs) {
-          openair0_cfg[card].sample_rate=46.08e6;
-          openair0_cfg[card].samples_per_frame = 460800;
-	}
-	else {
-          openair0_cfg[card].sample_rate=61.44e6;
-          openair0_cfg[card].samples_per_frame = 614400;
-        }
-      } else if (numerology==2) {
-        openair0_cfg[card].sample_rate=122.88e6;
-        openair0_cfg[card].samples_per_frame = 1228800;
-      } else {
-        LOG_E(PHY,"Unsupported numerology!\n");
-        exit(-1);
-      }
-    } else if(frame_parms->N_RB_DL == 50) {
-      openair0_cfg[card].sample_rate=15.36e6;
-      openair0_cfg[card].samples_per_frame = 153600;
-    } else if (frame_parms->N_RB_DL == 25) {
-      openair0_cfg[card].sample_rate=7.68e6;
-      openair0_cfg[card].samples_per_frame = 76800;
-    } else if (frame_parms->N_RB_DL == 6) {
-      openair0_cfg[card].sample_rate=1.92e6;
-      openair0_cfg[card].samples_per_frame = 19200;
-    }
-    else {
-      LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms->N_RB_DL);
-      exit(-1);
-    }
+    openair0_cfg[card].configFilename    = NULL;
+    openair0_cfg[card].threequarter_fs   = frame_parms->threequarter_fs;
+    openair0_cfg[card].sample_rate       = frame_parms->samples_per_subframe * 1e3;
+    openair0_cfg[card].samples_per_frame = frame_parms->samples_per_frame;
 
     if (frame_parms->frame_type==TDD)
       openair0_cfg[card].duplex_mode = duplex_mode_TDD;
@@ -412,18 +358,20 @@ void init_openair0(void) {
     openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL;
     openair0_cfg[card].clock_source = get_softmodem_params()->clock_source;
     openair0_cfg[card].time_source = get_softmodem_params()->timing_source;
-    openair0_cfg[card].tx_num_channels = min(2, frame_parms->nb_antennas_tx);
-    openair0_cfg[card].rx_num_channels = min(2, frame_parms->nb_antennas_rx);
+    openair0_cfg[card].tx_num_channels = min(4, frame_parms->nb_antennas_tx);
+    openair0_cfg[card].rx_num_channels = min(4, frame_parms->nb_antennas_rx);
 
-    LOG_I(PHY, "HW: Configuring card %d, tx/rx num_channels %d/%d, duplex_mode %s\n",
+    LOG_I(PHY, "HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n",
       card,
+      openair0_cfg[card].sample_rate,
       openair0_cfg[card].tx_num_channels,
       openair0_cfg[card].rx_num_channels,
       duplex_mode[openair0_cfg[card].duplex_mode]);
 
     nr_get_carrier_frequencies(frame_parms, &dl_carrier, &ul_carrier);
 
-    nr_rf_card_config(&openair0_cfg[card], rx_gain_off, ul_carrier, dl_carrier, freq_off);
+    nr_rf_card_config_freq(&openair0_cfg[card], ul_carrier, dl_carrier, freq_off);
+    nr_rf_card_config_gain(&openair0_cfg[card], rx_gain_off);
 
     openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file;
 
@@ -447,10 +395,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
@@ -478,6 +426,7 @@ int main( int argc, char **argv ) {
   get_options (); //Command-line options specific for NRUE
 
   get_common_options(SOFTMODEM_5GUE_BIT );
+  init_tpools(nrUE_params.nr_dlsch_parallel);
   CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
 #if T_TRACER
   T_Config_Init();
@@ -501,7 +450,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;
@@ -529,9 +478,24 @@ 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;
+    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]);
 
-    nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]);
-    init_symbol_rotation(&UE[CC_id]->frame_parms, UE[CC_id]->frame_parms.dl_CarrierFreq);
+    init_symbol_rotation(&UE[CC_id]->frame_parms);
     init_nr_ue_vars(UE[CC_id], 0, abstraction_flag);
 
     #ifdef FR2_TEST
@@ -551,7 +515,7 @@ int main( int argc, char **argv ) {
   configure_linux();
   mlockall(MCL_CURRENT | MCL_FUTURE);
  
-  if(IS_SOFTMODEM_DOFORMS) { 
+  if(IS_SOFTMODEM_DOSCOPE) {
     load_softscope("nr",PHY_vars_UE_g[0][0]);
   }     
 
@@ -561,6 +525,12 @@ int main( int argc, char **argv ) {
   
   // wait for end of program
   printf("TYPE <CTRL-C> TO TERMINATE\n");
+
+  if (create_tasks_nrue(1) < 0) {
+    printf("cannot create ITTI tasks\n");
+    exit(-1); // need a softer mode
+  }
+
   // Sleep a while before checking all parameters have been used
   // Some are used directly in external threads, asynchronously
   sleep(20);
diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h
index 5902c8cca8b30f1fa7bb410db266790bb7b6c6fc..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}, \
@@ -72,9 +72,6 @@ extern uint64_t get_nrUE_optmask(void);
 extern uint64_t set_nrUE_optmask(uint64_t bitmask);
 extern nrUE_params_t *get_nrUE_params(void);
 
-#ifdef NRUE_MAIN
-nrUE_params_t nrUE_params;
-#endif
 
 // In nr-ue.c
 extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
diff --git a/executables/ocp-gnb.c b/executables/ocp-gnb.c
index 4ddc7870d9c7f06301ba66752a0a4039d3f8fe50..326f7d277f7df5c5ff20f09da30d174d63d8f605 100644
--- a/executables/ocp-gnb.c
+++ b/executables/ocp-gnb.c
@@ -61,8 +61,6 @@ uint32_t do_forms=0;
 unsigned int mmapped_dma=0;
 int8_t threequarter_fs=0;
 
-uint32_t target_dl_mcs = 28; //maximum allowed mcs
-uint32_t target_ul_mcs = 20;
 int chain_offset=0;
 uint16_t sl_ahead=6;
 uint16_t sf_ahead=6;
@@ -70,16 +68,15 @@ uint32_t timing_advance = 0;
 int transmission_mode=1;
 int emulate_rf = 0;
 int numerology = 0;
-int usrp_tx_thread = 0;
 
 
 int config_sync_var=-1;
 pthread_mutex_t nfapi_sync_mutex;
 pthread_cond_t nfapi_sync_cond;
 int nfapi_sync_var=-1;
-uint8_t nfapi_mode = NFAPI_MONOLITHIC; // Default to monolithic mode
 double cpuf;
 
+THREAD_STRUCT thread_struct;
 
 pthread_cond_t sync_cond;
 pthread_mutex_t sync_mutex;
@@ -95,7 +92,8 @@ time_stats_t nfapi_meas; // total tx time
 time_stats_t softmodem_stats_rx_sf; // total rx time
 // not used but needed for link
 openair0_config_t openair0_cfg[MAX_CARDS];
-
+uint16_t slot_ahead=6;
+msc_interface_t msc_interface;
 AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB];
 AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB];
 int flexran_agent_start(mid_t mod_id) {
@@ -122,7 +120,6 @@ int restart_L1L2(module_id_t gnb_id) {
 }
 
 static int wait_for_sync = 0;
-static char *itti_dump_file = NULL;
 static double snr_dB=20;
 static int DEFBANDS[] = {7};
 static int DEFENBS[] = {0};
@@ -996,7 +993,7 @@ int main( int argc, char **argv ) {
                  (void *)NULL, "time_meas", -1, OAI_PRIORITY_RT_LOW);
   }
 
-  if(IS_SOFTMODEM_DOFORMS) {
+  if(IS_SOFTMODEM_DOSCOPE) {
     scopeParms_t tmp= {&argc, argv, &ru, RC.gNB[0]};
     load_softscope("nr",&tmp);
   }
diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c
index 1077c0e1ac4ae40c32953758c77424dbda479880..e10515ea1acab5330d18e23a0ded937459d23965 100644
--- a/executables/softmodem-common.c
+++ b/executables/softmodem-common.c
@@ -45,6 +45,8 @@
 static softmodem_params_t softmodem_params;
 char *parallel_config=NULL;
 char *worker_config=NULL;
+msc_interface_t msc_interface;
+int usrp_tx_thread = 0;
 
 uint8_t nfapi_mode=0;
 
@@ -86,8 +88,8 @@ char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr) {
 void get_common_options(uint32_t execmask) {
   uint32_t online_log_messages=0;
   uint32_t glog_level=0 ;
-  uint32_t start_telnetsrv = 0;
-  uint32_t noS1 = 0, nokrnmod = 0, nonbiot = 0;
+  uint32_t start_telnetsrv = 0, start_telnetclt = 0;
+  uint32_t noS1 = 0, nokrnmod = 1, nonbiot = 0;
   uint32_t rfsim = 0, basicsim = 0, do_forms = 0;
   char *logmem_filename = NULL;
   paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;
@@ -95,21 +97,26 @@ void get_common_options(uint32_t execmask) {
   checkedparam_t cmdline_log_CheckParams[] = CMDLINE_LOGPARAMS_CHECK_DESC;
   check_execmask(execmask);
   config_get( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
-  config_set_checkfunctions(cmdline_logparams, cmdline_log_CheckParams,
-                            sizeof(cmdline_logparams)/sizeof(paramdef_t));
-  config_get( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL);
-
-  if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) {
+  
+  int numparams=sizeof(cmdline_logparams)/sizeof(paramdef_t);
+  config_set_checkfunctions(cmdline_logparams, cmdline_log_CheckParams,numparams);
+  config_get( cmdline_logparams,numparams,NULL);
+  
+  if(config_isparamset(cmdline_logparams,config_paramidx_fromname(cmdline_logparams,numparams, CONFIG_FLOG_OPT))) {
     set_glog_onlinelog(online_log_messages);
   }
 
-  if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) {
+  if(config_isparamset(cmdline_logparams,config_paramidx_fromname(cmdline_logparams,numparams, CONFIG_LOGL_OPT))) {
     set_glog(glog_level);
   }
 
   if (start_telnetsrv) {
     load_module_shlib("telnetsrv",NULL,0,NULL);
   }
+  
+  if (start_telnetclt) {
+    set_softmodem_optmask(SOFTMODEM_TELNETCLT_BIT);
+  }
 
   if (logmem_filename != NULL && strlen(logmem_filename) > 0) {
     log_mem_filename = &logmem_filename[0];
@@ -140,7 +147,7 @@ void get_common_options(uint32_t execmask) {
   }
 
   if (do_forms) {
-    set_softmodem_optmask(SOFTMODEM_DOFORMS_BIT);
+    set_softmodem_optmask(SOFTMODEM_DOSCOPE_BIT);
   }
 
   if(parallel_config != NULL) set_parallel_conf(parallel_config);
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index 60a761c732a8bdbb3ad710516285ac6e9dec1d8b..b6a2b18215ab51b617b86a655f40e9ef6dc06f30 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -73,6 +73,7 @@ extern "C"
 #define CONFIG_HLP_STMON         "Enable processing timing measurement of lte softmodem on per subframe basis \n"
 #define CONFIG_HLP_256QAM        "Use the 256 QAM mcs table for PDSCH\n"
 
+#define CONFIG_HLP_NONSTOP       "Go back to frame sync mode after 100 consecutive PBCH failures\n"
 //#define CONFIG_HLP_NUMUES        "Set the number of UEs for the emulation"
 #define CONFIG_HLP_MSLOTS        "Skip the missed slots/subframes \n"
 #define CONFIG_HLP_ULMCS         "Set the maximum uplink MCS\n"
@@ -84,13 +85,17 @@ 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"
+#define CONFIG_HLP_USRP_THREAD   "having extra thead for usrp tx\n"
+
 #define CONFIG_HLP_NOS1          "Disable s1 interface\n"
 #define CONFIG_HLP_RFSIM         "Run in rf simulator mode (also known as basic simulator)\n"
 #define CONFIG_HLP_NOKRNMOD      "(noS1 only): Use tun instead of namesh module \n"
 #define CONFIG_HLP_DISABLNBIOT   "disable nb-iot, even if defined in config\n"
+#define CONFIG_HLP_USRP_THREAD   "having extra thead for usrp tx\n"
 #define CONFIG_HLP_NFAPI         "Change the nFAPI mode for NR\n"
 
 /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
@@ -107,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
@@ -114,27 +120,30 @@ extern "C"
 #define USIM_TEST           softmodem_params.usim_test
 #define USE_256QAM_TABLE    softmodem_params.use_256qam_table
 #define NFAPI               softmodem_params.nfapi
+#define NON_STOP            softmodem_params.non_stop
 
 #define DEFAULT_RFCONFIG_FILE    "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat";
 
+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},                     \
@@ -144,7 +153,9 @@ extern "C"
     {"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},                     \
-    {"nfapi",                CONFIG_HLP_NFAPI,        0,              u8ptr:&nfapi_mode,                       defintval:0,           TYPE_UINT8,  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},                     \
   }
 
   
@@ -153,23 +164,22 @@ extern "C"
 #define CONFIG_HLP_LOGV          "Set the global log verbosity \n"
 #define CONFIG_HLP_TELN          "Start embedded telnet server \n"
 #define CONFIG_HLP_MSC           "Enable the MSC tracing utility \n"
-/*----------------------------------------------------------------------------------------------------------------------------*/
-/*                                            command line parameters for LOG utility                                         */
-/*   optname         helpstr          paramflags        XXXptr                     defXXXval            type           numelt */
-/*----------------------------------------------------------------------------------------------------------------------------*/
+#define CONFIG_FLOG_OPT          "R"
+#define CONFIG_LOGL_OPT          "g"
+/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            command line parameters for LOG utility                                                              */
+/*   optname                        helpstr       paramflags        XXXptr                              defXXXval            type           numelt */
+/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define START_MSC                softmodem_params.start_msc
 #define CMDLINE_LOGPARAMS_DESC {  \
-    {"R" ,           CONFIG_HLP_FLOG, 0,                uptr:&online_log_messages, defintval:1,         TYPE_INT,      0},     \
-    {"g" ,           CONFIG_HLP_LOGL, 0,                uptr:&glog_level,          defintval:0,         TYPE_UINT,     0},     \
-	{"telnetsrv",    CONFIG_HLP_TELN, PARAMFLAG_BOOL,   uptr:&start_telnetsrv,     defintval:0,         TYPE_UINT,     0},     \
-    {"msc",          CONFIG_HLP_MSC,  PARAMFLAG_BOOL,   uptr:&START_MSC,           defintval:0,         TYPE_UINT,     0},     \
-	{"log-mem",      NULL,            0,      strptr:(char **)&logmem_filename,    defstrval:NULL,      TYPE_STRING,   0},     \
+    {CONFIG_FLOG_OPT ,           CONFIG_HLP_FLOG, 0,                uptr:&online_log_messages,           defintval:1,         TYPE_INT,      0},     \
+    {CONFIG_LOGL_OPT ,           CONFIG_HLP_LOGL, 0,                uptr:&glog_level,                    defintval:0,         TYPE_UINT,     0},     \
+	{"telnetsrv",                CONFIG_HLP_TELN, PARAMFLAG_BOOL,   uptr:&start_telnetsrv,               defintval:0,         TYPE_UINT,     0},     \
+    {"msc",                      CONFIG_HLP_MSC,  PARAMFLAG_BOOL,   uptr:&START_MSC,                     defintval:0,         TYPE_UINT,     0},     \
+	{"log-mem",                  NULL,            0,                strptr:(char **)&logmem_filename,    defstrval:NULL,      TYPE_STRING,   0},     \
+	{"telnetclt",                NULL,            0,                uptr:&start_telnetclt,               defstrval:NULL,      TYPE_UINT,     0},     \
   }
 
-#define CMDLINE_ONLINELOG_IDX     0
-#define CMDLINE_GLOGLEVEL_IDX     1
-#define CMDLINE_GLOGVERBO_IDX     2
-#define CMDLINE_STARTTELN_IDX     3
 
 /* check function for global log level */
 #define CMDLINE_LOGPARAMS_CHECK_DESC { \
@@ -178,6 +188,7 @@ extern "C"
     { .s5= {NULL} } ,                       \
     { .s5= {NULL} } ,                       \
     { .s5= {NULL} } ,                       \
+    { .s5= {NULL} } ,                       \
   }
 
 /***************************************************************************************************************************************/
@@ -188,8 +199,9 @@ extern "C"
 #define SOFTMODEM_RFSIM_BIT           (1<<10)
 #define SOFTMODEM_BASICSIM_BIT        (1<<11)
 #define SOFTMODEM_SIML1_BIT           (1<<12)
-#define SOFTMODEM_DOFORMS_BIT         (1<<15)
+#define SOFTMODEM_DOSCOPE_BIT         (1<<15)
 #define SOFTMODEM_RECPLAY_BIT         (1<<16)
+#define SOFTMODEM_TELNETCLT_BIT       (1<<17)
 #define SOFTMODEM_ENB_BIT             (1<<20)
 #define SOFTMODEM_GNB_BIT             (1<<21)
 #define SOFTMODEM_4GUE_BIT            (1<<22)
@@ -204,8 +216,9 @@ extern "C"
 #define IS_SOFTMODEM_RFSIM           ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT)
 #define IS_SOFTMODEM_BASICSIM        ( get_softmodem_optmask() & SOFTMODEM_BASICSIM_BIT)
 #define IS_SOFTMODEM_SIML1           ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT)
-#define IS_SOFTMODEM_DOFORMS         ( get_softmodem_optmask() & SOFTMODEM_DOFORMS_BIT)
+#define IS_SOFTMODEM_DOSCOPE         ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT)
 #define IS_SOFTMODEM_IQPLAYER        ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT)
+#define IS_SOFTMODEM_TELNETCLT_BIT   ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT)    
 #define IS_SOFTMODEM_ENB_BIT         ( get_softmodem_optmask() & SOFTMODEM_ENB_BIT)
 #define IS_SOFTMODEM_GNB_BIT         ( get_softmodem_optmask() & SOFTMODEM_GNB_BIT)
 #define IS_SOFTMODEM_4GUE_BIT        ( get_softmodem_optmask() & SOFTMODEM_4GUE_BIT)
@@ -226,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;
@@ -233,6 +247,7 @@ typedef struct {
   uint32_t       send_dmrs_sync;
   int            use_256qam_table;
   uint8_t        nfapi;
+  int            non_stop;
 } softmodem_params_t;
 
 extern uint64_t get_softmodem_optmask(void);
@@ -244,6 +259,14 @@ extern char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr);
 extern void set_softmodem_sighandler(void);
 extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
 extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+extern int usrp_tx_thread;
+extern uint16_t sl_ahead;
+extern uint16_t sf_ahead;
+extern volatile int  oai_exit;
+
+void tx_func(void *param);
+void rx_func(void *param);
+void ru_tx_func(void *param);
 extern uint8_t nfapi_mode;
 #ifdef __cplusplus
 }
diff --git a/executables/thread-common.h b/executables/thread-common.h
index 6f3af3cfc00f69fef57958f58d3b0a0f193de10b..0aaeb3c30ed04a48ae596ab19852adccee56502d 100644
--- a/executables/thread-common.h
+++ b/executables/thread-common.h
@@ -3,7 +3,7 @@
 
 #include "PHY/defs_common.h"
 
-THREAD_STRUCT thread_struct;
+extern THREAD_STRUCT thread_struct;
 
 static inline void set_parallel_conf(char *parallel_conf) {
   mapping config[]= {
diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c
index 4ca02ed929c2f2d5444462135c9cc85e1a61c3fd..d9c5df199c09e70b9239923b03dc71ca9fc62697 100644
--- a/nfapi/oai_integration/nfapi_pnf.c
+++ b/nfapi/oai_integration/nfapi_pnf.c
@@ -59,6 +59,9 @@ extern RAN_CONTEXT_t RC;
 #include "openair1/SCHED_NR/fapi_nr_l1.h"
 #include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h"
 #include "openair1/PHY/defs_gNB.h"
+#include <openair1/SCHED/fapi_l1.h>
+#include <openair1/PHY/NR_TRANSPORT/nr_transport_proto.h>
+#include <targets/RT/USER/lte-softmodem.h>
 
 
 #define NUM_P5_PHY 2
@@ -73,46 +76,6 @@ extern pthread_mutex_t nfapi_sync_mutex;
 extern int nfapi_sync_var;
 
 extern int sync_var;
-char uecap_xer_in;
-
-extern void init_eNB_afterRU(void);
-extern void init_UE_stub(int nb_inst,int,int);
-extern void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu);
-extern void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu, uint16_t frame,uint8_t subframe,uint8_t srs_present);
-extern void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1_rxtx_proc_t *proc,  nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu);
-extern void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu);
-extern void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu);
-extern void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu);
-extern void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
-			       int frame, int slot,
-			       nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu);
-extern void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
-			       int frame, int slot,
-			       nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu);
-extern void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
-                            nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
-                            uint8_t *sdu);
-extern void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
-                             nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu);
-extern void nr_fill_ulsch(PHY_VARS_gNB *gNB,
-                   int frame,
-                   int slot,
-                   nfapi_nr_pusch_pdu_t *ulsch_pdu);
-extern void nr_fill_pucch(PHY_VARS_gNB *gNB,
-                   int frame,
-                   int slot,
-                   nfapi_nr_pucch_pdu_t *pucch_pdu);
-extern void nr_fill_prach(PHY_VARS_gNB *gNB,
-                   int SFN,
-                   int Slot,
-                   nfapi_nr_prach_pdu_t *prach_pdu);
-extern void nr_fill_prach_ru(RU_t *ru,
-                      int SFN,
-                      int Slot,
-                      nfapi_nr_prach_pdu_t *prach_pdu);
-
-
-
 
 nfapi_tx_request_pdu_t *tx_request_pdu[1023][10][10]; // [frame][subframe][max_num_pdus]
 uint8_t nr_tx_pdus[32][16][4096];
@@ -2199,7 +2162,7 @@ void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_add
   pnf.phys[0].udp.tx_port = vnf_p7_port;
   strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr);
   strcpy(pnf.phys[0].local_addr, pnf_ip_addr);
-  printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n",
+  printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%u rx:%u]\n",
          __FUNCTION__,config->vnf_ip_addr, config->vnf_p5_port,
          pnf.phys[0].local_addr,
          pnf.phys[0].udp.tx_addr, pnf.phys[0].udp.tx_port,
@@ -2250,7 +2213,7 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr,
   pnf.phys[0].udp.tx_port = vnf_p7_port;
   strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr);
   strcpy(pnf.phys[0].local_addr, pnf_ip_addr);
-  printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n",
+  printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%u rx:%u]\n",
          __FUNCTION__,
          config->vnf_ip_addr, config->vnf_p5_port,
          pnf.phys[0].local_addr,
diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h
index b3ab7cbdbc874ac08eeba71bb5975bb4a4ce7f44..61d4847ebab2a70196366753135a846d6efb96f5 100644
--- a/nfapi/oai_integration/nfapi_pnf.h
+++ b/nfapi/oai_integration/nfapi_pnf.h
@@ -21,6 +21,7 @@
 
 #if !defined(NFAPI_PNF_H__)
 #define NFAPI_PNF_H__
+extern nfapi_ue_release_request_body_t release_rntis;
 int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
 void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
 void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c
index 485f17922fed1584dca1aca2b574c7b952b50ad4..f4448e71dff3862e7018014282b3b22b4c9a3d94 100644
--- a/nfapi/oai_integration/nfapi_vnf.c
+++ b/nfapi/oai_integration/nfapi_vnf.c
@@ -40,6 +40,7 @@
 #include "PHY/defs_eNB.h"
 #include "PHY/LTE_TRANSPORT/transport_proto.h"
 #include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
+#include <targets/RT/USER/lte-softmodem.h>
 
 #include "common/ran_context.h"
 
@@ -196,7 +197,6 @@ int vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessag
 void install_nr_schedule_handlers(NR_IF_Module_t *if_inst);
 void install_schedule_handlers(IF_Module_t *if_inst);
 extern int single_thread_flag;
-extern void init_eNB_afterRU(void);
 extern uint16_t sf_ahead;
 extern uint16_t slot_ahead;
 
diff --git a/nfapi/open-nFAPI/common/src/debug.c b/nfapi/open-nFAPI/common/src/debug.c
index a45d41d7d7218f806869f6fda7dd9c628b893d9a..f53be43223f132a2f43bc3c3d69e2f0760f730e5 100644
--- a/nfapi/open-nFAPI/common/src/debug.c
+++ b/nfapi/open-nFAPI/common/src/debug.c
@@ -1,76 +1,76 @@
-/*
- * Copyright 2017 Cisco Systems, Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 
- * 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.
- */
-
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <pthread.h>
-#include <syslog.h>
-
-#include <debug.h>
-
-#define MAX_MSG_LENGTH 			2096
-#define TRACE_HEADER_LENGTH		44
-
-void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...);
-
-// initialize the trace function to 0
-void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg;
-
-nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO;
-//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN;
-
-void nfapi_set_trace_level(nfapi_trace_level_t new_level)
-{
-	nfapi_trace_level_g = new_level;
-}
-
-void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...)
-{
-	char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH];
-	uint32_t num_chars;
-	va_list p_args;
-	struct timeval tv;
-	pthread_t tid = pthread_self();
-
-	(void)gettimeofday(&tv, NULL);
-
-	num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
-
-	if (num_chars > TRACE_HEADER_LENGTH)
-	{
-		printf("trace_dbg: Error, num_chars is too large: %d", num_chars);
-		return;
-	}
-
-	va_start(p_args, format);
-	if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args)))
-	{
-		if (level <= NFAPI_TRACE_WARN)
-		{
-			printf("%s", trace_buff);
-		}
-		printf("%s", trace_buff);
-	}
-	va_end(p_args);
-}
+/*
+ * Copyright 2017 Cisco Systems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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.
+ */
+
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <pthread.h>
+#include <syslog.h>
+
+#include <debug.h>
+
+#define MAX_MSG_LENGTH 			2096
+#define TRACE_HEADER_LENGTH		44
+
+void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...);
+
+// initialize the trace function to 0
+void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg;
+
+nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO;
+//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN;
+
+void nfapi_set_trace_level(nfapi_trace_level_t new_level)
+{
+	nfapi_trace_level_g = new_level;
+}
+
+void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...)
+{
+	char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH];
+	uint32_t num_chars;
+	va_list p_args;
+	struct timeval tv;
+	pthread_t tid = pthread_self();
+
+	(void)gettimeofday(&tv, NULL);
+
+	num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
+
+	if (num_chars > TRACE_HEADER_LENGTH)
+	{
+		printf("trace_dbg: Error, num_chars is too large: %u", num_chars);
+		return;
+	}
+
+	va_start(p_args, format);
+	if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args)))
+	{
+		if (level <= NFAPI_TRACE_WARN)
+		{
+			printf("%s", trace_buff);
+		}
+		printf("%s", trace_buff);
+	}
+	va_end(p_args);
+}
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 9df9be4cbd4b656be44f4fb282a06cb8dff5148e..e1bb2579eb056cfb686307bea53ddf7a893890ba 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
@@ -101,6 +101,8 @@ typedef struct {
 
 
 typedef struct {
+  uint8_t harq_pid;
+  uint8_t ack_nack;
   uint32_t pdu_length;
   uint8_t* pdu;
 } fapi_nr_pdsch_pdu_t;
@@ -111,21 +113,15 @@ typedef struct {
   uint8_t ssb_index;
   uint8_t ssb_length;
   uint16_t cell_id;
-
-} fapi_nr_mib_pdu_t;
-
-typedef struct {
-  uint32_t pdu_length;
-  uint8_t* pdu;
-  uint32_t sibs_mask;
-} fapi_nr_sib_pdu_t;
+  uint16_t ssb_start_subcarrier;
+  short rsrp_dBm;
+} fapi_nr_ssb_pdu_t;
 
 typedef struct {
   uint8_t pdu_type;
   union {
     fapi_nr_pdsch_pdu_t pdsch_pdu;
-    fapi_nr_mib_pdu_t mib_pdu;
-    fapi_nr_sib_pdu_t sib_pdu;
+    fapi_nr_ssb_pdu_t ssb_pdu;
   };
 } fapi_nr_rx_indication_body_t;
 
@@ -187,87 +183,33 @@ typedef struct {
 } fapi_nr_ul_config_prach_pdu;
 
 typedef struct {
-
-        pucch_format_nr_t      format;              /* format   0    1    2    3    4    */
-        uint8_t                initialCyclicShift;  /*          x    x                   */
-        uint8_t                nrofSymbols;         /*          x    x    x    x    x    */
-        uint8_t                startingSymbolIndex; /*          x    x    x    x    x    */
-        uint8_t                timeDomainOCC;       /*               x                   */
-        uint8_t                nrofPRBs;            /*                    x    x         */
-        uint16_t               startingPRB;         /*                                     maxNrofPhysicalResourceBlocks  = 275 */
-        uint8_t                occ_length;          /*                              x    */
-        uint8_t                occ_Index;           /*                              x    */
-
-        feature_status_t       intraSlotFrequencyHopping;
-        uint16_t               secondHopPRB;
-
-        /*
-         -- Enabling inter-slot frequency hopping when PUCCH Format 1, 3 or 4 is repeated over multiple slots.
-         -- The field is not applicable for format 2.
-         */
-        feature_status_t       interslotFrequencyHopping;
-        /*
-            -- Enabling 2 DMRS symbols per hop of a PUCCH Format 3 or 4 if both hops are more than X symbols when FH is enabled (X=4).
-            -- Enabling 4 DMRS sybmols for a PUCCH Format 3 or 4 with more than 2X+1 symbols when FH is disabled (X=4).
-            -- Corresponds to L1 parameter 'PUCCH-F3-F4-additional-DMRS' (see 38.213, section 9.2.1)
-            -- The field is not applicable for format 1 and 2.
-        */
-        enable_feature_t       additionalDMRS;
-        /*
-            -- Max coding rate to determine how to feedback UCI on PUCCH for format 2, 3 or 4
-            -- Corresponds to L1 parameter 'PUCCH-F2-maximum-coderate', 'PUCCH-F3-maximum-coderate' and 'PUCCH-F4-maximum-coderate'
-            -- (see 38.213, section 9.2.5)
-            -- The field is not applicable for format 1.
-         */
-        PUCCH_MaxCodeRate_t    maxCodeRate;
-        /*
-            -- Number of slots with the same PUCCH F1, F3 or F4. When the field is absent the UE applies the value n1.
-            -- Corresponds to L1 parameter 'PUCCH-F1-number-of-slots', 'PUCCH-F3-number-of-slots' and 'PUCCH-F4-number-of-slots'
-            -- (see 38.213, section 9.2.6)
-            -- The field is not applicable for format 2.
-         */
-        uint8_t                nrofSlots;
-        /*
-            -- Enabling pi/2 BPSK for UCI symbols instead of QPSK for PUCCH.
-            -- Corresponds to L1 parameter 'PUCCH-PF3-PF4-pi/2PBSK' (see 38.213, section 9.2.5)
-            -- The field is not applicable for format 1 and 2.
-         */
-        feature_status_t       pi2PBSK;
-        /*
-            -- Enabling simultaneous transmission of CSI and HARQ-ACK feedback with or without SR with PUCCH Format 2, 3 or 4
-            -- Corresponds to L1 parameter 'PUCCH-F2-Simultaneous-HARQ-ACK-CSI', 'PUCCH-F3-Simultaneous-HARQ-ACK-CSI' and
-            -- 'PUCCH-F4-Simultaneous-HARQ-ACK-CSI' (see 38.213, section 9.2.5)
-            -- When the field is absent the UE applies the value OFF
-            -- The field is not applicable for format 1.
-         */
-        enable_feature_t       simultaneousHARQ_ACK_CSI;
-        /*
-              -- Configuration of group- and sequence hopping for all the PUCCH formats 0, 1, 3 and 4. "neither" implies neither group
-              -- or sequence hopping is enabled. "enable" enables group hopping and disables sequence hopping. "disable"” disables group
-              -- hopping and enables sequence hopping. Corresponds to L1 parameter 'PUCCH-GroupHopping' (see 38.211, section 6.4.1.3)
-              pucch-GroupHopping            ENUMERATED { neither, enable, disable },
-         */
-        pucch_GroupHopping_t   pucch_GroupHopping;
-        /*
-              -- Cell-Specific scrambling ID for group hoppping and sequence hopping if enabled.
-              -- Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2)
-              hoppingId               BIT STRING (SIZE (10))                              OPTIONAL,   -- Need R
-         */
-        uint16_t               hoppingId;
-        /*
-              -- Power control parameter P0 for PUCCH transmissions. Value in dBm. Only even values (step size 2) allowed.
-              -- Corresponds to L1 parameter 'p0-nominal-pucch' (see 38.213, section 7.2)
-              p0-nominal                INTEGER (-202..24)                                OPTIONAL,   -- Need R
-         */
-        int8_t                 p0_nominal;
-
-        int8_t                 deltaF_PUCCH_f[NUMBER_PUCCH_FORMAT_NR];
-        uint8_t                p0_PUCCH_Id;     /* INTEGER (1..8)     */
-        int8_t                 p0_PUCCH_Value;
-        // pathlossReferenceRSs        SEQUENCE (SIZE (1..maxNrofPUCCH-PathlossReferenceRSs)) OF PUCCH-PathlossReferenceRS OPTIONAL, -- Need M
-        int8_t                 twoPUCCH_PC_AdjustmentStates;
-
-    } fapi_nr_ul_config_pucch_pdu;
+  uint16_t rnti;
+  uint16_t bwp_size;
+  uint16_t bwp_start;
+  uint8_t format_type;
+  uint8_t start_symbol_index;
+  uint8_t nr_of_symbols;
+  uint16_t prb_start;
+  uint16_t prb_size;
+  uint32_t hopping_id;
+  uint8_t freq_hop_flag;
+  uint8_t group_hop_flag;
+  uint8_t sequence_hop_flag;
+  uint16_t second_hop_prb;
+  uint16_t initial_cyclic_shift;
+  uint8_t time_domain_occ_idx;
+  uint8_t add_dmrs_flag;
+  uint16_t dmrs_scrambling_id;
+  uint16_t data_scrambling_id;
+  uint8_t dmrs_cyclic_shift;
+  uint8_t pi_2bpsk;
+  uint8_t mcs;
+  uint8_t pre_dft_occ_idx;
+  uint8_t pre_dft_occ_len;
+  int16_t pucch_tx_power;
+  uint32_t n_bit;
+  uint64_t payload;
+} fapi_nr_ul_config_pucch_pdu;
 
 typedef struct
 {
@@ -459,11 +401,8 @@ typedef struct {
   uint8_t tb2_rv;
   uint8_t harq_process_nbr;
   vrb_to_prb_mapping_t vrb_to_prb_mapping;
-  uint8_t dai;
   double scaling_factor_S;
   int8_t accumulated_delta_PUCCH;
-  uint8_t pucch_resource_id;
-  uint8_t pdsch_to_harq_feedback_time_ind;
   uint8_t n_dmrs_cdm_groups;
   uint8_t dmrs_ports[10];
   uint8_t n_front_load_symb;
@@ -510,437 +449,6 @@ typedef struct {
 } fapi_nr_dl_config_request_t;
 
 
-//
-// P5
-//
-
-    
-
-typedef struct {
-  fapi_nr_coreset_t coreset;
-
-  uint8_t monitoring_slot_peridicity;
-  uint8_t monitoring_slot_offset;
-  uint16_t duration;
-  uint16_t monitoring_symbols_within_slot;
-  uint8_t number_of_candidates[5];            //  aggregation level 1, 2, 4, 8, 16
-
-  uint8_t dci_2_0_number_of_candidates[5];    //  aggregation level 1, 2, 4, 8, 16
-  uint8_t dci_2_3_monitorying_periodicity;
-  uint8_t dci_2_3_number_of_candidates;
-        
-} fapi_nr_search_space_t;
-
-typedef struct {
-  fapi_nr_search_space_t search_space_sib1;
-  fapi_nr_search_space_t search_space_others_sib;
-  fapi_nr_search_space_t search_space_paging;
-  //fapi_nr_coreset_t      coreset_ra;         //  common coreset
-  fapi_nr_search_space_t search_space_ra;    
-} fapi_nr_pdcch_config_common_t;
-
-typedef struct {
-  uint8_t k0;
-  uint8_t mapping_type;
-  uint8_t symbol_starting;
-  uint8_t symbol_length;
-} fapi_nr_pdsch_time_domain_resource_allocation_t;
-
-typedef struct {
-  fapi_nr_pdsch_time_domain_resource_allocation_t allocation_list[FAPI_NR_MAX_NUM_DL_ALLOCATIONS];
-} fapi_nr_pdsch_config_common_t;
-
-typedef struct {
-  uint8_t prach_configuration_index;
-  uint8_t msg1_fdm;
-  uint8_t msg1_frequency_start;
-  uint8_t zero_correlation_zone_config;
-  uint8_t preamble_received_target_power;
-  uint8_t preamble_transmission_max;
-  uint8_t power_ramping_step;
-  uint8_t ra_window_size;
-
-  uint8_t total_number_of_preamble;
-  uint8_t ssb_occasion_per_rach;
-  uint8_t cb_preamble_per_ssb;
-
-  uint8_t group_a_msg3_size;
-  uint8_t group_a_number_of_preamble;
-  uint8_t group_b_power_offset;
-  uint8_t contention_resolution_timer;
-  uint8_t rsrp_threshold_ssb;
-  uint8_t rsrp_threshold_ssb_sul;
-  uint8_t prach_length;   //  l839, l139
-  uint8_t prach_root_sequence_index;  //  0 - 837 for l839, 0 - 137 for l139
-  uint8_t msg1_subcarrier_spacing;
-  uint8_t restrictedset_config;
-  uint8_t msg3_transform_precoding;
-} fapi_nr_rach_config_common_t;
-
-typedef struct {
-  uint8_t k2;
-  uint8_t mapping_type;
-  uint8_t symbol_starting;
-  uint8_t symbol_length;
-} fapi_nr_pusch_time_domain_resource_allocation_t;
-      
-typedef struct {
-  uint8_t group_hopping_enabled_transform_precoding;
-  fapi_nr_pusch_time_domain_resource_allocation_t allocation_list[FAPI_NR_MAX_NUM_UL_ALLOCATIONS];
-  uint8_t msg3_delta_preamble;
-  uint8_t p0_nominal_with_grant;
-} fapi_nr_pusch_config_common_t;
-
-typedef struct {
-  uint8_t pucch_resource_common;
-  uint8_t pucch_group_hopping;
-  uint8_t hopping_id;
-  uint8_t p0_nominal;
-} fapi_nr_pucch_config_common_t;
-
-typedef struct {
-        
-  fapi_nr_pdcch_config_common_t pdcch_config_common;
-  fapi_nr_pdsch_config_common_t pdsch_config_common;
-        
-} fapi_nr_dl_bwp_common_config_t;
-
-
-
-typedef struct {
-  uint16_t int_rnti;
-  uint8_t time_frequency_set;
-  uint8_t dci_payload_size;
-  uint8_t serving_cell_id[FAPI_NR_MAX_NUM_SERVING_CELLS];    //  interrupt configuration per serving cell
-  uint8_t position_in_dci[FAPI_NR_MAX_NUM_SERVING_CELLS];    //  interrupt configuration per serving cell
-} fapi_nr_downlink_preemption_t;
-
-typedef struct {
-  uint8_t tpc_index;
-  uint8_t tpc_index_sul;
-  uint8_t target_cell;
-} fapi_nr_pusch_tpc_command_config_t;
-
-typedef struct {
-  uint8_t tpc_index_pcell;
-  uint8_t tpc_index_pucch_scell;
-} fapi_nr_pucch_tpc_command_config_t;
-
-typedef struct {
-  uint8_t starting_bit_of_format_2_3;
-  uint8_t feild_type_format_2_3;
-} fapi_nr_srs_tpc_command_config_t;
-
-typedef struct {
-  fapi_nr_downlink_preemption_t downlink_preemption;
-  fapi_nr_pusch_tpc_command_config_t tpc_pusch;
-  fapi_nr_pucch_tpc_command_config_t tpc_pucch;
-  fapi_nr_srs_tpc_command_config_t tpc_srs;
-} fapi_nr_pdcch_config_dedicated_t;
-
-typedef struct {
-  uint8_t dmrs_type;
-  uint8_t dmrs_addition_position;
-  uint8_t max_length;
-  uint16_t scrambling_id0;
-  uint16_t scrambling_id1;
-  uint8_t ptrs_frequency_density[2];      //  phase tracking rs
-  uint8_t ptrs_time_density[3];           //  phase tracking rs
-  uint8_t ptrs_epre_ratio;                //  phase tracking rs
-  uint8_t ptrs_resource_element_offset;   //  phase tracking rs
-} fapi_nr_dmrs_downlink_config_t;
-
-typedef struct {
-  uint8_t bwp_or_cell_level;
-  uint8_t pattern_type;
-  uint32_t resource_blocks[9];        //  bitmaps type 275 bits
-  uint8_t slot_type;                  //  bitmaps type one/two slot(s)
-  uint32_t symbols_in_resouece_block; //  bitmaps type 14/28 bits
-  uint8_t periodic;                   //  bitmaps type 
-  uint32_t pattern[2];                //  bitmaps type 2/4/5/8/10/20/40 bits
-
-  fapi_nr_coreset_t coreset;         //  coreset
-
-  uint8_t subcarrier_spacing;
-  uint8_t mode;
-} fapi_nr_rate_matching_pattern_group_t;
-
-typedef struct {
-  //  resource mapping
-  uint8_t row;    //  row1/row2/row4/other
-  uint16_t frequency_domain_allocation; //    4/12/3/6 bits
-  uint8_t number_of_ports;
-  uint8_t first_ofdm_symbol_in_time_domain;
-  uint8_t first_ofdm_symbol_in_time_domain2;
-  uint8_t cdm_type;
-  uint8_t density;            //  .5/1/3
-  uint8_t density_dot5_type;  //  even/odd PRBs
-        
-  uint8_t frequency_band_starting_rb;     //  freqBand
-  uint8_t frequency_band_number_of_rb;    //  freqBand
-
-  //  periodicityAndOffset
-  uint8_t periodicity;    //  slot4/5/8/10/16/20/32/40/64/80/160/320/640
-  uint32_t offset;        //  0..639 bits
-} fapi_nr_zp_csi_rs_resource_t;
-
-typedef struct {
-  uint16_t data_scrambling_id_pdsch;
-  fapi_nr_dmrs_downlink_config_t dmrs_dl_for_pdsch_mapping_type_a;
-  fapi_nr_dmrs_downlink_config_t dmrs_dl_for_pdsch_mapping_type_b; 
-  uint8_t vrb_to_prb_interleaver;
-  uint8_t resource_allocation;
-  fapi_nr_pdsch_time_domain_resource_allocation_t allocation_list[FAPI_NR_MAX_NUM_DL_ALLOCATIONS];
-  uint8_t pdsch_aggregation_factor;
-  fapi_nr_rate_matching_pattern_group_t rate_matching_pattern_group1;
-  fapi_nr_rate_matching_pattern_group_t rate_matching_pattern_group2;
-  uint8_t rbg_size;
-  uint8_t mcs_table;
-  uint8_t max_num_of_code_word_scheduled_by_dci;
-  uint8_t bundle_size;        //  prb_bundling static
-  uint8_t bundle_size_set1;   //  prb_bundling dynamic 
-  uint8_t bundle_size_set2;   //  prb_bundling dynamic
-  fapi_nr_zp_csi_rs_resource_t periodically_zp_csi_rs_resource_set[FAPI_NR_MAX_NUM_ZP_CSI_RS_RESOURCE_PER_SET];
-} fapi_nr_pdsch_config_dedicated_t;
-
-typedef struct {
-  uint16_t starting_prb;
-  uint8_t intra_slot_frequency_hopping;
-  uint16_t second_hop_prb;
-  uint8_t format;                 //  pucch format 0..4
-  uint8_t initial_cyclic_shift;
-  uint8_t number_of_symbols;
-  uint8_t starting_symbol_index;
-  uint8_t time_domain_occ;
-  uint8_t number_of_prbs;
-  uint8_t occ_length;
-  uint8_t occ_index;
-} fapi_nr_pucch_resource_t;
-
-typedef struct {
-  uint8_t periodicity;
-  uint8_t number_of_harq_process;
-  fapi_nr_pucch_resource_t n1_pucch_an;
-} fapi_nr_sps_config_t;
-
-typedef struct {
-  uint8_t beam_failure_instance_max_count;
-  uint8_t beam_failure_detection_timer;
-} fapi_nr_radio_link_monitoring_config_t;
-
-typedef struct {
-  fapi_nr_pdcch_config_dedicated_t pdcch_config_dedicated;
-  fapi_nr_pdsch_config_dedicated_t pdsch_config_dedicated;
-  fapi_nr_sps_config_t sps_config;
-  fapi_nr_radio_link_monitoring_config_t radio_link_monitoring_config;
-
-} fapi_nr_dl_bwp_dedicated_config_t;
-
-typedef struct {
-  fapi_nr_rach_config_common_t  rach_config_common;
-  fapi_nr_pusch_config_common_t pusch_config_common;
-  fapi_nr_pucch_config_common_t pucch_config_common;
-
-} fapi_nr_ul_bwp_common_config_t;
-        
-typedef struct {
-  uint8_t inter_slot_frequency_hopping;
-  uint8_t additional_dmrs;
-  uint8_t max_code_rate;
-  uint8_t number_of_slots;
-  uint8_t pi2bpsk;
-  uint8_t simultaneous_harq_ack_csi;
-} fapi_nr_pucch_format_config_t;
-
-typedef struct {
-  fapi_nr_pucch_format_config_t format1;
-  fapi_nr_pucch_format_config_t format2;
-  fapi_nr_pucch_format_config_t format3;
-  fapi_nr_pucch_format_config_t format4;
-  fapi_nr_pucch_resource_t multi_csi_pucch_resources[2];
-  uint8_t dl_data_to_ul_ack[8];
-  //  pucch power control
-  uint8_t deltaF_pucch_f0;
-  uint8_t deltaF_pucch_f1;
-  uint8_t deltaF_pucch_f2;
-  uint8_t deltaF_pucch_f3;
-  uint8_t deltaF_pucch_f4;
-  uint8_t two_pucch_pc_adjusment_states;
-} fapi_nr_pucch_config_dedicated_t;
-
-typedef struct {
-  uint8_t dmrs_type;
-  uint8_t dmrs_addition_position;
-  uint8_t ptrs_uplink_config; // to indicate if PTRS Uplink is configured of not
-  uint8_t ptrs_type;  //cp-OFDM, dft-S-OFDM
-  uint16_t ptrs_frequency_density[2];
-  uint8_t ptrs_time_density[3];
-  uint8_t ptrs_max_number_of_ports;
-  uint8_t ptrs_resource_element_offset;
-  uint8_t ptrs_power;
-  uint16_t ptrs_sample_density[5];
-  uint8_t ptrs_time_density_transform_precoding;
-
-  uint8_t max_length;
-  uint16_t scrambling_id0;
-  uint16_t scrambling_id1;
-  uint8_t npusch_identity;
-  uint8_t disable_sequence_group_hopping;
-  uint8_t sequence_hopping_enable;
-} fapi_nr_dmrs_uplink_config_t;
-
-typedef struct {
-  uint8_t tpc_accmulation;
-  uint8_t msg3_alpha;
-  uint8_t p0_nominal_with_grant;
-  uint8_t two_pusch_pc_adjustments_states;
-  uint8_t delta_mcs;
-} fapi_nr_pusch_power_control_t;
-
-typedef enum {tx_config_codebook = 1, tx_config_nonCodebook = 2} tx_config_t;
-typedef enum {transform_precoder_enabled = 0, transform_precoder_disabled = 1} transform_precoder_t;
-typedef enum {
-  codebook_subset_fullyAndPartialAndNonCoherent = 1,
-  codebook_subset_partialAndNonCoherent = 2,
-  codebook_subset_nonCoherent = 3} codebook_subset_t;
-typedef struct {
-  uint16_t data_scrambling_identity;
-  tx_config_t tx_config;
-  fapi_nr_dmrs_uplink_config_t dmrs_ul_for_pusch_mapping_type_a;
-  fapi_nr_dmrs_uplink_config_t dmrs_ul_for_pusch_mapping_type_b;
-  fapi_nr_pusch_power_control_t pusch_power_control;
-  uint8_t frequency_hopping;
-  uint16_t frequency_hopping_offset_lists[4];
-  uint8_t resource_allocation;
-  fapi_nr_pusch_time_domain_resource_allocation_t allocation_list[FAPI_NR_MAX_NUM_UL_ALLOCATIONS];
-  uint8_t pusch_aggregation_factor;
-  uint8_t mcs_table;
-  uint8_t mcs_table_transform_precoder;
-  transform_precoder_t transform_precoder;
-  codebook_subset_t codebook_subset;
-  uint8_t max_rank;
-  uint8_t rbg_size;
-
-  //uci-OnPUSCH
-  uint8_t uci_on_pusch_type;  //dynamic, semi-static
-  uint8_t beta_offset_ack_index1[4];
-  uint8_t beta_offset_ack_index2[4];
-  uint8_t beta_offset_ack_index3[4];
-  uint8_t beta_offset_csi_part1_index1[4];
-  uint8_t beta_offset_csi_part1_index2[4];
-  uint8_t beta_offset_csi_part2_index1[4];
-  uint8_t beta_offset_csi_part2_index2[4];
-
-  uint8_t tp_pi2BPSK;
-} fapi_nr_pusch_config_dedicated_t;
-
-typedef struct {
-  uint8_t frequency_hopping;
-  fapi_nr_dmrs_uplink_config_t cg_dmrs_configuration;
-  uint8_t mcs_table;
-  uint8_t mcs_table_transform_precoder;
-
-  //uci-OnPUSCH
-  uint8_t uci_on_pusch_type;  //dynamic, semi-static
-  uint8_t beta_offset_ack_index1[4];
-  uint8_t beta_offset_ack_index2[4];
-  uint8_t beta_offset_ack_index3[4];
-  uint8_t beta_offset_csi_part1_index1[4];
-  uint8_t beta_offset_csi_part1_index2[4];
-  uint8_t beta_offset_csi_part2_index1[4];
-  uint8_t beta_offset_csi_part2_index2[4];
-
-  uint8_t resource_allocation;
-  //  rgb-Size structure missing in spec.
-  uint8_t power_control_loop_to_use;
-  //  p0-PUSCH-Alpha
-  uint8_t p0;
-  uint8_t alpha;
-
-  uint8_t transform_precoder;
-  uint8_t number_of_harq_process;
-  uint8_t rep_k;
-  uint8_t rep_k_rv;
-  uint8_t periodicity;
-  uint8_t configured_grant_timer;
-  //  rrc-ConfiguredUplinkGrant
-  uint16_t time_domain_offset;
-  uint8_t time_domain_allocation;
-  uint32_t frequency_domain_allocation;
-  uint8_t antenna_ports;
-  uint8_t dmrs_seq_initialization;
-  uint8_t precoding_and_number_of_layers;
-  uint8_t srs_resource_indicator;
-  uint8_t mcs_and_tbs;
-  uint8_t frequency_hopping_offset;
-  uint8_t path_loss_reference_index;
-
-} fapi_nr_configured_grant_config_t;
-
-typedef struct {
-  uint8_t qcl_type1_serving_cell_index;
-  uint8_t qcl_type1_bwp_id;
-  uint8_t qcl_type1_rs_type;  //  csi-rs or ssb
-  uint8_t qcl_type1_nzp_csi_rs_resource_id;
-  uint8_t qcl_type1_ssb_index;
-  uint8_t qcl_type1_type;
-        
-  uint8_t qcl_type2_serving_cell_index;
-  uint8_t qcl_type2_bwp_id;
-  uint8_t qcl_type2_rs_type;  //  csi-rs or ssb
-  uint8_t qcl_type2_nzp_csi_rs_resource_id;
-  uint8_t qcl_type2_ssb_index;
-  uint8_t qcl_type2_type;
-
-} fapi_nr_tci_state_t;
-
-typedef struct {
-  uint8_t root_sequence_index;
-  //  rach genertic
-  uint8_t prach_configuration_index;
-  uint8_t msg1_fdm;
-  uint8_t msg1_frequency_start;
-  uint8_t zero_correlation_zone_config;
-  uint8_t preamble_received_target_power;
-  uint8_t preamble_transmission_max;
-  uint8_t power_ramping_step;
-  uint8_t ra_window_size;
-
-  uint8_t rsrp_threshold_ssb;
-  //  PRACH-ResourceDedicatedBFR
-  uint8_t bfr_ssb_index[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS];
-  uint8_t bfr_ssb_ra_preamble_index[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS];
-  // NZP-CSI-RS-Resource
-  uint8_t bfr_csi_rs_nzp_resource_mapping[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS];
-  uint8_t bfr_csi_rs_power_control_offset[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS];
-  uint8_t bfr_csi_rs_power_control_offset_ss[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS];
-  uint16_t bfr_csi_rs_scrambling_id[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS];
-  uint8_t bfr_csi_rs_resource_periodicity[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS];
-  uint16_t bfr_csi_rs_resource_offset[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS];
-  fapi_nr_tci_state_t qcl_infomation_periodic_csi_rs[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS];
-
-  uint8_t bfr_csirs_ra_occasions[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS];
-  uint8_t bfr_csirs_ra_preamble_index[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS][FAPI_NR_MAX_RA_OCCASION_PER_CSIRS];
-
-  uint8_t ssb_per_rach_occasion;
-  uint8_t ra_ssb_occasion_mask_index;
-  fapi_nr_search_space_t recovery_search_space;
-  //  RA-Prioritization
-  uint8_t power_ramping_step_high_priority;
-  uint8_t scaling_factor_bi;
-  uint8_t beam_failure_recovery_timer;
-} fapi_nr_beam_failure_recovery_config_t;
-
-typedef struct {
-  fapi_nr_pucch_config_dedicated_t pucch_config_dedicated;
-  fapi_nr_pusch_config_dedicated_t pusch_config_dedicated;
-  fapi_nr_configured_grant_config_t configured_grant_config;
-  //  SRS-Config
-  uint8_t srs_tpc_accumulation;
-  fapi_nr_beam_failure_recovery_config_t beam_failure_recovery_config;
-        
-} fapi_nr_ul_bwp_dedicated_config_t;
-
 #define FAPI_NR_CONFIG_REQUEST_MASK_PBCH                0x01
 #define FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_COMMON       0x02
 #define FAPI_NR_CONFIG_REQUEST_MASK_UL_BWP_COMMON       0x04
@@ -972,7 +480,7 @@ typedef struct
 
 typedef struct 
 {
-  uint32_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
+  int ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
   uint8_t  bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload
   uint8_t  scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3
 
@@ -1058,12 +566,6 @@ typedef struct {
   fapi_nr_tdd_table_t tdd_table;
   fapi_nr_prach_config_t prach_config;
 
-  fapi_nr_dl_bwp_common_config_t     dl_bwp_common;
-  fapi_nr_dl_bwp_dedicated_config_t  dl_bwp_dedicated;
-
-  fapi_nr_ul_bwp_common_config_t     ul_bwp_common;
-  fapi_nr_ul_bwp_dedicated_config_t  ul_bwp_dedicated;
-
 } fapi_nr_config_request_t;
 
 #endif
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
index 0eb77a9d262d0c1a64c7d26bd9e0f718bfb69c6b..ea459138e1e00aff374b50d0081ff07e9d476132 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
@@ -2727,7 +2727,7 @@ typedef struct {
 } nfapi_cqi_indication_rel8_t;
 #define NFAPI_CQI_INDICATION_REL8_TAG 0x202f
 
-#define NFAPI_CC_MAX 4
+#define NFAPI_CC_MAX MAX_NUM_CCs
 typedef struct {
 	nfapi_tl_t tl;
 	uint16_t length;
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index bc5e7af45fb98e4c50c938457fed1afec386e7f0..be6f92b2b992038a35a0534784ef005b1a8a60ea 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -357,7 +357,7 @@ typedef struct
 //table 3-23
 typedef struct 
 {
-  nfapi_uint32_tlv_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
+  nfapi_int32_tlv_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
   nfapi_uint8_tlv_t  bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload
   nfapi_uint8_tlv_t  scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3
 
@@ -398,13 +398,13 @@ typedef struct
 {
   nfapi_uint32_tlv_t ssb_mask;//Bitmap for actually transmitted SSB. MSB->LSB of first 32 bit number corresponds to SSB 0 to SSB 31 MSB->LSB of second 32 bit number corresponds to SSB 32 to SSB 63 Value for each bit: 0: not transmitted 1: transmitted
 
-} nfapi_nr_ssb_mask_size_2_t;
+} nfapi_nr_ssb_mask_list_t;
 
 typedef struct 
 {
-  nfapi_uint8_tlv_t beam_id[64];//BeamID for each SSB in SsbMask. For example, if SSB mask bit 26 is set to 1, then BeamId[26] will be used to indicate beam ID of SSB 26. Value: from 0 to 63
+  nfapi_uint8_tlv_t beam_id;//BeamID for each SSB in SsbMask. For example, if SSB mask bit 26 is set to 1, then BeamId[26] will be used to indicate beam ID of SSB 26. Value: from 0 to 63
 
-} nfapi_nr_ssb_mask_size_64_t;
+} nfapi_nr_ssb_beam_id_list_t;
 
 typedef struct 
 {
@@ -413,8 +413,8 @@ typedef struct
   nfapi_uint8_tlv_t  ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160
   nfapi_uint8_tlv_t  ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31
   nfapi_uint32_tlv_t MIB;//MIB payload, where the 24 MSB are used and represent the MIB in [38.331 MIB IE] and represent 0 1 2 3 1 , , , ,..., A− a a a a a [38.212, sec 7.1.1]
-  nfapi_nr_ssb_mask_size_2_t ssb_mask_list[2];
-  nfapi_nr_ssb_mask_size_64_t* ssb_beam_id_list;//64
+  nfapi_nr_ssb_mask_list_t ssb_mask_list[2];
+  nfapi_nr_ssb_beam_id_list_t ssb_beam_id_list[64];
   nfapi_uint8_tlv_t  ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
   nfapi_uint8_tlv_t  multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled
 
@@ -678,7 +678,7 @@ typedef struct {
   
 } nfapi_nr_slot_indication_scf_t;
 
-// 3.4.2 
+// 3.4.2
 
 //for pdcch_pdu:
 
@@ -691,11 +691,10 @@ typedef struct
 typedef struct
 {
   uint16_t pm_idx;//Index to precoding matrix (PM) pre-stored at cell configuration. Note: If precoding is not used this parameter should be set to 0. Value: 0->65535.
-  nfapi_nr_dig_bf_interface_t* dig_bf_interface_list;
+  nfapi_nr_dig_bf_interface_t dig_bf_interface_list[1];//max dig_bf_interfaces
 
 }nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t;
 
-/*
 //table 3-43
 typedef struct 
 {
@@ -703,23 +702,10 @@ typedef struct
   uint16_t prg_size;//Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275
   //watchout: dig_bf_interfaces here, in table 3-53 it's dig_bf_interface
   uint8_t  dig_bf_interfaces;//Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255
-  nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t* prgs_list;//
+  nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t prgs_list[1];//max prg_size
 
 }nfapi_nr_tx_precoding_and_beamforming_t;
-*/
 
-typedef struct {
-  /// Number of PRGs spanning this allocation. Value : 1->275
-  uint16_t numPRGs;
-  /// Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275
-  uint16_t prgSize;
-  /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255
-  uint8_t digBFInterfaces;
-  // Depends on numPRGs
-  uint16_t PMIdx[275];
-  // Depends on digBFInterfaces
-  uint16_t beamIdx[256];
-} nfapi_nr_tx_precoding_and_beamforming_t;
 
 //table 3-37 
 
@@ -755,16 +741,6 @@ typedef struct {
 
 } nfapi_nr_dl_dci_pdu_t;
 
-typedef struct {
-  /// Number of PRGs spanning this allocation. Value : 1->275
-  uint16_t numPRGs;
-  /// Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275
-  uint16_t prgSize;
-  /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255
-  uint8_t digBFInterfaces;
-  uint16_t PMIdx[275];
-  uint16_t *beamIdx[275];
-} nr_beamforming_t;
 
 typedef struct {
   ///Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP,Value: 1->275
@@ -1028,7 +1004,7 @@ typedef struct {
 
 typedef struct {
   uint16_t PDUType;
-  uint16_t PDUSize;
+  uint32_t PDUSize;
 
   union {
   nfapi_nr_dl_tti_pdcch_pdu      pdcch_pdu;
@@ -1595,8 +1571,7 @@ typedef struct
 {
   uint8_t  csi_part1_crc;
   uint16_t csi_part1_bit_len;
-  //! fixme
-  uint8_t*  csi_part1_payload;//uint8_t[ceil(csiPart1BitLen/8)]
+  uint8_t*  csi_part1_payload;
   
 } nfapi_nr_csi_part1_pdu_t;
 
@@ -1605,8 +1580,7 @@ typedef struct
 {
   uint8_t  csi_part2_crc;
   uint16_t csi_part2_bit_len;
-  //! fixme
-  uint8_t*  csi_part2_payload;//uint8_t[ceil(csiPart2BitLen/8)]
+  uint8_t*  csi_part2_payload;
 } nfapi_nr_csi_part2_pdu_t;
 
 //table 3-63
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi.c b/nfapi/open-nFAPI/nfapi/src/nfapi.c
index ba800c36348ca16dc50d91b0cf02d90ff692bdf2..63dd8a16ae81489f3fd655ec469766a23461651d 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi.c
@@ -1,969 +1,783 @@
-/*
- * Copyright (c) 2001-2016, Cisco Systems, Inc.
- * All rights reserved.
- *  
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *  
- * Neither the name of the Cisco Systems, Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <signal.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sched.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <pthread.h>
-
-#include <nfapi_interface.h>
-#include <nfapi.h>
-#include <debug.h>
-
-
-// Fundamental routines
-
-uint8_t push8(uint8_t in, uint8_t **out, uint8_t *end)
-{
-	uint8_t *pOut = *out;
-
-	if((end - pOut) >= 1)
-	{
-		pOut[0] = in;
-
-		(*out)+=1;
-
-		return 1;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-
-}
-
-uint8_t pushs8(int8_t in, uint8_t **out, uint8_t *end)
-{
-	uint8_t *pOut = *out;
-
-	if((end - pOut) >= 1)
-	{
-		pOut[0] = in;
-
-		(*out)+=1;
-
-		return 1;
-	}
-	else 
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end)
-{
-	uint8_t *pOut = *out;
-	
-	if((end - pOut) >= 2)
-	{
-		pOut[0] = (in & 0xFF00) >> 8;
-		pOut[1] = (in & 0xFF);
-
-		(*out)+=2;
-
-		return 2;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end)
-{
-	uint8_t *pOut = *out;
-
-	if((end - pOut) >= 2)
-	{
-		pOut[0] = (in & 0xFF00) >> 8;
-		pOut[1] = (in & 0xFF);
-
-		(*out)+=2;
-
-		return 2;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end)
-{
-	uint8_t *pOut = *out;
-	if((end - pOut) >= 4)
-	{
-		pOut[0] = (in & 0xFF000000) >> 24;
-		pOut[1] = (in & 0xFF0000) >> 16;
-		pOut[2] = (in & 0xFF00) >> 8;
-		pOut[3] = (in & 0xFF);
-
-		(*out)+=4;
-
-		return 4;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end)
-{
-	uint8_t *pOut = *out;
-
-	if((end - pOut) >= 4)
-	{
-		pOut[0] = (in & 0xFF000000) >> 24;
-		pOut[1] = (in & 0xFF0000) >> 16;
-		pOut[2] = (in & 0xFF00) >> 8;
-		pOut[3] = (in & 0xFF);
-
-		(*out)+=4;
-
-		return 4;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-uint8_t pull8(uint8_t **in, uint8_t *out, uint8_t *end)
-{
-	uint8_t *pIn = *in;
-
-	if((end - pIn) >= 1 )
-	{
-		*out = *pIn;
-
-		(*in)+=1;
-
-		return 1;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-uint8_t pulls8(uint8_t **in, int8_t *out, uint8_t *end)
-{
-	uint8_t *pIn = *in;
-
-	if((end - pIn) >= 1 )
-	{
-		*out = *pIn;
-
-		(*in)+=1;
-
-		return 1;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end)
-{
-	uint8_t *pIn = *in;
-
-	if((end - pIn) >=2 )
-	{
-		*out = ((pIn[0]) << 8) | pIn[1];
-		(*in)+=2;
-
-		return 2;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end)
-{
-	uint8_t *pIn = *in;
-
-	if((end - pIn) >=2 )
-	{
-		*out = ((pIn[0]) << 8) | pIn[1];
-
-		(*in)+=2;
-
-		return 2;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end)
-{
-	uint8_t *pIn = *in;
-
-	if((end - pIn) >=4 )
-	{
-		*out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
-
-		(*in)+=4;
-
-		return 4;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n",  __FUNCTION__);
-		return 0;
-	}
-}
-
-uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end)
-{
-	uint8_t *pIn = *in;
-
-	if((end - pIn) >=4 )
-	{
-		*out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
-
-		(*in)+=4;
-
-		return 4;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-/*
-inline void pusharray16(uint8_t **, uint16_t, uint32_t len)
-{
-}
-*/
-
-uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end)
-{
-	if(len == 0)
-		return 1;
-
-	if(len > max_len)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-		return 0;
-	}
-
-	if((end - (*in)) >= sizeof(uint16_t) * len)
-	{
-		uint32_t idx;
-		for(idx = 0; idx < len; ++idx)
-		{
-			if(!pull16(in, &out[idx], end))
-				return 0;
-		}
-
-		return sizeof(uint16_t) * len;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end)
-{
-	if(len == 0)
-		return 1;
-
-	if(len > max_len)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-		return 0;
-	}
-
-	if((end - (*in)) >= sizeof(uint16_t) * len)
-	{
-		uint32_t idx;
-		for(idx = 0; idx < len; ++idx)
-		{
-			if(!pulls16(in, &out[idx], end))
-			return 0;
-		}
-
-		return sizeof(uint16_t) * len;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end)
-{
-	if(len == 0)
-		return 1;
-
-	if(len > max_len)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-		return 0;
-	}
-
-	if((end - (*out)) >= sizeof(uint16_t) * len)
-	{
-		uint32_t idx;
-		for(idx = 0; idx < len; ++idx)
-		{
-			if(!push16(in[idx], out, end))
-				return 0;
-		}
-		return sizeof(uint16_t) * len;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end)
-{
-	if(len == 0)
-		return 1;
-
-	if(len > max_len)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-		return 0;
-	}
-
-	if((end - (*out)) >= sizeof(uint16_t) * len)
-	{
-		uint32_t idx;
-		for(idx = 0; idx < len; ++idx)
-		{
-			pushs16(in[idx], out, end);
-		}
-		return sizeof(uint16_t) * len;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-uint32_t pullarray32(uint8_t **in, uint32_t out[], uint32_t max_len, uint32_t len, uint8_t *end)
-{
-       if(len == 0)
-               return 1;
-
-       if(len > max_len)
-       {
-               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-               return 0;
-       }
-
-       if((end - (*in)) >= sizeof(uint32_t) * len)
-       {
-               uint32_t idx;
-               for(idx = 0; idx < len; ++idx)
-               {
-                       if(!pull32(in, &out[idx], end))
-                               return 0;
-               }
-
-               return sizeof(uint32_t) * len;
-       }
-       else
-       {
-               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-               return 0;
-       }
-}
-
-uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end)
-{
-       if(len == 0)
-               return 1;
-
-       if(len > max_len)
-       {
-               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-               return 0;
-       }
-
-       if((end - (*in)) >= sizeof(uint32_t) * len)
-       {
-               uint32_t idx;
-               for(idx = 0; idx < len; ++idx)
-               {
-                       if(!pulls32(in, &out[idx], end))
-                       return 0;
-               }
-
-               return sizeof(uint32_t) * len;
-       }
-       else
-       {
-               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-               return 0;
-       }
-}
-uint32_t pusharray32(uint32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end)
-{
-       if(len == 0)
-               return 1;
-
-       if(len > max_len)
-       {
-               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-               return 0;
-       }
-
-       if((end - (*out)) >= sizeof(uint32_t) * len)
-       {
-               uint32_t idx;
-               for(idx = 0; idx < len; ++idx)
-               {
-                       if(!push32(in[idx], out, end))
-                               return 0;
-               }
-               return sizeof(uint32_t) * len;
-       }
-       else
-       {
-               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-               return 0;
-       }
-}
-uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end)
-{
-       if(len == 0)
-               return 1;
-
-       if(len > max_len)
-       {
-               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-               return 0;
-       }
-
-       if((end - (*out)) >= sizeof(uint32_t) * len)
-       {
-               uint32_t idx;
-               for(idx = 0; idx < len; ++idx)
-               {
-                       pushs32(in[idx], out, end);
-               }
-               return sizeof(uint32_t) * len;
-       }
-       else
-       {
-               NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-               return 0;
-       }
-}
-uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end)
-{
-	if(len == 0)
-		return 1;
-
-	if(len > max_len)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-		return 0;
-	}
-
-	if((end - (*in)) >= sizeof(uint8_t) * len)
-	{
-		memcpy(out, (*in), len);
-		(*in)+=len;
-
-		return sizeof(uint8_t) * len;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end)
-{
-	if(len == 0)
-		return 1;
-
-	if(len > max_len)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-		return 0;
-	}
-
-	if((end - (*out)) >= sizeof(uint8_t) * len)
-	{
-		memcpy((*out), in, len);
-		(*out)+=len;
-
-		return sizeof(uint8_t) * len;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-		return 0;
-	}
-}
-
-uint8_t packarray(void* array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t **ppwritepackedmsg, uint8_t *end, pack_array_elem_fn fn)
-{
-	if(count > max_count)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count);
-		return 0;
-	}
-
-	uint16_t i = 0;
-	for(i = 0; i < count; ++i)
-	{
-		if((fn)(array, ppwritepackedmsg, end) == 0)
-			return 0;
-
-		array += array_element_size;
-	}
-
-	return 1;
-}
-
-uint8_t unpackarray(uint8_t **ppReadPackedMsg, void* array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t *end, unpack_array_elem_fn fn)
-{
-	if(count > max_count)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count);
-		return 0;
-	}
-
-	uint16_t i = 0;
-	for(i = 0; i < count; ++i)
-	{
-		if((fn)(array, ppReadPackedMsg, end) == 0)
-			return 0;
-
-		array += array_element_size;
-	}
-
-	return 1;
-}
-
-
-uint32_t pack_vendor_extension_tlv(nfapi_tl_t* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	if(ve != 0 && config != 0)
-	{
-		if(config->pack_vendor_extension_tlv)
-		{
-
-			uint8_t* pStartOfTlv = *ppWritePackedMsg;
-			if(pack_tl(ve, ppWritePackedMsg, end) == 0)
-				return 0;
-
-			uint8_t* pStartOfValue = *ppWritePackedMsg;
-			if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0)
-				return 0;
-
-			ve->length = (*ppWritePackedMsg) - pStartOfValue;
-
-			pack_tl(ve, &pStartOfTlv, end);
-
-			return 1;
-
-		}
-	}
-	return 1;
-}
-
-uint32_t unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config, nfapi_tl_t** ve_tlv)
-{
-	if(ve_tlv != 0 && config != 0)
-	{
-		if(config->unpack_vendor_extension_tlv)
-		{
-			return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void**)ve_tlv, config);
-		}
-	}
-	return 1;
-}
-
-uint32_t pack_p7_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end ,nfapi_p7_codec_config_t* config)
-{
-	if(ve != 0 && config != 0)
-	{
-		if(config->pack_vendor_extension_tlv)
-		{
-			uint8_t* pStartOfTlv = *ppWritePackedMsg;
-			if(pack_tl(ve, ppWritePackedMsg, end) == 0)
-				return 0;
-
-			uint8_t* pStartOfValue = *ppWritePackedMsg;
-			if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0)
-				return 0;
-
-			ve->length = (*ppWritePackedMsg) - pStartOfValue;
-
-			pack_tl(ve, &pStartOfTlv, end);
-
-			return 1;
-			
-		}
-	}
-	return 1;
-}
-
-int unpack_p7_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config, nfapi_tl_t** ve_tlv)
-{
-	if(ve_tlv != 0 && config != 0)
-	{
-		if(config->unpack_vendor_extension_tlv)
-		{
-			return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void**)ve_tlv, config);
-		}
-	}
-	return 1;
-}
-
-
-uint8_t pack_tl(nfapi_tl_t *tl, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return (push16(tl->tag, ppWritePackedMsg, end) &&
-			push16(tl->length, ppWritePackedMsg, end));
-}
-
-uint8_t unpack_tl(uint8_t **ppReadPackedMsg, nfapi_tl_t *tl, uint8_t *end)
-{
-	return (pull16(ppReadPackedMsg, &tl->tag, end) &&
-			pull16(ppReadPackedMsg, &tl->length, end));
-}
-
-int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config, nfapi_tl_t** ve)
-{
-	nfapi_tl_t generic_tl;
-	uint8_t numBadTags = 0;
-	uint16_t idx = 0;
-
-	while ((uint8_t*)(*ppReadPackedMsg) < end)
-	{
-		// unpack the tl and process the values accordingly
-		if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
-			return 0;
-
-		uint8_t tagMatch = 0;
-
-		uint8_t* pStartOfValue = *ppReadPackedMsg;
-
-		for(idx = 0; idx < size; ++idx)
-		{
-			if(unpack_fns[idx].tag == generic_tl.tag) // match the extracted tag value with all the tags in unpack_fn list
-			{
-				tagMatch = 1;
-				nfapi_tl_t* tl = (nfapi_tl_t*)(unpack_fns[idx].tlv);
-				tl->tag = generic_tl.tag;
-				tl->length = generic_tl.length;
-
-				int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end);
-
-				if(result == 0)
-				{
-					return 0;
-				}
-
-				// check if the length was right;
-				if(tl->length != (*ppReadPackedMsg - pStartOfValue))
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %d\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue));
-				}
-			}
-		}
-
-		if(tagMatch == 0)
-		{
-
-			if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE && 
-			   generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE)
-			{
-				int result = unpack_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve);
-				if(result == 0)
-				{
-					// got tot the end.
-					return 0;
-				}
-				else if(result < 0)
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown VE TAG value: 0x%04x\n", generic_tl.tag);
-
-					if (++numBadTags > MAX_BAD_TAG)
-					{
-						NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
-						return 0;
-					}
-
-					if((end - *ppReadPackedMsg) >= generic_tl.length)
-					{
-						// Advance past the unknown TLV
-						(*ppReadPackedMsg) += generic_tl.length;
-					}
-					else
-					{
-						// go to the end
-						return 0;
-					}
-				}
-			}
-			else
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag);
-
-				if (++numBadTags > MAX_BAD_TAG)
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
-					return 0;
-				}
-
-				if((end - *ppReadPackedMsg) >= generic_tl.length)
-				{
-					// Advance past the unknown TLV
-					(*ppReadPackedMsg) += generic_tl.length;
-				}
-				else
-				{
-					// go to the end
-					return 0;
-				}
-			}
-
-		}
-	}
-
-	return 1;
-}
-int unpack_p7_tlv_list(unpack_p7_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t* end, nfapi_p7_codec_config_t* config, nfapi_tl_t** ve)
-{
-	nfapi_tl_t generic_tl;
-	uint8_t numBadTags = 0;
-	uint16_t idx = 0;
-
-	while ((uint8_t*)(*ppReadPackedMsg) < end)
-	{
-		// unpack the tl and process the values accordingly
-		if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
-			return 0;
-
-		uint8_t tagMatch = 0;
-
-		uint8_t* pStartOfValue = *ppReadPackedMsg;
-
-		for(idx = 0; idx < size; ++idx)
-		{
-			if(unpack_fns[idx].tag == generic_tl.tag)
-			{
-				tagMatch = 1;
-				nfapi_tl_t* tl = (nfapi_tl_t*)(unpack_fns[idx].tlv);
-				tl->tag = generic_tl.tag;
-				tl->length = generic_tl.length;
-
-				int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end , config);
-
-				if(result == 0)
-				{
-					return  0;
-				}
-
-				// check if the length was right;
-				if(tl->length != (*ppReadPackedMsg - pStartOfValue))
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %d\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue));
-				}
-			}
-		}
-
-		if(tagMatch == 0)
-		{
-
-			if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE && 
-			   generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE)
-			{
-				int result = unpack_p7_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve);
-				if(result == 0)
-				{
-					// got to end
-					return 0;
-				}
-				else if(result < 0)
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag);
-
-					if (++numBadTags > MAX_BAD_TAG)
-					{
-						NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
-						return -1;
-					}
-
-					if((end - *ppReadPackedMsg) >= generic_tl.length)
-					{
-						// Advance past the unknown TLV
-						(*ppReadPackedMsg) += generic_tl.length;
-					}
-					else
-					{
-						// got ot the dn
-						return 0;
-					}
-				}
-			}
-			else
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag);
-
-				if (++numBadTags > MAX_BAD_TAG)
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
-					return -1;
-				}
-
-				if((end - *ppReadPackedMsg) >= generic_tl.length)
-				{
-					// Advance past the unknown TLV
-					(*ppReadPackedMsg) += generic_tl.length;
-				}
-				else
-				{
-					// got ot the dn
-					return 0;
-				}
-
-			}
-
-		}
-	}
-
-	return 1;
-}
-
-// This intermediate function deals with calculating the length of the value
-// and writing into the tlv header.
-uint8_t pack_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, pack_tlv_fn fn)
-{
-	nfapi_tl_t* tl = (nfapi_tl_t*)tlv;
-
-	// If the tag is defined
-	if(tl->tag == tag)
-	{
-		uint8_t* pStartOfTlv = *ppWritePackedMsg;
-
-		// write a dumy tlv header
-		if(pack_tl(tl, ppWritePackedMsg, end) == 0)
-			return 0;
-
-		// Record the start of the value
-		uint8_t* pStartOfValue = *ppWritePackedMsg;
-
-		// pack the tlv value
-		if(fn(tlv, ppWritePackedMsg, end) == 0)
-			return 0;
-
-		// calculate the length of the value and rewrite the tl header
-		tl->length = (*ppWritePackedMsg) - pStartOfValue;
-
-		// rewrite the header with the correct length
-		pack_tl(tl, &pStartOfTlv, end);
-	}
-	else
-	{
-		if(tl->tag != 0)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_WARN, "Warning pack_tlv tag 0x%x does not match expected 0x%x\n", tl->tag, tag);
-		}
-                else
-                {
-			//NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning pack_tlv tag 0x%x ZERO does not match expected 0x%x\n", tl->tag, tag);
-                }
-	}
-
-	return 1;
-}
-
-const char* nfapi_error_code_to_str(nfapi_error_code_e value)
-{
-	switch(value)
-	{
-		case NFAPI_MSG_OK:
-			return "NFAPI_MSG_OK";
-		case NFAPI_MSG_INVALID_STATE:
-			return "NFAPI_MSG_INVALID_STATE";
-		case NFAPI_MSG_INVALID_CONFIG:
-			return "NFAPI_MSG_INVALID_CONFIG";
-		case NFAPI_SFN_OUT_OF_SYNC:
-			return "NFAPI_SFN_OUT_OF_SYNC";
-		case NFAPI_MSG_SUBFRAME_ERR:
-			return "NFAPI_MSG_SUBFRAME_ERR";
-		case NFAPI_MSG_BCH_MISSING:
-			return "NFAPI_MSG_BCH_MISSING";
-		case NFAPI_MSG_INVALID_SFN:
-			return "NFAPI_MSG_INVALID_SFN";
-		case NFAPI_MSG_HI_ERR:
-			return "NFAPI_MSG_HI_ERR";
-		case NFAPI_MSG_TX_ERR:
-			return "NFAPI_MSG_TX_ERR";
-		default:
-			return "UNKNOWN";
-	}
-}
+/*
+ * Copyright (c) 2001-2016, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sched.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <nfapi_interface.h>
+#include <nfapi.h>
+#include <debug.h>
+
+
+// Fundamental routines
+
+uint8_t push8(uint8_t in, uint8_t **out, uint8_t *end) {
+  uint8_t *pOut = *out;
+
+  if((end - pOut) >= 1) {
+    pOut[0] = in;
+    (*out)+=1;
+    return 1;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint8_t pushs8(int8_t in, uint8_t **out, uint8_t *end) {
+  uint8_t *pOut = *out;
+
+  if((end - pOut) >= 1) {
+    pOut[0] = in;
+    (*out)+=1;
+    return 1;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end) {
+  uint8_t *pOut = *out;
+
+  if((end - pOut) >= 2) {
+    pOut[0] = (in & 0xFF00) >> 8;
+    pOut[1] = (in & 0xFF);
+    (*out)+=2;
+    return 2;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end) {
+  uint8_t *pOut = *out;
+
+  if((end - pOut) >= 2) {
+    pOut[0] = (in & 0xFF00) >> 8;
+    pOut[1] = (in & 0xFF);
+    (*out)+=2;
+    return 2;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end) {
+  uint8_t *pOut = *out;
+
+  if((end - pOut) >= 4) {
+    pOut[0] = (in & 0xFF000000) >> 24;
+    pOut[1] = (in & 0xFF0000) >> 16;
+    pOut[2] = (in & 0xFF00) >> 8;
+    pOut[3] = (in & 0xFF);
+    (*out)+=4;
+    return 4;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end) {
+  uint8_t *pOut = *out;
+
+  if((end - pOut) >= 4) {
+    pOut[0] = (in & 0xFF000000) >> 24;
+    pOut[1] = (in & 0xFF0000) >> 16;
+    pOut[2] = (in & 0xFF00) >> 8;
+    pOut[3] = (in & 0xFF);
+    (*out)+=4;
+    return 4;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint8_t pull8(uint8_t **in, uint8_t *out, uint8_t *end) {
+  uint8_t *pIn = *in;
+
+  if((end - pIn) >= 1 ) {
+    *out = *pIn;
+    (*in)+=1;
+    return 1;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint8_t pulls8(uint8_t **in, int8_t *out, uint8_t *end) {
+  uint8_t *pIn = *in;
+
+  if((end - pIn) >= 1 ) {
+    *out = *pIn;
+    (*in)+=1;
+    return 1;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end) {
+  uint8_t *pIn = *in;
+
+  if((end - pIn) >=2 ) {
+    *out = ((pIn[0]) << 8) | pIn[1];
+    (*in)+=2;
+    return 2;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end) {
+  uint8_t *pIn = *in;
+
+  if((end - pIn) >=2 ) {
+    *out = ((pIn[0]) << 8) | pIn[1];
+    (*in)+=2;
+    return 2;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end) {
+  uint8_t *pIn = *in;
+
+  if((end - pIn) >=4 ) {
+    *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
+    (*in)+=4;
+    return 4;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n",  __FUNCTION__);
+    return 0;
+  }
+}
+
+uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end) {
+  uint8_t *pIn = *in;
+
+  if((end - pIn) >=4 ) {
+    *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
+    (*in)+=4;
+    return 4;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+/*
+inline void pusharray16(uint8_t **, uint16_t, uint32_t len)
+{
+}
+*/
+
+uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    return 0;
+  }
+
+  if((end - (*in)) >= sizeof(uint16_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      if(!pull16(in, &out[idx], end))
+        return 0;
+    }
+
+    return sizeof(uint16_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    return 0;
+  }
+
+  if((end - (*in)) >= sizeof(uint16_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      if(!pulls16(in, &out[idx], end))
+        return 0;
+    }
+
+    return sizeof(uint16_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    return 0;
+  }
+
+  if((end - (*out)) >= sizeof(uint16_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      if(!push16(in[idx], out, end))
+        return 0;
+    }
+
+    return sizeof(uint16_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    return 0;
+  }
+
+  if((end - (*out)) >= sizeof(uint16_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      pushs16(in[idx], out, end);
+    }
+
+    return sizeof(uint16_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+uint32_t pullarray32(uint8_t **in, uint32_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    return 0;
+  }
+
+  if((end - (*in)) >= sizeof(uint32_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      if(!pull32(in, &out[idx], end))
+        return 0;
+    }
+
+    return sizeof(uint32_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    return 0;
+  }
+
+  if((end - (*in)) >= sizeof(uint32_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      if(!pulls32(in, &out[idx], end))
+        return 0;
+    }
+
+    return sizeof(uint32_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+uint32_t pusharray32(uint32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    return 0;
+  }
+
+  if((end - (*out)) >= sizeof(uint32_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      if(!push32(in[idx], out, end))
+        return 0;
+    }
+
+    return sizeof(uint32_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    return 0;
+  }
+
+  if((end - (*out)) >= sizeof(uint32_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      pushs32(in[idx], out, end);
+    }
+
+    return sizeof(uint32_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    return 0;
+  }
+
+  if((end - (*in)) >= sizeof(uint8_t) * len) {
+    memcpy(out, (*in), len);
+    (*in)+=len;
+    return sizeof(uint8_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    return 0;
+  }
+
+  if((end - (*out)) >= sizeof(uint8_t) * len) {
+    memcpy((*out), in, len);
+    (*out)+=len;
+    return sizeof(uint8_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    return 0;
+  }
+}
+
+uint8_t packarray(void *array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t **ppwritepackedmsg, uint8_t *end, pack_array_elem_fn fn) {
+  if(count > max_count) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count);
+    return 0;
+  }
+
+  uint16_t i = 0;
+
+  for(i = 0; i < count; ++i) {
+    if((fn)(array, ppwritepackedmsg, end) == 0)
+      return 0;
+
+    array += array_element_size;
+  }
+
+  return 1;
+}
+
+uint8_t unpackarray(uint8_t **ppReadPackedMsg, void *array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t *end, unpack_array_elem_fn fn) {
+  if(count > max_count) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count);
+    return 0;
+  }
+
+  uint16_t i = 0;
+
+  for(i = 0; i < count; ++i) {
+    if((fn)(array, ppReadPackedMsg, end) == 0)
+      return 0;
+
+    array += array_element_size;
+  }
+
+  return 1;
+}
+
+
+uint32_t pack_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  if(ve != 0 && config != 0) {
+    if(config->pack_vendor_extension_tlv) {
+      uint8_t *pStartOfTlv = *ppWritePackedMsg;
+
+      if(pack_tl(ve, ppWritePackedMsg, end) == 0)
+        return 0;
+
+      uint8_t *pStartOfValue = *ppWritePackedMsg;
+
+      if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0)
+        return 0;
+
+      ve->length = (*ppWritePackedMsg) - pStartOfValue;
+      pack_tl(ve, &pStartOfTlv, end);
+      return 1;
+    }
+  }
+
+  return 1;
+}
+
+uint32_t unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config, nfapi_tl_t **ve_tlv) {
+  if(ve_tlv != 0 && config != 0) {
+    if(config->unpack_vendor_extension_tlv) {
+      return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void **)ve_tlv, config);
+    }
+  }
+
+  return 1;
+}
+
+uint32_t pack_p7_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end,nfapi_p7_codec_config_t *config) {
+  if(ve != 0 && config != 0) {
+    if(config->pack_vendor_extension_tlv) {
+      uint8_t *pStartOfTlv = *ppWritePackedMsg;
+
+      if(pack_tl(ve, ppWritePackedMsg, end) == 0)
+        return 0;
+
+      uint8_t *pStartOfValue = *ppWritePackedMsg;
+
+      if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0)
+        return 0;
+
+      ve->length = (*ppWritePackedMsg) - pStartOfValue;
+      pack_tl(ve, &pStartOfTlv, end);
+      return 1;
+    }
+  }
+
+  return 1;
+}
+
+int unpack_p7_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config, nfapi_tl_t **ve_tlv) {
+  if(ve_tlv != 0 && config != 0) {
+    if(config->unpack_vendor_extension_tlv) {
+      return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void **)ve_tlv, config);
+    }
+  }
+
+  return 1;
+}
+
+
+uint8_t pack_tl(nfapi_tl_t *tl, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return (push16(tl->tag, ppWritePackedMsg, end) &&
+          push16(tl->length, ppWritePackedMsg, end));
+}
+
+uint8_t unpack_tl(uint8_t **ppReadPackedMsg, nfapi_tl_t *tl, uint8_t *end) {
+  return (pull16(ppReadPackedMsg, &tl->tag, end) &&
+          pull16(ppReadPackedMsg, &tl->length, end));
+}
+
+int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config, nfapi_tl_t **ve) {
+  nfapi_tl_t generic_tl;
+  uint8_t numBadTags = 0;
+  uint16_t idx = 0;
+
+  while ((uint8_t *)(*ppReadPackedMsg) < end) {
+    // unpack the tl and process the values accordingly
+    if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
+      return 0;
+
+    uint8_t tagMatch = 0;
+    uint8_t *pStartOfValue = *ppReadPackedMsg;
+
+    for(idx = 0; idx < size; ++idx) {
+      if(unpack_fns[idx].tag == generic_tl.tag) { // match the extracted tag value with all the tags in unpack_fn list
+        tagMatch = 1;
+        nfapi_tl_t *tl = (nfapi_tl_t *)(unpack_fns[idx].tlv);
+        tl->tag = generic_tl.tag;
+        tl->length = generic_tl.length;
+        int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end);
+
+        if(result == 0) {
+          return 0;
+        }
+
+        // check if the length was right;
+        if(tl->length != (*ppReadPackedMsg - pStartOfValue)) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %d\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue));
+        }
+      }
+    }
+
+    if(tagMatch == 0) {
+      if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE &&
+          generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE) {
+        int result = unpack_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve);
+
+        if(result == 0) {
+          // got tot the end.
+          return 0;
+        } else if(result < 0) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown VE TAG value: 0x%04x\n", generic_tl.tag);
+
+          if (++numBadTags > MAX_BAD_TAG) {
+            NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
+            return 0;
+          }
+
+          if((end - *ppReadPackedMsg) >= generic_tl.length) {
+            // Advance past the unknown TLV
+            (*ppReadPackedMsg) += generic_tl.length;
+          } else {
+            // go to the end
+            return 0;
+          }
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag);
+
+        if (++numBadTags > MAX_BAD_TAG) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
+          return 0;
+        }
+
+        if((end - *ppReadPackedMsg) >= generic_tl.length) {
+          // Advance past the unknown TLV
+          (*ppReadPackedMsg) += generic_tl.length;
+        } else {
+          // go to the end
+          return 0;
+        }
+      }
+    }
+  }
+
+  return 1;
+}
+int unpack_p7_tlv_list(unpack_p7_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config, nfapi_tl_t **ve) {
+  nfapi_tl_t generic_tl;
+  uint8_t numBadTags = 0;
+  uint16_t idx = 0;
+
+  while ((uint8_t *)(*ppReadPackedMsg) < end) {
+    // unpack the tl and process the values accordingly
+    if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
+      return 0;
+
+    uint8_t tagMatch = 0;
+    uint8_t *pStartOfValue = *ppReadPackedMsg;
+
+    for(idx = 0; idx < size; ++idx) {
+      if(unpack_fns[idx].tag == generic_tl.tag) {
+        tagMatch = 1;
+        nfapi_tl_t *tl = (nfapi_tl_t *)(unpack_fns[idx].tlv);
+        tl->tag = generic_tl.tag;
+        tl->length = generic_tl.length;
+        int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end, config);
+
+        if(result == 0) {
+          return  0;
+        }
+
+        // check if the length was right;
+        if(tl->length != (*ppReadPackedMsg - pStartOfValue)) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %d\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue));
+        }
+      }
+    }
+
+    if(tagMatch == 0) {
+      if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE &&
+          generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE) {
+        int result = unpack_p7_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve);
+
+        if(result == 0) {
+          // got to end
+          return 0;
+        } else if(result < 0) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag);
+
+          if (++numBadTags > MAX_BAD_TAG) {
+            NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
+            return -1;
+          }
+
+          if((end - *ppReadPackedMsg) >= generic_tl.length) {
+            // Advance past the unknown TLV
+            (*ppReadPackedMsg) += generic_tl.length;
+          } else {
+            // got ot the dn
+            return 0;
+          }
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag);
+
+        if (++numBadTags > MAX_BAD_TAG) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
+          return -1;
+        }
+
+        if((end - *ppReadPackedMsg) >= generic_tl.length) {
+          // Advance past the unknown TLV
+          (*ppReadPackedMsg) += generic_tl.length;
+        } else {
+          // got ot the dn
+          return 0;
+        }
+      }
+    }
+  }
+
+  return 1;
+}
+
+// This intermediate function deals with calculating the length of the value
+// and writing into the tlv header.
+uint8_t pack_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, pack_tlv_fn fn) {
+  nfapi_tl_t *tl = (nfapi_tl_t *)tlv;
+
+  // If the tag is defined
+  if(tl->tag == tag) {
+    uint8_t *pStartOfTlv = *ppWritePackedMsg;
+
+    // write a dumy tlv header
+    if(pack_tl(tl, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    // Record the start of the value
+    uint8_t *pStartOfValue = *ppWritePackedMsg;
+
+    // pack the tlv value
+    if(fn(tlv, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    // calculate the length of the value and rewrite the tl header
+    tl->length = (*ppWritePackedMsg) - pStartOfValue;
+    // rewrite the header with the correct length
+    pack_tl(tl, &pStartOfTlv, end);
+  } else {
+    if(tl->tag != 0) {
+      NFAPI_TRACE(NFAPI_TRACE_WARN, "Warning pack_tlv tag 0x%x does not match expected 0x%x\n", tl->tag, tag);
+    } else {
+      //NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning pack_tlv tag 0x%x ZERO does not match expected 0x%x\n", tl->tag, tag);
+    }
+  }
+
+  return 1;
+}
+
+const char *nfapi_error_code_to_str(nfapi_error_code_e value) {
+  switch(value) {
+    case NFAPI_MSG_OK:
+      return "NFAPI_MSG_OK";
+
+    case NFAPI_MSG_INVALID_STATE:
+      return "NFAPI_MSG_INVALID_STATE";
+
+    case NFAPI_MSG_INVALID_CONFIG:
+      return "NFAPI_MSG_INVALID_CONFIG";
+
+    case NFAPI_SFN_OUT_OF_SYNC:
+      return "NFAPI_SFN_OUT_OF_SYNC";
+
+    case NFAPI_MSG_SUBFRAME_ERR:
+      return "NFAPI_MSG_SUBFRAME_ERR";
+
+    case NFAPI_MSG_BCH_MISSING:
+      return "NFAPI_MSG_BCH_MISSING";
+
+    case NFAPI_MSG_INVALID_SFN:
+      return "NFAPI_MSG_INVALID_SFN";
+
+    case NFAPI_MSG_HI_ERR:
+      return "NFAPI_MSG_HI_ERR";
+
+    case NFAPI_MSG_TX_ERR:
+      return "NFAPI_MSG_TX_ERR";
+
+    default:
+      return "UNKNOWN";
+  }
+}
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c
index b429e0a6ce586b1efd943e7f337464e7852e26a2..dbaa4347d33313ce4957b106c623d02ddf28c858 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c
@@ -1,12 +1,12 @@
 /*
  * Copyright 2017 Cisco Systems, Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * 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.
@@ -27,2059 +27,1804 @@
 #include <nfapi.h>
 #include <debug.h>
 
-static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd)
-{
-	if (msgEnd < msgHead)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %d, %d\n", msgHead, msgEnd);
-		return 0;
-	}
-
-	return (msgEnd - msgHead);
+static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) {
+  if (msgEnd < msgHead) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %d, %d\n", msgHead, msgEnd);
+    return 0;
+  }
+
+  return (msgEnd - msgHead);
 }
 
-static uint8_t pack_opaque_data_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_opaqaue_data_t* value = (nfapi_opaqaue_data_t*)tlv;
-	return pusharray8(value->value, NFAPI_MAX_OPAQUE_DATA, value->length, ppWritePackedMsg, end);
+static uint8_t pack_opaque_data_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_opaqaue_data_t *value = (nfapi_opaqaue_data_t *)tlv;
+  return pusharray8(value->value, NFAPI_MAX_OPAQUE_DATA, value->length, ppWritePackedMsg, end);
 }
 
-static uint8_t unpack_opaque_data_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_opaqaue_data_t* value = (nfapi_opaqaue_data_t*)tlv;
-	value->length = value->tl.length;
-	if(value->length <= NFAPI_MAX_OPAQUE_DATA)
-	{
-		if(!pullarray8(ppReadPackedMsg, value->value, NFAPI_MAX_OPAQUE_DATA, value->length, end))
-			return 0;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Opaque date to long %d \n", value->length);
-		return 0;
-	}
-
-	return 1;
-
-}
-
-static uint8_t pack_lte_rssi_request_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lte_rssi_request_t* value = (nfapi_lte_rssi_request_t*)tlv;
-
-	return (push8(value->frequency_band_indicator, ppWritePackedMsg, end) &&
-			push16(value->measurement_period, ppWritePackedMsg, end) &&
-			push8(value->bandwidth, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end) &&
-			push8(value->number_of_earfcns, ppWritePackedMsg, end) &&
-			pusharray16(value->earfcn, NFAPI_MAX_CARRIER_LIST, value->number_of_earfcns, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_utran_rssi_request_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_utran_rssi_request_t* value = (nfapi_utran_rssi_request_t*)tlv;
-
-	return (push8(value->frequency_band_indicator, ppWritePackedMsg, end) &&
-			push16(value->measurement_period, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end) &&
-			push8(value->number_of_uarfcns, ppWritePackedMsg, end) &&
-			pusharray16(value->uarfcn, NFAPI_MAX_CARRIER_LIST, value->number_of_uarfcns, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_geran_rssi_request_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_geran_rssi_request_t* value = (nfapi_geran_rssi_request_t*)tlv;
-	uint16_t idx = 0;
-
-	if(!(push8(value->frequency_band_indicator, ppWritePackedMsg, end) &&
-		 push16(value->measurement_period, ppWritePackedMsg, end) &&
-		 push32(value->timeout, ppWritePackedMsg, end) &&
-		 push8(value->number_of_arfcns, ppWritePackedMsg, end)))
-		return 0;
+static uint8_t unpack_opaque_data_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_opaqaue_data_t *value = (nfapi_opaqaue_data_t *)tlv;
+  value->length = value->tl.length;
+
+  if(value->length <= NFAPI_MAX_OPAQUE_DATA) {
+    if(!pullarray8(ppReadPackedMsg, value->value, NFAPI_MAX_OPAQUE_DATA, value->length, end))
+      return 0;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Opaque date to long %d \n", value->length);
+    return 0;
+  }
+
+  return 1;
+}
 
-	for(;idx < value->number_of_arfcns; ++idx)
-	{
-		if(!(push16(value->arfcn[idx].arfcn, ppWritePackedMsg, end) &&
-			push8(value->arfcn[idx].direction, ppWritePackedMsg, end)))
-			return 0;
-	}
+static uint8_t pack_lte_rssi_request_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lte_rssi_request_t *value = (nfapi_lte_rssi_request_t *)tlv;
+  return (push8(value->frequency_band_indicator, ppWritePackedMsg, end) &&
+          push16(value->measurement_period, ppWritePackedMsg, end) &&
+          push8(value->bandwidth, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end) &&
+          push8(value->number_of_earfcns, ppWritePackedMsg, end) &&
+          pusharray16(value->earfcn, NFAPI_MAX_CARRIER_LIST, value->number_of_earfcns, ppWritePackedMsg, end));
+}
 
-	return 1;
+static uint8_t pack_utran_rssi_request_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_utran_rssi_request_t *value = (nfapi_utran_rssi_request_t *)tlv;
+  return (push8(value->frequency_band_indicator, ppWritePackedMsg, end) &&
+          push16(value->measurement_period, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end) &&
+          push8(value->number_of_uarfcns, ppWritePackedMsg, end) &&
+          pusharray16(value->uarfcn, NFAPI_MAX_CARRIER_LIST, value->number_of_uarfcns, ppWritePackedMsg, end));
 }
 
-static uint8_t pack_nb_iot_rssi_request_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_rssi_request_t* value = (nfapi_nb_iot_rssi_request_t*)tlv;
-	uint16_t idx = 0;
+static uint8_t pack_geran_rssi_request_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_geran_rssi_request_t *value = (nfapi_geran_rssi_request_t *)tlv;
+  uint16_t idx = 0;
+
+  if(!(push8(value->frequency_band_indicator, ppWritePackedMsg, end) &&
+       push16(value->measurement_period, ppWritePackedMsg, end) &&
+       push32(value->timeout, ppWritePackedMsg, end) &&
+       push8(value->number_of_arfcns, ppWritePackedMsg, end)))
+    return 0;
+
+  for(; idx < value->number_of_arfcns; ++idx) {
+    if(!(push16(value->arfcn[idx].arfcn, ppWritePackedMsg, end) &&
+         push8(value->arfcn[idx].direction, ppWritePackedMsg, end)))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_nb_iot_rssi_request_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nb_iot_rssi_request_t *value = (nfapi_nb_iot_rssi_request_t *)tlv;
+  uint16_t idx = 0;
+
+  if(!(push8(value->frequency_band_indicator, ppWritePackedMsg, end) &&
+       push16(value->measurement_period, ppWritePackedMsg, end) &&
+       push32(value->timeout, ppWritePackedMsg, end) &&
+       push8(value->number_of_earfcns, ppWritePackedMsg, end)))
+    return 0;
 
-	if(!(push8(value->frequency_band_indicator, ppWritePackedMsg, end) &&
-		 push16(value->measurement_period, ppWritePackedMsg, end) &&
-		 push32(value->timeout, ppWritePackedMsg, end) &&
-		 push8(value->number_of_earfcns, ppWritePackedMsg, end)))
-		return 0;
+  for(; idx < value->number_of_earfcns; ++idx) {
+    if(!(push16(value->earfcn[idx].earfcn, ppWritePackedMsg, end) &&
+         push8(value->earfcn[idx].number_of_ro_dl, ppWritePackedMsg, end)))
+      return 0;
 
-	for(;idx < value->number_of_earfcns; ++idx)
-	{
-		if(!(push16(value->earfcn[idx].earfcn, ppWritePackedMsg, end) &&
-			 push8(value->earfcn[idx].number_of_ro_dl, ppWritePackedMsg, end)))
-			return 0;
-			
-		uint8_t ro_dl_idx = 0;
-		for(ro_dl_idx = 0; ro_dl_idx < value->earfcn[idx].number_of_ro_dl; ++ro_dl_idx)
-		{
-			if(!push8(value->earfcn[idx].ro_dl[ro_dl_idx], ppWritePackedMsg, end))
-				return 0;
-		}
-	}
+    uint8_t ro_dl_idx = 0;
 
-	return 1;
+    for(ro_dl_idx = 0; ro_dl_idx < value->earfcn[idx].number_of_ro_dl; ++ro_dl_idx) {
+      if(!push8(value->earfcn[idx].ro_dl[ro_dl_idx], ppWritePackedMsg, end))
+        return 0;
+    }
+  }
+
+  return 1;
 }
 
 
 
-static uint8_t pack_rssi_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_rssi_request_t *pNfapiMsg = (nfapi_rssi_request_t*)msg;
+static uint8_t pack_rssi_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_rssi_request_t *pNfapiMsg = (nfapi_rssi_request_t *)msg;
+
+  if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  switch(pNfapiMsg->rat_type) {
+    case NFAPI_RAT_TYPE_LTE:
+      if(pack_tlv(NFAPI_LTE_RSSI_REQUEST_TAG, &pNfapiMsg->lte_rssi_request, ppWritePackedMsg, end, &pack_lte_rssi_request_value) == 0)
+        return 0;
+
+      break;
+
+    case NFAPI_RAT_TYPE_UTRAN:
+      if(pack_tlv(NFAPI_UTRAN_RSSI_REQUEST_TAG, &pNfapiMsg->utran_rssi_request, ppWritePackedMsg, end, &pack_utran_rssi_request_value) == 0)
+        return 0;
+
+      break;
 
-	if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0)
-		return 0;
+    case NFAPI_RAT_TYPE_GERAN:
+      if(pack_tlv(NFAPI_GERAN_RSSI_REQUEST_TAG, &pNfapiMsg->geran_rssi_request, ppWritePackedMsg, end, &pack_geran_rssi_request_value) == 0)
+        return 0;
 
-	switch(pNfapiMsg->rat_type)
-	{
-		case NFAPI_RAT_TYPE_LTE:
-			if(pack_tlv(NFAPI_LTE_RSSI_REQUEST_TAG, &pNfapiMsg->lte_rssi_request, ppWritePackedMsg, end, &pack_lte_rssi_request_value) == 0)
-				return 0;
-			break;
-		case NFAPI_RAT_TYPE_UTRAN:
-			if(pack_tlv(NFAPI_UTRAN_RSSI_REQUEST_TAG, &pNfapiMsg->utran_rssi_request, ppWritePackedMsg, end, &pack_utran_rssi_request_value) == 0)
-				return 0;
-			break;
-		case NFAPI_RAT_TYPE_GERAN:
-			if(pack_tlv(NFAPI_GERAN_RSSI_REQUEST_TAG, &pNfapiMsg->geran_rssi_request, ppWritePackedMsg, end, &pack_geran_rssi_request_value) == 0)
-				return 0;
-			break;
-		case NFAPI_RAT_TYPE_NB_IOT:
-			if(pack_tlv(NFAPI_NB_IOT_RSSI_REQUEST_TAG, &pNfapiMsg->nb_iot_rssi_request, ppWritePackedMsg, end, &pack_nb_iot_rssi_request_value) == 0)
-				return 0;
-			break;
-	}
-
-	return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
-}
-
-static uint8_t pack_rssi_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_rssi_response_t *pNfapiMsg = (nfapi_rssi_response_t*)msg;
-	
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_rssi_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_rssi_indication_body_t* value = (nfapi_rssi_indication_body_t*)tlv;
-
-	return (push16(value->number_of_rssi, ppWritePackedMsg, end) &&
-			pusharrays16(value->rssi, NFAPI_MAX_RSSI, value->number_of_rssi, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_rssi_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_rssi_indication_t *pNfapiMsg = (nfapi_rssi_indication_t*)msg;
-
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_tlv(NFAPI_RSSI_INDICATION_TAG, &pNfapiMsg->rssi_indication_body, ppWritePackedMsg, end, &pack_rssi_indication_body_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-
-static uint8_t pack_lte_cell_search_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lte_cell_search_request_t* value = (nfapi_lte_cell_search_request_t*)msg;
-
-	return (push16(value->earfcn, ppWritePackedMsg, end) &&
-			push8(value->measurement_bandwidth,  ppWritePackedMsg, end) &&
-			push8(value->exhaustive_search, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end) &&
-			push8(value->number_of_pci, ppWritePackedMsg, end) &&
-			pusharray16(value->pci, NFAPI_MAX_PCI_LIST, value->number_of_pci, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_utran_cell_search_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_utran_cell_search_request_t* value = (nfapi_utran_cell_search_request_t*)msg;
-
-	return (push16(value->uarfcn, ppWritePackedMsg, end) &&
-			push8(value->exhaustive_search, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end) &&
-			push8(value->number_of_psc, ppWritePackedMsg, end) &&
-			pusharray16(value->psc, NFAPI_MAX_PSC_LIST, value->number_of_psc, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_geran_cell_search_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_geran_cell_search_request_t* value = (nfapi_geran_cell_search_request_t*)msg;
-
-	return (push32(value->timeout, ppWritePackedMsg, end) &&
-			push8(value->number_of_arfcn, ppWritePackedMsg, end) &&
-			pusharray16(value->arfcn, NFAPI_MAX_ARFCN_LIST, value->number_of_arfcn, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_nb_iot_cell_search_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_cell_search_request_t* value = (nfapi_nb_iot_cell_search_request_t*)msg;
-
-	return (push16(value->earfcn, ppWritePackedMsg, end) &&
-			push8(value->ro_dl, ppWritePackedMsg, end) &&
-			push8(value->exhaustive_search, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end) &&
-			push8(value->number_of_pci, ppWritePackedMsg, end) &&
-			pusharray16(value->pci, NFAPI_MAX_PCI_LIST, value->number_of_pci, ppWritePackedMsg, end));
-}
-
-
-static uint8_t pack_cell_search_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_cell_search_request_t *pNfapiMsg = (nfapi_cell_search_request_t*)msg;
-
-	if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	switch(pNfapiMsg->rat_type)
-	{
-		case NFAPI_RAT_TYPE_LTE:
-			{
-				if(pack_tlv(NFAPI_LTE_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->lte_cell_search_request, ppWritePackedMsg, end, &pack_lte_cell_search_request_value) == 0)
-					return 0;
-			}
-			break;
-		case NFAPI_RAT_TYPE_UTRAN:
-			{
-				if(pack_tlv(NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->utran_cell_search_request, ppWritePackedMsg, end, &pack_utran_cell_search_request_value) == 0)
-					return 0;
-			}
-			break;
-		case NFAPI_RAT_TYPE_GERAN:
-			{
-				if(pack_tlv(NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->geran_cell_search_request, ppWritePackedMsg, end, &pack_geran_cell_search_request_value) == 0)
-					return 0;
-			}
-			break;
-		case NFAPI_RAT_TYPE_NB_IOT:
-			{
-				if(pack_tlv(NFAPI_NB_IOT_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->nb_iot_cell_search_request, ppWritePackedMsg, end, &pack_nb_iot_cell_search_request_value) == 0)
-					return 0;
-			}
-			break;
-	};
-	
-	return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_cell_search_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_cell_search_response_t *pNfapiMsg = (nfapi_cell_search_response_t*)msg;
-	
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_lte_cell_search_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lte_cell_search_indication_t* value = (nfapi_lte_cell_search_indication_t*)msg;
-	uint16_t idx = 0;
-
-	if(push16(value->number_of_lte_cells_found, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	for(idx = 0; idx < value->number_of_lte_cells_found; ++idx)
-	{
-		if(!(push16(value->lte_found_cells[idx].pci, ppWritePackedMsg, end) &&
-			 push8(value->lte_found_cells[idx].rsrp, ppWritePackedMsg, end) &&
-			 push8(value->lte_found_cells[idx].rsrq, ppWritePackedMsg, end) &&
-			 pushs16(value->lte_found_cells[idx].frequency_offset, ppWritePackedMsg, end)))
-			return 0;
-	}
-	return 1;
-}
-
-static uint8_t pack_utran_cell_search_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_utran_cell_search_indication_t* value = (nfapi_utran_cell_search_indication_t*)msg;
-	uint16_t idx = 0;
-
-	if(push16(value->number_of_utran_cells_found, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	for(idx = 0; idx < value->number_of_utran_cells_found; ++idx)
-	{
-		if(!(push16(value->utran_found_cells[idx].psc, ppWritePackedMsg, end) &&
-			 push8(value->utran_found_cells[idx].rscp, ppWritePackedMsg, end) &&
-			 push8(value->utran_found_cells[idx].ecno, ppWritePackedMsg, end) &&
-			 pushs16(value->utran_found_cells[idx].frequency_offset, ppWritePackedMsg, end)))
-			return 0;
-	}
-
-	return 1;
-}
-
-static uint8_t pack_geran_cell_search_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_geran_cell_search_indication_t* value = (nfapi_geran_cell_search_indication_t*)msg;
-	uint16_t idx = 0;
-
-	if(push16(value->number_of_gsm_cells_found, ppWritePackedMsg, end) == 0)
-		return 0;
- 
-	for(idx = 0; idx < value->number_of_gsm_cells_found; ++idx)
-	{
-		if(!(push16(value->gsm_found_cells[idx].arfcn, ppWritePackedMsg, end) &&
-			 push8(value->gsm_found_cells[idx].bsic, ppWritePackedMsg, end) &&
-			 push8(value->gsm_found_cells[idx].rxlev, ppWritePackedMsg, end) &&
-			 push8(value->gsm_found_cells[idx].rxqual, ppWritePackedMsg, end) &&
-			 pushs16(value->gsm_found_cells[idx].frequency_offset, ppWritePackedMsg, end) &&
-			 push32(value->gsm_found_cells[idx].sfn_offset, ppWritePackedMsg, end)))
-			return 0;
-	}
-
-	return 1;
-}
-
-static uint8_t pack_nb_iot_cell_search_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_cell_search_indication_t* value = (nfapi_nb_iot_cell_search_indication_t*)msg;
-	uint16_t idx = 0;
-
-	if(push16(value->number_of_nb_iot_cells_found, ppWritePackedMsg, end) == 0)
-		return 0;
- 
-	for(idx = 0; idx < value->number_of_nb_iot_cells_found; ++idx)
-	{
-		if(!(push16(value->nb_iot_found_cells[idx].pci, ppWritePackedMsg, end) &&
-			 push8(value->nb_iot_found_cells[idx].rsrp, ppWritePackedMsg, end) &&
-			 push8(value->nb_iot_found_cells[idx].rsrq, ppWritePackedMsg, end) &&
-			 pushs16(value->nb_iot_found_cells[idx].frequency_offset, ppWritePackedMsg, end)))
-			return 0;
-	}
-
-	return 1;
-}
-static uint8_t pack_cell_search_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_cell_search_indication_t *pNfapiMsg = (nfapi_cell_search_indication_t*)msg;
-
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_tlv(NFAPI_LTE_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->lte_cell_search_indication, ppWritePackedMsg, end, &pack_lte_cell_search_indication_value) &&
-			pack_tlv(NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->utran_cell_search_indication, ppWritePackedMsg, end, &pack_utran_cell_search_indication_value) &&
-			pack_tlv(NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->geran_cell_search_indication, ppWritePackedMsg, end, &pack_geran_cell_search_indication_value) &&
-			pack_tlv(NFAPI_PNF_CELL_SEARCH_STATE_TAG, &pNfapiMsg->pnf_cell_search_state, ppWritePackedMsg, end, &pack_opaque_data_value) &&
-			pack_tlv(NFAPI_NB_IOT_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->nb_iot_cell_search_indication, ppWritePackedMsg, end, &pack_nb_iot_cell_search_indication_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-
-}
-
-static uint8_t pack_lte_broadcast_detect_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lte_broadcast_detect_request_t* value = (nfapi_lte_broadcast_detect_request_t*)msg;
-
-	return (push16(value->earfcn, ppWritePackedMsg, end) &&
-			push16(value->pci, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_utran_broadcast_detect_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_utran_broadcast_detect_request_t* value = (nfapi_utran_broadcast_detect_request_t*)msg;
-
-	return (push16(value->uarfcn, ppWritePackedMsg, end) &&
-			push16(value->psc, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_nb_iot_broadcast_detect_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_broadcast_detect_request_t* value = (nfapi_nb_iot_broadcast_detect_request_t*)msg;
+      break;
 
-	return (push16(value->earfcn, ppWritePackedMsg, end) &&
-			push8(value->ro_dl, ppWritePackedMsg, end) &&
-			push16(value->pci, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_broadcast_detect_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t * end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_broadcast_detect_request_t *pNfapiMsg = (nfapi_broadcast_detect_request_t*)msg;
+    case NFAPI_RAT_TYPE_NB_IOT:
+      if(pack_tlv(NFAPI_NB_IOT_RSSI_REQUEST_TAG, &pNfapiMsg->nb_iot_rssi_request, ppWritePackedMsg, end, &pack_nb_iot_rssi_request_value) == 0)
+        return 0;
 
-	if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0)
-		return 0;
+      break;
+  }
 
-	switch(pNfapiMsg->rat_type)
-	{
-		case NFAPI_RAT_TYPE_LTE:
-			if(pack_tlv(NFAPI_LTE_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->lte_broadcast_detect_request, ppWritePackedMsg, end ,&pack_lte_broadcast_detect_request_value) == 0)
-				return 0;
-			break;
-		case NFAPI_RAT_TYPE_UTRAN:
-			if(pack_tlv(NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->utran_broadcast_detect_request, ppWritePackedMsg, end, &pack_utran_broadcast_detect_request_value) == 0)
-				return 0;
-			break;
-		case NFAPI_RAT_TYPE_NB_IOT:
-			if(pack_tlv(NFAPI_NB_IOT_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->nb_iot_broadcast_detect_request, ppWritePackedMsg, end, &pack_nb_iot_broadcast_detect_request_value) == 0)
-				return 0;
-			break;
-			
-	}
-
-	return (pack_tlv(NFAPI_PNF_CELL_SEARCH_STATE_TAG, &pNfapiMsg->pnf_cell_search_state, ppWritePackedMsg, end, &pack_opaque_data_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+  return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
 }
 
-static uint8_t pack_broadcast_detect_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_broadcast_detect_response_t *pNfapiMsg = (nfapi_broadcast_detect_response_t*)msg;
-	
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+static uint8_t pack_rssi_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_rssi_response_t *pNfapiMsg = (nfapi_rssi_response_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
 }
 
-static uint8_t pack_lte_broadcast_detect_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lte_broadcast_detect_indication_t* value = (nfapi_lte_broadcast_detect_indication_t*)msg;
+static uint8_t pack_rssi_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_rssi_indication_body_t *value = (nfapi_rssi_indication_body_t *)tlv;
+  return (push16(value->number_of_rssi, ppWritePackedMsg, end) &&
+          pusharrays16(value->rssi, NFAPI_MAX_RSSI, value->number_of_rssi, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_rssi_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_rssi_indication_t *pNfapiMsg = (nfapi_rssi_indication_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_tlv(NFAPI_RSSI_INDICATION_TAG, &pNfapiMsg->rssi_indication_body, ppWritePackedMsg, end, &pack_rssi_indication_body_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
+static uint8_t pack_lte_cell_search_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lte_cell_search_request_t *value = (nfapi_lte_cell_search_request_t *)msg;
+  return (push16(value->earfcn, ppWritePackedMsg, end) &&
+          push8(value->measurement_bandwidth,  ppWritePackedMsg, end) &&
+          push8(value->exhaustive_search, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end) &&
+          push8(value->number_of_pci, ppWritePackedMsg, end) &&
+          pusharray16(value->pci, NFAPI_MAX_PCI_LIST, value->number_of_pci, ppWritePackedMsg, end));
+}
 
-	return (push8(value->number_of_tx_antenna, ppWritePackedMsg, end) &&
-			push16(value->mib_length, ppWritePackedMsg, end) &&
-			pusharray8(value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, ppWritePackedMsg, end) &&
-			push32(value->sfn_offset, ppWritePackedMsg, end));
+static uint8_t pack_utran_cell_search_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_utran_cell_search_request_t *value = (nfapi_utran_cell_search_request_t *)msg;
+  return (push16(value->uarfcn, ppWritePackedMsg, end) &&
+          push8(value->exhaustive_search, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end) &&
+          push8(value->number_of_psc, ppWritePackedMsg, end) &&
+          pusharray16(value->psc, NFAPI_MAX_PSC_LIST, value->number_of_psc, ppWritePackedMsg, end));
 }
 
-static uint8_t pack_utran_broadcast_detect_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_utran_broadcast_detect_indication_t* value = (nfapi_utran_broadcast_detect_indication_t*)msg;
+static uint8_t pack_geran_cell_search_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_geran_cell_search_request_t *value = (nfapi_geran_cell_search_request_t *)msg;
+  return (push32(value->timeout, ppWritePackedMsg, end) &&
+          push8(value->number_of_arfcn, ppWritePackedMsg, end) &&
+          pusharray16(value->arfcn, NFAPI_MAX_ARFCN_LIST, value->number_of_arfcn, ppWritePackedMsg, end));
+}
 
-	return (push16(value->mib_length, ppWritePackedMsg, end) &&
-			pusharray8(value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, ppWritePackedMsg, end) &&
-			push32(value->sfn_offset, ppWritePackedMsg, end));
+static uint8_t pack_nb_iot_cell_search_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nb_iot_cell_search_request_t *value = (nfapi_nb_iot_cell_search_request_t *)msg;
+  return (push16(value->earfcn, ppWritePackedMsg, end) &&
+          push8(value->ro_dl, ppWritePackedMsg, end) &&
+          push8(value->exhaustive_search, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end) &&
+          push8(value->number_of_pci, ppWritePackedMsg, end) &&
+          pusharray16(value->pci, NFAPI_MAX_PCI_LIST, value->number_of_pci, ppWritePackedMsg, end));
 }
 
-static uint8_t pack_nb_iot_broadcast_detect_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_broadcast_detect_indication_t* value = (nfapi_nb_iot_broadcast_detect_indication_t*)msg;
 
-	return (push8(value->number_of_tx_antenna, ppWritePackedMsg, end) &&
-			push16(value->mib_length, ppWritePackedMsg, end) &&
-			pusharray8(value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, ppWritePackedMsg, end) &&
-			push32(value->sfn_offset, ppWritePackedMsg, end));
+static uint8_t pack_cell_search_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_cell_search_request_t *pNfapiMsg = (nfapi_cell_search_request_t *)msg;
+
+  if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  switch(pNfapiMsg->rat_type) {
+    case NFAPI_RAT_TYPE_LTE: {
+      if(pack_tlv(NFAPI_LTE_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->lte_cell_search_request, ppWritePackedMsg, end, &pack_lte_cell_search_request_value) == 0)
+        return 0;
+    }
+    break;
+
+    case NFAPI_RAT_TYPE_UTRAN: {
+      if(pack_tlv(NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->utran_cell_search_request, ppWritePackedMsg, end, &pack_utran_cell_search_request_value) == 0)
+        return 0;
+    }
+    break;
+
+    case NFAPI_RAT_TYPE_GERAN: {
+      if(pack_tlv(NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->geran_cell_search_request, ppWritePackedMsg, end, &pack_geran_cell_search_request_value) == 0)
+        return 0;
+    }
+    break;
+
+    case NFAPI_RAT_TYPE_NB_IOT: {
+      if(pack_tlv(NFAPI_NB_IOT_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->nb_iot_cell_search_request, ppWritePackedMsg, end, &pack_nb_iot_cell_search_request_value) == 0)
+        return 0;
+    }
+    break;
+  };
+
+  return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
 }
 
-static uint8_t pack_broadcast_detect_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_broadcast_detect_indication_t *pNfapiMsg = (nfapi_broadcast_detect_indication_t*)msg;
+static uint8_t pack_cell_search_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_cell_search_response_t *pNfapiMsg = (nfapi_cell_search_response_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_lte_cell_search_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lte_cell_search_indication_t *value = (nfapi_lte_cell_search_indication_t *)msg;
+  uint16_t idx = 0;
+
+  if(push16(value->number_of_lte_cells_found, ppWritePackedMsg, end) == 0)
+    return 0;
 
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_tlv(NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->lte_broadcast_detect_indication, ppWritePackedMsg, end, &pack_lte_broadcast_detect_indication_value) &&
-			pack_tlv(NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->utran_broadcast_detect_indication, ppWritePackedMsg, end, &pack_utran_broadcast_detect_indication_value) &&
-			pack_tlv(NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, ppWritePackedMsg, end, &pack_opaque_data_value) &&
-			pack_tlv(NFAPI_NB_IOT_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->nb_iot_broadcast_detect_indication, ppWritePackedMsg, end, &pack_nb_iot_broadcast_detect_indication_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+  for(idx = 0; idx < value->number_of_lte_cells_found; ++idx) {
+    if(!(push16(value->lte_found_cells[idx].pci, ppWritePackedMsg, end) &&
+         push8(value->lte_found_cells[idx].rsrp, ppWritePackedMsg, end) &&
+         push8(value->lte_found_cells[idx].rsrq, ppWritePackedMsg, end) &&
+         pushs16(value->lte_found_cells[idx].frequency_offset, ppWritePackedMsg, end)))
+      return 0;
+  }
+
+  return 1;
 }
 
-static uint8_t pack_lte_system_information_schedule_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lte_system_information_schedule_request_t* value = (nfapi_lte_system_information_schedule_request_t*)msg;
+static uint8_t pack_utran_cell_search_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_utran_cell_search_indication_t *value = (nfapi_utran_cell_search_indication_t *)msg;
+  uint16_t idx = 0;
+
+  if(push16(value->number_of_utran_cells_found, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  for(idx = 0; idx < value->number_of_utran_cells_found; ++idx) {
+    if(!(push16(value->utran_found_cells[idx].psc, ppWritePackedMsg, end) &&
+         push8(value->utran_found_cells[idx].rscp, ppWritePackedMsg, end) &&
+         push8(value->utran_found_cells[idx].ecno, ppWritePackedMsg, end) &&
+         pushs16(value->utran_found_cells[idx].frequency_offset, ppWritePackedMsg, end)))
+      return 0;
+  }
 
-	return (push16(value->earfcn, ppWritePackedMsg, end) &&
-			push16(value->pci, ppWritePackedMsg, end) &&
-			push16(value->downlink_channel_bandwidth, ppWritePackedMsg, end) &&
-			push8(value->phich_configuration, ppWritePackedMsg, end) &&
-			push8(value->number_of_tx_antenna, ppWritePackedMsg, end) &&
-			push8(value->retry_count, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end));
+  return 1;
 }
 
-static uint8_t pack_nb_iot_system_information_schedule_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_system_information_schedule_request_t* value = (nfapi_nb_iot_system_information_schedule_request_t*)msg;
+static uint8_t pack_geran_cell_search_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_geran_cell_search_indication_t *value = (nfapi_geran_cell_search_indication_t *)msg;
+  uint16_t idx = 0;
 
-	return (push16(value->earfcn, ppWritePackedMsg, end) &&
-			push8(value->ro_dl, ppWritePackedMsg, end) &&
-			push16(value->pci, ppWritePackedMsg, end) &&
-			push8(value->scheduling_info_sib1_nb, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end));
+  if(push16(value->number_of_gsm_cells_found, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  for(idx = 0; idx < value->number_of_gsm_cells_found; ++idx) {
+    if(!(push16(value->gsm_found_cells[idx].arfcn, ppWritePackedMsg, end) &&
+         push8(value->gsm_found_cells[idx].bsic, ppWritePackedMsg, end) &&
+         push8(value->gsm_found_cells[idx].rxlev, ppWritePackedMsg, end) &&
+         push8(value->gsm_found_cells[idx].rxqual, ppWritePackedMsg, end) &&
+         pushs16(value->gsm_found_cells[idx].frequency_offset, ppWritePackedMsg, end) &&
+         push32(value->gsm_found_cells[idx].sfn_offset, ppWritePackedMsg, end)))
+      return 0;
+  }
+
+  return 1;
 }
 
+static uint8_t pack_nb_iot_cell_search_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nb_iot_cell_search_indication_t *value = (nfapi_nb_iot_cell_search_indication_t *)msg;
+  uint16_t idx = 0;
 
-static uint8_t pack_system_information_schedule_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_system_information_schedule_request_t *pNfapiMsg = (nfapi_system_information_schedule_request_t*)msg;
+  if(push16(value->number_of_nb_iot_cells_found, ppWritePackedMsg, end) == 0)
+    return 0;
 
-	if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0)
-		return 0;
+  for(idx = 0; idx < value->number_of_nb_iot_cells_found; ++idx) {
+    if(!(push16(value->nb_iot_found_cells[idx].pci, ppWritePackedMsg, end) &&
+         push8(value->nb_iot_found_cells[idx].rsrp, ppWritePackedMsg, end) &&
+         push8(value->nb_iot_found_cells[idx].rsrq, ppWritePackedMsg, end) &&
+         pushs16(value->nb_iot_found_cells[idx].frequency_offset, ppWritePackedMsg, end)))
+      return 0;
+  }
 
-	switch(pNfapiMsg->rat_type)
-	{
-		case NFAPI_RAT_TYPE_LTE:
-			if(pack_tlv(NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &pNfapiMsg->lte_system_information_schedule_request, ppWritePackedMsg, end, &pack_lte_system_information_schedule_request_value) == 0)
-				return 0;
-			break;
-		case NFAPI_RAT_TYPE_NB_IOT:
-			if(pack_tlv(NFAPI_NB_IOT_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &pNfapiMsg->nb_iot_system_information_schedule_request, ppWritePackedMsg, end, &pack_nb_iot_system_information_schedule_request_value) == 0)
-				return 0;
-			break;
-	}
+  return 1;
+}
+static uint8_t pack_cell_search_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_cell_search_indication_t *pNfapiMsg = (nfapi_cell_search_indication_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_tlv(NFAPI_LTE_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->lte_cell_search_indication, ppWritePackedMsg, end, &pack_lte_cell_search_indication_value) &&
+          pack_tlv(NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->utran_cell_search_indication, ppWritePackedMsg, end, &pack_utran_cell_search_indication_value) &&
+          pack_tlv(NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->geran_cell_search_indication, ppWritePackedMsg, end, &pack_geran_cell_search_indication_value) &&
+          pack_tlv(NFAPI_PNF_CELL_SEARCH_STATE_TAG, &pNfapiMsg->pnf_cell_search_state, ppWritePackedMsg, end, &pack_opaque_data_value) &&
+          pack_tlv(NFAPI_NB_IOT_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->nb_iot_cell_search_indication, ppWritePackedMsg, end, &pack_nb_iot_cell_search_indication_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
 
-	return (pack_tlv(NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, ppWritePackedMsg, end, &pack_opaque_data_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+static uint8_t pack_lte_broadcast_detect_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lte_broadcast_detect_request_t *value = (nfapi_lte_broadcast_detect_request_t *)msg;
+  return (push16(value->earfcn, ppWritePackedMsg, end) &&
+          push16(value->pci, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end));
+}
 
+static uint8_t pack_utran_broadcast_detect_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_utran_broadcast_detect_request_t *value = (nfapi_utran_broadcast_detect_request_t *)msg;
+  return (push16(value->uarfcn, ppWritePackedMsg, end) &&
+          push16(value->psc, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end));
 }
 
-static uint8_t pack_system_information_schedule_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_system_information_schedule_response_t *pNfapiMsg = (nfapi_system_information_schedule_response_t*)msg;
-	
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+static uint8_t pack_nb_iot_broadcast_detect_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nb_iot_broadcast_detect_request_t *value = (nfapi_nb_iot_broadcast_detect_request_t *)msg;
+  return (push16(value->earfcn, ppWritePackedMsg, end) &&
+          push8(value->ro_dl, ppWritePackedMsg, end) &&
+          push16(value->pci, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end));
 }
 
-static uint8_t pack_lte_system_information_indication_value(void* msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lte_system_information_indication_t* value = (nfapi_lte_system_information_indication_t*)msg;
+static uint8_t pack_broadcast_detect_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_broadcast_detect_request_t *pNfapiMsg = (nfapi_broadcast_detect_request_t *)msg;
+
+  if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  switch(pNfapiMsg->rat_type) {
+    case NFAPI_RAT_TYPE_LTE:
+      if(pack_tlv(NFAPI_LTE_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->lte_broadcast_detect_request, ppWritePackedMsg, end,&pack_lte_broadcast_detect_request_value) == 0)
+        return 0;
+
+      break;
 
-	return (push8(value->sib_type, ppWritePackedMsg, end) &&
-			push16(value->sib_length, ppWritePackedMsg, end) &&
-			pusharray8(value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, ppWritePackedMsg, end));
+    case NFAPI_RAT_TYPE_UTRAN:
+      if(pack_tlv(NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->utran_broadcast_detect_request, ppWritePackedMsg, end, &pack_utran_broadcast_detect_request_value) == 0)
+        return 0;
+
+      break;
+
+    case NFAPI_RAT_TYPE_NB_IOT:
+      if(pack_tlv(NFAPI_NB_IOT_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->nb_iot_broadcast_detect_request, ppWritePackedMsg, end, &pack_nb_iot_broadcast_detect_request_value) == 0)
+        return 0;
+
+      break;
+  }
+
+  return (pack_tlv(NFAPI_PNF_CELL_SEARCH_STATE_TAG, &pNfapiMsg->pnf_cell_search_state, ppWritePackedMsg, end, &pack_opaque_data_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
 }
 
-static uint8_t pack_nb_iot_system_information_indication_value(void* msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_system_information_indication_t* value = (nfapi_nb_iot_system_information_indication_t*)msg;
-
-	return (push8(value->sib_type, ppWritePackedMsg, end) &&
-			push16(value->sib_length, ppWritePackedMsg, end) &&
-			pusharray8(value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_system_information_schedule_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_system_information_schedule_indication_t *pNfapiMsg = (nfapi_system_information_schedule_indication_t*)msg;
-
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_tlv(NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->lte_system_information_indication, ppWritePackedMsg, end, &pack_lte_system_information_indication_value) &&
-			pack_tlv(NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->nb_iot_system_information_indication, ppWritePackedMsg, end, &pack_nb_iot_system_information_indication_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_lte_system_information_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lte_system_information_request_t* value = (nfapi_lte_system_information_request_t*)msg;
-	uint16_t idx = 0;
-
-	if(!(push16(value->earfcn, ppWritePackedMsg, end) &&
-		 push16(value->pci, ppWritePackedMsg, end) &&
-		 push16(value->downlink_channel_bandwidth, ppWritePackedMsg, end) &&
-		 push8(value->phich_configuration, ppWritePackedMsg, end) &&
-		 push8(value->number_of_tx_antenna, ppWritePackedMsg, end) &&
-		 push8(value->number_of_si_periodicity, ppWritePackedMsg, end)))
-		return 0;
-
-	for(idx = 0; idx < value->number_of_si_periodicity; ++idx)
-	{
-		if(!(push8(value->si_periodicity[idx].si_periodicity, ppWritePackedMsg, end) &&
-			 push8(value->si_periodicity[idx].si_index, ppWritePackedMsg, end)))
-			return 0;
-	}
-
-	return (push8(value->si_window_length, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end));
-}
-static uint8_t pack_utran_system_information_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_utran_system_information_request_t* value = (nfapi_utran_system_information_request_t*)msg;
-
-	return (push16(value->uarfcn, ppWritePackedMsg, end) &&
-			push16(value->psc, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end));
-}
-static uint8_t pack_geran_system_information_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_geran_system_information_request_t* value = (nfapi_geran_system_information_request_t*)msg;
-
-	return (push16(value->arfcn, ppWritePackedMsg, end) &&
-			push8(value->bsic, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end));
-}
-static uint8_t pack_nb_iot_system_information_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_system_information_request_t* value = (nfapi_nb_iot_system_information_request_t*)msg;
-	uint16_t idx = 0;
-
-	if(!(push16(value->earfcn, ppWritePackedMsg, end) &&
-		 push8(value->ro_dl, ppWritePackedMsg, end) &&
-		 push16(value->pci, ppWritePackedMsg, end) &&
-		 push8(value->number_of_si_periodicity, ppWritePackedMsg, end)))
-		return 0;
-
-	for(idx = 0; idx < value->number_of_si_periodicity; ++idx)
-	{
-		if(!(push8(value->si_periodicity[idx].si_periodicity, ppWritePackedMsg, end) &&
-			 push8(value->si_periodicity[idx].si_repetition_pattern, ppWritePackedMsg, end) &&
-			 push8(value->si_periodicity[idx].si_tb_size, ppWritePackedMsg, end) &&
-			 push8(value->si_periodicity[idx].number_of_si_index, ppWritePackedMsg, end)))
-			return 0;
-			
-		uint8_t si_idx;	
-		for(si_idx = 0; si_idx < value->si_periodicity[idx].number_of_si_index; ++si_idx)
-		{
-			if(!(push8(value->si_periodicity[idx].si_index[si_idx], ppWritePackedMsg, end)))
-				return 0;
-		}
-	}
-
-	return (push8(value->si_window_length, ppWritePackedMsg, end) &&
-			push32(value->timeout, ppWritePackedMsg, end));
-}
-
-
-static uint8_t pack_system_information_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_system_information_request_t *pNfapiMsg = (nfapi_system_information_request_t*)msg;
-
-	if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	switch(pNfapiMsg->rat_type)
-	{
-		case NFAPI_RAT_TYPE_LTE:
-			if(pack_tlv(NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->lte_system_information_request, ppWritePackedMsg, end, &pack_lte_system_information_request_value) == 0)
-				return 0;
-			break;
-		case NFAPI_RAT_TYPE_UTRAN:
-			if(pack_tlv(NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->utran_system_information_request, ppWritePackedMsg, end, &pack_utran_system_information_request_value) == 0)
-				return 0;
-			break;
-		case NFAPI_RAT_TYPE_GERAN:
-			if(pack_tlv(NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->geran_system_information_request, ppWritePackedMsg, end, &pack_geran_system_information_request_value) == 0)
-				return 0;
-			break;
-		case NFAPI_RAT_TYPE_NB_IOT:
-			if(pack_tlv(NFAPI_NB_IOT_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->nb_iot_system_information_request, ppWritePackedMsg, end, &pack_nb_iot_system_information_request_value) == 0)
-				return 0;
-			break;
-	}
-
-	return (pack_tlv(NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, ppWritePackedMsg, end, &pack_opaque_data_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_system_information_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end,  nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_system_information_response_t *pNfapiMsg = (nfapi_system_information_response_t*)msg;
-	
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_utran_system_information_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_utran_system_information_indication_t* value = (nfapi_utran_system_information_indication_t*)msg;
-	
-	return (push16(value->sib_length, ppWritePackedMsg, end) &&
-			pusharray8(value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_geran_system_information_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_geran_system_information_indication_t* value = (nfapi_geran_system_information_indication_t*)msg;
-
-	return (push16(value->si_length, ppWritePackedMsg, end) &&
-			pusharray8(value->si, NFAPI_MAX_SIB_LENGTH, value->si_length, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_system_information_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_system_information_indication_t *pNfapiMsg = (nfapi_system_information_indication_t*)msg;
-	
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_tlv(NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->lte_system_information_indication, ppWritePackedMsg, end, &pack_lte_system_information_indication_value) &&
-			pack_tlv(NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->utran_system_information_indication, ppWritePackedMsg, end, &pack_utran_system_information_indication_value) &&
-			pack_tlv(NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->geran_system_information_indication, ppWritePackedMsg, end, &pack_geran_system_information_indication_value) &&
-			pack_tlv(NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->nb_iot_system_information_indication, ppWritePackedMsg, end, &pack_nb_iot_system_information_indication_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-	
-static uint8_t pack_nmm_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nmm_stop_request_t *pNfapiMsg = (nfapi_nmm_stop_request_t*)msg;
-
-	return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_nmm_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nmm_stop_response_t *pNfapiMsg = (nfapi_nmm_stop_response_t*)msg;
-	
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t unpack_lte_rssi_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	//int result = 0;
-	nfapi_lte_rssi_request_t* value = (nfapi_lte_rssi_request_t*)tlv;
-
-	if(!(pull8(ppReadPackedMsg, &value->frequency_band_indicator, end) &&
-		 pull16(ppReadPackedMsg, &value->measurement_period, end) &&
-		 pull8(ppReadPackedMsg, &value->bandwidth, end) &&
-		 pull32(ppReadPackedMsg, &value->timeout, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_earfcns, end)))
-		return 0;
-
-	if(value->number_of_earfcns <= NFAPI_MAX_CARRIER_LIST)
-	{
-		if(pullarray16(ppReadPackedMsg, value->earfcn, NFAPI_MAX_CARRIER_LIST, value->number_of_earfcns, end) == 0)
-			return 0;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More EARFCN's than we can decode %d \n", value->number_of_earfcns);
-		return 0;
-	}
-
-	return 1;
-
-}
-
-static uint8_t unpack_utran_rssi_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_utran_rssi_request_t* value = (nfapi_utran_rssi_request_t*)tlv;
-
-	if(!(pull8(ppReadPackedMsg, &value->frequency_band_indicator, end) &&
-		 pull16(ppReadPackedMsg, &value->measurement_period, end) &&
-		 pull32(ppReadPackedMsg, &value->timeout, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_uarfcns, end)))
-		return 0;
-
-	if(value->number_of_uarfcns <= NFAPI_MAX_CARRIER_LIST)
-	{
-		if(pullarray16(ppReadPackedMsg, value->uarfcn, NFAPI_MAX_CARRIER_LIST, value->number_of_uarfcns, end) == 0)
-			return 0;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More UARFCN's than we can decode %d \n", value->number_of_uarfcns);
-		return 0;
-	}
-
-	return 1;
-}
-
-static uint8_t unpack_geran_rssi_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_geran_rssi_request_t* value = (nfapi_geran_rssi_request_t*)tlv;
-	uint16_t idx = 0;
-
-	if(!(pull8(ppReadPackedMsg, &value->frequency_band_indicator, end) &&
-	 	 pull16(ppReadPackedMsg, &value->measurement_period, end) &&
-		 pull32(ppReadPackedMsg, &value->timeout, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_arfcns, end)))
-		return 0;
-
-	if(value->number_of_arfcns <= NFAPI_MAX_CARRIER_LIST)
-	{
-		for(idx = 0; idx < value->number_of_arfcns; ++idx)
-		{
-			if(!(pull16(ppReadPackedMsg, &value->arfcn[idx].arfcn, end) &&
-			 	 pull8(ppReadPackedMsg, &value->arfcn[idx].direction, end)))
-				return 0;
-		}
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More ARFCN's than we can decode %d \n", value->number_of_arfcns);
-		return 0;
-	}
-
-	return 1;
-}
-
-static uint8_t unpack_nb_iot_rssi_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_rssi_request_t* value = (nfapi_nb_iot_rssi_request_t*)tlv;
-	uint16_t idx = 0;
-
-	if(!(pull8(ppReadPackedMsg, &value->frequency_band_indicator, end) &&
-	 	 pull16(ppReadPackedMsg, &value->measurement_period, end) &&
-		 pull32(ppReadPackedMsg, &value->timeout, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_earfcns, end)))
-		return 0;
-
-	if(value->number_of_earfcns <= NFAPI_MAX_CARRIER_LIST)
-	{
-		for(idx = 0; idx < value->number_of_earfcns; ++idx)
-		{
-			if(!(pull16(ppReadPackedMsg, &value->earfcn[idx].earfcn, end) &&
-			 	 pull8(ppReadPackedMsg, &value->earfcn[idx].number_of_ro_dl, end)))
-				return 0;
-				
-			if(value->earfcn[idx].number_of_ro_dl <= NFAPI_MAX_RO_DL)
-			{
-				uint8_t ro_dl_idx = 0;
-				for(ro_dl_idx = 0; ro_dl_idx < value->earfcn[idx].number_of_ro_dl; ++ro_dl_idx)
-				{
-					if(!pull8(ppReadPackedMsg, &value->earfcn[idx].ro_dl[ro_dl_idx], end))
-						return 0;
-				}
-			}
-			else
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "More ROdl's than we can decode %d \n", value->earfcn[idx].number_of_ro_dl);
-				return 0;
-			}
-			
-		}
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More EARFCN's than we can decode %d \n", value->number_of_earfcns);
-		return 0;
-	}
-
-	return 1;
-}
-
-static uint8_t unpack_rssi_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_rssi_request_t *pNfapiMsg = (nfapi_rssi_request_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_LTE_RSSI_REQUEST_TAG, &pNfapiMsg->lte_rssi_request, &unpack_lte_rssi_request_value},
-		{ NFAPI_UTRAN_RSSI_REQUEST_TAG, &pNfapiMsg->utran_rssi_request, &unpack_utran_rssi_request_value},
-		{ NFAPI_GERAN_RSSI_REQUEST_TAG, &pNfapiMsg->geran_rssi_request, &unpack_geran_rssi_request_value},
-		{ NFAPI_NB_IOT_RSSI_REQUEST_TAG, &pNfapiMsg->nb_iot_rssi_request, &unpack_nb_iot_rssi_request_value},
-	};
-
-	int result = 0;
-
-	result = (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) &&
-			  unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
-
-
-	// Verify that the rat type and the tlv match
-	if(result == 1 &&
-	   !((pNfapiMsg->rat_type == NFAPI_RAT_TYPE_LTE && pNfapiMsg->lte_rssi_request.tl.tag == NFAPI_LTE_RSSI_REQUEST_TAG) ||
-	    (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_UTRAN && pNfapiMsg->utran_rssi_request.tl.tag == NFAPI_UTRAN_RSSI_REQUEST_TAG) ||
-	    (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_GERAN && pNfapiMsg->geran_rssi_request.tl.tag == NFAPI_GERAN_RSSI_REQUEST_TAG) ||
-	    (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_NB_IOT && pNfapiMsg->nb_iot_rssi_request.tl.tag == NFAPI_NB_IOT_RSSI_REQUEST_TAG)))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Mismatch RAT Type: %d and TAG value: 0x%04x \n", pNfapiMsg->rat_type, pNfapiMsg->lte_rssi_request.tl.tag);
-		result = 0;
-	}
-	
-	return result;
-}
-
-static uint8_t unpack_rssi_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_rssi_response_t *pNfapiMsg = (nfapi_rssi_response_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
-}
-
-static uint8_t unpack_rssi_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_rssi_indication_body_t* value = (nfapi_rssi_indication_body_t*)tlv;
-
-	if(pull16(ppReadPackedMsg, &value->number_of_rssi, end) == 0)
-		return 0;
-
-	if(value->number_of_rssi <= NFAPI_MAX_RSSI)
-	{
-		if(pullarrays16(ppReadPackedMsg, value->rssi, NFAPI_MAX_RSSI, value->number_of_rssi, end) == 0)
-			return 0;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More RSSI's than we can decode %d \n", value->number_of_rssi);
-		return 0;
-	}
-
-	return 1;
-}
-
-static uint8_t unpack_rssi_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_rssi_indication_t *pNfapiMsg = (nfapi_rssi_indication_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_RSSI_INDICATION_TAG, &pNfapiMsg->rssi_indication_body, &unpack_rssi_indication_value},
-	};
-
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-		    unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_lte_cell_search_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_lte_cell_search_request_t* value = (nfapi_lte_cell_search_request_t*)tlv;
-
-	if(!(pull16(ppReadPackedMsg, &value->earfcn, end) &&
-		 pull8(ppReadPackedMsg, &value->measurement_bandwidth, end) &&
-		 pull8(ppReadPackedMsg, &value->exhaustive_search, end) &&
-		 pull32(ppReadPackedMsg, &value->timeout, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_pci, end)))
-		return 0;
-
-	if(value->number_of_pci <= NFAPI_MAX_PCI_LIST)
-	{
-		if(pullarray16(ppReadPackedMsg, value->pci, NFAPI_MAX_PCI_LIST, value->number_of_pci, end) == 0)
-			return 0;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More PCI's than we can decode %d \n", value->number_of_pci);
-		return 0;
-	}
-	return 1;
-}
-
-static uint8_t unpack_utran_cell_search_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_utran_cell_search_request_t* value = (nfapi_utran_cell_search_request_t*)tlv;
-
-	if(!(pull16(ppReadPackedMsg, &value->uarfcn, end) &&
-		 pull8(ppReadPackedMsg, &value->exhaustive_search, end) &&
-		 pull32(ppReadPackedMsg, &value->timeout, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_psc, end)))
-		return 0;
-
-	if(value->number_of_psc <= NFAPI_MAX_PSC_LIST)
-	{
-		if(pullarray16(ppReadPackedMsg, value->psc, NFAPI_MAX_PSC_LIST, value->number_of_psc, end) == 0)
-			return 0;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More PSC's than we can decode %d \n", value->number_of_psc);
-		return 0;
-	}
-	return 1;
-}
-
-static uint8_t unpack_geran_cell_search_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_geran_cell_search_request_t* value = (nfapi_geran_cell_search_request_t*)tlv;
-
-	if(!(pull32(ppReadPackedMsg, &value->timeout, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_arfcn, end)))
-		return 0;
-
-	if(value->number_of_arfcn <= NFAPI_MAX_ARFCN_LIST)
-	{
-		if(pullarray16(ppReadPackedMsg, value->arfcn, NFAPI_MAX_ARFCN_LIST, value->number_of_arfcn, end) == 0)
-			return 0;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More ARFCN's than we can decode %d \n", value->number_of_arfcn);
-		return 0;
-	}
-	return 1;
-}
-
-static uint8_t unpack_nb_iot_cell_search_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_cell_search_request_t* value = (nfapi_nb_iot_cell_search_request_t*)tlv;
-
-	if(!(pull16(ppReadPackedMsg, &value->earfcn, end) &&
-		 pull8(ppReadPackedMsg, &value->ro_dl, end) &&
-		 pull8(ppReadPackedMsg, &value->exhaustive_search, end) &&
-		 pull32(ppReadPackedMsg, &value->timeout, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_pci, end)))
-		return 0;
-
-	if(value->number_of_pci <= NFAPI_MAX_PCI_LIST)
-	{
-		if(pullarray16(ppReadPackedMsg, value->pci, NFAPI_MAX_PCI_LIST, value->number_of_pci, end) == 0)
-			return 0;
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More PCI's than we can decode %d \n", value->number_of_pci);
-		return 0;
-	}
-	return 1;
-}
-
-static uint8_t unpack_cell_search_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_cell_search_request_t *pNfapiMsg = (nfapi_cell_search_request_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_LTE_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->lte_cell_search_request, &unpack_lte_cell_search_request_value},
-		{ NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->utran_cell_search_request, &unpack_utran_cell_search_request_value},
-		{ NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->geran_cell_search_request, &unpack_geran_cell_search_request_value},
-		{ NFAPI_NB_IOT_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->nb_iot_cell_search_request, &unpack_nb_iot_cell_search_request_value},
-	};
-
-	int result = (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) &&
-			  unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-
-	// Verify that the rat type and the tlv match
-	if(result == 1 &&
-	   !((pNfapiMsg->rat_type == NFAPI_RAT_TYPE_LTE && pNfapiMsg->lte_cell_search_request.tl.tag == NFAPI_LTE_CELL_SEARCH_REQUEST_TAG) ||
-	    (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_UTRAN && pNfapiMsg->utran_cell_search_request.tl.tag == NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG) ||
-	    (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_GERAN && pNfapiMsg->geran_cell_search_request.tl.tag == NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG) ||
-	    (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_NB_IOT && pNfapiMsg->nb_iot_cell_search_request.tl.tag == NFAPI_NB_IOT_CELL_SEARCH_REQUEST_TAG)))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Mismatch RAT Type: %d and TAG value: 0x%04x \n", pNfapiMsg->rat_type, pNfapiMsg->lte_cell_search_request.tl.tag);
-		result = 0;
-	}
-	
-	return result;
-}
-
-static uint8_t unpack_cell_search_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_cell_search_response_t *pNfapiMsg = (nfapi_cell_search_response_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_lte_cell_search_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_lte_cell_search_indication_t* value = (nfapi_lte_cell_search_indication_t*)tlv;
-
-	uint16_t idx = 0;
-	if(pull16(ppReadPackedMsg, &value->number_of_lte_cells_found, end) == 0)
-		return 0;
-
-	if(value->number_of_lte_cells_found <= NFAPI_MAX_LTE_CELLS_FOUND)
-	{
-		for(idx = 0; idx < value->number_of_lte_cells_found; ++idx)
-		{
-			if(!(pull16(ppReadPackedMsg, &value->lte_found_cells[idx].pci, end) &&
-				 pull8(ppReadPackedMsg, &value->lte_found_cells[idx].rsrp, end) &&
-				 pull8(ppReadPackedMsg, &value->lte_found_cells[idx].rsrq, end) &&
-				 pulls16(ppReadPackedMsg, &value->lte_found_cells[idx].frequency_offset, end)))
-				return 0;
-		}
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found LTE cells than we can decode %d \n", value->number_of_lte_cells_found);
-		return 0;
-	}
-	return 1;
-}
-
-static uint8_t unpack_utran_cell_search_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_utran_cell_search_indication_t* value = (nfapi_utran_cell_search_indication_t*)tlv;
-
-	uint16_t idx = 0;
-	if(pull16(ppReadPackedMsg, &value->number_of_utran_cells_found, end) == 0)
-		return 0;
-
-	if(value->number_of_utran_cells_found <= NFAPI_MAX_UTRAN_CELLS_FOUND)
-	{
-		for(idx = 0; idx < value->number_of_utran_cells_found; ++idx)
-		{
-			if(!(pull16(ppReadPackedMsg, &value->utran_found_cells[idx].psc, end) &&
-				 pull8(ppReadPackedMsg, &value->utran_found_cells[idx].rscp, end) &&
-				 pull8(ppReadPackedMsg, &value->utran_found_cells[idx].ecno, end) &&
-				 pulls16(ppReadPackedMsg, &value->utran_found_cells[idx].frequency_offset, end)))
-				return 0;
-		}
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found UTRAN cells than we can decode %d \n", value->number_of_utran_cells_found);
-		return 0;
-	}
-	return 1;
-}
-
-static uint8_t unpack_geran_cell_search_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_geran_cell_search_indication_t* value = (nfapi_geran_cell_search_indication_t*)tlv;
-
-	uint16_t idx = 0;
-	if(pull16(ppReadPackedMsg, &value->number_of_gsm_cells_found, end) == 0)
-		return 0;
-
-	if(value->number_of_gsm_cells_found <= NFAPI_MAX_GSM_CELLS_FOUND)
-	{
-		for(idx = 0; idx < value->number_of_gsm_cells_found; ++idx)
-		{
-			if(!(pull16(ppReadPackedMsg, &value->gsm_found_cells[idx].arfcn, end) &&
-				 pull8(ppReadPackedMsg, &value->gsm_found_cells[idx].bsic, end) &&
-				 pull8(ppReadPackedMsg, &value->gsm_found_cells[idx].rxlev, end) &&
-				 pull8(ppReadPackedMsg, &value->gsm_found_cells[idx].rxqual, end) &&
-				 pulls16(ppReadPackedMsg, &value->gsm_found_cells[idx].frequency_offset, end) &&
-				 pull32(ppReadPackedMsg, &value->gsm_found_cells[idx].sfn_offset, end)))
-				return 0;
-		}
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found GSM cells than we can decode %d \n", value->number_of_gsm_cells_found);
-		return 0;
-	}
-	return 1;
-}
-
-static uint8_t unpack_nb_iot_cell_search_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_cell_search_indication_t* value = (nfapi_nb_iot_cell_search_indication_t*)tlv;
-
-	uint16_t idx = 0;
-	if(pull16(ppReadPackedMsg, &value->number_of_nb_iot_cells_found, end) == 0)
-		return 0;
-
-	if(value->number_of_nb_iot_cells_found <= NFAPI_MAX_NB_IOT_CELLS_FOUND)
-	{
-		for(idx = 0; idx < value->number_of_nb_iot_cells_found; ++idx)
-		{
-			if(!(pull16(ppReadPackedMsg, &value->nb_iot_found_cells[idx].pci, end) &&
-				 pull8(ppReadPackedMsg, &value->nb_iot_found_cells[idx].rsrp, end) &&
-				 pull8(ppReadPackedMsg, &value->nb_iot_found_cells[idx].rsrq, end) &&
-				 pulls16(ppReadPackedMsg, &value->nb_iot_found_cells[idx].frequency_offset, end)))
-				return 0;
-		}
-	}
-	else
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found NB_IOT cells than we can decode %d \n", value->number_of_nb_iot_cells_found);
-		return 0;
-	}
-	return 1;
-}
-
-static uint8_t unpack_cell_search_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_cell_search_indication_t *pNfapiMsg = (nfapi_cell_search_indication_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_LTE_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->lte_cell_search_indication, &unpack_lte_cell_search_indication_value},
-		{ NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->utran_cell_search_indication, &unpack_utran_cell_search_indication_value},
-		{ NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->geran_cell_search_indication, &unpack_geran_cell_search_indication_value},
-		{ NFAPI_PNF_CELL_SEARCH_STATE_TAG, &pNfapiMsg->pnf_cell_search_state, &unpack_opaque_data_value},
-		{ NFAPI_NB_IOT_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->nb_iot_cell_search_indication, &unpack_nb_iot_cell_search_indication_value},
-	};
-
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-		
-}
-
-static uint8_t unpack_lte_broadcast_detect_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_lte_broadcast_detect_request_t* value = (nfapi_lte_broadcast_detect_request_t*)tlv;
-
-	return (pull16(ppReadPackedMsg, &value->earfcn, end) &&
-			pull16(ppReadPackedMsg, &value->pci, end) &&
-			pull32(ppReadPackedMsg, &value->timeout, end));
-}
-
-static uint8_t unpack_utran_broadcast_detect_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_utran_broadcast_detect_request_t* value = (nfapi_utran_broadcast_detect_request_t*)tlv;
-
-	return (pull16(ppReadPackedMsg, &value->uarfcn, end) &&
-			pull16(ppReadPackedMsg, &value->psc, end) &&
-			pull32(ppReadPackedMsg, &value->timeout, end));
-}
-
-static uint8_t unpack_nb_iot_broadcast_detect_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_broadcast_detect_request_t* value = (nfapi_nb_iot_broadcast_detect_request_t*)tlv;
-
-	return (pull16(ppReadPackedMsg, &value->earfcn, end) &&
-			pull8(ppReadPackedMsg, &value->ro_dl, end) &&
-			pull16(ppReadPackedMsg, &value->pci, end) &&
-			pull32(ppReadPackedMsg, &value->timeout, end));
-}
-
-static uint8_t unpack_broadcast_detect_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_broadcast_detect_request_t *pNfapiMsg = (nfapi_broadcast_detect_request_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_LTE_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->lte_broadcast_detect_request, &unpack_lte_broadcast_detect_request_value},
-		{ NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->utran_broadcast_detect_request, &unpack_utran_broadcast_detect_request_value},
-		{ NFAPI_PNF_CELL_SEARCH_STATE_TAG, &pNfapiMsg->pnf_cell_search_state, &unpack_opaque_data_value},
-		{ NFAPI_NB_IOT_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->nb_iot_broadcast_detect_request, &unpack_nb_iot_broadcast_detect_request_value}
-	};
-
-	return (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) &&	
-			unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_broadcast_detect_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_broadcast_detect_response_t *pNfapiMsg = (nfapi_broadcast_detect_response_t*)msg;
+static uint8_t pack_broadcast_detect_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_broadcast_detect_response_t *pNfapiMsg = (nfapi_broadcast_detect_response_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
 
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
+static uint8_t pack_lte_broadcast_detect_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lte_broadcast_detect_indication_t *value = (nfapi_lte_broadcast_detect_indication_t *)msg;
+  return (push8(value->number_of_tx_antenna, ppWritePackedMsg, end) &&
+          push16(value->mib_length, ppWritePackedMsg, end) &&
+          pusharray8(value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, ppWritePackedMsg, end) &&
+          push32(value->sfn_offset, ppWritePackedMsg, end));
+}
 
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+static uint8_t pack_utran_broadcast_detect_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_utran_broadcast_detect_indication_t *value = (nfapi_utran_broadcast_detect_indication_t *)msg;
+  return (push16(value->mib_length, ppWritePackedMsg, end) &&
+          pusharray8(value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, ppWritePackedMsg, end) &&
+          push32(value->sfn_offset, ppWritePackedMsg, end));
 }
 
-static uint8_t unpack_lte_broadcast_detect_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_lte_broadcast_detect_indication_t* value = (nfapi_lte_broadcast_detect_indication_t*)tlv;
+static uint8_t pack_nb_iot_broadcast_detect_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nb_iot_broadcast_detect_indication_t *value = (nfapi_nb_iot_broadcast_detect_indication_t *)msg;
+  return (push8(value->number_of_tx_antenna, ppWritePackedMsg, end) &&
+          push16(value->mib_length, ppWritePackedMsg, end) &&
+          pusharray8(value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, ppWritePackedMsg, end) &&
+          push32(value->sfn_offset, ppWritePackedMsg, end));
+}
 
-	if(!(pull8(ppReadPackedMsg, &value->number_of_tx_antenna, end) &&
-	 	 pull16(ppReadPackedMsg, &value->mib_length, end)))
-		return 0;
+static uint8_t pack_broadcast_detect_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_broadcast_detect_indication_t *pNfapiMsg = (nfapi_broadcast_detect_indication_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_tlv(NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->lte_broadcast_detect_indication, ppWritePackedMsg, end, &pack_lte_broadcast_detect_indication_value) &&
+          pack_tlv(NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->utran_broadcast_detect_indication, ppWritePackedMsg, end, &pack_utran_broadcast_detect_indication_value) &&
+          pack_tlv(NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, ppWritePackedMsg, end, &pack_opaque_data_value) &&
+          pack_tlv(NFAPI_NB_IOT_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->nb_iot_broadcast_detect_indication, ppWritePackedMsg, end, &pack_nb_iot_broadcast_detect_indication_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
 
-	if(value->mib_length > NFAPI_MAX_MIB_LENGTH)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "MIB too long %d \n", value->mib_length);
-		return 0;
-	}
-	
-	return (pullarray8(ppReadPackedMsg, value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, end) &&
-			pull32(ppReadPackedMsg, &value->sfn_offset, end));
+static uint8_t pack_lte_system_information_schedule_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lte_system_information_schedule_request_t *value = (nfapi_lte_system_information_schedule_request_t *)msg;
+  return (push16(value->earfcn, ppWritePackedMsg, end) &&
+          push16(value->pci, ppWritePackedMsg, end) &&
+          push16(value->downlink_channel_bandwidth, ppWritePackedMsg, end) &&
+          push8(value->phich_configuration, ppWritePackedMsg, end) &&
+          push8(value->number_of_tx_antenna, ppWritePackedMsg, end) &&
+          push8(value->retry_count, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end));
 }
 
-static uint8_t unpack_utran_broadcast_detect_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_utran_broadcast_detect_indication_t* value = (nfapi_utran_broadcast_detect_indication_t*)tlv;
+static uint8_t pack_nb_iot_system_information_schedule_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nb_iot_system_information_schedule_request_t *value = (nfapi_nb_iot_system_information_schedule_request_t *)msg;
+  return (push16(value->earfcn, ppWritePackedMsg, end) &&
+          push8(value->ro_dl, ppWritePackedMsg, end) &&
+          push16(value->pci, ppWritePackedMsg, end) &&
+          push8(value->scheduling_info_sib1_nb, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end));
+}
+
+
+static uint8_t pack_system_information_schedule_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_system_information_schedule_request_t *pNfapiMsg = (nfapi_system_information_schedule_request_t *)msg;
 
-	if(pull16(ppReadPackedMsg, &value->mib_length, end) == 0)
-		return 0;
+  if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0)
+    return 0;
 
-	if(value->mib_length > NFAPI_MAX_MIB_LENGTH)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "MIB too long %d \n", value->mib_length);
-		return 0;
-	}
+  switch(pNfapiMsg->rat_type) {
+    case NFAPI_RAT_TYPE_LTE:
+      if(pack_tlv(NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &pNfapiMsg->lte_system_information_schedule_request, ppWritePackedMsg, end, &pack_lte_system_information_schedule_request_value) == 0)
+        return 0;
 
-	return (pullarray8(ppReadPackedMsg, value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, end) &&
-			pull32(ppReadPackedMsg, &value->sfn_offset, end));
+      break;
+
+    case NFAPI_RAT_TYPE_NB_IOT:
+      if(pack_tlv(NFAPI_NB_IOT_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &pNfapiMsg->nb_iot_system_information_schedule_request, ppWritePackedMsg, end,
+                  &pack_nb_iot_system_information_schedule_request_value) == 0)
+        return 0;
+
+      break;
+  }
+
+  return (pack_tlv(NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, ppWritePackedMsg, end, &pack_opaque_data_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
 }
 
-static uint8_t unpack_nb_iot_broadcast_detect_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_broadcast_detect_indication_t* value = (nfapi_nb_iot_broadcast_detect_indication_t*)tlv;
+static uint8_t pack_system_information_schedule_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_system_information_schedule_response_t *pNfapiMsg = (nfapi_system_information_schedule_response_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
 
-	if(!(pull8(ppReadPackedMsg, &value->number_of_tx_antenna, end) && 
-		 pull16(ppReadPackedMsg, &value->mib_length, end)))
-		return 0;
+static uint8_t pack_lte_system_information_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lte_system_information_indication_t *value = (nfapi_lte_system_information_indication_t *)msg;
+  return (push8(value->sib_type, ppWritePackedMsg, end) &&
+          push16(value->sib_length, ppWritePackedMsg, end) &&
+          pusharray8(value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, ppWritePackedMsg, end));
+}
 
-	if(value->mib_length > NFAPI_MAX_MIB_LENGTH)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "MIB too long %d \n", value->mib_length);
-		return 0;
-	}
+static uint8_t pack_nb_iot_system_information_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nb_iot_system_information_indication_t *value = (nfapi_nb_iot_system_information_indication_t *)msg;
+  return (push8(value->sib_type, ppWritePackedMsg, end) &&
+          push16(value->sib_length, ppWritePackedMsg, end) &&
+          pusharray8(value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, ppWritePackedMsg, end));
+}
 
-	return (pullarray8(ppReadPackedMsg, value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, end) &&
-			pull32(ppReadPackedMsg, &value->sfn_offset, end));
+static uint8_t pack_system_information_schedule_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_system_information_schedule_indication_t *pNfapiMsg = (nfapi_system_information_schedule_indication_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_tlv(NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->lte_system_information_indication, ppWritePackedMsg, end, &pack_lte_system_information_indication_value) &&
+          pack_tlv(NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->nb_iot_system_information_indication, ppWritePackedMsg, end, &pack_nb_iot_system_information_indication_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
 }
 
-static uint8_t unpack_broadcast_detect_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_broadcast_detect_indication_t *pNfapiMsg = (nfapi_broadcast_detect_indication_t*)msg;
+static uint8_t pack_lte_system_information_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lte_system_information_request_t *value = (nfapi_lte_system_information_request_t *)msg;
+  uint16_t idx = 0;
 
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->lte_broadcast_detect_indication, &unpack_lte_broadcast_detect_indication_value},
-		{ NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->utran_broadcast_detect_indication, &unpack_utran_broadcast_detect_indication_value},
-		{ NFAPI_NB_IOT_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->nb_iot_broadcast_detect_indication, &unpack_nb_iot_broadcast_detect_indication_value},
-		{ NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, &unpack_opaque_data_value}
-	};
+  if(!(push16(value->earfcn, ppWritePackedMsg, end) &&
+       push16(value->pci, ppWritePackedMsg, end) &&
+       push16(value->downlink_channel_bandwidth, ppWritePackedMsg, end) &&
+       push8(value->phich_configuration, ppWritePackedMsg, end) &&
+       push8(value->number_of_tx_antenna, ppWritePackedMsg, end) &&
+       push8(value->number_of_si_periodicity, ppWritePackedMsg, end)))
+    return 0;
 
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+  for(idx = 0; idx < value->number_of_si_periodicity; ++idx) {
+    if(!(push8(value->si_periodicity[idx].si_periodicity, ppWritePackedMsg, end) &&
+         push8(value->si_periodicity[idx].si_index, ppWritePackedMsg, end)))
+      return 0;
+  }
+
+  return (push8(value->si_window_length, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end));
+}
+static uint8_t pack_utran_system_information_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_utran_system_information_request_t *value = (nfapi_utran_system_information_request_t *)msg;
+  return (push16(value->uarfcn, ppWritePackedMsg, end) &&
+          push16(value->psc, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end));
+}
+static uint8_t pack_geran_system_information_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_geran_system_information_request_t *value = (nfapi_geran_system_information_request_t *)msg;
+  return (push16(value->arfcn, ppWritePackedMsg, end) &&
+          push8(value->bsic, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end));
 }
+static uint8_t pack_nb_iot_system_information_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nb_iot_system_information_request_t *value = (nfapi_nb_iot_system_information_request_t *)msg;
+  uint16_t idx = 0;
+
+  if(!(push16(value->earfcn, ppWritePackedMsg, end) &&
+       push8(value->ro_dl, ppWritePackedMsg, end) &&
+       push16(value->pci, ppWritePackedMsg, end) &&
+       push8(value->number_of_si_periodicity, ppWritePackedMsg, end)))
+    return 0;
+
+  for(idx = 0; idx < value->number_of_si_periodicity; ++idx) {
+    if(!(push8(value->si_periodicity[idx].si_periodicity, ppWritePackedMsg, end) &&
+         push8(value->si_periodicity[idx].si_repetition_pattern, ppWritePackedMsg, end) &&
+         push8(value->si_periodicity[idx].si_tb_size, ppWritePackedMsg, end) &&
+         push8(value->si_periodicity[idx].number_of_si_index, ppWritePackedMsg, end)))
+      return 0;
 
-static uint8_t unpack_lte_system_information_schedule_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_lte_system_information_schedule_request_t* value = (nfapi_lte_system_information_schedule_request_t*)tlv;
+    uint8_t si_idx;
 
-	return (pull16(ppReadPackedMsg, &value->earfcn, end) &&
-			pull16(ppReadPackedMsg, &value->pci, end) &&
-			pull16(ppReadPackedMsg, &value->downlink_channel_bandwidth, end) &&
-			pull8(ppReadPackedMsg, &value->phich_configuration, end) &&
-			pull8(ppReadPackedMsg, &value->number_of_tx_antenna, end) &&
-			pull8(ppReadPackedMsg, &value->retry_count, end) &&
-			pull32(ppReadPackedMsg, &value->timeout, end));
+    for(si_idx = 0; si_idx < value->si_periodicity[idx].number_of_si_index; ++si_idx) {
+      if(!(push8(value->si_periodicity[idx].si_index[si_idx], ppWritePackedMsg, end)))
+        return 0;
+    }
+  }
+
+  return (push8(value->si_window_length, ppWritePackedMsg, end) &&
+          push32(value->timeout, ppWritePackedMsg, end));
 }
 
-static uint8_t unpack_nb_iot_system_information_schedule_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_system_information_schedule_request_t* value = (nfapi_nb_iot_system_information_schedule_request_t*)tlv;
 
-	return (pull16(ppReadPackedMsg, &value->earfcn, end) &&
-			pull8(ppReadPackedMsg, &value->ro_dl, end) &&	
-			pull16(ppReadPackedMsg, &value->pci, end) &&
-			pull8(ppReadPackedMsg, &value->scheduling_info_sib1_nb, end) &&
-			pull32(ppReadPackedMsg, &value->timeout, end));
+static uint8_t pack_system_information_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_system_information_request_t *pNfapiMsg = (nfapi_system_information_request_t *)msg;
+
+  if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  switch(pNfapiMsg->rat_type) {
+    case NFAPI_RAT_TYPE_LTE:
+      if(pack_tlv(NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->lte_system_information_request, ppWritePackedMsg, end, &pack_lte_system_information_request_value) == 0)
+        return 0;
+
+      break;
+
+    case NFAPI_RAT_TYPE_UTRAN:
+      if(pack_tlv(NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->utran_system_information_request, ppWritePackedMsg, end, &pack_utran_system_information_request_value) == 0)
+        return 0;
+
+      break;
+
+    case NFAPI_RAT_TYPE_GERAN:
+      if(pack_tlv(NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->geran_system_information_request, ppWritePackedMsg, end, &pack_geran_system_information_request_value) == 0)
+        return 0;
+
+      break;
+
+    case NFAPI_RAT_TYPE_NB_IOT:
+      if(pack_tlv(NFAPI_NB_IOT_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->nb_iot_system_information_request, ppWritePackedMsg, end, &pack_nb_iot_system_information_request_value) == 0)
+        return 0;
+
+      break;
+  }
+
+  return (pack_tlv(NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, ppWritePackedMsg, end, &pack_opaque_data_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
 }
 
-static uint8_t unpack_system_information_schedule_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_system_information_schedule_request_t *pNfapiMsg = (nfapi_system_information_schedule_request_t*)msg;
+static uint8_t pack_system_information_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end,  nfapi_p4_p5_codec_config_t *config) {
+  nfapi_system_information_response_t *pNfapiMsg = (nfapi_system_information_response_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
 
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &pNfapiMsg->lte_system_information_schedule_request, &unpack_lte_system_information_schedule_request_value},
-		{ NFAPI_NB_IOT_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &pNfapiMsg->nb_iot_system_information_schedule_request, &unpack_nb_iot_system_information_schedule_request_value},
-		{ NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, &unpack_opaque_data_value}
-	};
+static uint8_t pack_utran_system_information_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_utran_system_information_indication_t *value = (nfapi_utran_system_information_indication_t *)msg;
+  return (push16(value->sib_length, ppWritePackedMsg, end) &&
+          pusharray8(value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, ppWritePackedMsg, end));
+}
 
-	return (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) &&
-			unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+static uint8_t pack_geran_system_information_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_geran_system_information_indication_t *value = (nfapi_geran_system_information_indication_t *)msg;
+  return (push16(value->si_length, ppWritePackedMsg, end) &&
+          pusharray8(value->si, NFAPI_MAX_SIB_LENGTH, value->si_length, ppWritePackedMsg, end));
 }
 
-static uint8_t unpack_system_information_schedule_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_system_information_schedule_response_t *pNfapiMsg = (nfapi_system_information_schedule_response_t*)msg;
+static uint8_t pack_system_information_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_system_information_indication_t *pNfapiMsg = (nfapi_system_information_indication_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_tlv(NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->lte_system_information_indication, ppWritePackedMsg, end, &pack_lte_system_information_indication_value) &&
+          pack_tlv(NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->utran_system_information_indication, ppWritePackedMsg, end, &pack_utran_system_information_indication_value) &&
+          pack_tlv(NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->geran_system_information_indication, ppWritePackedMsg, end, &pack_geran_system_information_indication_value) &&
+          pack_tlv(NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->nb_iot_system_information_indication, ppWritePackedMsg, end, &pack_nb_iot_system_information_indication_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
 
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
+static uint8_t pack_nmm_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nmm_stop_request_t *pNfapiMsg = (nfapi_nmm_stop_request_t *)msg;
+  return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
 
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+static uint8_t pack_nmm_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nmm_stop_response_t *pNfapiMsg = (nfapi_nmm_stop_response_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
 }
 
-static uint8_t unpack_lte_system_information_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_lte_system_information_indication_t* value = (nfapi_lte_system_information_indication_t*)tlv;
+static uint8_t unpack_lte_rssi_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  //int result = 0;
+  nfapi_lte_rssi_request_t *value = (nfapi_lte_rssi_request_t *)tlv;
 
-	if(!(pull8(ppReadPackedMsg, &value->sib_type, end) &&
-		 pull16(ppReadPackedMsg, &value->sib_length, end)))
-		return 0;
+  if(!(pull8(ppReadPackedMsg, &value->frequency_band_indicator, end) &&
+       pull16(ppReadPackedMsg, &value->measurement_period, end) &&
+       pull8(ppReadPackedMsg, &value->bandwidth, end) &&
+       pull32(ppReadPackedMsg, &value->timeout, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_earfcns, end)))
+    return 0;
 
-	if(value->sib_length > NFAPI_MAX_SIB_LENGTH)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "SIB too long %d \n", value->sib_length);
-		return 0;
-	}
-	
-	if(pullarray8(ppReadPackedMsg, value->sib, NFAPI_MAX_SIB_LENGTH,  value->sib_length, end) == 0)
-		return 0;
+  if(value->number_of_earfcns <= NFAPI_MAX_CARRIER_LIST) {
+    if(pullarray16(ppReadPackedMsg, value->earfcn, NFAPI_MAX_CARRIER_LIST, value->number_of_earfcns, end) == 0)
+      return 0;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More EARFCN's than we can decode %d \n", value->number_of_earfcns);
+    return 0;
+  }
 
-	return 1;
+  return 1;
 }
 
-static uint8_t unpack_nb_iot_system_information_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_system_information_indication_t* value = (nfapi_nb_iot_system_information_indication_t*)tlv;
+static uint8_t unpack_utran_rssi_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_utran_rssi_request_t *value = (nfapi_utran_rssi_request_t *)tlv;
+
+  if(!(pull8(ppReadPackedMsg, &value->frequency_band_indicator, end) &&
+       pull16(ppReadPackedMsg, &value->measurement_period, end) &&
+       pull32(ppReadPackedMsg, &value->timeout, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_uarfcns, end)))
+    return 0;
+
+  if(value->number_of_uarfcns <= NFAPI_MAX_CARRIER_LIST) {
+    if(pullarray16(ppReadPackedMsg, value->uarfcn, NFAPI_MAX_CARRIER_LIST, value->number_of_uarfcns, end) == 0)
+      return 0;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More UARFCN's than we can decode %d \n", value->number_of_uarfcns);
+    return 0;
+  }
 
-	if(!(pull8(ppReadPackedMsg, &value->sib_type, end) &&
-		 pull16(ppReadPackedMsg, &value->sib_length, end)))
-		return 0;
+  return 1;
+}
 
-	if(value->sib_length > NFAPI_MAX_SIB_LENGTH)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "SIB too long %d \n", value->sib_length);
-		return 0;
-	}
-	
-	if(pullarray8(ppReadPackedMsg, value->sib, NFAPI_MAX_SIB_LENGTH,  value->sib_length, end) == 0)
-		return 0;
-
-	return 1;
-}
-
-static uint8_t unpack_system_information_schedule_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_system_information_schedule_indication_t *pNfapiMsg = (nfapi_system_information_schedule_indication_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->lte_system_information_indication, &unpack_lte_system_information_indication_value},
-		{ NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->nb_iot_system_information_indication, &unpack_nb_iot_system_information_indication_value},
-	};
-
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_lte_system_information_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_lte_system_information_request_t* value = (nfapi_lte_system_information_request_t*)tlv;
-	uint16_t idx = 0;
-
-	if(!(pull16(ppReadPackedMsg, &value->earfcn, end) &&
-		 pull16(ppReadPackedMsg, &value->pci, end) &&
-		 pull16(ppReadPackedMsg, &value->downlink_channel_bandwidth, end) &&
-		 pull8(ppReadPackedMsg, &value->phich_configuration, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_tx_antenna, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_si_periodicity, end)))
-		return 0;
-
-	if(value->number_of_si_periodicity > NFAPI_MAX_SI_PERIODICITY)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found SI periodicity than we can decode %d \n", value->number_of_si_periodicity);
-		return 0;
-	}
-
-	for(idx = 0; idx < value->number_of_si_periodicity; ++idx)
-	{
-		if(!(pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_periodicity, end) &&
-			 pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_index, end)))
-			return 0;
-	}
-
-	if(!(pull8(ppReadPackedMsg, &value->si_window_length, end) &&
-	 	 pull32(ppReadPackedMsg, &value->timeout, end)))
-		return 0;
-
-	return 1;
-}
-
-static uint8_t unpack_utran_system_information_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_utran_system_information_request_t* value = (nfapi_utran_system_information_request_t*)tlv;
-
-	return (pull16(ppReadPackedMsg, &value->uarfcn, end) &&
-			pull16(ppReadPackedMsg, &value->psc, end) &&
-			pull32(ppReadPackedMsg, &value->timeout, end));
-}
-
-static uint8_t unpack_geran_system_information_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_geran_system_information_request_t* value = (nfapi_geran_system_information_request_t*)tlv;
-
-	return (pull16(ppReadPackedMsg, &value->arfcn, end) &&
-			pull8(ppReadPackedMsg, &value->bsic, end) &&
-			pull32(ppReadPackedMsg, &value->timeout, end));
-}
-
-static uint8_t unpack_nb_iot_system_information_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nb_iot_system_information_request_t* value = (nfapi_nb_iot_system_information_request_t*)tlv;
-	uint16_t idx = 0;
-
-	if(!(pull16(ppReadPackedMsg, &value->earfcn, end) &&
-		 pull8(ppReadPackedMsg, &value->ro_dl, end) &&
-		 pull16(ppReadPackedMsg, &value->pci, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_si_periodicity, end)))
-		return 0;
-
-	if(value->number_of_si_periodicity > NFAPI_MAX_SI_PERIODICITY)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found SI periodicity than we can decode %d \n", value->number_of_si_periodicity);
-		return 0;
-	}
-
-	for(idx = 0; idx < value->number_of_si_periodicity; ++idx)
-	{
-		if(!(pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_periodicity, end) &&
-			 pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_repetition_pattern, end) &&
-			 pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_tb_size, end) &&
-			 pull8(ppReadPackedMsg, &value->si_periodicity[idx].number_of_si_index, end)))
-			return 0;
-			
-		uint8_t si_idx;
-		for(si_idx = 0; si_idx < value->si_periodicity[idx].number_of_si_index; ++si_idx)
-		{
-			if(!(pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_index[si_idx], end)))
-				return 0;
-			
-		}
-	}
-
-	if(!(pull8(ppReadPackedMsg, &value->si_window_length, end) &&
-	 	 pull32(ppReadPackedMsg, &value->timeout, end)))
-		return 0;
+static uint8_t unpack_geran_rssi_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_geran_rssi_request_t *value = (nfapi_geran_rssi_request_t *)tlv;
+  uint16_t idx = 0;
+
+  if(!(pull8(ppReadPackedMsg, &value->frequency_band_indicator, end) &&
+       pull16(ppReadPackedMsg, &value->measurement_period, end) &&
+       pull32(ppReadPackedMsg, &value->timeout, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_arfcns, end)))
+    return 0;
+
+  if(value->number_of_arfcns <= NFAPI_MAX_CARRIER_LIST) {
+    for(idx = 0; idx < value->number_of_arfcns; ++idx) {
+      if(!(pull16(ppReadPackedMsg, &value->arfcn[idx].arfcn, end) &&
+           pull8(ppReadPackedMsg, &value->arfcn[idx].direction, end)))
+        return 0;
+    }
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More ARFCN's than we can decode %d \n", value->number_of_arfcns);
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nb_iot_rssi_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nb_iot_rssi_request_t *value = (nfapi_nb_iot_rssi_request_t *)tlv;
+  uint16_t idx = 0;
+
+  if(!(pull8(ppReadPackedMsg, &value->frequency_band_indicator, end) &&
+       pull16(ppReadPackedMsg, &value->measurement_period, end) &&
+       pull32(ppReadPackedMsg, &value->timeout, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_earfcns, end)))
+    return 0;
+
+  if(value->number_of_earfcns <= NFAPI_MAX_CARRIER_LIST) {
+    for(idx = 0; idx < value->number_of_earfcns; ++idx) {
+      if(!(pull16(ppReadPackedMsg, &value->earfcn[idx].earfcn, end) &&
+           pull8(ppReadPackedMsg, &value->earfcn[idx].number_of_ro_dl, end)))
+        return 0;
+
+      if(value->earfcn[idx].number_of_ro_dl <= NFAPI_MAX_RO_DL) {
+        uint8_t ro_dl_idx = 0;
+
+        for(ro_dl_idx = 0; ro_dl_idx < value->earfcn[idx].number_of_ro_dl; ++ro_dl_idx) {
+          if(!pull8(ppReadPackedMsg, &value->earfcn[idx].ro_dl[ro_dl_idx], end))
+            return 0;
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "More ROdl's than we can decode %d \n", value->earfcn[idx].number_of_ro_dl);
+        return 0;
+      }
+    }
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More EARFCN's than we can decode %d \n", value->number_of_earfcns);
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_rssi_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_rssi_request_t *pNfapiMsg = (nfapi_rssi_request_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_LTE_RSSI_REQUEST_TAG, &pNfapiMsg->lte_rssi_request, &unpack_lte_rssi_request_value},
+    { NFAPI_UTRAN_RSSI_REQUEST_TAG, &pNfapiMsg->utran_rssi_request, &unpack_utran_rssi_request_value},
+    { NFAPI_GERAN_RSSI_REQUEST_TAG, &pNfapiMsg->geran_rssi_request, &unpack_geran_rssi_request_value},
+    { NFAPI_NB_IOT_RSSI_REQUEST_TAG, &pNfapiMsg->nb_iot_rssi_request, &unpack_nb_iot_rssi_request_value},
+  };
+  int result = 0;
+  result = (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) &&
+            unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+
+  // Verify that the rat type and the tlv match
+  if(result == 1 &&
+      !((pNfapiMsg->rat_type == NFAPI_RAT_TYPE_LTE && pNfapiMsg->lte_rssi_request.tl.tag == NFAPI_LTE_RSSI_REQUEST_TAG) ||
+        (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_UTRAN && pNfapiMsg->utran_rssi_request.tl.tag == NFAPI_UTRAN_RSSI_REQUEST_TAG) ||
+        (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_GERAN && pNfapiMsg->geran_rssi_request.tl.tag == NFAPI_GERAN_RSSI_REQUEST_TAG) ||
+        (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_NB_IOT && pNfapiMsg->nb_iot_rssi_request.tl.tag == NFAPI_NB_IOT_RSSI_REQUEST_TAG))) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Mismatch RAT Type: %d and TAG value: 0x%04x \n", pNfapiMsg->rat_type, pNfapiMsg->lte_rssi_request.tl.tag);
+    result = 0;
+  }
+
+  return result;
+}
+
+static uint8_t unpack_rssi_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_rssi_response_t *pNfapiMsg = (nfapi_rssi_response_t *)msg;
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+          unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+
+static uint8_t unpack_rssi_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_rssi_indication_body_t *value = (nfapi_rssi_indication_body_t *)tlv;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_rssi, end) == 0)
+    return 0;
+
+  if(value->number_of_rssi <= NFAPI_MAX_RSSI) {
+    if(pullarrays16(ppReadPackedMsg, value->rssi, NFAPI_MAX_RSSI, value->number_of_rssi, end) == 0)
+      return 0;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More RSSI's than we can decode %d \n", value->number_of_rssi);
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_rssi_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_rssi_indication_t *pNfapiMsg = (nfapi_rssi_indication_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_RSSI_INDICATION_TAG, &pNfapiMsg->rssi_indication_body, &unpack_rssi_indication_value},
+  };
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+          unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_lte_cell_search_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_lte_cell_search_request_t *value = (nfapi_lte_cell_search_request_t *)tlv;
+
+  if(!(pull16(ppReadPackedMsg, &value->earfcn, end) &&
+       pull8(ppReadPackedMsg, &value->measurement_bandwidth, end) &&
+       pull8(ppReadPackedMsg, &value->exhaustive_search, end) &&
+       pull32(ppReadPackedMsg, &value->timeout, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_pci, end)))
+    return 0;
+
+  if(value->number_of_pci <= NFAPI_MAX_PCI_LIST) {
+    if(pullarray16(ppReadPackedMsg, value->pci, NFAPI_MAX_PCI_LIST, value->number_of_pci, end) == 0)
+      return 0;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More PCI's than we can decode %d \n", value->number_of_pci);
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_utran_cell_search_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_utran_cell_search_request_t *value = (nfapi_utran_cell_search_request_t *)tlv;
+
+  if(!(pull16(ppReadPackedMsg, &value->uarfcn, end) &&
+       pull8(ppReadPackedMsg, &value->exhaustive_search, end) &&
+       pull32(ppReadPackedMsg, &value->timeout, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_psc, end)))
+    return 0;
+
+  if(value->number_of_psc <= NFAPI_MAX_PSC_LIST) {
+    if(pullarray16(ppReadPackedMsg, value->psc, NFAPI_MAX_PSC_LIST, value->number_of_psc, end) == 0)
+      return 0;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More PSC's than we can decode %d \n", value->number_of_psc);
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_geran_cell_search_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_geran_cell_search_request_t *value = (nfapi_geran_cell_search_request_t *)tlv;
+
+  if(!(pull32(ppReadPackedMsg, &value->timeout, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_arfcn, end)))
+    return 0;
+
+  if(value->number_of_arfcn <= NFAPI_MAX_ARFCN_LIST) {
+    if(pullarray16(ppReadPackedMsg, value->arfcn, NFAPI_MAX_ARFCN_LIST, value->number_of_arfcn, end) == 0)
+      return 0;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More ARFCN's than we can decode %d \n", value->number_of_arfcn);
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nb_iot_cell_search_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nb_iot_cell_search_request_t *value = (nfapi_nb_iot_cell_search_request_t *)tlv;
+
+  if(!(pull16(ppReadPackedMsg, &value->earfcn, end) &&
+       pull8(ppReadPackedMsg, &value->ro_dl, end) &&
+       pull8(ppReadPackedMsg, &value->exhaustive_search, end) &&
+       pull32(ppReadPackedMsg, &value->timeout, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_pci, end)))
+    return 0;
+
+  if(value->number_of_pci <= NFAPI_MAX_PCI_LIST) {
+    if(pullarray16(ppReadPackedMsg, value->pci, NFAPI_MAX_PCI_LIST, value->number_of_pci, end) == 0)
+      return 0;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More PCI's than we can decode %d \n", value->number_of_pci);
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_cell_search_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_cell_search_request_t *pNfapiMsg = (nfapi_cell_search_request_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_LTE_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->lte_cell_search_request, &unpack_lte_cell_search_request_value},
+    { NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->utran_cell_search_request, &unpack_utran_cell_search_request_value},
+    { NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->geran_cell_search_request, &unpack_geran_cell_search_request_value},
+    { NFAPI_NB_IOT_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->nb_iot_cell_search_request, &unpack_nb_iot_cell_search_request_value},
+  };
+  int result = (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) &&
+                unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+
+  // Verify that the rat type and the tlv match
+  if(result == 1 &&
+      !((pNfapiMsg->rat_type == NFAPI_RAT_TYPE_LTE && pNfapiMsg->lte_cell_search_request.tl.tag == NFAPI_LTE_CELL_SEARCH_REQUEST_TAG) ||
+        (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_UTRAN && pNfapiMsg->utran_cell_search_request.tl.tag == NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG) ||
+        (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_GERAN && pNfapiMsg->geran_cell_search_request.tl.tag == NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG) ||
+        (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_NB_IOT && pNfapiMsg->nb_iot_cell_search_request.tl.tag == NFAPI_NB_IOT_CELL_SEARCH_REQUEST_TAG))) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Mismatch RAT Type: %d and TAG value: 0x%04x \n", pNfapiMsg->rat_type, pNfapiMsg->lte_cell_search_request.tl.tag);
+    result = 0;
+  }
+
+  return result;
+}
+
+static uint8_t unpack_cell_search_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_cell_search_response_t *pNfapiMsg = (nfapi_cell_search_response_t *)msg;
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+          unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_lte_cell_search_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_lte_cell_search_indication_t *value = (nfapi_lte_cell_search_indication_t *)tlv;
+  uint16_t idx = 0;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_lte_cells_found, end) == 0)
+    return 0;
+
+  if(value->number_of_lte_cells_found <= NFAPI_MAX_LTE_CELLS_FOUND) {
+    for(idx = 0; idx < value->number_of_lte_cells_found; ++idx) {
+      if(!(pull16(ppReadPackedMsg, &value->lte_found_cells[idx].pci, end) &&
+           pull8(ppReadPackedMsg, &value->lte_found_cells[idx].rsrp, end) &&
+           pull8(ppReadPackedMsg, &value->lte_found_cells[idx].rsrq, end) &&
+           pulls16(ppReadPackedMsg, &value->lte_found_cells[idx].frequency_offset, end)))
+        return 0;
+    }
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found LTE cells than we can decode %d \n", value->number_of_lte_cells_found);
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_utran_cell_search_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_utran_cell_search_indication_t *value = (nfapi_utran_cell_search_indication_t *)tlv;
+  uint16_t idx = 0;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_utran_cells_found, end) == 0)
+    return 0;
+
+  if(value->number_of_utran_cells_found <= NFAPI_MAX_UTRAN_CELLS_FOUND) {
+    for(idx = 0; idx < value->number_of_utran_cells_found; ++idx) {
+      if(!(pull16(ppReadPackedMsg, &value->utran_found_cells[idx].psc, end) &&
+           pull8(ppReadPackedMsg, &value->utran_found_cells[idx].rscp, end) &&
+           pull8(ppReadPackedMsg, &value->utran_found_cells[idx].ecno, end) &&
+           pulls16(ppReadPackedMsg, &value->utran_found_cells[idx].frequency_offset, end)))
+        return 0;
+    }
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found UTRAN cells than we can decode %d \n", value->number_of_utran_cells_found);
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_geran_cell_search_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_geran_cell_search_indication_t *value = (nfapi_geran_cell_search_indication_t *)tlv;
+  uint16_t idx = 0;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_gsm_cells_found, end) == 0)
+    return 0;
+
+  if(value->number_of_gsm_cells_found <= NFAPI_MAX_GSM_CELLS_FOUND) {
+    for(idx = 0; idx < value->number_of_gsm_cells_found; ++idx) {
+      if(!(pull16(ppReadPackedMsg, &value->gsm_found_cells[idx].arfcn, end) &&
+           pull8(ppReadPackedMsg, &value->gsm_found_cells[idx].bsic, end) &&
+           pull8(ppReadPackedMsg, &value->gsm_found_cells[idx].rxlev, end) &&
+           pull8(ppReadPackedMsg, &value->gsm_found_cells[idx].rxqual, end) &&
+           pulls16(ppReadPackedMsg, &value->gsm_found_cells[idx].frequency_offset, end) &&
+           pull32(ppReadPackedMsg, &value->gsm_found_cells[idx].sfn_offset, end)))
+        return 0;
+    }
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found GSM cells than we can decode %d \n", value->number_of_gsm_cells_found);
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nb_iot_cell_search_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nb_iot_cell_search_indication_t *value = (nfapi_nb_iot_cell_search_indication_t *)tlv;
+  uint16_t idx = 0;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_nb_iot_cells_found, end) == 0)
+    return 0;
+
+  if(value->number_of_nb_iot_cells_found <= NFAPI_MAX_NB_IOT_CELLS_FOUND) {
+    for(idx = 0; idx < value->number_of_nb_iot_cells_found; ++idx) {
+      if(!(pull16(ppReadPackedMsg, &value->nb_iot_found_cells[idx].pci, end) &&
+           pull8(ppReadPackedMsg, &value->nb_iot_found_cells[idx].rsrp, end) &&
+           pull8(ppReadPackedMsg, &value->nb_iot_found_cells[idx].rsrq, end) &&
+           pulls16(ppReadPackedMsg, &value->nb_iot_found_cells[idx].frequency_offset, end)))
+        return 0;
+    }
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found NB_IOT cells than we can decode %d \n", value->number_of_nb_iot_cells_found);
+    return 0;
+  }
 
-	return 1;
-}
-
-static uint8_t unpack_system_information_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_system_information_request_t *pNfapiMsg = (nfapi_system_information_request_t*)msg;
+  return 1;
+}
 
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->lte_system_information_request, &unpack_lte_system_information_request_value},
-		{ NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->utran_system_information_request, &unpack_utran_system_information_request_value},
-		{ NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->geran_system_information_request, &unpack_geran_system_information_request_value},
-		{ NFAPI_NB_IOT_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->nb_iot_system_information_request, &unpack_nb_iot_system_information_request_value},
-		{ NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, &unpack_opaque_data_value}
-	};
+static uint8_t unpack_cell_search_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_cell_search_indication_t *pNfapiMsg = (nfapi_cell_search_indication_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_LTE_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->lte_cell_search_indication, &unpack_lte_cell_search_indication_value},
+    { NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->utran_cell_search_indication, &unpack_utran_cell_search_indication_value},
+    { NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->geran_cell_search_indication, &unpack_geran_cell_search_indication_value},
+    { NFAPI_PNF_CELL_SEARCH_STATE_TAG, &pNfapiMsg->pnf_cell_search_state, &unpack_opaque_data_value},
+    { NFAPI_NB_IOT_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->nb_iot_cell_search_indication, &unpack_nb_iot_cell_search_indication_value},
+  };
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+          unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_lte_broadcast_detect_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_lte_broadcast_detect_request_t *value = (nfapi_lte_broadcast_detect_request_t *)tlv;
+  return (pull16(ppReadPackedMsg, &value->earfcn, end) &&
+          pull16(ppReadPackedMsg, &value->pci, end) &&
+          pull32(ppReadPackedMsg, &value->timeout, end));
+}
+
+static uint8_t unpack_utran_broadcast_detect_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_utran_broadcast_detect_request_t *value = (nfapi_utran_broadcast_detect_request_t *)tlv;
+  return (pull16(ppReadPackedMsg, &value->uarfcn, end) &&
+          pull16(ppReadPackedMsg, &value->psc, end) &&
+          pull32(ppReadPackedMsg, &value->timeout, end));
+}
+
+static uint8_t unpack_nb_iot_broadcast_detect_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nb_iot_broadcast_detect_request_t *value = (nfapi_nb_iot_broadcast_detect_request_t *)tlv;
+  return (pull16(ppReadPackedMsg, &value->earfcn, end) &&
+          pull8(ppReadPackedMsg, &value->ro_dl, end) &&
+          pull16(ppReadPackedMsg, &value->pci, end) &&
+          pull32(ppReadPackedMsg, &value->timeout, end));
+}
+
+static uint8_t unpack_broadcast_detect_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_broadcast_detect_request_t *pNfapiMsg = (nfapi_broadcast_detect_request_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_LTE_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->lte_broadcast_detect_request, &unpack_lte_broadcast_detect_request_value},
+    { NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->utran_broadcast_detect_request, &unpack_utran_broadcast_detect_request_value},
+    { NFAPI_PNF_CELL_SEARCH_STATE_TAG, &pNfapiMsg->pnf_cell_search_state, &unpack_opaque_data_value},
+    { NFAPI_NB_IOT_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->nb_iot_broadcast_detect_request, &unpack_nb_iot_broadcast_detect_request_value}
+  };
+  return (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) &&
+          unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_broadcast_detect_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_broadcast_detect_response_t *pNfapiMsg = (nfapi_broadcast_detect_response_t *)msg;
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+          unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_lte_broadcast_detect_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_lte_broadcast_detect_indication_t *value = (nfapi_lte_broadcast_detect_indication_t *)tlv;
+
+  if(!(pull8(ppReadPackedMsg, &value->number_of_tx_antenna, end) &&
+       pull16(ppReadPackedMsg, &value->mib_length, end)))
+    return 0;
+
+  if(value->mib_length > NFAPI_MAX_MIB_LENGTH) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "MIB too long %d \n", value->mib_length);
+    return 0;
+  }
+
+  return (pullarray8(ppReadPackedMsg, value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, end) &&
+          pull32(ppReadPackedMsg, &value->sfn_offset, end));
+}
+
+static uint8_t unpack_utran_broadcast_detect_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_utran_broadcast_detect_indication_t *value = (nfapi_utran_broadcast_detect_indication_t *)tlv;
 
+  if(pull16(ppReadPackedMsg, &value->mib_length, end) == 0)
+    return 0;
 
-	int result = (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) &&
-				  unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+  if(value->mib_length > NFAPI_MAX_MIB_LENGTH) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "MIB too long %d \n", value->mib_length);
+    return 0;
+  }
 
-	// Verify that the rat type and the tlv match
-	if(result == 1 &&
-	   !((pNfapiMsg->rat_type == NFAPI_RAT_TYPE_LTE && pNfapiMsg->lte_system_information_request.tl.tag == NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG) ||
-	    (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_UTRAN && pNfapiMsg->utran_system_information_request.tl.tag == NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG) ||
-	    (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_GERAN && pNfapiMsg->geran_system_information_request.tl.tag == NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG)))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Mismatch RAT Type: %d and TAG value: 0x%04x \n", pNfapiMsg->rat_type, pNfapiMsg->lte_system_information_request.tl.tag);
-		result = 0;
-	}
-	
-	return result;
+  return (pullarray8(ppReadPackedMsg, value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, end) &&
+          pull32(ppReadPackedMsg, &value->sfn_offset, end));
 }
 
-static uint8_t unpack_system_information_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_system_information_response_t *pNfapiMsg = (nfapi_system_information_response_t*)msg;
+static uint8_t unpack_nb_iot_broadcast_detect_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nb_iot_broadcast_detect_indication_t *value = (nfapi_nb_iot_broadcast_detect_indication_t *)tlv;
+
+  if(!(pull8(ppReadPackedMsg, &value->number_of_tx_antenna, end) &&
+       pull16(ppReadPackedMsg, &value->mib_length, end)))
+    return 0;
 
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
+  if(value->mib_length > NFAPI_MAX_MIB_LENGTH) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "MIB too long %d \n", value->mib_length);
+    return 0;
+  }
 
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+  return (pullarray8(ppReadPackedMsg, value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, end) &&
+          pull32(ppReadPackedMsg, &value->sfn_offset, end));
 }
 
-static uint8_t unpack_utran_system_information_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_utran_system_information_indication_t* value = (nfapi_utran_system_information_indication_t*)tlv;
+static uint8_t unpack_broadcast_detect_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_broadcast_detect_indication_t *pNfapiMsg = (nfapi_broadcast_detect_indication_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->lte_broadcast_detect_indication, &unpack_lte_broadcast_detect_indication_value},
+    { NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->utran_broadcast_detect_indication, &unpack_utran_broadcast_detect_indication_value},
+    { NFAPI_NB_IOT_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->nb_iot_broadcast_detect_indication, &unpack_nb_iot_broadcast_detect_indication_value},
+    { NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, &unpack_opaque_data_value}
+  };
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+          unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
 
-	if(pull16(ppReadPackedMsg, &value->sib_length, end) == 0)
-		return 0;
+static uint8_t unpack_lte_system_information_schedule_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_lte_system_information_schedule_request_t *value = (nfapi_lte_system_information_schedule_request_t *)tlv;
+  return (pull16(ppReadPackedMsg, &value->earfcn, end) &&
+          pull16(ppReadPackedMsg, &value->pci, end) &&
+          pull16(ppReadPackedMsg, &value->downlink_channel_bandwidth, end) &&
+          pull8(ppReadPackedMsg, &value->phich_configuration, end) &&
+          pull8(ppReadPackedMsg, &value->number_of_tx_antenna, end) &&
+          pull8(ppReadPackedMsg, &value->retry_count, end) &&
+          pull32(ppReadPackedMsg, &value->timeout, end));
+}
 
-	if(value->sib_length > NFAPI_MAX_SIB_LENGTH)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "SIB too long %d \n", value->sib_length);
-		return 0;
-	}
-	
-	if(pullarray8(ppReadPackedMsg, value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, end) == 0)
-		return 0;
+static uint8_t unpack_nb_iot_system_information_schedule_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nb_iot_system_information_schedule_request_t *value = (nfapi_nb_iot_system_information_schedule_request_t *)tlv;
+  return (pull16(ppReadPackedMsg, &value->earfcn, end) &&
+          pull8(ppReadPackedMsg, &value->ro_dl, end) &&
+          pull16(ppReadPackedMsg, &value->pci, end) &&
+          pull8(ppReadPackedMsg, &value->scheduling_info_sib1_nb, end) &&
+          pull32(ppReadPackedMsg, &value->timeout, end));
+}
+
+static uint8_t unpack_system_information_schedule_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_system_information_schedule_request_t *pNfapiMsg = (nfapi_system_information_schedule_request_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &pNfapiMsg->lte_system_information_schedule_request, &unpack_lte_system_information_schedule_request_value},
+    { NFAPI_NB_IOT_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &pNfapiMsg->nb_iot_system_information_schedule_request, &unpack_nb_iot_system_information_schedule_request_value},
+    { NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, &unpack_opaque_data_value}
+  };
+  return (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) &&
+          unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_system_information_schedule_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_system_information_schedule_response_t *pNfapiMsg = (nfapi_system_information_schedule_response_t *)msg;
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+          unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_lte_system_information_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_lte_system_information_indication_t *value = (nfapi_lte_system_information_indication_t *)tlv;
+
+  if(!(pull8(ppReadPackedMsg, &value->sib_type, end) &&
+       pull16(ppReadPackedMsg, &value->sib_length, end)))
+    return 0;
+
+  if(value->sib_length > NFAPI_MAX_SIB_LENGTH) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "SIB too long %d \n", value->sib_length);
+    return 0;
+  }
+
+  if(pullarray8(ppReadPackedMsg, value->sib, NFAPI_MAX_SIB_LENGTH,  value->sib_length, end) == 0)
+    return 0;
+
+  return 1;
+}
 
-	return 1;
-}
-
-static uint8_t unpack_geran_system_information_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_geran_system_information_indication_t* value = (nfapi_geran_system_information_indication_t*)tlv;
-
-	if(pull16(ppReadPackedMsg, &value->si_length, end) == 0)
-		return 0;
+static uint8_t unpack_nb_iot_system_information_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nb_iot_system_information_indication_t *value = (nfapi_nb_iot_system_information_indication_t *)tlv;
 
-	if(value->si_length > NFAPI_MAX_SI_LENGTH)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "SIB too long %d \n", value->si_length);
-		return 0;
-	}
+  if(!(pull8(ppReadPackedMsg, &value->sib_type, end) &&
+       pull16(ppReadPackedMsg, &value->sib_length, end)))
+    return 0;
 
-	if(pullarray8(ppReadPackedMsg, value->si, NFAPI_MAX_SI_LENGTH, value->si_length, end) == 0)
-		return 0;
+  if(value->sib_length > NFAPI_MAX_SIB_LENGTH) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "SIB too long %d \n", value->sib_length);
+    return 0;
+  }
 
-	return 1;
+  if(pullarray8(ppReadPackedMsg, value->sib, NFAPI_MAX_SIB_LENGTH,  value->sib_length, end) == 0)
+    return 0;
+
+  return 1;
+}
+
+static uint8_t unpack_system_information_schedule_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_system_information_schedule_indication_t *pNfapiMsg = (nfapi_system_information_schedule_indication_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->lte_system_information_indication, &unpack_lte_system_information_indication_value},
+    { NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->nb_iot_system_information_indication, &unpack_nb_iot_system_information_indication_value},
+  };
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+          unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_lte_system_information_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_lte_system_information_request_t *value = (nfapi_lte_system_information_request_t *)tlv;
+  uint16_t idx = 0;
+
+  if(!(pull16(ppReadPackedMsg, &value->earfcn, end) &&
+       pull16(ppReadPackedMsg, &value->pci, end) &&
+       pull16(ppReadPackedMsg, &value->downlink_channel_bandwidth, end) &&
+       pull8(ppReadPackedMsg, &value->phich_configuration, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_tx_antenna, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_si_periodicity, end)))
+    return 0;
+
+  if(value->number_of_si_periodicity > NFAPI_MAX_SI_PERIODICITY) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found SI periodicity than we can decode %d \n", value->number_of_si_periodicity);
+    return 0;
+  }
+
+  for(idx = 0; idx < value->number_of_si_periodicity; ++idx) {
+    if(!(pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_periodicity, end) &&
+         pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_index, end)))
+      return 0;
+  }
+
+  if(!(pull8(ppReadPackedMsg, &value->si_window_length, end) &&
+       pull32(ppReadPackedMsg, &value->timeout, end)))
+    return 0;
+
+  return 1;
 }
 
-static uint8_t unpack_system_information_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_system_information_indication_t *pNfapiMsg = (nfapi_system_information_indication_t*)msg;
+static uint8_t unpack_utran_system_information_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_utran_system_information_request_t *value = (nfapi_utran_system_information_request_t *)tlv;
+  return (pull16(ppReadPackedMsg, &value->uarfcn, end) &&
+          pull16(ppReadPackedMsg, &value->psc, end) &&
+          pull32(ppReadPackedMsg, &value->timeout, end));
+}
+
+static uint8_t unpack_geran_system_information_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_geran_system_information_request_t *value = (nfapi_geran_system_information_request_t *)tlv;
+  return (pull16(ppReadPackedMsg, &value->arfcn, end) &&
+          pull8(ppReadPackedMsg, &value->bsic, end) &&
+          pull32(ppReadPackedMsg, &value->timeout, end));
+}
+
+static uint8_t unpack_nb_iot_system_information_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nb_iot_system_information_request_t *value = (nfapi_nb_iot_system_information_request_t *)tlv;
+  uint16_t idx = 0;
+
+  if(!(pull16(ppReadPackedMsg, &value->earfcn, end) &&
+       pull8(ppReadPackedMsg, &value->ro_dl, end) &&
+       pull16(ppReadPackedMsg, &value->pci, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_si_periodicity, end)))
+    return 0;
 
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->lte_system_information_indication, &unpack_lte_system_information_indication_value},
-		{ NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->utran_system_information_indication, &unpack_utran_system_information_indication_value},
-		{ NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->geran_system_information_indication, &unpack_geran_system_information_indication_value},
-		{ NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->nb_iot_system_information_indication, &unpack_nb_iot_system_information_indication_value},
-	};
+  if(value->number_of_si_periodicity > NFAPI_MAX_SI_PERIODICITY) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found SI periodicity than we can decode %d \n", value->number_of_si_periodicity);
+    return 0;
+  }
 
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+  for(idx = 0; idx < value->number_of_si_periodicity; ++idx) {
+    if(!(pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_periodicity, end) &&
+         pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_repetition_pattern, end) &&
+         pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_tb_size, end) &&
+         pull8(ppReadPackedMsg, &value->si_periodicity[idx].number_of_si_index, end)))
+      return 0;
 
+    uint8_t si_idx;
+
+    for(si_idx = 0; si_idx < value->si_periodicity[idx].number_of_si_index; ++si_idx) {
+      if(!(pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_index[si_idx], end)))
+        return 0;
+    }
+  }
+
+  if(!(pull8(ppReadPackedMsg, &value->si_window_length, end) &&
+       pull32(ppReadPackedMsg, &value->timeout, end)))
+    return 0;
+
+  return 1;
 }
 
-static uint8_t unpack_nmm_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nmm_stop_request_t *pNfapiMsg = (nfapi_nmm_stop_request_t*)msg;
+static uint8_t unpack_system_information_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_system_information_request_t *pNfapiMsg = (nfapi_system_information_request_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->lte_system_information_request, &unpack_lte_system_information_request_value},
+    { NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->utran_system_information_request, &unpack_utran_system_information_request_value},
+    { NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->geran_system_information_request, &unpack_geran_system_information_request_value},
+    { NFAPI_NB_IOT_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->nb_iot_system_information_request, &unpack_nb_iot_system_information_request_value},
+    { NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, &unpack_opaque_data_value}
+  };
+  int result = (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) &&
+                unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
 
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
+  // Verify that the rat type and the tlv match
+  if(result == 1 &&
+      !((pNfapiMsg->rat_type == NFAPI_RAT_TYPE_LTE && pNfapiMsg->lte_system_information_request.tl.tag == NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG) ||
+        (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_UTRAN && pNfapiMsg->utran_system_information_request.tl.tag == NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG) ||
+        (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_GERAN && pNfapiMsg->geran_system_information_request.tl.tag == NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG))) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Mismatch RAT Type: %d and TAG value: 0x%04x \n", pNfapiMsg->rat_type, pNfapiMsg->lte_system_information_request.tl.tag);
+    result = 0;
+  }
 
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension);
+  return result;
 }
 
-static uint8_t unpack_nmm_stop_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nmm_stop_response_t *pNfapiMsg = (nfapi_nmm_stop_response_t*)msg;
+static uint8_t unpack_system_information_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_system_information_response_t *pNfapiMsg = (nfapi_system_information_response_t *)msg;
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+          unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_utran_system_information_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_utran_system_information_indication_t *value = (nfapi_utran_system_information_indication_t *)tlv;
+
+  if(pull16(ppReadPackedMsg, &value->sib_length, end) == 0)
+    return 0;
 
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
+  if(value->sib_length > NFAPI_MAX_SIB_LENGTH) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "SIB too long %d \n", value->sib_length);
+    return 0;
+  }
 
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+  if(pullarray8(ppReadPackedMsg, value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, end) == 0)
+    return 0;
+
+  return 1;
 }
 
+static uint8_t unpack_geran_system_information_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_geran_system_information_indication_t *value = (nfapi_geran_system_information_indication_t *)tlv;
+
+  if(pull16(ppReadPackedMsg, &value->si_length, end) == 0)
+    return 0;
 
-static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen)
-{
-	int retLen = 0;
+  if(value->si_length > NFAPI_MAX_SI_LENGTH) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "SIB too long %d \n", value->si_length);
+    return 0;
+  }
 
-	switch (msgId)
-	{
-		case NFAPI_RSSI_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_rssi_request_t))
-				retLen = sizeof(nfapi_rssi_request_t);
-			break;
+  if(pullarray8(ppReadPackedMsg, value->si, NFAPI_MAX_SI_LENGTH, value->si_length, end) == 0)
+    return 0;
 
-		case NFAPI_RSSI_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_rssi_response_t))
-				retLen = sizeof(nfapi_rssi_response_t);
-			break;
+  return 1;
+}
+
+static uint8_t unpack_system_information_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_system_information_indication_t *pNfapiMsg = (nfapi_system_information_indication_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->lte_system_information_indication, &unpack_lte_system_information_indication_value},
+    { NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->utran_system_information_indication, &unpack_utran_system_information_indication_value},
+    { NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->geran_system_information_indication, &unpack_geran_system_information_indication_value},
+    { NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->nb_iot_system_information_indication, &unpack_nb_iot_system_information_indication_value},
+  };
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+          unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
 
-		case NFAPI_RSSI_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_rssi_indication_t))
-				retLen = sizeof(nfapi_rssi_indication_t);
-			break;
-
-		case NFAPI_CELL_SEARCH_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_cell_search_request_t))
-				retLen = sizeof(nfapi_cell_search_request_t);
-			break;
-
-		case NFAPI_CELL_SEARCH_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_cell_search_response_t))
-				retLen = sizeof(nfapi_cell_search_response_t);
-			break;
-
-		case NFAPI_CELL_SEARCH_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_cell_search_indication_t))
-				retLen = sizeof(nfapi_cell_search_indication_t);
-			break;
-
-		case NFAPI_BROADCAST_DETECT_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_broadcast_detect_request_t))
-				retLen = sizeof(nfapi_broadcast_detect_request_t);
-			break;
-
-		case NFAPI_BROADCAST_DETECT_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_broadcast_detect_response_t))
-				retLen = sizeof(nfapi_broadcast_detect_response_t);
-			break;
-
-		case NFAPI_BROADCAST_DETECT_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_broadcast_detect_indication_t))
-				retLen = sizeof(nfapi_broadcast_detect_indication_t);
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_system_information_schedule_request_t))
-				retLen = sizeof(nfapi_system_information_schedule_request_t);
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_system_information_schedule_response_t))
-				retLen = sizeof(nfapi_system_information_schedule_response_t);
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_system_information_schedule_indication_t))
-				retLen = sizeof(nfapi_system_information_schedule_indication_t);
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_system_information_request_t))
-				retLen = sizeof(nfapi_system_information_request_t);
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_system_information_response_t))
-				retLen = sizeof(nfapi_system_information_response_t);
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_system_information_indication_t))
-				retLen = sizeof(nfapi_system_information_indication_t);
-			break;
-
-		case NFAPI_NMM_STOP_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nmm_stop_request_t))
-				retLen = sizeof(nfapi_nmm_stop_request_t);
-			break;
-
-		case NFAPI_NMM_STOP_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_nmm_stop_response_t))
-				retLen = sizeof(nfapi_nmm_stop_response_t);
-			break;
-
-		default:
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId);
-			break;
-	}
-
-	return retLen;
-}
-
-int nfapi_p4_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
-	uint8_t *end = pPackedBuf + packedBufLen;
-	uint8_t *pWritePackedMessage = pPackedBuf;
-	uint8_t *pPackedLengthField = &pWritePackedMessage[4];
-	uint32_t packedMsgLen;
-	uint16_t packedMsgLen16;
-
-	if (pMessageBuf == NULL || pPackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P4 Pack supplied pointers are null\n");
-		return -1;
-	}
-
-	// process the header
-	if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) &&
-		 push16(pMessageHeader->message_id, &pWritePackedMessage, end) &&
-		 push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, end) &&
-		 push16(pMessageHeader->spare, &pWritePackedMessage, end)))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to pack p4 message header\n");
-		return -1;
-	}
-
-	// look for the specific message
-	uint8_t result = 0;
-	switch (pMessageHeader->message_id)
-	{
-		case NFAPI_RSSI_REQUEST:
-			result = pack_rssi_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_RSSI_RESPONSE:
-			result = pack_rssi_response(pMessageHeader, &pWritePackedMessage,  end,config);
-			break;
-
-		case NFAPI_RSSI_INDICATION:
-			result = pack_rssi_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_CELL_SEARCH_REQUEST:
-			result = pack_cell_search_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_CELL_SEARCH_RESPONSE:
-			result = pack_cell_search_response(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_CELL_SEARCH_INDICATION:
-			result = pack_cell_search_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_BROADCAST_DETECT_REQUEST:
-			result = pack_broadcast_detect_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_BROADCAST_DETECT_RESPONSE:
-			result = pack_broadcast_detect_response(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_BROADCAST_DETECT_INDICATION:
-			result = pack_broadcast_detect_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST:
-			result = pack_system_information_schedule_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE:
-			result = pack_system_information_schedule_response(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION:
-			result = pack_system_information_schedule_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_REQUEST:
-			result = pack_system_information_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_RESPONSE:
-			result = pack_system_information_response(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_INDICATION:
-			result = pack_system_information_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_NMM_STOP_REQUEST:
-			result = pack_nmm_stop_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_NMM_STOP_RESPONSE:
-			result = pack_nmm_stop_response(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		default:
-			{
-				if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
-				   pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MIN)
-				{
-					if(config && config->pack_p4_p5_vendor_extension)
-					{
-						result =(config->pack_p4_p5_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config);
-					}
-					else
-					{
-						NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve encoder provided\n", __FUNCTION__, pMessageHeader->message_id);
-					}
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
-				}
-			}
-			break;
-	}	
-	
-	// return the packed length
-	if(result == 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Result is 0\n");
-		return -1;
-	}
-
-
-	// check for a valid message length
-	packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pWritePackedMessage);
-	if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
-		return -1;
-	}
-	else
-	{
-		packedMsgLen16 = (uint16_t)packedMsgLen;
-	}
-
-	// Update the message length in the header
-	if(push16(packedMsgLen16, &pPackedLengthField, end) == 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to pack p4 message header lengt\n");
-		return -1;
-	}
-
-	return (packedMsgLen);
+static uint8_t unpack_nmm_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nmm_stop_request_t *pNfapiMsg = (nfapi_nmm_stop_request_t *)msg;
+  return unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension);
+}
 
+static uint8_t unpack_nmm_stop_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nmm_stop_response_t *pNfapiMsg = (nfapi_nmm_stop_response_t *)msg;
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+          unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+
+static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen) {
+  int retLen = 0;
+
+  switch (msgId) {
+    case NFAPI_RSSI_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_rssi_request_t))
+        retLen = sizeof(nfapi_rssi_request_t);
+
+      break;
+
+    case NFAPI_RSSI_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_rssi_response_t))
+        retLen = sizeof(nfapi_rssi_response_t);
+
+      break;
+
+    case NFAPI_RSSI_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_rssi_indication_t))
+        retLen = sizeof(nfapi_rssi_indication_t);
+
+      break;
+
+    case NFAPI_CELL_SEARCH_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_cell_search_request_t))
+        retLen = sizeof(nfapi_cell_search_request_t);
+
+      break;
+
+    case NFAPI_CELL_SEARCH_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_cell_search_response_t))
+        retLen = sizeof(nfapi_cell_search_response_t);
+
+      break;
+
+    case NFAPI_CELL_SEARCH_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_cell_search_indication_t))
+        retLen = sizeof(nfapi_cell_search_indication_t);
+
+      break;
+
+    case NFAPI_BROADCAST_DETECT_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_broadcast_detect_request_t))
+        retLen = sizeof(nfapi_broadcast_detect_request_t);
+
+      break;
+
+    case NFAPI_BROADCAST_DETECT_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_broadcast_detect_response_t))
+        retLen = sizeof(nfapi_broadcast_detect_response_t);
+
+      break;
+
+    case NFAPI_BROADCAST_DETECT_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_broadcast_detect_indication_t))
+        retLen = sizeof(nfapi_broadcast_detect_indication_t);
+
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_system_information_schedule_request_t))
+        retLen = sizeof(nfapi_system_information_schedule_request_t);
+
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_system_information_schedule_response_t))
+        retLen = sizeof(nfapi_system_information_schedule_response_t);
+
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_system_information_schedule_indication_t))
+        retLen = sizeof(nfapi_system_information_schedule_indication_t);
+
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_system_information_request_t))
+        retLen = sizeof(nfapi_system_information_request_t);
+
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_system_information_response_t))
+        retLen = sizeof(nfapi_system_information_response_t);
+
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_system_information_indication_t))
+        retLen = sizeof(nfapi_system_information_indication_t);
+
+      break;
+
+    case NFAPI_NMM_STOP_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nmm_stop_request_t))
+        retLen = sizeof(nfapi_nmm_stop_request_t);
+
+      break;
+
+    case NFAPI_NMM_STOP_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_nmm_stop_response_t))
+        retLen = sizeof(nfapi_nmm_stop_response_t);
+
+      break;
+
+    default:
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId);
+      break;
+  }
+
+  return retLen;
+}
+
+int nfapi_p4_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
+  uint8_t *end = pPackedBuf + packedBufLen;
+  uint8_t *pWritePackedMessage = pPackedBuf;
+  uint8_t *pPackedLengthField = &pWritePackedMessage[4];
+  uint32_t packedMsgLen;
+  uint16_t packedMsgLen16;
+
+  if (pMessageBuf == NULL || pPackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P4 Pack supplied pointers are null\n");
+    return -1;
+  }
+
+  // process the header
+  if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) &&
+       push16(pMessageHeader->message_id, &pWritePackedMessage, end) &&
+       push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, end) &&
+       push16(pMessageHeader->spare, &pWritePackedMessage, end))) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to pack p4 message header\n");
+    return -1;
+  }
+
+  // look for the specific message
+  uint8_t result = 0;
+
+  switch (pMessageHeader->message_id) {
+    case NFAPI_RSSI_REQUEST:
+      result = pack_rssi_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_RSSI_RESPONSE:
+      result = pack_rssi_response(pMessageHeader, &pWritePackedMessage,  end,config);
+      break;
+
+    case NFAPI_RSSI_INDICATION:
+      result = pack_rssi_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_CELL_SEARCH_REQUEST:
+      result = pack_cell_search_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_CELL_SEARCH_RESPONSE:
+      result = pack_cell_search_response(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_CELL_SEARCH_INDICATION:
+      result = pack_cell_search_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_BROADCAST_DETECT_REQUEST:
+      result = pack_broadcast_detect_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_BROADCAST_DETECT_RESPONSE:
+      result = pack_broadcast_detect_response(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_BROADCAST_DETECT_INDICATION:
+      result = pack_broadcast_detect_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST:
+      result = pack_system_information_schedule_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE:
+      result = pack_system_information_schedule_response(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION:
+      result = pack_system_information_schedule_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_REQUEST:
+      result = pack_system_information_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_RESPONSE:
+      result = pack_system_information_response(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_INDICATION:
+      result = pack_system_information_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_NMM_STOP_REQUEST:
+      result = pack_nmm_stop_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_NMM_STOP_RESPONSE:
+      result = pack_nmm_stop_response(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    default: {
+      if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+          pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MIN) {
+        if(config && config->pack_p4_p5_vendor_extension) {
+          result =(config->pack_p4_p5_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve encoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+      }
+    }
+    break;
+  }
+
+  // return the packed length
+  if(result == 0) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Result is 0\n");
+    return -1;
+  }
+
+  // check for a valid message length
+  packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pWritePackedMessage);
+
+  if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
+    return -1;
+  } else {
+    packedMsgLen16 = (uint16_t)packedMsgLen;
+  }
+
+  // Update the message length in the header
+  if(push16(packedMsgLen16, &pPackedLengthField, end) == 0) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to pack p4 message header lengt\n");
+    return -1;
+  }
+
+  return (packedMsgLen);
 }
 
 // Main unpack functions - public
 
-int nfapi_p4_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
-	uint8_t *pReadPackedMessage = pMessageBuf;
-	uint8_t *end = pMessageBuf + messageBufLen;
-
-	if (pMessageBuf == NULL || pUnpackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P4 header unpack supplied pointers are null\n");
-		return -1;
-	}
-
-	if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
-		return -1;
-	}
-
-	// process the headei
-	if (pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
-		pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-		pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-		pull16(&pReadPackedMessage, &pMessageHeader->spare, end))
-		return -1;
-
-	return 0;
-}
-
-int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config)
-{
-	int result = 0;
-	nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
-	uint8_t *pReadPackedMessage = pMessageBuf;
-	uint8_t *end = pMessageBuf + messageBufLen;
-
-	if (pMessageBuf == NULL || pUnpackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P4 unpack supplied pointers are null\n");
-		return -1;
-	}
-
-	if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P4 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
-		return -1;
-	}
-
-	// clean the supplied buffer for - tag value blanking
-	(void)memset(pUnpackedBuf, 0, unpackedBufLen);
-
-	// process the header
-	if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
-	 	 pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->spare, end)))
-		return -1;
-
-	// look for the specific message
-	switch (pMessageHeader->message_id)
-	{
-		case NFAPI_RSSI_REQUEST:
-			if (check_unpack_length(NFAPI_RSSI_REQUEST, unpackedBufLen))
-				result = unpack_rssi_request(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_RSSI_RESPONSE:
-			if (check_unpack_length(NFAPI_RSSI_RESPONSE, unpackedBufLen))
-				result = unpack_rssi_response(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_RSSI_INDICATION:
-			if (check_unpack_length(NFAPI_RSSI_INDICATION, unpackedBufLen))
-				result = unpack_rssi_indication(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_CELL_SEARCH_REQUEST:
-			if (check_unpack_length(NFAPI_CELL_SEARCH_REQUEST, unpackedBufLen))
-				result = unpack_cell_search_request(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_CELL_SEARCH_RESPONSE:
-			if (check_unpack_length(NFAPI_CELL_SEARCH_RESPONSE, unpackedBufLen))
-				result = unpack_cell_search_response(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_CELL_SEARCH_INDICATION:
-			if (check_unpack_length(NFAPI_CELL_SEARCH_INDICATION, unpackedBufLen))
-				result = unpack_cell_search_indication(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_BROADCAST_DETECT_REQUEST:
-			if (check_unpack_length(NFAPI_BROADCAST_DETECT_REQUEST, unpackedBufLen))
-				result = unpack_broadcast_detect_request(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_BROADCAST_DETECT_RESPONSE:
-			if (check_unpack_length(NFAPI_BROADCAST_DETECT_RESPONSE, unpackedBufLen))
-				result = unpack_broadcast_detect_response(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_BROADCAST_DETECT_INDICATION:
-			if (check_unpack_length(NFAPI_BROADCAST_DETECT_INDICATION, unpackedBufLen))
-				result = unpack_broadcast_detect_indication(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST:
-			if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST, unpackedBufLen))
-				result = unpack_system_information_schedule_request(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-			
-		case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE:
-			if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE, unpackedBufLen))
-				result = unpack_system_information_schedule_response(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION:
-			if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION, unpackedBufLen))
-				result = unpack_system_information_schedule_indication(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_REQUEST:
-			if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_REQUEST, unpackedBufLen))
-				result = unpack_system_information_request(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_RESPONSE:
-			if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_RESPONSE, unpackedBufLen))
-				result = unpack_system_information_response(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result =  -1;
-			break;
-
-		case NFAPI_SYSTEM_INFORMATION_INDICATION:
-			if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_INDICATION, unpackedBufLen))
-				result = unpack_system_information_indication(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result =  -1;
-			break;
-
-		case NFAPI_NMM_STOP_REQUEST:
-			if (check_unpack_length(NFAPI_NMM_STOP_REQUEST, unpackedBufLen))
-				result = unpack_nmm_stop_request(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		case NFAPI_NMM_STOP_RESPONSE:
-			if (check_unpack_length(NFAPI_NMM_STOP_RESPONSE, unpackedBufLen))
-				result = unpack_nmm_stop_response(&pReadPackedMessage, end , pMessageHeader, config);
-			else
-				result = -1;
-			break;
-
-		default:
-			if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && 
-			   pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
-			{
-				if(config && config->unpack_p4_p5_vendor_extension)
-				{
-					result = (config->unpack_p4_p5_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
-				}
-			}
-			else
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown P4 message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
-			}
-			break;
-	}
-
-	if(result == 0)
-		return -1;
-
-	return result;
+int nfapi_p4_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+  uint8_t *end = pMessageBuf + messageBufLen;
+
+  if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P4 header unpack supplied pointers are null\n");
+    return -1;
+  }
+
+  if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t)) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+    return -1;
+  }
+
+  // process the headei
+  if (pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
+      pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
+      pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
+      pull16(&pReadPackedMessage, &pMessageHeader->spare, end))
+    return -1;
+
+  return 0;
+}
+
+int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t *config) {
+  int result = 0;
+  nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+  uint8_t *end = pMessageBuf + messageBufLen;
+
+  if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P4 unpack supplied pointers are null\n");
+    return -1;
+  }
+
+  if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t)) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P4 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+    return -1;
+  }
+
+  // clean the supplied buffer for - tag value blanking
+  (void)memset(pUnpackedBuf, 0, unpackedBufLen);
+
+  // process the header
+  if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
+       pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
+       pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
+       pull16(&pReadPackedMessage, &pMessageHeader->spare, end)))
+    return -1;
+
+  // look for the specific message
+  switch (pMessageHeader->message_id) {
+    case NFAPI_RSSI_REQUEST:
+      if (check_unpack_length(NFAPI_RSSI_REQUEST, unpackedBufLen))
+        result = unpack_rssi_request(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_RSSI_RESPONSE:
+      if (check_unpack_length(NFAPI_RSSI_RESPONSE, unpackedBufLen))
+        result = unpack_rssi_response(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_RSSI_INDICATION:
+      if (check_unpack_length(NFAPI_RSSI_INDICATION, unpackedBufLen))
+        result = unpack_rssi_indication(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_CELL_SEARCH_REQUEST:
+      if (check_unpack_length(NFAPI_CELL_SEARCH_REQUEST, unpackedBufLen))
+        result = unpack_cell_search_request(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_CELL_SEARCH_RESPONSE:
+      if (check_unpack_length(NFAPI_CELL_SEARCH_RESPONSE, unpackedBufLen))
+        result = unpack_cell_search_response(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_CELL_SEARCH_INDICATION:
+      if (check_unpack_length(NFAPI_CELL_SEARCH_INDICATION, unpackedBufLen))
+        result = unpack_cell_search_indication(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_BROADCAST_DETECT_REQUEST:
+      if (check_unpack_length(NFAPI_BROADCAST_DETECT_REQUEST, unpackedBufLen))
+        result = unpack_broadcast_detect_request(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_BROADCAST_DETECT_RESPONSE:
+      if (check_unpack_length(NFAPI_BROADCAST_DETECT_RESPONSE, unpackedBufLen))
+        result = unpack_broadcast_detect_response(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_BROADCAST_DETECT_INDICATION:
+      if (check_unpack_length(NFAPI_BROADCAST_DETECT_INDICATION, unpackedBufLen))
+        result = unpack_broadcast_detect_indication(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST:
+      if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST, unpackedBufLen))
+        result = unpack_system_information_schedule_request(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE:
+      if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE, unpackedBufLen))
+        result = unpack_system_information_schedule_response(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION:
+      if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION, unpackedBufLen))
+        result = unpack_system_information_schedule_indication(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_REQUEST:
+      if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_REQUEST, unpackedBufLen))
+        result = unpack_system_information_request(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_RESPONSE:
+      if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_RESPONSE, unpackedBufLen))
+        result = unpack_system_information_response(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result =  -1;
+
+      break;
+
+    case NFAPI_SYSTEM_INFORMATION_INDICATION:
+      if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_INDICATION, unpackedBufLen))
+        result = unpack_system_information_indication(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result =  -1;
+
+      break;
+
+    case NFAPI_NMM_STOP_REQUEST:
+      if (check_unpack_length(NFAPI_NMM_STOP_REQUEST, unpackedBufLen))
+        result = unpack_nmm_stop_request(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    case NFAPI_NMM_STOP_RESPONSE:
+      if (check_unpack_length(NFAPI_NMM_STOP_RESPONSE, unpackedBufLen))
+        result = unpack_nmm_stop_response(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        result = -1;
+
+      break;
+
+    default:
+      if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+          pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if(config && config->unpack_p4_p5_vendor_extension) {
+          result = (config->unpack_p4_p5_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown P4 message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+      }
+
+      break;
+  }
+
+  if(result == 0)
+    return -1;
+
+  return result;
 }
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
index 8aea9f590c91f8142884c0bcc8bd554780f9119d..0c0a8750bc2d5e5d8a302f41dcd5327cc47da318 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
@@ -1,2785 +1,2368 @@
-/*
- * Copyright 2017 Cisco Systems, Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 
- * 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.
- */
-
-
-#include <signal.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sched.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <pthread.h>
-#include <stdint.h>
-
-#include <nfapi_interface.h>
-#include <nfapi.h>
-#include "nfapi_nr_interface.h"
-#include "nfapi_nr_interface_scf.h"
-#include <debug.h>
-
-
-// Pack routines
-//TODO: Add pacl/unpack fns for uint32 and uint64
-static uint8_t pack_nr_pnf_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_param_request_t* request = (nfapi_nr_pnf_param_request_t*)msg;
-	return pack_vendor_extension_tlv(request->vendor_extension, ppWritePackedMsg, end, config);
-}
-
-static uint8_t pack_pnf_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_param_request_t* request = (nfapi_pnf_param_request_t*)msg;
-	return pack_vendor_extension_tlv(request->vendor_extension, ppWritePackedMsg, end, config);
-}
-
-static uint8_t pack_pnf_param_general_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_param_general_t* value = (nfapi_pnf_param_general_t*)tlv;
-
-	return ( push8(value->nfapi_sync_mode, ppWritePackedMsg, end) &&
-			 push8(value->location_mode, ppWritePackedMsg, end) &&
-			 push16(value->location_coordinates_length, ppWritePackedMsg, end) &&
-			 pusharray8(value->location_coordinates, NFAPI_PNF_PARAM_GENERAL_LOCATION_LENGTH, value->location_coordinates_length, ppWritePackedMsg, end) &&
-			 push32(value->dl_config_timing, ppWritePackedMsg, end) &&
-			 push32(value->tx_timing, ppWritePackedMsg, end) &&
-			 push32(value->ul_config_timing, ppWritePackedMsg, end) &&
-			 push32(value->hi_dci0_timing, ppWritePackedMsg, end) &&
-			 push16(value->maximum_number_phys, ppWritePackedMsg, end) &&
-			 push16(value->maximum_total_bandwidth, ppWritePackedMsg, end) &&
-			 push8(value->maximum_total_number_dl_layers, ppWritePackedMsg, end) &&
-			 push8(value->maximum_total_number_ul_layers, ppWritePackedMsg, end) &&
-			 push8(value->shared_bands, ppWritePackedMsg, end) &&
-			 push8(value->shared_pa, ppWritePackedMsg, end) &&
-			 pushs16(value->maximum_total_power, ppWritePackedMsg, end) &&
-			 pusharray8(value->oui, NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH, NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_rf_config_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_rf_config_info_t* rf = (nfapi_rf_config_info_t*)elem;
-
-	return (push16(rf->rf_config_index, ppWritePackedMsg, end));
-}
-
-
-static uint8_t pack_pnf_phy_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t* end)
-{
-	nfapi_pnf_phy_info_t* phy = (nfapi_pnf_phy_info_t*)elem;
-
-	return (  push16(phy->phy_config_index, ppWritePackedMsg, end) &&
-			  push16(phy->number_of_rfs, ppWritePackedMsg, end) &&
-			  packarray(phy->rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rfs, ppWritePackedMsg, end, &pack_rf_config_info) &&
-			  push16(phy->number_of_rf_exclusions, ppWritePackedMsg, end) &&
-			  packarray(phy->excluded_rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rf_exclusions, ppWritePackedMsg, end, &pack_rf_config_info) &&
-			  push16(phy->downlink_channel_bandwidth_supported, ppWritePackedMsg, end) &&
-			  push16(phy->uplink_channel_bandwidth_supported, ppWritePackedMsg, end) &&
-			  push8(phy->number_of_dl_layers_supported, ppWritePackedMsg, end) &&
-			  push8(phy->number_of_ul_layers_supported, ppWritePackedMsg, end) &&
-			  push16(phy->maximum_3gpp_release_supported, ppWritePackedMsg, end) &&
-			  push8(phy->nmm_modes_supported, ppWritePackedMsg, end));
-
-
-}
-
-static uint8_t pack_pnf_phy_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_t* value = (nfapi_pnf_phy_t*)tlv;
-
-	return ( push16(value->number_of_phys, ppWritePackedMsg, end) &&
-			 packarray(value->phy, sizeof(nfapi_pnf_phy_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_info));
-}
-
-static uint8_t pack_pnf_rf_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_rf_t* value = (nfapi_pnf_rf_t*)tlv;
-	uint16_t rf_index = 0;
-
-	if(push16(value->number_of_rfs, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	for(; rf_index < value->number_of_rfs; ++rf_index)
-	{
-		if( !(push16(value->rf[rf_index].rf_config_index, ppWritePackedMsg, end) &&
-			  push16(value->rf[rf_index].band, ppWritePackedMsg, end) &&
-			  pushs16(value->rf[rf_index].maximum_transmit_power, ppWritePackedMsg, end) &&
-			  pushs16(value->rf[rf_index].minimum_transmit_power, ppWritePackedMsg, end) &&
-			  push8(value->rf[rf_index].number_of_antennas_suppported, ppWritePackedMsg, end) &&
-			  push32(value->rf[rf_index].minimum_downlink_frequency, ppWritePackedMsg, end) &&
-			  push32(value->rf[rf_index].maximum_downlink_frequency, ppWritePackedMsg, end) &&
-			  push32(value->rf[rf_index].minimum_uplink_frequency, ppWritePackedMsg, end) &&
-			  push32(value->rf[rf_index].maximum_uplink_frequency, ppWritePackedMsg, end)))
-			return 0;
-	}
-
-	return 1;
-}
-static uint8_t pack_pnf_phy_rel10_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel10_info_t* phy = (nfapi_pnf_phy_rel10_info_t*)elem;
-
-	return(push16(phy->phy_config_index, ppWritePackedMsg, end) &&
-		   push16(phy->transmission_mode_7_supported, ppWritePackedMsg, end) &&
-		   push16(phy->transmission_mode_8_supported, ppWritePackedMsg, end) &&
-		   push16(phy->two_antenna_ports_for_pucch, ppWritePackedMsg, end) &&
-		   push16(phy->transmission_mode_9_supported, ppWritePackedMsg, end) &&
-		   push16(phy->simultaneous_pucch_pusch, ppWritePackedMsg, end) &&
-		   push16(phy->four_layer_tx_with_tm3_and_tm4, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_pnf_phy_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel10_t* value = (nfapi_pnf_phy_rel10_t*)tlv;
-
-	return (push16(value->number_of_phys, ppWritePackedMsg, end) &&
-			packarray(value->phy, sizeof(nfapi_pnf_phy_rel10_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel10_info));
-
-}
-
-static uint8_t pack_pnf_phy_rel11_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel11_info_t* phy = (nfapi_pnf_phy_rel11_info_t*)elem;
-		
-	return (push16(phy->phy_config_index, ppWritePackedMsg, end) &&
-			push16(phy->edpcch_supported, ppWritePackedMsg, end) &&
-			push16(phy->multi_ack_csi_reporting, ppWritePackedMsg, end) &&
-			push16(phy->pucch_tx_diversity, ppWritePackedMsg, end) &&
-			push16(phy->ul_comp_supported, ppWritePackedMsg, end) &&
-			push16(phy->transmission_mode_5_supported, ppWritePackedMsg, end ));
-}
-static uint8_t pack_pnf_phy_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel11_t* value = (nfapi_pnf_phy_rel11_t*)tlv;
-
-	return (push16(value->number_of_phys, ppWritePackedMsg, end) &&
-			packarray(value->phy, sizeof(nfapi_pnf_phy_rel11_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel11_info));
-}
-static uint8_t pack_pnf_phy_rel12_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel12_info_t* phy = (nfapi_pnf_phy_rel12_info_t*)elem;
-
-	return( push16(phy->phy_config_index, ppWritePackedMsg, end) &&
-			push16(phy->csi_subframe_set, ppWritePackedMsg, end) &&
-			push16(phy->enhanced_4tx_codebook, ppWritePackedMsg, end) &&
-			push16(phy->drs_supported, ppWritePackedMsg, end) &&
-			push16(phy->ul_64qam_supported, ppWritePackedMsg, end) &&
-			push16(phy->transmission_mode_10_supported, ppWritePackedMsg, end) &&
-			push16(phy->alternative_bts_indices, ppWritePackedMsg, end));
-}
-static uint8_t pack_pnf_phy_rel12_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel12_t* value = (nfapi_pnf_phy_rel12_t*)tlv;
-
-	return (push16(value->number_of_phys, ppWritePackedMsg, end) &&
-			packarray(value->phy, sizeof(nfapi_pnf_phy_rel12_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel12_info));
-
-}
-
-static uint8_t pack_pnf_phy_rel13_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel13_info_t* phy = (nfapi_pnf_phy_rel13_info_t*)elem;
-		
-	return( push16(phy->phy_config_index, ppWritePackedMsg, end) &&
-			push16(phy->pucch_format4_supported, ppWritePackedMsg, end) &&
-			push16(phy->pucch_format5_supported, ppWritePackedMsg, end) &&
-			push16(phy->more_than_5_ca_support, ppWritePackedMsg, end) &&
-			push16(phy->laa_supported, ppWritePackedMsg, end) &&
-			push16(phy->laa_ending_in_dwpts_supported, ppWritePackedMsg, end) &&
-			push16(phy->laa_starting_in_second_slot_supported, ppWritePackedMsg, end) &&
-			push16(phy->beamforming_supported, ppWritePackedMsg, end) &&
-			push16(phy->csi_rs_enhancement_supported, ppWritePackedMsg, end) &&
-			push16(phy->drms_enhancement_supported, ppWritePackedMsg, end) &&
-			push16(phy->srs_enhancement_supported, ppWritePackedMsg, end) );
-}
-
-static uint8_t pack_pnf_phy_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel13_t* value = (nfapi_pnf_phy_rel13_t*)tlv;
-
-	return (push16(value->number_of_phys, ppWritePackedMsg, end) &&
-	        packarray(value->phy, sizeof(nfapi_pnf_phy_rel13_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel13_info));
-}
-
-static uint8_t pack_pnf_phy_rel13_nb_iot_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel13_nb_iot_info_t* phy = (nfapi_pnf_phy_rel13_nb_iot_info_t*)elem;
-		
-	return( push16(phy->phy_config_index, ppWritePackedMsg, end) &&
-			push16(phy->number_of_rfs, ppWritePackedMsg, end) &&
-			packarray(phy->rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rfs, ppWritePackedMsg, end, &pack_rf_config_info) &&
-			push16(phy->number_of_rf_exclusions, ppWritePackedMsg, end) &&
-			packarray(phy->excluded_rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rf_exclusions, ppWritePackedMsg, end, &pack_rf_config_info) &&
-			push8(phy->number_of_dl_layers_supported, ppWritePackedMsg, end) &&
-			push8(phy->number_of_ul_layers_supported, ppWritePackedMsg, end) &&
-			push16(phy->maximum_3gpp_release_supported, ppWritePackedMsg, end) &&
-			push8(phy->nmm_modes_supported, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_pnf_phy_rel13_nb_iot_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel13_nb_iot_t* value = (nfapi_pnf_phy_rel13_nb_iot_t*)tlv;
-
-	return (push16(value->number_of_phys, ppWritePackedMsg, end) &&
-	        packarray(value->phy, sizeof(nfapi_pnf_phy_rel13_nb_iot_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel13_nb_iot_info));
-}
-/*
-static uint8_t pack_nr_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_param_response_t *pNfapiMsg = (nfapi_nr_pnf_param_response_t*)msg;
-
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_tlv(NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, ppWritePackedMsg, end, &pack_pnf_param_general_value) &&
-			pack_tlv(NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, ppWritePackedMsg, end, &pack_pnf_phy_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-*/
-static uint8_t pack_nr_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_param_response_t *pNfapiMsg = (nfapi_nr_pnf_param_response_t*)msg;
-
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_tlv(NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, ppWritePackedMsg, end, &pack_pnf_param_general_value) &&
-			pack_tlv(NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, ppWritePackedMsg, end, &pack_pnf_phy_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-
-static uint8_t pack_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_param_response_t *pNfapiMsg = (nfapi_pnf_param_response_t*)msg;
-
-	return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_tlv(NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, ppWritePackedMsg, end, &pack_pnf_param_general_value) &&
-			pack_tlv(NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, ppWritePackedMsg, end, &pack_pnf_phy_value) &&
-			pack_tlv(NFAPI_PNF_RF_TAG, &pNfapiMsg->pnf_rf, ppWritePackedMsg, end, &pack_pnf_rf_value) &&
-			pack_tlv(NFAPI_PNF_PHY_REL10_TAG, &pNfapiMsg->pnf_phy_rel10, ppWritePackedMsg, end, &pack_pnf_phy_rel10_value) &&
-			pack_tlv(NFAPI_PNF_PHY_REL11_TAG, &pNfapiMsg->pnf_phy_rel11, ppWritePackedMsg, end, &pack_pnf_phy_rel11_value) &&
-			pack_tlv(NFAPI_PNF_PHY_REL12_TAG, &pNfapiMsg->pnf_phy_rel12, ppWritePackedMsg, end, &pack_pnf_phy_rel12_value) &&
-			pack_tlv(NFAPI_PNF_PHY_REL13_TAG, &pNfapiMsg->pnf_phy_rel13, ppWritePackedMsg, end, &pack_pnf_phy_rel13_value) &&
-			pack_tlv(NFAPI_PNF_PHY_REL13_NB_IOT_TAG, &pNfapiMsg->pnf_phy_rel13_nb_iot, ppWritePackedMsg, end, &pack_pnf_phy_rel13_nb_iot_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-
-static uint8_t pack_phy_rf_config_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_phy_rf_config_info_t* rf = (nfapi_phy_rf_config_info_t*)elem;
-		
-	return (push16(rf->phy_id, ppWritePackedMsg, end) &&
-			push16(rf->phy_config_index, ppWritePackedMsg, end) &&
-			push16(rf->rf_config_index, ppWritePackedMsg, end));
-}
-		
-
-static uint8_t pack_pnf_phy_rf_config_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rf_config_t *value = (nfapi_pnf_phy_rf_config_t*)tlv;
-
-	return(push16(value->number_phy_rf_config_info, ppWritePackedMsg, end) &&
-		   packarray(value->phy_rf_config, sizeof(nfapi_phy_rf_config_info_t), NFAPI_MAX_PHY_RF_INSTANCES, value->number_phy_rf_config_info, ppWritePackedMsg, end, &pack_phy_rf_config_info));
-
-}
-
-static uint8_t pack_nr_pnf_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_config_request_t *pNfapiMsg = (nfapi_nr_pnf_config_request_t*)msg;
-	return (pack_tlv(NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, ppWritePackedMsg, end, &pack_pnf_phy_rf_config_value) && 
-			//push8(pNfapiMsg->num_tlvs,ppWritePackedMsg,end) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end , config));
-}
-
-static uint8_t pack_pnf_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_config_request_t *pNfapiMsg = (nfapi_pnf_config_request_t*)msg;
-	return (pack_tlv(NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, ppWritePackedMsg, end, &pack_pnf_phy_rf_config_value) && 
-			push8(pNfapiMsg->num_tlvs,ppWritePackedMsg,end) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end , config));
-}
-
-
-static uint8_t pack_nr_pnf_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_config_response_t *pNfapiMsg = (nfapi_nr_pnf_config_response_t*)msg;
-
-	return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			 pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-
-static uint8_t pack_pnf_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_config_response_t *pNfapiMsg = (nfapi_pnf_config_response_t*)msg;
-
-	return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			 pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_nr_pnf_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_start_request_t *pNfapiMsg = (nfapi_nr_pnf_start_request_t*)msg;
-	return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_pnf_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_start_request_t *pNfapiMsg = (nfapi_pnf_start_request_t*)msg;
-	return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-
-static uint8_t pack_nr_pnf_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_start_response_t *pNfapiMsg = (nfapi_nr_pnf_start_response_t*)msg;
-
-	return( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && 
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-
-static uint8_t pack_pnf_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_start_response_t *pNfapiMsg = (nfapi_pnf_start_response_t*)msg;
-
-	return( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && 
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-
-static uint8_t pack_nr_pnf_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_stop_request_t *pNfapiMsg = (nfapi_nr_pnf_stop_request_t*)msg;
-	return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
-}
-
-
-
-static uint8_t pack_pnf_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_stop_request_t *pNfapiMsg = (nfapi_pnf_stop_request_t*)msg;
-	return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
-}
-
-
-static uint8_t pack_nr_pnf_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_stop_response_t *pNfapiMsg = (nfapi_nr_pnf_stop_response_t*)msg;
-
-	return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-		 	 pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-
-static uint8_t pack_pnf_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_stop_response_t *pNfapiMsg = (nfapi_pnf_stop_response_t*)msg;
-
-	return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-		 	 pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_nr_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{	
-	nfapi_nr_param_request_scf_t *pNfapiMsg = (nfapi_nr_param_request_scf_t*)msg;
-	return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{	
-	nfapi_param_request_t *pNfapiMsg = (nfapi_param_request_t*)msg;
-	return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_uint32_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_uint32_tlv_t* value = (nfapi_uint32_tlv_t*)tlv;
-	return push32(value->value, ppWritePackedMsg, end);
-}
-
-static uint8_t unpack_uint32_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_uint32_tlv_t* value = (nfapi_uint32_tlv_t*)tlv;
-	return pull32(ppReadPackedMsg, &value->value, end);
-}
-
-
-static uint8_t pack_uint16_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_uint16_tlv_t* value = (nfapi_uint16_tlv_t*)tlv;
-	return push16(value->value, ppWritePackedMsg, end);
-}
-
-static uint8_t unpack_uint16_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_uint16_tlv_t* value = (nfapi_uint16_tlv_t*)tlv;
-	return pull16(ppReadPackedMsg, &value->value, end);
-}
-
-static uint8_t pack_int16_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_int16_tlv_t* value = (nfapi_int16_tlv_t*)tlv;
-	return pushs16(value->value, ppWritePackedMsg, end);
-}
-
-static uint8_t unpack_int16_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_int16_tlv_t* value = (nfapi_int16_tlv_t*)tlv;
-	return pulls16(ppReadPackedMsg, &value->value, end);
-}
-
-static uint8_t pack_uint8_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_uint8_tlv_t* value = (nfapi_uint8_tlv_t*)tlv;
-	return push8(value->value, ppWritePackedMsg, end);
-}
-static uint8_t unpack_uint8_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_uint8_tlv_t* value = (nfapi_uint8_tlv_t*)tlv;
-	return pull8(ppReadPackedMsg, &value->value, end);
-}
-
-static uint8_t pack_ipv4_address_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ipv4_address_t* value = (nfapi_ipv4_address_t*)tlv;
-	return pusharray8(value->address, NFAPI_IPV4_ADDRESS_LENGTH, NFAPI_IPV4_ADDRESS_LENGTH, ppWritePackedMsg, end);
-}
-static uint8_t unpack_ipv4_address_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ipv4_address_t* value = (nfapi_ipv4_address_t*)tlv;
-	return pullarray8(ppReadPackedMsg, value->address, NFAPI_IPV4_ADDRESS_LENGTH, NFAPI_IPV4_ADDRESS_LENGTH, end);
-}
-static uint8_t pack_ipv6_address_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ipv6_address_t* value = (nfapi_ipv6_address_t*)tlv;
-	return pusharray8(value->address, NFAPI_IPV6_ADDRESS_LENGTH, NFAPI_IPV6_ADDRESS_LENGTH, ppWritePackedMsg, end);
-}
-static uint8_t unpack_ipv6_address_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ipv4_address_t* value = (nfapi_ipv4_address_t*)tlv;
-	return pullarray8(ppReadPackedMsg, value->address, NFAPI_IPV6_ADDRESS_LENGTH, NFAPI_IPV6_ADDRESS_LENGTH, end);
-}
-
-static uint8_t pack_rf_bands_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_rf_bands_t* value = (nfapi_rf_bands_t*)tlv;
-	
-	return ( push16(value->number_rf_bands, ppWritePackedMsg, end) &&
-			 pusharray16(value->rf_band, NFAPI_MAX_NUM_RF_BANDS, value->number_rf_bands, ppWritePackedMsg, end));
-}
-static uint8_t unpack_rf_bands_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t* end)
-{
-	nfapi_rf_bands_t* value = (nfapi_rf_bands_t*)tlv;
-
-	return ( pull16(ppReadPackedMsg, &value->number_rf_bands, end) &&
-			 pullarray16(ppReadPackedMsg, value->rf_band, NFAPI_MAX_NUM_RF_BANDS, value->number_rf_bands, end));
-}
-
-static uint8_t pack_nmm_frequency_bands_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nmm_frequency_bands_t* value = (nfapi_nmm_frequency_bands_t*)tlv;
-	
-	return( push16(value->number_of_rf_bands, ppWritePackedMsg, end) &&
-			pusharray16(value->bands, NFAPI_MAX_NMM_FREQUENCY_BANDS, value->number_of_rf_bands, ppWritePackedMsg, end));
-}
-static uint8_t unpack_nmm_frequency_bands_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nmm_frequency_bands_t* value = (nfapi_nmm_frequency_bands_t*)tlv;
-	
-	return ( pull16(ppReadPackedMsg, &value->number_of_rf_bands, end) &&
-			 pullarray16(ppReadPackedMsg, value->bands, NFAPI_MAX_NMM_FREQUENCY_BANDS, value->number_of_rf_bands, end));
-}
-static uint8_t pack_embms_mbsfn_config_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-       nfapi_embms_mbsfn_config_t* value = (nfapi_embms_mbsfn_config_t*)tlv;
-       
-       return ( push16(value->num_mbsfn_config, ppWritePackedMsg, end) &&
-                pusharray16(value->radioframe_allocation_period, 8,value->num_mbsfn_config ,ppWritePackedMsg, end) &&
-                pusharray16(value->radioframe_allocation_offset, 8,value->num_mbsfn_config ,ppWritePackedMsg, end) &&
-                pusharray8(value->fourframes_flag, 8,value->num_mbsfn_config,ppWritePackedMsg, end) &&
-                pusharrays32(value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, ppWritePackedMsg, end));
-}
-// static uint8_t unpack_embms_mbsfn_config_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t* end)
-// {
-//     nfapi_embms_mbsfn_config_t* value = (nfapi_embms_mbsfn_config_t*)tlv;
-
-//     return ( pull16(ppReadPackedMsg, &value->num_mbsfn_config, end) &&
-//              pull16(ppReadPackedMsg, &value->radioframe_allocation_period, end) &&
-//              pull16(ppReadPackedMsg, &value->radioframe_allocation_offset, end) &&
-//              pull8(ppReadPackedMsg, &value->fourframes_flag, end) &&
-//                      pullarrays32(ppReadPackedMsg, value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, end));
-// }
-
-static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{	
-	nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t*)msg;
-
-	return( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) &&
-			pack_tlv(NFAPI_L1_STATUS_PHY_STATE_TAG,  &pNfapiMsg->l1_status.phy_state, ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			// Do we check the phy state and then just fill those sepecified, however
-			// we do not know the duplex mode, so just attempt to pack all and assumme
-			// that the callee has set the right tlvs
-
-			pack_tlv(NFAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, &(pNfapiMsg->phy_capabilities.dl_bandwidth_support), ppWritePackedMsg, end, &pack_uint16_tlv_value) && 
-			pack_tlv(NFAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, &(pNfapiMsg->phy_capabilities.ul_bandwidth_support), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PHY_CAPABILITIES_DL_MODULATION_SUPPORT_TAG, &(pNfapiMsg->phy_capabilities.dl_modulation_support), ppWritePackedMsg, end, &pack_uint16_tlv_value) && 
-			pack_tlv(NFAPI_PHY_CAPABILITIES_UL_MODULATION_SUPPORT_TAG, &(pNfapiMsg->phy_capabilities.ul_modulation_support), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PHY_CAPABILITIES_PHY_ANTENNA_CAPABILITY_TAG, &(pNfapiMsg->phy_capabilities.phy_antenna_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PHY_CAPABILITIES_RELEASE_CAPABILITY_TAG, &(pNfapiMsg->phy_capabilities.release_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PHY_CAPABILITIES_MBSFN_CAPABILITY_TAG, &(pNfapiMsg->phy_capabilities.mbsfn_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			// laa capability
-
-			pack_tlv(NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &(pNfapiMsg->subframe_config.duplex_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &(pNfapiMsg->subframe_config.pcfich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value)&&
-			pack_tlv(NFAPI_SUBFRAME_CONFIG_PB_TAG, &(pNfapiMsg->subframe_config.pb), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.dl_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.ul_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.dl_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.ul_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &(pNfapiMsg->rf_config.reference_signal_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) && 
-			pack_tlv(NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.tx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.rx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &(pNfapiMsg->phich_config.phich_resource), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &(pNfapiMsg->phich_config.phich_duration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &(pNfapiMsg->phich_config.phich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &(pNfapiMsg->sch_config.physical_cell_id), ppWritePackedMsg, end ,&pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->prach_config.configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &(pNfapiMsg->prach_config.zero_correlation_zone_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &(pNfapiMsg->prach_config.high_speed_flag), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->prach_config.frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &(pNfapiMsg->pusch_config.hopping_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &(pNfapiMsg->pusch_config.hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &(pNfapiMsg->pusch_config.number_of_subbands), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &(pNfapiMsg->pucch_config.delta_pucch_shift), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &(pNfapiMsg->pucch_config.n_cqi_rb), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-                       pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_idx), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-                       pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_id_r9), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-                       pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_TAG, &(pNfapiMsg->embms_mbsfn_config), ppWritePackedMsg, end, &pack_embms_mbsfn_config_value) &&
-
-                       pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-                       pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-                       pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_config_flag), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-                       pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_SUBFRAMECONFIG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_subframeconfig), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-
-			pack_tlv(NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.bandwidth_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &(pNfapiMsg->srs_config.max_up_pts), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.srs_subframe_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &(pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &(pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &(pNfapiMsg->uplink_reference_signal_config.group_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &(pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &(pNfapiMsg->tdd_frame_structure_config.subframe_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &(pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &(pNfapiMsg->l23_config.data_report_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_L23_CONFIG_SFNSF_TAG, &(pNfapiMsg->l23_config.sfnsf), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
-			pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
-
-			pack_tlv(NFAPI_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
-			pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
-
-			pack_tlv(NFAPI_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.dl_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-
-			pack_tlv(NFAPI_NFAPI_RF_BANDS_TAG, &(pNfapiMsg->nfapi_config.rf_bands), ppWritePackedMsg, end, &pack_rf_bands_value) &&
-
-			pack_tlv(NFAPI_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-
-			pack_tlv(NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NFAPI_EARFCN_TAG, &(pNfapiMsg->nfapi_config.earfcn), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-
-			pack_tlv(NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) &&
-			pack_tlv(NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_umts_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) &&
-			pack_tlv(NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_lte_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) &&
-			pack_tlv(NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &(pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
-
-}
-
-static uint8_t pack_nr_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	printf("\nRUNNING pack_param_response\n");
-	nfapi_nr_param_response_scf_t *pNfapiMsg = (nfapi_nr_param_response_scf_t*)msg;
-	
-	return (push8(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG, &(pNfapiMsg->cell_param.release_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PHY_STATE_TAG, &(pNfapiMsg->cell_param.phy_state), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_dl_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_ul_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG, &(pNfapiMsg->cell_param.num_config_tlvs_to_report ), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			
-			pack_tlv(NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG, &(pNfapiMsg->carrier_param.cyclic_prefix), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_dl), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_dl), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_ul), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_ul), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG, &(pNfapiMsg->pdcch_param.cce_mapping_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG, &(pNfapiMsg->pdcch_param.coreset_outside_first_3_of_ofdm_syms_of_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG, &(pNfapiMsg->pdcch_param.coreset_precoder_granularity_coreset), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG, &(pNfapiMsg->pdcch_param.pdcch_mu_mimo), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG, &(pNfapiMsg->pdcch_param.pdcch_precoder_cycling), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG, &(pNfapiMsg->pdcch_param.max_pdcch_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			
-			pack_tlv(NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG, &(pNfapiMsg->pucch_param.pucch_formats), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG, &(pNfapiMsg->pucch_param.max_pucchs_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			
-			pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pdsch_param.pdsch_mapping_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_allocation_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pdsch_param.pdsch_vrb_to_prb_mapping), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG, &(pNfapiMsg->pdsch_param.pdsch_cbg), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_config_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DMRS_MAX_LENGTH_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_max_length), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_additional_pos), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PDSCH_S_YBS_PER_SLOT_TAG, &(pNfapiMsg->pdsch_param.max_pdsch_tbs_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG, &(pNfapiMsg->pdsch_param.max_number_mimo_layers_pdsch), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG, &(pNfapiMsg->pdsch_param.max_mu_mimo_users_dl), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG, &(pNfapiMsg->pdsch_param.pdsch_data_in_dmrs_symbols), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.premption_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.pdsch_non_slot_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-
-			pack_tlv(NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG, &(pNfapiMsg->pusch_param.uci_mux_ulsch_in_pusch), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG, &(pNfapiMsg->pusch_param.uci_only_pusch), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG, &(pNfapiMsg->pusch_param.pusch_frequency_hopping), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_config_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_max_len), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_additional_pos), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG, &(pNfapiMsg->pusch_param.pusch_cbg), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pusch_param.pusch_mapping_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pusch_param.pusch_allocation_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pusch_param.pusch_vrb_to_prb_mapping), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG, &(pNfapiMsg->pusch_param.pusch_max_ptrs_ports), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG, &(pNfapiMsg->pusch_param.max_pduschs_tbs_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG, &(pNfapiMsg->pusch_param.max_number_mimo_layers_non_cb_pusch), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG, &(pNfapiMsg->pusch_param.supported_modulation_order_ul), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG, &(pNfapiMsg->pusch_param.max_mu_mimo_users_ul), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG, &(pNfapiMsg->pusch_param.dfts_ofdm_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG, &(pNfapiMsg->pusch_param.pusch_aggregation_factor), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-
-            pack_tlv(NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG, &(pNfapiMsg->prach_param.prach_long_formats), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG, &(pNfapiMsg->prach_param.prach_short_formats), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG, &(pNfapiMsg->prach_param.prach_restricted_sets), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG, &(pNfapiMsg->prach_param.max_prach_fd_occasions_in_a_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-
-			pack_tlv(NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG, &(pNfapiMsg->measurement_param.rssi_measurement_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-            
-			// config:
-			
-			pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
-
-			pack_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
-
-			pack_tlv(NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-    	
-}
-
-static uint8_t pack_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_config_request_t *pNfapiMsg = (nfapi_config_request_t*)msg;
-
-	return ( push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) &&
-
-			 // Do we check the phy state and then just fill those sepecified, however
-			 // we do not know the duplex mode, so just attempt to pack all and assumme
-			 // that the callee has set the right tlvs
-
-			 pack_tlv(NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &(pNfapiMsg->subframe_config.duplex_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &(pNfapiMsg->subframe_config.pcfich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_SUBFRAME_CONFIG_PB_TAG, &(pNfapiMsg->subframe_config.pb), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.dl_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.ul_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			 pack_tlv(NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.dl_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.ul_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &(pNfapiMsg->rf_config.reference_signal_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.tx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.rx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			 pack_tlv(NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &(pNfapiMsg->phich_config.phich_resource), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &(pNfapiMsg->phich_config.phich_duration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &(pNfapiMsg->phich_config.phich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			 pack_tlv(NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &(pNfapiMsg->sch_config.physical_cell_id), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			 pack_tlv(NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->prach_config.configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &(pNfapiMsg->prach_config.zero_correlation_zone_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &(pNfapiMsg->prach_config.high_speed_flag), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->prach_config.frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			 pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &(pNfapiMsg->pusch_config.hopping_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &(pNfapiMsg->pusch_config.hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &(pNfapiMsg->pusch_config.number_of_subbands), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			 pack_tlv(NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &(pNfapiMsg->pucch_config.delta_pucch_shift), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &(pNfapiMsg->pucch_config.n_cqi_rb), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			 pack_tlv(NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.bandwidth_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &(pNfapiMsg->srs_config.max_up_pts), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.srs_subframe_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &(pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			 pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &(pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &(pNfapiMsg->uplink_reference_signal_config.group_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &(pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			 pack_tlv(NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_PDSCH_TAG, &(pNfapiMsg->laa_config.ed_threshold_lbt_pdsch), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_DRS_TAG, &(pNfapiMsg->laa_config.ed_threshold_lbt_drs), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_LAA_CONFIG_PD_THRESHOLD_TAG, &(pNfapiMsg->laa_config.pd_threshold), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_LAA_CONFIG_MULTI_CARRIER_TYPE_TAG, &(pNfapiMsg->laa_config.multi_carrier_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_LAA_CONFIG_MULTI_CARRIER_TX_TAG, &(pNfapiMsg->laa_config.multi_carrier_tx), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_LAA_CONFIG_MULTI_CARRIER_FREEZE_TAG, &(pNfapiMsg->laa_config.multi_carrier_freeze), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_LAA_CONFIG_TX_ANTENNA_PORTS_FOR_DRS_TAG, &(pNfapiMsg->laa_config.tx_antenna_ports_drs), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_LAA_CONFIG_TRANSMISSION_POWER_FOR_DRS_TAG, &(pNfapiMsg->laa_config.tx_power_drs), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			 pack_tlv(NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG, &(pNfapiMsg->emtc_config.pbch_repetitions_enable_r13), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_catm_root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &(pNfapiMsg->emtc_config.prach_catm_zero_correlation_zone_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG, &(pNfapiMsg->emtc_config.prach_catm_high_speed_flag), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_starting_subframe_periodicity), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_starting_subframe_periodicity), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_starting_subframe_periodicity), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_starting_subframe_periodicity), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG, &(pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG, &(pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			 pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &(pNfapiMsg->tdd_frame_structure_config.subframe_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &(pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-			 pack_tlv(NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &(pNfapiMsg->l23_config.data_report_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_L23_CONFIG_SFNSF_TAG, &(pNfapiMsg->l23_config.sfnsf), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-
-			 pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
-			 pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
-			 pack_tlv(NFAPI_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
-			 pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
-			 pack_tlv(NFAPI_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.dl_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			 pack_tlv(NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-
-			 pack_tlv(NFAPI_PHY_RF_BANDS_TAG, &(pNfapiMsg->nfapi_config.rf_bands), ppWritePackedMsg, end, &pack_rf_bands_value) &&
-
-			 pack_tlv(NFAPI_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			 pack_tlv(NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			 pack_tlv(NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-
-			 pack_tlv(NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			 pack_tlv(NFAPI_NFAPI_EARFCN_TAG, &(pNfapiMsg->nfapi_config.earfcn), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-
-
-			 pack_tlv(NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) &&
-			 pack_tlv(NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_umts_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) &&
-			 pack_tlv(NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_lte_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) &&
-			 pack_tlv(NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &(pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-
-			 pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
-}
-
-
-static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	printf("\n\nEntering pack_config_request\n");
-	nfapi_nr_config_request_scf_t *pNfapiMsg = (nfapi_nr_config_request_scf_t*)msg;
-
-
-	return (push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) &&
-		    pack_tlv(NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG, &(pNfapiMsg->carrier_config.dl_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_DL_FREQUENCY_TAG, &(pNfapiMsg->carrier_config.dl_frequency), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG, &(pNfapiMsg->carrier_config.dl_grid_size[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_DL_K0_TAG, &(pNfapiMsg->carrier_config.dl_k0[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_NUM_RX_ANT_TAG, &(pNfapiMsg->carrier_config.num_rx_ant), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_NUM_TX_ANT_TAG, &(pNfapiMsg->carrier_config.num_tx_ant), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG, &(pNfapiMsg->carrier_config.ul_grid_size[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_UL_K0_TAG, &(pNfapiMsg->carrier_config.ul_k0[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG, &(pNfapiMsg->carrier_config.uplink_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG, &(pNfapiMsg->carrier_config.uplink_frequency), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
-			
-			pack_tlv(NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG, &(pNfapiMsg->cell_config.frame_duplex_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_PHY_CELL_ID_TAG, &(pNfapiMsg->cell_config.phy_cell_id), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			
-			pack_tlv(NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG, &(pNfapiMsg->prach_config.prach_sequence_length), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG, &(pNfapiMsg->prach_config.restricted_set_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_SSB_PER_RACH_TAG, &(pNfapiMsg->prach_config.ssb_per_rach), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-            pack_tlv(NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG, &(pNfapiMsg->prach_config.prach_sub_c_spacing), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-             pack_tlv(NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-             pack_tlv(NFAPI_NR_CONFIG_K1_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].k1), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-             pack_tlv(NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_zero_corr_conf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			 pack_tlv(NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].num_root_sequences), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-
-
-			pack_tlv(NFAPI_NR_CONFIG_SCS_COMMON_TAG, &(pNfapiMsg->ssb_config.scs_common), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG, &(pNfapiMsg->ssb_config.ss_pbch_power), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
-
-			pack_tlv(NFAPI_NR_CONFIG_BETA_PSS_TAG, &(pNfapiMsg->ssb_table.beta_pss), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_MIB_TAG, &(pNfapiMsg->ssb_table.MIB), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[1].ssb_mask), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
-
-			pack_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG, &(pNfapiMsg->ssb_table.ssb_offset_point_a), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG, &(pNfapiMsg->ssb_table.ssb_subcarrier_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-
-			pack_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-		   	pack_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG, &(pNfapiMsg->tdd_table.max_tdd_periodicity_list[0].max_num_of_symbol_per_slot_list[0].slot_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-
-			//pack_tlv(NFAPI_NR_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.dl_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			//pack_tlv(NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			//pack_tlv(NFAPI_NR_NFAPI_NRARFCN_TAG, &(pNfapiMsg->nfapi_config.nrarfcn), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			//pack_tlv(NFAPI_NR_NFAPI_RF_BANDS_TAG, &(pNfapiMsg->nfapi_config.rf_bands), ppWritePackedMsg, end, &pack_rf_bands_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			pack_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-			//pack_tlv(NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
-
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
-}
-
-static uint8_t pack_nr_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_config_response_scf_t *pNfapiMsg = (nfapi_nr_config_response_scf_t*)msg;
-
-	return ( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			 pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
-}
-
-static uint8_t pack_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_config_response_t *pNfapiMsg = (nfapi_config_response_t*)msg;
-
-	return ( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			 pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
-}
-
-static uint8_t pack_nr_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_start_request_scf_t *pNfapiMsg = (nfapi_nr_start_request_scf_t*)msg;
-	return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
-}
-
-static uint8_t pack_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_start_request_t *pNfapiMsg = (nfapi_start_request_t*)msg;
-	return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
-}
-
-static uint8_t pack_nr_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_start_response_scf_t *pNfapiMsg = (nfapi_nr_start_response_scf_t*)msg;
-
-	return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end ) &&
-			 pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
-}
-
-static uint8_t pack_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_start_response_t *pNfapiMsg = (nfapi_start_response_t*)msg;
-
-	return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end ) &&
-			 pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
-}
-
-
-static uint8_t pack_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_stop_request_t *pNfapiMsg = (nfapi_stop_request_t*)msg;
-	return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
-}
-
-static uint8_t pack_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_stop_response_t *pNfapiMsg = (nfapi_stop_response_t*)msg;
-
-	return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			 pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
-}
-
-static uint8_t pack_measurement_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_measurement_request_t *pNfapiMsg = (nfapi_measurement_request_t*)msg;
-
-	return( pack_tlv(NFAPI_MEASUREMENT_REQUEST_DL_RS_XTX_POWER_TAG, &(pNfapiMsg->dl_rs_tx_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_MEASUREMENT_REQUEST_RECEIVED_INTERFERENCE_POWER_TAG, &(pNfapiMsg->received_interference_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_tlv(NFAPI_MEASUREMENT_REQUEST_THERMAL_NOISE_POWER_TAG, &(pNfapiMsg->thermal_noise_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_recevied_interference_power_measurement_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_received_interference_power_measurement_t* value = (nfapi_received_interference_power_measurement_t*)tlv;
-	
-	return  ( push16(value->number_of_resource_blocks, ppWritePackedMsg, end) &&
-			  pusharrays16(value->received_interference_power, NFAPI_MAX_RECEIVED_INTERFERENCE_POWER_RESULTS, value->number_of_resource_blocks, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_measurement_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_measurement_response_t *pNfapiMsg = (nfapi_measurement_response_t*)msg;
-
-	return( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
-			pack_tlv(NFAPI_MEASUREMENT_RESPONSE_DL_RS_POWER_MEASUREMENT_TAG, &(pNfapiMsg->dl_rs_tx_power_measurement), ppWritePackedMsg, end, &pack_int16_tlv_value) &&
-			pack_tlv(NFAPI_MEASUREMENT_RESPONSE_RECEIVED_INTERFERENCE_POWER_MEASUREMENT_TAG, &(pNfapiMsg->received_interference_power_measurement), ppWritePackedMsg, end, &pack_recevied_interference_power_measurement_value) &&
-			pack_tlv(NFAPI_MEASUREMENT_RESPONSE_THERMAL_NOISE_MEASUREMENT_TAG, &(pNfapiMsg->thermal_noise_power_measurement), ppWritePackedMsg, end, &pack_uint16_tlv_value) && 
-			pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_nr_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	uint8_t result = 0;
-	// look for the specific message
-	switch (header->message_id)
-	{
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
-			result = pack_nr_pnf_param_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_PNF_PARAM_RESPONSE:
-			result = pack_nr_pnf_param_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
-			result = pack_nr_pnf_config_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE:
-			result = pack_nr_pnf_config_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
-			result = pack_nr_pnf_start_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE:
-			result = pack_nr_pnf_start_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST:
-			result = pack_nr_pnf_stop_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_PNF_STOP_RESPONSE:
-			result = pack_nr_pnf_stop_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
-			result = pack_nr_param_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
-			result = pack_nr_param_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
-			result = pack_nr_config_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
-			result = pack_nr_config_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
-			result = pack_nr_start_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
-			result = pack_nr_start_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
-			result = pack_stop_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
-			result = pack_stop_response(header, ppWritePackedMsg, end, config);
-			break;
-		default:
-			{
-				if(header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
-				   header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
-				{
-					if(config && config->pack_p4_p5_vendor_extension)
-					{
-						result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config);
-					}
-					else
-					{
-						NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id);
-					}
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
-				}
-			}
-			break;
-	}
-
-	return result;
-}
-
-
-static uint8_t pack_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
-{
-	uint8_t result = 0;
-	// look for the specific message
-	switch (header->message_id)
-	{
-		case NFAPI_PNF_PARAM_REQUEST:
-			result = pack_pnf_param_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_PNF_PARAM_RESPONSE:
-			result = pack_pnf_param_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_PNF_CONFIG_REQUEST:
-			result = pack_pnf_config_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_PNF_CONFIG_RESPONSE:
-			result = pack_pnf_config_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_PNF_START_REQUEST:
-			result = pack_pnf_start_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_PNF_START_RESPONSE:
-			result = pack_pnf_start_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_PNF_STOP_REQUEST:
-			result = pack_pnf_stop_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_PNF_STOP_RESPONSE:
-			result = pack_pnf_stop_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_PARAM_REQUEST:
-			result = pack_param_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_PARAM_RESPONSE:
-			result = pack_param_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_CONFIG_REQUEST:
-			result = pack_config_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_CONFIG_RESPONSE:
-			result = pack_config_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_START_REQUEST:
-			result = pack_start_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_START_RESPONSE:
-			result = pack_start_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_STOP_REQUEST:
-			result = pack_stop_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_STOP_RESPONSE:
-			result = pack_stop_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_MEASUREMENT_REQUEST:
-			result = pack_measurement_request(header, ppWritePackedMsg, end, config);
-			break;
-
-		case NFAPI_MEASUREMENT_RESPONSE:
-			result = pack_measurement_response(header, ppWritePackedMsg, end, config);
-			break;
-
-		default:
-			{
-				if(header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
-				   header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
-				{
-					if(config && config->pack_p4_p5_vendor_extension)
-					{
-						result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config);
-					}
-					else
-					{
-						NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id);
-					}
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
-				}
-			}
-			break;
-	}
-
-	return result;
-}
-
-
-// helper function for message length calculation -
-// takes the pointers to the start of message to end of message
-
-static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd)
-{
-	if (msgEnd < msgHead)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %d, %d\n", msgHead, msgEnd);
-		return 0;
-	}
-
-	return (msgEnd - msgHead);
-}
-
-// Main pack function - public
-int nfapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
-	uint8_t *pWritePackedMessage = pPackedBuf;
-	uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
-	uint8_t *pPackedLengthField = &pWritePackedMessage[4];
-	uint32_t packedMsgLen;
-	uint16_t packedMsgLen16;
-
-	if (pMessageBuf == NULL || pPackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n");
-		return -1;
-	}
-
-	// pack the message
-	if(push16(pMessageHeader->phy_id, &pWritePackedMessage, pPackMessageEnd) &&
-	   push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd) &&
-	   push16(0, &pWritePackedMessage, pPackMessageEnd) &&
-	   push16(pMessageHeader->spare, &pWritePackedMessage, pPackMessageEnd) &&
-	   pack_nr_p5_message_body(pMessageHeader, &pWritePackedMessage, pPackMessageEnd, config))
-	{
-		// check for a valid message length
-		packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pWritePackedMessage);
-		if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
-			return -1;
-		}
-		else
-		{
-			packedMsgLen16 = (uint16_t)packedMsgLen;
-		}
-
-		// Update the message length in the header
-		if(!push16(packedMsgLen16, &pPackedLengthField, pPackMessageEnd))
-			return -1;
-
-		// return the packed length
-		return (packedMsgLen);
-	}
-	else
-	{
-		// Failed to pack the meassage
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Failed to pack message\n");
-		return -1;
-    }
-
-}
-
-int nfapi_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
-	uint8_t *pWritePackedMessage = pPackedBuf;
-	uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
-	uint8_t *pPackedLengthField = &pWritePackedMessage[4];
-	uint32_t packedMsgLen;
-	uint16_t packedMsgLen16;
-
-	if (pMessageBuf == NULL || pPackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n");
-		return -1;
-	}
-
-	// pack the message
-	if(push16(pMessageHeader->phy_id, &pWritePackedMessage, pPackMessageEnd) &&
-	   push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd) &&
-	   push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, pPackMessageEnd) &&
-	   push16(pMessageHeader->spare, &pWritePackedMessage, pPackMessageEnd) &&
-	   pack_p5_message_body(pMessageHeader, &pWritePackedMessage, pPackMessageEnd, config))
-	{
-		// check for a valid message length
-		packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pWritePackedMessage);
-		if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
-			return -1;
-		}
-		else
-		{
-			packedMsgLen16 = (uint16_t)packedMsgLen;
-		}
-
-		// Update the message length in the header
-		if(!push16(packedMsgLen16, &pPackedLengthField, pPackMessageEnd))
-			return -1;
-
-		// return the packed length
-		return (packedMsgLen);
-	}
-	else
-	{
-		// Failed to pack the meassage
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Failed to pack message\n");
-		return -1;
-    }
-
-}
-
-
-
-// Unpack routines
-
-
-static uint8_t  unpack_nr_pnf_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_param_request_t *pNfapiMsg = (nfapi_nr_pnf_param_request_t*)msg;
-	
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-	
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
-}
-
-
-static uint8_t  unpack_pnf_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_param_request_t *pNfapiMsg = (nfapi_pnf_param_request_t*)msg;
-	
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-	
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_pnf_param_general_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_param_general_t* value = (nfapi_pnf_param_general_t*)tlv;
-	
-	return( pull8(ppReadPackedMsg, &value->nfapi_sync_mode, end) &&
-			pull8(ppReadPackedMsg, &value->location_mode, end) &&
-			pull16(ppReadPackedMsg, &value->location_coordinates_length, end) &&
-			pullarray8(ppReadPackedMsg, value->location_coordinates, NFAPI_PNF_PARAM_GENERAL_LOCATION_LENGTH, value->location_coordinates_length, end) &&
-			pull32(ppReadPackedMsg, &value->dl_config_timing, end) &&
-			pull32(ppReadPackedMsg, &value->tx_timing, end) &&
-			pull32(ppReadPackedMsg, &value->ul_config_timing, end) &&
-			pull32(ppReadPackedMsg, &value->hi_dci0_timing, end) &&
-			pull16(ppReadPackedMsg, &value->maximum_number_phys, end) &&
-			pull16(ppReadPackedMsg, &value->maximum_total_bandwidth, end) &&
-			pull8(ppReadPackedMsg, &value->maximum_total_number_dl_layers, end) &&
-			pull8(ppReadPackedMsg, &value->maximum_total_number_ul_layers, end) &&
-			pull8(ppReadPackedMsg, &value->shared_bands, end) &&
-			pull8(ppReadPackedMsg, &value->shared_pa, end) &&
-			pulls16(ppReadPackedMsg, &value->maximum_total_power, end) &&
-			pullarray8(ppReadPackedMsg, value->oui, NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH, NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH, end));
-}
-
-static uint8_t unpack_rf_config_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_rf_config_info_t* info = (nfapi_rf_config_info_t*)elem;
-	return pull16(ppReadPackedMsg, &info->rf_config_index, end);
-}
-
-static uint8_t unpack_pnf_phy_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_info_t* phy = (nfapi_pnf_phy_info_t*)elem;
-
-	return ( pull16(ppReadPackedMsg, &phy->phy_config_index, end) && 
-			 pull16(ppReadPackedMsg, &phy->number_of_rfs, end) &&
-			 unpackarray(ppReadPackedMsg, phy->rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rfs, end, &unpack_rf_config_info) &&
-			 pull16(ppReadPackedMsg, &phy->number_of_rf_exclusions, end) &&
-			 unpackarray(ppReadPackedMsg, phy->excluded_rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rf_exclusions, end, &unpack_rf_config_info) &&
-			 pull16(ppReadPackedMsg, &phy->downlink_channel_bandwidth_supported, end) &&
-			 pull16(ppReadPackedMsg, &phy->uplink_channel_bandwidth_supported, end) &&
-			 pull8(ppReadPackedMsg, &phy->number_of_dl_layers_supported, end) &&
-			 pull8(ppReadPackedMsg, &phy->number_of_ul_layers_supported, end) &&
-			 pull16(ppReadPackedMsg, &phy->maximum_3gpp_release_supported, end) &&
-			 pull8(ppReadPackedMsg, &phy->nmm_modes_supported, end));
-}
-
-
-static uint8_t unpack_pnf_phy_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_t* value = (nfapi_pnf_phy_t*)tlv;
-	return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) && 
-			 unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_info));
-}
-
-static uint8_t unpack_pnf_rf_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_rf_info_t* rf = (nfapi_pnf_rf_info_t*)elem;
-		
-	return( pull16(ppReadPackedMsg, &rf->rf_config_index, end) &&
-			pull16(ppReadPackedMsg, &rf->band, end) &&
-			pulls16(ppReadPackedMsg, &rf->maximum_transmit_power, end) &&
-			pulls16(ppReadPackedMsg, &rf->minimum_transmit_power, end) &&
-			pull8(ppReadPackedMsg, &rf->number_of_antennas_suppported, end) &&
-			pull32(ppReadPackedMsg, &rf->minimum_downlink_frequency, end) &&
-			pull32(ppReadPackedMsg, &rf->maximum_downlink_frequency, end) &&
-			pull32(ppReadPackedMsg, &rf->minimum_uplink_frequency, end) &&
-			pull32(ppReadPackedMsg, &rf->maximum_uplink_frequency, end));
-
-}
-static uint8_t unpack_pnf_rf_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_rf_t* value = (nfapi_pnf_rf_t*)tlv;
-
-	return ( pull16(ppReadPackedMsg, &value->number_of_rfs, end) &&
-		     unpackarray(ppReadPackedMsg, value->rf, sizeof(nfapi_pnf_rf_info_t), NFAPI_MAX_PNF_RF, value->number_of_rfs, end, &unpack_pnf_rf_info));
-}
-
-static uint8_t unpack_pnf_phy_rel10_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel10_info_t* phy = (nfapi_pnf_phy_rel10_info_t*)elem;
-		
-	return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) &&
-			pull16(ppReadPackedMsg, &phy->transmission_mode_7_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->transmission_mode_8_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->two_antenna_ports_for_pucch, end) &&
-			pull16(ppReadPackedMsg, &phy->transmission_mode_9_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->simultaneous_pucch_pusch, end) &&
-			pull16(ppReadPackedMsg, &phy->four_layer_tx_with_tm3_and_tm4, end));
-
-
-}
-static uint8_t unpack_pnf_phy_rel10_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel10_t* value = (nfapi_pnf_phy_rel10_t*)tlv;
-
-	return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) &&
-			 unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel10_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel10_info));
-
-}
-
-
-static uint8_t unpack_pnf_phy_rel11_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel11_info_t* phy = (nfapi_pnf_phy_rel11_info_t*)elem;
-
-	return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) &&
-			pull16(ppReadPackedMsg, &phy->edpcch_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->multi_ack_csi_reporting, end ) &&
-			pull16(ppReadPackedMsg, &phy->pucch_tx_diversity, end) &&
-			pull16(ppReadPackedMsg, &phy->ul_comp_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->transmission_mode_5_supported, end));
-}
-
-static uint8_t unpack_pnf_phy_rel11_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel11_t* value = (nfapi_pnf_phy_rel11_t*)tlv;
-
-	return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) &&
-			 unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel11_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel11_info));
-
-}
-
-static uint8_t unpack_phy_phy_rel12_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel12_info_t* phy = (nfapi_pnf_phy_rel12_info_t*)elem;
-
-	return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) &&
-			pull16(ppReadPackedMsg, &phy->csi_subframe_set, end) &&
-			pull16(ppReadPackedMsg, &phy->enhanced_4tx_codebook, end) &&
-			pull16(ppReadPackedMsg, &phy->drs_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->ul_64qam_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->transmission_mode_10_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->alternative_bts_indices, end));
-}
-
-static uint8_t unpack_pnf_phy_rel12_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel12_t* value = (nfapi_pnf_phy_rel12_t*)tlv;
-
-	return (pull16(ppReadPackedMsg, &value->number_of_phys, end) &&
-			unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel12_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_phy_phy_rel12_info));
-
-}
-
-static uint8_t unpack_pnf_phy_rel13_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel13_info_t* phy = (nfapi_pnf_phy_rel13_info_t*)elem;
-
-	return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) &&
-			pull16(ppReadPackedMsg, &phy->pucch_format4_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->pucch_format5_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->more_than_5_ca_support, end) &&
-			pull16(ppReadPackedMsg, &phy->laa_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->laa_ending_in_dwpts_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->laa_starting_in_second_slot_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->beamforming_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->csi_rs_enhancement_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->drms_enhancement_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->srs_enhancement_supported, end));
-}
-
-static uint8_t unpack_pnf_phy_rel13_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel13_t* value = (nfapi_pnf_phy_rel13_t*)tlv;
-	
-	return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) &&
-			 unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel13_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel13_info));
-}
-
-static uint8_t unpack_pnf_phy_rel13_nb_info_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel13_nb_iot_info_t* phy = (nfapi_pnf_phy_rel13_nb_iot_info_t*)elem;
-
-	return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) &&
-			pull16(ppReadPackedMsg, &phy->number_of_rfs, end) &&
-			unpackarray(ppReadPackedMsg, phy->rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rfs, end, &unpack_rf_config_info) &&
-			pull16(ppReadPackedMsg, &phy->number_of_rf_exclusions, end) &&
-			unpackarray(ppReadPackedMsg, phy->excluded_rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rf_exclusions, end, &unpack_rf_config_info) &&
-			pull8(ppReadPackedMsg, &phy->number_of_dl_layers_supported, end) &&
-			pull8(ppReadPackedMsg, &phy->number_of_ul_layers_supported, end) &&
-			pull16(ppReadPackedMsg, &phy->maximum_3gpp_release_supported, end) &&
-			pull8(ppReadPackedMsg, &phy->nmm_modes_supported, end));
-}
-
-static uint8_t unpack_pnf_phy_rel13_nb_iot_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rel13_nb_iot_t* value = (nfapi_pnf_phy_rel13_nb_iot_t*)tlv;
-	
-	return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) &&
-			 unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel13_nb_iot_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel13_nb_info_info));
-}
-
-static uint8_t unpack_nr_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_param_response_t *pNfapiMsg = (nfapi_nr_pnf_param_response_t*)msg;
-	
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, &unpack_pnf_param_general_value},
-		{ NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, &unpack_pnf_phy_value},
-	};
-
-	return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-
-
-static uint8_t unpack_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_param_response_t *pNfapiMsg = (nfapi_pnf_param_response_t*)msg;
-	
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, &unpack_pnf_param_general_value},
-		{ NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, &unpack_pnf_phy_value},
-		{ NFAPI_PNF_RF_TAG, &pNfapiMsg->pnf_rf, &unpack_pnf_rf_value},
-		{ NFAPI_PNF_PHY_REL10_TAG, &pNfapiMsg->pnf_phy_rel10, &unpack_pnf_phy_rel10_value},
-		{ NFAPI_PNF_PHY_REL11_TAG, &pNfapiMsg->pnf_phy_rel11, &unpack_pnf_phy_rel11_value},
-		{ NFAPI_PNF_PHY_REL12_TAG, &pNfapiMsg->pnf_phy_rel12, &unpack_pnf_phy_rel12_value},
-		{ NFAPI_PNF_PHY_REL13_TAG, &pNfapiMsg->pnf_phy_rel13, &unpack_pnf_phy_rel13_value},
-		{ NFAPI_PNF_PHY_REL13_NB_IOT_TAG, &pNfapiMsg->pnf_phy_rel13_nb_iot, &unpack_pnf_phy_rel13_nb_iot_value},
-	
-	};
-
-	return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-
-static uint8_t unpack_phy_rf_config_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_phy_rf_config_info_t* rf = (nfapi_phy_rf_config_info_t*)elem;
-		
-	return( pull16(ppReadPackedMsg, &rf->phy_id, end) &&
-			pull16(ppReadPackedMsg, &rf->phy_config_index, end) &&
-			pull16(ppReadPackedMsg, &rf->rf_config_index, end));
-
-}
-
-static uint8_t unpack_pnf_phy_rf_config_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_pnf_phy_rf_config_t* value = (nfapi_pnf_phy_rf_config_t*)tlv;
-
-	return ( pull16(ppReadPackedMsg, &value->number_phy_rf_config_info, end) &&
-			 unpackarray(ppReadPackedMsg, value->phy_rf_config, sizeof(nfapi_phy_rf_config_info_t), NFAPI_MAX_PHY_RF_INSTANCES, value->number_phy_rf_config_info, end, &unpack_phy_rf_config_info));
-}
-
-static uint8_t unpack_nr_pnf_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_config_request_t *pNfapiMsg = (nfapi_nr_pnf_config_request_t*)msg;
-	
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, &unpack_pnf_phy_rf_config_value},
-	};
-
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension);
-}
-
-
-
-static uint8_t unpack_pnf_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_config_request_t *pNfapiMsg = (nfapi_pnf_config_request_t*)msg;
-	
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, &unpack_pnf_phy_rf_config_value},
-	};
-
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension);
-}
-
-
-static uint8_t unpack_nr_pnf_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_config_response_t *pNfapiMsg = (nfapi_nr_pnf_config_response_t*)msg;
-	
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
-
-}
-
-static uint8_t unpack_pnf_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_config_response_t *pNfapiMsg = (nfapi_pnf_config_response_t*)msg;
-	
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
-
-}
-
-static uint8_t unpack_nr_pnf_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_start_request_t *pNfapiMsg = (nfapi_nr_pnf_start_request_t*)msg;
-	
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
-}
-
-
-static uint8_t unpack_pnf_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_start_request_t *pNfapiMsg = (nfapi_pnf_start_request_t*)msg;
-	
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
-}
-
-
-static uint8_t unpack_pnf_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_start_response_t *pNfapiMsg = (nfapi_pnf_start_response_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end ) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
-}
-
-static uint8_t unpack_nr_pnf_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_pnf_start_response_t *pNfapiMsg = (nfapi_nr_pnf_start_response_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end ) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
-}
-
-
-static uint8_t unpack_pnf_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_stop_request_t *pNfapiMsg = (nfapi_pnf_stop_request_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_pnf_stop_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_pnf_stop_response_t *pNfapiMsg = (nfapi_pnf_stop_response_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
-
-}
-
-static uint8_t unpack_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_param_request_t *pNfapiMsg = (nfapi_param_request_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_nr_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_param_request_scf_t *pNfapiMsg = (nfapi_nr_param_request_scf_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_L1_STATUS_PHY_STATE_TAG, &pNfapiMsg->l1_status.phy_state, &unpack_uint16_tlv_value},
-
-		{ NFAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, &pNfapiMsg->phy_capabilities.dl_bandwidth_support, &unpack_uint16_tlv_value},
-		{ NFAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, &pNfapiMsg->phy_capabilities.ul_bandwidth_support, &unpack_uint16_tlv_value},
-		{ NFAPI_PHY_CAPABILITIES_DL_MODULATION_SUPPORT_TAG, &pNfapiMsg->phy_capabilities.dl_modulation_support, &unpack_uint16_tlv_value},
-		{ NFAPI_PHY_CAPABILITIES_UL_MODULATION_SUPPORT_TAG, &pNfapiMsg->phy_capabilities.ul_modulation_support, &unpack_uint16_tlv_value},
-		{ NFAPI_PHY_CAPABILITIES_PHY_ANTENNA_CAPABILITY_TAG, &pNfapiMsg->phy_capabilities.phy_antenna_capability, &unpack_uint16_tlv_value},
-		{ NFAPI_PHY_CAPABILITIES_RELEASE_CAPABILITY_TAG, &pNfapiMsg->phy_capabilities.release_capability, &unpack_uint16_tlv_value},
-		{ NFAPI_PHY_CAPABILITIES_MBSFN_CAPABILITY_TAG, &pNfapiMsg->phy_capabilities.mbsfn_capability, &unpack_uint16_tlv_value},
-
-		{ NFAPI_LAA_CAPABILITY_LAA_SUPPORT_TAG, &pNfapiMsg->laa_capability.laa_support, &unpack_uint16_tlv_value},
-		{ NFAPI_LAA_CAPABILITY_PD_SENSING_LBT_SUPPORT_TAG, &pNfapiMsg->laa_capability.pd_sensing_lbt_support, &unpack_uint16_tlv_value},
-		{ NFAPI_LAA_CAPABILITY_MULTI_CARRIER_LBT_SUPPORT_TAG, &pNfapiMsg->laa_capability.multi_carrier_lbt_support, &unpack_uint16_tlv_value},
-		{ NFAPI_LAA_CAPABILITY_PARTIAL_SF_SUPPORT_TAG, &pNfapiMsg->laa_capability.partial_sf_support, &unpack_uint16_tlv_value},
-
-		{ NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &pNfapiMsg->subframe_config.duplex_mode, &unpack_uint16_tlv_value},
-		{ NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &pNfapiMsg->subframe_config.pcfich_power_offset, &unpack_uint16_tlv_value},
-		{ NFAPI_SUBFRAME_CONFIG_PB_TAG, &pNfapiMsg->subframe_config.pb, &unpack_uint16_tlv_value},
-		{ NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &pNfapiMsg->subframe_config.dl_cyclic_prefix_type, &unpack_uint16_tlv_value},
-		{ NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &pNfapiMsg->subframe_config.ul_cyclic_prefix_type, &unpack_uint16_tlv_value},
-
-		{ NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &pNfapiMsg->rf_config.dl_channel_bandwidth, &unpack_uint16_tlv_value},
-		{ NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &pNfapiMsg->rf_config.ul_channel_bandwidth, &unpack_uint16_tlv_value},
-		{ NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &pNfapiMsg->rf_config.reference_signal_power, &unpack_uint16_tlv_value},
-		{ NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &pNfapiMsg->rf_config.tx_antenna_ports, &unpack_uint16_tlv_value},
-		{ NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &pNfapiMsg->rf_config.rx_antenna_ports, &unpack_uint16_tlv_value},
-
-		{ NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &pNfapiMsg->phich_config.phich_resource, &unpack_uint16_tlv_value},
-		{ NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &pNfapiMsg->phich_config.phich_duration, &unpack_uint16_tlv_value},
-		{ NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &pNfapiMsg->phich_config.phich_power_offset, &unpack_uint16_tlv_value},
-
-		{ NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers, &unpack_uint16_tlv_value},
-		{ NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers, &unpack_uint16_tlv_value},
-		{ NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &pNfapiMsg->sch_config.physical_cell_id, &unpack_uint16_tlv_value},
-
-		{ NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &pNfapiMsg->prach_config.configuration_index, &unpack_uint16_tlv_value},
-		{ NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &pNfapiMsg->prach_config.root_sequence_index, &unpack_uint16_tlv_value},
-		{ NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &pNfapiMsg->prach_config.zero_correlation_zone_configuration, &unpack_uint16_tlv_value},
-		{ NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &pNfapiMsg->prach_config.high_speed_flag, &unpack_uint16_tlv_value},
-		{ NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &pNfapiMsg->prach_config.frequency_offset, &unpack_uint16_tlv_value},
-
-		{ NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &pNfapiMsg->pusch_config.hopping_mode, &unpack_uint16_tlv_value},
-		{ NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &pNfapiMsg->pusch_config.hopping_offset, &unpack_uint16_tlv_value},
-		{ NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &pNfapiMsg->pusch_config.number_of_subbands, &unpack_uint16_tlv_value},
-
-		{ NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &pNfapiMsg->pucch_config.delta_pucch_shift, &unpack_uint16_tlv_value},
-		{ NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &pNfapiMsg->pucch_config.n_cqi_rb, &unpack_uint16_tlv_value},
-		{ NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &pNfapiMsg->pucch_config.n_an_cs, &unpack_uint16_tlv_value},
-		{ NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &pNfapiMsg->pucch_config.n1_pucch_an, &unpack_uint16_tlv_value},
-
-		{ NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &pNfapiMsg->srs_config.bandwidth_configuration, &unpack_uint16_tlv_value},
-		{ NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &pNfapiMsg->srs_config.max_up_pts, &unpack_uint16_tlv_value},
-		{ NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &pNfapiMsg->srs_config.srs_subframe_configuration, &unpack_uint16_tlv_value},
-		{ NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission, &unpack_uint16_tlv_value},
-
-		{ NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping, &unpack_uint16_tlv_value},
-		{ NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &pNfapiMsg->uplink_reference_signal_config.group_assignment, &unpack_uint16_tlv_value},
-		{ NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms, &unpack_uint16_tlv_value},
-
-		{ NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &pNfapiMsg->tdd_frame_structure_config.subframe_assignment, &unpack_uint16_tlv_value},
-		{ NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns, &unpack_uint16_tlv_value},
-
-		{ NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &pNfapiMsg->l23_config.data_report_mode, &unpack_uint16_tlv_value},
-		{ NFAPI_L23_CONFIG_SFNSF_TAG, &pNfapiMsg->l23_config.sfnsf, &unpack_uint16_tlv_value},
-
-		{ NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv4, &unpack_ipv4_address_value},
-		{ NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv6, &unpack_ipv6_address_value},
-		{ NFAPI_NFAPI_P7_VNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_vnf_port, &unpack_uint16_tlv_value},
-		{ NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv4, &unpack_ipv4_address_value},
-		{ NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv6, &unpack_ipv6_address_value},
-		{ NFAPI_NFAPI_P7_PNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_pnf_port, &unpack_uint16_tlv_value},
-		{ NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &pNfapiMsg->nfapi_config.dl_ue_per_sf, &unpack_uint8_tlv_value},
-		{ NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &pNfapiMsg->nfapi_config.ul_ue_per_sf, &unpack_uint8_tlv_value},
-		{ NFAPI_NFAPI_RF_BANDS_TAG, &pNfapiMsg->nfapi_config.rf_bands, &unpack_rf_bands_value},
-		{ NFAPI_NFAPI_TIMING_WINDOW_TAG, &pNfapiMsg->nfapi_config.timing_window, &unpack_uint8_tlv_value},
-		{ NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &pNfapiMsg->nfapi_config.timing_info_mode, &unpack_uint8_tlv_value},
-		{ NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &pNfapiMsg->nfapi_config.timing_info_period, &unpack_uint8_tlv_value},
-		{ NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &pNfapiMsg->nfapi_config.max_transmit_power, &unpack_uint16_tlv_value},
-		{ NFAPI_NFAPI_EARFCN_TAG, &pNfapiMsg->nfapi_config.earfcn, &unpack_uint16_tlv_value},
-		{ NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands, &unpack_nmm_frequency_bands_value},
-		{ NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_umts_frequency_bands, &unpack_nmm_frequency_bands_value},
-		{ NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_lte_frequency_bands, &unpack_nmm_frequency_bands_value},
-		{ NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported, &unpack_uint8_tlv_value},
-
-	};
-
-	return ( pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			 pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-
-}
-
-static uint8_t unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_param_response_scf_t *pNfapiMsg = (nfapi_nr_param_response_scf_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{   
-		{ NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG, &(pNfapiMsg->cell_param.release_capability), &unpack_uint16_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PHY_STATE_TAG, &(pNfapiMsg->cell_param.phy_state),&unpack_uint16_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_dl_config), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_ul_config), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG, &(pNfapiMsg->cell_param.num_config_tlvs_to_report ), &unpack_uint16_tlv_value},
-		
-		{ NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG, &(pNfapiMsg->carrier_param.cyclic_prefix), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_dl), &unpack_uint16_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_dl), &unpack_uint16_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_ul), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_ul), &unpack_uint16_tlv_value},
-
-
-		{ NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG, &(pNfapiMsg->pdcch_param.cce_mapping_type), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG, &(pNfapiMsg->pdcch_param.coreset_outside_first_3_of_ofdm_syms_of_slot), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG, &(pNfapiMsg->pdcch_param.coreset_precoder_granularity_coreset), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG, &(pNfapiMsg->pdcch_param.pdcch_mu_mimo), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG, &(pNfapiMsg->pdcch_param.pdcch_precoder_cycling), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG, &(pNfapiMsg->pdcch_param.max_pdcch_per_slot), &unpack_uint8_tlv_value},
-		
-		{ NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG, &(pNfapiMsg->pucch_param.pucch_formats), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG, &(pNfapiMsg->pucch_param.max_pucchs_per_slot), &unpack_uint8_tlv_value},
-		
-		{ NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pdsch_param.pdsch_mapping_type), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_allocation_types), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pdsch_param.pdsch_vrb_to_prb_mapping), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG, &(pNfapiMsg->pdsch_param.pdsch_cbg), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_config_types), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PDSCH_DMRS_MAX_LENGTH_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_max_length), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_additional_pos), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_MAX_PDSCH_S_YBS_PER_SLOT_TAG, &(pNfapiMsg->pdsch_param.max_pdsch_tbs_per_slot), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG, &(pNfapiMsg->pdsch_param.max_number_mimo_layers_pdsch), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG, &(pNfapiMsg->pdsch_param.max_mu_mimo_users_dl), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG, &(pNfapiMsg->pdsch_param.pdsch_data_in_dmrs_symbols), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.premption_support), &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.pdsch_non_slot_support), &unpack_uint8_tlv_value},
-
-		{ NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG,  &(pNfapiMsg->pusch_param.uci_mux_ulsch_in_pusch),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG,  &(pNfapiMsg->pusch_param.uci_only_pusch),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG,  &(pNfapiMsg->pusch_param.pusch_frequency_hopping),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG,  &(pNfapiMsg->pusch_param.pusch_dmrs_config_types),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG,  &(pNfapiMsg->pusch_param.pusch_dmrs_max_len),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG,  &(pNfapiMsg->pusch_param.pusch_dmrs_additional_pos),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG,  &(pNfapiMsg->pusch_param.pusch_cbg),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG,  &(pNfapiMsg->pusch_param.pusch_mapping_type),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG,  &(pNfapiMsg->pusch_param.pusch_allocation_types),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG,  &(pNfapiMsg->pusch_param.pusch_vrb_to_prb_mapping),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG,  &(pNfapiMsg->pusch_param.pusch_max_ptrs_ports),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG,  &(pNfapiMsg->pusch_param.max_pduschs_tbs_per_slot),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG,  &(pNfapiMsg->pusch_param.max_number_mimo_layers_non_cb_pusch),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG,  &(pNfapiMsg->pusch_param.supported_modulation_order_ul),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG,  &(pNfapiMsg->pusch_param.max_mu_mimo_users_ul),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG,  &(pNfapiMsg->pusch_param.dfts_ofdm_support),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG,  &(pNfapiMsg->pusch_param.pusch_aggregation_factor),  &unpack_uint8_tlv_value},
-		
-		{ NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG,  &(pNfapiMsg->prach_param.prach_long_formats),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG,  &(pNfapiMsg->prach_param.prach_short_formats),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG,  &(pNfapiMsg->prach_param.prach_restricted_sets),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG,  &(pNfapiMsg->prach_param.max_prach_fd_occasions_in_a_slot),  &unpack_uint8_tlv_value},
-		
-		{ NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG,  &(pNfapiMsg->measurement_param.rssi_measurement_support),  &unpack_uint8_tlv_value},
-		//config
-		{ NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv4, &unpack_ipv4_address_value},
-		{ NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv6, &unpack_ipv6_address_value},
-		{ NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_vnf_port, &unpack_uint16_tlv_value},
-		{ NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv4, &unpack_ipv4_address_value},
-		{ NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv6, &unpack_ipv6_address_value},
-		{ NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_pnf_port, &unpack_uint16_tlv_value},
-		{ NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &pNfapiMsg->nfapi_config.timing_window, &unpack_uint8_tlv_value},
-		{ NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &pNfapiMsg->nfapi_config.timing_info_mode, &unpack_uint8_tlv_value},
-		{ NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &pNfapiMsg->nfapi_config.timing_info_period, &unpack_uint8_tlv_value},
-	};
-	// print ppReadPackedMsg
-	uint8_t *ptr = *ppReadPackedMsg;
-	printf("\n Read message unpack_param_response: ");
-	while(ptr < end){
-		printf(" %d ", *ptr);
-		ptr++;
-	}
-	printf("\n");
-
-
-	return ( pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			 pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-
-}
-
-static uint8_t unpack_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_config_request_t *pNfapiMsg = (nfapi_config_request_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &pNfapiMsg->subframe_config.duplex_mode, &unpack_uint16_tlv_value},
-		{ NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &pNfapiMsg->subframe_config.pcfich_power_offset, &unpack_uint16_tlv_value},
-		{ NFAPI_SUBFRAME_CONFIG_PB_TAG, &pNfapiMsg->subframe_config.pb, &unpack_uint16_tlv_value},
-		{ NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &pNfapiMsg->subframe_config.dl_cyclic_prefix_type, &unpack_uint16_tlv_value},
-		{ NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &pNfapiMsg->subframe_config.ul_cyclic_prefix_type, &unpack_uint16_tlv_value},
-
-		{ NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &pNfapiMsg->rf_config.dl_channel_bandwidth, &unpack_uint16_tlv_value},
-		{ NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &pNfapiMsg->rf_config.ul_channel_bandwidth, &unpack_uint16_tlv_value},
-		{ NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &pNfapiMsg->rf_config.reference_signal_power, &unpack_uint16_tlv_value},
-		{ NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &pNfapiMsg->rf_config.tx_antenna_ports, &unpack_uint16_tlv_value},
-		{ NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &pNfapiMsg->rf_config.rx_antenna_ports, &unpack_uint16_tlv_value},
-
-		{ NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &pNfapiMsg->phich_config.phich_resource, &unpack_uint16_tlv_value},
-		{ NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &pNfapiMsg->phich_config.phich_duration, &unpack_uint16_tlv_value},
-		{ NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &pNfapiMsg->phich_config.phich_power_offset, &unpack_uint16_tlv_value},
-
-		{ NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers, &unpack_uint16_tlv_value},
-		{ NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers, &unpack_uint16_tlv_value},
-		{ NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &pNfapiMsg->sch_config.physical_cell_id, &unpack_uint16_tlv_value},
-
-		{ NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &pNfapiMsg->prach_config.configuration_index, &unpack_uint16_tlv_value},
-		{ NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &pNfapiMsg->prach_config.root_sequence_index, &unpack_uint16_tlv_value},
-		{ NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &pNfapiMsg->prach_config.zero_correlation_zone_configuration, &unpack_uint16_tlv_value},
-		{ NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &pNfapiMsg->prach_config.high_speed_flag, &unpack_uint16_tlv_value},
-		{ NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &pNfapiMsg->prach_config.frequency_offset, &unpack_uint16_tlv_value},
-
-		{ NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &pNfapiMsg->pusch_config.hopping_mode, &unpack_uint16_tlv_value},
-		{ NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &pNfapiMsg->pusch_config.hopping_offset, &unpack_uint16_tlv_value},
-		{ NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &pNfapiMsg->pusch_config.number_of_subbands, &unpack_uint16_tlv_value},
-
-		{ NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &pNfapiMsg->pucch_config.delta_pucch_shift, &unpack_uint16_tlv_value},
-		{ NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &pNfapiMsg->pucch_config.n_cqi_rb, &unpack_uint16_tlv_value},
-		{ NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &pNfapiMsg->pucch_config.n_an_cs, &unpack_uint16_tlv_value},
-		{ NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &pNfapiMsg->pucch_config.n1_pucch_an, &unpack_uint16_tlv_value},
-
-		{ NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &pNfapiMsg->srs_config.bandwidth_configuration, &unpack_uint16_tlv_value},
-		{ NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &pNfapiMsg->srs_config.max_up_pts, &unpack_uint16_tlv_value},
-		{ NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &pNfapiMsg->srs_config.srs_subframe_configuration, &unpack_uint16_tlv_value},
-		{ NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission, &unpack_uint16_tlv_value},
-
-		{ NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping, &unpack_uint16_tlv_value},
-		{ NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &pNfapiMsg->uplink_reference_signal_config.group_assignment, &unpack_uint16_tlv_value},
-		{ NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms, &unpack_uint16_tlv_value},
-
-
-		{ NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_PDSCH_TAG, &pNfapiMsg->laa_config.ed_threshold_lbt_pdsch, &unpack_uint16_tlv_value},
-		{ NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_DRS_TAG, &pNfapiMsg->laa_config.ed_threshold_lbt_drs, &unpack_uint16_tlv_value},
-		{ NFAPI_LAA_CONFIG_PD_THRESHOLD_TAG, &pNfapiMsg->laa_config.pd_threshold, &unpack_uint16_tlv_value},
-		{ NFAPI_LAA_CONFIG_MULTI_CARRIER_TYPE_TAG, &pNfapiMsg->laa_config.multi_carrier_type, &unpack_uint16_tlv_value},
-		{ NFAPI_LAA_CONFIG_MULTI_CARRIER_TX_TAG, &pNfapiMsg->laa_config.multi_carrier_tx, &unpack_uint16_tlv_value},
-		{ NFAPI_LAA_CONFIG_MULTI_CARRIER_FREEZE_TAG, &pNfapiMsg->laa_config.multi_carrier_freeze, &unpack_uint16_tlv_value},
-		{ NFAPI_LAA_CONFIG_TX_ANTENNA_PORTS_FOR_DRS_TAG, &pNfapiMsg->laa_config.tx_antenna_ports_drs, &unpack_uint16_tlv_value},
-		{ NFAPI_LAA_CONFIG_TRANSMISSION_POWER_FOR_DRS_TAG, &pNfapiMsg->laa_config.tx_power_drs, &unpack_uint16_tlv_value},
-
-		{ NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG, &pNfapiMsg->emtc_config.pbch_repetitions_enable_r13, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG, &pNfapiMsg->emtc_config.prach_catm_root_sequence_index, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &pNfapiMsg->emtc_config.prach_catm_zero_correlation_zone_configuration, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG, &pNfapiMsg->emtc_config.prach_catm_high_speed_flag, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_enable, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_configuration_index, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_frequency_offset, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_starting_subframe_periodicity, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_hopping_enable, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_hopping_offset, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_enable, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_configuration_index, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_frequency_offset, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_starting_subframe_periodicity, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_hopping_enable, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_hopping_offset, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_enable, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_configuration_index, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_frequency_offset, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_starting_subframe_periodicity, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_hopping_enable, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_hopping_offset, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_enable, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_configuration_index, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_frequency_offset, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_starting_subframe_periodicity, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_hopping_enable, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_hopping_offset, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG, &pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea, &unpack_uint16_tlv_value},
-		{ NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG, &pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb, &unpack_uint16_tlv_value},
-
-		{ NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &pNfapiMsg->tdd_frame_structure_config.subframe_assignment, &unpack_uint16_tlv_value},
-		{ NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns, &unpack_uint16_tlv_value},
-
-		{ NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &pNfapiMsg->l23_config.data_report_mode, &unpack_uint16_tlv_value},
-		{ NFAPI_L23_CONFIG_SFNSF_TAG, &pNfapiMsg->l23_config.sfnsf, &unpack_uint16_tlv_value},
-
-		{ NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv4, &unpack_ipv4_address_value},
-		{ NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv6, &unpack_ipv6_address_value},
-		{ NFAPI_NFAPI_P7_VNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_vnf_port, &unpack_uint16_tlv_value},
-		{ NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv4, &unpack_ipv4_address_value},
-		{ NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv6, &unpack_ipv6_address_value},
-		{ NFAPI_NFAPI_P7_PNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_pnf_port, &unpack_uint16_tlv_value},
-		{ NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &pNfapiMsg->nfapi_config.dl_ue_per_sf, &unpack_uint8_tlv_value},
-		{ NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &pNfapiMsg->nfapi_config.ul_ue_per_sf, &unpack_uint8_tlv_value},
-		{ NFAPI_NFAPI_RF_BANDS_TAG, &pNfapiMsg->nfapi_config.rf_bands, &unpack_rf_bands_value},
-		{ NFAPI_NFAPI_TIMING_WINDOW_TAG, &pNfapiMsg->nfapi_config.timing_window, &unpack_uint8_tlv_value},
-		{ NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &pNfapiMsg->nfapi_config.timing_info_mode, &unpack_uint8_tlv_value},
-		{ NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &pNfapiMsg->nfapi_config.timing_info_period, &unpack_uint8_tlv_value},
-		{ NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &pNfapiMsg->nfapi_config.max_transmit_power, &unpack_uint16_tlv_value},
-		{ NFAPI_NFAPI_EARFCN_TAG, &pNfapiMsg->nfapi_config.earfcn, &unpack_uint16_tlv_value},
-		{ NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands, &unpack_nmm_frequency_bands_value},
-		{ NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_umts_frequency_bands, &unpack_nmm_frequency_bands_value},
-		{ NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_lte_frequency_bands, &unpack_nmm_frequency_bands_value},
-		{ NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported, &unpack_uint8_tlv_value},
-
-	};
-
-	return ( pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) &&
-		     unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-
-}
-static uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_config_request_scf_t *pNfapiMsg = (nfapi_nr_config_request_scf_t*)msg;
-
-	pNfapiMsg->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t*) malloc(20*sizeof(nfapi_nr_max_tdd_periodicity_t));
-	for(int i=0;i<40;i++)
-	pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list = (nfapi_nr_max_num_of_symbol_per_slot_t*) malloc(14*sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
-
-    pNfapiMsg->prach_config.num_prach_fd_occasions_list=(nfapi_nr_num_prach_fd_occasions_t *) malloc(sizeof(nfapi_nr_num_prach_fd_occasions_t));
-
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG,  &(pNfapiMsg->carrier_config.dl_bandwidth),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_CONFIG_DL_FREQUENCY_TAG,  &(pNfapiMsg->carrier_config.dl_frequency),  &unpack_uint32_tlv_value},
-		{ NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG,  &(pNfapiMsg->carrier_config.dl_grid_size[1]),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_CONFIG_DL_K0_TAG,  &(pNfapiMsg->carrier_config.dl_k0[1]),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_CONFIG_NUM_RX_ANT_TAG,  &(pNfapiMsg->carrier_config.num_rx_ant),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_CONFIG_NUM_TX_ANT_TAG,  &(pNfapiMsg->carrier_config.num_tx_ant),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG,  &(pNfapiMsg->carrier_config.ul_grid_size[1]),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_CONFIG_UL_K0_TAG,  &(pNfapiMsg->carrier_config.ul_k0[1]),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG,  &(pNfapiMsg->carrier_config.uplink_bandwidth),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG,  &(pNfapiMsg->carrier_config.uplink_frequency),  &unpack_uint32_tlv_value},
-		{ NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG,  &(pNfapiMsg->cell_config.frame_duplex_type),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_PHY_CELL_ID_TAG,  &(pNfapiMsg->cell_config.phy_cell_id),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG,  &(pNfapiMsg->prach_config.num_prach_fd_occasions),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG,  &(pNfapiMsg->prach_config.prach_sequence_length),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG,  &(pNfapiMsg->prach_config.restricted_set_config),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_SSB_PER_RACH_TAG,  &(pNfapiMsg->prach_config.ssb_per_rach),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG,  &(pNfapiMsg->prach_config.prach_sub_c_spacing),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG,  &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_root_sequence_index),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_CONFIG_K1_TAG,  &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].k1),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG,  &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_zero_corr_conf),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG,  &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].num_root_sequences),  &unpack_uint8_tlv_value},
-
-		{ NFAPI_NR_CONFIG_SCS_COMMON_TAG,  &(pNfapiMsg->ssb_config.scs_common),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG,  &(pNfapiMsg->ssb_config.ss_pbch_power),  &unpack_uint32_tlv_value},
-		{ NFAPI_NR_CONFIG_BETA_PSS_TAG,  &(pNfapiMsg->ssb_table.beta_pss),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_MIB_TAG,  &(pNfapiMsg->ssb_table.MIB),  &unpack_uint32_tlv_value},
-		{ NFAPI_NR_CONFIG_SSB_MASK_TAG,  &(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask),  &unpack_uint32_tlv_value},
-		{ NFAPI_NR_CONFIG_SSB_MASK_TAG,  &(pNfapiMsg->ssb_table.ssb_mask_list[1].ssb_mask),  &unpack_uint32_tlv_value},
-
-		{ NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG,  &(pNfapiMsg->ssb_table.ssb_offset_point_a),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_CONFIG_SSB_PERIOD_TAG,  &(pNfapiMsg->ssb_table.ssb_period),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG,  &(pNfapiMsg->ssb_table.ssb_subcarrier_offset),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_TDD_PERIOD_TAG,  &(pNfapiMsg->tdd_table.tdd_period),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,  &(pNfapiMsg->tdd_table.max_tdd_periodicity_list[0].max_num_of_symbol_per_slot_list[0].slot_config),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG,  &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4),  &unpack_ipv4_address_value},
-		{ NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG,  &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6),  &unpack_ipv6_address_value},
-		{ NFAPI_NR_NFAPI_P7_PNF_PORT_TAG,  &(pNfapiMsg->nfapi_config.p7_pnf_port),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG,  &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4),  &unpack_ipv4_address_value},
-		{ NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG,  &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6),  &unpack_ipv6_address_value},
-		{ NFAPI_NR_NFAPI_P7_VNF_PORT_TAG,  &(pNfapiMsg->nfapi_config.p7_vnf_port),  &unpack_uint16_tlv_value},
-		{ NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG,  &(pNfapiMsg->nfapi_config.timing_info_mode),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG,  &(pNfapiMsg->nfapi_config.timing_info_period),  &unpack_uint8_tlv_value},
-		{ NFAPI_NR_NFAPI_TIMING_WINDOW_TAG,  &(pNfapiMsg->nfapi_config.timing_window),  &unpack_uint8_tlv_value},
-	};
-	return ( pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-
-}
-
-static uint8_t unpack_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_config_response_t *pNfapiMsg = (nfapi_config_response_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && 
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
-}
-
-static uint8_t unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_config_response_scf_t *pNfapiMsg = (nfapi_nr_config_response_scf_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return ( pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) && 
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
-}
-
-static uint8_t unpack_nr_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	 nfapi_nr_start_request_scf_t *pNfapiMsg = ( nfapi_nr_start_request_scf_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	 nfapi_start_request_t *pNfapiMsg = ( nfapi_start_request_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_start_response_t *pNfapiMsg = (nfapi_start_response_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
-
-}
-
-static uint8_t unpack_nr_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_nr_start_response_scf_t *pNfapiMsg = (nfapi_nr_start_response_scf_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
-
-}
-
-static uint8_t unpack_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_stop_request_t *pNfapiMsg = (nfapi_stop_request_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_stop_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_stop_response_t *pNfapiMsg = (nfapi_stop_response_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-	};
-
-	return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
-
-}
-static uint8_t unpack_measurement_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_measurement_request_t *pNfapiMsg = (nfapi_measurement_request_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_MEASUREMENT_REQUEST_DL_RS_XTX_POWER_TAG, &pNfapiMsg->dl_rs_tx_power, &unpack_uint16_tlv_value},
-		{ NFAPI_MEASUREMENT_REQUEST_RECEIVED_INTERFERENCE_POWER_TAG, &pNfapiMsg->received_interference_power, &unpack_uint16_tlv_value},
-		{ NFAPI_MEASUREMENT_REQUEST_THERMAL_NOISE_POWER_TAG, &pNfapiMsg->thermal_noise_power, &unpack_uint16_tlv_value},
-	};
-
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
-
-}
-
-static uint8_t unpack_received_interference_power_measurement_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_received_interference_power_measurement_t* value = (nfapi_received_interference_power_measurement_t*)tlv;
-
-	return ( pull16(ppReadPackedMsg, &value->number_of_resource_blocks, end) &&
-			 pullarrays16(ppReadPackedMsg, value->received_interference_power,  NFAPI_MAX_RECEIVED_INTERFERENCE_POWER_RESULTS, value->number_of_resource_blocks, end)); 
-}
-
-
-static uint8_t unpack_measurement_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_measurement_response_t *pNfapiMsg = (nfapi_measurement_response_t*)msg;
-
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_MEASUREMENT_RESPONSE_DL_RS_POWER_MEASUREMENT_TAG, &pNfapiMsg->dl_rs_tx_power_measurement, &unpack_int16_tlv_value},
-		{ NFAPI_MEASUREMENT_RESPONSE_RECEIVED_INTERFERENCE_POWER_MEASUREMENT_TAG, &pNfapiMsg->received_interference_power_measurement, &unpack_received_interference_power_measurement_value},
-		{ NFAPI_MEASUREMENT_RESPONSE_THERMAL_NOISE_MEASUREMENT_TAG, &pNfapiMsg->thermal_noise_power_measurement, &unpack_int16_tlv_value},
-	};
-
-	return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
-			 unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-
-}
-
-// unpack length check
-
-static int check_nr_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpackedBufLen)
-{
-	int retLen = 0;
-
-	switch (msgId)
-	{
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_pnf_param_request_t))
-				retLen = sizeof(nfapi_pnf_param_request_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_nr_pnf_param_response_t))
-				retLen = sizeof(nfapi_nr_pnf_param_response_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_pnf_config_request_t))
-				retLen = sizeof(nfapi_nr_pnf_config_request_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_nr_pnf_config_response_t))
-				retLen = sizeof(nfapi_nr_pnf_config_response_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_pnf_start_request_t))
-				retLen = sizeof(nfapi_nr_pnf_start_request_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_nr_pnf_start_response_t))
-				retLen = sizeof(nfapi_nr_pnf_start_response_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_pnf_stop_request_t))
-				retLen = sizeof(nfapi_nr_pnf_stop_request_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_nr_pnf_stop_response_t))
-				retLen = sizeof(nfapi_nr_pnf_stop_response_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_param_request_scf_t))
-				retLen = sizeof(nfapi_nr_param_request_scf_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_nr_param_response_scf_t))
-				retLen = sizeof(nfapi_nr_param_response_scf_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_config_request_scf_t))
-				retLen = sizeof(nfapi_nr_config_request_scf_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_nr_config_response_scf_t))
-				retLen = sizeof(nfapi_nr_config_response_scf_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
-			if (unpackedBufLen >= sizeof( nfapi_nr_start_request_scf_t))
-				retLen = sizeof( nfapi_nr_start_request_scf_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_nr_start_response_scf_t))
-				retLen = sizeof(nfapi_nr_start_response_scf_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_stop_request_t))
-				retLen = sizeof(nfapi_stop_request_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_stop_response_t))
-				retLen = sizeof(nfapi_stop_response_t);
-			break;
-		default:
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s Unknown message ID %d\n", __FUNCTION__, msgId);
-			break;
-	}
-
-	return retLen;
-}
-
-
-static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen)
-{
-	int retLen = 0;
-
-	switch (msgId)
-	{
-		case NFAPI_PNF_PARAM_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_pnf_param_request_t))
-				retLen = sizeof(nfapi_pnf_param_request_t);
-			break;
-
-		case NFAPI_PNF_PARAM_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_pnf_param_response_t))
-				retLen = sizeof(nfapi_pnf_param_response_t);
-			break;
-
-		case NFAPI_PNF_CONFIG_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_pnf_config_request_t))
-				retLen = sizeof(nfapi_pnf_config_request_t);
-			break;
-
-		case NFAPI_PNF_CONFIG_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_pnf_config_response_t))
-				retLen = sizeof(nfapi_pnf_config_response_t);
-			break;
-
-		case NFAPI_PNF_START_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_pnf_start_request_t))
-				retLen = sizeof(nfapi_pnf_start_request_t);
-			break;
-
-		case NFAPI_PNF_START_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_pnf_start_response_t))
-				retLen = sizeof(nfapi_pnf_start_response_t);
-			break;
-
-		case NFAPI_PNF_STOP_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_pnf_stop_request_t))
-				retLen = sizeof(nfapi_pnf_stop_request_t);
-			break;
-
-		case NFAPI_PNF_STOP_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_pnf_stop_response_t))
-				retLen = sizeof(nfapi_pnf_stop_response_t);
-			break;
-
-		case NFAPI_PARAM_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_param_request_t))
-				retLen = sizeof(nfapi_param_request_t);
-			break;
-
-		case NFAPI_PARAM_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_param_response_t))
-				retLen = sizeof(nfapi_param_response_t);
-			break;
-
-		case NFAPI_CONFIG_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_config_request_t))
-				retLen = sizeof(nfapi_config_request_t);
-			break;
-
-		case NFAPI_CONFIG_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_config_response_t))
-				retLen = sizeof(nfapi_config_response_t);
-			break;
-
-		case NFAPI_START_REQUEST:
-			if (unpackedBufLen >= sizeof( nfapi_start_request_t))
-				retLen = sizeof( nfapi_start_request_t);
-			break;
-
-		case NFAPI_START_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_start_response_t))
-				retLen = sizeof(nfapi_start_response_t);
-			break;
-
-		case NFAPI_STOP_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_stop_request_t))
-				retLen = sizeof(nfapi_stop_request_t);
-			break;
-
-		case NFAPI_STOP_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_stop_response_t))
-				retLen = sizeof(nfapi_stop_response_t);
-			break;
-
-		case NFAPI_MEASUREMENT_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_measurement_request_t))
-				retLen = sizeof(nfapi_measurement_request_t);
-			break;
-
-		case NFAPI_MEASUREMENT_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_measurement_response_t))
-				retLen = sizeof(nfapi_measurement_response_t);
-			break;
-
-		default:
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s Unknown message ID %d\n", __FUNCTION__, msgId);
-			break;
-	}
-
-	return retLen;
-}
-
-
-// Main unpack functions - public
-
-int nfapi_p5_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
-	uint8_t *pReadPackedMessage = pMessageBuf;
-	uint8_t *end = pMessageBuf + messageBufLen;
-
-	if (pMessageBuf == NULL || pUnpackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied pointers are null\n");
-		return -1;
-	}
-
-	if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
-		return -1;
-	}
-
-	// process the header
-	return ( pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
-			 pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-			 pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-			 pull16(&pReadPackedMessage, &pMessageHeader->spare, end) );
-
-}
-
-int nfapi_nr_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
-	uint8_t *pReadPackedMessage = pMessageBuf;
-	uint8_t *end = pMessageBuf + messageBufLen;
-
-	if (pMessageBuf == NULL || pUnpackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied pointers are null\n");
-		return -1;
-	}
-
-	if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
-		return -1;
-	}
-
-	uint8_t *ptr = pReadPackedMessage;
-	printf("\n Read message unpack: ");
-	while(ptr < end){
-		printf(" %d ", *ptr);
-		ptr++;
-	}
-	printf("\n");
-	
-	// clean the supplied buffer for - tag value blanking
-	(void)memset(pUnpackedBuf, 0, unpackedBufLen);
-
-	// process the header
-	if( !(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end ) && 
-		  pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-		  pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-		  pull16(&pReadPackedMessage, &pMessageHeader->spare, end)))
-	{
-		// failed to read the header
-		return -1;
-	}
-
-	int result = -1;
-
-
-	if(check_nr_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0)
-	{
-		// the unpack buffer is not big enough for the struct 
-		return -1;
-	}
-
-	// look for the specific message
-	switch (pMessageHeader->message_id)
-	{
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
-			result = unpack_nr_pnf_param_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE:
-			result = unpack_nr_pnf_param_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
-			result = unpack_nr_pnf_config_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE:
-			result = unpack_nr_pnf_config_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
-			result = unpack_nr_pnf_start_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE:
-			result = unpack_nr_pnf_start_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST:
-			result = unpack_pnf_stop_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_RESPONSE:
-			result = unpack_pnf_stop_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
-			result = unpack_nr_param_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
-			result = unpack_nr_param_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
-			result = unpack_nr_config_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
-			result = unpack_nr_config_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
-			result = unpack_nr_start_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
-			result = unpack_nr_start_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
-			result = unpack_stop_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
-			result = unpack_stop_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_MEASUREMENT_REQUEST:
-			result = unpack_measurement_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_MEASUREMENT_RESPONSE:
-			result = unpack_measurement_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		default:
-			if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && 
-			   pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
-			{
-				if(config && config->unpack_p4_p5_vendor_extension)
-				{
-					result = (config->unpack_p4_p5_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
-				}
-			}
-			else
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown P5 message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
-			}
-			break;
-	}
-
-	return result;
-}
-
-int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config)
-{
-	nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
-	uint8_t *pReadPackedMessage = pMessageBuf;
-	uint8_t *end = pMessageBuf + messageBufLen;
-
-	if (pMessageBuf == NULL || pUnpackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied pointers are null\n");
-		return -1;
-	}
-
-	if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
-		return -1;
-	}
-
-	uint8_t *ptr = pReadPackedMessage;
-	printf("\n Read message unpack: ");
-	while(ptr < end){
-		printf(" %d ", *ptr);
-		ptr++;
-	}
-	printf("\n");
-	
-	// clean the supplied buffer for - tag value blanking
-	(void)memset(pUnpackedBuf, 0, unpackedBufLen);
-
-	// process the header
-	if( !(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end ) && 
-		  pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-		  pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-		  pull16(&pReadPackedMessage, &pMessageHeader->spare, end)))
-	{
-		// failed to read the header
-		return -1;
-	}
-
-	int result = -1;
-
-
-	if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0)
-	{
-		// the unpack buffer is not big enough for the struct 
-		return -1;
-	}
-
-	// look for the specific message
-	switch (pMessageHeader->message_id)
-	{
-		case NFAPI_PNF_PARAM_REQUEST:
-			result = unpack_pnf_param_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_PNF_PARAM_RESPONSE:
-			result = unpack_pnf_param_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_PNF_CONFIG_REQUEST:
-			result = unpack_pnf_config_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_PNF_CONFIG_RESPONSE:
-			result = unpack_pnf_config_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_PNF_START_REQUEST:
-			result = unpack_pnf_start_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_PNF_START_RESPONSE:
-			result = unpack_pnf_start_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_PNF_STOP_REQUEST:
-			result = unpack_pnf_stop_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_PNF_STOP_RESPONSE:
-			result = unpack_pnf_stop_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_PARAM_REQUEST:
-			result = unpack_param_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_PARAM_RESPONSE:
-			result = unpack_param_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_CONFIG_REQUEST:
-			result = unpack_config_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_CONFIG_RESPONSE:
-			result = unpack_config_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_START_REQUEST:
-			result = unpack_start_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_START_RESPONSE:
-			result = unpack_start_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_STOP_REQUEST:
-			result = unpack_stop_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_STOP_RESPONSE:
-			result = unpack_stop_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_MEASUREMENT_REQUEST:
-			result = unpack_measurement_request(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		case NFAPI_MEASUREMENT_RESPONSE:
-			result = unpack_measurement_response(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
-
-		default:
-			if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && 
-			   pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
-			{
-				if(config && config->unpack_p4_p5_vendor_extension)
-				{
-					result = (config->unpack_p4_p5_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
-				}
-			}
-			else
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown P5 message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
-			}
-			break;
-	}
-
-	return result;
-}
-
+/*
+ * Copyright 2017 Cisco Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sched.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdint.h>
+
+#include <nfapi_interface.h>
+#include <nfapi.h>
+#include "nfapi_nr_interface.h"
+#include "nfapi_nr_interface_scf.h"
+#include <debug.h>
+
+
+// Pack routines
+//TODO: Add pacl/unpack fns for uint32 and uint64
+static uint8_t pack_nr_pnf_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_param_request_t *request = (nfapi_nr_pnf_param_request_t *)msg;
+  return pack_vendor_extension_tlv(request->vendor_extension, ppWritePackedMsg, end, config);
+}
+
+static uint8_t pack_pnf_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_param_request_t *request = (nfapi_pnf_param_request_t *)msg;
+  return pack_vendor_extension_tlv(request->vendor_extension, ppWritePackedMsg, end, config);
+}
+
+static uint8_t pack_pnf_param_general_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_param_general_t *value = (nfapi_pnf_param_general_t *)tlv;
+  return ( push8(value->nfapi_sync_mode, ppWritePackedMsg, end) &&
+           push8(value->location_mode, ppWritePackedMsg, end) &&
+           push16(value->location_coordinates_length, ppWritePackedMsg, end) &&
+           pusharray8(value->location_coordinates, NFAPI_PNF_PARAM_GENERAL_LOCATION_LENGTH, value->location_coordinates_length, ppWritePackedMsg, end) &&
+           push32(value->dl_config_timing, ppWritePackedMsg, end) &&
+           push32(value->tx_timing, ppWritePackedMsg, end) &&
+           push32(value->ul_config_timing, ppWritePackedMsg, end) &&
+           push32(value->hi_dci0_timing, ppWritePackedMsg, end) &&
+           push16(value->maximum_number_phys, ppWritePackedMsg, end) &&
+           push16(value->maximum_total_bandwidth, ppWritePackedMsg, end) &&
+           push8(value->maximum_total_number_dl_layers, ppWritePackedMsg, end) &&
+           push8(value->maximum_total_number_ul_layers, ppWritePackedMsg, end) &&
+           push8(value->shared_bands, ppWritePackedMsg, end) &&
+           push8(value->shared_pa, ppWritePackedMsg, end) &&
+           pushs16(value->maximum_total_power, ppWritePackedMsg, end) &&
+           pusharray8(value->oui, NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH, NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_rf_config_info(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_rf_config_info_t *rf = (nfapi_rf_config_info_t *)elem;
+  return (push16(rf->rf_config_index, ppWritePackedMsg, end));
+}
+
+
+static uint8_t pack_pnf_phy_info(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_info_t *phy = (nfapi_pnf_phy_info_t *)elem;
+  return (  push16(phy->phy_config_index, ppWritePackedMsg, end) &&
+            push16(phy->number_of_rfs, ppWritePackedMsg, end) &&
+            packarray(phy->rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rfs, ppWritePackedMsg, end, &pack_rf_config_info) &&
+            push16(phy->number_of_rf_exclusions, ppWritePackedMsg, end) &&
+            packarray(phy->excluded_rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rf_exclusions, ppWritePackedMsg, end, &pack_rf_config_info) &&
+            push16(phy->downlink_channel_bandwidth_supported, ppWritePackedMsg, end) &&
+            push16(phy->uplink_channel_bandwidth_supported, ppWritePackedMsg, end) &&
+            push8(phy->number_of_dl_layers_supported, ppWritePackedMsg, end) &&
+            push8(phy->number_of_ul_layers_supported, ppWritePackedMsg, end) &&
+            push16(phy->maximum_3gpp_release_supported, ppWritePackedMsg, end) &&
+            push8(phy->nmm_modes_supported, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_pnf_phy_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_t *value = (nfapi_pnf_phy_t *)tlv;
+  return ( push16(value->number_of_phys, ppWritePackedMsg, end) &&
+           packarray(value->phy, sizeof(nfapi_pnf_phy_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_info));
+}
+
+static uint8_t pack_pnf_rf_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_rf_t *value = (nfapi_pnf_rf_t *)tlv;
+  uint16_t rf_index = 0;
+
+  if(push16(value->number_of_rfs, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  for(; rf_index < value->number_of_rfs; ++rf_index) {
+    if( !(push16(value->rf[rf_index].rf_config_index, ppWritePackedMsg, end) &&
+          push16(value->rf[rf_index].band, ppWritePackedMsg, end) &&
+          pushs16(value->rf[rf_index].maximum_transmit_power, ppWritePackedMsg, end) &&
+          pushs16(value->rf[rf_index].minimum_transmit_power, ppWritePackedMsg, end) &&
+          push8(value->rf[rf_index].number_of_antennas_suppported, ppWritePackedMsg, end) &&
+          push32(value->rf[rf_index].minimum_downlink_frequency, ppWritePackedMsg, end) &&
+          push32(value->rf[rf_index].maximum_downlink_frequency, ppWritePackedMsg, end) &&
+          push32(value->rf[rf_index].minimum_uplink_frequency, ppWritePackedMsg, end) &&
+          push32(value->rf[rf_index].maximum_uplink_frequency, ppWritePackedMsg, end)))
+      return 0;
+  }
+
+  return 1;
+}
+static uint8_t pack_pnf_phy_rel10_info(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel10_info_t *phy = (nfapi_pnf_phy_rel10_info_t *)elem;
+  return(push16(phy->phy_config_index, ppWritePackedMsg, end) &&
+         push16(phy->transmission_mode_7_supported, ppWritePackedMsg, end) &&
+         push16(phy->transmission_mode_8_supported, ppWritePackedMsg, end) &&
+         push16(phy->two_antenna_ports_for_pucch, ppWritePackedMsg, end) &&
+         push16(phy->transmission_mode_9_supported, ppWritePackedMsg, end) &&
+         push16(phy->simultaneous_pucch_pusch, ppWritePackedMsg, end) &&
+         push16(phy->four_layer_tx_with_tm3_and_tm4, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_pnf_phy_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel10_t *value = (nfapi_pnf_phy_rel10_t *)tlv;
+  return (push16(value->number_of_phys, ppWritePackedMsg, end) &&
+          packarray(value->phy, sizeof(nfapi_pnf_phy_rel10_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel10_info));
+}
+
+static uint8_t pack_pnf_phy_rel11_info(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel11_info_t *phy = (nfapi_pnf_phy_rel11_info_t *)elem;
+  return (push16(phy->phy_config_index, ppWritePackedMsg, end) &&
+          push16(phy->edpcch_supported, ppWritePackedMsg, end) &&
+          push16(phy->multi_ack_csi_reporting, ppWritePackedMsg, end) &&
+          push16(phy->pucch_tx_diversity, ppWritePackedMsg, end) &&
+          push16(phy->ul_comp_supported, ppWritePackedMsg, end) &&
+          push16(phy->transmission_mode_5_supported, ppWritePackedMsg, end ));
+}
+static uint8_t pack_pnf_phy_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel11_t *value = (nfapi_pnf_phy_rel11_t *)tlv;
+  return (push16(value->number_of_phys, ppWritePackedMsg, end) &&
+          packarray(value->phy, sizeof(nfapi_pnf_phy_rel11_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel11_info));
+}
+static uint8_t pack_pnf_phy_rel12_info(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel12_info_t *phy = (nfapi_pnf_phy_rel12_info_t *)elem;
+  return( push16(phy->phy_config_index, ppWritePackedMsg, end) &&
+          push16(phy->csi_subframe_set, ppWritePackedMsg, end) &&
+          push16(phy->enhanced_4tx_codebook, ppWritePackedMsg, end) &&
+          push16(phy->drs_supported, ppWritePackedMsg, end) &&
+          push16(phy->ul_64qam_supported, ppWritePackedMsg, end) &&
+          push16(phy->transmission_mode_10_supported, ppWritePackedMsg, end) &&
+          push16(phy->alternative_bts_indices, ppWritePackedMsg, end));
+}
+static uint8_t pack_pnf_phy_rel12_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel12_t *value = (nfapi_pnf_phy_rel12_t *)tlv;
+  return (push16(value->number_of_phys, ppWritePackedMsg, end) &&
+          packarray(value->phy, sizeof(nfapi_pnf_phy_rel12_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel12_info));
+}
+
+static uint8_t pack_pnf_phy_rel13_info(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel13_info_t *phy = (nfapi_pnf_phy_rel13_info_t *)elem;
+  return( push16(phy->phy_config_index, ppWritePackedMsg, end) &&
+          push16(phy->pucch_format4_supported, ppWritePackedMsg, end) &&
+          push16(phy->pucch_format5_supported, ppWritePackedMsg, end) &&
+          push16(phy->more_than_5_ca_support, ppWritePackedMsg, end) &&
+          push16(phy->laa_supported, ppWritePackedMsg, end) &&
+          push16(phy->laa_ending_in_dwpts_supported, ppWritePackedMsg, end) &&
+          push16(phy->laa_starting_in_second_slot_supported, ppWritePackedMsg, end) &&
+          push16(phy->beamforming_supported, ppWritePackedMsg, end) &&
+          push16(phy->csi_rs_enhancement_supported, ppWritePackedMsg, end) &&
+          push16(phy->drms_enhancement_supported, ppWritePackedMsg, end) &&
+          push16(phy->srs_enhancement_supported, ppWritePackedMsg, end) );
+}
+
+static uint8_t pack_pnf_phy_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel13_t *value = (nfapi_pnf_phy_rel13_t *)tlv;
+  return (push16(value->number_of_phys, ppWritePackedMsg, end) &&
+          packarray(value->phy, sizeof(nfapi_pnf_phy_rel13_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel13_info));
+}
+
+static uint8_t pack_pnf_phy_rel13_nb_iot_info(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel13_nb_iot_info_t *phy = (nfapi_pnf_phy_rel13_nb_iot_info_t *)elem;
+  return( push16(phy->phy_config_index, ppWritePackedMsg, end) &&
+          push16(phy->number_of_rfs, ppWritePackedMsg, end) &&
+          packarray(phy->rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rfs, ppWritePackedMsg, end, &pack_rf_config_info) &&
+          push16(phy->number_of_rf_exclusions, ppWritePackedMsg, end) &&
+          packarray(phy->excluded_rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rf_exclusions, ppWritePackedMsg, end, &pack_rf_config_info) &&
+          push8(phy->number_of_dl_layers_supported, ppWritePackedMsg, end) &&
+          push8(phy->number_of_ul_layers_supported, ppWritePackedMsg, end) &&
+          push16(phy->maximum_3gpp_release_supported, ppWritePackedMsg, end) &&
+          push8(phy->nmm_modes_supported, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_pnf_phy_rel13_nb_iot_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel13_nb_iot_t *value = (nfapi_pnf_phy_rel13_nb_iot_t *)tlv;
+  return (push16(value->number_of_phys, ppWritePackedMsg, end) &&
+          packarray(value->phy, sizeof(nfapi_pnf_phy_rel13_nb_iot_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel13_nb_iot_info));
+}
+/*
+static uint8_t pack_nr_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
+{
+  nfapi_nr_pnf_param_response_t *pNfapiMsg = (nfapi_nr_pnf_param_response_t*)msg;
+
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+      pack_tlv(NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, ppWritePackedMsg, end, &pack_pnf_param_general_value) &&
+      pack_tlv(NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, ppWritePackedMsg, end, &pack_pnf_phy_value) &&
+      pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+*/
+static uint8_t pack_nr_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_param_response_t *pNfapiMsg = (nfapi_nr_pnf_param_response_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_tlv(NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, ppWritePackedMsg, end, &pack_pnf_param_general_value) &&
+          pack_tlv(NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, ppWritePackedMsg, end, &pack_pnf_phy_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
+static uint8_t pack_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_param_response_t *pNfapiMsg = (nfapi_pnf_param_response_t *)msg;
+  return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_tlv(NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, ppWritePackedMsg, end, &pack_pnf_param_general_value) &&
+          pack_tlv(NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, ppWritePackedMsg, end, &pack_pnf_phy_value) &&
+          pack_tlv(NFAPI_PNF_RF_TAG, &pNfapiMsg->pnf_rf, ppWritePackedMsg, end, &pack_pnf_rf_value) &&
+          pack_tlv(NFAPI_PNF_PHY_REL10_TAG, &pNfapiMsg->pnf_phy_rel10, ppWritePackedMsg, end, &pack_pnf_phy_rel10_value) &&
+          pack_tlv(NFAPI_PNF_PHY_REL11_TAG, &pNfapiMsg->pnf_phy_rel11, ppWritePackedMsg, end, &pack_pnf_phy_rel11_value) &&
+          pack_tlv(NFAPI_PNF_PHY_REL12_TAG, &pNfapiMsg->pnf_phy_rel12, ppWritePackedMsg, end, &pack_pnf_phy_rel12_value) &&
+          pack_tlv(NFAPI_PNF_PHY_REL13_TAG, &pNfapiMsg->pnf_phy_rel13, ppWritePackedMsg, end, &pack_pnf_phy_rel13_value) &&
+          pack_tlv(NFAPI_PNF_PHY_REL13_NB_IOT_TAG, &pNfapiMsg->pnf_phy_rel13_nb_iot, ppWritePackedMsg, end, &pack_pnf_phy_rel13_nb_iot_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
+static uint8_t pack_phy_rf_config_info(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_phy_rf_config_info_t *rf = (nfapi_phy_rf_config_info_t *)elem;
+  return (push16(rf->phy_id, ppWritePackedMsg, end) &&
+          push16(rf->phy_config_index, ppWritePackedMsg, end) &&
+          push16(rf->rf_config_index, ppWritePackedMsg, end));
+}
+
+
+static uint8_t pack_pnf_phy_rf_config_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rf_config_t *value = (nfapi_pnf_phy_rf_config_t *)tlv;
+  return(push16(value->number_phy_rf_config_info, ppWritePackedMsg, end) &&
+         packarray(value->phy_rf_config, sizeof(nfapi_phy_rf_config_info_t), NFAPI_MAX_PHY_RF_INSTANCES, value->number_phy_rf_config_info, ppWritePackedMsg, end, &pack_phy_rf_config_info));
+}
+
+static uint8_t pack_nr_pnf_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_config_request_t *pNfapiMsg = (nfapi_nr_pnf_config_request_t *)msg;
+  return (pack_tlv(NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, ppWritePackedMsg, end, &pack_pnf_phy_rf_config_value) &&
+          //push8(pNfapiMsg->num_tlvs,ppWritePackedMsg,end) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_pnf_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_config_request_t *pNfapiMsg = (nfapi_pnf_config_request_t *)msg;
+  return (pack_tlv(NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, ppWritePackedMsg, end, &pack_pnf_phy_rf_config_value) &&
+          push8(pNfapiMsg->num_tlvs,ppWritePackedMsg,end) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
+static uint8_t pack_nr_pnf_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_config_response_t *pNfapiMsg = (nfapi_nr_pnf_config_response_t *)msg;
+  return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+           pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
+static uint8_t pack_pnf_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_config_response_t *pNfapiMsg = (nfapi_pnf_config_response_t *)msg;
+  return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+           pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_nr_pnf_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_start_request_t *pNfapiMsg = (nfapi_nr_pnf_start_request_t *)msg;
+  return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_pnf_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_start_request_t *pNfapiMsg = (nfapi_pnf_start_request_t *)msg;
+  return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
+static uint8_t pack_nr_pnf_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_start_response_t *pNfapiMsg = (nfapi_nr_pnf_start_response_t *)msg;
+  return( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
+static uint8_t pack_pnf_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_start_response_t *pNfapiMsg = (nfapi_pnf_start_response_t *)msg;
+  return( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
+static uint8_t pack_nr_pnf_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_stop_request_t *pNfapiMsg = (nfapi_nr_pnf_stop_request_t *)msg;
+  return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
+
+
+static uint8_t pack_pnf_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_stop_request_t *pNfapiMsg = (nfapi_pnf_stop_request_t *)msg;
+  return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
+
+static uint8_t pack_nr_pnf_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_stop_response_t *pNfapiMsg = (nfapi_nr_pnf_stop_response_t *)msg;
+  return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+           pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
+static uint8_t pack_pnf_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_stop_response_t *pNfapiMsg = (nfapi_pnf_stop_response_t *)msg;
+  return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+           pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_nr_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_param_request_scf_t *pNfapiMsg = (nfapi_nr_param_request_scf_t *)msg;
+  return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_param_request_t *pNfapiMsg = (nfapi_param_request_t *)msg;
+  return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_uint32_tlv_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_uint32_tlv_t *value = (nfapi_uint32_tlv_t *)tlv;
+  return push32(value->value, ppWritePackedMsg, end);
+}
+
+static uint8_t unpack_uint32_tlv_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_uint32_tlv_t *value = (nfapi_uint32_tlv_t *)tlv;
+  return pull32(ppReadPackedMsg, &value->value, end);
+}
+
+
+static uint8_t pack_uint16_tlv_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_uint16_tlv_t *value = (nfapi_uint16_tlv_t *)tlv;
+  return push16(value->value, ppWritePackedMsg, end);
+}
+
+static uint8_t unpack_uint16_tlv_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_uint16_tlv_t *value = (nfapi_uint16_tlv_t *)tlv;
+  return pull16(ppReadPackedMsg, &value->value, end);
+}
+
+static uint8_t pack_int16_tlv_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_int16_tlv_t *value = (nfapi_int16_tlv_t *)tlv;
+  return pushs16(value->value, ppWritePackedMsg, end);
+}
+
+static uint8_t unpack_int16_tlv_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_int16_tlv_t *value = (nfapi_int16_tlv_t *)tlv;
+  return pulls16(ppReadPackedMsg, &value->value, end);
+}
+
+static uint8_t pack_uint8_tlv_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_uint8_tlv_t *value = (nfapi_uint8_tlv_t *)tlv;
+  return push8(value->value, ppWritePackedMsg, end);
+}
+static uint8_t unpack_uint8_tlv_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_uint8_tlv_t *value = (nfapi_uint8_tlv_t *)tlv;
+  return pull8(ppReadPackedMsg, &value->value, end);
+}
+
+static uint8_t pack_ipv4_address_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ipv4_address_t *value = (nfapi_ipv4_address_t *)tlv;
+  return pusharray8(value->address, NFAPI_IPV4_ADDRESS_LENGTH, NFAPI_IPV4_ADDRESS_LENGTH, ppWritePackedMsg, end);
+}
+static uint8_t unpack_ipv4_address_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ipv4_address_t *value = (nfapi_ipv4_address_t *)tlv;
+  return pullarray8(ppReadPackedMsg, value->address, NFAPI_IPV4_ADDRESS_LENGTH, NFAPI_IPV4_ADDRESS_LENGTH, end);
+}
+static uint8_t pack_ipv6_address_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ipv6_address_t *value = (nfapi_ipv6_address_t *)tlv;
+  return pusharray8(value->address, NFAPI_IPV6_ADDRESS_LENGTH, NFAPI_IPV6_ADDRESS_LENGTH, ppWritePackedMsg, end);
+}
+static uint8_t unpack_ipv6_address_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ipv4_address_t *value = (nfapi_ipv4_address_t *)tlv;
+  return pullarray8(ppReadPackedMsg, value->address, NFAPI_IPV6_ADDRESS_LENGTH, NFAPI_IPV6_ADDRESS_LENGTH, end);
+}
+
+static uint8_t pack_rf_bands_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_rf_bands_t *value = (nfapi_rf_bands_t *)tlv;
+  return ( push16(value->number_rf_bands, ppWritePackedMsg, end) &&
+           pusharray16(value->rf_band, NFAPI_MAX_NUM_RF_BANDS, value->number_rf_bands, ppWritePackedMsg, end));
+}
+static uint8_t unpack_rf_bands_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_rf_bands_t *value = (nfapi_rf_bands_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &value->number_rf_bands, end) &&
+           pullarray16(ppReadPackedMsg, value->rf_band, NFAPI_MAX_NUM_RF_BANDS, value->number_rf_bands, end));
+}
+
+static uint8_t pack_nmm_frequency_bands_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nmm_frequency_bands_t *value = (nfapi_nmm_frequency_bands_t *)tlv;
+  return( push16(value->number_of_rf_bands, ppWritePackedMsg, end) &&
+          pusharray16(value->bands, NFAPI_MAX_NMM_FREQUENCY_BANDS, value->number_of_rf_bands, ppWritePackedMsg, end));
+}
+static uint8_t unpack_nmm_frequency_bands_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nmm_frequency_bands_t *value = (nfapi_nmm_frequency_bands_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &value->number_of_rf_bands, end) &&
+           pullarray16(ppReadPackedMsg, value->bands, NFAPI_MAX_NMM_FREQUENCY_BANDS, value->number_of_rf_bands, end));
+}
+static uint8_t pack_embms_mbsfn_config_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_embms_mbsfn_config_t *value = (nfapi_embms_mbsfn_config_t *)tlv;
+  return ( push16(value->num_mbsfn_config, ppWritePackedMsg, end) &&
+           pusharray16(value->radioframe_allocation_period, 8,value->num_mbsfn_config,ppWritePackedMsg, end) &&
+           pusharray16(value->radioframe_allocation_offset, 8,value->num_mbsfn_config,ppWritePackedMsg, end) &&
+           pusharray8(value->fourframes_flag, 8,value->num_mbsfn_config,ppWritePackedMsg, end) &&
+           pusharrays32(value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, ppWritePackedMsg, end));
+}
+// static uint8_t unpack_embms_mbsfn_config_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t* end)
+// {
+//     nfapi_embms_mbsfn_config_t* value = (nfapi_embms_mbsfn_config_t*)tlv;
+
+//     return ( pull16(ppReadPackedMsg, &value->num_mbsfn_config, end) &&
+//              pull16(ppReadPackedMsg, &value->radioframe_allocation_period, end) &&
+//              pull16(ppReadPackedMsg, &value->radioframe_allocation_offset, end) &&
+//              pull8(ppReadPackedMsg, &value->fourframes_flag, end) &&
+//                      pullarrays32(ppReadPackedMsg, value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, end));
+// }
+
+static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t *)msg;
+  return( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) &&
+          pack_tlv(NFAPI_L1_STATUS_PHY_STATE_TAG,  &pNfapiMsg->l1_status.phy_state, ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          // Do we check the phy state and then just fill those sepecified, however
+          // we do not know the duplex mode, so just attempt to pack all and assumme
+          // that the callee has set the right tlvs
+          pack_tlv(NFAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, &(pNfapiMsg->phy_capabilities.dl_bandwidth_support), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, &(pNfapiMsg->phy_capabilities.ul_bandwidth_support), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PHY_CAPABILITIES_DL_MODULATION_SUPPORT_TAG, &(pNfapiMsg->phy_capabilities.dl_modulation_support), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PHY_CAPABILITIES_UL_MODULATION_SUPPORT_TAG, &(pNfapiMsg->phy_capabilities.ul_modulation_support), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PHY_CAPABILITIES_PHY_ANTENNA_CAPABILITY_TAG, &(pNfapiMsg->phy_capabilities.phy_antenna_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PHY_CAPABILITIES_RELEASE_CAPABILITY_TAG, &(pNfapiMsg->phy_capabilities.release_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PHY_CAPABILITIES_MBSFN_CAPABILITY_TAG, &(pNfapiMsg->phy_capabilities.mbsfn_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          // laa capability
+          pack_tlv(NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &(pNfapiMsg->subframe_config.duplex_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &(pNfapiMsg->subframe_config.pcfich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value)&&
+          pack_tlv(NFAPI_SUBFRAME_CONFIG_PB_TAG, &(pNfapiMsg->subframe_config.pb), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.dl_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.ul_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.dl_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.ul_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &(pNfapiMsg->rf_config.reference_signal_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.tx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.rx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &(pNfapiMsg->phich_config.phich_resource), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &(pNfapiMsg->phich_config.phich_duration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &(pNfapiMsg->phich_config.phich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &(pNfapiMsg->sch_config.physical_cell_id), ppWritePackedMsg, end,&pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->prach_config.configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &(pNfapiMsg->prach_config.zero_correlation_zone_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &(pNfapiMsg->prach_config.high_speed_flag), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->prach_config.frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &(pNfapiMsg->pusch_config.hopping_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &(pNfapiMsg->pusch_config.hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &(pNfapiMsg->pusch_config.number_of_subbands), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &(pNfapiMsg->pucch_config.delta_pucch_shift), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &(pNfapiMsg->pucch_config.n_cqi_rb), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_idx), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_id_r9), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_TAG, &(pNfapiMsg->embms_mbsfn_config), ppWritePackedMsg, end, &pack_embms_mbsfn_config_value) &&
+          pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_config_flag), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_SUBFRAMECONFIG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_subframeconfig), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.bandwidth_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &(pNfapiMsg->srs_config.max_up_pts), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.srs_subframe_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &(pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &(pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &(pNfapiMsg->uplink_reference_signal_config.group_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &(pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &(pNfapiMsg->tdd_frame_structure_config.subframe_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &(pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &(pNfapiMsg->l23_config.data_report_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_L23_CONFIG_SFNSF_TAG, &(pNfapiMsg->l23_config.sfnsf), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
+          pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
+          pack_tlv(NFAPI_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
+          pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
+          pack_tlv(NFAPI_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.dl_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NFAPI_RF_BANDS_TAG, &(pNfapiMsg->nfapi_config.rf_bands), ppWritePackedMsg, end, &pack_rf_bands_value) &&
+          pack_tlv(NFAPI_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NFAPI_EARFCN_TAG, &(pNfapiMsg->nfapi_config.earfcn), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) &&
+          pack_tlv(NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_umts_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) &&
+          pack_tlv(NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_lte_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) &&
+          pack_tlv(NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &(pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
+static uint8_t pack_nr_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  printf("\nRUNNING pack_param_response\n");
+  nfapi_nr_param_response_scf_t *pNfapiMsg = (nfapi_nr_param_response_scf_t *)msg;
+  return (push8(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG, &(pNfapiMsg->cell_param.release_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PHY_STATE_TAG, &(pNfapiMsg->cell_param.phy_state), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_dl_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_ul_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG, &(pNfapiMsg->cell_param.num_config_tlvs_to_report ), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG, &(pNfapiMsg->carrier_param.cyclic_prefix), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_dl), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_dl), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_ul), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_ul), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG, &(pNfapiMsg->pdcch_param.cce_mapping_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG, &(pNfapiMsg->pdcch_param.coreset_outside_first_3_of_ofdm_syms_of_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG, &(pNfapiMsg->pdcch_param.coreset_precoder_granularity_coreset), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG, &(pNfapiMsg->pdcch_param.pdcch_mu_mimo), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG, &(pNfapiMsg->pdcch_param.pdcch_precoder_cycling), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG, &(pNfapiMsg->pdcch_param.max_pdcch_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG, &(pNfapiMsg->pucch_param.pucch_formats), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG, &(pNfapiMsg->pucch_param.max_pucchs_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pdsch_param.pdsch_mapping_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_allocation_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pdsch_param.pdsch_vrb_to_prb_mapping), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG, &(pNfapiMsg->pdsch_param.pdsch_cbg), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_config_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DMRS_MAX_LENGTH_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_max_length), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_additional_pos), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PDSCH_S_YBS_PER_SLOT_TAG, &(pNfapiMsg->pdsch_param.max_pdsch_tbs_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG, &(pNfapiMsg->pdsch_param.max_number_mimo_layers_pdsch), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG, &(pNfapiMsg->pdsch_param.max_mu_mimo_users_dl), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG, &(pNfapiMsg->pdsch_param.pdsch_data_in_dmrs_symbols), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.premption_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.pdsch_non_slot_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG, &(pNfapiMsg->pusch_param.uci_mux_ulsch_in_pusch), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG, &(pNfapiMsg->pusch_param.uci_only_pusch), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG, &(pNfapiMsg->pusch_param.pusch_frequency_hopping), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_config_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_max_len), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_additional_pos), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG, &(pNfapiMsg->pusch_param.pusch_cbg), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pusch_param.pusch_mapping_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pusch_param.pusch_allocation_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pusch_param.pusch_vrb_to_prb_mapping), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG, &(pNfapiMsg->pusch_param.pusch_max_ptrs_ports), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG, &(pNfapiMsg->pusch_param.max_pduschs_tbs_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG, &(pNfapiMsg->pusch_param.max_number_mimo_layers_non_cb_pusch), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG, &(pNfapiMsg->pusch_param.supported_modulation_order_ul), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG, &(pNfapiMsg->pusch_param.max_mu_mimo_users_ul), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG, &(pNfapiMsg->pusch_param.dfts_ofdm_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG, &(pNfapiMsg->pusch_param.pusch_aggregation_factor), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG, &(pNfapiMsg->prach_param.prach_long_formats), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG, &(pNfapiMsg->prach_param.prach_short_formats), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG, &(pNfapiMsg->prach_param.prach_restricted_sets), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG, &(pNfapiMsg->prach_param.max_prach_fd_occasions_in_a_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG, &(pNfapiMsg->measurement_param.rssi_measurement_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          // config:
+          pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_config_request_t *pNfapiMsg = (nfapi_config_request_t *)msg;
+  return ( push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) &&
+           // Do we check the phy state and then just fill those sepecified, however
+           // we do not know the duplex mode, so just attempt to pack all and assumme
+           // that the callee has set the right tlvs
+           pack_tlv(NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &(pNfapiMsg->subframe_config.duplex_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &(pNfapiMsg->subframe_config.pcfich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_SUBFRAME_CONFIG_PB_TAG, &(pNfapiMsg->subframe_config.pb), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.dl_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.ul_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.dl_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.ul_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &(pNfapiMsg->rf_config.reference_signal_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.tx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.rx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &(pNfapiMsg->phich_config.phich_resource), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &(pNfapiMsg->phich_config.phich_duration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &(pNfapiMsg->phich_config.phich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &(pNfapiMsg->sch_config.physical_cell_id), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->prach_config.configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &(pNfapiMsg->prach_config.zero_correlation_zone_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &(pNfapiMsg->prach_config.high_speed_flag), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->prach_config.frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &(pNfapiMsg->pusch_config.hopping_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &(pNfapiMsg->pusch_config.hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &(pNfapiMsg->pusch_config.number_of_subbands), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &(pNfapiMsg->pucch_config.delta_pucch_shift), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &(pNfapiMsg->pucch_config.n_cqi_rb), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.bandwidth_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &(pNfapiMsg->srs_config.max_up_pts), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.srs_subframe_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &(pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &(pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &(pNfapiMsg->uplink_reference_signal_config.group_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &(pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_PDSCH_TAG, &(pNfapiMsg->laa_config.ed_threshold_lbt_pdsch), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_DRS_TAG, &(pNfapiMsg->laa_config.ed_threshold_lbt_drs), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_LAA_CONFIG_PD_THRESHOLD_TAG, &(pNfapiMsg->laa_config.pd_threshold), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_LAA_CONFIG_MULTI_CARRIER_TYPE_TAG, &(pNfapiMsg->laa_config.multi_carrier_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_LAA_CONFIG_MULTI_CARRIER_TX_TAG, &(pNfapiMsg->laa_config.multi_carrier_tx), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_LAA_CONFIG_MULTI_CARRIER_FREEZE_TAG, &(pNfapiMsg->laa_config.multi_carrier_freeze), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_LAA_CONFIG_TX_ANTENNA_PORTS_FOR_DRS_TAG, &(pNfapiMsg->laa_config.tx_antenna_ports_drs), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_LAA_CONFIG_TRANSMISSION_POWER_FOR_DRS_TAG, &(pNfapiMsg->laa_config.tx_power_drs), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG, &(pNfapiMsg->emtc_config.pbch_repetitions_enable_r13), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_catm_root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &(pNfapiMsg->emtc_config.prach_catm_zero_correlation_zone_configuration), ppWritePackedMsg, end,
+                    &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG, &(pNfapiMsg->emtc_config.prach_catm_high_speed_flag), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt), ppWritePackedMsg, end,
+                    &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_starting_subframe_periodicity), ppWritePackedMsg, end,
+                    &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt), ppWritePackedMsg, end,
+                    &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_starting_subframe_periodicity), ppWritePackedMsg, end,
+                    &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt), ppWritePackedMsg, end,
+                    &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_starting_subframe_periodicity), ppWritePackedMsg, end,
+                    &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt), ppWritePackedMsg, end,
+                    &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_starting_subframe_periodicity), ppWritePackedMsg, end,
+                    &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG, &(pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG, &(pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &(pNfapiMsg->tdd_frame_structure_config.subframe_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &(pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &(pNfapiMsg->l23_config.data_report_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_L23_CONFIG_SFNSF_TAG, &(pNfapiMsg->l23_config.sfnsf), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
+           pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
+           pack_tlv(NFAPI_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
+           pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
+           pack_tlv(NFAPI_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.dl_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+           pack_tlv(NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+           pack_tlv(NFAPI_PHY_RF_BANDS_TAG, &(pNfapiMsg->nfapi_config.rf_bands), ppWritePackedMsg, end, &pack_rf_bands_value) &&
+           pack_tlv(NFAPI_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+           pack_tlv(NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+           pack_tlv(NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+           pack_tlv(NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_NFAPI_EARFCN_TAG, &(pNfapiMsg->nfapi_config.earfcn), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+           pack_tlv(NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) &&
+           pack_tlv(NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_umts_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) &&
+           pack_tlv(NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_lte_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) &&
+           pack_tlv(NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &(pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+           pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
+
+static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  printf("\n\nEntering pack_config_request\n");
+  nfapi_nr_config_request_scf_t *pNfapiMsg = (nfapi_nr_config_request_scf_t *)msg;
+  return (push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) &&
+          pack_tlv(NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG, &(pNfapiMsg->carrier_config.dl_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_DL_FREQUENCY_TAG, &(pNfapiMsg->carrier_config.dl_frequency), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG, &(pNfapiMsg->carrier_config.dl_grid_size[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_DL_K0_TAG, &(pNfapiMsg->carrier_config.dl_k0[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_NUM_RX_ANT_TAG, &(pNfapiMsg->carrier_config.num_rx_ant), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_NUM_TX_ANT_TAG, &(pNfapiMsg->carrier_config.num_tx_ant), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG, &(pNfapiMsg->carrier_config.ul_grid_size[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_UL_K0_TAG, &(pNfapiMsg->carrier_config.ul_k0[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG, &(pNfapiMsg->carrier_config.uplink_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG, &(pNfapiMsg->carrier_config.uplink_frequency), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG, &(pNfapiMsg->cell_config.frame_duplex_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_PHY_CELL_ID_TAG, &(pNfapiMsg->cell_config.phy_cell_id), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG, &(pNfapiMsg->prach_config.prach_sequence_length), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG, &(pNfapiMsg->prach_config.restricted_set_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_SSB_PER_RACH_TAG, &(pNfapiMsg->prach_config.ssb_per_rach), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG, &(pNfapiMsg->prach_config.prach_sub_c_spacing), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_K1_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].k1), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_zero_corr_conf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].num_root_sequences), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_SCS_COMMON_TAG, &(pNfapiMsg->ssb_config.scs_common), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG, &(pNfapiMsg->ssb_config.ss_pbch_power), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_BETA_PSS_TAG, &(pNfapiMsg->ssb_table.beta_pss), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_MIB_TAG, &(pNfapiMsg->ssb_table.MIB), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[1].ssb_mask), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG, &(pNfapiMsg->ssb_table.ssb_offset_point_a), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG, &(pNfapiMsg->ssb_table.ssb_subcarrier_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG, &(pNfapiMsg->tdd_table.max_tdd_periodicity_list[0].max_num_of_symbol_per_slot_list[0].slot_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          //pack_tlv(NFAPI_NR_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.dl_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          //pack_tlv(NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          //pack_tlv(NFAPI_NR_NFAPI_NRARFCN_TAG, &(pNfapiMsg->nfapi_config.nrarfcn), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          //pack_tlv(NFAPI_NR_NFAPI_RF_BANDS_TAG, &(pNfapiMsg->nfapi_config.rf_bands), ppWritePackedMsg, end, &pack_rf_bands_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          //pack_tlv(NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
+static uint8_t pack_nr_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_config_response_scf_t *pNfapiMsg = (nfapi_nr_config_response_scf_t *)msg;
+  return ( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+           pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
+static uint8_t pack_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_config_response_t *pNfapiMsg = (nfapi_config_response_t *)msg;
+  return ( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+           pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
+static uint8_t pack_nr_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_start_request_scf_t *pNfapiMsg = (nfapi_nr_start_request_scf_t *)msg;
+  return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+}
+
+static uint8_t pack_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_start_request_t *pNfapiMsg = (nfapi_start_request_t *)msg;
+  return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+}
+
+static uint8_t pack_nr_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_start_response_scf_t *pNfapiMsg = (nfapi_nr_start_response_scf_t *)msg;
+  return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end ) &&
+           pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
+static uint8_t pack_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_start_response_t *pNfapiMsg = (nfapi_start_response_t *)msg;
+  return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end ) &&
+           pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
+
+static uint8_t pack_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_stop_request_t *pNfapiMsg = (nfapi_stop_request_t *)msg;
+  return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+}
+
+static uint8_t pack_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_stop_response_t *pNfapiMsg = (nfapi_stop_response_t *)msg;
+  return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+           pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
+static uint8_t pack_measurement_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_measurement_request_t *pNfapiMsg = (nfapi_measurement_request_t *)msg;
+  return( pack_tlv(NFAPI_MEASUREMENT_REQUEST_DL_RS_XTX_POWER_TAG, &(pNfapiMsg->dl_rs_tx_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_MEASUREMENT_REQUEST_RECEIVED_INTERFERENCE_POWER_TAG, &(pNfapiMsg->received_interference_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_tlv(NFAPI_MEASUREMENT_REQUEST_THERMAL_NOISE_POWER_TAG, &(pNfapiMsg->thermal_noise_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_recevied_interference_power_measurement_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_received_interference_power_measurement_t *value = (nfapi_received_interference_power_measurement_t *)tlv;
+  return  ( push16(value->number_of_resource_blocks, ppWritePackedMsg, end) &&
+            pusharrays16(value->received_interference_power, NFAPI_MAX_RECEIVED_INTERFERENCE_POWER_RESULTS, value->number_of_resource_blocks, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_measurement_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_measurement_response_t *pNfapiMsg = (nfapi_measurement_response_t *)msg;
+  return( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+          pack_tlv(NFAPI_MEASUREMENT_RESPONSE_DL_RS_POWER_MEASUREMENT_TAG, &(pNfapiMsg->dl_rs_tx_power_measurement), ppWritePackedMsg, end, &pack_int16_tlv_value) &&
+          pack_tlv(NFAPI_MEASUREMENT_RESPONSE_RECEIVED_INTERFERENCE_POWER_MEASUREMENT_TAG, &(pNfapiMsg->received_interference_power_measurement), ppWritePackedMsg, end,
+                   &pack_recevied_interference_power_measurement_value) &&
+          pack_tlv(NFAPI_MEASUREMENT_RESPONSE_THERMAL_NOISE_MEASUREMENT_TAG, &(pNfapiMsg->thermal_noise_power_measurement), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+          pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_nr_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  uint8_t result = 0;
+
+  // look for the specific message
+  switch (header->message_id) {
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
+      result = pack_nr_pnf_param_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_PNF_PARAM_RESPONSE:
+      result = pack_nr_pnf_param_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
+      result = pack_nr_pnf_config_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE:
+      result = pack_nr_pnf_config_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
+      result = pack_nr_pnf_start_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE:
+      result = pack_nr_pnf_start_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST:
+      result = pack_nr_pnf_stop_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_PNF_STOP_RESPONSE:
+      result = pack_nr_pnf_stop_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
+      result = pack_nr_param_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
+      result = pack_nr_param_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
+      result = pack_nr_config_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
+      result = pack_nr_config_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
+      result = pack_nr_start_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
+      result = pack_nr_start_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
+      result = pack_stop_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
+      result = pack_stop_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    default: {
+      if(header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+          header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if(config && config->pack_p4_p5_vendor_extension) {
+          result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
+      }
+    }
+    break;
+  }
+
+  return result;
+}
+
+
+static uint8_t pack_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  uint8_t result = 0;
+
+  // look for the specific message
+  switch (header->message_id) {
+    case NFAPI_PNF_PARAM_REQUEST:
+      result = pack_pnf_param_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_PNF_PARAM_RESPONSE:
+      result = pack_pnf_param_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_PNF_CONFIG_REQUEST:
+      result = pack_pnf_config_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_PNF_CONFIG_RESPONSE:
+      result = pack_pnf_config_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_PNF_START_REQUEST:
+      result = pack_pnf_start_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_PNF_START_RESPONSE:
+      result = pack_pnf_start_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_PNF_STOP_REQUEST:
+      result = pack_pnf_stop_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_PNF_STOP_RESPONSE:
+      result = pack_pnf_stop_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_PARAM_REQUEST:
+      result = pack_param_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_PARAM_RESPONSE:
+      result = pack_param_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_CONFIG_REQUEST:
+      result = pack_config_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_CONFIG_RESPONSE:
+      result = pack_config_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_START_REQUEST:
+      result = pack_start_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_START_RESPONSE:
+      result = pack_start_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_STOP_REQUEST:
+      result = pack_stop_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_STOP_RESPONSE:
+      result = pack_stop_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_MEASUREMENT_REQUEST:
+      result = pack_measurement_request(header, ppWritePackedMsg, end, config);
+      break;
+
+    case NFAPI_MEASUREMENT_RESPONSE:
+      result = pack_measurement_response(header, ppWritePackedMsg, end, config);
+      break;
+
+    default: {
+      if(header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+          header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if(config && config->pack_p4_p5_vendor_extension) {
+          result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
+      }
+    }
+    break;
+  }
+
+  return result;
+}
+
+
+// helper function for message length calculation -
+// takes the pointers to the start of message to end of message
+
+static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) {
+  if (msgEnd < msgHead) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %d, %d\n", msgHead, msgEnd);
+    return 0;
+  }
+
+  return (msgEnd - msgHead);
+}
+
+// Main pack function - public
+int nfapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
+  uint8_t *pWritePackedMessage = pPackedBuf;
+  uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
+  uint8_t *pPackedLengthField = &pWritePackedMessage[4];
+  uint32_t packedMsgLen;
+  uint16_t packedMsgLen16;
+
+  if (pMessageBuf == NULL || pPackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n");
+    return -1;
+  }
+
+  // pack the message
+  if(push16(pMessageHeader->phy_id, &pWritePackedMessage, pPackMessageEnd) &&
+      push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd) &&
+      push16(0, &pWritePackedMessage, pPackMessageEnd) &&
+      push16(pMessageHeader->spare, &pWritePackedMessage, pPackMessageEnd) &&
+      pack_nr_p5_message_body(pMessageHeader, &pWritePackedMessage, pPackMessageEnd, config)) {
+    // check for a valid message length
+    packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pWritePackedMessage);
+
+    if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
+      return -1;
+    } else {
+      packedMsgLen16 = (uint16_t)packedMsgLen;
+    }
+
+    // Update the message length in the header
+    if(!push16(packedMsgLen16, &pPackedLengthField, pPackMessageEnd))
+      return -1;
+
+    // return the packed length
+    return (packedMsgLen);
+  } else {
+    // Failed to pack the meassage
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Failed to pack message\n");
+    return -1;
+  }
+}
+
+int nfapi_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
+  uint8_t *pWritePackedMessage = pPackedBuf;
+  uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
+  uint8_t *pPackedLengthField = &pWritePackedMessage[4];
+  uint32_t packedMsgLen;
+  uint16_t packedMsgLen16;
+
+  if (pMessageBuf == NULL || pPackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n");
+    return -1;
+  }
+
+  // pack the message
+  if(push16(pMessageHeader->phy_id, &pWritePackedMessage, pPackMessageEnd) &&
+      push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd) &&
+      push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, pPackMessageEnd) &&
+      push16(pMessageHeader->spare, &pWritePackedMessage, pPackMessageEnd) &&
+      pack_p5_message_body(pMessageHeader, &pWritePackedMessage, pPackMessageEnd, config)) {
+    // check for a valid message length
+    packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pWritePackedMessage);
+
+    if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
+      return -1;
+    } else {
+      packedMsgLen16 = (uint16_t)packedMsgLen;
+    }
+
+    // Update the message length in the header
+    if(!push16(packedMsgLen16, &pPackedLengthField, pPackMessageEnd))
+      return -1;
+
+    // return the packed length
+    return (packedMsgLen);
+  } else {
+    // Failed to pack the meassage
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Failed to pack message\n");
+    return -1;
+  }
+}
+
+
+
+// Unpack routines
+
+
+static uint8_t  unpack_nr_pnf_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_param_request_t *pNfapiMsg = (nfapi_nr_pnf_param_request_t *)msg;
+  return unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+
+static uint8_t  unpack_pnf_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_param_request_t *pNfapiMsg = (nfapi_pnf_param_request_t *)msg;
+  return unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_pnf_param_general_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_param_general_t *value = (nfapi_pnf_param_general_t *)tlv;
+  return( pull8(ppReadPackedMsg, &value->nfapi_sync_mode, end) &&
+          pull8(ppReadPackedMsg, &value->location_mode, end) &&
+          pull16(ppReadPackedMsg, &value->location_coordinates_length, end) &&
+          pullarray8(ppReadPackedMsg, value->location_coordinates, NFAPI_PNF_PARAM_GENERAL_LOCATION_LENGTH, value->location_coordinates_length, end) &&
+          pull32(ppReadPackedMsg, &value->dl_config_timing, end) &&
+          pull32(ppReadPackedMsg, &value->tx_timing, end) &&
+          pull32(ppReadPackedMsg, &value->ul_config_timing, end) &&
+          pull32(ppReadPackedMsg, &value->hi_dci0_timing, end) &&
+          pull16(ppReadPackedMsg, &value->maximum_number_phys, end) &&
+          pull16(ppReadPackedMsg, &value->maximum_total_bandwidth, end) &&
+          pull8(ppReadPackedMsg, &value->maximum_total_number_dl_layers, end) &&
+          pull8(ppReadPackedMsg, &value->maximum_total_number_ul_layers, end) &&
+          pull8(ppReadPackedMsg, &value->shared_bands, end) &&
+          pull8(ppReadPackedMsg, &value->shared_pa, end) &&
+          pulls16(ppReadPackedMsg, &value->maximum_total_power, end) &&
+          pullarray8(ppReadPackedMsg, value->oui, NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH, NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH, end));
+}
+
+static uint8_t unpack_rf_config_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_rf_config_info_t *info = (nfapi_rf_config_info_t *)elem;
+  return pull16(ppReadPackedMsg, &info->rf_config_index, end);
+}
+
+static uint8_t unpack_pnf_phy_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_info_t *phy = (nfapi_pnf_phy_info_t *)elem;
+  return ( pull16(ppReadPackedMsg, &phy->phy_config_index, end) &&
+           pull16(ppReadPackedMsg, &phy->number_of_rfs, end) &&
+           unpackarray(ppReadPackedMsg, phy->rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rfs, end, &unpack_rf_config_info) &&
+           pull16(ppReadPackedMsg, &phy->number_of_rf_exclusions, end) &&
+           unpackarray(ppReadPackedMsg, phy->excluded_rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rf_exclusions, end, &unpack_rf_config_info) &&
+           pull16(ppReadPackedMsg, &phy->downlink_channel_bandwidth_supported, end) &&
+           pull16(ppReadPackedMsg, &phy->uplink_channel_bandwidth_supported, end) &&
+           pull8(ppReadPackedMsg, &phy->number_of_dl_layers_supported, end) &&
+           pull8(ppReadPackedMsg, &phy->number_of_ul_layers_supported, end) &&
+           pull16(ppReadPackedMsg, &phy->maximum_3gpp_release_supported, end) &&
+           pull8(ppReadPackedMsg, &phy->nmm_modes_supported, end));
+}
+
+
+static uint8_t unpack_pnf_phy_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_t *value = (nfapi_pnf_phy_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) &&
+           unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_info));
+}
+
+static uint8_t unpack_pnf_rf_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_rf_info_t *rf = (nfapi_pnf_rf_info_t *)elem;
+  return( pull16(ppReadPackedMsg, &rf->rf_config_index, end) &&
+          pull16(ppReadPackedMsg, &rf->band, end) &&
+          pulls16(ppReadPackedMsg, &rf->maximum_transmit_power, end) &&
+          pulls16(ppReadPackedMsg, &rf->minimum_transmit_power, end) &&
+          pull8(ppReadPackedMsg, &rf->number_of_antennas_suppported, end) &&
+          pull32(ppReadPackedMsg, &rf->minimum_downlink_frequency, end) &&
+          pull32(ppReadPackedMsg, &rf->maximum_downlink_frequency, end) &&
+          pull32(ppReadPackedMsg, &rf->minimum_uplink_frequency, end) &&
+          pull32(ppReadPackedMsg, &rf->maximum_uplink_frequency, end));
+}
+static uint8_t unpack_pnf_rf_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_rf_t *value = (nfapi_pnf_rf_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &value->number_of_rfs, end) &&
+           unpackarray(ppReadPackedMsg, value->rf, sizeof(nfapi_pnf_rf_info_t), NFAPI_MAX_PNF_RF, value->number_of_rfs, end, &unpack_pnf_rf_info));
+}
+
+static uint8_t unpack_pnf_phy_rel10_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel10_info_t *phy = (nfapi_pnf_phy_rel10_info_t *)elem;
+  return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) &&
+          pull16(ppReadPackedMsg, &phy->transmission_mode_7_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->transmission_mode_8_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->two_antenna_ports_for_pucch, end) &&
+          pull16(ppReadPackedMsg, &phy->transmission_mode_9_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->simultaneous_pucch_pusch, end) &&
+          pull16(ppReadPackedMsg, &phy->four_layer_tx_with_tm3_and_tm4, end));
+}
+static uint8_t unpack_pnf_phy_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel10_t *value = (nfapi_pnf_phy_rel10_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) &&
+           unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel10_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel10_info));
+}
+
+
+static uint8_t unpack_pnf_phy_rel11_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel11_info_t *phy = (nfapi_pnf_phy_rel11_info_t *)elem;
+  return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) &&
+          pull16(ppReadPackedMsg, &phy->edpcch_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->multi_ack_csi_reporting, end ) &&
+          pull16(ppReadPackedMsg, &phy->pucch_tx_diversity, end) &&
+          pull16(ppReadPackedMsg, &phy->ul_comp_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->transmission_mode_5_supported, end));
+}
+
+static uint8_t unpack_pnf_phy_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel11_t *value = (nfapi_pnf_phy_rel11_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) &&
+           unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel11_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel11_info));
+}
+
+static uint8_t unpack_phy_phy_rel12_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel12_info_t *phy = (nfapi_pnf_phy_rel12_info_t *)elem;
+  return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) &&
+          pull16(ppReadPackedMsg, &phy->csi_subframe_set, end) &&
+          pull16(ppReadPackedMsg, &phy->enhanced_4tx_codebook, end) &&
+          pull16(ppReadPackedMsg, &phy->drs_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->ul_64qam_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->transmission_mode_10_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->alternative_bts_indices, end));
+}
+
+static uint8_t unpack_pnf_phy_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel12_t *value = (nfapi_pnf_phy_rel12_t *)tlv;
+  return (pull16(ppReadPackedMsg, &value->number_of_phys, end) &&
+          unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel12_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_phy_phy_rel12_info));
+}
+
+static uint8_t unpack_pnf_phy_rel13_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel13_info_t *phy = (nfapi_pnf_phy_rel13_info_t *)elem;
+  return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) &&
+          pull16(ppReadPackedMsg, &phy->pucch_format4_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->pucch_format5_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->more_than_5_ca_support, end) &&
+          pull16(ppReadPackedMsg, &phy->laa_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->laa_ending_in_dwpts_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->laa_starting_in_second_slot_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->beamforming_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->csi_rs_enhancement_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->drms_enhancement_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->srs_enhancement_supported, end));
+}
+
+static uint8_t unpack_pnf_phy_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel13_t *value = (nfapi_pnf_phy_rel13_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) &&
+           unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel13_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel13_info));
+}
+
+static uint8_t unpack_pnf_phy_rel13_nb_info_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel13_nb_iot_info_t *phy = (nfapi_pnf_phy_rel13_nb_iot_info_t *)elem;
+  return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) &&
+          pull16(ppReadPackedMsg, &phy->number_of_rfs, end) &&
+          unpackarray(ppReadPackedMsg, phy->rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rfs, end, &unpack_rf_config_info) &&
+          pull16(ppReadPackedMsg, &phy->number_of_rf_exclusions, end) &&
+          unpackarray(ppReadPackedMsg, phy->excluded_rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rf_exclusions, end, &unpack_rf_config_info) &&
+          pull8(ppReadPackedMsg, &phy->number_of_dl_layers_supported, end) &&
+          pull8(ppReadPackedMsg, &phy->number_of_ul_layers_supported, end) &&
+          pull16(ppReadPackedMsg, &phy->maximum_3gpp_release_supported, end) &&
+          pull8(ppReadPackedMsg, &phy->nmm_modes_supported, end));
+}
+
+static uint8_t unpack_pnf_phy_rel13_nb_iot_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rel13_nb_iot_t *value = (nfapi_pnf_phy_rel13_nb_iot_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) &&
+           unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel13_nb_iot_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel13_nb_info_info));
+}
+
+static uint8_t unpack_nr_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_param_response_t *pNfapiMsg = (nfapi_nr_pnf_param_response_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, &unpack_pnf_param_general_value},
+    { NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, &unpack_pnf_phy_value},
+  };
+  return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+
+
+static uint8_t unpack_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_param_response_t *pNfapiMsg = (nfapi_pnf_param_response_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, &unpack_pnf_param_general_value},
+    { NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, &unpack_pnf_phy_value},
+    { NFAPI_PNF_RF_TAG, &pNfapiMsg->pnf_rf, &unpack_pnf_rf_value},
+    { NFAPI_PNF_PHY_REL10_TAG, &pNfapiMsg->pnf_phy_rel10, &unpack_pnf_phy_rel10_value},
+    { NFAPI_PNF_PHY_REL11_TAG, &pNfapiMsg->pnf_phy_rel11, &unpack_pnf_phy_rel11_value},
+    { NFAPI_PNF_PHY_REL12_TAG, &pNfapiMsg->pnf_phy_rel12, &unpack_pnf_phy_rel12_value},
+    { NFAPI_PNF_PHY_REL13_TAG, &pNfapiMsg->pnf_phy_rel13, &unpack_pnf_phy_rel13_value},
+    { NFAPI_PNF_PHY_REL13_NB_IOT_TAG, &pNfapiMsg->pnf_phy_rel13_nb_iot, &unpack_pnf_phy_rel13_nb_iot_value},
+
+  };
+  return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+
+static uint8_t unpack_phy_rf_config_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_phy_rf_config_info_t *rf = (nfapi_phy_rf_config_info_t *)elem;
+  return( pull16(ppReadPackedMsg, &rf->phy_id, end) &&
+          pull16(ppReadPackedMsg, &rf->phy_config_index, end) &&
+          pull16(ppReadPackedMsg, &rf->rf_config_index, end));
+}
+
+static uint8_t unpack_pnf_phy_rf_config_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_pnf_phy_rf_config_t *value = (nfapi_pnf_phy_rf_config_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &value->number_phy_rf_config_info, end) &&
+           unpackarray(ppReadPackedMsg, value->phy_rf_config, sizeof(nfapi_phy_rf_config_info_t), NFAPI_MAX_PHY_RF_INSTANCES, value->number_phy_rf_config_info, end, &unpack_phy_rf_config_info));
+}
+
+static uint8_t unpack_nr_pnf_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_config_request_t *pNfapiMsg = (nfapi_nr_pnf_config_request_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, &unpack_pnf_phy_rf_config_value},
+  };
+  return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension);
+}
+
+
+
+static uint8_t unpack_pnf_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_config_request_t *pNfapiMsg = (nfapi_pnf_config_request_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, &unpack_pnf_phy_rf_config_value},
+  };
+  return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension);
+}
+
+
+static uint8_t unpack_nr_pnf_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_config_response_t *pNfapiMsg = (nfapi_nr_pnf_config_response_t *)msg;
+  return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+
+static uint8_t unpack_pnf_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_config_response_t *pNfapiMsg = (nfapi_pnf_config_response_t *)msg;
+  return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+
+static uint8_t unpack_nr_pnf_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_start_request_t *pNfapiMsg = (nfapi_nr_pnf_start_request_t *)msg;
+  return unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+
+static uint8_t unpack_pnf_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_start_request_t *pNfapiMsg = (nfapi_pnf_start_request_t *)msg;
+  return unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+
+static uint8_t unpack_pnf_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_start_response_t *pNfapiMsg = (nfapi_pnf_start_response_t *)msg;
+  return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end ) &&
+           unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+
+static uint8_t unpack_nr_pnf_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_pnf_start_response_t *pNfapiMsg = (nfapi_nr_pnf_start_response_t *)msg;
+  return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end ) &&
+           unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+
+
+static uint8_t unpack_pnf_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_stop_request_t *pNfapiMsg = (nfapi_pnf_stop_request_t *)msg;
+  return unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_pnf_stop_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_pnf_stop_response_t *pNfapiMsg = (nfapi_pnf_stop_response_t *)msg;
+  return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+
+static uint8_t unpack_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_param_request_t *pNfapiMsg = (nfapi_param_request_t *)msg;
+  return unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_nr_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_param_request_scf_t *pNfapiMsg = (nfapi_nr_param_request_scf_t *)msg;
+  return unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_L1_STATUS_PHY_STATE_TAG, &pNfapiMsg->l1_status.phy_state, &unpack_uint16_tlv_value},
+
+    { NFAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, &pNfapiMsg->phy_capabilities.dl_bandwidth_support, &unpack_uint16_tlv_value},
+    { NFAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, &pNfapiMsg->phy_capabilities.ul_bandwidth_support, &unpack_uint16_tlv_value},
+    { NFAPI_PHY_CAPABILITIES_DL_MODULATION_SUPPORT_TAG, &pNfapiMsg->phy_capabilities.dl_modulation_support, &unpack_uint16_tlv_value},
+    { NFAPI_PHY_CAPABILITIES_UL_MODULATION_SUPPORT_TAG, &pNfapiMsg->phy_capabilities.ul_modulation_support, &unpack_uint16_tlv_value},
+    { NFAPI_PHY_CAPABILITIES_PHY_ANTENNA_CAPABILITY_TAG, &pNfapiMsg->phy_capabilities.phy_antenna_capability, &unpack_uint16_tlv_value},
+    { NFAPI_PHY_CAPABILITIES_RELEASE_CAPABILITY_TAG, &pNfapiMsg->phy_capabilities.release_capability, &unpack_uint16_tlv_value},
+    { NFAPI_PHY_CAPABILITIES_MBSFN_CAPABILITY_TAG, &pNfapiMsg->phy_capabilities.mbsfn_capability, &unpack_uint16_tlv_value},
+
+    { NFAPI_LAA_CAPABILITY_LAA_SUPPORT_TAG, &pNfapiMsg->laa_capability.laa_support, &unpack_uint16_tlv_value},
+    { NFAPI_LAA_CAPABILITY_PD_SENSING_LBT_SUPPORT_TAG, &pNfapiMsg->laa_capability.pd_sensing_lbt_support, &unpack_uint16_tlv_value},
+    { NFAPI_LAA_CAPABILITY_MULTI_CARRIER_LBT_SUPPORT_TAG, &pNfapiMsg->laa_capability.multi_carrier_lbt_support, &unpack_uint16_tlv_value},
+    { NFAPI_LAA_CAPABILITY_PARTIAL_SF_SUPPORT_TAG, &pNfapiMsg->laa_capability.partial_sf_support, &unpack_uint16_tlv_value},
+
+    { NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &pNfapiMsg->subframe_config.duplex_mode, &unpack_uint16_tlv_value},
+    { NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &pNfapiMsg->subframe_config.pcfich_power_offset, &unpack_uint16_tlv_value},
+    { NFAPI_SUBFRAME_CONFIG_PB_TAG, &pNfapiMsg->subframe_config.pb, &unpack_uint16_tlv_value},
+    { NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &pNfapiMsg->subframe_config.dl_cyclic_prefix_type, &unpack_uint16_tlv_value},
+    { NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &pNfapiMsg->subframe_config.ul_cyclic_prefix_type, &unpack_uint16_tlv_value},
+
+    { NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &pNfapiMsg->rf_config.dl_channel_bandwidth, &unpack_uint16_tlv_value},
+    { NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &pNfapiMsg->rf_config.ul_channel_bandwidth, &unpack_uint16_tlv_value},
+    { NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &pNfapiMsg->rf_config.reference_signal_power, &unpack_uint16_tlv_value},
+    { NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &pNfapiMsg->rf_config.tx_antenna_ports, &unpack_uint16_tlv_value},
+    { NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &pNfapiMsg->rf_config.rx_antenna_ports, &unpack_uint16_tlv_value},
+
+    { NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &pNfapiMsg->phich_config.phich_resource, &unpack_uint16_tlv_value},
+    { NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &pNfapiMsg->phich_config.phich_duration, &unpack_uint16_tlv_value},
+    { NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &pNfapiMsg->phich_config.phich_power_offset, &unpack_uint16_tlv_value},
+
+    { NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers, &unpack_uint16_tlv_value},
+    { NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers, &unpack_uint16_tlv_value},
+    { NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &pNfapiMsg->sch_config.physical_cell_id, &unpack_uint16_tlv_value},
+
+    { NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &pNfapiMsg->prach_config.configuration_index, &unpack_uint16_tlv_value},
+    { NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &pNfapiMsg->prach_config.root_sequence_index, &unpack_uint16_tlv_value},
+    { NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &pNfapiMsg->prach_config.zero_correlation_zone_configuration, &unpack_uint16_tlv_value},
+    { NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &pNfapiMsg->prach_config.high_speed_flag, &unpack_uint16_tlv_value},
+    { NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &pNfapiMsg->prach_config.frequency_offset, &unpack_uint16_tlv_value},
+
+    { NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &pNfapiMsg->pusch_config.hopping_mode, &unpack_uint16_tlv_value},
+    { NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &pNfapiMsg->pusch_config.hopping_offset, &unpack_uint16_tlv_value},
+    { NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &pNfapiMsg->pusch_config.number_of_subbands, &unpack_uint16_tlv_value},
+
+    { NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &pNfapiMsg->pucch_config.delta_pucch_shift, &unpack_uint16_tlv_value},
+    { NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &pNfapiMsg->pucch_config.n_cqi_rb, &unpack_uint16_tlv_value},
+    { NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &pNfapiMsg->pucch_config.n_an_cs, &unpack_uint16_tlv_value},
+    { NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &pNfapiMsg->pucch_config.n1_pucch_an, &unpack_uint16_tlv_value},
+
+    { NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &pNfapiMsg->srs_config.bandwidth_configuration, &unpack_uint16_tlv_value},
+    { NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &pNfapiMsg->srs_config.max_up_pts, &unpack_uint16_tlv_value},
+    { NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &pNfapiMsg->srs_config.srs_subframe_configuration, &unpack_uint16_tlv_value},
+    { NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission, &unpack_uint16_tlv_value},
+
+    { NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping, &unpack_uint16_tlv_value},
+    { NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &pNfapiMsg->uplink_reference_signal_config.group_assignment, &unpack_uint16_tlv_value},
+    { NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms, &unpack_uint16_tlv_value},
+
+    { NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &pNfapiMsg->tdd_frame_structure_config.subframe_assignment, &unpack_uint16_tlv_value},
+    { NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns, &unpack_uint16_tlv_value},
+
+    { NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &pNfapiMsg->l23_config.data_report_mode, &unpack_uint16_tlv_value},
+    { NFAPI_L23_CONFIG_SFNSF_TAG, &pNfapiMsg->l23_config.sfnsf, &unpack_uint16_tlv_value},
+
+    { NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv4, &unpack_ipv4_address_value},
+    { NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv6, &unpack_ipv6_address_value},
+    { NFAPI_NFAPI_P7_VNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_vnf_port, &unpack_uint16_tlv_value},
+    { NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv4, &unpack_ipv4_address_value},
+    { NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv6, &unpack_ipv6_address_value},
+    { NFAPI_NFAPI_P7_PNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_pnf_port, &unpack_uint16_tlv_value},
+    { NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &pNfapiMsg->nfapi_config.dl_ue_per_sf, &unpack_uint8_tlv_value},
+    { NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &pNfapiMsg->nfapi_config.ul_ue_per_sf, &unpack_uint8_tlv_value},
+    { NFAPI_NFAPI_RF_BANDS_TAG, &pNfapiMsg->nfapi_config.rf_bands, &unpack_rf_bands_value},
+    { NFAPI_NFAPI_TIMING_WINDOW_TAG, &pNfapiMsg->nfapi_config.timing_window, &unpack_uint8_tlv_value},
+    { NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &pNfapiMsg->nfapi_config.timing_info_mode, &unpack_uint8_tlv_value},
+    { NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &pNfapiMsg->nfapi_config.timing_info_period, &unpack_uint8_tlv_value},
+    { NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &pNfapiMsg->nfapi_config.max_transmit_power, &unpack_uint16_tlv_value},
+    { NFAPI_NFAPI_EARFCN_TAG, &pNfapiMsg->nfapi_config.earfcn, &unpack_uint16_tlv_value},
+    { NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands, &unpack_nmm_frequency_bands_value},
+    { NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_umts_frequency_bands, &unpack_nmm_frequency_bands_value},
+    { NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_lte_frequency_bands, &unpack_nmm_frequency_bands_value},
+    { NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported, &unpack_uint8_tlv_value},
+
+  };
+  return ( pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) &&
+           unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_param_response_scf_t *pNfapiMsg = (nfapi_nr_param_response_scf_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG, &(pNfapiMsg->cell_param.release_capability), &unpack_uint16_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PHY_STATE_TAG, &(pNfapiMsg->cell_param.phy_state),&unpack_uint16_tlv_value},
+    { NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_dl_config), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_ul_config), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG, &(pNfapiMsg->cell_param.num_config_tlvs_to_report ), &unpack_uint16_tlv_value},
+
+    { NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG, &(pNfapiMsg->carrier_param.cyclic_prefix), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_dl), &unpack_uint16_tlv_value},
+    { NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_dl), &unpack_uint16_tlv_value},
+    { NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_ul), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_ul), &unpack_uint16_tlv_value},
+
+
+    { NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG, &(pNfapiMsg->pdcch_param.cce_mapping_type), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG, &(pNfapiMsg->pdcch_param.coreset_outside_first_3_of_ofdm_syms_of_slot), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG, &(pNfapiMsg->pdcch_param.coreset_precoder_granularity_coreset), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG, &(pNfapiMsg->pdcch_param.pdcch_mu_mimo), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG, &(pNfapiMsg->pdcch_param.pdcch_precoder_cycling), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG, &(pNfapiMsg->pdcch_param.max_pdcch_per_slot), &unpack_uint8_tlv_value},
+
+    { NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG, &(pNfapiMsg->pucch_param.pucch_formats), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG, &(pNfapiMsg->pucch_param.max_pucchs_per_slot), &unpack_uint8_tlv_value},
+
+    { NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pdsch_param.pdsch_mapping_type), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_allocation_types), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pdsch_param.pdsch_vrb_to_prb_mapping), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG, &(pNfapiMsg->pdsch_param.pdsch_cbg), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_config_types), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PDSCH_DMRS_MAX_LENGTH_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_max_length), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_additional_pos), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_MAX_PDSCH_S_YBS_PER_SLOT_TAG, &(pNfapiMsg->pdsch_param.max_pdsch_tbs_per_slot), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG, &(pNfapiMsg->pdsch_param.max_number_mimo_layers_pdsch), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG, &(pNfapiMsg->pdsch_param.max_mu_mimo_users_dl), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG, &(pNfapiMsg->pdsch_param.pdsch_data_in_dmrs_symbols), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.premption_support), &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.pdsch_non_slot_support), &unpack_uint8_tlv_value},
+
+    { NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG,  &(pNfapiMsg->pusch_param.uci_mux_ulsch_in_pusch),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG,  &(pNfapiMsg->pusch_param.uci_only_pusch),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG,  &(pNfapiMsg->pusch_param.pusch_frequency_hopping),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG,  &(pNfapiMsg->pusch_param.pusch_dmrs_config_types),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG,  &(pNfapiMsg->pusch_param.pusch_dmrs_max_len),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG,  &(pNfapiMsg->pusch_param.pusch_dmrs_additional_pos),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG,  &(pNfapiMsg->pusch_param.pusch_cbg),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG,  &(pNfapiMsg->pusch_param.pusch_mapping_type),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG,  &(pNfapiMsg->pusch_param.pusch_allocation_types),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG,  &(pNfapiMsg->pusch_param.pusch_vrb_to_prb_mapping),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG,  &(pNfapiMsg->pusch_param.pusch_max_ptrs_ports),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG,  &(pNfapiMsg->pusch_param.max_pduschs_tbs_per_slot),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG,  &(pNfapiMsg->pusch_param.max_number_mimo_layers_non_cb_pusch),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG,  &(pNfapiMsg->pusch_param.supported_modulation_order_ul),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG,  &(pNfapiMsg->pusch_param.max_mu_mimo_users_ul),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG,  &(pNfapiMsg->pusch_param.dfts_ofdm_support),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG,  &(pNfapiMsg->pusch_param.pusch_aggregation_factor),  &unpack_uint8_tlv_value},
+
+    { NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG,  &(pNfapiMsg->prach_param.prach_long_formats),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG,  &(pNfapiMsg->prach_param.prach_short_formats),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG,  &(pNfapiMsg->prach_param.prach_restricted_sets),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG,  &(pNfapiMsg->prach_param.max_prach_fd_occasions_in_a_slot),  &unpack_uint8_tlv_value},
+
+    { NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG,  &(pNfapiMsg->measurement_param.rssi_measurement_support),  &unpack_uint8_tlv_value},
+    //config
+    { NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv4, &unpack_ipv4_address_value},
+    { NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv6, &unpack_ipv6_address_value},
+    { NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_vnf_port, &unpack_uint16_tlv_value},
+    { NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv4, &unpack_ipv4_address_value},
+    { NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv6, &unpack_ipv6_address_value},
+    { NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_pnf_port, &unpack_uint16_tlv_value},
+    { NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &pNfapiMsg->nfapi_config.timing_window, &unpack_uint8_tlv_value},
+    { NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &pNfapiMsg->nfapi_config.timing_info_mode, &unpack_uint8_tlv_value},
+    { NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &pNfapiMsg->nfapi_config.timing_info_period, &unpack_uint8_tlv_value},
+  };
+  // print ppReadPackedMsg
+  uint8_t *ptr = *ppReadPackedMsg;
+  printf("\n Read message unpack_param_response: ");
+
+  while(ptr < end) {
+    printf(" %d ", *ptr);
+    ptr++;
+  }
+
+  printf("\n");
+  return ( pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) &&
+           unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_config_request_t *pNfapiMsg = (nfapi_config_request_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &pNfapiMsg->subframe_config.duplex_mode, &unpack_uint16_tlv_value},
+    { NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &pNfapiMsg->subframe_config.pcfich_power_offset, &unpack_uint16_tlv_value},
+    { NFAPI_SUBFRAME_CONFIG_PB_TAG, &pNfapiMsg->subframe_config.pb, &unpack_uint16_tlv_value},
+    { NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &pNfapiMsg->subframe_config.dl_cyclic_prefix_type, &unpack_uint16_tlv_value},
+    { NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &pNfapiMsg->subframe_config.ul_cyclic_prefix_type, &unpack_uint16_tlv_value},
+
+    { NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &pNfapiMsg->rf_config.dl_channel_bandwidth, &unpack_uint16_tlv_value},
+    { NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &pNfapiMsg->rf_config.ul_channel_bandwidth, &unpack_uint16_tlv_value},
+    { NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &pNfapiMsg->rf_config.reference_signal_power, &unpack_uint16_tlv_value},
+    { NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &pNfapiMsg->rf_config.tx_antenna_ports, &unpack_uint16_tlv_value},
+    { NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &pNfapiMsg->rf_config.rx_antenna_ports, &unpack_uint16_tlv_value},
+
+    { NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &pNfapiMsg->phich_config.phich_resource, &unpack_uint16_tlv_value},
+    { NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &pNfapiMsg->phich_config.phich_duration, &unpack_uint16_tlv_value},
+    { NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &pNfapiMsg->phich_config.phich_power_offset, &unpack_uint16_tlv_value},
+
+    { NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers, &unpack_uint16_tlv_value},
+    { NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers, &unpack_uint16_tlv_value},
+    { NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &pNfapiMsg->sch_config.physical_cell_id, &unpack_uint16_tlv_value},
+
+    { NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &pNfapiMsg->prach_config.configuration_index, &unpack_uint16_tlv_value},
+    { NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &pNfapiMsg->prach_config.root_sequence_index, &unpack_uint16_tlv_value},
+    { NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &pNfapiMsg->prach_config.zero_correlation_zone_configuration, &unpack_uint16_tlv_value},
+    { NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &pNfapiMsg->prach_config.high_speed_flag, &unpack_uint16_tlv_value},
+    { NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &pNfapiMsg->prach_config.frequency_offset, &unpack_uint16_tlv_value},
+
+    { NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &pNfapiMsg->pusch_config.hopping_mode, &unpack_uint16_tlv_value},
+    { NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &pNfapiMsg->pusch_config.hopping_offset, &unpack_uint16_tlv_value},
+    { NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &pNfapiMsg->pusch_config.number_of_subbands, &unpack_uint16_tlv_value},
+
+    { NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &pNfapiMsg->pucch_config.delta_pucch_shift, &unpack_uint16_tlv_value},
+    { NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &pNfapiMsg->pucch_config.n_cqi_rb, &unpack_uint16_tlv_value},
+    { NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &pNfapiMsg->pucch_config.n_an_cs, &unpack_uint16_tlv_value},
+    { NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &pNfapiMsg->pucch_config.n1_pucch_an, &unpack_uint16_tlv_value},
+
+    { NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &pNfapiMsg->srs_config.bandwidth_configuration, &unpack_uint16_tlv_value},
+    { NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &pNfapiMsg->srs_config.max_up_pts, &unpack_uint16_tlv_value},
+    { NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &pNfapiMsg->srs_config.srs_subframe_configuration, &unpack_uint16_tlv_value},
+    { NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission, &unpack_uint16_tlv_value},
+
+    { NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping, &unpack_uint16_tlv_value},
+    { NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &pNfapiMsg->uplink_reference_signal_config.group_assignment, &unpack_uint16_tlv_value},
+    { NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms, &unpack_uint16_tlv_value},
+
+
+    { NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_PDSCH_TAG, &pNfapiMsg->laa_config.ed_threshold_lbt_pdsch, &unpack_uint16_tlv_value},
+    { NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_DRS_TAG, &pNfapiMsg->laa_config.ed_threshold_lbt_drs, &unpack_uint16_tlv_value},
+    { NFAPI_LAA_CONFIG_PD_THRESHOLD_TAG, &pNfapiMsg->laa_config.pd_threshold, &unpack_uint16_tlv_value},
+    { NFAPI_LAA_CONFIG_MULTI_CARRIER_TYPE_TAG, &pNfapiMsg->laa_config.multi_carrier_type, &unpack_uint16_tlv_value},
+    { NFAPI_LAA_CONFIG_MULTI_CARRIER_TX_TAG, &pNfapiMsg->laa_config.multi_carrier_tx, &unpack_uint16_tlv_value},
+    { NFAPI_LAA_CONFIG_MULTI_CARRIER_FREEZE_TAG, &pNfapiMsg->laa_config.multi_carrier_freeze, &unpack_uint16_tlv_value},
+    { NFAPI_LAA_CONFIG_TX_ANTENNA_PORTS_FOR_DRS_TAG, &pNfapiMsg->laa_config.tx_antenna_ports_drs, &unpack_uint16_tlv_value},
+    { NFAPI_LAA_CONFIG_TRANSMISSION_POWER_FOR_DRS_TAG, &pNfapiMsg->laa_config.tx_power_drs, &unpack_uint16_tlv_value},
+
+    { NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG, &pNfapiMsg->emtc_config.pbch_repetitions_enable_r13, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG, &pNfapiMsg->emtc_config.prach_catm_root_sequence_index, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &pNfapiMsg->emtc_config.prach_catm_zero_correlation_zone_configuration, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG, &pNfapiMsg->emtc_config.prach_catm_high_speed_flag, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_enable, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_configuration_index, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_frequency_offset, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_starting_subframe_periodicity, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_hopping_enable, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_hopping_offset, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_enable, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_configuration_index, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_frequency_offset, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_starting_subframe_periodicity, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_hopping_enable, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_hopping_offset, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_enable, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_configuration_index, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_frequency_offset, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_starting_subframe_periodicity, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_hopping_enable, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_hopping_offset, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_enable, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_configuration_index, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_frequency_offset, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_starting_subframe_periodicity, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_hopping_enable, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_hopping_offset, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG, &pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea, &unpack_uint16_tlv_value},
+    { NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG, &pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb, &unpack_uint16_tlv_value},
+
+    { NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &pNfapiMsg->tdd_frame_structure_config.subframe_assignment, &unpack_uint16_tlv_value},
+    { NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns, &unpack_uint16_tlv_value},
+
+    { NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &pNfapiMsg->l23_config.data_report_mode, &unpack_uint16_tlv_value},
+    { NFAPI_L23_CONFIG_SFNSF_TAG, &pNfapiMsg->l23_config.sfnsf, &unpack_uint16_tlv_value},
+
+    { NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv4, &unpack_ipv4_address_value},
+    { NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv6, &unpack_ipv6_address_value},
+    { NFAPI_NFAPI_P7_VNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_vnf_port, &unpack_uint16_tlv_value},
+    { NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv4, &unpack_ipv4_address_value},
+    { NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv6, &unpack_ipv6_address_value},
+    { NFAPI_NFAPI_P7_PNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_pnf_port, &unpack_uint16_tlv_value},
+    { NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &pNfapiMsg->nfapi_config.dl_ue_per_sf, &unpack_uint8_tlv_value},
+    { NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &pNfapiMsg->nfapi_config.ul_ue_per_sf, &unpack_uint8_tlv_value},
+    { NFAPI_NFAPI_RF_BANDS_TAG, &pNfapiMsg->nfapi_config.rf_bands, &unpack_rf_bands_value},
+    { NFAPI_NFAPI_TIMING_WINDOW_TAG, &pNfapiMsg->nfapi_config.timing_window, &unpack_uint8_tlv_value},
+    { NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &pNfapiMsg->nfapi_config.timing_info_mode, &unpack_uint8_tlv_value},
+    { NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &pNfapiMsg->nfapi_config.timing_info_period, &unpack_uint8_tlv_value},
+    { NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &pNfapiMsg->nfapi_config.max_transmit_power, &unpack_uint16_tlv_value},
+    { NFAPI_NFAPI_EARFCN_TAG, &pNfapiMsg->nfapi_config.earfcn, &unpack_uint16_tlv_value},
+    { NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands, &unpack_nmm_frequency_bands_value},
+    { NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_umts_frequency_bands, &unpack_nmm_frequency_bands_value},
+    { NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_lte_frequency_bands, &unpack_nmm_frequency_bands_value},
+    { NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported, &unpack_uint8_tlv_value},
+
+  };
+  return ( pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) &&
+           unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+static uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_config_request_scf_t *pNfapiMsg = (nfapi_nr_config_request_scf_t *)msg;
+  pNfapiMsg->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t *) malloc(20*sizeof(nfapi_nr_max_tdd_periodicity_t));
+
+  for(int i=0; i<40; i++)
+    pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list = (nfapi_nr_max_num_of_symbol_per_slot_t *) malloc(14*sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
+
+  pNfapiMsg->prach_config.num_prach_fd_occasions_list=(nfapi_nr_num_prach_fd_occasions_t *) malloc(sizeof(nfapi_nr_num_prach_fd_occasions_t));
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG,  &(pNfapiMsg->carrier_config.dl_bandwidth),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_CONFIG_DL_FREQUENCY_TAG,  &(pNfapiMsg->carrier_config.dl_frequency),  &unpack_uint32_tlv_value},
+    { NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG,  &(pNfapiMsg->carrier_config.dl_grid_size[1]),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_CONFIG_DL_K0_TAG,  &(pNfapiMsg->carrier_config.dl_k0[1]),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_CONFIG_NUM_RX_ANT_TAG,  &(pNfapiMsg->carrier_config.num_rx_ant),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_CONFIG_NUM_TX_ANT_TAG,  &(pNfapiMsg->carrier_config.num_tx_ant),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG,  &(pNfapiMsg->carrier_config.ul_grid_size[1]),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_CONFIG_UL_K0_TAG,  &(pNfapiMsg->carrier_config.ul_k0[1]),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG,  &(pNfapiMsg->carrier_config.uplink_bandwidth),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG,  &(pNfapiMsg->carrier_config.uplink_frequency),  &unpack_uint32_tlv_value},
+    { NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG,  &(pNfapiMsg->cell_config.frame_duplex_type),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_PHY_CELL_ID_TAG,  &(pNfapiMsg->cell_config.phy_cell_id),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG,  &(pNfapiMsg->prach_config.num_prach_fd_occasions),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG,  &(pNfapiMsg->prach_config.prach_sequence_length),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG,  &(pNfapiMsg->prach_config.restricted_set_config),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_SSB_PER_RACH_TAG,  &(pNfapiMsg->prach_config.ssb_per_rach),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG,  &(pNfapiMsg->prach_config.prach_sub_c_spacing),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG,  &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_root_sequence_index),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_CONFIG_K1_TAG,  &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].k1),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG,  &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_zero_corr_conf),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG,  &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].num_root_sequences),  &unpack_uint8_tlv_value},
+
+    { NFAPI_NR_CONFIG_SCS_COMMON_TAG,  &(pNfapiMsg->ssb_config.scs_common),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG,  &(pNfapiMsg->ssb_config.ss_pbch_power),  &unpack_uint32_tlv_value},
+    { NFAPI_NR_CONFIG_BETA_PSS_TAG,  &(pNfapiMsg->ssb_table.beta_pss),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_MIB_TAG,  &(pNfapiMsg->ssb_table.MIB),  &unpack_uint32_tlv_value},
+    { NFAPI_NR_CONFIG_SSB_MASK_TAG,  &(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask),  &unpack_uint32_tlv_value},
+    { NFAPI_NR_CONFIG_SSB_MASK_TAG,  &(pNfapiMsg->ssb_table.ssb_mask_list[1].ssb_mask),  &unpack_uint32_tlv_value},
+
+    { NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG,  &(pNfapiMsg->ssb_table.ssb_offset_point_a),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_CONFIG_SSB_PERIOD_TAG,  &(pNfapiMsg->ssb_table.ssb_period),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG,  &(pNfapiMsg->ssb_table.ssb_subcarrier_offset),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_TDD_PERIOD_TAG,  &(pNfapiMsg->tdd_table.tdd_period),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,  &(pNfapiMsg->tdd_table.max_tdd_periodicity_list[0].max_num_of_symbol_per_slot_list[0].slot_config),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG,  &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4),  &unpack_ipv4_address_value},
+    { NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG,  &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6),  &unpack_ipv6_address_value},
+    { NFAPI_NR_NFAPI_P7_PNF_PORT_TAG,  &(pNfapiMsg->nfapi_config.p7_pnf_port),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG,  &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4),  &unpack_ipv4_address_value},
+    { NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG,  &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6),  &unpack_ipv6_address_value},
+    { NFAPI_NR_NFAPI_P7_VNF_PORT_TAG,  &(pNfapiMsg->nfapi_config.p7_vnf_port),  &unpack_uint16_tlv_value},
+    { NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG,  &(pNfapiMsg->nfapi_config.timing_info_mode),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG,  &(pNfapiMsg->nfapi_config.timing_info_period),  &unpack_uint8_tlv_value},
+    { NFAPI_NR_NFAPI_TIMING_WINDOW_TAG,  &(pNfapiMsg->nfapi_config.timing_window),  &unpack_uint8_tlv_value},
+  };
+  return ( pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) &&
+           unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_config_response_t *pNfapiMsg = (nfapi_config_response_t *)msg;
+  return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+
+static uint8_t unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_config_response_scf_t *pNfapiMsg = (nfapi_nr_config_response_scf_t *)msg;
+  return ( pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+
+static uint8_t unpack_nr_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_start_request_scf_t *pNfapiMsg = ( nfapi_nr_start_request_scf_t *)msg;
+  return unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_start_request_t *pNfapiMsg = ( nfapi_start_request_t *)msg;
+  return unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_start_response_t *pNfapiMsg = (nfapi_start_response_t *)msg;
+  return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+
+static uint8_t unpack_nr_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_nr_start_response_scf_t *pNfapiMsg = (nfapi_nr_start_response_scf_t *)msg;
+  return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+
+static uint8_t unpack_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_stop_request_t *pNfapiMsg = (nfapi_stop_request_t *)msg;
+  return unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_stop_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_stop_response_t *pNfapiMsg = (nfapi_stop_response_t *)msg;
+  return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           unpack_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+static uint8_t unpack_measurement_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_measurement_request_t *pNfapiMsg = (nfapi_measurement_request_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_MEASUREMENT_REQUEST_DL_RS_XTX_POWER_TAG, &pNfapiMsg->dl_rs_tx_power, &unpack_uint16_tlv_value},
+    { NFAPI_MEASUREMENT_REQUEST_RECEIVED_INTERFERENCE_POWER_TAG, &pNfapiMsg->received_interference_power, &unpack_uint16_tlv_value},
+    { NFAPI_MEASUREMENT_REQUEST_THERMAL_NOISE_POWER_TAG, &pNfapiMsg->thermal_noise_power, &unpack_uint16_tlv_value},
+  };
+  return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_received_interference_power_measurement_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_received_interference_power_measurement_t *value = (nfapi_received_interference_power_measurement_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &value->number_of_resource_blocks, end) &&
+           pullarrays16(ppReadPackedMsg, value->received_interference_power,  NFAPI_MAX_RECEIVED_INTERFERENCE_POWER_RESULTS, value->number_of_resource_blocks, end));
+}
+
+
+static uint8_t unpack_measurement_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_measurement_response_t *pNfapiMsg = (nfapi_measurement_response_t *)msg;
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_MEASUREMENT_RESPONSE_DL_RS_POWER_MEASUREMENT_TAG, &pNfapiMsg->dl_rs_tx_power_measurement, &unpack_int16_tlv_value},
+    { NFAPI_MEASUREMENT_RESPONSE_RECEIVED_INTERFERENCE_POWER_MEASUREMENT_TAG, &pNfapiMsg->received_interference_power_measurement, &unpack_received_interference_power_measurement_value},
+    { NFAPI_MEASUREMENT_RESPONSE_THERMAL_NOISE_MEASUREMENT_TAG, &pNfapiMsg->thermal_noise_power_measurement, &unpack_int16_tlv_value},
+  };
+  return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+           unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+// unpack length check
+
+static int check_nr_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpackedBufLen) {
+  int retLen = 0;
+
+  switch (msgId) {
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_pnf_param_request_t))
+        retLen = sizeof(nfapi_pnf_param_request_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_nr_pnf_param_response_t))
+        retLen = sizeof(nfapi_nr_pnf_param_response_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_pnf_config_request_t))
+        retLen = sizeof(nfapi_nr_pnf_config_request_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_nr_pnf_config_response_t))
+        retLen = sizeof(nfapi_nr_pnf_config_response_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_pnf_start_request_t))
+        retLen = sizeof(nfapi_nr_pnf_start_request_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_nr_pnf_start_response_t))
+        retLen = sizeof(nfapi_nr_pnf_start_response_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_pnf_stop_request_t))
+        retLen = sizeof(nfapi_nr_pnf_stop_request_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_nr_pnf_stop_response_t))
+        retLen = sizeof(nfapi_nr_pnf_stop_response_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_param_request_scf_t))
+        retLen = sizeof(nfapi_nr_param_request_scf_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_nr_param_response_scf_t))
+        retLen = sizeof(nfapi_nr_param_response_scf_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_config_request_scf_t))
+        retLen = sizeof(nfapi_nr_config_request_scf_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_nr_config_response_scf_t))
+        retLen = sizeof(nfapi_nr_config_response_scf_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
+      if (unpackedBufLen >= sizeof( nfapi_nr_start_request_scf_t))
+        retLen = sizeof( nfapi_nr_start_request_scf_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_nr_start_response_scf_t))
+        retLen = sizeof(nfapi_nr_start_response_scf_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_stop_request_t))
+        retLen = sizeof(nfapi_stop_request_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_stop_response_t))
+        retLen = sizeof(nfapi_stop_response_t);
+
+      break;
+
+    default:
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s Unknown message ID %d\n", __FUNCTION__, msgId);
+      break;
+  }
+
+  return retLen;
+}
+
+
+static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen) {
+  int retLen = 0;
+
+  switch (msgId) {
+    case NFAPI_PNF_PARAM_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_pnf_param_request_t))
+        retLen = sizeof(nfapi_pnf_param_request_t);
+
+      break;
+
+    case NFAPI_PNF_PARAM_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_pnf_param_response_t))
+        retLen = sizeof(nfapi_pnf_param_response_t);
+
+      break;
+
+    case NFAPI_PNF_CONFIG_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_pnf_config_request_t))
+        retLen = sizeof(nfapi_pnf_config_request_t);
+
+      break;
+
+    case NFAPI_PNF_CONFIG_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_pnf_config_response_t))
+        retLen = sizeof(nfapi_pnf_config_response_t);
+
+      break;
+
+    case NFAPI_PNF_START_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_pnf_start_request_t))
+        retLen = sizeof(nfapi_pnf_start_request_t);
+
+      break;
+
+    case NFAPI_PNF_START_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_pnf_start_response_t))
+        retLen = sizeof(nfapi_pnf_start_response_t);
+
+      break;
+
+    case NFAPI_PNF_STOP_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_pnf_stop_request_t))
+        retLen = sizeof(nfapi_pnf_stop_request_t);
+
+      break;
+
+    case NFAPI_PNF_STOP_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_pnf_stop_response_t))
+        retLen = sizeof(nfapi_pnf_stop_response_t);
+
+      break;
+
+    case NFAPI_PARAM_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_param_request_t))
+        retLen = sizeof(nfapi_param_request_t);
+
+      break;
+
+    case NFAPI_PARAM_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_param_response_t))
+        retLen = sizeof(nfapi_param_response_t);
+
+      break;
+
+    case NFAPI_CONFIG_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_config_request_t))
+        retLen = sizeof(nfapi_config_request_t);
+
+      break;
+
+    case NFAPI_CONFIG_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_config_response_t))
+        retLen = sizeof(nfapi_config_response_t);
+
+      break;
+
+    case NFAPI_START_REQUEST:
+      if (unpackedBufLen >= sizeof( nfapi_start_request_t))
+        retLen = sizeof( nfapi_start_request_t);
+
+      break;
+
+    case NFAPI_START_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_start_response_t))
+        retLen = sizeof(nfapi_start_response_t);
+
+      break;
+
+    case NFAPI_STOP_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_stop_request_t))
+        retLen = sizeof(nfapi_stop_request_t);
+
+      break;
+
+    case NFAPI_STOP_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_stop_response_t))
+        retLen = sizeof(nfapi_stop_response_t);
+
+      break;
+
+    case NFAPI_MEASUREMENT_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_measurement_request_t))
+        retLen = sizeof(nfapi_measurement_request_t);
+
+      break;
+
+    case NFAPI_MEASUREMENT_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_measurement_response_t))
+        retLen = sizeof(nfapi_measurement_response_t);
+
+      break;
+
+    default:
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s Unknown message ID %d\n", __FUNCTION__, msgId);
+      break;
+  }
+
+  return retLen;
+}
+
+
+// Main unpack functions - public
+
+int nfapi_p5_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+  uint8_t *end = pMessageBuf + messageBufLen;
+
+  if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied pointers are null\n");
+    return -1;
+  }
+
+  if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t)) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+    return -1;
+  }
+
+  // process the header
+  return ( pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
+           pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
+           pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
+           pull16(&pReadPackedMessage, &pMessageHeader->spare, end) );
+}
+
+int nfapi_nr_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+  uint8_t *end = pMessageBuf + messageBufLen;
+
+  if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied pointers are null\n");
+    return -1;
+  }
+
+  if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t)) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+    return -1;
+  }
+
+  uint8_t *ptr = pReadPackedMessage;
+  printf("\n Read message unpack: ");
+
+  while(ptr < end) {
+    printf(" %d ", *ptr);
+    ptr++;
+  }
+
+  printf("\n");
+  // clean the supplied buffer for - tag value blanking
+  (void)memset(pUnpackedBuf, 0, unpackedBufLen);
+
+  // process the header
+  if( !(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end ) &&
+        pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
+        pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
+        pull16(&pReadPackedMessage, &pMessageHeader->spare, end))) {
+    // failed to read the header
+    return -1;
+  }
+
+  int result = -1;
+
+  if(check_nr_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0) {
+    // the unpack buffer is not big enough for the struct
+    return -1;
+  }
+
+  // look for the specific message
+  switch (pMessageHeader->message_id) {
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
+      result = unpack_nr_pnf_param_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE:
+      result = unpack_nr_pnf_param_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
+      result = unpack_nr_pnf_config_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE:
+      result = unpack_nr_pnf_config_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
+      result = unpack_nr_pnf_start_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE:
+      result = unpack_nr_pnf_start_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST:
+      result = unpack_pnf_stop_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_RESPONSE:
+      result = unpack_pnf_stop_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
+      result = unpack_nr_param_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
+      result = unpack_nr_param_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
+      result = unpack_nr_config_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
+      result = unpack_nr_config_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
+      result = unpack_nr_start_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
+      result = unpack_nr_start_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
+      result = unpack_stop_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
+      result = unpack_stop_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_MEASUREMENT_REQUEST:
+      result = unpack_measurement_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_MEASUREMENT_RESPONSE:
+      result = unpack_measurement_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    default:
+      if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+          pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if(config && config->unpack_p4_p5_vendor_extension) {
+          result = (config->unpack_p4_p5_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown P5 message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+      }
+
+      break;
+  }
+
+  return result;
+}
+
+int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t *config) {
+  nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+  uint8_t *end = pMessageBuf + messageBufLen;
+
+  if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied pointers are null\n");
+    return -1;
+  }
+
+  if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t)) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+    return -1;
+  }
+
+  uint8_t *ptr = pReadPackedMessage;
+  printf("\n Read message unpack: ");
+
+  while(ptr < end) {
+    printf(" %d ", *ptr);
+    ptr++;
+  }
+
+  printf("\n");
+  // clean the supplied buffer for - tag value blanking
+  (void)memset(pUnpackedBuf, 0, unpackedBufLen);
+
+  // process the header
+  if( !(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end ) &&
+        pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
+        pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
+        pull16(&pReadPackedMessage, &pMessageHeader->spare, end))) {
+    // failed to read the header
+    return -1;
+  }
+
+  int result = -1;
+
+  if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0) {
+    // the unpack buffer is not big enough for the struct
+    return -1;
+  }
+
+  // look for the specific message
+  switch (pMessageHeader->message_id) {
+    case NFAPI_PNF_PARAM_REQUEST:
+      result = unpack_pnf_param_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_PNF_PARAM_RESPONSE:
+      result = unpack_pnf_param_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_PNF_CONFIG_REQUEST:
+      result = unpack_pnf_config_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_PNF_CONFIG_RESPONSE:
+      result = unpack_pnf_config_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_PNF_START_REQUEST:
+      result = unpack_pnf_start_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_PNF_START_RESPONSE:
+      result = unpack_pnf_start_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_PNF_STOP_REQUEST:
+      result = unpack_pnf_stop_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_PNF_STOP_RESPONSE:
+      result = unpack_pnf_stop_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_PARAM_REQUEST:
+      result = unpack_param_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_PARAM_RESPONSE:
+      result = unpack_param_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_CONFIG_REQUEST:
+      result = unpack_config_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_CONFIG_RESPONSE:
+      result = unpack_config_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_START_REQUEST:
+      result = unpack_start_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_START_RESPONSE:
+      result = unpack_start_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_STOP_REQUEST:
+      result = unpack_stop_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_STOP_RESPONSE:
+      result = unpack_stop_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_MEASUREMENT_REQUEST:
+      result = unpack_measurement_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    case NFAPI_MEASUREMENT_RESPONSE:
+      result = unpack_measurement_response(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+
+    default:
+      if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+          pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if(config && config->unpack_p4_p5_vendor_extension) {
+          result = (config->unpack_p4_p5_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown P5 message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+      }
+
+      break;
+  }
+
+  return result;
+}
+
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
old mode 100755
new mode 100644
index 837f33fe6f6907436ee3d15346dc9225322ee471..9e9c9d5496673f4911fb1c08be3ce5ca8bf9e5f1
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
@@ -1,8269 +1,7362 @@
-/*
- * Copyright 2017 Cisco Systems, Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 
- * 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.
- */
-
-
-#include <assert.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <zlib.h>
-#include <sched.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <pthread.h>
-#include <stdint.h>
-
-#include <nfapi_interface.h>
-#include <nfapi.h>
-#include <debug.h>
-#include "nfapi_nr_interface_scf.h"
-
-extern int nfapi_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t **ppReadPackedMsg, void* user_data);
-extern int nfapi_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t **ppWritePackedMsg, void* user_data);
-
-uint32_t nfapi_calculate_checksum(uint8_t* buffer, uint16_t len)
-{
-	uint32_t chksum = 0;
-	// calcaulte upto the checksum
-	chksum = crc32(chksum, buffer, 8);
-	
-	// skip the checksum
-	uint8_t zeros[4] = {0, 0, 0, 0};
-	chksum = crc32(chksum, zeros, 4);
-	
-	// continu with the rest of the mesage
-	chksum = crc32(chksum, &buffer[NFAPI_P7_HEADER_LENGTH], len - NFAPI_P7_HEADER_LENGTH);
-	
-	// return the inverse
-	return ~(chksum);
-}
-
-int nfapi_p7_update_checksum(uint8_t* buffer, uint32_t len)
-{
-	uint32_t checksum = nfapi_calculate_checksum(buffer, len);
-
-	uint8_t* p_write = &buffer[8];
-	return (push32(checksum, &p_write, buffer + len) > 0 ? 0 : -1);
-}
-
-int nfapi_p7_update_transmit_timestamp(uint8_t* buffer, uint32_t timestamp)
-{
-	uint8_t* p_write = &buffer[12];
-	return (push32(timestamp, &p_write, buffer + 16) > 0 ? 0 : -1);
-}
-
-uint32_t nfapi_p7_calculate_checksum(uint8_t* buffer, uint32_t len)
-{
-	return nfapi_calculate_checksum(buffer, len);
-}
-
-void* nfapi_p7_allocate(size_t size, nfapi_p7_codec_config_t* config)
-{
-	if(size == 0)
-		return 0;
-
-       void* buffer_p = NULL;
-	if(config && config->allocate)
-	{
-               buffer_p = (config->allocate)(size);
-               if(buffer_p != NULL){
-               memset(buffer_p,0,size);
-               }
-               return buffer_p;
-	}
-	else
-	{
-               buffer_p = calloc(1, size);
-               return buffer_p;
-	}
-}
-
-void nfapi_p7_deallocate(void* ptr, nfapi_p7_codec_config_t* config)
-{
-	if(ptr == NULL)
-		return;
-
-	if(config && config->deallocate)
-	{
-		return (config->deallocate)(ptr);
-	}
-	else
-	{
-		return free(ptr);
-	}
-}
-// Pack routines
-
-
-static uint8_t pack_dl_config_dci_dl_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dci_dl_pdu_rel8_t* value = (nfapi_dl_config_dci_dl_pdu_rel8_t*)tlv;
-	
-        //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() dci_format:%u\n", __FUNCTION__, value->dci_format);
-
-	return ( push8(value->dci_format, ppWritePackedMsg, end) &&
-			 push8(value->cce_idx, ppWritePackedMsg, end) &&
-			 push8(value->aggregation_level, ppWritePackedMsg, end) &&
-			 push16(value->rnti, ppWritePackedMsg, end) &&
-			 push8(value->resource_allocation_type, ppWritePackedMsg, end) &&
-			 push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) &&
-			 push32(value->resource_block_coding, ppWritePackedMsg, end) &&
-			 push8(value->mcs_1, ppWritePackedMsg, end) &&
-			 push8(value->redundancy_version_1, ppWritePackedMsg, end) &&
-			 push8(value->new_data_indicator_1, ppWritePackedMsg, end) &&
-			 push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) &&
-			 push8(value->mcs_2, ppWritePackedMsg, end) &&
-			 push8(value->redundancy_version_2, ppWritePackedMsg, end) &&
-			 push8(value->new_data_indicator_2, ppWritePackedMsg, end) &&
-			 push8(value->harq_process, ppWritePackedMsg, end) &&
-			 push8(value->tpmi, ppWritePackedMsg, end) &&
-			 push8(value->pmi, ppWritePackedMsg, end) &&
-			 push8(value->precoding_information, ppWritePackedMsg, end) &&
-			 push8(value->tpc, ppWritePackedMsg, end) &&
-			 push8(value->downlink_assignment_index, ppWritePackedMsg, end) &&
-			 push8(value->ngap, ppWritePackedMsg, end) &&
-			 push8(value->transport_block_size_index, ppWritePackedMsg, end) &&
-			 push8(value->downlink_power_offset, ppWritePackedMsg, end) &&
-			 push8(value->allocate_prach_flag, ppWritePackedMsg, end) &&
-			 push8(value->preamble_index, ppWritePackedMsg, end) &&
-			 push8(value->prach_mask_index, ppWritePackedMsg, end) &&
-			 push8(value->rnti_type, ppWritePackedMsg, end) &&
-			 push16(value->transmission_power, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_dl_config_dci_dl_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dci_dl_pdu_rel9_t* value = (nfapi_dl_config_dci_dl_pdu_rel9_t*)tlv;
-
-	return( push8(value->mcch_flag, ppWritePackedMsg, end) &&
-			push8(value->mcch_change_notification, ppWritePackedMsg, end) &&
-			push8(value->scrambling_identity, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_dl_config_dci_dl_pdu_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dci_dl_pdu_rel10_t* value = (nfapi_dl_config_dci_dl_pdu_rel10_t*)tlv;
-	
-	return ( push8(value->cross_carrier_scheduling_flag, ppWritePackedMsg, end) &&
-			 push8(value->carrier_indicator, ppWritePackedMsg, end) &&
-			 push8(value->srs_flag, ppWritePackedMsg, end) &&
-			 push8(value->srs_request, ppWritePackedMsg, end) &&
-			 push8(value->antenna_ports_scrambling_and_layers, ppWritePackedMsg, end) &&
-			 push8(value->total_dci_length_including_padding, ppWritePackedMsg, end) && 
-			 push8(value->n_dl_rb, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_dl_config_dci_dl_pdu_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dci_dl_pdu_rel11_t* value = (nfapi_dl_config_dci_dl_pdu_rel11_t*)tlv;
-	
-	return ( push8(value->harq_ack_resource_offset, ppWritePackedMsg, end) &&
-		 	 push8(value->pdsch_re_mapping_quasi_co_location_indicator, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_dl_config_dci_dl_pdu_rel12_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dci_dl_pdu_rel12_t* value = (nfapi_dl_config_dci_dl_pdu_rel12_t*)tlv;
-	
-	return ( push8(value->primary_cell_type, ppWritePackedMsg, end) &&
-			 push8(value->ul_dl_configuration_flag, ppWritePackedMsg, end) &&
-			 push8(value->number_ul_dl_configurations, ppWritePackedMsg, end) &&
-			 pusharray8(value->ul_dl_configuration_indication, NFAPI_MAX_UL_DL_CONFIGURATIONS, value->number_ul_dl_configurations, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_tpm_value(nfapi_dl_config_dci_dl_tpm_t* value, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	if (!( push8(value->num_prb_per_subband, ppWritePackedMsg, end) &&
-	       push8(value->number_of_subbands, ppWritePackedMsg, end) &&
-	       push8(value->num_antennas, ppWritePackedMsg, end)))
-		return 0;
-	
-	uint8_t idx = 0;
-	for(idx = 0; idx < value->number_of_subbands; ++idx)
-	{
-		nfapi_dl_config_dci_dl_tpm_subband_info_t* subband_info = &(value->subband_info[idx]);
-		
-		if(!(push8(subband_info->subband_index, ppWritePackedMsg, end) &&
-			 push8(subband_info->scheduled_ues, ppWritePackedMsg, end)))
-			return 0;	
-		
-
-		uint8_t antenna_idx = 0;
-		uint8_t scheduled_ue_idx = 0;
-		
-		for(antenna_idx = 0; antenna_idx < value->num_antennas; ++antenna_idx)
-		{
-			for(scheduled_ue_idx = 0; scheduled_ue_idx < subband_info->scheduled_ues; ++scheduled_ue_idx)
-			{
-				if(!push16(subband_info->precoding_value[antenna_idx][scheduled_ue_idx], ppWritePackedMsg, end))
-					return 0;
-			}
-		}
-
-	}
-	
-	
-	return 1;			
-	
-}
-
-
-static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nr_dl_tti_csi_rs_pdu_rel15_t* value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t*)tlv;
-
-	return(
-		push16(value->bwp_size, ppWritePackedMsg, end) &&
-		push16(value->bwp_start, ppWritePackedMsg, end) &&
-
-		push8(value->subcarrier_spacing, ppWritePackedMsg, end) &&
-		push8(value->cyclic_prefix, ppWritePackedMsg, end) &&
-
-		push16(value->start_rb, ppWritePackedMsg, end) &&
-		push16(value->nr_of_rbs, ppWritePackedMsg, end) &&
-
-		push8(value->csi_type, ppWritePackedMsg, end) &&
-		push8(value->row, ppWritePackedMsg, end) &&
-
-		push16(value->freq_domain, ppWritePackedMsg, end) &&
-		push8(value->symb_l0, ppWritePackedMsg, end) &&
-
-		push8(value->symb_l1, ppWritePackedMsg, end) &&
-		push8(value->cdm_type, ppWritePackedMsg, end) &&
-
-		push8(value->freq_density, ppWritePackedMsg, end) &&
-		push16(value->scramb_id, ppWritePackedMsg, end) &&
-
-		push8(value->power_control_offset, ppWritePackedMsg, end) &&
-		push8(value->power_control_offset_ss, ppWritePackedMsg, end)
-	);
-
-}
-
-
-static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nr_dl_tti_pdcch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t*)tlv;
-	
-	for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i)
-	{
-		if(!push16(value->dci_pdu[i].RNTI, ppWritePackedMsg, end) &&
-		push16(value->dci_pdu[i].ScramblingId, ppWritePackedMsg, end) &&
-
-		push16(value->dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end) &&
-		push8(value->dci_pdu[i].CceIndex, ppWritePackedMsg, end) &&
-		push8(value->dci_pdu[i].AggregationLevel, ppWritePackedMsg, end) &&
-		push8(value->dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end) &&
-
-		push8(value->dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
-		push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
-		pusharray8(value->dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end));
-
-		return 0;
-	}
-
-	// TODO: resolve the packaging of array (currently sending a single element)
-	return(
-		push16(value->BWPSize, ppWritePackedMsg, end) &&
-		push16(value->BWPStart, ppWritePackedMsg, end) &&
-		push8(value->SubcarrierSpacing, ppWritePackedMsg, end) &&
-		push8(value->CyclicPrefix, ppWritePackedMsg, end) &&
-
-		push8(value->StartSymbolIndex, ppWritePackedMsg, end) &&
-		push8(value->DurationSymbols, ppWritePackedMsg, end) &&
-		pusharray8(value->FreqDomainResource, 6, 6, ppWritePackedMsg, end) &&
-		push8(value->CceRegMappingType, ppWritePackedMsg, end) &&
-
-		push8(value->RegBundleSize, ppWritePackedMsg, end) &&
-		push8(value->InterleaverSize, ppWritePackedMsg, end) &&
-		push8(value->CoreSetType, ppWritePackedMsg, end) &&
-		push16(value->ShiftIndex, ppWritePackedMsg, end) &&
-
-		push8(value->precoderGranularity, ppWritePackedMsg, end) &&
-		push16(value->numDlDci, ppWritePackedMsg, end));
-
-}
-
-
-static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nr_dl_tti_pdsch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t*)tlv;
-
-	// TODO: resolve the packaging of array (currently sending a single element)
-	return(
-		push16(value->pduBitmap, ppWritePackedMsg, end) &&
-		push16(value->rnti, ppWritePackedMsg, end) &&
-		push16(value->pduIndex, ppWritePackedMsg, end) &&
-		push16(value->BWPSize, ppWritePackedMsg, end) &&
-		
-		push16(value->BWPStart, ppWritePackedMsg, end) &&
-		push8(value->SubcarrierSpacing, ppWritePackedMsg, end) &&
-		push8(value->CyclicPrefix, ppWritePackedMsg, end) &&
-		push8(value->NrOfCodewords, ppWritePackedMsg, end) &&
-		
-		pusharray16(value->targetCodeRate, 2, 1, ppWritePackedMsg, end) &&
-		pusharray8(value->qamModOrder, 2, 1, ppWritePackedMsg, end) &&
-		pusharray8(value->mcsIndex, 2, 1, ppWritePackedMsg, end) &&
-        pusharray8(value->mcsTable, 2, 1, ppWritePackedMsg, end) &&
-		
-		pusharray8(value->rvIndex, 2, 1, ppWritePackedMsg, end) &&
-	    pusharray32(value->TBSize, 2, 1, ppWritePackedMsg, end) &&
-	    push16(value->dataScramblingId, ppWritePackedMsg, end) &&
-		push8(value->nrOfLayers, ppWritePackedMsg, end) &&
-		
-		push8(value->transmissionScheme, ppWritePackedMsg, end) &&
-		push8(value->refPoint, ppWritePackedMsg, end) &&
-		push16(value->dlDmrsSymbPos, ppWritePackedMsg, end) &&
-		push8(value->dmrsConfigType, ppWritePackedMsg, end) &&
-		
-		push16(value->dlDmrsScramblingId, ppWritePackedMsg, end) &&
-		push8(value->SCID, ppWritePackedMsg, end) &&
-		push8(value->numDmrsCdmGrpsNoData, ppWritePackedMsg, end) &&
-		push16(value->dmrsPorts, ppWritePackedMsg, end) &&
-
-		push8(value->resourceAlloc, ppWritePackedMsg, end) &&
-		push16(value->rbStart, ppWritePackedMsg, end) &&
-		push16(value->rbSize, ppWritePackedMsg, end) &&
-
-		push8(value->VRBtoPRBMapping, ppWritePackedMsg, end) &&
-		push8(value->StartSymbolIndex, ppWritePackedMsg, end) &&
-		push8(value->NrOfSymbols, ppWritePackedMsg, end) &&
-		push8(value->PTRSPortIndex, ppWritePackedMsg, end) &&
-
-		push8(value->PTRSTimeDensity, ppWritePackedMsg, end) &&
-		push8(value->PTRSFreqDensity, ppWritePackedMsg, end) &&
-		push8(value->PTRSReOffset, ppWritePackedMsg, end) 	
-	);
-
-}
-
-
-static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nr_dl_tti_ssb_pdu_rel15_t* value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t*)tlv;
-
-	return(
-		push16(value->PhysCellId, ppWritePackedMsg, end) &&
-		push8(value->BetaPss, ppWritePackedMsg, end) &&
-		push8(value->SsbBlockIndex, ppWritePackedMsg, end) &&
-		push8(value->SsbSubcarrierOffset, ppWritePackedMsg, end) &&
-		push16(value->ssbOffsetPointA, ppWritePackedMsg, end) &&
-		push8(value->bchPayloadFlag, ppWritePackedMsg, end) &&
-		push32(value->bchPayload, ppWritePackedMsg, end)	
-		// TODO: pack precoding_and_beamforming too
-	);
-
-}
-
-
-static uint8_t pack_dl_config_dci_dl_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dci_dl_pdu_rel13_t* value = (nfapi_dl_config_dci_dl_pdu_rel13_t*)tlv;
-
-	return( push8(value->laa_end_partial_sf_flag, ppWritePackedMsg, end) &&
-			push8(value->laa_end_partial_sf_configuration, ppWritePackedMsg, end) &&
-			push8(value->initial_lbt_sf, ppWritePackedMsg, end) &&
-			push8(value->codebook_size_determination, ppWritePackedMsg, end) &&
-			push8(value->drms_table_flag, ppWritePackedMsg, end) &&
-			push8(value->tpm_struct_flag, ppWritePackedMsg, end) &&
-			(value->tpm_struct_flag == 1 ? pack_tpm_value(&(value->tpm), ppWritePackedMsg, end) : 1));
-}
-
-static uint8_t pack_dl_config_bch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_bch_pdu_rel8_t* value = (nfapi_dl_config_bch_pdu_rel8_t*)tlv;
-	
-        //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s()\n", __FUNCTION__);
-
-	return( push16(value->length, ppWritePackedMsg, end) &&
-			push16(value->pdu_index, ppWritePackedMsg, end) &&
-			push16(value->transmission_power, ppWritePackedMsg, end));
-}
-static uint8_t pack_dl_config_mch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_mch_pdu_rel8_t* value = (nfapi_dl_config_mch_pdu_rel8_t*)tlv;
-
-	return ( push16(value->length, ppWritePackedMsg, end) &&
-			 push16(value->pdu_index, ppWritePackedMsg, end) &&
-			 push16(value->rnti, ppWritePackedMsg, end) &&
-			 push8(value->resource_allocation_type, ppWritePackedMsg, end) &&
-			 push32(value->resource_block_coding, ppWritePackedMsg, end) &&
-			 push8(value->modulation, ppWritePackedMsg, end) &&
-			 push16(value->transmission_power, ppWritePackedMsg, end) &&
-			 push16(value->mbsfn_area_id, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_bf_vector_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_bf_vector_t* bf = (nfapi_bf_vector_t*)elem;
-
-	return ( push8(bf->subband_index, ppWritePackedMsg, end) &&
-			 push8(bf->num_antennas, ppWritePackedMsg, end) &&
-			 pusharray16(bf->bf_value, NFAPI_MAX_NUM_ANTENNAS, bf->num_antennas, ppWritePackedMsg, end));
-
-	
-}
-static uint8_t pack_dl_config_dlsch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dlsch_pdu_rel8_t* value = (nfapi_dl_config_dlsch_pdu_rel8_t*)tlv;
-
-	return ( push16(value->length, ppWritePackedMsg, end) && 
-			 push16(value->pdu_index, ppWritePackedMsg, end) &&
-			 push16(value->rnti, ppWritePackedMsg, end) &&
-			 push8(value->resource_allocation_type, ppWritePackedMsg, end) &&
-			 push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) &&
-			 push32(value->resource_block_coding, ppWritePackedMsg, end) &&
-			 push8(value->modulation, ppWritePackedMsg, end) &&
-			 push8(value->redundancy_version, ppWritePackedMsg, end) &&
-			 push8(value->transport_blocks, ppWritePackedMsg, end) &&
-			 push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) &&
-			 push8(value->transmission_scheme, ppWritePackedMsg, end) &&
-			 push8(value->number_of_layers, ppWritePackedMsg, end) &&
-			 push8(value->number_of_subbands, ppWritePackedMsg, end) &&
-			 pusharray8(value->codebook_index, NFAPI_MAX_NUM_SUBBANDS, value->number_of_subbands, ppWritePackedMsg, end) &&
-			 push8(value->ue_category_capacity, ppWritePackedMsg, end) &&
-			 push8(value->pa, ppWritePackedMsg, end) &&
-			 push8(value->delta_power_offset_index, ppWritePackedMsg, end) &&
-			 push8(value->ngap, ppWritePackedMsg, end) &&
-			 push8(value->nprb, ppWritePackedMsg, end) &&
-			 push8(value->transmission_mode, ppWritePackedMsg, end) &&
-			 push8(value->num_bf_prb_per_subband, ppWritePackedMsg, end) &&
-			 push8(value->num_bf_vector, ppWritePackedMsg, end) &&
-			 packarray(value->bf_vector, sizeof(nfapi_bf_vector_t), NFAPI_MAX_BF_VECTORS, value->num_bf_vector, ppWritePackedMsg, end, &pack_bf_vector_info));
-
-}
-static uint8_t pack_dl_config_dlsch_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dlsch_pdu_rel9_t* value = (nfapi_dl_config_dlsch_pdu_rel9_t*)tlv;
-	return ( push8(value->nscid, ppWritePackedMsg, end) );
-}
-static uint8_t pack_dl_config_dlsch_pdu_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dlsch_pdu_rel10_t* value = (nfapi_dl_config_dlsch_pdu_rel10_t*)tlv;
-	
-	return ( push8(value->csi_rs_flag, ppWritePackedMsg, end) &&
-			 push8(value->csi_rs_resource_config_r10, ppWritePackedMsg, end) &&
-			 push16(value->csi_rs_zero_tx_power_resource_config_bitmap_r10, ppWritePackedMsg, end) &&
-			 push8(value->csi_rs_number_nzp_configuration, ppWritePackedMsg, end) &&
-			 pusharray8(value->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, value->csi_rs_number_nzp_configuration, ppWritePackedMsg, end) &&
-			 push8(value->pdsch_start, ppWritePackedMsg, end));
-}
-static uint8_t pack_dl_config_dlsch_pdu_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dlsch_pdu_rel11_t* value = (nfapi_dl_config_dlsch_pdu_rel11_t*)tlv;
-	
-	return( push8(value->drms_config_flag, ppWritePackedMsg, end) &&
-			push16(value->drms_scrambling, ppWritePackedMsg, end) &&
-			push8(value->csi_config_flag, ppWritePackedMsg, end) &&
-			push16(value->csi_scrambling, ppWritePackedMsg, end) &&
-			push8(value->pdsch_re_mapping_flag, ppWritePackedMsg, end) &&
-			push8(value->pdsch_re_mapping_atenna_ports, ppWritePackedMsg, end) &&
-			push8(value->pdsch_re_mapping_freq_shift, ppWritePackedMsg, end));
-}
-static uint8_t pack_dl_config_dlsch_pdu_rel12_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dlsch_pdu_rel12_t* value = (nfapi_dl_config_dlsch_pdu_rel12_t*)tlv;
-
-	return( push8(value->altcqi_table_r12, ppWritePackedMsg, end) &&
-			push8(value->maxlayers, ppWritePackedMsg, end) &&
-			push8(value->n_dl_harq, ppWritePackedMsg, end));
-}
-static uint8_t pack_dl_config_dlsch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dlsch_pdu_rel13_t* value = (nfapi_dl_config_dlsch_pdu_rel13_t*)tlv;
-	
-	return( push8(value->dwpts_symbols, ppWritePackedMsg, end) &&
-			push8(value->initial_lbt_sf, ppWritePackedMsg, end) &&
-			push8(value->ue_type, ppWritePackedMsg, end) &&
-			push8(value->pdsch_payload_type, ppWritePackedMsg, end) &&
-			push16(value->initial_transmission_sf_io, ppWritePackedMsg, end) &&
-			push8(value->drms_table_flag, ppWritePackedMsg, end));
-}
-static uint8_t pack_dl_config_pch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_pch_pdu_rel8_t* value = (nfapi_dl_config_pch_pdu_rel8_t*)tlv;
-	
-	return( push16(value->length, ppWritePackedMsg, end) &&
-			push16(value->pdu_index, ppWritePackedMsg, end) &&
-			push16(value->p_rnti, ppWritePackedMsg, end) &&
-			push8(value->resource_allocation_type, ppWritePackedMsg, end) &&
-			push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) &&
-			push32(value->resource_block_coding, ppWritePackedMsg, end) &&
-			push8(value->mcs, ppWritePackedMsg, end) &&
-			push8(value->redundancy_version, ppWritePackedMsg, end) &&
-			push8(value->number_of_transport_blocks, ppWritePackedMsg, end) &&
-			push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) &&
-			push8(value->transmission_scheme, ppWritePackedMsg, end) &&
-			push8(value->number_of_layers, ppWritePackedMsg, end) &&
-			push8(value->codebook_index, ppWritePackedMsg, end) &&
-			push8(value->ue_category_capacity, ppWritePackedMsg, end) &&
-			push8(value->pa, ppWritePackedMsg, end) &&
-			push16(value->transmission_power, ppWritePackedMsg, end) &&
-			push8(value->nprb, ppWritePackedMsg, end) &&
-			push8(value->ngap, ppWritePackedMsg, end));
-}
-static uint8_t pack_dl_config_pch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_pch_pdu_rel13_t* value = (nfapi_dl_config_pch_pdu_rel13_t*)tlv;
-
-	return ( push8(value->ue_mode, ppWritePackedMsg, end) &&
-		 	 push16(value->initial_transmission_sf_io, ppWritePackedMsg, end));
-}
-static uint8_t pack_dl_config_prs_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_prs_pdu_rel9_t* value = (nfapi_dl_config_prs_pdu_rel9_t*)tlv;
-
-	return( push16(value->transmission_power, ppWritePackedMsg, end) &&
-			push8(value->prs_bandwidth, ppWritePackedMsg, end) &&
-			push8(value->prs_cyclic_prefix_type, ppWritePackedMsg, end) &&
-			push8(value->prs_muting, ppWritePackedMsg, end));
-}
-static uint8_t pack_dl_config_csi_rs_pdu_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_csi_rs_pdu_rel10_t* value = (nfapi_dl_config_csi_rs_pdu_rel10_t*)tlv;
-
-	return( push8(value->csi_rs_antenna_port_count_r10, ppWritePackedMsg, end) &&
-			push8(value->csi_rs_resource_config_r10, ppWritePackedMsg, end) &&
-			push16(value->transmission_power, ppWritePackedMsg, end) &&
-			push16(value->csi_rs_zero_tx_power_resource_config_bitmap_r10, ppWritePackedMsg, end) &&
-			push8(value->csi_rs_number_of_nzp_configuration, ppWritePackedMsg, end) &&
-			pusharray8(value->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, value->csi_rs_number_of_nzp_configuration, ppWritePackedMsg, end));
-}
-static uint8_t pack_dl_config_csi_rs_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_csi_rs_pdu_rel13_t* value = (nfapi_dl_config_csi_rs_pdu_rel13_t*)tlv;
-
-	if(!(push8(value->csi_rs_class, ppWritePackedMsg, end) &&
-		 	 push8(value->cdm_type, ppWritePackedMsg, end) &&
-		 	 push8(value->num_bf_vector, ppWritePackedMsg, end)))
-	{
-		return 0;
-	}
-
-	uint16_t i; 
-	for(i = 0; i < value->num_bf_vector; ++i)
-	{
-		if(!(push8(value->bf_vector[i].csi_rs_resource_index, ppWritePackedMsg, end) &&
-		     pusharray16(value->bf_vector[i].bf_value, NFAPI_MAX_ANTENNA_PORT_COUNT, NFAPI_MAX_ANTENNA_PORT_COUNT, ppWritePackedMsg, end)))
-			return 0;
-	}
-
-	return 1;
-}
-static uint8_t pack_bf_vector(nfapi_bf_vector_t* vector, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return ( push8(vector->subband_index, ppWritePackedMsg, end) &&
-			 push8(vector->num_antennas, ppWritePackedMsg, end) &&
-		 	 pusharray16(vector->bf_value, NFAPI_MAX_NUM_ANTENNAS, vector->num_antennas, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_dl_config_epdcch_parameters_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_epdcch_parameters_rel11_t* value = (nfapi_dl_config_epdcch_parameters_rel11_t*)tlv;
-
-	return ( push8(value->epdcch_resource_assignment_flag, ppWritePackedMsg, end) &&
-			push16(value->epdcch_id, ppWritePackedMsg, end) &&
-			push8(value->epdcch_start_symbol, ppWritePackedMsg, end) &&
-			push8(value->epdcch_num_prb, ppWritePackedMsg, end) &&
-			pusharray8(value->epdcch_prb_index, NFAPI_MAX_EPDCCH_PRB, value->epdcch_num_prb, ppWritePackedMsg, end) &&
-			pack_bf_vector(&value->bf_vector, ppWritePackedMsg, end));
-}
-static uint8_t pack_dl_config_epdcch_parameters_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_epdcch_parameters_rel13_t* value = (nfapi_dl_config_epdcch_parameters_rel13_t*)tlv;
-	
-	return (push8(value->dwpts_symbols, ppWritePackedMsg, end) &&
-		 	push8(value->initial_lbt_sf, ppWritePackedMsg, end));
-}
-static uint8_t pack_dl_config_mpdcch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_mpdcch_pdu_rel13_t* value = (nfapi_dl_config_mpdcch_pdu_rel13_t*)tlv;
-	
-	return ( push8(value->mpdcch_narrow_band, ppWritePackedMsg, end) &&
-			 push8(value->number_of_prb_pairs, ppWritePackedMsg, end) &&
-			 push8(value->resource_block_assignment, ppWritePackedMsg, end) &&
-			 push8(value->mpdcch_tansmission_type, ppWritePackedMsg, end) &&
-			 push8(value->start_symbol, ppWritePackedMsg, end) &&
-			 push8(value->ecce_index, ppWritePackedMsg, end) &&
-			 push8(value->aggregation_level, ppWritePackedMsg, end) &&
-			 push8(value->rnti_type, ppWritePackedMsg, end) &&
-			 push16(value->rnti, ppWritePackedMsg, end) &&
-			 push8(value->ce_mode, ppWritePackedMsg, end) &&
-			 push16(value->drms_scrambling_init, ppWritePackedMsg, end) &&
-			 push16(value->initial_transmission_sf_io, ppWritePackedMsg, end) &&
-			 push16(value->transmission_power, ppWritePackedMsg, end) &&
-			 push8(value->dci_format, ppWritePackedMsg, end) &&
-			 push16(value->resource_block_coding, ppWritePackedMsg, end) &&
-			 push8(value->mcs, ppWritePackedMsg, end) &&
-			 push8(value->pdsch_reptition_levels, ppWritePackedMsg, end) &&
-			 push8(value->redundancy_version, ppWritePackedMsg, end) &&
-			 push8(value->new_data_indicator, ppWritePackedMsg, end) &&
-			 push8(value->harq_process, ppWritePackedMsg, end) &&
-			 push8(value->tpmi_length, ppWritePackedMsg, end) &&
-			 push8(value->tpmi, ppWritePackedMsg, end) &&
-			 push8(value->pmi_flag, ppWritePackedMsg, end) &&
-			 push8(value->pmi, ppWritePackedMsg, end) &&
-			 push8(value->harq_resource_offset, ppWritePackedMsg, end) &&
-			 push8(value->dci_subframe_repetition_number, ppWritePackedMsg, end) &&
-			 push8(value->tpc, ppWritePackedMsg, end) &&
-			 push8(value->downlink_assignment_index_length, ppWritePackedMsg, end) &&
-			 push8(value->downlink_assignment_index, ppWritePackedMsg, end) &&
-			 push8(value->allocate_prach_flag, ppWritePackedMsg, end) &&
-			 push8(value->preamble_index, ppWritePackedMsg, end) &&
-			 push8(value->prach_mask_index, ppWritePackedMsg, end) &&
-			 push8(value->starting_ce_level, ppWritePackedMsg, end) &&
-			 push8(value->srs_request, ppWritePackedMsg, end) &&
-			 push8(value->antenna_ports_and_scrambling_identity_flag, ppWritePackedMsg, end) &&
-			 push8(value->antenna_ports_and_scrambling_identity, ppWritePackedMsg, end) &&
-			 push8(value->frequency_hopping_enabled_flag, ppWritePackedMsg, end) &&
-			 push8(value->paging_direct_indication_differentiation_flag, ppWritePackedMsg, end) &&
-			 push8(value->direct_indication, ppWritePackedMsg, end) &&
-			 push8(value->total_dci_length_including_padding, ppWritePackedMsg, end) &&
-			 push8(value->number_of_tx_antenna_ports, ppWritePackedMsg, end) &&
-			 pusharray16(value->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, value->number_of_tx_antenna_ports, ppWritePackedMsg, end));
-}
-
-
-static uint8_t pack_dl_config_nbch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_nbch_pdu_rel13_t* value = (nfapi_dl_config_nbch_pdu_rel13_t*)tlv;
-	
-	return (push16(value->length, ppWritePackedMsg, end) &&
-		 	push16(value->pdu_index, ppWritePackedMsg, end) &&
-		 	push16(value->transmission_power, ppWritePackedMsg, end) &&
-		 	push16(value->hyper_sfn_2_lsbs, ppWritePackedMsg, end));
-}
-
-
-static uint8_t pack_dl_config_npdcch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_npdcch_pdu_rel13_t* value = (nfapi_dl_config_npdcch_pdu_rel13_t*)tlv;
-	
-	return (push16(value->length, ppWritePackedMsg, end) &&
-			push16(value->pdu_index, ppWritePackedMsg, end) &&
-			push8(value->ncce_index, ppWritePackedMsg, end) &&
-			push8(value->aggregation_level, ppWritePackedMsg, end) &&
-			push8(value->start_symbol, ppWritePackedMsg, end) &&
-			push8(value->rnti_type, ppWritePackedMsg, end) &&
-			push16(value->rnti, ppWritePackedMsg, end) &&
-			push8(value->scrambling_reinitialization_batch_index, ppWritePackedMsg, end) &&
-			push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end) &&
-			push8(value->dci_format, ppWritePackedMsg, end) &&
-			push8(value->scheduling_delay, ppWritePackedMsg, end) &&
-			push8(value->resource_assignment, ppWritePackedMsg, end) &&
-			push8(value->repetition_number, ppWritePackedMsg, end) &&
-			push8(value->mcs, ppWritePackedMsg, end) &&
-			push8(value->new_data_indicator, ppWritePackedMsg, end) &&
-			push8(value->harq_ack_resource, ppWritePackedMsg, end) &&
-			push8(value->npdcch_order_indication, ppWritePackedMsg, end) &&
-			push8(value->starting_number_of_nprach_repetitions, ppWritePackedMsg, end) &&
-			push8(value->subcarrier_indication_of_nprach, ppWritePackedMsg, end) &&
-			push8(value->paging_direct_indication_differentation_flag, ppWritePackedMsg, end) &&
-			push8(value->direct_indication, ppWritePackedMsg, end) &&
-			push8(value->dci_subframe_repetition_number, ppWritePackedMsg, end) &&
-			push8(value->total_dci_length_including_padding, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_dl_config_ndlsch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_ndlsch_pdu_rel13_t* value = (nfapi_dl_config_ndlsch_pdu_rel13_t*)tlv;
-	
-	return (push16(value->length, ppWritePackedMsg, end) &&
-			push16(value->pdu_index, ppWritePackedMsg, end) &&
-			push8(value->start_symbol, ppWritePackedMsg, end) &&
-			push8(value->rnti_type, ppWritePackedMsg, end) &&
-			push16(value->rnti, ppWritePackedMsg, end) &&
-			push16(value->resource_assignment, ppWritePackedMsg, end) &&
-			push16(value->repetition_number, ppWritePackedMsg, end) &&
-			push8(value->modulation, ppWritePackedMsg, end) &&
-			push8(value->number_of_subframes_for_resource_assignment, ppWritePackedMsg, end) &&
-			push8(value->scrambling_sequence_initialization_cinit, ppWritePackedMsg, end) &&
-			push16(value->sf_idx, ppWritePackedMsg, end) &&
-			push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end));
-}
-
-
-static uint8_t pack_dl_tti_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nr_dl_tti_request_pdu_t* value = (nfapi_nr_dl_tti_request_pdu_t*)tlv;
-
-	if(!(push16(value->PDUSize, ppWritePackedMsg, end) &&
-	 	 push16(value->PDUType, ppWritePackedMsg, end) ))
-		  return 0;
-
-
-	// first match the pdu type, then call the respective function
-	switch(value->PDUType)
-	{
-		case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
-		{
-			if(!(pack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15,ppWritePackedMsg,end)))
-				return 0;
-		}
-		break;
-
-		case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
-		{
-			if(!(pack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15,ppWritePackedMsg,end)))
-				return 0;
-		}
-		break;
-		case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
-		{
-			if(!(pack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15,ppWritePackedMsg,end)))
-				return 0;
-		}
-		break;
-		case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
-		{
-			if(!(pack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15,ppWritePackedMsg,end)))
-				return 0;
-		}
-		break;
-
-		default:
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType );
-		}
-		break;
-	}
-
-	return 1;
-}
-
-static uint8_t pack_dl_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_request_body_t* value = (nfapi_dl_config_request_body_t*)tlv;
-
-        //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() dci:%u pdu:%u pdsch:%u rnti:%u pcfich:%u\n", __FUNCTION__, value->number_dci, value->number_pdu, value->number_pdsch_rnti, value->transmission_power_pcfich);
-
-	if(!(push8(value->number_pdcch_ofdm_symbols, ppWritePackedMsg, end) &&
-		 push8(value->number_dci, ppWritePackedMsg, end) &&
-		 push16(value->number_pdu, ppWritePackedMsg, end) &&
-		 push8(value->number_pdsch_rnti, ppWritePackedMsg, end) &&
-		 push16(value->transmission_power_pcfich, ppWritePackedMsg, end)))
-	{
-		return 0;
-	}
-
-	uint16_t i = 0;
-	uint16_t total_number_of_pdus = value->number_pdu;
-	for(; i < total_number_of_pdus; ++i)
-	{
-		nfapi_dl_config_request_pdu_t* pdu = &(value->dl_config_pdu_list[i]);
-
-		if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0)
-			return 0;
-
-		// Put a 0 size in and then determine the size after the pdu 
-		// has been writen and write the calculated size
-		uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg;
-		pdu->pdu_size = 0;
-		if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0)
-			return 0;
-
-		switch(pdu->pdu_type)
-		{
-			case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE:
-				{
-                                  //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE\n", __FUNCTION__);
-
-					if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel8_value) &&
-					pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel9_value) &&
-					pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel10_value) &&
-					pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel11_value) &&
-					pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel12_value) &&
-					pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel13_value)))
-					{
-						return 0;
-					}
-				}
-				break;
-			case NFAPI_DL_CONFIG_BCH_PDU_TYPE:
-				{
-                                  //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE\n", __FUNCTION__);
-
-					if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG, &pdu->bch_pdu.bch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_bch_pdu_rel8_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_DL_CONFIG_MCH_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG, &pdu->mch_pdu.mch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_mch_pdu_rel8_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel8_value) &&
-					pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel9_value) &&
-					pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel10_value) &&
-					pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel11_value) &&
-					pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel12_value) &&
-					pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel13_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_DL_CONFIG_PCH_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG, &pdu->pch_pdu.pch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_pch_pdu_rel8_value) &&
-					pack_tlv(NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG, &pdu->pch_pdu.pch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_pch_pdu_rel13_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_DL_CONFIG_PRS_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG, &pdu->prs_pdu.prs_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_prs_pdu_rel9_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel10, ppWritePackedMsg, end,  &pack_dl_config_csi_rs_pdu_rel10_value) &&
-						 pack_tlv(NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel13, ppWritePackedMsg, end,  &pack_dl_config_csi_rs_pdu_rel13_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel8_value) &&
-						 pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel9_value) &&
-						 pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel10_value) &&
-						 pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel11_value) &&
-						 pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel12_value) &&
-						 pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel13_value) &&
-						 pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG, &pdu->epdcch_pdu.epdcch_params_rel11, ppWritePackedMsg, end, &pack_dl_config_epdcch_parameters_rel11_value) &
-						 pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG, &pdu->epdcch_pdu.epdcch_params_rel13, ppWritePackedMsg, end, &pack_dl_config_epdcch_parameters_rel13_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG, &pdu->mpdcch_pdu.mpdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_mpdcch_pdu_rel13_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_DL_CONFIG_NBCH_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG, &pdu->nbch_pdu.nbch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_nbch_pdu_rel13_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG, &pdu->npdcch_pdu.npdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_npdcch_pdu_rel13_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG, &pdu->ndlsch_pdu.ndlsch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_ndlsch_pdu_rel13_value)))
-						return 0;
-				}
-				break;
-			default:
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type );
-				}
-				break;
-		};
-
-		// add 1 for the pdu_type. The delta will include the pdu_size
-		pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize);
-		push8(pdu->pdu_size, &pWritePackedMsgPduSize, end);
-	}
-
-	return 1;
-}
-
-
-static uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t*)msg;
-
-	if (!(push16(pNfapiMsg->SFN , ppWritePackedMsg, end) &&
-		push16(pNfapiMsg->Slot , ppWritePackedMsg, end) &&
-		push8(pNfapiMsg->dl_tti_request_body.nGroup , ppWritePackedMsg, end) &&
-		push8(pNfapiMsg->dl_tti_request_body.nPDUs , ppWritePackedMsg, end) &&
-		pusharray8(pNfapiMsg->dl_tti_request_body.nUe ,256,pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end)
-		//pusharray8(pNfapiMsg->PduIdx[0] ,256,256, ppWritePackedMsg, end)
-		))
-			return 0;
-
-	int arr[12];
-	for(int i=0;i<pNfapiMsg->dl_tti_request_body.nGroup;i++)
-	{
-		for(int j=0;j<pNfapiMsg->dl_tti_request_body.nUe[i];j++)
-		{
-			arr[j] = pNfapiMsg->dl_tti_request_body.PduIdx[i][j];
-		}
-		if(!(pusharrays32(arr,12,pNfapiMsg->dl_tti_request_body.nUe[i],ppWritePackedMsg, end)))
-		return 0;
-	}
-
-	for(int i=0;i<pNfapiMsg->dl_tti_request_body.nPDUs;i++)	
-	{
-		if(!pack_dl_tti_request_body_value(&pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i],ppWritePackedMsg,end))
-		return 0;
-	}
-
-return 1;
-}
-
-
-static uint8_t pack_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t*)msg;
-	
-	//return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 //pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value) &&
-			 //pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-        { 
-          uint8_t x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end);
-          uint8_t y = pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value);
-          uint8_t z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
-
-          if (!x || !y || !z)
-          {
-            NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_DL_CONFIG_REQUEST x:%u y:%u z:%u \n", __FUNCTION__,x,y,z);
-          }
-
-          return x && y && z;
-        }
-}
-
-
-
-
-static uint8_t pack_ul_config_request_ulsch_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t * end)
-{
-	nfapi_ul_config_ulsch_pdu_rel8_t* ulsch_pdu_rel8 = (nfapi_ul_config_ulsch_pdu_rel8_t*)tlv;
-	
-	return( push32(ulsch_pdu_rel8->handle, ppWritePackedMsg, end) &&
-			push16(ulsch_pdu_rel8->size, ppWritePackedMsg, end) &&
-			push16(ulsch_pdu_rel8->rnti, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel8->resource_block_start, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel8->modulation_type, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel8->frequency_hopping_enabled_flag, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel8->frequency_hopping_bits, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel8->new_data_indication, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel8->redundancy_version, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel8->harq_process_number, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel8->ul_tx_mode, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel8->current_tx_nb, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel8->n_srs, ppWritePackedMsg, end));
-}
-static uint8_t pack_ul_config_request_ulsch_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ulsch_pdu_rel10_t* ulsch_pdu_rel10 = (nfapi_ul_config_ulsch_pdu_rel10_t*)tlv;
-	
-	return (push8(ulsch_pdu_rel10->resource_allocation_type, ppWritePackedMsg, end) &&
-			push32(ulsch_pdu_rel10->resource_block_coding, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel10->transport_blocks, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel10->transmission_scheme, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel10->number_of_layers, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel10->codebook_index, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel10->disable_sequence_hopping_flag, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_config_request_ulsch_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ulsch_pdu_rel11_t* ulsch_pdu_rel11 = (nfapi_ul_config_ulsch_pdu_rel11_t*)tlv;
-	
-	return (push8(ulsch_pdu_rel11->virtual_cell_id_enabled_flag, ppWritePackedMsg, end) &&
-			push16(ulsch_pdu_rel11->npusch_identity, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel11->dmrs_config_flag, ppWritePackedMsg, end) &&
-			push16(ulsch_pdu_rel11->ndmrs_csh_identity, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_config_request_ulsch_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ulsch_pdu_rel13_t* ulsch_pdu_rel13 = (nfapi_ul_config_ulsch_pdu_rel13_t*)tlv;
-
-	return (push8(ulsch_pdu_rel13->ue_type, ppWritePackedMsg, end) &&
-			push16(ulsch_pdu_rel13->total_number_of_repetitions, ppWritePackedMsg, end) &&
-			push16(ulsch_pdu_rel13->repetition_number, ppWritePackedMsg, end) &&
-			push16(ulsch_pdu_rel13->initial_transmission_sf_io, ppWritePackedMsg, end) &&
-			push8(ulsch_pdu_rel13->empty_symbols_due_to_re_tunning, ppWritePackedMsg, end));
-}
-
-//Pack fns for ul_tti PDUS
-
-
-static uint8_t pack_ul_tti_request_prach_pdu(nfapi_nr_prach_pdu_t* prach_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return(
-		push16(prach_pdu->phys_cell_id, ppWritePackedMsg, end) &&
-		push8(prach_pdu->num_prach_ocas, ppWritePackedMsg, end) &&
-		push8(prach_pdu->prach_format, ppWritePackedMsg, end) &&
-		push8(prach_pdu->num_ra, ppWritePackedMsg, end) &&
-		push8(prach_pdu->prach_start_symbol, ppWritePackedMsg, end) &&
-		push16(prach_pdu->num_cs, ppWritePackedMsg, end)
-		// TODO: ignoring beamforming tlv for now
-	);
-	
-}
-
-static uint8_t pack_ul_tti_request_pucch_pdu(nfapi_nr_pucch_pdu_t* pucch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return(
-		push16(pucch_pdu->rnti, ppWritePackedMsg, end) &&
-		push32(pucch_pdu->handle, ppWritePackedMsg, end) &&
-		push16(pucch_pdu->bwp_size, ppWritePackedMsg, end) &&
-		push16(pucch_pdu->bwp_start, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->subcarrier_spacing, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->cyclic_prefix, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->format_type, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->multi_slot_tx_indicator, ppWritePackedMsg, end) &&
-		push16(pucch_pdu->prb_start, ppWritePackedMsg, end) &&
-		push16(pucch_pdu->prb_size, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->start_symbol_index, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->nr_of_symbols, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->freq_hop_flag, ppWritePackedMsg, end) &&
-		push16(pucch_pdu->second_hop_prb, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->group_hop_flag, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->sequence_hop_flag, ppWritePackedMsg, end) &&
-		push16(pucch_pdu->hopping_id, ppWritePackedMsg, end) &&
-		push16(pucch_pdu->initial_cyclic_shift, ppWritePackedMsg, end) &&
-		push16(pucch_pdu->data_scrambling_id, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->time_domain_occ_idx, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->pre_dft_occ_idx, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->pre_dft_occ_len, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->add_dmrs_flag, ppWritePackedMsg, end) &&
-		push16(pucch_pdu->dmrs_scrambling_id, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->dmrs_cyclic_shift, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->sr_flag, ppWritePackedMsg, end) &&
-		push8(pucch_pdu->bit_len_harq, ppWritePackedMsg, end) &&
-		push16(pucch_pdu->bit_len_csi_part1, ppWritePackedMsg, end) &&
-		push16(pucch_pdu->bit_len_csi_part2, ppWritePackedMsg, end) 
-		// TODO: ignoring beamforming tlv for now
-	);
-	
-}
-
-
-static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t* pusch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
-{ 
-	
-	if (!(
-	push16(pusch_pdu->pdu_bit_map, ppWritePackedMsg, end) &&
-	push16(pusch_pdu->rnti, ppWritePackedMsg, end) &&
-	push32(pusch_pdu->handle, ppWritePackedMsg, end) &&
-	push16(pusch_pdu->bwp_size, ppWritePackedMsg, end) &&
-	push16(pusch_pdu->bwp_start, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->subcarrier_spacing, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->cyclic_prefix, ppWritePackedMsg, end) &&
-	push16(pusch_pdu->target_code_rate, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->mcs_index, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end) &&
-	push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end) &&
-	push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end) &&
-	push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->scid, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->num_dmrs_cdm_grps_no_data, ppWritePackedMsg, end) &&
-	push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->resource_alloc, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->resource_alloc,ppWritePackedMsg, end) &&
-	push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) &&
-	push16(pusch_pdu->rb_start, ppWritePackedMsg, end) &&
-	push16(pusch_pdu->rb_size, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->vrb_to_prb_mapping, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->frequency_hopping, ppWritePackedMsg, end) &&
-	push16(pusch_pdu->tx_direct_current_location, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->uplink_frequency_shift_7p5khz, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->start_symbol_index, ppWritePackedMsg, end) &&
-	push8(pusch_pdu->nr_of_symbols, ppWritePackedMsg, end) 
-	// TODO: ignoring beamforming tlv for now 
-	))
-		return 0;
-
-
-	//Pack Optional Data only included if indicated in pduBitmap
-	switch(pusch_pdu->pdu_bit_map){
-		case PUSCH_PDU_BITMAP_PUSCH_DATA:
-		{
-			// pack optional TLVs
-			return(
-				push8(pusch_pdu->pusch_data.rv_index, ppWritePackedMsg, end) &&
-				push8(pusch_pdu->pusch_data.harq_process_id, ppWritePackedMsg, end) &&
-				push32(pusch_pdu->pusch_data.tb_size, ppWritePackedMsg, end) &&
-				push16(pusch_pdu->pusch_data.num_cb, ppWritePackedMsg, end) &&
-				pusharray8(pusch_pdu->pusch_data.cb_present_and_position,1,1,ppWritePackedMsg, end)
-			);
-		}
-		break;
-
-		case PUSCH_PDU_BITMAP_PUSCH_UCI:
-		{
-			return(
-				push16(pusch_pdu->pusch_uci.harq_ack_bit_length, ppWritePackedMsg, end) &&
-				push16(pusch_pdu->pusch_uci.csi_part1_bit_length, ppWritePackedMsg, end) &&
-				push16(pusch_pdu->pusch_uci.csi_part2_bit_length, ppWritePackedMsg, end) &&
-				push8(pusch_pdu->pusch_uci.alpha_scaling, ppWritePackedMsg, end) &&
-				push8(pusch_pdu->pusch_uci.beta_offset_harq_ack, ppWritePackedMsg, end) &&
-				push8(pusch_pdu->pusch_uci.beta_offset_csi1, ppWritePackedMsg, end) &&
-				push8(pusch_pdu->pusch_uci.beta_offset_csi2, ppWritePackedMsg, end)
-			);
-		}
-		break;
-
-		case PUSCH_PDU_BITMAP_PUSCH_PTRS:
-		{
-			return(
-				push8(pusch_pdu->pusch_ptrs.num_ptrs_ports, ppWritePackedMsg, end) &&
-				push8(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_dmrs_port, ppWritePackedMsg, end) &&
-				push16(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_port_index, ppWritePackedMsg, end) &&
-				push8(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset, ppWritePackedMsg, end) &&
-				push8(pusch_pdu->pusch_ptrs.ptrs_time_density, ppWritePackedMsg, end) &&
-				push8(pusch_pdu->pusch_ptrs.ptrs_freq_density, ppWritePackedMsg, end) &&
-				push8(pusch_pdu->pusch_ptrs.ul_ptrs_power, ppWritePackedMsg, end)
-			);
-		}
-		break;
-
-		case PUSCH_PDU_BITMAP_DFTS_OFDM:
-		{
-			return(
-				push8(pusch_pdu->dfts_ofdm.low_papr_group_number, ppWritePackedMsg, end) &&
-				push16(pusch_pdu->dfts_ofdm.low_papr_sequence_number, ppWritePackedMsg, end) &&
-				push8(pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, ppWritePackedMsg, end) &&
-				push8(pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, ppWritePackedMsg, end)
-			);
-		}
-		break;
-
-		default:
-		{
-			NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map );
-		}
-	}
-
-	return 1;
-}
-
-static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t* srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return(
-		push16(srs_pdu->rnti, ppWritePackedMsg, end) &&
-		push32(srs_pdu->handle, ppWritePackedMsg, end) &&
-		push16(srs_pdu->bwp_size, ppWritePackedMsg, end) &&
-		push16(srs_pdu->bwp_start, ppWritePackedMsg, end) &&
-		push8(srs_pdu->subcarrier_spacing, ppWritePackedMsg, end) &&
-		push8(srs_pdu->cyclic_prefix, ppWritePackedMsg, end) &&
-		push8(srs_pdu->num_ant_ports, ppWritePackedMsg, end) &&
-		push8(srs_pdu->num_symbols, ppWritePackedMsg, end) &&
-		push8(srs_pdu->num_repetitions, ppWritePackedMsg, end) &&
-		push8(srs_pdu->time_start_position, ppWritePackedMsg, end) &&
-		push8(srs_pdu->config_index, ppWritePackedMsg, end) &&
-		push16(srs_pdu->sequence_id, ppWritePackedMsg, end) &&
-		push8(srs_pdu->bandwidth_index, ppWritePackedMsg, end) &&
-		push8(srs_pdu->comb_size, ppWritePackedMsg, end) &&
-		push8(srs_pdu->comb_offset, ppWritePackedMsg, end) &&
-		push8(srs_pdu->cyclic_shift, ppWritePackedMsg, end) &&
-		push8(srs_pdu->frequency_position, ppWritePackedMsg, end) &&
-		push8(srs_pdu->frequency_shift, ppWritePackedMsg, end) &&
-		push8(srs_pdu->frequency_hopping, ppWritePackedMsg, end) &&
-		push8(srs_pdu->group_or_sequence_hopping, ppWritePackedMsg, end) &&
-		push8(srs_pdu->resource_type, ppWritePackedMsg, end) &&
-		push16(srs_pdu->t_srs, ppWritePackedMsg, end) &&
-		push16(srs_pdu->t_offset, ppWritePackedMsg, end) 
-
-		// TODO: ignoring beamforming tlv for now
-	);
-	
-}
-
-static uint8_t pack_ul_config_request_ulsch_pdu(nfapi_ul_config_ulsch_pdu* ulsch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG, &ulsch_pdu->ulsch_pdu_rel8, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel8_value) &&
-			pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG, &ulsch_pdu->ulsch_pdu_rel10, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel10_value) &&
-			pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG, &ulsch_pdu->ulsch_pdu_rel11, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel11_value) &&
-			pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG, &ulsch_pdu->ulsch_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel13_value));
-}
-
-static uint8_t pack_ul_config_request_cqi_ri_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_cqi_ri_information_rel8_t* cqi_ri_info_rel8 = (nfapi_ul_config_cqi_ri_information_rel8_t*)tlv;
-
-	return ( push8(cqi_ri_info_rel8->dl_cqi_pmi_size_rank_1, ppWritePackedMsg, end) &&
-			 push8(cqi_ri_info_rel8->dl_cqi_pmi_size_rank_greater_1, ppWritePackedMsg, end) &&
-			 push8(cqi_ri_info_rel8->ri_size, ppWritePackedMsg, end) &&
-			 push8(cqi_ri_info_rel8->delta_offset_cqi, ppWritePackedMsg, end) &&
-			 push8(cqi_ri_info_rel8->delta_offset_ri, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_config_request_cqi_ri_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_cqi_ri_information_rel9_t* cqi_ri_info_rel9 = (nfapi_ul_config_cqi_ri_information_rel9_t*)tlv;
-
-	if(!(push8(cqi_ri_info_rel9->report_type, ppWritePackedMsg, end) &&
-		 push8(cqi_ri_info_rel9->delta_offset_cqi, ppWritePackedMsg, end) &&
-		 push8(cqi_ri_info_rel9->delta_offset_ri, ppWritePackedMsg, end)))
-	{
-		return 0;
-	}
-
-	switch(cqi_ri_info_rel9->report_type)
-	{
-		case NFAPI_CSI_REPORT_TYPE_PERIODIC:
-			{
-				if(!(push8(cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size, ppWritePackedMsg, end) &&
-					 push8(cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.control_type, ppWritePackedMsg, end)))
-				{
-					return 0;
-				}
-			}
-			break;
-		case NFAPI_CSI_REPORT_TYPE_APERIODIC:
-			{
-				if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc, ppWritePackedMsg, end) == 0)
-					return 0;
-
-				uint8_t i;
-				for(i = 0; i < cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc; ++i)
-				{
-					if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size, ppWritePackedMsg, end) == 0)
-						return 0;
-
-                                        uint8_t j;
-                                        for(j = 0; j < 8; ++j)
-					{
-                                              if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size[j], ppWritePackedMsg, end) == 0)
-							return 0;
-					}
-				}
-			}
-			break;
-		default:
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel9->report_type );
-			}
-			break;
-	};
-
-	return 1;
-}
-
-static uint8_t pack_ul_config_request_cqi_ri_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_cqi_ri_information_rel13_t* cqi_ri_info_rel13 = (nfapi_ul_config_cqi_ri_information_rel13_t*)tlv;
-
-	switch(cqi_ri_info_rel13->report_type)
-	{
-		case NFAPI_CSI_REPORT_TYPE_PERIODIC:
-			{
-				if(push16(cqi_ri_info_rel13->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2, ppWritePackedMsg, end) == 0)
-					return 0;
-			}
-			break;
-		case NFAPI_CSI_REPORT_TYPE_APERIODIC:
-			{
-				// No parameters
-			}
-			break;
-		default:
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel13->report_type );
-			}
-			break;
-	};
-
-	return 1;
-}
-
-static uint8_t pack_ul_config_request_cqi_ri_information(nfapi_ul_config_cqi_ri_information* cqi_ri_info, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return (pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG, &cqi_ri_info->cqi_ri_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel8_value) &&
-			pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG, &cqi_ri_info->cqi_ri_information_rel9, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel9_value) &&
-			pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG, &cqi_ri_info->cqi_ri_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel13_value));
-
-}
-
-static uint8_t pack_ul_config_request_init_tx_params_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_initial_transmission_parameters_rel8_t* init_tx_params_rel8 = (nfapi_ul_config_initial_transmission_parameters_rel8_t*)tlv;
-	
-	return (push8(init_tx_params_rel8->n_srs_initial, ppWritePackedMsg, end) &&
-		 	push8(init_tx_params_rel8->initial_number_of_resource_blocks, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_config_request_initial_transmission_parameters(nfapi_ul_config_initial_transmission_parameters* init_tx_params, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return pack_tlv(NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG, &init_tx_params->initial_transmission_parameters_rel8, ppWritePackedMsg, end, &pack_ul_config_request_init_tx_params_rel8_value);
-}
-
-static uint8_t pack_ul_config_request_ulsch_harq_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ulsch_harq_information_rel10_t* harq_info_rel10 = (nfapi_ul_config_ulsch_harq_information_rel10_t*)tlv;
-	
-	return (push8(harq_info_rel10->harq_size, ppWritePackedMsg, end) &&
-			push8(harq_info_rel10->delta_offset_harq, ppWritePackedMsg, end) &&
-			push8(harq_info_rel10->ack_nack_mode, ppWritePackedMsg, end));
-}
-static uint8_t pack_ul_config_request_ulsch_harq_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ulsch_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_ulsch_harq_information_rel13_t*)tlv;
-	
-	return (push16(harq_info_rel13->harq_size_2, ppWritePackedMsg, end) &&
-		 	push8(harq_info_rel13->delta_offset_harq_2, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_config_request_ulsch_harq_information(nfapi_ul_config_ulsch_harq_information* harq_info, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG, &harq_info->harq_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_harq_info_rel10_value) &&
-			 pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG, &harq_info->harq_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_harq_info_rel13_value));
-}
-
-static uint8_t pack_ul_config_request_ue_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ue_information_rel8_t* ue_info_rel8 = (nfapi_ul_config_ue_information_rel8_t*)tlv;
-	
-	return ( push32(ue_info_rel8->handle, ppWritePackedMsg, end) &&
-		 	 push16(ue_info_rel8->rnti, ppWritePackedMsg, end));
-}
-static uint8_t pack_ul_config_request_ue_info_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ue_information_rel11_t* ue_info_rel11 = (nfapi_ul_config_ue_information_rel11_t*)tlv;
-
-	return ( push8(ue_info_rel11->virtual_cell_id_enabled_flag, ppWritePackedMsg, end) &&
-		 	 push16(ue_info_rel11->npusch_identity, ppWritePackedMsg, end));
-}
-static uint8_t pack_ul_config_request_ue_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ue_information_rel13_t* ue_info_rel13 = (nfapi_ul_config_ue_information_rel13_t*)tlv;
-
-	return ( push8(ue_info_rel13->ue_type, ppWritePackedMsg, end) &&
-			 push8(ue_info_rel13->empty_symbols, ppWritePackedMsg, end) &&
-			 push16(ue_info_rel13->total_number_of_repetitions, ppWritePackedMsg, end) &&
-			 push16(ue_info_rel13->repetition_number, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_config_request_ue_information(nfapi_ul_config_ue_information* ue_info, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &ue_info->ue_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel8_value) &&
-	pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &ue_info->ue_information_rel11, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel11_value) &&
-	pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &ue_info->ue_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel13_value));
-}
-
-static uint8_t pack_ul_config_request_harq_info_rel10_tdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_harq_information_rel10_tdd_t* harq_info_rel10_tdd = (nfapi_ul_config_harq_information_rel10_tdd_t*)tlv;
-
-	return ( push8(harq_info_rel10_tdd->harq_size, ppWritePackedMsg, end) &&
-			push8(harq_info_rel10_tdd->ack_nack_mode, ppWritePackedMsg, end) &&
-			push8(harq_info_rel10_tdd->number_of_pucch_resources, ppWritePackedMsg, end) &&
-			push16(harq_info_rel10_tdd->n_pucch_1_0, ppWritePackedMsg, end) &&
-			push16(harq_info_rel10_tdd->n_pucch_1_1, ppWritePackedMsg, end) &&
-			push16(harq_info_rel10_tdd->n_pucch_1_2, ppWritePackedMsg, end) &&
-			push16(harq_info_rel10_tdd->n_pucch_1_3, ppWritePackedMsg, end));
-}
-static uint8_t pack_ul_config_request_harq_info_rel8_fdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_harq_information_rel8_fdd_t* harq_info_rel8_fdd = (nfapi_ul_config_harq_information_rel8_fdd_t*)tlv;
-
-	return ( push16(harq_info_rel8_fdd->n_pucch_1_0, ppWritePackedMsg, end) &&
-			push8(harq_info_rel8_fdd->harq_size, ppWritePackedMsg, end));
-}
-static uint8_t pack_ul_config_request_harq_info_rel9_fdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_harq_information_rel9_fdd_t* harq_info_rel9_fdd = (nfapi_ul_config_harq_information_rel9_fdd_t*)tlv;
-	
-	return ( push8(harq_info_rel9_fdd->harq_size, ppWritePackedMsg, end) &&
-			push8(harq_info_rel9_fdd->ack_nack_mode, ppWritePackedMsg, end) &&
-			push8(harq_info_rel9_fdd->number_of_pucch_resources, ppWritePackedMsg, end) &&
-			push16(harq_info_rel9_fdd->n_pucch_1_0, ppWritePackedMsg, end) &&
-			push16(harq_info_rel9_fdd->n_pucch_1_1, ppWritePackedMsg, end) &&
-			push16(harq_info_rel9_fdd->n_pucch_1_2, ppWritePackedMsg, end) &&
-			push16(harq_info_rel9_fdd->n_pucch_1_3, ppWritePackedMsg, end));
-}
-static uint8_t pack_ul_config_request_harq_info_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_harq_information_rel11_t* harq_info_rel11 = (nfapi_ul_config_harq_information_rel11_t*)tlv;
-	
-	return ( push8(harq_info_rel11->num_ant_ports, ppWritePackedMsg, end) &&
-			push16(harq_info_rel11->n_pucch_2_0, ppWritePackedMsg, end) &&
-			push16(harq_info_rel11->n_pucch_2_1, ppWritePackedMsg, end) &&
-			push16(harq_info_rel11->n_pucch_2_2, ppWritePackedMsg, end) &&
-			push16(harq_info_rel11->n_pucch_2_3, ppWritePackedMsg, end));
-}
-static uint8_t pack_ul_config_request_harq_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_harq_information_rel13_t*)tlv;
-	
-	return ( push16(harq_info_rel13->harq_size_2, ppWritePackedMsg, end) &&
-			push8(harq_info_rel13->starting_prb, ppWritePackedMsg, end) &&
-			push8(harq_info_rel13->n_prb, ppWritePackedMsg, end) &&
-			push8(harq_info_rel13->cdm_index, ppWritePackedMsg, end) &&
-			push8(harq_info_rel13->n_srs, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_config_request_harq_information(nfapi_ul_config_harq_information* harq_info, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG, &harq_info->harq_information_rel10_tdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel10_tdd_value) &&
-	pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG, &harq_info->harq_information_rel8_fdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel8_fdd_value) &&
-	pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG, &harq_info->harq_information_rel9_fdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel9_fdd_value) &&
-	pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG, &harq_info->harq_information_rel11, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel11_value) &&
-	pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG, &harq_info->harq_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel13_value));
-
-}
-
-static uint8_t pack_ul_config_request_cqi_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_cqi_information_rel8_t* cqi_info_rel8 = (nfapi_ul_config_cqi_information_rel8_t*)tlv;
-
-	return ( push16(cqi_info_rel8->pucch_index, ppWritePackedMsg, end) &&
-			 push8(cqi_info_rel8->dl_cqi_pmi_size, ppWritePackedMsg, end));
-}
-static uint8_t pack_ul_config_request_cqi_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_cqi_information_rel10_t* cqi_info_rel10 = (nfapi_ul_config_cqi_information_rel10_t*)tlv;
-	
-	return ( push8(cqi_info_rel10->number_of_pucch_resource, ppWritePackedMsg, end) &&
-			 push16(cqi_info_rel10->pucch_index_p1, ppWritePackedMsg, end));
-}
-static uint8_t pack_ul_config_request_cqi_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_cqi_information_rel13_t* cqi_info_rel13 = (nfapi_ul_config_cqi_information_rel13_t*)tlv;
-	
-	return ( push8(cqi_info_rel13->csi_mode, ppWritePackedMsg, end) &&
-			push16(cqi_info_rel13->dl_cqi_pmi_size_2, ppWritePackedMsg, end) &&
-			push8(cqi_info_rel13->starting_prb, ppWritePackedMsg, end) &&
-			push8(cqi_info_rel13->n_prb, ppWritePackedMsg, end) &&
-			push8(cqi_info_rel13->cdm_index, ppWritePackedMsg, end) &&
-			push8(cqi_info_rel13->n_srs, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_config_request_cqi_information(nfapi_ul_config_cqi_information* cqi_info, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG, &cqi_info->cqi_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel8_value) && 
-	pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG, &cqi_info->cqi_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel10_value) &&
-	pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG, &cqi_info->cqi_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel13_value));
-
-}
-
-static uint8_t pack_ul_config_request_sr_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_sr_information_rel8_t* sr_info_rel8 = (nfapi_ul_config_sr_information_rel8_t*)tlv;
-	return push16(sr_info_rel8->pucch_index, ppWritePackedMsg, end);
-}
-static uint8_t pack_ul_config_request_sr_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_sr_information_rel10_t* sr_info_rel10 = (nfapi_ul_config_sr_information_rel10_t*)tlv;
-
-	return ( push8(sr_info_rel10->number_of_pucch_resources, ppWritePackedMsg, end) &&
-		 	 push16(sr_info_rel10->pucch_index_p1, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_config_request_sr_information(nfapi_ul_config_sr_information* sr_info, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG, &sr_info->sr_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_sr_info_rel8_value) &&
-	pack_tlv(NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG, &sr_info->sr_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_sr_info_rel10_value));
-}
-
-static uint8_t pack_ul_config_request_srs_pdu_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_srs_pdu_rel8_t* srs_pdu_rel8 = (nfapi_ul_config_srs_pdu_rel8_t*)tlv;
-	
-	return (push32(srs_pdu_rel8->handle, ppWritePackedMsg, end) &&
-			push16(srs_pdu_rel8->size, ppWritePackedMsg, end) &&
-			push16(srs_pdu_rel8->rnti, ppWritePackedMsg, end) &&
-			push8(srs_pdu_rel8->srs_bandwidth, ppWritePackedMsg, end) &&
-			push8(srs_pdu_rel8->frequency_domain_position, ppWritePackedMsg, end) &&
-			push8(srs_pdu_rel8->srs_hopping_bandwidth, ppWritePackedMsg, end) &&
-			push8(srs_pdu_rel8->transmission_comb, ppWritePackedMsg, end) &&
-			push16(srs_pdu_rel8->i_srs, ppWritePackedMsg, end) &&
-			push8(srs_pdu_rel8->sounding_reference_cyclic_shift, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_config_request_srs_pdu_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_srs_pdu_rel10_t* srs_pdu_rel10 = (nfapi_ul_config_srs_pdu_rel10_t*)tlv;
-	return push8(srs_pdu_rel10->antenna_port, ppWritePackedMsg, end);
-}
-
-static uint8_t pack_ul_config_request_srs_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_srs_pdu_rel13_t* srs_pdu_rel13 = (nfapi_ul_config_srs_pdu_rel13_t*)tlv;
-	
-	return ( push8(srs_pdu_rel13->number_of_combs, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_config_request_nb_harq_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_nb_harq_information_rel13_fdd_t* nb_harq_pdu_rel13 = (nfapi_ul_config_nb_harq_information_rel13_fdd_t*)tlv;
-	
-	return ( push8(nb_harq_pdu_rel13->harq_ack_resource, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_config_request_nulsch_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_nulsch_pdu_rel13_t* nulsch_pdu_rel13 = (nfapi_ul_config_nulsch_pdu_rel13_t*)tlv;
-	
-	return (push8(nulsch_pdu_rel13->nulsch_format, ppWritePackedMsg, end) &&
-		    push32(nulsch_pdu_rel13->handle, ppWritePackedMsg, end) &&
-		    push16(nulsch_pdu_rel13->size, ppWritePackedMsg, end) &&
-		    push16(nulsch_pdu_rel13->rnti, ppWritePackedMsg, end) &&
-		    push8(nulsch_pdu_rel13->subcarrier_indication, ppWritePackedMsg, end) &&
-		    push8(nulsch_pdu_rel13->resource_assignment, ppWritePackedMsg, end) &&
-		    push8(nulsch_pdu_rel13->mcs, ppWritePackedMsg, end) &&
-		    push8(nulsch_pdu_rel13->redudancy_version, ppWritePackedMsg, end) &&
-		    push8(nulsch_pdu_rel13->repetition_number, ppWritePackedMsg, end) &&
-		    push8(nulsch_pdu_rel13->new_data_indication, ppWritePackedMsg, end) &&
-		    push8(nulsch_pdu_rel13->n_srs, ppWritePackedMsg, end) &&
-		    push16(nulsch_pdu_rel13->scrambling_sequence_initialization_cinit, ppWritePackedMsg, end) &&
-		    push16(nulsch_pdu_rel13->sf_idx, ppWritePackedMsg, end) && 
-		    pack_ul_config_request_ue_information(&(nulsch_pdu_rel13->ue_information), ppWritePackedMsg, end) &&
-		    pack_tlv(NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG, &nulsch_pdu_rel13->nb_harq_information.nb_harq_information_rel13_fdd, ppWritePackedMsg, end, &pack_ul_config_request_nb_harq_rel13_value));
-}
-static uint8_t pack_ul_config_request_nrach_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_nrach_pdu_rel13_t* nrach_pdu_rel13 = (nfapi_ul_config_nrach_pdu_rel13_t*)tlv;
-	
-	return ( push8(nrach_pdu_rel13->nprach_config_0, ppWritePackedMsg, end) &&
-			 push8(nrach_pdu_rel13->nprach_config_1, ppWritePackedMsg, end) &&
-			 push8(nrach_pdu_rel13->nprach_config_2, ppWritePackedMsg, end));
-	
-}
-
-
-
-static uint8_t pack_ul_tti_pdu_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nr_ul_tti_request_number_of_pdus_t* value = (nfapi_nr_ul_tti_request_number_of_pdus_t*)tlv;
-
-	if(!(push16(value->pdu_size, ppWritePackedMsg, end) &&
-	 	 push16(value->pdu_type, ppWritePackedMsg, end) ))
-		  return 0;
-
-
-	// first match the pdu type, then call the respective function
-	switch(value->pdu_type)
-	{
-		case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
-		{
-			if(!pack_ul_tti_request_prach_pdu(&value->prach_pdu, ppWritePackedMsg, end))
-				return 0;
-		}
-		break;
-
-		case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
-		{
-			if(!pack_ul_tti_request_pucch_pdu(&value->pucch_pdu, ppWritePackedMsg, end))
-				return 0;
-		}
-		break;
-		case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
-		{
-			if(!pack_ul_tti_request_pusch_pdu(&value->pusch_pdu, ppWritePackedMsg, end))
-				return 0;
-		}
-		break;
-		case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
-		{
-			if(!pack_ul_tti_request_srs_pdu(&value->srs_pdu, ppWritePackedMsg, end))
-				return 0;
-		}
-		break;
-
-		default:
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", value->pdu_type );
-		}
-		break;
-	}
-
-	return 1;
-}
-
-static uint8_t pack_ul_tti_groups_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nr_ul_tti_request_number_of_groups_t* value = (nfapi_nr_ul_tti_request_number_of_groups_t*)tlv;
-
-	if(!push8(value->n_ue, ppWritePackedMsg, end))
-		return 0;
-	for(int i=0; i<value->n_ue;i++)
-	{
-		if(!push8(value->ue_list[i].pdu_idx, ppWritePackedMsg, end))
-		return 0;
-	}
-	return 1;
-}
-
-static uint8_t pack_ul_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_request_body_t* value = (nfapi_ul_config_request_body_t*)tlv;
-
-	if(!(push8(value->number_of_pdus, ppWritePackedMsg, end) &&
-	 	 push8(value->rach_prach_frequency_resources, ppWritePackedMsg, end) &&
-		 push8(value->srs_present, ppWritePackedMsg, end)))
-		return 0;
-
-	uint16_t i = 0;
-	for(i = 0; i < value->number_of_pdus; ++i)
-	{
-		nfapi_ul_config_request_pdu_t* pdu = &(value->ul_config_pdu_list[i]);
-
-		if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0)
-			return 0;
-
-		// Put a 0 size in and then determine the size after the pdu 
-		// has been writen and write the calculated size
-		uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg;
-		pdu->pdu_size = 0;
-		if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0)
-			return 0;
-
-		switch(pdu->pdu_type)
-		{
-			case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE:
-				{
-					if(!pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_pdu), ppWritePackedMsg, end))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_cqi_ri_pdu.ulsch_pdu), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_cqi_ri_information(&(pdu->ulsch_cqi_ri_pdu.cqi_ri_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_cqi_ri_pdu.initial_transmission_parameters), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_ulsch_harq_information(&(pdu->ulsch_harq_pdu.harq_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_harq_pdu.initial_transmission_parameters), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_cqi_ri_information(&(pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_ulsch_harq_information(&(pdu->ulsch_cqi_harq_ri_pdu.harq_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_pdu.ue_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_cqi_information(&(pdu->uci_cqi_pdu.cqi_information), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ue_information(&(pdu->uci_sr_pdu.ue_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_sr_information(&(pdu->uci_sr_pdu.sr_information), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ue_information(&(pdu->uci_harq_pdu.ue_information), ppWritePackedMsg, end) &&
-	 					 pack_ul_config_request_harq_information(&(pdu->uci_harq_pdu.harq_information), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ue_information(&(pdu->uci_sr_harq_pdu.ue_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_sr_information(&(pdu->uci_sr_harq_pdu.sr_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_harq_information(&(pdu->uci_sr_harq_pdu.harq_information), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_harq_pdu.ue_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_cqi_information(&(pdu->uci_cqi_harq_pdu.cqi_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_harq_information(&(pdu->uci_cqi_harq_pdu.harq_information), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_sr_pdu.ue_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_cqi_information(&(pdu->uci_cqi_sr_pdu.cqi_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_sr_information(&(pdu->uci_cqi_sr_pdu.sr_information), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_sr_harq_pdu.ue_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_cqi_information(&(pdu->uci_cqi_sr_harq_pdu.cqi_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_sr_information(&(pdu->uci_cqi_sr_harq_pdu.sr_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_harq_information(&(pdu->uci_cqi_sr_harq_pdu.harq_information), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_SRS_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG, &pdu->srs_pdu.srs_pdu_rel8, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel8_value) &&
-						 pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG, &pdu->srs_pdu.srs_pdu_rel10, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel10_value) &&
-						 pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG, &pdu->srs_pdu.srs_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel13_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ue_information(&(pdu->harq_buffer_pdu.ue_information), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_uci_csi_pdu.ulsch_pdu), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_cqi_information(&(pdu->ulsch_uci_csi_pdu.csi_information), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_uci_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_harq_information(&(pdu->ulsch_uci_harq_pdu.harq_information), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE:
-				{
-					if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_csi_uci_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_cqi_information(&(pdu->ulsch_csi_uci_harq_pdu.csi_information), ppWritePackedMsg, end) &&
-						 pack_ul_config_request_harq_information(&(pdu->ulsch_csi_uci_harq_pdu.harq_information), ppWritePackedMsg, end)))
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG, &pdu->nulsch_pdu.nulsch_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_nulsch_pdu_rel13_value)))	
-						return 0;
-				}
-				break;
-			case NFAPI_UL_CONFIG_NRACH_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG, &pdu->nrach_pdu.nrach_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_nrach_pdu_rel13_value)))
-						return 0;
-				}
-				break;				
-			default:
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type );
-				}
-				break;
-		};
-
-		// add 1 for the pdu_type. The delta will include the pdu_size
-		pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize);
-		push8(pdu->pdu_size, &pWritePackedMsgPduSize, end);
-		
-	}
-	return 1;
-}
-
-
-static uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t*)msg;
-
-	if (!(push16(pNfapiMsg->SFN , ppWritePackedMsg, end) &&
-		push16(pNfapiMsg->Slot , ppWritePackedMsg, end) &&
-		push8(pNfapiMsg->n_pdus , ppWritePackedMsg, end) &&
-		push8(pNfapiMsg->rach_present, ppWritePackedMsg, end) &&
-		push8(pNfapiMsg->n_ulsch, ppWritePackedMsg, end) &&
-		push8(pNfapiMsg->n_ulcch, ppWritePackedMsg, end) &&
-		push8(pNfapiMsg->n_group, ppWritePackedMsg, end) ))
-			return 0;
-		
-	for(int i=0; i<pNfapiMsg->n_pdus; i++)
-	{
-		if(!pack_ul_tti_pdu_list_value(&pNfapiMsg->pdus_list[i], ppWritePackedMsg, end))
-			return 0;
-	}
-
-	for(int i=0; i<pNfapiMsg->n_group; i++)
-	{
-		if(!pack_ul_tti_groups_list_value(&pNfapiMsg->groups_list[i], ppWritePackedMsg, end))
-			return 0;
-
-	}
-
-	return 1;
-}
-
-
-static uint8_t pack_ul_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_UL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->ul_config_request_body, ppWritePackedMsg, end, &pack_ul_config_request_body_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)) ;
-}
-
-static uint8_t pack_hi_dci0_hi_rel8_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_hi_pdu_rel8_t* hi_pdu_rel8 = (nfapi_hi_dci0_hi_pdu_rel8_t*)tlv;
-	
-	return ( push8(hi_pdu_rel8->resource_block_start, ppWritePackedMsg, end) &&
-			 push8(hi_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) &&
-			 push8(hi_pdu_rel8->hi_value, ppWritePackedMsg, end) &&
-			 push8(hi_pdu_rel8->i_phich, ppWritePackedMsg, end) &&
-			 push16(hi_pdu_rel8->transmission_power, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_hi_dci0_hi_rel10_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_hi_pdu_rel10_t* hi_pdu_rel10 = (nfapi_hi_dci0_hi_pdu_rel10_t*)tlv;
-	
-	return ( push8(hi_pdu_rel10->flag_tb2, ppWritePackedMsg, end) &&
-			 push8(hi_pdu_rel10->hi_value_2, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_hi_dci0_dci_rel8_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_dci_pdu_rel8_t* dci_pdu_rel8 = (nfapi_hi_dci0_dci_pdu_rel8_t*)tlv;
-	
-	return ( push8(dci_pdu_rel8->dci_format, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->cce_index, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->aggregation_level, ppWritePackedMsg, end) &&
-			 push16(dci_pdu_rel8->rnti, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->resource_block_start, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->number_of_resource_block, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->mcs_1, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->frequency_hopping_enabled_flag, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->frequency_hopping_bits, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->new_data_indication_1, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->ue_tx_antenna_seleciton, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->tpc, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->cqi_csi_request, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->ul_index, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel8->dl_assignment_index, ppWritePackedMsg, end) &&
-			 push32(dci_pdu_rel8->tpc_bitmap, ppWritePackedMsg, end) &&
-			 push16(dci_pdu_rel8->transmission_power, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_hi_dci0_dci_rel10_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_dci_pdu_rel10_t* dci_pdu_rel10 = (nfapi_hi_dci0_dci_pdu_rel10_t*)tlv;
-	
-	return ( push8(dci_pdu_rel10->cross_carrier_scheduling_flag, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel10->carrier_indicator, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel10->size_of_cqi_csi_feild, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel10->srs_flag, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel10->srs_request, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel10->resource_allocation_flag, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel10->resource_allocation_type, ppWritePackedMsg, end) &&
-			 push32(dci_pdu_rel10->resource_block_coding, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel10->mcs_2, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel10->new_data_indication_2, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel10->number_of_antenna_ports, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel10->tpmi, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel10->total_dci_length_including_padding, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel10->n_ul_rb, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_hi_dci0_dci_rel12_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_dci_pdu_rel12_t* dci_pdu_rel12 = (nfapi_hi_dci0_dci_pdu_rel12_t*)tlv;
-	
-	return ( push8(dci_pdu_rel12->pscch_resource, ppWritePackedMsg, end) &&
-			 push8(dci_pdu_rel12->time_resource_pattern, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_hi_dci0_mpdcch_dci_rel13_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t* mpdcch_dci_pdu_rel13 = (nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t*)tlv;
-	
-	return ( push8(mpdcch_dci_pdu_rel13->mpdcch_narrowband, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->number_of_prb_pairs, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->resource_block_assignment, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->mpdcch_transmission_type, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->start_symbol, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->ecce_index, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->aggreagation_level, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->rnti_type, ppWritePackedMsg, end) &&
-			 push16(mpdcch_dci_pdu_rel13->rnti, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->ce_mode, ppWritePackedMsg, end) &&
-			 push16(mpdcch_dci_pdu_rel13->drms_scrambling_init, ppWritePackedMsg, end) &&
-			 push16(mpdcch_dci_pdu_rel13->initial_transmission_sf_io, ppWritePackedMsg, end) &&
-			 push16(mpdcch_dci_pdu_rel13->transmission_power, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->dci_format, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->resource_block_start, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->number_of_resource_blocks, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->mcs, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->pusch_repetition_levels, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->frequency_hopping_flag, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->new_data_indication, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->harq_process, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->redudency_version, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->tpc, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->csi_request, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->ul_inex, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->dai_presence_flag, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->dl_assignment_index, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->srs_request, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->dci_subframe_repetition_number, ppWritePackedMsg, end) &&
-			 push32(mpdcch_dci_pdu_rel13->tcp_bitmap, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->total_dci_length_include_padding, ppWritePackedMsg, end) &&
-			 push8(mpdcch_dci_pdu_rel13->number_of_tx_antenna_ports, ppWritePackedMsg, end) &&
-			 pusharray16(mpdcch_dci_pdu_rel13->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, mpdcch_dci_pdu_rel13->number_of_tx_antenna_ports, ppWritePackedMsg, end));
-	
-}
-
-static uint8_t pack_hi_dci0_npdcch_dci_rel13_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_npdcch_dci_pdu_rel13_t* npdcch_dci_pdu_rel13 = (nfapi_hi_dci0_npdcch_dci_pdu_rel13_t*)tlv;
-	
-	return ( push8(npdcch_dci_pdu_rel13->ncce_index, ppWritePackedMsg, end) &&
-			 push8(npdcch_dci_pdu_rel13->aggregation_level, ppWritePackedMsg, end) &&
-			 push8(npdcch_dci_pdu_rel13->start_symbol, ppWritePackedMsg, end) &&
-			 push16(npdcch_dci_pdu_rel13->rnti, ppWritePackedMsg, end) &&
-			 push8(npdcch_dci_pdu_rel13->scrambling_reinitialization_batch_index, ppWritePackedMsg, end) &&
-			 push8(npdcch_dci_pdu_rel13->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end) &&
-			 push8(npdcch_dci_pdu_rel13->subcarrier_indication, ppWritePackedMsg, end) &&
-			 push8(npdcch_dci_pdu_rel13->resource_assignment, ppWritePackedMsg, end) &&
-			 push8(npdcch_dci_pdu_rel13->scheduling_delay, ppWritePackedMsg, end) &&
-			 push8(npdcch_dci_pdu_rel13->mcs, ppWritePackedMsg, end) &&
-			 push8(npdcch_dci_pdu_rel13->redudancy_version, ppWritePackedMsg, end) &&
-			 push8(npdcch_dci_pdu_rel13->repetition_number, ppWritePackedMsg, end) &&
-			 push8(npdcch_dci_pdu_rel13->new_data_indicator, ppWritePackedMsg, end) &&
-			 push8(npdcch_dci_pdu_rel13->dci_subframe_repetition_number, ppWritePackedMsg, end));
-}
-
-
-static uint8_t pack_hi_dci0_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_request_body_t* value = (nfapi_hi_dci0_request_body_t*)tlv;
-
-	if(!(push16(value->sfnsf, ppWritePackedMsg, end) &&
-		 push8(value->number_of_dci, ppWritePackedMsg, end) &&
-		 push8(value->number_of_hi, ppWritePackedMsg, end)))
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_pdus = value->number_of_dci + value->number_of_hi;
-	for(i = 0; i < total_number_of_pdus; ++i)
-	{
-		nfapi_hi_dci0_request_pdu_t* pdu = &(value->hi_dci0_pdu_list[i]);
-
-		if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0)
-			return 0;
-
-		// Put a 0 size in and then determine the size after the pdu 
-		// has been writen and write the calculated size
-		uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg;
-		pdu->pdu_size = 0;
-		if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0)
-			return 0;
-
-		switch(pdu->pdu_type)
-		{
-			case NFAPI_HI_DCI0_HI_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG, &pdu->hi_pdu.hi_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_hi_rel8_pdu_value) &&
-						 pack_tlv(NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG, &pdu->hi_pdu.hi_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_hi_rel10_pdu_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_HI_DCI0_DCI_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG, &pdu->dci_pdu.dci_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_dci_rel8_pdu_value) &&
-						 pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG, &pdu->dci_pdu.dci_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_dci_rel10_pdu_value) &&
-						 pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG, &pdu->dci_pdu.dci_pdu_rel12, ppWritePackedMsg, end, pack_hi_dci0_dci_rel12_pdu_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_dci_rel8_pdu_value) &&
-						 pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_dci_rel10_pdu_value) &&
-						 pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG, &pdu->epdcch_dci_pdu.epdcch_parameters_rel11, ppWritePackedMsg, end, pack_dl_config_epdcch_parameters_rel11_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG, &pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13, ppWritePackedMsg, end, pack_hi_dci0_mpdcch_dci_rel13_pdu_value)))
-						return 0;
-				}
-				break;
-			case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE:
-				{
-					if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG, &pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13, ppWritePackedMsg, end, pack_hi_dci0_npdcch_dci_rel13_pdu_value)))
-						return 0;
-				}
-				break;				
-			default:
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type );
-				}
-				break;
-		};
-
-		// add 1 for the pdu_type. The delta will include the pdu_size
-		pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize);
-		push8(pdu->pdu_size, &pWritePackedMsgPduSize, end);
-		
-	}
-
-	return 1;
-}
-
-static uint8_t pack_ul_dci_pdu_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nr_ul_dci_request_pdus_t* value = (nfapi_nr_ul_dci_request_pdus_t*)tlv;
-	
-	for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i)
-	{
-		if(!push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI, ppWritePackedMsg, end) &&
-		push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, ppWritePackedMsg, end) &&
-
-		push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end) &&
-		push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, ppWritePackedMsg, end) &&
-		push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, ppWritePackedMsg, end) &&
-		push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end) &&
-
-		push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
-		push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
-		
-		pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end));
-
-		return 0;
-	}
-
-	return (push16(value->PDUType, ppWritePackedMsg, end) &&
-	   	    push16(value->PDUSize, ppWritePackedMsg, end) &&
-			push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, ppWritePackedMsg, end) &&
-			push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, ppWritePackedMsg, end) &&
-			push8(value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, ppWritePackedMsg, end) &&
-			push8(value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, ppWritePackedMsg, end) &&
-
-			push8(value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, ppWritePackedMsg, end) &&
-			push8(value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, ppWritePackedMsg, end) &&
-			pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, ppWritePackedMsg, end) &&
-			push8(value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, ppWritePackedMsg, end) &&
-
-			push8(value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, ppWritePackedMsg, end) &&
-			push8(value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, ppWritePackedMsg, end) &&
-			push8(value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, ppWritePackedMsg, end) &&
-			push16(value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, ppWritePackedMsg, end));
-
-}
-
-static uint8_t pack_ul_dci_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t*)msg;
-	
-	if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) &&
-		     push16(pNfapiMsg->Slot, ppWritePackedMsg, end) &&
-			 push8(pNfapiMsg->numPdus, ppWritePackedMsg, end)
-        ))
-		return 0;
-
-	for(int i=0; i<pNfapiMsg->numPdus; i++)
-	{
-		if(!pack_ul_dci_pdu_list_value(&pNfapiMsg->ul_dci_pdu_list[i], ppWritePackedMsg, end))
-			return 0;
-	}
-	return 1;
-
-
-}
-
-
-
-static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_HI_DCI0_REQUEST_BODY_TAG, &pNfapiMsg->hi_dci0_request_body, ppWritePackedMsg, end, &pack_hi_dci0_request_body_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-//pack_tx_data_pdu_list_value
-static uint8_t pack_tx_data_pdu_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nr_pdu_t* value = (nfapi_nr_pdu_t*)tlv;
-	
-	if(!(push32(value->num_TLV, ppWritePackedMsg, end) &&
-	    push16(value->PDU_index, ppWritePackedMsg, end) &&
-		push16(value->PDU_length, ppWritePackedMsg, end)
-	 ))
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_tlvs = value->num_TLV;
-	for(; i < total_number_of_tlvs; ++i)
-	{
-		
-		if (!(push16(value->TLVs[i].length, ppWritePackedMsg, end) &&
-			push16(value->TLVs[i].tag, ppWritePackedMsg, end)))
-			return 0;
-
-		switch(value->TLVs[i].tag)
-		{
-			case 0:
-			{
-				if(!pusharray32(value->TLVs[i].value.direct, 16384, value->TLVs[i].length, ppWritePackedMsg, end))
-					return 0;
-				break;
-
-			}
-
-			case 1:
-			{
-				if(!pusharray32(value->TLVs[i].value.ptr, value->TLVs[i].length , value->TLVs[i].length, ppWritePackedMsg, end))
-					return 0;
-				break;
-
-			}
-				
-			default:
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", value->TLVs[i].tag );
-				break;
-			}
-				
-		}		
-	}
-	return 1;
-}
-
-static uint8_t pack_tx_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_tx_request_body_t* value = (nfapi_tx_request_body_t*)tlv;
-	
-	if(push16(value->number_of_pdus, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_pdus = value->number_of_pdus;
-	for(; i < total_number_of_pdus; ++i)
-	{
-		nfapi_tx_request_pdu_t* pdu = &(value->tx_pdu_list[i]);
-				
-		if(!(push16(pdu->pdu_length, ppWritePackedMsg, end) &&
-			 push16(pdu->pdu_index, ppWritePackedMsg, end)))
-			return 0;
-
-		uint8_t j;
-		for(j = 0; j < pdu->num_segments; ++j)
-		{
-			// Use -1 as it is unbounded 
-			// DJP - does not handle -1
-                        // DJP - if(pusharray8(pdu->segments[j].segment_data, (uint32_t)(-1), pdu->segments[j].segment_length, ppWritePackedMsg, end) == 0)
-			int push_ret = pusharray8(pdu->segments[j].segment_data, 65535, pdu->segments[j].segment_length, ppWritePackedMsg, end);
-                        
-                        if (pdu->segments[j].segment_length == 3)
-                        {
-                          NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, 
-                          pdu->segments[j].segment_data[0], 
-                          pdu->segments[j].segment_data[1], 
-                          pdu->segments[j].segment_data[2]
-                          );
-                        }
-                        //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() segment_data:%p segment_length:%u pusharray8()=%d\n", __FUNCTION__, pdu->segments[j].segment_data, pdu->segments[j].segment_length, push_ret);
-
-                        if (push_ret == 0)
-			{
-				return 0;
-			}
-		}
-	}
-
-	return 1;
-}
-
-static uint8_t pack_tx_data_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t*)msg;
-	
-	if (!(
-	 push16(pNfapiMsg->SFN, ppWritePackedMsg, end) &&
-	 push16(pNfapiMsg->Slot, ppWritePackedMsg, end) &&
-	 push16(pNfapiMsg->Number_of_PDUs, ppWritePackedMsg, end)
-	))
-	return 0;
-
-	for(int i=0; i<pNfapiMsg->Number_of_PDUs; i++)
-	{
-		if(!pack_tx_data_pdu_list_value(&pNfapiMsg->pdu_list[i], ppWritePackedMsg, end))
-			return 0;
-	}
-
-    return 1;
-}
-
-static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t*)msg;
-	
-	int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end);
-        int y = pack_tlv(NFAPI_TX_REQUEST_BODY_TAG, &pNfapiMsg->tx_request_body, ppWritePackedMsg, end, &pack_tx_request_body_value);
-        int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
-
-        //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() x:%d y:%d z:%d\n", __FUNCTION__, x, y, z);
-
-        return x && y && z;
-}
-
-static uint8_t pack_release_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  nfapi_ue_release_request_body_t* value = (nfapi_ue_release_request_body_t*)tlv;
-  if(push16(value->number_of_TLVs, ppWritePackedMsg, end) == 0){
-    return 0;
-  }
-
-  uint8_t j;
-  uint16_t num = value->number_of_TLVs;
-  for(j = 0; j < num; ++j){
-    if(push16(value->ue_release_request_TLVs_list[j].rnti, ppWritePackedMsg, end) == 0){
-      return 0;
-    }
-  }
-  return 1;
-}
-
-static uint8_t pack_ue_release_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-  nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg;
-  int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end);
-  int y = pack_tlv(NFAPI_UE_RELEASE_BODY_TAG, &pNfapiMsg->ue_release_request_body, ppWritePackedMsg, end, &pack_release_request_body_value);
-  int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
-  return x && y && z;
-}
-
-static uint8_t pack_ue_release_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-
-	nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg;
-
-	int x = push32(pNfapiMsg->error_code, ppWritePackedMsg, end);
-	int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
-	return x && z;
-}
-
-static uint8_t pack_rx_ue_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_rx_ue_information* value = (nfapi_rx_ue_information*)tlv;
-	
-	return ( push32(value->handle, ppWritePackedMsg, end) &&
-			 push16(value->rnti, ppWritePackedMsg, end) );
-}
-
-static uint8_t unpack_rx_ue_information_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_rx_ue_information* value = (nfapi_rx_ue_information*)tlv;
-	
-	return ( pull32(ppReadPackedMsg, &value->handle, end) &&
-			 pull16(ppReadPackedMsg, &value->rnti, end));
-}
-
-static uint8_t pack_harq_indication_tdd_harq_data_bundling(nfapi_harq_indication_tdd_harq_data_bundling_t* data, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return ( push8(data->value_0, ppWritePackedMsg, end) &&
-			 push8(data->value_1, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_harq_indication_tdd_harq_data_multiplexing(nfapi_harq_indication_tdd_harq_data_multiplexing_t* data, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return ( push8(data->value_0, ppWritePackedMsg, end) &&
-			 push8(data->value_1, ppWritePackedMsg, end) &&
-			 push8(data->value_2, ppWritePackedMsg, end) &&
-			 push8(data->value_3, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_harq_indication_tdd_harq_data_special_bundling(nfapi_harq_indication_tdd_harq_data_special_bundling_t* data, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return ( push8(data->value_0, ppWritePackedMsg, end) );
-}
-
-static uint8_t pack_harq_indication_tdd_harq_data(nfapi_harq_indication_tdd_harq_data_t* data, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	return ( push8(data->value_0, ppWritePackedMsg, end) );
-}
-
-static uint8_t pack_harq_indication_tdd_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_tdd_rel8_t* harq_indication_tdd_rel8 = (nfapi_harq_indication_tdd_rel8_t*)tlv;
-	
-	if(!(push8(harq_indication_tdd_rel8->mode, ppWritePackedMsg, end) &&
-		 push8(harq_indication_tdd_rel8->number_of_ack_nack, ppWritePackedMsg, end)))
-			return 0;
-
-	uint8_t result = 0;
-	switch(harq_indication_tdd_rel8->mode)
-	{
-		case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING:
-			result = pack_harq_indication_tdd_harq_data_bundling(&harq_indication_tdd_rel8->harq_data.bundling, ppWritePackedMsg, end);
-			break;
-		case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING:
-			result = pack_harq_indication_tdd_harq_data_multiplexing(&harq_indication_tdd_rel8->harq_data.multiplex, ppWritePackedMsg, end);
-			break;
-		case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING:
-			result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel8->harq_data.special_bundling, ppWritePackedMsg, end);
-			break;
-		case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION:
-		case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3:
-			result = 1;
-			break;			
-		default:
-			// err....
-			break;
-	}
-
-	return result;
-	
-}
-
-static uint8_t pack_harq_indication_tdd_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_tdd_rel9_t* harq_indication_tdd_rel9 = (nfapi_harq_indication_tdd_rel9_t*)tlv;
-	
-	if(!(push8(harq_indication_tdd_rel9->mode, ppWritePackedMsg, end) &&
-		 push8(harq_indication_tdd_rel9->number_of_ack_nack, ppWritePackedMsg, end)))
-		return 0;
-
-	uint8_t idx; 
-	for(idx = 0; idx < harq_indication_tdd_rel9->number_of_ack_nack; ++idx)
-	{
-		uint8_t result = 0;
-
-		switch(harq_indication_tdd_rel9->mode)
-		{
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING:
-				result = pack_harq_indication_tdd_harq_data(&(harq_indication_tdd_rel9->harq_data[idx].bundling), ppWritePackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING:
-				result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].multiplex, ppWritePackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING:
-				result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel9->harq_data[idx].special_bundling, ppWritePackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION:
-				result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].channel_selection, ppWritePackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3:
-				result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].format_3, ppWritePackedMsg, end);
-				break;
-			default:
-				// err....
-				break;
-		}
-
-		if(result == 0)
-			return 0;
-	}
-
-	return 1;
-}
-
-static uint8_t pack_harq_indication_tdd_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_tdd_rel13_t* harq_indication_tdd_rel13 = (nfapi_harq_indication_tdd_rel13_t*)tlv;
-	
-	if(!(push8(harq_indication_tdd_rel13->mode, ppWritePackedMsg, end) &&
-		 push16(harq_indication_tdd_rel13->number_of_ack_nack, ppWritePackedMsg, end)))
-		return 0;
-
-	uint8_t idx; 
-	for(idx = 0; idx < harq_indication_tdd_rel13->number_of_ack_nack; ++idx)
-	{
-		uint8_t result = 0;
-		switch(harq_indication_tdd_rel13->mode)
-		{
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING:
-				result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].bundling, ppWritePackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING:
-				result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].multiplex, ppWritePackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING:
-				result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel13->harq_data[idx].special_bundling, ppWritePackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION:
-				result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].channel_selection, ppWritePackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3:
-				result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_3, ppWritePackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_4:
-				result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_4, ppWritePackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_5:
-				result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_5, ppWritePackedMsg, end);
-				break;
-			default:
-				// err....
-				break;
-		}
-
-		if(result == 0)
-			return 0;
-	}
-
-	return 1;
-}
-
-static uint8_t pack_harq_indication_fdd_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_fdd_rel8_t* harq_indication_fdd_rel8 = (nfapi_harq_indication_fdd_rel8_t*)tlv;
-	
-	return ( push8(harq_indication_fdd_rel8->harq_tb1, ppWritePackedMsg, end) &&
-			 push8(harq_indication_fdd_rel8->harq_tb2, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_harq_indication_fdd_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_fdd_rel9_t* harq_indication_fdd_rel9 = (nfapi_harq_indication_fdd_rel9_t*)tlv;
-	
-	return ( push8(harq_indication_fdd_rel9->mode, ppWritePackedMsg, end) &&
-			 push8(harq_indication_fdd_rel9->number_of_ack_nack, ppWritePackedMsg, end) &&
-			 pusharray8(harq_indication_fdd_rel9->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL9_MAX, harq_indication_fdd_rel9->number_of_ack_nack, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_harq_indication_fdd_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_fdd_rel13_t* harq_indication_fdd_rel13 = (nfapi_harq_indication_fdd_rel13_t*)tlv;
-	
-	return ( push8(harq_indication_fdd_rel13->mode, ppWritePackedMsg, end) &&
-			 push16(harq_indication_fdd_rel13->number_of_ack_nack, ppWritePackedMsg, end) &&
-			 pusharray8(harq_indication_fdd_rel13->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL13_MAX, harq_indication_fdd_rel13->number_of_ack_nack, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_ul_cqi_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_ul_cqi_information_t* value = (nfapi_ul_cqi_information_t*)tlv;
-	
-	return ( push8(value->ul_cqi, ppWritePackedMsg, end) &&
-			 push8(value->channel, ppWritePackedMsg, end));
-
-}
-
-static uint8_t pack_harq_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_body_t* value = (nfapi_harq_indication_body_t*)tlv;
-	
-	if(push16(value->number_of_harqs, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_pdus = value->number_of_harqs;
-	for(; i < total_number_of_pdus; ++i)
-	{
-		nfapi_harq_indication_pdu_t* pdu = &(value->harq_pdu_list[i]);
-
-		uint8_t* instance_length_p = *ppWritePackedMsg;
-		if(!push16(pdu->instance_length, ppWritePackedMsg, end))
-			return 0;
-
-		if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) &&
-			 pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL8_TAG, &pdu->harq_indication_tdd_rel8, ppWritePackedMsg, end, pack_harq_indication_tdd_rel8_value) &&
-			 pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL9_TAG, &pdu->harq_indication_tdd_rel9, ppWritePackedMsg, end, pack_harq_indication_tdd_rel9_value) &&
-			 pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL13_TAG, &pdu->harq_indication_tdd_rel13, ppWritePackedMsg, end, pack_harq_indication_tdd_rel13_value) &&
-			 pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL8_TAG, &pdu->harq_indication_fdd_rel8, ppWritePackedMsg, end, pack_harq_indication_fdd_rel8_value) &&
-			 pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL9_TAG, &pdu->harq_indication_fdd_rel9, ppWritePackedMsg, end, pack_harq_indication_fdd_rel9_value) &&
-			 pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL13_TAG, &pdu->harq_indication_fdd_rel13, ppWritePackedMsg, end, pack_harq_indication_fdd_rel13_value) &&
-			 pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value)))
-			return 0;
-
-		// calculate the instance length subtracting the size of the instance
-		// length feild
-		uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
-		push16(instance_length, &instance_length_p, end);
-	}
-
-	return 1;
-}
-
-static uint8_t pack_harq_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_harq_indication_t *pNfapiMsg = (nfapi_harq_indication_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->harq_indication_body, ppWritePackedMsg, end, pack_harq_indication_body_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_crc_indication_rel8_body(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_crc_indication_rel8_t* crc_indication_rel8 = (nfapi_crc_indication_rel8_t*)tlv;
-	
-	return ( push8(crc_indication_rel8->crc_flag, ppWritePackedMsg, end) );
-}
-
-static uint8_t pack_crc_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_crc_indication_body_t* value = (nfapi_crc_indication_body_t*)tlv;
-	
-	if(push16(value->number_of_crcs, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_pdus = value->number_of_crcs;
-	for(; i < total_number_of_pdus; ++i)
-	{
-		nfapi_crc_indication_pdu_t* pdu = &(value->crc_pdu_list[i]);
-		
-		uint8_t* instance_length_p = *ppWritePackedMsg;
-		if(!push16(pdu->instance_length, ppWritePackedMsg, end))
-			return 0;
-		
-		if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) &&
-			 pack_tlv(NFAPI_CRC_INDICATION_REL8_TAG, &pdu->crc_indication_rel8, ppWritePackedMsg, end, pack_crc_indication_rel8_body)))
-			return 0;
-
-		// calculate the instance length subtracting the size of the instance
-		// length feild
-		uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
-		push16(instance_length, &instance_length_p, end);
-	}
-	return 1;
-}
-
-static uint8_t pack_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_crc_indication_t *pNfapiMsg = (nfapi_crc_indication_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_CRC_INDICATION_BODY_TAG, &pNfapiMsg->crc_indication_body, ppWritePackedMsg, end, &pack_crc_indication_body_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-
-}
-static uint8_t pack_rx_indication_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_rx_indication_rel8_t* value = (nfapi_rx_indication_rel8_t*)tlv;
-	
-	return ( push16(value->length, ppWritePackedMsg, end) &&
-			 push16(value->offset, ppWritePackedMsg, end) &&
-			 push8(value->ul_cqi, ppWritePackedMsg, end) &&
-			 push16(value->timing_advance, ppWritePackedMsg, end));
-}
-static uint8_t pack_rx_indication_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_rx_indication_rel9_t* value = (nfapi_rx_indication_rel9_t*)tlv;
-	
-	return ( push16(value->timing_advance_r9, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_rx_ulsch_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_rx_indication_body_t* value = (nfapi_rx_indication_body_t*)tlv;
-
-        //printf("RX ULSCH BODY\n");
-
-	if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	// need to calculate the data offset's. 
-	uint16_t i = 0;
-	uint16_t offset = 2; // taking into account the number_of_pdus
-	uint16_t total_number_of_pdus = value->number_of_pdus;
-        //printf("ULSCH:pdus:%d\n", total_number_of_pdus);
-
-	for(i = 0; i < total_number_of_pdus; ++i)
-	{
-		nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]);
-		if(pdu->rx_ue_information.tl.tag == NFAPI_RX_UE_INFORMATION_TAG)
-		{
-                  //printf("NFAPI_RX_UE_INFORMATION_TAG\n");
-			offset += 4 + 6; 
-		}
-				
-		if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG)
-		{
-                  //printf("NFAPI_RX_INDICATION_REL8_TAG\n");
-			offset += 4 + 7;
-		}
-
-		if(pdu->rx_indication_rel9.tl.tag == NFAPI_RX_INDICATION_REL9_TAG)
-		{
-                  //printf("NFAPI_RX_INDICATION_REL9_TAG\n");
-			offset += 4 + 2;
-		}
-	}
-
-	// Now update the structure to include the offset
-	for(i =0; i < total_number_of_pdus; ++i)
-	{
-		nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]);
-				
-		if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG)
-		{
-			if(pdu->rx_indication_rel8.offset == 1)
-			{
-				pdu->rx_indication_rel8.offset = offset;
-				offset += pdu->rx_indication_rel8.length;
-			}
-		}
-	}
-	
-	// Write out the pdu
-	for(i = 0; i < total_number_of_pdus; ++i)
-	{
-		nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]);
-		if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) &&
-			 pack_tlv(NFAPI_RX_INDICATION_REL8_TAG, &pdu->rx_indication_rel8, ppWritePackedMsg, end, pack_rx_indication_rel8_value) &&
-			 pack_tlv(NFAPI_RX_INDICATION_REL9_TAG, &pdu->rx_indication_rel9, ppWritePackedMsg, end, pack_rx_indication_rel9_value)))
-			return 0;
-	}
-
-	// Write out the pdu data
-	for(i = 0; i < total_number_of_pdus; ++i)
-	{
-		uint16_t length = 0;
-		nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]);
-
-		if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG)
-		{
-			length = pdu->rx_indication_rel8.length;
-		}
-
-		if( pusharray8(value->rx_pdu_list[i].data, length, length, ppWritePackedMsg, end) == 0)
-			return 0;
-	}
-	return 1;
-}
-
-
-static uint8_t pack_rx_ulsch_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_rx_indication_t *pNfapiMsg = (nfapi_rx_indication_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_RX_INDICATION_BODY_TAG, &pNfapiMsg->rx_indication_body, ppWritePackedMsg, end, pack_rx_ulsch_indication_body_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_preamble_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_preamble_pdu_rel8_t* preamble_rel8 = (nfapi_preamble_pdu_rel8_t*)tlv;
-	
-	return ( push16(preamble_rel8->rnti, ppWritePackedMsg, end) &&
-			 push8(preamble_rel8->preamble, ppWritePackedMsg, end) &&
-			 push16(preamble_rel8->timing_advance, ppWritePackedMsg, end));
-}
-static uint8_t pack_preamble_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_preamble_pdu_rel9_t* preamble_rel9 = (nfapi_preamble_pdu_rel9_t*)tlv;
-	
-	return ( push16(preamble_rel9->timing_advance_r9, ppWritePackedMsg, end) );
-}
-static uint8_t pack_preamble_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_preamble_pdu_rel13_t* preamble_rel13 = (nfapi_preamble_pdu_rel13_t*)tlv;
-	
-	return ( push8(preamble_rel13->rach_resource_type, ppWritePackedMsg, end) );
-}
-
-static uint8_t pack_rach_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_rach_indication_body_t* value = (nfapi_rach_indication_body_t*)tlv;
-	
-	if( push16(value->number_of_preambles, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_pdus = value->number_of_preambles;
-	for(; i < total_number_of_pdus; ++i)
-	{
-		nfapi_preamble_pdu_t* pdu = &(value->preamble_list[i]);
-		
-		uint8_t* instance_length_p = *ppWritePackedMsg;
-		if(!push16(pdu->instance_length, ppWritePackedMsg, end))
-			return 0;
-		
-		if(!(pack_tlv(NFAPI_PREAMBLE_REL8_TAG, &pdu->preamble_rel8, ppWritePackedMsg, end, pack_preamble_pdu_rel8_value) &&
-			 pack_tlv(NFAPI_PREAMBLE_REL9_TAG, &pdu->preamble_rel9, ppWritePackedMsg, end, pack_preamble_pdu_rel9_value) &&
-			 pack_tlv(NFAPI_PREAMBLE_REL13_TAG, &pdu->preamble_rel13, ppWritePackedMsg, end, pack_preamble_pdu_rel13_value)))
-			return 0;
-
-		// calculate the instance length subtracting the size of the instance
-		// length feild
-		uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
-		push16(instance_length, &instance_length_p, end);
-	}
-
-	return 1;
-}
-
-static uint8_t pack_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_rach_indication_t *pNfapiMsg = (nfapi_rach_indication_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_RACH_INDICATION_BODY_TAG, &pNfapiMsg->rach_indication_body, ppWritePackedMsg, end, pack_rach_indication_body_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_srs_indication_fdd_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_srs_indication_fdd_rel8_t* srs_pdu_rel8 = (nfapi_srs_indication_fdd_rel8_t*)tlv;
-	
-	return ( push16(srs_pdu_rel8->doppler_estimation, ppWritePackedMsg, end) &&
-			 push16(srs_pdu_rel8->timing_advance, ppWritePackedMsg, end) &&
-			 push8(srs_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end) &&
-			 push8(srs_pdu_rel8->rb_start, ppWritePackedMsg, end) &&
-			 pusharray8(srs_pdu_rel8->snr, NFAPI_NUM_RB_MAX, srs_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_srs_indication_fdd_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_srs_indication_fdd_rel9_t* srs_pdu_rel9 = (nfapi_srs_indication_fdd_rel9_t*)tlv;
-	
-	return ( push16(srs_pdu_rel9->timing_advance_r9, ppWritePackedMsg, end) );
-}
-
-static uint8_t pack_srs_indication_tdd_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_srs_indication_ttd_rel10_t* srs_pdu_rel10 = (nfapi_srs_indication_ttd_rel10_t*)tlv;
-	
-	return ( push8(srs_pdu_rel10->uppts_symbol, ppWritePackedMsg, end) );
-	
-}
-
-static uint8_t pack_srs_indication_fdd_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_srs_indication_fdd_rel11_t* srs_pdu_rel11 = (nfapi_srs_indication_fdd_rel11_t*)tlv;
-	
-	return ( push16(srs_pdu_rel11->ul_rtoa, ppWritePackedMsg, end) ) ;
-}
-
-static uint8_t pack_tdd_channel_measurement_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_tdd_channel_measurement_t* value = (nfapi_tdd_channel_measurement_t*)tlv;
-
-	if(!(push8(value->num_prb_per_subband, ppWritePackedMsg, end) &&
-		 push8(value->number_of_subbands, ppWritePackedMsg, end) &&
-		 push8(value->num_atennas, ppWritePackedMsg, end)))
-		return 0;
-
-	uint8_t idx = 0;
-	for(idx = 0; idx < value->number_of_subbands; ++idx)
-	{
-		if(!(push8(value->subands[idx].subband_index, ppWritePackedMsg, end) &&
-			 pusharray16(value->subands[idx].channel, NFAPI_MAX_NUM_PHYSICAL_ANTENNAS, value->num_atennas, ppWritePackedMsg, end)))
-			return 0;
-	}
-
-	return 1;
-}
-
-static uint8_t pack_srs_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg,  uint8_t *end)
-{
-	nfapi_srs_indication_body_t *value = (nfapi_srs_indication_body_t*)tlv;
-
-	if( push8(value->number_of_ues, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_pdus = value->number_of_ues;
-	for(; i < total_number_of_pdus; ++i)
-	{
-		nfapi_srs_indication_pdu_t* pdu = &(value->srs_pdu_list[i]);
-		
-		uint8_t* instance_length_p = *ppWritePackedMsg;
-		if(!push16(pdu->instance_length, ppWritePackedMsg, end))
-			return 0;
-		
-		if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, &pack_rx_ue_information_value) &&
-			 pack_tlv(NFAPI_SRS_INDICATION_FDD_REL8_TAG, &pdu->srs_indication_fdd_rel8, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel8_value) &&
-			 pack_tlv(NFAPI_SRS_INDICATION_FDD_REL9_TAG, &pdu->srs_indication_fdd_rel9, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel9_value) &&
-			 pack_tlv(NFAPI_SRS_INDICATION_TDD_REL10_TAG, &pdu->srs_indication_tdd_rel10, ppWritePackedMsg, end, &pack_srs_indication_tdd_rel10_value) &&
-			 pack_tlv(NFAPI_SRS_INDICATION_FDD_REL11_TAG, &pdu->srs_indication_fdd_rel11, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel11_value) &&
-			 pack_tlv(NFAPI_TDD_CHANNEL_MEASUREMENT_TAG, &pdu->tdd_channel_measurement, ppWritePackedMsg, end, &pack_tdd_channel_measurement_value)))
-			return 0;
-
-		// calculate the instance length subtracting the size of the instance
-		// length feild
-		uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
-		push16(instance_length, &instance_length_p, end);
-	}
-
-	return 1;
-}
-
-static uint8_t pack_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_srs_indication_t *pNfapiMsg = (nfapi_srs_indication_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_SRS_INDICATION_BODY_TAG, &pNfapiMsg->srs_indication_body, ppWritePackedMsg, end, &pack_srs_indication_body_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-
-}
-
-static uint8_t pack_sr_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_sr_indication_body_t* value = (nfapi_sr_indication_body_t*)tlv;
-
-	if(push16(value->number_of_srs, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_pdus = value->number_of_srs;
-	for(; i < total_number_of_pdus; ++i)
-	{
-		nfapi_sr_indication_pdu_t* pdu = &(value->sr_pdu_list[i]);
-
-		uint8_t* instance_length_p = *ppWritePackedMsg;
-		if(!push16(pdu->instance_length, ppWritePackedMsg, end))
-			return 0;
-
-		if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) &&
-			 pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value)))
-			return 0;
-
-		// calculate the instance length subtracting the size of the instance
-		// length feild
-		uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
-		push16(instance_length, &instance_length_p, end);
-	}
-	return 1;
-}
-
-static uint8_t pack_sr_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_sr_indication_t *pNfapiMsg = (nfapi_sr_indication_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_SR_INDICATION_BODY_TAG, &pNfapiMsg->sr_indication_body, ppWritePackedMsg, end, &pack_sr_indication_body_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-
-}
-
-static uint8_t pack_cqi_indication_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_cqi_indication_rel8_t* cqi_pdu_rel8 = (nfapi_cqi_indication_rel8_t*)tlv;
-	
-	return ( push16(cqi_pdu_rel8->length, ppWritePackedMsg, end) &&
-			 push16(cqi_pdu_rel8->data_offset, ppWritePackedMsg, end) &&
-			 push8(cqi_pdu_rel8->ul_cqi, ppWritePackedMsg, end) &&
-			 push8(cqi_pdu_rel8->ri, ppWritePackedMsg, end) &&
-			 push16(cqi_pdu_rel8->timing_advance, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_cqi_indication_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_cqi_indication_rel9_t* cqi_pdu_rel9 = (nfapi_cqi_indication_rel9_t*)tlv;
-	
-	return  ( push16(cqi_pdu_rel9->length, ppWritePackedMsg, end) &&
-			  push16(cqi_pdu_rel9->data_offset, ppWritePackedMsg, end) &&
-			  push8(cqi_pdu_rel9->ul_cqi, ppWritePackedMsg, end) &&
-			  push8(cqi_pdu_rel9->number_of_cc_reported, ppWritePackedMsg, end) &&
-			  pusharray8(cqi_pdu_rel9->ri, NFAPI_CC_MAX, cqi_pdu_rel9->number_of_cc_reported, ppWritePackedMsg, end) &&
-			  push16(cqi_pdu_rel9->timing_advance, ppWritePackedMsg, end) &&
-			  push16(cqi_pdu_rel9->timing_advance_r9, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_cqi_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_cqi_indication_body_t* value = (nfapi_cqi_indication_body_t*)tlv;
-
-	if( push16(value->number_of_cqis, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	// need to calculate the data offset's. This very bittle due the hardcoding
-	// of the sizes. can not use the sizeof as we have an array for the Rel9
-	// info
-	uint16_t i = 0;
-	uint16_t offset = 2; // taking into account the number_of_cqis
-	uint16_t total_number_of_pdus = value->number_of_cqis;
-	for(i = 0; i < total_number_of_pdus; ++i)
-	{
-		nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]);
-		
-		offset += 2; // for the instance length
-		
-		if(pdu->rx_ue_information.tl.tag == NFAPI_RX_UE_INFORMATION_TAG)
-		{
-			offset += 4 + 6; // sizeof(nfapi_rx_ue_information) - sizeof(nfapi_tl_t)
-		}
-				
-		if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG)
-		{
-			offset += 4 + 8;
-		}
-
-		if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG)
-		{
-			offset += 4 + 10 + pdu->cqi_indication_rel9.number_of_cc_reported;
-		}
-
-		if(pdu->ul_cqi_information.tl.tag == NFAPI_UL_CQI_INFORMATION_TAG)
-		{
-			offset += 4 + 2;
-		}
-	}
-
-	// Now update the structure to include the offset
-	for(i =0; i < total_number_of_pdus; ++i)
-	{
-		nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]);
-				
-		if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG)
-		{
-			if(pdu->cqi_indication_rel8.data_offset == 1)
-			{
-				pdu->cqi_indication_rel8.data_offset = offset;
-				offset += pdu->cqi_indication_rel8.length;
-			}
-		}
-
-		if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG)
-		{
-			if(pdu->cqi_indication_rel9.data_offset == 1)
-			{
-				pdu->cqi_indication_rel9.data_offset = offset;
-				offset += pdu->cqi_indication_rel9.length;
-			}
-		}
-
-	}
-	
-	// Write out the cqi information
-	for(i = 0; i < total_number_of_pdus; ++i)
-	{
-		nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]);
-
-		uint8_t* instance_length_p = *ppWritePackedMsg;
-		if(!push16(pdu->instance_length, ppWritePackedMsg, end))
-			return 0;
-		
-		if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end ,pack_rx_ue_information_value) &&
-			 pack_tlv(NFAPI_CQI_INDICATION_REL8_TAG, &pdu->cqi_indication_rel8, ppWritePackedMsg, end, pack_cqi_indication_rel8_value) &&
-			 pack_tlv(NFAPI_CQI_INDICATION_REL9_TAG, &pdu->cqi_indication_rel9, ppWritePackedMsg, end, pack_cqi_indication_rel9_value) &&
-			 pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value)))
-			return 0;
-
-		// calculate the instance length subtracting the size of the instance
-		// length feild
-		uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
-		push16(instance_length, &instance_length_p, end);
-		
-	}
-
-	// Write out the cqi raw data
-	for(i = 0; i < total_number_of_pdus; ++i)
-	{
-		uint16_t length = 0;
-		nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]);
-
-		if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG)
-		{
-			length = pdu->cqi_indication_rel8.length;
-		}
-
-		if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG)
-		{
-			length = pdu->cqi_indication_rel9.length;
-		}
-
-		if( pusharray8(value->cqi_raw_pdu_list[i].pdu, NFAPI_CQI_RAW_MAX_LEN, length, ppWritePackedMsg, end) == 0)
-			return 0;
-	}
-
-	return 1; 
-}
-
-static uint8_t pack_cqi_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_cqi_indication_t *pNfapiMsg = (nfapi_cqi_indication_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_CQI_INDICATION_BODY_TAG, &pNfapiMsg->cqi_indication_body, ppWritePackedMsg, end, pack_cqi_indication_body_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-
-}
-
-static uint8_t pack_lbt_pdsch_req_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lbt_pdsch_req_pdu_rel13_t* value = (nfapi_lbt_pdsch_req_pdu_rel13_t*)tlv;
-	
-	return ( push32(value->handle, ppWritePackedMsg, end) &&
-			 push32(value->mp_cca, ppWritePackedMsg, end) &&
-			 push32(value->n_cca, ppWritePackedMsg, end) &&
-			 push32(value->offset, ppWritePackedMsg, end) &&
-			 push32(value->lte_txop_sf, ppWritePackedMsg, end) &&
-			 push16(value->txop_sfn_sf_end, ppWritePackedMsg, end) &&
-			 push32(value->lbt_mode, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_lbt_drs_req_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lbt_drs_req_pdu_rel13_t* value = (nfapi_lbt_drs_req_pdu_rel13_t*)tlv;
-	
-	return ( push32(value->handle, ppWritePackedMsg, end) &&
-			 push32(value->offset, ppWritePackedMsg, end) &&
-			 push16(value->sfn_sf_end, ppWritePackedMsg, end) &&
-			 push32(value->lbt_mode, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_lbt_dl_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lbt_dl_config_request_body_t* value = (nfapi_lbt_dl_config_request_body_t*)tlv;
-	
-	if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_pdus = value->number_of_pdus;
-	for(; i < total_number_of_pdus; ++i)
-	{
-		nfapi_lbt_dl_config_request_pdu_t* pdu = &(value->lbt_dl_config_req_pdu_list[i]);
-		
-		if( push8(pdu->pdu_type, ppWritePackedMsg, end) == 0)
-			return 0;
-
-		// Put a 0 size in and then determine the size after the pdu 
-		// has been writen and write the calculated size
-		uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg;
-		pdu->pdu_size = 0;
-		if( push8(pdu->pdu_size, ppWritePackedMsg, end) == 0)
-			return 0;
-
-		switch(pdu->pdu_type)
-		{
-			case NFAPI_LBT_DL_CONFIG_REQUEST_PDSCH_PDU_TYPE:
-				{
-					if( pack_tlv(NFAPI_LBT_PDSCH_REQ_PDU_REL13_TAG, &pdu->lbt_pdsch_req_pdu.lbt_pdsch_req_pdu_rel13, ppWritePackedMsg, end, pack_lbt_pdsch_req_pdu_rel13_value) == 0)
-						return 0;
-				}
-				break;
-			case NFAPI_LBT_DL_CONFIG_REQUEST_DRS_PDU_TYPE:
-				{
-					if(pack_tlv(NFAPI_LBT_DRS_REQ_PDU_REL13_TAG, &pdu->lbt_drs_req_pdu.lbt_drs_req_pdu_rel13, ppWritePackedMsg, end, pack_lbt_drs_req_pdu_rel13_value) == 0)
-						return 0;
-				}
-				break;
-			default:
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL_CONFIG.request invalid pdu type %d \n", pdu->pdu_type );
-				}
-				break;
-		};
-
-		// add 1 for the pdu_type. The delta will include the pdu_size
-		pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize);
-		push8(pdu->pdu_size, &pWritePackedMsgPduSize, end);
-	}
-
-	return 1;
-}
-
-static uint8_t pack_lbt_pdsch_rsp_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lbt_pdsch_rsp_pdu_rel13_t* value = (nfapi_lbt_pdsch_rsp_pdu_rel13_t*)tlv;
-	
-	return ( push32(value->handle, ppWritePackedMsg, end) &&
-			 push32(value->result, ppWritePackedMsg, end) &&
-			 push32(value->lte_txop_symbols, ppWritePackedMsg, end) &&
-			 push32(value->initial_partial_sf, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_lbt_drs_rsp_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lbt_drs_rsp_pdu_rel13_t* value = (nfapi_lbt_drs_rsp_pdu_rel13_t*)tlv;
-	
-	return ( push32(value->handle, ppWritePackedMsg, end) &&
-			 push32(value->result, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_lbt_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_lbt_dl_config_request_t *pNfapiMsg = (nfapi_lbt_dl_config_request_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_LBT_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->lbt_dl_config_request_body, ppWritePackedMsg, end, &pack_lbt_dl_config_request_body_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_lbt_dl_config_indication_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_lbt_dl_indication_body_t* value = (nfapi_lbt_dl_indication_body_t*)tlv;
-	
-	if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_pdus = value->number_of_pdus;
-	for(; i < total_number_of_pdus; ++i)
-	{
-		nfapi_lbt_dl_indication_pdu_t* pdu = &(value->lbt_indication_pdu_list[i]);
-		
-		if( push8(pdu->pdu_type, ppWritePackedMsg, end) == 0)
-			return 0;
-
-		// Put a 0 size in and then determine the size after the pdu 
-		// has been writen and write the calculated size
-		uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg;
-		pdu->pdu_size = 0;
-		
-		if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0)
-			return 0;
-
-		switch(pdu->pdu_type)
-		{
-			case NFAPI_LBT_DL_RSP_PDSCH_PDU_TYPE:
-				{
-					if( pack_tlv(NFAPI_LBT_PDSCH_RSP_PDU_REL13_TAG, &pdu->lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13, ppWritePackedMsg, end, pack_lbt_pdsch_rsp_pdu_rel13_value) == 0)
-						return 0;
-				}
-				break;
-			case NFAPI_LBT_DL_RSP_DRS_PDU_TYPE:
-				{
-					if( pack_tlv(NFAPI_LBT_DRS_RSP_PDU_REL13_TAG, &pdu->lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13, ppWritePackedMsg, end, pack_lbt_drs_rsp_pdu_rel13_value) == 0)
-						return 0;
-				}
-				break;
-			default:
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL.indication body invalid pdu type %d \n", pdu->pdu_type );
-				}
-				break;
-		};
-
-		// add 1 for the pdu_type. The delta will include the pdu_size
-		pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize);
-		push8(pdu->pdu_size, &pWritePackedMsgPduSize, end);
-	}
-
-	return 1;
-}
-
-static uint8_t pack_lbt_dl_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_lbt_dl_indication_t *pNfapiMsg = (nfapi_lbt_dl_indication_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_LBT_DL_INDICATION_BODY_TAG, &pNfapiMsg->lbt_dl_indication_body, ppWritePackedMsg, end, &pack_lbt_dl_config_indication_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_nb_harq_indication_fdd_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nb_harq_indication_fdd_rel13_t* nb_harq_indication_fdd_rel13 = (nfapi_nb_harq_indication_fdd_rel13_t*)tlv;
-	
-	return ( push8(nb_harq_indication_fdd_rel13->harq_tb1, ppWritePackedMsg, end) );
-}
-
-static uint8_t pack_nb_harq_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nb_harq_indication_body_t* value = (nfapi_nb_harq_indication_body_t*)tlv;
-	
-	if( push16(value->number_of_harqs, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_harqs = value->number_of_harqs;
-	for(; i < total_number_of_harqs; ++i)
-	{
-		nfapi_nb_harq_indication_pdu_t* pdu = &(value->nb_harq_pdu_list[i]);
-		
-		uint8_t* instance_length_p = *ppWritePackedMsg;
-		if(!push16(pdu->instance_length, ppWritePackedMsg, end))
-			return 0;
-
-		if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) &&
-			 pack_tlv(NFAPI_NB_HARQ_INDICATION_FDD_REL13_TAG, &pdu->nb_harq_indication_fdd_rel13, ppWritePackedMsg, end, pack_nb_harq_indication_fdd_rel13_value) &&
-			 pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value)))
-			return 0;
-			
-		// calculate the instance length subtracting the size of the instance
-		// length feild
-		uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
-		push16(instance_length, &instance_length_p, end);
-	}
-
-	return 1;
-}
-
-
-static uint8_t pack_nb_harq_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nb_harq_indication_t *pNfapiMsg = (nfapi_nb_harq_indication_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_NB_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->nb_harq_indication_body, ppWritePackedMsg, end, &pack_nb_harq_indication_body_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_nrach_indication_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nrach_indication_pdu_rel13_t* nrach_indication_fdd_rel13 = (nfapi_nrach_indication_pdu_rel13_t*)tlv;
-	
-	return ( push16(nrach_indication_fdd_rel13->rnti, ppWritePackedMsg, end) &&
-			 push8(nrach_indication_fdd_rel13->initial_sc, ppWritePackedMsg, end) &&
-			 push16(nrach_indication_fdd_rel13->timing_advance, ppWritePackedMsg, end) &&
-			 push8(nrach_indication_fdd_rel13->nrach_ce_level, ppWritePackedMsg, end));
-}
-
-
-static uint8_t pack_nrach_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nrach_indication_body_t* value = (nfapi_nrach_indication_body_t*)tlv;
-	
-	if( push8(value->number_of_initial_scs_detected, ppWritePackedMsg, end) == 0)
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_initial_scs_detected = value->number_of_initial_scs_detected;
-	for(; i < total_number_of_initial_scs_detected; ++i)
-	{
-		nfapi_nrach_indication_pdu_t* pdu = &(value->nrach_pdu_list[i]);
-		
-		//uint8_t* instance_length_p = *ppWritePackedMsg;
-		//if(!push16(pdu->instance_length, ppWritePackedMsg, end))
-		//	return 0;
-
-		if(!(pack_tlv(NFAPI_NRACH_INDICATION_REL13_TAG, &pdu->nrach_indication_rel13, ppWritePackedMsg, end, pack_nrach_indication_rel13_value)))
-			return 0;
-			
-		// calculate the instance length subtracting the size of the instance
-		// length feild
-		//uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
-		//push16(instance_length, &instance_length_p, end);
-	}
-
-	return 1;
-}
-
-static uint8_t pack_nrach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nrach_indication_t *pNfapiMsg = (nfapi_nrach_indication_t*)msg;
-	
-	return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
-			 pack_tlv(NFAPI_NRACH_INDICATION_BODY_TAG, &pNfapiMsg->nrach_indication_body, ppWritePackedMsg, end, &pack_nrach_indication_body_value) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_nr_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_dl_node_sync_t *pNfapiMsg = (nfapi_nr_dl_node_sync_t*)msg;
-
-	return ( push32(pNfapiMsg->t1, ppWritePackedMsg, end) &&
-			 pushs32(pNfapiMsg->delta_sfn_slot, ppWritePackedMsg, end) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_dl_node_sync_t *pNfapiMsg = (nfapi_dl_node_sync_t*)msg;
-
-	return ( push32(pNfapiMsg->t1, ppWritePackedMsg, end) &&
-			 pushs32(pNfapiMsg->delta_sfn_sf, ppWritePackedMsg, end) &&
-			 pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_nr_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_ul_node_sync_t *pNfapiMsg = (nfapi_nr_ul_node_sync_t*)msg;
-
-	return (push32(pNfapiMsg->t1, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->t2, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->t3, ppWritePackedMsg, end) &&
-			pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_ul_node_sync_t *pNfapiMsg = (nfapi_ul_node_sync_t*)msg;
-
-	return (push32(pNfapiMsg->t1, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->t2, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->t3, ppWritePackedMsg, end) &&
-			pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_timing_info_t *pNfapiMsg = (nfapi_timing_info_t*)msg;
-    
-	return (push32(pNfapiMsg->last_sfn_sf, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->time_since_last_timing_info, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->dl_config_jitter, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->tx_request_jitter, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->ul_config_jitter, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->hi_dci0_jitter, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->dl_config_latest_delay, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->tx_request_latest_delay, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->ul_config_latest_delay, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->hi_dci0_latest_delay, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->dl_config_earliest_arrival, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->tx_request_earliest_arrival, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->ul_config_earliest_arrival, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->hi_dci0_earliest_arrival, ppWritePackedMsg, end) &&
-			pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-static uint8_t pack_nr_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_timing_info_t *pNfapiMsg = (nfapi_nr_timing_info_t*)msg;
-    
-	return (push32(pNfapiMsg->last_sfn, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->last_slot, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->time_since_last_timing_info, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->dl_tti_jitter, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->tx_data_request_jitter, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->ul_tti_jitter, ppWritePackedMsg, end) &&
-			push32(pNfapiMsg->ul_dci_jitter, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->dl_tti_latest_delay, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->tx_data_request_latest_delay, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->ul_tti_latest_delay, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->ul_dci_latest_delay, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->dl_tti_earliest_arrival, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->tx_data_request_earliest_arrival, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->ul_tti_earliest_arrival, ppWritePackedMsg, end) &&
-			pushs32(pNfapiMsg->ul_dci_earliest_arrival, ppWritePackedMsg, end) &&
-			pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
-}
-
-
-
-// Main pack function - public
-
-int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config)
-{
-	nfapi_p7_message_header_t *pMessageHeader = pMessageBuf;
-	uint8_t *pWritePackedMessage = pPackedBuf;
-	uint8_t *pPackedLengthField = &pWritePackedMessage[4];
-	uint8_t *end = pPackedBuf + packedBufLen;
-
-	if (pMessageBuf == NULL || pPackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n");
-		return -1;
-	}
-	/*
-	printf("\n P7 MESSAGE SENT: \n");
-	for(int i=0; i< packedBufLen; i++){
-		printf("%d", *(uint8_t *)(pMessageBuf + i));
-	}
-	printf("\n");
-	*/
-	// process the header
-	if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) &&
-		 push16(pMessageHeader->message_id, &pWritePackedMessage, end) &&
-		 push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, end) &&
-		 push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end) &&
-		 push32(0/*pMessageHeader->checksum*/, &pWritePackedMessage, end) &&
-		 push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end)))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n");
-		return -1;
-	}
-
-        if (pMessageHeader->message_id != NFAPI_TIMING_INFO)
-        {
-          //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__, pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp);
-        }
-	// look for the specific message
-	uint8_t result = 0;
-	switch (pMessageHeader->message_id)
-	{
-		case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
-			result = pack_dl_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
-			result = pack_ul_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
-			result = pack_tx_data_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
-			result = pack_ul_dci_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-		
-		case NFAPI_UE_RELEASE_REQUEST:
-			result =pack_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_UE_RELEASE_RESPONSE:
-			result =pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_HARQ_INDICATION:
-			result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_CRC_INDICATION:
-			result = pack_crc_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_RX_ULSCH_INDICATION:
-                        //printf("RX ULSCH\n");
-			result = pack_rx_ulsch_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_RACH_INDICATION:
-			result = pack_rach_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_SRS_INDICATION:
-			result = pack_srs_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_RX_SR_INDICATION:
-			result = pack_sr_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_RX_CQI_INDICATION:
-			result = pack_cqi_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_LBT_DL_CONFIG_REQUEST:
-			result = pack_lbt_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_LBT_DL_INDICATION:
-			result = pack_lbt_dl_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_NB_HARQ_INDICATION:
-			result = pack_nb_harq_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_NRACH_INDICATION:
-			result = pack_nrach_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
-			result = pack_nr_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
-			result = pack_nr_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_TIMING_INFO:
-			result = pack_nr_timing_info(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		default:
-			{
-				if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
-				   pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
-				{
-					if(config && config->pack_p7_vendor_extension)
-					{
-						result = (config->pack_p7_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config);
-					}
-					else
-					{
-						NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, pMessageHeader->message_id);
-					}
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
-				}
-			}
-			break;
-	}
-
-	if(result == 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
-		return -1;
-	}
-
-	// check for a valid message length
-	uintptr_t msgHead = (uintptr_t)pPackedBuf;
-	uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
-	uint32_t packedMsgLen = msgEnd - msgHead;
-	uint16_t packedMsgLen16;
-	if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
-		return -1;
-	}
-	else
-	{
-		packedMsgLen16 = (uint16_t)packedMsgLen;
-	}
-
-	// Update the message length in the header
-	pMessageHeader->message_length = packedMsgLen16;
-	
-	if(!push16(packedMsgLen16, &pPackedLengthField, end))
-		return -1;
-		
-	if(1)
-	{
-		//quick test
-		if(pMessageHeader->message_length != packedMsgLen)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi packedMsgLen(%d) != message_length(%d) id %d\n", packedMsgLen, pMessageHeader->message_length, pMessageHeader->message_id);
-		}
-	}
-
-	return (packedMsgLen);
-}
-
-int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config)
-{
-	nfapi_p7_message_header_t *pMessageHeader = pMessageBuf;
-	uint8_t *pWritePackedMessage = pPackedBuf;
-	uint8_t *pPackedLengthField = &pWritePackedMessage[4];
-	uint8_t *end = pPackedBuf + packedBufLen;
-
-	if (pMessageBuf == NULL || pPackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n");
-		return -1;
-	}
-	/*
-	printf("\n P7 MESSAGE SENT: \n");
-	for(int i=0; i< packedBufLen; i++){
-		printf("%d", *(uint8_t *)(pMessageBuf + i));
-	}
-	printf("\n");
-	*/
-	// process the header
-	if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) &&
-		 push16(pMessageHeader->message_id, &pWritePackedMessage, end) &&
-		 push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, end) &&
-		 push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end) &&
-		 push32(0/*pMessageHeader->checksum*/, &pWritePackedMessage, end) &&
-		 push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end)))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n");
-		return -1;
-	}
-
-        if (pMessageHeader->message_id != NFAPI_TIMING_INFO)
-        {
-          //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__, pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp);
-        }
-	// look for the specific message
-	uint8_t result = 0;
-	switch (pMessageHeader->message_id)
-	{
-		case NFAPI_DL_CONFIG_REQUEST:
-                  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_DL_CONFIG_REQUEST\n", __FUNCTION__);
-			result = pack_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_UL_CONFIG_REQUEST:
-			result = pack_ul_config_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-        case NFAPI_TX_REQUEST:
-            //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_TX_REQUEST\n", __FUNCTION__);
-			result = pack_tx_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-		case NFAPI_HI_DCI0_REQUEST:
-			result = pack_hi_dci0_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-		
-		case NFAPI_UE_RELEASE_REQUEST:
-			result =pack_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_UE_RELEASE_RESPONSE:
-			result =pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_HARQ_INDICATION:
-			result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_CRC_INDICATION:
-			result = pack_crc_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_RX_ULSCH_INDICATION:
-                        //printf("RX ULSCH\n");
-			result = pack_rx_ulsch_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_RACH_INDICATION:
-			result = pack_rach_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_SRS_INDICATION:
-			result = pack_srs_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_RX_SR_INDICATION:
-			result = pack_sr_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_RX_CQI_INDICATION:
-			result = pack_cqi_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_LBT_DL_CONFIG_REQUEST:
-			result = pack_lbt_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_LBT_DL_INDICATION:
-			result = pack_lbt_dl_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_NB_HARQ_INDICATION:
-			result = pack_nb_harq_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_NRACH_INDICATION:
-			result = pack_nrach_indication(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_DL_NODE_SYNC:
-			result = pack_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_UL_NODE_SYNC:
-			result = pack_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		case NFAPI_TIMING_INFO:
-			result = pack_timing_info(pMessageHeader, &pWritePackedMessage, end, config);
-			break;
-
-		default:
-			{
-				if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
-				   pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
-				{
-					if(config && config->pack_p7_vendor_extension)
-					{
-						result = (config->pack_p7_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config);
-					}
-					else
-					{
-						NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, pMessageHeader->message_id);
-					}
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
-				}
-			}
-			break;
-	}
-
-	if(result == 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
-		return -1;
-	}
-
-	// check for a valid message length
-	uintptr_t msgHead = (uintptr_t)pPackedBuf;
-	uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
-	uint32_t packedMsgLen = msgEnd - msgHead;
-	uint16_t packedMsgLen16;
-	if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
-		return -1;
-	}
-	else
-	{
-		packedMsgLen16 = (uint16_t)packedMsgLen;
-	}
-
-	// Update the message length in the header
-	pMessageHeader->message_length = packedMsgLen16;
-	
-	if(!push16(packedMsgLen16, &pPackedLengthField, end))
-		return -1;
-		
-	if(1)
-	{
-		//quick test
-		if(pMessageHeader->message_length != packedMsgLen)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi packedMsgLen(%d) != message_length(%d) id %d\n", packedMsgLen, pMessageHeader->message_length, pMessageHeader->message_id);
-		}
-	}
-
-	return (packedMsgLen);
-}
-
-// Unpack routines
-// NR:
-static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nr_dl_tti_csi_rs_pdu_rel15_t* value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t*)tlv;
-
-	return(
-		pull16(ppReadPackedMsg, &value->bwp_size, end) &&
-		pull16(ppReadPackedMsg, &value->bwp_start, end) &&
-
-		pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) &&
-		pull8(ppReadPackedMsg, &value->cyclic_prefix, end) &&
-
-		pull16(ppReadPackedMsg, &value->start_rb, end) &&
-		pull16(ppReadPackedMsg, &value->nr_of_rbs, end) &&
-
-		pull8(ppReadPackedMsg, &value->csi_type, end) &&
-		pull8(ppReadPackedMsg, &value->row, end) &&
-
-		pull16(ppReadPackedMsg, &value->freq_domain, end) &&
-		pull8(ppReadPackedMsg, &value->symb_l0, end) &&
-
-		pull8(ppReadPackedMsg, &value->symb_l1, end) &&
-		pull8(ppReadPackedMsg, &value->cdm_type, end) &&
-
-		pull8(ppReadPackedMsg, &value->freq_density, end) &&
-		pull16(ppReadPackedMsg, &value->scramb_id, end) &&
-
-		pull8(ppReadPackedMsg, &value->power_control_offset, end) &&
-		pull8(ppReadPackedMsg, &value->power_control_offset_ss, end)
-	);
-
-}
-
-
-static uint8_t unpack_dl_tti_pdcch_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nr_dl_tti_pdcch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t*)tlv;
-	
-	for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i)
-	{
-		if(!pull16(ppReadPackedMsg, &value->dci_pdu[i].RNTI, end) &&
-		pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingId, end) &&
-
-		pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingRNTI, end) &&
-		pull8(ppReadPackedMsg, &value->dci_pdu[i].CceIndex, end) &&
-		pull8(ppReadPackedMsg, &value->dci_pdu[i].AggregationLevel, end) &&
-		pull8(ppReadPackedMsg, &value->dci_pdu[i].beta_PDCCH_1_0, end) &&
-
-		pull8(ppReadPackedMsg, &value->dci_pdu[i].powerControlOffsetSS, end) &&
-		pull16(ppReadPackedMsg, &value->dci_pdu[i].PayloadSizeBits, end) &&
-		
-		pullarray8(ppReadPackedMsg, value->dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->dci_pdu[i].PayloadSizeBits, end));
-			
-		return 0;
-	}
-
-	// TODO: resolve the packaging of array (currently sending a single element)
-	return(
-		pull16(ppReadPackedMsg, &value->BWPSize, end) &&
-		pull16(ppReadPackedMsg, &value->BWPStart, end) &&
-		pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) &&
-		pull8(ppReadPackedMsg, &value->CyclicPrefix, end) &&
-
-		pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) &&
-		pull8(ppReadPackedMsg, &value->DurationSymbols, end) &&
-		pullarray8(ppReadPackedMsg, value->FreqDomainResource, 6, 6, end) &&
-		pull8(ppReadPackedMsg, &value->CceRegMappingType, end) &&
-
-		pull8(ppReadPackedMsg, &value->RegBundleSize, end) &&
-		pull8(ppReadPackedMsg, &value->InterleaverSize, end) &&
-		pull8(ppReadPackedMsg, &value->CoreSetType, end) &&
-		pull16(ppReadPackedMsg, &value->ShiftIndex, end) &&
-
-		pull8(ppReadPackedMsg, &value->precoderGranularity, end) &&
-		pull16(ppReadPackedMsg, &value->numDlDci, end));
-
-}
-
-
-static uint8_t unpack_dl_tti_pdsch_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nr_dl_tti_pdsch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t*)tlv;
-
-	// TODO: resolve the packaging of array (currently sending a single element)
-	return(
-		pull16(ppReadPackedMsg, &value->pduBitmap, end) &&
-		pull16(ppReadPackedMsg, &value->rnti, end) &&
-		pull16(ppReadPackedMsg, &value->pduIndex, end) &&
-		pull16(ppReadPackedMsg, &value->BWPSize, end) &&
-		
-		pull16(ppReadPackedMsg, &value->BWPStart, end) &&
-		pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) &&
-		pull8(ppReadPackedMsg, &value->CyclicPrefix, end) &&
-		pull8(ppReadPackedMsg, &value->NrOfCodewords, end) &&
-		
-		pullarray16(ppReadPackedMsg, value->targetCodeRate, 2, 1, end) &&
-		pullarray8(ppReadPackedMsg, value->qamModOrder, 2, 1, end) &&
-		pullarray8(ppReadPackedMsg, value->mcsIndex, 2, 1, end) &&
-        pullarray8(ppReadPackedMsg, value->mcsTable, 2, 1, end) &&
-		
-		pullarray8(ppReadPackedMsg, value->rvIndex, 2, 1, end) &&
-	    pullarray32(ppReadPackedMsg, value->TBSize, 2, 1, end) &&
-	    pull16(ppReadPackedMsg, &value->dataScramblingId, end) &&
-		pull8(ppReadPackedMsg, &value->nrOfLayers, end) &&
-		
-		pull8(ppReadPackedMsg, &value->transmissionScheme, end) &&
-		pull8(ppReadPackedMsg, &value->refPoint, end) &&
-		pull16(ppReadPackedMsg, &value->dlDmrsSymbPos, end) &&
-		pull8(ppReadPackedMsg, &value->dmrsConfigType, end) &&
-		
-		pull16(ppReadPackedMsg, &value->dlDmrsScramblingId, end) &&
-		pull8(ppReadPackedMsg, &value->SCID, end) &&
-		pull8(ppReadPackedMsg, &value->numDmrsCdmGrpsNoData, end) &&
-		pull16(ppReadPackedMsg, &value->dmrsPorts, end) &&
-
-		pull8(ppReadPackedMsg, &value->resourceAlloc, end) &&
-		pull16(ppReadPackedMsg, &value->rbStart, end) &&
-		pull16(ppReadPackedMsg, &value->rbSize, end) &&
-
-		pull8(ppReadPackedMsg, &value->VRBtoPRBMapping, end) &&
-		pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) &&
-		pull8(ppReadPackedMsg, &value->NrOfSymbols, end) &&
-		pull8(ppReadPackedMsg, &value->PTRSPortIndex, end) &&
-
-		pull8(ppReadPackedMsg, &value->PTRSTimeDensity, end) &&
-		pull8(ppReadPackedMsg, &value->PTRSFreqDensity, end) &&
-		pull8(ppReadPackedMsg, &value->PTRSReOffset, end) 	
-	);
-
-}
-
-
-static uint8_t unpack_dl_tti_ssb_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nr_dl_tti_ssb_pdu_rel15_t* value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t*)tlv;
-
-	return(
-		pull16(ppReadPackedMsg, &value->PhysCellId, end) &&
-		pull8(ppReadPackedMsg, &value->BetaPss, end) &&
-		pull8(ppReadPackedMsg, &value->SsbBlockIndex, end) &&
-		pull8(ppReadPackedMsg, &value->SsbSubcarrierOffset, end) &&
-		pull16(ppReadPackedMsg, &value->ssbOffsetPointA, end) &&
-		pull8(ppReadPackedMsg, &value->bchPayloadFlag, end) &&
-		pull32(ppReadPackedMsg, &value->bchPayload, end)	
-		// TODO: pack precoding_and_beamforming too
-	);
-
-}
-
-
-// LTE:
-static uint8_t unpack_dl_config_dci_dl_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dci_dl_pdu_rel8_t* dci_dl_pdu_rel8 = (nfapi_dl_config_dci_dl_pdu_rel8_t*)tlv; 
-
-	return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->dci_format, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->cce_idx, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->aggregation_level, end) &&
-			pull16(ppReadPackedMsg, &dci_dl_pdu_rel8->rnti, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->resource_allocation_type, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->virtual_resource_block_assignment_flag, end) &&
-			pull32(ppReadPackedMsg, &dci_dl_pdu_rel8->resource_block_coding, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->mcs_1, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->redundancy_version_1, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->new_data_indicator_1, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->transport_block_to_codeword_swap_flag, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->mcs_2, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->redundancy_version_2, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->new_data_indicator_2, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->harq_process, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->tpmi, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->pmi, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->precoding_information, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->tpc, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->downlink_assignment_index, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->ngap, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->transport_block_size_index, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->downlink_power_offset, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->allocate_prach_flag, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->preamble_index, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->prach_mask_index, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->rnti_type, end) &&
-			pull16(ppReadPackedMsg, &dci_dl_pdu_rel8->transmission_power, end));
-
-}
-
-static uint8_t unpack_dl_config_dci_dl_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dci_dl_pdu_rel9_t* dci_dl_pdu_rel9 = (nfapi_dl_config_dci_dl_pdu_rel9_t*)tlv;
-	
-	return ( pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->mcch_flag, end) &&
-			 pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->mcch_change_notification, end) &&
-			 pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->scrambling_identity, end));
-}
-
-static uint8_t unpack_dl_config_dci_dl_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dci_dl_pdu_rel10_t* dci_dl_pdu_rel10 = (nfapi_dl_config_dci_dl_pdu_rel10_t*)tlv;
-
-	return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->cross_carrier_scheduling_flag, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->carrier_indicator, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->srs_flag, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->srs_request, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->antenna_ports_scrambling_and_layers, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->total_dci_length_including_padding, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->n_dl_rb, end));
-}
-
-static uint8_t unpack_dl_config_dci_dl_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dci_dl_pdu_rel11_t* dci_dl_pdu_rel11 = (nfapi_dl_config_dci_dl_pdu_rel11_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel11->harq_ack_resource_offset, end) && 
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel11->pdsch_re_mapping_quasi_co_location_indicator, end));
-}
-
-static uint8_t unpack_dl_config_dci_dl_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dci_dl_pdu_rel12_t* dci_dl_pdu_rel12 = (nfapi_dl_config_dci_dl_pdu_rel12_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->primary_cell_type, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->ul_dl_configuration_flag, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->number_ul_dl_configurations, end) &&
-			pullarray8(ppReadPackedMsg, dci_dl_pdu_rel12->ul_dl_configuration_indication, NFAPI_MAX_UL_DL_CONFIGURATIONS, dci_dl_pdu_rel12->number_ul_dl_configurations, end));
-}
-
-static uint8_t unpack_tpm_value(uint8_t **ppReadPackedMsg, nfapi_dl_config_dci_dl_tpm_t *value, uint8_t *end)
-{
-	if(!(pull8(ppReadPackedMsg, &value->num_prb_per_subband, end) && 
-		 pull8(ppReadPackedMsg, &value->number_of_subbands, end) &&
-		 pull8(ppReadPackedMsg, &value->num_antennas, end)))
-		return 0;
-	
-	
-	uint8_t idx = 0;
-	for(idx = 0; idx < value->number_of_subbands; ++idx)
-	{
-		nfapi_dl_config_dci_dl_tpm_subband_info_t* subband_info = &(value->subband_info[idx]);
-		
-		if(!(pull8(ppReadPackedMsg, &subband_info->subband_index, end) &&
-			 pull8(ppReadPackedMsg, &subband_info->scheduled_ues, end)))
-			return 0;
-			
-		uint8_t antenna_idx = 0;
-		uint8_t scheduled_ue_idx = 0;
-		
-		for(antenna_idx = 0; antenna_idx < value->num_antennas; ++antenna_idx)
-		{
-			for(scheduled_ue_idx = 0; scheduled_ue_idx < subband_info->scheduled_ues; ++scheduled_ue_idx)
-			{
-				if(!pull16(ppReadPackedMsg, &(subband_info->precoding_value[antenna_idx][scheduled_ue_idx]), end))
-					return 0;
-			}
-		}
-
-	}
-	
-	
-	return 1;
-			
-}
-
-
-static uint8_t unpack_dl_config_dci_dl_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dci_dl_pdu_rel13_t* dci_dl_pdu_rel13 = (nfapi_dl_config_dci_dl_pdu_rel13_t*)tlv;
-	
-	// If the length is greater than 5 then the TPM struct flag and possiably the TPM structure have been 
-	// added
-	uint8_t tpm_struct_flag_present = dci_dl_pdu_rel13->tl.length > 5;
-	dci_dl_pdu_rel13->tpm_struct_flag = 0;
-	
-	return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->laa_end_partial_sf_flag, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->laa_end_partial_sf_configuration, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->initial_lbt_sf, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->codebook_size_determination, end) &&
-			pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->drms_table_flag, end) && 
-			( (tpm_struct_flag_present == 1) ? pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->tpm_struct_flag, end) : 1) &&
-			( (tpm_struct_flag_present == 1 &&  dci_dl_pdu_rel13->tpm_struct_flag == 1) ? unpack_tpm_value(ppReadPackedMsg, &dci_dl_pdu_rel13->tpm, end) : 1));
-			
-}
-
-static uint8_t unpack_dl_config_bch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_bch_pdu_rel8_t* bch_pdu_rel8 = (nfapi_dl_config_bch_pdu_rel8_t*)tlv;
-	
-	return ( pull16(ppReadPackedMsg, &bch_pdu_rel8->length, end) &&
-			 pull16(ppReadPackedMsg, (uint16_t *)&bch_pdu_rel8->pdu_index, end) &&
-			 pull16(ppReadPackedMsg, &bch_pdu_rel8->transmission_power, end));
-}
-
-static uint8_t unpack_dl_config_mch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_mch_pdu_rel8_t* mch_pdu_rel8 = (nfapi_dl_config_mch_pdu_rel8_t*)tlv;
-	
-	return (pull16(ppReadPackedMsg, &mch_pdu_rel8->length, end) &&
-			pull16(ppReadPackedMsg, (uint16_t *)&mch_pdu_rel8->pdu_index, end) &&
-			pull16(ppReadPackedMsg, &mch_pdu_rel8->rnti, end) &&
-			pull8(ppReadPackedMsg, &mch_pdu_rel8->resource_allocation_type, end) &&
-			pull32(ppReadPackedMsg, &mch_pdu_rel8->resource_block_coding, end) &&
-			pull8(ppReadPackedMsg, &mch_pdu_rel8->modulation, end) &&
-			pull16(ppReadPackedMsg, &mch_pdu_rel8->transmission_power, end) &&
-			pull16(ppReadPackedMsg, &mch_pdu_rel8->mbsfn_area_id, end));
-}
-
-static uint8_t unpack_dl_config_dlsch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dlsch_pdu_rel8_t* dlsch_pdu_rel8 = (nfapi_dl_config_dlsch_pdu_rel8_t*)tlv;
-	
-	if (!(pull16(ppReadPackedMsg, &dlsch_pdu_rel8->length, end) &&
-		  pull16(ppReadPackedMsg, (uint16_t *)&dlsch_pdu_rel8->pdu_index, end) &&
-		  pull16(ppReadPackedMsg, &dlsch_pdu_rel8->rnti, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->resource_allocation_type, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->virtual_resource_block_assignment_flag, end) &&
-		  pull32(ppReadPackedMsg, &dlsch_pdu_rel8->resource_block_coding, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->modulation, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->redundancy_version, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transport_blocks, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transport_block_to_codeword_swap_flag, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transmission_scheme, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->number_of_layers, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->number_of_subbands, end) &&
-		  pullarray8(ppReadPackedMsg, dlsch_pdu_rel8->codebook_index, NFAPI_MAX_NUM_SUBBANDS, dlsch_pdu_rel8->number_of_subbands, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->ue_category_capacity, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->pa, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->delta_power_offset_index, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->ngap, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->nprb, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transmission_mode, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->num_bf_prb_per_subband, end) &&
-		  pull8(ppReadPackedMsg, &dlsch_pdu_rel8->num_bf_vector, end)))
-		return 0;
-
-	uint16_t j = 0;
-	for(j = 0; j < dlsch_pdu_rel8->num_bf_vector; ++j)
-	{								
-		if(!(pull8(ppReadPackedMsg, &dlsch_pdu_rel8->bf_vector[j].subband_index, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel8->bf_vector[j].num_antennas, end) &&
-			 pullarray16(ppReadPackedMsg, dlsch_pdu_rel8->bf_vector[j].bf_value, NFAPI_MAX_NUM_ANTENNAS, dlsch_pdu_rel8->bf_vector[j].num_antennas, end)))
-			return 0;
-	}
-	return 1;
-}
-static uint8_t unpack_dl_config_dlsch_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dlsch_pdu_rel9_t* dlsch_pdu_rel9 = (nfapi_dl_config_dlsch_pdu_rel9_t*)tlv;
-	return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel9->nscid, end) );
-}
-static uint8_t unpack_dl_config_dlsch_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dlsch_pdu_rel10_t* dlsch_pdu_rel10 = (nfapi_dl_config_dlsch_pdu_rel10_t*)tlv;
-	
-	return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_flag, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_resource_config_r10, end) &&
-			 pull16(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_zero_tx_power_resource_config_bitmap_r10, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_number_nzp_configuration, end) &&
-			 pullarray8(ppReadPackedMsg, dlsch_pdu_rel10->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, dlsch_pdu_rel10->csi_rs_number_nzp_configuration, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel10->pdsch_start, end)) ;
-}
-static uint8_t unpack_dl_config_dlsch_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dlsch_pdu_rel11_t* dlsch_pdu_rel11 = (nfapi_dl_config_dlsch_pdu_rel11_t*)tlv;
-	
-	return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel11->drms_config_flag, end) &&
-			 pull16(ppReadPackedMsg, &dlsch_pdu_rel11->drms_scrambling, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel11->csi_config_flag, end) &&
-			 pull16(ppReadPackedMsg, &dlsch_pdu_rel11->csi_scrambling, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_flag, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_atenna_ports, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_freq_shift, end));
-}
-static uint8_t unpack_dl_config_dlsch_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dlsch_pdu_rel12_t* dlsch_pdu_rel12 = (nfapi_dl_config_dlsch_pdu_rel12_t*)tlv;
-	
-	return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel12->altcqi_table_r12, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel12->maxlayers, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel12->n_dl_harq, end));
-}
-static uint8_t unpack_dl_config_dlsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_dlsch_pdu_rel13_t* dlsch_pdu_rel13 = (nfapi_dl_config_dlsch_pdu_rel13_t*)tlv;
-	
-	return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel13->dwpts_symbols, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel13->initial_lbt_sf, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel13->ue_type, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel13->pdsch_payload_type, end) &&
-			 pull16(ppReadPackedMsg, &dlsch_pdu_rel13->initial_transmission_sf_io, end) &&
-			 pull8(ppReadPackedMsg, &dlsch_pdu_rel13->drms_table_flag, end));
-}
-
-static uint8_t unpack_dl_config_pch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_pch_pdu_rel8_t* pch_pdu_rel8 = (nfapi_dl_config_pch_pdu_rel8_t*)tlv;
-	
-	return ( pull16(ppReadPackedMsg, &pch_pdu_rel8->length, end) &&
-			 pull16(ppReadPackedMsg, (uint16_t *)&pch_pdu_rel8->pdu_index, end) &&
-			 pull16(ppReadPackedMsg, &pch_pdu_rel8->p_rnti, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->resource_allocation_type, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->virtual_resource_block_assignment_flag, end) &&
-			 pull32(ppReadPackedMsg, &pch_pdu_rel8->resource_block_coding, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->mcs, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->redundancy_version, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->number_of_transport_blocks, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->transport_block_to_codeword_swap_flag, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->transmission_scheme, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->number_of_layers, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->codebook_index, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->ue_category_capacity, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->pa, end) &&
-			 pull16(ppReadPackedMsg, &pch_pdu_rel8->transmission_power, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->nprb, end) &&
-			 pull8(ppReadPackedMsg, &pch_pdu_rel8->ngap, end));
-}
-static uint8_t unpack_dl_config_pch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_pch_pdu_rel13_t* pch_pdu_rel13 = (nfapi_dl_config_pch_pdu_rel13_t*)tlv;
-	
-	return ( pull8(ppReadPackedMsg, &pch_pdu_rel13->ue_mode, end) &&
-			 pull16(ppReadPackedMsg, &pch_pdu_rel13->initial_transmission_sf_io, end));
-}
-
-static uint8_t unpack_dl_config_prs_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_prs_pdu_rel9_t* prs_pdu_rel9 = (nfapi_dl_config_prs_pdu_rel9_t*)tlv;
-	
-	return ( pull16(ppReadPackedMsg, &prs_pdu_rel9->transmission_power, end) &&
-			 pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_bandwidth, end) &&
-			 pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_cyclic_prefix_type, end) &&
-			 pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_muting, end));
-}
-
-static uint8_t unpack_dl_config_csi_rs_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_csi_rs_pdu_rel10_t* csi_rs_pdu_rel10 = (nfapi_dl_config_csi_rs_pdu_rel10_t*)tlv;
-	
-	return ( pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_antenna_port_count_r10, end) &&
-			 pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_resource_config_r10, end) &&
-			 pull16(ppReadPackedMsg, &csi_rs_pdu_rel10->transmission_power, end) &&
-			 pull16(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_zero_tx_power_resource_config_bitmap_r10, end) &&
-			 pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_number_of_nzp_configuration, end) &&
-			 pullarray8(ppReadPackedMsg, csi_rs_pdu_rel10->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, csi_rs_pdu_rel10->csi_rs_number_of_nzp_configuration, end));
-}
-
-static uint8_t unpack_dl_config_csi_rs_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_csi_rs_pdu_rel13_t* csi_rs_pdu_rel13 = (nfapi_dl_config_csi_rs_pdu_rel13_t*)tlv;
-	
-	if (!(pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->csi_rs_class, end) &&
-		  pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->cdm_type, end) &&
-		  pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->num_bf_vector, end)))
-		return 0;
-
-	
-	uint16_t idx =0;
-	for(idx = 0; idx < csi_rs_pdu_rel13->num_bf_vector; ++idx)
-	{
-		if(!(pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->bf_vector[idx].csi_rs_resource_index, end)))
-			return 0;
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : HOW TO DECODE BF VALUE \n");
-		//pullarray16(ppReadPackedMsg, &csi_rs_pdu_rel13->bf_vector[idx].bf_vector, ??);
-	}
-	return 1;
-}
-
-static uint8_t unpack_dl_config_epdcch_params_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_epdcch_parameters_rel11_t* epdcch_params_rel11 = (nfapi_dl_config_epdcch_parameters_rel11_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_resource_assignment_flag, end) &&
-			pull16(ppReadPackedMsg, &epdcch_params_rel11->epdcch_id, end) &&
-			pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_start_symbol, end) &&
-			pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_num_prb, end) &&
-			pullarray8(ppReadPackedMsg, epdcch_params_rel11->epdcch_prb_index, NFAPI_MAX_EPDCCH_PRB, epdcch_params_rel11->epdcch_num_prb, end) &&
-			pull8(ppReadPackedMsg, &epdcch_params_rel11->bf_vector.subband_index, end) &&
-			pull8(ppReadPackedMsg, &epdcch_params_rel11->bf_vector.num_antennas, end) &&
-			pullarray16(ppReadPackedMsg, epdcch_params_rel11->bf_vector.bf_value, NFAPI_MAX_NUM_ANTENNAS, epdcch_params_rel11->bf_vector.num_antennas, end));
-}
-
-static uint8_t unpack_dl_config_epdcch_params_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_epdcch_parameters_rel13_t* epdcch_params_rel13 = (nfapi_dl_config_epdcch_parameters_rel13_t*)tlv;
-	
-	return ( pull8(ppReadPackedMsg, &epdcch_params_rel13->dwpts_symbols, end) &&
-			 pull8(ppReadPackedMsg, &epdcch_params_rel13->initial_lbt_sf, end));
-}
-
-static uint8_t unpack_dl_config_mpdcch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_mpdcch_pdu_rel13_t* mpdcch_params_rel13 = (nfapi_dl_config_mpdcch_pdu_rel13_t*)tlv;
-	
-	
-	return ( pull8(ppReadPackedMsg, &mpdcch_params_rel13->mpdcch_narrow_band, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->number_of_prb_pairs, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->resource_block_assignment, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->mpdcch_tansmission_type, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->start_symbol, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->ecce_index, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->aggregation_level, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->rnti_type, end) &&
-			 pull16(ppReadPackedMsg, &mpdcch_params_rel13->rnti, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->ce_mode, end) &&
-			 pull16(ppReadPackedMsg, &mpdcch_params_rel13->drms_scrambling_init, end) &&
-			 pull16(ppReadPackedMsg, &mpdcch_params_rel13->initial_transmission_sf_io, end) &&
-			 pull16(ppReadPackedMsg, &mpdcch_params_rel13->transmission_power, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->dci_format, end) &&
-			 pull16(ppReadPackedMsg, &mpdcch_params_rel13->resource_block_coding, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->mcs, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->pdsch_reptition_levels, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->redundancy_version, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->new_data_indicator, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->harq_process, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpmi_length, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpmi, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->pmi_flag, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->pmi, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->harq_resource_offset, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->dci_subframe_repetition_number, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpc, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->downlink_assignment_index_length, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->downlink_assignment_index, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->allocate_prach_flag, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->preamble_index, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->prach_mask_index, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->starting_ce_level, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->srs_request, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->antenna_ports_and_scrambling_identity_flag, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->antenna_ports_and_scrambling_identity, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->frequency_hopping_enabled_flag, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->paging_direct_indication_differentiation_flag, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->direct_indication, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->total_dci_length_including_padding, end) &&
-			 pull8(ppReadPackedMsg, &mpdcch_params_rel13->number_of_tx_antenna_ports, end) &&
-			 pullarray16(ppReadPackedMsg, mpdcch_params_rel13->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, mpdcch_params_rel13->number_of_tx_antenna_ports, end));
-}
-
-
-static uint8_t unpack_dl_config_nbch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_nbch_pdu_rel13_t* nbch_params_rel13 = (nfapi_dl_config_nbch_pdu_rel13_t*)tlv;
-	
-	return ( pull16(ppReadPackedMsg, &nbch_params_rel13->length, end) &&
-			 pull16(ppReadPackedMsg, (uint16_t *)&nbch_params_rel13->pdu_index, end) &&
-			 pull16(ppReadPackedMsg, &nbch_params_rel13->transmission_power, end) &&
-			 pull16(ppReadPackedMsg, &nbch_params_rel13->hyper_sfn_2_lsbs, end));
-}
-
-static uint8_t unpack_dl_config_npdcch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_npdcch_pdu_rel13_t* npdcch_params_rel13 = (nfapi_dl_config_npdcch_pdu_rel13_t*)tlv;
-	
-	return ( pull16(ppReadPackedMsg, &npdcch_params_rel13->length, end) &&
-			 pull16(ppReadPackedMsg, (uint16_t *)&npdcch_params_rel13->pdu_index, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->ncce_index, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->aggregation_level, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->start_symbol, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->rnti_type, end) &&
-			 pull16(ppReadPackedMsg, &npdcch_params_rel13->rnti, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->scrambling_reinitialization_batch_index, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->nrs_antenna_ports_assumed_by_the_ue, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->dci_format, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->scheduling_delay, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->resource_assignment, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->repetition_number, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->mcs, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->new_data_indicator, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->harq_ack_resource, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->npdcch_order_indication, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->starting_number_of_nprach_repetitions, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->subcarrier_indication_of_nprach, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->paging_direct_indication_differentation_flag, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->direct_indication, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->dci_subframe_repetition_number, end) &&
-			 pull8(ppReadPackedMsg, &npdcch_params_rel13->total_dci_length_including_padding, end));
-}
-
-static uint8_t unpack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_dl_config_ndlsch_pdu_rel13_t* ndlsch_params_rel13 = (nfapi_dl_config_ndlsch_pdu_rel13_t*)tlv;
-	
-	return ( pull16(ppReadPackedMsg, &ndlsch_params_rel13->length, end) &&
-			 pull16(ppReadPackedMsg, (uint16_t *)&ndlsch_params_rel13->pdu_index, end) &&
-			 pull8(ppReadPackedMsg, &ndlsch_params_rel13->start_symbol, end) &&
-			 pull8(ppReadPackedMsg, &ndlsch_params_rel13->rnti_type, end) &&
-			 pull16(ppReadPackedMsg, &ndlsch_params_rel13->rnti, end) &&
-			 pull16(ppReadPackedMsg, &ndlsch_params_rel13->resource_assignment, end) &&
-			 pull16(ppReadPackedMsg, &ndlsch_params_rel13->repetition_number, end) &&
-			 pull8(ppReadPackedMsg, &ndlsch_params_rel13->modulation, end) &&
-			 pull8(ppReadPackedMsg, &ndlsch_params_rel13->number_of_subframes_for_resource_assignment, end) &&
-			 pull8(ppReadPackedMsg, &ndlsch_params_rel13->scrambling_sequence_initialization_cinit, end) &&
-			 pull16(ppReadPackedMsg, &ndlsch_params_rel13->sf_idx, end) &&
-			 pull8(ppReadPackedMsg, &ndlsch_params_rel13->nrs_antenna_ports_assumed_by_the_ue, end));
-}
-
-
-static uint8_t unpack_dl_tti_request_body_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
-{
-	nfapi_nr_dl_tti_request_pdu_t* value = (nfapi_nr_dl_tti_request_pdu_t*)msg;
-
-	if(!(pull16(ppReadPackedMsg, &value->PDUSize, end) &&
-	 	 pull16(ppReadPackedMsg, &value->PDUType, end) ))
-		  return 0;
-
-
-	// first match the pdu type, then call the respective function
-	switch(value->PDUType)
-	{
-		case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
-		{
-			if(!(unpack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15,ppReadPackedMsg,end)))
-				return 0;
-		}
-		break;
-
-		case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
-		{
-			if(!(unpack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15,ppReadPackedMsg,end)))
-				return 0;
-		}
-		break;
-		case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
-		{
-			if(!(unpack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15,ppReadPackedMsg,end)))
-				return 0;
-		}
-		break;
-		case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
-		{
-			if(!(unpack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15,ppReadPackedMsg,end)))
-				return 0;
-		}
-		break;
-
-		default:
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType );
-		}
-		break;
-	}
-
-	return 1;
-}
-
-
-
-
-static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_dl_config_request_body_t* value = (nfapi_dl_config_request_body_t*)tlv;
-
-	if(!(pull8(ppReadPackedMsg, &value->number_pdcch_ofdm_symbols, end) &&
-		 pull8(ppReadPackedMsg, &value->number_dci, end) &&
-		 pull16(ppReadPackedMsg, &value->number_pdu, end) &&
-		 pull8(ppReadPackedMsg, &value->number_pdsch_rnti, end) &&
-		 pull16(ppReadPackedMsg, &value->transmission_power_pcfich, end)))
-		return 0;
-
-	if(value->number_pdu > NFAPI_DL_CONFIG_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of dl config pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_pdu, NFAPI_DL_CONFIG_MAX_PDU);
-		return 0;		
-	}
-
-	if(value->number_pdu)
-	{
-		value->dl_config_pdu_list = (nfapi_dl_config_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_dl_config_request_pdu_t) * value->number_pdu, config);
-		if(value->dl_config_pdu_list == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate dl config pdu list (count:%d)\n", __FUNCTION__, value->number_pdu);
-			return 0;
-		}
-	}
-	else
-	{
-		value->dl_config_pdu_list = 0;
-	}
-
-	uint16_t i;
-	uint16_t total_number_of_pdus = value->number_pdu;
-	for(i = 0; i < total_number_of_pdus; ++i)
-	{
-		nfapi_dl_config_request_pdu_t* pdu = &(value->dl_config_pdu_list[i]);
-		
-		if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) &&
-			 pull8(ppReadPackedMsg, &pdu->pdu_size, end)))
-			return 0;
-					
-		uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2;
-
-		if(packedPduEnd > end)
-		{
-			// pdu end of beyond buffer end
-			return 0;
-		}
-
-		switch(pdu->pdu_type)
-		{
-			case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel8, &unpack_dl_config_dci_dl_pdu_rel8_value},
-						{ NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel9, &unpack_dl_config_dci_dl_pdu_rel9_value},
-						{ NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel10, &unpack_dl_config_dci_dl_pdu_rel10_value},
-						{ NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel11, &unpack_dl_config_dci_dl_pdu_rel11_value},
-						{ NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel12, &unpack_dl_config_dci_dl_pdu_rel12_value},
-						{ NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel13, &unpack_dl_config_dci_dl_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_DL_CONFIG_BCH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG, &pdu->bch_pdu.bch_pdu_rel8, &unpack_dl_config_bch_pdu_rel8_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_DL_CONFIG_MCH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG, &pdu->mch_pdu.mch_pdu_rel8, &unpack_dl_config_mch_pdu_rel8_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel8, &unpack_dl_config_dlsch_pdu_rel8_value},
-						{ NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel9, &unpack_dl_config_dlsch_pdu_rel9_value},
-						{ NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel10, &unpack_dl_config_dlsch_pdu_rel10_value},
-						{ NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel11, &unpack_dl_config_dlsch_pdu_rel11_value},
-						{ NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel12, &unpack_dl_config_dlsch_pdu_rel12_value},
-						{ NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel13, &unpack_dl_config_dlsch_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_DL_CONFIG_PCH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG, &pdu->pch_pdu.pch_pdu_rel8, &unpack_dl_config_pch_pdu_rel8_value},
-						{ NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG, &pdu->pch_pdu.pch_pdu_rel13, &unpack_dl_config_pch_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_DL_CONFIG_PRS_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG, &pdu->prs_pdu.prs_pdu_rel9, &unpack_dl_config_prs_pdu_rel9_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel10, &unpack_dl_config_csi_rs_pdu_rel10_value},
-						{ NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel13, &unpack_dl_config_csi_rs_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel8, &unpack_dl_config_dci_dl_pdu_rel8_value},
-						{ NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel9, &unpack_dl_config_dci_dl_pdu_rel9_value},
-						{ NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel10, &unpack_dl_config_dci_dl_pdu_rel10_value},
-						{ NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel11, &unpack_dl_config_dci_dl_pdu_rel11_value},
-						{ NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel12, &unpack_dl_config_dci_dl_pdu_rel12_value},
-						{ NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel13, &unpack_dl_config_dci_dl_pdu_rel13_value},
-						{ NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG, &pdu->epdcch_pdu.epdcch_params_rel11, &unpack_dl_config_epdcch_params_rel11_value},
-						{ NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG, &pdu->epdcch_pdu.epdcch_params_rel13, &unpack_dl_config_epdcch_params_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG, &pdu->mpdcch_pdu.mpdcch_pdu_rel13, &unpack_dl_config_mpdcch_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_DL_CONFIG_NBCH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG, &pdu->nbch_pdu.nbch_pdu_rel13, &unpack_dl_config_nbch_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG, &pdu->npdcch_pdu.npdcch_pdu_rel13, &unpack_dl_config_npdcch_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				
-				}
-				break;
-			case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG, &pdu->ndlsch_pdu.ndlsch_pdu_rel13, &unpack_dl_config_ndlsch_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				
-				}
-				break;
-			default:
-				// Need to log an error
-				break;
-		}
-	}
-
-	return 1;
-}
-
-
-static uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t*)msg;
-
-	if (!(pull16(ppReadPackedMsg,&pNfapiMsg->SFN, end) &&
-		pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
-		pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nGroup, end) &&
-		pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nPDUs, end) &&
-		pullarray8(ppReadPackedMsg,pNfapiMsg->dl_tti_request_body.nUe ,256,pNfapiMsg->dl_tti_request_body.nGroup, end)
-		//pusharray8(pNfapiMsg->PduIdx[0] ,256,256, ppWritePackedMsg, end)
-		))
-			return 0;
-	
-	int arr[12];
-	for(int i=0;i<pNfapiMsg->dl_tti_request_body.nGroup;i++)
-	{
-		for(int j=0;j<pNfapiMsg->dl_tti_request_body.nUe[i];j++)
-		{
-			arr[j] = pNfapiMsg->dl_tti_request_body.PduIdx[i][j];
-		}
-		if(!(pullarrays32(ppReadPackedMsg,arr,12,pNfapiMsg->dl_tti_request_body.nUe[i], end)))
-		return 0;
-	}
-
-	for(int i=0;i<pNfapiMsg->dl_tti_request_body.nPDUs;i++)	
-	{
-		if(!unpack_dl_tti_request_body_value(ppReadPackedMsg, end, &pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i]))
-		return 0;
-	}
-
-return 1;
-}
-
-
-static uint8_t unpack_ul_tti_request_prach_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nr_prach_pdu_t* prach_pdu = (nfapi_nr_prach_pdu_t*)tlv;
-
-	return(
-	pull16(ppReadPackedMsg, &prach_pdu->phys_cell_id, end) &&
-	pull8(ppReadPackedMsg, &prach_pdu->num_prach_ocas, end) &&
-	pull8(ppReadPackedMsg, &prach_pdu->prach_format, end) &&
-	pull8(ppReadPackedMsg, &prach_pdu->num_ra, end) &&
-	pull8(ppReadPackedMsg, &prach_pdu->prach_start_symbol, end) &&
-	pull16(ppReadPackedMsg, &prach_pdu->num_cs, end)
-	// TODO: ignoring beamforming tlv for now
-	);
-}
-
-
-static uint8_t unpack_ul_tti_request_pucch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nr_pucch_pdu_t* pucch_pdu = (nfapi_nr_pucch_pdu_t*)tlv;
-	
-	return(
-		pull16(ppReadPackedMsg, &pucch_pdu->rnti, end) &&
-		pull32(ppReadPackedMsg, &pucch_pdu->handle, end) &&
-		pull16(ppReadPackedMsg, &pucch_pdu->bwp_size, end) &&
-		pull16(ppReadPackedMsg, &pucch_pdu->bwp_start, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->subcarrier_spacing, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->cyclic_prefix, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->format_type, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->multi_slot_tx_indicator, end) &&
-		pull16(ppReadPackedMsg, &pucch_pdu->prb_start, end) &&
-		pull16(ppReadPackedMsg, &pucch_pdu->prb_size, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->start_symbol_index, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->nr_of_symbols, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->freq_hop_flag, end) &&
-		pull16(ppReadPackedMsg, &pucch_pdu->second_hop_prb, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->group_hop_flag, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->sequence_hop_flag, end) &&
-		pull16(ppReadPackedMsg, &pucch_pdu->hopping_id, end) &&
-		pull16(ppReadPackedMsg, &pucch_pdu->initial_cyclic_shift, end) &&
-		pull16(ppReadPackedMsg, &pucch_pdu->data_scrambling_id, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->time_domain_occ_idx, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_idx, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_len, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->add_dmrs_flag, end) &&
-		pull16(ppReadPackedMsg, &pucch_pdu->dmrs_scrambling_id, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->dmrs_cyclic_shift, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->sr_flag, end) &&
-		pull8(ppReadPackedMsg, &pucch_pdu->bit_len_harq, end) &&
-		pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part1, end) &&
-		pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part2, end) 
-		// TODO: ignoring beamforming tlv for now
-	);
-}
-
-
-static uint8_t unpack_ul_tti_request_pusch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nr_pusch_pdu_t* pusch_pdu = (nfapi_nr_pusch_pdu_t*)tlv;
-	
-	if (!(
-	pull16(ppReadPackedMsg, &pusch_pdu->pdu_bit_map, end) &&
-	pull16(ppReadPackedMsg, &pusch_pdu->rnti, end) &&
-	pull32(ppReadPackedMsg, &pusch_pdu->handle, end) &&
-	pull16(ppReadPackedMsg, &pusch_pdu->bwp_size, end) &&
-	pull16(ppReadPackedMsg, &pusch_pdu->bwp_start, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->subcarrier_spacing, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->cyclic_prefix, end) &&
-	pull16(ppReadPackedMsg, &pusch_pdu->target_code_rate,  end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order,  end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->mcs_index,  end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end) &&
-	pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end) &&
-	pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end) &&
-	pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->scid, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->num_dmrs_cdm_grps_no_data, end) &&
-	pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc,end) &&
-	pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) &&
-	pull16(ppReadPackedMsg, &pusch_pdu->rb_start, end) &&
-	pull16(ppReadPackedMsg, &pusch_pdu->rb_size, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->vrb_to_prb_mapping, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->frequency_hopping, end) &&
-	pull16(ppReadPackedMsg, &pusch_pdu->tx_direct_current_location, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->uplink_frequency_shift_7p5khz, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->start_symbol_index, end) &&
-	pull8(ppReadPackedMsg, &pusch_pdu->nr_of_symbols, end) 
-	// TODO: ignoring beamforming tlv for now 
-	))
-		return 0;
-
-
-	//Pack Optional Data only included if indicated in pduBitmap
-	switch(pusch_pdu->pdu_bit_map){
-		case PUSCH_PDU_BITMAP_PUSCH_DATA:
-		{
-			// pack optional TLVs
-			return(
-				pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.rv_index, end) &&
-				pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.harq_process_id, end) &&
-				pull32(ppReadPackedMsg, &pusch_pdu->pusch_data.tb_size, end) &&
-				pull16(ppReadPackedMsg, &pusch_pdu->pusch_data.num_cb, end) &&
-				pullarray8(ppReadPackedMsg, pusch_pdu->pusch_data.cb_present_and_position,1,1,end)
-			);
-		}
-		break;
-
-		case PUSCH_PDU_BITMAP_PUSCH_UCI:
-		{
-			return(
-				pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.harq_ack_bit_length, end) &&
-				pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part1_bit_length, end) &&
-				pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part2_bit_length, end) &&
-				pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.alpha_scaling, end) &&
-				pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_harq_ack, end) &&
-				pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi1, end) &&
-				pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi2, end)
-			);
-		}
-		break;
-
-		case PUSCH_PDU_BITMAP_PUSCH_PTRS:
-		{
-			return(
-				pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.num_ptrs_ports, end) &&
-				pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_dmrs_port, end) &&
-+               pull16(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_port_index, end) &&
-+               pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset, end) &&
-				pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_time_density, end) &&
-				pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_freq_density, end) &&
-				pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ul_ptrs_power, end)
-			);
-		}
-		break;
-
-		case PUSCH_PDU_BITMAP_DFTS_OFDM:
-		{
-			return(
-				pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_group_number, end) &&
-				pull16(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_sequence_number, end) &&
-				pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, end) &&
-				pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, end)
-			);
-		}
-		break;
-
-		default:
-		{
-			NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map );
-		}
-	}
-
-	return 1;
-}
-
-
-static uint8_t unpack_ul_tti_request_srs_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nr_srs_pdu_t* srs_pdu = (nfapi_nr_srs_pdu_t*)tlv;
-	
-	return(
-		pull16(ppReadPackedMsg, &srs_pdu->rnti, end) &&
-		pull32(ppReadPackedMsg, &srs_pdu->handle, end) &&
-		pull16(ppReadPackedMsg, &srs_pdu->bwp_size, end) &&
-		pull16(ppReadPackedMsg, &srs_pdu->bwp_start, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->subcarrier_spacing, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->cyclic_prefix, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->num_ant_ports, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->num_symbols,  end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->num_repetitions, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->time_start_position, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->config_index, end) &&
-		pull16(ppReadPackedMsg, &srs_pdu->sequence_id, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->bandwidth_index, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->comb_size, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->comb_offset, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->cyclic_shift, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->frequency_position, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->frequency_shift, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->frequency_hopping, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->group_or_sequence_hopping, end) &&
-		pull8(ppReadPackedMsg, &srs_pdu->resource_type, end) &&
-		pull16(ppReadPackedMsg, &srs_pdu->t_srs, end) &&
-		pull16(ppReadPackedMsg, &srs_pdu->t_offset, end) 
-		// TODO: ignoring beamforming tlv for now
-	);
-}
-
-
-static uint8_t unpack_ul_tti_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
-{
-	nfapi_nr_ul_tti_request_number_of_pdus_t* pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_pdus_t*)msg;
-
-	if(!(pull16(ppReadPackedMsg, &pNfapiMsg->pdu_size, end) &&
-	 	 pull16(ppReadPackedMsg, &pNfapiMsg->pdu_type, end) ))
-		  return 0;
-
-
-	// first natch the pdu type, then call the respective function
-	switch(pNfapiMsg->pdu_type)
-	{
-
-		case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
-		{
-			if(!unpack_ul_tti_request_prach_pdu(&pNfapiMsg->prach_pdu, ppReadPackedMsg, end))
-				return 0;
-		}
-		break;
-
-		case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
-		{
-			if(!unpack_ul_tti_request_pucch_pdu(&pNfapiMsg->pucch_pdu, ppReadPackedMsg, end))
-				return 0;
-		}
-		break;
-		
-		case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
-		{
-			if(!unpack_ul_tti_request_pusch_pdu(&pNfapiMsg->pusch_pdu, ppReadPackedMsg, end))
-				return 0;
-		}
-		break;
-
-		case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
-		{
-			if(!unpack_ul_tti_request_srs_pdu(&pNfapiMsg->srs_pdu, ppReadPackedMsg, end))
-				return 0;
-		}
-		break;
-
-		default:
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", pNfapiMsg->pdu_type );
-		}
-		break;
-
-
-	}
-
-	return 1;
-}
-
-
-static uint8_t unpack_ul_tti_groups_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
-{
-	nfapi_nr_ul_tti_request_number_of_groups_t* pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_groups_t*)msg;
-
-	    if(!pull8(ppReadPackedMsg, &pNfapiMsg->n_ue, end))
-      return 0;
-       for (int i = 0; i < pNfapiMsg->n_ue; i++)
-       {
-               if(!pull8(ppReadPackedMsg, &pNfapiMsg->ue_list[i].pdu_idx ,end) )
-               return 0;
-       }
-       return 1; 
-}
-
-
-static uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t*)msg;
-
-	if (!( 
-		pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) &&
-		pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
-		pull8(ppReadPackedMsg, &pNfapiMsg->n_pdus, end) &&
-		pull8(ppReadPackedMsg, &pNfapiMsg->n_group, end) &&
-		pull8(ppReadPackedMsg, &pNfapiMsg->rach_present, end) &&
-		pull8(ppReadPackedMsg, &pNfapiMsg->n_ulcch, end) &&
-		pull8(ppReadPackedMsg, &pNfapiMsg->n_ulsch, end) ))
-			return 0;
-
-	for(int i=0; i< pNfapiMsg->n_pdus; i++)
-	{
-		if (!unpack_ul_tti_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdus_list[i]))
-			return 0;
-	}
-
-	for(int i=0; i< pNfapiMsg->n_group; i++)
-	{
-		if (!unpack_ul_tti_groups_list_value(ppReadPackedMsg, end, &pNfapiMsg->groups_list[i]))
-			return 0;
-	}
-
-	return 1;
-}
-
-
-
-static uint8_t unpack_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, &unpack_dl_config_request_body_value},
-	};
-
-	return ( pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			 unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_ul_config_ulsch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-
-
-	
-	nfapi_ul_config_ulsch_pdu_rel8_t* ulsch_pdu_rel8 = (nfapi_ul_config_ulsch_pdu_rel8_t*)tlv;
-	
-	return (pull32(ppReadPackedMsg, &ulsch_pdu_rel8->handle, end) &&
-			pull16(ppReadPackedMsg, &ulsch_pdu_rel8->size, end) &&
-			pull16(ppReadPackedMsg, &ulsch_pdu_rel8->rnti, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel8->resource_block_start, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel8->number_of_resource_blocks, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel8->modulation_type, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel8->cyclic_shift_2_for_drms, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel8->frequency_hopping_enabled_flag, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel8->frequency_hopping_bits, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel8->new_data_indication, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel8->redundancy_version, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel8->harq_process_number, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel8->ul_tx_mode, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel8->current_tx_nb, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel8->n_srs, end ));
-}
-
-static uint8_t unpack_ul_config_ulsch_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ulsch_pdu_rel10_t* ulsch_pdu_rel10 = (nfapi_ul_config_ulsch_pdu_rel10_t*)tlv; 
-	
-	return (pull8(ppReadPackedMsg, &ulsch_pdu_rel10->resource_allocation_type, end) &&
-			pull32(ppReadPackedMsg, &ulsch_pdu_rel10->resource_block_coding, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel10->transport_blocks, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel10->transmission_scheme, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel10->number_of_layers, end) &
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel10->codebook_index, end) &&
-			pull8(ppReadPackedMsg, &ulsch_pdu_rel10->disable_sequence_hopping_flag, end));
-}
-static uint8_t unpack_ul_config_ulsch_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ulsch_pdu_rel11_t* ulsch_pdu_rel11 = (nfapi_ul_config_ulsch_pdu_rel11_t*)tlv;
-	
-	return ( pull8(ppReadPackedMsg,	&ulsch_pdu_rel11->virtual_cell_id_enabled_flag, end) &&
-			 pull16(ppReadPackedMsg, &ulsch_pdu_rel11->npusch_identity, end) &&
-			 pull8(ppReadPackedMsg,	&ulsch_pdu_rel11->dmrs_config_flag, end) &&
-			 pull16(ppReadPackedMsg, &ulsch_pdu_rel11->ndmrs_csh_identity, end));
-}
-static uint8_t unpack_ul_config_ulsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ulsch_pdu_rel13_t* ulsch_pdu_rel13 = (nfapi_ul_config_ulsch_pdu_rel13_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg,  &ulsch_pdu_rel13->ue_type, end) &&
-			pull16(ppReadPackedMsg, &ulsch_pdu_rel13->total_number_of_repetitions, end) &&
-			pull16(ppReadPackedMsg, &ulsch_pdu_rel13->repetition_number, end) &&
-			pull16(ppReadPackedMsg, &ulsch_pdu_rel13->initial_transmission_sf_io, end) &&
-			pull8(ppReadPackedMsg,  &ulsch_pdu_rel13->empty_symbols_due_to_re_tunning, end));
-}
-static uint8_t unpack_ul_config_cqi_ri_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_cqi_ri_information_rel8_t* cqi_ri_info_rel8 = (nfapi_ul_config_cqi_ri_information_rel8_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &cqi_ri_info_rel8->dl_cqi_pmi_size_rank_1, end) &&
-			pull8(ppReadPackedMsg, &cqi_ri_info_rel8->dl_cqi_pmi_size_rank_greater_1, end) &&
-			pull8(ppReadPackedMsg, &cqi_ri_info_rel8->ri_size, end) &&
-			pull8(ppReadPackedMsg, &cqi_ri_info_rel8->delta_offset_cqi, end) &&
-			pull8(ppReadPackedMsg, &cqi_ri_info_rel8->delta_offset_ri, end));
-}
-
-static uint8_t unpack_ul_config_cqi_ri_info_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_cqi_ri_information_rel9_t* cqi_ri_info_rel9 = (nfapi_ul_config_cqi_ri_information_rel9_t*)tlv;
-	
-	if(!(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->report_type, end) &&
-		 pull8(ppReadPackedMsg, &cqi_ri_info_rel9->delta_offset_cqi, end) &&
-		 pull8(ppReadPackedMsg, &cqi_ri_info_rel9->delta_offset_ri, end)))
-		return 0;
-
-	switch(cqi_ri_info_rel9->report_type)
-	{
-		case NFAPI_CSI_REPORT_TYPE_PERIODIC:
-			{
-				if(!(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size, end) &&
-					 pull8(ppReadPackedMsg, &cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.control_type, end)))
-					return 0;
-			}
-			break;
-		case NFAPI_CSI_REPORT_TYPE_APERIODIC:
-			{
-				if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc, end) ==0)
-					return 0;
-					
-				uint8_t i;
-				for(i = 0; i < cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc; ++i)
-				{
-					if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size, end) == 0)
-						return 0;
-
-                                        uint8_t j;
-                                        for(j = 0; j < 8; ++j)
-					{
-						if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size[j], end) == 0)
-							return 0;
-					}
-				}
-			}
-			break;
-		default:
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel9->report_type );
-				return 0;
-			}
-			break;
-	};
-	return 1;
-}
-
-// NOTE : This function is a little unconventional as we uese the side to
-// determine the report type
-static uint8_t unpack_ul_config_cqi_ri_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_cqi_ri_information_rel13_t* cqi_ri_info_rel13 = (nfapi_ul_config_cqi_ri_information_rel13_t*)tlv;
-	if(cqi_ri_info_rel13->tl.length == 0)
-	{
-		cqi_ri_info_rel13->report_type = NFAPI_CSI_REPORT_TYPE_APERIODIC;
-	}
-	else
-	{
-		cqi_ri_info_rel13->report_type = NFAPI_CSI_REPORT_TYPE_PERIODIC;
-		if(pull16(ppReadPackedMsg, &cqi_ri_info_rel13->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2, end) == 0)
-			return 0;
-	}
-	return 1;
-}
-static uint8_t unpack_ul_config_cqi_init_tx_params_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_initial_transmission_parameters_rel8_t* init_tx_params_rel8 = (nfapi_ul_config_initial_transmission_parameters_rel8_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &init_tx_params_rel8->n_srs_initial, end) &&
-			pull8(ppReadPackedMsg, &init_tx_params_rel8->initial_number_of_resource_blocks, end));
-}
-static uint8_t unpack_ul_config_ulsch_harq_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ulsch_harq_information_rel10_t* harq_info_rel10 = (nfapi_ul_config_ulsch_harq_information_rel10_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &harq_info_rel10->harq_size, end) &&
-			pull8(ppReadPackedMsg, &harq_info_rel10->delta_offset_harq, end) &&
-			pull8(ppReadPackedMsg, &harq_info_rel10->ack_nack_mode, end));
-}
-
-static uint8_t unpack_ul_config_ulsch_harq_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ulsch_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_ulsch_harq_information_rel13_t*)tlv;
-	
-	return (pull16(ppReadPackedMsg, &harq_info_rel13->harq_size_2, end) &&
-			pull8(ppReadPackedMsg, &harq_info_rel13->delta_offset_harq_2, end));
-}
-
-static uint8_t unpack_ul_config_ue_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ue_information_rel8_t* ue_info_rel8 = (nfapi_ul_config_ue_information_rel8_t*)tlv;
-	
-	return (pull32(ppReadPackedMsg, &ue_info_rel8->handle, end) &&
-			pull16(ppReadPackedMsg, (uint16_t *)&ue_info_rel8->rnti, end));
-}
-static uint8_t unpack_ul_config_ue_info_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ue_information_rel11_t* ue_info_rel11 = (nfapi_ul_config_ue_information_rel11_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &ue_info_rel11->virtual_cell_id_enabled_flag, end) &&
-			pull16(ppReadPackedMsg, &ue_info_rel11->npusch_identity, end));
-}
-static uint8_t unpack_ul_config_ue_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_ue_information_rel13_t* ue_info_rel13 = (nfapi_ul_config_ue_information_rel13_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &ue_info_rel13->ue_type, end) &&
-			pull8(ppReadPackedMsg, &ue_info_rel13->empty_symbols, end) &&
-			pull16(ppReadPackedMsg, &ue_info_rel13->total_number_of_repetitions, end) &&
-			pull16(ppReadPackedMsg, &ue_info_rel13->repetition_number, end));
-}
-
-static uint8_t unpack_ul_config_cqi_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_cqi_information_rel8_t* cqi_info_rel8 = (nfapi_ul_config_cqi_information_rel8_t*)tlv;
-	
-	return ( pull16(ppReadPackedMsg, &cqi_info_rel8->pucch_index, end) &&
-			 pull8(ppReadPackedMsg, &cqi_info_rel8->dl_cqi_pmi_size, end));
-}
-static uint8_t unpack_ul_config_cqi_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_cqi_information_rel10_t* cqi_info_rel10 = (nfapi_ul_config_cqi_information_rel10_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &cqi_info_rel10->number_of_pucch_resource, end) &&
-			pull16(ppReadPackedMsg, &cqi_info_rel10->pucch_index_p1, end));
-}
-static uint8_t unpack_ul_config_cqi_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_cqi_information_rel13_t* cqi_info_rel13 = (nfapi_ul_config_cqi_information_rel13_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &cqi_info_rel13->csi_mode, end) &&
-			pull16(ppReadPackedMsg, &cqi_info_rel13->dl_cqi_pmi_size_2, end) &&
-			pull8(ppReadPackedMsg, &cqi_info_rel13->starting_prb, end) &&
-			pull8(ppReadPackedMsg, &cqi_info_rel13->n_prb, end) &&
-			pull8(ppReadPackedMsg, &cqi_info_rel13->cdm_index, end) &&
-			pull8(ppReadPackedMsg, &cqi_info_rel13->n_srs, end));
-}
-		
-static uint8_t unpack_ul_config_sr_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_sr_information_rel8_t* sr_info_rel8 = (nfapi_ul_config_sr_information_rel8_t*)tlv;
-	
-	return ( pull16(ppReadPackedMsg, &sr_info_rel8->pucch_index, end));
-}
-
-static uint8_t unpack_ul_config_sr_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_sr_information_rel10_t* sr_info_rel10 = (nfapi_ul_config_sr_information_rel10_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &sr_info_rel10->number_of_pucch_resources, end) &&
-			pull16(ppReadPackedMsg, &sr_info_rel10->pucch_index_p1, end));
-}
-
-static uint8_t unpack_ul_config_harq_info_rel10_tdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_harq_information_rel10_tdd_t* harq_info_tdd_rel10 = (nfapi_ul_config_harq_information_rel10_tdd_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &harq_info_tdd_rel10->harq_size, end) &&
-			pull8(ppReadPackedMsg, &harq_info_tdd_rel10->ack_nack_mode, end) &&
-			pull8(ppReadPackedMsg, &harq_info_tdd_rel10->number_of_pucch_resources, end) &&
-			pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_0, end) &&
-			pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_1, end) &&
-			pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_2, end) &&
-			pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_3, end));
-}
-
-static uint8_t unpack_ul_config_harq_info_rel8_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_harq_information_rel8_fdd_t* harq_info_fdd_rel8 = (nfapi_ul_config_harq_information_rel8_fdd_t*)tlv;
-	
-	return (pull16(ppReadPackedMsg, &harq_info_fdd_rel8->n_pucch_1_0, end) &&
-			pull8(ppReadPackedMsg, &harq_info_fdd_rel8->harq_size, end));
-}
-
-static uint8_t unpack_ul_config_harq_info_rel9_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_harq_information_rel9_fdd_t* harq_info_fdd_rel9 = (nfapi_ul_config_harq_information_rel9_fdd_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &harq_info_fdd_rel9->harq_size, end) &&
-			pull8(ppReadPackedMsg, &harq_info_fdd_rel9->ack_nack_mode, end) &&
-			pull8(ppReadPackedMsg, &harq_info_fdd_rel9->number_of_pucch_resources, end) &&
-			pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_0, end) &&
-			pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_1, end) &&
-			pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_2, end) &&
-			pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_3, end));
-}
-
-static uint8_t unpack_ul_config_harq_info_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_harq_information_rel11_t* harq_info_rel11 = (nfapi_ul_config_harq_information_rel11_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &harq_info_rel11->num_ant_ports, end) &&
-			pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_0, end) &&
-			pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_1, end) &&
-			pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_2, end) &&
-			pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_3, end));
-}
-
-static uint8_t unpack_ul_config_harq_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_harq_information_rel13_t*)tlv;
-	
-	return (pull16(ppReadPackedMsg, &harq_info_rel13->harq_size_2, end) &&
-			pull8(ppReadPackedMsg, &harq_info_rel13->starting_prb, end) &&
-			pull8(ppReadPackedMsg, &harq_info_rel13->n_prb, end) &&
-			pull8(ppReadPackedMsg, &harq_info_rel13->cdm_index, end) &&
-			pull8(ppReadPackedMsg, &harq_info_rel13->n_srs, end));
-}
-
-
-static uint8_t unpack_ul_config_srs_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_srs_pdu_rel8_t* srs_pdu_rel8 = (nfapi_ul_config_srs_pdu_rel8_t*)tlv;
-	
-	return (pull32(ppReadPackedMsg, &srs_pdu_rel8->handle, end) &&
-			pull16(ppReadPackedMsg, &srs_pdu_rel8->size, end) &&
-			pull16(ppReadPackedMsg, &srs_pdu_rel8->rnti, end) &&
-			pull8(ppReadPackedMsg, &srs_pdu_rel8->srs_bandwidth, end) &&
-			pull8(ppReadPackedMsg, &srs_pdu_rel8->frequency_domain_position, end) &&
-			pull8(ppReadPackedMsg, &srs_pdu_rel8->srs_hopping_bandwidth, end) &&
-			pull8(ppReadPackedMsg, &srs_pdu_rel8->transmission_comb, end) &&
-			pull16(ppReadPackedMsg, &srs_pdu_rel8->i_srs, end) &&
-			pull8(ppReadPackedMsg, &srs_pdu_rel8->sounding_reference_cyclic_shift, end));
-}
-
-static uint8_t unpack_ul_config_srs_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_srs_pdu_rel10_t* srs_pdu_rel10 = (nfapi_ul_config_srs_pdu_rel10_t*)tlv;
-	return pull8(ppReadPackedMsg, &srs_pdu_rel10->antenna_port, end);
-}
-
-static uint8_t unpack_ul_config_srs_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_srs_pdu_rel13_t* srs_pdu_rel13 = (nfapi_ul_config_srs_pdu_rel13_t*)tlv;
-
-	return (pull8(ppReadPackedMsg, &srs_pdu_rel13->number_of_combs, end));
-}
-
-static uint8_t unpack_ul_nb_harq_info_rel13_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_nb_harq_information_rel13_fdd_t* nb_harq_info_fdd_rel13 = (nfapi_ul_config_nb_harq_information_rel13_fdd_t*)tlv;
-
-	return (pull8(ppReadPackedMsg, &nb_harq_info_fdd_rel13->harq_ack_resource, end));
-}
-
-static uint8_t unpack_ul_config_nulsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_nulsch_pdu_rel13_t* nulsch_pdu_rel13 = (nfapi_ul_config_nulsch_pdu_rel13_t*)tlv;
-
-	if(!(pull8(ppReadPackedMsg, &nulsch_pdu_rel13->nulsch_format, end) && 
-		 pull32(ppReadPackedMsg, &nulsch_pdu_rel13->handle, end) && 
-		 pull16(ppReadPackedMsg, &nulsch_pdu_rel13->size, end) && 
-		 pull16(ppReadPackedMsg, &nulsch_pdu_rel13->rnti, end) && 
-		 pull8(ppReadPackedMsg, &nulsch_pdu_rel13->subcarrier_indication, end) && 
-		 pull8(ppReadPackedMsg, &nulsch_pdu_rel13->resource_assignment, end) && 
-		 pull8(ppReadPackedMsg, &nulsch_pdu_rel13->mcs, end) && 
-		 pull8(ppReadPackedMsg, &nulsch_pdu_rel13->redudancy_version, end) && 
-		 pull8(ppReadPackedMsg, &nulsch_pdu_rel13->repetition_number, end) && 
-		 pull8(ppReadPackedMsg, &nulsch_pdu_rel13->new_data_indication, end) && 
-		 pull8(ppReadPackedMsg, &nulsch_pdu_rel13->n_srs, end) && 
-		 pull16(ppReadPackedMsg, &nulsch_pdu_rel13->scrambling_sequence_initialization_cinit, end) && 
-		 pull16(ppReadPackedMsg, &nulsch_pdu_rel13->sf_idx, end)))
-		return 0;
-		
-	unpack_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel8, &unpack_ul_config_ue_info_rel8_value},
-		{ NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel11, &unpack_ul_config_ue_info_rel11_value},
-		{ NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel13, &unpack_ul_config_ue_info_rel13_value},
-		{ NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG, &nulsch_pdu_rel13->nb_harq_information.nb_harq_information_rel13_fdd, &unpack_ul_nb_harq_info_rel13_fdd_value},
-	};
-
-	return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, 0, 0);		
-}
-
-static uint8_t unpack_ul_config_nrach_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_config_nrach_pdu_rel13_t* nrach_pdu_rel13 = (nfapi_ul_config_nrach_pdu_rel13_t*)tlv;
-
-	return (pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_0, end) &&
-			pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_1, end) &&
-			pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_2, end));
-}
-
-
-static uint8_t unpack_ul_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	#define UL_CONFIG_ULSCH_PDU_UNPACK_FNS(_pdu) \
-		{ NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG, &_pdu.ulsch_pdu_rel8, &unpack_ul_config_ulsch_pdu_rel8_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG, &_pdu.ulsch_pdu_rel10, &unpack_ul_config_ulsch_pdu_rel10_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG, &_pdu.ulsch_pdu_rel11, &unpack_ul_config_ulsch_pdu_rel11_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG, &_pdu.ulsch_pdu_rel13, &unpack_ul_config_ulsch_pdu_rel13_value}, 
-
-	#define UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(_pdu) \
-		{ NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG, &_pdu.cqi_ri_information_rel8, &unpack_ul_config_cqi_ri_info_rel8_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG, &_pdu.cqi_ri_information_rel9, &unpack_ul_config_cqi_ri_info_rel9_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG, &_pdu.cqi_ri_information_rel13, &unpack_ul_config_cqi_ri_info_rel13_value},
-
-	#define UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(_pdu) \
-		{ NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG, &_pdu.harq_information_rel10, &unpack_ul_config_ulsch_harq_info_rel10_value},\
-		{ NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG, &_pdu.harq_information_rel13, &unpack_ul_config_ulsch_harq_info_rel13_value},
-
-	#define UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(_pdu) \
-		{ NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG, &_pdu.initial_transmission_parameters_rel8, &unpack_ul_config_cqi_init_tx_params_rel8_value},
-
-	#define UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(_pdu) \
-		{ NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &_pdu.ue_information_rel8, &unpack_ul_config_ue_info_rel8_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &_pdu.ue_information_rel11, &unpack_ul_config_ue_info_rel11_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &_pdu.ue_information_rel13, &unpack_ul_config_ue_info_rel13_value},
-
-	#define UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(_pdu) \
-		{ NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG, &_pdu.cqi_information_rel8, &unpack_ul_config_cqi_info_rel8_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG, &_pdu.cqi_information_rel10, &unpack_ul_config_cqi_info_rel10_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG, &_pdu.cqi_information_rel13, &unpack_ul_config_cqi_info_rel13_value},
-						
-	#define UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(_pdu) \
-		{ NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG, &_pdu.sr_information_rel8, &unpack_ul_config_sr_info_rel8_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG, &_pdu.sr_information_rel10, &unpack_ul_config_sr_info_rel10_value},
-
-	#define UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(_pdu) \
-		{ NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG, &_pdu.harq_information_rel10_tdd, &unpack_ul_config_harq_info_rel10_tdd_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG, &_pdu.harq_information_rel8_fdd, &unpack_ul_config_harq_info_rel8_fdd_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG, &_pdu.harq_information_rel9_fdd, &unpack_ul_config_harq_info_rel9_fdd_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG, &_pdu.harq_information_rel11, &unpack_ul_config_harq_info_rel11_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG, &_pdu.harq_information_rel13, &unpack_ul_config_harq_info_rel13_value},
-
-	#define UL_CONFIG_SRS_PDU_UNPACK_FNS(_pdu) \
-		{ NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG, &_pdu.srs_pdu_rel8, &unpack_ul_config_srs_pdu_rel8_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG, &_pdu.srs_pdu_rel10, &unpack_ul_config_srs_pdu_rel10_value}, \
-		{ NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG, &_pdu.srs_pdu_rel13, &unpack_ul_config_srs_pdu_rel13_value},
-		
-	#define UL_CONFIG_NULSCH_PDU_UNPACK_FNS(_pdu) \
-		{ NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG, &_pdu.nulsch_pdu_rel13, &unpack_ul_config_nulsch_pdu_rel13_value},		
-
-	#define UL_CONFIG_NRACH_PDU_UNPACK_FNS(_pdu) \
-		{ NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG, &_pdu.nrach_pdu_rel13, &unpack_ul_config_nrach_pdu_rel13_value},		
-
-
-	nfapi_ul_config_request_body_t* value = (nfapi_ul_config_request_body_t*)tlv;
-
-	if(!(pull8(ppReadPackedMsg, &value->number_of_pdus, end) &&
-		 pull8(ppReadPackedMsg, &value->rach_prach_frequency_resources, end) &&
-		 pull8(ppReadPackedMsg, &value->srs_present, end)))
-		return 0;
-
-	if(value->number_of_pdus > NFAPI_UL_CONFIG_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of ul config pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_UL_CONFIG_MAX_PDU);
-		return 0;		
-	}
-
-	if(value->number_of_pdus > 0)
-	{
-		value->ul_config_pdu_list = (nfapi_ul_config_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_ul_config_request_pdu_t) * value->number_of_pdus, config);
-
-		if(value->ul_config_pdu_list == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate ul config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus);
-			return 0;
-		}
-	}
-	else
-	{
-		value->ul_config_pdu_list = 0;
-	}
-
-
-	uint16_t i;
-	uint16_t total_number_of_pdus = value->number_of_pdus;
-	for(i = 0; i < total_number_of_pdus; ++i)
-	{
-		nfapi_ul_config_request_pdu_t* pdu = &(value->ul_config_pdu_list[i]);
-		
-		if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) &&
-			 pull8(ppReadPackedMsg, &pdu->pdu_size, end)))
-			return 0;
-					
-		uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2;
-
-		if(packedPduEnd > end)
-		{
-			// pdu end is past buffer end
-			return 0;
-		}
-
-		switch(pdu->pdu_type)
-		{
-			case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_pdu)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-
-			case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.ulsch_pdu)
-						UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.cqi_ri_information)
-						UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.initial_transmission_parameters)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_harq_pdu.ulsch_pdu)
-						UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(pdu->ulsch_harq_pdu.harq_information)
-						UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_harq_pdu.initial_transmission_parameters)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu)
-						UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information)
-						UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.harq_information)
-						UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_pdu.ue_information)
-						UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_pdu.cqi_information)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_sr_pdu.ue_information)
-						UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_sr_pdu.sr_information)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_harq_pdu.ue_information)
-						UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_harq_pdu.harq_information)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.ue_information)
-						UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.sr_information)
-						UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.harq_information)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.ue_information)
-						UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.cqi_information)
-						UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.harq_information)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.ue_information)
-						UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.cqi_information)
-						UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.sr_information)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.ue_information)
-						UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.cqi_information)
-						UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.sr_information)
-						UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.harq_information)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_SRS_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_SRS_PDU_UNPACK_FNS(pdu->srs_pdu)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->harq_buffer_pdu.ue_information)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_uci_csi_pdu.ulsch_pdu)
-						UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->ulsch_uci_csi_pdu.csi_information)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_uci_harq_pdu.ulsch_pdu)
-						UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->ulsch_uci_harq_pdu.harq_information)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.ulsch_pdu)
-						UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.csi_information)
-						UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.harq_information)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_NULSCH_PDU_UNPACK_FNS(pdu->nulsch_pdu)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;	
-			case NFAPI_UL_CONFIG_NRACH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						UL_CONFIG_NRACH_PDU_UNPACK_FNS(pdu->nrach_pdu)
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;						
-		}
-	}
-	return 1;
-}
-
-
-static uint8_t unpack_ul_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_UL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->ul_config_request_body, &unpack_ul_config_request_body_value},
-	};
-
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_hi_dci0_hi_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_hi_pdu_rel8_t* hi_pdu_rel8 = (nfapi_hi_dci0_hi_pdu_rel8_t*)tlv;
-	
-	return( pull8(ppReadPackedMsg, &hi_pdu_rel8->resource_block_start, end) &&
-			pull8(ppReadPackedMsg, &hi_pdu_rel8->cyclic_shift_2_for_drms, end) &&
-			pull8(ppReadPackedMsg, &hi_pdu_rel8->hi_value, end) &&
-			pull8(ppReadPackedMsg, &hi_pdu_rel8->i_phich, end) &&
-			pull16(ppReadPackedMsg, &hi_pdu_rel8->transmission_power, end));
-}
-
-static uint8_t unpack_hi_dci0_hi_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_hi_pdu_rel10_t* hi_pdu_rel10 = (nfapi_hi_dci0_hi_pdu_rel10_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &hi_pdu_rel10->flag_tb2, end) &&
-			pull8(ppReadPackedMsg, &hi_pdu_rel10->hi_value_2, end));
-}
-
-static uint8_t unpack_hi_dci0_dci_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_dci_pdu_rel8_t* dci_pdu_rel8 = (nfapi_hi_dci0_dci_pdu_rel8_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &dci_pdu_rel8->dci_format, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->cce_index, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->aggregation_level, end) &&
-			pull16(ppReadPackedMsg, &dci_pdu_rel8->rnti, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->resource_block_start, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->number_of_resource_block, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->mcs_1, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->cyclic_shift_2_for_drms, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->frequency_hopping_enabled_flag, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->frequency_hopping_bits, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->new_data_indication_1, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->ue_tx_antenna_seleciton, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->tpc, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->cqi_csi_request, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->ul_index, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel8->dl_assignment_index, end) &&
-			pull32(ppReadPackedMsg, &dci_pdu_rel8->tpc_bitmap, end) &&
-			pull16(ppReadPackedMsg, &dci_pdu_rel8->transmission_power, end));
-}
-
-static uint8_t unpack_hi_dci0_dci_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_dci_pdu_rel10_t* dci_pdu_rel10 = (nfapi_hi_dci0_dci_pdu_rel10_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &dci_pdu_rel10->cross_carrier_scheduling_flag, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel10->carrier_indicator, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel10->size_of_cqi_csi_feild, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel10->srs_flag, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel10->srs_request, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel10->resource_allocation_flag, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel10->resource_allocation_type, end) &&
-			pull32(ppReadPackedMsg, &dci_pdu_rel10->resource_block_coding, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel10->mcs_2, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel10->new_data_indication_2, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel10->number_of_antenna_ports, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel10->tpmi, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel10->total_dci_length_including_padding, end) &&
-			pull8(ppReadPackedMsg, &dci_pdu_rel10->n_ul_rb, end));
-}
-
-static uint8_t unpack_hi_dci0_dci_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_dci_pdu_rel12_t* dci_pdu_rel12 = (nfapi_hi_dci0_dci_pdu_rel12_t*)tlv;
-	
-	return ( pull8(ppReadPackedMsg, &dci_pdu_rel12->pscch_resource, end) &&
-			 pull8(ppReadPackedMsg, &dci_pdu_rel12->time_resource_pattern, end));
-}
-
-static uint8_t unpack_hi_dci0_mpdcch_dci_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t* value = (nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &value->mpdcch_narrowband, end) &&
-			pull8(ppReadPackedMsg, &value->number_of_prb_pairs, end) &&
-			pull8(ppReadPackedMsg, &value->resource_block_assignment, end) &&
-			pull8(ppReadPackedMsg, &value->mpdcch_transmission_type, end) &&
-			pull8(ppReadPackedMsg, &value->start_symbol, end) &&
-			pull8(ppReadPackedMsg, &value->ecce_index, end) &&
-			pull8(ppReadPackedMsg, &value->aggreagation_level, end) &&
-			pull8(ppReadPackedMsg, &value->rnti_type, end) &&
-			pull16(ppReadPackedMsg, &value->rnti, end) &&
-			pull8(ppReadPackedMsg, &value->ce_mode, end) &&
-			pull16(ppReadPackedMsg, &value->drms_scrambling_init, end) &&
-			pull16(ppReadPackedMsg, &value->initial_transmission_sf_io, end) &&
-			pull16(ppReadPackedMsg, &value->transmission_power, end) &&
-			pull8(ppReadPackedMsg, &value->dci_format, end) &&
-			pull8(ppReadPackedMsg, &value->resource_block_start, end) &&
-			pull8(ppReadPackedMsg, &value->number_of_resource_blocks, end) &&
-			pull8(ppReadPackedMsg, &value->mcs, end) &&
-			pull8(ppReadPackedMsg, &value->pusch_repetition_levels, end) &&
-			pull8(ppReadPackedMsg, &value->frequency_hopping_flag, end) &&
-			pull8(ppReadPackedMsg, &value->new_data_indication, end) &&
-			pull8(ppReadPackedMsg, &value->harq_process, end) &&
-			pull8(ppReadPackedMsg, &value->redudency_version, end) &&
-			pull8(ppReadPackedMsg, &value->tpc, end) &&
-			pull8(ppReadPackedMsg, &value->csi_request, end) &&
-			pull8(ppReadPackedMsg, &value->ul_inex, end) &&
-			pull8(ppReadPackedMsg, &value->dai_presence_flag, end) &&
-			pull8(ppReadPackedMsg, &value->dl_assignment_index, end) &&
-			pull8(ppReadPackedMsg, &value->srs_request, end) &&
-			pull8(ppReadPackedMsg, &value->dci_subframe_repetition_number, end) &&
-			pull32(ppReadPackedMsg, &value->tcp_bitmap, end) &&
-			pull8(ppReadPackedMsg, &value->total_dci_length_include_padding, end) &&
-			pull8(ppReadPackedMsg, &value->number_of_tx_antenna_ports, end) &&
-			pullarray16(ppReadPackedMsg, value->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, value->number_of_tx_antenna_ports, end));
-}
-
-static uint8_t unpack_hi_dci0_npdcch_dci_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_hi_dci0_npdcch_dci_pdu_rel13_t* value = (nfapi_hi_dci0_npdcch_dci_pdu_rel13_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &value->ncce_index, end) &&
-			pull8(ppReadPackedMsg, &value->aggregation_level, end) &&
-			pull8(ppReadPackedMsg, &value->start_symbol, end) &&
-			pull16(ppReadPackedMsg, &value->rnti, end) &&
-			pull8(ppReadPackedMsg, &value->scrambling_reinitialization_batch_index, end) &&
-			pull8(ppReadPackedMsg, &value->nrs_antenna_ports_assumed_by_the_ue, end) &&
-			pull8(ppReadPackedMsg, &value->subcarrier_indication, end) &&
-			pull8(ppReadPackedMsg, &value->resource_assignment, end) &&
-			pull8(ppReadPackedMsg, &value->scheduling_delay, end) &&
-			pull8(ppReadPackedMsg, &value->mcs, end) &&
-			pull8(ppReadPackedMsg, &value->redudancy_version, end) &&
-			pull8(ppReadPackedMsg, &value->repetition_number, end) &&
-			pull8(ppReadPackedMsg, &value->new_data_indicator, end) &&
-			pull8(ppReadPackedMsg, &value->dci_subframe_repetition_number, end));
-}
-
-static uint8_t unpack_hi_dci0_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_hi_dci0_request_body_t* value = (nfapi_hi_dci0_request_body_t*)tlv;
-
-	if(!(pull16(ppReadPackedMsg, &value->sfnsf, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_dci, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_hi, end)))
-		return 0;
-
-	uint8_t totalNumPdus = value->number_of_hi + value->number_of_dci;
-
-	if(totalNumPdus > NFAPI_HI_DCI0_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of dci0 pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, totalNumPdus, NFAPI_HI_DCI0_MAX_PDU);
-		return 0;		
-	}
-
-	if(totalNumPdus > 0)
-	{
-		value->hi_dci0_pdu_list = (nfapi_hi_dci0_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_hi_dci0_request_pdu_t) * totalNumPdus, config);
-		if(value->hi_dci0_pdu_list == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate hi dci0 pdu list (count:%d)\n", __FUNCTION__, totalNumPdus);
-			return 0;
-		}
-	}
-	else
-	{
-		value->hi_dci0_pdu_list = 0;
-	}
-
-	uint8_t i;
-	for(i = 0; i < totalNumPdus; ++i)
-	{
-		nfapi_hi_dci0_request_pdu_t* pdu = &(value->hi_dci0_pdu_list[i]);
-
-		if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) &&
-			 pull8(ppReadPackedMsg, &pdu->pdu_size, end)))
-			return 0;
-
-		uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2;
-
-		if(packedPduEnd > end)
-		{
-			// pdu end if past buffer end
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pdu size to big %d %d\n", __FUNCTION__, packedPduEnd, end);
-			return 0;
-		}
-
-		switch(pdu->pdu_type)
-		{
-			case NFAPI_HI_DCI0_HI_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG, &pdu->hi_pdu.hi_pdu_rel8, &unpack_hi_dci0_hi_pdu_rel8_value},
-						{ NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG, &pdu->hi_pdu.hi_pdu_rel10, &unpack_hi_dci0_hi_pdu_rel10_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_HI_DCI0_DCI_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG, &pdu->dci_pdu.dci_pdu_rel8, &unpack_hi_dci0_dci_pdu_rel8_value},
-						{ NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG, &pdu->dci_pdu.dci_pdu_rel10, &unpack_hi_dci0_dci_pdu_rel10_value},
-						{ NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG, &pdu->dci_pdu.dci_pdu_rel12, &unpack_hi_dci0_dci_pdu_rel12_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel8, &unpack_hi_dci0_dci_pdu_rel8_value},
-						{ NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel10, &unpack_hi_dci0_dci_pdu_rel10_value},
-						{ NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG, &pdu->epdcch_dci_pdu.epdcch_parameters_rel11, &unpack_dl_config_epdcch_params_rel11_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG, &pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13, &unpack_hi_dci0_mpdcch_dci_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG, &pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13, &unpack_hi_dci0_npdcch_dci_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			default:
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type );
-				}
-				break;
-		};
-	}
-
-	return 1;
-}
-//unpack_ul_dci_pdu_list_value
-
-static uint8_t unpack_ul_dci_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
-{
-	nfapi_nr_ul_dci_request_pdus_t* value = (nfapi_nr_ul_dci_request_pdus_t*)msg;
-	
-	for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i)
-	{
-		if(!pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI,  end) &&
-		pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, end) &&
-
-		pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, end) &&
-		pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, end) &&
-		pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, end) &&
-		pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, end) &&
-
-		pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, end) &&
-		pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, end) &&
-		
-		pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, end));
-	
-		return 0;
-	}
-
-	return (pull16(ppReadPackedMsg, &value->PDUType, end) &&
-	   	    pull16(ppReadPackedMsg, &value->PDUSize, end) &&
-			pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, end) &&
-			pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, end) &&
-			pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, end) &&
-			pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, end) &&
-
-			pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, end) &&
-			pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, end) &&
-			pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, end) &&
-			pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, end) &&
-
-			pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, end) &&
-			pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, end) &&
-			pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, end) &&
-			pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, end) &&
-
-			pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, end) &&
-			pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end));
-		  
-}
-
-static uint8_t unpack_ul_dci_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t*)msg;
-	
-	if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) &&
-		     pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
-			 pull8(ppReadPackedMsg, &pNfapiMsg->numPdus, end)
-        ))
-		return 0;
-	for(int i=0; i< pNfapiMsg->numPdus; i++)
-		{
-			if (!unpack_ul_dci_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->ul_dci_pdu_list[i]))
-				return 0;
-		}
-
-		return 1;
-
-}
-
-static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_HI_DCI0_REQUEST_BODY_TAG, &pNfapiMsg->hi_dci0_request_body, &unpack_hi_dci0_request_body_value},
-	};
-
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-
-}
-static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
-{
-	nfapi_nr_pdu_t* pNfapiMsg = (nfapi_nr_pdu_t*)msg;
-
-	if(!(pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end) &&
-	    pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end) &&
-		pull16(ppReadPackedMsg, &pNfapiMsg->PDU_length, end)
-	 ))
-		return 0;
-
-	uint16_t i = 0;
-	uint16_t total_number_of_tlvs = pNfapiMsg->num_TLV;
-	for(; i < total_number_of_tlvs; ++i)
-	{
-		
-		if (!(pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].length, end) &&
-			pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].tag, end)))
-			return 0;
-
-		switch(pNfapiMsg->TLVs[i].tag){
-			case 0:
-			{
-				if(!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.direct, 16384, pNfapiMsg->TLVs[i].length, end))
-					return 0;
-				break;
-
-			}
-
-			case 1:
-			{
-				if(!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.ptr, pNfapiMsg->TLVs[i].length , pNfapiMsg->TLVs[i].length, end))
-					return 0;
-				break;
-
-			}
-				
-			default:
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", pNfapiMsg->TLVs[i].tag );
-				break;
-			}
-				
-		}		
-	}
-
-
-	return 1;
-}
-
-static uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t*)msg;
-
-	if(!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) &&
-		 pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
-		 pull16(ppReadPackedMsg, &pNfapiMsg->Number_of_PDUs, end)))
-		return 0;
-
-	for(int i=0; i< pNfapiMsg->Number_of_PDUs; i++)
-	{
-		if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i]))
-			return 0;
-	}
-
-	return 1;
-}
-
-static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	uint8_t proceed = 1;
-	nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t*)msg;
-
-	if(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) == 0)
-		return 0;
-
-	while (((uint8_t*)(*ppReadPackedMsg) < end) && proceed)
-	{
-		nfapi_tl_t generic_tl;
-		if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
-			return 0;
-
-		switch(generic_tl.tag)
-		{
-			case NFAPI_TX_REQUEST_BODY_TAG:
-			{
-				pNfapiMsg->tx_request_body.tl = generic_tl;
-
-				if( pull16(ppReadPackedMsg, &pNfapiMsg->tx_request_body.number_of_pdus, end) == 0)
-					return 0;
-
-				if(pNfapiMsg->tx_request_body.number_of_pdus > NFAPI_TX_MAX_PDU)
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of tx pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->tx_request_body.number_of_pdus, NFAPI_TX_MAX_PDU);
-					return 0;		
-				}
-
-				if(pNfapiMsg->tx_request_body.number_of_pdus > 0)
-				{
-					pNfapiMsg->tx_request_body.tx_pdu_list = (nfapi_tx_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_tx_request_pdu_t) * pNfapiMsg->tx_request_body.number_of_pdus, config);
-					if(pNfapiMsg->tx_request_body.tx_pdu_list == NULL)
-					{
-						NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate tx  pdu list (count:%d)\n", __FUNCTION__, pNfapiMsg->tx_request_body.number_of_pdus);
-						return 0;
-					}
-				}
-				else
-				{
-					pNfapiMsg->tx_request_body.tx_pdu_list = 0;
-				}
-
-
-				uint16_t i;
-				uint16_t totalNumPdus = pNfapiMsg->tx_request_body.number_of_pdus;
-				for(i = 0; i < totalNumPdus; ++i)
-				{
-					nfapi_tx_request_pdu_t* pdu = &(pNfapiMsg->tx_request_body.tx_pdu_list[i]);
-					if (pdu) {
-					  uint16_t length = 0;
-					  uint16_t index = 0;
-					
-					  if(!(pull16(ppReadPackedMsg, &length, end) &&
-						 pull16(ppReadPackedMsg, &index, end)))
-						  return 0;
-
-                                          pdu->pdu_length = length;
-                                          pdu->pdu_index = index;
-					
-
-					// TODO : May need to rethink this bit
-					  pdu->num_segments = 1;
-					  pdu->segments[0].segment_length = pdu->pdu_length;
-					  pdu->segments[0].segment_data = nfapi_p7_allocate(pdu->pdu_length, config);
-
-					  if(pdu->segments[0].segment_data)
-					  {
-						  if(!pullarray8(ppReadPackedMsg, pdu->segments[0].segment_data, pdu->segments[0].segment_length, pdu->segments[0].segment_length, end))
-							return 0;
-                                                  if (pdu->segments[0].segment_length == 3)
-                                                  {
-                                                  NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, 
-                                                      pdu->segments[0].segment_data[0], 
-                                                      pdu->segments[0].segment_data[1], 
-                                                      pdu->segments[0].segment_data[2]
-                                                      );
-                                                  }
-					  }
-					  else
-					  {
-						NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request: Failed to allocate pdu (len:%d) %d/%d %d\n", pdu->pdu_length, totalNumPdus, i, pdu->pdu_index);
-					  }
-                                      } else {
-                                          NFAPI_TRACE(NFAPI_TRACE_ERROR, "NULL pdu\n");
-                                      }
-				}
-			}
-			break;
-			default:
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request FIXME : Invalid pdu type %d \n", generic_tl.tag );
-			}
-			break;
-		};
-	}
-
-	return 1;
-}
-
-static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-    uint8_t proceed = 1;
-    nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg;
-
-    if(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) == 0)
-        return 0;
-
-    while (((uint8_t*)(*ppReadPackedMsg) < end) && proceed)
-    {
-        nfapi_tl_t generic_tl;
-        if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
-            return 0;
-
-        switch(generic_tl.tag)
-        {
-            case NFAPI_UE_RELEASE_BODY_TAG:
-            {
-                pNfapiMsg->ue_release_request_body.tl = generic_tl;
-                if( pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.number_of_TLVs, end) == 0)
-                    return 0;
-
-                if(pNfapiMsg->ue_release_request_body.number_of_TLVs > NFAPI_RELEASE_MAX_RNTI)
-                {
-                    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of relese rnti's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->ue_release_request_body.number_of_TLVs, NFAPI_RELEASE_MAX_RNTI);
-                    return 0;
-                } else {
-                    uint8_t j;
-                    uint16_t num = pNfapiMsg->ue_release_request_body.number_of_TLVs;
-                    for(j = 0; j < num; ++j){
-                    		if(pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.ue_release_request_TLVs_list[j].rnti, end) == 0){
-                    				return 0;
-                    		}
-                    }
-                }
-            }
-            break;
-            default:
-            {
-              NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_ue_release_request FIXME : Invalid type %d \n", generic_tl.tag );
-            }
-            break;
-        };
-    }
-
-    return 1;
-}
-
-static uint8_t unpack_harq_indication_tdd_harq_data_bundling(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_tdd_harq_data_bundling_t* value = (nfapi_harq_indication_tdd_harq_data_bundling_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &value->value_0, end) &&
-			pull8(ppReadPackedMsg, &value->value_1, end));
-}
-
-static uint8_t unpack_harq_indication_tdd_harq_data_multiplexing(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_tdd_harq_data_multiplexing_t* value = (nfapi_harq_indication_tdd_harq_data_multiplexing_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &value->value_0, end) &&
-			pull8(ppReadPackedMsg, &value->value_1, end) &&
-			pull8(ppReadPackedMsg, &value->value_2, end) &&
-			pull8(ppReadPackedMsg, &value->value_3, end));
-}
-static uint8_t unpack_harq_indication_tdd_harq_data_special_bundling(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_tdd_harq_data_special_bundling_t* value = (nfapi_harq_indication_tdd_harq_data_special_bundling_t*)tlv;
-	return ( pull8(ppReadPackedMsg, &value->value_0, end));
-}
-static uint8_t unpack_harq_indication_tdd_harq_data(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_tdd_harq_data_t* value = (nfapi_harq_indication_tdd_harq_data_t*)tlv;
-	return  (pull8(ppReadPackedMsg, &value->value_0, end));
-}
-
-static uint8_t unpack_harq_indication_tdd_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_tdd_rel8_t* value = (nfapi_harq_indication_tdd_rel8_t*)tlv;
-	
-	if(!(pull8(ppReadPackedMsg, &value->mode, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_ack_nack, end)))
-		return 0;
-
-	uint8_t result = 0;
-	switch(value->mode)
-	{
-		case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING:
-			result = unpack_harq_indication_tdd_harq_data_bundling(&value->harq_data.bundling, ppReadPackedMsg, end);
-			break;
-		case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING:
-			result = unpack_harq_indication_tdd_harq_data_multiplexing(&value->harq_data.multiplex, ppReadPackedMsg, end);
-			break;
-		case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING:
-			result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data.special_bundling, ppReadPackedMsg, end);
-			break;
-		case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3:
-		case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION:
-			result = 1;
-			break;
-		default:
-			// TODO add error message
-			return 0;
-			break;
-	}
-	return result;
-}
-
-static uint8_t unpack_harq_indication_tdd_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_tdd_rel9_t* value = (nfapi_harq_indication_tdd_rel9_t*)tlv;
-	
-	if(!(pull8(ppReadPackedMsg, &value->mode, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_ack_nack, end)))
-		return 0;
-
-	if(value->number_of_ack_nack > NFAPI_MAX_NUMBER_ACK_NACK_TDD)
-	{
-		// TODO : add error message
-		return 0;
-	}
-
-	uint16_t idx = 0;
-	for(idx = 0; idx < value->number_of_ack_nack; ++idx)
-	{
-		uint8_t result = 0;
-		switch(value->mode)
-		{
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING:
-				result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].bundling, ppReadPackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING:
-				result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].multiplex, ppReadPackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING:
-				result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data[idx].special_bundling, ppReadPackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION:
-				result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].channel_selection, ppReadPackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3:
-				result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_3, ppReadPackedMsg, end);
-				break;
-			default:
-				// TODO add error message
-				return 0;
-				break;
-		}
-
-		if(result == 0)
-			return 0;
-	}
-	return 1;
-}
-
-static uint8_t unpack_harq_indication_tdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_tdd_rel13_t* value = (nfapi_harq_indication_tdd_rel13_t*)tlv;
-	
-	if(!(pull8(ppReadPackedMsg, &value->mode, end) &&
-		 pull16(ppReadPackedMsg, &value->number_of_ack_nack, end)))
-		return 0;
-
-	if(value->number_of_ack_nack > NFAPI_MAX_NUMBER_ACK_NACK_TDD)
-	{
-		// TODO : add error message
-		return 0;
-	}
-
-	uint16_t idx = 0;
-	for(idx = 0; idx < value->number_of_ack_nack; ++idx)
-	{
-		uint8_t result = 0;
-		switch(value->mode)
-		{
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING:
-				result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].bundling, ppReadPackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING:
-				result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].multiplex, ppReadPackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING:
-				result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data[idx].special_bundling, ppReadPackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION:
-				result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].channel_selection, ppReadPackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3:
-				result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_3, ppReadPackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_4:
-				result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_4, ppReadPackedMsg, end);
-				break;
-			case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_5:
-				result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_5, ppReadPackedMsg, end);
-				break;
-			default:
-				// TODO add error message
-				return 0;
-				break;
-		}
-
-		if(result == 0)
-			return 0;
-	}
-	return 1;
-}
-
-static uint8_t unpack_harq_indication_fdd_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_fdd_rel8_t* value = (nfapi_harq_indication_fdd_rel8_t*)tlv;
-	return (pull8(ppReadPackedMsg, &value->harq_tb1, end) &&
-			pull8(ppReadPackedMsg, &value->harq_tb2, end));
-}
-
-static uint8_t unpack_harq_indication_fdd_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_fdd_rel9_t* value = (nfapi_harq_indication_fdd_rel9_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &value->mode, end) &&
-			pull8(ppReadPackedMsg, &value->number_of_ack_nack, end) &&
-			pullarray8(ppReadPackedMsg, value->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL9_MAX, value->number_of_ack_nack, end));
-}
-
-static uint8_t unpack_harq_indication_fdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_harq_indication_fdd_rel13_t* value = (nfapi_harq_indication_fdd_rel13_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &value->mode, end) &&
-			pull16(ppReadPackedMsg, &value->number_of_ack_nack, end) &&
-			pullarray8(ppReadPackedMsg, value->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL13_MAX, value->number_of_ack_nack, end));
-}
-
-static uint8_t unpack_ul_cqi_information_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_ul_cqi_information_t* value = (nfapi_ul_cqi_information_t*)tlv;
-	
-	return (pull8(ppReadPackedMsg, &value->ul_cqi, end) &&
-			pull8(ppReadPackedMsg, &value->channel, end));
-}
-
-
-
-static uint8_t unpack_harq_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_harq_indication_body_t* value = (nfapi_harq_indication_body_t*)tlv;
-	uint8_t* harqBodyEnd = *ppReadPackedMsg + value->tl.length;
-
-	if(harqBodyEnd > end)
-		return 0;
-
-	if(pull16(ppReadPackedMsg, &value->number_of_harqs, end) == 0)
-		return 0;
-
-	if(value->number_of_harqs > NFAPI_HARQ_IND_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of harq ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_harqs, NFAPI_HARQ_IND_MAX_PDU);
-		return 0;		
-	}
-
-	value->harq_pdu_list = (nfapi_harq_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_harq_indication_pdu_t) * value->number_of_harqs, config);
-	if(value->harq_pdu_list == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_harqs);
-		return 0;
-	}
-	
-	uint8_t i = 0;
-	for(i = 0; i < value->number_of_harqs; ++i)
-	{
-		nfapi_harq_indication_pdu_t* pdu = &(value->harq_pdu_list[i]);
-		if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
-			return 0;
-
-		uint8_t* harqPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
-
-		unpack_tlv_t unpack_fns[] =
-		{
-			{ NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value },
-			{ NFAPI_HARQ_INDICATION_TDD_REL8_TAG, &pdu->harq_indication_tdd_rel8, &unpack_harq_indication_tdd_rel8_value},
-			{ NFAPI_HARQ_INDICATION_TDD_REL9_TAG, &pdu->harq_indication_tdd_rel9, &unpack_harq_indication_tdd_rel9_value},
-			{ NFAPI_HARQ_INDICATION_TDD_REL13_TAG, &pdu->harq_indication_tdd_rel13, &unpack_harq_indication_tdd_rel13_value},
-			{ NFAPI_HARQ_INDICATION_FDD_REL8_TAG, &pdu->harq_indication_fdd_rel8, &unpack_harq_indication_fdd_rel8_value},
-			{ NFAPI_HARQ_INDICATION_FDD_REL9_TAG, &pdu->harq_indication_fdd_rel9, &unpack_harq_indication_fdd_rel9_value},
-			{ NFAPI_HARQ_INDICATION_FDD_REL13_TAG, &pdu->harq_indication_fdd_rel13, &unpack_harq_indication_fdd_rel13_value},
-			{ NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, &unpack_ul_cqi_information_value}
-		};
-
-		if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, harqPduInstanceEnd, 0, 0) == 0)
-			return 0;
-	
-	}
-
-	return 1;
-}
-
-static uint8_t unpack_harq_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_harq_indication_t *pNfapiMsg = (nfapi_harq_indication_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->harq_indication_body, &unpack_harq_indication_body_value},
-	};
-
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_crc_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_crc_indication_rel8_t* crc_pdu_rel8 = (nfapi_crc_indication_rel8_t*)tlv;
-	return ( pull8(ppReadPackedMsg, &crc_pdu_rel8->crc_flag, end) );
-}
-
-static uint8_t unpack_crc_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end,  nfapi_p7_codec_config_t* config)
-{
-	nfapi_crc_indication_body_t* value = (nfapi_crc_indication_body_t*)tlv;
-	uint8_t* crcBodyEnd = *ppReadPackedMsg + value->tl.length;
-
-	if(crcBodyEnd > end)
-		return 0;
-
-	if(pull16(ppReadPackedMsg, &value->number_of_crcs, end) == 0)
-		return 0;
-
-	if(value->number_of_crcs > NFAPI_CRC_IND_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of crc ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_crcs, NFAPI_CRC_IND_MAX_PDU);
-		return 0;		
-	}
-
-	if(value->number_of_crcs > 0)
-	{
-		value->crc_pdu_list = (nfapi_crc_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_crc_indication_pdu_t) * value->number_of_crcs, config);
-		if(value->crc_pdu_list == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate crc ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_crcs);
-			return 0;
-		}
-	}
-	else
-	{
-		value->crc_pdu_list = 0;
-	}
-
-	
-	uint8_t i = 0;
-	for(i = 0; i < value->number_of_crcs; ++i)
-	{
-		nfapi_crc_indication_pdu_t* pdu = &(value->crc_pdu_list[i]);
-
-		if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
-			return 0;
-
-		uint8_t* crcPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
-
-
-		unpack_tlv_t unpack_fns[] =
-		{
-			{ NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value },
-			{ NFAPI_CRC_INDICATION_REL8_TAG, &pdu->crc_indication_rel8, unpack_crc_indication_rel8_value },
-		};
-
-		if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, crcPduInstanceEnd, 0, 0) == 0)
-			return 0;
-	}
-
-	return 1;
-}
-
-static uint8_t unpack_crc_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_crc_indication_t *pNfapiMsg = (nfapi_crc_indication_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_CRC_INDICATION_BODY_TAG, &pNfapiMsg->crc_indication_body, &unpack_crc_indication_body_value},
-	};
-
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_rx_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_rx_indication_rel8_t* value = (nfapi_rx_indication_rel8_t*)tlv;
-	
-	return (pull16(ppReadPackedMsg, &value->length, end) &&
-			pull16(ppReadPackedMsg, &value->offset, end) &&
-			pull8(ppReadPackedMsg, &value->ul_cqi, end) &&
-			pull16(ppReadPackedMsg, &value->timing_advance, end));
-}
-static uint8_t unpack_rx_indication_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_rx_indication_rel9_t* value = (nfapi_rx_indication_rel9_t*)tlv;
-	return (pull16(ppReadPackedMsg, &value->timing_advance_r9, end));
-}
-
-static uint8_t unpack_rx_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_rx_indication_body_t* value = (nfapi_rx_indication_body_t*)tlv;
-
-	// the rxBodyEnd points to the end of the cqi PDU's
-	uint8_t* rxBodyEnd = *ppReadPackedMsg + value->tl.length;
-	uint8_t* rxPduEnd = rxBodyEnd;
-
-	uint8_t* numberOfPdusAddress = *ppReadPackedMsg;
-
-	if(rxBodyEnd > end)
-	{
-		// pdu end is past buffer end
-		return 0;
-	}
-
-	if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0)
-		return 0;
-
-	if(value->number_of_pdus > NFAPI_RX_IND_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of rx ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_RX_IND_MAX_PDU);
-		return 0;		
-	}
-
-	if(value->number_of_pdus > 0)
-	{
-		value->rx_pdu_list = (nfapi_rx_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_rx_indication_pdu_t) * value->number_of_pdus, config);
-		if(value->rx_pdu_list == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate rx ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus);
-			return 0;
-		}
-	}
-	else
-	{
-		value->rx_pdu_list = 0;
-	}
-	
-	uint8_t i = 0;
-	nfapi_rx_indication_pdu_t* pdu = 0;
-	while((uint8_t*)(*ppReadPackedMsg) < rxBodyEnd && (uint8_t*)(*ppReadPackedMsg) < rxPduEnd)
-	{
-		nfapi_tl_t generic_tl;
-		if( unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
-			return 0;
-
-		switch(generic_tl.tag)
-		{
-			case NFAPI_RX_UE_INFORMATION_TAG:
-				{
-					pdu = &(value->rx_pdu_list[i++]);
-					pdu->rx_ue_information.tl = generic_tl;
-					if(unpack_rx_ue_information_value(&pdu->rx_ue_information, ppReadPackedMsg, end) == 0)
-						return 0;
-				}
-				break;
-			case NFAPI_RX_INDICATION_REL8_TAG:
-				{
-					if(pdu != 0)
-					{
-						pdu->rx_indication_rel8.tl = generic_tl;
-						if(unpack_rx_indication_rel8_value(&pdu->rx_indication_rel8, ppReadPackedMsg, end) == 0)
-							return 0;
-		
-						if(pdu->rx_indication_rel8.offset > 0)
-						{
-							// Need to check that the data is within the tlv
-							if(numberOfPdusAddress + pdu->rx_indication_rel8.offset + pdu->rx_indication_rel8.length <= rxBodyEnd)
-							{
-								// If this the first pdu set the rxPduEnd
-								if(numberOfPdusAddress + pdu->rx_indication_rel8.offset < rxPduEnd)
-								{
-									rxPduEnd = numberOfPdusAddress + pdu->rx_indication_rel8.offset;
-		
-									if(rxPduEnd > end)
-									{
-										// pdu end is past buffer end
-										return 0;
-									}
-								}
-							}
-							else
-							{
-								NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME: the rx data is outside of the tlv\n");
-							}
-						}
-					}
-				}
-				break;
-			case NFAPI_RX_INDICATION_REL9_TAG:
-				{
-					if(pdu != 0)
-					{
-						pdu->rx_indication_rel9.tl = generic_tl;
-						if(unpack_rx_indication_rel9_value(&pdu->rx_indication_rel9, ppReadPackedMsg, end) == 0)
-							return 0;
-					}
-				}
-				break;
-			default:
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "RX_ULSCH.indication Invalid pdu type %d \n", generic_tl.tag );
-				}
-				break;
-		}
-	}
-	
-	uint8_t idx = 0;
-	for(idx = 0; idx < value->number_of_pdus; ++idx)
-	{
-		if(value->rx_pdu_list[idx].rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG)
-		{
-			uint32_t length = value->rx_pdu_list[idx].rx_indication_rel8.length;
-			value->rx_pdu_list[idx].data = nfapi_p7_allocate(length, config);
-			if(pullarray8(ppReadPackedMsg, value->rx_pdu_list[idx].data, length, length, end) == 0)
-			{
-				return 0;
-			}
-		}
-	}
-
-	return 1;
-}
-
-static uint8_t unpack_rx_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_rx_indication_t *pNfapiMsg = (nfapi_rx_indication_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_RX_INDICATION_BODY_TAG, &pNfapiMsg->rx_indication_body, &unpack_rx_indication_body_value},
-	};
-
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_preamble_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_preamble_pdu_rel8_t* preamble_pdu_rel8 = (nfapi_preamble_pdu_rel8_t*)tlv;
-	
-	return (pull16(ppReadPackedMsg, &preamble_pdu_rel8->rnti, end) &&
-			pull8(ppReadPackedMsg, &preamble_pdu_rel8->preamble, end) &&
-			pull16(ppReadPackedMsg, &preamble_pdu_rel8->timing_advance, end));
-}
-
-static uint8_t unpack_preamble_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_preamble_pdu_rel9_t* preamble_pdu_rel9 = (nfapi_preamble_pdu_rel9_t*)tlv;
-	return pull16(ppReadPackedMsg, &preamble_pdu_rel9->timing_advance_r9, end);
-}
-
-static uint8_t unpack_preamble_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_preamble_pdu_rel13_t* preamble_pdu_rel13 = (nfapi_preamble_pdu_rel13_t*)tlv;
-	return pull8(ppReadPackedMsg, &preamble_pdu_rel13->rach_resource_type, end);
-}
-
-static uint8_t unpack_rach_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_rach_indication_body_t* value = (nfapi_rach_indication_body_t*)tlv;
-	uint8_t* rachBodyEnd = *ppReadPackedMsg + value->tl.length;
-
-	if(rachBodyEnd > end)
-		return 0;
-
-	if(pull16(ppReadPackedMsg, &value->number_of_preambles, end) == 0)
-		return 0;
-
-	if(value->number_of_preambles > NFAPI_PREAMBLE_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of preamble du's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_preambles, NFAPI_PREAMBLE_MAX_PDU);
-		return 0;		
-	}
-
-	if(value->number_of_preambles > 0)
-	{
-		value->preamble_list = (nfapi_preamble_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_preamble_pdu_t) * value->number_of_preambles, config);
-		if(value->preamble_list == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate preamble pdu list (count:%d)\n", __FUNCTION__, value->number_of_preambles);
-			return 0;
-		}
-	}
-	else
-	{
-		value->preamble_list = 0;
-	}
-
-	
-	uint8_t i = 0;
-	for(i = 0; i < value->number_of_preambles; ++i)
-	{
-		nfapi_preamble_pdu_t* pdu = &(value->preamble_list[i]);
-
-		if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
-			return 0;
-
-		uint8_t* preamblePduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
-
-
-		unpack_tlv_t unpack_fns[] =
-		{
-			{ NFAPI_PREAMBLE_REL8_TAG, &pdu->preamble_rel8, unpack_preamble_pdu_rel8_value },
-			{ NFAPI_PREAMBLE_REL9_TAG, &pdu->preamble_rel9, unpack_preamble_pdu_rel9_value },
-			{ NFAPI_PREAMBLE_REL13_TAG, &pdu->preamble_rel13, unpack_preamble_pdu_rel13_value },
-		};
-
-		if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, preamblePduInstanceEnd, 0, 0) == 0)
-			return 0;
-	}
-	return 1;
-}
-
-static uint8_t unpack_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_rach_indication_t *pNfapiMsg = (nfapi_rach_indication_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_RACH_INDICATION_BODY_TAG, &pNfapiMsg->rach_indication_body, &unpack_rach_indication_body_value},
-	};
-
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_srs_indication_fdd_rel8_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_srs_indication_fdd_rel8_t* srs_pdu_fdd_rel8 = (nfapi_srs_indication_fdd_rel8_t*)tlv;
-	
-	if(!(pull16(ppReadPackedMsg, &srs_pdu_fdd_rel8->doppler_estimation, end) &&
-		 pull16(ppReadPackedMsg, &srs_pdu_fdd_rel8->timing_advance, end) &&
-		 pull8(ppReadPackedMsg, &srs_pdu_fdd_rel8->number_of_resource_blocks, end) &&
-		 pull8(ppReadPackedMsg, &srs_pdu_fdd_rel8->rb_start, end) &&
-		 pullarray8(ppReadPackedMsg, srs_pdu_fdd_rel8->snr, NFAPI_NUM_RB_MAX, srs_pdu_fdd_rel8->number_of_resource_blocks, end)))
-		return 0;
-	return 1;
-}
-
-static uint8_t unpack_srs_indication_fdd_rel9_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_srs_indication_fdd_rel9_t* srs_pdu_fdd_rel9 = (nfapi_srs_indication_fdd_rel9_t*)tlv;
-	return (pull16(ppReadPackedMsg, &srs_pdu_fdd_rel9->timing_advance_r9, end));
-}
-
-static uint8_t unpack_srs_indication_tdd_rel10_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_srs_indication_ttd_rel10_t* srs_pdu_tdd_rel10 = (nfapi_srs_indication_ttd_rel10_t*)tlv;
-	return (pull8(ppReadPackedMsg, &srs_pdu_tdd_rel10->uppts_symbol, end));
-}
-
-static uint8_t unpack_srs_indication_fdd_rel11_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_srs_indication_fdd_rel11_t* srs_pdu_fdd_rel11 = (nfapi_srs_indication_fdd_rel11_t*)tlv;
-	return ( pull16(ppReadPackedMsg, &srs_pdu_fdd_rel11->ul_rtoa, end));
-}
-
-static uint8_t unpack_tdd_channel_measurement_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_tdd_channel_measurement_t* value = (nfapi_tdd_channel_measurement_t*)tlv;
-	
-	if(!(pull8(ppReadPackedMsg, &value->num_prb_per_subband, end) &&
-		 pull8(ppReadPackedMsg, &value->number_of_subbands, end) &&
-		 pull8(ppReadPackedMsg, &value->num_atennas, end)))
-		return 0;
-
-	if(value->number_of_subbands > NFAPI_MAX_NUM_SUBBANDS)
-	{
-		// todo : add error
-		return 0;
-	}
-
-	if(value->num_atennas > NFAPI_MAX_NUM_PHYSICAL_ANTENNAS)
-	{
-		// todo : add error
-		return 0;
-	}
-
-	uint8_t idx = 0;
-	for(idx = 0; idx < value->number_of_subbands; ++idx)
-	{
-		if(!(pull8(ppReadPackedMsg, &value->subands[idx].subband_index, end) &&
-			 pullarray16(ppReadPackedMsg, value->subands[idx].channel, NFAPI_MAX_NUM_PHYSICAL_ANTENNAS, value->num_atennas, end)))
-			return 0;
-	}
-
-	return 1;
-}
-
-
-static uint8_t unpack_srs_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_srs_indication_body_t* value = (nfapi_srs_indication_body_t*)tlv;
-	uint8_t* srsBodyEnd = *ppReadPackedMsg + value->tl.length;
-	
-	if(srsBodyEnd > end)
-		return 0;
-
-	if(pull8(ppReadPackedMsg, &value->number_of_ues, end) == 0)
-		return 0;
-
-	if(value->number_of_ues > NFAPI_SRS_IND_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of srs ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_ues, NFAPI_SRS_IND_MAX_PDU);
-		return 0;		
-	}
-
-	if(value->number_of_ues > 0)
-	{
-		value->srs_pdu_list = (nfapi_srs_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_srs_indication_pdu_t) * value->number_of_ues, config);
-		if(value->srs_pdu_list == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate srs ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_ues);
-			return 0;
-		}
-	}
-	else
-	{
-		value->srs_pdu_list = 0;
-	}
-
-
-	
-	uint8_t i = 0;
-	for(i = 0; i < value->number_of_ues; ++i)
-	{
-		nfapi_srs_indication_pdu_t* pdu = &(value->srs_pdu_list[i]);
-
-		
-		if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
-			return 0;
-
-		uint8_t* srsPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
-
-
-		unpack_tlv_t unpack_fns[] =
-		{
-			{ NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value },
-			{ NFAPI_SRS_INDICATION_FDD_REL8_TAG, &pdu->srs_indication_fdd_rel8, unpack_srs_indication_fdd_rel8_value},
-			{ NFAPI_SRS_INDICATION_FDD_REL9_TAG, &pdu->srs_indication_fdd_rel9, unpack_srs_indication_fdd_rel9_value},
-			{ NFAPI_SRS_INDICATION_TDD_REL10_TAG, &pdu->srs_indication_tdd_rel10, unpack_srs_indication_tdd_rel10_value},
-			{ NFAPI_SRS_INDICATION_FDD_REL11_TAG, &pdu->srs_indication_fdd_rel11, unpack_srs_indication_fdd_rel11_value},
-			{ NFAPI_TDD_CHANNEL_MEASUREMENT_TAG, &pdu->tdd_channel_measurement, unpack_tdd_channel_measurement_value},
-		};
-
-		if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, srsPduInstanceEnd, 0, 0) == 0)
-			return 0;
-	}
-	return 1;
-}
-
-static uint8_t unpack_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_srs_indication_t *pNfapiMsg = (nfapi_srs_indication_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_SRS_INDICATION_BODY_TAG, &pNfapiMsg->srs_indication_body, &unpack_srs_indication_body_value},
-	};
-
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-
-static uint8_t unpack_sr_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_sr_indication_body_t* value = (nfapi_sr_indication_body_t*)tlv;
-	uint8_t* srBodyEnd = *ppReadPackedMsg + value->tl.length;
-
-	if(srBodyEnd > end)
-		return 0;
-
-	if(pull16(ppReadPackedMsg, &value->number_of_srs, end) == 0)
-		return 0;
-
-	if(value->number_of_srs > NFAPI_SR_IND_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of sr ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_srs, NFAPI_SR_IND_MAX_PDU);
-		return 0;		
-	}
-
-	if(value->number_of_srs > 0)
-	{
-		value->sr_pdu_list = (nfapi_sr_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_sr_indication_pdu_t) * value->number_of_srs, config);
-		if(value->sr_pdu_list == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate sr ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_srs);
-			return 0;
-		}
-	}
-	else
-	{
-		value->sr_pdu_list = 0;
-	}
-	
-	uint8_t i = 0;
-	for(i = 0; i < value->number_of_srs; ++i)
-	{
-		nfapi_sr_indication_pdu_t* pdu = &(value->sr_pdu_list[i]);
-
-		if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
-			return 0;
-
-		uint8_t* srPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
-
-
-		unpack_tlv_t unpack_fns[] =
-		{
-			{ NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value },
-			{ NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, unpack_ul_cqi_information_value },
-		};
-
-		if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, srPduInstanceEnd, 0, 0) == 0)
-			return 0;
-	}
-
-	return 1;
-
-}
-
-static int unpack_sr_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_sr_indication_t *pNfapiMsg = (nfapi_sr_indication_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_SR_INDICATION_BODY_TAG, &pNfapiMsg->sr_indication_body, &unpack_sr_indication_body_value},
-	};
-
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-static uint8_t unpack_cqi_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_cqi_indication_rel8_t* cqi_pdu_rel8 = (nfapi_cqi_indication_rel8_t*)tlv;
-	
-	return (pull16(ppReadPackedMsg, &cqi_pdu_rel8->length, end) &&
-			pull16(ppReadPackedMsg, &cqi_pdu_rel8->data_offset, end) &&
-			pull8(ppReadPackedMsg, &cqi_pdu_rel8->ul_cqi, end) &&
-			pull8(ppReadPackedMsg, &cqi_pdu_rel8->ri, end) &&
-			pull16(ppReadPackedMsg, &cqi_pdu_rel8->timing_advance, end));
-
-}
-
-static uint8_t unpack_cqi_indication_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_cqi_indication_rel9_t* cqi_pdu_rel9 = (nfapi_cqi_indication_rel9_t*)tlv;
-	
-	if(!(pull16(ppReadPackedMsg, &cqi_pdu_rel9->length, end) &&
-		 pull16(ppReadPackedMsg, &cqi_pdu_rel9->data_offset, end) &&
-		 pull8(ppReadPackedMsg, &cqi_pdu_rel9->ul_cqi, end) &&
-		 pull8(ppReadPackedMsg, &cqi_pdu_rel9->number_of_cc_reported, end)))
-		return 0;
-
-	if(cqi_pdu_rel9->number_of_cc_reported > NFAPI_CC_MAX)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : out of bound array\n");
-		return 0;
-	}
-	
-	if(!(pullarray8(ppReadPackedMsg, cqi_pdu_rel9->ri, NFAPI_CC_MAX, cqi_pdu_rel9->number_of_cc_reported, end) &&
-		 pull16(ppReadPackedMsg, &cqi_pdu_rel9->timing_advance, end) &&
-		 pull16(ppReadPackedMsg, &cqi_pdu_rel9->timing_advance_r9, end)))
-		return 0;
-
-	return 1;
-}
-
-static uint8_t  unpack_cqi_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end,  nfapi_p7_codec_config_t* config)
-{
-	nfapi_cqi_indication_body_t* value = (nfapi_cqi_indication_body_t*)tlv;
-
-	// the cqiBodyEnd points to the end of the cqi PDU's
-	uint8_t* cqiBodyEnd = *ppReadPackedMsg + value->tl.length;
-
-	//uint8_t* cqiPduEnd = cqiBodyEnd;
-	//uint8_t* numberOfPdusAddress = *ppReadPackedMsg;
-
-	if(cqiBodyEnd > end)
-		return 0;
-
-	if(pull16(ppReadPackedMsg, &value->number_of_cqis, end) == 0)
-		return 0;
-
-	if(value->number_of_cqis > NFAPI_CQI_IND_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of cqi ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_cqis, NFAPI_CQI_IND_MAX_PDU);
-		return -1;		
-	}
-
-	if(value->number_of_cqis > 0)
-	{
-		value->cqi_pdu_list = (nfapi_cqi_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_cqi_indication_pdu_t) * value->number_of_cqis, config);
-		if(value->cqi_pdu_list == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate cqi ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_cqis);
-			return 0;
-		}
-	}
-	else
-	{
-		value->cqi_pdu_list = 0;
-	}
-
-	if(value->number_of_cqis > 0)
-	{
-		value->cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_cqi_indication_raw_pdu_t) * value->number_of_cqis, config);
-		if(value->cqi_raw_pdu_list == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate raw cqi ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_cqis);
-			return 0;
-		}
-	}
-	else
-	{
-		value->cqi_raw_pdu_list = 0;
-	}
-
-	uint8_t i = 0;
-	for(i = 0; i < value->number_of_cqis; ++i)
-	{
-		nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]);
-		memset(pdu, 0, sizeof(nfapi_cqi_indication_pdu_t));
-
-		if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
-			return 0;
-
-		uint8_t* cqiPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
-
-
-		while((uint8_t*)(*ppReadPackedMsg) < cqiPduInstanceEnd)
-		{
-			nfapi_tl_t generic_tl;
-			if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
-				return 0;
-
-			switch(generic_tl.tag)
-			{
-				case NFAPI_RX_UE_INFORMATION_TAG:
-					pdu->rx_ue_information.tl = generic_tl;
-					if(unpack_rx_ue_information_value(&pdu->rx_ue_information, ppReadPackedMsg, end) == 0)
-						return 0;
-					break;
-				case NFAPI_CQI_INDICATION_REL8_TAG:
-					pdu->cqi_indication_rel8.tl = generic_tl;
-					if(unpack_cqi_indication_rel8_value(&pdu->cqi_indication_rel8, ppReadPackedMsg, end) == 0)
-						return 0;
-
-					break;
-				case NFAPI_CQI_INDICATION_REL9_TAG:
-					pdu->cqi_indication_rel9.tl = generic_tl;
-					if(unpack_cqi_indication_rel9_value(&pdu->cqi_indication_rel9, ppReadPackedMsg, end) == 0)
-						return 0;
-
-					break;
-				case NFAPI_UL_CQI_INFORMATION_TAG:
-					pdu->ul_cqi_information.tl = generic_tl;
-					if(unpack_ul_cqi_information_value(&pdu->ul_cqi_information, ppReadPackedMsg, end) == 0)
-						return 0;
-					break;
-				default:
-					{
-						NFAPI_TRACE(NFAPI_TRACE_ERROR, "RX_CQI.indication Invalid pdu type %d \n", generic_tl.tag );
-					}
-					break;
-
-			};
-		}
-	}
-
-	uint8_t idx = 0;
-	for(idx = 0; idx < value->number_of_cqis; ++idx)
-	{
-		if(value->cqi_pdu_list[idx].cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG)
-		{
-			if(pullarray8(ppReadPackedMsg, &(value->cqi_raw_pdu_list[idx].pdu[0]), NFAPI_CQI_RAW_MAX_LEN, value->cqi_pdu_list[idx].cqi_indication_rel8.length, end) == 0)
-				return 0;
-		}
-		else if(value->cqi_pdu_list[idx].cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG)
-		{
-			if(pullarray8(ppReadPackedMsg, &(value->cqi_raw_pdu_list[idx].pdu[0]), NFAPI_CQI_RAW_MAX_LEN, value->cqi_pdu_list[idx].cqi_indication_rel9.length, end) == 0)
-				return 0;
-		}
-	}
-
-
-	return 1;
-
-}
-
-static uint8_t unpack_cqi_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_cqi_indication_t *pNfapiMsg = (nfapi_cqi_indication_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_CQI_INDICATION_BODY_TAG, &pNfapiMsg->cqi_indication_body, &unpack_cqi_indication_body_value},
-	};
-
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-static uint8_t unpack_lbt_pdsch_req_pdu_rel13_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_lbt_pdsch_req_pdu_rel13_t* value = (nfapi_lbt_pdsch_req_pdu_rel13_t*)tlv;
-
-	return (pull32(ppReadPackedMsg, &value->handle, end) &&
-			pull32(ppReadPackedMsg, &value->mp_cca, end) &&
-			pull32(ppReadPackedMsg, &value->n_cca, end) &&
-			pull32(ppReadPackedMsg, &value->offset, end) &&
-			pull32(ppReadPackedMsg, &value->lte_txop_sf, end) &&
-			pull16(ppReadPackedMsg, &value->txop_sfn_sf_end, end) &&
-			pull32(ppReadPackedMsg, &value->lbt_mode, end));
-}
-
-static uint8_t unpack_lbt_drs_req_pdu_rel13_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_lbt_drs_req_pdu_rel13_t* value = (nfapi_lbt_drs_req_pdu_rel13_t*)tlv;
-
-	return (pull32(ppReadPackedMsg, &value->handle, end) &&
-			pull32(ppReadPackedMsg, &value->offset, end) &&
-			pull16(ppReadPackedMsg, &value->sfn_sf_end, end) &&
-			pull32(ppReadPackedMsg, &value->lbt_mode, end));
-}
-
-
-static uint8_t unpack_lbt_config_request_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_lbt_dl_config_request_body_t* value = (nfapi_lbt_dl_config_request_body_t*)tlv;
-
-	if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0)
-		return 0;
-
-	if(value->number_of_pdus > NFAPI_LBT_DL_CONFIG_REQ_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of lbt dl config pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_LBT_DL_CONFIG_REQ_MAX_PDU);
-		return 0;		
-	}
-
-	if(value->number_of_pdus)
-	{
-		value->lbt_dl_config_req_pdu_list = (nfapi_lbt_dl_config_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_lbt_dl_config_request_pdu_t) * value->number_of_pdus, config);
-		if(value->lbt_dl_config_req_pdu_list == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate lbt dl config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus);
-			return 0;
-		}
-	}
-	else
-	{
-		value->lbt_dl_config_req_pdu_list = 0;
-	}
-
-
-	uint16_t i;
-	uint16_t total_number_of_pdus = value->number_of_pdus;
-	for(i = 0; i < total_number_of_pdus; ++i)
-	{
-		nfapi_lbt_dl_config_request_pdu_t* pdu = &(value->lbt_dl_config_req_pdu_list[i]);
-
-		if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) &&
-			 pull8(ppReadPackedMsg, &pdu->pdu_size, end)))
-			return 0;
-			
-		uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2;
-
-		if(packedPduEnd > end)
-			return 0;
-
-		switch(pdu->pdu_type)
-		{
-			case NFAPI_LBT_DL_CONFIG_REQUEST_PDSCH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_LBT_PDSCH_REQ_PDU_REL13_TAG, &pdu->lbt_pdsch_req_pdu.lbt_pdsch_req_pdu_rel13, &unpack_lbt_pdsch_req_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_LBT_DL_CONFIG_REQUEST_DRS_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_LBT_DRS_REQ_PDU_REL13_TAG, &pdu->lbt_drs_req_pdu.lbt_drs_req_pdu_rel13, &unpack_lbt_drs_req_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			default:
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL_CONFIG.request body invalid pdu type %d\n", pdu->pdu_type);
-				return 0;
-		}
-	}
-
-	return 1;
-}
-static uint8_t unpack_lbt_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_lbt_dl_config_request_t *pNfapiMsg = (nfapi_lbt_dl_config_request_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_LBT_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->lbt_dl_config_request_body, &unpack_lbt_config_request_body_value},
-	};
-	
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_lbt_pdsch_rsp_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_lbt_pdsch_rsp_pdu_rel13_t* value = (nfapi_lbt_pdsch_rsp_pdu_rel13_t*)tlv;
-	
-	return (pull32(ppReadPackedMsg, &value->handle, end) &&
-			pull32(ppReadPackedMsg, &value->result, end) &&
-			pull32(ppReadPackedMsg, &value->lte_txop_symbols, end) &&
-			pull32(ppReadPackedMsg, &value->initial_partial_sf, end));
-	
-}
-static uint8_t unpack_lbt_drs_rsp_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_lbt_drs_rsp_pdu_rel13_t* value = (nfapi_lbt_drs_rsp_pdu_rel13_t*)tlv;
-	
-	return (pull32(ppReadPackedMsg, &value->handle, end) &&
-			pull32(ppReadPackedMsg, &value->result, end));
-}
-
-static uint8_t unpack_lbt_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_lbt_dl_indication_body_t* value = (nfapi_lbt_dl_indication_body_t*)tlv;
-
-	if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0)
-		return 0;
-
-	if(value->number_of_pdus > NFAPI_LBT_IND_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of lbt dl ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_LBT_IND_MAX_PDU);
-		return 0;		
-	}
-
-	if(value->number_of_pdus > 0)
-	{
-		value->lbt_indication_pdu_list = (nfapi_lbt_dl_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_lbt_dl_indication_pdu_t) * value->number_of_pdus, config);
-		if(value->lbt_indication_pdu_list == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate lbt dl ind config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus);
-			return 0;
-		}
-	}
-	else
-	{
-		value->lbt_indication_pdu_list = 0;
-	}
-
-	uint16_t i;
-	uint16_t total_number_of_pdus = value->number_of_pdus;
-	for(i = 0; i < total_number_of_pdus; ++i)
-	{
-		nfapi_lbt_dl_indication_pdu_t* pdu = &(value->lbt_indication_pdu_list[i]);
-
-		if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) &&
-			 pull8(ppReadPackedMsg, &pdu->pdu_size, end)))
-			return 0;
-			
-		uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2;
-
-		if(packedPduEnd > end)
-			return 0;
-
-		switch(pdu->pdu_type)
-		{
-			case NFAPI_LBT_DL_RSP_PDSCH_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_LBT_PDSCH_RSP_PDU_REL13_TAG, &pdu->lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13, &unpack_lbt_pdsch_rsp_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			case NFAPI_LBT_DL_RSP_DRS_PDU_TYPE:
-				{
-					unpack_tlv_t unpack_fns[] =
-					{
-						{ NFAPI_LBT_DRS_RSP_PDU_REL13_TAG, &pdu->lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13, &unpack_lbt_drs_rsp_pdu_rel13_value},
-					};
-
-					unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
-				}
-				break;
-			default:
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL.indication body invalid pdu type %d\n", pdu->pdu_type);
-				return 0;
-		}
-	}
-
-	return 1;
-}
-static uint8_t unpack_lbt_dl_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_lbt_dl_indication_t *pNfapiMsg = (nfapi_lbt_dl_indication_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_LBT_DL_INDICATION_BODY_TAG, &pNfapiMsg->lbt_dl_indication_body, &unpack_lbt_indication_body_value},
-	};
-
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_nb_harq_indication_fdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nb_harq_indication_fdd_rel13_t* value = (nfapi_nb_harq_indication_fdd_rel13_t*)tlv;
-	return (pull8(ppReadPackedMsg, &value->harq_tb1, end));
-}
-
-
-static uint8_t unpack_nb_harq_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nb_harq_indication_body_t* value = (nfapi_nb_harq_indication_body_t*)tlv;
-	uint8_t* nbharqBodyEnd = *ppReadPackedMsg + value->tl.length;
-
-	if(nbharqBodyEnd > end)
-		return 0;
-
-	if(pull16(ppReadPackedMsg, &value->number_of_harqs, end) == 0)
-		return 0;
-
-	if(value->number_of_harqs > NFAPI_HARQ_IND_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of harq ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_harqs, NFAPI_HARQ_IND_MAX_PDU);
-		return 0;		
-	}
-
-	value->nb_harq_pdu_list = (nfapi_nb_harq_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_nb_harq_indication_pdu_t) * value->number_of_harqs, config);
-	if(value->nb_harq_pdu_list == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_harqs);
-		return 0;
-	}
-	
-	uint8_t i = 0;
-	for(i = 0; i < value->number_of_harqs; ++i)
-	{
-		nfapi_nb_harq_indication_pdu_t* pdu = &(value->nb_harq_pdu_list[i]);
-		if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
-			return 0;
-
-		uint8_t* harqPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
-
-		unpack_tlv_t unpack_fns[] =
-		{
-			{ NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value },
-			{ NFAPI_NB_HARQ_INDICATION_FDD_REL13_TAG, &pdu->nb_harq_indication_fdd_rel13, &unpack_nb_harq_indication_fdd_rel13_value},
-			{ NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, &unpack_ul_cqi_information_value}
-		};
-
-		if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, harqPduInstanceEnd, 0, 0) == 0)
-			return 0;
-	
-	}
-
-	return 1;
-}
-
-static uint8_t unpack_nb_harq_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nb_harq_indication_t *pNfapiMsg = (nfapi_nb_harq_indication_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_NB_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->nb_harq_indication_body, &unpack_nb_harq_indication_body_value},
-	};
-
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_nrach_indication_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-	nfapi_nrach_indication_pdu_rel13_t* value = (nfapi_nrach_indication_pdu_rel13_t*)tlv;
-	
-	return (pull16(ppReadPackedMsg, &value->rnti, end) && 
-			pull8(ppReadPackedMsg, &value->initial_sc, end) &&
-			pull16(ppReadPackedMsg, &value->timing_advance, end) &&
-			pull8(ppReadPackedMsg, &value->nrach_ce_level, end));
-}
-
-static uint8_t unpack_ue_release_resp(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg;
-	if(pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) == 0){
-		return 0;
-	}
-	else{
-		NFAPI_TRACE(NFAPI_TRACE_INFO, "ue_release_response:error_code = %d\n", pNfapiMsg->error_code);
-	}
-	return 1;
-}
-
-static uint8_t unpack_nrach_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nrach_indication_body_t* value = (nfapi_nrach_indication_body_t*)tlv;
-	uint8_t* nrachBodyEnd = *ppReadPackedMsg + value->tl.length;
-
-	if(nrachBodyEnd > end)
-		return 0;
-
-	if(pull8(ppReadPackedMsg, &value->number_of_initial_scs_detected, end) == 0)
-		return 0;
-
-	if(value->number_of_initial_scs_detected > NFAPI_PREAMBLE_MAX_PDU)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of detected scs ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_initial_scs_detected, NFAPI_PREAMBLE_MAX_PDU);
-		return 0;		
-	}
-
-	value->nrach_pdu_list = (nfapi_nrach_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_nrach_indication_pdu_t) * value->number_of_initial_scs_detected, config);
-	if(value->nrach_pdu_list == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate nrach ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_initial_scs_detected);
-		return 0;
-	}
-	
-	uint8_t i = 0;
-	for(i = 0; i < value->number_of_initial_scs_detected; ++i)
-	{
-		nfapi_nrach_indication_pdu_t* pdu = &(value->nrach_pdu_list[i]);
-
-		uint8_t* nrachPduInstanceEnd = *ppReadPackedMsg + 4 + 6;
-
-		unpack_tlv_t unpack_fns[] =
-		{
-			{ NFAPI_NRACH_INDICATION_REL13_TAG, &pdu->nrach_indication_rel13, &unpack_nrach_indication_rel13_value},
-		};
-
-		if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, nrachPduInstanceEnd, 0, 0) == 0)
-			return 0;
-	
-	}
-
-	return 1;
-}
-
-static uint8_t unpack_nrach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nrach_indication_t *pNfapiMsg = (nfapi_nrach_indication_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-		{ NFAPI_NRACH_INDICATION_BODY_TAG, &pNfapiMsg->nrach_indication_body, &unpack_nrach_indication_body_value},
-	};
-
-	return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_nr_dl_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_dl_node_sync_t *pNfapiMsg = (nfapi_nr_dl_node_sync_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-	};
-
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) && 
-			pulls32(ppReadPackedMsg, &pNfapiMsg->delta_sfn_slot, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_dl_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_dl_node_sync_t *pNfapiMsg = (nfapi_dl_node_sync_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-	};
-
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) && 
-			pulls32(ppReadPackedMsg, &pNfapiMsg->delta_sfn_sf, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-
-static uint8_t unpack_nr_ul_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_ul_node_sync_t *pNfapiMsg = (nfapi_nr_ul_node_sync_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-	};
-
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->t2, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->t3, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-
-static uint8_t unpack_ul_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_ul_node_sync_t *pNfapiMsg = (nfapi_ul_node_sync_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-	};
-
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->t2, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->t3, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-static uint8_t unpack_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_timing_info_t *pNfapiMsg = (nfapi_timing_info_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-	};
-    
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->last_sfn_sf, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->time_since_last_timing_info, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->dl_config_jitter, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->tx_request_jitter, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->ul_config_jitter, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_jitter, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->dl_config_latest_delay, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->tx_request_latest_delay, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->ul_config_latest_delay, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_latest_delay, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->dl_config_earliest_arrival, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->tx_request_earliest_arrival, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->ul_config_earliest_arrival, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_earliest_arrival, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-
-static uint8_t unpack_nr_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
-	nfapi_nr_timing_info_t *pNfapiMsg = (nfapi_nr_timing_info_t*)msg;
-
-	unpack_p7_tlv_t unpack_fns[] =
-	{
-	};
-    
-	return (pull32(ppReadPackedMsg, &pNfapiMsg->last_sfn, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->last_slot, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->time_since_last_timing_info, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->dl_tti_jitter, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->tx_data_request_jitter, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->ul_tti_jitter, end) &&
-			pull32(ppReadPackedMsg, &pNfapiMsg->ul_dci_jitter, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->dl_tti_latest_delay, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->tx_data_request_latest_delay, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->ul_tti_latest_delay, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->ul_dci_latest_delay, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->dl_tti_earliest_arrival, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->tx_data_request_earliest_arrival, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->ul_tti_earliest_arrival, end) &&
-			pulls32(ppReadPackedMsg, &pNfapiMsg->ul_dci_earliest_arrival, end) &&
-			unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
-}
-
-
-
-// unpack length check
-
-static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen)
-{
-	int retLen = 0;
-
-	switch (msgId)
-	{
-		case NFAPI_DL_CONFIG_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_dl_config_request_t))
-				retLen = sizeof(nfapi_dl_config_request_t);
-			break;
-
-		case NFAPI_UL_CONFIG_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_ul_config_request_t))
-				retLen = sizeof(nfapi_ul_config_request_t);
-			break;
-
-		case NFAPI_SUBFRAME_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_subframe_indication_t))
-				retLen = sizeof(nfapi_subframe_indication_t);
-			break;
-
-		case NFAPI_HI_DCI0_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_hi_dci0_request_t))
-				retLen = sizeof(nfapi_hi_dci0_request_t);
-			break;
-
-		case NFAPI_TX_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_tx_request_t))
-				retLen = sizeof(nfapi_tx_request_t);
-			break;
-
-		case NFAPI_HARQ_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_harq_indication_t))
-				retLen = sizeof(nfapi_harq_indication_t);
-			break;
-
-		case NFAPI_CRC_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_crc_indication_t))
-				retLen = sizeof(nfapi_crc_indication_t);
-			break;
-
-		case NFAPI_RX_ULSCH_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_rx_indication_t))
-				retLen = sizeof(nfapi_rx_indication_t);
-			break;
-
-		case NFAPI_RACH_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_rach_indication_t))
-				retLen = sizeof(nfapi_rach_indication_t);
-			break;
-
-		case NFAPI_SRS_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_srs_indication_t))
-				retLen = sizeof(nfapi_srs_indication_t);
-			break;
-
-		case NFAPI_RX_SR_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_sr_indication_t))
-				retLen = sizeof(nfapi_sr_indication_t);
-			break;
-
-		case NFAPI_RX_CQI_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_cqi_indication_t))
-				retLen = sizeof(nfapi_cqi_indication_t);
-			break;
-
-		case NFAPI_LBT_DL_CONFIG_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_lbt_dl_config_request_t))
-				retLen = sizeof(nfapi_lbt_dl_config_request_t);
-			break;
-
-		case NFAPI_LBT_DL_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_lbt_dl_indication_t))
-				retLen = sizeof(nfapi_lbt_dl_indication_t);
-			break;
-	
-		case NFAPI_NB_HARQ_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_nb_harq_indication_t))
-				retLen = sizeof(nfapi_nb_harq_indication_t);
-			break;
-			
-		case NFAPI_NRACH_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_nrach_indication_t))
-				retLen = sizeof(nfapi_nrach_indication_t);
-			break;			
-			
-		case NFAPI_DL_NODE_SYNC:
-			if (unpackedBufLen >= sizeof(nfapi_dl_node_sync_t))
-				retLen = sizeof(nfapi_dl_node_sync_t);
-			break;
-
-		case NFAPI_UL_NODE_SYNC:
-			if (unpackedBufLen >= sizeof(nfapi_ul_node_sync_t))
-				retLen = sizeof(nfapi_ul_node_sync_t);
-			break;
-
-		case NFAPI_TIMING_INFO:
-			if (unpackedBufLen >= sizeof(nfapi_timing_info_t))
-				retLen = sizeof(nfapi_timing_info_t);
-			break;
-
-		case NFAPI_UE_RELEASE_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_ue_release_request_t))
-				retLen = sizeof(nfapi_ue_release_request_t);
-			break;
-
-		case NFAPI_UE_RELEASE_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_ue_release_response_t))
-				retLen = sizeof(nfapi_ue_release_response_t);
-			break;
-
-		default:
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId);
-			break;
-	}
-
-	return retLen;
-}
-
-static int check_nr_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen)
-{
-	int retLen = 0;
-
-	switch (msgId)
-	{
-		case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_dl_tti_request_t))
-				retLen = sizeof(nfapi_nr_dl_tti_request_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_ul_tti_request_t))
-				retLen = sizeof(nfapi_nr_ul_tti_request_t);
-			break;
-
-		case NFAPI_SUBFRAME_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_subframe_indication_t))
-				retLen = sizeof(nfapi_subframe_indication_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_ul_dci_request_t))
-				retLen = sizeof(nfapi_nr_ul_dci_request_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_tx_data_request_t))
-				retLen = sizeof(nfapi_nr_tx_data_request_t);
-			break;
-
-		case NFAPI_HARQ_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_harq_indication_t))
-				retLen = sizeof(nfapi_harq_indication_t);
-			break;
-
-		case NFAPI_CRC_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_crc_indication_t))
-				retLen = sizeof(nfapi_crc_indication_t);
-			break;
-
-		case NFAPI_RX_ULSCH_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_rx_indication_t))
-				retLen = sizeof(nfapi_rx_indication_t);
-			break;
-
-		case NFAPI_RACH_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_rach_indication_t))
-				retLen = sizeof(nfapi_rach_indication_t);
-			break;
-
-		case NFAPI_SRS_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_srs_indication_t))
-				retLen = sizeof(nfapi_srs_indication_t);
-			break;
-
-		case NFAPI_RX_SR_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_sr_indication_t))
-				retLen = sizeof(nfapi_sr_indication_t);
-			break;
-
-		case NFAPI_RX_CQI_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_cqi_indication_t))
-				retLen = sizeof(nfapi_cqi_indication_t);
-			break;
-
-		case NFAPI_LBT_DL_CONFIG_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_lbt_dl_config_request_t))
-				retLen = sizeof(nfapi_lbt_dl_config_request_t);
-			break;
-
-		case NFAPI_LBT_DL_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_lbt_dl_indication_t))
-				retLen = sizeof(nfapi_lbt_dl_indication_t);
-			break;
-	
-		case NFAPI_NB_HARQ_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_nb_harq_indication_t))
-				retLen = sizeof(nfapi_nb_harq_indication_t);
-			break;
-			
-		case NFAPI_NRACH_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_nrach_indication_t))
-				retLen = sizeof(nfapi_nrach_indication_t);
-			break;			
-			
-		case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
-			if (unpackedBufLen >= sizeof(nfapi_nr_dl_node_sync_t))
-				retLen = sizeof(nfapi_nr_dl_node_sync_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
-			if (unpackedBufLen >= sizeof(nfapi_nr_ul_node_sync_t))
-				retLen = sizeof(nfapi_nr_ul_node_sync_t);
-			break;
-
-		case NFAPI_TIMING_INFO:
-			if (unpackedBufLen >= sizeof(nfapi_timing_info_t))
-				retLen = sizeof(nfapi_timing_info_t);
-			break;
-
-		case NFAPI_UE_RELEASE_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_ue_release_request_t))
-				retLen = sizeof(nfapi_ue_release_request_t);
-			break;
-
-		case NFAPI_UE_RELEASE_RESPONSE:
-			if (unpackedBufLen >= sizeof(nfapi_ue_release_response_t))
-				retLen = sizeof(nfapi_ue_release_response_t);
-			break;
-
-		default:
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId);
-			break;
-	}
-
-	return retLen;
-}
-
-
-
-// Main unpack functions - public
-
-int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config)
-{
-	nfapi_p7_message_header_t *pMessageHeader = pUnpackedBuf;
-	uint8_t *pReadPackedMessage = pMessageBuf;
-	uint8_t *end = pMessageBuf + messageBufLen;
-
-	if (pMessageBuf == NULL || pUnpackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied pointers are null\n");
-		return -1;
-	}
-
-	if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
-		return -1;
-	}
-
-	// process the header
-	if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) &&
-		 pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) &&
-		 pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end)))
-		return -1;
-
-	return 0;
-}
-
-int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config)
-{
-	int result = 0;
-	nfapi_p7_message_header_t *pMessageHeader = (nfapi_p7_message_header_t*)pUnpackedBuf;
-	uint8_t *pReadPackedMessage = pMessageBuf;
-	uint8_t *end = pMessageBuf + messageBufLen;
-
-	if (pMessageBuf == NULL || pUnpackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n");
-		return -1;
-	}
-
-	if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
-		return -1;
-	}
-  /*
-    uint8_t *ptr = pMessageBuf;
-	printf("\n Read P7 message unpack: ");
-	while(ptr < end){
-		printf(" %d ", *ptr);
-		ptr++;
-	}
-	printf("\n");
-*/
-	// clean the supplied buffer for - tag value blanking
-	(void)memset(pUnpackedBuf, 0, unpackedBufLen);
-
-	// process the header
-	if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) &&
-		 pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) &&
-		 pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end)))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n");
-		return -1;
-	}
-
-	if((uint8_t*)(pMessageBuf + pMessageHeader->message_length) > end)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
-		return -1;
-	}
-
-	/*
-	if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack unpack buffer is not large enough \n");
-		return -1;
-	}
-	*/
-
-	// look for the specific message
-	switch (pMessageHeader->message_id)
-	{   
-		case NFAPI_DL_CONFIG_REQUEST:
-			if (check_unpack_length(NFAPI_DL_CONFIG_REQUEST, unpackedBufLen))
-				result = unpack_dl_config_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_UL_CONFIG_REQUEST:
-			if (check_unpack_length(NFAPI_UL_CONFIG_REQUEST, unpackedBufLen))
-				result = unpack_ul_config_request(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-		case NFAPI_TX_REQUEST:
-			if (check_unpack_length(NFAPI_TX_REQUEST, unpackedBufLen))
-				result = unpack_tx_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-			case NFAPI_HI_DCI0_REQUEST:
-			if (check_unpack_length(NFAPI_HI_DCI0_REQUEST, unpackedBufLen))
-				result = unpack_hi_dci0_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_UE_RELEASE_REQUEST:
-			if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen))
-				result = unpack_ue_release_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_HARQ_INDICATION:
-			if (check_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen))
-				result = unpack_harq_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_CRC_INDICATION:
-			if (check_unpack_length(NFAPI_CRC_INDICATION, unpackedBufLen))
-				result = unpack_crc_indication(&pReadPackedMessage,end , pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_RX_ULSCH_INDICATION:
-			if (check_unpack_length(NFAPI_RX_ULSCH_INDICATION, unpackedBufLen))
-				result = unpack_rx_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_RACH_INDICATION:
-			if (check_unpack_length(NFAPI_RACH_INDICATION, unpackedBufLen))
-				result = unpack_rach_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_SRS_INDICATION:
-			if (check_unpack_length(NFAPI_SRS_INDICATION, unpackedBufLen))
-				result = unpack_srs_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_RX_SR_INDICATION:
-			if (check_unpack_length(NFAPI_RX_SR_INDICATION, unpackedBufLen))
-				result = unpack_sr_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_RX_CQI_INDICATION:
-			if (check_unpack_length(NFAPI_RX_CQI_INDICATION, unpackedBufLen))
-				result = unpack_cqi_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_LBT_DL_CONFIG_REQUEST:
-			if (check_unpack_length(NFAPI_LBT_DL_CONFIG_REQUEST, unpackedBufLen))
-				result = unpack_lbt_dl_config_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_LBT_DL_INDICATION:
-			if (check_unpack_length(NFAPI_LBT_DL_INDICATION, unpackedBufLen))
-				result = unpack_lbt_dl_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-			
-		case NFAPI_NB_HARQ_INDICATION:
-			if (check_unpack_length(NFAPI_NB_HARQ_INDICATION, unpackedBufLen))
-				result = unpack_nb_harq_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;	
-			
-		case NFAPI_NRACH_INDICATION:
-			if (check_unpack_length(NFAPI_NRACH_INDICATION, unpackedBufLen))
-				result = unpack_nrach_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-			
-		case NFAPI_DL_NODE_SYNC:
-			if (check_unpack_length(NFAPI_DL_NODE_SYNC, unpackedBufLen))
-				result = unpack_dl_node_sync(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_UL_NODE_SYNC:
-			if (check_unpack_length(NFAPI_UL_NODE_SYNC, unpackedBufLen))
-				result = unpack_ul_node_sync(&pReadPackedMessage, end , pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_TIMING_INFO:
-			if (check_unpack_length(NFAPI_TIMING_INFO, unpackedBufLen))
-				result = unpack_timing_info(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_UE_RELEASE_RESPONSE:
-			if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen))
-				result = unpack_ue_release_resp(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		default:
-
-			if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && 
-			   pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
-			{
-				if(config && config->unpack_p7_vendor_extension)
-				{
-					result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
-				}
-			}
-			else
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
-			}
-			break;
-	}
-
-	if(result == 0)
-		return -1;
-	else 
-		return 0;
-}
-
-int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config)
-{
-	int result = 0;
-	nfapi_p7_message_header_t *pMessageHeader = (nfapi_p7_message_header_t*)pUnpackedBuf;
-	uint8_t *pReadPackedMessage = pMessageBuf;
-	uint8_t *end = pMessageBuf + messageBufLen;
-
-	if (pMessageBuf == NULL || pUnpackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n");
-		return -1;
-	}
-
-	if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
-		return -1;
-	}
-  /*
-    uint8_t *ptr = pMessageBuf;
-	printf("\n Read P7 message unpack: ");
-	while(ptr < end){
-		printf(" %d ", *ptr);
-		ptr++;
-	}
-	printf("\n");
-*/
-	// clean the supplied buffer for - tag value blanking
-	(void)memset(pUnpackedBuf, 0, unpackedBufLen);
-
-	// process the header
-	if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) &&
-		 pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) &&
-		 pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end)))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n");
-		return -1;
-	}
-
-	if((uint8_t*)(pMessageBuf + pMessageHeader->message_length) > end)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
-		return -1;
-	}
-
-	/*
-	if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack unpack buffer is not large enough \n");
-		return -1;
-	}
-	*/
-
-	// look for the specific message
-	switch (pMessageHeader->message_id)
-	{   
-		case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST, unpackedBufLen))
-				result = unpack_dl_tti_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST, unpackedBufLen))
-				result = unpack_ul_tti_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST, unpackedBufLen))
-				result = unpack_tx_data_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST, unpackedBufLen))
-				result = unpack_ul_dci_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-		
-		case NFAPI_UE_RELEASE_REQUEST:
-			if (check_nr_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen))
-				result = unpack_ue_release_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_HARQ_INDICATION:
-			if (check_nr_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen))
-				result = unpack_harq_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_CRC_INDICATION:
-			if (check_nr_unpack_length(NFAPI_CRC_INDICATION, unpackedBufLen))
-				result = unpack_crc_indication(&pReadPackedMessage,end , pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_RX_ULSCH_INDICATION:
-			if (check_nr_unpack_length(NFAPI_RX_ULSCH_INDICATION, unpackedBufLen))
-				result = unpack_rx_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_RACH_INDICATION:
-			if (check_nr_unpack_length(NFAPI_RACH_INDICATION, unpackedBufLen))
-				result = unpack_rach_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_SRS_INDICATION:
-			if (check_nr_unpack_length(NFAPI_SRS_INDICATION, unpackedBufLen))
-				result = unpack_srs_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_RX_SR_INDICATION:
-			if (check_nr_unpack_length(NFAPI_RX_SR_INDICATION, unpackedBufLen))
-				result = unpack_sr_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_RX_CQI_INDICATION:
-			if (check_nr_unpack_length(NFAPI_RX_CQI_INDICATION, unpackedBufLen))
-				result = unpack_cqi_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_LBT_DL_CONFIG_REQUEST:
-			if (check_nr_unpack_length(NFAPI_LBT_DL_CONFIG_REQUEST, unpackedBufLen))
-				result = unpack_lbt_dl_config_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_LBT_DL_INDICATION:
-			if (check_nr_unpack_length(NFAPI_LBT_DL_INDICATION, unpackedBufLen))
-				result = unpack_lbt_dl_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-			
-		case NFAPI_NB_HARQ_INDICATION:
-			if (check_nr_unpack_length(NFAPI_NB_HARQ_INDICATION, unpackedBufLen))
-				result = unpack_nb_harq_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;	
-			
-		case NFAPI_NRACH_INDICATION:
-			if (check_nr_unpack_length(NFAPI_NRACH_INDICATION, unpackedBufLen))
-				result = unpack_nrach_indication(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-			
-		case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC, unpackedBufLen))
-				result = unpack_nr_dl_node_sync(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC, unpackedBufLen))
-				result = unpack_nr_ul_node_sync(&pReadPackedMessage, end , pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_TIMING_INFO:
-			if (check_nr_unpack_length(NFAPI_TIMING_INFO, unpackedBufLen))
-				result = unpack_nr_timing_info(&pReadPackedMessage, end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		case NFAPI_UE_RELEASE_RESPONSE:
-			if (check_nr_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen))
-				result = unpack_ue_release_resp(&pReadPackedMessage,  end, pMessageHeader, config);
-			else
-				return -1;
-			break;
-
-		default:
-
-			if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && 
-			   pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
-			{
-				if(config && config->unpack_p7_vendor_extension)
-				{
-					result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
-				}
-			}
-			else
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
-			}
-			break;
-	}
-
-	if(result == 0)
-		return -1;
-	else 
-		return 0;
-}
-
-
+/*
+ * Copyright 2017 Cisco Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+
+#include <assert.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <zlib.h>
+#include <sched.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdint.h>
+
+#include <nfapi_interface.h>
+#include <nfapi.h>
+#include <debug.h>
+#include "nfapi_nr_interface_scf.h"
+
+extern int nfapi_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppReadPackedMsg, void *user_data);
+extern int nfapi_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppWritePackedMsg, void *user_data);
+
+uint32_t nfapi_calculate_checksum(uint8_t *buffer, uint16_t len) {
+  uint32_t chksum = 0;
+  // calcaulte upto the checksum
+  chksum = crc32(chksum, buffer, 8);
+  // skip the checksum
+  uint8_t zeros[4] = {0, 0, 0, 0};
+  chksum = crc32(chksum, zeros, 4);
+  // continu with the rest of the mesage
+  chksum = crc32(chksum, &buffer[NFAPI_P7_HEADER_LENGTH], len - NFAPI_P7_HEADER_LENGTH);
+  // return the inverse
+  return ~(chksum);
+}
+
+int nfapi_p7_update_checksum(uint8_t *buffer, uint32_t len) {
+  uint32_t checksum = nfapi_calculate_checksum(buffer, len);
+  uint8_t *p_write = &buffer[8];
+  return (push32(checksum, &p_write, buffer + len) > 0 ? 0 : -1);
+}
+
+int nfapi_p7_update_transmit_timestamp(uint8_t *buffer, uint32_t timestamp) {
+  uint8_t *p_write = &buffer[12];
+  return (push32(timestamp, &p_write, buffer + 16) > 0 ? 0 : -1);
+}
+
+uint32_t nfapi_p7_calculate_checksum(uint8_t *buffer, uint32_t len) {
+  return nfapi_calculate_checksum(buffer, len);
+}
+
+void *nfapi_p7_allocate(size_t size, nfapi_p7_codec_config_t *config) {
+  if(size == 0)
+    return 0;
+
+  void *buffer_p = NULL;
+
+  if(config && config->allocate) {
+    buffer_p = (config->allocate)(size);
+
+    if(buffer_p != NULL) {
+      memset(buffer_p,0,size);
+    }
+
+    return buffer_p;
+  } else {
+    buffer_p = calloc(1, size);
+    return buffer_p;
+  }
+}
+
+void nfapi_p7_deallocate(void *ptr, nfapi_p7_codec_config_t *config) {
+  if(ptr == NULL)
+    return;
+
+  if(config && config->deallocate) {
+    return (config->deallocate)(ptr);
+  } else {
+    return free(ptr);
+  }
+}
+// Pack routines
+
+
+static uint8_t pack_dl_config_dci_dl_pdu_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_dci_dl_pdu_rel8_t *value = (nfapi_dl_config_dci_dl_pdu_rel8_t *)tlv;
+  //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() dci_format:%u\n", __FUNCTION__, value->dci_format);
+  return ( push8(value->dci_format, ppWritePackedMsg, end) &&
+           push8(value->cce_idx, ppWritePackedMsg, end) &&
+           push8(value->aggregation_level, ppWritePackedMsg, end) &&
+           push16(value->rnti, ppWritePackedMsg, end) &&
+           push8(value->resource_allocation_type, ppWritePackedMsg, end) &&
+           push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) &&
+           push32(value->resource_block_coding, ppWritePackedMsg, end) &&
+           push8(value->mcs_1, ppWritePackedMsg, end) &&
+           push8(value->redundancy_version_1, ppWritePackedMsg, end) &&
+           push8(value->new_data_indicator_1, ppWritePackedMsg, end) &&
+           push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) &&
+           push8(value->mcs_2, ppWritePackedMsg, end) &&
+           push8(value->redundancy_version_2, ppWritePackedMsg, end) &&
+           push8(value->new_data_indicator_2, ppWritePackedMsg, end) &&
+           push8(value->harq_process, ppWritePackedMsg, end) &&
+           push8(value->tpmi, ppWritePackedMsg, end) &&
+           push8(value->pmi, ppWritePackedMsg, end) &&
+           push8(value->precoding_information, ppWritePackedMsg, end) &&
+           push8(value->tpc, ppWritePackedMsg, end) &&
+           push8(value->downlink_assignment_index, ppWritePackedMsg, end) &&
+           push8(value->ngap, ppWritePackedMsg, end) &&
+           push8(value->transport_block_size_index, ppWritePackedMsg, end) &&
+           push8(value->downlink_power_offset, ppWritePackedMsg, end) &&
+           push8(value->allocate_prach_flag, ppWritePackedMsg, end) &&
+           push8(value->preamble_index, ppWritePackedMsg, end) &&
+           push8(value->prach_mask_index, ppWritePackedMsg, end) &&
+           push8(value->rnti_type, ppWritePackedMsg, end) &&
+           push16(value->transmission_power, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_dl_config_dci_dl_pdu_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_dci_dl_pdu_rel9_t *value = (nfapi_dl_config_dci_dl_pdu_rel9_t *)tlv;
+  return( push8(value->mcch_flag, ppWritePackedMsg, end) &&
+          push8(value->mcch_change_notification, ppWritePackedMsg, end) &&
+          push8(value->scrambling_identity, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_dl_config_dci_dl_pdu_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_dci_dl_pdu_rel10_t *value = (nfapi_dl_config_dci_dl_pdu_rel10_t *)tlv;
+  return ( push8(value->cross_carrier_scheduling_flag, ppWritePackedMsg, end) &&
+           push8(value->carrier_indicator, ppWritePackedMsg, end) &&
+           push8(value->srs_flag, ppWritePackedMsg, end) &&
+           push8(value->srs_request, ppWritePackedMsg, end) &&
+           push8(value->antenna_ports_scrambling_and_layers, ppWritePackedMsg, end) &&
+           push8(value->total_dci_length_including_padding, ppWritePackedMsg, end) &&
+           push8(value->n_dl_rb, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_dl_config_dci_dl_pdu_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_dci_dl_pdu_rel11_t *value = (nfapi_dl_config_dci_dl_pdu_rel11_t *)tlv;
+  return ( push8(value->harq_ack_resource_offset, ppWritePackedMsg, end) &&
+           push8(value->pdsch_re_mapping_quasi_co_location_indicator, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_dl_config_dci_dl_pdu_rel12_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_dci_dl_pdu_rel12_t *value = (nfapi_dl_config_dci_dl_pdu_rel12_t *)tlv;
+  return ( push8(value->primary_cell_type, ppWritePackedMsg, end) &&
+           push8(value->ul_dl_configuration_flag, ppWritePackedMsg, end) &&
+           push8(value->number_ul_dl_configurations, ppWritePackedMsg, end) &&
+           pusharray8(value->ul_dl_configuration_indication, NFAPI_MAX_UL_DL_CONFIGURATIONS, value->number_ul_dl_configurations, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_tpm_value(nfapi_dl_config_dci_dl_tpm_t *value, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  if (!( push8(value->num_prb_per_subband, ppWritePackedMsg, end) &&
+         push8(value->number_of_subbands, ppWritePackedMsg, end) &&
+         push8(value->num_antennas, ppWritePackedMsg, end)))
+    return 0;
+
+  uint8_t idx = 0;
+
+  for(idx = 0; idx < value->number_of_subbands; ++idx) {
+    nfapi_dl_config_dci_dl_tpm_subband_info_t *subband_info = &(value->subband_info[idx]);
+
+    if(!(push8(subband_info->subband_index, ppWritePackedMsg, end) &&
+         push8(subband_info->scheduled_ues, ppWritePackedMsg, end)))
+      return 0;
+
+    uint8_t antenna_idx = 0;
+    uint8_t scheduled_ue_idx = 0;
+
+    for(antenna_idx = 0; antenna_idx < value->num_antennas; ++antenna_idx) {
+      for(scheduled_ue_idx = 0; scheduled_ue_idx < subband_info->scheduled_ues; ++scheduled_ue_idx) {
+        if(!push16(subband_info->precoding_value[antenna_idx][scheduled_ue_idx], ppWritePackedMsg, end))
+          return 0;
+      }
+    }
+  }
+
+  return 1;
+}
+
+
+static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
+  return(
+          push16(value->bwp_size, ppWritePackedMsg, end) &&
+          push16(value->bwp_start, ppWritePackedMsg, end) &&
+          push8(value->subcarrier_spacing, ppWritePackedMsg, end) &&
+          push8(value->cyclic_prefix, ppWritePackedMsg, end) &&
+          push16(value->start_rb, ppWritePackedMsg, end) &&
+          push16(value->nr_of_rbs, ppWritePackedMsg, end) &&
+          push8(value->csi_type, ppWritePackedMsg, end) &&
+          push8(value->row, ppWritePackedMsg, end) &&
+          push16(value->freq_domain, ppWritePackedMsg, end) &&
+          push8(value->symb_l0, ppWritePackedMsg, end) &&
+          push8(value->symb_l1, ppWritePackedMsg, end) &&
+          push8(value->cdm_type, ppWritePackedMsg, end) &&
+          push8(value->freq_density, ppWritePackedMsg, end) &&
+          push16(value->scramb_id, ppWritePackedMsg, end) &&
+          push8(value->power_control_offset, ppWritePackedMsg, end) &&
+          push8(value->power_control_offset_ss, ppWritePackedMsg, end)
+        );
+}
+
+
+static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv;
+
+  for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i) {
+    if(!push16(value->dci_pdu[i].RNTI, ppWritePackedMsg, end) &&
+        push16(value->dci_pdu[i].ScramblingId, ppWritePackedMsg, end) &&
+        push16(value->dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end) &&
+        push8(value->dci_pdu[i].CceIndex, ppWritePackedMsg, end) &&
+        push8(value->dci_pdu[i].AggregationLevel, ppWritePackedMsg, end) &&
+        push8(value->dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end) &&
+        push8(value->dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
+        push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
+        pusharray8(value->dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end));
+
+    return 0;
+  }
+
+  // TODO: resolve the packaging of array (currently sending a single element)
+  return(
+          push16(value->BWPSize, ppWritePackedMsg, end) &&
+          push16(value->BWPStart, ppWritePackedMsg, end) &&
+          push8(value->SubcarrierSpacing, ppWritePackedMsg, end) &&
+          push8(value->CyclicPrefix, ppWritePackedMsg, end) &&
+          push8(value->StartSymbolIndex, ppWritePackedMsg, end) &&
+          push8(value->DurationSymbols, ppWritePackedMsg, end) &&
+          pusharray8(value->FreqDomainResource, 6, 6, ppWritePackedMsg, end) &&
+          push8(value->CceRegMappingType, ppWritePackedMsg, end) &&
+          push8(value->RegBundleSize, ppWritePackedMsg, end) &&
+          push8(value->InterleaverSize, ppWritePackedMsg, end) &&
+          push8(value->CoreSetType, ppWritePackedMsg, end) &&
+          push16(value->ShiftIndex, ppWritePackedMsg, end) &&
+          push8(value->precoderGranularity, ppWritePackedMsg, end) &&
+          push16(value->numDlDci, ppWritePackedMsg, end));
+}
+
+
+static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv;
+  // TODO: resolve the packaging of array (currently sending a single element)
+  return(
+          push16(value->pduBitmap, ppWritePackedMsg, end) &&
+          push16(value->rnti, ppWritePackedMsg, end) &&
+          push16(value->pduIndex, ppWritePackedMsg, end) &&
+          push16(value->BWPSize, ppWritePackedMsg, end) &&
+          push16(value->BWPStart, ppWritePackedMsg, end) &&
+          push8(value->SubcarrierSpacing, ppWritePackedMsg, end) &&
+          push8(value->CyclicPrefix, ppWritePackedMsg, end) &&
+          push8(value->NrOfCodewords, ppWritePackedMsg, end) &&
+          pusharray16(value->targetCodeRate, 2, 1, ppWritePackedMsg, end) &&
+          pusharray8(value->qamModOrder, 2, 1, ppWritePackedMsg, end) &&
+          pusharray8(value->mcsIndex, 2, 1, ppWritePackedMsg, end) &&
+          pusharray8(value->mcsTable, 2, 1, ppWritePackedMsg, end) &&
+          pusharray8(value->rvIndex, 2, 1, ppWritePackedMsg, end) &&
+          pusharray32(value->TBSize, 2, 1, ppWritePackedMsg, end) &&
+          push16(value->dataScramblingId, ppWritePackedMsg, end) &&
+          push8(value->nrOfLayers, ppWritePackedMsg, end) &&
+          push8(value->transmissionScheme, ppWritePackedMsg, end) &&
+          push8(value->refPoint, ppWritePackedMsg, end) &&
+          push16(value->dlDmrsSymbPos, ppWritePackedMsg, end) &&
+          push8(value->dmrsConfigType, ppWritePackedMsg, end) &&
+          push16(value->dlDmrsScramblingId, ppWritePackedMsg, end) &&
+          push8(value->SCID, ppWritePackedMsg, end) &&
+          push8(value->numDmrsCdmGrpsNoData, ppWritePackedMsg, end) &&
+          push16(value->dmrsPorts, ppWritePackedMsg, end) &&
+          push8(value->resourceAlloc, ppWritePackedMsg, end) &&
+          push16(value->rbStart, ppWritePackedMsg, end) &&
+          push16(value->rbSize, ppWritePackedMsg, end) &&
+          push8(value->VRBtoPRBMapping, ppWritePackedMsg, end) &&
+          push8(value->StartSymbolIndex, ppWritePackedMsg, end) &&
+          push8(value->NrOfSymbols, ppWritePackedMsg, end) &&
+          push8(value->PTRSPortIndex, ppWritePackedMsg, end) &&
+          push8(value->PTRSTimeDensity, ppWritePackedMsg, end) &&
+          push8(value->PTRSFreqDensity, ppWritePackedMsg, end) &&
+          push8(value->PTRSReOffset, ppWritePackedMsg, end)
+        );
+}
+
+
+static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv;
+  return(
+          push16(value->PhysCellId, ppWritePackedMsg, end) &&
+          push8(value->BetaPss, ppWritePackedMsg, end) &&
+          push8(value->SsbBlockIndex, ppWritePackedMsg, end) &&
+          push8(value->SsbSubcarrierOffset, ppWritePackedMsg, end) &&
+          push16(value->ssbOffsetPointA, ppWritePackedMsg, end) &&
+          push8(value->bchPayloadFlag, ppWritePackedMsg, end) &&
+          push32(value->bchPayload, ppWritePackedMsg, end)
+          // TODO: pack precoding_and_beamforming too
+        );
+}
+
+
+static uint8_t pack_dl_config_dci_dl_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_dci_dl_pdu_rel13_t *value = (nfapi_dl_config_dci_dl_pdu_rel13_t *)tlv;
+  return( push8(value->laa_end_partial_sf_flag, ppWritePackedMsg, end) &&
+          push8(value->laa_end_partial_sf_configuration, ppWritePackedMsg, end) &&
+          push8(value->initial_lbt_sf, ppWritePackedMsg, end) &&
+          push8(value->codebook_size_determination, ppWritePackedMsg, end) &&
+          push8(value->drms_table_flag, ppWritePackedMsg, end) &&
+          push8(value->tpm_struct_flag, ppWritePackedMsg, end) &&
+          (value->tpm_struct_flag == 1 ? pack_tpm_value(&(value->tpm), ppWritePackedMsg, end) : 1));
+}
+
+static uint8_t pack_dl_config_bch_pdu_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_bch_pdu_rel8_t *value = (nfapi_dl_config_bch_pdu_rel8_t *)tlv;
+  //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s()\n", __FUNCTION__);
+  return( push16(value->length, ppWritePackedMsg, end) &&
+          push16(value->pdu_index, ppWritePackedMsg, end) &&
+          push16(value->transmission_power, ppWritePackedMsg, end));
+}
+static uint8_t pack_dl_config_mch_pdu_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_mch_pdu_rel8_t *value = (nfapi_dl_config_mch_pdu_rel8_t *)tlv;
+  return ( push16(value->length, ppWritePackedMsg, end) &&
+           push16(value->pdu_index, ppWritePackedMsg, end) &&
+           push16(value->rnti, ppWritePackedMsg, end) &&
+           push8(value->resource_allocation_type, ppWritePackedMsg, end) &&
+           push32(value->resource_block_coding, ppWritePackedMsg, end) &&
+           push8(value->modulation, ppWritePackedMsg, end) &&
+           push16(value->transmission_power, ppWritePackedMsg, end) &&
+           push16(value->mbsfn_area_id, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_bf_vector_info(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_bf_vector_t *bf = (nfapi_bf_vector_t *)elem;
+  return ( push8(bf->subband_index, ppWritePackedMsg, end) &&
+           push8(bf->num_antennas, ppWritePackedMsg, end) &&
+           pusharray16(bf->bf_value, NFAPI_MAX_NUM_ANTENNAS, bf->num_antennas, ppWritePackedMsg, end));
+}
+static uint8_t pack_dl_config_dlsch_pdu_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_dlsch_pdu_rel8_t *value = (nfapi_dl_config_dlsch_pdu_rel8_t *)tlv;
+  return ( push16(value->length, ppWritePackedMsg, end) &&
+           push16(value->pdu_index, ppWritePackedMsg, end) &&
+           push16(value->rnti, ppWritePackedMsg, end) &&
+           push8(value->resource_allocation_type, ppWritePackedMsg, end) &&
+           push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) &&
+           push32(value->resource_block_coding, ppWritePackedMsg, end) &&
+           push8(value->modulation, ppWritePackedMsg, end) &&
+           push8(value->redundancy_version, ppWritePackedMsg, end) &&
+           push8(value->transport_blocks, ppWritePackedMsg, end) &&
+           push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) &&
+           push8(value->transmission_scheme, ppWritePackedMsg, end) &&
+           push8(value->number_of_layers, ppWritePackedMsg, end) &&
+           push8(value->number_of_subbands, ppWritePackedMsg, end) &&
+           pusharray8(value->codebook_index, NFAPI_MAX_NUM_SUBBANDS, value->number_of_subbands, ppWritePackedMsg, end) &&
+           push8(value->ue_category_capacity, ppWritePackedMsg, end) &&
+           push8(value->pa, ppWritePackedMsg, end) &&
+           push8(value->delta_power_offset_index, ppWritePackedMsg, end) &&
+           push8(value->ngap, ppWritePackedMsg, end) &&
+           push8(value->nprb, ppWritePackedMsg, end) &&
+           push8(value->transmission_mode, ppWritePackedMsg, end) &&
+           push8(value->num_bf_prb_per_subband, ppWritePackedMsg, end) &&
+           push8(value->num_bf_vector, ppWritePackedMsg, end) &&
+           packarray(value->bf_vector, sizeof(nfapi_bf_vector_t), NFAPI_MAX_BF_VECTORS, value->num_bf_vector, ppWritePackedMsg, end, &pack_bf_vector_info));
+}
+static uint8_t pack_dl_config_dlsch_pdu_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_dlsch_pdu_rel9_t *value = (nfapi_dl_config_dlsch_pdu_rel9_t *)tlv;
+  return ( push8(value->nscid, ppWritePackedMsg, end) );
+}
+static uint8_t pack_dl_config_dlsch_pdu_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_dlsch_pdu_rel10_t *value = (nfapi_dl_config_dlsch_pdu_rel10_t *)tlv;
+  return ( push8(value->csi_rs_flag, ppWritePackedMsg, end) &&
+           push8(value->csi_rs_resource_config_r10, ppWritePackedMsg, end) &&
+           push16(value->csi_rs_zero_tx_power_resource_config_bitmap_r10, ppWritePackedMsg, end) &&
+           push8(value->csi_rs_number_nzp_configuration, ppWritePackedMsg, end) &&
+           pusharray8(value->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, value->csi_rs_number_nzp_configuration, ppWritePackedMsg, end) &&
+           push8(value->pdsch_start, ppWritePackedMsg, end));
+}
+static uint8_t pack_dl_config_dlsch_pdu_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_dlsch_pdu_rel11_t *value = (nfapi_dl_config_dlsch_pdu_rel11_t *)tlv;
+  return( push8(value->drms_config_flag, ppWritePackedMsg, end) &&
+          push16(value->drms_scrambling, ppWritePackedMsg, end) &&
+          push8(value->csi_config_flag, ppWritePackedMsg, end) &&
+          push16(value->csi_scrambling, ppWritePackedMsg, end) &&
+          push8(value->pdsch_re_mapping_flag, ppWritePackedMsg, end) &&
+          push8(value->pdsch_re_mapping_atenna_ports, ppWritePackedMsg, end) &&
+          push8(value->pdsch_re_mapping_freq_shift, ppWritePackedMsg, end));
+}
+static uint8_t pack_dl_config_dlsch_pdu_rel12_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_dlsch_pdu_rel12_t *value = (nfapi_dl_config_dlsch_pdu_rel12_t *)tlv;
+  return( push8(value->altcqi_table_r12, ppWritePackedMsg, end) &&
+          push8(value->maxlayers, ppWritePackedMsg, end) &&
+          push8(value->n_dl_harq, ppWritePackedMsg, end));
+}
+static uint8_t pack_dl_config_dlsch_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_dlsch_pdu_rel13_t *value = (nfapi_dl_config_dlsch_pdu_rel13_t *)tlv;
+  return( push8(value->dwpts_symbols, ppWritePackedMsg, end) &&
+          push8(value->initial_lbt_sf, ppWritePackedMsg, end) &&
+          push8(value->ue_type, ppWritePackedMsg, end) &&
+          push8(value->pdsch_payload_type, ppWritePackedMsg, end) &&
+          push16(value->initial_transmission_sf_io, ppWritePackedMsg, end) &&
+          push8(value->drms_table_flag, ppWritePackedMsg, end));
+}
+static uint8_t pack_dl_config_pch_pdu_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_pch_pdu_rel8_t *value = (nfapi_dl_config_pch_pdu_rel8_t *)tlv;
+  return( push16(value->length, ppWritePackedMsg, end) &&
+          push16(value->pdu_index, ppWritePackedMsg, end) &&
+          push16(value->p_rnti, ppWritePackedMsg, end) &&
+          push8(value->resource_allocation_type, ppWritePackedMsg, end) &&
+          push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) &&
+          push32(value->resource_block_coding, ppWritePackedMsg, end) &&
+          push8(value->mcs, ppWritePackedMsg, end) &&
+          push8(value->redundancy_version, ppWritePackedMsg, end) &&
+          push8(value->number_of_transport_blocks, ppWritePackedMsg, end) &&
+          push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) &&
+          push8(value->transmission_scheme, ppWritePackedMsg, end) &&
+          push8(value->number_of_layers, ppWritePackedMsg, end) &&
+          push8(value->codebook_index, ppWritePackedMsg, end) &&
+          push8(value->ue_category_capacity, ppWritePackedMsg, end) &&
+          push8(value->pa, ppWritePackedMsg, end) &&
+          push16(value->transmission_power, ppWritePackedMsg, end) &&
+          push8(value->nprb, ppWritePackedMsg, end) &&
+          push8(value->ngap, ppWritePackedMsg, end));
+}
+static uint8_t pack_dl_config_pch_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_pch_pdu_rel13_t *value = (nfapi_dl_config_pch_pdu_rel13_t *)tlv;
+  return ( push8(value->ue_mode, ppWritePackedMsg, end) &&
+           push16(value->initial_transmission_sf_io, ppWritePackedMsg, end));
+}
+static uint8_t pack_dl_config_prs_pdu_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_prs_pdu_rel9_t *value = (nfapi_dl_config_prs_pdu_rel9_t *)tlv;
+  return( push16(value->transmission_power, ppWritePackedMsg, end) &&
+          push8(value->prs_bandwidth, ppWritePackedMsg, end) &&
+          push8(value->prs_cyclic_prefix_type, ppWritePackedMsg, end) &&
+          push8(value->prs_muting, ppWritePackedMsg, end));
+}
+static uint8_t pack_dl_config_csi_rs_pdu_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_csi_rs_pdu_rel10_t *value = (nfapi_dl_config_csi_rs_pdu_rel10_t *)tlv;
+  return( push8(value->csi_rs_antenna_port_count_r10, ppWritePackedMsg, end) &&
+          push8(value->csi_rs_resource_config_r10, ppWritePackedMsg, end) &&
+          push16(value->transmission_power, ppWritePackedMsg, end) &&
+          push16(value->csi_rs_zero_tx_power_resource_config_bitmap_r10, ppWritePackedMsg, end) &&
+          push8(value->csi_rs_number_of_nzp_configuration, ppWritePackedMsg, end) &&
+          pusharray8(value->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, value->csi_rs_number_of_nzp_configuration, ppWritePackedMsg, end));
+}
+static uint8_t pack_dl_config_csi_rs_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_csi_rs_pdu_rel13_t *value = (nfapi_dl_config_csi_rs_pdu_rel13_t *)tlv;
+
+  if(!(push8(value->csi_rs_class, ppWritePackedMsg, end) &&
+       push8(value->cdm_type, ppWritePackedMsg, end) &&
+       push8(value->num_bf_vector, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  uint16_t i;
+
+  for(i = 0; i < value->num_bf_vector; ++i) {
+    if(!(push8(value->bf_vector[i].csi_rs_resource_index, ppWritePackedMsg, end) &&
+         pusharray16(value->bf_vector[i].bf_value, NFAPI_MAX_ANTENNA_PORT_COUNT, NFAPI_MAX_ANTENNA_PORT_COUNT, ppWritePackedMsg, end)))
+      return 0;
+  }
+
+  return 1;
+}
+static uint8_t pack_bf_vector(nfapi_bf_vector_t *vector, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return ( push8(vector->subband_index, ppWritePackedMsg, end) &&
+           push8(vector->num_antennas, ppWritePackedMsg, end) &&
+           pusharray16(vector->bf_value, NFAPI_MAX_NUM_ANTENNAS, vector->num_antennas, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_dl_config_epdcch_parameters_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_epdcch_parameters_rel11_t *value = (nfapi_dl_config_epdcch_parameters_rel11_t *)tlv;
+  return ( push8(value->epdcch_resource_assignment_flag, ppWritePackedMsg, end) &&
+           push16(value->epdcch_id, ppWritePackedMsg, end) &&
+           push8(value->epdcch_start_symbol, ppWritePackedMsg, end) &&
+           push8(value->epdcch_num_prb, ppWritePackedMsg, end) &&
+           pusharray8(value->epdcch_prb_index, NFAPI_MAX_EPDCCH_PRB, value->epdcch_num_prb, ppWritePackedMsg, end) &&
+           pack_bf_vector(&value->bf_vector, ppWritePackedMsg, end));
+}
+static uint8_t pack_dl_config_epdcch_parameters_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_epdcch_parameters_rel13_t *value = (nfapi_dl_config_epdcch_parameters_rel13_t *)tlv;
+  return (push8(value->dwpts_symbols, ppWritePackedMsg, end) &&
+          push8(value->initial_lbt_sf, ppWritePackedMsg, end));
+}
+static uint8_t pack_dl_config_mpdcch_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_mpdcch_pdu_rel13_t *value = (nfapi_dl_config_mpdcch_pdu_rel13_t *)tlv;
+  return ( push8(value->mpdcch_narrow_band, ppWritePackedMsg, end) &&
+           push8(value->number_of_prb_pairs, ppWritePackedMsg, end) &&
+           push8(value->resource_block_assignment, ppWritePackedMsg, end) &&
+           push8(value->mpdcch_tansmission_type, ppWritePackedMsg, end) &&
+           push8(value->start_symbol, ppWritePackedMsg, end) &&
+           push8(value->ecce_index, ppWritePackedMsg, end) &&
+           push8(value->aggregation_level, ppWritePackedMsg, end) &&
+           push8(value->rnti_type, ppWritePackedMsg, end) &&
+           push16(value->rnti, ppWritePackedMsg, end) &&
+           push8(value->ce_mode, ppWritePackedMsg, end) &&
+           push16(value->drms_scrambling_init, ppWritePackedMsg, end) &&
+           push16(value->initial_transmission_sf_io, ppWritePackedMsg, end) &&
+           push16(value->transmission_power, ppWritePackedMsg, end) &&
+           push8(value->dci_format, ppWritePackedMsg, end) &&
+           push16(value->resource_block_coding, ppWritePackedMsg, end) &&
+           push8(value->mcs, ppWritePackedMsg, end) &&
+           push8(value->pdsch_reptition_levels, ppWritePackedMsg, end) &&
+           push8(value->redundancy_version, ppWritePackedMsg, end) &&
+           push8(value->new_data_indicator, ppWritePackedMsg, end) &&
+           push8(value->harq_process, ppWritePackedMsg, end) &&
+           push8(value->tpmi_length, ppWritePackedMsg, end) &&
+           push8(value->tpmi, ppWritePackedMsg, end) &&
+           push8(value->pmi_flag, ppWritePackedMsg, end) &&
+           push8(value->pmi, ppWritePackedMsg, end) &&
+           push8(value->harq_resource_offset, ppWritePackedMsg, end) &&
+           push8(value->dci_subframe_repetition_number, ppWritePackedMsg, end) &&
+           push8(value->tpc, ppWritePackedMsg, end) &&
+           push8(value->downlink_assignment_index_length, ppWritePackedMsg, end) &&
+           push8(value->downlink_assignment_index, ppWritePackedMsg, end) &&
+           push8(value->allocate_prach_flag, ppWritePackedMsg, end) &&
+           push8(value->preamble_index, ppWritePackedMsg, end) &&
+           push8(value->prach_mask_index, ppWritePackedMsg, end) &&
+           push8(value->starting_ce_level, ppWritePackedMsg, end) &&
+           push8(value->srs_request, ppWritePackedMsg, end) &&
+           push8(value->antenna_ports_and_scrambling_identity_flag, ppWritePackedMsg, end) &&
+           push8(value->antenna_ports_and_scrambling_identity, ppWritePackedMsg, end) &&
+           push8(value->frequency_hopping_enabled_flag, ppWritePackedMsg, end) &&
+           push8(value->paging_direct_indication_differentiation_flag, ppWritePackedMsg, end) &&
+           push8(value->direct_indication, ppWritePackedMsg, end) &&
+           push8(value->total_dci_length_including_padding, ppWritePackedMsg, end) &&
+           push8(value->number_of_tx_antenna_ports, ppWritePackedMsg, end) &&
+           pusharray16(value->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, value->number_of_tx_antenna_ports, ppWritePackedMsg, end));
+}
+
+
+static uint8_t pack_dl_config_nbch_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_nbch_pdu_rel13_t *value = (nfapi_dl_config_nbch_pdu_rel13_t *)tlv;
+  return (push16(value->length, ppWritePackedMsg, end) &&
+          push16(value->pdu_index, ppWritePackedMsg, end) &&
+          push16(value->transmission_power, ppWritePackedMsg, end) &&
+          push16(value->hyper_sfn_2_lsbs, ppWritePackedMsg, end));
+}
+
+
+static uint8_t pack_dl_config_npdcch_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_npdcch_pdu_rel13_t *value = (nfapi_dl_config_npdcch_pdu_rel13_t *)tlv;
+  return (push16(value->length, ppWritePackedMsg, end) &&
+          push16(value->pdu_index, ppWritePackedMsg, end) &&
+          push8(value->ncce_index, ppWritePackedMsg, end) &&
+          push8(value->aggregation_level, ppWritePackedMsg, end) &&
+          push8(value->start_symbol, ppWritePackedMsg, end) &&
+          push8(value->rnti_type, ppWritePackedMsg, end) &&
+          push16(value->rnti, ppWritePackedMsg, end) &&
+          push8(value->scrambling_reinitialization_batch_index, ppWritePackedMsg, end) &&
+          push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end) &&
+          push8(value->dci_format, ppWritePackedMsg, end) &&
+          push8(value->scheduling_delay, ppWritePackedMsg, end) &&
+          push8(value->resource_assignment, ppWritePackedMsg, end) &&
+          push8(value->repetition_number, ppWritePackedMsg, end) &&
+          push8(value->mcs, ppWritePackedMsg, end) &&
+          push8(value->new_data_indicator, ppWritePackedMsg, end) &&
+          push8(value->harq_ack_resource, ppWritePackedMsg, end) &&
+          push8(value->npdcch_order_indication, ppWritePackedMsg, end) &&
+          push8(value->starting_number_of_nprach_repetitions, ppWritePackedMsg, end) &&
+          push8(value->subcarrier_indication_of_nprach, ppWritePackedMsg, end) &&
+          push8(value->paging_direct_indication_differentation_flag, ppWritePackedMsg, end) &&
+          push8(value->direct_indication, ppWritePackedMsg, end) &&
+          push8(value->dci_subframe_repetition_number, ppWritePackedMsg, end) &&
+          push8(value->total_dci_length_including_padding, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_ndlsch_pdu_rel13_t *value = (nfapi_dl_config_ndlsch_pdu_rel13_t *)tlv;
+  return (push16(value->length, ppWritePackedMsg, end) &&
+          push16(value->pdu_index, ppWritePackedMsg, end) &&
+          push8(value->start_symbol, ppWritePackedMsg, end) &&
+          push8(value->rnti_type, ppWritePackedMsg, end) &&
+          push16(value->rnti, ppWritePackedMsg, end) &&
+          push16(value->resource_assignment, ppWritePackedMsg, end) &&
+          push16(value->repetition_number, ppWritePackedMsg, end) &&
+          push8(value->modulation, ppWritePackedMsg, end) &&
+          push8(value->number_of_subframes_for_resource_assignment, ppWritePackedMsg, end) &&
+          push8(value->scrambling_sequence_initialization_cinit, ppWritePackedMsg, end) &&
+          push16(value->sf_idx, ppWritePackedMsg, end) &&
+          push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end));
+}
+
+
+static uint8_t pack_dl_tti_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)tlv;
+
+  if(!(push16(value->PDUSize, ppWritePackedMsg, end) &&
+       push16(value->PDUType, ppWritePackedMsg, end) ))
+    return 0;
+
+  // first match the pdu type, then call the respective function
+  switch(value->PDUType) {
+    case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: {
+      if(!(pack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15,ppWritePackedMsg,end)))
+        return 0;
+    }
+    break;
+
+    case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: {
+      if(!(pack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15,ppWritePackedMsg,end)))
+        return 0;
+    }
+    break;
+
+    case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: {
+      if(!(pack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15,ppWritePackedMsg,end)))
+        return 0;
+    }
+    break;
+
+    case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: {
+      if(!(pack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15,ppWritePackedMsg,end)))
+        return 0;
+    }
+    break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType );
+    }
+    break;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_dl_config_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_dl_config_request_body_t *value = (nfapi_dl_config_request_body_t *)tlv;
+
+  //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() dci:%u pdu:%u pdsch:%u rnti:%u pcfich:%u\n", __FUNCTION__, value->number_dci, value->number_pdu, value->number_pdsch_rnti, value->transmission_power_pcfich);
+
+  if(!(push8(value->number_pdcch_ofdm_symbols, ppWritePackedMsg, end) &&
+       push8(value->number_dci, ppWritePackedMsg, end) &&
+       push16(value->number_pdu, ppWritePackedMsg, end) &&
+       push8(value->number_pdsch_rnti, ppWritePackedMsg, end) &&
+       push16(value->transmission_power_pcfich, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  uint16_t i = 0;
+  uint16_t total_number_of_pdus = value->number_pdu;
+
+  for(; i < total_number_of_pdus; ++i) {
+    nfapi_dl_config_request_pdu_t *pdu = &(value->dl_config_pdu_list[i]);
+
+    if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    // Put a 0 size in and then determine the size after the pdu
+    // has been writen and write the calculated size
+    uint8_t *pWritePackedMsgPduSize = *ppWritePackedMsg;
+    pdu->pdu_size = 0;
+
+    if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    switch(pdu->pdu_type) {
+      case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: {
+        //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE\n", __FUNCTION__);
+        if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel8_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel9_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel10_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel11_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel12_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel13_value))) {
+          return 0;
+        }
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_BCH_PDU_TYPE: {
+        //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE\n", __FUNCTION__);
+        if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG, &pdu->bch_pdu.bch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_bch_pdu_rel8_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_MCH_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG, &pdu->mch_pdu.mch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_mch_pdu_rel8_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel8_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel9_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel10_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel11_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel12_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel13_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_PCH_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG, &pdu->pch_pdu.pch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_pch_pdu_rel8_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG, &pdu->pch_pdu.pch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_pch_pdu_rel13_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_PRS_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG, &pdu->prs_pdu.prs_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_prs_pdu_rel9_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel10, ppWritePackedMsg, end,  &pack_dl_config_csi_rs_pdu_rel10_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel13, ppWritePackedMsg, end,  &pack_dl_config_csi_rs_pdu_rel13_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel8_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel9_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel10_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel11_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel12_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel13_value) &&
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG, &pdu->epdcch_pdu.epdcch_params_rel11, ppWritePackedMsg, end, &pack_dl_config_epdcch_parameters_rel11_value) &
+             pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG, &pdu->epdcch_pdu.epdcch_params_rel13, ppWritePackedMsg, end, &pack_dl_config_epdcch_parameters_rel13_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG, &pdu->mpdcch_pdu.mpdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_mpdcch_pdu_rel13_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG, &pdu->nbch_pdu.nbch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_nbch_pdu_rel13_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG, &pdu->npdcch_pdu.npdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_npdcch_pdu_rel13_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG, &pdu->ndlsch_pdu.ndlsch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_ndlsch_pdu_rel13_value)))
+          return 0;
+      }
+      break;
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type );
+      }
+      break;
+    };
+
+    // add 1 for the pdu_type. The delta will include the pdu_size
+    pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize);
+
+    push8(pdu->pdu_size, &pWritePackedMsgPduSize, end);
+  }
+
+  return 1;
+}
+
+
+static uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg;
+
+  if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) &&
+        push16(pNfapiMsg->Slot, ppWritePackedMsg, end) &&
+        push8(pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end) &&
+        push8(pNfapiMsg->dl_tti_request_body.nPDUs, ppWritePackedMsg, end) &&
+        pusharray8(pNfapiMsg->dl_tti_request_body.nUe,256,pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end)
+        //pusharray8(pNfapiMsg->PduIdx[0] ,256,256, ppWritePackedMsg, end)
+       ))
+    return 0;
+
+  int arr[12];
+
+  for(int i=0; i<pNfapiMsg->dl_tti_request_body.nGroup; i++) {
+    for(int j=0; j<pNfapiMsg->dl_tti_request_body.nUe[i]; j++) {
+      arr[j] = pNfapiMsg->dl_tti_request_body.PduIdx[i][j];
+    }
+
+    if(!(pusharrays32(arr,12,pNfapiMsg->dl_tti_request_body.nUe[i],ppWritePackedMsg, end)))
+      return 0;
+  }
+
+  for(int i=0; i<pNfapiMsg->dl_tti_request_body.nPDUs; i++) {
+    if(!pack_dl_tti_request_body_value(&pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i],ppWritePackedMsg,end))
+      return 0;
+  }
+
+  return 1;
+}
+
+
+static uint8_t pack_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t *)msg;
+  //return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+  //pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value) &&
+  //pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+  {
+    uint8_t x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end);
+    uint8_t y = pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value);
+    uint8_t z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+
+    if (!x || !y || !z) {
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_DL_CONFIG_REQUEST x:%u y:%u z:%u \n", __FUNCTION__,x,y,z);
+    }
+
+    return x && y && z;
+  }
+}
+
+
+
+
+static uint8_t pack_ul_config_request_ulsch_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_ulsch_pdu_rel8_t *ulsch_pdu_rel8 = (nfapi_ul_config_ulsch_pdu_rel8_t *)tlv;
+  return( push32(ulsch_pdu_rel8->handle, ppWritePackedMsg, end) &&
+          push16(ulsch_pdu_rel8->size, ppWritePackedMsg, end) &&
+          push16(ulsch_pdu_rel8->rnti, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel8->resource_block_start, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel8->modulation_type, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel8->frequency_hopping_enabled_flag, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel8->frequency_hopping_bits, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel8->new_data_indication, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel8->redundancy_version, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel8->harq_process_number, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel8->ul_tx_mode, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel8->current_tx_nb, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel8->n_srs, ppWritePackedMsg, end));
+}
+static uint8_t pack_ul_config_request_ulsch_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_ulsch_pdu_rel10_t *ulsch_pdu_rel10 = (nfapi_ul_config_ulsch_pdu_rel10_t *)tlv;
+  return (push8(ulsch_pdu_rel10->resource_allocation_type, ppWritePackedMsg, end) &&
+          push32(ulsch_pdu_rel10->resource_block_coding, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel10->transport_blocks, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel10->transmission_scheme, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel10->number_of_layers, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel10->codebook_index, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel10->disable_sequence_hopping_flag, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_config_request_ulsch_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_ulsch_pdu_rel11_t *ulsch_pdu_rel11 = (nfapi_ul_config_ulsch_pdu_rel11_t *)tlv;
+  return (push8(ulsch_pdu_rel11->virtual_cell_id_enabled_flag, ppWritePackedMsg, end) &&
+          push16(ulsch_pdu_rel11->npusch_identity, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel11->dmrs_config_flag, ppWritePackedMsg, end) &&
+          push16(ulsch_pdu_rel11->ndmrs_csh_identity, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_config_request_ulsch_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_ulsch_pdu_rel13_t *ulsch_pdu_rel13 = (nfapi_ul_config_ulsch_pdu_rel13_t *)tlv;
+  return (push8(ulsch_pdu_rel13->ue_type, ppWritePackedMsg, end) &&
+          push16(ulsch_pdu_rel13->total_number_of_repetitions, ppWritePackedMsg, end) &&
+          push16(ulsch_pdu_rel13->repetition_number, ppWritePackedMsg, end) &&
+          push16(ulsch_pdu_rel13->initial_transmission_sf_io, ppWritePackedMsg, end) &&
+          push8(ulsch_pdu_rel13->empty_symbols_due_to_re_tunning, ppWritePackedMsg, end));
+}
+
+//Pack fns for ul_tti PDUS
+
+
+static uint8_t pack_ul_tti_request_prach_pdu(nfapi_nr_prach_pdu_t *prach_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return(
+          push16(prach_pdu->phys_cell_id, ppWritePackedMsg, end) &&
+          push8(prach_pdu->num_prach_ocas, ppWritePackedMsg, end) &&
+          push8(prach_pdu->prach_format, ppWritePackedMsg, end) &&
+          push8(prach_pdu->num_ra, ppWritePackedMsg, end) &&
+          push8(prach_pdu->prach_start_symbol, ppWritePackedMsg, end) &&
+          push16(prach_pdu->num_cs, ppWritePackedMsg, end)
+          // TODO: ignoring beamforming tlv for now
+        );
+}
+
+static uint8_t pack_ul_tti_request_pucch_pdu(nfapi_nr_pucch_pdu_t *pucch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return(
+          push16(pucch_pdu->rnti, ppWritePackedMsg, end) &&
+          push32(pucch_pdu->handle, ppWritePackedMsg, end) &&
+          push16(pucch_pdu->bwp_size, ppWritePackedMsg, end) &&
+          push16(pucch_pdu->bwp_start, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->subcarrier_spacing, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->cyclic_prefix, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->format_type, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->multi_slot_tx_indicator, ppWritePackedMsg, end) &&
+          push16(pucch_pdu->prb_start, ppWritePackedMsg, end) &&
+          push16(pucch_pdu->prb_size, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->start_symbol_index, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->nr_of_symbols, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->freq_hop_flag, ppWritePackedMsg, end) &&
+          push16(pucch_pdu->second_hop_prb, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->group_hop_flag, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->sequence_hop_flag, ppWritePackedMsg, end) &&
+          push16(pucch_pdu->hopping_id, ppWritePackedMsg, end) &&
+          push16(pucch_pdu->initial_cyclic_shift, ppWritePackedMsg, end) &&
+          push16(pucch_pdu->data_scrambling_id, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->time_domain_occ_idx, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->pre_dft_occ_idx, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->pre_dft_occ_len, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->add_dmrs_flag, ppWritePackedMsg, end) &&
+          push16(pucch_pdu->dmrs_scrambling_id, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->dmrs_cyclic_shift, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->sr_flag, ppWritePackedMsg, end) &&
+          push8(pucch_pdu->bit_len_harq, ppWritePackedMsg, end) &&
+          push16(pucch_pdu->bit_len_csi_part1, ppWritePackedMsg, end) &&
+          push16(pucch_pdu->bit_len_csi_part2, ppWritePackedMsg, end)
+          // TODO: ignoring beamforming tlv for now
+        );
+}
+
+
+static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  if (!(
+        push16(pusch_pdu->pdu_bit_map, ppWritePackedMsg, end) &&
+        push16(pusch_pdu->rnti, ppWritePackedMsg, end) &&
+        push32(pusch_pdu->handle, ppWritePackedMsg, end) &&
+        push16(pusch_pdu->bwp_size, ppWritePackedMsg, end) &&
+        push16(pusch_pdu->bwp_start, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->subcarrier_spacing, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->cyclic_prefix, ppWritePackedMsg, end) &&
+        push16(pusch_pdu->target_code_rate, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->mcs_index, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end) &&
+        push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end) &&
+        push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end) &&
+        push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->scid, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->num_dmrs_cdm_grps_no_data, ppWritePackedMsg, end) &&
+        push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->resource_alloc, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->resource_alloc,ppWritePackedMsg, end) &&
+        push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) &&
+        push16(pusch_pdu->rb_start, ppWritePackedMsg, end) &&
+        push16(pusch_pdu->rb_size, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->vrb_to_prb_mapping, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->frequency_hopping, ppWritePackedMsg, end) &&
+        push16(pusch_pdu->tx_direct_current_location, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->uplink_frequency_shift_7p5khz, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->start_symbol_index, ppWritePackedMsg, end) &&
+        push8(pusch_pdu->nr_of_symbols, ppWritePackedMsg, end)
+        // TODO: ignoring beamforming tlv for now
+      ))
+    return 0;
+
+  //Pack Optional Data only included if indicated in pduBitmap
+  switch(pusch_pdu->pdu_bit_map) {
+    case PUSCH_PDU_BITMAP_PUSCH_DATA: {
+      // pack optional TLVs
+      return(
+              push8(pusch_pdu->pusch_data.rv_index, ppWritePackedMsg, end) &&
+              push8(pusch_pdu->pusch_data.harq_process_id, ppWritePackedMsg, end) &&
+              push32(pusch_pdu->pusch_data.tb_size, ppWritePackedMsg, end) &&
+              push16(pusch_pdu->pusch_data.num_cb, ppWritePackedMsg, end) &&
+              pusharray8(pusch_pdu->pusch_data.cb_present_and_position,1,1,ppWritePackedMsg, end)
+            );
+    }
+    break;
+
+    case PUSCH_PDU_BITMAP_PUSCH_UCI: {
+      return(
+              push16(pusch_pdu->pusch_uci.harq_ack_bit_length, ppWritePackedMsg, end) &&
+              push16(pusch_pdu->pusch_uci.csi_part1_bit_length, ppWritePackedMsg, end) &&
+              push16(pusch_pdu->pusch_uci.csi_part2_bit_length, ppWritePackedMsg, end) &&
+              push8(pusch_pdu->pusch_uci.alpha_scaling, ppWritePackedMsg, end) &&
+              push8(pusch_pdu->pusch_uci.beta_offset_harq_ack, ppWritePackedMsg, end) &&
+              push8(pusch_pdu->pusch_uci.beta_offset_csi1, ppWritePackedMsg, end) &&
+              push8(pusch_pdu->pusch_uci.beta_offset_csi2, ppWritePackedMsg, end)
+            );
+    }
+    break;
+
+    case PUSCH_PDU_BITMAP_PUSCH_PTRS: {
+      return(
+              push8(pusch_pdu->pusch_ptrs.num_ptrs_ports, ppWritePackedMsg, end) &&
+              push8(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_dmrs_port, ppWritePackedMsg, end) &&
+              push16(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_port_index, ppWritePackedMsg, end) &&
+              push8(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset, ppWritePackedMsg, end) &&
+              push8(pusch_pdu->pusch_ptrs.ptrs_time_density, ppWritePackedMsg, end) &&
+              push8(pusch_pdu->pusch_ptrs.ptrs_freq_density, ppWritePackedMsg, end) &&
+              push8(pusch_pdu->pusch_ptrs.ul_ptrs_power, ppWritePackedMsg, end)
+            );
+    }
+    break;
+
+    case PUSCH_PDU_BITMAP_DFTS_OFDM: {
+      return(
+              push8(pusch_pdu->dfts_ofdm.low_papr_group_number, ppWritePackedMsg, end) &&
+              push16(pusch_pdu->dfts_ofdm.low_papr_sequence_number, ppWritePackedMsg, end) &&
+              push8(pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, ppWritePackedMsg, end) &&
+              push8(pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, ppWritePackedMsg, end)
+            );
+    }
+    break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map );
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return(
+          push16(srs_pdu->rnti, ppWritePackedMsg, end) &&
+          push32(srs_pdu->handle, ppWritePackedMsg, end) &&
+          push16(srs_pdu->bwp_size, ppWritePackedMsg, end) &&
+          push16(srs_pdu->bwp_start, ppWritePackedMsg, end) &&
+          push8(srs_pdu->subcarrier_spacing, ppWritePackedMsg, end) &&
+          push8(srs_pdu->cyclic_prefix, ppWritePackedMsg, end) &&
+          push8(srs_pdu->num_ant_ports, ppWritePackedMsg, end) &&
+          push8(srs_pdu->num_symbols, ppWritePackedMsg, end) &&
+          push8(srs_pdu->num_repetitions, ppWritePackedMsg, end) &&
+          push8(srs_pdu->time_start_position, ppWritePackedMsg, end) &&
+          push8(srs_pdu->config_index, ppWritePackedMsg, end) &&
+          push16(srs_pdu->sequence_id, ppWritePackedMsg, end) &&
+          push8(srs_pdu->bandwidth_index, ppWritePackedMsg, end) &&
+          push8(srs_pdu->comb_size, ppWritePackedMsg, end) &&
+          push8(srs_pdu->comb_offset, ppWritePackedMsg, end) &&
+          push8(srs_pdu->cyclic_shift, ppWritePackedMsg, end) &&
+          push8(srs_pdu->frequency_position, ppWritePackedMsg, end) &&
+          push8(srs_pdu->frequency_shift, ppWritePackedMsg, end) &&
+          push8(srs_pdu->frequency_hopping, ppWritePackedMsg, end) &&
+          push8(srs_pdu->group_or_sequence_hopping, ppWritePackedMsg, end) &&
+          push8(srs_pdu->resource_type, ppWritePackedMsg, end) &&
+          push16(srs_pdu->t_srs, ppWritePackedMsg, end) &&
+          push16(srs_pdu->t_offset, ppWritePackedMsg, end)
+          // TODO: ignoring beamforming tlv for now
+        );
+}
+
+static uint8_t pack_ul_config_request_ulsch_pdu(nfapi_ul_config_ulsch_pdu *ulsch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG, &ulsch_pdu->ulsch_pdu_rel8, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel8_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG, &ulsch_pdu->ulsch_pdu_rel10, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel10_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG, &ulsch_pdu->ulsch_pdu_rel11, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel11_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG, &ulsch_pdu->ulsch_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel13_value));
+}
+
+static uint8_t pack_ul_config_request_cqi_ri_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_cqi_ri_information_rel8_t *cqi_ri_info_rel8 = (nfapi_ul_config_cqi_ri_information_rel8_t *)tlv;
+  return ( push8(cqi_ri_info_rel8->dl_cqi_pmi_size_rank_1, ppWritePackedMsg, end) &&
+           push8(cqi_ri_info_rel8->dl_cqi_pmi_size_rank_greater_1, ppWritePackedMsg, end) &&
+           push8(cqi_ri_info_rel8->ri_size, ppWritePackedMsg, end) &&
+           push8(cqi_ri_info_rel8->delta_offset_cqi, ppWritePackedMsg, end) &&
+           push8(cqi_ri_info_rel8->delta_offset_ri, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_config_request_cqi_ri_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_cqi_ri_information_rel9_t *cqi_ri_info_rel9 = (nfapi_ul_config_cqi_ri_information_rel9_t *)tlv;
+
+  if(!(push8(cqi_ri_info_rel9->report_type, ppWritePackedMsg, end) &&
+       push8(cqi_ri_info_rel9->delta_offset_cqi, ppWritePackedMsg, end) &&
+       push8(cqi_ri_info_rel9->delta_offset_ri, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  switch(cqi_ri_info_rel9->report_type) {
+    case NFAPI_CSI_REPORT_TYPE_PERIODIC: {
+      if(!(push8(cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size, ppWritePackedMsg, end) &&
+           push8(cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.control_type, ppWritePackedMsg, end))) {
+        return 0;
+      }
+    }
+    break;
+
+    case NFAPI_CSI_REPORT_TYPE_APERIODIC: {
+      if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc, ppWritePackedMsg, end) == 0)
+        return 0;
+
+      uint8_t i;
+
+      for(i = 0; i < cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc; ++i) {
+        if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size, ppWritePackedMsg, end) == 0)
+          return 0;
+
+        uint8_t j;
+
+        for(j = 0; j < 8; ++j) {
+          if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size[j], ppWritePackedMsg, end) == 0)
+            return 0;
+        }
+      }
+    }
+    break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel9->report_type );
+    }
+    break;
+  };
+
+  return 1;
+}
+
+static uint8_t pack_ul_config_request_cqi_ri_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_cqi_ri_information_rel13_t *cqi_ri_info_rel13 = (nfapi_ul_config_cqi_ri_information_rel13_t *)tlv;
+
+  switch(cqi_ri_info_rel13->report_type) {
+    case NFAPI_CSI_REPORT_TYPE_PERIODIC: {
+      if(push16(cqi_ri_info_rel13->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2, ppWritePackedMsg, end) == 0)
+        return 0;
+    }
+    break;
+
+    case NFAPI_CSI_REPORT_TYPE_APERIODIC: {
+      // No parameters
+    }
+    break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel13->report_type );
+    }
+    break;
+  };
+
+  return 1;
+}
+
+static uint8_t pack_ul_config_request_cqi_ri_information(nfapi_ul_config_cqi_ri_information *cqi_ri_info, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return (pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG, &cqi_ri_info->cqi_ri_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel8_value) &&
+          pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG, &cqi_ri_info->cqi_ri_information_rel9, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel9_value) &&
+          pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG, &cqi_ri_info->cqi_ri_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel13_value));
+}
+
+static uint8_t pack_ul_config_request_init_tx_params_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_initial_transmission_parameters_rel8_t *init_tx_params_rel8 = (nfapi_ul_config_initial_transmission_parameters_rel8_t *)tlv;
+  return (push8(init_tx_params_rel8->n_srs_initial, ppWritePackedMsg, end) &&
+          push8(init_tx_params_rel8->initial_number_of_resource_blocks, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_config_request_initial_transmission_parameters(nfapi_ul_config_initial_transmission_parameters *init_tx_params, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return pack_tlv(NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG, &init_tx_params->initial_transmission_parameters_rel8, ppWritePackedMsg, end,
+                  &pack_ul_config_request_init_tx_params_rel8_value);
+}
+
+static uint8_t pack_ul_config_request_ulsch_harq_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_ulsch_harq_information_rel10_t *harq_info_rel10 = (nfapi_ul_config_ulsch_harq_information_rel10_t *)tlv;
+  return (push8(harq_info_rel10->harq_size, ppWritePackedMsg, end) &&
+          push8(harq_info_rel10->delta_offset_harq, ppWritePackedMsg, end) &&
+          push8(harq_info_rel10->ack_nack_mode, ppWritePackedMsg, end));
+}
+static uint8_t pack_ul_config_request_ulsch_harq_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_ulsch_harq_information_rel13_t *harq_info_rel13 = (nfapi_ul_config_ulsch_harq_information_rel13_t *)tlv;
+  return (push16(harq_info_rel13->harq_size_2, ppWritePackedMsg, end) &&
+          push8(harq_info_rel13->delta_offset_harq_2, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_config_request_ulsch_harq_information(nfapi_ul_config_ulsch_harq_information *harq_info, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG, &harq_info->harq_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_harq_info_rel10_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG, &harq_info->harq_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_harq_info_rel13_value));
+}
+
+static uint8_t pack_ul_config_request_ue_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_ue_information_rel8_t *ue_info_rel8 = (nfapi_ul_config_ue_information_rel8_t *)tlv;
+  return ( push32(ue_info_rel8->handle, ppWritePackedMsg, end) &&
+           push16(ue_info_rel8->rnti, ppWritePackedMsg, end));
+}
+static uint8_t pack_ul_config_request_ue_info_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_ue_information_rel11_t *ue_info_rel11 = (nfapi_ul_config_ue_information_rel11_t *)tlv;
+  return ( push8(ue_info_rel11->virtual_cell_id_enabled_flag, ppWritePackedMsg, end) &&
+           push16(ue_info_rel11->npusch_identity, ppWritePackedMsg, end));
+}
+static uint8_t pack_ul_config_request_ue_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_ue_information_rel13_t *ue_info_rel13 = (nfapi_ul_config_ue_information_rel13_t *)tlv;
+  return ( push8(ue_info_rel13->ue_type, ppWritePackedMsg, end) &&
+           push8(ue_info_rel13->empty_symbols, ppWritePackedMsg, end) &&
+           push16(ue_info_rel13->total_number_of_repetitions, ppWritePackedMsg, end) &&
+           push16(ue_info_rel13->repetition_number, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_config_request_ue_information(nfapi_ul_config_ue_information *ue_info, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &ue_info->ue_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel8_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &ue_info->ue_information_rel11, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel11_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &ue_info->ue_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel13_value));
+}
+
+static uint8_t pack_ul_config_request_harq_info_rel10_tdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_harq_information_rel10_tdd_t *harq_info_rel10_tdd = (nfapi_ul_config_harq_information_rel10_tdd_t *)tlv;
+  return ( push8(harq_info_rel10_tdd->harq_size, ppWritePackedMsg, end) &&
+           push8(harq_info_rel10_tdd->ack_nack_mode, ppWritePackedMsg, end) &&
+           push8(harq_info_rel10_tdd->number_of_pucch_resources, ppWritePackedMsg, end) &&
+           push16(harq_info_rel10_tdd->n_pucch_1_0, ppWritePackedMsg, end) &&
+           push16(harq_info_rel10_tdd->n_pucch_1_1, ppWritePackedMsg, end) &&
+           push16(harq_info_rel10_tdd->n_pucch_1_2, ppWritePackedMsg, end) &&
+           push16(harq_info_rel10_tdd->n_pucch_1_3, ppWritePackedMsg, end));
+}
+static uint8_t pack_ul_config_request_harq_info_rel8_fdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_harq_information_rel8_fdd_t *harq_info_rel8_fdd = (nfapi_ul_config_harq_information_rel8_fdd_t *)tlv;
+  return ( push16(harq_info_rel8_fdd->n_pucch_1_0, ppWritePackedMsg, end) &&
+           push8(harq_info_rel8_fdd->harq_size, ppWritePackedMsg, end));
+}
+static uint8_t pack_ul_config_request_harq_info_rel9_fdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_harq_information_rel9_fdd_t *harq_info_rel9_fdd = (nfapi_ul_config_harq_information_rel9_fdd_t *)tlv;
+  return ( push8(harq_info_rel9_fdd->harq_size, ppWritePackedMsg, end) &&
+           push8(harq_info_rel9_fdd->ack_nack_mode, ppWritePackedMsg, end) &&
+           push8(harq_info_rel9_fdd->number_of_pucch_resources, ppWritePackedMsg, end) &&
+           push16(harq_info_rel9_fdd->n_pucch_1_0, ppWritePackedMsg, end) &&
+           push16(harq_info_rel9_fdd->n_pucch_1_1, ppWritePackedMsg, end) &&
+           push16(harq_info_rel9_fdd->n_pucch_1_2, ppWritePackedMsg, end) &&
+           push16(harq_info_rel9_fdd->n_pucch_1_3, ppWritePackedMsg, end));
+}
+static uint8_t pack_ul_config_request_harq_info_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_harq_information_rel11_t *harq_info_rel11 = (nfapi_ul_config_harq_information_rel11_t *)tlv;
+  return ( push8(harq_info_rel11->num_ant_ports, ppWritePackedMsg, end) &&
+           push16(harq_info_rel11->n_pucch_2_0, ppWritePackedMsg, end) &&
+           push16(harq_info_rel11->n_pucch_2_1, ppWritePackedMsg, end) &&
+           push16(harq_info_rel11->n_pucch_2_2, ppWritePackedMsg, end) &&
+           push16(harq_info_rel11->n_pucch_2_3, ppWritePackedMsg, end));
+}
+static uint8_t pack_ul_config_request_harq_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_harq_information_rel13_t *harq_info_rel13 = (nfapi_ul_config_harq_information_rel13_t *)tlv;
+  return ( push16(harq_info_rel13->harq_size_2, ppWritePackedMsg, end) &&
+           push8(harq_info_rel13->starting_prb, ppWritePackedMsg, end) &&
+           push8(harq_info_rel13->n_prb, ppWritePackedMsg, end) &&
+           push8(harq_info_rel13->cdm_index, ppWritePackedMsg, end) &&
+           push8(harq_info_rel13->n_srs, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_config_request_harq_information(nfapi_ul_config_harq_information *harq_info, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG, &harq_info->harq_information_rel10_tdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel10_tdd_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG, &harq_info->harq_information_rel8_fdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel8_fdd_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG, &harq_info->harq_information_rel9_fdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel9_fdd_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG, &harq_info->harq_information_rel11, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel11_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG, &harq_info->harq_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel13_value));
+}
+
+static uint8_t pack_ul_config_request_cqi_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_cqi_information_rel8_t *cqi_info_rel8 = (nfapi_ul_config_cqi_information_rel8_t *)tlv;
+  return ( push16(cqi_info_rel8->pucch_index, ppWritePackedMsg, end) &&
+           push8(cqi_info_rel8->dl_cqi_pmi_size, ppWritePackedMsg, end));
+}
+static uint8_t pack_ul_config_request_cqi_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_cqi_information_rel10_t *cqi_info_rel10 = (nfapi_ul_config_cqi_information_rel10_t *)tlv;
+  return ( push8(cqi_info_rel10->number_of_pucch_resource, ppWritePackedMsg, end) &&
+           push16(cqi_info_rel10->pucch_index_p1, ppWritePackedMsg, end));
+}
+static uint8_t pack_ul_config_request_cqi_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_cqi_information_rel13_t *cqi_info_rel13 = (nfapi_ul_config_cqi_information_rel13_t *)tlv;
+  return ( push8(cqi_info_rel13->csi_mode, ppWritePackedMsg, end) &&
+           push16(cqi_info_rel13->dl_cqi_pmi_size_2, ppWritePackedMsg, end) &&
+           push8(cqi_info_rel13->starting_prb, ppWritePackedMsg, end) &&
+           push8(cqi_info_rel13->n_prb, ppWritePackedMsg, end) &&
+           push8(cqi_info_rel13->cdm_index, ppWritePackedMsg, end) &&
+           push8(cqi_info_rel13->n_srs, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_config_request_cqi_information(nfapi_ul_config_cqi_information *cqi_info, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG, &cqi_info->cqi_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel8_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG, &cqi_info->cqi_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel10_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG, &cqi_info->cqi_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel13_value));
+}
+
+static uint8_t pack_ul_config_request_sr_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_sr_information_rel8_t *sr_info_rel8 = (nfapi_ul_config_sr_information_rel8_t *)tlv;
+  return push16(sr_info_rel8->pucch_index, ppWritePackedMsg, end);
+}
+static uint8_t pack_ul_config_request_sr_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_sr_information_rel10_t *sr_info_rel10 = (nfapi_ul_config_sr_information_rel10_t *)tlv;
+  return ( push8(sr_info_rel10->number_of_pucch_resources, ppWritePackedMsg, end) &&
+           push16(sr_info_rel10->pucch_index_p1, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_config_request_sr_information(nfapi_ul_config_sr_information *sr_info, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG, &sr_info->sr_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_sr_info_rel8_value) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG, &sr_info->sr_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_sr_info_rel10_value));
+}
+
+static uint8_t pack_ul_config_request_srs_pdu_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_srs_pdu_rel8_t *srs_pdu_rel8 = (nfapi_ul_config_srs_pdu_rel8_t *)tlv;
+  return (push32(srs_pdu_rel8->handle, ppWritePackedMsg, end) &&
+          push16(srs_pdu_rel8->size, ppWritePackedMsg, end) &&
+          push16(srs_pdu_rel8->rnti, ppWritePackedMsg, end) &&
+          push8(srs_pdu_rel8->srs_bandwidth, ppWritePackedMsg, end) &&
+          push8(srs_pdu_rel8->frequency_domain_position, ppWritePackedMsg, end) &&
+          push8(srs_pdu_rel8->srs_hopping_bandwidth, ppWritePackedMsg, end) &&
+          push8(srs_pdu_rel8->transmission_comb, ppWritePackedMsg, end) &&
+          push16(srs_pdu_rel8->i_srs, ppWritePackedMsg, end) &&
+          push8(srs_pdu_rel8->sounding_reference_cyclic_shift, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_config_request_srs_pdu_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_srs_pdu_rel10_t *srs_pdu_rel10 = (nfapi_ul_config_srs_pdu_rel10_t *)tlv;
+  return push8(srs_pdu_rel10->antenna_port, ppWritePackedMsg, end);
+}
+
+static uint8_t pack_ul_config_request_srs_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_srs_pdu_rel13_t *srs_pdu_rel13 = (nfapi_ul_config_srs_pdu_rel13_t *)tlv;
+  return ( push8(srs_pdu_rel13->number_of_combs, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_config_request_nb_harq_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_nb_harq_information_rel13_fdd_t *nb_harq_pdu_rel13 = (nfapi_ul_config_nb_harq_information_rel13_fdd_t *)tlv;
+  return ( push8(nb_harq_pdu_rel13->harq_ack_resource, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_config_request_nulsch_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_nulsch_pdu_rel13_t *nulsch_pdu_rel13 = (nfapi_ul_config_nulsch_pdu_rel13_t *)tlv;
+  return (push8(nulsch_pdu_rel13->nulsch_format, ppWritePackedMsg, end) &&
+          push32(nulsch_pdu_rel13->handle, ppWritePackedMsg, end) &&
+          push16(nulsch_pdu_rel13->size, ppWritePackedMsg, end) &&
+          push16(nulsch_pdu_rel13->rnti, ppWritePackedMsg, end) &&
+          push8(nulsch_pdu_rel13->subcarrier_indication, ppWritePackedMsg, end) &&
+          push8(nulsch_pdu_rel13->resource_assignment, ppWritePackedMsg, end) &&
+          push8(nulsch_pdu_rel13->mcs, ppWritePackedMsg, end) &&
+          push8(nulsch_pdu_rel13->redudancy_version, ppWritePackedMsg, end) &&
+          push8(nulsch_pdu_rel13->repetition_number, ppWritePackedMsg, end) &&
+          push8(nulsch_pdu_rel13->new_data_indication, ppWritePackedMsg, end) &&
+          push8(nulsch_pdu_rel13->n_srs, ppWritePackedMsg, end) &&
+          push16(nulsch_pdu_rel13->scrambling_sequence_initialization_cinit, ppWritePackedMsg, end) &&
+          push16(nulsch_pdu_rel13->sf_idx, ppWritePackedMsg, end) &&
+          pack_ul_config_request_ue_information(&(nulsch_pdu_rel13->ue_information), ppWritePackedMsg, end) &&
+          pack_tlv(NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG, &nulsch_pdu_rel13->nb_harq_information.nb_harq_information_rel13_fdd, ppWritePackedMsg, end,
+                   &pack_ul_config_request_nb_harq_rel13_value));
+}
+static uint8_t pack_ul_config_request_nrach_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_nrach_pdu_rel13_t *nrach_pdu_rel13 = (nfapi_ul_config_nrach_pdu_rel13_t *)tlv;
+  return ( push8(nrach_pdu_rel13->nprach_config_0, ppWritePackedMsg, end) &&
+           push8(nrach_pdu_rel13->nprach_config_1, ppWritePackedMsg, end) &&
+           push8(nrach_pdu_rel13->nprach_config_2, ppWritePackedMsg, end));
+}
+
+
+
+static uint8_t pack_ul_tti_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nr_ul_tti_request_number_of_pdus_t *value = (nfapi_nr_ul_tti_request_number_of_pdus_t *)tlv;
+
+  if(!(push16(value->pdu_size, ppWritePackedMsg, end) &&
+       push16(value->pdu_type, ppWritePackedMsg, end) ))
+    return 0;
+
+  // first match the pdu type, then call the respective function
+  switch(value->pdu_type) {
+    case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: {
+      if(!pack_ul_tti_request_prach_pdu(&value->prach_pdu, ppWritePackedMsg, end))
+        return 0;
+    }
+    break;
+
+    case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
+      if(!pack_ul_tti_request_pucch_pdu(&value->pucch_pdu, ppWritePackedMsg, end))
+        return 0;
+    }
+    break;
+
+    case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
+      if(!pack_ul_tti_request_pusch_pdu(&value->pusch_pdu, ppWritePackedMsg, end))
+        return 0;
+    }
+    break;
+
+    case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: {
+      if(!pack_ul_tti_request_srs_pdu(&value->srs_pdu, ppWritePackedMsg, end))
+        return 0;
+    }
+    break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", value->pdu_type );
+    }
+    break;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_ul_tti_groups_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nr_ul_tti_request_number_of_groups_t *value = (nfapi_nr_ul_tti_request_number_of_groups_t *)tlv;
+
+  if(!push8(value->n_ue, ppWritePackedMsg, end))
+    return 0;
+
+  for(int i=0; i<value->n_ue; i++) {
+    if(!push8(value->ue_list[i].pdu_idx, ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_ul_config_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_config_request_body_t *value = (nfapi_ul_config_request_body_t *)tlv;
+
+  if(!(push8(value->number_of_pdus, ppWritePackedMsg, end) &&
+       push8(value->rach_prach_frequency_resources, ppWritePackedMsg, end) &&
+       push8(value->srs_present, ppWritePackedMsg, end)))
+    return 0;
+
+  uint16_t i = 0;
+
+  for(i = 0; i < value->number_of_pdus; ++i) {
+    nfapi_ul_config_request_pdu_t *pdu = &(value->ul_config_pdu_list[i]);
+
+    if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    // Put a 0 size in and then determine the size after the pdu
+    // has been writen and write the calculated size
+    uint8_t *pWritePackedMsgPduSize = *ppWritePackedMsg;
+    pdu->pdu_size = 0;
+
+    if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    switch(pdu->pdu_type) {
+      case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: {
+        if(!pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_pdu), ppWritePackedMsg, end))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: {
+        if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_cqi_ri_pdu.ulsch_pdu), ppWritePackedMsg, end) &&
+             pack_ul_config_request_cqi_ri_information(&(pdu->ulsch_cqi_ri_pdu.cqi_ri_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_cqi_ri_pdu.initial_transmission_parameters), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: {
+        if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) &&
+             pack_ul_config_request_ulsch_harq_information(&(pdu->ulsch_harq_pdu.harq_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_harq_pdu.initial_transmission_parameters), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: {
+        if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu), ppWritePackedMsg, end) &&
+             pack_ul_config_request_cqi_ri_information(&(pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_ulsch_harq_information(&(pdu->ulsch_cqi_harq_ri_pdu.harq_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: {
+        if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_pdu.ue_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_cqi_information(&(pdu->uci_cqi_pdu.cqi_information), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: {
+        if(!(pack_ul_config_request_ue_information(&(pdu->uci_sr_pdu.ue_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_sr_information(&(pdu->uci_sr_pdu.sr_information), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: {
+        if(!(pack_ul_config_request_ue_information(&(pdu->uci_harq_pdu.ue_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_harq_information(&(pdu->uci_harq_pdu.harq_information), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: {
+        if(!(pack_ul_config_request_ue_information(&(pdu->uci_sr_harq_pdu.ue_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_sr_information(&(pdu->uci_sr_harq_pdu.sr_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_harq_information(&(pdu->uci_sr_harq_pdu.harq_information), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: {
+        if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_harq_pdu.ue_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_cqi_information(&(pdu->uci_cqi_harq_pdu.cqi_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_harq_information(&(pdu->uci_cqi_harq_pdu.harq_information), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: {
+        if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_sr_pdu.ue_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_cqi_information(&(pdu->uci_cqi_sr_pdu.cqi_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_sr_information(&(pdu->uci_cqi_sr_pdu.sr_information), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: {
+        if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_sr_harq_pdu.ue_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_cqi_information(&(pdu->uci_cqi_sr_harq_pdu.cqi_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_sr_information(&(pdu->uci_cqi_sr_harq_pdu.sr_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_harq_information(&(pdu->uci_cqi_sr_harq_pdu.harq_information), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_SRS_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG, &pdu->srs_pdu.srs_pdu_rel8, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel8_value) &&
+             pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG, &pdu->srs_pdu.srs_pdu_rel10, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel10_value) &&
+             pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG, &pdu->srs_pdu.srs_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel13_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE: {
+        if(!(pack_ul_config_request_ue_information(&(pdu->harq_buffer_pdu.ue_information), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: {
+        if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_uci_csi_pdu.ulsch_pdu), ppWritePackedMsg, end) &&
+             pack_ul_config_request_cqi_information(&(pdu->ulsch_uci_csi_pdu.csi_information), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: {
+        if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_uci_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) &&
+             pack_ul_config_request_harq_information(&(pdu->ulsch_uci_harq_pdu.harq_information), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: {
+        if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_csi_uci_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) &&
+             pack_ul_config_request_cqi_information(&(pdu->ulsch_csi_uci_harq_pdu.csi_information), ppWritePackedMsg, end) &&
+             pack_ul_config_request_harq_information(&(pdu->ulsch_csi_uci_harq_pdu.harq_information), ppWritePackedMsg, end)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG, &pdu->nulsch_pdu.nulsch_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_nulsch_pdu_rel13_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_NRACH_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG, &pdu->nrach_pdu.nrach_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_nrach_pdu_rel13_value)))
+          return 0;
+      }
+      break;
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type );
+      }
+      break;
+    };
+
+    // add 1 for the pdu_type. The delta will include the pdu_size
+    pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize);
+
+    push8(pdu->pdu_size, &pWritePackedMsgPduSize, end);
+  }
+
+  return 1;
+}
+
+
+static uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
+
+  if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) &&
+        push16(pNfapiMsg->Slot, ppWritePackedMsg, end) &&
+        push8(pNfapiMsg->n_pdus, ppWritePackedMsg, end) &&
+        push8(pNfapiMsg->rach_present, ppWritePackedMsg, end) &&
+        push8(pNfapiMsg->n_ulsch, ppWritePackedMsg, end) &&
+        push8(pNfapiMsg->n_ulcch, ppWritePackedMsg, end) &&
+        push8(pNfapiMsg->n_group, ppWritePackedMsg, end) ))
+    return 0;
+
+  for(int i=0; i<pNfapiMsg->n_pdus; i++) {
+    if(!pack_ul_tti_pdu_list_value(&pNfapiMsg->pdus_list[i], ppWritePackedMsg, end))
+      return 0;
+  }
+
+  for(int i=0; i<pNfapiMsg->n_group; i++) {
+    if(!pack_ul_tti_groups_list_value(&pNfapiMsg->groups_list[i], ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+
+static uint8_t pack_ul_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t *)msg;
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_UL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->ul_config_request_body, ppWritePackedMsg, end, &pack_ul_config_request_body_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)) ;
+}
+
+static uint8_t pack_hi_dci0_hi_rel8_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_hi_pdu_rel8_t *hi_pdu_rel8 = (nfapi_hi_dci0_hi_pdu_rel8_t *)tlv;
+  return ( push8(hi_pdu_rel8->resource_block_start, ppWritePackedMsg, end) &&
+           push8(hi_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) &&
+           push8(hi_pdu_rel8->hi_value, ppWritePackedMsg, end) &&
+           push8(hi_pdu_rel8->i_phich, ppWritePackedMsg, end) &&
+           push16(hi_pdu_rel8->transmission_power, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_hi_dci0_hi_rel10_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_hi_pdu_rel10_t *hi_pdu_rel10 = (nfapi_hi_dci0_hi_pdu_rel10_t *)tlv;
+  return ( push8(hi_pdu_rel10->flag_tb2, ppWritePackedMsg, end) &&
+           push8(hi_pdu_rel10->hi_value_2, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_hi_dci0_dci_rel8_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_dci_pdu_rel8_t *dci_pdu_rel8 = (nfapi_hi_dci0_dci_pdu_rel8_t *)tlv;
+  return ( push8(dci_pdu_rel8->dci_format, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->cce_index, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->aggregation_level, ppWritePackedMsg, end) &&
+           push16(dci_pdu_rel8->rnti, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->resource_block_start, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->number_of_resource_block, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->mcs_1, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->frequency_hopping_enabled_flag, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->frequency_hopping_bits, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->new_data_indication_1, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->ue_tx_antenna_seleciton, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->tpc, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->cqi_csi_request, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->ul_index, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel8->dl_assignment_index, ppWritePackedMsg, end) &&
+           push32(dci_pdu_rel8->tpc_bitmap, ppWritePackedMsg, end) &&
+           push16(dci_pdu_rel8->transmission_power, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_hi_dci0_dci_rel10_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_dci_pdu_rel10_t *dci_pdu_rel10 = (nfapi_hi_dci0_dci_pdu_rel10_t *)tlv;
+  return ( push8(dci_pdu_rel10->cross_carrier_scheduling_flag, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel10->carrier_indicator, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel10->size_of_cqi_csi_feild, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel10->srs_flag, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel10->srs_request, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel10->resource_allocation_flag, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel10->resource_allocation_type, ppWritePackedMsg, end) &&
+           push32(dci_pdu_rel10->resource_block_coding, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel10->mcs_2, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel10->new_data_indication_2, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel10->number_of_antenna_ports, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel10->tpmi, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel10->total_dci_length_including_padding, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel10->n_ul_rb, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_hi_dci0_dci_rel12_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_dci_pdu_rel12_t *dci_pdu_rel12 = (nfapi_hi_dci0_dci_pdu_rel12_t *)tlv;
+  return ( push8(dci_pdu_rel12->pscch_resource, ppWritePackedMsg, end) &&
+           push8(dci_pdu_rel12->time_resource_pattern, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_hi_dci0_mpdcch_dci_rel13_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t *mpdcch_dci_pdu_rel13 = (nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t *)tlv;
+  return ( push8(mpdcch_dci_pdu_rel13->mpdcch_narrowband, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->number_of_prb_pairs, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->resource_block_assignment, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->mpdcch_transmission_type, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->start_symbol, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->ecce_index, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->aggreagation_level, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->rnti_type, ppWritePackedMsg, end) &&
+           push16(mpdcch_dci_pdu_rel13->rnti, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->ce_mode, ppWritePackedMsg, end) &&
+           push16(mpdcch_dci_pdu_rel13->drms_scrambling_init, ppWritePackedMsg, end) &&
+           push16(mpdcch_dci_pdu_rel13->initial_transmission_sf_io, ppWritePackedMsg, end) &&
+           push16(mpdcch_dci_pdu_rel13->transmission_power, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->dci_format, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->resource_block_start, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->number_of_resource_blocks, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->mcs, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->pusch_repetition_levels, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->frequency_hopping_flag, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->new_data_indication, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->harq_process, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->redudency_version, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->tpc, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->csi_request, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->ul_inex, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->dai_presence_flag, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->dl_assignment_index, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->srs_request, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->dci_subframe_repetition_number, ppWritePackedMsg, end) &&
+           push32(mpdcch_dci_pdu_rel13->tcp_bitmap, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->total_dci_length_include_padding, ppWritePackedMsg, end) &&
+           push8(mpdcch_dci_pdu_rel13->number_of_tx_antenna_ports, ppWritePackedMsg, end) &&
+           pusharray16(mpdcch_dci_pdu_rel13->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, mpdcch_dci_pdu_rel13->number_of_tx_antenna_ports, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_hi_dci0_npdcch_dci_rel13_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_npdcch_dci_pdu_rel13_t *npdcch_dci_pdu_rel13 = (nfapi_hi_dci0_npdcch_dci_pdu_rel13_t *)tlv;
+  return ( push8(npdcch_dci_pdu_rel13->ncce_index, ppWritePackedMsg, end) &&
+           push8(npdcch_dci_pdu_rel13->aggregation_level, ppWritePackedMsg, end) &&
+           push8(npdcch_dci_pdu_rel13->start_symbol, ppWritePackedMsg, end) &&
+           push16(npdcch_dci_pdu_rel13->rnti, ppWritePackedMsg, end) &&
+           push8(npdcch_dci_pdu_rel13->scrambling_reinitialization_batch_index, ppWritePackedMsg, end) &&
+           push8(npdcch_dci_pdu_rel13->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end) &&
+           push8(npdcch_dci_pdu_rel13->subcarrier_indication, ppWritePackedMsg, end) &&
+           push8(npdcch_dci_pdu_rel13->resource_assignment, ppWritePackedMsg, end) &&
+           push8(npdcch_dci_pdu_rel13->scheduling_delay, ppWritePackedMsg, end) &&
+           push8(npdcch_dci_pdu_rel13->mcs, ppWritePackedMsg, end) &&
+           push8(npdcch_dci_pdu_rel13->redudancy_version, ppWritePackedMsg, end) &&
+           push8(npdcch_dci_pdu_rel13->repetition_number, ppWritePackedMsg, end) &&
+           push8(npdcch_dci_pdu_rel13->new_data_indicator, ppWritePackedMsg, end) &&
+           push8(npdcch_dci_pdu_rel13->dci_subframe_repetition_number, ppWritePackedMsg, end));
+}
+
+
+static uint8_t pack_hi_dci0_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_request_body_t *value = (nfapi_hi_dci0_request_body_t *)tlv;
+
+  if(!(push16(value->sfnsf, ppWritePackedMsg, end) &&
+       push8(value->number_of_dci, ppWritePackedMsg, end) &&
+       push8(value->number_of_hi, ppWritePackedMsg, end)))
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_pdus = value->number_of_dci + value->number_of_hi;
+
+  for(i = 0; i < total_number_of_pdus; ++i) {
+    nfapi_hi_dci0_request_pdu_t *pdu = &(value->hi_dci0_pdu_list[i]);
+
+    if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    // Put a 0 size in and then determine the size after the pdu
+    // has been writen and write the calculated size
+    uint8_t *pWritePackedMsgPduSize = *ppWritePackedMsg;
+    pdu->pdu_size = 0;
+
+    if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    switch(pdu->pdu_type) {
+      case NFAPI_HI_DCI0_HI_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG, &pdu->hi_pdu.hi_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_hi_rel8_pdu_value) &&
+             pack_tlv(NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG, &pdu->hi_pdu.hi_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_hi_rel10_pdu_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_HI_DCI0_DCI_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG, &pdu->dci_pdu.dci_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_dci_rel8_pdu_value) &&
+             pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG, &pdu->dci_pdu.dci_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_dci_rel10_pdu_value) &&
+             pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG, &pdu->dci_pdu.dci_pdu_rel12, ppWritePackedMsg, end, pack_hi_dci0_dci_rel12_pdu_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_dci_rel8_pdu_value) &&
+             pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_dci_rel10_pdu_value) &&
+             pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG, &pdu->epdcch_dci_pdu.epdcch_parameters_rel11, ppWritePackedMsg, end, pack_dl_config_epdcch_parameters_rel11_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG, &pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13, ppWritePackedMsg, end, pack_hi_dci0_mpdcch_dci_rel13_pdu_value)))
+          return 0;
+      }
+      break;
+
+      case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE: {
+        if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG, &pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13, ppWritePackedMsg, end, pack_hi_dci0_npdcch_dci_rel13_pdu_value)))
+          return 0;
+      }
+      break;
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type );
+      }
+      break;
+    };
+
+    // add 1 for the pdu_type. The delta will include the pdu_size
+    pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize);
+
+    push8(pdu->pdu_size, &pWritePackedMsgPduSize, end);
+  }
+
+  return 1;
+}
+
+static uint8_t pack_ul_dci_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nr_ul_dci_request_pdus_t *value = (nfapi_nr_ul_dci_request_pdus_t *)tlv;
+
+  for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i) {
+    if(!push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI, ppWritePackedMsg, end) &&
+        push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, ppWritePackedMsg, end) &&
+        push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end) &&
+        push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, ppWritePackedMsg, end) &&
+        push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, ppWritePackedMsg, end) &&
+        push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end) &&
+        push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
+        push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
+        pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end));
+
+    return 0;
+  }
+
+  return (push16(value->PDUType, ppWritePackedMsg, end) &&
+          push16(value->PDUSize, ppWritePackedMsg, end) &&
+          push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, ppWritePackedMsg, end) &&
+          push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, ppWritePackedMsg, end) &&
+          push8(value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, ppWritePackedMsg, end) &&
+          push8(value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, ppWritePackedMsg, end) &&
+          push8(value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, ppWritePackedMsg, end) &&
+          push8(value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, ppWritePackedMsg, end) &&
+          pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, ppWritePackedMsg, end) &&
+          push8(value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, ppWritePackedMsg, end) &&
+          push8(value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, ppWritePackedMsg, end) &&
+          push8(value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, ppWritePackedMsg, end) &&
+          push8(value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, ppWritePackedMsg, end) &&
+          push16(value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_dci_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t *)msg;
+
+  if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) &&
+        push16(pNfapiMsg->Slot, ppWritePackedMsg, end) &&
+        push8(pNfapiMsg->numPdus, ppWritePackedMsg, end)
+       ))
+    return 0;
+
+  for(int i=0; i<pNfapiMsg->numPdus; i++) {
+    if(!pack_ul_dci_pdu_list_value(&pNfapiMsg->ul_dci_pdu_list[i], ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+
+
+static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t *)msg;
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_HI_DCI0_REQUEST_BODY_TAG, &pNfapiMsg->hi_dci0_request_body, ppWritePackedMsg, end, &pack_hi_dci0_request_body_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+//pack_tx_data_pdu_list_value
+static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)tlv;
+
+  if(!(push32(value->num_TLV, ppWritePackedMsg, end) &&
+       push16(value->PDU_index, ppWritePackedMsg, end) &&
+       push16(value->PDU_length, ppWritePackedMsg, end)
+      ))
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_tlvs = value->num_TLV;
+
+  for(; i < total_number_of_tlvs; ++i) {
+    if (!(push16(value->TLVs[i].length, ppWritePackedMsg, end) &&
+          push16(value->TLVs[i].tag, ppWritePackedMsg, end)))
+      return 0;
+
+    switch(value->TLVs[i].tag) {
+      case 0: {
+        if(!pusharray32(value->TLVs[i].value.direct, 16384, value->TLVs[i].length, ppWritePackedMsg, end))
+          return 0;
+
+        break;
+      }
+
+      case 1: {
+        if(!pusharray32(value->TLVs[i].value.ptr, value->TLVs[i].length, value->TLVs[i].length, ppWritePackedMsg, end))
+          return 0;
+
+        break;
+      }
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", value->TLVs[i].tag );
+        break;
+      }
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t pack_tx_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_tx_request_body_t *value = (nfapi_tx_request_body_t *)tlv;
+
+  if(push16(value->number_of_pdus, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_pdus = value->number_of_pdus;
+
+  for(; i < total_number_of_pdus; ++i) {
+    nfapi_tx_request_pdu_t *pdu = &(value->tx_pdu_list[i]);
+
+    if(!(push16(pdu->pdu_length, ppWritePackedMsg, end) &&
+         push16(pdu->pdu_index, ppWritePackedMsg, end)))
+      return 0;
+
+    uint8_t j;
+
+    for(j = 0; j < pdu->num_segments; ++j) {
+      // Use -1 as it is unbounded
+      // DJP - does not handle -1
+      // DJP - if(pusharray8(pdu->segments[j].segment_data, (uint32_t)(-1), pdu->segments[j].segment_length, ppWritePackedMsg, end) == 0)
+      int push_ret = pusharray8(pdu->segments[j].segment_data, 65535, pdu->segments[j].segment_length, ppWritePackedMsg, end);
+
+      if (pdu->segments[j].segment_length == 3) {
+        NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__,
+                    pdu->segments[j].segment_data[0],
+                    pdu->segments[j].segment_data[1],
+                    pdu->segments[j].segment_data[2]
+                   );
+      }
+
+      //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() segment_data:%p segment_length:%u pusharray8()=%d\n", __FUNCTION__, pdu->segments[j].segment_data, pdu->segments[j].segment_length, push_ret);
+
+      if (push_ret == 0) {
+        return 0;
+      }
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t pack_tx_data_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)msg;
+
+  if (!(
+        push16(pNfapiMsg->SFN, ppWritePackedMsg, end) &&
+        push16(pNfapiMsg->Slot, ppWritePackedMsg, end) &&
+        push16(pNfapiMsg->Number_of_PDUs, ppWritePackedMsg, end)
+      ))
+    return 0;
+
+  for(int i=0; i<pNfapiMsg->Number_of_PDUs; i++) {
+    if(!pack_tx_data_pdu_list_value(&pNfapiMsg->pdu_list[i], ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t *)msg;
+  int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end);
+  int y = pack_tlv(NFAPI_TX_REQUEST_BODY_TAG, &pNfapiMsg->tx_request_body, ppWritePackedMsg, end, &pack_tx_request_body_value);
+  int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() x:%d y:%d z:%d\n", __FUNCTION__, x, y, z);
+  return x && y && z;
+}
+
+static uint8_t pack_release_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ue_release_request_body_t *value = (nfapi_ue_release_request_body_t *)tlv;
+
+  if(push16(value->number_of_TLVs, ppWritePackedMsg, end) == 0) {
+    return 0;
+  }
+
+  uint8_t j;
+  uint16_t num = value->number_of_TLVs;
+
+  for(j = 0; j < num; ++j) {
+    if(push16(value->ue_release_request_TLVs_list[j].rnti, ppWritePackedMsg, end) == 0) {
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t pack_ue_release_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t *)msg;
+  int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end);
+  int y = pack_tlv(NFAPI_UE_RELEASE_BODY_TAG, &pNfapiMsg->ue_release_request_body, ppWritePackedMsg, end, &pack_release_request_body_value);
+  int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+  return x && y && z;
+}
+
+static uint8_t pack_ue_release_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t *)msg;
+  int x = push32(pNfapiMsg->error_code, ppWritePackedMsg, end);
+  int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+  return x && z;
+}
+
+static uint8_t pack_rx_ue_information_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_rx_ue_information *value = (nfapi_rx_ue_information *)tlv;
+  return ( push32(value->handle, ppWritePackedMsg, end) &&
+           push16(value->rnti, ppWritePackedMsg, end) );
+}
+
+static uint8_t unpack_rx_ue_information_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_rx_ue_information *value = (nfapi_rx_ue_information *)tlv;
+  return ( pull32(ppReadPackedMsg, &value->handle, end) &&
+           pull16(ppReadPackedMsg, &value->rnti, end));
+}
+
+static uint8_t pack_harq_indication_tdd_harq_data_bundling(nfapi_harq_indication_tdd_harq_data_bundling_t *data, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return ( push8(data->value_0, ppWritePackedMsg, end) &&
+           push8(data->value_1, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_harq_indication_tdd_harq_data_multiplexing(nfapi_harq_indication_tdd_harq_data_multiplexing_t *data, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return ( push8(data->value_0, ppWritePackedMsg, end) &&
+           push8(data->value_1, ppWritePackedMsg, end) &&
+           push8(data->value_2, ppWritePackedMsg, end) &&
+           push8(data->value_3, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_harq_indication_tdd_harq_data_special_bundling(nfapi_harq_indication_tdd_harq_data_special_bundling_t *data, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return ( push8(data->value_0, ppWritePackedMsg, end) );
+}
+
+static uint8_t pack_harq_indication_tdd_harq_data(nfapi_harq_indication_tdd_harq_data_t *data, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return ( push8(data->value_0, ppWritePackedMsg, end) );
+}
+
+static uint8_t pack_harq_indication_tdd_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_harq_indication_tdd_rel8_t *harq_indication_tdd_rel8 = (nfapi_harq_indication_tdd_rel8_t *)tlv;
+
+  if(!(push8(harq_indication_tdd_rel8->mode, ppWritePackedMsg, end) &&
+       push8(harq_indication_tdd_rel8->number_of_ack_nack, ppWritePackedMsg, end)))
+    return 0;
+
+  uint8_t result = 0;
+
+  switch(harq_indication_tdd_rel8->mode) {
+    case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING:
+      result = pack_harq_indication_tdd_harq_data_bundling(&harq_indication_tdd_rel8->harq_data.bundling, ppWritePackedMsg, end);
+      break;
+
+    case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING:
+      result = pack_harq_indication_tdd_harq_data_multiplexing(&harq_indication_tdd_rel8->harq_data.multiplex, ppWritePackedMsg, end);
+      break;
+
+    case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING:
+      result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel8->harq_data.special_bundling, ppWritePackedMsg, end);
+      break;
+
+    case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION:
+    case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3:
+      result = 1;
+      break;
+
+    default:
+      // err....
+      break;
+  }
+
+  return result;
+}
+
+static uint8_t pack_harq_indication_tdd_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_harq_indication_tdd_rel9_t *harq_indication_tdd_rel9 = (nfapi_harq_indication_tdd_rel9_t *)tlv;
+
+  if(!(push8(harq_indication_tdd_rel9->mode, ppWritePackedMsg, end) &&
+       push8(harq_indication_tdd_rel9->number_of_ack_nack, ppWritePackedMsg, end)))
+    return 0;
+
+  uint8_t idx;
+
+  for(idx = 0; idx < harq_indication_tdd_rel9->number_of_ack_nack; ++idx) {
+    uint8_t result = 0;
+
+    switch(harq_indication_tdd_rel9->mode) {
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING:
+        result = pack_harq_indication_tdd_harq_data(&(harq_indication_tdd_rel9->harq_data[idx].bundling), ppWritePackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING:
+        result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].multiplex, ppWritePackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING:
+        result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel9->harq_data[idx].special_bundling, ppWritePackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION:
+        result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].channel_selection, ppWritePackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3:
+        result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].format_3, ppWritePackedMsg, end);
+        break;
+
+      default:
+        // err....
+        break;
+    }
+
+    if(result == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_harq_indication_tdd_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_harq_indication_tdd_rel13_t *harq_indication_tdd_rel13 = (nfapi_harq_indication_tdd_rel13_t *)tlv;
+
+  if(!(push8(harq_indication_tdd_rel13->mode, ppWritePackedMsg, end) &&
+       push16(harq_indication_tdd_rel13->number_of_ack_nack, ppWritePackedMsg, end)))
+    return 0;
+
+  uint8_t idx;
+
+  for(idx = 0; idx < harq_indication_tdd_rel13->number_of_ack_nack; ++idx) {
+    uint8_t result = 0;
+
+    switch(harq_indication_tdd_rel13->mode) {
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING:
+        result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].bundling, ppWritePackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING:
+        result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].multiplex, ppWritePackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING:
+        result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel13->harq_data[idx].special_bundling, ppWritePackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION:
+        result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].channel_selection, ppWritePackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3:
+        result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_3, ppWritePackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_4:
+        result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_4, ppWritePackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_5:
+        result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_5, ppWritePackedMsg, end);
+        break;
+
+      default:
+        // err....
+        break;
+    }
+
+    if(result == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_harq_indication_fdd_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_harq_indication_fdd_rel8_t *harq_indication_fdd_rel8 = (nfapi_harq_indication_fdd_rel8_t *)tlv;
+  return ( push8(harq_indication_fdd_rel8->harq_tb1, ppWritePackedMsg, end) &&
+           push8(harq_indication_fdd_rel8->harq_tb2, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_harq_indication_fdd_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_harq_indication_fdd_rel9_t *harq_indication_fdd_rel9 = (nfapi_harq_indication_fdd_rel9_t *)tlv;
+  return ( push8(harq_indication_fdd_rel9->mode, ppWritePackedMsg, end) &&
+           push8(harq_indication_fdd_rel9->number_of_ack_nack, ppWritePackedMsg, end) &&
+           pusharray8(harq_indication_fdd_rel9->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL9_MAX, harq_indication_fdd_rel9->number_of_ack_nack, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_harq_indication_fdd_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_harq_indication_fdd_rel13_t *harq_indication_fdd_rel13 = (nfapi_harq_indication_fdd_rel13_t *)tlv;
+  return ( push8(harq_indication_fdd_rel13->mode, ppWritePackedMsg, end) &&
+           push16(harq_indication_fdd_rel13->number_of_ack_nack, ppWritePackedMsg, end) &&
+           pusharray8(harq_indication_fdd_rel13->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL13_MAX, harq_indication_fdd_rel13->number_of_ack_nack, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_ul_cqi_information_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_ul_cqi_information_t *value = (nfapi_ul_cqi_information_t *)tlv;
+  return ( push8(value->ul_cqi, ppWritePackedMsg, end) &&
+           push8(value->channel, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_harq_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_harq_indication_body_t *value = (nfapi_harq_indication_body_t *)tlv;
+
+  if(push16(value->number_of_harqs, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_pdus = value->number_of_harqs;
+
+  for(; i < total_number_of_pdus; ++i) {
+    nfapi_harq_indication_pdu_t *pdu = &(value->harq_pdu_list[i]);
+    uint8_t *instance_length_p = *ppWritePackedMsg;
+
+    if(!push16(pdu->instance_length, ppWritePackedMsg, end))
+      return 0;
+
+    if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) &&
+         pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL8_TAG, &pdu->harq_indication_tdd_rel8, ppWritePackedMsg, end, pack_harq_indication_tdd_rel8_value) &&
+         pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL9_TAG, &pdu->harq_indication_tdd_rel9, ppWritePackedMsg, end, pack_harq_indication_tdd_rel9_value) &&
+         pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL13_TAG, &pdu->harq_indication_tdd_rel13, ppWritePackedMsg, end, pack_harq_indication_tdd_rel13_value) &&
+         pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL8_TAG, &pdu->harq_indication_fdd_rel8, ppWritePackedMsg, end, pack_harq_indication_fdd_rel8_value) &&
+         pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL9_TAG, &pdu->harq_indication_fdd_rel9, ppWritePackedMsg, end, pack_harq_indication_fdd_rel9_value) &&
+         pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL13_TAG, &pdu->harq_indication_fdd_rel13, ppWritePackedMsg, end, pack_harq_indication_fdd_rel13_value) &&
+         pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value)))
+      return 0;
+
+    // calculate the instance length subtracting the size of the instance
+    // length feild
+    uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
+    push16(instance_length, &instance_length_p, end);
+  }
+
+  return 1;
+}
+
+static uint8_t pack_harq_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_harq_indication_t *pNfapiMsg = (nfapi_harq_indication_t *)msg;
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->harq_indication_body, ppWritePackedMsg, end, pack_harq_indication_body_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_crc_indication_rel8_body(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_crc_indication_rel8_t *crc_indication_rel8 = (nfapi_crc_indication_rel8_t *)tlv;
+  return ( push8(crc_indication_rel8->crc_flag, ppWritePackedMsg, end) );
+}
+
+static uint8_t pack_crc_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_crc_indication_body_t *value = (nfapi_crc_indication_body_t *)tlv;
+
+  if(push16(value->number_of_crcs, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_pdus = value->number_of_crcs;
+
+  for(; i < total_number_of_pdus; ++i) {
+    nfapi_crc_indication_pdu_t *pdu = &(value->crc_pdu_list[i]);
+    uint8_t *instance_length_p = *ppWritePackedMsg;
+
+    if(!push16(pdu->instance_length, ppWritePackedMsg, end))
+      return 0;
+
+    if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) &&
+         pack_tlv(NFAPI_CRC_INDICATION_REL8_TAG, &pdu->crc_indication_rel8, ppWritePackedMsg, end, pack_crc_indication_rel8_body)))
+      return 0;
+
+    // calculate the instance length subtracting the size of the instance
+    // length feild
+    uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
+    push16(instance_length, &instance_length_p, end);
+  }
+
+  return 1;
+}
+
+static uint8_t pack_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_crc_indication_t *pNfapiMsg = (nfapi_crc_indication_t *)msg;
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_CRC_INDICATION_BODY_TAG, &pNfapiMsg->crc_indication_body, ppWritePackedMsg, end, &pack_crc_indication_body_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+static uint8_t pack_rx_indication_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_rx_indication_rel8_t *value = (nfapi_rx_indication_rel8_t *)tlv;
+  return ( push16(value->length, ppWritePackedMsg, end) &&
+           push16(value->offset, ppWritePackedMsg, end) &&
+           push8(value->ul_cqi, ppWritePackedMsg, end) &&
+           push16(value->timing_advance, ppWritePackedMsg, end));
+}
+static uint8_t pack_rx_indication_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_rx_indication_rel9_t *value = (nfapi_rx_indication_rel9_t *)tlv;
+  return ( push16(value->timing_advance_r9, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_rx_ulsch_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_rx_indication_body_t *value = (nfapi_rx_indication_body_t *)tlv;
+
+  //printf("RX ULSCH BODY\n");
+
+  if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  // need to calculate the data offset's.
+  uint16_t i = 0;
+  uint16_t offset = 2; // taking into account the number_of_pdus
+  uint16_t total_number_of_pdus = value->number_of_pdus;
+  //printf("ULSCH:pdus:%d\n", total_number_of_pdus);
+
+  for(i = 0; i < total_number_of_pdus; ++i) {
+    nfapi_rx_indication_pdu_t *pdu = &(value->rx_pdu_list[i]);
+
+    if(pdu->rx_ue_information.tl.tag == NFAPI_RX_UE_INFORMATION_TAG) {
+      //printf("NFAPI_RX_UE_INFORMATION_TAG\n");
+      offset += 4 + 6;
+    }
+
+    if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) {
+      //printf("NFAPI_RX_INDICATION_REL8_TAG\n");
+      offset += 4 + 7;
+    }
+
+    if(pdu->rx_indication_rel9.tl.tag == NFAPI_RX_INDICATION_REL9_TAG) {
+      //printf("NFAPI_RX_INDICATION_REL9_TAG\n");
+      offset += 4 + 2;
+    }
+  }
+
+  // Now update the structure to include the offset
+  for(i =0; i < total_number_of_pdus; ++i) {
+    nfapi_rx_indication_pdu_t *pdu = &(value->rx_pdu_list[i]);
+
+    if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) {
+      if(pdu->rx_indication_rel8.offset == 1) {
+        pdu->rx_indication_rel8.offset = offset;
+        offset += pdu->rx_indication_rel8.length;
+      }
+    }
+  }
+
+  // Write out the pdu
+  for(i = 0; i < total_number_of_pdus; ++i) {
+    nfapi_rx_indication_pdu_t *pdu = &(value->rx_pdu_list[i]);
+
+    if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) &&
+         pack_tlv(NFAPI_RX_INDICATION_REL8_TAG, &pdu->rx_indication_rel8, ppWritePackedMsg, end, pack_rx_indication_rel8_value) &&
+         pack_tlv(NFAPI_RX_INDICATION_REL9_TAG, &pdu->rx_indication_rel9, ppWritePackedMsg, end, pack_rx_indication_rel9_value)))
+      return 0;
+  }
+
+  // Write out the pdu data
+  for(i = 0; i < total_number_of_pdus; ++i) {
+    uint16_t length = 0;
+    nfapi_rx_indication_pdu_t *pdu = &(value->rx_pdu_list[i]);
+
+    if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) {
+      length = pdu->rx_indication_rel8.length;
+    }
+
+    if( pusharray8(value->rx_pdu_list[i].data, length, length, ppWritePackedMsg, end) == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+
+static uint8_t pack_rx_ulsch_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_rx_indication_t *pNfapiMsg = (nfapi_rx_indication_t *)msg;
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_RX_INDICATION_BODY_TAG, &pNfapiMsg->rx_indication_body, ppWritePackedMsg, end, pack_rx_ulsch_indication_body_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_preamble_pdu_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_preamble_pdu_rel8_t *preamble_rel8 = (nfapi_preamble_pdu_rel8_t *)tlv;
+  return ( push16(preamble_rel8->rnti, ppWritePackedMsg, end) &&
+           push8(preamble_rel8->preamble, ppWritePackedMsg, end) &&
+           push16(preamble_rel8->timing_advance, ppWritePackedMsg, end));
+}
+static uint8_t pack_preamble_pdu_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_preamble_pdu_rel9_t *preamble_rel9 = (nfapi_preamble_pdu_rel9_t *)tlv;
+  return ( push16(preamble_rel9->timing_advance_r9, ppWritePackedMsg, end) );
+}
+static uint8_t pack_preamble_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_preamble_pdu_rel13_t *preamble_rel13 = (nfapi_preamble_pdu_rel13_t *)tlv;
+  return ( push8(preamble_rel13->rach_resource_type, ppWritePackedMsg, end) );
+}
+
+static uint8_t pack_rach_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_rach_indication_body_t *value = (nfapi_rach_indication_body_t *)tlv;
+
+  if( push16(value->number_of_preambles, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_pdus = value->number_of_preambles;
+
+  for(; i < total_number_of_pdus; ++i) {
+    nfapi_preamble_pdu_t *pdu = &(value->preamble_list[i]);
+    uint8_t *instance_length_p = *ppWritePackedMsg;
+
+    if(!push16(pdu->instance_length, ppWritePackedMsg, end))
+      return 0;
+
+    if(!(pack_tlv(NFAPI_PREAMBLE_REL8_TAG, &pdu->preamble_rel8, ppWritePackedMsg, end, pack_preamble_pdu_rel8_value) &&
+         pack_tlv(NFAPI_PREAMBLE_REL9_TAG, &pdu->preamble_rel9, ppWritePackedMsg, end, pack_preamble_pdu_rel9_value) &&
+         pack_tlv(NFAPI_PREAMBLE_REL13_TAG, &pdu->preamble_rel13, ppWritePackedMsg, end, pack_preamble_pdu_rel13_value)))
+      return 0;
+
+    // calculate the instance length subtracting the size of the instance
+    // length feild
+    uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
+    push16(instance_length, &instance_length_p, end);
+  }
+
+  return 1;
+}
+
+static uint8_t pack_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_rach_indication_t *pNfapiMsg = (nfapi_rach_indication_t *)msg;
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_RACH_INDICATION_BODY_TAG, &pNfapiMsg->rach_indication_body, ppWritePackedMsg, end, pack_rach_indication_body_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_srs_indication_fdd_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_srs_indication_fdd_rel8_t *srs_pdu_rel8 = (nfapi_srs_indication_fdd_rel8_t *)tlv;
+  return ( push16(srs_pdu_rel8->doppler_estimation, ppWritePackedMsg, end) &&
+           push16(srs_pdu_rel8->timing_advance, ppWritePackedMsg, end) &&
+           push8(srs_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end) &&
+           push8(srs_pdu_rel8->rb_start, ppWritePackedMsg, end) &&
+           pusharray8(srs_pdu_rel8->snr, NFAPI_NUM_RB_MAX, srs_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_srs_indication_fdd_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_srs_indication_fdd_rel9_t *srs_pdu_rel9 = (nfapi_srs_indication_fdd_rel9_t *)tlv;
+  return ( push16(srs_pdu_rel9->timing_advance_r9, ppWritePackedMsg, end) );
+}
+
+static uint8_t pack_srs_indication_tdd_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_srs_indication_ttd_rel10_t *srs_pdu_rel10 = (nfapi_srs_indication_ttd_rel10_t *)tlv;
+  return ( push8(srs_pdu_rel10->uppts_symbol, ppWritePackedMsg, end) );
+}
+
+static uint8_t pack_srs_indication_fdd_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_srs_indication_fdd_rel11_t *srs_pdu_rel11 = (nfapi_srs_indication_fdd_rel11_t *)tlv;
+  return ( push16(srs_pdu_rel11->ul_rtoa, ppWritePackedMsg, end) ) ;
+}
+
+static uint8_t pack_tdd_channel_measurement_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_tdd_channel_measurement_t *value = (nfapi_tdd_channel_measurement_t *)tlv;
+
+  if(!(push8(value->num_prb_per_subband, ppWritePackedMsg, end) &&
+       push8(value->number_of_subbands, ppWritePackedMsg, end) &&
+       push8(value->num_atennas, ppWritePackedMsg, end)))
+    return 0;
+
+  uint8_t idx = 0;
+
+  for(idx = 0; idx < value->number_of_subbands; ++idx) {
+    if(!(push8(value->subands[idx].subband_index, ppWritePackedMsg, end) &&
+         pusharray16(value->subands[idx].channel, NFAPI_MAX_NUM_PHYSICAL_ANTENNAS, value->num_atennas, ppWritePackedMsg, end)))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_srs_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg,  uint8_t *end) {
+  nfapi_srs_indication_body_t *value = (nfapi_srs_indication_body_t *)tlv;
+
+  if( push8(value->number_of_ues, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_pdus = value->number_of_ues;
+
+  for(; i < total_number_of_pdus; ++i) {
+    nfapi_srs_indication_pdu_t *pdu = &(value->srs_pdu_list[i]);
+    uint8_t *instance_length_p = *ppWritePackedMsg;
+
+    if(!push16(pdu->instance_length, ppWritePackedMsg, end))
+      return 0;
+
+    if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, &pack_rx_ue_information_value) &&
+         pack_tlv(NFAPI_SRS_INDICATION_FDD_REL8_TAG, &pdu->srs_indication_fdd_rel8, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel8_value) &&
+         pack_tlv(NFAPI_SRS_INDICATION_FDD_REL9_TAG, &pdu->srs_indication_fdd_rel9, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel9_value) &&
+         pack_tlv(NFAPI_SRS_INDICATION_TDD_REL10_TAG, &pdu->srs_indication_tdd_rel10, ppWritePackedMsg, end, &pack_srs_indication_tdd_rel10_value) &&
+         pack_tlv(NFAPI_SRS_INDICATION_FDD_REL11_TAG, &pdu->srs_indication_fdd_rel11, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel11_value) &&
+         pack_tlv(NFAPI_TDD_CHANNEL_MEASUREMENT_TAG, &pdu->tdd_channel_measurement, ppWritePackedMsg, end, &pack_tdd_channel_measurement_value)))
+      return 0;
+
+    // calculate the instance length subtracting the size of the instance
+    // length feild
+    uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
+    push16(instance_length, &instance_length_p, end);
+  }
+
+  return 1;
+}
+
+static uint8_t pack_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_srs_indication_t *pNfapiMsg = (nfapi_srs_indication_t *)msg;
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_SRS_INDICATION_BODY_TAG, &pNfapiMsg->srs_indication_body, ppWritePackedMsg, end, &pack_srs_indication_body_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_sr_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_sr_indication_body_t *value = (nfapi_sr_indication_body_t *)tlv;
+
+  if(push16(value->number_of_srs, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_pdus = value->number_of_srs;
+
+  for(; i < total_number_of_pdus; ++i) {
+    nfapi_sr_indication_pdu_t *pdu = &(value->sr_pdu_list[i]);
+    uint8_t *instance_length_p = *ppWritePackedMsg;
+
+    if(!push16(pdu->instance_length, ppWritePackedMsg, end))
+      return 0;
+
+    if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) &&
+         pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value)))
+      return 0;
+
+    // calculate the instance length subtracting the size of the instance
+    // length feild
+    uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
+    push16(instance_length, &instance_length_p, end);
+  }
+
+  return 1;
+}
+
+static uint8_t pack_sr_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_sr_indication_t *pNfapiMsg = (nfapi_sr_indication_t *)msg;
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_SR_INDICATION_BODY_TAG, &pNfapiMsg->sr_indication_body, ppWritePackedMsg, end, &pack_sr_indication_body_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_cqi_indication_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_cqi_indication_rel8_t *cqi_pdu_rel8 = (nfapi_cqi_indication_rel8_t *)tlv;
+  return ( push16(cqi_pdu_rel8->length, ppWritePackedMsg, end) &&
+           push16(cqi_pdu_rel8->data_offset, ppWritePackedMsg, end) &&
+           push8(cqi_pdu_rel8->ul_cqi, ppWritePackedMsg, end) &&
+           push8(cqi_pdu_rel8->ri, ppWritePackedMsg, end) &&
+           push16(cqi_pdu_rel8->timing_advance, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_cqi_indication_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_cqi_indication_rel9_t *cqi_pdu_rel9 = (nfapi_cqi_indication_rel9_t *)tlv;
+  return  ( push16(cqi_pdu_rel9->length, ppWritePackedMsg, end) &&
+            push16(cqi_pdu_rel9->data_offset, ppWritePackedMsg, end) &&
+            push8(cqi_pdu_rel9->ul_cqi, ppWritePackedMsg, end) &&
+            push8(cqi_pdu_rel9->number_of_cc_reported, ppWritePackedMsg, end) &&
+            pusharray8(cqi_pdu_rel9->ri, NFAPI_CC_MAX, cqi_pdu_rel9->number_of_cc_reported, ppWritePackedMsg, end) &&
+            push16(cqi_pdu_rel9->timing_advance, ppWritePackedMsg, end) &&
+            push16(cqi_pdu_rel9->timing_advance_r9, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_cqi_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_cqi_indication_body_t *value = (nfapi_cqi_indication_body_t *)tlv;
+
+  if( push16(value->number_of_cqis, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  // need to calculate the data offset's. This very bittle due the hardcoding
+  // of the sizes. can not use the sizeof as we have an array for the Rel9
+  // info
+  uint16_t i = 0;
+  uint16_t offset = 2; // taking into account the number_of_cqis
+  uint16_t total_number_of_pdus = value->number_of_cqis;
+
+  for(i = 0; i < total_number_of_pdus; ++i) {
+    nfapi_cqi_indication_pdu_t *pdu = &(value->cqi_pdu_list[i]);
+    offset += 2; // for the instance length
+
+    if(pdu->rx_ue_information.tl.tag == NFAPI_RX_UE_INFORMATION_TAG) {
+      offset += 4 + 6; // sizeof(nfapi_rx_ue_information) - sizeof(nfapi_tl_t)
+    }
+
+    if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) {
+      offset += 4 + 8;
+    }
+
+    if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) {
+      offset += 4 + 10 + pdu->cqi_indication_rel9.number_of_cc_reported;
+    }
+
+    if(pdu->ul_cqi_information.tl.tag == NFAPI_UL_CQI_INFORMATION_TAG) {
+      offset += 4 + 2;
+    }
+  }
+
+  // Now update the structure to include the offset
+  for(i =0; i < total_number_of_pdus; ++i) {
+    nfapi_cqi_indication_pdu_t *pdu = &(value->cqi_pdu_list[i]);
+
+    if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) {
+      if(pdu->cqi_indication_rel8.data_offset == 1) {
+        pdu->cqi_indication_rel8.data_offset = offset;
+        offset += pdu->cqi_indication_rel8.length;
+      }
+    }
+
+    if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) {
+      if(pdu->cqi_indication_rel9.data_offset == 1) {
+        pdu->cqi_indication_rel9.data_offset = offset;
+        offset += pdu->cqi_indication_rel9.length;
+      }
+    }
+  }
+
+  // Write out the cqi information
+  for(i = 0; i < total_number_of_pdus; ++i) {
+    nfapi_cqi_indication_pdu_t *pdu = &(value->cqi_pdu_list[i]);
+    uint8_t *instance_length_p = *ppWritePackedMsg;
+
+    if(!push16(pdu->instance_length, ppWritePackedMsg, end))
+      return 0;
+
+    if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end,pack_rx_ue_information_value) &&
+         pack_tlv(NFAPI_CQI_INDICATION_REL8_TAG, &pdu->cqi_indication_rel8, ppWritePackedMsg, end, pack_cqi_indication_rel8_value) &&
+         pack_tlv(NFAPI_CQI_INDICATION_REL9_TAG, &pdu->cqi_indication_rel9, ppWritePackedMsg, end, pack_cqi_indication_rel9_value) &&
+         pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value)))
+      return 0;
+
+    // calculate the instance length subtracting the size of the instance
+    // length feild
+    uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
+    push16(instance_length, &instance_length_p, end);
+  }
+
+  // Write out the cqi raw data
+  for(i = 0; i < total_number_of_pdus; ++i) {
+    uint16_t length = 0;
+    nfapi_cqi_indication_pdu_t *pdu = &(value->cqi_pdu_list[i]);
+
+    if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) {
+      length = pdu->cqi_indication_rel8.length;
+    }
+
+    if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) {
+      length = pdu->cqi_indication_rel9.length;
+    }
+
+    if( pusharray8(value->cqi_raw_pdu_list[i].pdu, NFAPI_CQI_RAW_MAX_LEN, length, ppWritePackedMsg, end) == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_cqi_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_cqi_indication_t *pNfapiMsg = (nfapi_cqi_indication_t *)msg;
+  //Fixme: allocate some mem to fix pure bug, need to find out proper size
+  pNfapiMsg->vendor_extension=NULL;//(nfapi_vendor_extension_tlv_t)malloc( sizeof(* pNfapiMsg->vendor_extension));
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_CQI_INDICATION_BODY_TAG, &pNfapiMsg->cqi_indication_body, ppWritePackedMsg, end, pack_cqi_indication_body_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_lbt_pdsch_req_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lbt_pdsch_req_pdu_rel13_t *value = (nfapi_lbt_pdsch_req_pdu_rel13_t *)tlv;
+  return ( push32(value->handle, ppWritePackedMsg, end) &&
+           push32(value->mp_cca, ppWritePackedMsg, end) &&
+           push32(value->n_cca, ppWritePackedMsg, end) &&
+           push32(value->offset, ppWritePackedMsg, end) &&
+           push32(value->lte_txop_sf, ppWritePackedMsg, end) &&
+           push16(value->txop_sfn_sf_end, ppWritePackedMsg, end) &&
+           push32(value->lbt_mode, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_lbt_drs_req_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lbt_drs_req_pdu_rel13_t *value = (nfapi_lbt_drs_req_pdu_rel13_t *)tlv;
+  return ( push32(value->handle, ppWritePackedMsg, end) &&
+           push32(value->offset, ppWritePackedMsg, end) &&
+           push16(value->sfn_sf_end, ppWritePackedMsg, end) &&
+           push32(value->lbt_mode, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_lbt_dl_config_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lbt_dl_config_request_body_t *value = (nfapi_lbt_dl_config_request_body_t *)tlv;
+
+  if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_pdus = value->number_of_pdus;
+
+  for(; i < total_number_of_pdus; ++i) {
+    nfapi_lbt_dl_config_request_pdu_t *pdu = &(value->lbt_dl_config_req_pdu_list[i]);
+
+    if( push8(pdu->pdu_type, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    // Put a 0 size in and then determine the size after the pdu
+    // has been writen and write the calculated size
+    uint8_t *pWritePackedMsgPduSize = *ppWritePackedMsg;
+    pdu->pdu_size = 0;
+
+    if( push8(pdu->pdu_size, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    switch(pdu->pdu_type) {
+      case NFAPI_LBT_DL_CONFIG_REQUEST_PDSCH_PDU_TYPE: {
+        if( pack_tlv(NFAPI_LBT_PDSCH_REQ_PDU_REL13_TAG, &pdu->lbt_pdsch_req_pdu.lbt_pdsch_req_pdu_rel13, ppWritePackedMsg, end, pack_lbt_pdsch_req_pdu_rel13_value) == 0)
+          return 0;
+      }
+      break;
+
+      case NFAPI_LBT_DL_CONFIG_REQUEST_DRS_PDU_TYPE: {
+        if(pack_tlv(NFAPI_LBT_DRS_REQ_PDU_REL13_TAG, &pdu->lbt_drs_req_pdu.lbt_drs_req_pdu_rel13, ppWritePackedMsg, end, pack_lbt_drs_req_pdu_rel13_value) == 0)
+          return 0;
+      }
+      break;
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL_CONFIG.request invalid pdu type %d \n", pdu->pdu_type );
+      }
+      break;
+    };
+
+    // add 1 for the pdu_type. The delta will include the pdu_size
+    pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize);
+
+    push8(pdu->pdu_size, &pWritePackedMsgPduSize, end);
+  }
+
+  return 1;
+}
+
+static uint8_t pack_lbt_pdsch_rsp_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lbt_pdsch_rsp_pdu_rel13_t *value = (nfapi_lbt_pdsch_rsp_pdu_rel13_t *)tlv;
+  return ( push32(value->handle, ppWritePackedMsg, end) &&
+           push32(value->result, ppWritePackedMsg, end) &&
+           push32(value->lte_txop_symbols, ppWritePackedMsg, end) &&
+           push32(value->initial_partial_sf, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_lbt_drs_rsp_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lbt_drs_rsp_pdu_rel13_t *value = (nfapi_lbt_drs_rsp_pdu_rel13_t *)tlv;
+  return ( push32(value->handle, ppWritePackedMsg, end) &&
+           push32(value->result, ppWritePackedMsg, end));
+}
+
+static uint8_t pack_lbt_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_lbt_dl_config_request_t *pNfapiMsg = (nfapi_lbt_dl_config_request_t *)msg;
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_LBT_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->lbt_dl_config_request_body, ppWritePackedMsg, end, &pack_lbt_dl_config_request_body_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_lbt_dl_config_indication_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_lbt_dl_indication_body_t *value = (nfapi_lbt_dl_indication_body_t *)tlv;
+
+  if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_pdus = value->number_of_pdus;
+
+  for(; i < total_number_of_pdus; ++i) {
+    nfapi_lbt_dl_indication_pdu_t *pdu = &(value->lbt_indication_pdu_list[i]);
+
+    if( push8(pdu->pdu_type, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    // Put a 0 size in and then determine the size after the pdu
+    // has been writen and write the calculated size
+    uint8_t *pWritePackedMsgPduSize = *ppWritePackedMsg;
+    pdu->pdu_size = 0;
+
+    if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    switch(pdu->pdu_type) {
+      case NFAPI_LBT_DL_RSP_PDSCH_PDU_TYPE: {
+        if( pack_tlv(NFAPI_LBT_PDSCH_RSP_PDU_REL13_TAG, &pdu->lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13, ppWritePackedMsg, end, pack_lbt_pdsch_rsp_pdu_rel13_value) == 0)
+          return 0;
+      }
+      break;
+
+      case NFAPI_LBT_DL_RSP_DRS_PDU_TYPE: {
+        if( pack_tlv(NFAPI_LBT_DRS_RSP_PDU_REL13_TAG, &pdu->lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13, ppWritePackedMsg, end, pack_lbt_drs_rsp_pdu_rel13_value) == 0)
+          return 0;
+      }
+      break;
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL.indication body invalid pdu type %d \n", pdu->pdu_type );
+      }
+      break;
+    };
+
+    // add 1 for the pdu_type. The delta will include the pdu_size
+    pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize);
+
+    push8(pdu->pdu_size, &pWritePackedMsgPduSize, end);
+  }
+
+  return 1;
+}
+
+static uint8_t pack_lbt_dl_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_lbt_dl_indication_t *pNfapiMsg = (nfapi_lbt_dl_indication_t *)msg;
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_LBT_DL_INDICATION_BODY_TAG, &pNfapiMsg->lbt_dl_indication_body, ppWritePackedMsg, end, &pack_lbt_dl_config_indication_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_nb_harq_indication_fdd_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nb_harq_indication_fdd_rel13_t *nb_harq_indication_fdd_rel13 = (nfapi_nb_harq_indication_fdd_rel13_t *)tlv;
+  return ( push8(nb_harq_indication_fdd_rel13->harq_tb1, ppWritePackedMsg, end) );
+}
+
+static uint8_t pack_nb_harq_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nb_harq_indication_body_t *value = (nfapi_nb_harq_indication_body_t *)tlv;
+
+  if( push16(value->number_of_harqs, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_harqs = value->number_of_harqs;
+
+  for(; i < total_number_of_harqs; ++i) {
+    nfapi_nb_harq_indication_pdu_t *pdu = &(value->nb_harq_pdu_list[i]);
+    uint8_t *instance_length_p = *ppWritePackedMsg;
+
+    if(!push16(pdu->instance_length, ppWritePackedMsg, end))
+      return 0;
+
+    if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) &&
+         pack_tlv(NFAPI_NB_HARQ_INDICATION_FDD_REL13_TAG, &pdu->nb_harq_indication_fdd_rel13, ppWritePackedMsg, end, pack_nb_harq_indication_fdd_rel13_value) &&
+         pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value)))
+      return 0;
+
+    // calculate the instance length subtracting the size of the instance
+    // length feild
+    uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
+    push16(instance_length, &instance_length_p, end);
+  }
+
+  return 1;
+}
+
+
+static uint8_t pack_nb_harq_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_nb_harq_indication_t *pNfapiMsg = (nfapi_nb_harq_indication_t *)msg;
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_NB_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->nb_harq_indication_body, ppWritePackedMsg, end, &pack_nb_harq_indication_body_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_nrach_indication_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nrach_indication_pdu_rel13_t *nrach_indication_fdd_rel13 = (nfapi_nrach_indication_pdu_rel13_t *)tlv;
+  return ( push16(nrach_indication_fdd_rel13->rnti, ppWritePackedMsg, end) &&
+           push8(nrach_indication_fdd_rel13->initial_sc, ppWritePackedMsg, end) &&
+           push16(nrach_indication_fdd_rel13->timing_advance, ppWritePackedMsg, end) &&
+           push8(nrach_indication_fdd_rel13->nrach_ce_level, ppWritePackedMsg, end));
+}
+
+
+static uint8_t pack_nrach_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  nfapi_nrach_indication_body_t *value = (nfapi_nrach_indication_body_t *)tlv;
+
+  if( push8(value->number_of_initial_scs_detected, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_initial_scs_detected = value->number_of_initial_scs_detected;
+
+  for(; i < total_number_of_initial_scs_detected; ++i) {
+    nfapi_nrach_indication_pdu_t *pdu = &(value->nrach_pdu_list[i]);
+
+    //uint8_t* instance_length_p = *ppWritePackedMsg;
+    //if(!push16(pdu->instance_length, ppWritePackedMsg, end))
+    //  return 0;
+
+    if(!(pack_tlv(NFAPI_NRACH_INDICATION_REL13_TAG, &pdu->nrach_indication_rel13, ppWritePackedMsg, end, pack_nrach_indication_rel13_value)))
+      return 0;
+
+    // calculate the instance length subtracting the size of the instance
+    // length feild
+    //uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2;
+    //push16(instance_length, &instance_length_p, end);
+  }
+
+  return 1;
+}
+
+static uint8_t pack_nrach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_nrach_indication_t *pNfapiMsg = (nfapi_nrach_indication_t *)msg;
+  return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
+           pack_tlv(NFAPI_NRACH_INDICATION_BODY_TAG, &pNfapiMsg->nrach_indication_body, ppWritePackedMsg, end, &pack_nrach_indication_body_value) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_nr_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_dl_node_sync_t *pNfapiMsg = (nfapi_nr_dl_node_sync_t *)msg;
+  return ( push32(pNfapiMsg->t1, ppWritePackedMsg, end) &&
+           pushs32(pNfapiMsg->delta_sfn_slot, ppWritePackedMsg, end) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_dl_node_sync_t *pNfapiMsg = (nfapi_dl_node_sync_t *)msg;
+  return ( push32(pNfapiMsg->t1, ppWritePackedMsg, end) &&
+           pushs32(pNfapiMsg->delta_sfn_sf, ppWritePackedMsg, end) &&
+           pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_nr_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_ul_node_sync_t *pNfapiMsg = (nfapi_nr_ul_node_sync_t *)msg;
+  return (push32(pNfapiMsg->t1, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->t2, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->t3, ppWritePackedMsg, end) &&
+          pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_ul_node_sync_t *pNfapiMsg = (nfapi_ul_node_sync_t *)msg;
+  return (push32(pNfapiMsg->t1, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->t2, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->t3, ppWritePackedMsg, end) &&
+          pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_timing_info_t *pNfapiMsg = (nfapi_timing_info_t *)msg;
+  return (push32(pNfapiMsg->last_sfn_sf, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->time_since_last_timing_info, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->dl_config_jitter, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->tx_request_jitter, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->ul_config_jitter, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->hi_dci0_jitter, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->dl_config_latest_delay, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->tx_request_latest_delay, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->ul_config_latest_delay, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->hi_dci0_latest_delay, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->dl_config_earliest_arrival, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->tx_request_earliest_arrival, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->ul_config_earliest_arrival, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->hi_dci0_earliest_arrival, ppWritePackedMsg, end) &&
+          pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+static uint8_t pack_nr_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_timing_info_t *pNfapiMsg = (nfapi_nr_timing_info_t *)msg;
+  return (push32(pNfapiMsg->last_sfn, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->last_slot, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->time_since_last_timing_info, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->dl_tti_jitter, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->tx_data_request_jitter, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->ul_tti_jitter, ppWritePackedMsg, end) &&
+          push32(pNfapiMsg->ul_dci_jitter, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->dl_tti_latest_delay, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->tx_data_request_latest_delay, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->ul_tti_latest_delay, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->ul_dci_latest_delay, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->dl_tti_earliest_arrival, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->tx_data_request_earliest_arrival, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->ul_tti_earliest_arrival, ppWritePackedMsg, end) &&
+          pushs32(pNfapiMsg->ul_dci_earliest_arrival, ppWritePackedMsg, end) &&
+          pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
+
+// Main pack function - public
+
+int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config) {
+  nfapi_p7_message_header_t *pMessageHeader = pMessageBuf;
+  uint8_t *pWritePackedMessage = pPackedBuf;
+  uint8_t *pPackedLengthField = &pWritePackedMessage[4];
+  uint8_t *end = pPackedBuf + packedBufLen;
+
+  if (pMessageBuf == NULL || pPackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n");
+    return -1;
+  }
+
+  /*
+  printf("\n P7 MESSAGE SENT: \n");
+  for(int i=0; i< packedBufLen; i++){
+    printf("%d", *(uint8_t *)(pMessageBuf + i));
+  }
+  printf("\n");
+  */
+  // process the header
+  if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) &&
+       push16(pMessageHeader->message_id, &pWritePackedMessage, end) &&
+       push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, end) &&
+       push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end) &&
+       push32(0/*pMessageHeader->checksum*/, &pWritePackedMessage, end) &&
+       push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end))) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n");
+    return -1;
+  }
+
+  if (pMessageHeader->message_id != NFAPI_TIMING_INFO) {
+    //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__, pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp);
+  }
+
+  // look for the specific message
+  uint8_t result = 0;
+
+  switch (pMessageHeader->message_id) {
+    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+      result = pack_dl_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+      result = pack_ul_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+      result = pack_tx_data_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+      result = pack_ul_dci_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_UE_RELEASE_REQUEST:
+      result =pack_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_UE_RELEASE_RESPONSE:
+      result =pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_HARQ_INDICATION:
+      result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_CRC_INDICATION:
+      result = pack_crc_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_RX_ULSCH_INDICATION:
+      //printf("RX ULSCH\n");
+      result = pack_rx_ulsch_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_RACH_INDICATION:
+      result = pack_rach_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_SRS_INDICATION:
+      result = pack_srs_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_RX_SR_INDICATION:
+      result = pack_sr_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_RX_CQI_INDICATION:
+      result = pack_cqi_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_LBT_DL_CONFIG_REQUEST:
+      result = pack_lbt_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_LBT_DL_INDICATION:
+      result = pack_lbt_dl_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_NB_HARQ_INDICATION:
+      result = pack_nb_harq_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_NRACH_INDICATION:
+      result = pack_nrach_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
+      result = pack_nr_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
+      result = pack_nr_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_TIMING_INFO:
+      result = pack_nr_timing_info(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    default: {
+      if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+          pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if(config && config->pack_p7_vendor_extension) {
+          result = (config->pack_p7_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+      }
+    }
+    break;
+  }
+
+  if(result == 0) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
+    return -1;
+  }
+
+  // check for a valid message length
+  uintptr_t msgHead = (uintptr_t)pPackedBuf;
+  uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
+  uint32_t packedMsgLen = msgEnd - msgHead;
+  uint16_t packedMsgLen16;
+
+  if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
+    return -1;
+  } else {
+    packedMsgLen16 = (uint16_t)packedMsgLen;
+  }
+
+  // Update the message length in the header
+  pMessageHeader->message_length = packedMsgLen16;
+
+  if(!push16(packedMsgLen16, &pPackedLengthField, end))
+    return -1;
+
+  if(1) {
+    //quick test
+    if(pMessageHeader->message_length != packedMsgLen) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi packedMsgLen(%d) != message_length(%d) id %d\n", packedMsgLen, pMessageHeader->message_length, pMessageHeader->message_id);
+    }
+  }
+
+  return (packedMsgLen);
+}
+
+int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config) {
+  nfapi_p7_message_header_t *pMessageHeader = pMessageBuf;
+  uint8_t *pWritePackedMessage = pPackedBuf;
+  uint8_t *pPackedLengthField = &pWritePackedMessage[4];
+  uint8_t *end = pPackedBuf + packedBufLen;
+
+  if (pMessageBuf == NULL || pPackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n");
+    return -1;
+  }
+
+  /*
+  printf("\n P7 MESSAGE SENT: \n");
+  for(int i=0; i< packedBufLen; i++){
+    printf("%d", *(uint8_t *)(pMessageBuf + i));
+  }
+  printf("\n");
+  */
+  // process the header
+  if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) &&
+       push16(pMessageHeader->message_id, &pWritePackedMessage, end) &&
+       push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, end) &&
+       push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end) &&
+       push32(0/*pMessageHeader->checksum*/, &pWritePackedMessage, end) &&
+       push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end))) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n");
+    return -1;
+  }
+
+  if (pMessageHeader->message_id != NFAPI_TIMING_INFO) {
+    //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__, pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp);
+  }
+
+  // look for the specific message
+  uint8_t result = 0;
+
+  switch (pMessageHeader->message_id) {
+    case NFAPI_DL_CONFIG_REQUEST:
+      //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_DL_CONFIG_REQUEST\n", __FUNCTION__);
+      result = pack_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_UL_CONFIG_REQUEST:
+      result = pack_ul_config_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_TX_REQUEST:
+      //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_TX_REQUEST\n", __FUNCTION__);
+      result = pack_tx_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_HI_DCI0_REQUEST:
+      result = pack_hi_dci0_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_UE_RELEASE_REQUEST:
+      result =pack_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_UE_RELEASE_RESPONSE:
+      result =pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_HARQ_INDICATION:
+      result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_CRC_INDICATION:
+      result = pack_crc_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_RX_ULSCH_INDICATION:
+      //printf("RX ULSCH\n");
+      result = pack_rx_ulsch_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_RACH_INDICATION:
+      result = pack_rach_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_SRS_INDICATION:
+      result = pack_srs_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_RX_SR_INDICATION:
+      result = pack_sr_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_RX_CQI_INDICATION:
+      result = pack_cqi_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_LBT_DL_CONFIG_REQUEST:
+      result = pack_lbt_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_LBT_DL_INDICATION:
+      result = pack_lbt_dl_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_NB_HARQ_INDICATION:
+      result = pack_nb_harq_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_NRACH_INDICATION:
+      result = pack_nrach_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_DL_NODE_SYNC:
+      result = pack_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_UL_NODE_SYNC:
+      result = pack_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    case NFAPI_TIMING_INFO:
+      result = pack_timing_info(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+
+    default: {
+      if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+          pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if(config && config->pack_p7_vendor_extension) {
+          result = (config->pack_p7_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+      }
+    }
+    break;
+  }
+
+  if(result == 0) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
+    return -1;
+  }
+
+  // check for a valid message length
+  uintptr_t msgHead = (uintptr_t)pPackedBuf;
+  uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
+  uint32_t packedMsgLen = msgEnd - msgHead;
+  uint16_t packedMsgLen16;
+
+  if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
+    return -1;
+  } else {
+    packedMsgLen16 = (uint16_t)packedMsgLen;
+  }
+
+  // Update the message length in the header
+  pMessageHeader->message_length = packedMsgLen16;
+
+  if(!push16(packedMsgLen16, &pPackedLengthField, end))
+    return -1;
+
+  if(1) {
+    //quick test
+    if(pMessageHeader->message_length != packedMsgLen) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi packedMsgLen(%d) != message_length(%d) id %d\n", packedMsgLen, pMessageHeader->message_length, pMessageHeader->message_id);
+    }
+  }
+
+  return (packedMsgLen);
+}
+
+// Unpack routines
+// NR:
+static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
+  return(
+          pull16(ppReadPackedMsg, &value->bwp_size, end) &&
+          pull16(ppReadPackedMsg, &value->bwp_start, end) &&
+          pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) &&
+          pull8(ppReadPackedMsg, &value->cyclic_prefix, end) &&
+          pull16(ppReadPackedMsg, &value->start_rb, end) &&
+          pull16(ppReadPackedMsg, &value->nr_of_rbs, end) &&
+          pull8(ppReadPackedMsg, &value->csi_type, end) &&
+          pull8(ppReadPackedMsg, &value->row, end) &&
+          pull16(ppReadPackedMsg, &value->freq_domain, end) &&
+          pull8(ppReadPackedMsg, &value->symb_l0, end) &&
+          pull8(ppReadPackedMsg, &value->symb_l1, end) &&
+          pull8(ppReadPackedMsg, &value->cdm_type, end) &&
+          pull8(ppReadPackedMsg, &value->freq_density, end) &&
+          pull16(ppReadPackedMsg, &value->scramb_id, end) &&
+          pull8(ppReadPackedMsg, &value->power_control_offset, end) &&
+          pull8(ppReadPackedMsg, &value->power_control_offset_ss, end)
+        );
+}
+
+
+static uint8_t unpack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv;
+
+  for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i) {
+    if(!pull16(ppReadPackedMsg, &value->dci_pdu[i].RNTI, end) &&
+        pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingId, end) &&
+        pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingRNTI, end) &&
+        pull8(ppReadPackedMsg, &value->dci_pdu[i].CceIndex, end) &&
+        pull8(ppReadPackedMsg, &value->dci_pdu[i].AggregationLevel, end) &&
+        pull8(ppReadPackedMsg, &value->dci_pdu[i].beta_PDCCH_1_0, end) &&
+        pull8(ppReadPackedMsg, &value->dci_pdu[i].powerControlOffsetSS, end) &&
+        pull16(ppReadPackedMsg, &value->dci_pdu[i].PayloadSizeBits, end) &&
+        pullarray8(ppReadPackedMsg, value->dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->dci_pdu[i].PayloadSizeBits, end));
+
+    return 0;
+  }
+
+  // TODO: resolve the packaging of array (currently sending a single element)
+  return(
+          pull16(ppReadPackedMsg, &value->BWPSize, end) &&
+          pull16(ppReadPackedMsg, &value->BWPStart, end) &&
+          pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) &&
+          pull8(ppReadPackedMsg, &value->CyclicPrefix, end) &&
+          pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) &&
+          pull8(ppReadPackedMsg, &value->DurationSymbols, end) &&
+          pullarray8(ppReadPackedMsg, value->FreqDomainResource, 6, 6, end) &&
+          pull8(ppReadPackedMsg, &value->CceRegMappingType, end) &&
+          pull8(ppReadPackedMsg, &value->RegBundleSize, end) &&
+          pull8(ppReadPackedMsg, &value->InterleaverSize, end) &&
+          pull8(ppReadPackedMsg, &value->CoreSetType, end) &&
+          pull16(ppReadPackedMsg, &value->ShiftIndex, end) &&
+          pull8(ppReadPackedMsg, &value->precoderGranularity, end) &&
+          pull16(ppReadPackedMsg, &value->numDlDci, end));
+}
+
+
+static uint8_t unpack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv;
+  // TODO: resolve the packaging of array (currently sending a single element)
+  return(
+          pull16(ppReadPackedMsg, &value->pduBitmap, end) &&
+          pull16(ppReadPackedMsg, &value->rnti, end) &&
+          pull16(ppReadPackedMsg, &value->pduIndex, end) &&
+          pull16(ppReadPackedMsg, &value->BWPSize, end) &&
+          pull16(ppReadPackedMsg, &value->BWPStart, end) &&
+          pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) &&
+          pull8(ppReadPackedMsg, &value->CyclicPrefix, end) &&
+          pull8(ppReadPackedMsg, &value->NrOfCodewords, end) &&
+          pullarray16(ppReadPackedMsg, value->targetCodeRate, 2, 1, end) &&
+          pullarray8(ppReadPackedMsg, value->qamModOrder, 2, 1, end) &&
+          pullarray8(ppReadPackedMsg, value->mcsIndex, 2, 1, end) &&
+          pullarray8(ppReadPackedMsg, value->mcsTable, 2, 1, end) &&
+          pullarray8(ppReadPackedMsg, value->rvIndex, 2, 1, end) &&
+          pullarray32(ppReadPackedMsg, value->TBSize, 2, 1, end) &&
+          pull16(ppReadPackedMsg, &value->dataScramblingId, end) &&
+          pull8(ppReadPackedMsg, &value->nrOfLayers, end) &&
+          pull8(ppReadPackedMsg, &value->transmissionScheme, end) &&
+          pull8(ppReadPackedMsg, &value->refPoint, end) &&
+          pull16(ppReadPackedMsg, &value->dlDmrsSymbPos, end) &&
+          pull8(ppReadPackedMsg, &value->dmrsConfigType, end) &&
+          pull16(ppReadPackedMsg, &value->dlDmrsScramblingId, end) &&
+          pull8(ppReadPackedMsg, &value->SCID, end) &&
+          pull8(ppReadPackedMsg, &value->numDmrsCdmGrpsNoData, end) &&
+          pull16(ppReadPackedMsg, &value->dmrsPorts, end) &&
+          pull8(ppReadPackedMsg, &value->resourceAlloc, end) &&
+          pull16(ppReadPackedMsg, &value->rbStart, end) &&
+          pull16(ppReadPackedMsg, &value->rbSize, end) &&
+          pull8(ppReadPackedMsg, &value->VRBtoPRBMapping, end) &&
+          pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) &&
+          pull8(ppReadPackedMsg, &value->NrOfSymbols, end) &&
+          pull8(ppReadPackedMsg, &value->PTRSPortIndex, end) &&
+          pull8(ppReadPackedMsg, &value->PTRSTimeDensity, end) &&
+          pull8(ppReadPackedMsg, &value->PTRSFreqDensity, end) &&
+          pull8(ppReadPackedMsg, &value->PTRSReOffset, end)
+        );
+}
+
+
+static uint8_t unpack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv;
+  return(
+          pull16(ppReadPackedMsg, &value->PhysCellId, end) &&
+          pull8(ppReadPackedMsg, &value->BetaPss, end) &&
+          pull8(ppReadPackedMsg, &value->SsbBlockIndex, end) &&
+          pull8(ppReadPackedMsg, &value->SsbSubcarrierOffset, end) &&
+          pull16(ppReadPackedMsg, &value->ssbOffsetPointA, end) &&
+          pull8(ppReadPackedMsg, &value->bchPayloadFlag, end) &&
+          pull32(ppReadPackedMsg, &value->bchPayload, end)
+          // TODO: pack precoding_and_beamforming too
+        );
+}
+
+
+// LTE:
+static uint8_t unpack_dl_config_dci_dl_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_dci_dl_pdu_rel8_t *dci_dl_pdu_rel8 = (nfapi_dl_config_dci_dl_pdu_rel8_t *)tlv;
+  return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->dci_format, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->cce_idx, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->aggregation_level, end) &&
+          pull16(ppReadPackedMsg, &dci_dl_pdu_rel8->rnti, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->resource_allocation_type, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->virtual_resource_block_assignment_flag, end) &&
+          pull32(ppReadPackedMsg, &dci_dl_pdu_rel8->resource_block_coding, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->mcs_1, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->redundancy_version_1, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->new_data_indicator_1, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->transport_block_to_codeword_swap_flag, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->mcs_2, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->redundancy_version_2, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->new_data_indicator_2, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->harq_process, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->tpmi, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->pmi, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->precoding_information, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->tpc, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->downlink_assignment_index, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->ngap, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->transport_block_size_index, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->downlink_power_offset, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->allocate_prach_flag, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->preamble_index, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->prach_mask_index, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->rnti_type, end) &&
+          pull16(ppReadPackedMsg, &dci_dl_pdu_rel8->transmission_power, end));
+}
+
+static uint8_t unpack_dl_config_dci_dl_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_dci_dl_pdu_rel9_t *dci_dl_pdu_rel9 = (nfapi_dl_config_dci_dl_pdu_rel9_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->mcch_flag, end) &&
+           pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->mcch_change_notification, end) &&
+           pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->scrambling_identity, end));
+}
+
+static uint8_t unpack_dl_config_dci_dl_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_dci_dl_pdu_rel10_t *dci_dl_pdu_rel10 = (nfapi_dl_config_dci_dl_pdu_rel10_t *)tlv;
+  return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->cross_carrier_scheduling_flag, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->carrier_indicator, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->srs_flag, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->srs_request, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->antenna_ports_scrambling_and_layers, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->total_dci_length_including_padding, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->n_dl_rb, end));
+}
+
+static uint8_t unpack_dl_config_dci_dl_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_dci_dl_pdu_rel11_t *dci_dl_pdu_rel11 = (nfapi_dl_config_dci_dl_pdu_rel11_t *)tlv;
+  return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel11->harq_ack_resource_offset, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel11->pdsch_re_mapping_quasi_co_location_indicator, end));
+}
+
+static uint8_t unpack_dl_config_dci_dl_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_dci_dl_pdu_rel12_t *dci_dl_pdu_rel12 = (nfapi_dl_config_dci_dl_pdu_rel12_t *)tlv;
+  return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->primary_cell_type, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->ul_dl_configuration_flag, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->number_ul_dl_configurations, end) &&
+          pullarray8(ppReadPackedMsg, dci_dl_pdu_rel12->ul_dl_configuration_indication, NFAPI_MAX_UL_DL_CONFIGURATIONS, dci_dl_pdu_rel12->number_ul_dl_configurations, end));
+}
+
+static uint8_t unpack_tpm_value(uint8_t **ppReadPackedMsg, nfapi_dl_config_dci_dl_tpm_t *value, uint8_t *end) {
+  if(!(pull8(ppReadPackedMsg, &value->num_prb_per_subband, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_subbands, end) &&
+       pull8(ppReadPackedMsg, &value->num_antennas, end)))
+    return 0;
+
+  uint8_t idx = 0;
+
+  for(idx = 0; idx < value->number_of_subbands; ++idx) {
+    nfapi_dl_config_dci_dl_tpm_subband_info_t *subband_info = &(value->subband_info[idx]);
+
+    if(!(pull8(ppReadPackedMsg, &subband_info->subband_index, end) &&
+         pull8(ppReadPackedMsg, &subband_info->scheduled_ues, end)))
+      return 0;
+
+    uint8_t antenna_idx = 0;
+    uint8_t scheduled_ue_idx = 0;
+
+    for(antenna_idx = 0; antenna_idx < value->num_antennas; ++antenna_idx) {
+      for(scheduled_ue_idx = 0; scheduled_ue_idx < subband_info->scheduled_ues; ++scheduled_ue_idx) {
+        if(!pull16(ppReadPackedMsg, &(subband_info->precoding_value[antenna_idx][scheduled_ue_idx]), end))
+          return 0;
+      }
+    }
+  }
+
+  return 1;
+}
+
+
+static uint8_t unpack_dl_config_dci_dl_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_dci_dl_pdu_rel13_t *dci_dl_pdu_rel13 = (nfapi_dl_config_dci_dl_pdu_rel13_t *)tlv;
+  // If the length is greater than 5 then the TPM struct flag and possiably the TPM structure have been
+  // added
+  uint8_t tpm_struct_flag_present = dci_dl_pdu_rel13->tl.length > 5;
+  dci_dl_pdu_rel13->tpm_struct_flag = 0;
+  return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->laa_end_partial_sf_flag, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->laa_end_partial_sf_configuration, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->initial_lbt_sf, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->codebook_size_determination, end) &&
+          pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->drms_table_flag, end) &&
+          ( (tpm_struct_flag_present == 1) ? pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->tpm_struct_flag, end) : 1) &&
+          ( (tpm_struct_flag_present == 1 &&  dci_dl_pdu_rel13->tpm_struct_flag == 1) ? unpack_tpm_value(ppReadPackedMsg, &dci_dl_pdu_rel13->tpm, end) : 1));
+}
+
+static uint8_t unpack_dl_config_bch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_bch_pdu_rel8_t *bch_pdu_rel8 = (nfapi_dl_config_bch_pdu_rel8_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &bch_pdu_rel8->length, end) &&
+           pull16(ppReadPackedMsg, (uint16_t *)&bch_pdu_rel8->pdu_index, end) &&
+           pull16(ppReadPackedMsg, &bch_pdu_rel8->transmission_power, end));
+}
+
+static uint8_t unpack_dl_config_mch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_mch_pdu_rel8_t *mch_pdu_rel8 = (nfapi_dl_config_mch_pdu_rel8_t *)tlv;
+  return (pull16(ppReadPackedMsg, &mch_pdu_rel8->length, end) &&
+          pull16(ppReadPackedMsg, (uint16_t *)&mch_pdu_rel8->pdu_index, end) &&
+          pull16(ppReadPackedMsg, &mch_pdu_rel8->rnti, end) &&
+          pull8(ppReadPackedMsg, &mch_pdu_rel8->resource_allocation_type, end) &&
+          pull32(ppReadPackedMsg, &mch_pdu_rel8->resource_block_coding, end) &&
+          pull8(ppReadPackedMsg, &mch_pdu_rel8->modulation, end) &&
+          pull16(ppReadPackedMsg, &mch_pdu_rel8->transmission_power, end) &&
+          pull16(ppReadPackedMsg, &mch_pdu_rel8->mbsfn_area_id, end));
+}
+
+static uint8_t unpack_dl_config_dlsch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_dlsch_pdu_rel8_t *dlsch_pdu_rel8 = (nfapi_dl_config_dlsch_pdu_rel8_t *)tlv;
+
+  if (!(pull16(ppReadPackedMsg, &dlsch_pdu_rel8->length, end) &&
+        pull16(ppReadPackedMsg, (uint16_t *)&dlsch_pdu_rel8->pdu_index, end) &&
+        pull16(ppReadPackedMsg, &dlsch_pdu_rel8->rnti, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->resource_allocation_type, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->virtual_resource_block_assignment_flag, end) &&
+        pull32(ppReadPackedMsg, &dlsch_pdu_rel8->resource_block_coding, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->modulation, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->redundancy_version, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transport_blocks, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transport_block_to_codeword_swap_flag, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transmission_scheme, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->number_of_layers, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->number_of_subbands, end) &&
+        pullarray8(ppReadPackedMsg, dlsch_pdu_rel8->codebook_index, NFAPI_MAX_NUM_SUBBANDS, dlsch_pdu_rel8->number_of_subbands, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->ue_category_capacity, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->pa, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->delta_power_offset_index, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->ngap, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->nprb, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transmission_mode, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->num_bf_prb_per_subband, end) &&
+        pull8(ppReadPackedMsg, &dlsch_pdu_rel8->num_bf_vector, end)))
+    return 0;
+
+  uint16_t j = 0;
+
+  for(j = 0; j < dlsch_pdu_rel8->num_bf_vector; ++j) {
+    if(!(pull8(ppReadPackedMsg, &dlsch_pdu_rel8->bf_vector[j].subband_index, end) &&
+         pull8(ppReadPackedMsg, &dlsch_pdu_rel8->bf_vector[j].num_antennas, end) &&
+         pullarray16(ppReadPackedMsg, dlsch_pdu_rel8->bf_vector[j].bf_value, NFAPI_MAX_NUM_ANTENNAS, dlsch_pdu_rel8->bf_vector[j].num_antennas, end)))
+      return 0;
+  }
+
+  return 1;
+}
+static uint8_t unpack_dl_config_dlsch_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_dlsch_pdu_rel9_t *dlsch_pdu_rel9 = (nfapi_dl_config_dlsch_pdu_rel9_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel9->nscid, end) );
+}
+static uint8_t unpack_dl_config_dlsch_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_dlsch_pdu_rel10_t *dlsch_pdu_rel10 = (nfapi_dl_config_dlsch_pdu_rel10_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_flag, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_resource_config_r10, end) &&
+           pull16(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_zero_tx_power_resource_config_bitmap_r10, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_number_nzp_configuration, end) &&
+           pullarray8(ppReadPackedMsg, dlsch_pdu_rel10->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, dlsch_pdu_rel10->csi_rs_number_nzp_configuration, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel10->pdsch_start, end)) ;
+}
+static uint8_t unpack_dl_config_dlsch_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_dlsch_pdu_rel11_t *dlsch_pdu_rel11 = (nfapi_dl_config_dlsch_pdu_rel11_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel11->drms_config_flag, end) &&
+           pull16(ppReadPackedMsg, &dlsch_pdu_rel11->drms_scrambling, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel11->csi_config_flag, end) &&
+           pull16(ppReadPackedMsg, &dlsch_pdu_rel11->csi_scrambling, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_flag, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_atenna_ports, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_freq_shift, end));
+}
+static uint8_t unpack_dl_config_dlsch_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_dlsch_pdu_rel12_t *dlsch_pdu_rel12 = (nfapi_dl_config_dlsch_pdu_rel12_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel12->altcqi_table_r12, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel12->maxlayers, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel12->n_dl_harq, end));
+}
+static uint8_t unpack_dl_config_dlsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_dlsch_pdu_rel13_t *dlsch_pdu_rel13 = (nfapi_dl_config_dlsch_pdu_rel13_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel13->dwpts_symbols, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel13->initial_lbt_sf, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel13->ue_type, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel13->pdsch_payload_type, end) &&
+           pull16(ppReadPackedMsg, &dlsch_pdu_rel13->initial_transmission_sf_io, end) &&
+           pull8(ppReadPackedMsg, &dlsch_pdu_rel13->drms_table_flag, end));
+}
+
+static uint8_t unpack_dl_config_pch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_pch_pdu_rel8_t *pch_pdu_rel8 = (nfapi_dl_config_pch_pdu_rel8_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &pch_pdu_rel8->length, end) &&
+           pull16(ppReadPackedMsg, (uint16_t *)&pch_pdu_rel8->pdu_index, end) &&
+           pull16(ppReadPackedMsg, &pch_pdu_rel8->p_rnti, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->resource_allocation_type, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->virtual_resource_block_assignment_flag, end) &&
+           pull32(ppReadPackedMsg, &pch_pdu_rel8->resource_block_coding, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->mcs, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->redundancy_version, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->number_of_transport_blocks, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->transport_block_to_codeword_swap_flag, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->transmission_scheme, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->number_of_layers, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->codebook_index, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->ue_category_capacity, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->pa, end) &&
+           pull16(ppReadPackedMsg, &pch_pdu_rel8->transmission_power, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->nprb, end) &&
+           pull8(ppReadPackedMsg, &pch_pdu_rel8->ngap, end));
+}
+static uint8_t unpack_dl_config_pch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_pch_pdu_rel13_t *pch_pdu_rel13 = (nfapi_dl_config_pch_pdu_rel13_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &pch_pdu_rel13->ue_mode, end) &&
+           pull16(ppReadPackedMsg, &pch_pdu_rel13->initial_transmission_sf_io, end));
+}
+
+static uint8_t unpack_dl_config_prs_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_prs_pdu_rel9_t *prs_pdu_rel9 = (nfapi_dl_config_prs_pdu_rel9_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &prs_pdu_rel9->transmission_power, end) &&
+           pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_bandwidth, end) &&
+           pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_cyclic_prefix_type, end) &&
+           pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_muting, end));
+}
+
+static uint8_t unpack_dl_config_csi_rs_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_csi_rs_pdu_rel10_t *csi_rs_pdu_rel10 = (nfapi_dl_config_csi_rs_pdu_rel10_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_antenna_port_count_r10, end) &&
+           pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_resource_config_r10, end) &&
+           pull16(ppReadPackedMsg, &csi_rs_pdu_rel10->transmission_power, end) &&
+           pull16(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_zero_tx_power_resource_config_bitmap_r10, end) &&
+           pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_number_of_nzp_configuration, end) &&
+           pullarray8(ppReadPackedMsg, csi_rs_pdu_rel10->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, csi_rs_pdu_rel10->csi_rs_number_of_nzp_configuration, end));
+}
+
+static uint8_t unpack_dl_config_csi_rs_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_csi_rs_pdu_rel13_t *csi_rs_pdu_rel13 = (nfapi_dl_config_csi_rs_pdu_rel13_t *)tlv;
+
+  if (!(pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->csi_rs_class, end) &&
+        pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->cdm_type, end) &&
+        pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->num_bf_vector, end)))
+    return 0;
+
+  uint16_t idx =0;
+
+  for(idx = 0; idx < csi_rs_pdu_rel13->num_bf_vector; ++idx) {
+    if(!(pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->bf_vector[idx].csi_rs_resource_index, end)))
+      return 0;
+
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : HOW TO DECODE BF VALUE \n");
+    //pullarray16(ppReadPackedMsg, &csi_rs_pdu_rel13->bf_vector[idx].bf_vector, ??);
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_dl_config_epdcch_params_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_epdcch_parameters_rel11_t *epdcch_params_rel11 = (nfapi_dl_config_epdcch_parameters_rel11_t *)tlv;
+  return (pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_resource_assignment_flag, end) &&
+          pull16(ppReadPackedMsg, &epdcch_params_rel11->epdcch_id, end) &&
+          pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_start_symbol, end) &&
+          pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_num_prb, end) &&
+          pullarray8(ppReadPackedMsg, epdcch_params_rel11->epdcch_prb_index, NFAPI_MAX_EPDCCH_PRB, epdcch_params_rel11->epdcch_num_prb, end) &&
+          pull8(ppReadPackedMsg, &epdcch_params_rel11->bf_vector.subband_index, end) &&
+          pull8(ppReadPackedMsg, &epdcch_params_rel11->bf_vector.num_antennas, end) &&
+          pullarray16(ppReadPackedMsg, epdcch_params_rel11->bf_vector.bf_value, NFAPI_MAX_NUM_ANTENNAS, epdcch_params_rel11->bf_vector.num_antennas, end));
+}
+
+static uint8_t unpack_dl_config_epdcch_params_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_epdcch_parameters_rel13_t *epdcch_params_rel13 = (nfapi_dl_config_epdcch_parameters_rel13_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &epdcch_params_rel13->dwpts_symbols, end) &&
+           pull8(ppReadPackedMsg, &epdcch_params_rel13->initial_lbt_sf, end));
+}
+
+static uint8_t unpack_dl_config_mpdcch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_mpdcch_pdu_rel13_t *mpdcch_params_rel13 = (nfapi_dl_config_mpdcch_pdu_rel13_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &mpdcch_params_rel13->mpdcch_narrow_band, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->number_of_prb_pairs, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->resource_block_assignment, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->mpdcch_tansmission_type, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->start_symbol, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->ecce_index, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->aggregation_level, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->rnti_type, end) &&
+           pull16(ppReadPackedMsg, &mpdcch_params_rel13->rnti, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->ce_mode, end) &&
+           pull16(ppReadPackedMsg, &mpdcch_params_rel13->drms_scrambling_init, end) &&
+           pull16(ppReadPackedMsg, &mpdcch_params_rel13->initial_transmission_sf_io, end) &&
+           pull16(ppReadPackedMsg, &mpdcch_params_rel13->transmission_power, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->dci_format, end) &&
+           pull16(ppReadPackedMsg, &mpdcch_params_rel13->resource_block_coding, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->mcs, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->pdsch_reptition_levels, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->redundancy_version, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->new_data_indicator, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->harq_process, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpmi_length, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpmi, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->pmi_flag, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->pmi, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->harq_resource_offset, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->dci_subframe_repetition_number, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpc, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->downlink_assignment_index_length, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->downlink_assignment_index, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->allocate_prach_flag, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->preamble_index, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->prach_mask_index, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->starting_ce_level, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->srs_request, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->antenna_ports_and_scrambling_identity_flag, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->antenna_ports_and_scrambling_identity, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->frequency_hopping_enabled_flag, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->paging_direct_indication_differentiation_flag, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->direct_indication, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->total_dci_length_including_padding, end) &&
+           pull8(ppReadPackedMsg, &mpdcch_params_rel13->number_of_tx_antenna_ports, end) &&
+           pullarray16(ppReadPackedMsg, mpdcch_params_rel13->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, mpdcch_params_rel13->number_of_tx_antenna_ports, end));
+}
+
+
+static uint8_t unpack_dl_config_nbch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_nbch_pdu_rel13_t *nbch_params_rel13 = (nfapi_dl_config_nbch_pdu_rel13_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &nbch_params_rel13->length, end) &&
+           pull16(ppReadPackedMsg, (uint16_t *)&nbch_params_rel13->pdu_index, end) &&
+           pull16(ppReadPackedMsg, &nbch_params_rel13->transmission_power, end) &&
+           pull16(ppReadPackedMsg, &nbch_params_rel13->hyper_sfn_2_lsbs, end));
+}
+
+static uint8_t unpack_dl_config_npdcch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_npdcch_pdu_rel13_t *npdcch_params_rel13 = (nfapi_dl_config_npdcch_pdu_rel13_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &npdcch_params_rel13->length, end) &&
+           pull16(ppReadPackedMsg, (uint16_t *)&npdcch_params_rel13->pdu_index, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->ncce_index, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->aggregation_level, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->start_symbol, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->rnti_type, end) &&
+           pull16(ppReadPackedMsg, &npdcch_params_rel13->rnti, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->scrambling_reinitialization_batch_index, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->nrs_antenna_ports_assumed_by_the_ue, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->dci_format, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->scheduling_delay, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->resource_assignment, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->repetition_number, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->mcs, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->new_data_indicator, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->harq_ack_resource, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->npdcch_order_indication, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->starting_number_of_nprach_repetitions, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->subcarrier_indication_of_nprach, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->paging_direct_indication_differentation_flag, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->direct_indication, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->dci_subframe_repetition_number, end) &&
+           pull8(ppReadPackedMsg, &npdcch_params_rel13->total_dci_length_including_padding, end));
+}
+
+static uint8_t unpack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_dl_config_ndlsch_pdu_rel13_t *ndlsch_params_rel13 = (nfapi_dl_config_ndlsch_pdu_rel13_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &ndlsch_params_rel13->length, end) &&
+           pull16(ppReadPackedMsg, (uint16_t *)&ndlsch_params_rel13->pdu_index, end) &&
+           pull8(ppReadPackedMsg, &ndlsch_params_rel13->start_symbol, end) &&
+           pull8(ppReadPackedMsg, &ndlsch_params_rel13->rnti_type, end) &&
+           pull16(ppReadPackedMsg, &ndlsch_params_rel13->rnti, end) &&
+           pull16(ppReadPackedMsg, &ndlsch_params_rel13->resource_assignment, end) &&
+           pull16(ppReadPackedMsg, &ndlsch_params_rel13->repetition_number, end) &&
+           pull8(ppReadPackedMsg, &ndlsch_params_rel13->modulation, end) &&
+           pull8(ppReadPackedMsg, &ndlsch_params_rel13->number_of_subframes_for_resource_assignment, end) &&
+           pull8(ppReadPackedMsg, &ndlsch_params_rel13->scrambling_sequence_initialization_cinit, end) &&
+           pull16(ppReadPackedMsg, &ndlsch_params_rel13->sf_idx, end) &&
+           pull8(ppReadPackedMsg, &ndlsch_params_rel13->nrs_antenna_ports_assumed_by_the_ue, end));
+}
+
+
+static uint8_t unpack_dl_tti_request_body_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
+  nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)msg;
+
+  if(!(pull32(ppReadPackedMsg, &value->PDUSize, end) &&
+       pull16(ppReadPackedMsg, &value->PDUType, end) ))
+    return 0;
+
+  // first match the pdu type, then call the respective function
+  switch(value->PDUType) {
+    case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: {
+      if(!(unpack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15,ppReadPackedMsg,end)))
+        return 0;
+    }
+    break;
+
+    case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: {
+      if(!(unpack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15,ppReadPackedMsg,end)))
+        return 0;
+    }
+    break;
+
+    case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: {
+      if(!(unpack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15,ppReadPackedMsg,end)))
+        return 0;
+    }
+    break;
+
+    case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: {
+      if(!(unpack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15,ppReadPackedMsg,end)))
+        return 0;
+    }
+    break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType );
+    }
+    break;
+  }
+
+  return 1;
+}
+
+
+
+
+static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_dl_config_request_body_t *value = (nfapi_dl_config_request_body_t *)tlv;
+
+  if(!(pull8(ppReadPackedMsg, &value->number_pdcch_ofdm_symbols, end) &&
+       pull8(ppReadPackedMsg, &value->number_dci, end) &&
+       pull16(ppReadPackedMsg, &value->number_pdu, end) &&
+       pull8(ppReadPackedMsg, &value->number_pdsch_rnti, end) &&
+       pull16(ppReadPackedMsg, &value->transmission_power_pcfich, end)))
+    return 0;
+
+  if(value->number_pdu > NFAPI_DL_CONFIG_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of dl config pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_pdu, NFAPI_DL_CONFIG_MAX_PDU);
+    return 0;
+  }
+
+  if(value->number_pdu) {
+    value->dl_config_pdu_list = (nfapi_dl_config_request_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_dl_config_request_pdu_t) * value->number_pdu, config);
+
+    if(value->dl_config_pdu_list == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate dl config pdu list (count:%d)\n", __FUNCTION__, value->number_pdu);
+      return 0;
+    }
+  } else {
+    value->dl_config_pdu_list = 0;
+  }
+
+  uint16_t i;
+  uint16_t total_number_of_pdus = value->number_pdu;
+
+  for(i = 0; i < total_number_of_pdus; ++i) {
+    nfapi_dl_config_request_pdu_t *pdu = &(value->dl_config_pdu_list[i]);
+
+    if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) &&
+         pull8(ppReadPackedMsg, &pdu->pdu_size, end)))
+      return 0;
+
+    uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2;
+
+    if(packedPduEnd > end) {
+      // pdu end of beyond buffer end
+      return 0;
+    }
+
+    switch(pdu->pdu_type) {
+      case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel8, &unpack_dl_config_dci_dl_pdu_rel8_value},
+          { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel9, &unpack_dl_config_dci_dl_pdu_rel9_value},
+          { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel10, &unpack_dl_config_dci_dl_pdu_rel10_value},
+          { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel11, &unpack_dl_config_dci_dl_pdu_rel11_value},
+          { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel12, &unpack_dl_config_dci_dl_pdu_rel12_value},
+          { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel13, &unpack_dl_config_dci_dl_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_BCH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG, &pdu->bch_pdu.bch_pdu_rel8, &unpack_dl_config_bch_pdu_rel8_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_MCH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG, &pdu->mch_pdu.mch_pdu_rel8, &unpack_dl_config_mch_pdu_rel8_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel8, &unpack_dl_config_dlsch_pdu_rel8_value},
+          { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel9, &unpack_dl_config_dlsch_pdu_rel9_value},
+          { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel10, &unpack_dl_config_dlsch_pdu_rel10_value},
+          { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel11, &unpack_dl_config_dlsch_pdu_rel11_value},
+          { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel12, &unpack_dl_config_dlsch_pdu_rel12_value},
+          { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel13, &unpack_dl_config_dlsch_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_PCH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG, &pdu->pch_pdu.pch_pdu_rel8, &unpack_dl_config_pch_pdu_rel8_value},
+          { NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG, &pdu->pch_pdu.pch_pdu_rel13, &unpack_dl_config_pch_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_PRS_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG, &pdu->prs_pdu.prs_pdu_rel9, &unpack_dl_config_prs_pdu_rel9_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel10, &unpack_dl_config_csi_rs_pdu_rel10_value},
+          { NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel13, &unpack_dl_config_csi_rs_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel8, &unpack_dl_config_dci_dl_pdu_rel8_value},
+          { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel9, &unpack_dl_config_dci_dl_pdu_rel9_value},
+          { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel10, &unpack_dl_config_dci_dl_pdu_rel10_value},
+          { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel11, &unpack_dl_config_dci_dl_pdu_rel11_value},
+          { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel12, &unpack_dl_config_dci_dl_pdu_rel12_value},
+          { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel13, &unpack_dl_config_dci_dl_pdu_rel13_value},
+          { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG, &pdu->epdcch_pdu.epdcch_params_rel11, &unpack_dl_config_epdcch_params_rel11_value},
+          { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG, &pdu->epdcch_pdu.epdcch_params_rel13, &unpack_dl_config_epdcch_params_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG, &pdu->mpdcch_pdu.mpdcch_pdu_rel13, &unpack_dl_config_mpdcch_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG, &pdu->nbch_pdu.nbch_pdu_rel13, &unpack_dl_config_nbch_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG, &pdu->npdcch_pdu.npdcch_pdu_rel13, &unpack_dl_config_npdcch_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG, &pdu->ndlsch_pdu.ndlsch_pdu_rel13, &unpack_dl_config_ndlsch_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      default:
+        // Need to log an error
+        break;
+    }
+  }
+
+  return 1;
+}
+
+
+static uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg;
+
+  if (!(pull16(ppReadPackedMsg,&pNfapiMsg->SFN, end) &&
+        pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
+        pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nGroup, end) &&
+        pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nPDUs, end) &&
+        pullarray8(ppReadPackedMsg,pNfapiMsg->dl_tti_request_body.nUe,256,pNfapiMsg->dl_tti_request_body.nGroup, end)
+        //pusharray8(pNfapiMsg->PduIdx[0] ,256,256, ppWritePackedMsg, end)
+       ))
+    return 0;
+
+  int arr[12];
+
+  for(int i=0; i<pNfapiMsg->dl_tti_request_body.nGroup; i++) {
+    for(int j=0; j<pNfapiMsg->dl_tti_request_body.nUe[i]; j++) {
+      arr[j] = pNfapiMsg->dl_tti_request_body.PduIdx[i][j];
+    }
+
+    if(!(pullarrays32(ppReadPackedMsg,arr,12,pNfapiMsg->dl_tti_request_body.nUe[i], end)))
+      return 0;
+  }
+
+  for(int i=0; i<pNfapiMsg->dl_tti_request_body.nPDUs; i++) {
+    if(!unpack_dl_tti_request_body_value(ppReadPackedMsg, end, &pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i]))
+      return 0;
+  }
+
+  return 1;
+}
+
+
+static uint8_t unpack_ul_tti_request_prach_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nr_prach_pdu_t *prach_pdu = (nfapi_nr_prach_pdu_t *)tlv;
+  return(
+          pull16(ppReadPackedMsg, &prach_pdu->phys_cell_id, end) &&
+          pull8(ppReadPackedMsg, &prach_pdu->num_prach_ocas, end) &&
+          pull8(ppReadPackedMsg, &prach_pdu->prach_format, end) &&
+          pull8(ppReadPackedMsg, &prach_pdu->num_ra, end) &&
+          pull8(ppReadPackedMsg, &prach_pdu->prach_start_symbol, end) &&
+          pull16(ppReadPackedMsg, &prach_pdu->num_cs, end)
+          // TODO: ignoring beamforming tlv for now
+        );
+}
+
+
+static uint8_t unpack_ul_tti_request_pucch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nr_pucch_pdu_t *pucch_pdu = (nfapi_nr_pucch_pdu_t *)tlv;
+  return(
+          pull16(ppReadPackedMsg, &pucch_pdu->rnti, end) &&
+          pull32(ppReadPackedMsg, &pucch_pdu->handle, end) &&
+          pull16(ppReadPackedMsg, &pucch_pdu->bwp_size, end) &&
+          pull16(ppReadPackedMsg, &pucch_pdu->bwp_start, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->subcarrier_spacing, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->cyclic_prefix, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->format_type, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->multi_slot_tx_indicator, end) &&
+          pull16(ppReadPackedMsg, &pucch_pdu->prb_start, end) &&
+          pull16(ppReadPackedMsg, &pucch_pdu->prb_size, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->start_symbol_index, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->nr_of_symbols, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->freq_hop_flag, end) &&
+          pull16(ppReadPackedMsg, &pucch_pdu->second_hop_prb, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->group_hop_flag, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->sequence_hop_flag, end) &&
+          pull16(ppReadPackedMsg, &pucch_pdu->hopping_id, end) &&
+          pull16(ppReadPackedMsg, &pucch_pdu->initial_cyclic_shift, end) &&
+          pull16(ppReadPackedMsg, &pucch_pdu->data_scrambling_id, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->time_domain_occ_idx, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_idx, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_len, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->add_dmrs_flag, end) &&
+          pull16(ppReadPackedMsg, &pucch_pdu->dmrs_scrambling_id, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->dmrs_cyclic_shift, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->sr_flag, end) &&
+          pull8(ppReadPackedMsg, &pucch_pdu->bit_len_harq, end) &&
+          pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part1, end) &&
+          pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part2, end)
+          // TODO: ignoring beamforming tlv for now
+        );
+}
+
+
+static uint8_t unpack_ul_tti_request_pusch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nr_pusch_pdu_t *pusch_pdu = (nfapi_nr_pusch_pdu_t *)tlv;
+
+  if (!(
+        pull16(ppReadPackedMsg, &pusch_pdu->pdu_bit_map, end) &&
+        pull16(ppReadPackedMsg, &pusch_pdu->rnti, end) &&
+        pull32(ppReadPackedMsg, &pusch_pdu->handle, end) &&
+        pull16(ppReadPackedMsg, &pusch_pdu->bwp_size, end) &&
+        pull16(ppReadPackedMsg, &pusch_pdu->bwp_start, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->subcarrier_spacing, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->cyclic_prefix, end) &&
+        pull16(ppReadPackedMsg, &pusch_pdu->target_code_rate,  end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order,  end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->mcs_index,  end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end) &&
+        pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end) &&
+        pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end) &&
+        pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->scid, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->num_dmrs_cdm_grps_no_data, end) &&
+        pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc,end) &&
+        pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) &&
+        pull16(ppReadPackedMsg, &pusch_pdu->rb_start, end) &&
+        pull16(ppReadPackedMsg, &pusch_pdu->rb_size, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->vrb_to_prb_mapping, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->frequency_hopping, end) &&
+        pull16(ppReadPackedMsg, &pusch_pdu->tx_direct_current_location, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->uplink_frequency_shift_7p5khz, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->start_symbol_index, end) &&
+        pull8(ppReadPackedMsg, &pusch_pdu->nr_of_symbols, end)
+        // TODO: ignoring beamforming tlv for now
+      ))
+    return 0;
+
+  //Pack Optional Data only included if indicated in pduBitmap
+  switch(pusch_pdu->pdu_bit_map) {
+    case PUSCH_PDU_BITMAP_PUSCH_DATA: {
+      // pack optional TLVs
+      return(
+              pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.rv_index, end) &&
+              pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.harq_process_id, end) &&
+              pull32(ppReadPackedMsg, &pusch_pdu->pusch_data.tb_size, end) &&
+              pull16(ppReadPackedMsg, &pusch_pdu->pusch_data.num_cb, end) &&
+              pullarray8(ppReadPackedMsg, pusch_pdu->pusch_data.cb_present_and_position,1,1,end)
+            );
+    }
+    break;
+
+    case PUSCH_PDU_BITMAP_PUSCH_UCI: {
+      return(
+              pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.harq_ack_bit_length, end) &&
+              pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part1_bit_length, end) &&
+              pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part2_bit_length, end) &&
+              pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.alpha_scaling, end) &&
+              pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_harq_ack, end) &&
+              pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi1, end) &&
+              pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi2, end)
+            );
+    }
+    break;
+
+    case PUSCH_PDU_BITMAP_PUSCH_PTRS: {
+      return(
+              pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.num_ptrs_ports, end) &&
+              pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_dmrs_port, end) &&
+              +               pull16(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_port_index, end) &&
+              +               pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset, end) &&
+              pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_time_density, end) &&
+              pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_freq_density, end) &&
+              pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ul_ptrs_power, end)
+            );
+    }
+    break;
+
+    case PUSCH_PDU_BITMAP_DFTS_OFDM: {
+      return(
+              pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_group_number, end) &&
+              pull16(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_sequence_number, end) &&
+              pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, end) &&
+              pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, end)
+            );
+    }
+    break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map );
+    }
+  }
+
+  return 1;
+}
+
+
+static uint8_t unpack_ul_tti_request_srs_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nr_srs_pdu_t *srs_pdu = (nfapi_nr_srs_pdu_t *)tlv;
+  return(
+          pull16(ppReadPackedMsg, &srs_pdu->rnti, end) &&
+          pull32(ppReadPackedMsg, &srs_pdu->handle, end) &&
+          pull16(ppReadPackedMsg, &srs_pdu->bwp_size, end) &&
+          pull16(ppReadPackedMsg, &srs_pdu->bwp_start, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->subcarrier_spacing, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->cyclic_prefix, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->num_ant_ports, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->num_symbols,  end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->num_repetitions, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->time_start_position, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->config_index, end) &&
+          pull16(ppReadPackedMsg, &srs_pdu->sequence_id, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->bandwidth_index, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->comb_size, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->comb_offset, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->cyclic_shift, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->frequency_position, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->frequency_shift, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->frequency_hopping, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->group_or_sequence_hopping, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu->resource_type, end) &&
+          pull16(ppReadPackedMsg, &srs_pdu->t_srs, end) &&
+          pull16(ppReadPackedMsg, &srs_pdu->t_offset, end)
+          // TODO: ignoring beamforming tlv for now
+        );
+}
+
+
+static uint8_t unpack_ul_tti_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
+  nfapi_nr_ul_tti_request_number_of_pdus_t *pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_pdus_t *)msg;
+
+  if(!(pull16(ppReadPackedMsg, &pNfapiMsg->pdu_size, end) &&
+       pull16(ppReadPackedMsg, &pNfapiMsg->pdu_type, end) ))
+    return 0;
+
+  // first natch the pdu type, then call the respective function
+  switch(pNfapiMsg->pdu_type) {
+    case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: {
+      if(!unpack_ul_tti_request_prach_pdu(&pNfapiMsg->prach_pdu, ppReadPackedMsg, end))
+        return 0;
+    }
+    break;
+
+    case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
+      if(!unpack_ul_tti_request_pucch_pdu(&pNfapiMsg->pucch_pdu, ppReadPackedMsg, end))
+        return 0;
+    }
+    break;
+
+    case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
+      if(!unpack_ul_tti_request_pusch_pdu(&pNfapiMsg->pusch_pdu, ppReadPackedMsg, end))
+        return 0;
+    }
+    break;
+
+    case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: {
+      if(!unpack_ul_tti_request_srs_pdu(&pNfapiMsg->srs_pdu, ppReadPackedMsg, end))
+        return 0;
+    }
+    break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", pNfapiMsg->pdu_type );
+    }
+    break;
+  }
+
+  return 1;
+}
+
+
+static uint8_t unpack_ul_tti_groups_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
+  nfapi_nr_ul_tti_request_number_of_groups_t *pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_groups_t *)msg;
+
+  if(!pull8(ppReadPackedMsg, &pNfapiMsg->n_ue, end))
+    return 0;
+
+  for (int i = 0; i < pNfapiMsg->n_ue; i++) {
+    if(!pull8(ppReadPackedMsg, &pNfapiMsg->ue_list[i].pdu_idx,end) )
+      return 0;
+  }
+
+  return 1;
+}
+
+
+static uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
+
+  if (!(
+        pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) &&
+        pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
+        pull8(ppReadPackedMsg, &pNfapiMsg->n_pdus, end) &&
+        pull8(ppReadPackedMsg, &pNfapiMsg->n_group, end) &&
+        pull8(ppReadPackedMsg, &pNfapiMsg->rach_present, end) &&
+        pull8(ppReadPackedMsg, &pNfapiMsg->n_ulcch, end) &&
+        pull8(ppReadPackedMsg, &pNfapiMsg->n_ulsch, end) ))
+    return 0;
+
+  for(int i=0; i< pNfapiMsg->n_pdus; i++) {
+    if (!unpack_ul_tti_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdus_list[i]))
+      return 0;
+  }
+
+  for(int i=0; i< pNfapiMsg->n_group; i++) {
+    if (!unpack_ul_tti_groups_list_value(ppReadPackedMsg, end, &pNfapiMsg->groups_list[i]))
+      return 0;
+  }
+
+  return 1;
+}
+
+
+
+static uint8_t unpack_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, &unpack_dl_config_request_body_value},
+  };
+  return ( pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+           unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_ul_config_ulsch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_ulsch_pdu_rel8_t *ulsch_pdu_rel8 = (nfapi_ul_config_ulsch_pdu_rel8_t *)tlv;
+  return (pull32(ppReadPackedMsg, &ulsch_pdu_rel8->handle, end) &&
+          pull16(ppReadPackedMsg, &ulsch_pdu_rel8->size, end) &&
+          pull16(ppReadPackedMsg, &ulsch_pdu_rel8->rnti, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel8->resource_block_start, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel8->number_of_resource_blocks, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel8->modulation_type, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel8->cyclic_shift_2_for_drms, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel8->frequency_hopping_enabled_flag, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel8->frequency_hopping_bits, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel8->new_data_indication, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel8->redundancy_version, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel8->harq_process_number, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel8->ul_tx_mode, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel8->current_tx_nb, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel8->n_srs, end ));
+}
+
+static uint8_t unpack_ul_config_ulsch_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_ulsch_pdu_rel10_t *ulsch_pdu_rel10 = (nfapi_ul_config_ulsch_pdu_rel10_t *)tlv;
+  return (pull8(ppReadPackedMsg, &ulsch_pdu_rel10->resource_allocation_type, end) &&
+          pull32(ppReadPackedMsg, &ulsch_pdu_rel10->resource_block_coding, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel10->transport_blocks, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel10->transmission_scheme, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel10->number_of_layers, end) &
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel10->codebook_index, end) &&
+          pull8(ppReadPackedMsg, &ulsch_pdu_rel10->disable_sequence_hopping_flag, end));
+}
+static uint8_t unpack_ul_config_ulsch_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_ulsch_pdu_rel11_t *ulsch_pdu_rel11 = (nfapi_ul_config_ulsch_pdu_rel11_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &ulsch_pdu_rel11->virtual_cell_id_enabled_flag, end) &&
+           pull16(ppReadPackedMsg, &ulsch_pdu_rel11->npusch_identity, end) &&
+           pull8(ppReadPackedMsg, &ulsch_pdu_rel11->dmrs_config_flag, end) &&
+           pull16(ppReadPackedMsg, &ulsch_pdu_rel11->ndmrs_csh_identity, end));
+}
+static uint8_t unpack_ul_config_ulsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_ulsch_pdu_rel13_t *ulsch_pdu_rel13 = (nfapi_ul_config_ulsch_pdu_rel13_t *)tlv;
+  return (pull8(ppReadPackedMsg,  &ulsch_pdu_rel13->ue_type, end) &&
+          pull16(ppReadPackedMsg, &ulsch_pdu_rel13->total_number_of_repetitions, end) &&
+          pull16(ppReadPackedMsg, &ulsch_pdu_rel13->repetition_number, end) &&
+          pull16(ppReadPackedMsg, &ulsch_pdu_rel13->initial_transmission_sf_io, end) &&
+          pull8(ppReadPackedMsg,  &ulsch_pdu_rel13->empty_symbols_due_to_re_tunning, end));
+}
+static uint8_t unpack_ul_config_cqi_ri_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_cqi_ri_information_rel8_t *cqi_ri_info_rel8 = (nfapi_ul_config_cqi_ri_information_rel8_t *)tlv;
+  return (pull8(ppReadPackedMsg, &cqi_ri_info_rel8->dl_cqi_pmi_size_rank_1, end) &&
+          pull8(ppReadPackedMsg, &cqi_ri_info_rel8->dl_cqi_pmi_size_rank_greater_1, end) &&
+          pull8(ppReadPackedMsg, &cqi_ri_info_rel8->ri_size, end) &&
+          pull8(ppReadPackedMsg, &cqi_ri_info_rel8->delta_offset_cqi, end) &&
+          pull8(ppReadPackedMsg, &cqi_ri_info_rel8->delta_offset_ri, end));
+}
+
+static uint8_t unpack_ul_config_cqi_ri_info_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_cqi_ri_information_rel9_t *cqi_ri_info_rel9 = (nfapi_ul_config_cqi_ri_information_rel9_t *)tlv;
+
+  if(!(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->report_type, end) &&
+       pull8(ppReadPackedMsg, &cqi_ri_info_rel9->delta_offset_cqi, end) &&
+       pull8(ppReadPackedMsg, &cqi_ri_info_rel9->delta_offset_ri, end)))
+    return 0;
+
+  switch(cqi_ri_info_rel9->report_type) {
+    case NFAPI_CSI_REPORT_TYPE_PERIODIC: {
+      if(!(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size, end) &&
+           pull8(ppReadPackedMsg, &cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.control_type, end)))
+        return 0;
+    }
+    break;
+
+    case NFAPI_CSI_REPORT_TYPE_APERIODIC: {
+      if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc, end) ==0)
+        return 0;
+
+      uint8_t i;
+
+      for(i = 0; i < cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc; ++i) {
+        if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size, end) == 0)
+          return 0;
+
+        uint8_t j;
+
+        for(j = 0; j < 8; ++j) {
+          if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size[j], end) == 0)
+            return 0;
+        }
+      }
+    }
+    break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel9->report_type );
+      return 0;
+    }
+    break;
+  };
+
+  return 1;
+}
+
+// NOTE : This function is a little unconventional as we uese the side to
+// determine the report type
+static uint8_t unpack_ul_config_cqi_ri_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_cqi_ri_information_rel13_t *cqi_ri_info_rel13 = (nfapi_ul_config_cqi_ri_information_rel13_t *)tlv;
+
+  if(cqi_ri_info_rel13->tl.length == 0) {
+    cqi_ri_info_rel13->report_type = NFAPI_CSI_REPORT_TYPE_APERIODIC;
+  } else {
+    cqi_ri_info_rel13->report_type = NFAPI_CSI_REPORT_TYPE_PERIODIC;
+
+    if(pull16(ppReadPackedMsg, &cqi_ri_info_rel13->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2, end) == 0)
+      return 0;
+  }
+
+  return 1;
+}
+static uint8_t unpack_ul_config_cqi_init_tx_params_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_initial_transmission_parameters_rel8_t *init_tx_params_rel8 = (nfapi_ul_config_initial_transmission_parameters_rel8_t *)tlv;
+  return (pull8(ppReadPackedMsg, &init_tx_params_rel8->n_srs_initial, end) &&
+          pull8(ppReadPackedMsg, &init_tx_params_rel8->initial_number_of_resource_blocks, end));
+}
+static uint8_t unpack_ul_config_ulsch_harq_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_ulsch_harq_information_rel10_t *harq_info_rel10 = (nfapi_ul_config_ulsch_harq_information_rel10_t *)tlv;
+  return (pull8(ppReadPackedMsg, &harq_info_rel10->harq_size, end) &&
+          pull8(ppReadPackedMsg, &harq_info_rel10->delta_offset_harq, end) &&
+          pull8(ppReadPackedMsg, &harq_info_rel10->ack_nack_mode, end));
+}
+
+static uint8_t unpack_ul_config_ulsch_harq_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_ulsch_harq_information_rel13_t *harq_info_rel13 = (nfapi_ul_config_ulsch_harq_information_rel13_t *)tlv;
+  return (pull16(ppReadPackedMsg, &harq_info_rel13->harq_size_2, end) &&
+          pull8(ppReadPackedMsg, &harq_info_rel13->delta_offset_harq_2, end));
+}
+
+static uint8_t unpack_ul_config_ue_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_ue_information_rel8_t *ue_info_rel8 = (nfapi_ul_config_ue_information_rel8_t *)tlv;
+  return (pull32(ppReadPackedMsg, &ue_info_rel8->handle, end) &&
+          pull16(ppReadPackedMsg, (uint16_t *)&ue_info_rel8->rnti, end));
+}
+static uint8_t unpack_ul_config_ue_info_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_ue_information_rel11_t *ue_info_rel11 = (nfapi_ul_config_ue_information_rel11_t *)tlv;
+  return (pull8(ppReadPackedMsg, &ue_info_rel11->virtual_cell_id_enabled_flag, end) &&
+          pull16(ppReadPackedMsg, &ue_info_rel11->npusch_identity, end));
+}
+static uint8_t unpack_ul_config_ue_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_ue_information_rel13_t *ue_info_rel13 = (nfapi_ul_config_ue_information_rel13_t *)tlv;
+  return (pull8(ppReadPackedMsg, &ue_info_rel13->ue_type, end) &&
+          pull8(ppReadPackedMsg, &ue_info_rel13->empty_symbols, end) &&
+          pull16(ppReadPackedMsg, &ue_info_rel13->total_number_of_repetitions, end) &&
+          pull16(ppReadPackedMsg, &ue_info_rel13->repetition_number, end));
+}
+
+static uint8_t unpack_ul_config_cqi_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_cqi_information_rel8_t *cqi_info_rel8 = (nfapi_ul_config_cqi_information_rel8_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &cqi_info_rel8->pucch_index, end) &&
+           pull8(ppReadPackedMsg, &cqi_info_rel8->dl_cqi_pmi_size, end));
+}
+static uint8_t unpack_ul_config_cqi_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_cqi_information_rel10_t *cqi_info_rel10 = (nfapi_ul_config_cqi_information_rel10_t *)tlv;
+  return (pull8(ppReadPackedMsg, &cqi_info_rel10->number_of_pucch_resource, end) &&
+          pull16(ppReadPackedMsg, &cqi_info_rel10->pucch_index_p1, end));
+}
+static uint8_t unpack_ul_config_cqi_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_cqi_information_rel13_t *cqi_info_rel13 = (nfapi_ul_config_cqi_information_rel13_t *)tlv;
+  return (pull8(ppReadPackedMsg, &cqi_info_rel13->csi_mode, end) &&
+          pull16(ppReadPackedMsg, &cqi_info_rel13->dl_cqi_pmi_size_2, end) &&
+          pull8(ppReadPackedMsg, &cqi_info_rel13->starting_prb, end) &&
+          pull8(ppReadPackedMsg, &cqi_info_rel13->n_prb, end) &&
+          pull8(ppReadPackedMsg, &cqi_info_rel13->cdm_index, end) &&
+          pull8(ppReadPackedMsg, &cqi_info_rel13->n_srs, end));
+}
+
+static uint8_t unpack_ul_config_sr_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_sr_information_rel8_t *sr_info_rel8 = (nfapi_ul_config_sr_information_rel8_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &sr_info_rel8->pucch_index, end));
+}
+
+static uint8_t unpack_ul_config_sr_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_sr_information_rel10_t *sr_info_rel10 = (nfapi_ul_config_sr_information_rel10_t *)tlv;
+  return (pull8(ppReadPackedMsg, &sr_info_rel10->number_of_pucch_resources, end) &&
+          pull16(ppReadPackedMsg, &sr_info_rel10->pucch_index_p1, end));
+}
+
+static uint8_t unpack_ul_config_harq_info_rel10_tdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_harq_information_rel10_tdd_t *harq_info_tdd_rel10 = (nfapi_ul_config_harq_information_rel10_tdd_t *)tlv;
+  return (pull8(ppReadPackedMsg, &harq_info_tdd_rel10->harq_size, end) &&
+          pull8(ppReadPackedMsg, &harq_info_tdd_rel10->ack_nack_mode, end) &&
+          pull8(ppReadPackedMsg, &harq_info_tdd_rel10->number_of_pucch_resources, end) &&
+          pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_0, end) &&
+          pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_1, end) &&
+          pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_2, end) &&
+          pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_3, end));
+}
+
+static uint8_t unpack_ul_config_harq_info_rel8_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_harq_information_rel8_fdd_t *harq_info_fdd_rel8 = (nfapi_ul_config_harq_information_rel8_fdd_t *)tlv;
+  return (pull16(ppReadPackedMsg, &harq_info_fdd_rel8->n_pucch_1_0, end) &&
+          pull8(ppReadPackedMsg, &harq_info_fdd_rel8->harq_size, end));
+}
+
+static uint8_t unpack_ul_config_harq_info_rel9_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_harq_information_rel9_fdd_t *harq_info_fdd_rel9 = (nfapi_ul_config_harq_information_rel9_fdd_t *)tlv;
+  return (pull8(ppReadPackedMsg, &harq_info_fdd_rel9->harq_size, end) &&
+          pull8(ppReadPackedMsg, &harq_info_fdd_rel9->ack_nack_mode, end) &&
+          pull8(ppReadPackedMsg, &harq_info_fdd_rel9->number_of_pucch_resources, end) &&
+          pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_0, end) &&
+          pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_1, end) &&
+          pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_2, end) &&
+          pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_3, end));
+}
+
+static uint8_t unpack_ul_config_harq_info_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_harq_information_rel11_t *harq_info_rel11 = (nfapi_ul_config_harq_information_rel11_t *)tlv;
+  return (pull8(ppReadPackedMsg, &harq_info_rel11->num_ant_ports, end) &&
+          pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_0, end) &&
+          pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_1, end) &&
+          pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_2, end) &&
+          pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_3, end));
+}
+
+static uint8_t unpack_ul_config_harq_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_harq_information_rel13_t *harq_info_rel13 = (nfapi_ul_config_harq_information_rel13_t *)tlv;
+  return (pull16(ppReadPackedMsg, &harq_info_rel13->harq_size_2, end) &&
+          pull8(ppReadPackedMsg, &harq_info_rel13->starting_prb, end) &&
+          pull8(ppReadPackedMsg, &harq_info_rel13->n_prb, end) &&
+          pull8(ppReadPackedMsg, &harq_info_rel13->cdm_index, end) &&
+          pull8(ppReadPackedMsg, &harq_info_rel13->n_srs, end));
+}
+
+
+static uint8_t unpack_ul_config_srs_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_srs_pdu_rel8_t *srs_pdu_rel8 = (nfapi_ul_config_srs_pdu_rel8_t *)tlv;
+  return (pull32(ppReadPackedMsg, &srs_pdu_rel8->handle, end) &&
+          pull16(ppReadPackedMsg, &srs_pdu_rel8->size, end) &&
+          pull16(ppReadPackedMsg, &srs_pdu_rel8->rnti, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu_rel8->srs_bandwidth, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu_rel8->frequency_domain_position, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu_rel8->srs_hopping_bandwidth, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu_rel8->transmission_comb, end) &&
+          pull16(ppReadPackedMsg, &srs_pdu_rel8->i_srs, end) &&
+          pull8(ppReadPackedMsg, &srs_pdu_rel8->sounding_reference_cyclic_shift, end));
+}
+
+static uint8_t unpack_ul_config_srs_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_srs_pdu_rel10_t *srs_pdu_rel10 = (nfapi_ul_config_srs_pdu_rel10_t *)tlv;
+  return pull8(ppReadPackedMsg, &srs_pdu_rel10->antenna_port, end);
+}
+
+static uint8_t unpack_ul_config_srs_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_srs_pdu_rel13_t *srs_pdu_rel13 = (nfapi_ul_config_srs_pdu_rel13_t *)tlv;
+  return (pull8(ppReadPackedMsg, &srs_pdu_rel13->number_of_combs, end));
+}
+
+static uint8_t unpack_ul_nb_harq_info_rel13_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_nb_harq_information_rel13_fdd_t *nb_harq_info_fdd_rel13 = (nfapi_ul_config_nb_harq_information_rel13_fdd_t *)tlv;
+  return (pull8(ppReadPackedMsg, &nb_harq_info_fdd_rel13->harq_ack_resource, end));
+}
+
+static uint8_t unpack_ul_config_nulsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_nulsch_pdu_rel13_t *nulsch_pdu_rel13 = (nfapi_ul_config_nulsch_pdu_rel13_t *)tlv;
+
+  if(!(pull8(ppReadPackedMsg, &nulsch_pdu_rel13->nulsch_format, end) &&
+       pull32(ppReadPackedMsg, &nulsch_pdu_rel13->handle, end) &&
+       pull16(ppReadPackedMsg, &nulsch_pdu_rel13->size, end) &&
+       pull16(ppReadPackedMsg, &nulsch_pdu_rel13->rnti, end) &&
+       pull8(ppReadPackedMsg, &nulsch_pdu_rel13->subcarrier_indication, end) &&
+       pull8(ppReadPackedMsg, &nulsch_pdu_rel13->resource_assignment, end) &&
+       pull8(ppReadPackedMsg, &nulsch_pdu_rel13->mcs, end) &&
+       pull8(ppReadPackedMsg, &nulsch_pdu_rel13->redudancy_version, end) &&
+       pull8(ppReadPackedMsg, &nulsch_pdu_rel13->repetition_number, end) &&
+       pull8(ppReadPackedMsg, &nulsch_pdu_rel13->new_data_indication, end) &&
+       pull8(ppReadPackedMsg, &nulsch_pdu_rel13->n_srs, end) &&
+       pull16(ppReadPackedMsg, &nulsch_pdu_rel13->scrambling_sequence_initialization_cinit, end) &&
+       pull16(ppReadPackedMsg, &nulsch_pdu_rel13->sf_idx, end)))
+    return 0;
+
+  unpack_tlv_t unpack_fns[] = {
+    { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel8, &unpack_ul_config_ue_info_rel8_value},
+    { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel11, &unpack_ul_config_ue_info_rel11_value},
+    { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel13, &unpack_ul_config_ue_info_rel13_value},
+    { NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG, &nulsch_pdu_rel13->nb_harq_information.nb_harq_information_rel13_fdd, &unpack_ul_nb_harq_info_rel13_fdd_value},
+  };
+  return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, 0, 0);
+}
+
+static uint8_t unpack_ul_config_nrach_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_config_nrach_pdu_rel13_t *nrach_pdu_rel13 = (nfapi_ul_config_nrach_pdu_rel13_t *)tlv;
+  return (pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_0, end) &&
+          pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_1, end) &&
+          pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_2, end));
+}
+
+
+static uint8_t unpack_ul_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+#define UL_CONFIG_ULSCH_PDU_UNPACK_FNS(_pdu) \
+  { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG, &_pdu.ulsch_pdu_rel8, &unpack_ul_config_ulsch_pdu_rel8_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG, &_pdu.ulsch_pdu_rel10, &unpack_ul_config_ulsch_pdu_rel10_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG, &_pdu.ulsch_pdu_rel11, &unpack_ul_config_ulsch_pdu_rel11_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG, &_pdu.ulsch_pdu_rel13, &unpack_ul_config_ulsch_pdu_rel13_value},
+#define UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(_pdu) \
+  { NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG, &_pdu.cqi_ri_information_rel8, &unpack_ul_config_cqi_ri_info_rel8_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG, &_pdu.cqi_ri_information_rel9, &unpack_ul_config_cqi_ri_info_rel9_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG, &_pdu.cqi_ri_information_rel13, &unpack_ul_config_cqi_ri_info_rel13_value},
+#define UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(_pdu) \
+  { NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG, &_pdu.harq_information_rel10, &unpack_ul_config_ulsch_harq_info_rel10_value},\
+  { NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG, &_pdu.harq_information_rel13, &unpack_ul_config_ulsch_harq_info_rel13_value},
+#define UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(_pdu) \
+  { NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG, &_pdu.initial_transmission_parameters_rel8, &unpack_ul_config_cqi_init_tx_params_rel8_value},
+#define UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(_pdu) \
+  { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &_pdu.ue_information_rel8, &unpack_ul_config_ue_info_rel8_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &_pdu.ue_information_rel11, &unpack_ul_config_ue_info_rel11_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &_pdu.ue_information_rel13, &unpack_ul_config_ue_info_rel13_value},
+#define UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(_pdu) \
+  { NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG, &_pdu.cqi_information_rel8, &unpack_ul_config_cqi_info_rel8_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG, &_pdu.cqi_information_rel10, &unpack_ul_config_cqi_info_rel10_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG, &_pdu.cqi_information_rel13, &unpack_ul_config_cqi_info_rel13_value},
+#define UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(_pdu) \
+  { NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG, &_pdu.sr_information_rel8, &unpack_ul_config_sr_info_rel8_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG, &_pdu.sr_information_rel10, &unpack_ul_config_sr_info_rel10_value},
+#define UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(_pdu) \
+  { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG, &_pdu.harq_information_rel10_tdd, &unpack_ul_config_harq_info_rel10_tdd_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG, &_pdu.harq_information_rel8_fdd, &unpack_ul_config_harq_info_rel8_fdd_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG, &_pdu.harq_information_rel9_fdd, &unpack_ul_config_harq_info_rel9_fdd_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG, &_pdu.harq_information_rel11, &unpack_ul_config_harq_info_rel11_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG, &_pdu.harq_information_rel13, &unpack_ul_config_harq_info_rel13_value},
+#define UL_CONFIG_SRS_PDU_UNPACK_FNS(_pdu) \
+  { NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG, &_pdu.srs_pdu_rel8, &unpack_ul_config_srs_pdu_rel8_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG, &_pdu.srs_pdu_rel10, &unpack_ul_config_srs_pdu_rel10_value}, \
+  { NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG, &_pdu.srs_pdu_rel13, &unpack_ul_config_srs_pdu_rel13_value},
+#define UL_CONFIG_NULSCH_PDU_UNPACK_FNS(_pdu) \
+  { NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG, &_pdu.nulsch_pdu_rel13, &unpack_ul_config_nulsch_pdu_rel13_value},
+#define UL_CONFIG_NRACH_PDU_UNPACK_FNS(_pdu) \
+  { NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG, &_pdu.nrach_pdu_rel13, &unpack_ul_config_nrach_pdu_rel13_value},
+  nfapi_ul_config_request_body_t *value = (nfapi_ul_config_request_body_t *)tlv;
+
+  if(!(pull8(ppReadPackedMsg, &value->number_of_pdus, end) &&
+       pull8(ppReadPackedMsg, &value->rach_prach_frequency_resources, end) &&
+       pull8(ppReadPackedMsg, &value->srs_present, end)))
+    return 0;
+
+  if(value->number_of_pdus > NFAPI_UL_CONFIG_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of ul config pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_UL_CONFIG_MAX_PDU);
+    return 0;
+  }
+
+  if(value->number_of_pdus > 0) {
+    value->ul_config_pdu_list = (nfapi_ul_config_request_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_ul_config_request_pdu_t) * value->number_of_pdus, config);
+
+    if(value->ul_config_pdu_list == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate ul config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus);
+      return 0;
+    }
+  } else {
+    value->ul_config_pdu_list = 0;
+  }
+
+  uint16_t i;
+  uint16_t total_number_of_pdus = value->number_of_pdus;
+
+  for(i = 0; i < total_number_of_pdus; ++i) {
+    nfapi_ul_config_request_pdu_t *pdu = &(value->ul_config_pdu_list[i]);
+
+    if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) &&
+         pull8(ppReadPackedMsg, &pdu->pdu_size, end)))
+      return 0;
+
+    uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2;
+
+    if(packedPduEnd > end) {
+      // pdu end is past buffer end
+      return 0;
+    }
+
+    switch(pdu->pdu_type) {
+      case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_pdu)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.ulsch_pdu)
+          UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.cqi_ri_information)
+          UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.initial_transmission_parameters)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_harq_pdu.ulsch_pdu)
+          UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(pdu->ulsch_harq_pdu.harq_information)
+          UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_harq_pdu.initial_transmission_parameters)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu)
+          UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information)
+          UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.harq_information)
+          UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_pdu.ue_information)
+          UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_pdu.cqi_information)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_sr_pdu.ue_information)
+          UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_sr_pdu.sr_information)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_harq_pdu.ue_information)
+          UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_harq_pdu.harq_information)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.ue_information)
+          UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.sr_information)
+          UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.harq_information)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.ue_information)
+          UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.cqi_information)
+          UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.harq_information)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.ue_information)
+          UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.cqi_information)
+          UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.sr_information)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.ue_information)
+          UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.cqi_information)
+          UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.sr_information)
+          UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.harq_information)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_SRS_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_SRS_PDU_UNPACK_FNS(pdu->srs_pdu)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->harq_buffer_pdu.ue_information)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_uci_csi_pdu.ulsch_pdu)
+          UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->ulsch_uci_csi_pdu.csi_information)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_uci_harq_pdu.ulsch_pdu)
+          UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->ulsch_uci_harq_pdu.harq_information)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.ulsch_pdu)
+          UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.csi_information)
+          UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.harq_information)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_NULSCH_PDU_UNPACK_FNS(pdu->nulsch_pdu)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_UL_CONFIG_NRACH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          UL_CONFIG_NRACH_PDU_UNPACK_FNS(pdu->nrach_pdu)
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+    }
+  }
+
+  return 1;
+}
+
+
+static uint8_t unpack_ul_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_UL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->ul_config_request_body, &unpack_ul_config_request_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_hi_dci0_hi_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_hi_pdu_rel8_t *hi_pdu_rel8 = (nfapi_hi_dci0_hi_pdu_rel8_t *)tlv;
+  return( pull8(ppReadPackedMsg, &hi_pdu_rel8->resource_block_start, end) &&
+          pull8(ppReadPackedMsg, &hi_pdu_rel8->cyclic_shift_2_for_drms, end) &&
+          pull8(ppReadPackedMsg, &hi_pdu_rel8->hi_value, end) &&
+          pull8(ppReadPackedMsg, &hi_pdu_rel8->i_phich, end) &&
+          pull16(ppReadPackedMsg, &hi_pdu_rel8->transmission_power, end));
+}
+
+static uint8_t unpack_hi_dci0_hi_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_hi_pdu_rel10_t *hi_pdu_rel10 = (nfapi_hi_dci0_hi_pdu_rel10_t *)tlv;
+  return (pull8(ppReadPackedMsg, &hi_pdu_rel10->flag_tb2, end) &&
+          pull8(ppReadPackedMsg, &hi_pdu_rel10->hi_value_2, end));
+}
+
+static uint8_t unpack_hi_dci0_dci_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_dci_pdu_rel8_t *dci_pdu_rel8 = (nfapi_hi_dci0_dci_pdu_rel8_t *)tlv;
+  return (pull8(ppReadPackedMsg, &dci_pdu_rel8->dci_format, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->cce_index, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->aggregation_level, end) &&
+          pull16(ppReadPackedMsg, &dci_pdu_rel8->rnti, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->resource_block_start, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->number_of_resource_block, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->mcs_1, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->cyclic_shift_2_for_drms, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->frequency_hopping_enabled_flag, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->frequency_hopping_bits, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->new_data_indication_1, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->ue_tx_antenna_seleciton, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->tpc, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->cqi_csi_request, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->ul_index, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel8->dl_assignment_index, end) &&
+          pull32(ppReadPackedMsg, &dci_pdu_rel8->tpc_bitmap, end) &&
+          pull16(ppReadPackedMsg, &dci_pdu_rel8->transmission_power, end));
+}
+
+static uint8_t unpack_hi_dci0_dci_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_dci_pdu_rel10_t *dci_pdu_rel10 = (nfapi_hi_dci0_dci_pdu_rel10_t *)tlv;
+  return (pull8(ppReadPackedMsg, &dci_pdu_rel10->cross_carrier_scheduling_flag, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel10->carrier_indicator, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel10->size_of_cqi_csi_feild, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel10->srs_flag, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel10->srs_request, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel10->resource_allocation_flag, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel10->resource_allocation_type, end) &&
+          pull32(ppReadPackedMsg, &dci_pdu_rel10->resource_block_coding, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel10->mcs_2, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel10->new_data_indication_2, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel10->number_of_antenna_ports, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel10->tpmi, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel10->total_dci_length_including_padding, end) &&
+          pull8(ppReadPackedMsg, &dci_pdu_rel10->n_ul_rb, end));
+}
+
+static uint8_t unpack_hi_dci0_dci_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_dci_pdu_rel12_t *dci_pdu_rel12 = (nfapi_hi_dci0_dci_pdu_rel12_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &dci_pdu_rel12->pscch_resource, end) &&
+           pull8(ppReadPackedMsg, &dci_pdu_rel12->time_resource_pattern, end));
+}
+
+static uint8_t unpack_hi_dci0_mpdcch_dci_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t *value = (nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t *)tlv;
+  return (pull8(ppReadPackedMsg, &value->mpdcch_narrowband, end) &&
+          pull8(ppReadPackedMsg, &value->number_of_prb_pairs, end) &&
+          pull8(ppReadPackedMsg, &value->resource_block_assignment, end) &&
+          pull8(ppReadPackedMsg, &value->mpdcch_transmission_type, end) &&
+          pull8(ppReadPackedMsg, &value->start_symbol, end) &&
+          pull8(ppReadPackedMsg, &value->ecce_index, end) &&
+          pull8(ppReadPackedMsg, &value->aggreagation_level, end) &&
+          pull8(ppReadPackedMsg, &value->rnti_type, end) &&
+          pull16(ppReadPackedMsg, &value->rnti, end) &&
+          pull8(ppReadPackedMsg, &value->ce_mode, end) &&
+          pull16(ppReadPackedMsg, &value->drms_scrambling_init, end) &&
+          pull16(ppReadPackedMsg, &value->initial_transmission_sf_io, end) &&
+          pull16(ppReadPackedMsg, &value->transmission_power, end) &&
+          pull8(ppReadPackedMsg, &value->dci_format, end) &&
+          pull8(ppReadPackedMsg, &value->resource_block_start, end) &&
+          pull8(ppReadPackedMsg, &value->number_of_resource_blocks, end) &&
+          pull8(ppReadPackedMsg, &value->mcs, end) &&
+          pull8(ppReadPackedMsg, &value->pusch_repetition_levels, end) &&
+          pull8(ppReadPackedMsg, &value->frequency_hopping_flag, end) &&
+          pull8(ppReadPackedMsg, &value->new_data_indication, end) &&
+          pull8(ppReadPackedMsg, &value->harq_process, end) &&
+          pull8(ppReadPackedMsg, &value->redudency_version, end) &&
+          pull8(ppReadPackedMsg, &value->tpc, end) &&
+          pull8(ppReadPackedMsg, &value->csi_request, end) &&
+          pull8(ppReadPackedMsg, &value->ul_inex, end) &&
+          pull8(ppReadPackedMsg, &value->dai_presence_flag, end) &&
+          pull8(ppReadPackedMsg, &value->dl_assignment_index, end) &&
+          pull8(ppReadPackedMsg, &value->srs_request, end) &&
+          pull8(ppReadPackedMsg, &value->dci_subframe_repetition_number, end) &&
+          pull32(ppReadPackedMsg, &value->tcp_bitmap, end) &&
+          pull8(ppReadPackedMsg, &value->total_dci_length_include_padding, end) &&
+          pull8(ppReadPackedMsg, &value->number_of_tx_antenna_ports, end) &&
+          pullarray16(ppReadPackedMsg, value->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, value->number_of_tx_antenna_ports, end));
+}
+
+static uint8_t unpack_hi_dci0_npdcch_dci_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_hi_dci0_npdcch_dci_pdu_rel13_t *value = (nfapi_hi_dci0_npdcch_dci_pdu_rel13_t *)tlv;
+  return (pull8(ppReadPackedMsg, &value->ncce_index, end) &&
+          pull8(ppReadPackedMsg, &value->aggregation_level, end) &&
+          pull8(ppReadPackedMsg, &value->start_symbol, end) &&
+          pull16(ppReadPackedMsg, &value->rnti, end) &&
+          pull8(ppReadPackedMsg, &value->scrambling_reinitialization_batch_index, end) &&
+          pull8(ppReadPackedMsg, &value->nrs_antenna_ports_assumed_by_the_ue, end) &&
+          pull8(ppReadPackedMsg, &value->subcarrier_indication, end) &&
+          pull8(ppReadPackedMsg, &value->resource_assignment, end) &&
+          pull8(ppReadPackedMsg, &value->scheduling_delay, end) &&
+          pull8(ppReadPackedMsg, &value->mcs, end) &&
+          pull8(ppReadPackedMsg, &value->redudancy_version, end) &&
+          pull8(ppReadPackedMsg, &value->repetition_number, end) &&
+          pull8(ppReadPackedMsg, &value->new_data_indicator, end) &&
+          pull8(ppReadPackedMsg, &value->dci_subframe_repetition_number, end));
+}
+
+static uint8_t unpack_hi_dci0_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_hi_dci0_request_body_t *value = (nfapi_hi_dci0_request_body_t *)tlv;
+
+  if(!(pull16(ppReadPackedMsg, &value->sfnsf, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_dci, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_hi, end)))
+    return 0;
+
+  uint8_t totalNumPdus = value->number_of_hi + value->number_of_dci;
+
+  if(totalNumPdus > NFAPI_HI_DCI0_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of dci0 pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, totalNumPdus, NFAPI_HI_DCI0_MAX_PDU);
+    return 0;
+  }
+
+  if(totalNumPdus > 0) {
+    value->hi_dci0_pdu_list = (nfapi_hi_dci0_request_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_hi_dci0_request_pdu_t) * totalNumPdus, config);
+
+    if(value->hi_dci0_pdu_list == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate hi dci0 pdu list (count:%d)\n", __FUNCTION__, totalNumPdus);
+      return 0;
+    }
+  } else {
+    value->hi_dci0_pdu_list = 0;
+  }
+
+  uint8_t i;
+
+  for(i = 0; i < totalNumPdus; ++i) {
+    nfapi_hi_dci0_request_pdu_t *pdu = &(value->hi_dci0_pdu_list[i]);
+
+    if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) &&
+         pull8(ppReadPackedMsg, &pdu->pdu_size, end)))
+      return 0;
+
+    uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2;
+
+    if(packedPduEnd > end) {
+      // pdu end if past buffer end
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pdu size to big %d %d\n", __FUNCTION__, packedPduEnd, end);
+      return 0;
+    }
+
+    switch(pdu->pdu_type) {
+      case NFAPI_HI_DCI0_HI_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG, &pdu->hi_pdu.hi_pdu_rel8, &unpack_hi_dci0_hi_pdu_rel8_value},
+          { NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG, &pdu->hi_pdu.hi_pdu_rel10, &unpack_hi_dci0_hi_pdu_rel10_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_HI_DCI0_DCI_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG, &pdu->dci_pdu.dci_pdu_rel8, &unpack_hi_dci0_dci_pdu_rel8_value},
+          { NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG, &pdu->dci_pdu.dci_pdu_rel10, &unpack_hi_dci0_dci_pdu_rel10_value},
+          { NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG, &pdu->dci_pdu.dci_pdu_rel12, &unpack_hi_dci0_dci_pdu_rel12_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel8, &unpack_hi_dci0_dci_pdu_rel8_value},
+          { NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel10, &unpack_hi_dci0_dci_pdu_rel10_value},
+          { NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG, &pdu->epdcch_dci_pdu.epdcch_parameters_rel11, &unpack_dl_config_epdcch_params_rel11_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG, &pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13, &unpack_hi_dci0_mpdcch_dci_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG, &pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13, &unpack_hi_dci0_npdcch_dci_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type );
+      }
+      break;
+    };
+  }
+
+  return 1;
+}
+//unpack_ul_dci_pdu_list_value
+
+static uint8_t unpack_ul_dci_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
+  nfapi_nr_ul_dci_request_pdus_t *value = (nfapi_nr_ul_dci_request_pdus_t *)msg;
+
+  for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i) {
+    if(!pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI,  end) &&
+        pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, end) &&
+        pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, end) &&
+        pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, end) &&
+        pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, end) &&
+        pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, end) &&
+        pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, end) &&
+        pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, end) &&
+        pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, end));
+
+    return 0;
+  }
+
+  return (pull16(ppReadPackedMsg, &value->PDUType, end) &&
+          pull16(ppReadPackedMsg, &value->PDUSize, end) &&
+          pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, end) &&
+          pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, end) &&
+          pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, end) &&
+          pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, end) &&
+          pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, end) &&
+          pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, end) &&
+          pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, end) &&
+          pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, end) &&
+          pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, end) &&
+          pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, end) &&
+          pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, end) &&
+          pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, end) &&
+          pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, end) &&
+          pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end));
+}
+
+static uint8_t unpack_ul_dci_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t *)msg;
+
+  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) &&
+        pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
+        pull8(ppReadPackedMsg, &pNfapiMsg->numPdus, end)
+       ))
+    return 0;
+
+  for(int i=0; i< pNfapiMsg->numPdus; i++) {
+    if (!unpack_ul_dci_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->ul_dci_pdu_list[i]))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_HI_DCI0_REQUEST_BODY_TAG, &pNfapiMsg->hi_dci0_request_body, &unpack_hi_dci0_request_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
+  nfapi_nr_pdu_t *pNfapiMsg = (nfapi_nr_pdu_t *)msg;
+
+  if(!(pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end) &&
+       pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end) &&
+       pull16(ppReadPackedMsg, &pNfapiMsg->PDU_length, end)
+      ))
+    return 0;
+
+  uint16_t i = 0;
+  uint16_t total_number_of_tlvs = pNfapiMsg->num_TLV;
+
+  for(; i < total_number_of_tlvs; ++i) {
+    if (!(pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].length, end) &&
+          pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].tag, end)))
+      return 0;
+
+    switch(pNfapiMsg->TLVs[i].tag) {
+      case 0: {
+        if(!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.direct, 16384, pNfapiMsg->TLVs[i].length, end))
+          return 0;
+
+        break;
+      }
+
+      case 1: {
+        if(!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.ptr, pNfapiMsg->TLVs[i].length, pNfapiMsg->TLVs[i].length, end))
+          return 0;
+
+        break;
+      }
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", pNfapiMsg->TLVs[i].tag );
+        break;
+      }
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)msg;
+
+  if(!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) &&
+       pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
+       pull16(ppReadPackedMsg, &pNfapiMsg->Number_of_PDUs, end)))
+    return 0;
+
+  for(int i=0; i< pNfapiMsg->Number_of_PDUs; i++) {
+    if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i]))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  uint8_t proceed = 1;
+  nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t *)msg;
+
+  if(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) == 0)
+    return 0;
+
+  while (((uint8_t *)(*ppReadPackedMsg) < end) && proceed) {
+    nfapi_tl_t generic_tl;
+
+    if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
+      return 0;
+
+    switch(generic_tl.tag) {
+      case NFAPI_TX_REQUEST_BODY_TAG: {
+        pNfapiMsg->tx_request_body.tl = generic_tl;
+
+        if( pull16(ppReadPackedMsg, &pNfapiMsg->tx_request_body.number_of_pdus, end) == 0)
+          return 0;
+
+        if(pNfapiMsg->tx_request_body.number_of_pdus > NFAPI_TX_MAX_PDU) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of tx pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->tx_request_body.number_of_pdus, NFAPI_TX_MAX_PDU);
+          return 0;
+        }
+
+        if(pNfapiMsg->tx_request_body.number_of_pdus > 0) {
+          pNfapiMsg->tx_request_body.tx_pdu_list = (nfapi_tx_request_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_tx_request_pdu_t) * pNfapiMsg->tx_request_body.number_of_pdus, config);
+
+          if(pNfapiMsg->tx_request_body.tx_pdu_list == NULL) {
+            NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate tx  pdu list (count:%d)\n", __FUNCTION__, pNfapiMsg->tx_request_body.number_of_pdus);
+            return 0;
+          }
+        } else {
+          pNfapiMsg->tx_request_body.tx_pdu_list = 0;
+        }
+
+        uint16_t i;
+        uint16_t totalNumPdus = pNfapiMsg->tx_request_body.number_of_pdus;
+
+        for(i = 0; i < totalNumPdus; ++i) {
+          nfapi_tx_request_pdu_t *pdu = &(pNfapiMsg->tx_request_body.tx_pdu_list[i]);
+
+          if (pdu) {
+            uint16_t length = 0;
+            uint16_t index = 0;
+
+            if(!(pull16(ppReadPackedMsg, &length, end) &&
+                 pull16(ppReadPackedMsg, &index, end)))
+              return 0;
+
+            pdu->pdu_length = length;
+            pdu->pdu_index = index;
+            // TODO : May need to rethink this bit
+            pdu->num_segments = 1;
+            pdu->segments[0].segment_length = pdu->pdu_length;
+            pdu->segments[0].segment_data = nfapi_p7_allocate(pdu->pdu_length, config);
+
+            if(pdu->segments[0].segment_data) {
+              if(!pullarray8(ppReadPackedMsg, pdu->segments[0].segment_data, pdu->segments[0].segment_length, pdu->segments[0].segment_length, end))
+                return 0;
+
+              if (pdu->segments[0].segment_length == 3) {
+                NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__,
+                            pdu->segments[0].segment_data[0],
+                            pdu->segments[0].segment_data[1],
+                            pdu->segments[0].segment_data[2]
+                           );
+              }
+            } else {
+              NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request: Failed to allocate pdu (len:%d) %d/%d %d\n", pdu->pdu_length, totalNumPdus, i, pdu->pdu_index);
+            }
+          } else {
+            NFAPI_TRACE(NFAPI_TRACE_ERROR, "NULL pdu\n");
+          }
+        }
+      }
+      break;
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request FIXME : Invalid pdu type %d \n", generic_tl.tag );
+      }
+      break;
+    };
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  uint8_t proceed = 1;
+  nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t *)msg;
+
+  if(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) == 0)
+    return 0;
+
+  while (((uint8_t *)(*ppReadPackedMsg) < end) && proceed) {
+    nfapi_tl_t generic_tl;
+
+    if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
+      return 0;
+
+    switch(generic_tl.tag) {
+      case NFAPI_UE_RELEASE_BODY_TAG: {
+        pNfapiMsg->ue_release_request_body.tl = generic_tl;
+
+        if( pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.number_of_TLVs, end) == 0)
+          return 0;
+
+        if(pNfapiMsg->ue_release_request_body.number_of_TLVs > NFAPI_RELEASE_MAX_RNTI) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of relese rnti's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->ue_release_request_body.number_of_TLVs, NFAPI_RELEASE_MAX_RNTI);
+          return 0;
+        } else {
+          uint8_t j;
+          uint16_t num = pNfapiMsg->ue_release_request_body.number_of_TLVs;
+
+          for(j = 0; j < num; ++j) {
+            if(pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.ue_release_request_TLVs_list[j].rnti, end) == 0) {
+              return 0;
+            }
+          }
+        }
+      }
+      break;
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_ue_release_request FIXME : Invalid type %d \n", generic_tl.tag );
+      }
+      break;
+    };
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_harq_indication_tdd_harq_data_bundling(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_harq_indication_tdd_harq_data_bundling_t *value = (nfapi_harq_indication_tdd_harq_data_bundling_t *)tlv;
+  return (pull8(ppReadPackedMsg, &value->value_0, end) &&
+          pull8(ppReadPackedMsg, &value->value_1, end));
+}
+
+static uint8_t unpack_harq_indication_tdd_harq_data_multiplexing(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_harq_indication_tdd_harq_data_multiplexing_t *value = (nfapi_harq_indication_tdd_harq_data_multiplexing_t *)tlv;
+  return (pull8(ppReadPackedMsg, &value->value_0, end) &&
+          pull8(ppReadPackedMsg, &value->value_1, end) &&
+          pull8(ppReadPackedMsg, &value->value_2, end) &&
+          pull8(ppReadPackedMsg, &value->value_3, end));
+}
+static uint8_t unpack_harq_indication_tdd_harq_data_special_bundling(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_harq_indication_tdd_harq_data_special_bundling_t *value = (nfapi_harq_indication_tdd_harq_data_special_bundling_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &value->value_0, end));
+}
+static uint8_t unpack_harq_indication_tdd_harq_data(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_harq_indication_tdd_harq_data_t *value = (nfapi_harq_indication_tdd_harq_data_t *)tlv;
+  return  (pull8(ppReadPackedMsg, &value->value_0, end));
+}
+
+static uint8_t unpack_harq_indication_tdd_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_harq_indication_tdd_rel8_t *value = (nfapi_harq_indication_tdd_rel8_t *)tlv;
+
+  if(!(pull8(ppReadPackedMsg, &value->mode, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_ack_nack, end)))
+    return 0;
+
+  uint8_t result = 0;
+
+  switch(value->mode) {
+    case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING:
+      result = unpack_harq_indication_tdd_harq_data_bundling(&value->harq_data.bundling, ppReadPackedMsg, end);
+      break;
+
+    case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING:
+      result = unpack_harq_indication_tdd_harq_data_multiplexing(&value->harq_data.multiplex, ppReadPackedMsg, end);
+      break;
+
+    case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING:
+      result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data.special_bundling, ppReadPackedMsg, end);
+      break;
+
+    case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3:
+    case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION:
+      result = 1;
+      break;
+
+    default:
+      // TODO add error message
+      return 0;
+      break;
+  }
+
+  return result;
+}
+
+static uint8_t unpack_harq_indication_tdd_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_harq_indication_tdd_rel9_t *value = (nfapi_harq_indication_tdd_rel9_t *)tlv;
+
+  if(!(pull8(ppReadPackedMsg, &value->mode, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_ack_nack, end)))
+    return 0;
+
+  if(value->number_of_ack_nack > NFAPI_MAX_NUMBER_ACK_NACK_TDD) {
+    // TODO : add error message
+    return 0;
+  }
+
+  uint16_t idx = 0;
+
+  for(idx = 0; idx < value->number_of_ack_nack; ++idx) {
+    uint8_t result = 0;
+
+    switch(value->mode) {
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING:
+        result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].bundling, ppReadPackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING:
+        result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].multiplex, ppReadPackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING:
+        result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data[idx].special_bundling, ppReadPackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION:
+        result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].channel_selection, ppReadPackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3:
+        result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_3, ppReadPackedMsg, end);
+        break;
+
+      default:
+        // TODO add error message
+        return 0;
+        break;
+    }
+
+    if(result == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_harq_indication_tdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_harq_indication_tdd_rel13_t *value = (nfapi_harq_indication_tdd_rel13_t *)tlv;
+
+  if(!(pull8(ppReadPackedMsg, &value->mode, end) &&
+       pull16(ppReadPackedMsg, &value->number_of_ack_nack, end)))
+    return 0;
+
+  if(value->number_of_ack_nack > NFAPI_MAX_NUMBER_ACK_NACK_TDD) {
+    // TODO : add error message
+    return 0;
+  }
+
+  uint16_t idx = 0;
+
+  for(idx = 0; idx < value->number_of_ack_nack; ++idx) {
+    uint8_t result = 0;
+
+    switch(value->mode) {
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING:
+        result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].bundling, ppReadPackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING:
+        result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].multiplex, ppReadPackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING:
+        result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data[idx].special_bundling, ppReadPackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION:
+        result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].channel_selection, ppReadPackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3:
+        result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_3, ppReadPackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_4:
+        result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_4, ppReadPackedMsg, end);
+        break;
+
+      case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_5:
+        result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_5, ppReadPackedMsg, end);
+        break;
+
+      default:
+        // TODO add error message
+        return 0;
+        break;
+    }
+
+    if(result == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_harq_indication_fdd_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_harq_indication_fdd_rel8_t *value = (nfapi_harq_indication_fdd_rel8_t *)tlv;
+  return (pull8(ppReadPackedMsg, &value->harq_tb1, end) &&
+          pull8(ppReadPackedMsg, &value->harq_tb2, end));
+}
+
+static uint8_t unpack_harq_indication_fdd_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_harq_indication_fdd_rel9_t *value = (nfapi_harq_indication_fdd_rel9_t *)tlv;
+  return (pull8(ppReadPackedMsg, &value->mode, end) &&
+          pull8(ppReadPackedMsg, &value->number_of_ack_nack, end) &&
+          pullarray8(ppReadPackedMsg, value->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL9_MAX, value->number_of_ack_nack, end));
+}
+
+static uint8_t unpack_harq_indication_fdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_harq_indication_fdd_rel13_t *value = (nfapi_harq_indication_fdd_rel13_t *)tlv;
+  return (pull8(ppReadPackedMsg, &value->mode, end) &&
+          pull16(ppReadPackedMsg, &value->number_of_ack_nack, end) &&
+          pullarray8(ppReadPackedMsg, value->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL13_MAX, value->number_of_ack_nack, end));
+}
+
+static uint8_t unpack_ul_cqi_information_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_ul_cqi_information_t *value = (nfapi_ul_cqi_information_t *)tlv;
+  return (pull8(ppReadPackedMsg, &value->ul_cqi, end) &&
+          pull8(ppReadPackedMsg, &value->channel, end));
+}
+
+
+
+static uint8_t unpack_harq_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_harq_indication_body_t *value = (nfapi_harq_indication_body_t *)tlv;
+  uint8_t *harqBodyEnd = *ppReadPackedMsg + value->tl.length;
+
+  if(harqBodyEnd > end)
+    return 0;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_harqs, end) == 0)
+    return 0;
+
+  if(value->number_of_harqs > NFAPI_HARQ_IND_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of harq ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_harqs, NFAPI_HARQ_IND_MAX_PDU);
+    return 0;
+  }
+
+  value->harq_pdu_list = (nfapi_harq_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_harq_indication_pdu_t) * value->number_of_harqs, config);
+
+  if(value->harq_pdu_list == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_harqs);
+    return 0;
+  }
+
+  uint8_t i = 0;
+
+  for(i = 0; i < value->number_of_harqs; ++i) {
+    nfapi_harq_indication_pdu_t *pdu = &(value->harq_pdu_list[i]);
+
+    if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
+      return 0;
+
+    uint8_t *harqPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
+    unpack_tlv_t unpack_fns[] = {
+      { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value },
+      { NFAPI_HARQ_INDICATION_TDD_REL8_TAG, &pdu->harq_indication_tdd_rel8, &unpack_harq_indication_tdd_rel8_value},
+      { NFAPI_HARQ_INDICATION_TDD_REL9_TAG, &pdu->harq_indication_tdd_rel9, &unpack_harq_indication_tdd_rel9_value},
+      { NFAPI_HARQ_INDICATION_TDD_REL13_TAG, &pdu->harq_indication_tdd_rel13, &unpack_harq_indication_tdd_rel13_value},
+      { NFAPI_HARQ_INDICATION_FDD_REL8_TAG, &pdu->harq_indication_fdd_rel8, &unpack_harq_indication_fdd_rel8_value},
+      { NFAPI_HARQ_INDICATION_FDD_REL9_TAG, &pdu->harq_indication_fdd_rel9, &unpack_harq_indication_fdd_rel9_value},
+      { NFAPI_HARQ_INDICATION_FDD_REL13_TAG, &pdu->harq_indication_fdd_rel13, &unpack_harq_indication_fdd_rel13_value},
+      { NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, &unpack_ul_cqi_information_value}
+    };
+
+    if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, harqPduInstanceEnd, 0, 0) == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_harq_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_harq_indication_t *pNfapiMsg = (nfapi_harq_indication_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->harq_indication_body, &unpack_harq_indication_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_crc_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_crc_indication_rel8_t *crc_pdu_rel8 = (nfapi_crc_indication_rel8_t *)tlv;
+  return ( pull8(ppReadPackedMsg, &crc_pdu_rel8->crc_flag, end) );
+}
+
+static uint8_t unpack_crc_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end,  nfapi_p7_codec_config_t *config) {
+  nfapi_crc_indication_body_t *value = (nfapi_crc_indication_body_t *)tlv;
+  uint8_t *crcBodyEnd = *ppReadPackedMsg + value->tl.length;
+
+  if(crcBodyEnd > end)
+    return 0;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_crcs, end) == 0)
+    return 0;
+
+  if(value->number_of_crcs > NFAPI_CRC_IND_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of crc ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_crcs, NFAPI_CRC_IND_MAX_PDU);
+    return 0;
+  }
+
+  if(value->number_of_crcs > 0) {
+    value->crc_pdu_list = (nfapi_crc_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_crc_indication_pdu_t) * value->number_of_crcs, config);
+
+    if(value->crc_pdu_list == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate crc ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_crcs);
+      return 0;
+    }
+  } else {
+    value->crc_pdu_list = 0;
+  }
+
+  uint8_t i = 0;
+
+  for(i = 0; i < value->number_of_crcs; ++i) {
+    nfapi_crc_indication_pdu_t *pdu = &(value->crc_pdu_list[i]);
+
+    if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
+      return 0;
+
+    uint8_t *crcPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
+    unpack_tlv_t unpack_fns[] = {
+      { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value },
+      { NFAPI_CRC_INDICATION_REL8_TAG, &pdu->crc_indication_rel8, unpack_crc_indication_rel8_value },
+    };
+
+    if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, crcPduInstanceEnd, 0, 0) == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_crc_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_crc_indication_t *pNfapiMsg = (nfapi_crc_indication_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_CRC_INDICATION_BODY_TAG, &pNfapiMsg->crc_indication_body, &unpack_crc_indication_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_rx_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_rx_indication_rel8_t *value = (nfapi_rx_indication_rel8_t *)tlv;
+  return (pull16(ppReadPackedMsg, &value->length, end) &&
+          pull16(ppReadPackedMsg, &value->offset, end) &&
+          pull8(ppReadPackedMsg, &value->ul_cqi, end) &&
+          pull16(ppReadPackedMsg, &value->timing_advance, end));
+}
+static uint8_t unpack_rx_indication_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_rx_indication_rel9_t *value = (nfapi_rx_indication_rel9_t *)tlv;
+  return (pull16(ppReadPackedMsg, &value->timing_advance_r9, end));
+}
+
+static uint8_t unpack_rx_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_rx_indication_body_t *value = (nfapi_rx_indication_body_t *)tlv;
+  // the rxBodyEnd points to the end of the cqi PDU's
+  uint8_t *rxBodyEnd = *ppReadPackedMsg + value->tl.length;
+  uint8_t *rxPduEnd = rxBodyEnd;
+  uint8_t *numberOfPdusAddress = *ppReadPackedMsg;
+
+  if(rxBodyEnd > end) {
+    // pdu end is past buffer end
+    return 0;
+  }
+
+  if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0)
+    return 0;
+
+  if(value->number_of_pdus > NFAPI_RX_IND_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of rx ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_RX_IND_MAX_PDU);
+    return 0;
+  }
+
+  if(value->number_of_pdus > 0) {
+    value->rx_pdu_list = (nfapi_rx_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_rx_indication_pdu_t) * value->number_of_pdus, config);
+
+    if(value->rx_pdu_list == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate rx ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus);
+      return 0;
+    }
+  } else {
+    value->rx_pdu_list = 0;
+  }
+
+  uint8_t i = 0;
+  nfapi_rx_indication_pdu_t *pdu = 0;
+
+  while((uint8_t *)(*ppReadPackedMsg) < rxBodyEnd && (uint8_t *)(*ppReadPackedMsg) < rxPduEnd) {
+    nfapi_tl_t generic_tl;
+
+    if( unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
+      return 0;
+
+    switch(generic_tl.tag) {
+      case NFAPI_RX_UE_INFORMATION_TAG: {
+        pdu = &(value->rx_pdu_list[i++]);
+        pdu->rx_ue_information.tl = generic_tl;
+
+        if(unpack_rx_ue_information_value(&pdu->rx_ue_information, ppReadPackedMsg, end) == 0)
+          return 0;
+      }
+      break;
+
+      case NFAPI_RX_INDICATION_REL8_TAG: {
+        if(pdu != 0) {
+          pdu->rx_indication_rel8.tl = generic_tl;
+
+          if(unpack_rx_indication_rel8_value(&pdu->rx_indication_rel8, ppReadPackedMsg, end) == 0)
+            return 0;
+
+          if(pdu->rx_indication_rel8.offset > 0) {
+            // Need to check that the data is within the tlv
+            if(numberOfPdusAddress + pdu->rx_indication_rel8.offset + pdu->rx_indication_rel8.length <= rxBodyEnd) {
+              // If this the first pdu set the rxPduEnd
+              if(numberOfPdusAddress + pdu->rx_indication_rel8.offset < rxPduEnd) {
+                rxPduEnd = numberOfPdusAddress + pdu->rx_indication_rel8.offset;
+
+                if(rxPduEnd > end) {
+                  // pdu end is past buffer end
+                  return 0;
+                }
+              }
+            } else {
+              NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME: the rx data is outside of the tlv\n");
+            }
+          }
+        }
+      }
+      break;
+
+      case NFAPI_RX_INDICATION_REL9_TAG: {
+        if(pdu != 0) {
+          pdu->rx_indication_rel9.tl = generic_tl;
+
+          if(unpack_rx_indication_rel9_value(&pdu->rx_indication_rel9, ppReadPackedMsg, end) == 0)
+            return 0;
+        }
+      }
+      break;
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "RX_ULSCH.indication Invalid pdu type %d \n", generic_tl.tag );
+      }
+      break;
+    }
+  }
+
+  uint8_t idx = 0;
+
+  for(idx = 0; idx < value->number_of_pdus; ++idx) {
+    if(value->rx_pdu_list[idx].rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) {
+      uint32_t length = value->rx_pdu_list[idx].rx_indication_rel8.length;
+      value->rx_pdu_list[idx].data = nfapi_p7_allocate(length, config);
+
+      if(pullarray8(ppReadPackedMsg, value->rx_pdu_list[idx].data, length, length, end) == 0) {
+        return 0;
+      }
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_rx_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_rx_indication_t *pNfapiMsg = (nfapi_rx_indication_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_RX_INDICATION_BODY_TAG, &pNfapiMsg->rx_indication_body, &unpack_rx_indication_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_preamble_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_preamble_pdu_rel8_t *preamble_pdu_rel8 = (nfapi_preamble_pdu_rel8_t *)tlv;
+  return (pull16(ppReadPackedMsg, &preamble_pdu_rel8->rnti, end) &&
+          pull8(ppReadPackedMsg, &preamble_pdu_rel8->preamble, end) &&
+          pull16(ppReadPackedMsg, &preamble_pdu_rel8->timing_advance, end));
+}
+
+static uint8_t unpack_preamble_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_preamble_pdu_rel9_t *preamble_pdu_rel9 = (nfapi_preamble_pdu_rel9_t *)tlv;
+  return pull16(ppReadPackedMsg, &preamble_pdu_rel9->timing_advance_r9, end);
+}
+
+static uint8_t unpack_preamble_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_preamble_pdu_rel13_t *preamble_pdu_rel13 = (nfapi_preamble_pdu_rel13_t *)tlv;
+  return pull8(ppReadPackedMsg, &preamble_pdu_rel13->rach_resource_type, end);
+}
+
+static uint8_t unpack_rach_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_rach_indication_body_t *value = (nfapi_rach_indication_body_t *)tlv;
+  uint8_t *rachBodyEnd = *ppReadPackedMsg + value->tl.length;
+
+  if(rachBodyEnd > end)
+    return 0;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_preambles, end) == 0)
+    return 0;
+
+  if(value->number_of_preambles > NFAPI_PREAMBLE_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of preamble du's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_preambles, NFAPI_PREAMBLE_MAX_PDU);
+    return 0;
+  }
+
+  if(value->number_of_preambles > 0) {
+    value->preamble_list = (nfapi_preamble_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_preamble_pdu_t) * value->number_of_preambles, config);
+
+    if(value->preamble_list == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate preamble pdu list (count:%d)\n", __FUNCTION__, value->number_of_preambles);
+      return 0;
+    }
+  } else {
+    value->preamble_list = 0;
+  }
+
+  uint8_t i = 0;
+
+  for(i = 0; i < value->number_of_preambles; ++i) {
+    nfapi_preamble_pdu_t *pdu = &(value->preamble_list[i]);
+
+    if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
+      return 0;
+
+    uint8_t *preamblePduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
+    unpack_tlv_t unpack_fns[] = {
+      { NFAPI_PREAMBLE_REL8_TAG, &pdu->preamble_rel8, unpack_preamble_pdu_rel8_value },
+      { NFAPI_PREAMBLE_REL9_TAG, &pdu->preamble_rel9, unpack_preamble_pdu_rel9_value },
+      { NFAPI_PREAMBLE_REL13_TAG, &pdu->preamble_rel13, unpack_preamble_pdu_rel13_value },
+    };
+
+    if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, preamblePduInstanceEnd, 0, 0) == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_rach_indication_t *pNfapiMsg = (nfapi_rach_indication_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_RACH_INDICATION_BODY_TAG, &pNfapiMsg->rach_indication_body, &unpack_rach_indication_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_srs_indication_fdd_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_srs_indication_fdd_rel8_t *srs_pdu_fdd_rel8 = (nfapi_srs_indication_fdd_rel8_t *)tlv;
+
+  if(!(pull16(ppReadPackedMsg, &srs_pdu_fdd_rel8->doppler_estimation, end) &&
+       pull16(ppReadPackedMsg, &srs_pdu_fdd_rel8->timing_advance, end) &&
+       pull8(ppReadPackedMsg, &srs_pdu_fdd_rel8->number_of_resource_blocks, end) &&
+       pull8(ppReadPackedMsg, &srs_pdu_fdd_rel8->rb_start, end) &&
+       pullarray8(ppReadPackedMsg, srs_pdu_fdd_rel8->snr, NFAPI_NUM_RB_MAX, srs_pdu_fdd_rel8->number_of_resource_blocks, end)))
+    return 0;
+
+  return 1;
+}
+
+static uint8_t unpack_srs_indication_fdd_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_srs_indication_fdd_rel9_t *srs_pdu_fdd_rel9 = (nfapi_srs_indication_fdd_rel9_t *)tlv;
+  return (pull16(ppReadPackedMsg, &srs_pdu_fdd_rel9->timing_advance_r9, end));
+}
+
+static uint8_t unpack_srs_indication_tdd_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_srs_indication_ttd_rel10_t *srs_pdu_tdd_rel10 = (nfapi_srs_indication_ttd_rel10_t *)tlv;
+  return (pull8(ppReadPackedMsg, &srs_pdu_tdd_rel10->uppts_symbol, end));
+}
+
+static uint8_t unpack_srs_indication_fdd_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_srs_indication_fdd_rel11_t *srs_pdu_fdd_rel11 = (nfapi_srs_indication_fdd_rel11_t *)tlv;
+  return ( pull16(ppReadPackedMsg, &srs_pdu_fdd_rel11->ul_rtoa, end));
+}
+
+static uint8_t unpack_tdd_channel_measurement_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_tdd_channel_measurement_t *value = (nfapi_tdd_channel_measurement_t *)tlv;
+
+  if(!(pull8(ppReadPackedMsg, &value->num_prb_per_subband, end) &&
+       pull8(ppReadPackedMsg, &value->number_of_subbands, end) &&
+       pull8(ppReadPackedMsg, &value->num_atennas, end)))
+    return 0;
+
+  if(value->number_of_subbands > NFAPI_MAX_NUM_SUBBANDS) {
+    // todo : add error
+    return 0;
+  }
+
+  if(value->num_atennas > NFAPI_MAX_NUM_PHYSICAL_ANTENNAS) {
+    // todo : add error
+    return 0;
+  }
+
+  uint8_t idx = 0;
+
+  for(idx = 0; idx < value->number_of_subbands; ++idx) {
+    if(!(pull8(ppReadPackedMsg, &value->subands[idx].subband_index, end) &&
+         pullarray16(ppReadPackedMsg, value->subands[idx].channel, NFAPI_MAX_NUM_PHYSICAL_ANTENNAS, value->num_atennas, end)))
+      return 0;
+  }
+
+  return 1;
+}
+
+
+static uint8_t unpack_srs_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_srs_indication_body_t *value = (nfapi_srs_indication_body_t *)tlv;
+  uint8_t *srsBodyEnd = *ppReadPackedMsg + value->tl.length;
+
+  if(srsBodyEnd > end)
+    return 0;
+
+  if(pull8(ppReadPackedMsg, &value->number_of_ues, end) == 0)
+    return 0;
+
+  if(value->number_of_ues > NFAPI_SRS_IND_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of srs ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_ues, NFAPI_SRS_IND_MAX_PDU);
+    return 0;
+  }
+
+  if(value->number_of_ues > 0) {
+    value->srs_pdu_list = (nfapi_srs_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_srs_indication_pdu_t) * value->number_of_ues, config);
+
+    if(value->srs_pdu_list == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate srs ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_ues);
+      return 0;
+    }
+  } else {
+    value->srs_pdu_list = 0;
+  }
+
+  uint8_t i = 0;
+
+  for(i = 0; i < value->number_of_ues; ++i) {
+    nfapi_srs_indication_pdu_t *pdu = &(value->srs_pdu_list[i]);
+
+    if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
+      return 0;
+
+    uint8_t *srsPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
+    unpack_tlv_t unpack_fns[] = {
+      { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value },
+      { NFAPI_SRS_INDICATION_FDD_REL8_TAG, &pdu->srs_indication_fdd_rel8, unpack_srs_indication_fdd_rel8_value},
+      { NFAPI_SRS_INDICATION_FDD_REL9_TAG, &pdu->srs_indication_fdd_rel9, unpack_srs_indication_fdd_rel9_value},
+      { NFAPI_SRS_INDICATION_TDD_REL10_TAG, &pdu->srs_indication_tdd_rel10, unpack_srs_indication_tdd_rel10_value},
+      { NFAPI_SRS_INDICATION_FDD_REL11_TAG, &pdu->srs_indication_fdd_rel11, unpack_srs_indication_fdd_rel11_value},
+      { NFAPI_TDD_CHANNEL_MEASUREMENT_TAG, &pdu->tdd_channel_measurement, unpack_tdd_channel_measurement_value},
+    };
+
+    if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, srsPduInstanceEnd, 0, 0) == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_srs_indication_t *pNfapiMsg = (nfapi_srs_indication_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_SRS_INDICATION_BODY_TAG, &pNfapiMsg->srs_indication_body, &unpack_srs_indication_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+
+static uint8_t unpack_sr_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_sr_indication_body_t *value = (nfapi_sr_indication_body_t *)tlv;
+  uint8_t *srBodyEnd = *ppReadPackedMsg + value->tl.length;
+
+  if(srBodyEnd > end)
+    return 0;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_srs, end) == 0)
+    return 0;
+
+  if(value->number_of_srs > NFAPI_SR_IND_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of sr ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_srs, NFAPI_SR_IND_MAX_PDU);
+    return 0;
+  }
+
+  if(value->number_of_srs > 0) {
+    value->sr_pdu_list = (nfapi_sr_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_sr_indication_pdu_t) * value->number_of_srs, config);
+
+    if(value->sr_pdu_list == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate sr ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_srs);
+      return 0;
+    }
+  } else {
+    value->sr_pdu_list = 0;
+  }
+
+  uint8_t i = 0;
+
+  for(i = 0; i < value->number_of_srs; ++i) {
+    nfapi_sr_indication_pdu_t *pdu = &(value->sr_pdu_list[i]);
+
+    if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
+      return 0;
+
+    uint8_t *srPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
+    unpack_tlv_t unpack_fns[] = {
+      { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value },
+      { NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, unpack_ul_cqi_information_value },
+    };
+
+    if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, srPduInstanceEnd, 0, 0) == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+static int unpack_sr_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_sr_indication_t *pNfapiMsg = (nfapi_sr_indication_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_SR_INDICATION_BODY_TAG, &pNfapiMsg->sr_indication_body, &unpack_sr_indication_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+static uint8_t unpack_cqi_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_cqi_indication_rel8_t *cqi_pdu_rel8 = (nfapi_cqi_indication_rel8_t *)tlv;
+  return (pull16(ppReadPackedMsg, &cqi_pdu_rel8->length, end) &&
+          pull16(ppReadPackedMsg, &cqi_pdu_rel8->data_offset, end) &&
+          pull8(ppReadPackedMsg, &cqi_pdu_rel8->ul_cqi, end) &&
+          pull8(ppReadPackedMsg, &cqi_pdu_rel8->ri, end) &&
+          pull16(ppReadPackedMsg, &cqi_pdu_rel8->timing_advance, end));
+}
+
+static uint8_t unpack_cqi_indication_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_cqi_indication_rel9_t *cqi_pdu_rel9 = (nfapi_cqi_indication_rel9_t *)tlv;
+
+  if(!(pull16(ppReadPackedMsg, &cqi_pdu_rel9->length, end) &&
+       pull16(ppReadPackedMsg, &cqi_pdu_rel9->data_offset, end) &&
+       pull8(ppReadPackedMsg, &cqi_pdu_rel9->ul_cqi, end) &&
+       pull8(ppReadPackedMsg, &cqi_pdu_rel9->number_of_cc_reported, end)))
+    return 0;
+
+  if(cqi_pdu_rel9->number_of_cc_reported > NFAPI_CC_MAX) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : out of bound array\n");
+    return 0;
+  }
+
+  if(!(pullarray8(ppReadPackedMsg, cqi_pdu_rel9->ri, NFAPI_CC_MAX, cqi_pdu_rel9->number_of_cc_reported, end) &&
+       pull16(ppReadPackedMsg, &cqi_pdu_rel9->timing_advance, end) &&
+       pull16(ppReadPackedMsg, &cqi_pdu_rel9->timing_advance_r9, end)))
+    return 0;
+
+  return 1;
+}
+
+static uint8_t  unpack_cqi_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end,  nfapi_p7_codec_config_t *config) {
+  nfapi_cqi_indication_body_t *value = (nfapi_cqi_indication_body_t *)tlv;
+  // the cqiBodyEnd points to the end of the cqi PDU's
+  uint8_t *cqiBodyEnd = *ppReadPackedMsg + value->tl.length;
+
+  //uint8_t* cqiPduEnd = cqiBodyEnd;
+  //uint8_t* numberOfPdusAddress = *ppReadPackedMsg;
+
+  if(cqiBodyEnd > end)
+    return 0;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_cqis, end) == 0)
+    return 0;
+
+  if(value->number_of_cqis > NFAPI_CQI_IND_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of cqi ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_cqis, NFAPI_CQI_IND_MAX_PDU);
+    return -1;
+  }
+
+  if(value->number_of_cqis > 0) {
+    value->cqi_pdu_list = (nfapi_cqi_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_cqi_indication_pdu_t) * value->number_of_cqis, config);
+
+    if(value->cqi_pdu_list == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate cqi ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_cqis);
+      return 0;
+    }
+  } else {
+    value->cqi_pdu_list = 0;
+  }
+
+  if(value->number_of_cqis > 0) {
+    value->cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_cqi_indication_raw_pdu_t) * value->number_of_cqis, config);
+
+    if(value->cqi_raw_pdu_list == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate raw cqi ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_cqis);
+      return 0;
+    }
+  } else {
+    value->cqi_raw_pdu_list = 0;
+  }
+
+  uint8_t i = 0;
+
+  for(i = 0; i < value->number_of_cqis; ++i) {
+    nfapi_cqi_indication_pdu_t *pdu = &(value->cqi_pdu_list[i]);
+    memset(pdu, 0, sizeof(nfapi_cqi_indication_pdu_t));
+
+    if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
+      return 0;
+
+    uint8_t *cqiPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
+
+    while((uint8_t *)(*ppReadPackedMsg) < cqiPduInstanceEnd) {
+      nfapi_tl_t generic_tl;
+
+      if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
+        return 0;
+
+      switch(generic_tl.tag) {
+        case NFAPI_RX_UE_INFORMATION_TAG:
+          pdu->rx_ue_information.tl = generic_tl;
+
+          if(unpack_rx_ue_information_value(&pdu->rx_ue_information, ppReadPackedMsg, end) == 0)
+            return 0;
+
+          break;
+
+        case NFAPI_CQI_INDICATION_REL8_TAG:
+          pdu->cqi_indication_rel8.tl = generic_tl;
+
+          if(unpack_cqi_indication_rel8_value(&pdu->cqi_indication_rel8, ppReadPackedMsg, end) == 0)
+            return 0;
+
+          break;
+
+        case NFAPI_CQI_INDICATION_REL9_TAG:
+          pdu->cqi_indication_rel9.tl = generic_tl;
+
+          if(unpack_cqi_indication_rel9_value(&pdu->cqi_indication_rel9, ppReadPackedMsg, end) == 0)
+            return 0;
+
+          break;
+
+        case NFAPI_UL_CQI_INFORMATION_TAG:
+          pdu->ul_cqi_information.tl = generic_tl;
+
+          if(unpack_ul_cqi_information_value(&pdu->ul_cqi_information, ppReadPackedMsg, end) == 0)
+            return 0;
+
+          break;
+
+        default: {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "RX_CQI.indication Invalid pdu type %d \n", generic_tl.tag );
+        }
+        break;
+      };
+    }
+  }
+
+  uint8_t idx = 0;
+
+  for(idx = 0; idx < value->number_of_cqis; ++idx) {
+    if(value->cqi_pdu_list[idx].cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) {
+      if(pullarray8(ppReadPackedMsg, &(value->cqi_raw_pdu_list[idx].pdu[0]), NFAPI_CQI_RAW_MAX_LEN, value->cqi_pdu_list[idx].cqi_indication_rel8.length, end) == 0)
+        return 0;
+    } else if(value->cqi_pdu_list[idx].cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) {
+      if(pullarray8(ppReadPackedMsg, &(value->cqi_raw_pdu_list[idx].pdu[0]), NFAPI_CQI_RAW_MAX_LEN, value->cqi_pdu_list[idx].cqi_indication_rel9.length, end) == 0)
+        return 0;
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_cqi_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_cqi_indication_t *pNfapiMsg = (nfapi_cqi_indication_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_CQI_INDICATION_BODY_TAG, &pNfapiMsg->cqi_indication_body, &unpack_cqi_indication_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+static uint8_t unpack_lbt_pdsch_req_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_lbt_pdsch_req_pdu_rel13_t *value = (nfapi_lbt_pdsch_req_pdu_rel13_t *)tlv;
+  return (pull32(ppReadPackedMsg, &value->handle, end) &&
+          pull32(ppReadPackedMsg, &value->mp_cca, end) &&
+          pull32(ppReadPackedMsg, &value->n_cca, end) &&
+          pull32(ppReadPackedMsg, &value->offset, end) &&
+          pull32(ppReadPackedMsg, &value->lte_txop_sf, end) &&
+          pull16(ppReadPackedMsg, &value->txop_sfn_sf_end, end) &&
+          pull32(ppReadPackedMsg, &value->lbt_mode, end));
+}
+
+static uint8_t unpack_lbt_drs_req_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_lbt_drs_req_pdu_rel13_t *value = (nfapi_lbt_drs_req_pdu_rel13_t *)tlv;
+  return (pull32(ppReadPackedMsg, &value->handle, end) &&
+          pull32(ppReadPackedMsg, &value->offset, end) &&
+          pull16(ppReadPackedMsg, &value->sfn_sf_end, end) &&
+          pull32(ppReadPackedMsg, &value->lbt_mode, end));
+}
+
+
+static uint8_t unpack_lbt_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_lbt_dl_config_request_body_t *value = (nfapi_lbt_dl_config_request_body_t *)tlv;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0)
+    return 0;
+
+  if(value->number_of_pdus > NFAPI_LBT_DL_CONFIG_REQ_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of lbt dl config pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_LBT_DL_CONFIG_REQ_MAX_PDU);
+    return 0;
+  }
+
+  if(value->number_of_pdus) {
+    value->lbt_dl_config_req_pdu_list = (nfapi_lbt_dl_config_request_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_lbt_dl_config_request_pdu_t) * value->number_of_pdus, config);
+
+    if(value->lbt_dl_config_req_pdu_list == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate lbt dl config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus);
+      return 0;
+    }
+  } else {
+    value->lbt_dl_config_req_pdu_list = 0;
+  }
+
+  uint16_t i;
+  uint16_t total_number_of_pdus = value->number_of_pdus;
+
+  for(i = 0; i < total_number_of_pdus; ++i) {
+    nfapi_lbt_dl_config_request_pdu_t *pdu = &(value->lbt_dl_config_req_pdu_list[i]);
+
+    if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) &&
+         pull8(ppReadPackedMsg, &pdu->pdu_size, end)))
+      return 0;
+
+    uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2;
+
+    if(packedPduEnd > end)
+      return 0;
+
+    switch(pdu->pdu_type) {
+      case NFAPI_LBT_DL_CONFIG_REQUEST_PDSCH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_LBT_PDSCH_REQ_PDU_REL13_TAG, &pdu->lbt_pdsch_req_pdu.lbt_pdsch_req_pdu_rel13, &unpack_lbt_pdsch_req_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_LBT_DL_CONFIG_REQUEST_DRS_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_LBT_DRS_REQ_PDU_REL13_TAG, &pdu->lbt_drs_req_pdu.lbt_drs_req_pdu_rel13, &unpack_lbt_drs_req_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      default:
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL_CONFIG.request body invalid pdu type %d\n", pdu->pdu_type);
+        return 0;
+    }
+  }
+
+  return 1;
+}
+static uint8_t unpack_lbt_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_lbt_dl_config_request_t *pNfapiMsg = (nfapi_lbt_dl_config_request_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_LBT_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->lbt_dl_config_request_body, &unpack_lbt_config_request_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_lbt_pdsch_rsp_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_lbt_pdsch_rsp_pdu_rel13_t *value = (nfapi_lbt_pdsch_rsp_pdu_rel13_t *)tlv;
+  return (pull32(ppReadPackedMsg, &value->handle, end) &&
+          pull32(ppReadPackedMsg, &value->result, end) &&
+          pull32(ppReadPackedMsg, &value->lte_txop_symbols, end) &&
+          pull32(ppReadPackedMsg, &value->initial_partial_sf, end));
+}
+static uint8_t unpack_lbt_drs_rsp_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_lbt_drs_rsp_pdu_rel13_t *value = (nfapi_lbt_drs_rsp_pdu_rel13_t *)tlv;
+  return (pull32(ppReadPackedMsg, &value->handle, end) &&
+          pull32(ppReadPackedMsg, &value->result, end));
+}
+
+static uint8_t unpack_lbt_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_lbt_dl_indication_body_t *value = (nfapi_lbt_dl_indication_body_t *)tlv;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0)
+    return 0;
+
+  if(value->number_of_pdus > NFAPI_LBT_IND_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of lbt dl ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_LBT_IND_MAX_PDU);
+    return 0;
+  }
+
+  if(value->number_of_pdus > 0) {
+    value->lbt_indication_pdu_list = (nfapi_lbt_dl_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_lbt_dl_indication_pdu_t) * value->number_of_pdus, config);
+
+    if(value->lbt_indication_pdu_list == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate lbt dl ind config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus);
+      return 0;
+    }
+  } else {
+    value->lbt_indication_pdu_list = 0;
+  }
+
+  uint16_t i;
+  uint16_t total_number_of_pdus = value->number_of_pdus;
+
+  for(i = 0; i < total_number_of_pdus; ++i) {
+    nfapi_lbt_dl_indication_pdu_t *pdu = &(value->lbt_indication_pdu_list[i]);
+
+    if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) &&
+         pull8(ppReadPackedMsg, &pdu->pdu_size, end)))
+      return 0;
+
+    uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2;
+
+    if(packedPduEnd > end)
+      return 0;
+
+    switch(pdu->pdu_type) {
+      case NFAPI_LBT_DL_RSP_PDSCH_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_LBT_PDSCH_RSP_PDU_REL13_TAG, &pdu->lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13, &unpack_lbt_pdsch_rsp_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      case NFAPI_LBT_DL_RSP_DRS_PDU_TYPE: {
+        unpack_tlv_t unpack_fns[] = {
+          { NFAPI_LBT_DRS_RSP_PDU_REL13_TAG, &pdu->lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13, &unpack_lbt_drs_rsp_pdu_rel13_value},
+        };
+        unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0);
+      }
+      break;
+
+      default:
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL.indication body invalid pdu type %d\n", pdu->pdu_type);
+        return 0;
+    }
+  }
+
+  return 1;
+}
+static uint8_t unpack_lbt_dl_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_lbt_dl_indication_t *pNfapiMsg = (nfapi_lbt_dl_indication_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_LBT_DL_INDICATION_BODY_TAG, &pNfapiMsg->lbt_dl_indication_body, &unpack_lbt_indication_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_nb_harq_indication_fdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nb_harq_indication_fdd_rel13_t *value = (nfapi_nb_harq_indication_fdd_rel13_t *)tlv;
+  return (pull8(ppReadPackedMsg, &value->harq_tb1, end));
+}
+
+
+static uint8_t unpack_nb_harq_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_nb_harq_indication_body_t *value = (nfapi_nb_harq_indication_body_t *)tlv;
+  uint8_t *nbharqBodyEnd = *ppReadPackedMsg + value->tl.length;
+
+  if(nbharqBodyEnd > end)
+    return 0;
+
+  if(pull16(ppReadPackedMsg, &value->number_of_harqs, end) == 0)
+    return 0;
+
+  if(value->number_of_harqs > NFAPI_HARQ_IND_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of harq ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_harqs, NFAPI_HARQ_IND_MAX_PDU);
+    return 0;
+  }
+
+  value->nb_harq_pdu_list = (nfapi_nb_harq_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_nb_harq_indication_pdu_t) * value->number_of_harqs, config);
+
+  if(value->nb_harq_pdu_list == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_harqs);
+    return 0;
+  }
+
+  uint8_t i = 0;
+
+  for(i = 0; i < value->number_of_harqs; ++i) {
+    nfapi_nb_harq_indication_pdu_t *pdu = &(value->nb_harq_pdu_list[i]);
+
+    if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0)
+      return 0;
+
+    uint8_t *harqPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length;
+    unpack_tlv_t unpack_fns[] = {
+      { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value },
+      { NFAPI_NB_HARQ_INDICATION_FDD_REL13_TAG, &pdu->nb_harq_indication_fdd_rel13, &unpack_nb_harq_indication_fdd_rel13_value},
+      { NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, &unpack_ul_cqi_information_value}
+    };
+
+    if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, harqPduInstanceEnd, 0, 0) == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nb_harq_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_nb_harq_indication_t *pNfapiMsg = (nfapi_nb_harq_indication_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_NB_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->nb_harq_indication_body, &unpack_nb_harq_indication_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_nrach_indication_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+  nfapi_nrach_indication_pdu_rel13_t *value = (nfapi_nrach_indication_pdu_rel13_t *)tlv;
+  return (pull16(ppReadPackedMsg, &value->rnti, end) &&
+          pull8(ppReadPackedMsg, &value->initial_sc, end) &&
+          pull16(ppReadPackedMsg, &value->timing_advance, end) &&
+          pull8(ppReadPackedMsg, &value->nrach_ce_level, end));
+}
+
+static uint8_t unpack_ue_release_resp(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t *)msg;
+
+  if(pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) == 0) {
+    return 0;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "ue_release_response:error_code = %d\n", pNfapiMsg->error_code);
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nrach_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+  nfapi_nrach_indication_body_t *value = (nfapi_nrach_indication_body_t *)tlv;
+  uint8_t *nrachBodyEnd = *ppReadPackedMsg + value->tl.length;
+
+  if(nrachBodyEnd > end)
+    return 0;
+
+  if(pull8(ppReadPackedMsg, &value->number_of_initial_scs_detected, end) == 0)
+    return 0;
+
+  if(value->number_of_initial_scs_detected > NFAPI_PREAMBLE_MAX_PDU) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of detected scs ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_initial_scs_detected, NFAPI_PREAMBLE_MAX_PDU);
+    return 0;
+  }
+
+  value->nrach_pdu_list = (nfapi_nrach_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_nrach_indication_pdu_t) * value->number_of_initial_scs_detected, config);
+
+  if(value->nrach_pdu_list == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate nrach ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_initial_scs_detected);
+    return 0;
+  }
+
+  uint8_t i = 0;
+
+  for(i = 0; i < value->number_of_initial_scs_detected; ++i) {
+    nfapi_nrach_indication_pdu_t *pdu = &(value->nrach_pdu_list[i]);
+    uint8_t *nrachPduInstanceEnd = *ppReadPackedMsg + 4 + 6;
+    unpack_tlv_t unpack_fns[] = {
+      { NFAPI_NRACH_INDICATION_REL13_TAG, &pdu->nrach_indication_rel13, &unpack_nrach_indication_rel13_value},
+    };
+
+    if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, nrachPduInstanceEnd, 0, 0) == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nrach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_nrach_indication_t *pNfapiMsg = (nfapi_nrach_indication_t *)msg;
+  unpack_p7_tlv_t unpack_fns[] = {
+    { NFAPI_NRACH_INDICATION_BODY_TAG, &pNfapiMsg->nrach_indication_body, &unpack_nrach_indication_body_value},
+  };
+  return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
+          unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_nr_dl_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_dl_node_sync_t *pNfapiMsg = (nfapi_nr_dl_node_sync_t *)msg;
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->delta_sfn_slot, end) &&
+          unpack_p7_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_dl_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_dl_node_sync_t *pNfapiMsg = (nfapi_dl_node_sync_t *)msg;
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->delta_sfn_sf, end) &&
+          unpack_p7_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+
+static uint8_t unpack_nr_ul_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_ul_node_sync_t *pNfapiMsg = (nfapi_nr_ul_node_sync_t *)msg;
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->t2, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->t3, end) &&
+          unpack_p7_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+
+static uint8_t unpack_ul_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_ul_node_sync_t *pNfapiMsg = (nfapi_ul_node_sync_t *)msg;
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->t2, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->t3, end) &&
+          unpack_p7_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+static uint8_t unpack_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_timing_info_t *pNfapiMsg = (nfapi_timing_info_t *)msg;
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->last_sfn_sf, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->time_since_last_timing_info, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->dl_config_jitter, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->tx_request_jitter, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->ul_config_jitter, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_jitter, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->dl_config_latest_delay, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->tx_request_latest_delay, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->ul_config_latest_delay, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_latest_delay, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->dl_config_earliest_arrival, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->tx_request_earliest_arrival, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->ul_config_earliest_arrival, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_earliest_arrival, end) &&
+          unpack_p7_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+
+static uint8_t unpack_nr_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+  nfapi_nr_timing_info_t *pNfapiMsg = (nfapi_nr_timing_info_t *)msg;
+  return (pull32(ppReadPackedMsg, &pNfapiMsg->last_sfn, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->last_slot, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->time_since_last_timing_info, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->dl_tti_jitter, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->tx_data_request_jitter, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->ul_tti_jitter, end) &&
+          pull32(ppReadPackedMsg, &pNfapiMsg->ul_dci_jitter, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->dl_tti_latest_delay, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->tx_data_request_latest_delay, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->ul_tti_latest_delay, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->ul_dci_latest_delay, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->dl_tti_earliest_arrival, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->tx_data_request_earliest_arrival, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->ul_tti_earliest_arrival, end) &&
+          pulls32(ppReadPackedMsg, &pNfapiMsg->ul_dci_earliest_arrival, end) &&
+          unpack_p7_tlv_list(NULL, 0, ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+
+
+// unpack length check
+
+static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen) {
+  int retLen = 0;
+
+  switch (msgId) {
+    case NFAPI_DL_CONFIG_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_dl_config_request_t))
+        retLen = sizeof(nfapi_dl_config_request_t);
+
+      break;
+
+    case NFAPI_UL_CONFIG_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_ul_config_request_t))
+        retLen = sizeof(nfapi_ul_config_request_t);
+
+      break;
+
+    case NFAPI_SUBFRAME_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_subframe_indication_t))
+        retLen = sizeof(nfapi_subframe_indication_t);
+
+      break;
+
+    case NFAPI_HI_DCI0_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_hi_dci0_request_t))
+        retLen = sizeof(nfapi_hi_dci0_request_t);
+
+      break;
+
+    case NFAPI_TX_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_tx_request_t))
+        retLen = sizeof(nfapi_tx_request_t);
+
+      break;
+
+    case NFAPI_HARQ_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_harq_indication_t))
+        retLen = sizeof(nfapi_harq_indication_t);
+
+      break;
+
+    case NFAPI_CRC_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_crc_indication_t))
+        retLen = sizeof(nfapi_crc_indication_t);
+
+      break;
+
+    case NFAPI_RX_ULSCH_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_rx_indication_t))
+        retLen = sizeof(nfapi_rx_indication_t);
+
+      break;
+
+    case NFAPI_RACH_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_rach_indication_t))
+        retLen = sizeof(nfapi_rach_indication_t);
+
+      break;
+
+    case NFAPI_SRS_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_srs_indication_t))
+        retLen = sizeof(nfapi_srs_indication_t);
+
+      break;
+
+    case NFAPI_RX_SR_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_sr_indication_t))
+        retLen = sizeof(nfapi_sr_indication_t);
+
+      break;
+
+    case NFAPI_RX_CQI_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_cqi_indication_t))
+        retLen = sizeof(nfapi_cqi_indication_t);
+
+      break;
+
+    case NFAPI_LBT_DL_CONFIG_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_lbt_dl_config_request_t))
+        retLen = sizeof(nfapi_lbt_dl_config_request_t);
+
+      break;
+
+    case NFAPI_LBT_DL_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_lbt_dl_indication_t))
+        retLen = sizeof(nfapi_lbt_dl_indication_t);
+
+      break;
+
+    case NFAPI_NB_HARQ_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_nb_harq_indication_t))
+        retLen = sizeof(nfapi_nb_harq_indication_t);
+
+      break;
+
+    case NFAPI_NRACH_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_nrach_indication_t))
+        retLen = sizeof(nfapi_nrach_indication_t);
+
+      break;
+
+    case NFAPI_DL_NODE_SYNC:
+      if (unpackedBufLen >= sizeof(nfapi_dl_node_sync_t))
+        retLen = sizeof(nfapi_dl_node_sync_t);
+
+      break;
+
+    case NFAPI_UL_NODE_SYNC:
+      if (unpackedBufLen >= sizeof(nfapi_ul_node_sync_t))
+        retLen = sizeof(nfapi_ul_node_sync_t);
+
+      break;
+
+    case NFAPI_TIMING_INFO:
+      if (unpackedBufLen >= sizeof(nfapi_timing_info_t))
+        retLen = sizeof(nfapi_timing_info_t);
+
+      break;
+
+    case NFAPI_UE_RELEASE_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_ue_release_request_t))
+        retLen = sizeof(nfapi_ue_release_request_t);
+
+      break;
+
+    case NFAPI_UE_RELEASE_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_ue_release_response_t))
+        retLen = sizeof(nfapi_ue_release_response_t);
+
+      break;
+
+    default:
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId);
+      break;
+  }
+
+  return retLen;
+}
+
+static int check_nr_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen) {
+  int retLen = 0;
+
+  switch (msgId) {
+    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_dl_tti_request_t))
+        retLen = sizeof(nfapi_nr_dl_tti_request_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_ul_tti_request_t))
+        retLen = sizeof(nfapi_nr_ul_tti_request_t);
+
+      break;
+
+    case NFAPI_SUBFRAME_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_subframe_indication_t))
+        retLen = sizeof(nfapi_subframe_indication_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_ul_dci_request_t))
+        retLen = sizeof(nfapi_nr_ul_dci_request_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_tx_data_request_t))
+        retLen = sizeof(nfapi_nr_tx_data_request_t);
+
+      break;
+
+    case NFAPI_HARQ_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_harq_indication_t))
+        retLen = sizeof(nfapi_harq_indication_t);
+
+      break;
+
+    case NFAPI_CRC_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_crc_indication_t))
+        retLen = sizeof(nfapi_crc_indication_t);
+
+      break;
+
+    case NFAPI_RX_ULSCH_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_rx_indication_t))
+        retLen = sizeof(nfapi_rx_indication_t);
+
+      break;
+
+    case NFAPI_RACH_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_rach_indication_t))
+        retLen = sizeof(nfapi_rach_indication_t);
+
+      break;
+
+    case NFAPI_SRS_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_srs_indication_t))
+        retLen = sizeof(nfapi_srs_indication_t);
+
+      break;
+
+    case NFAPI_RX_SR_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_sr_indication_t))
+        retLen = sizeof(nfapi_sr_indication_t);
+
+      break;
+
+    case NFAPI_RX_CQI_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_cqi_indication_t))
+        retLen = sizeof(nfapi_cqi_indication_t);
+
+      break;
+
+    case NFAPI_LBT_DL_CONFIG_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_lbt_dl_config_request_t))
+        retLen = sizeof(nfapi_lbt_dl_config_request_t);
+
+      break;
+
+    case NFAPI_LBT_DL_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_lbt_dl_indication_t))
+        retLen = sizeof(nfapi_lbt_dl_indication_t);
+
+      break;
+
+    case NFAPI_NB_HARQ_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_nb_harq_indication_t))
+        retLen = sizeof(nfapi_nb_harq_indication_t);
+
+      break;
+
+    case NFAPI_NRACH_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_nrach_indication_t))
+        retLen = sizeof(nfapi_nrach_indication_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
+      if (unpackedBufLen >= sizeof(nfapi_nr_dl_node_sync_t))
+        retLen = sizeof(nfapi_nr_dl_node_sync_t);
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
+      if (unpackedBufLen >= sizeof(nfapi_nr_ul_node_sync_t))
+        retLen = sizeof(nfapi_nr_ul_node_sync_t);
+
+      break;
+
+    case NFAPI_TIMING_INFO:
+      if (unpackedBufLen >= sizeof(nfapi_timing_info_t))
+        retLen = sizeof(nfapi_timing_info_t);
+
+      break;
+
+    case NFAPI_UE_RELEASE_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_ue_release_request_t))
+        retLen = sizeof(nfapi_ue_release_request_t);
+
+      break;
+
+    case NFAPI_UE_RELEASE_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_ue_release_response_t))
+        retLen = sizeof(nfapi_ue_release_response_t);
+
+      break;
+
+    default:
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId);
+      break;
+  }
+
+  return retLen;
+}
+
+
+
+// Main unpack functions - public
+
+int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t *config) {
+  nfapi_p7_message_header_t *pMessageHeader = pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+  uint8_t *end = pMessageBuf + messageBufLen;
+
+  if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied pointers are null\n");
+    return -1;
+  }
+
+  if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+    return -1;
+  }
+
+  // process the header
+  if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
+       pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
+       pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
+       pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) &&
+       pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) &&
+       pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end)))
+    return -1;
+
+  return 0;
+}
+
+int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t *config) {
+  int result = 0;
+  nfapi_p7_message_header_t *pMessageHeader = (nfapi_p7_message_header_t *)pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+  uint8_t *end = pMessageBuf + messageBufLen;
+
+  if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n");
+    return -1;
+  }
+
+  if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+    return -1;
+  }
+
+  /*
+    uint8_t *ptr = pMessageBuf;
+  printf("\n Read P7 message unpack: ");
+  while(ptr < end){
+    printf(" %d ", *ptr);
+    ptr++;
+  }
+  printf("\n");
+  */
+  // clean the supplied buffer for - tag value blanking
+  (void)memset(pUnpackedBuf, 0, unpackedBufLen);
+
+  // process the header
+  if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
+       pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
+       pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
+       pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) &&
+       pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) &&
+       pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n");
+    return -1;
+  }
+
+  if((uint8_t *)(pMessageBuf + pMessageHeader->message_length) > end) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
+    return -1;
+  }
+
+  /*
+  if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0)
+  {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack unpack buffer is not large enough \n");
+    return -1;
+  }
+  */
+
+  // look for the specific message
+  switch (pMessageHeader->message_id) {
+    case NFAPI_DL_CONFIG_REQUEST:
+      if (check_unpack_length(NFAPI_DL_CONFIG_REQUEST, unpackedBufLen))
+        result = unpack_dl_config_request(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_UL_CONFIG_REQUEST:
+      if (check_unpack_length(NFAPI_UL_CONFIG_REQUEST, unpackedBufLen))
+        result = unpack_ul_config_request(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_TX_REQUEST:
+      if (check_unpack_length(NFAPI_TX_REQUEST, unpackedBufLen))
+        result = unpack_tx_request(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_HI_DCI0_REQUEST:
+      if (check_unpack_length(NFAPI_HI_DCI0_REQUEST, unpackedBufLen))
+        result = unpack_hi_dci0_request(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_UE_RELEASE_REQUEST:
+      if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen))
+        result = unpack_ue_release_request(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_HARQ_INDICATION:
+      if (check_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen))
+        result = unpack_harq_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_CRC_INDICATION:
+      if (check_unpack_length(NFAPI_CRC_INDICATION, unpackedBufLen))
+        result = unpack_crc_indication(&pReadPackedMessage,end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_RX_ULSCH_INDICATION:
+      if (check_unpack_length(NFAPI_RX_ULSCH_INDICATION, unpackedBufLen))
+        result = unpack_rx_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_RACH_INDICATION:
+      if (check_unpack_length(NFAPI_RACH_INDICATION, unpackedBufLen))
+        result = unpack_rach_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_SRS_INDICATION:
+      if (check_unpack_length(NFAPI_SRS_INDICATION, unpackedBufLen))
+        result = unpack_srs_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_RX_SR_INDICATION:
+      if (check_unpack_length(NFAPI_RX_SR_INDICATION, unpackedBufLen))
+        result = unpack_sr_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_RX_CQI_INDICATION:
+      if (check_unpack_length(NFAPI_RX_CQI_INDICATION, unpackedBufLen))
+        result = unpack_cqi_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_LBT_DL_CONFIG_REQUEST:
+      if (check_unpack_length(NFAPI_LBT_DL_CONFIG_REQUEST, unpackedBufLen))
+        result = unpack_lbt_dl_config_request(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_LBT_DL_INDICATION:
+      if (check_unpack_length(NFAPI_LBT_DL_INDICATION, unpackedBufLen))
+        result = unpack_lbt_dl_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_NB_HARQ_INDICATION:
+      if (check_unpack_length(NFAPI_NB_HARQ_INDICATION, unpackedBufLen))
+        result = unpack_nb_harq_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_NRACH_INDICATION:
+      if (check_unpack_length(NFAPI_NRACH_INDICATION, unpackedBufLen))
+        result = unpack_nrach_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_DL_NODE_SYNC:
+      if (check_unpack_length(NFAPI_DL_NODE_SYNC, unpackedBufLen))
+        result = unpack_dl_node_sync(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_UL_NODE_SYNC:
+      if (check_unpack_length(NFAPI_UL_NODE_SYNC, unpackedBufLen))
+        result = unpack_ul_node_sync(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_TIMING_INFO:
+      if (check_unpack_length(NFAPI_TIMING_INFO, unpackedBufLen))
+        result = unpack_timing_info(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_UE_RELEASE_RESPONSE:
+      if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen))
+        result = unpack_ue_release_resp(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    default:
+      if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+          pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if(config && config->unpack_p7_vendor_extension) {
+          result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+      }
+
+      break;
+  }
+
+  if(result == 0)
+    return -1;
+  else
+    return 0;
+}
+
+int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t *config) {
+  int result = 0;
+  nfapi_p7_message_header_t *pMessageHeader = (nfapi_p7_message_header_t *)pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+  uint8_t *end = pMessageBuf + messageBufLen;
+
+  if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n");
+    return -1;
+  }
+
+  if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+    return -1;
+  }
+
+  /*
+    uint8_t *ptr = pMessageBuf;
+  printf("\n Read P7 message unpack: ");
+  while(ptr < end){
+    printf(" %d ", *ptr);
+    ptr++;
+  }
+  printf("\n");
+  */
+  // clean the supplied buffer for - tag value blanking
+  (void)memset(pUnpackedBuf, 0, unpackedBufLen);
+
+  // process the header
+  if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
+       pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
+       pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
+       pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) &&
+       pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) &&
+       pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n");
+    return -1;
+  }
+
+  if((uint8_t *)(pMessageBuf + pMessageHeader->message_length) > end) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
+    return -1;
+  }
+
+  /*
+  if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0)
+  {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack unpack buffer is not large enough \n");
+    return -1;
+  }
+  */
+
+  // look for the specific message
+  switch (pMessageHeader->message_id) {
+    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+      if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST, unpackedBufLen))
+        result = unpack_dl_tti_request(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+      if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST, unpackedBufLen))
+        result = unpack_ul_tti_request(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+      if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST, unpackedBufLen))
+        result = unpack_tx_data_request(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+      if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST, unpackedBufLen))
+        result = unpack_ul_dci_request(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_UE_RELEASE_REQUEST:
+      if (check_nr_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen))
+        result = unpack_ue_release_request(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_HARQ_INDICATION:
+      if (check_nr_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen))
+        result = unpack_harq_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_CRC_INDICATION:
+      if (check_nr_unpack_length(NFAPI_CRC_INDICATION, unpackedBufLen))
+        result = unpack_crc_indication(&pReadPackedMessage,end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_RX_ULSCH_INDICATION:
+      if (check_nr_unpack_length(NFAPI_RX_ULSCH_INDICATION, unpackedBufLen))
+        result = unpack_rx_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_RACH_INDICATION:
+      if (check_nr_unpack_length(NFAPI_RACH_INDICATION, unpackedBufLen))
+        result = unpack_rach_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_SRS_INDICATION:
+      if (check_nr_unpack_length(NFAPI_SRS_INDICATION, unpackedBufLen))
+        result = unpack_srs_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_RX_SR_INDICATION:
+      if (check_nr_unpack_length(NFAPI_RX_SR_INDICATION, unpackedBufLen))
+        result = unpack_sr_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_RX_CQI_INDICATION:
+      if (check_nr_unpack_length(NFAPI_RX_CQI_INDICATION, unpackedBufLen))
+        result = unpack_cqi_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_LBT_DL_CONFIG_REQUEST:
+      if (check_nr_unpack_length(NFAPI_LBT_DL_CONFIG_REQUEST, unpackedBufLen))
+        result = unpack_lbt_dl_config_request(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_LBT_DL_INDICATION:
+      if (check_nr_unpack_length(NFAPI_LBT_DL_INDICATION, unpackedBufLen))
+        result = unpack_lbt_dl_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_NB_HARQ_INDICATION:
+      if (check_nr_unpack_length(NFAPI_NB_HARQ_INDICATION, unpackedBufLen))
+        result = unpack_nb_harq_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_NRACH_INDICATION:
+      if (check_nr_unpack_length(NFAPI_NRACH_INDICATION, unpackedBufLen))
+        result = unpack_nrach_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
+      if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC, unpackedBufLen))
+        result = unpack_nr_dl_node_sync(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
+      if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC, unpackedBufLen))
+        result = unpack_nr_ul_node_sync(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_TIMING_INFO:
+      if (check_nr_unpack_length(NFAPI_TIMING_INFO, unpackedBufLen))
+        result = unpack_nr_timing_info(&pReadPackedMessage, end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    case NFAPI_UE_RELEASE_RESPONSE:
+      if (check_nr_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen))
+        result = unpack_ue_release_resp(&pReadPackedMessage,  end, pMessageHeader, config);
+      else
+        return -1;
+
+      break;
+
+    default:
+      if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+          pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if(config && config->unpack_p7_vendor_extension) {
+          result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+      }
+
+      break;
+  }
+
+  if(result == 0)
+    return -1;
+  else
+    return 0;
+}
+
+
diff --git a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
index fc9cd660774bbf497e77eb76ecfa1691c8a2f965..8520a5d1620e74ad2b6848e27742f50412862113 100644
--- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
+++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
@@ -27,7 +27,6 @@ extern "C" {
 #include <openair2/PHY_INTERFACE/IF_Module.h>
 #include "nfapi_nr_interface.h"
 #include "nfapi_nr_interface_scf.h"
-
 #include <sys/types.h>
 #include "openair1/PHY/defs_gNB.h"
 
diff --git a/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp b/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp
index 1c2f0bef8078a072d7abd9eab6de65cbe3b5568d..4fe5065ceac54c687c1fa73e159b87f3061fc549 100644
--- a/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp
+++ b/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp
@@ -278,7 +278,7 @@ void *fapi_thread_start(void *ptr) {
 
     if(instance->tick == 1000) {
       if(instance->tx_byte_count > 0) {
-        printf("[FAPI] Tx rate %d bytes/sec\n", instance->tx_byte_count);
+        printf("[FAPI] Tx rate %u bytes/sec\n", instance->tx_byte_count);
         instance->tx_byte_count = 0;
       }
 
@@ -319,7 +319,7 @@ void *fapi_thread_start(void *ptr) {
       millisec = now_ts.tv_nsec / 1e6;
 
       if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec) {
-        printf("*** missing millisec %d %d\n", last_millisec, millisec);
+        printf("*** missing millisec %u %u\n", last_millisec, millisec);
         catchup = millisec - last_millisec - 1;
       }
 
diff --git a/openair1/PHY/CODING/3gpplte_sse.c b/openair1/PHY/CODING/3gpplte_sse.c
index 2a7b789650428ff12c2418ccb3c3ce0fa3ba4d74..393b0f4a5d2ae5af14bfaf6c620bea95ac2e72ca 100644
--- a/openair1/PHY/CODING/3gpplte_sse.c
+++ b/openair1/PHY/CODING/3gpplte_sse.c
@@ -44,8 +44,6 @@
 
 //#define DEBUG_TURBO_ENCODER 1
 //#define CALLGRIND 1
-unsigned short threegpplte_interleaver_output;
-unsigned long long threegpplte_interleaver_tmp;
 
 #if defined(__x86_64__) || defined(__i386__)
 struct treillis {
@@ -375,10 +373,10 @@ char interleave_compact_byte(short *base_interleaver,unsigned char *input, unsig
   short *ptr_intl=base_interleaver;
 #if defined(__x86_64) || defined(__i386__)
 #ifndef __AVX2__
-  __m128i tmp;
+  __m128i tmp={0};
   uint16_t *systematic2_ptr=(uint16_t *) output;
 #else
-  __m256i tmp;
+  __m256i tmp={0};
   uint32_t *systematic2_ptr=(uint32_t *) output;
 #endif
 #elif defined(__arm__)
diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c
index 8c2513b702b9822f7b8930604b46ea6c7e4543c6..619a8f07b9ac7211d97f915157641e7282f155f3 100644
--- a/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c
+++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c
@@ -933,7 +933,7 @@ unsigned char phy_threegpplte_turbo_decoder16avx2(int16_t *y,
   uint32_t db;
 
 
-  __m256i tmp, zeros=_mm256_setzero_si256();
+  __m256i tmp={0}, zeros=_mm256_setzero_si256();
 
 
   int offset8_flag=0;
diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c
index 50fae438b7629e24bd1e74d11f2b1f7d721fff59..c9d2579314f32a8f3c674ebde6470e700acfe9a9 100644
--- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c
+++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c
@@ -1105,7 +1105,7 @@ uint8_t phy_threegpplte_turbo_decoder16(int16_t *y,
   uint8_t temp;
 #if defined(__x86_64__) || defined(__i386__)
   __m128i *yp128;
-  __m128i tmp, zeros=_mm_setzero_si128();
+  __m128i tmp={0}, zeros=_mm_setzero_si128();
   __m128i tmpe;
 #elif defined(__arm__)
   int16x8_t *yp128;
diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
index e1ca906b55baead972e59753fdc04816879a131a..264b25deca4520b0d7ea910c35d9b2b2da9e8cd6 100644
--- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
+++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
@@ -798,11 +798,11 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
       n is the size in bits of the coded block, with the tail */
   int n2;
   llr_t y8[3*(n+16)] __attribute__((aligned(16)));
-  llr_t systematic0[n+16] __attribute__ ((aligned(16)));
-  llr_t systematic1[n+16] __attribute__ ((aligned(16)));
-  llr_t systematic2[n+16] __attribute__ ((aligned(16)));
-  llr_t yparity1[n+16] __attribute__ ((aligned(16)));
-  llr_t yparity2[n+16] __attribute__ ((aligned(16)));
+  llr_t systematic0[n+32] __attribute__ ((aligned(16)));
+  llr_t systematic1[n+32] __attribute__ ((aligned(16)));
+  llr_t systematic2[n+32] __attribute__ ((aligned(16)));
+  llr_t yparity1[n+32] __attribute__ ((aligned(16)));
+  llr_t yparity2[n+32] __attribute__ ((aligned(16)));
   llr_t ext[n+128] __attribute__((aligned(16)));
   llr_t ext2[n+128] __attribute__((aligned(16)));
   llr_t alpha[(n+16)*8] __attribute__ ((aligned(16)));
@@ -811,7 +811,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
   llr_t m10[n+16] __attribute__ ((aligned(16)));
   //  int *pi2_p,*pi4_p,*pi5_p,*pi6_p;
   int *pi4_p,*pi5_p,*pi6_p;
-  llr_t *s,*s1,*s2,*yp1,*yp2,*yp;
+  llr_t *s1,*s2,*yp1,*yp2,*yp;
   unsigned int i,j,iind;//,pi;
   unsigned char iteration_cnt=0;
   unsigned int crc,oldcrc,crc_len;
@@ -819,7 +819,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
 #if defined(__x86_64__) || defined(__i386__)
   __m128i *yp128;
   __m128i tmp128[(n+8)>>3];
-  __m128i tmp, zeros=_mm_setzero_si128();
+  __m128i tmp={0}, zeros=_mm_setzero_si128();
 #elif defined(__arm__)
   int8x16_t *yp128;
   int8x16_t tmp128[(n+8)>>3];
@@ -927,7 +927,6 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
 
   yp128 = (int8x16_t *)y8;
 #endif
-  s = systematic0;
   s1 = systematic1;
   s2 = systematic2;
   yp1 = yparity1;
@@ -938,7 +937,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
   for (i=0; i<16 ; i++ )
     for (j=0; j<n2; j+=16) {
       int k=i+j;
-      s[k]=*yp++;
+      systematic0[k]=*yp++;
       yp1[k]=*yp++;
       yp2[k]=*yp++;
     }
@@ -948,8 +947,8 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
 
   if (n2>n) {
     /*
-    s[n]=0;s[n+1]=0;s[n+2]=0;s[n+3]=0;
-    s[n+4]=0;s[n+5]=0;s[n+6]=0;s[n+7]=0;
+    systematic0[n]=0;systematic0[n+1]=0;systematic0[n+2]=0;systematic0[n+3]=0;
+    systematic0[n+4]=0;s[n+5]=0;s[n+6]=0;s[n+7]=0;
     s1[n]=0;s1[n+1]=0;s1[n+2]=0;s1[n+3]=0;
     s1[n+4]=0;s1[n+5]=0;s1[n+6]=0;s1[n+7]=0;
     s2[n]=0;s2[n+1]=0;s2[n+2]=0;s2[n+3]=0;
@@ -961,26 +960,26 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
 
   // Termination
   for (i=n2; i<n2+3; i++) {
-    s[i]= *yp;
-    s1[i] = s[i] ;
-    s2[i] = s[i];
+    systematic0[i]= *yp;
+    s1[i] = systematic0[i] ;
+    s2[i] = systematic0[i];
     yp++;
     yp1[i] = *yp;
     yp++;
 #ifdef DEBUG_LOGMAP
-    printf("Term 1 (%u): %d %d\n",i,s[i],yp1[i]);
+    printf("Term 1 (%u): %d %d\n",i,systematic0[i],yp1[i]);
 #endif //DEBUG_LOGMAP
   }
 
   for (i=n2+16; i<n2+19; i++) {
-    s[i]= *yp;
-    s1[i] = s[i] ;
-    s2[i] = s[i];
+    systematic0[i]= *yp;
+    s1[i] = systematic0[i] ;
+    s2[i] = systematic0[i];
     yp++;
     yp2[i-16] = *yp;
     yp++;
 #ifdef DEBUG_LOGMAP
-    printf("Term 2 (%u): %d %d\n",i-16,s[i],yp2[i-16]);
+    printf("Term 2 (%u): %d %d\n",i-16,systematic0[i],yp2[i-16]);
 #endif //DEBUG_LOGMAP
   }
 
diff --git a/openair1/PHY/CODING/TESTBENCH/coding_unitary_defs.h b/openair1/PHY/CODING/TESTBENCH/coding_unitary_defs.h
new file mode 100644
index 0000000000000000000000000000000000000000..f77ffff2eb5bcf5fe01a0d712ddd8c21411234ec
--- /dev/null
+++ b/openair1/PHY/CODING/TESTBENCH/coding_unitary_defs.h
@@ -0,0 +1,53 @@
+/*
+ *  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 __CODING_UNITARY_DEFS__h__
+#define __CODING_UNITARY_DEFS__h__
+int oai_exit=0;
+unsigned int NB_UE_INST = 1;
+#include "openair1/PHY/defs_UE.h"
+PHY_VARS_UE ***PHY_vars_UE_g;
+#include "common/ran_context.h"
+RAN_CONTEXT_t RC;
+
+void exit_function(const char* file, const char* function, const int line, const char *s) {
+  const char * msg= s==NULL ? "no comment": s;
+  printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
+  exit(-1);
+}
+
+signed char quantize(double D, double x, unsigned char B) {
+  double qxd;
+  short maxlev;
+  qxd = floor(x / D);
+  maxlev = 1 << (B - 1); //(char)(pow(2,B-1));
+
+  if (qxd <= -maxlev)
+    qxd = -maxlev;
+  else if (qxd >= maxlev)
+    qxd = maxlev - 1;
+
+  return ((char) qxd);
+}
+
+
+#endif
+
diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
index b42ac6e4c8fe21f93cb76f1c2ed396283c6bb368..91c5d5961127c7fe258578f5caafef1838d916e1 100644
--- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c
+++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
@@ -26,9 +26,11 @@
 #include "assertions.h"
 #include "SIMULATION/TOOLS/sim.h"
 #include "PHY/CODING/nrLDPC_extern.h"
-#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
+//#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
 #include "openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h"
-#define MAX_NUM_DLSCH_SEGMENTS 16
+#include "openair1/PHY/defs_nr_common.h"
+#include "coding_unitary_defs.h"
+
 #define MAX_BLOCK_LENGTH 8448
 
 #ifndef malloc16
@@ -81,9 +83,6 @@ typedef struct {
   int n_iter_max;
 } n_iter_stats_t;
 
-RAN_CONTEXT_t RC;
-PHY_VARS_UE ***PHY_vars_UE_g;
-uint16_t NB_UE_INST = 1;
 nrLDPC_encoderfunc_t encoder_orig;
 
 short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
@@ -116,9 +115,8 @@ int test_ldpc(short No_iteration,
   double sigma;
   sigma = 1.0/sqrt(2*SNR);
   opp_enabled=1;
-  cpu_freq_GHz = get_cpu_freq_GHz();
   //short test_input[block_length];
-  unsigned char *test_input[MAX_NUM_DLSCH_SEGMENTS]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};;
+  unsigned char *test_input[MAX_NUM_NR_DLSCH_SEGMENTS]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};;
   //short *c; //padded codeword
   unsigned char *estimated_output[MAX_NUM_DLSCH_SEGMENTS];
   unsigned char *estimated_output_bit[MAX_NUM_DLSCH_SEGMENTS];
@@ -144,7 +142,7 @@ int test_ldpc(short No_iteration,
   t_nrLDPC_procBuf nrLDPC_procBuf;
   t_nrLDPC_procBuf* p_nrLDPC_procBuf = &nrLDPC_procBuf;
     
-  t_nrLDPC_time_stats decoder_profiler;
+  t_nrLDPC_time_stats decoder_profiler = {0};
   t_nrLDPC_time_stats* p_decoder_profiler =&decoder_profiler ;
 
   int32_t n_iter = 0;
@@ -614,7 +612,6 @@ int main(int argc, char *argv[])
               exit(1);
               break;
     }
-  cpu_freq_GHz = get_cpu_freq_GHz();
   //printf("the decoder supports BG2, Kb=10, Z=128 & 256\n");
   //printf(" range of blocklength: 1201 -> 1280, 2401 -> 2560\n");
   printf("block length %d: \n", block_length);
@@ -704,25 +701,25 @@ int main(int argc, char *argv[])
     printf("SNR %f, Std iterations: %f\n",SNR, dec_iter->n_iter_std);
     printf("SNR %f, Max iterations: %d\n",SNR, dec_iter->n_iter_max);
     printf("\n");
-    printf("Encoding time mean: %15.3f us\n",(double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz);
-    printf("Encoding time std: %15.3f us\n",sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,2)));
-    printf("Encoding time max: %15.3f us\n",(double)time_optim->max/1000.0/cpu_freq_GHz);
+    printf("Encoding time mean: %15.3f us\n",(double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz());
+    printf("Encoding time std: %15.3f us\n",sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(),2)));
+    printf("Encoding time max: %15.3f us\n",(double)time_optim->max/1000.0/get_cpu_freq_GHz());
     printf("\n");
-    printf("Decoding time mean: %15.3f us\n",(double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz);
-    printf("Decoding time std: %15.3f us\n",sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,2)));
-    printf("Decoding time max: %15.3f us\n",(double)time_decoder->max/1000.0/cpu_freq_GHz);
+    printf("Decoding time mean: %15.3f us\n",(double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz());
+    printf("Decoding time std: %15.3f us\n",sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(),2)));
+    printf("Decoding time max: %15.3f us\n",(double)time_decoder->max/1000.0/get_cpu_freq_GHz());
 
     fprintf(fd,"%f %f %f %f %f %f %f %f %f %f %f %f %d \n",
     		SNR,
     		(double)decoded_errors[i]/(double)n_trials ,
     		(double)errors_bit/(double)n_trials/(double)block_length/(double)n_segments ,
     		errors_bit_uncoded/(double)n_trials/(double)n_segments ,
-    		(double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,
-    		sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,2)),
-    		(double)time_optim->max/1000.0/cpu_freq_GHz,
-    		(double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,
-    		sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,2)),
-    		(double)time_decoder->max/1000.0/cpu_freq_GHz,
+    		(double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(),
+    		sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(),2)),
+    		(double)time_optim->max/1000.0/get_cpu_freq_GHz(),
+    		(double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(),
+    		sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(),2)),
+    		(double)time_decoder->max/1000.0/get_cpu_freq_GHz(),
     		dec_iter->n_iter_mean,
     		dec_iter->n_iter_std,
     		dec_iter->n_iter_max
diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c
index d9adf3e24f679b37f80b0643eea4c12c76595d66..8e7e37754259a5b4051303032a55163a378ec36e 100644
--- a/openair1/PHY/CODING/TESTBENCH/polartest.c
+++ b/openair1/PHY/CODING/TESTBENCH/polartest.c
@@ -11,16 +11,12 @@
 #include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h"
 #include "PHY/CODING/coding_defs.h"
 #include "SIMULATION/TOOLS/sim.h"
-#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
 //#include "common/utils/LOG/log.h"
-
+#include "coding_unitary_defs.h"
 //#define DEBUG_DCI_POLAR_PARAMS
 //#define DEBUG_POLAR_TIMING
 //#define DEBUG_POLARTEST
 
-RAN_CONTEXT_t RC;
-PHY_VARS_UE ***PHY_vars_UE_g;
-uint16_t NB_UE_INST = 1;
 
 int main(int argc, char *argv[])
 {
@@ -113,7 +109,6 @@ int main(int argc, char *argv[])
   //Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
     time_stats_t timeEncoder,timeDecoder;
     opp_enabled=1;
-    cpu_freq_GHz = get_cpu_freq_GHz();
     reset_meas(&timeEncoder);
     reset_meas(&timeDecoder);
     randominit(0);
@@ -324,9 +319,9 @@ if (logFlag){
 #endif
 
       //Iteration times are in microseconds.
-      timeEncoderCumulative+=(timeEncoder.diff/(cpu_freq_GHz*1000.0));
-      timeDecoderCumulative+=(timeDecoder.diff/(cpu_freq_GHz*1000.0));
-      if (logFlag) fprintf(logFile,",%f,%d,%u,%f,%f\n", SNR, nBitError, blockErrorState, (timeEncoder.diff/(cpu_freq_GHz*1000.0)), (timeDecoder.diff/(cpu_freq_GHz*1000.0)));
+      timeEncoderCumulative+=(timeEncoder.diff/(get_cpu_freq_GHz()*1000.0));
+      timeDecoderCumulative+=(timeDecoder.diff/(get_cpu_freq_GHz()*1000.0));
+      if (logFlag) fprintf(logFile,",%f,%d,%u,%f,%f\n", SNR, nBitError, blockErrorState, (timeEncoder.diff/(get_cpu_freq_GHz()*1000.0)), (timeDecoder.diff/(get_cpu_freq_GHz()*1000.0)));
 
       if (nBitError<0) {
         blockErrorCumulative++;
@@ -348,7 +343,7 @@ if (logFlag){
     printf("[ListSize=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%9.3fus, t_Decoder=%9.3fus\n",
            decoderListSize, SNR, ((double)blockErrorCumulative/iterations),
            ((double)bitErrorCumulative / (iterations*testLength)),
-           (double)timeEncoder.diff/timeEncoder.trials/(cpu_freq_GHz*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(cpu_freq_GHz*1000.0));
+           (double)timeEncoder.diff/timeEncoder.trials/(get_cpu_freq_GHz()*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(get_cpu_freq_GHz()*1000.0));
     //(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations);
 
     if (blockErrorCumulative==0 && bitErrorCumulative==0) break;
diff --git a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c
index 02d5dc64e07a025a825b321511a9044f69be831b..c9ed678a8fb09301f4275cc6ddebe76e7c56643d 100644
--- a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c
+++ b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c
@@ -1,19 +1,15 @@
 #include <getopt.h>
 #include "SIMULATION/TOOLS/sim.h"
 #include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h"
-#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
+#include "coding_unitary_defs.h"
 
 //#define DEBUG_SMALLBLOCKTEST
 
-RAN_CONTEXT_t RC;
-PHY_VARS_UE ***PHY_vars_UE_g;
-uint16_t NB_UE_INST = 1;
 
 int main(int argc, char *argv[])
 {
 	time_stats_t timeEncoder,timeDecoder;
 	opp_enabled=1;
-	cpu_freq_GHz = get_cpu_freq_GHz();
 	reset_meas(&timeEncoder);
 	reset_meas(&timeDecoder);
 	randominit(0);
@@ -141,8 +137,8 @@ int main(int argc, char *argv[])
 				SNR,
 				((double)bitErrorCumulative / (iterations*messageLength)),
 				((double)blockErrorCumulative/iterations),
-				((double)timeEncoder.diff/timeEncoder.trials)/(cpu_freq_GHz),
-				((double)timeDecoder.diff/timeDecoder.trials)/(cpu_freq_GHz*1000.0));
+				((double)timeEncoder.diff/timeEncoder.trials)/(get_cpu_freq_GHz()),
+				((double)timeDecoder.diff/timeDecoder.trials)/(get_cpu_freq_GHz()*1000.0));
 
 		blockErrorCumulative=0;
 		bitErrorCumulative=0;
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
index 785b588b9fa0bcd61751b544daee1f8efc5e0503..3226c97f8759ed856232277efd052527f68678eb 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
@@ -39,7 +39,7 @@
 #include "nrLDPC_bnProc.h"
 
 #define NR_LDPC_ENABLE_PARITY_CHECK
-#define NR_LDPC_PROFILER_DETAIL
+//#define NR_LDPC_PROFILER_DETAIL
 
 #ifdef NR_LDPC_DEBUG_MODE
 #include "nrLDPC_tools/nrLDPC_debug.h"
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
index 18db8a01fbc5b65fb2ab09d442181b67f1b56429..8fe115b23a1aed0416503985d2793be985634c82 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
@@ -40,9 +40,9 @@
 #include "assertions.h"
 
 int8_t polar_decoder(double *input,
-					 uint32_t *out,
-					 t_nrPolar_params *polarParams,
-					 uint8_t listSize)
+                     uint32_t *out,
+                     const t_nrPolar_params *polarParams,
+                     uint8_t listSize)
 {
   //Assumes no a priori knowledge.
   uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
@@ -299,7 +299,7 @@ int8_t polar_decoder(double *input,
 
 int8_t polar_decoder_dci(double *input,
                          uint32_t *out,
-                         t_nrPolar_params *polarParams,
+                         const t_nrPolar_params *polarParams,
                          uint8_t listSize,
                          uint16_t n_RNTI) {
   uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
index a44a08a701256dcf1877abd7d1eeae4a491161df..c2e9fd938105fe2846f69f305fe0419632060fa0 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
@@ -138,22 +138,22 @@ typedef struct nrPolar_params t_nrPolar_params;
 
 void polar_encoder(uint32_t *input,
                    uint32_t *output,
-                   t_nrPolar_params *polarParams);
+                   const t_nrPolar_params *polarParams);
 
 void polar_encoder_dci(uint32_t *in,
                        uint32_t *out,
-                       t_nrPolar_params *polarParams,
+                       const t_nrPolar_params *polarParams,
                        uint16_t n_RNTI);
 
 void polar_encoder_fast(uint64_t *A,
                         void *out,
                         int32_t crcmask,
                         uint8_t ones_flag,
-                        t_nrPolar_params *polarParams);
+                        const t_nrPolar_params *polarParams);
 
 int8_t polar_decoder(double *input,
-					 uint32_t *output,
-                     t_nrPolar_params *polarParams,
+                     uint32_t *output,
+                     const t_nrPolar_params *polarParams,
                      uint8_t listSize);
 
 uint32_t polar_decoder_int16(int16_t *input,
@@ -163,21 +163,21 @@ uint32_t polar_decoder_int16(int16_t *input,
 
 int8_t polar_decoder_dci(double *input,
                          uint32_t *out,
-                         t_nrPolar_params *polarParams,
+                         const t_nrPolar_params *polarParams,
                          uint8_t listSize,
                          uint16_t n_RNTI);
 
 void generic_polar_decoder(const t_nrPolar_params *pp,
-						   decoder_node_t *node);
+                           decoder_node_t *node);
 
 void applyFtoleft(const t_nrPolar_params *pp,
-				  decoder_node_t *node);
+                  decoder_node_t *node);
 
 void applyGtoright(const t_nrPolar_params *pp,
-				   decoder_node_t *node);
+                   decoder_node_t *node);
 
 void computeBeta(const t_nrPolar_params *pp,
-				 decoder_node_t *node);
+                 decoder_node_t *node);
 
 void build_decoder_tree(t_nrPolar_params *pp);
 void build_polar_tables(t_nrPolar_params *polarParams);
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
index 27c062c217c1493292a1d567048a53c973dfa318..e61b3dff9b8ce02d597751dfdf9b1a96d727cec2 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
@@ -43,7 +43,7 @@
 
 void polar_encoder(uint32_t *in,
                    uint32_t *out,
-                   t_nrPolar_params *polarParams) {
+                   const t_nrPolar_params *polarParams) {
   if (1) {//polarParams->idx == 0 || polarParams->idx == 1) { //PBCH or PDCCH
     /*
     uint64_t B = (((uint64_t)*in)&((((uint64_t)1)<<32)-1)) | (((uint64_t)crc24c((uint8_t*)in,polarParams->payloadBits)>>8)<<polarParams->payloadBits);
@@ -154,7 +154,7 @@ void polar_encoder(uint32_t *in,
 
 void polar_encoder_dci(uint32_t *in,
                        uint32_t *out,
-                       t_nrPolar_params *polarParams,
+                       const t_nrPolar_params *polarParams,
                        uint16_t n_RNTI) {
 #ifdef DEBUG_POLAR_ENCODER_DCI
   printf("[polar_encoder_dci] in: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", in[0], in[1], in[2], in[3]);
@@ -251,9 +251,9 @@ void polar_encoder_dci(uint32_t *in,
 #endif
 }
 
-static inline void polar_rate_matching(t_nrPolar_params *polarParams,void *in,void *out) __attribute__((always_inline));
+static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void *in,void *out) __attribute__((always_inline));
 
-static inline void polar_rate_matching(t_nrPolar_params *polarParams,void *in,void *out) {
+static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void *in,void *out) {
 
   // handle rate matching with a single 128 bit word using bit shuffling
   // can be done with SIMD intrisics if needed
@@ -411,7 +411,7 @@ void polar_encoder_fast(uint64_t *A,
                         void *out,
                         int32_t crcmask,
                         uint8_t ones_flag,
-                        t_nrPolar_params *polarParams) {
+                        const t_nrPolar_params *polarParams) {
   //  AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
   AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
   AssertFatal(polarParams->payloadBits < 65, "payload bits = %d > 64, is not supported yet\n",polarParams->payloadBits);
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/init_top.c b/openair1/PHY/INIT/init_top.c
index 0990a58266ad7867bf7de52e748cada1d486e8d9..81fb28cc98eda5baa21e057313d0fe0f55ff82e8 100644
--- a/openair1/PHY/INIT/init_top.c
+++ b/openair1/PHY/INIT/init_top.c
@@ -73,7 +73,6 @@ void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) {
   init_unscrambling_lut();
   init_scrambling_lut();
   //set_taus_seed(1328);
-  init_sss();
 }
 
 void free_lte_top(void) {
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index 2c7e3e88eb5b06cc8c9a03f7e8713266687b06f0..1daeb72187b81454ecc2ed359b234b86ec4dec69 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -35,7 +35,7 @@
 #include "assertions.h"
 #include <math.h>
 #include "nfapi/oai_integration/vendor_ext.h"
-
+#include <openair1/PHY/LTE_ESTIMATION/lte_estimation.h>
 extern uint32_t from_earfcn(int eutra_bandP,uint32_t dl_earfcn);
 extern int32_t get_uldl_offset(int eutra_bandP);
 
@@ -46,6 +46,17 @@ uint8_t         dmrs1_tab[8] = { 0, 2, 3, 4, 6, 8, 9, 10 };
 
 int             N_RB_DL_array[6] = { 6, 15, 25, 50, 75, 100 };
 
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
+
+void pdsch_procedures(PHY_VARS_eNB *eNB,
+                      L1_rxtx_proc_t *proc,
+                      int harq_pid,
+                      LTE_eNB_DLSCH_t *dlsch,
+                      LTE_eNB_DLSCH_t *dlsch1);
+
+void init_sss(void);
+
 int
 l1_north_init_eNB () {
   int i,j;
@@ -347,6 +358,33 @@ void phy_config_sib13_eNB(module_id_t Mod_id,int CC_id,int mbsfn_Area_idx,
   lte_gold_mbsfn_khz_1dot25 (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_khz_1dot25_table, fp->Nid_cell_mbsfn);
 }
 
+void fill_subframe_mask(PHY_VARS_eNB *eNB) {
+
+  AssertFatal(eNB->subframe_mask!=NULL,"Subframe mask is null\n");
+  int32_t **dummy_tx=eNB->common_vars.txdataF;
+  eNB->common_vars.txdataF = eNB->subframe_mask;
+  
+  for (int sf=0;sf<10;sf++) {
+    if (subframe_select(&eNB->frame_parms,sf)==SF_DL) {
+      LTE_DL_eNB_HARQ_t *dlsch_harq=eNB->dlsch[0][0]->harq_processes[0];
+      L1_rxtx_proc_t proc;
+      proc.frame_tx=0;
+      proc.subframe_tx=sf;
+      eNB->dlsch[0][0]->harq_ids[0][sf]=0;
+      eNB->dlsch[0][0]->rnti=0x1234;
+      dlsch_harq->nb_rb=48;
+      dlsch_harq->rb_alloc[0]=(uint32_t)0xffffffff;
+      dlsch_harq->Qm=2;
+      dlsch_harq->Nl=1;
+      dlsch_harq->pdsch_start=1;
+      dlsch_harq->mimo_mode=(eNB->frame_parms.nb_antenna_ports_eNB>1) ? ALAMOUTI : SISO;
+      dlsch_harq->dl_power_off = 1;
+      computeRhoB_eNB(4,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,eNB->dlsch[0][0],dlsch_harq->dl_power_off);
+      pdsch_procedures(eNB,&proc,0,eNB->dlsch[0][0],NULL);
+    }
+  }
+  eNB->common_vars.txdataF = dummy_tx;
+}
 
 int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
                      unsigned char is_secondary_eNB,
@@ -385,7 +423,9 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
   lte_gold (fp, eNB->lte_gold_table, fp->Nid_cell);
   generate_pcfich_reg_mapping (fp);
   generate_phich_reg_mapping (fp);
+  init_sss();
 
+  init_fde();
   for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
     eNB->first_run_timing_advance[UE_id] =
       1;   ///This flag used to be static. With multiple eNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
@@ -397,9 +437,13 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
   eNB->first_run_I0_measurements =
     1; ///This flag used to be static. With multiple eNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
 
+  eNB->use_DTX=1;
   if (NFAPI_MODE!=NFAPI_MODE_VNF) {
     common_vars->rxdata  = (int32_t **)NULL;
     common_vars->txdataF = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t *));
+    if (eNB->use_DTX==0) {
+      eNB->subframe_mask = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t *));
+    }
     common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t *));
     LOG_I(PHY,"[INIT] NB_ANTENNA_PORTS_ENB:%d fp->nb_antenna_ports_eNB:%d\n", NB_ANTENNA_PORTS_ENB, fp->nb_antenna_ports_eNB);
 
@@ -409,17 +453,19 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
         LOG_I(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
               i,common_vars->txdataF[i],
               fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t));
+	if (eNB->use_DTX==0 && i<fp->nb_antenna_ports_eNB) eNB->subframe_mask[i] = malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) );
       }
     }
 
+    LOG_I(PHY,"[INIT]SRS allocation\n");
     // Channel estimates for SRS
-    for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
-      srs_vars[UE_id].srs_ch_estimates = (int32_t **) malloc16 (64 * sizeof (int32_t *));
-      srs_vars[UE_id].srs_ch_estimates_time = (int32_t **) malloc16 (64 * sizeof (int32_t *));
+    for (int srs_id = 0; srs_id < NUMBER_OF_SRS_MAX; srs_id++) {
+      srs_vars[srs_id].srs_ch_estimates = (int32_t **) malloc16 (64 * sizeof (int32_t *));
+      srs_vars[srs_id].srs_ch_estimates_time = (int32_t **) malloc16 (64 * sizeof (int32_t *));
 
       for (i = 0; i < 64; i++) {
-        srs_vars[UE_id].srs_ch_estimates[i] = (int32_t *) malloc16_clear (sizeof (int32_t) * fp->ofdm_symbol_size);
-        srs_vars[UE_id].srs_ch_estimates_time[i] = (int32_t *) malloc16_clear (sizeof (int32_t) * fp->ofdm_symbol_size * 2);
+        srs_vars[srs_id].srs_ch_estimates[i] = (int32_t *) malloc16_clear (sizeof (int32_t) * fp->ofdm_symbol_size);
+        srs_vars[srs_id].srs_ch_estimates_time[i] = (int32_t *) malloc16_clear (sizeof (int32_t) * fp->ofdm_symbol_size * 2);
       }
     }                             //UE_id
 
@@ -427,10 +473,11 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
     init_ulsch_power_LUT ();
 
     // SRS
-    for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
-      srs_vars[UE_id].srs = (int32_t *) malloc16_clear (2 * fp->ofdm_symbol_size * sizeof (int32_t));
+    for (int srs_id = 0; srs_id < NUMBER_OF_SRS_MAX; srs_id++) {
+      srs_vars[srs_id].srs = (int32_t *) malloc16_clear (2 * fp->ofdm_symbol_size * sizeof (int32_t));
     }
 
+    LOG_I(PHY,"PRACH allocation\n");
     // PRACH
     prach_vars->prachF = (int16_t *) malloc16_clear (1024 * 2 * sizeof (int16_t));
     // assume maximum of 64 RX antennas for PRACH receiver
@@ -461,34 +508,33 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
       LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]);
       }*/
 
-    for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
+    printf("NUMBER_OF_ULSCH_MAX %d\n",NUMBER_OF_ULSCH_MAX);
+    for (int ULSCH_id=0; ULSCH_id<NUMBER_OF_ULSCH_MAX; ULSCH_id++) {
       //FIXME
-      pusch_vars[UE_id] = (LTE_eNB_PUSCH *) malloc16_clear (NUMBER_OF_UE_MAX * sizeof (LTE_eNB_PUSCH));
-      pusch_vars[UE_id]->rxdataF_ext = (int32_t **) malloc16 (2 * sizeof (int32_t *));
-      pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **) malloc16 (2 * sizeof (int32_t *));
-      pusch_vars[UE_id]->drs_ch_estimates = (int32_t **) malloc16 (2 * sizeof (int32_t *));
-      pusch_vars[UE_id]->drs_ch_estimates_time = (int32_t **) malloc16 (2 * sizeof (int32_t *));
-      pusch_vars[UE_id]->rxdataF_comp = (int32_t **) malloc16 (2 * sizeof (int32_t *));
-      pusch_vars[UE_id]->ul_ch_mag = (int32_t **) malloc16 (2 * sizeof (int32_t *));
-      pusch_vars[UE_id]->ul_ch_magb = (int32_t **) malloc16 (2 * sizeof (int32_t *));
+      pusch_vars[ULSCH_id] = (LTE_eNB_PUSCH *) malloc16_clear (NUMBER_OF_ULSCH_MAX * sizeof (LTE_eNB_PUSCH));
+      pusch_vars[ULSCH_id]->rxdataF_ext = (int32_t **) malloc16 (4 * sizeof (int32_t *));
+      pusch_vars[ULSCH_id]->rxdataF_ext2 = (int32_t **) malloc16 (4 * sizeof (int32_t *));
+      pusch_vars[ULSCH_id]->drs_ch_estimates = (int32_t **) malloc16 (4 * sizeof (int32_t *));
+      pusch_vars[ULSCH_id]->drs_ch_estimates_time = (int32_t **) malloc16 (4 * sizeof (int32_t *));
+      pusch_vars[ULSCH_id]->rxdataF_comp = (int32_t **) malloc16 (4 * sizeof (int32_t *));
+      pusch_vars[ULSCH_id]->ul_ch_mag = (int32_t **) malloc16 (4 * sizeof (int32_t *));
+      pusch_vars[ULSCH_id]->ul_ch_magb = (int32_t **) malloc16 (4 * sizeof (int32_t *));
       AssertFatal (fp->ofdm_symbol_size > 127, "fp->ofdm_symbol_size %d<128\n", fp->ofdm_symbol_size);
       AssertFatal (fp->symbols_per_tti > 11, "fp->symbols_per_tti %d < 12\n", fp->symbols_per_tti);
       AssertFatal (fp->N_RB_UL > 5, "fp->N_RB_UL %d < 6\n", fp->N_RB_UL);
-
-      for (i = 0; i < 2; i++) {
-        // RK 2 times because of output format of FFT!
+      AssertFatal (fp->nb_antennas_rx > 0,"fp->nb_antennas_rx = %d\n",fp->nb_antennas_rx);
+      for (i = 0; i < fp->nb_antennas_rx; i++) {
         // FIXME We should get rid of this
-        pusch_vars[UE_id]->rxdataF_ext[i]      = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
-        pusch_vars[UE_id]->rxdataF_ext2[i]     = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
-        pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
-        pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
-        pusch_vars[UE_id]->rxdataF_comp[i]     = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
-        pusch_vars[UE_id]->ul_ch_mag[i]  = (int32_t *)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
-        pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
+        pusch_vars[ULSCH_id]->rxdataF_ext[i]      = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
+        pusch_vars[ULSCH_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
+        pusch_vars[ULSCH_id]->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear( 4*sizeof(int32_t)*fp->ofdm_symbol_size );
+        pusch_vars[ULSCH_id]->rxdataF_comp[i]     = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
+        pusch_vars[ULSCH_id]->ul_ch_mag[i]  = (int32_t *)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
+        pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
       }
 
-      pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
-    } //UE_id
+      pusch_vars[ULSCH_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
+    } //ULSCH_id
 
     for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++)
       eNB->UE_stats_ptr[UE_id] = &eNB->UE_stats[UE_id];
@@ -518,19 +564,19 @@ void phy_free_lte_eNB(PHY_VARS_eNB *eNB) {
   free_and_zero(common_vars->rxdataF);
 
   // Channel estimates for SRS
-  for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
+  for (int srs_id = 0; srs_id < NUMBER_OF_SRS_MAX; srs_id++) {
     for (i=0; i<64; i++) {
-      free_and_zero(srs_vars[UE_id].srs_ch_estimates[i]);
-      free_and_zero(srs_vars[UE_id].srs_ch_estimates_time[i]);
+      free_and_zero(srs_vars[srs_id].srs_ch_estimates[i]);
+      free_and_zero(srs_vars[srs_id].srs_ch_estimates_time[i]);
     }
 
-    free_and_zero(srs_vars[UE_id].srs_ch_estimates);
-    free_and_zero(srs_vars[UE_id].srs_ch_estimates_time);
+    free_and_zero(srs_vars[srs_id].srs_ch_estimates);
+    free_and_zero(srs_vars[srs_id].srs_ch_estimates_time);
   } //UE_id
 
   free_ul_ref_sigs();
 
-  for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) free_and_zero(srs_vars[UE_id].srs);
+  for (UE_id=0; UE_id<NUMBER_OF_SRS_MAX; UE_id++) free_and_zero(srs_vars[UE_id].srs);
 
   free_and_zero(prach_vars->prachF);
 
@@ -548,26 +594,26 @@ void phy_free_lte_eNB(PHY_VARS_eNB *eNB) {
   free_and_zero(prach_vars_br->prachF);
   free_and_zero(prach_vars->rxsigF[0]);
 
-  for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
-    for (i = 0; i < 2; i++) {
-      free_and_zero(pusch_vars[UE_id]->rxdataF_ext[i]);
-      free_and_zero(pusch_vars[UE_id]->rxdataF_ext2[i]);
-      free_and_zero(pusch_vars[UE_id]->drs_ch_estimates[i]);
-      free_and_zero(pusch_vars[UE_id]->drs_ch_estimates_time[i]);
-      free_and_zero(pusch_vars[UE_id]->rxdataF_comp[i]);
-      free_and_zero(pusch_vars[UE_id]->ul_ch_mag[i]);
-      free_and_zero(pusch_vars[UE_id]->ul_ch_magb[i]);
+  for (int ULSCH_id=0; ULSCH_id<NUMBER_OF_ULSCH_MAX; ULSCH_id++) {
+    for (i = 0; i < fp->nb_antennas_rx; i++) {
+      free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext[i]);
+      free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2[i]);
+      free_and_zero(pusch_vars[ULSCH_id]->drs_ch_estimates[i]);
+      free_and_zero(pusch_vars[ULSCH_id]->drs_ch_estimates_time[i]);
+      free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp[i]);
+      free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag[i]);
+      free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb[i]);
     }
 
-    free_and_zero(pusch_vars[UE_id]->rxdataF_ext);
-    free_and_zero(pusch_vars[UE_id]->rxdataF_ext2);
-    free_and_zero(pusch_vars[UE_id]->drs_ch_estimates);
-    free_and_zero(pusch_vars[UE_id]->drs_ch_estimates_time);
-    free_and_zero(pusch_vars[UE_id]->rxdataF_comp);
-    free_and_zero(pusch_vars[UE_id]->ul_ch_mag);
-    free_and_zero(pusch_vars[UE_id]->ul_ch_magb);
-    free_and_zero(pusch_vars[UE_id]->llr);
-    free_and_zero(pusch_vars[UE_id]);
+    free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext);
+    free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2);
+    free_and_zero(pusch_vars[ULSCH_id]->drs_ch_estimates);
+    free_and_zero(pusch_vars[ULSCH_id]->drs_ch_estimates_time);
+    free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp);
+    free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag);
+    free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb);
+    free_and_zero(pusch_vars[ULSCH_id]->llr);
+    free_and_zero(pusch_vars[ULSCH_id]);
   } //UE_id
 
   for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) eNB->UE_stats_ptr[UE_id] = NULL;
diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c
index 8ad928f8a0c3ee69419227d9c9c5af490809ba46..a856c33999e27fe138f3591438e70088137408d8 100644
--- a/openair1/PHY/INIT/lte_init_ru.c
+++ b/openair1/PHY/INIT/lte_init_ru.c
@@ -21,9 +21,8 @@
 
 #include "phy_init.h"
 #include "SCHED/sched_eNB.h"
-#include "PHY/phy_extern.h"
 #include "PHY/LTE_REFSIG/lte_refsig.h"
-#include "SIMULATION/TOOLS/sim.h"
+//#include "SIMULATION/TOOLS/sim.h"
 #include "LTE_RadioResourceConfigCommonSIB.h"
 #include "LTE_RadioResourceConfigDedicated.h"
 #include "LTE_TDD-Config.h"
@@ -34,6 +33,8 @@
 
 void init_7_5KHz(void);
 
+extern const char ru_if_types[MAX_RU_IF_TYPES][20];
+
 int phy_init_RU(RU_t *ru) {
   LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
   RU_CALIBRATION *calibration = &ru->calibration;
@@ -44,6 +45,7 @@ int phy_init_RU(RU_t *ru) {
   if (ru->is_slave == 1) {
     generate_ul_ref_sigs_rx();
   }
+  else generate_ul_ref_sigs();
 
   if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals
     // Time-domain signals
@@ -135,14 +137,14 @@ int phy_init_RU(RU_t *ru) {
       }
     }
 
-    AssertFatal(RC.nb_L1_inst <= NUMBER_OF_eNB_MAX,"eNB instances %d > %d\n",
-                RC.nb_L1_inst,NUMBER_OF_eNB_MAX);
-    LOG_D(PHY,"[INIT] %s() RC.nb_L1_inst:%d \n", __FUNCTION__, RC.nb_L1_inst);
+    AssertFatal(ru->num_eNB <= NUMBER_OF_eNB_MAX,"eNB instances %d > %d\n",
+                ru->num_eNB,NUMBER_OF_eNB_MAX);
+    LOG_D(PHY,"[INIT] %s() ru->num_eNB:%d \n", __FUNCTION__, ru->num_eNB);
     int starting_antenna_index=0;
 
     for (i=0; i<ru->idx; i++) starting_antenna_index+=ru->nb_tx;
 
-    for (i=0; i<RC.nb_L1_inst; i++) {
+    for (i=0; i<ru->num_eNB; i++) {
       for (p=0; p<15; p++) {
         LOG_D(PHY,"[INIT] %s() nb_antenna_ports_eNB:%d \n", __FUNCTION__, ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB);
 
@@ -240,7 +242,7 @@ void phy_free_RU(RU_t *ru) {
     free_and_zero(ru->prach_rxsigF[0]);
     /* ru->prach_rxsigF_br is not allocated -> don't free */
 
-    for (i = 0; i < RC.nb_L1_inst; i++) {
+    for (i = 0; i < ru->num_eNB; i++) {
       for (p = 0; p < 15; p++) {
         if (p < ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB || p == 5) {
           for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]);
diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c
index 64a5992a64345b80a0550bc90a581e96d75d2bc2..b75673581687731b5d51bd9eac0c9fd0d4802fde 100644
--- a/openair1/PHY/INIT/lte_init_ue.c
+++ b/openair1/PHY/INIT/lte_init_ue.c
@@ -39,6 +39,7 @@ void init_7_5KHz(void);
 
 uint8_t dmrs1_tab_ue[8] = {0,2,3,4,6,8,9,10};
 
+void init_sss(void);
 
 void phy_config_sib1_ue(module_id_t Mod_id,int CC_id,
                         uint8_t eNB_id,
@@ -629,6 +630,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
   init_frame_parms(&ue->frame_parms,1);
   lte_sync_time_init(&ue->frame_parms);
   init_lte_top(&ue->frame_parms);
+  init_sss();
   init_7_5KHz();
   init_ul_hopping(&ue->frame_parms);
   // many memory allocation sizes are hard coded
diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c
index 1505ee018e9f2ae6c4c43078476c917da8916634..504c8fa80a0f284d732d549c3d6d2af6c03d7d12 100644
--- a/openair1/PHY/INIT/lte_param_init.c
+++ b/openair1/PHY/INIT/lte_param_init.c
@@ -25,7 +25,6 @@
 #include <execinfo.h>
 #include <signal.h>
 
-#include "SIMULATION/TOOLS/sim.h"
 #include "PHY/types.h"
 #include "PHY/defs_eNB.h"
 #include "PHY/defs_UE.h"
@@ -33,7 +32,9 @@
 #include "phy_init.h"
 #include "PHY/LTE_REFSIG/lte_refsig.h"
 #include "PHY/LTE_TRANSPORT/transport_common_proto.h"
-#include "targets/RT/USER/lte-softmodem.h"
+#include "executables/softmodem-common.h"
+#include "SIMULATION/TOOLS/sim.h"
+
 extern PHY_VARS_eNB *eNB;
 extern PHY_VARS_UE *UE;
 extern RU_t *ru;
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index d00bc903157d8f4ea6ea04615ff7d8f67c3bbf92..7f2f9780d14b7c47299d83fe3e5de46341c5b57b 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -20,6 +20,7 @@
  */
 
 #include "executables/nr-softmodem-common.h"
+#include "common/utils/nr/nr_common.h"
 #include "PHY/defs_gNB.h"
 #include "PHY/phy_extern.h"
 #include "PHY/NR_REFSIG/nr_refsig.h"
@@ -45,10 +46,42 @@
 
 #include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
 
-/*
-extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
-extern openair0_config_t openair0_cfg[MAX_CARDS];
-*/
+static
+uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex)
+{
+  const uint64_t dl_freq_khz = downlink_frequency / 1000;
+  const int32_t  delta_duplex_khz = delta_duplex / 1000;
+
+  uint64_t center_freq_diff_khz = 999999999999999999; // 2^64
+  uint16_t current_band = 0;
+
+  for (int ind = 0; ind < nr_bandtable_size; ind++) {
+
+    LOG_D(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min, nr_bandtable[ind].ul_min);
+
+    if (dl_freq_khz < nr_bandtable[ind].dl_min || dl_freq_khz > nr_bandtable[ind].dl_max)
+      continue;
+
+    int32_t current_offset_khz = nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min;
+
+    if (current_offset_khz != delta_duplex_khz)
+      continue;
+
+    uint64_t center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min) / 2;
+
+    if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){
+      current_band = nr_bandtable[ind].band;
+      center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz);
+    }
+  }
+
+  LOG_I(PHY, "DL frequency %"PRIu64": band %d, UL frequency %"PRIu64"\n",
+        downlink_frequency, current_band, downlink_frequency+delta_duplex);
+
+  AssertFatal(current_band != 0, "Can't find EUTRA band for frequency %"PRIu64" and duplex_spacing %u\n", downlink_frequency, delta_duplex);
+
+  return current_band;
+}
 
 int l1_north_init_gNB() {
 
@@ -77,7 +110,7 @@ int l1_north_init_gNB() {
 
 int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
                     unsigned char is_secondary_gNB,
-                    unsigned char abstraction_flag) {
+                    unsigned char lowmem_flag) {
   // shortcuts
   NR_DL_FRAME_PARMS *const fp       = &gNB->frame_parms;
   nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
@@ -88,6 +121,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   int i;
   int Ptx=cfg->carrier_config.num_tx_ant.value;
   int Prx=cfg->carrier_config.num_rx_ant.value;
+  int max_ul_mimo_layers = 4;
 
   AssertFatal(Ptx>0 && Ptx<9,"Ptx %d is not supported\n",Ptx);
   AssertFatal(Prx>0 && Prx<9,"Prx %d is not supported\n",Prx);
@@ -95,6 +129,15 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
 
   while(gNB->configured == 0) usleep(10000);
 
+  if (lowmem_flag == 1) {
+    gNB->number_of_nr_dlsch_max = 2;
+    gNB->number_of_nr_ulsch_max = 2;
+  }
+  else {
+    gNB->number_of_nr_dlsch_max = NUMBER_OF_NR_DLSCH_MAX;
+    gNB->number_of_nr_ulsch_max = NUMBER_OF_NR_ULSCH_MAX;
+  }  
+
   load_dftslib();
 
   LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id);
@@ -109,6 +152,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   uint32_t ***pdcch_dmrs             = gNB->nr_gold_pdcch_dmrs;
   AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n");
 
+  gNB->bad_pucch = 0;
+
   for (int slot=0; slot<fp->slots_per_frame; slot++) {
     pdcch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
     AssertFatal(pdcch_dmrs[slot]!=NULL, "NR init: pdcch_dmrs for slot %d - malloc failed\n", slot);
@@ -183,28 +228,28 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
     }
   }
 
+  nr_init_csi_rs(gNB, cfg->cell_config.phy_cell_id.value);
+
   /* Generate low PAPR type 1 sequences for PUSCH DMRS, these are used if transform precoding is enabled.  */
   generate_lowpapr_typ1_refsig_sequences(SHRT_MAX);
-  
-
-  nr_init_csi_rs(gNB, 0); // TODO scramblingID currently hardcoded to 0, to be taken from higher layer parameter scramblingID when implemented
 
   /// Transport init necessary for NR synchro
   init_nr_transport(gNB);
 
-
   gNB->first_run_I0_measurements = 1;
 
   common_vars->rxdata  = (int32_t **)malloc16(Prx*sizeof(int32_t*));
   common_vars->txdataF = (int32_t **)malloc16(Ptx*sizeof(int32_t*));
   common_vars->rxdataF = (int32_t **)malloc16(Prx*sizeof(int32_t*));
+  common_vars->beam_id = (uint8_t **)malloc16(Ptx*sizeof(uint8_t*));
 
   for (i=0;i<Ptx;i++){
       common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
       LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
 	    i,common_vars->txdataF[i],
 	    fp->samples_per_frame_wCP*sizeof(int32_t));
-      
+      common_vars->beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
+      memset(common_vars->beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
   }
   for (i=0;i<Prx;i++){
     common_vars->rxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t));
@@ -249,27 +294,30 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   init_prach_list(gNB);
 
   int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value;
+  int n_buf = Prx*max_ul_mimo_layers;
 
-  for (int ULSCH_id=0; ULSCH_id<NUMBER_OF_NR_ULSCH_MAX; ULSCH_id++) {
+  for (int ULSCH_id=0; ULSCH_id<gNB->number_of_nr_ulsch_max; ULSCH_id++) {
     pusch_vars[ULSCH_id] = (NR_gNB_PUSCH *)malloc16_clear( sizeof(NR_gNB_PUSCH) );
     pusch_vars[ULSCH_id]->rxdataF_ext           = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
     pusch_vars[ULSCH_id]->rxdataF_ext2          = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
-    pusch_vars[ULSCH_id]->ul_ch_estimates       = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
-    pusch_vars[ULSCH_id]->ul_ch_estimates_ext   = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
-    pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates     = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
-    pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
-    pusch_vars[ULSCH_id]->ptrs_phase_per_slot   = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
-    pusch_vars[ULSCH_id]->ul_ch_estimates_time  = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
-    pusch_vars[ULSCH_id]->rxdataF_comp          = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
-    pusch_vars[ULSCH_id]->ul_ch_mag0            = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
-    pusch_vars[ULSCH_id]->ul_ch_magb0           = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
-    pusch_vars[ULSCH_id]->ul_ch_mag             = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
-    pusch_vars[ULSCH_id]->ul_ch_magb            = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
-    pusch_vars[ULSCH_id]->rho                   = (int32_t **)malloc16_clear(Prx*sizeof(int32_t*) );
+    pusch_vars[ULSCH_id]->ul_ch_estimates       = (int32_t **)malloc16(n_buf*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->ul_ch_estimates_ext   = (int32_t **)malloc16(n_buf*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates     = (int32_t **)malloc16(n_buf*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext = (int32_t **)malloc16(n_buf*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->ptrs_phase_per_slot   = (int32_t **)malloc16(n_buf*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->ul_ch_estimates_time  = (int32_t **)malloc16(n_buf*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->rxdataF_comp          = (int32_t **)malloc16(n_buf*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->ul_ch_mag0            = (int32_t **)malloc16(n_buf*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->ul_ch_magb0           = (int32_t **)malloc16(n_buf*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->ul_ch_mag             = (int32_t **)malloc16(n_buf*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->ul_ch_magb            = (int32_t **)malloc16(n_buf*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->rho                   = (int32_t **)malloc16_clear(n_buf*sizeof(int32_t*) );
 
     for (i=0; i<Prx; i++) {
       pusch_vars[ULSCH_id]->rxdataF_ext[i]           = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
       pusch_vars[ULSCH_id]->rxdataF_ext2[i]          = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
+    }
+    for (i=0; i<n_buf; i++) {
       pusch_vars[ULSCH_id]->ul_ch_estimates[i]       = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot );
       pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i]   = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
       pusch_vars[ULSCH_id]->ul_ch_estimates_time[i]  = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
@@ -295,7 +343,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
 
 void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
 {
-  //NR_DL_FRAME_PARMS* const fp       = &gNB->frame_parms;
+  NR_DL_FRAME_PARMS* const fp       = &gNB->frame_parms;
   NR_gNB_COMMON *const common_vars  = &gNB->common_vars;
   NR_gNB_PUSCH **const pusch_vars   = gNB->pusch_vars;
   /*LTE_eNB_SRS *const srs_vars        = gNB->srs_vars;
@@ -335,10 +383,12 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
   free_and_zero(prach_vars->prach_ifft[0]);
   free_and_zero(prach_vars->rxsigF[0]);
 */
-  for (int ULSCH_id=0; ULSCH_id<NUMBER_OF_NR_ULSCH_MAX; ULSCH_id++) {
-    for (int i = 0; i < 2; i++) {
+  for (int ULSCH_id=0; ULSCH_id<gNB->number_of_nr_ulsch_max; ULSCH_id++) {
+    for (int i = 0; i < fp->nb_antennas_rx; i++) {
       free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext[i]);
       free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2[i]);
+    }
+    for (int i = 0; i < 4*fp->nb_antennas_rx; i++) {
       free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates[i]);
       free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i]);
       free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time[i]);
@@ -352,7 +402,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
       free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb[i]);
       free_and_zero(pusch_vars[ULSCH_id]->rho[i]);
     }
-
     free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext);
     free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2);
     free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates);
@@ -431,8 +480,8 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
 
   gNB->mac_enabled   = 1;
   if (mu==1) {
-    fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
-    fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
+    fp->dl_CarrierFreq = 3600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
+    fp->ul_CarrierFreq = 3600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
     fp->nr_band = 78;
     //  fp->threequarter_fs= 0;
   } else if (mu==3) {
@@ -441,7 +490,8 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
     fp->nr_band = 261;
     //  fp->threequarter_fs= 0;
   }
-    
+
+  fp->threequarter_fs = 0;
   gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band);
 
   nr_init_frame_parms(gNB_config, fp);
@@ -455,7 +505,6 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
   uint8_t short_sequence, num_sequences, rootSequenceIndex, fd_occasion;
   NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms;
   nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config;
-  int32_t dlul_offset = 0;
 
   memcpy((void*)gNB_config,phy_config->cfg,sizeof(*phy_config->cfg));
   RC.gNB[Mod_id]->mac_enabled     = 1;
@@ -466,16 +515,9 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
   uint64_t ul_bw_khz = (12*gNB_config->carrier_config.ul_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<<gNB_config->ssb_config.scs_common.value);
   fp->ul_CarrierFreq = ((ul_bw_khz>>1) + gNB_config->carrier_config.uplink_frequency.value)*1000 ;
 
-  //fp->nr_band = *RC.nrmac[Mod_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
-  lte_frame_type_t frame_type = 0; // FDD
-  
-  get_band(fp->dl_CarrierFreq,&fp->nr_band,&dlul_offset,&frame_type); //RC.nrmac[Mod_id] cannot be accessed in NFAPI
-
-  get_delta_duplex(fp->nr_band, gNB_config->ssb_config.scs_common.value, &dlul_offset);
-  dlul_offset *= 1000;
+  int32_t dlul_offset = fp->ul_CarrierFreq - fp->dl_CarrierFreq;
+  fp->nr_band = get_band(fp->dl_CarrierFreq, dlul_offset);
 
-  AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + dlul_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 + dlul_offset);
-  
   LOG_I(PHY, "DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, dlul_offset);
 
   fp->threequarter_fs = openair0_cfg[0].threequarter_fs;
@@ -504,7 +546,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
 //  }
   RC.gNB[Mod_id]->configured     = 1;
 
-  init_symbol_rotation(fp,fp->dl_CarrierFreq);
+  init_symbol_rotation(fp);
 
   LOG_I(PHY,"gNB %d configured\n",Mod_id);
 }
@@ -533,9 +575,9 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
     AssertFatal(gNB->pucch[i]!=NULL,"Can't initialize pucch %d \n", i);
   }
 
-  for (i=0; i<NUMBER_OF_NR_DLSCH_MAX; i++) {
+  for (i=0; i<gNB->number_of_nr_dlsch_max; i++) {
 
-    LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH %d/%d\n",i,NUMBER_OF_NR_DLSCH_MAX);
+    LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH %d/%d\n",i,gNB->number_of_nr_dlsch_max);
 
     for (j=0; j<2; j++) {
       gNB->dlsch[i][j] = new_gNB_dlsch(fp,1,16,NSOFT,0,grid_size);
@@ -543,9 +585,9 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
     }
   }
 
-  for (i=0; i<NUMBER_OF_NR_ULSCH_MAX; i++) {
+  for (i=0; i<gNB->number_of_nr_ulsch_max; i++) {
 
-    LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
+    LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH  %d/%d\n",i,gNB->number_of_nr_ulsch_max);
 
     for (j=0; j<2; j++) {
       // ULSCH for data
@@ -556,27 +598,6 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
         exit(-1);
       }
 
-      /*
-      LOG_I(PHY,"Initializing nFAPI for ULSCH, UE %d\n",i);
-      // [hna] added here for RT implementation
-      uint8_t harq_pid = 0;
-      nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[i+1][j]->harq_processes[harq_pid]->ulsch_pdu;
-  
-      // --------- setting rel15_ul parameters ----------
-      rel15_ul->rnti                           = 0x1234;
-      rel15_ul->ulsch_pdu_rel15.start_rb       = 0;
-      rel15_ul->ulsch_pdu_rel15.number_rbs     = 50;
-      rel15_ul->ulsch_pdu_rel15.start_symbol   = 2;
-      rel15_ul->ulsch_pdu_rel15.number_symbols = 12;
-      rel15_ul->ulsch_pdu_rel15.length_dmrs    = gNB->dmrs_UplinkConfig.pusch_maxLength;
-      rel15_ul->ulsch_pdu_rel15.Qm             = 2;
-      rel15_ul->ulsch_pdu_rel15.R              = 679;
-      rel15_ul->ulsch_pdu_rel15.mcs            = 9;
-      rel15_ul->ulsch_pdu_rel15.rv             = 0;
-      rel15_ul->ulsch_pdu_rel15.n_layers       = 1;
-      ///////////////////////////////////////////////////
-      */
-
     }
 
   }
diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c
index 648b820f0780e25025ef3abb5a9b322059218ff3..097c2b3ad2dd4e6b95ac5859a23b541070b64a92 100644
--- a/openair1/PHY/INIT/nr_init_ru.c
+++ b/openair1/PHY/INIT/nr_init_ru.c
@@ -21,9 +21,6 @@
 
 #include "phy_init.h"
 #include "SCHED/sched_common.h"
-#include "PHY/phy_extern.h"
-#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
-#include "SIMULATION/TOOLS/sim.h"
 /*#include "RadioResourceConfigCommonSIB.h"
 #include "RadioResourceConfigDedicated.h"
 #include "TDD-Config.h"
@@ -33,6 +30,10 @@
 #include <math.h>
 #include "openair1/PHY/defs_RU.h"
 
+void init_prach_ru_list(RU_t *ru);
+
+extern const char ru_if_types[MAX_RU_IF_TYPES][20];
+
 int nr_phy_init_RU(RU_t *ru) {
 
   NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
@@ -44,7 +45,7 @@ int nr_phy_init_RU(RU_t *ru) {
 
   nfapi_nr_config_request_scf_t *cfg;
   ru->nb_log_antennas=0;
-  for (int n=0;n<RC.nb_nr_L1_inst;n++) {
+  for (int n=0;n<ru->num_gNB;n++) {
     cfg = &ru->config;
     if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas) ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;   
   }
@@ -117,34 +118,43 @@ int nr_phy_init_RU(RU_t *ru) {
       }
     }
     
-    AssertFatal(RC.nb_nr_L1_inst <= NUMBER_OF_eNB_MAX,"gNB instances %d > %d\n",
-		RC.nb_nr_L1_inst,NUMBER_OF_gNB_MAX);
+    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() RC.nb_nr_L1_inst:%d \n", __FUNCTION__, RC.nb_nr_L1_inst);
-    
-    int beam_count = 0;
-    if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1
-      for (p=0;p<ru->nb_log_antennas;p++) {
-        if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
-          beam_count++;
-      }
-      AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
-    
-      int l_ind = 0;
-      for (i=0; i<RC.nb_nr_L1_inst; i++) {
+    LOG_I(PHY,"[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB);
+
+    if (ru->do_precoding == 1) {
+      int beam_count = 0;
+      if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1
         for (p=0;p<ru->nb_log_antennas;p++) {
-          if ((fp->L_ssb >> (63-p)) & 0x01)  {
-	    ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
-	    for (j=0; j<ru->nb_tx; j++) {
-	      ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
-              for (re=0; re<fp->ofdm_symbol_size; re++) 
-		ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind];
-              //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j);
-              l_ind++; 
-  	    } // for j
-	  } // for p
+          //if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
+            beam_count++;
         }
+        AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
+    
+      for (i=0; i<ru->num_gNB; i++) {
+        int l_ind = 0;
+        for (p=0;p<ru->nb_log_antennas;p++) {
+          //if ((fp->L_ssb >> (63-p)) & 0x01)  {
+          ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
+          for (j=0; j<ru->nb_tx; j++) {
+            ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
+            AssertFatal(ru->bw_list[i],"ru->bw_list[%d] is null\n",i);
+            for (re=0; re<fp->ofdm_symbol_size; re++)
+              ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind];
+            //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j);
+            l_ind++;
+          } // for j
+          //}
+        } // for p
       } //for i
+      }
+
+      ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*));
+      for(i=0; i< ru->nb_tx; ++i) {
+        ru->common.beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
+        memset(ru->common.beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
+      }
     }
   } // !=IF5
 
@@ -193,8 +203,7 @@ void nr_phy_free_RU(RU_t *ru)
 	free_and_zero(ru->prach_rxsigF[j][i]);
       }
     }
-    
-    for (i = 0; i < RC.nb_nr_L1_inst; i++) {
+    for (i = 0; i < ru->num_gNB; i++) {
       for (p = 0; p < 15; p++) {
 	  for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]);
 	  free_and_zero(ru->beam_weights[i][p]);
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 8bcc58160ff01021fd38801909ccb95a5e1639b5..b29d679fe543cbf2f11321624e38d07de47233f5 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -28,6 +28,7 @@
 #include "TDD-Config.h"
 #include "MBSFN-SubframeConfigList.h"*/
 #include "openair1/PHY/defs_RU.h"
+#include "openair1/PHY/impl_defs_nr.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "assertions.h"
 #include <math.h>
@@ -71,33 +72,39 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
   pdsch->llr128 = (int16_t **)malloc16_clear( sizeof(int16_t *) );
   // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV
   // FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there
-  pdsch->rxdataF_ext            = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
-  pdsch->rxdataF_uespec_pilots  = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
-  pdsch->rxdataF_comp0          = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
-  pdsch->rho                    = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
-  pdsch->dl_ch_estimates        = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
-  pdsch->dl_ch_estimates_ext    = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
-  pdsch->dl_bf_ch_estimates     = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
-  pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
+  pdsch->rxdataF_ext            = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
+  pdsch->rxdataF_uespec_pilots  = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
+  pdsch->rxdataF_comp0          = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
+  pdsch->rho                    = (int32_t ***)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t **) );
+  pdsch->dl_ch_estimates        = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
+  pdsch->dl_ch_estimates_ext    = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
+  pdsch->dl_bf_ch_estimates     = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
+  pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
   //pdsch->dl_ch_rho_ext          = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
   //pdsch->dl_ch_rho2_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-  pdsch->dl_ch_mag0             = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
-  pdsch->dl_ch_magb0            = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
-  pdsch->dl_ch_magr0            = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
-  pdsch->ptrs_phase_per_slot    = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
-  pdsch->ptrs_re_per_slot       = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
-  pdsch->dl_ch_ptrs_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
+  pdsch->dl_ch_mag0             = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
+  pdsch->dl_ch_magb0            = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
+  pdsch->dl_ch_magr0            = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
+  pdsch->ptrs_phase_per_slot    = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
+  pdsch->ptrs_re_per_slot       = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
+  pdsch->dl_ch_ptrs_estimates_ext = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
   // the allocated memory size is fixed:
-  AssertFatal( fp->nb_antennas_rx <= 2, "nb_antennas_rx > 2" );
+  AssertFatal( fp->nb_antennas_rx <= 4, "nb_antennas_rx > 4" );//Extend the max number of UE Rx antennas to 4
 
+  const size_t num = 7*2*fp->N_RB_DL*12;
   for (int i=0; i<fp->nb_antennas_rx; i++) {
-    pdsch->rho[i]     = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) );
-
-    for (int j=0; j<4; j++) { //fp->nb_antennas_tx; j++)
-      const int idx = (j<<1)+i;
-      const size_t num = 7*2*fp->N_RB_DL*12;
-      pdsch->rxdataF_ext[idx]             = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->rxdataF_uespec_pilots[idx]   = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12);
+    pdsch->rxdataF_ext[i]              = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
+    pdsch->rxdataF_uespec_pilots[i]    = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12);
+    pdsch->ptrs_phase_per_slot[i]      = (int32_t *)malloc16_clear( sizeof(int32_t) * 14 );
+    pdsch->ptrs_re_per_slot[i]         = (int32_t *)malloc16_clear( sizeof(int32_t) * 14);
+    pdsch->dl_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * num);
+    pdsch->rho[i]                      = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t *) );
+
+    for (int j=0; j<NR_MAX_NB_LAYERS; j++) {
+      const int idx = (j*fp->nb_antennas_rx)+i;
+      for (int k=0; k<NR_MAX_NB_LAYERS; k++) {
+        pdsch->rho[i][j*NR_MAX_NB_LAYERS+k] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
+      }
       pdsch->rxdataF_comp0[idx]           = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
       pdsch->dl_ch_estimates[idx]         = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2);
       pdsch->dl_ch_estimates_ext[idx]     = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
@@ -108,9 +115,6 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
       pdsch->dl_ch_mag0[idx]              = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
       pdsch->dl_ch_magb0[idx]             = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
       pdsch->dl_ch_magr0[idx]             = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->ptrs_re_per_slot[idx]        = (int32_t *)malloc16_clear(sizeof(int32_t) * 14);
-      pdsch->ptrs_phase_per_slot[idx]     = (int32_t *)malloc16_clear( sizeof(int32_t) * 14 );
-      pdsch->dl_ch_ptrs_estimates_ext[idx]= (int32_t *)malloc16_clear( sizeof(int32_t) * num);
     }
   }
 }
@@ -139,16 +143,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig
   int n_scid;
   abstraction_flag = 0;
-  fp->nb_antennas_tx = 1;
-  fp->nb_antennas_rx=1;
-  // dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig;
-  // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
   LOG_I(PHY, "Initializing UE vars (abstraction %u) for gNB TXant %u, UE RXant %u\n", abstraction_flag, fp->nb_antennas_tx, fp->nb_antennas_rx);
-  //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST);
+  //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_gNB_INST);
   phy_init_nr_top(ue);
   // many memory allocation sizes are hard coded
-  AssertFatal( fp->nb_antennas_rx <= 2, "hard coded allocation for ue_common_vars->dl_ch_estimates[gNB_id]" );
-  AssertFatal(nb_connected_gNB <= NUMBER_OF_CONNECTED_gNB_MAX, "n_connected_gNB is too large" );
+  AssertFatal( fp->nb_antennas_rx <= 4, "hard coded allocation for ue_common_vars->dl_ch_estimates[gNB_id]" );
+  AssertFatal( nb_connected_gNB <= NUMBER_OF_CONNECTED_gNB_MAX, "n_connected_gNB is too large" );
   // init phy_vars_ue
 
   for (i=0; i<4; i++) {
@@ -181,34 +181,21 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
     }
   }
 
+  /////////////////////////PUCCH init/////////////////////////
+  ///////////
+  for (th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
+    for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
+      ue->pucch_vars[th_id][gNB_id] = (NR_UE_PUCCH *)malloc16(sizeof(NR_UE_PUCCH));
+      for (i=0; i<2; i++)
+        ue->pucch_vars[th_id][gNB_id]->active[i] = false;
+    }
+  }
+
   ///////////
   ////////////////////////////////////////////////////////////////////////////////////////////
 
   /////////////////////////PUSCH DMRS init/////////////////////////
   ///////////
-
-  // default values until overwritten by RRCConnectionReconfiguration
-
-  for (i=0; i<MAX_NR_OF_UL_ALLOCATIONS; i++) {
-    ue->pusch_config.pusch_TimeDomainResourceAllocation[i] = (PUSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(PUSCH_TimeDomainResourceAllocation_t));
-    ue->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB;
-  }
-
-  for (i=0;i<MAX_NR_OF_DL_ALLOCATIONS;i++){
-    ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i] = (NR_PDSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(NR_PDSCH_TimeDomainResourceAllocation_t));
-    ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i]->mappingType = typeA;
-  }
-
-  //------------- config DMRS parameters--------------//
-  // dmrs_Uplink_Config->pusch_dmrs_type = pusch_dmrs_type1;
-  // dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0;
-  // dmrs_Uplink_Config->pusch_maxLength = pusch_len1;
-  //-------------------------------------------------//
-  ue->dmrs_DownlinkConfig.pdsch_dmrs_type = pdsch_dmrs_type1;
-  ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = pdsch_dmrs_pos0;
-  ue->dmrs_DownlinkConfig.pdsch_maxLength = pdsch_len1;
-  //-------------------------------------------------//
-
   ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
   pusch_dmrs             = ue->nr_gold_pusch_dmrs;
   n_scid = 0; // This quantity is indicated by higher layer parameter dmrs-SeqInitialization
@@ -276,7 +263,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
     }
   }
 
-  //PDCCH DMRS init (eNB offset = 0)
+  //PDCCH DMRS init (gNB offset = 0)
   ue->nr_gold_pdcch[0] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
   uint32_t ***pdcch_dmrs = ue->nr_gold_pdcch[0];
   AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n");
@@ -291,6 +278,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
     }
   }
 
+  ue->scramblingID_pdcch = fp->Nid_cell;
+  nr_gold_pdcch(ue,fp->Nid_cell);
+
   //PDSCH DMRS init (eNB offset = 0)
   ue->nr_gold_pdsch[0] = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
   uint32_t ****pdsch_dmrs = ue->nr_gold_pdsch[0];
@@ -310,6 +300,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
     }
   }
 
+  // initializing the scrambling IDs for PDSCH DMRS
+  for (int i=0; i<2; i++)
+    ue->scramblingID[i]=fp->Nid_cell;
+
+  nr_gold_pdsch(ue,ue->scramblingID);
+
   // DLSCH
   for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
     for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
@@ -329,31 +325,25 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
       }
 
       for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-        ue->pdsch_vars[th_id][gNB_id]->llr_shifts       = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12);
-        ue->pdsch_vars[th_id][gNB_id]->llr_shifts_p     = ue->pdsch_vars[0][gNB_id]->llr_shifts;
-        ue->pdsch_vars[th_id][gNB_id]->llr[1]           = (int16_t *)malloc16_clear((8*(3*8*8448))*sizeof(int16_t));
-        ue->pdsch_vars[th_id][gNB_id]->layer_llr[1]     = (int16_t *)malloc16_clear((8*(3*8*8448))*sizeof(int16_t));
-        ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear(sizeof(int16_t *));
-        ue->pdsch_vars[th_id][gNB_id]->rho              = (int32_t **)malloc16_clear(fp->nb_antennas_rx*sizeof(int32_t *));
+        ue->pdsch_vars[th_id][gNB_id]->llr_shifts          = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12);
+        ue->pdsch_vars[th_id][gNB_id]->llr_shifts_p        = ue->pdsch_vars[0][gNB_id]->llr_shifts;
+        ue->pdsch_vars[th_id][gNB_id]->llr[1]              = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
+        ue->pdsch_vars[th_id][gNB_id]->layer_llr[1]        = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
+        ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream    = (int16_t **)malloc16_clear( sizeof(int16_t *) );
       }
 
-      for (int i=0; i<fp->nb_antennas_rx; i++) {
-        for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-          ue->pdsch_vars[th_id][gNB_id]->rho[i] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
-        }
-      }
 
       for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-        ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
+        ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext      = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
       }
 
       for (i=0; i<fp->nb_antennas_rx; i++)
         for (j=0; j<4; j++) {
-          const int idx = (j<<1)+i;
+          const int idx = (j*fp->nb_antennas_rx)+i;
           const size_t num = 7*2*fp->N_RB_DL*12+4;
 
           for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-            ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
+            ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
           }
         }
 
@@ -361,15 +351,15 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
       for (k=0; k<8; k++) { //harq_pid
         for (l=0; l<8; l++) { //round
           for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-            ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
-            ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
-            ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l]    = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
-            ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l]   = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
+            ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
+            ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
+            ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l]    = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
+            ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l]   = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
           }
 
           for (int i=0; i<fp->nb_antennas_rx; i++)
             for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++)
-              const int idx = (j<<1)+i;
+              const int idx = (j*fp->nb_antennas_rx)+i;
 
               for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
                 ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
@@ -383,26 +373,26 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
 
       // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
       for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-        ue->pdcch_vars[th_id][gNB_id]->llr                 = (int16_t *)malloc16_clear(2*4*100*12*sizeof(uint16_t));
-        ue->pdcch_vars[th_id][gNB_id]->llr16               = (int16_t *)malloc16_clear(2*4*100*12*sizeof(uint16_t));
-        ue->pdcch_vars[th_id][gNB_id]->wbar                = (int16_t *)malloc16_clear(2*4*100*12*sizeof(uint16_t));
-        ue->pdcch_vars[th_id][gNB_id]->e_rx                = (int16_t *)malloc16_clear(4*2*100*12 );
-        ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp        = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
-        ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext       = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
-        ue->pdcch_vars[th_id][gNB_id]->rho                 = (int32_t **)malloc16(fp->nb_antennas_rx*sizeof(int32_t *));
-        ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext         = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
-        ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
+        ue->pdcch_vars[th_id][gNB_id]->llr                 = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
+        ue->pdcch_vars[th_id][gNB_id]->llr16               = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
+        ue->pdcch_vars[th_id][gNB_id]->wbar                = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
+        ue->pdcch_vars[th_id][gNB_id]->e_rx                = (int16_t *)malloc16_clear( 4*2*100*12 );
+        ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp        = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
+        ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext       = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
+        ue->pdcch_vars[th_id][gNB_id]->rho                 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+        ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext         = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
+        ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
         // Channel estimates
-        ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates      = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
-        ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
+        ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates      = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *));
+        ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *));
 
         for (i=0; i<fp->nb_antennas_rx; i++) {
           ue->pdcch_vars[th_id][gNB_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(100*12*4));
 
           for (j=0; j<4; j++) {
-            int idx = (j<<1) + i;
-            ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH));
-            ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*fp->ofdm_symbol_size*2);
+            int idx = (j*fp->nb_antennas_rx)+i;
+            ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
+            ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
             //  size_t num = 7*2*fp->N_RB_DL*12;
             size_t num = 4*273*12;  // 4 symbols, 100 PRBs, 12 REs per PRB
             ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp[idx]        = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
@@ -414,24 +404,24 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
       }
 
       // PBCH
-      pbch_vars[gNB_id]->rxdataF_ext          = (int32_t **)malloc16(fp->nb_antennas_rx*sizeof(int32_t *));
-      pbch_vars[gNB_id]->rxdataF_comp         = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
-      pbch_vars[gNB_id]->dl_ch_estimates      = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
-      pbch_vars[gNB_id]->dl_ch_estimates_ext  = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
-      pbch_vars[gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(8*sizeof(int32_t *));
-      pbch_vars[gNB_id]->llr                  = (int16_t *)malloc16_clear(1920); //
-      prach_vars[gNB_id]->prachF              = (int16_t *)malloc16_clear(sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)));
-      prach_vars[gNB_id]->prach               = (int16_t *)malloc16_clear(sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)));
+      pbch_vars[gNB_id]->rxdataF_ext         = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+      pbch_vars[gNB_id]->rxdataF_comp        = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
+      pbch_vars[gNB_id]->dl_ch_estimates     = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
+      pbch_vars[gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
+      pbch_vars[gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
+      pbch_vars[gNB_id]->llr                 = (int16_t *)malloc16_clear( 1920 ); //
+      prach_vars[gNB_id]->prachF             = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
+      prach_vars[gNB_id]->prach              = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
 
       for (i=0; i<fp->nb_antennas_rx; i++) {
         pbch_vars[gNB_id]->rxdataF_ext[i]    = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 );
 
         for (j=0; j<4; j++) {//fp->nb_antennas_tx;j++) {
-          int idx = (j<<1)+i;
-          pbch_vars[gNB_id]->rxdataF_comp[idx]         = (int32_t *)malloc16_clear(sizeof(int32_t)*20*12*4);
-          pbch_vars[gNB_id]->dl_ch_estimates[idx]      = (int32_t *)malloc16_clear(sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size));
-          pbch_vars[gNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size));
-          pbch_vars[gNB_id]->dl_ch_estimates_ext[idx]  = (int32_t *)malloc16_clear(sizeof(int32_t)*20*12*4);
+          int idx = (j*fp->nb_antennas_rx)+i;
+          pbch_vars[gNB_id]->rxdataF_comp[idx]        = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 );
+          pbch_vars[gNB_id]->dl_ch_estimates[idx]     = (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) );
+          pbch_vars[gNB_id]->dl_ch_estimates_time[idx]= (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) );
+          pbch_vars[gNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 );
         }
       }
     }
@@ -463,9 +453,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   else
     ue->pdsch_config_dedicated->p_a = dB0;
 
-  // set channel estimation to do linear interpolation in time
-  ue->high_speed_flag = 1;
-  ue->ch_est_alpha    = 24576;
   // enable MIB/SIB decoding by default
   ue->decode_MIB = 1;
   ue->decode_SIB = 1;
@@ -507,50 +494,36 @@ void init_N_TA_offset(PHY_VARS_NR_UE *ue){
   if (fp->frame_type == FDD) {
     ue->N_TA_offset = 0;
   } else {
-    int N_RB = fp->N_RB_DL;
     int N_TA_offset = fp->ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples  for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2
-    double factor = 1;
+
+    double factor = 1.0;
     switch (fp->numerology_index) {
       case 0: //15 kHz scs
         AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n");
-        if (N_RB <= 25) factor = .25;      // 7.68 Ms/s
-        else if (N_RB <=50) factor = .5;   // 15.36 Ms/s
-        else if (N_RB <=75) factor = 1.0;  // 30.72 Ms/s
-        else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s
-        else AssertFatal(1==0, "Too many PRBS for mu=0\n");
+        factor = fp->samples_per_subframe / 30720.0;
         break;
       case 1: //30 kHz sc
         AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n");
-        if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s
-        else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s
+        factor = fp->samples_per_subframe / 30720.0;
         break;
       case 2: //60 kHz scs
         AssertFatal(1==0, "scs_common should not be 60 kHz\n");
         break;
       case 3: //120 kHz scs
         AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n");
+        factor = fp->samples_per_subframe / 61440.0;
         break;
       case 4: //240 kHz scs
-        AssertFatal(1==0, "scs_common should not be 60 kHz\n");
-        if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s
-        else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s
-        else AssertFatal(1==0, "N_RB %d is too big for curretn FR2 implementation\n", N_RB);
+        AssertFatal(N_TA_offset == 431, "scs_common 240kHz only for FR2\n");
+        factor = fp->samples_per_subframe / 61440.0;
         break;
-
-      if (N_RB == 100)
-        ue->N_TA_offset = 624;
-      else if (N_RB == 50)
-        ue->N_TA_offset = 624/2;
-      else if (N_RB == 25)
-        ue->N_TA_offset = 624/4;
+      default:
+        AssertFatal(1==0, "Invalid scs_common!\n");
     }
 
-    if (fp->threequarter_fs == 1)
-      factor = factor*.75;
-
     ue->N_TA_offset = (int)(N_TA_offset * factor);
 
-    LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, N_RB);
+    LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d, mu %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, fp->N_RB_DL, fp->numerology_index);
   }
 }
 
diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c
index ba4147e5cdbec204adc746698dc37694a49c0c71..dab280de263f79b12b46dccb00fab3f1594e0181 100644
--- a/openair1/PHY/INIT/nr_parms.c
+++ b/openair1/PHY/INIT/nr_parms.c
@@ -27,12 +27,9 @@
 uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
 uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16};
 
-int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
-{
+int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb) {
 
   int mu = fp->numerology_index;
-  uint8_t half_frame_index = fp->half_frame_bit;
-  uint8_t i_ssb = fp->ssb_index;
   int symbol = 0;
   uint8_t n, n_temp;
   nr_ssb_type_e type = fp->ssb_type;
@@ -69,15 +66,11 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
        AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu);
   }
 
-  if (half_frame_index)
-    symbol += (5 * fp->symbols_per_slot * fp->slots_per_subframe);
-
   return symbol;
 }
 
-void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw)
+void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL)
 {
-
   switch(mu) {
 
     case NR_MU_0: //15kHz scs
@@ -99,108 +92,17 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw)
 	else
 	  AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->nr_band, mu);
       }
-
-      switch(bw){
-        case 5:
-        case 15:
-        case 20:
-        case 25:
-        case 30:
-        case 40: //40 MHz
-          if (fp->threequarter_fs) {
-            fp->ofdm_symbol_size = 1536;
-            fp->first_carrier_offset = 900; //1536 - ( (106*12) / 2 )
-            fp->nb_prefix_samples0 = 132;
-            fp->nb_prefix_samples = 108;
-          }
-          else {
-            fp->ofdm_symbol_size = 2048;
-            fp->first_carrier_offset = 1412; //2048 - ( (106*12) / 2 )
-            fp->nb_prefix_samples0 = 176;
-            fp->nb_prefix_samples = 144;
-          }
-          break;
-
-        case 50:
-        case 60:
-        case 70:
-
-        case 80: //80 MHz
-          if (fp->threequarter_fs) {
-            fp->ofdm_symbol_size = 3072;
-            fp->first_carrier_offset = 1770; //3072 - ( (217*12) / 2 )
-            fp->nb_prefix_samples0 = 264;
-            fp->nb_prefix_samples = 216;
-          }
-	  else {
-	    fp->ofdm_symbol_size = 4096;
-	    fp->first_carrier_offset = 2794; //4096 - ( (217*12) / 2 )
-	    fp->nb_prefix_samples0 = 352;
-	    fp->nb_prefix_samples = 288;
-	  }
-          break;
-
-        case 90:
-	  AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for %d MHz band and MU %d\n",bw,mu); 
-	  fp->ofdm_symbol_size = 4096;
-	  fp->first_carrier_offset = 2626; //4096 - ( (245*12) / 2 )
-	  fp->nb_prefix_samples0 = 352;
-	  fp->nb_prefix_samples = 288;
-	  break;
-        case 100:
-	  AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for %d MHz band and MU %d\n",bw,mu); 
-	  fp->ofdm_symbol_size = 4096;
-	  fp->first_carrier_offset = 2458; //4096 - ( (273*12) / 2 )
-	  fp->nb_prefix_samples0 = 352;
-	  fp->nb_prefix_samples = 288;
-	  break;
-      default:
-        AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp);
-      }
       break;
 
     case NR_MU_2: //60kHz scs
       fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2];
       fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_2];
-
-      switch(bw){ //FR1 bands only
-        case 10:
-        case 15:
-        case 20:
-        case 25:
-        case 30:
-        case 40:
-        case 50:
-        case 60:
-        case 70:
-        case 80:
-        case 90:
-        case 100:
-      default:
-        AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp);
-      }
       break;
 
     case NR_MU_3:
       fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
       fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
       fp->ssb_type = nr_ssb_type_D;
-      switch(bw){
-        case 100:
-          fp->ofdm_symbol_size = 1024;
-          fp->first_carrier_offset = 628; //1024 - ( (66*12) / 2 )
-          fp->nb_prefix_samples0 = 136;
-          fp->nb_prefix_samples = 72;
-          break;
-        case 50:
-          fp->ofdm_symbol_size = 512;
-          fp->first_carrier_offset = 320; //1024 - ( (66*12) / 2 )
-          fp->nb_prefix_samples0 = 68;
-          fp->nb_prefix_samples = 36;
-          break;
-      default:
-        AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp);
-      }
       break;
 
     case NR_MU_4:
@@ -209,9 +111,21 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw)
       fp->ssb_type = nr_ssb_type_E;
       break;
 
-  default:
-    AssertFatal(1==0,"Invalid numerology index %d", mu);
+    default:
+      AssertFatal(1==0,"Invalid numerology index %d", mu);
   }
+
+  if(fp->threequarter_fs)
+    fp->ofdm_symbol_size = 3 * 128;
+  else
+    fp->ofdm_symbol_size = 4 * 128;
+
+  while(fp->ofdm_symbol_size < N_RB_DL * 12)
+    fp->ofdm_symbol_size <<= 1;
+
+  fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2);
+  fp->nb_prefix_samples    = fp->ofdm_symbol_size / 128 * 9;
+  fp->nb_prefix_samples0   = fp->ofdm_symbol_size / 128 * (9 + (1 << mu));
 }
 
 uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp)
@@ -280,13 +194,12 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg,
   fp->half_frame_bit = 0;  // half frame bit initialized to 0 here
   fp->numerology_index = mu;
 
-  set_scs_parameters(fp, mu, cfg->carrier_config.dl_bandwidth.value);
+  set_scs_parameters(fp, mu, fp->N_RB_DL);
 
   fp->slots_per_frame = 10* fp->slots_per_subframe;
 
-  fp->nb_antenna_ports_gNB = cfg->carrier_config.num_tx_ant.value;// It corresponds to pdsch_AntennaPorts
   fp->nb_antennas_rx = cfg->carrier_config.num_rx_ant.value;      // It denotes the number of rx antennas at gNB
-  fp->nb_antennas_tx = 1;                                         // It corresponds to the number of UE Tx antennas
+  fp->nb_antennas_tx = cfg->carrier_config.num_tx_ant.value;      // It corresponds to pdsch_AntennaPorts (logical antenna ports)
 
   fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
   fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
@@ -334,6 +247,11 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
   uint8_t Nid_cell          = 0;
   int     Ncp               = NORMAL;
 
+  if(fp->nb_antennas_rx == 0)
+    fp->nb_antennas_rx = 1;
+  if(fp->nb_antennas_tx == 0)
+    fp->nb_antennas_tx = 1;
+
   // default values until overwritten by RRCConnectionReconfiguration
   fp->nb_antenna_ports_gNB = nb_ant_ports_gNB;
   fp->tdd_config           = tdd_cfg;
@@ -345,6 +263,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 ;
 
@@ -352,14 +273,13 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
   fp->N_RB_UL = config->carrier_config.ul_grid_size[fp->numerology_index];
   fp->N_RB_DL = config->carrier_config.dl_grid_size[fp->numerology_index];
 
-  int32_t uplink_frequency_offset = 0;
-  get_delta_duplex(fp->nr_band, fp->numerology_index, &uplink_frequency_offset);
-  get_frame_type(fp->nr_band, fp->numerology_index, &fp->frame_type);
+  fp->frame_type = get_frame_type(fp->nr_band, fp->numerology_index);
+  int32_t uplink_frequency_offset = get_delta_duplex(fp->nr_band, fp->numerology_index);
   uplink_frequency_offset *= 1000;
 
   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);
 
@@ -374,7 +294,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
 
   fp->Ncp = Ncp;
 
-  set_scs_parameters(fp,fp->numerology_index,config->carrier_config.dl_bandwidth);
+  set_scs_parameters(fp, fp->numerology_index, fp->N_RB_DL);
 
   fp->slots_per_frame = 10* fp->slots_per_subframe;
   fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h
index 9c474264c8387288260a737533293541928c32c7..2ab610739d5fcfb772d2173e7f3cf5247de3a475 100644
--- a/openair1/PHY/INIT/phy_init.h
+++ b/openair1/PHY/INIT/phy_init.h
@@ -392,14 +392,14 @@ void phy_config_update_sib13_request(PHY_Config_t *phy_config);
 
 int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
 void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
-int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp);
+int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb);
 int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
 int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
 int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
 void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag);
 void init_N_TA_offset(PHY_VARS_NR_UE *ue);
 void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms);
-int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char is_secondary_gNB, unsigned char abstraction_flag);
+int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char is_secondary_gNB, unsigned char lowmem_flag);
 void nr_phy_config_request(NR_PHY_Config_t *gNB);
 void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell,uint64_t position_in_burst);
 void phy_free_nr_gNB(PHY_VARS_gNB *gNB);
@@ -408,6 +408,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB);
 
 void init_dfts(void);
 
+void fill_subframe_mask(PHY_VARS_eNB *eNB);
 
 /** @} */
 #endif
diff --git a/openair1/PHY/LTE_ESTIMATION/freq_equalization.c b/openair1/PHY/LTE_ESTIMATION/freq_equalization.c
index 3fd58a4989701d795401ae296b3a4241e159136a..6d382bdd633c95870aed567cdb6b471b76a7ef8d 100644
--- a/openair1/PHY/LTE_ESTIMATION/freq_equalization.c
+++ b/openair1/PHY/LTE_ESTIMATION/freq_equalization.c
@@ -20,11 +20,11 @@
  */
 
 #include "PHY/defs_eNB.h"
-#include "PHY/phy_extern.h"
 #include "PHY/sse_intrin.h"
+#include "PHY/LTE_ESTIMATION/lte_estimation.h"
 
-// This is 512/(1:256) in __m128i format
-int16_t inv_ch[256*8] = {512,512,512,512,512,512,512,512,
+// This is 4096/(1:4096) in __m128i format
+__m128i inv_ch[4096];/* = {512,512,512,512,512,512,512,512,
                          256,256,256,256,256,256,256,256,
                          170,170,170,170,170,170,170,170,
                          128,128,128,128,128,128,128,128,
@@ -280,7 +280,11 @@ int16_t inv_ch[256*8] = {512,512,512,512,512,512,512,512,
                          2,2,2,2,2,2,2,2,
                          2,2,2,2,2,2,2,2,
                          2,2,2,2,2,2,2,2,
-                        };
+                        };*/
+
+void init_fde() {
+  for (int i=1;i<4096;i++) inv_ch[i] = _mm_set1_epi16(4096/i);
+}
 
 void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms,
                        int32_t **rxdataF_comp,
@@ -313,12 +317,12 @@ void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms,
 
     amp=(*((int16_t*)&ul_ch_mag128[re]));
 
-    if (amp>255)
-      amp=255;
+    if (amp>4095)
+      amp=4095;
 
-    //     printf("freq_eq: symbol %d re %d => %d,%d,%d, (%d) (%d,%d) => ",symbol,re,*((int16_t*)(&ul_ch_mag128[re])),amp,inv_ch[8*amp],*((int16_t*)(&ul_ch_mag128[re]))*inv_ch[8*amp],*(int16_t*)&(rxdataF_comp128[re]),*(1+(int16_t*)&(rxdataF_comp128[re])));
+    //printf("freq_eq: symbol %d re %d => mag %d,amp %d,inv %d, prod %d (%d,%d)\n",symbol,re,*((int16_t*)(&ul_ch_mag128[re])),amp,_mm_extract_epi16(inv_ch[amp],0),(*((int16_t*)(&ul_ch_mag128[re]))*_mm_extract_epi16(inv_ch[amp],0))>>3,*(int16_t*)&(rxdataF_comp128[re]),*(1+(int16_t*)&(rxdataF_comp128[re])));
 #if defined(__x86_64__) || defined(__i386__)
-    rxdataF_comp128[re] = _mm_mullo_epi16(rxdataF_comp128[re],*((__m128i *)&inv_ch[8*amp]));
+    rxdataF_comp128[re] = _mm_srai_epi16(_mm_mullo_epi16(rxdataF_comp128[re],inv_ch[amp]),3);
 
     if (Qm==4)
       ul_ch_mag128[re]  = _mm_set1_epi16(324);  // this is 512*2/sqrt(10)
@@ -327,7 +331,7 @@ void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms,
       ul_ch_magb128[re] = _mm_set1_epi16(158);  // this is 512*2/sqrt(42)
     }
 #elif defined(__arm__)
-    rxdataF_comp128[re] = vmulq_s16(rxdataF_comp128[re],*((int16x8_t *)&inv_ch[8*amp]));
+    rxdataF_comp128[re] = vmulq_s16(rxdataF_comp128[re],inv_ch[amp]);
 
     if (Qm==4)
       ul_ch_mag128[re]  = vdupq_n_s16(324);  // this is 512*2/sqrt(10)
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
index f85162e095d4c711439ae0a9eceb2baf38bf1e83..aac8e71828d4499de5e686adfd70292e303fd48a 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
@@ -21,7 +21,6 @@
 
 #include "PHY/types.h"
 #include "PHY/defs_eNB.h"
-#include "PHY/phy_extern.h"
 
 #include "common/utils/LOG/vcd_signal_dumper.h"
 
@@ -118,12 +117,12 @@ int lte_est_timing_advance_pusch(LTE_DL_FRAME_PARMS *frame_parms,
   int temp, i, aa, max_pos=0, max_val=0;
   short Re,Im;
 
-  uint8_t cyclic_shift = 0;
-  int sync_pos = (frame_parms->ofdm_symbol_size-cyclic_shift*frame_parms->ofdm_symbol_size/12)%(frame_parms->ofdm_symbol_size);
+ // uint8_t cyclic_shift = 0;
+  int sync_pos = 0;//(frame_parms->ofdm_symbol_size-cyclic_shift*frame_parms->ofdm_symbol_size/12)%(frame_parms->ofdm_symbol_size);
   
   AssertFatal(frame_parms->ofdm_symbol_size > 127,"frame_parms->ofdm_symbol_size %d<128\n",frame_parms->ofdm_symbol_size);
-  AssertFatal(frame_parms->nb_antennas_rx >0 && frame_parms->nb_antennas_rx<3,"frame_parms->nb_antennas_rx %d not in [0,1]\n",
-	      frame_parms->nb_antennas_rx);
+  AssertFatal(frame_parms->nb_antennas_rx >0 && frame_parms->nb_antennas_rx<=4,"frame_parms->nb_antennas_rx %d not in [1...%d]\n",
+	      frame_parms->nb_antennas_rx,4);
   for (i = 0; i < frame_parms->ofdm_symbol_size; i++) {
     temp = 0;
 
@@ -142,9 +141,5 @@ int lte_est_timing_advance_pusch(LTE_DL_FRAME_PARMS *frame_parms,
   if (max_pos>frame_parms->ofdm_symbol_size/2)
     max_pos = max_pos-frame_parms->ofdm_symbol_size;
 
-  //#ifdef DEBUG_PHY
-  LOG_D(PHY,"max_pos = %d, sync_pos=%d\n",max_pos,sync_pos);
-  //#endif //DEBUG_PHY
-
   return max_pos - sync_pos;
 }
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c
index 2d79158920bb821d71e126822e193c7d50f20fcd..7eeeb998bab51f083a207c7e679691b3bb418821 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c
@@ -32,6 +32,30 @@
 int32_t rx_power_avg_eNB[3];
 
 
+void dump_I0_stats(FILE *fd,PHY_VARS_eNB *eNB) {
+
+
+    int min_I0=1000,max_I0=0;
+    int amin=0,amax=0;
+    for (int i=0; i<eNB->frame_parms.N_RB_UL; i++) {
+      if (i==(eNB->frame_parms.N_RB_UL>>1) - 1) i+=2;
+
+      if (eNB->measurements.n0_subband_power_tot_dB[i]<min_I0) {min_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; amin=i;}
+
+      if (eNB->measurements.n0_subband_power_tot_dB[i]>max_I0) {max_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; amax=i;}
+    }
+
+    for (int i=0; i<eNB->frame_parms.N_RB_UL; i++) {
+     fprintf(fd,"%2d.",eNB->measurements.n0_subband_power_tot_dB[i]-eNB->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, eNB->measurements.n0_subband_power_avg_dB);
+
+    fprintf(fd,"prach_I0 = %d.%d dB\n",eNB->measurements.prach_I0/10,eNB->measurements.prach_I0%10);
+
+
+}
 void lte_eNB_I0_measurements(PHY_VARS_eNB *eNB,
 			     int subframe,
                              module_id_t eNB_id,
@@ -87,46 +111,45 @@ void lte_eNB_I0_measurements(PHY_VARS_eNB *eNB,
       nb_rb++;
       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
         measurements->n0_subband_power[aarx][rb] = 0;
-        for (int s=0;s<14-(frame_parms->Ncp<<1);s++) {
-      // select the 7th symbol in an uplink subframe
-	  offset = offset0 + (s*frame_parms->ofdm_symbol_size);
-	  ul_ch  = &common_vars->rxdataF[aarx][offset];
-	  len = 12;
+        for (int s=0;s<(14-(frame_parms->Ncp<<1));s++) {
+	        offset = offset0 + (s*frame_parms->ofdm_symbol_size);
+	        ul_ch  = &common_vars->rxdataF[aarx][offset];
+	        len = 12;
 	// just do first half of middle PRB for odd number of PRBs
-	  if (((frame_parms->N_RB_UL&1) == 1) && 
-	      (rb==(frame_parms->N_RB_UL>>1))) {
-	    len=6;
-	  }
+	        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");
+	        AssertFatal(ul_ch, "RX signal buffer (freq) problem");
 
 
-	  measurements->n0_subband_power[aarx][rb] += signal_energy_nodc(ul_ch,len);
+	        measurements->n0_subband_power[aarx][rb] += signal_energy_nodc(ul_ch,len);
 	  
-        }
+        } // symbol
         measurements->n0_subband_power[aarx][rb]/=(14-(frame_parms->Ncp<<1));
         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/frame_parms->nb_antennas_rx);
+      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] - eNB->rx_total_gain_dB - dB_fixed(frame_parms->N_RB_UL);
       
-    }
-  }
+    } //rb not used in subframe
+  } //rb
   if (nb_rb>0) measurements->n0_subband_power_avg_dB = dB_fixed(n0_power_tot2/nb_rb);
 }
 
 void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB,
                               module_id_t eNB_id,
-                              module_id_t UE_id,
+                              module_id_t srs_id,
                               unsigned char init_averaging)
 {
   LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
   PHY_MEASUREMENTS_eNB *measurements = &eNB->measurements;
-  LTE_eNB_SRS *srs_vars = &eNB->srs_vars[UE_id];
+  LTE_eNB_SRS *srs_vars = &eNB->srs_vars[srs_id];
 
   int32_t aarx,rx_power_correction;
   int32_t rx_power;
@@ -136,7 +159,7 @@ void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB,
   //printf("Running eNB_srs_measurements for eNB_id %d\n",eNB_id);
 
   if (init_averaging == 1)
-    rx_power_avg_eNB[UE_id] = 0;
+    rx_power_avg_eNB[srs_id] = 0;
 
   rx_power = 0;
 
@@ -152,24 +175,24 @@ void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB,
   for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
 
-    measurements->rx_spatial_power[UE_id][0][aarx] =
+    measurements->rx_spatial_power[srs_id][0][aarx] =
       ((signal_energy_nodc(&srs_vars->srs_ch_estimates[aarx][frame_parms->first_carrier_offset],
                            (frame_parms->N_RB_DL*6)) +
         signal_energy_nodc(&srs_vars->srs_ch_estimates[aarx][1],
                            (frame_parms->N_RB_DL*6)))*rx_power_correction) -
       measurements->n0_power[aarx];
 
-    measurements->rx_spatial_power[UE_id][0][aarx]<<=1;  // because of noise only in odd samples
+    measurements->rx_spatial_power[srs_id][0][aarx]<<=1;  // because of noise only in odd samples
 
-    measurements->rx_spatial_power_dB[UE_id][0][aarx] = (unsigned short) dB_fixed(measurements->rx_spatial_power[UE_id][0][aarx]);
+    measurements->rx_spatial_power_dB[srs_id][0][aarx] = (unsigned short) dB_fixed(measurements->rx_spatial_power[srs_id][0][aarx]);
 
-    measurements->wideband_cqi[UE_id][aarx] = measurements->rx_spatial_power[UE_id][0][aarx];
+    measurements->wideband_cqi[srs_id][aarx] = measurements->rx_spatial_power[srs_id][0][aarx];
 
 
 
     //      measurements->rx_power[UE_id][aarx]/=frame_parms->nb_antennas_tx;
-    measurements->wideband_cqi_dB[UE_id][aarx] = (unsigned short) dB_fixed(measurements->wideband_cqi[UE_id][aarx]);
-    rx_power += measurements->wideband_cqi[UE_id][aarx];
+    measurements->wideband_cqi_dB[srs_id][aarx] = (unsigned short) dB_fixed(measurements->wideband_cqi[srs_id][aarx]);
+    rx_power += measurements->wideband_cqi[srs_id][aarx];
     //      measurements->rx_avg_power_dB[UE_id] += measurements->rx_power_dB[UE_id][aarx];
   }
 
@@ -177,14 +200,14 @@ void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB,
 
   //    measurements->rx_avg_power_dB[UE_id]/=frame_parms->nb_antennas_rx;
   if (init_averaging == 0)
-    rx_power_avg_eNB[UE_id] = ((k1*rx_power_avg_eNB[UE_id]) + (k2*rx_power))>>10;
+    rx_power_avg_eNB[srs_id] = ((k1*rx_power_avg_eNB[srs_id]) + (k2*rx_power))>>10;
   else
-    rx_power_avg_eNB[UE_id] = rx_power;
+    rx_power_avg_eNB[srs_id] = rx_power;
 
-  measurements->wideband_cqi_tot[UE_id] = dB_fixed2(rx_power,2*measurements->n0_power_tot);
+  measurements->wideband_cqi_tot[srs_id] = dB_fixed2(rx_power,2*measurements->n0_power_tot);
   // times 2 since we have noise only in the odd carriers of the srs comb
 
-  measurements->rx_rssi_dBm[UE_id] = (int32_t)dB_fixed(rx_power_avg_eNB[UE_id])-eNB->rx_total_gain_dB;
+  measurements->rx_rssi_dBm[srs_id] = (int32_t)dB_fixed(rx_power_avg_eNB[srs_id])-eNB->rx_total_gain_dB;
 
 
 
@@ -200,21 +223,21 @@ void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB,
       else if (rb>12)
         ul_ch    = &srs_vars->srs_ch_estimates[aarx][6 + (rb-13)*12];
       else {
-        measurements->subband_cqi_dB[UE_id][aarx][rb] = 0;
+        measurements->subband_cqi_dB[srs_id][aarx][rb] = 0;
         continue;
       }
 
       // cqi
       if (aarx==0)
-        measurements->subband_cqi_tot[UE_id][rb]=0;
+        measurements->subband_cqi_tot[srs_id][rb]=0;
 
-      measurements->subband_cqi[UE_id][aarx][rb] = (signal_energy_nodc(ul_ch,12))*rx_power_correction - measurements->n0_power[aarx];
+      measurements->subband_cqi[srs_id][aarx][rb] = (signal_energy_nodc(ul_ch,12))*rx_power_correction - measurements->n0_power[aarx];
 
-      if (measurements->subband_cqi[UE_id][aarx][rb] < 0)
-        measurements->subband_cqi[UE_id][aarx][rb]=0;
+      if (measurements->subband_cqi[srs_id][aarx][rb] < 0)
+        measurements->subband_cqi[srs_id][aarx][rb]=0;
 
-      measurements->subband_cqi_tot[UE_id][rb] += measurements->subband_cqi[UE_id][aarx][rb];
-      measurements->subband_cqi_dB[UE_id][aarx][rb] = dB_fixed2(measurements->subband_cqi[UE_id][aarx][rb],
+      measurements->subband_cqi_tot[srs_id][rb] += measurements->subband_cqi[srs_id][aarx][rb];
+      measurements->subband_cqi_dB[srs_id][aarx][rb] = dB_fixed2(measurements->subband_cqi[srs_id][aarx][rb],
           2*measurements->n0_power[aarx]);
       // 2*n0_power since we have noise from the odd carriers in the comb of the srs
 
@@ -225,7 +248,7 @@ void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB,
 
 
   for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
-    measurements->subband_cqi_tot_dB[UE_id][rb] = dB_fixed2(measurements->subband_cqi_tot[UE_id][rb],
+    measurements->subband_cqi_tot_dB[srs_id][rb] = dB_fixed2(measurements->subband_cqi_tot[srs_id][rb],
         measurements->n0_power_tot);
     /*
     if (measurements->subband_cqi_tot_dB[UE_id][rb] == 65)
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h
index fc40280853ec3adb48cc6866041508b8e3e0838b..6ba901e29f453d2dcbd63328abbb15a9c635a4e0 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h
+++ b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h
@@ -288,6 +288,8 @@ void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms,
                        unsigned short Msc_RS,
                        unsigned char Qm);
 
+void init_fde(void);
 
+void dump_I0_stats(FILE *fd,PHY_VARS_eNB *eNB);
 /** @} */
 #endif
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
index 0d765a18b339c6fe92109207cb7067cbd50ea3cc..1fbc8b7ef2bcd643a718245a9d3873edc3efeb0b 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
@@ -27,276 +27,89 @@
 
 //#include <string.h>
 #include <math.h>
-#include "LAYER2/MAC/mac.h"
 #include "PHY/defs_UE.h"
 #include "PHY/phy_extern_ue.h"
-#include "PHY_INTERFACE/phy_interface.h"
 #include "PHY/LTE_REFSIG/lte_refsig.h"
-#include "RRC/LTE/rrc_extern.h"
 
 // Note: this is for prototype of generate_drs_pusch (OTA synchronization of RRUs)
 #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
 
-int* sync_corr_ue0 = NULL;
-int* sync_corr_ue1 = NULL;
-int* sync_corr_ue2 = NULL;
-int sync_tmp[2048*4] __attribute__((aligned(32)));
-short syncF_tmp[2048*2] __attribute__((aligned(32)));
+static struct complex16 *primary_synch0_time __attribute__((aligned(32)));
+static struct complex16 *primary_synch1_time __attribute__((aligned(32)));
+static struct complex16 *primary_synch2_time __attribute__((aligned(32)));
 
-
-int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms )   // LTE_UE_COMMON *common_vars
-{
-  int i,k;
-
-  sync_corr_ue0 = (int *)malloc16(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms->samples_per_tti);
-  sync_corr_ue1 = (int *)malloc16(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms->samples_per_tti);
-  sync_corr_ue2 = (int *)malloc16(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms->samples_per_tti);
-
-  if (sync_corr_ue0) {
-#ifdef DEBUG_PHY
-    LOG_D(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue allocated at %p\n", sync_corr_ue0);
-#endif
-    //common_vars->sync_corr = sync_corr;
-  } else {
-    LOG_E(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue0 not allocated\n");
-    return(-1);
-  }
-
-  if (sync_corr_ue1) {
-#ifdef DEBUG_PHY
-    LOG_D(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue allocated at %p\n", sync_corr_ue1);
-#endif
-    //common_vars->sync_corr = sync_corr;
-  } else {
-    LOG_E(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue1 not allocated\n");
-    return(-1);
-  }
-
-  if (sync_corr_ue2) {
-#ifdef DEBUG_PHY
-    LOG_D(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue allocated at %p\n", sync_corr_ue2);
-#endif
-    //common_vars->sync_corr = sync_corr;
-  } else {
-    LOG_E(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue2 not allocated\n");
-    return(-1);
-  }
-
-  //  primary_synch0_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
-  primary_synch0_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
-
-  if (primary_synch0_time) {
-    //    bzero(primary_synch0_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
-    bzero(primary_synch0_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
-#ifdef DEBUG_PHY
-    LOG_D(PHY,"[openair][LTE_PHY][SYNC] primary_synch0_time allocated at %p\n", primary_synch0_time);
-#endif
-  } else {
-    LOG_E(PHY,"[openair][LTE_PHY][SYNC] primary_synch0_time not allocated\n");
-    return(-1);
-  }
-
-  //  primary_synch1_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
-  primary_synch1_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
-
-  if (primary_synch1_time) {
-    //    bzero(primary_synch1_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
-    bzero(primary_synch1_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
-#ifdef DEBUG_PHY
-    LOG_D(PHY,"[openair][LTE_PHY][SYNC] primary_synch1_time allocated at %p\n", primary_synch1_time);
-#endif
-  } else {
-    LOG_E(PHY,"[openair][LTE_PHY][SYNC] primary_synch1_time not allocated\n");
-    return(-1);
-  }
-
-  //  primary_synch2_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
-  primary_synch2_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
-
-  if (primary_synch2_time) {
-    //    bzero(primary_synch2_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
-    bzero(primary_synch2_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
-#ifdef DEBUG_PHY
-    LOG_D(PHY,"[openair][LTE_PHY][SYNC] primary_synch2_time allocated at %p\n", primary_synch2_time);
-#endif
-  } else {
-    LOG_E(PHY,"[openair][LTE_PHY][SYNC] primary_synch2_time not allocated\n");
-    return(-1);
-  }
-
-
-  // generate oversampled sync_time sequences
-  k=frame_parms->ofdm_symbol_size-36;
-
-  for (i=0; i<72; i++) {
-    syncF_tmp[2*k] = primary_synch0[2*i]>>2;  //we need to shift input to avoid overflow in fft
-    syncF_tmp[2*k+1] = primary_synch0[2*i+1]>>2;
-    k++;
-
-    if (k >= frame_parms->ofdm_symbol_size) {
-      k++;  // skip DC carrier
-      k-=frame_parms->ofdm_symbol_size;
-    }
-  }
-
-  switch (frame_parms->N_RB_DL) {
+static void doIdft(int size, short *in, short *out) {
+  switch (size) {
   case 6:
-    idft(IDFT_128,(short*)syncF_tmp,          /// complex input
-	   (short*)sync_tmp, /// complex output
-	   1);
+      idft(IDFT_128,in,out,1);
     break;
+
   case 25:
-    idft(IDFT_512,(short*)syncF_tmp,          /// complex input
-	   (short*)sync_tmp, /// complex output
-	   1);
+      idft(IDFT_512,in,out,1);
     break;
+
   case 50:
-    idft(IDFT_1024,(short*)syncF_tmp,          /// complex input
-	    (short*)sync_tmp, /// complex output
-	    1);
+      idft(IDFT_1024,in,out,1);
     break;
     
   case 75:
-    idft(IDFT_1536,(short*)syncF_tmp,          /// complex input
-	     (short*)sync_tmp,
-	     1); /// complex output
+      idft(IDFT_1536,in,out,1);
     break;
+
   case 100:
-    idft(IDFT_2048,(short*)syncF_tmp,          /// complex input
-	     (short*)sync_tmp, /// complex output
-	     1);
+      idft(IDFT_2048,in,out,1);
     break;
+
   default:
-    LOG_E(PHY,"Unsupported N_RB_DL %d\n",frame_parms->N_RB_DL);
+      LOG_E(PHY,"Unsupported N_RB_DL %d\n",size);
+      abort();
     break;
-  }
-
-  for (i=0; i<frame_parms->ofdm_symbol_size; i++)
-    ((int32_t*)primary_synch0_time)[i] = sync_tmp[i];
-
-  k=frame_parms->ofdm_symbol_size-36;
-
-  for (i=0; i<72; i++) {
-    syncF_tmp[2*k] = primary_synch1[2*i]>>2;  //we need to shift input to avoid overflow in fft
-    syncF_tmp[2*k+1] = primary_synch1[2*i+1]>>2;
-    k++;
-
-    if (k >= frame_parms->ofdm_symbol_size) {
-      k++;  // skip DC carrier
-      k-=frame_parms->ofdm_symbol_size;
     }
   }
 
-  switch (frame_parms->N_RB_DL) {
-  case 6:
-    idft(IDFT_128,(short*)syncF_tmp,          /// complex input
-	   (short*)sync_tmp, /// complex output
-	   1);
-    break;
-  case 25:
-    idft(IDFT_512,(short*)syncF_tmp,          /// complex input
-	   (short*)sync_tmp, /// complex output
-	   1);
-    break;
-  case 50:
-    idft(IDFT_1024,(short*)syncF_tmp,          /// complex input
-	    (short*)sync_tmp, /// complex output
-	    1);
-    break;
+static void copyPrimary( struct complex16 *out, struct complex16 *in, int ofdmSize) {
+  int k=ofdmSize-36;
     
-  case 75:
-    idft(IDFT_1536,(short*)syncF_tmp,          /// complex input
-	     (short*)sync_tmp, /// complex output
-	     1);
-    break;
-  case 100:
-    idft(IDFT_2048,(short*)syncF_tmp,          /// complex input
-	    (short*)sync_tmp, /// complex output
-	    1);
-    break;
-  default:
-    LOG_E(PHY,"Unsupported N_RB_DL %d\n",frame_parms->N_RB_DL);
-    break;
-  }
-
-  for (i=0; i<frame_parms->ofdm_symbol_size; i++)
-    ((int32_t*)primary_synch1_time)[i] = sync_tmp[i];
-
-  k=frame_parms->ofdm_symbol_size-36;
-
-  for (i=0; i<72; i++) {
-    syncF_tmp[2*k] = primary_synch2[2*i]>>2;  //we need to shift input to avoid overflow in fft
-    syncF_tmp[2*k+1] = primary_synch2[2*i+1]>>2;
+  for (int i=0; i<72; i++) {
+    out[k].r = in[i].r>>1;  //we need to shift input to avoid overflow in fft
+    out[k].i = in[i].i>>1;
     k++;
 
-    if (k >= frame_parms->ofdm_symbol_size) {
+    if (k >= ofdmSize) {
       k++;  // skip DC carrier
-      k-=frame_parms->ofdm_symbol_size;
+      k-=ofdmSize;
     }
   }
-
-  switch (frame_parms->N_RB_DL) {
-  case 6:
-    idft(IDFT_128,(short*)syncF_tmp,          /// complex input
-	   (short*)sync_tmp, /// complex output
-	   1);
-    break;
-  case 25:
-    idft(IDFT_512,(short*)syncF_tmp,          /// complex input
-	   (short*)sync_tmp, /// complex output
-	   1);
-    break;
-  case 50:
-    idft(IDFT_1024,(short*)syncF_tmp,          /// complex input
-	    (short*)sync_tmp, /// complex output
-	    1);
-    break;
-    
-  case 75:
-    idft(IDFT_1536,(short*)syncF_tmp,          /// complex input
-	     (short*)sync_tmp, /// complex output
-	     1);
-    break;
-  case 100:
-    idft(IDFT_2048,(short*)syncF_tmp,          /// complex input
-	    (short*)sync_tmp, /// complex output
-	    1);
-    break;
-  default:
-    LOG_E(PHY,"Unsupported N_RB_DL %d\n",frame_parms->N_RB_DL);
-    break;
   }
 
-  for (i=0; i<frame_parms->ofdm_symbol_size; i++)
-    ((int32_t*)primary_synch2_time)[i] = sync_tmp[i];
-
+int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) { // LTE_UE_COMMON *common_vars
+  struct complex16 syncF_tmp[2048]__attribute__((aligned(32)))= {{0}};
+  int sz=frame_parms->ofdm_symbol_size*sizeof(*primary_synch0_time);
+  AssertFatal( NULL != (primary_synch0_time = (struct complex16 *)malloc16(sz)),"");
+  bzero(primary_synch0_time,sz);
+  AssertFatal( NULL != (primary_synch1_time = (struct complex16 *)malloc16(sz)),"");
+  bzero(primary_synch1_time,sz);
+  AssertFatal( NULL != (primary_synch2_time = (struct complex16 *)malloc16(sz)),"");
+  bzero(primary_synch2_time,sz);
+  // generate oversampled sync_time sequences
+  copyPrimary( syncF_tmp, (struct complex16 *) primary_synch0, frame_parms->ofdm_symbol_size);
+  doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch0_time);
+  copyPrimary( syncF_tmp, (struct complex16 *) primary_synch1, frame_parms->ofdm_symbol_size);
+  doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch1_time);
+  copyPrimary( syncF_tmp, (struct complex16 *) primary_synch2, frame_parms->ofdm_symbol_size);
+  doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch2_time);
 
   if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){
     LOG_M("primary_sync0.m","psync0",primary_synch0_time,frame_parms->ofdm_symbol_size,1,1);
     LOG_M("primary_sync1.m","psync1",primary_synch1_time,frame_parms->ofdm_symbol_size,1,1);
     LOG_M("primary_sync2.m","psync2",primary_synch2_time,frame_parms->ofdm_symbol_size,1,1);
   }
+
   return (1);
 }
 
 
-void lte_sync_time_free(void)
-{
-  if (sync_corr_ue0) {
-    LOG_D(PHY,"Freeing sync_corr_ue (%p)...\n",sync_corr_ue0);
-    free(sync_corr_ue0);
-  }
-
-  if (sync_corr_ue1) {
-    LOG_D(PHY,"Freeing sync_corr_ue (%p)...\n",sync_corr_ue1);
-    free(sync_corr_ue1);
-  }
-
-  if (sync_corr_ue2) {
-    LOG_D(PHY,"Freeing sync_corr_ue (%p)...\n",sync_corr_ue2);
-    free(sync_corr_ue2);
-  }
-
+void lte_sync_time_free(void) {
   if (primary_synch0_time) {
     LOG_D(PHY,"Freeing primary_sync0_time ...\n");
     free(primary_synch0_time);
@@ -312,126 +125,81 @@ void lte_sync_time_free(void)
     free(primary_synch2_time);
   }
 
-  sync_corr_ue0 = NULL;
-  sync_corr_ue1 = NULL;
-  sync_corr_ue2 = NULL;
   primary_synch0_time = NULL;
   primary_synch1_time = NULL;
   primary_synch2_time = NULL;
 }
 
 
-static inline int abs32(int x)
-{
+static inline int abs32(int x) {
   return (((int)((short*)&x)[0])*((int)((short*)&x)[0]) + ((int)((short*)&x)[1])*((int)((short*)&x)[1]));
 }
 
+static inline double absF(struct complexd x) {
+  return x.r*x.r+x.i*x.i;
+}
+
+#define complexNull(c) bzero((void*) &(c), sizeof(c))
 
 #define SHIFT 17
 
 
 int lte_sync_time(int **rxdata, ///rx data in time domain
                   LTE_DL_FRAME_PARMS *frame_parms,
-                  int *eNB_id)
-{
+                  int *eNB_id) {
   // perform a time domain correlation using the oversampled sync sequence
-
   unsigned int n, ar, s, peak_pos, peak_val, sync_source;
   int result,result2;
-  int sync_out[3] = {0,0,0},sync_out2[3] = {0,0,0};
-  int tmp[3] = {0,0,0};
+  struct complexd sync_out[3]= {{0}}, sync_out2[3]= {{0}};
   int length =   LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti>>1;
-
-  //LOG_D(PHY,"[SYNC TIME] Calling sync_time.\n");
-  AssertFatal(sync_corr_ue0 != NULL,
-             "sync_corr_ue0 not yet allocated! Exiting.\n");
-  AssertFatal(sync_corr_ue1 != NULL,
-             "sync_corr_ue0 not yet allocated! Exiting.\n");
-  AssertFatal(sync_corr_ue2 != NULL,
-             "sync_corr_ue0 not yet allocated! Exiting.\n");
-
   peak_val = 0;
   peak_pos = 0;
   sync_source = 0;
 
-
   for (n=0; n<length; n+=4) {
-
-    sync_corr_ue0[n] = 0;
-    sync_corr_ue0[n+length] = 0;
-    sync_corr_ue1[n] = 0;
-    sync_corr_ue1[n+length] = 0;
-    sync_corr_ue2[n] = 0;
-    sync_corr_ue2[n+length] = 0;
-
     for (s=0; s<3; s++) {
-      sync_out[s]=0;
-      sync_out2[s]=0;
+      complexNull(sync_out[s]);
+      complexNull(sync_out2[s]);
     }
 
     //    if (n<(length-frame_parms->ofdm_symbol_size-frame_parms->nb_prefix_samples)) {
     if (n<(length-frame_parms->ofdm_symbol_size)) {
-
       //calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n];
       for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
-
-        result  = dot_product((short*)primary_synch0_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
-        result2 = dot_product((short*)primary_synch0_time, (short*) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
-
-        ((short*)sync_corr_ue0)[2*n] += ((short*) &result)[0];
-        ((short*)sync_corr_ue0)[2*n+1] += ((short*) &result)[1];
-        ((short*)sync_corr_ue0)[2*(length+n)] += ((short*) &result2)[0];
-        ((short*)sync_corr_ue0)[(2*(length+n))+1] += ((short*) &result2)[1];
-        ((short*)sync_out)[0] += ((short*) &result)[0];
-        ((short*)sync_out)[1] += ((short*) &result)[1];
-        ((short*)sync_out2)[0] += ((short*) &result2)[0];
-        ((short*)sync_out2)[1] += ((short*) &result2)[1];
+        result  = dot_product((short *)primary_synch0_time, (short *) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
+        result2 = dot_product((short *)primary_synch0_time, (short *) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
+        sync_out[0].r += ((short *) &result)[0];
+        sync_out[0].i += ((short *) &result)[1];
+        sync_out2[0].r += ((short *) &result2)[0];
+        sync_out2[0].i += ((short *) &result2)[1];
       }
 
       for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
-        result = dot_product((short*)primary_synch1_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
-        result2 = dot_product((short*)primary_synch1_time, (short*) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
-        ((short*)sync_corr_ue1)[2*n] += ((short*) &result)[0];
-        ((short*)sync_corr_ue1)[2*n+1] += ((short*) &result)[1];
-        ((short*)sync_corr_ue1)[2*(length+n)] += ((short*) &result2)[0];
-        ((short*)sync_corr_ue1)[(2*(length+n))+1] += ((short*) &result2)[1];
-
-        ((short*)sync_out)[2] += ((short*) &result)[0];
-        ((short*)sync_out)[3] += ((short*) &result)[1];
-        ((short*)sync_out2)[2] += ((short*) &result2)[0];
-        ((short*)sync_out2)[3] += ((short*) &result2)[1];
+        result = dot_product((short *)primary_synch1_time, (short *) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
+        result2 = dot_product((short *)primary_synch1_time, (short *) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
+        sync_out[1].r += ((short *) &result)[0];
+        sync_out[1].i += ((short *) &result)[1];
+        sync_out2[1].r += ((short *) &result2)[0];
+        sync_out2[1].i += ((short *) &result2)[1];
       }
 
       for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
-
-        result = dot_product((short*)primary_synch2_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
-        result2 = dot_product((short*)primary_synch2_time, (short*) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
-        ((short*)sync_corr_ue2)[2*n] += ((short*) &result)[0];
-        ((short*)sync_corr_ue2)[2*n+1] += ((short*) &result)[1];
-        ((short*)sync_corr_ue2)[2*(length+n)] += ((short*) &result2)[0];
-        ((short*)sync_corr_ue2)[(2*(length+n))+1] += ((short*) &result2)[1];
-        ((short*)sync_out)[4] += ((short*) &result)[0];
-        ((short*)sync_out)[5] += ((short*) &result)[1];
-        ((short*)sync_out2)[4] += ((short*) &result2)[0];
-        ((short*)sync_out2)[5] += ((short*) &result2)[1];
+        result = dot_product((short *)primary_synch2_time, (short *) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
+        result2 = dot_product((short *)primary_synch2_time, (short *) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
+        sync_out[2].r += ((short *) &result)[0];
+        sync_out[2].i += ((short *) &result)[1];
+        sync_out2[2].r += ((short *) &result2)[0];
+        sync_out2[2].i += ((short *) &result2)[1];
       }
-
     }
 
     // calculate the absolute value of sync_corr[n]
 
-    sync_corr_ue0[n] = abs32(sync_corr_ue0[n]);
-    sync_corr_ue0[n+length] = abs32(sync_corr_ue0[n+length]);
-    sync_corr_ue1[n] = abs32(sync_corr_ue1[n]);
-    sync_corr_ue1[n+length] = abs32(sync_corr_ue1[n+length]);
-    sync_corr_ue2[n] = abs32(sync_corr_ue2[n]);
-    sync_corr_ue2[n+length] = abs32(sync_corr_ue2[n+length]);
-
     for (s=0; s<3; s++) {
-      tmp[s] = (abs32(sync_out[s])>>1) + (abs32(sync_out2[s])>>1);
+      double tmp = absF(sync_out[s]) + absF(sync_out2[s]);
 
-      if (tmp[s]>peak_val) {
-        peak_val = tmp[s];
+      if (tmp>peak_val) {
+        peak_val = tmp;
         peak_pos = n;
         sync_source = s;
         /*
@@ -443,42 +211,22 @@ int lte_sync_time(int **rxdata, ///rx data in time domain
   }
 
   *eNB_id = sync_source;
-
-  LOG_I(PHY,"[UE] lte_sync_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n",sync_source,peak_pos,peak_val,dB_fixed(peak_val)/2);
-
-
-  if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){
-    static int debug_cnt;
-    if (debug_cnt == 0) {
-      LOG_M("sync_corr0_ue.m","synccorr0",sync_corr_ue0,2*length,1,2);
-      LOG_M("sync_corr1_ue.m","synccorr1",sync_corr_ue1,2*length,1,2);
-      LOG_M("sync_corr2_ue.m","synccorr2",sync_corr_ue2,2*length,1,2);
-      LOG_M("rxdata0.m","rxd0",rxdata[0],length<<1,1,1);
-      //    exit(-1);
-    } else {
-    debug_cnt++;
-  }
-}
+  LOG_I(PHY,"[UE] lte_sync_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n",sync_source,peak_pos,peak_val/2,dB_fixed(peak_val/2)/2);
   return(peak_pos);
 }
 
 
-int ru_sync_time_init(RU_t *ru)   // LTE_UE_COMMON *common_vars
-{
+int ru_sync_time_init(RU_t *ru) { // LTE_UE_COMMON *common_vars
   /*
   int16_t dmrs[2048];
   int16_t *dmrsp[2] = {dmrs,NULL};
   */
-
   int32_t dmrs[ru->frame_parms->ofdm_symbol_size*14] __attribute__((aligned(32)));
   //int32_t *dmrsp[2] = {&dmrs[(3-ru->frame_parms->Ncp)*ru->frame_parms->ofdm_symbol_size],NULL};
   int32_t *dmrsp[2] = {&dmrs[0],NULL};
-
   generate_ul_ref_sigs();
- 
-  ru->dmrssync = (int16_t*)malloc16_clear(ru->frame_parms->ofdm_symbol_size*2*sizeof(int16_t));
-  ru->dmrs_corr = (uint64_t*)malloc16_clear(ru->frame_parms->samples_per_tti*10*sizeof(uint64_t));
-
+  ru->dmrssync = (int16_t *)malloc16_clear(ru->frame_parms->ofdm_symbol_size*2*sizeof(int16_t));
+  ru->dmrs_corr = (uint64_t *)malloc16_clear(ru->frame_parms->samples_per_tti*10*sizeof(uint64_t));
   generate_drs_pusch(NULL,
                      NULL,
                      ru->frame_parms,
@@ -491,35 +239,39 @@ int ru_sync_time_init(RU_t *ru)   // LTE_UE_COMMON *common_vars
                      0);
 
   switch (ru->frame_parms->N_RB_DL) {
-  case 6:
-    idft(IDFT_128,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
-	    ru->dmrssync, /// complex output
-	    1);
-    break;
-  case 25:
-    idft(IDFT_512,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
-	    ru->dmrssync, /// complex output
-	    1);
-    break;
-  case 50:
-    idft(IDFT_1024,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
-	    ru->dmrssync, /// complex output
-	    1);
-    break;
-     
-  case 75:
-    idft(IDFT_1536,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
-	     ru->dmrssync,
-	     1); /// complex output
-    break;
-  case 100:
-    idft(IDFT_2048,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
-	     ru->dmrssync, /// complex output
-	     1);
-    break;
-  default:
-    AssertFatal(1==0,"Unsupported N_RB_DL %d\n",ru->frame_parms->N_RB_DL);
-    break;
+    case 6:
+      idft(IDFT_128,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+           ru->dmrssync, /// complex output
+           1);
+      break;
+
+    case 25:
+      idft(IDFT_512,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+           ru->dmrssync, /// complex output
+           1);
+      break;
+
+    case 50:
+      idft(IDFT_1024,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+           ru->dmrssync, /// complex output
+           1);
+      break;
+
+    case 75:
+      idft(IDFT_1536,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+           ru->dmrssync,
+           1); /// complex output
+      break;
+
+    case 100:
+      idft(IDFT_2048,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+           ru->dmrssync, /// complex output
+           1);
+      break;
+
+    default:
+      AssertFatal(1==0,"Unsupported N_RB_DL %d\n",ru->frame_parms->N_RB_DL);
+      break;
   }
 
   return(0);
@@ -527,10 +279,11 @@ int ru_sync_time_init(RU_t *ru)   // LTE_UE_COMMON *common_vars
 
 
 void ru_sync_time_free(RU_t *ru) {
-
   AssertFatal(ru->dmrssync!=NULL,"ru->dmrssync is NULL\n");
   free(ru->dmrssync);
-  if (ru->dmrs_corr) free(ru->dmrs_corr);
+
+  if (ru->dmrs_corr)
+    free(ru->dmrs_corr);
 }
 
 //#define DEBUG_PHY
@@ -539,10 +292,8 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
                       LTE_DL_FRAME_PARMS *frame_parms,
                       uint32_t length,
                       uint32_t *peak_val_out,
-                      uint32_t *sync_corr_eNB)
-{
+                      uint32_t *sync_corr_eNB) {
   // perform a time domain correlation using the oversampled sync sequence
-
   unsigned int n, ar, peak_val, peak_pos;
   uint64_t mean_val;
   int result;
@@ -556,21 +307,21 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
   }
 
   switch (eNB_id) {
-  case 0:
-    primary_synch_time = (short*)primary_synch0_time;
-    break;
+    case 0:
+      primary_synch_time = (short *)primary_synch0_time;
+      break;
 
-  case 1:
-    primary_synch_time = (short*)primary_synch1_time;
-    break;
+    case 1:
+      primary_synch_time = (short *)primary_synch1_time;
+      break;
 
-  case 2:
-    primary_synch_time = (short*)primary_synch2_time;
-    break;
+    case 2:
+      primary_synch_time = (short *)primary_synch2_time;
+      break;
 
-  default:
-    LOG_E(PHY,"[SYNC TIME] Illegal eNB_id!\n");
-    return (-1);
+    default:
+      LOG_E(PHY,"[SYNC TIME] Illegal eNB_id!\n");
+      return (-1);
   }
 
   peak_val = 0;
@@ -578,21 +329,16 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
   mean_val = 0;
 
   for (n=0; n<length; n+=4) {
-
     sync_corr_eNB[n] = 0;
 
     if (n<(length-frame_parms->ofdm_symbol_size-frame_parms->nb_prefix_samples)) {
-
       //calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n];
       for (ar=0; ar<frame_parms->nb_antennas_rx; ar++)  {
-
-        result = dot_product((short*)primary_synch_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
+        result = dot_product((short *)primary_synch_time, (short *) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
         //((short*)sync_corr)[2*n]   += ((short*) &result)[0];
         //((short*)sync_corr)[2*n+1] += ((short*) &result)[1];
         sync_corr_eNB[n] += abs32(result);
-
       }
-
     }
 
     /*
@@ -610,7 +356,6 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
   }
 
   mean_val/=length;
-
   *peak_val_out = peak_val;
 
   if (peak_val <= (40*(uint32_t)mean_val)) {
@@ -620,88 +365,91 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
     LOG_I(PHY,"[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %"PRIu64"\n",peak_pos,peak_val,mean_val);
     return(peak_pos);
   }
-
 }
 
 
-static inline int64_t abs64(int64_t x)
-{
-  return (((int64_t)((int32_t*)&x)[0])*((int64_t)((int32_t*)&x)[0]) + ((int64_t)
-((int32_t*)&x)[1])*((int64_t)((int32_t*)&x)[1]));
+static inline int64_t abs64(int64_t x) {
+  return (((int64_t)((int32_t *)&x)[0])*((int64_t)((int32_t *)&x)[0]) + ((int64_t)
+          ((int32_t *)&x)[1])*((int64_t)((int32_t *)&x)[1]));
 }
 
 
 int ru_sync_time(RU_t *ru,
                  int64_t *lev,
-                 int64_t *avg)
-{
+                 int64_t *avg) {
   LTE_DL_FRAME_PARMS *frame_parms = ru->frame_parms;
   RU_CALIBRATION *calibration = &ru->calibration;
-		      
   // perform a time domain correlation using the oversampled sync sequence
-
   int length =   LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti;
-  
 
   // circular copy of beginning to end of rxdata buffer. Note: buffer should be big enough upon calling this function
-  for (int ar=0;ar<ru->nb_rx;ar++) memcpy((void*)&ru->common.rxdata[ar][2*length],
-					  (void*)&ru->common.rxdata[ar][0],
-					  frame_parms->ofdm_symbol_size);
-  
+  for (int ar=0; ar<ru->nb_rx; ar++)
+    memcpy((void *)&ru->common.rxdata[ar][2*length],
+           (void *)&ru->common.rxdata[ar][0],
+           frame_parms->ofdm_symbol_size);
+
   int32_t maxlev0=0;
   int     maxpos0=0;
   int64_t avg0=0;
   int64_t result;
   int64_t dmrs_corr;
-
   int maxval=0;
-  for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) {
+
+  for (int i=0; i<2*(frame_parms->ofdm_symbol_size); i++) {
     maxval = max(maxval,ru->dmrssync[i]);
     maxval = max(maxval,-ru->dmrssync[i]);
   }
 
   if (ru->state == RU_CHECK_SYNC) {
-  	for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) {
-    		maxval = max(maxval,calibration->drs_ch_estimates_time[0][i]);
-	        maxval = max(maxval,-calibration->drs_ch_estimates_time[0][i]);
-        }
+    for (int i=0; i<2*(frame_parms->ofdm_symbol_size); i++) {
+      maxval = max(maxval,calibration->drs_ch_estimates_time[0][i]);
+      maxval = max(maxval,-calibration->drs_ch_estimates_time[0][i]);
+    }
   }
 
   int shift = log2_approx(maxval);
 
   for (int n=0; n<length; n+=4) {
-
     dmrs_corr = 0;
 
     //calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n];
     for (int ar=0; ar<ru->nb_rx; ar++) {
-      
       result  = dot_product64(ru->dmrssync,
-			      (int16_t*) &ru->common.rxdata[ar][n],
-			      frame_parms->ofdm_symbol_size,
-			      shift);     
-
-      if (ru->state == RU_CHECK_SYNC) {
-      	result  = dot_product64((int16_t*) &calibration->drs_ch_estimates_time[ar],
-                              (int16_t*) &ru->common.rxdata[ar][n],
+                              (int16_t *) &ru->common.rxdata[ar][n],
                               frame_parms->ofdm_symbol_size,
                               shift);
+
+      if (ru->state == RU_CHECK_SYNC) {
+        result  = dot_product64((int16_t *) &calibration->drs_ch_estimates_time[ar],
+                                (int16_t *) &ru->common.rxdata[ar][n],
+                                frame_parms->ofdm_symbol_size,
+                                shift);
       }
+
       dmrs_corr += abs64(result);
     }
-    if (ru->dmrs_corr != NULL) ru->dmrs_corr[n] = dmrs_corr;
+
+    if (ru->dmrs_corr != NULL)
+      ru->dmrs_corr[n] = dmrs_corr;
 
     // tmpi holds <synchi,rx0>+<synci,rx1>+...+<synchi,rx_{nbrx-1}>
 
+    if (dmrs_corr>maxlev0) {
+      maxlev0 = dmrs_corr;
+      maxpos0 = n;
+    }
 
-    if (dmrs_corr>maxlev0) { maxlev0 = dmrs_corr; maxpos0 = n; }
     avg0 += dmrs_corr;
   }
-  avg0/=(length/4);
 
+  avg0/=(length/4);
   int dmrsoffset = frame_parms->samples_per_tti + (3*frame_parms->ofdm_symbol_size)+(3*frame_parms->nb_prefix_samples) + frame_parms->nb_prefix_samples0;
-  
-  if ((int64_t)maxlev0 > (10*avg0)) {*lev = maxlev0; *avg=avg0; return((length+maxpos0-dmrsoffset)%length);}
+
+  if ((int64_t)maxlev0 > (10*avg0)) {
+    *lev = maxlev0;
+    *avg=avg0;
+    return((length+maxpos0-dmrsoffset)%length);
+  }
 
   return(-1);
 }
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
index 1d1b16e036d22b5b02915ca208ed425ebefcd03a..c867292942f840d3bffd2891769ddf9b0d4dc7ca 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
@@ -20,7 +20,7 @@
  */
 
 #include "PHY/defs_eNB.h"
-#include "PHY/phy_extern.h"
+//#include "PHY/phy_extern.h"
 #include "PHY/sse_intrin.h"
 //#define DEBUG_CH
 #include "common/utils/LOG/log.h"
@@ -34,12 +34,17 @@ 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};
+
+extern unsigned short dftsizes[34];
+extern int16_t *ul_ref_sigs_rx[30][2][34];
+
 int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
                                   L1_rxtx_proc_t *proc,
-				  LTE_eNB_ULSCH_t * ulsch,
-				  int32_t **ul_ch_estimates,
-				  int32_t **ul_ch_estimates_time,
-				  int32_t **rxdataF_ext,
+                        				  LTE_eNB_ULSCH_t * ulsch,
+				                          int32_t **ul_ch_estimates,
+				                          int32_t **ul_ch_estimates_time,
+				                          int32_t **rxdataF_ext,
                                   module_id_t UE_id,
                                   unsigned char l,
                                   unsigned char Ns) {
diff --git a/openair1/PHY/LTE_REFSIG/lte_gold.c b/openair1/PHY/LTE_REFSIG/lte_gold.c
index c5e48d83643a7782ff43e49dc12ffd827c258ef5..596760541b2a7087d75c173cbd33727852f5d330 100644
--- a/openair1/PHY/LTE_REFSIG/lte_gold.c
+++ b/openair1/PHY/LTE_REFSIG/lte_gold.c
@@ -56,7 +56,7 @@ void lte_gold(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_table[20][2][14]
        (((1+(Nid_cell<<1))*(1 + (((frame_parms->Ncp==0)?4:3)*l) + (7*(1+ns))))<<10); //cinit
       //x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit
       //n = 0
-      x1 = 1+ (1<<31);
+      x1 = 1+ (1U<<31);
       x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
 
       // skip first 50 double words (1600 bits)
@@ -103,7 +103,7 @@ void lte_gold_ue_spec(uint32_t lte_gold_uespec_table[2][20][2][21],uint16_t Nid_
         //x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit
         //n = 0
         //      printf("cinit (ns %d, l %d) => %d\n",ns,l,x2);
-        x1 = 1+ (1<<31);
+        x1 = 1+ (1U<<31);
         x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
 
         // skip first 50 double words (1600 bits)
@@ -143,7 +143,7 @@ void lte_gold_ue_spec_port5(uint32_t lte_gold_uespec_port5_table[20][38],uint16_
     //x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit
     //n = 0
     //printf("cinit (ns %d, l %d) => %d\n",ns,l,x2);
-    x1 = 1+ (1<<31);
+    x1 = 1+ (1U<<31);
     x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
 
     //skip first 50 double words (1600 bits)
diff --git a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c
index b057f6a40343719a5b85c575889563d15d1842de..78f0fd93fe3e9904a51fb871e099b8ce2c1d65ab 100644
--- a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c
+++ b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c
@@ -59,7 +59,7 @@ void lte_gold_mbsfn(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_mbsfn_tabl
       //n = 0
       //      printf("cinit (sfn %d, l %d) => %d\n",sfn,l,x2);
       // Initializing the Sequence
-      x1 = 1+ (1<<31);
+      x1 = 1+ (1U<<31);
       x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
       // skip first 50 double words (1600 bits)
       //      printf("n=0 : x1 %x, x2 %x\n",x1,x2);
@@ -90,7 +90,7 @@ void lte_gold_mbsfn_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold
 
   for (sfn=0; sfn<10; sfn++) {
     x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + (7*(1+sfn))))<<9); //cinit
-    x1 = 1+ (1<<31);
+    x1 = 1+ (1U<<31);
     x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
 
     for (n=1; n<50; n++) {
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index 4b06f67bbe8accbc9f163ddce57ecb63c4002ad2..61af617d6e6a6ae7dd47147a751a5bcdb83acd3e 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -53,22 +53,25 @@
 //#undef LOG_D
 //#define LOG_D(A,B...) printf(B)
 
-int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) {
-  uint16_t i;
-  int16_t first_free_index=-1;
+int find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) {
+  int first_free_index=-1;
   AssertFatal(eNB!=NULL,"eNB is null\n");
 
-  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
-    AssertFatal(eNB->dlsch[i]!=NULL,"eNB->dlsch[%d] is null\n",i);
-    AssertFatal(eNB->dlsch[i]!=NULL,"eNB->dlsch[%d][0] is null\n",i);
+  for (int i=0; i<NUMBER_OF_DLSCH_MAX; i++) {
+    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)
@@ -78,20 +81,23 @@ int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) {
 }
 
 
-int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) {
-  uint16_t i;
-  int16_t first_free_index=-1;
+int find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) {
+  int first_free_index=-1;
   AssertFatal(eNB!=NULL,"eNB is null\n");
 
-  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
-    AssertFatal(eNB->ulsch[i]!=NULL,"eNB->ulsch[%d] is null\n",i);
+  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)
@@ -301,7 +307,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,
 
   UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE);
 
-  if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ) {
+  if( (UE_id<0) || (UE_id>=NUMBER_OF_DLSCH_MAX) ) {
     LOG_E(PHY,"illegal UE_id found!!! rnti %04x UE_id %d\n",rel8->rnti,UE_id);
     return;
   }
@@ -476,7 +482,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,
             ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid  = rel8->harq_process;
             ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai       = rel8->downlink_assignment_index;
             ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->padding   = 0;
-            //        printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
+            //LOG_D(PHY,"TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",rel8->mcs_1,rel8->resource_block_coding,rel8->redundancy_version_1,NPRB);
           } else {
             dci_alloc->dci_length                         = sizeof_DCI1A_20MHz_FDD_t;
             ((DCI1A_20MHz_FDD_t *)dci_pdu)->type          = 1;
@@ -535,7 +541,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,
 
       dlsch0->harq_mask |= (1 << rel8->harq_process);
 
-      if (rel8->rnti_type == 1) LOG_D(PHY,"DCI 1A: round %d, mcs %d, TBS %d, rballoc %x, rv %d, rnti %x, harq process %d\n",dlsch0_harq->round,rel8->mcs_1,dlsch0_harq->TBS,rel8->resource_block_coding,
+      if (rel8->rnti != SI_RNTI) LOG_D(PHY,"DCI 1A: round %d, mcs %d, TBS %d, rballoc %x, rv %d, rnti %x, harq process %d\n",dlsch0_harq->round,rel8->mcs_1,dlsch0_harq->TBS,rel8->resource_block_coding,
                                         rel8->redundancy_version_1,rel8->rnti,rel8->harq_process);
 
       break;
@@ -1550,7 +1556,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dc
   dci_alloc->i0 = rel13->initial_transmission_sf_io;
   UE_id = find_dlsch (rel13->rnti, eNB, SEARCH_EXIST_OR_FREE);
   AssertFatal (UE_id != -1, "no free or exiting dlsch_context\n");
-  AssertFatal (UE_id < NUMBER_OF_UE_MAX, "returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n", UE_id, NUMBER_OF_UE_MAX);
+  AssertFatal (UE_id < NUMBER_OF_DLSCH_MAX, "returned UE_id %d >= %d(NUMBER_OF_DLSCH_MAX)\n", UE_id, NUMBER_OF_DLSCH_MAX);
   dlsch0 = eNB->dlsch[UE_id][0];
   dlsch0_harq = dlsch0->harq_processes[rel13->harq_process];
   dci_alloc->ra_flag = 0;
@@ -1955,7 +1961,7 @@ void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
   if(frame_parms->frame_type == TDD) {
     UE_id = find_ulsch(pdu->dci_pdu_rel8.rnti, eNB,SEARCH_EXIST_OR_FREE);
 
-    if(UE_id != -1) {
+    if(UE_id >=0 -1 || UE_id < NUMBER_OF_ULSCH_MAX) {
       eNB->ulsch[UE_id]->harq_processes[pdu->dci_pdu_rel8.harq_pid]->V_UL_DAI = dai +1;
     }
   }
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c
index 583d12eedb4a6d86f99e4ec9bbddcc4f0fc80b6e..64e74ebfbf80341dd7d1b70d74240769b90858dd 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c
@@ -32,7 +32,6 @@
 
 #include "PHY/defs_eNB.h"
 #include "PHY/phy_extern.h"
-#include "SCHED/sched_eNB.h"
 #ifdef DEBUG_DCI_TOOLS
 #include "PHY/phy_vars.h"
 #endif
@@ -43,7 +42,6 @@
 //#define DEBUG_HARQ
 
 
-#include "LAYER2/MAC/mac.h"
 
 //#define DEBUG_DCI
 
@@ -100,7 +98,6 @@ uint16_t RIV2nb_rb_LUT100[6000];
 uint16_t RIV2first_rb_LUT100[6000];
 uint16_t RIV_max100=0;
 
-extern RAN_CONTEXT_t RC;
 
 extern uint32_t current_dlsch_cqi;
 
@@ -273,15 +270,6 @@ uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint
 
 
 
-uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int subframe)
-{
-
-  // check for eNB only !
-  return(get_nCCE(num_pdcch_symbols,
-		  &RC.eNB[Mod_id][CC_id]->frame_parms,
-		  get_mi(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe)));
-}
-
 
 void conv_eMTC_rballoc (uint16_t resource_block_coding, uint32_t N_RB_DL, uint32_t * rb_alloc)
 {
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index 3eb44d98fa69abb1935cd7d24e4ea7d0a95ada5f..b5bcb0848d4d489f6ba862f21f81ddc74aba7fec 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -96,6 +96,7 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) {
 }
 
 
+
 LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
                                unsigned char Mdlharq,
                                uint32_t Nsoft,
@@ -110,7 +111,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
 
   switch (N_RB_DL) {
   case 6:
-    bw_scaling =16;
+    bw_scaling = 4;
     break;
 
   case 25:
@@ -160,7 +161,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
 
     for (i=0; i<Mdlharq; i++) {
       dlsch->harq_processes[i] = (LTE_DL_eNB_HARQ_t *)malloc16(sizeof(LTE_DL_eNB_HARQ_t));
-      LOG_T(PHY, "Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p\n",
+      LOG_I(PHY, "Required DLSCH mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p\n",
             MAX_DLSCH_PAYLOAD_BYTES/bw_scaling,bw_scaling, i,dlsch->harq_processes[i]);
 
       if (dlsch->harq_processes[i]) {
@@ -169,9 +170,9 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
         dlsch->harq_processes[i]->b = (unsigned char *)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
 
         if (dlsch->harq_processes[i]->b) {
-          bzero(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
+          memset(dlsch->harq_processes[i]->b,0,MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
         } else {
-          printf("Can't get b\n");
+          AssertFatal(1==0,"Can't get b\n");
           exit_flag=1;
         }
 
@@ -181,15 +182,15 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
             dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(((r==0)?8:0) + 3+ 768);
 
             if (dlsch->harq_processes[i]->c[r]) {
-              bzero(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+ 768);
+              memset(dlsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+ 768);
             } else {
-              printf("Can't get c\n");
+              AssertFatal(1==0,"Can't get c\n");
               exit_flag=2;
             }
           }
         }
       } else {
-        printf("Can't get harq_p %d\n",i);
+        AssertFatal(1==0,"Can't get harq_p %d\n",i);
         exit_flag=3;
       }
     }
@@ -203,7 +204,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
     }
   }
 
-  LOG_D(PHY,"new_eNB_dlsch exit flag %d, size of  %ld\n",
+  LOG_I(PHY,"new_eNB_dlsch exit flag %d, size of  %ld\n",
         exit_flag, sizeof(LTE_eNB_DLSCH_t));
   free_eNB_dlsch(dlsch);
   return(NULL);
@@ -360,6 +361,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
 
   proc->nbEncode=0;
 
+
   //  if (hadlsch->Ndi == 1) {  // this is a new packet
   if (hadlsch->round == 0) {  // this is a new packet
     // Add 24-bit crc (polynomial A) to payload
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
index 347fbb026be76a8a14f159f3bd774c5f30562386..aba4a464f2bcbbfbef7b008b4801216891674ea0 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
@@ -2375,16 +2375,14 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
   for (l=num_pdcch_symbols; l<nsymb; l++) {
 
   if (dlsch0 != NULL ) {
-#ifdef DEBUG_DLSCH_MODULATION
-    LOG_I(PHY,"Generating DLSCH (harq_pid %d,mimo %d, pmi_alloc0 %lx, mod0 %d, mod1 %d, rb_alloc[0] %d)\n",
-            harq_pid,
+     LOG_D(PHY,"Generating DLSCH (num_pdcch_symb %d harq_pid %d,mimo %d, pmi_alloc0 %lx, mod0 %d, mod1 %d, rb_alloc[0] %x)\n",
+            num_pdcch_symbols,harq_pid,
             dlsch0_harq->mimo_mode,
             pmi2hex_2Ar2(dlsch0_harq->pmi_alloc),
             mod_order0,
             mod_order1,
             rb_alloc[0]
             );
-#endif
   }
 
     if (frame_parms->Ncp==0) { // normal prefix
@@ -2980,7 +2978,7 @@ int allocate_REs_in_RB_MCH_khz_1dot25(int32_t **txdataF,
 
       case 2:  //QPSK
 
-                  LOG_D(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+      LOG_D(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
       ((int16_t*)&txdataF[0][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
 
       *jj = *jj + 1;
@@ -3082,7 +3080,7 @@ int mch_modulation_khz_1dot25(int32_t **txdataF,
   uint8_t skip_dc=0;
   uint8_t mod_order = dlsch->harq_processes[0]->Qm;
   int16_t qam16_table_a[4],qam64_table_a[8];//,qam16_table_b[4],qam64_table_b[8];
-  int16_t *qam_table_s;
+  int16_t *qam_table_s=qam16_table_a;
 
   nsymb_pmch = 1;
   nsymb = (frame_parms->Ncp == NORMAL) ? 14 : 12;
@@ -3125,12 +3123,8 @@ int mch_modulation_khz_1dot25(int32_t **txdataF,
 
       }
 
-      if (mod_order == 4)
-        qam_table_s = qam16_table_a;
-      else if (mod_order == 6)
+      if (mod_order == 6)
         qam_table_s = qam64_table_a;
-      else
-        qam_table_s = NULL;
 
       //LOG_I(PHY,"Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp);
       allocate_REs_in_RB_MCH_khz_1dot25(txdataF,
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
index d48164e07d605a16aa27e3c81415c85879585f67..015a95a8624744b631f844b0dc442bc08db3844a 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
@@ -113,15 +113,12 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
     x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell_mbsfn; //this is c_init in 36.211 Sec 6.3.1 for PMCH
   }
 
-#ifdef DEBUG_SCRAMBLING
-  printf("scrambling: i0 %d rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->i0,dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2);
-#endif
   s = lte_gold_generic(&x1, &x2, 1);
 
   for (n=0; n<(1+(G>>5)); n++) {
 #ifdef DEBUG_SCRAMBLING
 
-    for (int k=0; k<32; k++) printf("scrambling %d : %d xor %d = %d\n",k+(n<<5),e[k],(s>>k)&1,e[k]^((s>>k)&1));
+    for (int k=0; k<32; k++) printf("scrambling %d : %x xor %x = %d\n",k+(n<<5),e[k],(s>>k)&1,e[k]^((s>>k)&1));
 
 #endif
     e[0] = (e[0]) ^ (s&1);
diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
index 95ad42002823d5f836bf303369c9b8c899f915aa..09c0b4ba0f80a39ddf83c403035e92506b0b9062 100644
--- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
@@ -30,10 +30,13 @@
 * \warning
 */
 
-#include "PHY/defs_eNB.h"
+#include <stdio.h>
+//#include "PHY/defs_eNB.h"
+#include "PHY/defs_RU.h"
 #include "PHY/TOOLS/alaw_lut.h"
-#include "PHY/phy_extern.h"
-#include "SCHED/sched_eNB.h"
+//#include "PHY/phy_extern.h"
+//#include "SCHED/sched_eNB.h"
+lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
 
 //#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
 #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c
index f39f3ef872021d12fb73273f7a165e104d59cf75..e2bec337aa44be16b556b2b78ea8834cec179473 100644
--- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c
@@ -31,11 +31,11 @@
 */
 
 #include <time.h>
-#include "PHY/defs_eNB.h"
+#include <stdio.h>
+#include "PHY/defs_RU.h"
 #include "PHY/TOOLS/alaw_lut.h"
 //#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
 #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
-#include <intertask_interface.h>
 #include "common/utils/LOG/vcd_signal_dumper.h"
 //#define DEBUG_DL_MOBIPASS
 //#define DEBUG_UL_MOBIPASS
@@ -1469,7 +1469,7 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
         // HYPOTHESIS: first packet per subframe has lowest timestamp of subframe
         // should detect out of order and act accordingly ....
         AssertFatal(aid==0 || aid==1,"aid %d != 0 or 1\n",aid);
-        //LOG_I(PHY,"rxp[%d] %p, dest %p, offset %d (%lld,%lld)\n",aid,rxp[aid],rxp[aid]+(timestamp[packet_id]-timestamp[0]),(timestamp[packet_id]-timestamp[0]),timestamp[packet_id],timestamp[0]);
+        LOG_D(PHY,"rxp[%d] %p, dest %p, offset %d (%llu,%llu)\n",aid,rxp[aid],rxp[aid]+(timestamp[packet_id]-timestamp[0]),(int)(timestamp[packet_id]-timestamp[0]),(long long unsigned int)timestamp[packet_id],(long long unsigned int)timestamp[0]);
         memcpy((void*)(rxp[aid]+(timestamp[packet_id]-timestamp[0])),
                (void*)temp_rx,
                spp_eth<<2);
diff --git a/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c b/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c
index b249052cbf26c477276f251a7c502cd0b3b4c0cb..a23f8db4f28f0a3c861e65281904287f7c2f8634 100644
--- a/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c
+++ b/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c
@@ -41,7 +41,7 @@ extern inline  uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t res
   {
       // Init value for x1: x1(0) = 1, x1(n) = 0, n=1,2,...,30
       // x1(31) = [x1(3) + x1(0)]mod2 = 1
-      *x1 = 1 + (1<<31);
+      *x1 = 1 + (1U<<31);
       // Init value for x2: cinit = sum_{i=0}^30 x2*2^i
       // x2(31) = [x2(3)    + x2(2)    + x2(1)    + x2(0)]mod2
       //        =  (*x2>>3) ^ (*x2>>2) + (*x2>>1) + *x2
diff --git a/openair1/PHY/LTE_TRANSPORT/pbch.c b/openair1/PHY/LTE_TRANSPORT/pbch.c
index dfa990269ec864293d57ebf0eac259cd4d483b91..8e9a9688274bb38ca22581b85d4da8b849396fe5 100644
--- a/openair1/PHY/LTE_TRANSPORT/pbch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pbch.c
@@ -72,6 +72,7 @@ int allocate_pbch_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
   first_re=0;
   last_re=12;
 
+
   for (re=first_re; re<last_re; re++) {
 
     tti_offset = symbol_offset + re_off + re;
diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c
index 7b508239a9fa6090fadad3da69ef733a2cbcfece..37fe0d17ae88a0973cc6b1f280ffee1815d0a9cc 100644
--- a/openair1/PHY/LTE_TRANSPORT/pmch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pmch.c
@@ -24,22 +24,6 @@
 #include "transport_eNB.h"
 #include "transport_proto.h"
 #include "transport_common_proto.h"
-// Mask for identifying subframe for MBMS
-#define MBSFN_TDD_SF3 0x80// for TDD
-#define MBSFN_TDD_SF4 0x40
-#define MBSFN_TDD_SF7 0x20
-#define MBSFN_TDD_SF8 0x10
-#define MBSFN_TDD_SF9 0x08
-
-
-
-#define MBSFN_FDD_SF1 0x80// for FDD
-#define MBSFN_FDD_SF2 0x40
-#define MBSFN_FDD_SF3 0x20
-#define MBSFN_FDD_SF6 0x10
-#define MBSFN_FDD_SF7 0x08
-#define MBSFN_FDD_SF8 0x04
-
 
 
 
diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c
index 9e0fa239f67050ea51b17a040480f713fab15842..eb46a8d663df1d670857d0ad247945467024dcc8 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach.c
@@ -31,7 +31,7 @@
  */
 #include "PHY/sse_intrin.h"
 #include "PHY/defs_eNB.h"
-#include "PHY/phy_extern.h"
+//#include "PHY/phy_extern.h"
 //#include "prach.h"
 #include "PHY/LTE_TRANSPORT/if4_tools.h"
 
@@ -40,6 +40,7 @@
 #include "prach_extern.h"
 #include <openair1/PHY/LTE_TRANSPORT/transport_proto.h>
 #include <executables/split_headers.h>
+#include "common/utils/lte/prach_utils.h"
 
 void rx_prach0(PHY_VARS_eNB *eNB,
                RU_t *ru,
@@ -84,7 +85,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
   uint8_t aa;
   int32_t lev;
   int16_t levdB;
-  int fft_size,log2_ifft_size;
+  int fft_size=0,log2_ifft_size;
   int16_t prach_ifft_tmp[2048*2] __attribute__((aligned(32)));
   int32_t *prach_ifft=(int32_t *)NULL;
   int32_t **prach_ifftp=(int32_t **)NULL;
@@ -112,7 +113,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
     prach_ConfigIndex   = fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[ce_level];
     Ncs_config          = fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
     restricted_set      = fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag;
-    n_ra_prb            = get_prach_prb_offset(fp,prach_ConfigIndex,
+    n_ra_prb            = get_prach_prb_offset(fp->frame_type,fp->tdd_config,fp->N_RB_UL,fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[ce_level],
                           fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],
                           tdd_mapindex,Nf);
     // update pointers to results for ce_level
@@ -124,7 +125,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
     prach_ConfigIndex   = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
     Ncs_config          = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
     restricted_set      = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag;
-    n_ra_prb            = get_prach_prb_offset(fp,prach_ConfigIndex,
+    n_ra_prb            = get_prach_prb_offset(fp->frame_type,fp->tdd_config,fp->N_RB_UL,fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
                           fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,
                           tdd_mapindex,Nf);
   }
@@ -140,7 +141,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
       rxsigF              = eNB->prach_vars_br.rxsigF[ce_level];
 
       if (LOG_DEBUGFLAG(PRACH)) {
-        if (((frame_prach)&1023) < 20) LOG_I(PHY,
+        if (((frame_prach)&1023) < 20) LOG_D(PHY,
               "PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n",
               br_flag,ce_level,frame_prach,subframe,
               fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],
@@ -153,24 +154,24 @@ void rx_prach0(PHY_VARS_eNB *eNB,
       prachF            = eNB->prach_vars.prachF;
       rxsigF            = eNB->prach_vars.rxsigF[0];
 
-      if (LOG_DEBUGFLAG(PRACH)) {
-        if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,
+      //if (LOG_DEBUGFLAG(PRACH)) {
+        if (((frame_prach)&1023) < 20) LOG_D(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,
               fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex,rootSequenceIndex);
-      }
+      //}
     }
   } else {
     if (br_flag == 1) {
       rxsigF            = ru->prach_rxsigF_br[ce_level];
 
       if (LOG_DEBUGFLAG(PRACH)) {
-        if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
+        if (((frame_prach)&1023) < 20) LOG_D(PHY,"PRACH (RU) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
               br_flag,ce_level,frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex);
       }
     } else {
       rxsigF            = ru->prach_rxsigF[0];
 
       if (LOG_DEBUGFLAG(PRACH)) {
-        if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
+        if (((frame_prach)&1023) < 20) LOG_D(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
               subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex);
       }
     }
@@ -299,11 +300,13 @@ void rx_prach0(PHY_VARS_eNB *eNB,
         case 6:
           if (prach_fmt == 4) {
             dft(DFT_256,prach2,rxsigF[aa],1);
+            fft_size=256;
           } else {
             dft(DFT_1536,prach2,rxsigF[aa],1);
 
             if (prach_fmt>1)
               dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
+            fft_size=1536;
           }
 
           break;
@@ -311,13 +314,14 @@ void rx_prach0(PHY_VARS_eNB *eNB,
         case 15:
           if (prach_fmt == 4) {
             dft(DFT_256,prach2,rxsigF[aa],1);
+            fft_size=256;
           } else {
             dft(DFT_3072,prach2,rxsigF[aa],1);
 
             if (prach_fmt>1)
               dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
           }
-
+          fft_size=3072;
           break;
 
         case 25:
@@ -339,11 +343,13 @@ void rx_prach0(PHY_VARS_eNB *eNB,
         case 50:
           if (prach_fmt == 4) {
             dft(DFT_2048,prach2,rxsigF[aa],1);
+            fft_size=2048;
           } else {
             dft(DFT_12288,prach2,rxsigF[aa],1);
 
             if (prach_fmt>1)
               dft(DFT_12288,prach2+24576,rxsigF[aa]+24576,1);
+            fft_size=12288;
           }
 
           break;
@@ -351,11 +357,13 @@ void rx_prach0(PHY_VARS_eNB *eNB,
         case 75:
           if (prach_fmt == 4) {
             dft(DFT_3072,prach2,rxsigF[aa],1);
+            fft_size=3072;
           } else {
             dft(DFT_18432,prach2,rxsigF[aa],1);
 
             if (prach_fmt>1)
               dft(DFT_18432,prach2+36864,rxsigF[aa]+36864,1);
+            fft_size=18432;
           }
 
           break;
@@ -364,20 +372,24 @@ void rx_prach0(PHY_VARS_eNB *eNB,
           if (fp->threequarter_fs==0) {
             if (prach_fmt == 4) {
               dft(DFT_4096,prach2,rxsigF[aa],1);
+              fft_size=2048;
             } else {
               dft(DFT_24576,prach2,rxsigF[aa],1);
 
               if (prach_fmt>1)
                 dft(DFT_24576,prach2+49152,rxsigF[aa]+49152,1);
+              fft_size=24576;
             }
           } else {
             if (prach_fmt == 4) {
               dft(DFT_3072,prach2,rxsigF[aa],1);
+              fft_size=3072;
             } else {
               dft(DFT_18432,prach2,rxsigF[aa],1);
 
               if (prach_fmt>1)
                 dft(DFT_18432,prach2+36864,rxsigF[aa]+36864,1);
+              fft_size=18432;
             }
           }
 
@@ -547,7 +559,6 @@ void rx_prach0(PHY_VARS_eNB *eNB,
     }
 
     log2_ifft_size = 10;
-    fft_size = 6144;
 
     if (new_dft == 1) {
       new_dft = 0;
diff --git a/openair1/PHY/LTE_TRANSPORT/prach_common.c b/openair1/PHY/LTE_TRANSPORT/prach_common.c
index 393d4ca3f8bfd4c475dfbdfdbdfe9bef3f9582cb..e366e8edbc9008c1e5435fcdb4fb18405d6d4729 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach_common.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach_common.c
@@ -34,7 +34,7 @@
 #include "PHY/phy_extern.h"
 #include "PHY/phy_extern_ue.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
-
+#include "common/utils/lte/prach_utils.h"
 
 uint16_t NCS_unrestricted[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419};
 uint16_t NCS_restricted[15]   = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; // high-speed case
@@ -44,6 +44,9 @@ int16_t ru[2*839]; // quantized roots of unity
 uint32_t ZC_inv[839]; // multiplicative inverse for roots u
 uint16_t du[838];
 
+extern PRACH_TDD_PREAMBLE_MAP tdd_preamble_map[64][7];
+
+/*
 // This is table 5.7.1-4 from 36.211
 PRACH_TDD_PREAMBLE_MAP tdd_preamble_map[64][7] = {
   // TDD Configuration Index 0
@@ -254,7 +257,7 @@ PRACH_TDD_PREAMBLE_MAP tdd_preamble_map[64][7] = {
   }
 };
 
-
+*/
 
 uint16_t prach_root_sequence_map0_3[838] = { 129, 710, 140, 699, 120, 719, 210, 629, 168, 671, 84, 755, 105, 734, 93, 746, 70, 769, 60, 779,
                                              2, 837, 1, 838,
@@ -378,192 +381,13 @@ uint8_t get_fid_prach_tdd(module_id_t Mod_id,uint8_t tdd_map_index) {
   return(tdd_preamble_map[fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex][fp->tdd_config].map[tdd_map_index].f_ra);
 }
 
-uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type) {
-  if (frame_type == FDD) // FDD
-    return(prach_ConfigIndex>>4);
-  else {
-    if (prach_ConfigIndex < 20)
-      return (0);
-
-    if (prach_ConfigIndex < 30)
-      return (1);
-
-    if (prach_ConfigIndex < 40)
-      return (2);
-
-    if (prach_ConfigIndex < 48)
-      return (3);
-    else
-      return (4);
-  }
-}
-
-uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms,
-                             uint8_t prach_ConfigIndex,
-                             uint8_t n_ra_prboffset,
-                             uint8_t tdd_mapindex, uint16_t Nf) {
-  lte_frame_type_t frame_type         = frame_parms->frame_type;
-  uint8_t tdd_config         = frame_parms->tdd_config;
-  uint8_t n_ra_prb;
-  uint8_t f_ra,t1_ra;
-  uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
-  uint8_t Nsp=2;
-
-  if (frame_type == TDD) { // TDD
-    if (tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach==0) {
-      LOG_E(PHY, "Illegal prach_ConfigIndex %"PRIu8"", prach_ConfigIndex);
-      return(-1);
-    }
-
-    // adjust n_ra_prboffset for frequency multiplexing (p.36 36.211)
-    f_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[tdd_mapindex].f_ra;
-
-    if (prach_fmt < 4) {
-      if ((f_ra&1) == 0) {
-        n_ra_prb = n_ra_prboffset + 6*(f_ra>>1);
-      } else {
-        n_ra_prb = frame_parms->N_RB_UL - 6 - n_ra_prboffset + 6*(f_ra>>1);
-      }
-    } else {
-      if ((tdd_config >2) && (tdd_config<6))
-        Nsp = 2;
-
-      t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra;
-
-      if ((((Nf&1)*(2-Nsp)+t1_ra)&1) == 0) {
-        n_ra_prb = 6*f_ra;
-      } else {
-        n_ra_prb = frame_parms->N_RB_UL - 6*(f_ra+1);
-      }
-    }
-  } else { //FDD
-    n_ra_prb = n_ra_prboffset;
-  }
-
-  return(n_ra_prb);
-}
-
-int is_prach_subframe0(LTE_DL_FRAME_PARMS *frame_parms,uint8_t prach_ConfigIndex,uint32_t frame, uint8_t subframe) {
-  //  uint8_t prach_ConfigIndex  = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
-  uint8_t tdd_config         = frame_parms->tdd_config;
-  uint8_t t0_ra;
-  uint8_t t1_ra;
-  uint8_t t2_ra;
-  int prach_mask = 0;
-
-  if (frame_parms->frame_type == FDD) { //FDD
-    //implement Table 5.7.1-2 from 36.211 (Rel-10, p.41)
-    if ((((frame&1) == 1) && (subframe < 9)) ||
-        (((frame&1) == 0) && (subframe == 9)))  // This is an odd frame, ignore even-only PRACH frames
-      if (((prach_ConfigIndex&0xf)<3) || // 0,1,2,16,17,18,32,33,34,48,49,50
-          ((prach_ConfigIndex&0x1f)==18) || // 18,50
-          ((prach_ConfigIndex&0xf)==15))   // 15,47
-        return(0);
-
-    switch (prach_ConfigIndex&0x1f) {
-      case 0:
-      case 3:
-        if (subframe==1) prach_mask = 1;
-
-        break;
-
-      case 1:
-      case 4:
-        if (subframe==4) prach_mask = 1;
-
-        break;
-
-      case 2:
-      case 5:
-        if (subframe==7) prach_mask = 1;
-
-        break;
-
-      case 6:
-        if ((subframe==1) || (subframe==6)) prach_mask=1;
-
-        break;
-
-      case 7:
-        if ((subframe==2) || (subframe==7)) prach_mask=1;
-
-        break;
-
-      case 8:
-        if ((subframe==3) || (subframe==8)) prach_mask=1;
-
-        break;
-
-      case 9:
-        if ((subframe==1) || (subframe==4) || (subframe==7)) prach_mask=1;
-
-        break;
-
-      case 10:
-        if ((subframe==2) || (subframe==5) || (subframe==8)) prach_mask=1;
-
-        break;
-
-      case 11:
-        if ((subframe==3) || (subframe==6) || (subframe==9)) prach_mask=1;
-
-        break;
-
-      case 12:
-        if ((subframe&1)==0) prach_mask=1;
-
-        break;
-
-      case 13:
-        if ((subframe&1)==1) prach_mask=1;
-
-        break;
-
-      case 14:
-        prach_mask=1;
-        break;
-
-      case 15:
-        if (subframe==9) prach_mask=1;
-
-        break;
-    }
-  } else { // TDD
-    AssertFatal(prach_ConfigIndex<64,
-                "Illegal prach_ConfigIndex %d for ",prach_ConfigIndex);
-    AssertFatal(tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach>0,
-                "Illegal prach_ConfigIndex %d for ",prach_ConfigIndex);
-    t0_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t0_ra;
-    t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra;
-    t2_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t2_ra;
-#ifdef PRACH_DEBUG
-    LOG_I(PHY,"[PRACH] Checking for PRACH format (ConfigIndex %d) in TDD subframe %d (%d,%d,%d)\n",
-          prach_ConfigIndex,
-          subframe,
-          t0_ra,t1_ra,t2_ra);
-#endif
-
-    if ((((t0_ra == 1) && ((frame &1)==0))||  // frame is even and PRACH is in even frames
-         ((t0_ra == 2) && ((frame &1)==1))||  // frame is odd and PRACH is in odd frames
-         (t0_ra == 0)) &&                                // PRACH is in all frames
-        (((subframe<5)&&(t1_ra==0)) ||                   // PRACH is in 1st half-frame
-         (((subframe>4)&&(t1_ra==1))))) {                // PRACH is in 2nd half-frame
-      if ((prach_ConfigIndex<48) &&                          // PRACH only in normal UL subframe
-          (((subframe%5)-2)==t2_ra)) prach_mask=1;
-      else if ((prach_ConfigIndex>47) && (((subframe%5)-1)==t2_ra)) prach_mask=1;      // PRACH can be in UpPTS
-    }
-  }
-
-  return(prach_mask);
-}
-
 int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms, uint32_t frame, uint8_t subframe) {
   uint8_t prach_ConfigIndex  = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
-  int prach_mask             = is_prach_subframe0(frame_parms, prach_ConfigIndex, frame, subframe);
+  int prach_mask             = is_prach_subframe0(frame_parms->tdd_config,frame_parms->frame_type, prach_ConfigIndex, frame, subframe);
 
   for (int i=0; i<4; i++) {
     if (frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i] == 1)
-      prach_mask |= (is_prach_subframe0(frame_parms, frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i],
+      prach_mask |= (is_prach_subframe0(frame_parms->tdd_config,frame_parms->frame_type, frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i],
                                         frame, subframe) << (i+1));
   }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/prach_extern.h b/openair1/PHY/LTE_TRANSPORT/prach_extern.h
index 47fbd93ad7c964d2a15dd5215ca315e80a69f90b..3404646923adc9175b78a018f099f9ff2058a748 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach_extern.h
+++ b/openair1/PHY/LTE_TRANSPORT/prach_extern.h
@@ -35,7 +35,7 @@
 
 #include "PHY/sse_intrin.h"
 #include "PHY/defs_eNB.h"
-#include "PHY/phy_extern.h"
+//#include "PHY/phy_extern.h"
 
 //#define PRACH_DEBUG 1
 //#define PRACH_WRITE_OUTPUT_DEBUG 1
@@ -74,17 +74,6 @@ uint8_t get_num_prach_tdd(module_id_t Mod_id);
 uint8_t get_fid_prach_tdd(module_id_t Mod_id,uint8_t tdd_map_index);
 
 
-uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type);
-
-
-uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, 
-			     uint8_t prach_ConfigIndex, 
-			     uint8_t n_ra_prboffset,
-			     uint8_t tdd_mapindex, uint16_t Nf); 
-
-
-int is_prach_subframe0(LTE_DL_FRAME_PARMS *frame_parms,uint8_t prach_ConfigIndex,uint32_t frame, uint8_t subframe);
-
 int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe);
 
 
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index c72fa1b4802ac37e10fde2517260856767b7cf64..32700664480e2d9a37a60b2ead13dfcbacc0221a 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -65,10 +65,41 @@ int16_t cfo_pucch_ep[24*6] = {24278,-22005,29621,-14010,32412,-4808,32412,4807,2
 
 
 
+void dump_uci_stats(FILE *fd,PHY_VARS_eNB *eNB,int frame) {
+
+  int strpos=0;
+  char output[16384];
+
+  for (int i=0;i<NUMBER_OF_SCH_STATS_MAX;i++){
+    if (eNB->uci_stats[i].rnti>0) {
+      eNB_UCI_STATS_t *uci_stats = &eNB->uci_stats[i];
+      strpos+=sprintf(output+strpos,"UCI %d RNTI %x: pucch1_trials %d, pucch1_n0 %d dB, pucch1_thres %d dB, current pucch1_stat_pos %d dB, current pucch1_stat_neg %d dB, positive SR count %d\n",
+	i,uci_stats->rnti,uci_stats->pucch1_trials,eNB->measurements.n0_pucch_dB/*max(eNB->measurements.n0_subband_power_tot_dB[0], eNB->measurements.n0_subband_power_tot_dB[eNB->frame_parms.N_RB_UL-1])*/,uci_stats->pucch1_thres,dB_fixed(uci_stats->current_pucch1_stat_pos),dB_fixed(uci_stats->current_pucch1_stat_neg),uci_stats->pucch1_positive_SR);
+      strpos+=sprintf(output+strpos,"UCI %d RNTI %x: pucch1_low (%d,%d)dB pucch1_high (%d,%d)dB\n",
+	    i,uci_stats->rnti,
+            dB_fixed(uci_stats->pucch1_low_stat[0]),
+            dB_fixed(uci_stats->pucch1_low_stat[1]),
+            dB_fixed(uci_stats->pucch1_high_stat[0]),
+            dB_fixed(uci_stats->pucch1_high_stat[1]));
+      
+      strpos+=sprintf(output+strpos,"UCI %d RNTI %x: pucch1a_trials %d, pucch1a_stat (%d,%d), pucch1b_trials %d, pucch1b_stat (%d,%d) pucch1ab_DTX %d\n",
+            i,uci_stats->rnti,
+            uci_stats->pucch1a_trials,
+            uci_stats->current_pucch1a_stat_re,
+            uci_stats->current_pucch1a_stat_im,
+            uci_stats->pucch1b_trials,
+	    uci_stats->current_pucch1b_stat_re,
+	    uci_stats->current_pucch1b_stat_im,
+            uci_stats->pucch1ab_DTX);
+    }
+  }
+  if (fd) fprintf(fd,"%s",output);
+  else    printf("%s",output);  
+}
 /* PUCCH format3 >> */
 /* SubCarrier Demap */
 uint16_t pucchfmt3_subCarrierDeMapping( PHY_VARS_eNB *eNB,
-                                        int16_t SubCarrierDeMapData[NB_ANTENNAS_RX][14][12][2],
+                                        int16_t SubCarrierDeMapData[4][14][12][2],
                                         uint16_t n3_pucch ) {
   LTE_eNB_COMMON *eNB_common_vars  = &eNB->common_vars;
   LTE_DL_FRAME_PARMS  *frame_parms = &eNB->frame_parms;
@@ -118,8 +149,8 @@ uint16_t pucchfmt3_subCarrierDeMapping( PHY_VARS_eNB *eNB,
 }
 
 /* cyclic shift hopping remove */
-uint16_t pucchfmt3_Baseseq_csh_remove( int16_t SubCarrierDeMapData[NB_ANTENNAS_RX][14][12][2],
-                                       int16_t CshData_fmt3[NB_ANTENNAS_RX][14][12][2],
+uint16_t pucchfmt3_Baseseq_csh_remove( int16_t SubCarrierDeMapData[4][14][12][2],
+                                       int16_t CshData_fmt3[4][14][12][2],
                                        LTE_DL_FRAME_PARMS *frame_parms,
                                        uint8_t subframe,
                                        uint8_t ncs_cell[20][7] ) {
@@ -169,9 +200,9 @@ const int16_t TBL_3_SF5_GEN_N_DASH_NS[MAXROW_TBL_SF5_OS_IDX] = {0,3,6,8,10};
 const int16_t TBL_3_SF4_GEN_N_DASH_NS[MAXROW_TBL_SF4_OS_IDX] = {0,3,6,9};
 
 /* Channel estimation */
-uint16_t pucchfmt3_ChannelEstimation( int16_t SubCarrierDeMapData[NB_ANTENNAS_RX][14][12][2],
-                                      double delta_theta[NB_ANTENNAS_RX][12],
-                                      int16_t ChestValue[NB_ANTENNAS_RX][2][12][2],
+uint16_t pucchfmt3_ChannelEstimation( int16_t SubCarrierDeMapData[4][14][12][2],
+                                      double delta_theta[4][12],
+                                      int16_t ChestValue[4][2][12][2],
                                       int16_t *Interpw,
                                       uint8_t subframe,
                                       uint8_t shortened_format,
@@ -183,12 +214,12 @@ uint16_t pucchfmt3_ChannelEstimation( int16_t SubCarrierDeMapData[NB_ANTENNAS_RX
   int16_t         np, np_n, ip_ind=-1;
   //int16_t         npucch_sf;
   int16_t         calctmp[2];
-  int16_t         BsCshData[NB_ANTENNAS_RX][D_NSYM1SF][D_NSC1RB][2];
-  //int16_t         delta_theta_calctmp[NB_ANTENNAS_RX][4][D_NSC1RB][2], delta_theta_comp[NB_ANTENNAS_RX][D_NSC1RB][2];
-  int16_t         delta_theta_comp[NB_ANTENNAS_RX][D_NSC1RB][2];
-  int16_t         CsData_allavg[NB_ANTENNAS_RX][14][2];
-  int16_t         CsData_temp[NB_ANTENNAS_RX][D_NSYM1SF][D_NSC1RB][2];
-  int32_t         IP_CsData_allsfavg[NB_ANTENNAS_RX][14][4][2];
+  int16_t         BsCshData[4][D_NSYM1SF][D_NSC1RB][2];
+  //int16_t         delta_theta_calctmp[4][4][D_NSC1RB][2], delta_theta_comp[4][D_NSC1RB][2];
+  int16_t         delta_theta_comp[4][D_NSC1RB][2];
+  int16_t         CsData_allavg[4][14][2];
+  int16_t         CsData_temp[4][D_NSYM1SF][D_NSC1RB][2];
+  int32_t         IP_CsData_allsfavg[4][14][4][2];
   int32_t         IP_allavg[D_NPUCCH_SF5];
   //int16_t         temp_ch[2];
   int16_t         m[NUMBER_OF_UE_MAX], m_self=0, same_m_number;
@@ -432,9 +463,9 @@ uint16_t pucchfmt3_ChannelEstimation( int16_t SubCarrierDeMapData[NB_ANTENNAS_RX
 }
 
 /* Channel Equalization */
-uint16_t pucchfmt3_Equalization( int16_t CshData_fmt3[NB_ANTENNAS_RX][14][12][2],
-                                 int16_t ChdetAfterValue_fmt3[NB_ANTENNAS_RX][14][12][2],
-                                 int16_t ChestValue[NB_ANTENNAS_RX][2][12][2],
+uint16_t pucchfmt3_Equalization( int16_t CshData_fmt3[4][14][12][2],
+                                 int16_t ChdetAfterValue_fmt3[4][14][12][2],
+                                 int16_t ChestValue[4][2][12][2],
                                  LTE_DL_FRAME_PARMS *frame_parms) {
   int16_t aa, sltNo, symNo, k;
 
@@ -457,9 +488,9 @@ uint16_t pucchfmt3_Equalization( int16_t CshData_fmt3[NB_ANTENNAS_RX][14][12][2]
 }
 
 /* Frequency deviation remove AFC */
-uint16_t pucchfmt3_FrqDevRemove( int16_t ChdetAfterValue_fmt3[NB_ANTENNAS_RX][14][12][2],
-                                 double delta_theta[NB_ANTENNAS_RX][12],
-                                 int16_t RemoveFrqDev_fmt3[NB_ANTENNAS_RX][2][5][12][2],
+uint16_t pucchfmt3_FrqDevRemove( int16_t ChdetAfterValue_fmt3[4][14][12][2],
+                                 double delta_theta[4][12],
+                                 int16_t RemoveFrqDev_fmt3[4][2][5][12][2],
                                  LTE_DL_FRAME_PARMS *frame_parms ) {
   int16_t aa, sltNo, symNo1slt, k, n;
   double calctmp[2];
@@ -509,8 +540,8 @@ const int16_t TBL_3_SF4[MAXROW_TBL_SF4_fmt3][MAXCLM_TBL_SF4][2] = {
 };
 
 /* orthogonal sequence remove */
-uint16_t pucchfmt3_OrthSeqRemove( int16_t RemoveFrqDev_fmt3[NB_ANTENNAS_RX][2][5][12][2],
-                                  int16_t Fmt3xDataRmvOrth[NB_ANTENNAS_RX][2][5][12][2],
+uint16_t pucchfmt3_OrthSeqRemove( int16_t RemoveFrqDev_fmt3[4][2][5][12][2],
+                                  int16_t Fmt3xDataRmvOrth[4][2][5][12][2],
                                   uint8_t shortened_format,
                                   uint16_t n3_pucch,
                                   LTE_DL_FRAME_PARMS *frame_parms ) {
@@ -556,7 +587,7 @@ uint16_t pucchfmt3_OrthSeqRemove( int16_t RemoveFrqDev_fmt3[NB_ANTENNAS_RX][2][5
 }
 
 /* averaging antenna */
-uint16_t pucchfmt3_AvgAnt( int16_t Fmt3xDataRmvOrth[NB_ANTENNAS_RX][2][5][12][2],
+uint16_t pucchfmt3_AvgAnt( int16_t Fmt3xDataRmvOrth[4][2][5][12][2],
                            int16_t Fmt3xDataAvgAnt[2][5][12][2],
                            uint8_t shortened_format,
                            LTE_DL_FRAME_PARMS *frame_parms ) {
@@ -856,7 +887,7 @@ uint32_t calc_pucch_1x_interference(PHY_VARS_eNB *eNB,
 
 uint32_t rx_pucch(PHY_VARS_eNB *eNB,
                   PUCCH_FMT_t fmt,
-                  uint8_t UE_id,
+                  uint8_t UCI_id,
                   uint16_t n1_pucch,
                   uint16_t n2_pucch,
                   uint8_t shortened_format,
@@ -871,15 +902,15 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
   static int first_call = 1;
   LTE_eNB_COMMON *common_vars = &eNB->common_vars;
   LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
-  int8_t sigma2_dB = eNB->measurements.n0_pucch_dB;
+  int8_t sigma2_dB = /*max(eNB->measurements.n0_subband_power_tot_dB[0], eNB->measurements.n0_subband_power_tot_dB[eNB->frame_parms.N_RB_UL-1]); */eNB->measurements.n0_pucch_dB;
 
   uint32_t u,v,n,aa;
   uint32_t z[12*14];
   int16_t *zptr;
-  int16_t rxcomp[NB_ANTENNAS_RX][2*12*14];
+  int16_t rxcomp[4][2*12*14];
   uint8_t ns,N_UL_symb,nsymb,n_oc,n_oc0,n_oc1;
   uint8_t c = (frame_parms->Ncp==0) ? 3 : 2;
-  uint16_t nprime,nprime0,nprime1;
+  int16_t nprime,nprime0,nprime1;
   uint16_t i,j,re_offset,thres,h,off;
   uint8_t Nprime_div_deltaPUCCH_Shift,Nprime,d;
   uint8_t m,l,refs,phase,re,l2,phase_max=0;
@@ -887,12 +918,12 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
   int16_t tmp_re,tmp_im,W_re=0,W_im=0;
   int16_t *rxptr;
   uint32_t symbol_offset;
-  int16_t stat_ref_re,stat_ref_im,*cfo;
-  int16_t chest0_re[NB_ANTENNAS_RX][12],chest0_im[NB_ANTENNAS_RX][12];
-  int16_t chest1_re[NB_ANTENNAS_RX][12],chest1_im[NB_ANTENNAS_RX][12];
+  int16_t stat0_ref_re[4],stat0_ref_im[4],stat1_ref_re[4],stat1_ref_im[4],*cfo;
+  int16_t chest0_re[4][12],chest0_im[4][12];
+  int16_t chest1_re[4][12],chest1_im[4][12];
   int32_t chest_mag;
-  int32_t stat_re=0,stat_im=0;
-  uint32_t stat,stat_max=0;
+  int32_t stat0_re[4],stat1_re[4],stat0_im[4],stat1_im[4];
+  uint32_t stat0[4],stat1[4],stat_max=0,stat0_max[4],stat1_max[4]; 
   uint8_t log2_maxh;
   uint8_t deltaPUCCH_Shift          = frame_parms->pucch_config_common.deltaPUCCH_Shift;
   uint8_t NRB2                      = frame_parms->pucch_config_common.nRB_CQI;
@@ -905,13 +936,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
   int chL;
   /* PUCCH format3 >> */
   uint16_t Ret = 0;
-  int16_t SubCarrierDeMapData[NB_ANTENNAS_RX][14][12][2];       //[Antenna][Symbol][Subcarrier][Complex]
-  int16_t CshData_fmt3[NB_ANTENNAS_RX][14][12][2];              //[Antenna][Symbol][Subcarrier][Complex]
-  double delta_theta[NB_ANTENNAS_RX][12];                       //[Antenna][Subcarrier][Complex]
-  int16_t ChestValue[NB_ANTENNAS_RX][2][12][2];                 //[Antenna][Slot][Subcarrier][Complex]
-  int16_t ChdetAfterValue_fmt3[NB_ANTENNAS_RX][14][12][2];      //[Antenna][Symbol][Subcarrier][Complex]
-  int16_t RemoveFrqDev_fmt3[NB_ANTENNAS_RX][2][5][12][2];       //[Antenna][Slot][PUCCH_Symbol][Subcarrier][Complex]
-  int16_t Fmt3xDataRmvOrth[NB_ANTENNAS_RX][2][5][12][2];        //[Antenna][Slot][PUCCH_Symbol][Subcarrier][Complex]
+  int16_t SubCarrierDeMapData[4][14][12][2];       //[Antenna][Symbol][Subcarrier][Complex]
+  int16_t CshData_fmt3[4][14][12][2];              //[Antenna][Symbol][Subcarrier][Complex]
+  double delta_theta[4][12];                       //[Antenna][Subcarrier][Complex]
+  int16_t ChestValue[4][2][12][2];                 //[Antenna][Slot][Subcarrier][Complex]
+  int16_t ChdetAfterValue_fmt3[4][14][12][2];      //[Antenna][Symbol][Subcarrier][Complex]
+  int16_t RemoveFrqDev_fmt3[4][2][5][12][2];       //[Antenna][Slot][PUCCH_Symbol][Subcarrier][Complex]
+  int16_t Fmt3xDataRmvOrth[4][2][5][12][2];        //[Antenna][Slot][PUCCH_Symbol][Subcarrier][Complex]
   int16_t Fmt3xDataAvgAnt[2][5][12][2];                         //[Slot][PUCCH_Symbol][Subcarrier][Complex]
   int16_t Fmt3xDataAvgSym[2][12][2];                            //[Slot][Subcarrier][Complex]
   int16_t IFFTOutData_Fmt3[2][12][2];                           //[Slot][Subcarrier][Complex]
@@ -941,9 +972,27 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
 
     first_call=0;
   }
-
+  eNB_UCI_STATS_t *uci_stats = NULL;
   if(fmt!=pucch_format3) {  /* PUCCH format3 */
+ 
+    eNB_UCI_STATS_t *first_uci_stats=NULL;
+    for (int i=0;i<NUMBER_OF_SCH_STATS_MAX;i++) 
+      if (eNB->uci_stats[i].rnti == eNB->uci_vars[UCI_id].rnti) { 
+        uci_stats = &eNB->uci_stats[i];
+        break;
+      } else if (first_uci_stats == NULL && eNB->uci_stats[i].rnti == 0) first_uci_stats = &eNB->uci_stats[i];
+
+    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;
     // TODO
     // "SR+ACK/NACK" length is only 7 bits.
     // This restriction will be lifted in the future.
@@ -1149,57 +1198,63 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
     // Do cfo correction and MRC across symbols
 
     if (fmt == pucch_format1) {
+      uci_stats->pucch1_trials++;
 #ifdef DEBUG_PUCCH_RX
       printf("Doing PUCCH detection for format 1\n");
 #endif
       stat_max = 0;
 
       for (phase=0; phase<7; phase++) {
-        stat=0;
-
+        int stat=0;
         for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
+	  stat0[aa]=0;stat1[aa]=0;
           for (re=0; re<12; re++) {
-            stat_re=0;
-            stat_im=0;
+	    stat0_re[aa]=0;
+	    stat0_im[aa]=0;
+	    stat1_re[aa]=0;
+	    stat1_im[aa]=0;
             off=re<<1;
             cfo =  (frame_parms->Ncp==0) ? &cfo_pucch_np[14*phase] : &cfo_pucch_ep[12*phase];
 
             for (l=0; l<(nsymb>>1); l++) {
-              stat_re += (((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15))/nsymb;
-              stat_im += (((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15))/nsymb;
+              stat0_re[aa] += (((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15))/nsymb;
+              stat0_im[aa] += (((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15))/nsymb;
               off+=2;
 #ifdef DEBUG_PUCCH_RX
               printf("[eNB] PUCCH subframe %d (%d,%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) , stat %d\n",subframe,phase,l,re,
                      rxcomp[aa][off],rxcomp[aa][1+off],
                      cfo[l<<1],cfo[1+(l<<1)],
-                     stat_re,stat_im,stat);
+                     stat0_re[aa],stat0_im[aa],stat);
 #endif
             }
 
             for (l2=0,l=(nsymb>>1); l < nsymb; l++,l2++) {
-              stat_re += (((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15))/nsymb;
-              stat_im += (((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15))/nsymb;
+              stat1_re[aa] += (((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15))/nsymb;
+              stat1_im[aa] += (((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15))/nsymb;
               off+=2;
 #ifdef DEBUG_PUCCH_RX
               printf("[eNB] PUCCH subframe %d (%d,%d,%d) => (%d,%d) x (%d,%d) : (%d,%d), stat %d\n",subframe,phase,l2,re,
                      rxcomp[aa][off],rxcomp[aa][1+off],
                      cfo[l2<<1],cfo[1+(l2<<1)],
-                     stat_re,stat_im,stat);
+                     stat1_re[aa],stat1_im[aa],stat);
 #endif
             }
-
-            stat += ((stat_re*stat_re) + (stat_im*stat_im));
+           
+            stat0[aa] += ((stat0_re[aa]*stat0_re[aa]) + (stat0_im[aa]*stat0_im[aa]));
+	    stat1[aa] += ((stat1_re[aa]*stat1_re[aa]) + (stat1_im[aa]*stat1_im[aa]));
           } //re
+          stat+=(stat0[aa]+stat1[aa]);
         } // aa
-
         if (stat>stat_max) {
           stat_max = stat;
           phase_max = phase;
+          for (aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
+             stat0_max[aa] = stat0[aa];
+             stat1_max[aa] = stat1[aa];
+          }
         }
       } //phase
 
-      //    stat_max *= nsymb;  // normalize to energy per symbol
-      //    stat_max /= (frame_parms->N_RB_UL*12); //
       stat_max /= 12;
 #ifdef DEBUG_PUCCH_RX
       printf("[eNB] PUCCH: stat %d, stat_max %d, phase_max %d\n", stat,stat_max,phase_max);
@@ -1207,12 +1262,14 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
 #ifdef DEBUG_PUCCH_RX
       LOG_I(PHY,"[eNB] PUCCH fmt1:  stat_max : %d, sigma2_dB %d (%d, %d), phase_max : %d\n",dB_fixed(stat_max),sigma2_dB,eNB->measurements.n0_subband_power_tot_dBm[6],pucch1_thres,phase_max);
 #endif
-      eNB->pucch1_stats[UE_id][(subframe<<10)+eNB->pucch1_stats_cnt[UE_id][subframe]] = stat_max;
-      eNB->pucch1_stats_thres[UE_id][(subframe<<10)+eNB->pucch1_stats_cnt[UE_id][subframe]] = sigma2_dB+pucch1_thres;
-      eNB->pucch1_stats_cnt[UE_id][subframe] = (eNB->pucch1_stats_cnt[UE_id][subframe]+1)&1023;
-      T(T_ENB_PHY_PUCCH_1_ENERGY, T_INT(eNB->Mod_id), T_INT(eNB->uci_vars[UE_id].rnti), T_INT(frame), T_INT(subframe),
+      eNB->pucch1_stats[UCI_id][(subframe<<10)+eNB->pucch1_stats_cnt[UCI_id][subframe]] = stat_max;
+      eNB->pucch1_stats_thres[UCI_id][(subframe<<10)+eNB->pucch1_stats_cnt[UCI_id][subframe]] = sigma2_dB+pucch1_thres;
+      eNB->pucch1_stats_cnt[UCI_id][subframe] = (eNB->pucch1_stats_cnt[UCI_id][subframe]+1)&1023;
+      uci_stats->pucch1_thres = sigma2_dB+pucch1_thres;
+      T(T_ENB_PHY_PUCCH_1_ENERGY, T_INT(eNB->Mod_id), T_INT(eNB->uci_vars[UCI_id].rnti), T_INT(frame), T_INT(subframe),
         T_INT(stat_max), T_INT(sigma2_dB+pucch1_thres));
 
+      
       /*
       if (eNB->pucch1_stats_cnt[UE_id][subframe] == 0) {
         LOG_M("pucch_debug.m","pucch_energy",
@@ -1226,11 +1283,18 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
       // This is a moving average of the PUCCH1 statistics conditioned on being above or below the threshold
       if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres))  {
         *payload = 1;
+        uci_stats->current_pucch1_stat_pos = stat_max;
+        for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
+          uci_stats->pucch1_low_stat[aa]=stat0_max[aa];
+          uci_stats->pucch1_high_stat[aa]=stat1_max[aa];
+          uci_stats->pucch1_positive_SR++;
+        }
       } else {
+        uci_stats->current_pucch1_stat_neg = stat_max;
         *payload = 0;
       }
 
-      if (UE_id==0) {
+      if (UCI_id==0) {
         VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SR_ENERGY,dB_fixed(stat_max));
         VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SR_THRES,sigma2_dB+pucch1_thres);
       }
@@ -1239,29 +1303,30 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
 #ifdef DEBUG_PUCCH_RX
       LOG_D(PHY,"Doing PUCCH detection for format 1a/1b\n");
 #endif
-
+      int stat_re=0,stat_im=0;
       for (phase=0; phase<7; phase++) {
-        stat=0;
-
+        int stat=0;
         for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
+          stat0[aa]=0;
+          stat1[aa]=0;
           for (re=0; re<12; re++) {
             // compute received energy first slot, seperately for data and reference
             // by coherent combining across symbols but not resource elements
             // Note: assumption is that channel is stationary over symbols in slot after CFO
-            stat_re=0;
-            stat_im=0;
-            stat_ref_re=0;
-            stat_ref_im=0;
+            stat0_re[aa]=0;
+            stat0_im[aa]=0;
+            stat0_ref_re[aa]=0;
+            stat0_ref_im[aa]=0;
             off=re<<1;
             cfo =  (frame_parms->Ncp==0) ? &cfo_pucch_np[14*phase] : &cfo_pucch_ep[12*phase];
 
             for (l=0; l<(nsymb>>1); l++) {
               if ((l<2)||(l>(nsymb>>1) - 3)) {  //data symbols
-                stat_re += ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15);
-                stat_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15);
+                stat0_re[aa] += ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15);
+                stat0_im[aa] += ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15);
               } else { //reference symbols
-                stat_ref_re += ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15);
-                stat_ref_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15);
+                stat0_ref_re[aa] += ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15);
+                stat0_ref_im[aa] += ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15);
               }
 
               off+=2;
@@ -1274,26 +1339,21 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
             }
 
             // this is total energy received, summed over data and reference
-            if (fmt==pucch_format1a){
-                   stat += ((((stat_re*stat_re)) + ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb);
-            }else{
-                   stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) +
-                             ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb);
-            }
-
+            stat0[aa] += ((((stat0_re[aa]*stat0_re[aa])) + ((stat0_im[aa]*stat0_im[aa])) +
+                      ((stat0_ref_re[aa]*stat0_ref_re[aa])) + ((stat0_ref_im[aa]*stat0_ref_im[aa])))/nsymb);
             // now second slot
-            stat_re=0;
-            stat_im=0;
-            stat_ref_re=0;
-            stat_ref_im=0;
+            stat1_re[aa]=0;
+            stat1_im[aa]=0;
+            stat1_ref_re[aa]=0;
+            stat1_ref_im[aa]=0;
 
             for (l2=0,l=(nsymb>>1); l< nsymb; l++,l2++) {
               if ((l2<2) || ((l2>(nsymb>>1) - 3)) ) {  // data symbols
-                stat_re += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15);
-                stat_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15);
+                stat1_re[aa] += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15);
+                stat1_im[aa] += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15);
               } else { //reference_symbols
-                stat_ref_re += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15);
-                stat_ref_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15);
+                stat1_ref_re[aa] += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15);
+                stat1_ref_im[aa] += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15);
               }
 
               off+=2;
@@ -1308,20 +1368,16 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
 #ifdef DEBUG_PUCCH_RX
             printf("aa%d re %d : phase %d : stat %d\n",aa,re,phase,stat);
 #endif
-            if (fmt==pucch_format1a){
-                   stat += ((((stat_re*stat_re)) + ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb);
-            }else{
-                   stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) +
-                             ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb);
-            }
-
+            stat1[aa] += ((((stat1_re[aa]*stat1_re[aa])) + ((stat1_im[aa]*stat1_im[aa])) +
+                      ((stat1_ref_re[aa]*stat1_ref_re[aa])) + ((stat1_ref_im[aa]*stat1_ref_im[aa])))/nsymb);
           } //re
+          stat+=(stat0[aa]+stat1[aa]);
         } // aa
 
 #ifdef DEBUG_PUCCH_RX
         LOG_D(PHY,"Format 1A: phase %d : stat %d\n",phase,stat);
 #endif
-
+        
         if (stat>stat_max) {
           stat_max = stat;
           phase_max = phase;
@@ -1332,8 +1388,6 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
 #ifdef DEBUG_PUCCH_RX
       LOG_I(PHY,"[eNB] PUCCH fmt1a/b:  stat_max : %d (%d : sigma2 %d), phase_max : %d\n",stat_max,dB_fixed(stat_max),sigma2_dB,phase_max);
 #endif
-      stat_re=0;
-      stat_im=0;
       // Do detection now
 
 
@@ -1341,13 +1395,12 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
       // For instance i assume to skip pucch1_thres from the test below.
       // Not 100% sure
         
-        if (sigma2_dB<(dB_fixed(stat_max) - (IS_SOFTMODEM_IQPLAYER?0:pucch1_thres)) ) {//
+      if (sigma2_dB<(dB_fixed(stat_max) - (IS_SOFTMODEM_IQPLAYER?0:pucch1_thres)) ) {//
         chL = (nsymb>>1)-4;
         chest_mag=0;
         cfo =  (frame_parms->Ncp==0) ? &cfo_pucch_np[14*phase_max] : &cfo_pucch_ep[12*phase_max];
 
         for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-          // channel estimates first
           for (re=0; re<12; re++) {
             // channel estimate for first slot
             chest0_re[aa][re]=0;
@@ -1381,6 +1434,11 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
 
         // now do channel matched filter
         for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
+          stat0_re[aa]=0;
+          stat0_im[aa]=0;
+          stat1_re[aa]=0;
+          stat1_im[aa]=0;
+
           for (re=0; re<12; re++) {
 #ifdef DEBUG_PUCCH_RX
             printf("[eNB] PUCCH subframe %d chest0[%d][%d] => (%d,%d)\n",subframe,aa,re,
@@ -1392,8 +1450,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
               off=(re<<1) + (24*l);
               tmp_re = ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15);
               tmp_im = ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15);
-              stat_re += (((tmp_re*chest0_re[aa][re])>>log2_maxh) + ((tmp_im*chest0_im[aa][re])>>log2_maxh));
-              stat_im += (((tmp_re*chest0_im[aa][re])>>log2_maxh) - ((tmp_im*chest0_re[aa][re])>>log2_maxh));
+              stat0_re[aa] += (((tmp_re*chest0_re[aa][re])>>log2_maxh) + ((tmp_im*chest0_im[aa][re])>>log2_maxh));
+              stat0_im[aa] += (((tmp_re*chest0_im[aa][re])>>log2_maxh) - ((tmp_im*chest0_re[aa][re])>>log2_maxh));
               off+=2;
 #ifdef DEBUG_PUCCH_RX
               printf("[eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) => (%d,%d)\n",subframe,l,re,
@@ -1409,8 +1467,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
               off=(re<<1) + (24*l);
               tmp_re = ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15);
               tmp_im = ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15);
-              stat_re += (((tmp_re*chest0_re[aa][re])>>log2_maxh) + ((tmp_im*chest0_im[aa][re])>>log2_maxh));
-              stat_im += (((tmp_re*chest0_im[aa][re])>>log2_maxh) - ((tmp_im*chest0_re[aa][re])>>log2_maxh));
+              stat0_re[aa] += (((tmp_re*chest0_re[aa][re])>>log2_maxh) + ((tmp_im*chest0_im[aa][re])>>log2_maxh));
+              stat0_im[aa] += (((tmp_re*chest0_im[aa][re])>>log2_maxh) - ((tmp_im*chest0_re[aa][re])>>log2_maxh));
               off+=2;
 #ifdef DEBUG_PUCCH_RX
               printf("[eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) => (%d,%d)\n",subframe,l,re,
@@ -1431,8 +1489,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
               off=(re<<1) + (24*l) + (nsymb>>1)*24;
               tmp_re = ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15);
               tmp_im = ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15);
-              stat_re += (((tmp_re*chest1_re[aa][re])>>log2_maxh) + ((tmp_im*chest1_im[aa][re])>>log2_maxh));
-              stat_im += (((tmp_re*chest1_im[aa][re])>>log2_maxh) - ((tmp_im*chest1_re[aa][re])>>log2_maxh));
+              stat1_re[aa] += (((tmp_re*chest1_re[aa][re])>>log2_maxh) + ((tmp_im*chest1_im[aa][re])>>log2_maxh));
+              stat1_im[aa] += (((tmp_re*chest1_im[aa][re])>>log2_maxh) - ((tmp_im*chest1_re[aa][re])>>log2_maxh));
               off+=2;
 #ifdef DEBUG_PUCCH_RX
               printf("[PHY][eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) => (%d,%d)\n",subframe,l,re,
@@ -1448,8 +1506,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
               off=(re<<1) + (24*l) + (nsymb>>1)*24;
               tmp_re = ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15);
               tmp_im = ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15);
-              stat_re += (((tmp_re*chest1_re[aa][re])>>log2_maxh) + ((tmp_im*chest1_im[aa][re])>>log2_maxh));
-              stat_im += (((tmp_re*chest1_im[aa][re])>>log2_maxh) - ((tmp_im*chest1_re[aa][re])>>log2_maxh));
+              stat1_re[aa] += (((tmp_re*chest1_re[aa][re])>>log2_maxh) + ((tmp_im*chest1_im[aa][re])>>log2_maxh));
+              stat1_im[aa] += (((tmp_re*chest1_im[aa][re])>>log2_maxh) - ((tmp_im*chest1_re[aa][re])>>log2_maxh));
               off+=2;
 #ifdef DEBUG_PUCCH_RX
               printf("[PHY][eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) => (%d,%d)\n",subframe,l,re,
@@ -1464,29 +1522,42 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
             printf("aa%d re %d : stat %d,%d\n",aa,re,stat_re,stat_im);
 #endif
           } //re
+          stat_re+=stat0_re[aa]+stat1_re[aa];
+          stat_im+=stat0_im[aa]+stat1_im[aa];
         } // aa
 
         LOG_D(PHY,"PUCCH 1a/b: subframe %d : stat %d,%d (pos %d)\n",subframe,stat_re,stat_im,
-              (subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe]));
+              (subframe<<10) + (eNB->pucch1ab_stats_cnt[UCI_id][subframe]));
         LOG_D(PHY,"In pucch.c PUCCH 1a/b: ACK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres);
-        eNB->pucch1ab_stats[UE_id][(subframe<<11) + 2*(eNB->pucch1ab_stats_cnt[UE_id][subframe])] = (stat_re);
-        eNB->pucch1ab_stats[UE_id][(subframe<<11) + 1+2*(eNB->pucch1ab_stats_cnt[UE_id][subframe])] = (stat_im);
-        eNB->pucch1ab_stats_cnt[UE_id][subframe] = (eNB->pucch1ab_stats_cnt[UE_id][subframe]+1)&1023;
+        eNB->pucch1ab_stats[UCI_id][(subframe<<11) + 2*(eNB->pucch1ab_stats_cnt[UCI_id][subframe])] = (stat_re);
+        eNB->pucch1ab_stats[UCI_id][(subframe<<11) + 1+2*(eNB->pucch1ab_stats_cnt[UCI_id][subframe])] = (stat_im);
+        eNB->pucch1ab_stats_cnt[UCI_id][subframe] = (eNB->pucch1ab_stats_cnt[UCI_id][subframe]+1)&1023;
         /* frame not available here - set to -1 for the moment */
-        T(T_ENB_PHY_PUCCH_1AB_IQ, T_INT(eNB->Mod_id), T_INT(eNB->uci_vars[UE_id].rnti), T_INT(-1), T_INT(subframe), T_INT(stat_re), T_INT(stat_im));
+        T(T_ENB_PHY_PUCCH_1AB_IQ, T_INT(eNB->Mod_id), T_INT(eNB->uci_vars[UCI_id].rnti), T_INT(-1), T_INT(subframe), T_INT(stat_re), T_INT(stat_im));
         *payload = (stat_re<0) ? 1 : 2; // 1 == ACK, 2 == NAK
 
-        if (fmt==pucch_format1b)
+        if (fmt==pucch_format1b) {
+          uci_stats->pucch1b_trials++;
           *(1+payload) = (stat_im<0) ? 1 : 2;
+          uci_stats->current_pucch1b_stat_re = stat_re;
+          uci_stats->current_pucch1b_stat_im = stat_im;
+        }
+        else {
+          uci_stats->pucch1a_trials++;
+          uci_stats->current_pucch1a_stat_re = stat_re;
+          uci_stats->current_pucch1a_stat_im = stat_im;
+        }
+
       } else { // insufficient energy on PUCCH so NAK
         LOG_D(PHY,"In pucch.c PUCCH 1a/b: NAK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres);
         *payload = 4;  // DTX
-        ((int16_t *)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[0] = (int16_t)(stat_re);
-        ((int16_t *)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[1] = (int16_t)(stat_im);
-        eNB->pucch1ab_stats_cnt[UE_id][subframe] = (eNB->pucch1ab_stats_cnt[UE_id][subframe]+1)&1023;
+        ((int16_t *)&eNB->pucch1ab_stats[UCI_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UCI_id][subframe])])[0] = (int16_t)(stat_re);
+        ((int16_t *)&eNB->pucch1ab_stats[UCI_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UCI_id][subframe])])[1] = (int16_t)(stat_im);
+        eNB->pucch1ab_stats_cnt[UCI_id][subframe] = (eNB->pucch1ab_stats_cnt[UCI_id][subframe]+1)&1023;
 
         if (fmt==pucch_format1b)
           *(1+payload) = 4;
+        uci_stats->pucch1ab_DTX++;
       }
     } else {
       LOG_E(PHY,"[eNB] PUCCH fmt2/2a/2b not supported\n");
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch_common.c b/openair1/PHY/LTE_TRANSPORT/pucch_common.c
index 5b939b08d25ae005f9ed136ba9bd320936b3ee4e..d7a500d5f77b50e80a2143356cda26bc54e251e1 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch_common.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch_common.c
@@ -31,7 +31,6 @@
 */
 #include "PHY/defs_eNB.h"
 #include "PHY/phy_extern.h" 
-#include "LAYER2/MAC/mac.h"
 
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "common/utils/LOG/log.h"
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common.h b/openair1/PHY/LTE_TRANSPORT/transport_common.h
index ab2921c2b9405a65ae5ef8bce9d5b21840b73b39..135f3cdf4bb1b372e775f42e4cbfe04590748568 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_common.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_common.h
@@ -35,9 +35,9 @@
 #include "dci.h"
 #include "mdci.h"
 //#include "uci.h"
-#ifndef STANDALONE_COMPILE
-  #include "UTIL/LISTS/list.h"
-#endif
+//#ifndef STANDALONE_COMPILE
+//  #include "UTIL/LISTS/list.h"
+//#endif
 
 #define MOD_TABLE_QPSK_OFFSET 1
 #define MOD_TABLE_16QAM_OFFSET 5
@@ -57,7 +57,7 @@
 
 // maximum of 3 segments before each coding block if data length exceeds 6144 bits.
 
-#define MAX_NUM_DLSCH_SEGMENTS 16
+#define MAX_NUM_DLSCH_SEGMENTS 13
 #define MAX_NUM_ULSCH_SEGMENTS MAX_NUM_DLSCH_SEGMENTS
 #define MAX_DLSCH_PAYLOAD_BYTES (MAX_NUM_DLSCH_SEGMENTS*768)
 #define MAX_ULSCH_PAYLOAD_BYTES (MAX_NUM_ULSCH_SEGMENTS*768)
@@ -65,22 +65,6 @@
 #define MAX_NUM_CHANNEL_BITS (14*1200*6)  // 14 symbols, 1200 REs, 12 bits/RE
 #define MAX_NUM_RE (14*1200)
 
-#if !defined(SI_RNTI)
-  #define SI_RNTI  (rnti_t)0xffff
-  #define SI_RNTI_MBMS  (rnti_t)0xfff9
-#endif
-#if !defined(M_RNTI)
-  #define M_RNTI   (rnti_t)0xfffd
-#endif
-#if !defined(P_RNTI)
-  #define P_RNTI   (rnti_t)0xfffe
-#endif
-#if !defined(CBA_RNTI)
-  #define CBA_RNTI (rnti_t)0xfff4
-#endif
-#if !defined(C_RNTI)
-  #define C_RNTI   (rnti_t)0x1234
-#endif
 // These are the codebook indexes according to Table 6.3.4.2.3-1 of 36.211
 //1 layer
 #define PMI_2A_11  0
@@ -93,7 +77,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/LTE_TRANSPORT/transport_common_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h
index 1944f06fab7a410dc21ee3a9130dba4f4c1bf311..622f37b3bcba54d22fc46e719e78c33e25603eb3 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h
@@ -223,7 +223,9 @@ uint8_t get_num_prach_tdd(module_id_t Mod_id);
   @param frame_type 0-FDD, 1-TDD
   @returns 0-1 accordingly
 */
+/*
 uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type);
+*/
 
 /*!
   \brief Helper for MAC, returns frequency index of PRACH resource in TDD for a particular configuration index
@@ -306,12 +308,12 @@ void init_scrambling_lut(void);
 
 void init_unscrambling_lut(void);
 
-
+/*
 uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms,
                              uint8_t prach_ConfigIndex,
                              uint8_t n_ra_prboffset,
                              uint8_t tdd_mapindex, uint16_t Nf);
-
+*/
 uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t subframe);
 uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n);
 
@@ -319,6 +321,6 @@ uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL);
 
 void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t *rb_alloc2);
 
-int16_t estimate_ue_tx_power(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs);
+int16_t estimate_ue_tx_power(int norm,uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs);
 
 #endif
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h
index 5e446db5fdd1a11431d2e3075bcda66fdc5bd68a..b3985e973a9835b0de1ea5a7ffda266ea9bf84c4 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h
@@ -36,9 +36,9 @@
 #include "dci.h"
 #include "mdci.h"
 #include "uci_common.h"
-#ifndef STANDALONE_COMPILE
-  #include "UTIL/LISTS/list.h"
-#endif
+//#ifndef STANDALONE_COMPILE
+//  #include "UTIL/LISTS/list.h"
+//#endif
 
 
 // structures below implement 36-211 and 36-212
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h
index 9e37821b0543219be9dcd5d5811e3b2769740131..19af50056c558160a86dd3888f08747ccbbe1afd 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h
@@ -520,6 +520,9 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB,
 
 void dump_ulsch(PHY_VARS_eNB *phy_vars_eNB,int frame, int subframe, uint8_t UE_id,int round);
 
+void dump_ulsch_stats(FILE *fd,PHY_VARS_eNB *eNB,int frame);
+void dump_uci_stats(FILE *fd,PHY_VARS_eNB *eNB,int frame);
+
 
 
 
@@ -691,13 +694,11 @@ void conv_eMTC_rballoc(uint16_t resource_block_coding,
                        uint32_t N_RB_DL,
                        uint32_t *rb_alloc);
 
-int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
-
-int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
+int find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
 
-int16_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type);
+int find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
 
-uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type);
+int find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type);
 
 uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset);
 
diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c
index f8ade9afc86f8bb6a0f233d6bc078ccc95896a48..ae039bec2a24b9d2e7bee780632896baa5b01232 100644
--- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c
@@ -37,12 +37,11 @@
 //#define DEBUG_UCI 1
 
 
-int16_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type) {
-  uint16_t i;
-  int16_t first_free_index=-1;
+int find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type) {
+  int first_free_index=-1;
   AssertFatal(eNB!=NULL,"eNB is null\n");
 
-  for (i=0; i<NUMBER_OF_UCI_VARS_MAX; i++) {
+  for (int i=0; i<NUMBER_OF_UCI_MAX; i++) {
     if ((eNB->uci_vars[i].active >0) &&
         (eNB->uci_vars[i].rnti==rnti) &&
         (eNB->uci_vars[i].frame==frame) &&
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index 92fe77720115b933095a05521fe8677021e6ef19..ae8c666d18e659d3050f13a8396ac4afff0cadd1 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -374,7 +374,7 @@ static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2,
   int n;
 
   if (reset) {
-    *x1 = 1+ (1<<31);
+    *x1 = 1+ (1U<<31);
     *x2=*x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31);
 
     // skip first 50 double words (1600 bits)
@@ -468,6 +468,35 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,
         ulsch_harq->Nsymb_pusch,
         nb_rb);
   //#endif
+
+  eNB_SCH_STATS_t *stats=NULL;
+  int first_free=-1;
+  for (int i=0;i<NUMBER_OF_SCH_STATS_MAX;i++) {
+    if (eNB->ulsch_stats[i].rnti == 0 && first_free == -1) {
+      first_free = i;
+      stats=&eNB->ulsch_stats[i];
+    }
+    if (eNB->ulsch_stats[i].rnti == ulsch->rnti) {
+      stats=&eNB->ulsch_stats[i];
+      break;
+    }
+  }
+  if (stats) {
+    stats->rnti = ulsch->rnti;
+    stats->round_trials[ulsch_harq->round]++;
+    stats->frame=proc->frame_rx;
+  }
+  if (ulsch_harq->round == 0) {
+    if (stats) {
+      stats->current_Qm = Q_m;
+      stats->current_RI = 1;
+      stats->total_bytes_tx += ulsch_harq->TBS;
+      stats->current_TBS = ulsch_harq->TBS;
+      stats->current_G   = ulsch_harq->G;
+    }
+  }
+
+
   //if (ulsch_harq->round == 0) { // delete for RB shortage pattern
   // This is a new packet, so compute quantities regarding segmentation
   ulsch_harq->B = A+24;
@@ -1086,3 +1115,44 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,
   ret = ulsch_decoding_data_all(eNB,proc, UE_id,harq_pid,llr8_flag);
   return(ret);
 }
+
+#define STATSTRLEN 16384
+void dump_ulsch_stats(FILE *fd,PHY_VARS_eNB *eNB,int frame) {
+
+  char output[16384];
+  int stroff=0;
+  for (int i=0;i<NUMBER_OF_ULSCH_MAX;i++)
+    if (eNB->ulsch_stats[i].rnti>0 && eNB->ulsch_stats[i].round_trials[0]>100) { 
+      for (int aa=0;aa<eNB->frame_parms.nb_antennas_rx;aa++) 
+        stroff+=sprintf(output+stroff,"ULSCH RNTI %x: ulsch_power[%d] %d, ulsch_noise_power[%d] %d\n", 
+              eNB->ulsch_stats[i].rnti, aa,eNB->ulsch_stats[i].ulsch_power[aa],aa,eNB->ulsch_stats[i].ulsch_noise_power[aa]);
+      AssertFatal(stroff<(STATSTRLEN-1000),"Increase STATSTRLEN\n");
+      stroff+=sprintf(output+stroff,"ULSCH RNTI %x: round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d\n",
+            eNB->ulsch_stats[i].rnti,
+            eNB->ulsch_stats[i].round_trials[0],
+            (double)eNB->ulsch_stats[i].round_trials[1]/eNB->ulsch_stats[i].round_trials[0],
+            eNB->ulsch_stats[i].round_trials[1],
+            (double)eNB->ulsch_stats[i].round_trials[2]/eNB->ulsch_stats[i].round_trials[0],
+            eNB->ulsch_stats[i].round_trials[2],
+           (double)eNB->ulsch_stats[i].round_trials[3]/eNB->ulsch_stats[i].round_trials[0],
+            eNB->ulsch_stats[i].round_trials[3]);
+      stroff+=sprintf(output+stroff,"ULSCH RNTI %x:  current_Qm %d, current_G %d, current_TBS %d, current_rate %f,current_RI %d, timing_offset %d, total_bytes RX/SCHED %d/%d\n",
+            eNB->ulsch_stats[i].rnti,
+            eNB->ulsch_stats[i].current_Qm,
+	    eNB->ulsch_stats[i].current_G,
+	    eNB->ulsch_stats[i].current_TBS,
+	    (double)eNB->ulsch_stats[i].current_G/eNB->ulsch_stats[i].current_TBS,
+            eNB->ulsch_stats[i].current_RI,
+	    eNB->ulsch_stats[i].timing_offset,
+            eNB->ulsch_stats[i].total_bytes_rx,
+            eNB->ulsch_stats[i].total_bytes_tx);
+    }
+  fprintf(fd,"%s",output);
+}
+
+void clear_ulsch_stats(PHY_VARS_eNB *eNB) {
+
+  for (int i=0;i<NUMBER_OF_ULSCH_MAX;i++)
+    memset((void*)&eNB->ulsch_stats[i],0,sizeof(eNB->ulsch_stats[i]));
+}
+
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
index eeab61609718ac16693924f8e38fd12bb85200b1..3529df8e44504435ef2d7948925dbdde41423976 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
@@ -31,12 +31,12 @@
 */
 
 #include "PHY/defs_eNB.h"
-#include "PHY/phy_extern.h"
+//#include "PHY/phy_extern.h"
 #include "transport_eNB.h"
 #include "PHY/sse_intrin.h"
 #include "transport_common_proto.h"
 #include "PHY/LTE_ESTIMATION/lte_estimation.h"
-#include "PHY/MODULATION/modulation_eNB.h"
+//#include "PHY/MODULATION/modulation_eNB.h"
 
 #include "T.h"
 
@@ -45,8 +45,11 @@
 //extern int **ulchmag_eren;
 //eren
 
-static short jitter[8]  __attribute__ ((aligned(16))) = {1,0,0,1,0,1,1,0};
-static short jitterc[8] __attribute__ ((aligned(16))) = {0,1,1,0,1,0,0,1};
+static const short jitter[8]  __attribute__ ((aligned(16))) = {1,0,0,1,0,1,1,0};
+static const short jitterc[8] __attribute__ ((aligned(16))) = {0,1,1,0,1,0,0,1};
+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};
+
 
 void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH) {
 #if defined(__x86_64__) || defined(__i386__)
@@ -511,7 +514,6 @@ void ulsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
   for (i=0; i<(nb_rb*3); i++) {
 #if defined(__x86_64__) || defined(__i386__)
     mmtmpU0 = _mm_abs_epi16(rxF[i]);
-    //    print_shorts("tmp0",&tmp0);
     mmtmpU0 = _mm_subs_epi16(ch_mag[i],mmtmpU0);
     (*llrp128)[0] = _mm_unpacklo_epi32(rxF[i],mmtmpU0);
     (*llrp128)[1] = _mm_unpackhi_epi32(rxF[i],mmtmpU0);
@@ -627,11 +629,15 @@ void ulsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
                          uint8_t symbol,
                          uint16_t nb_rb) {
 #if defined(__x86_64__) || defined(__i386__)
-  __m128i *rxdataF_comp128_0,*ul_ch_mag128_0,*ul_ch_mag128_0b;
-  __m128i *rxdataF_comp128_1,*ul_ch_mag128_1,*ul_ch_mag128_1b;
+  __m128i *rxdataF_comp128_0=NULL,*ul_ch_mag128_0=NULL,*ul_ch_mag128_0b=NULL;
+  __m128i *rxdataF_comp128_1=NULL,*ul_ch_mag128_1=NULL,*ul_ch_mag128_1b=NULL;
+  __m128i *rxdataF_comp128_2=NULL,*ul_ch_mag128_2=NULL,*ul_ch_mag128_2b=NULL;
+  __m128i *rxdataF_comp128_3=NULL,*ul_ch_mag128_3=NULL,*ul_ch_mag128_3b=NULL;
 #elif defined(__arm__)
   int16x8_t *rxdataF_comp128_0,*ul_ch_mag128_0,*ul_ch_mag128_0b;
   int16x8_t *rxdataF_comp128_1,*ul_ch_mag128_1,*ul_ch_mag128_1b;
+  int16x8_t *rxdataF_comp128_2,*ul_ch_mag128_2,*ul_ch_mag128_2b;
+  int16x8_t *rxdataF_comp128_3,*ul_ch_mag128_3,*ul_ch_mag128_3b;
 #endif
   int32_t i;
 
@@ -643,15 +649,39 @@ void ulsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
     ul_ch_mag128_1      = (__m128i *)&ul_ch_mag[1][symbol*frame_parms->N_RB_DL*12];
     ul_ch_mag128_0b     = (__m128i *)&ul_ch_magb[0][symbol*frame_parms->N_RB_DL*12];
     ul_ch_mag128_1b     = (__m128i *)&ul_ch_magb[1][symbol*frame_parms->N_RB_DL*12];
-
-    // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
-    for (i=0; i<nb_rb*3; i++) {
-      rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
-      ul_ch_mag128_0[i]    = _mm_adds_epi16(_mm_srai_epi16(ul_ch_mag128_0[i],1),_mm_srai_epi16(ul_ch_mag128_1[i],1));
-      ul_ch_mag128_0b[i]   = _mm_adds_epi16(_mm_srai_epi16(ul_ch_mag128_0b[i],1),_mm_srai_epi16(ul_ch_mag128_1b[i],1));
-      rxdataF_comp128_0[i] = _mm_add_epi16(rxdataF_comp128_0[i],(*(__m128i *)&jitterc[0]));
+    if (frame_parms->nb_antennas_rx>2) { 
+      rxdataF_comp128_2   = (__m128i *)&rxdataF_comp[2][symbol*frame_parms->N_RB_DL*12];
+      ul_ch_mag128_2      = (__m128i *)&ul_ch_mag[2][symbol*frame_parms->N_RB_DL*12];
+      ul_ch_mag128_2b     = (__m128i *)&ul_ch_magb[2][symbol*frame_parms->N_RB_DL*12];
+    }
+    if (frame_parms->nb_antennas_rx>3) { 
+      rxdataF_comp128_3   = (__m128i *)&rxdataF_comp[3][symbol*frame_parms->N_RB_DL*12];
+      ul_ch_mag128_3      = (__m128i *)&ul_ch_mag[3][symbol*frame_parms->N_RB_DL*12];
+      ul_ch_mag128_3b     = (__m128i *)&ul_ch_magb[3][symbol*frame_parms->N_RB_DL*12];
     }
 
+    // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
+    if (frame_parms->nb_antennas_rx==2) 
+      for (i=0; i<nb_rb*3; i++) {
+        rxdataF_comp128_0[i] = _mm_srai_epi16(_mm_adds_epi16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]),1);
+        ul_ch_mag128_0[i]    = _mm_srai_epi16(_mm_adds_epi16(ul_ch_mag128_0[i],ul_ch_mag128_1[i]),1);
+        ul_ch_mag128_0b[i]   = _mm_srai_epi16(_mm_adds_epi16(ul_ch_mag128_0b[i],ul_ch_mag128_1b[i]),1);
+        rxdataF_comp128_0[i] = _mm_add_epi16(rxdataF_comp128_0[i],(*(__m128i *)&jitterc[0]));
+      }
+    if (frame_parms->nb_antennas_rx==3)
+      for (i=0; i<nb_rb*3; i++) {
+        rxdataF_comp128_0[i] = _mm_srai_epi16(_mm_adds_epi16(rxdataF_comp128_0[i],_mm_adds_epi16(rxdataF_comp128_1[i],rxdataF_comp128_2[i])),1);
+        ul_ch_mag128_0[i]    = _mm_srai_epi16(_mm_adds_epi16(ul_ch_mag128_0[i],_mm_adds_epi16(ul_ch_mag128_1[i],ul_ch_mag128_2[i])),1);
+        ul_ch_mag128_0b[i]   = _mm_srai_epi16(_mm_adds_epi16(ul_ch_mag128_0b[i],_mm_adds_epi16(ul_ch_mag128_1b[i],ul_ch_mag128_2b[i])),1);
+        rxdataF_comp128_0[i] = _mm_add_epi16(rxdataF_comp128_0[i],(*(__m128i *)&jitterc[0]));
+      }
+     if (frame_parms->nb_antennas_rx==4)
+      for (i=0; i<nb_rb*3; i++) {
+        rxdataF_comp128_0[i] = _mm_srai_epi16(_mm_adds_epi16(rxdataF_comp128_0[i],_mm_adds_epi16(rxdataF_comp128_1[i],_mm_adds_epi16(rxdataF_comp128_2[i],rxdataF_comp128_3[i]))),2);
+        ul_ch_mag128_0[i]    = _mm_srai_epi16(_mm_adds_epi16(ul_ch_mag128_0[i],_mm_adds_epi16(ul_ch_mag128_1[i],_mm_adds_epi16(ul_ch_mag128_2[i],ul_ch_mag128_3[i]))),2);
+        ul_ch_mag128_0b[i]   = _mm_srai_epi16(_mm_adds_epi16(ul_ch_mag128_0b[i],_mm_adds_epi16(ul_ch_mag128_1b[i],_mm_adds_epi16(ul_ch_mag128_2b[i],ul_ch_mag128_3b[i]))),2);
+        rxdataF_comp128_0[i] = _mm_add_epi16(rxdataF_comp128_0[i],(*(__m128i *)&jitterc[0]));
+      }
 #elif defined(__arm__)
     rxdataF_comp128_0   = (int16x8_t *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12];
     rxdataF_comp128_1   = (int16x8_t *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12];
@@ -795,7 +825,7 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
       mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
       mmtmpU1 = _mm_packs_epi32(mmtmpU0,mmtmpU0);
       ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1);
-      LOG_D(PHY,"comp: symbol %d rb %d => %d,%d,%d (output_shift %d)\n",symbol,rb,*((int16_t *)&ul_ch_mag128[0]),*((int16_t *)&ul_ch_mag128[1]),*((int16_t *)&ul_ch_mag128[2]),output_shift);
+      //LOG_I(PHY,"comp: ant %d symbol %d rb %d => %d,%d,%d (output_shift %d)\n",aarx,symbol,rb,*((int16_t *)&ul_ch_mag128[0]),*((int16_t *)&ul_ch_mag128[1]),*((int16_t *)&ul_ch_mag128[2]),output_shift);
 #elif defined(__arm__)
       mmtmpU0 = vmull_s16(ul_ch128[0], ul_ch128[0]);
       mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
@@ -834,6 +864,7 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
       //  print_ints("c1",&mmtmpU3);
       rxdataF_comp128[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
       /*
+              LOG_I(PHY,"Antenna %d:",aarx); 
               print_shorts("rx:",&rxdataF128[0]);
               print_shorts("ch:",&ul_ch128[0]);
               print_shorts("pack:",&rxdataF_comp128[0]);
@@ -851,9 +882,12 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
       mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
       mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
       rxdataF_comp128[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
-      //        print_shorts("rx:",rxdataF128[1]);
-      //        print_shorts("ch:",ul_ch128[1]);
-      //        print_shorts("pack:",rxdataF_comp128[1]);
+      /*
+        LOG_I(PHY,"Antenna %d:",aarx);
+              print_shorts("rx:",&rxdataF128[1]);
+              print_shorts("ch:",&ul_ch128[1]);
+              print_shorts("pack:",&rxdataF_comp128[1]);
+      */
       //       multiply by conjugated channel
       mmtmpU0 = _mm_madd_epi16(ul_ch128[2],rxdataF128[2]);
       // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
@@ -867,9 +901,12 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
       mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
       mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
       rxdataF_comp128[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
-      //        print_shorts("rx:",rxdataF128[2]);
-      //        print_shorts("ch:",ul_ch128[2]);
-      //        print_shorts("pack:",rxdataF_comp128[2]);
+      /*
+              LOG_I(PHY,"Antenna %d:",aarx);
+              print_shorts("rx:",&rxdataF128[2]);
+              print_shorts("ch:",&ul_ch128[2]);
+              print_shorts("pack:",&rxdataF_comp128[2]);
+      */
       // Add a jitter to compensate for the saturation in "packs" resulting in a bias on the DC after IDFT
       rxdataF_comp128[0] = _mm_add_epi16(rxdataF_comp128[0],(*(__m128i *)&jitter[0]));
       rxdataF_comp128[1] = _mm_add_epi16(rxdataF_comp128[1],(*(__m128i *)&jitter[0]));
@@ -1078,6 +1115,15 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
   }
 
   for (i=0; i<frame_parms->nb_antennas_rx; i++) {
+    pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[i],
+                                 ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)/correction_factor;
+    LOG_D(PHY,"%4.4d.%d power harq_pid %d rb %2.2d TBS %2.2d (MPR_times_Ks %d correction %d)  power %d dBtimes10\n", proc->frame_rx, proc->subframe_rx, harq_pid,
+          ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, ulsch[UE_id]->harq_processes[harq_pid]->TBS,MPR_times_100Ks,correction_factor,dB_fixed_x10(pusch_vars->ulsch_power[i]));
+    pusch_vars->ulsch_noise_power[i]=0;
+    for (int rb=0;rb<ulsch[UE_id]->harq_processes[harq_pid]->nb_rb;rb++)
+      pusch_vars->ulsch_noise_power[i]+=eNB->measurements.n0_subband_power[i][rb]/ulsch[UE_id]->harq_processes[harq_pid]->nb_rb;
+    LOG_D(PHY,"noise power[%d] %d\n",i,dB_fixed_x10(pusch_vars->ulsch_noise_power[i]));
+/* Check this modification w.r.t to new PUSCH modifications
     //symbol 3
     int symbol_offset = frame_parms->N_RB_UL*12*(3 - frame_parms->Ncp);
     pusch_vars->ulsch_interference_power[i] = interference_power(&pusch_vars->drs_ch_estimates[i][symbol_offset],ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12);
@@ -1100,7 +1146,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
     }
 
     LOG_D(PHY,"%4.4d.%d power harq_pid %d rb %2.2d TBS %2.2d (MPR_times_Ks %d correction %d)  power %d dBtimes10\n", proc->frame_rx, proc->subframe_rx, harq_pid, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, ulsch[UE_id]->harq_processes[harq_pid]->TBS,MPR_times_100Ks,correction_factor,dB_fixed_x10(pusch_vars->ulsch_power[i]));
-     
+  */   
   }
 
   ulsch_channel_level(pusch_vars->drs_ch_estimates,
@@ -1113,8 +1159,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
   for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
     avgs = cmax(avgs,avgU[aarx]);
 
-  //      log2_maxh = 4+(log2_approx(avgs)/2);
-  log2_maxh = (log2_approx(avgs)/2)+ log2_approx(frame_parms->nb_antennas_rx-1)+4;
+  log2_maxh = 4+(log2_approx(avgs)/2); 
   LOG_D(PHY,"[ULSCH] log2_maxh = %d (%d,%d)\n",log2_maxh,avgU[0],avgs);
 
   for (l=0; l<(frame_parms->symbols_per_tti-ulsch[UE_id]->harq_processes[harq_pid]->srs_active); l++) {
@@ -1221,67 +1266,56 @@ void dump_ulsch(PHY_VARS_eNB *eNB,int frame,int subframe,uint8_t UE_id,int round
   uint8_t harq_pid;
   char fname[100],vname[100];
   harq_pid = subframe2harq_pid(&eNB->frame_parms,frame,subframe);
-  LOG_UI(PHY,"Dumping ULSCH in subframe %d with harq_pid %d, round %d for NB_rb %d, TBS %d, Qm %d, N_symb %d\n",
+  LOG_UI(PHY,"Dumping ULSCH in subframe %d with harq_pid %d, round %d for NB_rb %d, first_rb %d, TBS %d, Qm %d, N_symb %d\n",
          subframe,harq_pid,round,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb,
+         eNB->ulsch[UE_id]->harq_processes[harq_pid]->first_rb,
          eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS,eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm,
          eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch);
+  for (int aa=0;aa<eNB->frame_parms.nb_antennas_rx;aa++)
+     LOG_UI(PHY,"ulsch_power[%d] %d, ulsch_noise_power[%d] %d\n",aa,dB_fixed_x10(eNB->pusch_vars[UE_id]->ulsch_power[aa]),aa,dB_fixed_x10(eNB->pusch_vars[UE_id]->ulsch_noise_power[aa]));
   sprintf(fname,"/tmp/ulsch_r%d_d",round);
   sprintf(vname,"/tmp/ulsch_r%d_dseq",round);
   LOG_UM(fname,vname,&eNB->ulsch[UE_id]->harq_processes[harq_pid]->d[0][96],
          eNB->ulsch[UE_id]->harq_processes[harq_pid]->Kplus*3,1,0);
 
   if (eNB->common_vars.rxdata) {
-    sprintf(fname,"/tmp/rxsig0_r%d.m",round);
-    sprintf(vname,"rxs0_r%d",round);
-    LOG_UM(fname,vname, &eNB->common_vars.rxdata[0][0],eNB->frame_parms.samples_per_tti*10,1,1);
-
-    if (eNB->frame_parms.nb_antennas_rx>1)
-      if (eNB->common_vars.rxdata) {
-        sprintf(fname,"/tmp/rxsig1_r%d.m",round);
-        sprintf(vname,"rxs1_r%d",round);
-        LOG_UM(fname,vname, &eNB->common_vars.rxdata[1][0],eNB->frame_parms.samples_per_tti*10,1,1);
-      }
-  }
+    for (int aarx=0;aarx<eNB->frame_parms.nb_antennas_rx;aarx++) {
+       sprintf(fname,"/tmp/rxsig%d_r%d.m",aarx,round);
+       sprintf(vname,"rxs%d_r%d",aarx,round);
+       LOG_UM(fname,vname, &eNB->common_vars.rxdata[aarx][0],eNB->frame_parms.samples_per_tti*10,1,1);
 
-  sprintf(fname,"/tmp/rxsigF0_r%d.m",round);
-  sprintf(vname,"rxsF0_r%d",round);
-  LOG_UM(fname,vname, (void *)&eNB->common_vars.rxdataF[0][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1);
-
-  if (eNB->frame_parms.nb_antennas_rx>1) {
-    sprintf(fname,"/tmp/rxsigF1_r%d.m",round);
-    sprintf(vname,"rxsF1_r%d",round);
-    LOG_UM(vname,fname, &eNB->common_vars.rxdataF[1][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1);
+    }
   }
-
-  sprintf(fname,"/tmp/rxsigF0_ext_r%d.m",round);
-  sprintf(vname,"rxsF0_ext_r%d",round);
-  LOG_UM(fname,vname, &eNB->pusch_vars[UE_id]->rxdataF_ext[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
-
-  if (eNB->frame_parms.nb_antennas_rx>1) {
-    sprintf(fname,"/tmp/rxsigF1_ext_r%d.m",round);
-    sprintf(vname,"rxsF1_ext_r%d",round);
-    LOG_UM(fname,vname,&eNB->pusch_vars[UE_id]->rxdataF_ext[1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
+  if (eNB->common_vars.rxdataF) {
+   for (int aarx=0;aarx<eNB->frame_parms.nb_antennas_rx;aarx++) {
+       sprintf(fname,"/tmp/rxsigF%d_r%d.m",aarx,round);
+       sprintf(vname,"rxsF%d_r%d",aarx,round);
+       LOG_UM(fname,vname, (void *)&eNB->common_vars.rxdataF[aarx][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1);
+    }
+  }
+  if (eNB->pusch_vars[UE_id]->rxdataF_ext) {
+    for (int aarx=0;aarx<eNB->frame_parms.nb_antennas_rx;aarx++) {
+      sprintf(fname,"/tmp/rxsigF%d_ext_r%d.m",aarx,round);
+      sprintf(vname,"rxsF%d_ext_r%d",aarx,round);
+      LOG_UM(fname,vname, &eNB->pusch_vars[UE_id]->rxdataF_ext[aarx][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
+    }
   }
-
   /*
   if (eNB->srs_vars[UE_id].srs_ch_estimates) LOG_UM("/tmp/srs_est0.m","srsest0",eNB->srs_vars[UE_id].srs_ch_estimates[0],eNB->frame_parms.ofdm_symbol_size,1,1);
 
   if (eNB->frame_parms.nb_antennas_rx>1)
     if (eNB->srs_vars[UE_id].srs_ch_estimates) LOG_UM("/tmp/srs_est1.m","srsest1",eNB->srs_vars[UE_id].srs_ch_estimates[1],eNB->frame_parms.ofdm_symbol_size,1,1);
   */
-  sprintf(fname,"/tmp/drs_est0_r%d.m",round);
-  sprintf(vname,"drsest0_r%d",round);
-  LOG_UM(fname,vname,eNB->pusch_vars[UE_id]->drs_ch_estimates[0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
-
-  if (eNB->frame_parms.nb_antennas_rx>1) {
-    sprintf(fname,"/tmp/drs_est1_r%d.m",round);
-    sprintf(vname,"drsest1_r%d",round);
-    LOG_UM(fname,vname,eNB->pusch_vars[UE_id]->drs_ch_estimates[1],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
+  for (int aarx=0;aarx<eNB->frame_parms.nb_antennas_rx;aarx++) {
+    sprintf(fname,"/tmp/drs_est%d_r%d.m",aarx,round);
+    sprintf(vname,"drsest%d_r%d",aarx,round);
+    LOG_UM(fname,vname,eNB->pusch_vars[UE_id]->drs_ch_estimates[aarx],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
+
+    sprintf(fname,"/tmp/ulsch%d_rxF_comp0_r%d.m",aarx,round);
+    sprintf(vname,"ulsch_rxF%d_comp0_r%d",aarx,round);
+    LOG_UM(fname,vname,&eNB->pusch_vars[UE_id]->rxdataF_comp[aarx][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
   }
 
-  sprintf(fname,"/tmp/ulsch0_rxF_comp0_r%d.m",round);
-  sprintf(vname,"ulsch0_rxF_comp0_r%d",round);
-  LOG_UM(fname,vname,&eNB->pusch_vars[UE_id]->rxdataF_comp[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
   //  LOG_M("ulsch_rxF_comp1.m","ulsch0_rxF_comp1",&eNB->pusch_vars[UE_id]->rxdataF_comp[0][1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
   sprintf(fname,"/tmp/ulsch_rxF_llr_r%d.m",round);
   sprintf(vname,"ulsch_llr_r%d",round);
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c
index 7442a0ae7e0ff225c9486ff8442308d811127ea2..39900113b7bf3ebcf83fd5cdcebf56cd4db8f6f2 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c
@@ -78,7 +78,7 @@ LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_
 
   switch (N_RB_DL) {
     case 6:
-      bw_scaling =16;
+      bw_scaling =4;
       break;
 
     case 25:
@@ -276,7 +276,7 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
 
   switch (frame_parms->N_RB_DL) {
     case 6:
-      bw_scaling =16;
+      bw_scaling =4;
       break;
 
     case 25:
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
index 556a9f2d237f5e4cbf84dae7541d69b570e0d2a6..9906b945d81ca209046cb839280ec18926fb7afb 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
@@ -1234,7 +1234,7 @@ void dlsch_channel_compensation(int **rxdataF_ext,
   unsigned short rb;
   unsigned char aatx,aarx,symbol_mod,pilots=0;
   __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128;
-  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128;
+  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0};
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
   if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
@@ -1657,11 +1657,11 @@ void dlsch_channel_compensation_core(int **rxdataF_ext,
   int length_mod8 = 0;
   int length2;
   __m128i *dl_ch128,*dl_ch_mag128,*dl_ch_mag128b, *dl_ch128_2, *rxdataF128,*rxdataF_comp128,*rho128;
-  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128;
+  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0};
   int aatx = 0, aarx = 0;
 
   for (aatx=0; aatx<n_tx; aatx++) {
-    __m128i QAM_amp128b;
+    __m128i QAM_amp128b={0};
 
     if (mod_order == 4) {
       QAM_amp128 = _mm_set1_epi16(QAM16_n1);  // 2/sqrt(10)
@@ -2004,7 +2004,7 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext,
   __m128i *dl_ch0_128,*dl_ch1_128,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128;
   unsigned char aarx=0,symbol_mod,pilots=0;
   int precoded_signal_strength=0;
-  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128;
+  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0};
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
   if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp)))
@@ -2411,7 +2411,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms,
   int **rxdataF_comp0         = pdsch_vars->rxdataF_comp0;
   int **rxdataF_comp1         = pdsch_vars->rxdataF_comp1[harq_pid][round];
   unsigned char *pmi_ext      = pdsch_vars->pmi_ext;
-  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp1_128;
+  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128={0},QAM_amp1_128={0};
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
   if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp)))
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c
index 69aa1c06a34aefb8c0999db10b4b34cc8ab069b4..3c22c64a9e56a00c2c145ebd14a37e59e43b73e8 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c
@@ -328,7 +328,7 @@ void mch_channel_compensation(int **rxdataF_ext,
   int aarx,nre,i;
 #if defined(__x86_64__) || defined(__i386__)
   __m128i *dl_ch128,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128;
-  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b;
+  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0},QAM_amp128b={0};
 #elif defined(__arm__)
 #endif
 
@@ -455,7 +455,7 @@ void mch_channel_compensation_khz_1dot25(int **rxdataF_ext,
   int aarx,nre,i;
 #if defined(__x86_64__) || defined(__i386__)
   __m128i *dl_ch128,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128;
-  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b;
+  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0},QAM_amp128b={0};
 #elif defined(__arm__)
 #endif
   /*if ((symbol == 2) || (symbol == 6) || (symbol == 10))
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c
index ab7c2b90910d4df9eff3fe17d0139843bd73038c..929f63e9fc0092f56ac42203f7a8e5d1d54676b8 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c
@@ -41,6 +41,7 @@
 #include "common/utils/LOG/vcd_signal_dumper.h"
 
 #include "../LTE_TRANSPORT/prach_extern.h"
+#include "common/utils/lte/prach_utils.h"
 
 //#define PRACH_DEBUG 1
 
@@ -115,7 +116,9 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
     NCS = NCS_restricted[Ncs_config];
   }
 
-  n_ra_prb = get_prach_prb_offset(&(ue->frame_parms),
+  n_ra_prb = get_prach_prb_offset(ue->frame_parms.frame_type,
+				  ue->frame_parms.tdd_config,
+				  ue->frame_parms.N_RB_UL,
                                   ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
                                   ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset,
                                   tdd_mapindex, Nf);
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c
index e6960273c7300a707c44437f14bf4b146c2725fd..9c0edb467ca1a75efc66160c1f54521a3d4d09d7 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c
@@ -170,6 +170,7 @@ int32_t generate_srs(LTE_DL_FRAME_PARMS *frame_parms,
 
   Msc_RS = msrsb * 6;
   k0 = ( ( (int16_t)(frame_parms->N_RB_UL>>1) - (int16_t)(msrs0>>1) ) * 12 ) + kTC;
+  AssertFatal(msrsb,"divide by 0");
   nb  = (4*n_RRC/msrsb)%Nb;
 
   for (b=0; b<=Bsrs; b++) {
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h
index 3299401443c83799e0823fafdd1ad0f19709a03e..7ab795cae9a0eced9d89f06d39814256cc270713 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h
+++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h
@@ -1740,10 +1740,5 @@ double computeRhoB_UE(PDSCH_CONFIG_DEDICATED  *pdsch_config_dedicated,
   LTE_UE_DLSCH_t *dlsch_ue);
 */
 
-uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms,
-                             uint8_t prach_ConfigIndex,
-                             uint8_t n_ra_prboffset,
-                             uint8_t tdd_mapindex, uint16_t Nf);
-
 /**@}*/
 #endif
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h
index 4c433a5683b05be6a2899bb74c0ce449abe0bb25..6b84a5f9693981e816767a68a8e09704d83895c3 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h
+++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h
@@ -36,9 +36,11 @@
 #include "../LTE_TRANSPORT/mdci.h"
 #include "../LTE_TRANSPORT/uci_common.h"
 #include "../LTE_TRANSPORT/transport_common.h"
+/*
 #ifndef STANDALONE_COMPILE
 #include "UTIL/LISTS/list.h"
 #endif
+*/
 
 #include "../LTE_TRANSPORT/transport_common.h"
 
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c
index de1c3891da078517be8425ebf1556a916df5b6ec..ae3ebbce9dc0ba96df89af0ba7875bf3e7880df8 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c
@@ -52,8 +52,7 @@
 
 
 
-void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch)
-{
+void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch) {
   int i;
   int r;
 
@@ -68,6 +67,7 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch)
           free16(ulsch->harq_processes[i]->b,MAX_ULSCH_PAYLOAD_BYTES);
           ulsch->harq_processes[i]->b = NULL;
         }
+
         for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
           if (ulsch->harq_processes[i]->c[r]) {
             free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
@@ -79,51 +79,47 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch)
         ulsch->harq_processes[i] = NULL;
       }
     }
+
     free16(ulsch,sizeof(LTE_UE_ULSCH_t));
   }
-
 }
 
-LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag)
-{
-
+LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) {
   LTE_UE_ULSCH_t *ulsch;
   unsigned char exit_flag = 0,i,j,r;
   unsigned char bw_scaling =1;
 
   switch (N_RB_UL) {
-  case 6:
-    bw_scaling =16;
-    break;
-
-  case 25:
-    bw_scaling =4;
-    break;
-
-  case 50:
-    bw_scaling =2;
-    break;
- 
-  default:
-    bw_scaling =1;
-    break;
+    case 6:
+      bw_scaling =16;
+      break;
+
+    case 25:
+      bw_scaling =4;
+      break;
+
+    case 50:
+      bw_scaling =2;
+      break;
+
+    default:
+      bw_scaling =1;
+      break;
   }
 
   ulsch = (LTE_UE_ULSCH_t *)malloc16(sizeof(LTE_UE_ULSCH_t));
 
   if (ulsch) {
     memset(ulsch,0,sizeof(LTE_UE_ULSCH_t));
-
     ulsch->Mlimit = 4;
 
     for (i=0; i<8; i++) {
-
       ulsch->harq_processes[i] = (LTE_UL_UE_HARQ_t *)malloc16(sizeof(LTE_UL_UE_HARQ_t));
 
       //      printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]);
       if (ulsch->harq_processes[i]) {
         memset(ulsch->harq_processes[i], 0, sizeof(LTE_UL_UE_HARQ_t));
-        ulsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
+        ulsch->harq_processes[i]->b = (unsigned char *)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
 
         if (ulsch->harq_processes[i]->b)
           memset(ulsch->harq_processes[i]->b,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
@@ -134,7 +130,7 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag)
 
         if (abstraction_flag==0) {
           for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
-            ulsch->harq_processes[i]->c[r] = (unsigned char*)malloc16(((r==0)?8:0) + 3+768);  // account for filler in first segment and CRCs for multiple segment case
+            ulsch->harq_processes[i]->c[r] = (unsigned char *)malloc16(((r==0)?8:0) + 3+768); // account for filler in first segment and CRCs for multiple segment case
 
             if (ulsch->harq_processes[i]->c[r])
               memset(ulsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+768);
@@ -167,8 +163,6 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag)
   LOG_E(PHY,"new_ue_ulsch exit flag, size of  %d ,   %zu\n",exit_flag, sizeof(LTE_UE_ULSCH_t));
   free_ue_ulsch(ulsch);
   return(NULL);
-
-
 }
 
 
@@ -179,15 +173,12 @@ uint32_t ulsch_encoding(uint8_t *a,
                         uint8_t subframe_rx,
                         uint8_t tmode,
                         uint8_t control_only_flag,
-                        uint8_t Nbundled)
-{
-
+                        uint8_t Nbundled) {
   time_stats_t *seg_stats=&ue->ulsch_segmentation_stats;
   time_stats_t *rm_stats=&ue->ulsch_rate_matching_stats;
   time_stats_t *te_stats=&ue->ulsch_turbo_encoding_stats;
   time_stats_t *i_stats=&ue->ulsch_interleaving_stats;
   time_stats_t *m_stats=&ue->ulsch_multiplexing_stats;
-
   //  uint16_t offset;
   uint32_t crc=1;
   uint32_t A;
@@ -237,7 +228,6 @@ uint32_t ulsch_encoding(uint8_t *a,
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING_FILL_CQI, VCD_FUNCTION_IN);
     rnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
     fill_CQI(ulsch,meas,0,harq_pid,ue->frame_parms.N_RB_DL,rnti, tmode,ue->sinr_eff);
-
     LOG_D(PHY,"ULSCH Encoding rnti %x \n", rnti);
     print_CQI(ulsch->o,ulsch->uci_format,0,ue->frame_parms.N_RB_DL);
 
@@ -246,6 +236,7 @@ uint32_t ulsch_encoding(uint8_t *a,
       //LOG_I(PHY,"XXX saving pmi for DL %x\n",pmi2hex_2Ar1(((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi));
       dlsch[0]->pmi_alloc = ((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi;
     }
+
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING_FILL_CQI, VCD_FUNCTION_OUT);
   }
 
@@ -268,17 +259,15 @@ uint32_t ulsch_encoding(uint8_t *a,
   if (control_only_flag == 0) {
     A=ulsch->harq_processes[harq_pid]->TBS;
     Q_m = get_Qm_ul(ulsch->harq_processes[harq_pid]->mcs);
-
     ulsch->harq_processes[harq_pid]->control_only = 0;
-
 #ifdef DEBUG_ULSCH_CODING
     printf("[PHY][UE] ULSCH coding : A %d, Qm %d, mcs %d, harq_pid %d, round %d, RV %d\n",
-        ulsch->harq_processes[harq_pid]->TBS,
-        Q_m,
-        ulsch->harq_processes[harq_pid]->mcs,
-        harq_pid,
-        ulsch->harq_processes[harq_pid]->round,
-        ulsch->harq_processes[harq_pid]->rvidx);
+           ulsch->harq_processes[harq_pid]->TBS,
+           Q_m,
+           ulsch->harq_processes[harq_pid]->mcs,
+           harq_pid,
+           ulsch->harq_processes[harq_pid]->round,
+           ulsch->harq_processes[harq_pid]->rvidx);
 
     for (i=0; i<ulsch->harq_processes[harq_pid]->O_ACK; i++)
       printf("ulsch_coding: o_ACK[%d] %d\n",i,ulsch->o_ACK[i]);
@@ -301,16 +290,13 @@ uint32_t ulsch_encoding(uint8_t *a,
 #endif
 
     if (ulsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
-
       start_meas(seg_stats);
       // Add 24-bit crc (polynomial A) to payload
       crc = crc24a(a,
                    A)>>8;
-
-      a[A>>3] = ((uint8_t*)&crc)[2];
-      a[1+(A>>3)] = ((uint8_t*)&crc)[1];
-      a[2+(A>>3)] = ((uint8_t*)&crc)[0];
-
+      a[A>>3] = ((uint8_t *)&crc)[2];
+      a[1+(A>>3)] = ((uint8_t *)&crc)[1];
+      a[2+(A>>3)] = ((uint8_t *)&crc)[0];
       ulsch->harq_processes[harq_pid]->B = A+24;
       ulsch->harq_processes[harq_pid]->b = a;
       lte_segmentation(ulsch->harq_processes[harq_pid]->b,
@@ -322,7 +308,6 @@ uint32_t ulsch_encoding(uint8_t *a,
                        &ulsch->harq_processes[harq_pid]->Kplus,
                        &ulsch->harq_processes[harq_pid]->Kminus,
                        &ulsch->harq_processes[harq_pid]->F);
-
       stop_meas(seg_stats);
 
       for (r=0; r<ulsch->harq_processes[harq_pid]->C; r++) {
@@ -332,25 +317,20 @@ uint32_t ulsch_encoding(uint8_t *a,
           Kr = ulsch->harq_processes[harq_pid]->Kplus;
 
         Kr_bytes = Kr>>3;
-
 #ifdef DEBUG_ULSCH_CODING
         printf("Generating Code Segment %d (%d bits)\n",r,Kr);
         // generate codewords
-
         printf("bits_per_codeword (Kr)= %d\n",Kr);
         printf("N_RB = %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
         printf("Ncp %d\n",frame_parms->Ncp);
         printf("Qm %d\n",Q_m);
 #endif
-
         //  offset=0;
-
-
         start_meas(te_stats);
         encoder(ulsch->harq_processes[harq_pid]->c[r],
-        	Kr>>3,
-        	&ulsch->harq_processes[harq_pid]->d[r][96],
-        	(r==0) ? ulsch->harq_processes[harq_pid]->F : 0
+                Kr>>3,
+                &ulsch->harq_processes[harq_pid]->d[r][96],
+                (r==0) ? ulsch->harq_processes[harq_pid]->F : 0
                );
         stop_meas(te_stats);
 #ifdef DEBUG_ULSCH_CODING
@@ -366,7 +346,6 @@ uint32_t ulsch_encoding(uint8_t *a,
                                        ulsch->harq_processes[harq_pid]->w[r]);
         stop_meas(i_stats);
       }
-
     }
 
     if (ulsch->harq_processes[harq_pid]->C == 0) {
@@ -392,7 +371,6 @@ uint32_t ulsch_encoding(uint8_t *a,
 
   ulsch->harq_processes[harq_pid]->sumKr = sumKr;
   // Compute Q_ri (p. 23 36-212)
-
   Qprime = ulsch->O_RI*ulsch->harq_processes[harq_pid]->Msc_initial*ulsch->harq_processes[harq_pid]->Nsymb_initial * ulsch->beta_offset_ri_times8;
 
   if (Qprime > 0) {
@@ -407,7 +385,6 @@ uint32_t ulsch_encoding(uint8_t *a,
 
   Q_RI = Q_m*Qprime;
   Qprime_RI = Qprime;
-
   // Compute Q_ack (p. 23 36-212)
   Qprime = ulsch->harq_processes[harq_pid]->O_ACK*ulsch->harq_processes[harq_pid]->Msc_initial*ulsch->harq_processes[harq_pid]->Nsymb_initial * ulsch->beta_offset_harqack_times8;
 
@@ -423,20 +400,18 @@ uint32_t ulsch_encoding(uint8_t *a,
 
   Q_ACK = Qprime * Q_m;
   Qprime_ACK = Qprime;
-
   LOG_D(PHY,"UE (%x/%d) O_ACK %d, Mcs_initial %d, Nsymb_initial %d, beta_offset_harqack*8 %d, sum Kr %d, Qprime_ACK %d, Q_ACK %d\n",
-      rnti, harq_pid,
-      ulsch->harq_processes[harq_pid]->O_ACK,
-      ulsch->harq_processes[harq_pid]->Msc_initial,
-      ulsch->harq_processes[harq_pid]->Nsymb_initial,
-      ulsch->beta_offset_harqack_times8,
-      sumKr,
-      Qprime_ACK,
-      Q_ACK);
+        rnti, harq_pid,
+        ulsch->harq_processes[harq_pid]->O_ACK,
+        ulsch->harq_processes[harq_pid]->Msc_initial,
+        ulsch->harq_processes[harq_pid]->Nsymb_initial,
+        ulsch->beta_offset_harqack_times8,
+        sumKr,
+        Qprime_ACK,
+        Q_ACK);
 
   // Compute Q_cqi, assume O>11, p. 26 36-212
   if (control_only_flag == 0) {
-
     if (ulsch->O < 12)
       L=0;
     else
@@ -446,13 +421,13 @@ uint32_t ulsch_encoding(uint8_t *a,
       Qprime = (ulsch->O + L) * ulsch->harq_processes[harq_pid]->Msc_initial*ulsch->harq_processes[harq_pid]->Nsymb_initial * ulsch->beta_offset_cqi_times8;
     else
       Qprime = 0;
-      LOG_D(PHY,"Qprime %d, O_RI %d + %d, Msc %d, Nym %d beta %d\n",
-                  Qprime,
-                  ulsch->O, L,
-                  ulsch->harq_processes[harq_pid]->Msc_initial,
-                  ulsch->harq_processes[harq_pid]->Nsymb_initial,
-                  ulsch->beta_offset_cqi_times8);
 
+    LOG_D(PHY,"Qprime %d, O_RI %d + %d, Msc %d, Nym %d beta %d\n",
+          Qprime,
+          ulsch->O, L,
+          ulsch->harq_processes[harq_pid]->Msc_initial,
+          ulsch->harq_processes[harq_pid]->Nsymb_initial,
+          ulsch->beta_offset_cqi_times8);
 
     if (Qprime > 0) {
       if ((Qprime % (8*sumKr)) > 0)
@@ -463,31 +438,29 @@ uint32_t ulsch_encoding(uint8_t *a,
 
     G = ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch);
     LOG_D(PHY,"G: rb %d * ( 12 * Qm %d ) * nsymb %d, Qprime %d, O_RI %d\n", ulsch->harq_processes[harq_pid]->nb_rb, Q_m, ulsch->Nsymb_pusch, Qprime, ulsch->O_RI);
+
     if (Qprime > (G - ulsch->O_RI))
       Qprime = G - ulsch->O_RI;
 
     Q_CQI = Q_m * Qprime;
     Qprime_CQI = Qprime;
-
-
-
     G = G - Q_RI - Q_CQI;
-    LOG_D(PHY,"new G: %d, Q_RI %d Q_CQI %d\n",  G , Q_RI , Q_CQI);
+    LOG_D(PHY,"new G: %d, Q_RI %d Q_CQI %d\n",  G, Q_RI, Q_CQI);
     ulsch->harq_processes[harq_pid]->G = G;
 
-/*
-    LOG_I(PHY,"ULSCH Encoding G %d, Q_RI %d (O_RI%d, Msc_initial %d, Nsymb_initial%d, beta_offset_ri_times8 %d), Q_CQI %d, Q_ACK %d \n",G,Q_RI,ulsch->O_RI,ulsch->harq_processes[harq_pid]->Msc_initial,ulsch->harq_processes[harq_pid]->Nsymb_initial,ulsch->beta_offset_ri_times8,Q_CQI,Q_ACK);
-
-    LOG_I(PHY,"ULSCH Encoding (Nid_cell %d, rnti %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d\n",
-          frame_parms->Nid_cell,ulsch->rnti,
-          harq_pid,
-          ulsch->harq_processes[harq_pid]->round,
-          ulsch->harq_processes[harq_pid]->rvidx,
-          ulsch->harq_processes[harq_pid]->mcs,
-          ulsch->O_RI,
-          ulsch->harq_processes[harq_pid]->O_ACK,
-          G);
-*/
+    /*
+        LOG_I(PHY,"ULSCH Encoding G %d, Q_RI %d (O_RI%d, Msc_initial %d, Nsymb_initial%d, beta_offset_ri_times8 %d), Q_CQI %d, Q_ACK %d \n",G,Q_RI,ulsch->O_RI,ulsch->harq_processes[harq_pid]->Msc_initial,ulsch->harq_processes[harq_pid]->Nsymb_initial,ulsch->beta_offset_ri_times8,Q_CQI,Q_ACK);
+
+        LOG_I(PHY,"ULSCH Encoding (Nid_cell %d, rnti %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d\n",
+              frame_parms->Nid_cell,ulsch->rnti,
+              harq_pid,
+              ulsch->harq_processes[harq_pid]->round,
+              ulsch->harq_processes[harq_pid]->rvidx,
+              ulsch->harq_processes[harq_pid]->mcs,
+              ulsch->O_RI,
+              ulsch->harq_processes[harq_pid]->O_ACK,
+              G);
+    */
 
     if ((int)G < 0) {
       LOG_E(PHY,"FATAL: ulsch_coding.c G < 0 (%d) : Q_RI %d, Q_CQI %d, O %d, betaCQI_times8 %d)\n",G,Q_RI,Q_CQI,ulsch->O,ulsch->beta_offset_cqi_times8);
@@ -495,26 +468,21 @@ uint32_t ulsch_encoding(uint8_t *a,
       return(-1);
     }
 
-
     // Data and control multiplexing (5.2.2.7 36-212)
-
     H = G + Q_CQI;
     Hprime = H/Q_m;
 
-
-
     // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
     // outputs for each code segment, see Section 5.1.5 p.20
 
     for (r=0; r<ulsch->harq_processes[harq_pid]->C; r++) {
 #ifdef DEBUG_ULSCH_CODING
       printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
-          r,
-          G,
-          Kr*3,
-          Q_m,ulsch->harq_processes[harq_pid]->nb_rb);
+             r,
+             G,
+             Kr*3,
+             Q_m,ulsch->harq_processes[harq_pid]->nb_rb);
 #endif
-
       start_meas(rm_stats);
       r_offset += lte_rate_matching_turbo(ulsch->harq_processes[harq_pid]->RTC[r],
                                           G,
@@ -529,7 +497,7 @@ uint32_t ulsch_encoding(uint8_t *a,
                                           1,
                                           r,
                                           ulsch->harq_processes[harq_pid]->nb_rb);
-                                          //ulsch->harq_processes[harq_pid]->mcs);                       // r
+      //ulsch->harq_processes[harq_pid]->mcs);                       // r
       stop_meas(rm_stats);
 #ifdef DEBUG_ULSCH_CODING
 
@@ -544,7 +512,6 @@ uint32_t ulsch_encoding(uint8_t *a,
     Hprime = H/Q_m;
   }
 
-
   //  Do CQI coding
   if ((ulsch->O>1) && (ulsch->O < 12)) {
     LOG_E(PHY,"short CQI sizes not supported yet\n");
@@ -558,23 +525,18 @@ uint32_t ulsch_encoding(uint8_t *a,
     printf("crc(cqi) tx : %x\n",crc);
 #endif
     memset((void *)&ulsch->o_d[0],LTE_NULL,96);
-
     ccodelte_encode(ulsch->O,
                     1,
                     o_flip,
                     &ulsch->o_d[96],
                     0);
-
-
     o_RCC = sub_block_interleaving_cc(8+ulsch->O,
                                       &ulsch->o_d[96],
                                       ulsch->o_w);
-
     lte_rate_matching_cc(o_RCC,
                          Q_CQI,
                          ulsch->o_w,
                          ulsch->q);
-
   }
 
   i=0;
@@ -582,29 +544,29 @@ uint32_t ulsch_encoding(uint8_t *a,
   //  Do RI coding
   if (ulsch->O_RI == 1) {
     switch (Q_m) {
-    case 2:
-      ulsch->q_RI[0] = ulsch->o_RI[0];
-      ulsch->q_RI[1] = PUSCH_y;//ulsch->o_RI[0];
-      len_RI=2;
-      break;
-
-    case 4:
-      ulsch->q_RI[0] = ulsch->o_RI[0];
-      ulsch->q_RI[1] = PUSCH_y;//1;
-      ulsch->q_RI[2] = PUSCH_x;//ulsch->o_RI[0];
-      ulsch->q_RI[3] = PUSCH_x;//1;
-      len_RI=4;
-      break;
-
-    case 6:
-      ulsch->q_RI[0] = ulsch->o_RI[0];
-      ulsch->q_RI[1] = PUSCH_y;//1;
-      ulsch->q_RI[2] = PUSCH_x;//1;
-      ulsch->q_RI[3] = PUSCH_x;//ulsch->o_RI[0];
-      ulsch->q_RI[4] = PUSCH_x;//1;
-      ulsch->q_RI[5] = PUSCH_x;//1;
-      len_RI=6;
-      break;
+      case 2:
+        ulsch->q_RI[0] = ulsch->o_RI[0];
+        ulsch->q_RI[1] = PUSCH_y;//ulsch->o_RI[0];
+        len_RI=2;
+        break;
+
+      case 4:
+        ulsch->q_RI[0] = ulsch->o_RI[0];
+        ulsch->q_RI[1] = PUSCH_y;//1;
+        ulsch->q_RI[2] = PUSCH_x;//ulsch->o_RI[0];
+        ulsch->q_RI[3] = PUSCH_x;//1;
+        len_RI=4;
+        break;
+
+      case 6:
+        ulsch->q_RI[0] = ulsch->o_RI[0];
+        ulsch->q_RI[1] = PUSCH_y;//1;
+        ulsch->q_RI[2] = PUSCH_x;//1;
+        ulsch->q_RI[3] = PUSCH_x;//ulsch->o_RI[0];
+        ulsch->q_RI[4] = PUSCH_x;//1;
+        ulsch->q_RI[5] = PUSCH_x;//1;
+        len_RI=6;
+        break;
     }
   } else if (ulsch->O_RI>1) {
     LOG_E(PHY,"RI cannot be more than 1 bit yet\n");
@@ -616,35 +578,35 @@ uint32_t ulsch_encoding(uint8_t *a,
   wACK_idx = (ulsch->bundling==0) ? 4 : ((Nbundled-1)&3);
 #ifdef DEBUG_ULSCH_CODING
   printf("ulsch_coding.c: Bundling %d, Nbundled %d, wACK_idx %d\n",
-      ulsch->bundling,Nbundled,wACK_idx);
+         ulsch->bundling,Nbundled,wACK_idx);
 #endif
 
   // 1-bit ACK/NAK
   if (ulsch->harq_processes[harq_pid]->O_ACK == 1) {
     switch (Q_m) {
-    case 2:
-      ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
-      ulsch->q_ACK[1] = (ulsch->bundling==0)? PUSCH_y : ((ulsch->o_ACK[0]+wACK[wACK_idx][1])&1);//ulsch->o_ACK[0];
-      len_ACK = 2;
-      break;
-
-    case 4:
-      ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
-      ulsch->q_ACK[1] = (ulsch->bundling==0)? PUSCH_y : ((ulsch->o_ACK[0]+wACK[wACK_idx][1])&1);
-      ulsch->q_ACK[2] = PUSCH_x;
-      ulsch->q_ACK[3] = PUSCH_x;
-      len_ACK = 4;
-      break;
-
-    case 6:
-      ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
-      ulsch->q_ACK[1] = (ulsch->bundling==0)? PUSCH_y : ((ulsch->o_ACK[0]+wACK[wACK_idx][1])&1);
-      ulsch->q_ACK[2] = PUSCH_x;
-      ulsch->q_ACK[3] = PUSCH_x;
-      ulsch->q_ACK[4] = PUSCH_x;
-      ulsch->q_ACK[6] = PUSCH_x;
-      len_ACK = 6;
-      break;
+      case 2:
+        ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
+        ulsch->q_ACK[1] = (ulsch->bundling==0)? PUSCH_y : ((ulsch->o_ACK[0]+wACK[wACK_idx][1])&1);//ulsch->o_ACK[0];
+        len_ACK = 2;
+        break;
+
+      case 4:
+        ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
+        ulsch->q_ACK[1] = (ulsch->bundling==0)? PUSCH_y : ((ulsch->o_ACK[0]+wACK[wACK_idx][1])&1);
+        ulsch->q_ACK[2] = PUSCH_x;
+        ulsch->q_ACK[3] = PUSCH_x;
+        len_ACK = 4;
+        break;
+
+      case 6:
+        ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
+        ulsch->q_ACK[1] = (ulsch->bundling==0)? PUSCH_y : ((ulsch->o_ACK[0]+wACK[wACK_idx][1])&1);
+        ulsch->q_ACK[2] = PUSCH_x;
+        ulsch->q_ACK[3] = PUSCH_x;
+        ulsch->q_ACK[4] = PUSCH_x;
+        ulsch->q_ACK[6] = PUSCH_x;
+        len_ACK = 6;
+        break;
     }
   }
 
@@ -653,56 +615,53 @@ uint32_t ulsch_encoding(uint8_t *a,
     ack_parity = (ulsch->o_ACK[0]+ulsch->o_ACK[1])&1;
 
     switch (Q_m) {
-    case 2:
-      ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
-      ulsch->q_ACK[1] = (ulsch->o_ACK[1]+wACK[wACK_idx][0])&1;
-      ulsch->q_ACK[2] = (ack_parity+wACK[wACK_idx][0])&1;
-      ulsch->q_ACK[3] = (ulsch->o_ACK[0]+wACK[wACK_idx][1])&1;
-      ulsch->q_ACK[4] = (ulsch->o_ACK[1]+wACK[wACK_idx][1])&1;
-      ulsch->q_ACK[5] = (ack_parity+wACK[wACK_idx][1])&1;
-      len_ACK = 6;
-      break;
-
-    case 4:
-      ulsch->q_ACK[0]  = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
-      ulsch->q_ACK[1]  = (ulsch->o_ACK[1]+wACK[wACK_idx][0])&1;
-      ulsch->q_ACK[2]  = PUSCH_x;
-      ulsch->q_ACK[3]  = PUSCH_x;//1;
-      ulsch->q_ACK[4]  = (ack_parity+wACK[wACK_idx][0])&1;
-      ulsch->q_ACK[5]  = (ulsch->o_ACK[0]+wACK[wACK_idx][1])&1;
-      ulsch->q_ACK[6]  = PUSCH_x;
-      ulsch->q_ACK[7]  = PUSCH_x;//1;
-      ulsch->q_ACK[8]  = (ulsch->o_ACK[1]+wACK[wACK_idx][1])&1;
-      ulsch->q_ACK[9]  = (ack_parity+wACK[wACK_idx][1])&1;
-      ulsch->q_ACK[10] = PUSCH_x;
-      ulsch->q_ACK[11] = PUSCH_x;//1;
-      len_ACK = 12;
-      break;
-
-    case 6:
-      ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
-      ulsch->q_ACK[1] = (ulsch->o_ACK[1]+wACK[wACK_idx][0])&1;
-      ulsch->q_ACK[2] = PUSCH_x;
-      ulsch->q_ACK[3] = PUSCH_x;
-      ulsch->q_ACK[4] = PUSCH_x;
-      ulsch->q_ACK[5] = PUSCH_x;
-
-      ulsch->q_ACK[6] = (ack_parity+wACK[wACK_idx][0])&1;
-      ulsch->q_ACK[7] = (ulsch->o_ACK[0]+wACK[wACK_idx][1])&1;
-      ulsch->q_ACK[8] = PUSCH_x;
-      ulsch->q_ACK[9] = PUSCH_x;
-      ulsch->q_ACK[10] = PUSCH_x;
-      ulsch->q_ACK[11] = PUSCH_x;
-
-      ulsch->q_ACK[12] = (ulsch->o_ACK[1]+wACK[wACK_idx][1])&1;
-      ulsch->q_ACK[13] = (ack_parity+wACK[wACK_idx][1])&1;
-      ulsch->q_ACK[14] = PUSCH_x;
-      ulsch->q_ACK[15] = PUSCH_x;
-      ulsch->q_ACK[16] = PUSCH_x;
-      ulsch->q_ACK[17] = PUSCH_x;
-      len_ACK = 18;
-
-      break;
+      case 2:
+        ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
+        ulsch->q_ACK[1] = (ulsch->o_ACK[1]+wACK[wACK_idx][0])&1;
+        ulsch->q_ACK[2] = (ack_parity+wACK[wACK_idx][0])&1;
+        ulsch->q_ACK[3] = (ulsch->o_ACK[0]+wACK[wACK_idx][1])&1;
+        ulsch->q_ACK[4] = (ulsch->o_ACK[1]+wACK[wACK_idx][1])&1;
+        ulsch->q_ACK[5] = (ack_parity+wACK[wACK_idx][1])&1;
+        len_ACK = 6;
+        break;
+
+      case 4:
+        ulsch->q_ACK[0]  = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
+        ulsch->q_ACK[1]  = (ulsch->o_ACK[1]+wACK[wACK_idx][0])&1;
+        ulsch->q_ACK[2]  = PUSCH_x;
+        ulsch->q_ACK[3]  = PUSCH_x;//1;
+        ulsch->q_ACK[4]  = (ack_parity+wACK[wACK_idx][0])&1;
+        ulsch->q_ACK[5]  = (ulsch->o_ACK[0]+wACK[wACK_idx][1])&1;
+        ulsch->q_ACK[6]  = PUSCH_x;
+        ulsch->q_ACK[7]  = PUSCH_x;//1;
+        ulsch->q_ACK[8]  = (ulsch->o_ACK[1]+wACK[wACK_idx][1])&1;
+        ulsch->q_ACK[9]  = (ack_parity+wACK[wACK_idx][1])&1;
+        ulsch->q_ACK[10] = PUSCH_x;
+        ulsch->q_ACK[11] = PUSCH_x;//1;
+        len_ACK = 12;
+        break;
+
+      case 6:
+        ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
+        ulsch->q_ACK[1] = (ulsch->o_ACK[1]+wACK[wACK_idx][0])&1;
+        ulsch->q_ACK[2] = PUSCH_x;
+        ulsch->q_ACK[3] = PUSCH_x;
+        ulsch->q_ACK[4] = PUSCH_x;
+        ulsch->q_ACK[5] = PUSCH_x;
+        ulsch->q_ACK[6] = (ack_parity+wACK[wACK_idx][0])&1;
+        ulsch->q_ACK[7] = (ulsch->o_ACK[0]+wACK[wACK_idx][1])&1;
+        ulsch->q_ACK[8] = PUSCH_x;
+        ulsch->q_ACK[9] = PUSCH_x;
+        ulsch->q_ACK[10] = PUSCH_x;
+        ulsch->q_ACK[11] = PUSCH_x;
+        ulsch->q_ACK[12] = (ulsch->o_ACK[1]+wACK[wACK_idx][1])&1;
+        ulsch->q_ACK[13] = (ack_parity+wACK[wACK_idx][1])&1;
+        ulsch->q_ACK[14] = PUSCH_x;
+        ulsch->q_ACK[15] = PUSCH_x;
+        ulsch->q_ACK[16] = PUSCH_x;
+        ulsch->q_ACK[17] = PUSCH_x;
+        len_ACK = 18;
+        break;
     }
   }
 
@@ -712,23 +671,17 @@ uint32_t ulsch_encoding(uint8_t *a,
     return(-1);
   }
 
-
   // channel multiplexing/interleaving
-
   start_meas(m_stats);
   Hpp = Hprime + Q_RI;
-
   Cmux       = ulsch->Nsymb_pusch;
   Rmux       = Hpp*Q_m/Cmux;
   Rmux_prime = Rmux/Q_m;
-
   Qprime_RI  = Q_RI / Q_m;
   Qprime_ACK = Q_ACK / Q_m;
   Qprime_CQI = Q_CQI / Q_m;
-
   //  printf("Qprime_CQI = %d\n",Qprime_CQI);
   // RI BITS
-
   memset(y,LTE_NULL,Q_m*Hpp);
 
   if (frame_parms->Ncp == 0)
@@ -747,10 +700,8 @@ uint32_t ulsch_encoding(uint8_t *a,
     }
 
     j=(j+3)&3;
-
   }
 
-
   // CQI and Data bits
   j=0;
   /*
@@ -775,7 +726,6 @@ uint32_t ulsch_encoding(uint8_t *a,
   */
 
   for (i=0; i<Qprime_CQI; i++) {
-
     while (y[Q_m*j] != LTE_NULL) j++;
 
     for (q=0; q<Q_m; q++) {
@@ -789,47 +739,44 @@ uint32_t ulsch_encoding(uint8_t *a,
   j2 = j*Q_m;
 
   switch (Q_m) {
+    case 2:
+      for (iprime=0; iprime<(Hprime-Qprime_CQI)<<1; iprime+=2) {
+        while (y[j2] != LTE_NULL) j2+=2;
 
-  case 2:
-
-    for (iprime=0; iprime<(Hprime-Qprime_CQI)<<1; iprime+=2) {
-      while (y[j2] != LTE_NULL) j2+=2;
-
-      y[j2]   = ulsch->e[iprime];
-      y[1+j2] = ulsch->e[1+iprime];
-      j2+=2;
-    }
-
-    break;
-
-  case 4:
-    for (iprime=0; iprime<(Hprime-Qprime_CQI)<<2; iprime+=4) {
-      while (y[j2] != LTE_NULL) j2+=4;
-
-      y[j2]   = ulsch->e[iprime];
-      y[1+j2] = ulsch->e[1+iprime];
-      y[2+j2] = ulsch->e[2+iprime];
-      y[3+j2] = ulsch->e[3+iprime];
-      j2+=4;
-    }
+        y[j2]   = ulsch->e[iprime];
+        y[1+j2] = ulsch->e[1+iprime];
+        j2+=2;
+      }
 
-    break;
+      break;
 
-  case 6:
-    for (iprime=0; iprime<(Hprime-Qprime_CQI)*6; iprime+=6) {
-      while (y[j2] != LTE_NULL) j2+=6;
+    case 4:
+      for (iprime=0; iprime<(Hprime-Qprime_CQI)<<2; iprime+=4) {
+        while (y[j2] != LTE_NULL) j2+=4;
+
+        y[j2]   = ulsch->e[iprime];
+        y[1+j2] = ulsch->e[1+iprime];
+        y[2+j2] = ulsch->e[2+iprime];
+        y[3+j2] = ulsch->e[3+iprime];
+        j2+=4;
+      }
 
-      y[j2]   = ulsch->e[iprime];
-      y[1+j2] = ulsch->e[1+iprime];
-      y[2+j2] = ulsch->e[2+iprime];
-      y[3+j2] = ulsch->e[3+iprime];
-      y[4+j2] = ulsch->e[4+iprime];
-      y[5+j2] = ulsch->e[5+iprime];
-      j2+=6;
-    }
+      break;
 
-    break;
+    case 6:
+      for (iprime=0; iprime<(Hprime-Qprime_CQI)*6; iprime+=6) {
+        while (y[j2] != LTE_NULL) j2+=6;
+
+        y[j2]   = ulsch->e[iprime];
+        y[1+j2] = ulsch->e[1+iprime];
+        y[2+j2] = ulsch->e[2+iprime];
+        y[3+j2] = ulsch->e[3+iprime];
+        y[4+j2] = ulsch->e[4+iprime];
+        y[5+j2] = ulsch->e[5+iprime];
+        j2+=6;
+      }
 
+      break;
   }
 
   // HARQ-ACK Bits (Note these overwrite some bits)
@@ -848,57 +795,56 @@ uint32_t ulsch_encoding(uint8_t *a,
       y[q+(Q_m*((r*Cmux) + columnset[j]))]  = ulsch->q_ACK[(q+(Q_m*i))%len_ACK];
 #ifdef DEBUG_ULSCH_CODING
       printf("ulsch_coding.c: ACK %d => y[%d]=%d (i %d, r*Cmux %d, columnset %d)\n",q+(Q_m*i),
-          q+(Q_m*((r*Cmux) + columnset[j])),ulsch->q_ACK[(q+(Q_m*i))%len_ACK],
-          i,r*Cmux,columnset[j]);
+             q+(Q_m*((r*Cmux) + columnset[j])),ulsch->q_ACK[(q+(Q_m*i))%len_ACK],
+             i,r*Cmux,columnset[j]);
 #endif
     }
 
     j=(j+3)&3;
-
   }
 
   // write out buffer
   j=0;
 
   switch (Q_m) {
-  case 2:
-    for (i=0; i<Cmux; i++)
-      for (r=0; r<Rmux_prime; r++) {
-        yptr=&y[((r*Cmux)+i)<<1];
-        ulsch->h[j++] = *yptr++;
-        ulsch->h[j++] = *yptr++;
-      }
+    case 2:
+      for (i=0; i<Cmux; i++)
+        for (r=0; r<Rmux_prime; r++) {
+          yptr=&y[((r*Cmux)+i)<<1];
+          ulsch->h[j++] = *yptr++;
+          ulsch->h[j++] = *yptr++;
+        }
 
-    break;
+      break;
 
-  case 4:
-    for (i=0; i<Cmux; i++)
-      for (r=0; r<Rmux_prime; r++) {
-        yptr = &y[((r*Cmux)+i)<<2];
-        ulsch->h[j++] = *yptr++;
-        ulsch->h[j++] = *yptr++;
-        ulsch->h[j++] = *yptr++;
-        ulsch->h[j++] = *yptr++;
-      }
+    case 4:
+      for (i=0; i<Cmux; i++)
+        for (r=0; r<Rmux_prime; r++) {
+          yptr = &y[((r*Cmux)+i)<<2];
+          ulsch->h[j++] = *yptr++;
+          ulsch->h[j++] = *yptr++;
+          ulsch->h[j++] = *yptr++;
+          ulsch->h[j++] = *yptr++;
+        }
 
-    break;
-
-  case 6:
-    for (i=0; i<Cmux; i++)
-      for (r=0; r<Rmux_prime; r++) {
-        yptr = &y[((r*Cmux)+i)*6];
-        ulsch->h[j++] = *yptr++;
-        ulsch->h[j++] = *yptr++;
-        ulsch->h[j++] = *yptr++;
-        ulsch->h[j++] = *yptr++;
-        ulsch->h[j++] = *yptr++;
-        ulsch->h[j++] = *yptr++;
-      }
+      break;
 
-    break;
+    case 6:
+      for (i=0; i<Cmux; i++)
+        for (r=0; r<Rmux_prime; r++) {
+          yptr = &y[((r*Cmux)+i)*6];
+          ulsch->h[j++] = *yptr++;
+          ulsch->h[j++] = *yptr++;
+          ulsch->h[j++] = *yptr++;
+          ulsch->h[j++] = *yptr++;
+          ulsch->h[j++] = *yptr++;
+          ulsch->h[j++] = *yptr++;
+        }
 
-  default:
-    break;
+      break;
+
+    default:
+      break;
   }
 
   stop_meas(m_stats);
diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c
index b1f419b1724b8462489ba9d25789685265ddf52b..d592aa466e416da54d805dd279de0519158594c0 100644
--- a/openair1/PHY/MODULATION/beamforming.c
+++ b/openair1/PHY/MODULATION/beamforming.c
@@ -44,7 +44,6 @@
  
 #include "PHY/defs_common.h"
 #include "PHY/defs_eNB.h"
-#include "PHY/phy_extern.h"
 #include "PHY/CODING/coding_defs.h"
 #include "PHY/CODING/coding_extern.h"
 #include "PHY/CODING/lte_interleaver_inline.h"
@@ -145,7 +144,8 @@ int nr_beam_precoding(int32_t **txdataF,
                       int slot,
                       int symbol,
                       int aa,
-                      int nb_antenna_ports)
+                      int nb_antenna_ports,
+                      int offset)
 {
 
 
@@ -155,14 +155,14 @@ int nr_beam_precoding(int32_t **txdataF,
   memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size));
 
   for (p=0; p<nb_antenna_ports; p++) {
-    if ((frame_parms->L_ssb >> (63-p)) & 0x01)  {
-      multadd_cpx_vector((int16_t*)&txdataF[p][symbol*frame_parms->ofdm_symbol_size],
+    //if ((frame_parms->L_ssb >> (63-p)) & 0x01)  {
+      multadd_cpx_vector((int16_t*)&txdataF[p][(symbol*frame_parms->ofdm_symbol_size)+offset],
 			 (int16_t*)beam_weights[p][aa], 
 			 (int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], 
 			 0, 
 			 frame_parms->ofdm_symbol_size, 
 			 15);
-    }
+    //}
   }
   return 0;
 }
diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h
index 72a1334fe99be0e88f67a26480897e74bc8bbbfa..20fdaa7ad84f0fef7433432c7ac0c847f9fd1f99 100644
--- a/openair1/PHY/MODULATION/modulation_UE.h
+++ b/openair1/PHY/MODULATION/modulation_UE.h
@@ -51,16 +51,13 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue,
 int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue,
                 UE_nr_rxtx_proc_t *proc,
                 unsigned char l,
-                unsigned char Ns,
-                int sample_offset,
-                int no_prefix);
+                unsigned char Ns);
 
 int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
                           UE_nr_rxtx_proc_t *proc,
                           unsigned char symbol,
                           unsigned char Ns,
-                          int sample_offset,
-                          int no_prefix);
+                          int sample_offset);
 
 int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
                    unsigned char l,
diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c
index ed9a859fb64673c67faded9b0e33d4948b567a22..e32f6bf575add7a80ad80e60b9938bbccb770471 100644
--- a/openair1/PHY/MODULATION/nr_modulation.c
+++ b/openair1/PHY/MODULATION/nr_modulation.c
@@ -22,6 +22,101 @@
 #include "nr_modulation.h"
 #include "PHY/NR_REFSIG/nr_mod_table.h"
 
+//Table 6.3.1.5-1 Precoding Matrix W 1 layer 2 antenna ports 'n' = -1 and 'o' = -j
+char nr_W_1l_2p[6][2][1] = {
+  {{'1'}, {'0'}},//pmi 0
+  {{'0'}, {'1'}},
+  {{'1'}, {'1'}},
+  {{'1'}, {'n'}},
+  {{'1'}, {'j'}},
+  {{'1'}, {'o'}}//pmi 5
+};
+
+//Table 6.3.1.5-3 Precoding Matrix W 1 layer 4 antenna ports 'n' = -1 and 'o' = -j
+char nr_W_1l_4p[28][4][1] = {
+  {{'1'}, {'0'}, {'0'}, {'0'}},//pmi 0
+  {{'0'}, {'1'}, {'0'}, {'0'}},
+  {{'0'}, {'0'}, {'1'}, {'0'}},
+  {{'0'}, {'0'}, {'0'}, {'1'}},
+  {{'1'}, {'0'}, {'1'}, {'0'}},
+  {{'1'}, {'0'}, {'n'}, {'0'}},
+  {{'1'}, {'0'}, {'j'}, {'0'}},
+  {{'1'}, {'0'}, {'o'}, {'0'}},//pmi 7
+  {{'0'}, {'1'}, {'0'}, {'1'}},//pmi 8
+  {{'0'}, {'1'}, {'0'}, {'n'}},
+  {{'0'}, {'1'}, {'0'}, {'j'}},
+  {{'0'}, {'1'}, {'0'}, {'o'}},
+  {{'1'}, {'1'}, {'1'}, {'1'}},
+  {{'1'}, {'1'}, {'j'}, {'j'}},
+  {{'1'}, {'1'}, {'n'}, {'n'}},
+  {{'1'}, {'1'}, {'o'}, {'o'}},
+  {{'1'}, {'j'}, {'1'}, {'j'}},//pmi 16
+  {{'1'}, {'j'}, {'j'}, {'n'}},
+  {{'1'}, {'j'}, {'n'}, {'o'}},
+  {{'1'}, {'j'}, {'o'}, {'1'}},
+  {{'1'}, {'n'}, {'1'}, {'n'}},
+  {{'1'}, {'n'}, {'j'}, {'o'}},
+  {{'1'}, {'n'}, {'n'}, {'1'}},
+  {{'1'}, {'n'}, {'o'}, {'j'}},//pmi 23
+  {{'1'}, {'o'}, {'1'}, {'o'}},//pmi 24
+  {{'1'}, {'o'}, {'j'}, {'1'}},
+  {{'1'}, {'o'}, {'n'}, {'j'}},
+  {{'1'}, {'o'}, {'o'}, {'n'}}//pmi 27
+};
+
+//Table 6.3.1.5-4 Precoding Matrix W 2 antenna ports layers 2  'n' = -1 and 'o' = -j
+char nr_W_2l_2p[3][2][2] = {
+  {{'1', '0'}, {'0', '1'}},//pmi 0
+  {{'1', '1'}, {'1', 'n'}},
+  {{'1', '1'}, {'j', 'o'}} //pmi 2
+};
+
+//Table 6.3.1.5-5 Precoding Matrix W 2 layers 4 antenna ports 'n' = -1 and 'o' = -j
+char nr_W_2l_4p[22][4][2] = {
+  {{'1', '0'}, {'0', '1'}, {'0', '0'}, {'0', '0'}},//pmi 0
+  {{'1', '0'}, {'0', '0'}, {'0', '1'}, {'0', '0'}},
+  {{'1', '0'}, {'0', '0'}, {'0', '0'}, {'0', '1'}},
+  {{'0', '0'}, {'1', '0'}, {'0', '1'}, {'0', '0'}},//pmi 3
+  {{'0', '0'}, {'1', '0'}, {'0', '0'}, {'0', '1'}},//pmi 4
+  {{'0', '0'}, {'0', '0'}, {'1', '0'}, {'0', '1'}},
+  {{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'o'}},
+  {{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'j'}},
+  {{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', '1'}},//pmi 8
+  {{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', 'n'}},
+  {{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'o'}},
+  {{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'j'}},//pmi 11
+  {{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', '1'}},//pmi 12
+  {{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', 'n'}},
+  {{'1', '1'}, {'1', '1'}, {'1', 'n'}, {'1', 'n'}},
+  {{'1', '1'}, {'1', '1'}, {'j', 'o'}, {'j', 'o'}},//pmi 15
+  {{'1', '1'}, {'j', 'j'}, {'1', 'n'}, {'j', 'o'}},//pmi 16
+  {{'1', '1'}, {'j', 'j'}, {'j', 'o'}, {'n', '1'}},
+  {{'1', '1'}, {'n', 'n'}, {'1', 'n'}, {'n', '1'}},
+  {{'1', '1'}, {'n', 'n'}, {'j', 'o'}, {'o', 'j'}},//pmi 19
+  {{'1', '1'}, {'o', 'o'}, {'1', 'n'}, {'o', 'j'}},
+  {{'1', '1'}, {'o', 'o'}, {'j', 'o'}, {'1', 'n'}}//pmi 21
+};
+
+//Table 6.3.1.5-6 Precoding Matrix W 3 layers 4 antenna ports 'n' = -1 and 'o' = -j
+char nr_W_3l_4p[7][4][3] = {
+  {{'1', '0', '0'}, {'0', '1', '0'}, {'0', '0', '1'},{'0', '0', '0'}},//pmi 0
+  {{'1', '0', '0'}, {'0', '1', '0'}, {'1', '0', '0'},{'0', '0', '1'}},
+  {{'1', '0', '0'}, {'0', '1', '0'}, {'n', '0', '0'},{'0', '0', '1'}},
+  {{'1', '1', '1'}, {'1', 'n', '1'}, {'1', '1', 'n'},{'1', 'n', 'n'}},//pmi 3
+  {{'1', '1', '1'}, {'1', 'n', '1'}, {'j', 'j', 'o'},{'j', 'o', 'o'}},//pmi 4
+  {{'1', '1', '1'}, {'n', '1', 'n'}, {'1', '1', 'n'},{'n', '1', '1'}},
+  {{'1', '1', '1'}, {'n', '1', 'n'}, {'j', 'j', 'o'},{'o', 'j', 'j'}}
+};
+
+//Table 6.3.1.5-7 Precoding Matrix W 4 layers 4 antenna ports 'n' = -1 and 'o' = -j
+char nr_W_4l_4p[5][4][4] = {
+  {{'1', '0', '0', '0'}, {'0', '1', '0', '0'}, {'0', '0', '1', '0'}, {'0', '0', '0', '1'}},//pmi 0
+  {{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'1', 'n', '0', '0'}, {'0', '0', '1', 'n'}},
+  {{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'j', 'o', '0', '0'}, {'0', '0', 'j', 'o'}},
+  {{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'1', '1', 'n', 'n'}, {'1', 'n', 'n', '1'}},//pmi 3
+  {{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'j', 'j', 'o', 'o'}, {'j', 'o', 'o', 'j'}}//pmi 4
+};
+
 void nr_modulation(uint32_t *in,
                    uint32_t length,
                    uint16_t mod_order,
@@ -37,7 +132,7 @@ void nr_modulation(uint32_t *in,
   uint32_t i,j;
   uint32_t bit_cnt;
   uint64_t x,x1,x2;
-    
+
 #if defined(__SSE2__)
   __m128i *nr_mod_table128;
   __m128i *out128;
@@ -56,7 +151,7 @@ void nr_modulation(uint32_t *in,
     // the bits that are left out
     i = i*8/2;
     nr_mod_table32 = (int32_t*) nr_qpsk_mod_table;
-    while (i<length/2){
+    while (i<length/2) {
       idx = ((in_bytes[(i*2)/8]>>((i*2)&0x7)) & mask);
       out32[i] = nr_mod_table32[idx];
       i++;
@@ -78,7 +173,7 @@ void nr_modulation(uint32_t *in,
       out64[i] = nr_16qam_byte_mod_table[in_bytes[i]];
     // the bits that are left out
     i = i*8/4;
-    while (i<length/4){
+    while (i<length/4) {
       idx = ((in_bytes[(i*4)/8]>>((i*4)&0x7)) & mask);
       out32[i] = nr_16qam_mod_table[idx];
       i++;
@@ -88,7 +183,7 @@ void nr_modulation(uint32_t *in,
   case 6:
     j = 0;
     for (i=0; i<length/192; i++) {
-      x = in64[i*3]; 
+      x = in64[i*3];
       x1 = x&4095;
       out64[j++] = nr_64qam_mod_table[x1];
       x1 = (x>>12)&4095;
@@ -140,7 +235,7 @@ void nr_modulation(uint32_t *in,
       bit_cnt += 24;
     }
     return;
-      
+
   case 8:
     nr_mod_table32 = (int32_t*) nr_256qam_mod_table;
     for (i=0; i<length/8; i++)
@@ -151,20 +246,20 @@ void nr_modulation(uint32_t *in,
     break;
   }
   AssertFatal(false,"Invalid or unsupported modulation order %d\n",mod_order);
-
 }
 
 void nr_layer_mapping(int16_t **mod_symbs,
-		      uint8_t n_layers,
-		      uint16_t n_symbs,
-		      int16_t **tx_layers) {
+                      uint8_t n_layers,
+                      uint16_t n_symbs,
+                      int16_t **tx_layers)
+{
   LOG_D(PHY,"Doing layer mapping for %d layers, %d symbols\n",n_layers,n_symbs);
 
   switch (n_layers) {
 
     case 1:
       memcpy((void*)tx_layers[0], (void*)mod_symbs[0], (n_symbs<<1)*sizeof(int16_t));
-    break;
+      break;
 
     case 2:
     case 3:
@@ -174,7 +269,7 @@ void nr_layer_mapping(int16_t **mod_symbs,
           tx_layers[l][i<<1] = mod_symbs[0][(n_layers*i+l)<<1];
           tx_layers[l][(i<<1)+1] = mod_symbs[0][((n_layers*i+l)<<1)+1];
         }
-    break;
+      break;
 
     case 5:
       for (int i=0; i<n_symbs>>1; i++)
@@ -186,8 +281,8 @@ void nr_layer_mapping(int16_t **mod_symbs,
         for (int l=2; l<5; l++) {
           tx_layers[l][i<<1] = mod_symbs[1][(3*i+l)<<1];
           tx_layers[l][(i<<1)+1] = mod_symbs[1][((3*i+l)<<1)+1];
-      }
-    break;
+        }
+      break;
 
     case 6:
       for (int q=0; q<2; q++)
@@ -196,7 +291,7 @@ void nr_layer_mapping(int16_t **mod_symbs,
             tx_layers[l][i<<1] = mod_symbs[q][(3*i+l)<<1];
             tx_layers[l][(i<<1)+1] = mod_symbs[q][((3*i+l)<<1)+1];
           }
-    break;
+      break;
 
     case 7:
       for (int i=0; i<n_symbs/3; i++)
@@ -209,7 +304,7 @@ void nr_layer_mapping(int16_t **mod_symbs,
           tx_layers[l][i<<1] = mod_symbs[0][((i<<2)+l)<<1];
           tx_layers[l][(i<<1)+1] = mod_symbs[0][(((i<<2)+l)<<1)+1];
         }
-    break;
+      break;
 
     case 8:
       for (int q=0; q<2; q++)
@@ -218,42 +313,42 @@ void nr_layer_mapping(int16_t **mod_symbs,
             tx_layers[l][i<<1] = mod_symbs[q][((i<<2)+l)<<1];
             tx_layers[l][(i<<1)+1] = mod_symbs[q][(((i<<2)+l)<<1)+1];
           }
-    break;
+      break;
 
-  default:
-  AssertFatal(0, "Invalid number of layers %d\n", n_layers);
+    default:
+      AssertFatal(0, "Invalid number of layers %d\n", n_layers);
   }
 }
 
 void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
-                      uint8_t n_layers,
-                      uint16_t n_symbs,
-                      int16_t **tx_layers) {
-
+                         uint8_t n_layers,
+                         uint16_t n_symbs,
+                         int16_t **tx_layers)
+{
   int16_t *mod_symbs;
 
   switch (n_layers) {
 
     case 1:
       mod_symbs = (int16_t *)ulsch_ue[0]->d_mod;
-      for (int i=0; i<n_symbs; i++){
+      for (int i=0; i<n_symbs; i++) {
         tx_layers[0][i<<1] = (mod_symbs[i<<1]*AMP)>>15;
         tx_layers[0][(i<<1)+1] = (mod_symbs[(i<<1)+1]*AMP)>>15;
       }
-    break;
+      break;
 
     case 2:
     case 3:
     case 4:
       mod_symbs = (int16_t *)ulsch_ue[0]->d_mod;
 
-      for (int i=0; i<n_symbs/n_layers; i++){
+      for (int i=0; i<n_symbs/n_layers; i++) {
         for (int l=0; l<n_layers; l++) {
           tx_layers[l][i<<1] = (mod_symbs[(n_layers*i+l)<<1]*AMP)>>15;
           tx_layers[l][(i<<1)+1] = (mod_symbs[((n_layers*i+l)<<1)+1]*AMP)>>15;
         }
       }
-    break;
+      break;
 
     case 5:
       mod_symbs = (int16_t *)ulsch_ue[0]->d_mod;
@@ -271,11 +366,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
           tx_layers[l][i<<1] = (mod_symbs[(3*i+l)<<1]*AMP)>>15;
           tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15;
       }
-    break;
+      break;
 
     case 6:
-      for (int q=0; q<2; q++){
-
+      for (int q=0; q<2; q++) {
         mod_symbs = (int16_t *)ulsch_ue[q]->d_mod;
 
         for (int i=0; i<n_symbs/3; i++)
@@ -284,7 +378,7 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
             tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15;
           }
       }
-    break;
+      break;
 
     case 7:
       mod_symbs = (int16_t *)ulsch_ue[1]->d_mod;
@@ -302,11 +396,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
           tx_layers[l][i<<1] = (mod_symbs[((i<<2)+l)<<1]*AMP)>>15;
           tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15;
         }
-    break;
+      break;
 
     case 8:
-      for (int q=0; q<2; q++){
-
+      for (int q=0; q<2; q++) {
         mod_symbs = (int16_t *)ulsch_ue[q]->d_mod;
 
         for (int i=0; i<n_symbs>>2; i++)
@@ -315,10 +408,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
             tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15;
           }
       }
-    break;
+      break;
 
-  default:
-  AssertFatal(0, "Invalid number of layers %d\n", n_layers);
+    default:
+      AssertFatal(0, "Invalid number of layers %d\n", n_layers);
   }
 }
 
@@ -591,35 +684,103 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
 }
 
 
-void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq) {
+void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) {
+
+  uint64_t dl_CarrierFreq = fp->dl_CarrierFreq;
+  uint64_t ul_CarrierFreq = fp->ul_CarrierFreq;
+  double f[2] = {(double)dl_CarrierFreq, (double)ul_CarrierFreq};
 
   const int nsymb = fp->symbols_per_slot * fp->slots_per_frame/10;
   const double Tc=(1/480e3/4096);
   const double Nu=2048*64*(1/(float)(1<<fp->numerology_index));
-  const double f0= (double)CarrierFreq;
   const double Ncp0=16*64 + (144*64*(1/(float)(1<<fp->numerology_index)));
   const double Ncp1=(144*64*(1/(float)(1<<fp->numerology_index)));
-  double tl=0,poff,exp_re,exp_im;
-  double Ncp,Ncpm1=Ncp0;
-
-  poff = 2*M_PI*((Ncp0*Tc))*f0;
-  exp_re = cos(poff);
-  exp_im = sin(-poff);
-  fp->symbol_rotation[0]=(int16_t)floor(exp_re*32767);
-  fp->symbol_rotation[1]=(int16_t)floor(exp_im*32767);
-  LOG_I(PHY,"Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n",f0,nsymb);
-  LOG_I(PHY,"Symbol rotation %d/%d => (%d,%d)\n",0,nsymb,fp->symbol_rotation[0],fp->symbol_rotation[1]);
-  for (int l=1;l<nsymb;l++) {
-    if (l==(7*(1<<fp->numerology_index))) Ncp=Ncp0;
-    else Ncp=Ncp1;
-    tl += (Nu+Ncpm1)*Tc;					     
-    poff = 2*M_PI*(tl + (Ncp*Tc))*f0;
-    exp_re = cos(poff);
-    exp_im = sin(-poff);
-    fp->symbol_rotation[l<<1]=(int16_t)floor(exp_re*32767);
-    fp->symbol_rotation[1+(l<<1)]=(int16_t)floor(exp_im*32767);
-    LOG_I(PHY,"Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n",l,nsymb,tl,fp->symbol_rotation[l<<1],fp->symbol_rotation[1+(l<<1)],
-	  (poff/2/M_PI)-floor(poff/2/M_PI));
-    Ncpm1=Ncp;
+
+  for (uint8_t ll = 0; ll < 2; ll++){
+
+    double f0 = f[ll];
+    double Ncpm1 = Ncp0;
+    int16_t *symbol_rotation = fp->symbol_rotation[ll];
+
+    double tl = 0;
+    double poff = 2 * M_PI * ((Ncp0 * Tc)) * f0;
+    double exp_re = cos(poff);
+    double exp_im = sin(-poff);
+    symbol_rotation[0] = (int16_t)floor(exp_re * 32767);
+    symbol_rotation[1] = (int16_t)floor(exp_im * 32767);
+    LOG_I(PHY, "Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb);
+    LOG_I(PHY, "Symbol rotation %d/%d => (%d,%d)\n",
+      0,
+      nsymb,
+      symbol_rotation[0],
+      symbol_rotation[1]);
+
+    for (int l = 1; l < nsymb; l++) {
+
+      double Ncp;
+      if (l == (7 * (1 << fp->numerology_index))) {
+        Ncp = Ncp0;
+      } else {
+        Ncp = Ncp1;
+      }
+
+      tl += (Nu + Ncpm1) * Tc;
+      poff = 2 * M_PI * (tl + (Ncp * Tc)) * f0;
+      exp_re = cos(poff);
+      exp_im = sin(-poff);
+      symbol_rotation[l<<1] = (int16_t)floor(exp_re * 32767);
+      symbol_rotation[1 + (l<<1)] = (int16_t)floor(exp_im * 32767);
+
+      LOG_I(PHY, "Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n",
+        l,
+        nsymb,
+        tl,
+        symbol_rotation[l<<1],
+        symbol_rotation[1 + (l<<1)],
+        (poff / 2 / M_PI) - floor(poff / 2 / M_PI));
+
+      Ncpm1 = Ncp;
+
+    }
   }
 }
+
+int nr_layer_precoder(int16_t **datatx_F_precoding, char *prec_matrix, uint8_t n_layers, int32_t re_offset)
+{
+  int32_t precodatatx_F = 0;
+
+  for (int al = 0; al<n_layers; al++) {
+    int16_t antenna_re = datatx_F_precoding[al][re_offset<<1];
+    int16_t antenna_im = datatx_F_precoding[al][(re_offset<<1) +1];
+
+    switch (prec_matrix[al]) {
+      case '0': //multiply by zero
+        break;
+
+      case '1': //multiply by 1
+        ((int16_t *) &precodatatx_F)[0] += antenna_re;
+        ((int16_t *) &precodatatx_F)[1] += antenna_im;
+        break;
+
+      case 'n': // multiply by -1
+        ((int16_t *) &precodatatx_F)[0] -= antenna_re;
+        ((int16_t *) &precodatatx_F)[1] -= antenna_im;
+        break;
+
+      case 'j': //
+        ((int16_t *) &precodatatx_F)[0] -= antenna_im;
+        ((int16_t *) &precodatatx_F)[1] += antenna_re;
+        break;
+
+      case 'o': // -j
+        ((int16_t *) &precodatatx_F)[0] += antenna_im;
+        ((int16_t *) &precodatatx_F)[1] -= antenna_re;
+        break;
+    }
+  }
+
+  return precodatatx_F;
+  // normalize
+  /*  ((int16_t *)precodatatx_F)[0] = (int16_t)((((int16_t *)precodatatx_F)[0]*ONE_OVER_SQRT2_Q15)>>15);
+      ((int16_t *)precodatatx_F)[1] = (int16_t)((((int16_t *)precodatatx_F)[1]*ONE_OVER_SQRT2_Q15)>>15);*/
+}
diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h
index 3d2be905ac48bfba1ba236a64dbc08030057c17f..547d20952fb4d7e0b5e959535c00088d026af87c 100644
--- a/openair1/PHY/MODULATION/nr_modulation.h
+++ b/openair1/PHY/MODULATION/nr_modulation.h
@@ -28,7 +28,13 @@
 #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
 
 #define DMRS_MOD_ORDER 2
-
+/*Precoding matices: W[pmi][antenna_port][layer]*/
+extern char nr_W_1l_2p[6][2][1];
+extern char nr_W_2l_2p[3][2][2];
+extern char nr_W_1l_4p[28][4][1];
+extern char nr_W_2l_4p[22][4][2];
+extern char nr_W_3l_4p[7][4][3];
+extern char nr_W_4l_4p[5][4][4];
 /*! \brief Perform NR modulation. TS 38.211 V15.4.0 subclause 5.1
   @param[in] in, Pointer to input bits
   @param[in] length, size of input bits
@@ -74,7 +80,6 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
 \param symbol symbol within slot (0..12/14)
 \param Ns Slot number (0..19)
 \param sample_offset offset within rxdata (points to beginning of subframe)
-\param no_prefix if 1 prefix is removed by HW
 */
 
 int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
@@ -82,8 +87,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
                    int32_t *rxdataF,
                    unsigned char symbol,
                    unsigned char Ns,
-                   int sample_offset,
-                   int no_prefix);
+                   int sample_offset);
 
 /*!
 \brief This function implements the dft transform precoding in PUSCH
@@ -100,7 +104,8 @@ int nr_beam_precoding(int32_t **txdataF,
                       int slot,
                       int symbol,
                       int aa,
-                      int nb_antenna_ports
+                      int nb_antenna_ports,
+                      int offset
 );
 
 void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
@@ -110,7 +115,7 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
 		       int nsymb,
 		       int length);
 
-void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq);
+void init_symbol_rotation(NR_DL_FRAME_PARMS *fp);
 
 void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
 			  int32_t *rxdataF,
@@ -118,4 +123,14 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
 			  int first_symbol,
 			  int nsymb,
 			  int length);
+
+/*! \brief Perform NR precoding. TS 38.211 V15.4.0 subclause 6.3.1.5
+  @param[in] datatx_F_precoding, Pointer to n_layers*re data array
+  @param[in] prec_matrix, Pointer to precoding matrix
+  @param[in] n_layers, number of DLSCH layers
+*/
+int nr_layer_precoder(int16_t **datatx_F_precoding,
+		char *prec_matrix,
+		uint8_t n_layers,
+		int32_t re_offset);
 #endif
diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c
index 2d86b46742449b308ee24c93de1225b5ebe19a66..8cf9f05b9b63acd4bd4bab2e0f0296013a279302 100644
--- a/openair1/PHY/MODULATION/ofdm_mod.c
+++ b/openair1/PHY/MODULATION/ofdm_mod.c
@@ -306,15 +306,23 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
 		       int length) {
   int symb_offset = (slot%fp->slots_per_subframe)*fp->symbols_per_slot;
 
+  int16_t *symbol_rotation = fp->symbol_rotation[0];
+
   for (int sidx=0;sidx<nsymb;sidx++) {
+
     LOG_D(PHY,"Rotating symbol %d, slot %d, symbol_subframe_index %d, length %d (%d,%d)\n",
-	  first_symbol+sidx,slot,sidx+first_symbol+symb_offset,length,
-	  fp->symbol_rotation[2*(sidx+first_symbol+symb_offset)],fp->symbol_rotation[1+2*(sidx+first_symbol+symb_offset)]);
-    rotate_cpx_vector(trxdata+(sidx*length*2),
-		      &fp->symbol_rotation[2*(sidx+first_symbol+symb_offset)],
-		      trxdata+(sidx*length*2),
-		      length,
-		      15);
+      first_symbol + sidx,
+      slot,
+      sidx + first_symbol + symb_offset,
+      length,
+      symbol_rotation[2 * (sidx + first_symbol + symb_offset)],
+      symbol_rotation[1 + 2 * (sidx + first_symbol + symb_offset)]);
+
+    rotate_cpx_vector(trxdata + (sidx * length * 2),
+                      &symbol_rotation[2 * (sidx + first_symbol + symb_offset)],
+                      trxdata + (sidx * length * 2),
+                      length,
+                      15);
   }
 }
 		       
diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c
index 60b28d4ad18da254f99854369c028e134d014c1a..39c730bfac3a5b8c973e9e9643e40acbaf61cee0 100644
--- a/openair1/PHY/MODULATION/slot_fep_nr.c
+++ b/openair1/PHY/MODULATION/slot_fep_nr.c
@@ -29,364 +29,232 @@
 
 //#define DEBUG_FEP
 
-#define SOFFSET 0
-
 /*#ifdef LOG_I
 #undef LOG_I
 #define LOG_I(A,B...) printf(A)
 #endif*/
 
-int nr_slot_fep(PHY_VARS_NR_UE *ue,
-                UE_nr_rxtx_proc_t *proc,
-                unsigned char symbol,
-                unsigned char Ns,
-                int sample_offset,
-                int no_prefix)
+dft_size_idx_t get_dft_size_idx(uint16_t ofdm_symbol_size)
 {
-  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
-  NR_UE_COMMON *common_vars   = &ue->common_vars;
-  unsigned char aa;
-  unsigned int nb_prefix_samples;
-  unsigned int nb_prefix_samples0;
-  unsigned int abs_symbol;
-  if (ue->is_synchronized) {
-    nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
-    nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
-  }
-  else {
-    nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
-    nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
-  }
-  //unsigned int subframe_offset;//,subframe_offset_F;
-  unsigned int slot_offset;
-  //int i;
-  unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
-  unsigned int rx_offset;
-
-
-  dft_size_idx_t dftsize;
-  int tmp_dft_in[8192] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
-
-  switch (frame_parms->ofdm_symbol_size) {
+  switch (ofdm_symbol_size) {
   case 128:
-    dftsize = DFT_128;
-    break;
+    return DFT_128;
 
   case 256:
-    dftsize = DFT_256;
-    break;
+    return DFT_256;
 
   case 512:
-    dftsize = DFT_512;
-    break;
+    return DFT_512;
 
   case 1024:
-    dftsize = DFT_1024;
-    break;
+    return DFT_1024;
 
   case 1536:
-    dftsize = DFT_1536;
-    break;
+    return DFT_1536;
 
   case 2048:
-    dftsize = DFT_2048;
-    break;
+    return DFT_2048;
 
   case 3072:
-    dftsize = DFT_3072;
-    break;
+    return DFT_3072;
 
   case 4096:
-    dftsize = DFT_4096;
-    break;
+    return DFT_4096;
+
+  case 6144:
+    return DFT_6144;
 
   case 8192:
-    dftsize = DFT_8192;
-    break;
+    return DFT_8192;
 
   default:
     printf("unsupported ofdm symbol size \n");
     assert(0);
   }
 
-  if (no_prefix) {
-    slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns);
-  } else {
-    slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
-  }
+  return DFT_SIZE_IDXTABLESIZE;
+}
 
-  /*if (l<0 || l>=7-frame_parms->Ncp) {
-    printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
-    return(-1);
-    }*/
+int nr_slot_fep(PHY_VARS_NR_UE *ue,
+                UE_nr_rxtx_proc_t *proc,
+                unsigned char symbol,
+                unsigned char Ns)
+{
+  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  NR_UE_COMMON *common_vars      = &ue->common_vars;
 
-  if (Ns<0 || Ns>(frame_parms->slots_per_frame-1)) {
-    printf("slot_fep: Ns must be between 0 and %d\n",frame_parms->slots_per_frame-1);
-    return(-1);
+  AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
+  AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
+
+  unsigned int nb_prefix_samples;
+  unsigned int nb_prefix_samples0;
+  if (ue->is_synchronized) {
+    nb_prefix_samples  = frame_parms->nb_prefix_samples;
+    nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
+  } else {
+    nb_prefix_samples  = frame_parms->nb_prefix_samples;
+    nb_prefix_samples0 = frame_parms->nb_prefix_samples;
   }
 
-  for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-    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(int));
+  dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size);
+  // This is for misalignment issues
+  int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
 
-    rx_offset = sample_offset + slot_offset - SOFFSET;
-    // Align with 256 bit
-    //    rx_offset = rx_offset&0xfffffff8;
+  unsigned int rx_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
+  unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
+  for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
+    rx_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
+  rx_offset += frame_parms->ofdm_symbol_size * symbol;
+
+  // use OFDM symbol from within 1/8th of the CP to avoid ISI
+  rx_offset -= nb_prefix_samples / 8;
 
 #ifdef DEBUG_FEP
-      //  if (ue->frame <100)
-    /*LOG_I(PHY,*/printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
-			 Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
+  //  if (ue->frame <100)
+  printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n",
+         Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset);
 #endif
 
-    abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
-    
-    for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++)
-      rx_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
-
-    rx_offset += frame_parms->ofdm_symbol_size * symbol;
-
-    if (abs_symbol%(0x7<<frame_parms->numerology_index)) {
-
-      rx_offset += nb_prefix_samples;
-      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
-        memcpy((short*) &common_vars->rxdata[aa][frame_length_samples],
-               (short*) &common_vars->rxdata[aa][0],
-               frame_parms->ofdm_symbol_size*sizeof(int));
-
-      if ((rx_offset&7)!=0) {  // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
-        memcpy((void *)tmp_dft_in,
-               (void *) &common_vars->rxdata[aa][rx_offset % frame_length_samples],
-               frame_parms->ofdm_symbol_size*sizeof(int));
-        dft(dftsize,(int16_t *)tmp_dft_in,
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
-      } else { // use dft input from RX buffer directly
-#if UE_TIMING_TRACE
-          start_meas(&ue->rx_dft_stats);
-#endif
+  for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
+    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));
 
-        dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
-#if UE_TIMING_TRACE
-        stop_meas(&ue->rx_dft_stats);
-#endif
-      }
-    } else {
+    int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset];
+
+    // if input to dft is not 256-bit aligned
+    if ((rx_offset & 7) != 0) {
+      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;
+    }
 
-      rx_offset += nb_prefix_samples0;
-      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
-        memcpy((void *) &common_vars->rxdata[aa][frame_length_samples],
-               (void *) &common_vars->rxdata[aa][0],
-               frame_parms->ofdm_symbol_size*sizeof(int));
 #if UE_TIMING_TRACE
-      start_meas(&ue->rx_dft_stats);
+    start_meas(&ue->rx_dft_stats);
 #endif
 
-      if ((rx_offset&7)!=0) {  // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
-        memcpy((void *)tmp_dft_in,
-               (void *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
-               frame_parms->ofdm_symbol_size*sizeof(int));
-        dft(dftsize,(int16_t *)tmp_dft_in,
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
-      } else { // use dft input from RX buffer directly
-
-        dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
-      }
+    dft(dftsize,
+        rxdata_ptr,
+        (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
+        1);
+
 #if UE_TIMING_TRACE
-      stop_meas(&ue->rx_dft_stats);
+    stop_meas(&ue->rx_dft_stats);
 #endif
 
-
-    }
+    int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
+    int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol+symb_offset];
+    ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
 
 #ifdef DEBUG_FEP
     //  if (ue->frame <100)
-    printf("slot_fep: symbol %d rx_offset %u\n", symbol, rx_offset);
+    printf("slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset,
+	   symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]);
 #endif
-    
-    int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
-    int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset];
-    ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
+
     rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
 		      (int16_t*)&rot2,
 		      (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
 		      frame_parms->ofdm_symbol_size,
 		      15);
-    
   }
-  
 
 #ifdef DEBUG_FEP
   printf("slot_fep: done\n");
 #endif
-  return(0);
+
+  return 0;
 }
 
 int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
                           UE_nr_rxtx_proc_t *proc,
                           unsigned char symbol,
                           unsigned char Ns,
-                          int sample_offset,
-                          int no_prefix)
+                          int sample_offset)
 {
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   NR_UE_COMMON *common_vars   = &ue->common_vars;
-  unsigned char aa;
+
+  AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
+  AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
+
   unsigned int nb_prefix_samples;
   unsigned int nb_prefix_samples0;
-  unsigned int abs_symbol;
   if (ue->is_synchronized) {
-    nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
-    nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
+    nb_prefix_samples  = frame_parms->nb_prefix_samples;
+    nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
   }
   else {
-    nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
-    nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
+    nb_prefix_samples  = frame_parms->nb_prefix_samples;
+    nb_prefix_samples0 = frame_parms->nb_prefix_samples;
   }
-  //unsigned int subframe_offset;//,subframe_offset_F;
-  unsigned int slot_offset;
-  //int i;
-  unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
-  unsigned int rx_offset;
-
-
-  dft_size_idx_t dftsize;
-  int tmp_dft_in[8192] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
-
-  switch (frame_parms->ofdm_symbol_size) {
-  case 128:
-    dftsize = DFT_128;
-    break;
-
-  case 256:
-    dftsize = DFT_256;
-    break;
-
-  case 512:
-    dftsize = DFT_512;
-    break;
+  unsigned int frame_length_samples = frame_parms->samples_per_frame;
 
-  case 1024:
-    dftsize = DFT_1024;
-    break;
+  dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size);
+  // This is for misalignment issues
+  int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
 
-  case 1536:
-    dftsize = DFT_1536;
-    break;
-
-  case 2048:
-    dftsize = DFT_2048;
-    break;
+  unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
+  unsigned int rx_offset   = sample_offset + slot_offset;
+  unsigned int abs_symbol  = Ns * frame_parms->symbols_per_slot + symbol;
+  for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
+    rx_offset += (abs_symbol%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
+  rx_offset += frame_parms->ofdm_symbol_size * symbol;
 
-  case 3072:
-    dftsize = DFT_3072;
-    break;
+#ifdef DEBUG_FEP
+  //  if (ue->frame <100)
+  printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
+         Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
+#endif
 
-  case 4096:
-    dftsize = DFT_4096;
-    break;
+  for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
+    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));
 
-  case 8192:
-    dftsize = DFT_8192;
-    break;
+    int16_t *rxdata_ptr;
+    rx_offset%=frame_length_samples*2;
 
-  default:
-    printf("unsupported ofdm symbol size \n");
-    assert(0);
-  }
-
-  if (no_prefix) {
-    slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns);
-  } else {
-    slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
-  }
+    if (rx_offset+frame_parms->ofdm_symbol_size > frame_length_samples*2 ) {
+      // rxdata is 2 frames len
+      // we have to wrap on the end
 
-  /*if (l<0 || l>=7-frame_parms->Ncp) {
-    printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
-    return(-1);
-    }*/
+      memcpy((void *)&tmp_dft_in[0],
+             (void *)&common_vars->rxdata[aa][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*2 - rx_offset)) * sizeof(int32_t));
+      rxdata_ptr = (int16_t *)tmp_dft_in;
 
-  if (Ns<0 || Ns>(frame_parms->slots_per_frame-1)) {
-    printf("slot_fep: Ns must be between 0 and %d\n",frame_parms->slots_per_frame-1);
-    return(-1);
-  }
+    } else if ((rx_offset & 7) != 0) {
 
-  for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-    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(int));
+      // if input to dft is not 256-bit aligned
+      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;
 
-    rx_offset = sample_offset + slot_offset - SOFFSET;
-    // Align with 256 bit
-    //    rx_offset = rx_offset&0xfffffff8;
-
-#ifdef DEBUG_FEP
-      //  if (ue->frame <100)
-    /*LOG_I(PHY,*/printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
-    		Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
-#endif
+    } else {
 
-    abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
-    
-    for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++)
-      rx_offset += (abs_symbol%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
-
-    rx_offset += frame_parms->ofdm_symbol_size * symbol;
-
-    if (abs_symbol%(0x7<<frame_parms->numerology_index)) {
-
-      rx_offset += nb_prefix_samples;
-      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
-        memcpy((short*) &common_vars->rxdata[aa][frame_length_samples],
-               (short*) &common_vars->rxdata[aa][0],
-               frame_parms->ofdm_symbol_size*sizeof(int));
-
-      if ((rx_offset&7)!=0) {  // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
-        memcpy((void *)tmp_dft_in,
-               (void *) &common_vars->rxdata[aa][rx_offset],
-               frame_parms->ofdm_symbol_size*sizeof(int));
-        dft(dftsize,(int16_t *)tmp_dft_in,
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
-      } else { // use dft input from RX buffer directly
-#if UE_TIMING_TRACE
-          start_meas(&ue->rx_dft_stats);
-#endif
+      // use dft input from RX buffer directly
+      rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset];
 
+    }
 
-        dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset],
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
 #if UE_TIMING_TRACE
-        stop_meas(&ue->rx_dft_stats);
+    start_meas(&ue->rx_dft_stats);
 #endif
-      }
-    } else {
 
-      rx_offset += nb_prefix_samples0;
-      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
-        memcpy((void *) &common_vars->rxdata[aa][frame_length_samples],
-               (void *) &common_vars->rxdata[aa][0],
-               frame_parms->ofdm_symbol_size*sizeof(int));
-#if UE_TIMING_TRACE
-      start_meas(&ue->rx_dft_stats);
-#endif
+    dft(dftsize,
+        rxdata_ptr,
+        (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
+        1);
 
-      if ((rx_offset&7)!=0) {  // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
-        memcpy((void *)tmp_dft_in,
-               (void *) &common_vars->rxdata[aa][rx_offset],
-               frame_parms->ofdm_symbol_size*sizeof(int));
-        dft(dftsize,(int16_t *)tmp_dft_in,
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
-      } else { // use dft input from RX buffer directly
-        dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset],
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
-      }
 #if UE_TIMING_TRACE
-      stop_meas(&ue->rx_dft_stats);
+    stop_meas(&ue->rx_dft_stats);
 #endif
 
-
-    }
-
     int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
-    int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset];
+    int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset];
     ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
 
 #ifdef DEBUG_FEP
@@ -400,14 +268,13 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
 		      (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
 		      frame_parms->ofdm_symbol_size,
 		      15);
-    
   }
 
-
 #ifdef DEBUG_FEP
   printf("slot_fep: done\n");
 #endif
-  return(0);
+
+  return 0;
 }
 
 
@@ -416,89 +283,60 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
                    int32_t *rxdataF,
                    unsigned char symbol,
                    unsigned char Ns,
-                   int sample_offset,
-                   int no_prefix)
+                   int sample_offset)
 {
-  int32_t slot_offset, rxdata_offset;
-
-  unsigned int nb_prefix_samples  = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
-  unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
+  unsigned int nb_prefix_samples  = frame_parms->nb_prefix_samples;
+  unsigned int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
   
-  int tmp_dft_in[8192] __attribute__ ((aligned (32)));
+  dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size);
+  // This is for misalignment issues
+  int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
 
-  dft_size_idx_t dftsize;
+  unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
 
-  switch (frame_parms->ofdm_symbol_size) {
-    case 128:
-      dftsize = DFT_128;
-      break;
+  // offset of first OFDM symbol
+  int32_t rxdata_offset = slot_offset + nb_prefix_samples0;
+  // offset of n-th OFDM symbol
+  rxdata_offset += symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples);
+  // use OFDM symbol from within 1/8th of the CP to avoid ISI
+  rxdata_offset -= nb_prefix_samples / 8;
 
-    case 256:
-      dftsize = DFT_256;
-      break;
+  int16_t *rxdata_ptr;
 
-    case 512:
-      dftsize = DFT_512;
-      break;
+  if(sample_offset > rxdata_offset) {
 
-    case 1024:
-      dftsize = DFT_1024;
-      break;
+    memcpy((void *)&tmp_dft_in[0],
+           (void *)&rxdata[frame_parms->samples_per_frame - sample_offset + rxdata_offset],
+           (sample_offset - rxdata_offset) * sizeof(int32_t));
+    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;
 
-    case 1536:
-      dftsize = DFT_1536;
-      break;
+  } else if (((rxdata_offset - sample_offset) & 7) != 0) {
 
-    case 2048:
-      dftsize = DFT_2048;
-      break;
+    // if input to dft is not 256-bit aligned
+    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;
 
-    case 4096:
-      dftsize = DFT_4096;
-      break;
+  } else {
 
-    case 8192:
-      dftsize = DFT_8192;
-      break;
+    // use dft input from RX buffer directly
+    rxdata_ptr = (int16_t *)&rxdata[rxdata_offset - sample_offset];
 
-    default:
-      dftsize = DFT_512;
-      break;
   }
-  
-  slot_offset   = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
 
-  if(symbol == 0)
-    rxdata_offset = slot_offset + nb_prefix_samples0 - SOFFSET;
-  else
-    rxdata_offset = slot_offset + nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples)) - SOFFSET;
-
-  if(sample_offset>rxdata_offset) {
-    memcpy1((void *)tmp_dft_in,
-           (void *) &rxdata[frame_parms->samples_per_frame-sample_offset+rxdata_offset],
-           (sample_offset-rxdata_offset)*sizeof(int));
-
-    memcpy1((void *)&tmp_dft_in[sample_offset-rxdata_offset],
-           (void *) &rxdata[0],
-           (frame_parms->ofdm_symbol_size-sample_offset+rxdata_offset)*sizeof(int));
-
-    dft(dftsize,(int16_t *)&tmp_dft_in,
-        (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
-  }
-  else {
-    //dft(dftsize,(int16_t *)&rxdata[rxdata_offset-sample_offset],
-      //  (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
-    memcpy((void *)tmp_dft_in,
-           (void *) &rxdata[rxdata_offset-sample_offset],
-           (frame_parms->ofdm_symbol_size)*sizeof(int));
-    dft(dftsize,(int16_t *)&tmp_dft_in,
-        (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
-  }
+  dft(dftsize,
+      rxdata_ptr,
+      (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size],
+      1);
 
   // clear DC carrier from OFDM symbols
   rxdataF[symbol * frame_parms->ofdm_symbol_size] = 0;
 
-  return(0);
+  return 0;
 }
 
 void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
@@ -513,7 +351,7 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
 
   for (int symbol=0;symbol<nsymb;symbol++) {
     
-    uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset];
+    uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[1])[symbol + symb_offset];
     ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
     LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]);
     rotate_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
diff --git a/openair1/PHY/MODULATION/slot_fep_ul.c b/openair1/PHY/MODULATION/slot_fep_ul.c
index 746f8dbc0e1535dcca3bcdded7a83b6edee24a91..ccb7ee5f3e405ede1709e7ecfcac9b532f7ed533 100644
--- a/openair1/PHY/MODULATION/slot_fep_ul.c
+++ b/openair1/PHY/MODULATION/slot_fep_ul.c
@@ -20,8 +20,8 @@
  */
 
 #include "PHY/defs_eNB.h"
-#include "PHY/phy_extern.h"
-#include "modulation_eNB.h"
+//#include "PHY/phy_extern.h"
+//#include "modulation_eNB.h"
 //#define DEBUG_FEP
 
 
diff --git a/openair1/PHY/MODULATION/ul_7_5_kHz.c b/openair1/PHY/MODULATION/ul_7_5_kHz.c
index a5b428a813a1619774e70cbfbb9569e58e97caa2..384b9d621c59ddb0246b83d96e4c5602b70eaa54 100644
--- a/openair1/PHY/MODULATION/ul_7_5_kHz.c
+++ b/openair1/PHY/MODULATION/ul_7_5_kHz.c
@@ -20,7 +20,6 @@
  */
 
 #include "PHY/defs_eNB.h"
-#include "PHY/phy_extern.h"
 #include <math.h>
 #include "PHY/sse_intrin.h"
 #include "modulation_extern.h"
diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
index ec55eabf313378d49dc68a57d70c3e55e4dae520..e942ef2c6b52a57b2b520dd405e98b5d03c65943 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
@@ -20,12 +20,12 @@
  */
 
 /*! \file PHY/NR_ESTIMATION/nr_measurements_gNB.c
-* \brief TA estimation for TA updates
-* \author Ahmed Hussein
+* \brief gNB measurement routines
+* \author Ahmed Hussein, G. Casati, K. Saaifan
 * \date 2019
 * \version 0.1
 * \company Fraunhofer IIS
-* \email: ahmed.hussein@iis.fraunhofer.de
+* \email: ahmed.hussein@iis.fraunhofer.de, guido.casati@iis.fraunhofer.de, khodr.saaifan@iis.fraunhofer.de
 * \note
 * \warning
 */
@@ -35,24 +35,24 @@
 #include "PHY/phy_extern.h"
 #include "nr_ul_estimation.h"
 
+extern openair0_config_t openair0_cfg[MAX_CARDS];
+
 int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
 {
-  int temp, i, aa, max_pos = 0, max_val = 0;
-  short Re, Im;
-  uint8_t cyclic_shift = 0;
+  int i, aa, max_pos = 0, max_val = 0;
   
   NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
   NR_gNB_PUSCH *gNB_pusch_vars   = gNB->pusch_vars[UE_id];
   int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time;
   
-  int sync_pos = (frame_parms->ofdm_symbol_size - cyclic_shift*frame_parms->ofdm_symbol_size/12) % (frame_parms->ofdm_symbol_size);
+  int sync_pos = frame_parms->nb_prefix_samples / 8;
 
   for (i = 0; i < frame_parms->ofdm_symbol_size; i++) {
-    temp = 0;
+    int temp = 0;
 
     for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
-      Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
-      Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
+      short Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
+      short Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
       temp += (Re*Re/2) + (Im*Im/2);      
     }
 
@@ -70,36 +70,134 @@ 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;
   uint32_t *rb_mask = gNB->rb_mask_ul;
-  int symbol = gNB->ulmask_symb;
-  int rb, offset, nb_rb;
-  uint32_t n0_power_tot, n0_subband_power_temp=0;
+  int rb, offset, offset0, nb_rb, len;
   int32_t *ul_ch;
+  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
+
+  if (nb_rb>0) measurements->n0_subband_power_avg_dB = dB_fixed(n0_power_tot2/nb_rb);
 
-  if (symbol>-1) {
-    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);
-        }
+}
+
+
+// Scope: This function computes the UL SNR from the UL channel estimates
+//
+// Todo:
+// - averaging IIR filter for RX power and noise
+void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol, uint8_t nrOfLayers){
+
+  int rx_power_tot[NUMBER_OF_NR_ULSCH_MAX];
+  int rx_power[NUMBER_OF_NR_ULSCH_MAX][NB_ANTENNAS_RX];
+  unsigned short rx_power_avg_dB[NUMBER_OF_NR_ULSCH_MAX];
+  unsigned short rx_power_tot_dB[NUMBER_OF_NR_ULSCH_MAX];
+
+  double             rx_gain = openair0_cfg[0].rx_gain[0];
+  double      rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
+  PHY_MEASUREMENTS_gNB *meas = &gNB->measurements;
+  NR_DL_FRAME_PARMS      *fp = &gNB->frame_parms;
+  int              ch_offset = fp->ofdm_symbol_size * symbol;
+  int                N_RB_UL = gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu.rb_size;
+
+  rx_power_tot[ulsch_id] = 0;
+
+  for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++){
+
+    rx_power[ulsch_id][aarx] = 0;
+
+    for (int aatx = 0; aatx < nrOfLayers; aatx++){
+
+      meas->rx_spatial_power[ulsch_id][aatx][aarx] = (signal_energy_nodc(&gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aatx*fp->nb_antennas_rx+aarx][ch_offset], N_RB_UL * NR_NB_SC_PER_RB));
+
+      if (meas->rx_spatial_power[ulsch_id][aatx][aarx] < 0) {
+        meas->rx_spatial_power[ulsch_id][aatx][aarx] = 0;
       }
-      measurements->n0_power[aarx] = n0_subband_power_temp/nb_rb;
-      measurements->n0_power_dB[aarx] = dB_fixed(measurements->n0_power[aarx]);
-      n0_power_tot += measurements->n0_power[aarx];
+
+      meas->rx_spatial_power_dB[ulsch_id][aatx][aarx] = (unsigned short) dB_fixed(meas->rx_spatial_power[ulsch_id][aatx][aarx]);
+      rx_power[ulsch_id][aarx] += meas->rx_spatial_power[ulsch_id][aatx][aarx];
+
     }
-    measurements->n0_power_tot_dB = dB_fixed(n0_power_tot);
+
+    rx_power_tot[ulsch_id] += rx_power[ulsch_id][aarx];
+
   }
-}
 
+  rx_power_tot_dB[ulsch_id] = (unsigned short) dB_fixed(rx_power_tot[ulsch_id]);
+  rx_power_avg_dB[ulsch_id] = rx_power_tot_dB[ulsch_id];
+
+  meas->wideband_cqi_tot[ulsch_id] = dB_fixed2(rx_power_tot[ulsch_id], meas->n0_power_tot);
+  meas->rx_rssi_dBm[ulsch_id] = rx_power_avg_dB[ulsch_id] + 30 - 10 * log10(pow(2, 30)) - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size);
+
+  LOG_D(PHY, "[ULSCH %d] RSSI %d dBm/RE, RSSI (digital) %d dB (N_RB_UL %d), WBand CQI tot %d dB, N0 Power tot %d\n",
+    ulsch_id,
+    meas->rx_rssi_dBm[ulsch_id],
+    rx_power_avg_dB[ulsch_id],
+    N_RB_UL,
+    meas->wideband_cqi_tot[ulsch_id],
+    meas->n0_power_tot);
+
+}
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index 38b35dcf6d39a93969b7b3f1ee3cbb73158e7622..8f9a7a5edf9aef3cfa913b0584ead28b9c05e012 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -75,16 +75,21 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
   symbol_offset = gNB->frame_parms.ofdm_symbol_size*symbol;
 
   k = bwp_start_subcarrier;
-  int re_offset = k;
+  int re_offset;
 
   uint16_t nb_rb_pusch = pusch_pdu->rb_size;
 
-/*
 #ifdef DEBUG_CH
-  printf("PUSCH Channel Estimation : ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", ,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size,
-         gNB->frame_parms.Ncp,l,Ns,k, symbol);
+  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,
+        gNB->frame_parms.ofdm_symbol_size,
+        Ns,
+        k,
+        symbol);
 #endif
-*/
+
   switch (nushift) {
    case 0:
          fl = filt8_l0;
@@ -124,9 +129,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
 
   //------------------generate DMRS------------------//
 
-  if (pusch_pdu->transform_precoding == transform_precoder_disabled) 
-    nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->rb_start*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type);
-  
+  // transform precoding = 1 means disabled
+  if (pusch_pdu->transform_precoding == 1) {
+    nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch,
+                     (pusch_pdu->bwp_start + pusch_pdu->rb_start)*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type);
+  }
   else {  // if transform precoding or SC-FDMA is enabled in Uplink
 
     // NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible
@@ -151,27 +158,32 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
   //------------------------------------------------//
 
 
-
 #ifdef DEBUG_PUSCH
-  for (int i=0;i<(6*nb_rb_pusch);i++)
-    printf("%d+j*(%d)\n",((int16_t*)pilot)[2*i],((int16_t*)pilot)[1+(2*i)]);
+  for (int i = 0; i < (6 * nb_rb_pusch); i++) {
+    LOG_I(PHY, "In %s: %d + j*(%d)\n",
+      __FUNCTION__,
+      ((int16_t*)pilot)[2 * i],
+      ((int16_t*)pilot)[1 + (2 * i)]);
+  }
 #endif
+
   for (aarx=0; aarx<gNB->frame_parms.nb_antennas_rx; aarx++) {
 
     re_offset = k;   /* Initializing the Resource element offset for each Rx antenna */
 
     pil   = (int16_t *)&pilot[0];
     rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
-    ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
+    ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset];
+    re_offset = k;
 
     memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size));
 
 #ifdef DEBUG_PUSCH
-    printf("symbol_offset %d, nushift %d\n",symbol_offset,nushift);
-    printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL);
-    printf("bwp_start_subcarrier %d, k %d, first_carrier %d, nb_rb_pusch %d\n",bwp_start_subcarrier,k,gNB->frame_parms.first_carrier_offset,nb_rb_pusch);
-    printf("rxF addr %p p %d\n", rxF,p);
-    printf("ul_ch addr %p nushift %d\n",ul_ch,nushift);
+    LOG_I(PHY, "In %s symbol_offset %d, nushift %d\n", __FUNCTION__, symbol_offset, nushift);
+    LOG_I(PHY, "In %s ch est pilot addr %p, N_RB_UL %d\n", __FUNCTION__, &pilot[0], gNB->frame_parms.N_RB_UL);
+    LOG_I(PHY, "In %s bwp_start_subcarrier %d, k %d, first_carrier %d, nb_rb_pusch %d\n", __FUNCTION__, bwp_start_subcarrier, k, gNB->frame_parms.first_carrier_offset, nb_rb_pusch);
+    LOG_I(PHY, "In %s rxF addr %p p %d\n", __FUNCTION__, rxF, p);
+    LOG_I(PHY, "In %s ul_ch addr %p nushift %d\n", __FUNCTION__, ul_ch, nushift);
 #endif
     //if ((gNB->frame_parms.N_RB_UL&1)==0) {
 
@@ -182,9 +194,18 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
       ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
 
 #ifdef DEBUG_PUSCH
-      printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
-      printf("pilot 0 : rxF - > (%d,%d) (%d)  ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
-      printf("data 0 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
+      LOG_I(PHY, "In %s ch 0 %d\n", __FUNCTION__, ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
+      LOG_I(PHY, "In %s pilot 0 : rxF - > (%d,%d) (%d)  ch -> (%d,%d) (%d), pil -> (%d,%d) \n",
+        __FUNCTION__,
+        rxF[0],
+        rxF[1],
+        dBc(rxF[0],rxF[1]),
+        ch[0],
+        ch[1],
+        dBc(ch[0],ch[1]),
+        pil[0],
+        pil[1]);
+      LOG_I(PHY, "In %s data 0 : rxF - > (%d,%d) (%d)\n", __FUNCTION__, rxF[2], rxF[3], dBc(rxF[2],rxF[3]));
 #endif
 
       multadd_real_vector_complex_scalar(fl,
@@ -201,9 +222,23 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
       ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
 
 #ifdef DEBUG_PUSCH
-      printf("pilot 1 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
-      printf("data 1 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
+      LOG_I(PHY, "In %s pilot 1 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",
+        __FUNCTION__,
+        rxF[0],
+        rxF[1],
+        dBc(rxF[0],rxF[1]),
+        ch[0],
+        ch[1],
+        dBc(ch[0],ch[1]),
+        pil[0],
+        pil[1]);
+      LOG_I(PHY, "In %s data 1 : rxF - > (%d,%d) (%d)\n",
+        __FUNCTION__,
+        rxF[2],
+        rxF[3],
+        dBc(rxF[2],rxF[3]));
 #endif
+
       multadd_real_vector_complex_scalar(fml,
                                          ch,
                                          ul_ch,
@@ -217,9 +252,23 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
       ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
 
 #ifdef DEBUG_PUSCH
-      printf("pilot 2 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
-      printf("data 2 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
+      LOG_I(PHY, "In %s pilot 2 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",
+        __FUNCTION__,
+        rxF[0],
+        rxF[1],
+        dBc(rxF[0],rxF[1]),
+        ch[0],
+        ch[1],
+        dBc(ch[0],ch[1]),
+        pil[0],
+        pil[1]);
+      LOG_I(PHY, "In %s data 2 : rxF - > (%d,%d) (%d)\n",
+        __FUNCTION__,
+        rxF[2],
+        rxF[3],
+        dBc(rxF[2],rxF[3]));
 #endif
+
       multadd_real_vector_complex_scalar(fmm,
                                          ch,
                                          ul_ch,
@@ -323,7 +372,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
 
       // check if PRB crosses DC and improve estimates around DC
       if ((bwp_start_subcarrier < gNB->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) {
-        ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
+        ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset];
         uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier);
         uint16_t idxPil = idxDC/2;
         re_offset = k;
@@ -374,7 +423,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
         }
       }
 #ifdef DEBUG_PUSCH
-      ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
+      ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset];
       for(uint16_t idxP=0; idxP<ceil((float)nb_rb_pusch*12/8); idxP++) {
         for(uint8_t idxI=0; idxI<16; idxI+=2) {
           printf("%d\t%d\t",ul_ch[idxP*16+idxI],ul_ch[idxP*16+idxI+1]);
@@ -464,7 +513,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
                                                         ch_r,
                                                         ul_ch);
 
-        ul_ch_128 = (__m128i *)&ul_ch_estimates[aarx][ch_offset];
+        ul_ch_128 = (__m128i *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset];
 
         ul_ch_128[0] = _mm_slli_epi16 (ul_ch_128[0], 2);
     }
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
index a463e21839a70ba6515c8347cce3df5589047d39..c8e02fd13dcdcb6bb648dda5d25d889e04df2f38 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
@@ -47,10 +47,13 @@ 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);
 
-int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
+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, uint8_t nrOfLayers);
 
+int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
 
 void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
                               NR_DL_FRAME_PARMS *frame_parms,
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c
index 03a37e2b279f63b8c658105db6dcab94e3c7d41b..2e270318f822301e822ffd358870c63961c60593 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c
@@ -150,7 +150,7 @@ void pseudo_random_sequence_optimised(unsigned int size, uint32_t *c, uint32_t c
   unsigned int n,x1,x2;
 
   /* init of m-sequences */
-  x1 = 1+ (1<<31);
+  x1 = 1+ (1U<<31);
   x2 = cinit;
   x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
 
diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
index 5d62f9dbb9b8f1736904ff62d98a614a59204d20..920b78eac2b0880311bbac733c9b4fcbcd84ca76 100644
--- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
+++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
@@ -40,9 +40,9 @@
 #include "PHY/defs_gNB.h"
 
 /*Table 7.4.1.1.2-1/2 from 38.211 */
-int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1}};
+int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}};
 int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}};
-int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1},{1,1},{1,-1},{1,1},{1,1}};
+int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}};
 int wt2[12][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1}};
 
 // complex conjugate of mod table
@@ -111,9 +111,10 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
                      int32_t *output,
                      unsigned short p,
                      unsigned char lp,
-                     unsigned short nb_pdsch_rb)
+                     unsigned short nb_pdsch_rb,
+                     uint8_t config_type)
 {
-  int8_t w,config_type;
+  int8_t w;
   short *mod_table;
   unsigned char idx=0;
 
@@ -121,18 +122,16 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
   array_of_w *wf;
   array_of_w *wt;
 
-  config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
-
-  wf = (config_type==pdsch_dmrs_type1) ? wf1 : wf2;
-  wt = (config_type==pdsch_dmrs_type1) ? wt1 : wt2;
+  wf = (config_type==NFAPI_NR_DMRS_TYPE1) ? wf1 : wf2;
+  wt = (config_type==NFAPI_NR_DMRS_TYPE1) ? wt1 : wt2;
 
   if (config_type > 1)
     LOG_E(PHY,"Bad PDSCH DMRS config type %d\n", config_type);
 
-  if ((p>=1000) && (p<((config_type==pdsch_dmrs_type1) ? 1008 : 1012))) {
+  if ((p>=1000) && (p<((config_type==NFAPI_NR_DMRS_TYPE1) ? 1008 : 1012))) {
       if (ue->frame_parms.Ncp == NORMAL) {
 
-        for (int i=0; i<nb_pdsch_rb*((config_type==pdsch_dmrs_type1) ? 6:4); i++) {
+        for (int i=0; i<nb_pdsch_rb*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4); i++) {
 
         	w = (wf[p-1000][i&1])*(wt[p-1000][lp]);
         	mod_table = (w==1) ? nr_rx_mod_table : nr_rx_nmod_table;
diff --git a/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c b/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c
index b0f9e6d03c55562555bfb1048b86e5c132758fa4..9ed2bd949f8b68c774d3f30536799b3f8a26e7b5 100644
--- a/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c
+++ b/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c
@@ -21,6 +21,18 @@
 
 #include "nr_refsig.h"
 #include "nr_mod_table.h"
+short nr_qpsk_mod_table[8];
+
+int32_t nr_16qam_mod_table[16];
+#if defined(__SSE2__)
+__m128i nr_qpsk_byte_mod_table[2048];
+#endif
+
+int64_t nr_16qam_byte_mod_table[1024];
+
+int64_t nr_64qam_mod_table[4096];
+
+int32_t nr_256qam_mod_table[512];
 
 void nr_generate_modulation_table() {
   float sqrt2 = 0.70711;
diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c
index b253e7e9045a550bd34f6273933a03449e9e76b8..11e28a3046669e969865560ae4068c7510534b1a 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold.c
@@ -145,7 +145,7 @@ void nr_init_csi_rs(PHY_VARS_gNB* gNB, uint32_t Nid)
       reset = 1;
       x2 = ((1<<10) * (fp->symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) + (Nid));
 
-      for (uint32_t n=0; n<NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD; n++) {
+      for (uint32_t n=0; n<NR_MAX_CSI_RS_INIT_LENGTH_DWORD; n++) {
         csi_rs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
         reset = 0;
       }
diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c
index eefa6270ab58d553a461b418c9758386ab6f6621..623b86edfbb5dde7a5d7c1b392da6f971e47d4be 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c
@@ -52,22 +52,15 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue)
 }
 
 void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
-                   unsigned short n_idDMRS,
-                   unsigned short length_dmrs)
+                   unsigned short nid)
 {
   unsigned char ns,l;
   unsigned int n,x1,x2,x2tmp0;
-  unsigned int nid;
   uint8_t reset;
 
-  if (n_idDMRS)
-    nid = n_idDMRS;
-  else
-    nid = ue->frame_parms.Nid_cell;
-
   for (ns=0; ns<ue->frame_parms.slots_per_frame; ns++) {
 
-    for (l=0; l<length_dmrs; l++) {
+    for (l=0; l<ue->frame_parms.symbols_per_slot; l++) {
 
       reset = 1;
       x2tmp0 = ((ue->frame_parms.symbols_per_slot*ns+l+1)*((nid<<1)+1))<<17;
@@ -82,11 +75,10 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
 }
 
 void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
-                   unsigned char ns,
                    unsigned short *n_idDMRS)
 {
   unsigned char l;
-  unsigned int n,x1,x2,x2tmp0;
+  unsigned int n,x1,x2,x2tmp0,ns;
   int nscid;
   unsigned int nid;
   uint8_t reset;
@@ -95,23 +87,21 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
   //unsigned short lbar = 0;
 
   for (nscid=0; nscid<2; nscid++) {
-    if (n_idDMRS)
-      nid = n_idDMRS[nscid];
-    else
-      nid = ue->frame_parms.Nid_cell;
+    for (ns=0; ns<ue->frame_parms.slots_per_frame; ns++) {
 
-    //printf("gold pdsch nid %d lbar %d\n",nid,lbar);
+      nid = n_idDMRS[nscid];
 
-    for (l=0; l<ue->frame_parms.symbols_per_slot; l++) {
+      for (l=0; l<ue->frame_parms.symbols_per_slot; l++) {
 
-      reset = 1;
-      x2tmp0 = ((ue->frame_parms.symbols_per_slot*ns+l+1)*((nid<<1)+1))<<17;
-      x2 = (x2tmp0+(nid<<1)+nscid)%(1<<31);  //cinit
-      LOG_D(PHY,"UE DMRS slot %d, symb %d, x2 %x, nscid %d\n",ns,l,x2,nscid);
+        reset = 1;
+        x2tmp0 = ((ue->frame_parms.symbols_per_slot*ns+l+1)*((nid<<1)+1))<<17;
+        x2 = (x2tmp0+(nid<<1)+nscid)%(1<<31);  //cinit
+        LOG_D(PHY,"UE DMRS slot %d, symb %d, x2 %x, nscid %d\n",ns,l,x2,nscid);
 
-      for (n=0; n<NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD; n++) {
-        ue->nr_gold_pdsch[0][ns][l][nscid][n] = lte_gold_generic(&x1, &x2, reset);
-        reset = 0;
+        for (n=0; n<NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD; n++) {
+          ue->nr_gold_pdsch[0][ns][l][nscid][n] = lte_gold_generic(&x1, &x2, reset);
+          reset = 0;
+        }
       }
     }
   }
diff --git a/openair1/PHY/NR_REFSIG/nr_mod_table.h b/openair1/PHY/NR_REFSIG/nr_mod_table.h
index aa8b99f584b6d2554c1fbbd6563c1a64db5b9470..2c6964fe96e65d7d933e36ce05bf824408648a29 100644
--- a/openair1/PHY/NR_REFSIG/nr_mod_table.h
+++ b/openair1/PHY/NR_REFSIG/nr_mod_table.h
@@ -29,16 +29,16 @@
 #define NR_MOD_TABLE_QAM64_OFFSET 23
 #define NR_MOD_TABLE_QAM256_OFFSET 87
 
-short nr_qpsk_mod_table[8];
+extern short nr_qpsk_mod_table[8];
 
-int32_t nr_16qam_mod_table[16];
+extern int32_t nr_16qam_mod_table[16];
 #if defined(__SSE2__)
-__m128i nr_qpsk_byte_mod_table[2048];
+extern __m128i nr_qpsk_byte_mod_table[2048];
 #endif
 
-int64_t nr_16qam_byte_mod_table[1024];
+extern int64_t nr_16qam_byte_mod_table[1024];
 
-int64_t nr_64qam_mod_table[4096];
+extern int64_t nr_64qam_mod_table[4096];
 
-int32_t nr_256qam_mod_table[512];
+extern int32_t nr_256qam_mod_table[512];
 #endif
diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h
index 19b9736bcbeab0f10a5df838659df74ca911d939..b32d48a2e9f95e126e6dd3d77b2b8c9517a7fd76 100644
--- a/openair1/PHY/NR_REFSIG/pss_nr.h
+++ b/openair1/PHY/NR_REFSIG/pss_nr.h
@@ -120,8 +120,7 @@ EXTERN int64_t *pss_corr_ue[NUMBER_PSS_SEQUENCE]
 ;
 
 /* profiling structure */
-EXTERN double cpuf;
-time_stats_t generic_time[TIME_LAST];
+EXTERN time_stats_t generic_time[TIME_LAST];
 
 #ifndef DEFINE_HEADER_ONLY
 
diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
index 83b43c54a0820bb087caa088a58172cfd8433685..1fca2be2a187dd7643d7898ccfba7bd71b09e94c 100644
--- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
+++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
@@ -52,16 +52,15 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
                      int32_t *output,
                      unsigned short p,
                      unsigned char lp,
-                     unsigned short nb_pdsch_rb);
+                     unsigned short nb_pdsch_rb,
+                     uint8_t config_type);
 
 void nr_gold_pbch(PHY_VARS_NR_UE* ue);
 
 void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
-                   unsigned short n_idDMRS,
-                   unsigned short length_dmrs);
+                   unsigned short n_idDMRS);
 
 void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
-                   unsigned char ns,
                    unsigned short *n_idDMRS);
 
 void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
diff --git a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h
index 44d30da8f30540cf3866984077ec92cf7f6aba18..43ec0c03dc65bd2eee15e5f4dbfe7c7933d7da41 100644
--- a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h
+++ b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h
@@ -58,7 +58,7 @@
 
 #define   INDEX_SB_LESS_32            (4)    /* index of dftsizes array for which subcarrier number is less than 36 */
 
-const uint16_t ul_allocated_re[SRS_SB_CONF]     /* number of uplink allocated resource elements */
+EXTERN const uint16_t ul_allocated_re[SRS_SB_CONF]     /* number of uplink allocated resource elements */
 /* this table is derivated from TS 38.211 Table 6.4.1.4.3-1: SRS bandwidth configuration which gives m_SRS_b then all possible values of sequence length is */
 /* M_sc_b_SRS = m_SRS_b * N_SC_RB/K_TC with K_TC = 2 or K_TC = 4  as specified in TS 38.211 6.4.1.4.3 */
 #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
@@ -82,7 +82,7 @@ m_SRS_b    224   116,  240   256   264   272   144   152   160   168   176   184
 ;
 
 /* table of largest prime number lower than uplink allocated resource elements "ul_allocated_re" */
-const uint16_t ref_ul_primes[SRS_SB_CONF]
+EXTERN const uint16_t ref_ul_primes[SRS_SB_CONF]
 #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
 = {
 /*           6,   12,   18,   24,   30,   36,   48,   60,   72,   84,   96,  108,  120,  132,  144,  156,  168,  180,  192,  204,  216,  228,  240,  */
@@ -101,10 +101,10 @@ const uint16_t ref_ul_primes[SRS_SB_CONF]
 ;
 
 /* Low-PAPR base sequence; see TS 38.211 clause 5.2.2 */
-int16_t  *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF];
+EXTERN int16_t  *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF];
 
 /* 38.211 table Table 5.2.2.2-1: Definition of phi(n) for M_ZC = 6 */
-const char phi_M_ZC_6[6*U_GROUP_NUMBER]
+EXTERN const char phi_M_ZC_6[6*U_GROUP_NUMBER]
 #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
 = {
 /*        0   1   2   3   4   5  */
@@ -142,7 +142,7 @@ const char phi_M_ZC_6[6*U_GROUP_NUMBER]
 #endif
 ;
 /* Table 5.2.2.2-2: Definition of phi ( n ) for M ZC = 12  */
-const char phi_M_ZC_12[12*U_GROUP_NUMBER]
+EXTERN const char phi_M_ZC_12[12*U_GROUP_NUMBER]
 #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
 = {
 /*        0   1   2   3   4   5   6   7   8   9  10  11  */
@@ -181,7 +181,7 @@ const char phi_M_ZC_12[12*U_GROUP_NUMBER]
 ;
 
 /* Table 5.2.2.2-3: Definition of phi (n ) for M_ZC = 18 */
-const char phi_M_ZC_18[18*U_GROUP_NUMBER]
+EXTERN const char phi_M_ZC_18[18*U_GROUP_NUMBER]
 #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
 = {
 /*          0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17 */
@@ -220,7 +220,7 @@ const char phi_M_ZC_18[18*U_GROUP_NUMBER]
 ;
 
 /* Table 5.2.2.2-4: Definition of phi (n ) for M_ZC = 24 */
-const char phi_M_ZC_24[24*U_GROUP_NUMBER]
+EXTERN const char phi_M_ZC_24[24*U_GROUP_NUMBER]
 #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
 = {
 /*          0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23 */
@@ -260,10 +260,10 @@ const char phi_M_ZC_24[24*U_GROUP_NUMBER]
 /************** FUNCTION ******************************************/
 
 
-int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling, unsigned int if_dmrs_seq);
+EXTERN int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling, unsigned int if_dmrs_seq);
 
 
-int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling);
+EXTERN int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling);
 /*!
 \brief This function generate the sounding reference symbol (SRS) for the uplink.
 @param tables of srs
@@ -278,7 +278,7 @@ void free_ul_reference_signal_sequences(void);
 #define MAX_INDEX_DMRS_UL_ALLOCATED_REs 53
 
 
-const uint16_t dmrs_ul_allocated_res[MAX_INDEX_DMRS_UL_ALLOCATED_REs]     
+EXTERN const uint16_t dmrs_ul_allocated_res[MAX_INDEX_DMRS_UL_ALLOCATED_REs]     
 /* Number of possible DMRS REs based on PRBs allocated for PUSCH. Array has values until 273 RBs (100Mhz BW)
    Number of PUSCH RBs allocated should be able to be expressed as 2topowerofn*3topowerofn*5tothepowerofn
    According to 3GPP spec 38.211 section 6.3.1.4
@@ -307,7 +307,7 @@ const uint16_t dmrs_ul_allocated_res[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
 /* Table of largest prime number N_ZC < possible DMRS REs M_ZC, this array has values until 100Mhz
    According to 3GPP spec 38.211 section 5.2.2.1
    Table used in calculating DMRS low papr type1 sequence for transform precoding                              */
-const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
+EXTERN const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
 #ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
 = {
 /*DMRS REs              6,    12,   18,   24,    30,    36,    48,   54,   60,   72,   90,   96,    */
@@ -331,8 +331,8 @@ const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
 ;
 
 /// PUSCH DMRS for transform precoding
-int16_t  *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
-int16_t  *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
+EXTERN int16_t  *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
+EXTERN int16_t  *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
 int16_t  get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res);
 void     generate_lowpapr_typ1_refsig_sequences(unsigned int scaling);
 void     free_gnb_lowpapr_sequences(void);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
index 10090788b4ba33bdb60303ed67c84b73a1cc250b..ac0eac8a79c32683ba95053da38336183f95727f 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
@@ -22,17 +22,22 @@
 
 #include "PHY/NR_TRANSPORT/nr_transport_proto.h"
 #include "PHY/MODULATION/nr_modulation.h"
+#include "PHY/NR_REFSIG/nr_refsig.h"
 
 //#define NR_CSIRS_DEBUG
 
-int nr_generate_csi_rs(uint32_t **gold_csi_rs,
-                       int32_t** txdataF,
-                       int16_t amp,
-                       NR_DL_FRAME_PARMS frame_parms,
-                       nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params)
-{
 
-  int16_t mod_csi[frame_parms.symbols_per_slot][NR_MAX_CSI_RS_LENGTH>>1];
+void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
+                        int16_t amp,
+                        nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params,
+                        uint16_t cell_id,
+                        int slot){
+
+  NR_DL_FRAME_PARMS frame_parms=gNB->frame_parms;
+  int32_t **txdataF = gNB->common_vars.txdataF;
+  int txdataF_offset = (slot%2)*frame_parms.samples_per_slot_wCP;
+  uint32_t **gold_csi_rs = gNB->nr_gold_csi_rs[slot];
+  int16_t mod_csi[frame_parms.symbols_per_slot][NR_MAX_CSI_RS_LENGTH>>1] __attribute__((aligned(16)));;
   uint16_t b = csi_params.freq_domain;
   uint16_t n, csi_bw, csi_start, p, k, l, mprime, na, kpn, csi_length;
   uint8_t size, ports, kprime, lprime, i, gs;
@@ -45,6 +50,22 @@ int nr_generate_csi_rs(uint32_t **gold_csi_rs,
 
   AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
 
+  // pre-computed for scrambling id equel to cell id
+  // if the scrambling id is not the cell id we need to re-initialize the rs
+  if (csi_params.scramb_id != cell_id) {
+    uint8_t reset;
+    uint32_t x1, x2;
+    uint32_t Nid = csi_params.scramb_id;
+    for (uint8_t symb=0; symb<frame_parms.symbols_per_slot; symb++) {
+      reset = 1;
+      x2 = ((1<<10) * (frame_parms.symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) + (Nid));
+      for (uint32_t n=0; n<NR_MAX_CSI_RS_INIT_LENGTH_DWORD; n++) {
+        gold_csi_rs[symb][n] = lte_gold_generic(&x1, &x2, reset);
+        reset = 0;
+      }
+    }
+  }
+
   switch (csi_params.row) {
   // implementation of table 7.4.1.5.3-1 of 38.211
   // lprime and kprime are the max value of l' and k'
@@ -495,12 +516,12 @@ int nr_generate_csi_rs(uint32_t **gold_csi_rs,
 
   if (rho < 1) {
     if (csi_params.freq_density == 0)
-      csi_length = (((csi_bw + csi_start)>>1)<<kprime)<<1; 
+      csi_length = (((csi_bw + csi_start)>>1)<<kprime)<<1;
     else
       csi_length = ((((csi_bw + csi_start)>>1)<<kprime)+1)<<1;
   }
   else
-    csi_length = (((uint16_t) rho*(csi_bw + csi_start))<<kprime)<<1; 
+    csi_length = (((uint16_t) rho*(csi_bw + csi_start))<<kprime)<<1;
 
 #ifdef NR_CSIRS_DEBUG
     printf(" start rb %d, n. rbs %d, csi length %d\n",csi_start,csi_bw,csi_length);
@@ -514,41 +535,36 @@ int nr_generate_csi_rs(uint32_t **gold_csi_rs,
 
   // NZP CSI RS
   if (csi_params.csi_type == 1) {
-   // assuming amp is the amplitude of SSB channels
-   switch (csi_params.power_control_offset_ss) {
-   case 0:
-    beta = (amp*ONE_OVER_SQRT2_Q15)>>15;
-    break;
-  
-   case 1:
-    beta = amp;
-    break;
-
-   case 2:
-    beta = (amp*ONE_OVER_SQRT2_Q15)>>14;
-    break;
-
-   case 3:
-    beta = amp<<1;
-    break;
-
-  default:
-    AssertFatal(0==1, "Invalid SS power offset density index for CSI\n");
-   }
-
-   for (lp=0; lp<=lprime; lp++){
-     symb = csi_params.symb_l0;
-     nr_modulation(gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]);
-     if ((csi_params.row == 5) || (csi_params.row == 7) || (csi_params.row == 11) || (csi_params.row == 13) || (csi_params.row == 16))
-       nr_modulation(gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]); 
-     if ((csi_params.row == 14) || (csi_params.row == 13) || (csi_params.row == 16) || (csi_params.row == 17)) {
-       symb = csi_params.symb_l1;
-       nr_modulation(gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]);
-       if ((csi_params.row == 13) || (csi_params.row == 16))
-         nr_modulation(gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]); 
-     }
-   }
-      
+    // assuming amp is the amplitude of SSB channels
+    switch (csi_params.power_control_offset_ss) {
+    case 0:
+      beta = (amp*ONE_OVER_SQRT2_Q15)>>15;
+      break;
+    case 1:
+      beta = amp;
+      break;
+    case 2:
+      beta = (amp*ONE_OVER_SQRT2_Q15)>>14;
+      break;
+    case 3:
+      beta = amp<<1;
+      break;
+    default:
+      AssertFatal(0==1, "Invalid SS power offset density index for CSI\n");
+    }
+
+    for (lp=0; lp<=lprime; lp++){
+      symb = csi_params.symb_l0;
+      nr_modulation(gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]);
+      if ((csi_params.row == 5) || (csi_params.row == 7) || (csi_params.row == 11) || (csi_params.row == 13) || (csi_params.row == 16))
+        nr_modulation(gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]);
+      if ((csi_params.row == 14) || (csi_params.row == 13) || (csi_params.row == 16) || (csi_params.row == 17)) {
+        symb = csi_params.symb_l1;
+        nr_modulation(gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]);
+        if ((csi_params.row == 13) || (csi_params.row == 16))
+          nr_modulation(gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]);
+      }
+    }
   }
 
   uint16_t start_sc = frame_parms.first_carrier_offset;
@@ -586,16 +602,17 @@ int nr_generate_csi_rs(uint32_t **gold_csi_rs,
             }
             // ZP CSI RS
             if (csi_params.csi_type == 2) {
-              ((int16_t*)txdataF[p])[(l*frame_parms.ofdm_symbol_size + k)<<1] = 0;
-              ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = 0;
+              ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*txdataF_offset)] = 0;
+              ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*txdataF_offset)] = 0;
             }
             else {
-              ((int16_t*)txdataF[p])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15;
-              ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15;
+              ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*txdataF_offset)] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15;
+              ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*txdataF_offset)] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15;
             }
 #ifdef NR_CSIRS_DEBUG
-            printf("l,k (%d %d)  seq. index %d \t port %d \t (%d,%d)\n",l,k-start_sc,mprime,p+3000,((int16_t*)txdataF[p])[(l*frame_parms.ofdm_symbol_size + k)<<1],
-               ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1]);
+            printf("l,k (%d %d)  seq. index %d \t port %d \t (%d,%d)\n",l,k,mprime,p+3000,
+                   ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*txdataF_offset)],
+                   ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*txdataF_offset)]);
 #endif
           }
         }
@@ -603,6 +620,4 @@ int nr_generate_csi_rs(uint32_t **gold_csi_rs,
     }
    }
   } 
-
-  return 0;
 }
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index 469415908f6d4b58b2eecf04d6c160a9953199ff..54e6b2ac79a497a7660061e738ecea606dba99db 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -30,7 +30,7 @@
 * \warning
 */
 
-#include <LAYER2/NR_MAC_gNB/nr_mac_gNB.h>
+
 #include "nr_dci.h"
 #include "nr_dlsch.h"
 #include "nr_sch_dmrs.h"
@@ -70,7 +70,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
                         uint32_t **gold_pdcch_dmrs,
                         int32_t *txdataF,
                         int16_t amp,
-                        NR_DL_FRAME_PARMS frame_parms) {
+                        NR_DL_FRAME_PARMS *frame_parms) {
 
   int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1] __attribute__((aligned(16))); // 3 for the max coreset duration
   uint16_t cset_start_sc;
@@ -85,10 +85,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
   // compute rb_offset and n_prb based on frequency allocation
   nr_fill_cce_list(gNB,0,pdcch_pdu_rel15);
   get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
-  cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB;
-  if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) {
-    cset_start_sc = cset_start_sc + RC.nrmac[gNB->Mod_id]->type0_PDCCH_CSS_config.cset_start_rb*NR_NB_SC_PER_RB;
-  }
+  cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
 
   for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
     /*The coreset is initialised
@@ -100,7 +97,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
     cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
     cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
     dci_idx = 0;
-    LOG_D(PHY, "Coreset rb_offset %d, nb_rb %d\n",rb_offset,n_rb);
+    LOG_D(PHY, "Coreset rb_offset %d, nb_rb %d BWP Start %d\n",rb_offset,n_rb,pdcch_pdu_rel15->BWPStart);
     LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb);
     // DMRS length is per OFDM symbol
     uint32_t dmrs_length = n_rb*6; //2(QPSK)*3(per RB)*6(REG per CCE)
@@ -167,8 +164,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
 
     /// Resource mapping
 
-    if (cset_start_sc >= frame_parms.ofdm_symbol_size)
-      cset_start_sc -= frame_parms.ofdm_symbol_size;
+    if (cset_start_sc >= frame_parms->ofdm_symbol_size)
+      cset_start_sc -= frame_parms->ofdm_symbol_size;
 
     // Get cce_list indices by reg_idx in ascending order
     int reg_list_index = 0;
@@ -184,61 +181,64 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
     }
 
     /*Mapping the encoded DCI along with the DMRS */
-    for (int cce_count = 0; cce_count < dci_pdu->AggregationLevel; cce_count ++) {
+    for(int symbol_idx = 0; symbol_idx < pdcch_pdu_rel15->DurationSymbols; symbol_idx++) {
+      for (int cce_count = 0; cce_count < dci_pdu->AggregationLevel; cce_count+=pdcch_pdu_rel15->DurationSymbols) {
 
-      int8_t cce_idx = reg_list_order[cce_count];
+        int8_t cce_idx = reg_list_order[cce_count];
 
-      for (int reg_in_cce_idx = 0; reg_in_cce_idx < NR_NB_REG_PER_CCE; reg_in_cce_idx++) {
+        for (int reg_in_cce_idx = 0; reg_in_cce_idx < NR_NB_REG_PER_CCE; reg_in_cce_idx++) {
 
-        k = cset_start_sc + gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].start_sc_idx;
+          k = cset_start_sc + gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].start_sc_idx;
 
-        if (k >= frame_parms.ofdm_symbol_size)
-          k -= frame_parms.ofdm_symbol_size;
+          if (k >= frame_parms->ofdm_symbol_size)
+            k -= frame_parms->ofdm_symbol_size;
 
-        l = cset_start_symb + gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].symb_idx;
+          l = cset_start_symb + symbol_idx;
 
-        // dmrs index depends on reference point for k according to 38.211 7.4.1.3.2
-        if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
-          dmrs_idx =gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx * 3;
-        else
-          dmrs_idx = (gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx + rb_offset) * 3;
+          // dmrs index depends on reference point for k according to 38.211 7.4.1.3.2
+          if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
+            dmrs_idx = (gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx) * 3;
+          else
+            dmrs_idx = (gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx + rb_offset) * 3;
 
-        k_prime = 0;
+          k_prime = 0;
 
-        for (int m = 0; m < NR_NB_SC_PER_RB; m++) {
-          if (m == (k_prime << 2) + 1) { // DMRS if not already mapped
-            ((int16_t *) txdataF)[(l * frame_parms.ofdm_symbol_size + k) << 1] =
-                (amp * mod_dmrs[l][dmrs_idx << 1]) >> 15;
-            ((int16_t *) txdataF)[((l * frame_parms.ofdm_symbol_size + k) << 1) + 1] =
-                (amp * mod_dmrs[l][(dmrs_idx << 1) + 1]) >> 15;
+          for (int m = 0; m < NR_NB_SC_PER_RB; m++) {
+            if (m == (k_prime << 2) + 1) { // DMRS if not already mapped
+              ((int16_t *) txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] =
+                  (amp * mod_dmrs[l][dmrs_idx << 1]) >> 15;
+              ((int16_t *) txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] =
+                  (amp * mod_dmrs[l][(dmrs_idx << 1) + 1]) >> 15;
 
 #ifdef DEBUG_PDCCH_DMRS
-	    printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
-		   ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
+              printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
+               ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
 #endif
 
-            dmrs_idx++;
-            k_prime++;
+              dmrs_idx++;
+              k_prime++;
 
-          } else { // DCI payload
-            ((int16_t *) txdataF)[(l * frame_parms.ofdm_symbol_size + k) << 1] = (amp * mod_dci[dci_idx << 1]) >> 15;
-            ((int16_t *) txdataF)[((l * frame_parms.ofdm_symbol_size + k) << 1) + 1] =
-                (amp * mod_dci[(dci_idx << 1) + 1]) >> 15;
+            } else { // DCI payload
+              ((int16_t *) txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] = (amp * mod_dci[dci_idx << 1]) >> 15;
+              ((int16_t *) txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] =
+                  (amp * mod_dci[(dci_idx << 1) + 1]) >> 15;
 #ifdef DEBUG_DCI
-	  printf("PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
-		 ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
+              printf("PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
+               ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
 #endif
-            dci_idx++;
-          }
 
-          k++;
+              dci_idx++;
+            }
+
+            k++;
 
-          if (k >= frame_parms.ofdm_symbol_size)
-            k -= frame_parms.ofdm_symbol_size;
+            if (k >= frame_parms->ofdm_symbol_size)
+              k -= frame_parms->ofdm_symbol_size;
 
-        } // m
-      } // reg_in_cce_idx
-    } // cce_count
+          } // m
+        } // reg_in_cce_idx
+      } // cce_count
+    } // symbol_idx
 
     LOG_D(PHY,
           "DCI: payloadSize = %d | payload = %llx\n",
@@ -253,17 +253,15 @@ void nr_generate_dci_top(PHY_VARS_gNB *gNB,
                             uint32_t **gold_pdcch_dmrs,
                             int32_t *txdataF,
                             int16_t amp,
-                            NR_DL_FRAME_PARMS frame_parms) {
+                            NR_DL_FRAME_PARMS *frame_parms) {
 
   AssertFatal(pdcch_pdu!=NULL || ul_dci_pdu!=NULL,"At least one pointer has to be !NULL\n");
 
-  if (pdcch_pdu && ul_dci_pdu) {
+  if (pdcch_pdu) {
     nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
-    nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
   }
-  else if (pdcch_pdu)
-    nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
-  else
+  if (ul_dci_pdu) {
     nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
+  }
 }
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h
index 1b57acc6f40ff7edb2352486a827b9d446d6e55f..e3b53f9cf9658656cb5bb5132b1f3a65b2ad98bc 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h
@@ -35,7 +35,7 @@ void nr_generate_dci_top(PHY_VARS_gNB *gNB,
 			    uint32_t **gold_pdcch_dmrs,
                             int32_t *txdataF,
                             int16_t amp,
-                            NR_DL_FRAME_PARMS frame_parms);
+                            NR_DL_FRAME_PARMS *frame_parms);
 
 void nr_pdcch_scrambling(uint32_t *in,
                          uint32_t size,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
index 3814c782952a7d6dbe8ac2007fb039b2d360fb61..c562dfaa41b5710d3a3cf9df176d0e7c13ed6ecb 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
@@ -136,7 +136,7 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m,  nfapi_nr_dl_tti_pdcch_pdu_r
   get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
 
 
-  int N_reg = n_rb * pdcch_pdu_rel15->DurationSymbols;
+  int N_reg = n_rb;
   int C=-1;
 
   AssertFatal(N_reg > 0,"N_reg cannot be 0\n");
@@ -174,8 +174,8 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m,  nfapi_nr_dl_tti_pdcch_pdu_r
 	  for (uint8_t reg_idx=0; reg_idx<bsize; reg_idx++) {
 	    reg = &cce->reg_list[reg_idx];
 	    reg->reg_idx = bsize*idx + reg_idx;
-	    reg->start_sc_idx = (reg->reg_idx/pdcch_pdu_rel15->DurationSymbols) * NR_NB_SC_PER_RB;
-	    reg->symb_idx = reg->reg_idx % pdcch_pdu_rel15->DurationSymbols;
+	    reg->start_sc_idx = reg->reg_idx * NR_NB_SC_PER_RB;
+	    reg->symb_idx = 0;
 	    LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx);
 	  }
 	}
@@ -185,8 +185,8 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m,  nfapi_nr_dl_tti_pdcch_pdu_r
 	for (uint8_t reg_idx=0; reg_idx<NR_NB_REG_PER_CCE; reg_idx++) {
 	  reg = &cce->reg_list[reg_idx];
 	  reg->reg_idx = cce->cce_idx*NR_NB_REG_PER_CCE + reg_idx;
-	  reg->start_sc_idx = (reg->reg_idx/pdcch_pdu_rel15->DurationSymbols) * NR_NB_SC_PER_RB;
-	  reg->symb_idx = reg->reg_idx % pdcch_pdu_rel15->DurationSymbols;
+	  reg->start_sc_idx = reg->reg_idx * NR_NB_SC_PER_RB;
+	  reg->symb_idx = 0;
 	  LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx);
 	}
 	
@@ -239,7 +239,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
     //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu[i].Payload;
 
     int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->dci_pdu[i].RNTI,gNB,SEARCH_EXIST_OR_FREE);
-    if( (dlsch_id<0) || (dlsch_id>=NUMBER_OF_NR_DLSCH_MAX) ){
+    if( (dlsch_id<0) || (dlsch_id>=gNB->number_of_nr_dlsch_max) ){
       LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->dci_pdu[i].RNTI,dlsch_id);
       return;
     }
@@ -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 1cce5e117465f125538e57f48f1cd2d6f3fdf8a3..b1bf32b7904ab7fa165f04bf4ab51143304a1110 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__)
@@ -132,7 +132,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
   time_stats_t *dlsch_interleaving_stats=&gNB->dlsch_interleaving_stats;
   time_stats_t *dlsch_segmentation_stats=&gNB->dlsch_segmentation_stats;
 
-  for (int dlsch_id=0;dlsch_id<NUMBER_OF_NR_DLSCH_MAX;dlsch_id++) {
+  for (int dlsch_id=0;dlsch_id<gNB->number_of_nr_dlsch_max;dlsch_id++) {
     dlsch = gNB->dlsch[dlsch_id][0];
     if (dlsch->slot_tx[slot] == 0) continue;
 
@@ -141,25 +141,25 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
     uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
     int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs;
     int16_t **tx_layers = (int16_t**)dlsch->txdataF;
+    int16_t **txdataF_precoding = (int16_t**)dlsch->txdataF_precoding;
     int8_t Wf[2], Wt[2], l0, l_prime, l_overline, delta;
     uint8_t dmrs_Type = rel15->dmrsConfigType;
     int nb_re_dmrs;
     uint16_t n_dmrs;
     if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1) {
       nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData;
-      n_dmrs = ((rel15->rbSize+rel15->rbStart)*6)<<1;
     }
     else {
       nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData;
-      n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1;
     }
+    n_dmrs = (rel15->BWPStart+rel15->rbStart+rel15->rbSize)*nb_re_dmrs;
 
     uint16_t dmrs_symbol_map = rel15->dlDmrsSymbPos;//single DMRS: 010000100 Double DMRS 110001100
     uint8_t dmrs_len = get_num_dmrs(rel15->dlDmrsSymbPos);
     uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs*dmrs_len-xOverhead)*rel15->rbSize*rel15->nrOfLayers;
     uint8_t Qm = rel15->qamModOrder[0];
     uint32_t encoded_length = nb_re*Qm;
-    int16_t mod_dmrs[14][n_dmrs] __attribute__ ((aligned(16)));
+    int16_t mod_dmrs[n_dmrs<<1] __attribute__ ((aligned(16)));
 
     /* PTRS */
     uint16_t beta_ptrs = 1;
@@ -264,26 +264,6 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
 	printf("\n");
       }
 #endif
-    
-    /// Antenna port mapping
-    //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007
-
-    /// DMRS QPSK modulation
-    for (int l=rel15->StartSymbolIndex; l<rel15->StartSymbolIndex+rel15->NrOfSymbols; l++) {
-      if (rel15->dlDmrsSymbPos & (1 << l)) {
-        nr_modulation(pdsch_dmrs[l][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs[l]); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
-
-#ifdef DEBUG_DLSCH
-        printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs>>1, dmrs_Type);
-        for (int i=0; i<n_dmrs>>4; i++) {
-          for (int j=0; j<8; j++) {
-            printf("%d %d\t", mod_dmrs[l][((i<<3)+j)<<1], mod_dmrs[l][(((i<<3)+j)<<1)+1]);
-          }
-          printf("\n");
-        }
-#endif
-      }
-    }
 
     /// Resource mapping
     
@@ -291,13 +271,16 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
     uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart+rel15->BWPStart)*NR_NB_SC_PER_RB;
     if (start_sc >= frame_parms->ofdm_symbol_size)
       start_sc -= frame_parms->ofdm_symbol_size;
-    
+
+    int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP;
+
 #ifdef DEBUG_DLSCH_MAPPING
     printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
 	   start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers);
 #endif
+
     for (int ap=0; ap<rel15->nrOfLayers; ap++) {
-      
+
       // DMRS params for this ap
       get_Wt(Wt, ap, dmrs_Type);
       get_Wf(Wf, ap, dmrs_Type);
@@ -312,20 +295,31 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
 	     1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime, l0, dmrs_symbol);
 #endif
 
-      uint16_t m=0, dmrs_idx=0, k=0;
-
-      int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP;
+      uint16_t m=0, dmrs_idx=0;
 
       // Loop Over OFDM symbols:
       for (int l=rel15->StartSymbolIndex; l<rel15->StartSymbolIndex+rel15->NrOfSymbols; l++) {
         /// DMRS QPSK modulation
         uint8_t k_prime=0;
         uint16_t n=0;
-        if ((dmrs_symbol_map & (1 << l))){ //DMRS time occasion
-          if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k)
-            dmrs_idx = rel15->rbStart*6;
-          else
-            dmrs_idx = rel15->rbStart*4;
+
+        if ((dmrs_symbol_map & (1 << l))){ // DMRS time occasion
+          // The reference point for is subcarrier 0 of the lowest-numbered resource block in CORESET 0 if the corresponding
+          // PDCCH is associated with CORESET 0 and Type0-PDCCH common search space and is addressed to SI-RNTI
+          // 3GPP TS 38.211 V15.8.0 Section 7.4.1.1.2 Mapping to physical resources
+          if (rel15->rnti==SI_RNTI) {
+            if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) {
+              dmrs_idx = rel15->rbStart*6;
+            } else {
+              dmrs_idx = rel15->rbStart*4;
+            }
+          } else {
+            if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) {
+              dmrs_idx = (rel15->rbStart+rel15->BWPStart)*6;
+            } else {
+              dmrs_idx = (rel15->rbStart+rel15->BWPStart)*4;
+            }
+          }
         }
 
         // Update l_prime in the case of double DMRS config
@@ -338,6 +332,21 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
           }
         }
 
+        /// DMRS QPSK modulation
+        if (rel15->dlDmrsSymbPos & (1 << l)) {
+          nr_modulation(pdsch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
+
+#ifdef DEBUG_DLSCH
+          printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs, dmrs_Type);
+          for (int i=0; i<n_dmrs>>4; i++) {
+            for (int j=0; j<8; j++) {
+              printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]);
+            }
+            printf("\n");
+          }
+#endif
+        }
+
         /* calculate if current symbol is PTRS symbols */
         ptrs_idx = 0;
 
@@ -348,7 +357,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
             nr_modulation(pdsch_dmrs[l][0], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs);
           }
         }
-        k = start_sc;
+        uint16_t k = start_sc;
         // Loop Over SCs:
         for (int i=0; i<rel15->rbSize*NR_NB_SC_PER_RB; i++) {
           /* check if cuurent RE is PTRS RE*/
@@ -368,12 +377,12 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
 
           /* Map DMRS Symbol */
           if ( ( dmrs_symbol_map & (1 << l) ) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
-            ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][dmrs_idx<<1]) >> 15;
-            ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
+            txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) +     (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15;
+            txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
 #ifdef DEBUG_DLSCH_MAPPING
             printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
-                   dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
-                   ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
+                   dmrs_idx, l, k, k_prime, n, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
+                   txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
 #endif
             dmrs_idx++;
             k_prime++;
@@ -382,8 +391,8 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
           }
           /* Map PTRS Symbol */
           else if(is_ptrs_re){
-            ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15;
-            ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15;
+            txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) +     (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15;
+            txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15;
 #ifdef DEBUG_DLSCH_MAPPING
             printf("ptrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
                    ptrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
@@ -392,17 +401,20 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
             ptrs_idx++;
           }
           /* Map DATA Symbol */
-          else {
-            if( (!(dmrs_symbol_map & (1 << l))) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
-              ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
-              ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
+          else if( (!(dmrs_symbol_map & (1 << l))) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
+            txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) +     (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
+            txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
 #ifdef DEBUG_DLSCH_MAPPING
-              printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
-                     m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
-                     ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
+            printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
+                   m, l, k, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
+                   txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
 #endif
-              m++;
-            }
+            m++;
+          }
+          /* mute RE */
+          else {
+            txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) +     (2*txdataF_offset)] = 0;
+            txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = 0;
           }
           if (++k >= frame_parms->ofdm_symbol_size)
             k -= frame_parms->ofdm_symbol_size;
@@ -410,9 +422,108 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
       } // symbol loop
     }// layer loop
 
+    ///Layer Precoding and Antenna port mapping
+    // tx_layers 1-8 are mapped on antenna ports 1000-1007
+    // The precoding info is supported by nfapi such as num_prgs, prg_size, prgs_list and pm_idx
+    // The same precoding matrix is applied on prg_size RBs, Thus
+    //        pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1
+    // The Precoding matrix:
+    // The Codebook Type I and Type II are not supported yet.
+    // We adopt the precoding matrices of PUSCH for 4 layers.
+    for (int ap=0; ap<frame_parms->nb_antennas_tx; ap++) {
+
+      for (int l=rel15->StartSymbolIndex; l<rel15->StartSymbolIndex+rel15->NrOfSymbols; l++) {
+        uint16_t k = start_sc;
+
+        for (int rb=0; rb<rel15->rbSize; rb++) {
+          //get pmi info
+          uint8_t pmi;
+          if (rel15->precodingAndBeamforming.prg_size > 0)
+            pmi = rel15->precodingAndBeamforming.prgs_list[(int)rb/rel15->precodingAndBeamforming.prg_size].pm_idx;
+          else
+            pmi = 0;//no precoding
+
+          if (pmi == 0) {//unitary Precoding
+            if(ap<rel15->nrOfLayers)
+              memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k],
+                     (void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + txdataF_offset+ k)],
+                     NR_NB_SC_PER_RB*sizeof(int32_t));
+            else
+              memset((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k],
+                     0,
+                     NR_NB_SC_PER_RB*sizeof(int32_t));
+            k += NR_NB_SC_PER_RB;
+            if (k >= frame_parms->ofdm_symbol_size) {
+              k -= frame_parms->ofdm_symbol_size;
+            }
+          }
+          else {
+            //get the precoding matrix weights:
+            char *W_prec;
+            switch (frame_parms->nb_antennas_tx) {
+              case 1://1 antenna port
+                W_prec = nr_W_1l_2p[pmi][ap];
+                break;
+              case 2://2 antenna ports
+                if (rel15->nrOfLayers == 1)//1 layer
+                  W_prec = nr_W_1l_2p[pmi][ap];
+                else//2 layers
+                  W_prec = nr_W_2l_2p[pmi][ap];
+                break;
+              case 4://4 antenna ports
+                if (rel15->nrOfLayers == 1)//1 layer
+                  W_prec = nr_W_1l_4p[pmi][ap];
+                else if (rel15->nrOfLayers == 2)//2 layers
+                  W_prec = nr_W_2l_4p[pmi][ap];
+                else if (rel15->nrOfLayers == 3)//3 layers
+                  W_prec = nr_W_3l_4p[pmi][ap];
+                else//4 layers
+                  W_prec = nr_W_4l_4p[pmi][ap];
+                break;
+              default:
+                LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n");
+                W_prec = nr_W_1l_2p[pmi][ap];
+                break;
+            }
+            for (int i=0; i<NR_NB_SC_PER_RB; i++) {
+              int32_t re_offset = l*frame_parms->ofdm_symbol_size + k;
+              int32_t precodatatx_F = nr_layer_precoder(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset+txdataF_offset);
+              ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0];
+              ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1];
+#ifdef DEBUG_DLSCH_MAPPING
+              printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n",
+                     ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)],
+                     ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]);
+#endif
+              if (++k >= frame_parms->ofdm_symbol_size) {
+                k -= frame_parms->ofdm_symbol_size;
+              }
+            }
+          }
+        } //RB loop
+      } // symbol loop
+    }// port loop
 
     dlsch->slot_tx[slot]=0;
+
+    // TODO: handle precoding
+    // this maps the layers onto antenna ports
+    
+    // handle beamforming ID
+    // each antenna port is assigned a beam_index
+    // since PHY can only handle BF on slot basis we set the whole slot
+
+    // first check if this slot has not already been allocated to another beam
+    if (gNB->common_vars.beam_id[0][slot*frame_parms->symbols_per_slot]==255) {
+      for (int j=0;j<frame_parms->symbols_per_slot;j++) 
+	gNB->common_vars.beam_id[0][slot*frame_parms->symbols_per_slot+j] = rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
+    }
+    else {
+      LOG_D(PHY,"beam index for PDSCH allocation already taken\n");
+    }
   }// dlsch loop
+
+  
   return 0;
 }
 
@@ -430,6 +541,6 @@ void dump_pdsch_stats(PHY_VARS_gNB *gNB) {
 
 void clear_pdsch_stats(PHY_VARS_gNB *gNB) {
 
-  for (int i=0;i<NUMBER_OF_NR_DLSCH_MAX;i++)
+  for (int i=0;i<gNB->number_of_nr_dlsch_max;i++)
     memset((void*)&gNB->dlsch_stats[i],0,sizeof(gNB->dlsch_stats[i]));
 }
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index e6544bbe0c2a0115028d2fe1a9011cafd328dd74..2ae2549df31743e6d7263e1087c8d0714bf34091 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
@@ -61,10 +62,8 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB)
     if (N_RB != 273) {
       a_segments = a_segments*N_RB;
       a_segments = a_segments/273 +1;
-    }  
-    
-    
-    
+    }
+
 #ifdef DEBUG_DLSCH_FREE
     LOG_D(PHY,"Freeing dlsch %p\n",dlsch);
 #endif
@@ -110,8 +109,6 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB)
           harq->d[r] = NULL;
         }
       }
-      free16(harq, sizeof(NR_DL_gNB_HARQ_t));
-      harq = NULL;
     }
   }
 
@@ -133,7 +130,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
   if (N_RB != 273) {
     a_segments = a_segments*N_RB;
     a_segments = a_segments/273 +1;
-  }  
+  }
 
   uint16_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment
 
@@ -145,31 +142,30 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
   dlsch->Mdlharq = Mdlharq;
   dlsch->Mlimit = 4;
   dlsch->Nsoft = Nsoft;
-  
+
   for (layer=0; layer<NR_MAX_NB_LAYERS; layer++) {
-    dlsch->ue_spec_bf_weights[layer] = (int32_t **)malloc16(64 * sizeof(int32_t *));
+    dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*));
 
-    for (aa = 0; aa < 64; aa++) {
-      dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES * sizeof(int32_t));
-      for (re = 0; re < OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
+    for (aa=0; aa<64; aa++) {
+      dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
+      for (re=0;re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
         dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
       }
     }
 
-    dlsch->txdataF[layer] =
-        (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH / NR_MAX_NB_LAYERS)
-                            * sizeof(int32_t)); // NR_MAX_NB_LAYERS is already included in NR_MAX_PDSCH_ENCODED_LENGTH
+    dlsch->txdataF[layer] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH/NR_MAX_NB_LAYERS)*sizeof(int32_t)); // NR_MAX_NB_LAYERS is already included in NR_MAX_PDSCH_ENCODED_LENGTH
+    dlsch->txdataF_precoding[layer] = (int32_t *)malloc16(2*14*frame_parms->ofdm_symbol_size*sizeof(int32_t));
   }
 
-  for (int q = 0; q < NR_MAX_NB_CODEWORDS; q++)
-    dlsch->mod_symbs[q] = (int32_t *)malloc16(NR_MAX_PDSCH_ENCODED_LENGTH * sizeof(int32_t));
+  for (int q=0; q<NR_MAX_NB_CODEWORDS; q++)
+    dlsch->mod_symbs[q] = (int32_t *)malloc16(NR_MAX_PDSCH_ENCODED_LENGTH*sizeof(int32_t));
 
-  dlsch->calib_dl_ch_estimates = (int32_t **)malloc16(64 * sizeof(int32_t *));
-  for (aa = 0; aa < 64; aa++) {
-    dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES * sizeof(int32_t));
+  dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(64*sizeof(int32_t*));
+  for (aa=0; aa<64; aa++) {
+    dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
   }
 
-  for (i = 0; i < 20; i++) {
+  for (i=0; i<20; i++) {
     dlsch->harq_ids[0][i] = 0;
     dlsch->harq_ids[1][i] = 0;
   }
@@ -196,14 +192,15 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
     AssertFatal(harq->d[r], "cannot allocate harq->d[%d]\n", r); // max size for coded output
     bzero(harq->c[r], 8448);
     bzero(harq->d[r], (3 * 8448));
-    harq->e = malloc16(14 * N_RB * 12 * 8);
-    AssertFatal(harq->e, "cannot allocate harq->e\n");
-    bzero(harq->e, 14 * N_RB * 12 * 8);
-    harq->f = malloc16(14 * N_RB * 12 * 8);
-    AssertFatal(harq->f, "cannot allocate harq->f\n");
-    bzero(harq->f, 14 * N_RB * 12 * 8);
   }
 
+  harq->e = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
+  AssertFatal(harq->e, "cannot allocate harq->e\n");
+  bzero(harq->e, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
+  harq->f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
+  AssertFatal(harq->f, "cannot allocate harq->f\n");
+  bzero(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
+
   return(dlsch);
 }
 
@@ -268,10 +265,11 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
   float Coderate = 0.0;
   uint8_t Nl = 4;
 
-  
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
 
   A = rel15->TBSize[0]<<3;
+  if ( dlsch->rnti != SI_RNTI )
+     trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], 0, WS_C_RNTI, dlsch->rnti, frame, slot,0, 0);
 
   NR_gNB_SCH_STATS_t *stats=NULL;
   int first_free=-1;
@@ -294,7 +292,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
@@ -304,7 +302,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
     a[2+(A>>3)] = ((uint8_t*)&crc)[0];
     //printf("CRC %x (A %d)\n",crc,A);
     //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
-    
+
     harq->B = A+24;
     //    harq->b = a;
 
@@ -323,7 +321,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
     a[1+(A>>3)] = ((uint8_t*)&crc)[0];
     //printf("CRC %x (A %d)\n",crc,A);
     //printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
-    
+
     harq->B = A+16;
     //    harq->b = a;
 
@@ -339,17 +337,17 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
     Coderate = (float) R /(float) 1024;
   else  // to scale for mcs 20 and 26 in table 5.1.3.1-2 which are decimal and input 2* in nr_tbs_tools
     Coderate = (float) R /(float) 2048;
-  
+
   if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
     harq->BG = 2;
   else
     harq->BG = 1;
-  
+
   start_meas(dlsch_segmentation_stats);
   Kb = nr_segmentation(harq->b, harq->c, harq->B, &harq->C, &harq->K, Zc, &harq->F, harq->BG);
   stop_meas(dlsch_segmentation_stats);
   F = harq->F;
-  
+
   Kr = harq->K;
 #ifdef DEBUG_DLSCH_CODING
   uint16_t Kr_bytes;
@@ -357,7 +355,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
 #endif
 
   //printf("segment Z %d k %d Kr %d BG %d C %d\n", *Zc,harq->K,Kr,BG,harq->C);
-  
+
   for (r=0; r<harq->C; r++) {
     //d_tmp[r] = &harq->d[r][0];
     //channel_input[r] = &harq->d[r][0];
@@ -369,7 +367,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
       LOG_D(PHY,"%d ", harq->c[r][cnt]);
     }
     LOG_D(PHY,"\n");
-    
+
 #endif
     //ldpc_encoder_orig((unsigned char*)harq->c[r],harq->d[r],*Zc,Kb,Kr,BG,0);
     //ldpc_encoder_optim((unsigned char*)harq->c[r],(unsigned char*)&harq->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL);
@@ -380,23 +378,22 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
   impp.tinput = tinput;
   impp.tparity = tparity;
   impp.toutput = toutput;
-  
+
   for(int j=0;j<(harq->C/8+1);j++) {
     impp.macro_num=j;
     nrLDPC_encoder(harq->c,harq->d,*Zc,Kb,Kr,harq->BG,&impp);
   }
-  
 
 #ifdef DEBUG_DLSCH_CODING
   write_output("enc_input0.m","enc_in0",&harq->c[0][0],Kr_bytes,1,4);
   write_output("enc_output0.m","enc0",&harq->d[0][0],(3*8*Kr_bytes)+12,1,4);
 #endif
- 
+
   F = harq->F;
-  
+
   Kr = harq->K;
   for (r=0; r<harq->C; r++) {
-    
+
     if (F>0) {
       for (int k=(Kr-F-2*(*Zc)); k<Kr-2*(*Zc); k++) {
 	// writing into positions d[r][k-2Zc] as in clause 5.3.2 step 2) in 38.212
@@ -405,17 +402,15 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
 	//printf("r %d filler bits [%d] = %d \n", r,k, harq->d[r][k]);
       }
     }
-    
-    
-    
+
 #ifdef DEBUG_DLSCH_CODING
     LOG_D(PHY,"rvidx in encoding = %d\n", rel15->rvIndex[0]);
 #endif
-    
+
     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,
@@ -423,13 +418,13 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
 	  F,
 	  Kr-F-2*(*Zc),
 	  mod_order,nb_rb);
-    
+
     // for tbslbrm calculation according to 5.4.2.1 of 38.212
     if (rel15->nrOfLayers < Nl)
       Nl = rel15->nrOfLayers;
-    
+
     Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl);
-    
+
     start_meas(dlsch_rate_matching_stats);
     nr_rate_matching_ldpc(Ilbrm,
                           Tbslbrm,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
index 05d6c4c112bbe35ccc906425545ca63d25a85989..543002827d65b9f36e9414c11d36e0705161b5b3 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
@@ -260,7 +260,7 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
    int16_t first_free_index=-1;
  
    AssertFatal(gNB!=NULL,"gNB is null\n");
-   for (i=0; i<NUMBER_OF_NR_DLSCH_MAX; i++) {
+   for (i=0; i<gNB->number_of_nr_dlsch_max; i++) {
      AssertFatal(gNB->dlsch[i]!=NULL,"gNB->dlsch[%d] is null\n",i);
      AssertFatal(gNB->dlsch[i][0]!=NULL,"gNB->dlsch[%d][0] is null\n",i);
      LOG_D(PHY,"searching for rnti %x : dlsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,
@@ -286,7 +286,7 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB,
   nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &pdsch_pdu->pdsch_pdu_rel15;
  
   int dlsch_id = find_nr_dlsch(rel15->rnti,gNB,SEARCH_EXIST);
-  AssertFatal( (dlsch_id>=0) && (dlsch_id<NUMBER_OF_NR_DLSCH_MAX),
+  AssertFatal( (dlsch_id>=0) && (dlsch_id<gNB->number_of_nr_dlsch_max),
               "illegal or no dlsch_id found!!! rnti %04x dlsch_id %d\n",rel15->rnti,dlsch_id);
   NR_gNB_DLSCH_t  *dlsch = gNB->dlsch[dlsch_id][0];
   NR_DL_gNB_HARQ_t *harq  = &dlsch->harq_process;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
index bd1278b2eb192e82bba8f817e17716effaed7101..a4cec432de30d4b2805db685964b7dc7a52b137d 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
@@ -42,7 +42,7 @@
 
 extern short nr_qpsk_mod_table[8];
 
-uint8_t nr_pbch_payload_interleaving_pattern[32] = {16, 23, 18, 17, 8, 30, 10, 6, 24, 7, 0, 5, 3, 2, 1, 4,
+const uint8_t nr_pbch_payload_interleaving_pattern[32] = {16, 23, 18, 17, 8, 30, 10, 6, 24, 7, 0, 5, 3, 2, 1, 4,
                                                     9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31
                                                    };
 
@@ -141,7 +141,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
   return 0;
 }
 
-void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
+static void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
                         uint32_t Nid,
                         uint8_t nushift,
                         uint16_t M,
@@ -241,7 +241,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
   ///Payload generation
   memset((void *)pbch, 0, sizeof(NR_gNB_PBCH));
   pbch->pbch_a=0;
-  uint8_t ssb_index = frame_parms->ssb_index;
+  uint8_t ssb_index = ssb_pdu->ssb_pdu_rel15.SsbBlockIndex;
   uint8_t *pbch_pdu = (uint8_t*)&ssb_pdu->ssb_pdu_rel15.bchPayload;
   uint8_t Lmax = frame_parms->Lmax;
   for (int i=0; i<NR_PBCH_PDU_BITS; i++)
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c
index b5a3c061e9f4abbacd35d07186819a59209e106d..000348ae8728ef2fd2656f86db9ba317c827c5a6 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c
@@ -301,205 +301,300 @@ void rx_nr_prach_ru(RU_t *ru,
 
     // do DFT
     if (mu==1) {
-    if (fp->N_RB_UL <= 100)
-      AssertFatal(1==0,"N_RB_UL %d not support for NR PRACH yet\n",fp->N_RB_UL);
-    else if (fp->N_RB_UL < 137) {
-      if (fp->threequarter_fs==0) { 
-	//40 MHz @ 61.44 Ms/s 
-	//50 MHz @ 61.44 Ms/s
-	prach2 = prach[aa] + (Ncp<<2); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s
-	if (prach_sequence_length == 0) {
-	  if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
-            dftlen=49152;
-            dft(DFT_49152,prach2,rxsigF[aa],1);
+      switch(fp->samples_per_subframe) {
+        case 15360:
+          // 10, 15 MHz @ 15.36 Ms/s
+          prach2 = prach[aa] + (1*Ncp); // Ncp is for 30.72 Ms/s, so divide by 2 to bring to 15.36 Ms/s and multiply by 2 for I/Q
+          if (prach_sequence_length == 0) {
+            if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+              dftlen=12288;
+              dft(DFT_12288,prach2,rxsigF[aa],1);
+            }
+            if (prachFormat == 1 || prachFormat == 2) {
+              dft(DFT_12288,prach2+24576,rxsigF[aa]+24576,1);
+              reps++;
+            }
+            if (prachFormat == 2) {
+              dft(DFT_12288,prach2+(24576*2),rxsigF[aa]+(24576*2),1);
+              dft(DFT_12288,prach2+(24576*3),rxsigF[aa]+(24576*3),1);
+              reps+=2;
+            }
+            if (prachFormat == 3) {
+              dftlen=3072;
+              for (int i=0;i<4;i++) dft(DFT_3072,prach2+(i*3072*2),rxsigF[aa]+(i*3072*2),1);
+              reps=4;
+            }
+          } else { // 839 sequence
+            if (prachStartSymbol == 0) prach2+=16; // 8 samples @ 15.36 Ms/s in first symbol of each half subframe (15/30 kHz only)
+
+            dftlen=512;
+            dft(DFT_512,prach2,rxsigF[aa],1);
+            if (prachFormat != 9/*C0*/) {
+              dft(DFT_512,prach2+1024,rxsigF[aa]+1024,1);
+              reps++;
+            }
+            if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
+              dft(DFT_512,prach2+1024*2,rxsigF[aa]+1024*2,1);
+              dft(DFT_512,prach2+1024*3,rxsigF[aa]+1024*3,1);
+              reps+=2;
+            }
+            if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
+              dft(DFT_512,prach2+1024*4,rxsigF[aa]+1024*4,1);
+              dft(DFT_512,prach2+1024*5,rxsigF[aa]+1024*5,1);
+              reps+=2;
+            }
+            if (prachFormat == 8/*B4*/) {
+              for (int i=6;i<12;i++) dft(DFT_512,prach2+(1024*i),rxsigF[aa]+(1024*i),1);
+              reps+=6;
+            }
           }
-	  if (prachFormat == 1 || prachFormat == 2) {
-            dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1);
-	    reps++;
-	  }
-	  if (prachFormat == 2) {
-	    dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1);
-	    dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1);
-	    reps+=2;
-	  }
-	  if (prachFormat == 3) {
-            dftlen=12288;
-	    for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1);
-	    reps=4;
-	  }
-	}// 839 sequence
-	else {
-	  if (prachStartSymbol == 0)
-	    prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) 
-
-	  dftlen=2048;
-	  dft(DFT_2048,prach2,rxsigF[aa],1);
-	  if (prachFormat != 9/*C0*/) { 
-	    dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1);
-	    reps++;
-	  }
-	  if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {     
-	    dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1);
-	    dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1);
-	    reps+=2;
-	  }
-	  if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {     
-	    dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1);
-	    dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1);
-	    reps+=2;
-	  } 
-	  if (prachFormat == 8/*B4*/) {
-	    for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1);
-	    reps+=6;
-	  }
-	}
-      } else { // threequarter sampling
-	//	40 MHz @ 46.08 Ms/s
-	prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q
-	if (prach_sequence_length == 0) {
-	  AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n");
-	  if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
-            dftlen=36864;
-            dft(DFT_36864,prach2,rxsigF[aa],1);
-	    reps++;
-	  }
-	  if (prachFormat == 1 || prachFormat == 2) {
-	    dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1);
-	    reps++;
-	  }
-	  if (prachFormat == 2) {
-            dft(DFT_36864,prach2+(73728*2),rxsigF[aa]+(73728*2),1);
-	    dft(DFT_36864,prach2+(73728*3),rxsigF[aa]+(73728*3),1);
-	    reps+=2;
-	  }
-	  if (prachFormat == 3) {
-	    dftlen=9216;
-	    for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1);
-	    reps=4;
-	  }
-	} else {
-	  if (prachStartSymbol == 0) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only)
-	  dftlen=1536;
-	  dft(DFT_1536,prach2,rxsigF[aa],1);
-	  if (prachFormat != 9/*C0*/) {
-	    dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
-	    reps++;
-	  }
-	  
-	  if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {     
-	    dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1);
-	    dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1);
-	    reps+=2;
-	  } 
-	  if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {     
-	    dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1);
-	    dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1);
-	    reps+=2;
-	  } 
-	  if (prachFormat == 8/*B4*/) {
-	    for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
-	    reps+=6;
-	  }
-	} // short format
-      } // 3/4 sampling
-    } // <=50 MHz BW
-    else if (fp->N_RB_UL <= 273) {
-      if (fp->threequarter_fs==0) {
-	prach2 = prach[aa] + (Ncp<<3); 
-	//80,90,100 MHz @ 122.88 Ms/s 
-
-	if (prach_sequence_length == 0) {	
-	  if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
-            dftlen=98304;
-            dft(DFT_98304,prach2,rxsigF[aa],1);
+          break;
+
+        case 30720:
+          // 20, 25, 30 MHz @ 30.72 Ms/s
+          prach2 = prach[aa] + (2*Ncp); // Ncp is for 30.72 Ms/s, so just multiply by 2 for I/Q
+          if (prach_sequence_length == 0) {
+            if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+              dftlen=24576;
+              dft(DFT_24576,prach2,rxsigF[aa],1);
+            }
+            if (prachFormat == 1 || prachFormat == 2) {
+              dft(DFT_24576,prach2+49152,rxsigF[aa]+49152,1);
+              reps++;
+            }
+            if (prachFormat == 2) {
+              dft(DFT_24576,prach2+(49152*2),rxsigF[aa]+(49152*2),1);
+              dft(DFT_24576,prach2+(49152*3),rxsigF[aa]+(49152*3),1);
+              reps+=2;
+            }
+            if (prachFormat == 3) {
+              dftlen=6144;
+              for (int i=0;i<4;i++) dft(DFT_6144,prach2+(i*6144*2),rxsigF[aa]+(i*6144*2),1);
+              reps=4;
+            }
+          } else { // 839 sequence
+            if (prachStartSymbol == 0) prach2+=32; // 16 samples @ 30.72 Ms/s in first symbol of each half subframe (15/30 kHz only)
+
+            dftlen=1024;
+            dft(DFT_1024,prach2,rxsigF[aa],1);
+            if (prachFormat != 9/*C0*/) {
+              dft(DFT_1024,prach2+2048,rxsigF[aa]+2048,1);
+              reps++;
+            }
+            if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
+              dft(DFT_1024,prach2+2048*2,rxsigF[aa]+2048*2,1);
+              dft(DFT_1024,prach2+2048*3,rxsigF[aa]+2048*3,1);
+              reps+=2;
+            }
+            if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
+              dft(DFT_1024,prach2+2048*4,rxsigF[aa]+2048*4,1);
+              dft(DFT_1024,prach2+2048*5,rxsigF[aa]+2048*5,1);
+              reps+=2;
+            }
+            if (prachFormat == 8/*B4*/) {
+              for (int i=6;i<12;i++) dft(DFT_1024,prach2+(2048*i),rxsigF[aa]+(2048*i),1);
+              reps+=6;
+            }
           }
-	  if (prachFormat == 1 || prachFormat == 2) {
-	    dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1);
-	    reps++;
-	  }
-	  if (prachFormat == 2) {
-	    dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1);
-	    dft(DFT_98304,prach2+(196608*3),rxsigF[aa]+(196608*3),1);
-	    reps+=2;
-	  }
-	  if (prachFormat == 3) {
-            dftlen=24576;
-	    for (int i=0;i<4;i++) dft(DFT_24576,prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1);
-	    reps=4;
-	  }
-	}
-	else {
-	  if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) 
-
-	  dftlen=4096;
-	  dft(DFT_4096,prach2,rxsigF[aa],1);
-	  if (prachFormat != 9/*C0*/) { 
-	    dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1);
-	    reps++;
-	  }
-	  
-	  if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {     
-	    dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1);
-	    dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1);
-	    reps+=2;
-	  } 
-	  if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {     
-	    dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1);
-	    dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1);
-	    reps+=2;
-	  } 
-	  if (prachFormat == 8/*B4*/) {
-	    for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1);
-	    reps+=6;
-	  }
-	}
-      } else {
-	AssertFatal(fp->N_RB_UL <= 217,"cannot do more than 217 PRBs with 3/4 sampling\n");
-	prach2 = prach[aa] + (6*Ncp);
-	//	80 MHz @ 92.16 Ms/s
-	if (prach_sequence_length == 0) {
-	  if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
-            dftlen=73728;
-	    dft(DFT_73728,prach2,rxsigF[aa],1);
-	    reps++;
-	  }
-	  if (prachFormat == 1 || prachFormat == 2) {
-	    dft(DFT_73728,prach2+(2*73728),rxsigF[aa]+(2*73728),1);
-	    reps++;
-	  }
-	  if (prachFormat == 3) {
-            dftlen=18432;
-	    for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1);
-	    reps=4;
-	  }
-	} else {
-	  if (prachStartSymbol == 0) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) 
-
-	  dftlen=3072;
-	  dft(DFT_3072,prach2,rxsigF[aa],1);
-	  if (prachFormat != 9/*C0*/) {
-	    dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
-	    reps++;
-	  }
-	  
-	  if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {     
-	    dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1);
-	    dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1);
-	    reps+=2;
-	  } 
-	  if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {     
-	    dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1);
-	    dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1);
-	    reps+=2;
-	  } 
-	  if (prachFormat == 8/*B4*/) {
-	    for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1);
-	    reps+=6;
-	  }
-	}
+          break;
+
+        case 61440:
+          // 40, 50, 60 MHz @ 61.44 Ms/s
+          prach2 = prach[aa] + (4*Ncp); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s
+          if (prach_sequence_length == 0) {
+            if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+              dftlen=49152;
+              dft(DFT_49152,prach2,rxsigF[aa],1);
+            }
+            if (prachFormat == 1 || prachFormat == 2) {
+              dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1);
+              reps++;
+            }
+            if (prachFormat == 2) {
+              dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1);
+              dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1);
+              reps+=2;
+            }
+            if (prachFormat == 3) {
+              dftlen=12288;
+              for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1);
+              reps=4;
+            }
+          } else { // 839 sequence
+            if (prachStartSymbol == 0) prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only)
+
+            dftlen=2048;
+            dft(DFT_2048,prach2,rxsigF[aa],1);
+            if (prachFormat != 9/*C0*/) {
+              dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1);
+              reps++;
+            }
+            if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
+              dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1);
+              dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1);
+              reps+=2;
+            }
+            if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
+              dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1);
+              dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1);
+              reps+=2;
+            }
+            if (prachFormat == 8/*B4*/) {
+              for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1);
+              reps+=6;
+            }
+          }
+          break;
+
+        case 46080:
+          // 40 MHz @ 46.08 Ms/s
+          prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q
+          if (prach_sequence_length == 0) {
+            if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+              dftlen=36864;
+              dft(DFT_36864,prach2,rxsigF[aa],1);
+            }
+            if (prachFormat == 1 || prachFormat == 2) {
+              dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1);
+              reps++;
+            }
+            if (prachFormat == 2) {
+              dft(DFT_36864,prach2+(73728*2),rxsigF[aa]+(73728*2),1);
+              dft(DFT_36864,prach2+(73728*3),rxsigF[aa]+(73728*3),1);
+              reps+=2;
+            }
+            if (prachFormat == 3) {
+              dftlen=9216;
+              for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1);
+              reps=4;
+            }
+          } else { // 839 sequence
+            if (prachStartSymbol == 0) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only)
+
+            dftlen=1536;
+            dft(DFT_1536,prach2,rxsigF[aa],1);
+            if (prachFormat != 9/*C0*/) {
+              dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
+              reps++;
+            }
+            if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
+              dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1);
+              dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1);
+              reps+=2;
+            }
+            if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
+              dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1);
+              dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1);
+              reps+=2;
+            }
+            if (prachFormat == 8/*B4*/) {
+              for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
+              reps+=6;
+            }
+          }
+          break;
+
+        case 122880:
+          // 70, 80, 90, 100 MHz @ 122.88 Ms/s
+          prach2 = prach[aa] + (8*Ncp);
+          if (prach_sequence_length == 0) {
+            if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+              dftlen=98304;
+              dft(DFT_98304,prach2,rxsigF[aa],1);
+            }
+            if (prachFormat == 1 || prachFormat == 2) {
+              dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1);
+              reps++;
+            }
+            if (prachFormat == 2) {
+              dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1);
+              dft(DFT_98304,prach2+(196608*3),rxsigF[aa]+(196608*3),1);
+              reps+=2;
+            }
+            if (prachFormat == 3) {
+              dftlen=24576;
+              for (int i=0;i<4;i++) dft(DFT_24576,prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1);
+              reps=4;
+            }
+          } else { // 839 sequence
+            if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
+
+            dftlen=4096;
+            dft(DFT_4096,prach2,rxsigF[aa],1);
+            if (prachFormat != 9/*C0*/) {
+              dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1);
+              reps++;
+            }
+
+            if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
+              dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1);
+              dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1);
+              reps+=2;
+            }
+            if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
+              dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1);
+              dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1);
+              reps+=2;
+            }
+            if (prachFormat == 8/*B4*/) {
+              for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1);
+              reps+=6;
+            }
+          }
+          break;
+
+        case 92160:
+          // 80, 90 MHz @ 92.16 Ms/s
+          prach2 = prach[aa] + (6*Ncp);
+          if (prach_sequence_length == 0) {
+            if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+              dftlen=73728;
+              dft(DFT_73728,prach2,rxsigF[aa],1);
+            }
+            if (prachFormat == 1 || prachFormat == 2) {
+              dft(DFT_73728,prach2+147456,rxsigF[aa]+147456,1);
+              reps++;
+            }
+            if (prachFormat == 2) {
+              dft(DFT_73728,prach2+(147456*2),rxsigF[aa]+(147456*2),1);
+              dft(DFT_73728,prach2+(147456*3),rxsigF[aa]+(147456*3),1);
+              reps+=2;
+            }
+            if (prachFormat == 3) {
+              dftlen=18432;
+              for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1);
+              reps=4;
+            }
+          } else {
+            if (prachStartSymbol == 0) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
+
+            dftlen=3072;
+            dft(DFT_3072,prach2,rxsigF[aa],1);
+            if (prachFormat != 9/*C0*/) {
+              dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
+              reps++;
+            }
+
+            if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
+              dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1);
+              dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1);
+              reps+=2;
+            }
+            if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
+              dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1);
+              dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1);
+              reps+=2;
+            }
+            if (prachFormat == 8/*B4*/) {
+              for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1);
+              reps+=6;
+            }
+          }
+          break;
+        default:
+          AssertFatal(1==0,"sample_rate %f MHz not support for NR PRACH yet\n", fp->samples_per_subframe / 1000.0);
       }
     }
-    }
     else if (mu==3) {
       if (fp->threequarter_fs) {
 	AssertFatal(1==0,"3/4 sampling not supported for numerology %d\n",mu);
@@ -679,13 +774,13 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
       
       else {
         preamble_shift  -= NCS;
-	
+
         if (preamble_shift < 0)
           preamble_shift+=N_ZC;
       }
     } else { // This is the high-speed case
       new_dft = 0;
-
+      nr_fill_du(N_ZC,prach_root_sequence_map);
       // set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
       // preamble index and find the corresponding cyclic shift
       // Check if all shifts for that root have been processed
@@ -693,7 +788,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
         not_found = 1;
         new_dft   = 1;
         preamble_index0 -= numshift;
-        (preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++);
+        //(preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++);
 
         while (not_found == 1) {
           // current root depending on rootSequenceIndex
@@ -763,38 +858,50 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
 
       memset(prachF, 0, sizeof(int16_t)*2*1024 );
       if (LOG_DUMPFLAG(PRACH)) {      
-	LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1);
-	LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1);
+	       LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1);
+	       LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1);
       }
    
       for (aa=0;aa<nb_rx; aa++) {
 	// Do componentwise product with Xu* on each antenna 
 
-	for (offset=0; offset<(N_ZC<<1); offset+=2) {
-	  prachF[offset]   = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset]   + (int32_t)Xu[offset+1]*rxsigF[aa][offset+1])>>15);
-	  prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15);
-	}
+	       for (offset=0; offset<(N_ZC<<1); offset+=2) {
+	          prachF[offset]   = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset]   + (int32_t)Xu[offset+1]*rxsigF[aa][offset+1])>>15);
+	          prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15);
+	       }
 	
-	// Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
-	if (N_ZC == 839) {
-	  log2_ifft_size = 10;
-	  idft(IDFT_1024,prachF,prach_ifft_tmp,1);
-	  // compute energy and accumulate over receive antennas
-	  for (i=0;i<2048;i++)
-	    prach_ifft[i] += ((int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)])>>10;
-	} else {
-	  idft(IDFT_256,prachF,prach_ifft_tmp,1);
-	  log2_ifft_size = 8;
-	  // compute energy and accumulate over receive antennas and repetitions for BR
-	  for (i=0;i<256;i++)
-	    prach_ifft[i] += ((int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)])>>10;
-	}
-
-	if (LOG_DUMPFLAG(PRACH)) {	
-	  if (aa==0) LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
+	       // Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
+	       if (N_ZC == 839) {
+	         idft(IDFT_1024,prachF,prach_ifft_tmp,1);
+	         // compute energy and accumulate over receive antennas
+	         for (i=0;i<1024;i++)
+	           prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)];
+	       } else {
+	         idft(IDFT_256,prachF,prach_ifft_tmp,1);
+	         log2_ifft_size = 8;
+           // compute energy and accumulate over receive antennas and repetitions for BR
+           for (i=0;i<256;i++)
+             prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)];
+         }
+
+        if (LOG_DUMPFLAG(PRACH)) {
+          if (aa==0) LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
           if (aa==1) LOG_M("prach_rxF_comp1.m","prach_rxF_comp1",prachF,1024,1,1);
-	}
+        }
+
       }// antennas_rx
+
+      // Normalization of energy over ifft and receive antennas
+      if (N_ZC == 839) {
+        log2_ifft_size = 10;
+        for (i=0;i<1024;i++)
+          prach_ifft[i] = (prach_ifft[i]>>log2_ifft_size)/nb_rx;
+      } else {
+        log2_ifft_size = 8;
+        for (i=0;i<256;i++)
+          prach_ifft[i] = (prach_ifft[i]>>log2_ifft_size)/nb_rx;
+      }
+
     } // new dft
     
     // check energy in nth time shift, for 
@@ -805,10 +912,10 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
       lev = (int32_t)prach_ifft[(preamble_shift2+i)];
       levdB = dB_fixed_times10(lev);
       if (levdB>*max_preamble_energy) {
-	LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy);
-	*max_preamble_energy  = levdB;
-	*max_preamble_delay   = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate 
-	*max_preamble         = preamble_index;
+	      LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy);
+	      *max_preamble_energy  = levdB;
+	      *max_preamble_delay   = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate 
+	      *max_preamble         = preamble_index;
       }
     }
   }// preamble_index
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
index be3ba0098928ffab053e0206fa92fbe32a2a272c..02e594e76a3509ab2488f9639434d2c760d71791 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
@@ -73,6 +73,8 @@ void compute_nr_prach_seq(uint8_t short_sequence,
                           uint8_t rootSequenceIndex,
                           uint32_t X_u[64][839]);
 
+void nr_fill_du(uint16_t N_ZC,uint16_t *prach_root_sequence_map);
+
 void init_nr_prach_tables(int N_ZC);
 
 /**@}*/
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index e5e81109e492d005bf0a4709dfa3fcf66d0d5918..54188d22c0a863fa6d99470900b54d6208850876 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -78,19 +78,6 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
                           nfapi_nr_config_request_scf_t *config,
                           NR_DL_FRAME_PARMS *frame_parms);
 
-/*!
-\fn int nr_pbch_scrambling
-\brief PBCH scrambling function
-@param
- */
-void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
-                        uint32_t Nid,
-                        uint8_t nushift,
-                        uint16_t M,
-                        uint16_t length,
-                        uint8_t encoded,
-                        uint32_t unscrambling_mask);
-
 /*!
 \fn int nr_generate_pbch
 \brief Generation of the PBCH
@@ -133,15 +120,13 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
     @param ue Pointer to PHY variables
     @param UE_id id of current UE
     @param frame Frame number
-    @param nr_tti_rx TTI number
-    @param symbol Symbol on which to act (within-in nr_TTI_rx)
+    @param slot Slot number
     @param harq_pid HARQ process ID
 */
 int nr_rx_pusch(PHY_VARS_gNB *gNB,
                 uint8_t UE_id,
                 uint32_t frame,
-                uint8_t nr_tti_rx,
-                unsigned char symbol,
+                uint8_t slot,
                 unsigned char harq_pid);
 
 /** \brief This function performs RB extraction (signal and channel estimates) (currently signal only until channel estimation and compensation are implemented)
@@ -180,6 +165,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
                             int32_t *avg,
                             uint8_t symbol,
                             uint32_t len,
+                            uint8_t  nrOfLayers,
                             unsigned short nb_rb);
 
 /** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation.  In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
@@ -204,6 +190,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
                                 unsigned char symbol,
                                 uint8_t is_dmrs_symbol,
                                 unsigned char mod_order,
+                                uint8_t  nrOfLayers,
                                 unsigned short nb_rb,
                                 unsigned char output_shift);
 
@@ -328,11 +315,11 @@ void init_prach_list(PHY_VARS_gNB *gNB);
 void init_prach_ru_list(RU_t *ru);
 void free_nr_ru_prach_entry(RU_t *ru, int prach_id);
 
-int nr_generate_csi_rs(uint32_t **gold_csi_rs,
-                       int32_t **txdataF,
-                       int16_t amp,
-                       NR_DL_FRAME_PARMS frame_parms,
-                       nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params);
+void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
+                        int16_t amp,
+                        nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params,
+                        uint16_t cell_id,
+                        int slot);
 
 void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
 
@@ -357,6 +344,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 0040f015445ac40edec1723fac14353dfac93abc..53ff90404b430636719235bcd3689e6157cbe27e 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
@@ -41,7 +41,7 @@ int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
   int16_t first_free_index=-1;
 
   AssertFatal(gNB!=NULL,"gNB is null\n");
-  for (i=0; i<NUMBER_OF_NR_ULSCH_MAX; i++) {
+  for (i=0; i<gNB->number_of_nr_ulsch_max; i++) {
     AssertFatal(gNB->ulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i);
     AssertFatal(gNB->ulsch[i][0]!=NULL,"gNB->ulsch[%d][0] is null\n",i);
     LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i][0]->harq_mask,gNB->ulsch[i][0]->rnti,first_free_index);
@@ -62,7 +62,7 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB,
 
  
   int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE);
-  AssertFatal( (ulsch_id>=0) && (ulsch_id<NUMBER_OF_NR_ULSCH_MAX),
+  AssertFatal( (ulsch_id>=0) && (ulsch_id<gNB->number_of_nr_ulsch_max),
               "illegal or no ulsch_id found!!! rnti %04x ulsch_id %d\n",ulsch_pdu->rnti,ulsch_id);
 
   NR_gNB_ULSCH_t  *ulsch = gNB->ulsch[ulsch_id][0];
@@ -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<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,15 +165,35 @@ 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) {
 
-  for (int i=0;i<NUMBER_OF_NR_ULSCH_MAX;i++)
+  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..80c10d74b15a4c7bc82862efe7142d049975320f 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
@@ -89,6 +89,9 @@ 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 dump_nr_I0_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 d990176d79d03847f5d729068cd0a917dbe2eb32..3aad4980bc813e05e3f350cf76a26e517382e963 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -320,7 +320,7 @@ void nr_processULSegment(void* arg) {
   Kr_bytes = Kr>>3;
   K_bits_F = Kr-ulsch_harq->F;
 
-  t_nrLDPC_time_stats procTime;
+  t_nrLDPC_time_stats procTime = {0};
   t_nrLDPC_time_stats* p_procTime     = &procTime ;
 
   //start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
@@ -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 42d6cfad7a3e7ac19c3128fe86317628bc46269c..0531a8b98fdee5e396218f0a277a78a8c3f72499 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -7,11 +7,14 @@
 #include "PHY/NR_REFSIG/ptrs_nr.h"
 #include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
 #include "PHY/defs_nr_common.h"
+#include "common/utils/nr/nr_common.h"
 
 //#define DEBUG_CH_COMP
 //#define DEBUG_RB_EXT
 //#define DEBUG_CH_MAG
 
+#define INVALID_VALUE 255
+
 void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
 {
 
@@ -326,7 +329,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
 #endif
 
   uint8_t is_dmrs_re;
-  start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
+  start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start + pusch_pdu->bwp_start) * NR_NB_SC_PER_RB)%frame_parms->ofdm_symbol_size;
   nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size;
 #ifdef __AVX2__
   int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7);
@@ -345,6 +348,9 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
 
     n = 0;
     k_prime = 0;
+    rxF_ext_index = 0;
+    ul_ch0_ext_index = 0;
+    ul_ch0_index = 0;
 
     if (is_dmrs_symbol == 0) {
       //
@@ -406,7 +412,7 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
 #if defined(__x86_64__)||defined(__i386__)
 
   short rb, ch_amp;
-  unsigned char aatx,aarx;
+  unsigned char aarx;
   __m128i *ul_ch128, ch_amp128;
 
   // Determine scaling amplitude based the symbol
@@ -424,8 +430,7 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
   int off = 0;
 #endif
 
-  for (aatx=0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++) {
-    for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) {
+  for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) {
 
       ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*(off+(nb_rb*NR_NB_SC_PER_RB))];
 
@@ -454,7 +459,6 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
         }
       }
     }
-  }
 #endif
 }
 
@@ -464,6 +468,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
                             int32_t *avg,
                             uint8_t symbol,
                             uint32_t len,
+                            uint8_t nrOfLayers,
                             unsigned short nb_rb)
 {
 
@@ -482,12 +487,12 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
   int off = 0;
 #endif
 
-  for (aatx = 0; aatx < frame_parms->nb_antennas_tx; aatx++)
+  for (aatx = 0; aatx < nrOfLayers; aatx++)
     for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
       //clear average level
       avg128U = _mm_setzero_si128();
 
-      ul_ch128=(__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*(off+(nb_rb*12))];
+      ul_ch128=(__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
 
       for (rb = 0; rb < len/12; rb++) {
         avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x));
@@ -496,10 +501,10 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
         ul_ch128+=3;
       }
 
-      avg[(aatx<<1)+aarx] = (((int32_t*)&avg128U)[0] +
-                             ((int32_t*)&avg128U)[1] +
-                             ((int32_t*)&avg128U)[2] +
-                             ((int32_t*)&avg128U)[3]   ) / y;
+      avg[aatx*frame_parms->nb_antennas_rx+aarx] = (((int32_t*)&avg128U)[0] +
+                                                    ((int32_t*)&avg128U)[1] +
+                                                    ((int32_t*)&avg128U)[2] +
+                                                    ((int32_t*)&avg128U)[3]) / y;
 
     }
 
@@ -515,13 +520,13 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
-  for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++) {
+  for (aatx=0; aatx<nrOfLayers; aatx++) {
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
       //clear average level
       avg128U = vdupq_n_s32(0);
       // 5 is always a symbol with no pilots for both normal and extended prefix
 
-      ul_ch128 = (int16x4_t *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
+      ul_ch128 = (int16x4_t *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*frame_parms->N_RB_UL*12];
 
       for (rb = 0; rb < nb_rb; rb++) {
         //  printf("rb %d : ",rb);
@@ -531,7 +536,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
         avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[2], ul_ch128[2]));
         avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[3], ul_ch128[3]));
 
-        if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_gNB!=1)) {
+        if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(nrOfLayers!=1)) {
           ul_ch128+=4;
         } else {
           avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[4], ul_ch128[4]));
@@ -553,10 +558,10 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
       else
           nre=12;
 
-      avg[(aatx<<1)+aarx] = (((int32_t*)&avg128U)[0] +
-                             ((int32_t*)&avg128U)[1] +
-                             ((int32_t*)&avg128U)[2] +
-                             ((int32_t*)&avg128U)[3]   ) / (nb_rb*nre);
+      avg[aatx*frame_parms->nb_antennas_rx+aarx] = (((int32_t*)&avg128U)[0] +
+                                                    ((int32_t*)&avg128U)[1] +
+                                                    ((int32_t*)&avg128U)[2] +
+                                                    ((int32_t*)&avg128U)[3]) / (nb_rb*nre);
     }
   }
 #endif
@@ -572,6 +577,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
                                    unsigned char symbol,
                                    uint8_t is_dmrs_symbol,
                                    unsigned char mod_order,
+                                   uint8_t  nrOfLayers,
                                    unsigned short nb_rb,
                                    unsigned char output_shift) {
 
@@ -624,10 +630,10 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
   unsigned short rb;
   unsigned char aatx,aarx;
   __m128i *ul_ch128,*ul_ch128_2,*ul_ch_mag128,*ul_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128;
-  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b;
+  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0},QAM_amp128b={0};
   QAM_amp128b = _mm_setzero_si128();
 
-  for (aatx=0; aatx<frame_parms->nb_antennas_tx; aatx++) {
+  for (aatx=0; aatx<nrOfLayers; aatx++) {
 
     if (mod_order == 4) {
       QAM_amp128 = _mm_set1_epi16(QAM16_n1);  // 2/sqrt(10)
@@ -641,11 +647,11 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
 
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
-      ul_ch128          = (__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*(off+(nb_rb*12))];
-      ul_ch_mag128      = (__m128i *)&ul_ch_mag[(aatx<<1)+aarx][symbol*(off+(nb_rb*12))];
-      ul_ch_mag128b     = (__m128i *)&ul_ch_magb[(aatx<<1)+aarx][symbol*(off+(nb_rb*12))];
+      ul_ch128          = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
+      ul_ch_mag128      = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
+      ul_ch_mag128b     = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
       rxdataF128        = (__m128i *)&rxdataF_ext[aarx][symbol*(off+(nb_rb*12))];
-      rxdataF_comp128   = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*(off+(nb_rb*12))];
+      rxdataF_comp128   = (__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
 
 
       for (rb=0; rb<nb_rb; rb++) {
@@ -879,7 +885,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
   if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
-    if (frame_parms->nb_antenna_ports_gNB==1) { // 10 out of 12 so don't reduce size
+    if (nrOfLayers==1) { // 10 out of 12 so don't reduce size
       nb_rb=1+(5*nb_rb/6);
     }
     else {
@@ -887,7 +893,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
     }
   }
 
-  for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++) {
+  for (aatx=0; aatx<nrOfLayers; aatx++) {
     if (mod_order == 4) {
       QAM_amp128  = vmovq_n_s16(QAM16_n1);  // 2/sqrt(10)
       QAM_amp128b = vmovq_n_s16(0);
@@ -898,11 +904,11 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
     //    printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol);
 
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-      ul_ch128          = (int16x4_t*)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
-      ul_ch_mag128      = (int16x8_t*)&ul_ch_mag[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
-      ul_ch_mag128b     = (int16x8_t*)&ul_ch_magb[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
+      ul_ch128          = (int16x4_t*)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*frame_parms->N_RB_UL*12];
+      ul_ch_mag128      = (int16x8_t*)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aarx][symbol*frame_parms->N_RB_UL*12];
+      ul_ch_mag128b     = (int16x8_t*)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aarx][symbol*frame_parms->N_RB_UL*12];
       rxdataF128        = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_UL*12];
-      rxdataF_comp128   = (int16x4x2_t*)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
+      rxdataF_comp128   = (int16x4x2_t*)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx+aarx][symbol*frame_parms->N_RB_UL*12];
 
       for (rb=0; rb<nb_rb; rb++) {
   if (mod_order>2) {
@@ -1154,214 +1160,218 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
 int nr_rx_pusch(PHY_VARS_gNB *gNB,
                 uint8_t ulsch_id,
                 uint32_t frame,
-                uint8_t nr_tti_rx,
-                unsigned char symbol,
+                uint8_t slot,
                 unsigned char harq_pid)
 {
 
-  uint8_t aarx, aatx, dmrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
+  uint8_t aarx, aatx;
   uint32_t nb_re_pusch, bwp_start_subcarrier;
   int avgs;
-  int avg[4];
+
   NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
   nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu;
+  int avg[frame_parms->nb_antennas_rx*rel15_ul->nrOfLayers];
 
-  dmrs_symbol_flag = 0;
-
-  if(symbol == rel15_ul->start_symbol_index){
-    gNB->pusch_vars[ulsch_id]->dmrs_symbol = 0;
-    gNB->pusch_vars[ulsch_id]->cl_done = 0;
-  }
-
-
-  bwp_start_subcarrier = (rel15_ul->rb_start*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
+  gNB->pusch_vars[ulsch_id]->dmrs_symbol = INVALID_VALUE;
+  gNB->pusch_vars[ulsch_id]->cl_done = 0;
 
-  dmrs_symbol_flag = ((rel15_ul->ul_dmrs_symb_pos)>>symbol)&0x01;
-
-  LOG_D(PHY,"symbol %d bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n",symbol,bwp_start_subcarrier,rel15_ul->rb_start,frame_parms->first_carrier_offset);
+  bwp_start_subcarrier = ((rel15_ul->rb_start + rel15_ul->bwp_start)*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
+  LOG_D(PHY,"bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n", bwp_start_subcarrier, rel15_ul->rb_start, frame_parms->first_carrier_offset);
   LOG_D(PHY,"ul_dmrs_symb_pos %x\n",rel15_ul->ul_dmrs_symb_pos);
 
-  if (dmrs_symbol_flag == 1){
-    if (((rel15_ul->ul_dmrs_symb_pos)>>((symbol+1)%frame_parms->symbols_per_slot))&0x01)
-      AssertFatal(1==0,"Double DMRS configuration is not yet supported\n");
-
-    if (rel15_ul->dmrs_config_type == 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
-      nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*6));
-    }
-    else {
-      nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*4));
-    }
-    LOG_D(PHY,"dmrs_symbol: nb_re_pusch %d\n",nb_re_pusch);
-    gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol;
-
-  } else {
-    nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
-  }
-
   //----------------------------------------------------------
   //--------------------- Channel estimation ---------------------
   //----------------------------------------------------------
   start_meas(&gNB->ulsch_channel_estimation_stats);
-  if (dmrs_symbol_flag == 1) {
-    nr_pusch_channel_estimation(gNB,
-                                nr_tti_rx,
-                                0, // p
-                                symbol,
-                                ulsch_id,
-                                bwp_start_subcarrier,
-                                rel15_ul);
-
-    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);
+  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);
+    if (dmrs_symbol_flag == 1) {
+      if (gNB->pusch_vars[ulsch_id]->dmrs_symbol == INVALID_VALUE)
+        gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol;
+
+      for (int nl=0; nl<rel15_ul->nrOfLayers; nl++)
+        nr_pusch_channel_estimation(gNB,
+                                    slot,
+                                    get_dmrs_port(nl,rel15_ul->dmrs_ports),
+                                    symbol,
+                                    ulsch_id,
+                                    bwp_start_subcarrier,
+                                    rel15_ul);
+
+      nr_gnb_measurements(gNB, ulsch_id, harq_pid, symbol,rel15_ul->nrOfLayers);
+
+      for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
+        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;
+        }
+      }
     }
-
   }
   stop_meas(&gNB->ulsch_channel_estimation_stats);
-  //----------------------------------------------------------
-  //--------------------- RBs extraction ---------------------
-  //----------------------------------------------------------
 
-  gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] = nb_re_pusch;
+#ifdef __AVX2__
+  int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
+#else
+  int off = 0;
+#endif
+  uint32_t rxdataF_ext_offset = 0;
 
-  if (nb_re_pusch > 0) {
+  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;
+    if (dmrs_symbol_flag == 1) {
+      if ((rel15_ul->ul_dmrs_symb_pos >> ((symbol + 1) % frame_parms->symbols_per_slot)) & 0x01)
+        AssertFatal(1==0,"Double DMRS configuration is not yet supported\n");
 
-    start_meas(&gNB->ulsch_rbs_extraction_stats);
-    nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
-                                gNB->pusch_vars[ulsch_id],
-                                symbol,
-                                dmrs_symbol_flag,
-                                rel15_ul,
-                                frame_parms);
-    stop_meas(&gNB->ulsch_rbs_extraction_stats);
+      gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol;
 
-    //----------------------------------------------------------
-    //--------------------- Channel Scaling --------------------
-    //----------------------------------------------------------
+      if (rel15_ul->dmrs_config_type == 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
+        nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*6));
+      }
+      else {
+        nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*4));
+      }
+    } else {
+      nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
+    }
 
-    nr_ulsch_scale_channel(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
-                           frame_parms,
-                           gNB->ulsch[ulsch_id],
-                           symbol,
-                           dmrs_symbol_flag,
-                           rel15_ul->rb_size,
-                           rel15_ul->dmrs_config_type);
+    gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] = nb_re_pusch;
+    LOG_D(PHY,"symbol %d: nb_re_pusch %d, DMRS symbl used for Chest :%d \n", symbol, nb_re_pusch, gNB->pusch_vars[ulsch_id]->dmrs_symbol);
 
+    //----------------------------------------------------------
+    //--------------------- RBs extraction ---------------------
+    //----------------------------------------------------------
+    if (nb_re_pusch > 0) {
 
-    if (gNB->pusch_vars[ulsch_id]->cl_done==0) {
+      start_meas(&gNB->ulsch_rbs_extraction_stats);
+      nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
+                                  gNB->pusch_vars[ulsch_id],
+                                  symbol,
+                                  dmrs_symbol_flag,
+                                  rel15_ul,
+                                  frame_parms);
+      stop_meas(&gNB->ulsch_rbs_extraction_stats);
+
+      //----------------------------------------------------------
+      //--------------------- Channel Scaling --------------------
+      //----------------------------------------------------------
+      nr_ulsch_scale_channel(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
+                            frame_parms,
+                            gNB->ulsch[ulsch_id],
+                            symbol,
+                            dmrs_symbol_flag,
+                            rel15_ul->rb_size,
+                            rel15_ul->dmrs_config_type);
+
+      if (gNB->pusch_vars[ulsch_id]->cl_done==0) {
+        nr_ulsch_channel_level(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
+                              frame_parms,
+                              avg,
+                              symbol,
+                              nb_re_pusch,
+                              rel15_ul->nrOfLayers,
+                              rel15_ul->rb_size);
+
+        avgs = 0;
+
+        for (aatx=0;aatx<rel15_ul->nrOfLayers;aatx++)
+          for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
+            avgs = cmax(avgs,avg[aatx*frame_parms->nb_antennas_rx+aarx]);
+
+        gNB->pusch_vars[ulsch_id]->log2_maxh = (log2_approx(avgs)/2)+3;
+        gNB->pusch_vars[ulsch_id]->cl_done = 1;
+      }
 
-      nr_ulsch_channel_level(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
-                             frame_parms,
-                             avg,
+      //----------------------------------------------------------
+      //--------------------- Channel Compensation ---------------
+      //----------------------------------------------------------
+      start_meas(&gNB->ulsch_channel_compensation_stats);
+      nr_ulsch_channel_compensation(gNB->pusch_vars[ulsch_id]->rxdataF_ext,
+                                    gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
+                                    gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
+                                    gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
+                                    gNB->pusch_vars[ulsch_id]->rxdataF_comp,
+                                    (rel15_ul->nrOfLayers>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL,
+                                    frame_parms,
+                                    symbol,
+                                    dmrs_symbol_flag,
+                                    rel15_ul->qam_mod_order,
+                                    rel15_ul->nrOfLayers,
+                                    rel15_ul->rb_size,
+                                    gNB->pusch_vars[ulsch_id]->log2_maxh);
+      stop_meas(&gNB->ulsch_channel_compensation_stats);
+
+      start_meas(&gNB->ulsch_mrc_stats);
+      nr_ulsch_detection_mrc(frame_parms,
+                             gNB->pusch_vars[ulsch_id]->rxdataF_comp,
+                             gNB->pusch_vars[ulsch_id]->ul_ch_mag,
+                             gNB->pusch_vars[ulsch_id]->ul_ch_magb,
                              symbol,
-                             nb_re_pusch,
                              rel15_ul->rb_size);
+      stop_meas(&gNB->ulsch_mrc_stats);
 
-      avgs = 0;
-
-      for (aatx=0;aatx<frame_parms->nb_antennas_tx;aatx++)
-        for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
-          avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
+      // transform precoding = 0 means enabled
+      if (rel15_ul->transform_precoding == 0) {
 
-      gNB->pusch_vars[ulsch_id]->log2_maxh = (log2_approx(avgs)/2)+3;
-      gNB->pusch_vars[ulsch_id]->cl_done = 1;
-    }
-
-    //----------------------------------------------------------
-    //--------------------- Channel Compensation ---------------
-    //----------------------------------------------------------
-
-    start_meas(&gNB->ulsch_channel_compensation_stats);
-    nr_ulsch_channel_compensation(gNB->pusch_vars[ulsch_id]->rxdataF_ext,
-                                  gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
-                                  gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
-                                  gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
-                                  gNB->pusch_vars[ulsch_id]->rxdataF_comp,
-                                  (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL,
-                                  frame_parms,
-                                  symbol,
-                                  dmrs_symbol_flag,
-                                  rel15_ul->qam_mod_order,
-                                  rel15_ul->rb_size,
-                                  gNB->pusch_vars[ulsch_id]->log2_maxh);
-    stop_meas(&gNB->ulsch_channel_compensation_stats);
-
-    start_meas(&gNB->ulsch_mrc_stats);
-    nr_ulsch_detection_mrc(frame_parms,
-			   gNB->pusch_vars[ulsch_id]->rxdataF_comp,
-			   gNB->pusch_vars[ulsch_id]->ul_ch_mag,
-			   gNB->pusch_vars[ulsch_id]->ul_ch_magb,
-			   symbol,
-			   rel15_ul->rb_size);
-    stop_meas(&gNB->ulsch_mrc_stats);
-
-
-    if (rel15_ul->transform_precoding == transform_precoder_enabled) { 
-      
       #ifdef __AVX2__
         // For odd number of resource blocks need byte alignment to multiple of 8
         int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7);
       #else
         int nb_re_pusch2 = nb_re_pusch;
-      #endif      
-      
-      // perform IDFT operation on the compensated rxdata if transform precoding is enabled
-      nr_idft(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * nb_re_pusch2], nb_re_pusch);
-      LOG_D(PHY,"Transform precoding being done on data- symbol: %d, nb_re_pusch: %d\n", symbol, nb_re_pusch);      
-    }
+      #endif
 
+        // perform IDFT operation on the compensated rxdata if transform precoding is enabled
+        nr_idft(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * nb_re_pusch2], nb_re_pusch);
+        LOG_D(PHY,"Transform precoding being done on data- symbol: %d, nb_re_pusch: %d\n", symbol, nb_re_pusch);
+      }
 
-    //----------------------------------------------------------
-    //--------------------- PTRS Processing --------------------
-    //----------------------------------------------------------
-
-    /* In case PTRS is enabled then LLR will be calculated after PTRS symbols are processed *
-     * otherwise LLR are calculated for each symbol based upon DMRS channel estimates only. */
-    if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS)
-    {
-      start_meas(&gNB->ulsch_ptrs_processing_stats);
-      nr_pusch_ptrs_processing(gNB,
-                               frame_parms,
-                               rel15_ul,
-                               ulsch_id,
-                               nr_tti_rx,
-                               symbol,
-                               nb_re_pusch);
-      stop_meas(&gNB->ulsch_ptrs_processing_stats);
-
-      /*  Subtract total PTRS RE's in the symbol from PUSCH RE's */
-      gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] -= gNB->pusch_vars[ulsch_id]->ptrs_re_per_slot;
-    }
-  }
+      //----------------------------------------------------------
+      //--------------------- PTRS Processing --------------------
+      //----------------------------------------------------------
+      /* In case PTRS is enabled then LLR will be calculated after PTRS symbols are processed *
+      * otherwise LLR are calculated for each symbol based upon DMRS channel estimates only. */
+      if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
+        start_meas(&gNB->ulsch_ptrs_processing_stats);
+        nr_pusch_ptrs_processing(gNB,
+                                 frame_parms,
+                                 rel15_ul,
+                                 ulsch_id,
+                                 slot,
+                                 symbol,
+                                 nb_re_pusch);
+        stop_meas(&gNB->ulsch_ptrs_processing_stats);
+
+        /*  Subtract total PTRS RE's in the symbol from PUSCH RE's */
+        gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] -= gNB->pusch_vars[ulsch_id]->ptrs_re_per_slot;
+      }
 
-  /*---------------------------------------------------------------------------------------------------- */
-  /*--------------------  LLRs computation  -------------------------------------------------------------*/
-  /*-----------------------------------------------------------------------------------------------------*/
-  if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1)) {
-  
-#ifdef __AVX2__
-    int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
-#else
-    int off = 0;
-#endif
-    uint32_t rxdataF_ext_offset = 0;
-    for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++) {
+      /*---------------------------------------------------------------------------------------------------- */
+      /*--------------------  LLRs computation  -------------------------------------------------------------*/
+      /*-----------------------------------------------------------------------------------------------------*/
       start_meas(&gNB->ulsch_llr_stats);
-      nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][i * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)],
-                          gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
-                          gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
-                          &gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order],
-                          rel15_ul->rb_size,
-                          gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i],
-                          i,
-                          rel15_ul->qam_mod_order);
+      nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)],
+                           gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
+                           gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
+                           &gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order],
+                           rel15_ul->rb_size,
+                           gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol],
+                           symbol,
+                           rel15_ul->qam_mod_order);
       stop_meas(&gNB->ulsch_llr_stats);
-      rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i];
-    }// symbol loop
-  }// last symbol check
-  
-  return (0);
+      rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol];
+    }
+  } // symbol loop
+
+  return 0;
 }
diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
index 2d1fdff4be6d0c0803ae1ab9d75cdb4b7500e704..1524c840c3458dc3a077123feb2f5b45af7c2668 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,193 +232,154 @@ 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;
-
-    for (n=0; n<12; n++){
+  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;
 
-      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[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]];
 
-  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];
+
   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;
   // first bit of bitmap for sr presence and second bit for acknack presence
   uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
   uci_pdu->pucch_format = 0; // format 0
   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;
     }
@@ -410,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));
@@ -428,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;
@@ -1396,7 +1375,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
       rp2_im[aa] = (__m256i*)r_im_ext2[aa];
     }
     __m256i prod_re[Prx2],prod_im[Prx2];
-    int64_t corr=0;
+    uint64_t corr=0;
     int cw_ML=0;
     
     
@@ -1410,7 +1389,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
       }
       printf("\n");
 #endif
-      int64_t corr_tmp = 0;
+      uint64_t corr_tmp = 0;
 
       for (int group=0;group<ngroup;group++) {
 	// do complex correlation
@@ -1442,8 +1421,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
 	  prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
 	}
 	int64_t corr_re=0,corr_im=0;
-	
-	
+
+
 	for (int aa=0;aa<Prx;aa++) {
 	  LOG_D(PHY,"pucch2 cw %d group %d aa %d: (%d,%d)+(%d,%d) = (%d,%d)\n",cw,group,aa,
 		corr32_re[group][aa],corr32_im[group][aa],
@@ -1520,11 +1499,11 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
 	  if (cw==0) corr += ((int64_t)corr32_re[half_prb>>2][aa]*corr32_re[half_prb>>2][aa])+
 		       ((int64_t)corr32_im[half_prb>>2][aa]*corr32_im[half_prb>>2][aa]);
 
-	
+
 	  corr_re = ( corr32_re[half_prb>>2][aa]/(2*nc_group_size*4/2)+((int16_t*)(&prod_re[aa]))[0]);
 	  corr_im = ( corr32_im[half_prb>>2][aa]/(2*nc_group_size*4/2)+((int16_t*)(&prod_im[aa]))[0]);
 	  corr_tmp += corr_re*corr_re + corr_im*corr_im;
-          /*
+
           LOG_D(PHY,"pucch2 half_prb %d cw %d (%d,%d) aa %d: (%d,%d,%d,%d,%d,%d,%d,%d)x(%d,%d,%d,%d,%d,%d,%d,%d)  (%d,%d)+(%d,%d) = (%d,%d) => %d\n",
                 half_prb,cw,cw&15,cw>>4,aa,
                 ((int16_t*)&pucch2_polar_4bit[cw&15])[0],((int16_t*)&pucch2_polar_4bit[cw>>4])[0],
@@ -1541,15 +1520,15 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
                 corr_re,
                 corr_im,
                 corr_tmp);
-          */
+
 	}
 	corr16 = _mm_set1_epi16((int16_t)(corr_tmp>>8));
-	/*	
+
 	LOG_D(PHY,"half_prb %d cw %d corr16 %d\n",half_prb,cw,corr_tmp>>8);
-	*/
+
 	llr_num = _mm_max_epi16(_mm_mullo_epi16(corr16,pucch2_polar_llr_num_lut[cw]),llr_num);
 	llr_den = _mm_max_epi16(_mm_mullo_epi16(corr16,pucch2_polar_llr_den_lut[cw]),llr_den);
-	/*
+
 	LOG_D(PHY,"lut_num (%d,%d,%d,%d,%d,%d,%d,%d)\n",
 	      ((int16_t*)&pucch2_polar_llr_num_lut[cw])[0],
 	      ((int16_t*)&pucch2_polar_llr_num_lut[cw])[1],
@@ -1559,7 +1538,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
 	      ((int16_t*)&pucch2_polar_llr_num_lut[cw])[5],
 	      ((int16_t*)&pucch2_polar_llr_num_lut[cw])[6],
 	      ((int16_t*)&pucch2_polar_llr_num_lut[cw])[7]);
-	
+
 	LOG_D(PHY,"llr_num (%d,%d,%d,%d,%d,%d,%d,%d)\n",
 	      ((int16_t*)&llr_num)[0],
 	      ((int16_t*)&llr_num)[1],
@@ -1578,7 +1557,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
 	      ((int16_t*)&llr_den)[5],
 	      ((int16_t*)&llr_den)[6],
 	      ((int16_t*)&llr_den)[7]);
-	*/	
+
       }
       // compute llrs
       llrs[half_prb] = _mm_subs_epi16(llr_num,llr_den);
@@ -1604,7 +1583,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
   re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset;
   // estimate CQI for MAC (from antenna port 0 only)
   int SNRtimes10 = dB_fixed_times10(signal_energy_nodc(&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset],12*pucch_pdu->prb_size)) - (10*gNB->measurements.n0_power_tot_dB);
-  int cqi;
+  int cqi,bit_left;
   if (SNRtimes10 < -640) cqi=0;
   else if (SNRtimes10 >  635) cqi=255;
   else cqi=(640+SNRtimes10)/5;
@@ -1620,7 +1599,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
   if (pucch_pdu->bit_len_harq>0) {
     int harq_bytes=pucch_pdu->bit_len_harq>>3;
     if ((pucch_pdu->bit_len_harq&7) > 0) harq_bytes++;
-    uci_pdu->pduBitmap|=1;
+    uci_pdu->pduBitmap|=2;
     uci_pdu->harq.harq_payload = (uint8_t*)malloc(harq_bytes);
     uci_pdu->harq.harq_crc = decoderState;
     int i=0;
@@ -1628,12 +1607,13 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
       uci_pdu->harq.harq_payload[i] = decodedPayload[0] & 255;
       decodedPayload[0]>>=8;
     }
-    uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_harq&7))-1);
+    bit_left = pucch_pdu->bit_len_harq-((harq_bytes-1)<<3);
+    uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<<bit_left)-1);
     decodedPayload[0] >>= pucch_pdu->bit_len_harq;
   }
   
   if (pucch_pdu->sr_flag == 1) {
-    uci_pdu->pduBitmap|=2;
+    uci_pdu->pduBitmap|=1;
     uci_pdu->sr.sr_bit_len = 1;
     uci_pdu->sr.sr_payload = malloc(1);
     uci_pdu->sr.sr_payload[0] = decodedPayload[0]&1;
@@ -1642,6 +1622,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
   // csi
   if (pucch_pdu->bit_len_csi_part1>0) {
     uci_pdu->pduBitmap|=4;
+    uci_pdu->csi_part1.csi_part1_bit_len=pucch_pdu->bit_len_csi_part1;
     int csi_part1_bytes=pucch_pdu->bit_len_csi_part1>>3;
     if ((pucch_pdu->bit_len_csi_part1&7) > 0) csi_part1_bytes++;
     uci_pdu->csi_part1.csi_part1_payload = (uint8_t*)malloc(csi_part1_bytes);
@@ -1651,7 +1632,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
       uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & 255;
       decodedPayload[0]>>=8;
     }
-    uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_csi_part1&7))-1);
+    bit_left = pucch_pdu->bit_len_csi_part1-((csi_part1_bytes-1)<<3);
+    uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<<bit_left)-1);
     decodedPayload[0] >>= pucch_pdu->bit_len_csi_part1;
   }
   
@@ -1659,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_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
index 6cb0a612e9d6dd229f541aa251c085d1a8181d72..e4a82e7021fe1603df0d447d92979aad79f56163 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -36,7 +36,7 @@
 
 int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
                              UE_nr_rxtx_proc_t *proc,
-                             uint8_t eNB_offset,
+                             uint8_t gNB_id,
                              unsigned char Ns,
                              unsigned char symbol,
                              int dmrss,
@@ -70,16 +70,16 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
   k = nushift;
 
 #ifdef DEBUG_CH
-  printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("PBCH DMRS Correlation : ThreadId %d, gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,Ns,k, symbol);
 #endif
 
   // generate pilot
   nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
 
-  int re_offset = ssb_offset;
   for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
 
+    int re_offset = ssb_offset;
     pil   = (int16_t *)&pilot[0];
     rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
 
@@ -198,7 +198,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
 
 int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
                                UE_nr_rxtx_proc_t *proc,
-                               uint8_t eNB_offset,
+                               uint8_t gNB_id,
                                unsigned char Ns,
                                unsigned char symbol,
                                int dmrss,
@@ -213,10 +213,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
   int ch_offset,symbol_offset;
   //int slot_pbch;
 
-  //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
-
   uint8_t nushift;
-  int **dl_ch_estimates  =ue->pbch_vars[eNB_offset]->dl_ch_estimates;
+  int **dl_ch_estimates  =ue->pbch_vars[gNB_id]->dl_ch_estimates;
   int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
 
   nushift =  ue->frame_parms.Nid_cell%4;
@@ -224,10 +222,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
   unsigned int  ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
   if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
 
-  if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
-    ch_offset     = ue->frame_parms.ofdm_symbol_size ;
-  else
-    ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;
+  ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;
 
   AssertFatal(dmrss >= 0 && dmrss < 3,
 	      "symbol %d is illegal for PBCH DM-RS \n",
@@ -239,7 +234,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
   k = nushift;
 
 #ifdef DEBUG_CH
-  printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("PBCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,Ns,k, symbol);
 #endif
 
@@ -277,18 +272,15 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
   // generate pilot
   nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
 
-  int re_offset = ssb_offset;
   for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
 
+    int re_offset = ssb_offset;
     pil   = (int16_t *)&pilot[0];
     rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
     dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
 
     memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
-    if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
-      multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
-                                         ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
-                                         1,ue->frame_parms.ofdm_symbol_size);
+
 #ifdef DEBUG_CH
     printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
     printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
@@ -456,12 +448,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
       // do ifft of channel estimate
       for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
         for (p=0; p<ue->frame_parms.nb_antenna_ports_gNB; p++) {
-          if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx])
+          if (ue->pbch_vars[gNB_id]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx])
           {
             LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, proc->thread_id, symbol, ch_offset);
             idft(idftsizeidx,
-                 (int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset],
-                 (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1);
+                 (int16_t*) &ue->pbch_vars[gNB_id]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx][ch_offset],
+                 (int16_t*) ue->pbch_vars[gNB_id]->dl_ch_estimates_time[(p*ue->frame_parms.nb_antennas_rx)+aarx],1);
           }
         }
     }
@@ -474,7 +466,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t eNB_offset,
+                                uint8_t gNB_id,
                                 unsigned char Ns,
                                 unsigned char symbol,
                                 unsigned short coreset_start_subcarrier,
@@ -487,23 +479,16 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
   int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
   int ch_offset,symbol_offset;
 
-  //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
-
-  int **dl_ch_estimates  =ue->pdcch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates;
+  int **dl_ch_estimates  =ue->pdcch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
   int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
 
-
-  if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
-    ch_offset     = ue->frame_parms.ofdm_symbol_size ;
-  else
-    ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;
+  ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;
 
   symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
 
-  k = coreset_start_subcarrier;
 
 #ifdef DEBUG_PDCCH
-  printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("PDCCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,Ns,k, symbol);
 #endif
 
@@ -512,22 +497,27 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
   fr = filt16a_r1;
 
 
+  // checking if re-initialization of scrambling IDs is needed (should be done here but scrambling ID for PDCCH is not taken from RRC)
+/*  if (( != ue->scramblingID_pdcch){
+    ue->scramblingID_pdcch=;
+    nr_gold_pdsch(ue,ue->scramblingID_pdcch);
+  }*/
+
+
   // generate pilot
   int pilot[nb_rb_coreset * 3] __attribute__((aligned(16))); 
-  nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset);
+  nr_pdcch_dmrs_rx(ue,gNB_id,Ns,ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0],2000,nb_rb_coreset);
 
 
   for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
 
+    k = coreset_start_subcarrier;
     pil   = (int16_t *)&pilot[0];
     rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
     dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
 
     memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
-    if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
-      multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
-                                         ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
-                                         1,ue->frame_parms.ofdm_symbol_size);
+
 #ifdef DEBUG_PDCCH
     printf("pdcch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
     printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
@@ -649,7 +639,8 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t eNB_offset,
+                                uint8_t gNB_id,
+                                bool is_SI,
                                 unsigned char Ns,
                                 unsigned short p,
                                 unsigned char symbol,
@@ -665,16 +656,15 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh, *frl, *frr;
   int ch_offset,symbol_offset;
 
-  //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
+  NR_UE_DLSCH_t  **dlsch = ue->dlsch[proc->thread_id][gNB_id];
+  const unsigned char harq_pid = dlsch[0]->current_harq_pid;
+  NR_DL_UE_HARQ_t *dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
 
   uint8_t nushift;
-  int **dl_ch_estimates  =ue->pdsch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates;
+  int **dl_ch_estimates  =ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
   int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
 
-  if (ue->high_speed_flag == 0)
-    ch_offset     = ue->frame_parms.ofdm_symbol_size ;
-  else
-    ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;
+  ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;
 
   symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
 
@@ -682,19 +672,30 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   int re_offset = k;
 
 #ifdef DEBUG_CH
-  printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("PDSCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,Ns,k, symbol);
 #endif
 
   // generate pilot for gNB port number 1000+p
-  uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12 - BWPStart;
-  uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
+  uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12;
+  if (is_SI) {
+    rb_offset -= BWPStart;
+  }
+  uint8_t config_type = dlsch0_harq->dmrsConfigType;
   int8_t delta = get_delta(p, config_type);
-  nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol][0], &pilot[0],1000,0,nb_rb_pdsch+rb_offset);
 
-  if (config_type == pdsch_dmrs_type1){
+  // checking if re-initialization of scrambling IDs is needed
+  /*if ((XXX.scramblingID0 != ue->scramblingID[0]) || (XXX.scramblingID1 != ue->scramblingID[1])){
+    ue->scramblingID[0] = XXX.scramblingID0;
+    ue->scramblingID[1] = XXX.scramblingID1;
+    nr_gold_pdsch(ue,ue->scramblingID);
+  }*/
+
+  nr_pdsch_dmrs_rx(ue, Ns, ue->nr_gold_pdsch[gNB_id][Ns][symbol][0], &pilot[0], 1000+p, 0, nb_rb_pdsch+rb_offset, config_type);
+
+  if (config_type == NFAPI_NR_DMRS_TYPE1){
     nushift = (p>>1)&1;
-    ue->frame_parms.nushift = nushift;
+    if (p<4) ue->frame_parms.nushift = nushift;
     switch (delta) {
 
       case 0://port 0,1
@@ -732,9 +733,9 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
         return -1;
         break;
     }
-  } else {//pdsch_dmrs_type2
+  } else {//NFAPI_NR_DMRS_TYPE2
     nushift = delta;
-    ue->frame_parms.nushift = nushift;
+    if (p<6) ue->frame_parms.nushift = nushift;
     switch (delta) {
       case 0://port 0,1
         fl = filt8_l2;//left interpolation Filter should be fml
@@ -774,17 +775,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   }
 
   for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
-    pil   = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)];
+    pil   = (int16_t *)&pilot[rb_offset*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4)];
     k     = k % ue->frame_parms.ofdm_symbol_size;
     re_offset = k;
     rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+re_offset+nushift)];
     dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset];
 
     memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
-    if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
-      multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
-                                         ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
-                                         1,ue->frame_parms.ofdm_symbol_size);
+
 #ifdef DEBUG_PDSCH
     printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
     printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
@@ -792,7 +790,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
     printf("dl_ch addr %p nushift %d\n",dl_ch,nushift);
 #endif
 
-    if (config_type == pdsch_dmrs_type1) {
+    if (config_type == NFAPI_NR_DMRS_TYPE1) {
 
       // Treat first 2 pilots specially (left edge)
       ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
@@ -925,11 +923,11 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
     
     // check if PRB crosses DC and improve estimates around DC
     if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) {
-      dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
+      dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset];
       uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier);
       uint16_t idxPil = idxDC/2;
       re_offset = k;
-      pil = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)];
+      pil = (int16_t *)&pilot[rb_offset*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4)];
       pil += (idxPil-2);
       dl_ch += (idxDC-4);
       dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10);
@@ -975,7 +973,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                            8);
       }
     }
-    } else { //pdsch_dmrs_type2  |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0|
+    } else { //NFAPI_NR_DMRS_TYPE2  |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0|
 
       // Treat first 4 pilots specially (left edge)
       ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
@@ -1205,16 +1203,15 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
  *
  * NAME :         nr_pdsch_ptrs_processing
  *
- * PARAMETERS :   ue                : ue data structure
+ * PARAMETERS :   PHY_VARS_NR_UE    : ue data structure
  *                NR_UE_PDSCH       : pdsch_vars pointer
  *                NR_DL_FRAME_PARMS : frame_parms pointer
  *                NR_DL_UE_HARQ_t   : dlsch0_harq pointer
  *                NR_DL_UE_HARQ_t   : dlsch1_harq pointer
- *                uint8_t           : eNB_id,
+ *                uint8_t           : gNB_id,
  *                uint8_t           : nr_slot_rx,
  *                unsigned char     : symbol,
  *                uint32_t          : nb_re_pdsch,
- *                unsigned char     : harq_pid
  *                uint16_t          : rnti
  *                RX_type_t         : rx_type
  * RETURN : Nothing
@@ -1230,11 +1227,10 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
                               NR_DL_FRAME_PARMS *frame_parms,
                               NR_DL_UE_HARQ_t *dlsch0_harq,
                               NR_DL_UE_HARQ_t *dlsch1_harq,
-                              uint8_t eNB_id,
+                              uint8_t gNB_id,
                               uint8_t nr_slot_rx,
                               unsigned char symbol,
                               uint32_t nb_re_pdsch,
-                              unsigned char harq_pid,
                               uint16_t rnti,
                               RX_type_t rx_type)
 {
@@ -1265,7 +1261,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
     ptrsSymbPos     = &dlsch0_harq->ptrs_symbols;
     ptrsSymbIdx     = &dlsch0_harq->ptrs_symbol_index;
     ptrsReOffset    = &dlsch0_harq->PTRSReOffset;
-    dmrsConfigType  = &dlsch0_harq->ptrs_symbol_index;
+    dmrsConfigType  = &dlsch0_harq->dmrsConfigType;
     nb_rb           = &dlsch0_harq->nb_rb;
   }
   if(dlsch1_harq) {
@@ -1278,13 +1274,13 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
     ptrsSymbPos     = &dlsch1_harq->ptrs_symbols;
     ptrsSymbIdx     = &dlsch1_harq->ptrs_symbol_index;
     ptrsReOffset    = &dlsch1_harq->PTRSReOffset;
-    dmrsConfigType  = &dlsch1_harq->ptrs_symbol_index;
+    dmrsConfigType  = &dlsch1_harq->dmrsConfigType;
     nb_rb           = &dlsch1_harq->nb_rb;
   }
   /* loop over antennas */
   for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-    phase_per_symbol = (int16_t*)pdsch_vars[eNB_id]->ptrs_phase_per_slot[aarx];
-    ptrs_re_symbol = (int32_t*)pdsch_vars[eNB_id]->ptrs_re_per_slot[aarx];
+    phase_per_symbol = (int16_t*)pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx];
+    ptrs_re_symbol = (int32_t*)pdsch_vars[gNB_id]->ptrs_re_per_slot[aarx];
     ptrs_re_symbol[symbol] = 0;
     phase_per_symbol[(2*symbol)+1] = 0; // Imag
     /* set DMRS estimates to 0 angle with magnitude 1 */
@@ -1318,11 +1314,11 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
         /*------------------------------------------------------------------------------------------------------- */
         nr_ptrs_cpe_estimation(*K_ptrs,*ptrsReOffset,*dmrsConfigType,*nb_rb,
                                rnti,
-                               (int16_t *)&pdsch_vars[eNB_id]->dl_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pdsch],
+                               (int16_t *)&pdsch_vars[gNB_id]->dl_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pdsch],
                                nr_slot_rx,
                                symbol,frame_parms->ofdm_symbol_size,
-                               (int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)],
-                               ue->nr_gold_pdsch[eNB_id][nr_slot_rx][symbol][0],
+                               (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)],
+                               ue->nr_gold_pdsch[gNB_id][nr_slot_rx][symbol][0],
                                &phase_per_symbol[2* symbol],
                                &ptrs_re_symbol[symbol]);
       }
@@ -1341,9 +1337,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
         }
       }
 #ifdef DEBUG_DL_PTRS
-      LOG_M("ptrsEst.m","est",pdsch_vars[eNB_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
+      LOG_M("ptrsEst.m","est",pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
       LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp",
-            &pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ],
+            &pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ],
             (*nb_rb) * NR_NB_SC_PER_RB * (*nbSymb),1,1);
 #endif
       /*------------------------------------------------------------------------------------------------------- */
@@ -1356,9 +1352,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
 #ifdef DEBUG_DL_PTRS
           printf("[PHY][DL][PTRS]: Rotate Symbol %2d with  %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]);
 #endif
-          rotate_cpx_vector((int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
+          rotate_cpx_vector((int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
                             &phase_per_symbol[2* i],
-                            (int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
+                            (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
                             ((*nb_rb) * NR_NB_SC_PER_RB), 15);
         }// if not DMRS Symbol
       }// symbol loop
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index 6c461ef4480cce2089ea49724437715211201f18..c5330ce2f2e7e2a98f3d77591046f4ea8bb6cc84 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -34,17 +34,14 @@
 
 /*!
 \brief This function performs channel estimation including frequency and temporal interpolation
-\param phy_vars_ue Pointer to UE PHY variables
-\param eNB_id Index of target eNB
-\param eNB_offset Offset for interfering eNB (in terms cell ID mod 3)
+\param ue Pointer to UE PHY variables
+\param gNB_id Index of target gNB
 \param Ns slot number (0..19)
-\param p antenna port
-\param l symbol within slot
-\param symbol symbol within frame
+\param symbol symbol within slot
 */
 int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t eNB_offset,
+                                uint8_t gNB_id,
                                 unsigned char Ns,
                                 unsigned char symbol,
                                 unsigned short coreset_start_subcarrier,
@@ -52,7 +49,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
                              UE_nr_rxtx_proc_t *proc,
-                             uint8_t eNB_offset,
+                             uint8_t gNB_id,
                              unsigned char Ns,
                              unsigned char symbol,
                              int dmrss,
@@ -60,7 +57,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
 
 int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
                                UE_nr_rxtx_proc_t *proc,
-                               uint8_t eNB_offset,
+                               uint8_t gNB_id,
                                unsigned char Ns,
                                unsigned char symbol,
                                int dmrss,
@@ -69,7 +66,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t eNB_offset,
+                                uint8_t gNB_id,
+                                bool is_SI,
                                 unsigned char Ns,
                                 unsigned short p,
                                 unsigned char symbol,
@@ -79,7 +77,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
                         PHY_VARS_NR_UE *ue,
-                        module_id_t eNB_id,
+                        module_id_t gNB_id,
                         uint8_t frame,
                         uint8_t subframe,
                         unsigned char clear,
@@ -101,7 +99,7 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
 
 void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
                         uint32_t rx_power_fil_dB,
-                        uint8_t eNB_id);
+                        uint8_t gNB_id);
 
 int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
 
@@ -110,11 +108,10 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
                               NR_DL_FRAME_PARMS *frame_parms,
                               NR_DL_UE_HARQ_t *dlsch0_harq,
                               NR_DL_UE_HARQ_t *dlsch1_harq,
-                              uint8_t eNB_id,
+                              uint8_t gNB_id,
                               uint8_t nr_slot_rx,
                               unsigned char symbol,
                               uint32_t nb_re_pdsch,
-                              unsigned char harq_pid,
                               uint16_t rnti,
                               RX_type_t rx_type);
 
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
index 61fc40ad3f5539f5bc83335da6bc4298e01e4c9c..44f1844ae96dd180262410994dd973df2f295414 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
@@ -21,16 +21,17 @@
 
 /*! \file nr_ue_measurements.c
  * \brief UE measurements routines
- * \author  R. Knopp, G. Casati
+ * \author  R. Knopp, G. Casati, K. Saaifan
  * \date 2020
  * \version 0.1
  * \company Eurecom, Fraunhofer IIS
- * \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de
+ * \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de, khodr.saaifan@iis.fraunhofer.de
  * \note
  * \warning
  */
 
 #include "executables/softmodem-common.h"
+#include "executables/nr-softmodem-common.h"
 #include "PHY/defs_nr_UE.h"
 #include "PHY/phy_extern_nr_ue.h"
 #include "common/utils/LOG/log.h"
@@ -45,7 +46,7 @@
 //#define DEBUG_MEAS_UE
 //#define DEBUG_RANK_EST
 
-// Returns the pathloss in dBm for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission
+// Returns the pathloss in dB for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission
 // computation according to clause 7.4 (Physical random access channel) of 3GPP TS 38.213 version 16.3.0 Release 16
 // Assumptions:
 // - PRACH transmission from a UE is not in response to a detection of a PDCCH order by the UE
@@ -59,18 +60,17 @@ int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index){
   if (get_softmodem_params()->do_ra){
 
     long referenceSignalPower = ue->nrUE_config.ssb_config.ss_pbch_power;
-    double rsrp_dBm = 10*log10(ue->measurements.rsrp[gNB_index]) + 30 - ue->rx_total_gain_dB;
 
-    pathloss = (int16_t)(10*log10(pow(10, (double)(referenceSignalPower)/10) - pow(10, (double)(rsrp_dBm)/10)));
+    pathloss = (int16_t)(referenceSignalPower - ue->measurements.rsrp_dBm[gNB_index]);
 
-    LOG_D(MAC, "In %s: pathloss %d dBm, UE RX total gain %d dB, referenceSignalPower %ld dBm (%f mW), RSRP %f dBm (%f mW)\n",
+    LOG_D(MAC, "In %s: pathloss %d dB, UE RX total gain %d dB, referenceSignalPower %ld dBm/RE (%f mW), RSRP %d dBm (%f mW)\n",
       __FUNCTION__,
       pathloss,
       ue->rx_total_gain_dB,
       referenceSignalPower,
       pow(10, referenceSignalPower/10),
-      rsrp_dBm,
-      pow(10, rsrp_dBm/10));
+      ue->measurements.rsrp_dBm[gNB_index],
+      pow(10, ue->measurements.rsrp_dBm[gNB_index]/10));
 
   } else {
 
@@ -178,13 +178,13 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
     ue->measurements.rx_power_avg_dB[gNB_id] = dB_fixed( ue->measurements.rx_power_avg[gNB_id]);
     ue->measurements.wideband_cqi_tot[gNB_id] = dB_fixed2(ue->measurements.rx_power_tot[gNB_id], ue->measurements.n0_power_tot);
     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] - ue->rx_total_gain_dB;
+    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_D(PHY, "[gNB %d] Slot %d, RSSI %d dBm, 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);
@@ -258,15 +258,20 @@ void nr_ue_rsrp_measurements(PHY_VARS_NR_UE *ue,
 
   ue->measurements.rsrp_filtered[gNB_id] = ue->measurements.rsrp[gNB_id];
 
-  LOG_D(PHY, "In %s: [UE %d] slot %d SS-RSRP: %3.1f dBm/RE (%d W)\n",
+  ue->measurements.rsrp_dBm[gNB_id] = 10*log10(ue->measurements.rsrp[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_D(PHY, "In %s: [UE %d] slot %d SS-RSRP: %d dBm/RE (%d)\n",
     __FUNCTION__,
     ue->Mod_id,
     slot,
-    10*log10(ue->measurements.rsrp[gNB_id]) + 30 - ue->rx_total_gain_dB,
+    ue->measurements.rsrp_dBm[gNB_id],
     ue->measurements.rsrp[gNB_id]);
 
 }
 
+// This function computes the received noise power
+// Measurement units:
+// - psd_awgn (AWGN power spectral density):     dBm/Hz
 void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
                             UE_nr_rxtx_proc_t *proc,
                             uint8_t slot){
@@ -279,6 +284,9 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
   uint8_t k_length = 8;
   uint8_t l_sss = ue->symbol_offset + 2;
   unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
+  double rx_gain = openair0_cfg[0].rx_gain[0];
+  double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
+
   ue->measurements.n0_power_tot = 0;
 
   LOG_D(PHY, "In %s doing measurements for ssb_offset %d l_sss %d \n", __FUNCTION__, ssb_offset, l_sss);
@@ -322,10 +330,17 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
   ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/aarx);
 
   #ifdef DEBUG_MEAS_RRC
-  int nf_usrp = ue->measurements.n0_power_tot_dB + 30 - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - 90 - (-174 + dB_fixed(30000/*scs*/) + dB_fixed(ue->frame_parms.ofdm_symbol_size));
-  LOG_D(PHY, "In %s slot %d NF USRP %d dBm\n", __FUNCTION__, nf_usrp);
+  const int psd_awgn = -174;
+  const int scs = 15000 * (1 << ue->frame_parms.numerology_index);
+  const int nf_usrp = ue->measurements.n0_power_tot_dB + 3 + 30 - ((int)rx_gain - (int)rx_gain_offset) - 10 * log10(pow(2, 30)) - (psd_awgn + dB_fixed(scs) + dB_fixed(ue->frame_parms.ofdm_symbol_size));
+  LOG_D(PHY, "In [%s][slot:%d] NF USRP %d dB\n", __FUNCTION__, slot, nf_usrp);
   #endif
 
-  LOG_D(PHY, "In %s slot %d Noise Level %d ue->measurements.n0_power_tot_dB %d \n", __FUNCTION__, slot, ue->measurements.n0_power_tot, ue->measurements.n0_power_tot_dB);
+  LOG_D(PHY, "In [%s][slot:%d] Noise Level %d (digital level %d dB, noise power spectral density %f dBm/RE)\n",
+    __FUNCTION__,
+    slot,
+    ue->measurements.n0_power_tot,
+    ue->measurements.n0_power_tot_dB,
+    ue->measurements.n0_power_tot_dB + 30 - 10*log10(pow(2, 30)) - dB_fixed(ue->frame_parms.ofdm_symbol_size) - ((int)rx_gain - (int)rx_gain_offset));
 
 }
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index bfec64820b1300d18a6edc463f8e5c1237e4f10f..cadb4954c093cfd260640be1f26b1bb389ec1c9f 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
@@ -132,7 +142,7 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
 
   if (reg_bundle_size_L != 0) { // interleaving will be done only if reg_bundle_size_L != 0
     coreset_interleaved = 1;
-    coreset_C = (uint32_t) ((coreset_nbr_rb * coreset_time_dur) / (coreset_interleaver_size_R * reg_bundle_size_L));
+    coreset_C = (uint32_t) (coreset_nbr_rb / (coreset_interleaver_size_R * reg_bundle_size_L));
   } else {
     reg_bundle_size_L = 6;
   }
@@ -140,7 +150,7 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
 
   int f_bundle_j_list[NR_MAX_PDCCH_AGG_LEVEL] = {};
 
-  for (int reg = 0; reg < ((coreset_nbr_rb * coreset_time_dur)); reg++) {
+  for (int reg = 0; reg < coreset_nbr_rb; reg++) {
     if ((reg % reg_bundle_size_L) == 0) {
       if (r == coreset_interleaver_size_R) {
         r = 0;
@@ -148,7 +158,7 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
       }
 
       bundle_j = (c * coreset_interleaver_size_R) + r;
-      f_bundle_j = ((r * coreset_C) + c + n_shift) % ((coreset_nbr_rb * coreset_time_dur) / reg_bundle_size_L);
+      f_bundle_j = ((r * coreset_C) + c + n_shift) % (coreset_nbr_rb / reg_bundle_size_L);
 
       if (coreset_interleaved == 0) f_bundle_j = bundle_j;
 
@@ -158,7 +168,6 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
     if ((reg % reg_bundle_size_L) == 0) r++;
   }
 
-
   // Get cce_list indices by reg_idx in ascending order
   int f_bundle_j_list_id = 0;
   int f_bundle_j_list_ord[NR_MAX_PDCCH_AGG_LEVEL] = {};
@@ -175,23 +184,28 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
     }
   }
 
+  int rb = 0;
+  for (int c_id = 0; c_id < number_of_candidates; c_id++ ) {
+    for (int symbol_idx = 0; symbol_idx < coreset_time_dur; symbol_idx++) {
+      for (int cce_count = CCE[c_id/coreset_time_dur]+c_id%coreset_time_dur; cce_count < CCE[c_id/coreset_time_dur]+c_id%coreset_time_dur+L[c_id]; cce_count += coreset_time_dur) {
+        for (int reg_in_cce_idx = 0; reg_in_cce_idx < NR_NB_REG_PER_CCE; reg_in_cce_idx++) {
 
-  for(int reg=0; reg<((coreset_nbr_rb*coreset_time_dur)); reg++) {
-
-    f_reg = (f_bundle_j_list_ord[reg/6]*reg_bundle_size_L)+(reg%reg_bundle_size_L);
-    index_z   = 9*reg;
-    index_llr = 9*((uint16_t)floor(f_reg/coreset_time_dur)+((f_reg%coreset_time_dur)*(coreset_nbr_rb)));
+          f_reg = (f_bundle_j_list_ord[cce_count] * reg_bundle_size_L) + reg_in_cce_idx;
+          index_z = 9 * rb;
+          index_llr = (uint16_t) (f_reg + symbol_idx * coreset_nbr_rb) * 9;
 
-    for (int i=0; i<9; i++) {
-      z[index_z + i] = llr[index_llr + i];
+          for (int i = 0; i < 9; i++) {
+            z[index_z + i] = llr[index_llr + i];
 #ifdef NR_PDCCH_DCI_DEBUG
-      LOG_D(PHY,"[reg=%d,bundle_j=%d] z[%d]=(%d,%d) <-> \t[f_reg=%d,fbundle_j=%d] llr[%d]=(%d,%d) \n",
-             reg,bundle_j,(index_z + i),*(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]),
-             f_reg,f_bundle_j,(index_llr + i),*(int16_t *) &llr[index_llr + i], *(1 + (int16_t *) &llr[index_llr + i]));
+            LOG_I(PHY,"[cce_count=%d,reg_in_cce_idx=%d,bundle_j=%d,symbol_idx=%d,candidate=%d] z[%d]=(%d,%d) <-> \t[f_reg=%d,fbundle_j=%d] llr[%d]=(%d,%d) \n",
+                  cce_count,reg_in_cce_idx,bundle_j,symbol_idx,c_id,(index_z + i),*(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]),
+                   f_reg,f_bundle_j,(index_llr + i),*(int16_t *) &llr[index_llr + i], *(1 + (int16_t *) &llr[index_llr + i]));
 #endif
+          }
+          rb++;
+        }
+      }
     }
-
-    if ((reg%reg_bundle_size_L) == 0) r++;
   }
 }
 
@@ -404,11 +418,12 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
     c_rb = 0;
     for (int rb=0;rb<coreset_nbr_rb;rb++,c_rb++) {
       c_rb_by6 = c_rb/6;
+
       // skip zeros in frequency domain bitmap
       while ((coreset_freq_dom[c_rb_by6>>3] & (1<<(7-(c_rb_by6&7)))) == 0) {
-	  c_rb+=6;
-	  c_rb_by6 = c_rb/6;
-	}
+        c_rb+=6;
+        c_rb_by6 = c_rb/6;
+      }
 
       LOG_DDD("c_rb=%d\n",c_rb);
       rxF=NULL;
@@ -717,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");
 
@@ -742,7 +761,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
       for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
         avgs = cmax(avgs, avgP[aarx]);
 
-      log2_maxh = (log2_approx(avgs) / 2) + 5;  //+frame_parms->nb_antennas_rx;
+      log2_maxh = (log2_approx(avgs) / 2) + 1;  //+frame_parms->nb_antennas_rx;
 #ifdef UE_DEBUG_TRACE
       LOG_D(PHY,"slot %d: pdcch log2_maxh = %d (%d,%d)\n",slot,log2_maxh,avgP[0],avgs);
 #endif
@@ -875,6 +894,33 @@ void nr_pdcch_unscrambling(int16_t *z,
 
 
 #ifdef NR_PDCCH_DCI_RUN
+/* This function compares the received DCI bits with
+ * re-encoded DCI bits and returns the number of mismatched bits
+ */
+uint16_t nr_dci_false_detection(uint64_t *dci,
+                            int16_t *soft_in,
+                            const t_nrPolar_params *polar_param,
+                            int encoded_length,
+                            int rnti) {
+
+  uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
+  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;
+
+  for (int i=0; i<encoded_length/8; i++) {
+    x += ( enout_p[i] & 1 ) ^ ( ( soft_in[i*8] >> 15 ) & 1);
+    x += ( ( enout_p[i] >> 1 ) & 1 ) ^ ( ( soft_in[i*8+1] >> 15 ) & 1 );
+    x += ( ( enout_p[i] >> 2 ) & 1 ) ^ ( ( soft_in[i*8+2] >> 15 ) & 1 );
+    x += ( ( enout_p[i] >> 3 ) & 1 ) ^ ( ( soft_in[i*8+3] >> 15 ) & 1 );
+    x += ( ( enout_p[i] >> 4 ) & 1 ) ^ ( ( soft_in[i*8+4] >> 15 ) & 1 );
+    x += ( ( enout_p[i] >> 5 ) & 1 ) ^ ( ( soft_in[i*8+5] >> 15 ) & 1 );
+    x += ( ( enout_p[i] >> 6 ) & 1 ) ^ ( ( soft_in[i*8+6] >> 15 ) & 1 );
+    x += ( ( enout_p[i] >> 7 ) & 1 ) ^ ( ( soft_in[i*8+7] >> 15 ) & 1 );
+  }
+  return x;
+}
+
 uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
                                   fapi_nr_dci_indication_t *dci_ind) {
@@ -917,19 +963,29 @@ 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);
-          dci_ind->SFN = proc->frame_rx;
-          dci_ind->slot = proc->nr_slot_rx;
-          dci_ind->dci_list[dci_ind->number_of_dcis].rnti        = n_rnti;
-          dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE       = CCEind;
-          dci_ind->dci_list[dci_ind->number_of_dcis].dci_format  = rel15->dci_format_options[k];
-          dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
-          memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
-          dci_ind->number_of_dcis++;
-          break;    // If DCI is found, no need to check for remaining DCI lengths
+          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)) {
+            LOG_W(PHY,"DCI false positive. Dropping DCI index %d. Mismatched bits: %d/%d. Current DCI threshold: %d\n",j,mb,L*108,ue->dci_thres);
+            continue;
+          }
+          else {
+            dci_ind->SFN = proc->frame_rx;
+            dci_ind->slot = proc->nr_slot_rx;
+            dci_ind->dci_list[dci_ind->number_of_dcis].rnti        = n_rnti;
+            dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE       = CCEind;
+            dci_ind->dci_list[dci_ind->number_of_dcis].N_CCE       = L;
+            dci_ind->dci_list[dci_ind->number_of_dcis].dci_format  = rel15->dci_format_options[k];
+            dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
+            memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
+            dci_ind->number_of_dcis++;
+            break;    // If DCI is found, no need to check for remaining DCI lengths
+          }
         } else {
           LOG_D(PHY,"(%i.%i) Decoded crc %x does not match rnti %x for DCI format %d\n", proc->frame_rx, proc->nr_slot_rx, crc, n_rnti, rel15->dci_format_options[k]);
         }
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index 429bd9a836857abedbad4d99aec1880ebf60f704..c98a685ed8cff01d8aaa8344154fc2f3396cd2ae 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -60,23 +60,22 @@ int nbDlProcessing =0;
 static  tpool_t pool_dl;
 
 //extern double cpuf;
-void init_dlsch_tpool(uint8_t num_dlsch_threads)
-{
-    if( num_dlsch_threads==0)
-    	return;
+void init_dlsch_tpool(uint8_t num_dlsch_threads) {
+  if( num_dlsch_threads==0)
+    return;
 
   char *params=calloc(1,(num_dlsch_threads*3)+1);
+
   for (int i=0; i<num_dlsch_threads; i++) {
     memcpy(params+(i*3),"-1,",3);
   }
+
   initNamedTpool(params, &pool_dl, false,"dlsch");
   free(params);
 }
 
 
-void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL)
-{
-
+void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL) {
   int i,r;
   uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
   NR_UE_DLSCH_t *dlsch=*dlschptr;
@@ -85,8 +84,7 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL)
     if (N_RB_DL != 273) {
       a_segments = a_segments*N_RB_DL;
       a_segments = a_segments/273 +1;
-    }  
- 
+    }
 
     for (i=0; i<dlsch->Mdlharq; i++) {
       if (dlsch->harq_processes[i]) {
@@ -105,7 +103,7 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL)
             free16(dlsch->harq_processes[i]->d[r],(5*8448)*sizeof(short));
             dlsch->harq_processes[i]->d[r] = NULL;
           }
-        
+
         for (r=0; r<a_segments; r++)
           if (dlsch->harq_processes[i]->w[r]) {
             free16(dlsch->harq_processes[i]->w[r],(5*8448)*sizeof(short));
@@ -113,7 +111,7 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL)
           }
 
         for (r=0; r<a_segments; r++) {
-          if (dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]){
+          if (dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]) {
             nrLDPC_free_mem(dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
             dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL;
           }
@@ -123,27 +121,23 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL)
         dlsch->harq_processes[i] = NULL;
       }
     }
-      
+
     free16(dlsch,sizeof(NR_UE_DLSCH_t));
     dlsch = NULL;
   }
 }
 
-NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_ldpc_iterations,uint16_t N_RB_DL, uint8_t abstraction_flag)
-{
-
+NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_ldpc_iterations,uint16_t N_RB_DL, uint8_t abstraction_flag) {
   NR_UE_DLSCH_t *dlsch;
   uint8_t exit_flag = 0,i,r;
-
   uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
 
   if (N_RB_DL != 273) {
     a_segments = a_segments*N_RB_DL;
     a_segments = (a_segments/273)+1;
-  }  
+  }
 
   uint16_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment
-
   dlsch = (NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t));
 
   if (dlsch) {
@@ -154,7 +148,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
     dlsch->Nsoft = Nsoft;
     dlsch->Mlimit = 4;
     dlsch->max_ldpc_iterations = max_ldpc_iterations;
- 
+
     for (i=0; i<Mdlharq; i++) {
       dlsch->harq_processes[i] = (NR_DL_UE_HARQ_t *)malloc16(sizeof(NR_DL_UE_HARQ_t));
 
@@ -162,7 +156,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
         memset(dlsch->harq_processes[i],0,sizeof(NR_DL_UE_HARQ_t));
         init_downlink_harq_status(dlsch->harq_processes[i]);
         dlsch->harq_processes[i]->first_tx=1;
-        dlsch->harq_processes[i]->b = (uint8_t*)malloc16(dlsch_bytes);
+        dlsch->harq_processes[i]->b = (uint8_t *)malloc16(dlsch_bytes);
 
         if (dlsch->harq_processes[i]->b)
           memset(dlsch->harq_processes[i]->b,0,dlsch_bytes);
@@ -170,23 +164,23 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
           exit_flag=3;
 
         if (abstraction_flag == 0) {
-          for (r=0; r<a_segments; r++) { 
+          for (r=0; r<a_segments; r++) {
             dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
-            dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(1056);
+            dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(1056);
 
             if (dlsch->harq_processes[i]->c[r])
               memset(dlsch->harq_processes[i]->c[r],0,1056);
             else
               exit_flag=2;
 
-            dlsch->harq_processes[i]->d[r] = (short*)malloc16((5*8448)*sizeof(short));
+            dlsch->harq_processes[i]->d[r] = (short *)malloc16((5*8448)*sizeof(short));
 
             if (dlsch->harq_processes[i]->d[r])
               memset(dlsch->harq_processes[i]->d[r],0,(5*8448)*sizeof(short));
             else
               exit_flag=2;
 
-            dlsch->harq_processes[i]->w[r] = (short*)malloc16((5*8448)*sizeof(short));
+            dlsch->harq_processes[i]->w[r] = (short *)malloc16((5*8448)*sizeof(short));
 
             if (dlsch->harq_processes[i]->w[r])
               memset(dlsch->harq_processes[i]->w[r],0,(5*8448)*sizeof(short));
@@ -205,19 +199,16 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
 
   LOG_D(PHY,"new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag);
   free_nr_ue_dlsch(&dlsch,N_RB_DL);
-
   return(NULL);
 }
 
-void nr_dlsch_unscrambling(int16_t* llr,
-                         uint32_t size,
-                         uint8_t q,
-                         uint32_t Nid,
-                         uint32_t n_RNTI) {
-
+void nr_dlsch_unscrambling(int16_t *llr,
+                           uint32_t size,
+                           uint8_t q,
+                           uint32_t Nid,
+                           uint32_t n_RNTI) {
   uint8_t reset;
   uint32_t x1, x2, s=0;
-
   reset = 1;
   x2 = (n_RNTI<<15) + (q<<14) + Nid;
 
@@ -226,10 +217,10 @@ void nr_dlsch_unscrambling(int16_t* llr,
       s = lte_gold_generic(&x1, &x2, reset);
       reset = 0;
     }
+
     if (((s>>(i&0x1f))&1)==1)
       llr[i] = -llr[i];
   }
-
 }
 
 uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
@@ -244,9 +235,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
                            uint8_t nr_slot_rx,
                            uint8_t harq_pid,
                            uint8_t is_crnti,
-                           uint8_t llr8_flag)
-{
-
+                           uint8_t llr8_flag) {
 #if UE_TIMING_TRACE
   time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats;
   time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats;
@@ -260,48 +249,43 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
   uint8_t crc_type;
   int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
   t_nrLDPC_dec_params decParams;
-  t_nrLDPC_dec_params* p_decParams = &decParams;
-  t_nrLDPC_time_stats procTime;
-  t_nrLDPC_time_stats* p_procTime =&procTime ;
-  
+  t_nrLDPC_dec_params *p_decParams = &decParams;
+  t_nrLDPC_time_stats procTime = {0};
+  t_nrLDPC_time_stats *p_procTime =&procTime ;
+
   if (!harq_process) {
     LOG_E(PHY,"dlsch_decoding.c: NULL harq_process pointer\n");
     return(dlsch->max_ldpc_iterations + 1);
   }
-  t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
 
+  t_nrLDPC_procBuf **p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
   // HARQ stats
   phy_vars_ue->dl_stats[harq_process->round]++;
-    
   int16_t z [68*384];
   int8_t l [68*384];
   //__m128i l;
   //int16_t inv_d [68*384];
   uint8_t kc;
   uint8_t Ilbrm = 1;
-
   uint32_t Tbslbrm;// = 950984;
   uint16_t nb_rb;// = 30;
   double Coderate;// = 0.0;
-
   uint8_t dmrs_Type = harq_process->dmrsConfigType;
   AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
   uint8_t nb_re_dmrs;
+
   if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) {
     nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
-  }
-  else {
+  } else {
     nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
   }
-  uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
 
+  uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
   uint32_t i,j;
+  __m128i *pv = (__m128i *)&z;
+  __m128i *pl = (__m128i *)&l;
+  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
 
-  __m128i *pv = (__m128i*)&z;
-  __m128i *pl = (__m128i*)&l;
-  
-    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
-  
   //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0];
 
   if (!dlsch_llr) {
@@ -318,42 +302,31 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
     printf("dlsch_decoding.c: Illegal slot index %d\n",nr_slot_rx);
     return(dlsch->max_ldpc_iterations + 1);
   }*/
-
   /*if (harq_process->harq_ack.ack != 2) {
     LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
         phy_vars_ue->Mod_id, nr_slot_rx, harq_process->harq_ack.ack);
   }*/
-
   //  nb_rb = dlsch->nb_rb;
-
   /*
   if (nb_rb > frame_parms->N_RB_DL) {
     printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
     return(max_ldpc_iterations + 1);
     }*/
-
   /*harq_pid = dlsch->current_harq_pid[proc->thread_id];
   if (harq_pid >= 8) {
     printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
     return(max_ldpc_iterations + 1);
   }
   */
-
   nb_rb = harq_process->nb_rb;
-
   harq_process->trials[harq_process->round]++;
-
   uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
-
   harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, 0, harq_process->Nl);
-
   A = harq_process->TBS;
   ret = dlsch->max_ldpc_iterations + 1;
   dlsch->last_iteration_cnt = ret;
- 
   harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_length, harq_process->Qm,harq_process->Nl);
   G = harq_process->G;
-
   LOG_D(PHY,"DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,A/8,G, nb_re_dmrs,harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
 
   if ((harq_process->R)<1024)
@@ -361,41 +334,36 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
   else
     Coderate = (float) (harq_process->R) /(float) 2048;
 
-  if ((A <=292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25)
-  {
+  if ((A <=292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) {
     p_decParams->BG = 2;
     kc = 52;
-    if (Coderate < 0.3333){
+
+    if (Coderate < 0.3333) {
       p_decParams->R = 15;
-    }
-    else if (Coderate <0.6667){
+    } else if (Coderate <0.6667) {
       p_decParams->R = 13;
-    }
-    else {
+    } else {
       p_decParams->R = 23;
     }
-  }
-  else{
+  } else {
     p_decParams->BG = 1;
     kc = 68;
-    if (Coderate < 0.6667){
+
+    if (Coderate < 0.6667) {
       p_decParams->R = 13;
-    }
-    else if (Coderate <0.8889){
+    } else if (Coderate <0.8889) {
       p_decParams->R = 23;
-    }
-    else {
+    } else {
       p_decParams->R = 89;
     }
   }
 
-
   if (harq_process->round == 0) {
-  // This is a new packet, so compute quantities regarding segmentation
-  if (A > NR_MAX_PDSCH_TBS)
-	  harq_process->B = A+24;
-	else
-	  harq_process->B = A+16;
+    // This is a new packet, so compute quantities regarding segmentation
+    if (A > NR_MAX_PDSCH_TBS)
+      harq_process->B = A+24;
+    else
+      harq_process->B = A+16;
 
     nr_segmentation(NULL,
                     NULL,
@@ -406,29 +374,24 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
                     &harq_process->F,
                     p_decParams->BG);
 
-  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!frame%100))
-       LOG_I(PHY,"K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
+    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!frame%100))
+      LOG_I(PHY,"K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
   }
-  
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
 
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
   p_decParams->Z = harq_process->Z;
   //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z);
-
   //printf("coderate %f kc %d \n", Coderate, kc);
-
   p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
   p_decParams->outMode= 0;
-
   err_flag = 0;
   r_offset = 0;
-
   uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
 
   if (nb_rb != 273) {
     a_segments = a_segments*nb_rb;
     a_segments = a_segments/273 +1;
-  }  
+  }
 
   if (harq_process->C > a_segments) {
     LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
@@ -438,41 +401,29 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
   if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
     LOG_I(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
 
-
   opp_enabled=1;
-
   Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb"
   Kr_bytes = Kr>>3;
   K_bits_F = Kr-harq_process->F;
 
   for (r=0; r<harq_process->C; r++) {
-
     //printf("start rx segment %d\n",r);
     E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
-
 #if UE_TIMING_TRACE
     start_meas(dlsch_deinterleaving_stats);
 #endif
-
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN);
-
-
     nr_deinterleaving_ldpc(E,
                            harq_process->Qm,
                            harq_process->w[r], // [hna] w is e
                            dlsch_llr+r_offset);
-
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT);
-
-
 #if UE_TIMING_TRACE
     stop_meas(dlsch_deinterleaving_stats);
 #endif
-
 #if UE_TIMING_TRACE
     start_meas(dlsch_rate_unmatching_stats);
 #endif
-
     LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,E %d, F %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
           harq_pid,r, G,E,harq_process->F,
           Kr*3,
@@ -482,8 +433,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
           harq_process->Nl,
           harq_process->rvidx,
           harq_process->round);
-
-
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
 
     if ((harq_process->Nl)<4)
@@ -491,7 +440,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
     else
       Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
 
-
     if (nr_rate_matching_ldpc_rx(Ilbrm,
                                  Tbslbrm,
                                  p_decParams->BG,
@@ -504,14 +452,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
                                  E,
                                  harq_process->F,
                                  Kr-harq_process->F-2*(p_decParams->Z))==-1) {
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT);
 #if UE_TIMING_TRACE
       stop_meas(dlsch_rate_unmatching_stats);
 #endif
       LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
       return(dlsch->max_ldpc_iterations + 1);
     } else {
-
 #if UE_TIMING_TRACE
       stop_meas(dlsch_rate_unmatching_stats);
 #endif
@@ -519,38 +466,33 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 
     r_offset += E;
 
-  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
-  {
-    LOG_I(PHY,"decoder input(segment %u) :",r);
-    for (int i=0;i<E;i++)
-     LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
-    LOG_D(PHY,"\n");
-  }
+    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
+      LOG_I(PHY,"decoder input(segment %u) :",r);
 
-    memset(harq_process->c[r],0,Kr_bytes);
+      for (int i=0; i<E; i++)
+        LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
 
+      LOG_D(PHY,"\n");
+    }
 
-    if (harq_process->C == 1){
+    memset(harq_process->c[r],0,Kr_bytes);
+
+    if (harq_process->C == 1) {
       if (A > NR_MAX_PDSCH_TBS)
-    		crc_type = CRC24_A;
-    	else
-    		crc_type = CRC16;
-    	
-	length_dec = harq_process->B;
+        crc_type = CRC24_A;
+      else
+        crc_type = CRC16;
 
-    }
-    else{
+      length_dec = harq_process->B;
+    } else {
       crc_type = CRC24_B;
       length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
     }
 
     if (err_flag == 0) {
-
 #if UE_TIMING_TRACE
       start_meas(dlsch_turbo_decoding_stats);
 #endif
-
-
       //set first 2*Z_c bits to zeros
       memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
       //set Filler bits
@@ -559,62 +501,56 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
       memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t));
       //skip filler bits
       memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t));
+
       //Saturate coded bits before decoding into 8 bits values
-      for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++)
-      {
+      for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++) {
         pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
       }
 
-
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
-
       no_iteration_ldpc = nrLDPC_decoder(p_decParams,
-                           (int8_t*)&pl[0],
-                           llrProcBuf,
-                           p_nrLDPC_procBuf[r],
-                           p_procTime);
+                                         (int8_t *)&pl[0],
+                                         llrProcBuf,
+                                         p_nrLDPC_procBuf[r],
+                                         p_procTime);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT);
 
       // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
-      if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
+      if (check_crc((uint8_t *)llrProcBuf,length_dec,harq_process->F,crc_type)) {
         LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
+
         if (r==0) {
-          for (int i=0;i<10;i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t*)llrProcBuf)[i]);
+          for (int i=0; i<10; i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t *)llrProcBuf)[i]);
         }
 
         //Temporary hack
         no_iteration_ldpc = dlsch->max_ldpc_iterations;
         ret = no_iteration_ldpc;
-      }
-      else {
+      } else {
         LOG_D(PHY,"CRC NOT OK\n\033[0m");
-        ret = 1 + dlsch->max_ldpc_iterations;
       }
 
-
       nb_total_decod++;
-      if (no_iteration_ldpc > dlsch->max_ldpc_iterations){
+
+      if (no_iteration_ldpc > dlsch->max_ldpc_iterations) {
         nb_error_decod++;
       }
 
-      for (int m=0; m < Kr>>3; m ++)
-      {
+      for (int m=0; m < Kr>>3; m ++) {
         harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
       }
 
-      if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
-      	{
-        for (int k=0;k<A>>3;k++)
+      if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
+        for (int k=0; k<A>>3; k++)
           LOG_D(PHY,"output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
-        LOG_D(PHY,"no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
-        }
 
+        LOG_D(PHY,"no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
+      }
 
 #if UE_TIMING_TRACE
       stop_meas(dlsch_turbo_decoding_stats);
 #endif
     }
-    
 
     if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
       LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
@@ -624,11 +560,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 
   if (err_flag == 1) {
     LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
-        phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
-
-    harq_process->harq_ack.ack = 0;
-    harq_process->harq_ack.harq_id = harq_pid;
-    harq_process->harq_ack.send_harq_status = 1;
+          phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
+    harq_process->ack = 0;
     harq_process->errors[harq_process->round]++;
 
     if (harq_process->round >= dlsch->Mlimit) {
@@ -637,72 +570,62 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
       phy_vars_ue->dl_stats[4]++;
     }
 
-    if(is_crnti)
-    {
-    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
-               phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
+    if(is_crnti) {
+      LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
+            phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
     }
 
     return((1 + dlsch->max_ldpc_iterations));
   } else {
-
     LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
-	  phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
-
+          phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
     harq_process->status = SCH_IDLE;
     harq_process->round  = 0;
-    harq_process->harq_ack.ack = 1;
-    harq_process->harq_ack.harq_id = harq_pid;
-    harq_process->harq_ack.send_harq_status = 1;
-    
+    harq_process->ack = 1;
+
     //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
-      //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);
+    //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);
 
-    if(is_crnti)
-    {
-    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->round,harq_process->TBS);
+    if(is_crnti) {
+      LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->round,harq_process->TBS);
     }
-    //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
 
+    //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
   }
 
   // Reassembly of Transport block here
   offset = 0;
   Kr = harq_process->K;
   Kr_bytes = Kr>>3;
-
-
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_IN);
 
   for (r=0; r<harq_process->C; r++) {
-
     memcpy(harq_process->b+offset,
-	   harq_process->c[r],
-	   Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
+           harq_process->c[r],
+           Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
     offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
 
-    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
-      {
+    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
       LOG_D(PHY,"Segment %u : Kr= %u bytes\n",r,Kr_bytes);
       LOG_D(PHY,"copied %d bytes to b sequence (harq_pid %d)\n",
-             (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
+            (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
       LOG_D(PHY,"b[0] = %p,c[%d] = %p\n",
-              (void *)(uint64_t)(harq_process->b[offset]),
-              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, "[%d] : %x ", i, harq_process->b[i]);
-          }
+            (void *)(uint64_t)(harq_process->b[offset]),
+            harq_process->F>>3,
+            (void *)(uint64_t)(harq_process->c[r]) );
+
+      if (frame%100 == 0) {
+        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]);
         }
       }
+    }
   }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT);
-
   dlsch->last_iteration_cnt = ret;
-
   return(ret);
 }
 
@@ -719,9 +642,7 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
                                     uint8_t nr_slot_rx,
                                     uint8_t harq_pid,
                                     uint8_t is_crnti,
-                                    uint8_t llr8_flag)
-{
-
+                                    uint8_t llr8_flag) {
 #if UE_TIMING_TRACE
   time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats;
   time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats;
@@ -739,15 +660,17 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
   uint8_t r_thread;
   uint32_t Er, Gp,GpmodC;*/
   t_nrLDPC_dec_params decParams;
-  t_nrLDPC_dec_params* p_decParams = &decParams;
+  t_nrLDPC_dec_params *p_decParams = &decParams;
   t_nrLDPC_time_stats procTime;
-  t_nrLDPC_time_stats* p_procTime =&procTime ;
+  t_nrLDPC_time_stats *p_procTime =&procTime ;
   int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
-    if (!harq_process) {
+
+  if (!harq_process) {
     LOG_E(PHY,"dlsch_decoding.c: NULL harq_process pointer\n");
     return(dlsch->max_ldpc_iterations);
   }
-  t_nrLDPC_procBuf* p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0];
+
+  t_nrLDPC_procBuf *p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0];
   uint8_t Nl=4;
   int16_t z [68*384];
   int8_t l [68*384];
@@ -757,22 +680,19 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
   uint16_t nb_rb = 30;
   double Coderate = 0.0;
   uint8_t dmrs_type = harq_process->dmrsConfigType;
-
   uint8_t nb_re_dmrs;
+
   if (dmrs_type == NFAPI_NR_DMRS_TYPE1)
     nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
   else
     nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
 
-  uint16_t length_dmrs = get_num_dmrs(harq_process->dlDmrsSymbPos); 
-  
+  uint16_t length_dmrs = get_num_dmrs(harq_process->dlDmrsSymbPos);
   uint32_t i,j;
-
-  __m128i *pv = (__m128i*)&z;
-  __m128i *pl = (__m128i*)&l;
+  __m128i *pv = (__m128i *)&z;
+  __m128i *pl = (__m128i *)&l;
   notifiedFIFO_t nf;
   initNotifiedFIFO(&nf);
-
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
 
   if (!dlsch_llr) {
@@ -780,217 +700,188 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
     return(dlsch->max_ldpc_iterations);
   }
 
-
-
   if (!frame_parms) {
     LOG_E(PHY,"dlsch_decoding.c: NULL frame_parms pointer\n");
     return(dlsch->max_ldpc_iterations);
   }
 
- /* if (nr_slot_rx> (frame_parms->slots_per_frame-1)) {
-    printf("dlsch_decoding.c: Illegal slot index %d\n",nr_slot_rx);
-    return(dlsch->max_ldpc_iterations);
-  }
-
-  if (dlsch->harq_ack[nr_slot_rx].ack != 2) {
-    LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
-        phy_vars_ue->Mod_id, nr_slot_rx, dlsch->harq_ack[nr_slot_rx].ack);
-  }*/
+  /* if (nr_slot_rx> (frame_parms->slots_per_frame-1)) {
+     printf("dlsch_decoding.c: Illegal slot index %d\n",nr_slot_rx);
+     return(dlsch->max_ldpc_iterations);
+   }
 
+   if (dlsch->harq_ack[nr_slot_rx].ack != 2) {
+     LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
+         phy_vars_ue->Mod_id, nr_slot_rx, dlsch->harq_ack[nr_slot_rx].ack);
+   }*/
   /*
   if (nb_rb > frame_parms->N_RB_DL) {
     printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
     return(max_ldpc_iterations);
     }*/
-
   /*harq_pid = dlsch->current_harq_pid[proc->thread_id];
   if (harq_pid >= 8) {
     printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
     return(max_ldpc_iterations);
   }
   */
-
   nb_rb = harq_process->nb_rb;
   harq_process->trials[harq_process->round]++;
-
   // HARQ stats
   phy_vars_ue->dl_stats[harq_process->round]++;
-
   uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
-
   harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, 0, harq_process->Nl);
-
   A = harq_process->TBS;
-
   ret = dlsch->max_ldpc_iterations + 1;
   dlsch->last_iteration_cnt = ret;
-
   harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl);
-
   G = harq_process->G;
-
-  LOG_D(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d, nb_re_dmrs %d, length_dmrs %d  mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs, length_dmrs, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
-
+  LOG_D(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d, nb_re_dmrs %d, length_dmrs %d  mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs, length_dmrs, harq_process->mcs,
+        harq_process->Nl, nb_symb_sch,nb_rb);
   proc->decoder_main_available = 1;
   proc->decoder_thread_available = 0;
   proc->decoder_thread_available1 = 0;
 
-
   if ((harq_process->R)<1024)
     Coderate = (float) (harq_process->R) /(float) 1024;
   else
     Coderate = (float) (harq_process->R) /(float) 2048;
 
-  if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25)
-  {
+  if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) {
     p_decParams->BG = 2;
     kc = 52;
-    if (Coderate < 0.3333){
+
+    if (Coderate < 0.3333) {
       p_decParams->R = 15;
-    }
-    else if (Coderate <0.6667){
+    } else if (Coderate <0.6667) {
       p_decParams->R = 13;
-    }
-    else {
+    } else {
       p_decParams->R = 23;
     }
-  }
-  else{
+  } else {
     p_decParams->BG = 1;
     kc = 68;
-    if (Coderate < 0.6667){
+
+    if (Coderate < 0.6667) {
       p_decParams->R = 13;
-    }
-    else if (Coderate <0.8889){
+    } else if (Coderate <0.8889) {
       p_decParams->R = 23;
-    }
-    else {
+    } else {
       p_decParams->R = 89;
     }
   }
 
   if (harq_process->round == 0) {
-      // This is a new packet, so compute quantities regarding segmentation
+    // This is a new packet, so compute quantities regarding segmentation
     if (A > NR_MAX_PDSCH_TBS)
-	  	  harq_process->B = A+24;
-	  else
-	  	  harq_process->B = A+16;
-
-      nr_segmentation(NULL,
-                      NULL,
-                      harq_process->B,
-                      &harq_process->C,
-                      &harq_process->K,
-                      &harq_process->Z,
-                      &harq_process->F,
-                      p_decParams->BG);
-
+      harq_process->B = A+24;
+    else
+      harq_process->B = A+16;
 
-    }
-    
-    p_decParams->Z = harq_process->Z;
+    nr_segmentation(NULL,
+                    NULL,
+                    harq_process->B,
+                    &harq_process->C,
+                    &harq_process->K,
+                    &harq_process->Z,
+                    &harq_process->F,
+                    p_decParams->BG);
+  }
 
+  p_decParams->Z = harq_process->Z;
   p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
   p_decParams->outMode= 0;
-
   err_flag = 0;
   r_offset = 0;
-
   uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
 
   if (nb_rb != 273) {
     a_segments = a_segments*nb_rb;
     a_segments = a_segments/273 +1;
-  }  
+  }
 
   if (harq_process->C > a_segments) {
     LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
     return((1+dlsch->max_ldpc_iterations));
   }
+
   if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
     LOG_D(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
 
-
   notifiedFIFO_elt_t *res_dl;
   opp_enabled=1;
-  if (harq_process->C>1) {
-	for (int nb_seg =1 ; nb_seg<harq_process->C; nb_seg++){
-	  if ( (res_dl=tryPullTpool(&nf, &pool_dl)) != NULL ) {
-	          pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
-	        }
-
-	  AssertFatal((msgToPush_dl=pullNotifiedFIFO_nothreadSafe(&freeBlocks_dl)) != NULL,"chained list failure");
-          nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(msgToPush_dl);
-	  curMsg->UE=phy_vars_ue;
-	  
-	  nbDlProcessing++;
-
-
-	  memset(&curMsg->proc, 0, sizeof(curMsg->proc));
-	  curMsg->proc.frame_rx   = proc->frame_rx;
-	  curMsg->proc.nr_slot_rx = proc->nr_slot_rx;
-	  curMsg->proc.thread_id  = proc->thread_id;
-	  curMsg->proc.num_seg    = nb_seg;
-
-	  curMsg->proc.eNB_id= eNB_id;
-	  curMsg->proc.harq_pid=harq_pid;
-	  curMsg->proc.llr8_flag = llr8_flag;
-
-	  msgToPush_dl->key= (nr_slot_rx%2) ? (nb_seg+30): nb_seg;
-	  pushTpool(&pool_dl, msgToPush_dl);
 
-  /*Qm= harq_process->Qm;
-    Nl=harq_process->Nl;
-    r_thread = harq_process->C/2-1;
-    C= harq_process->C;
-
-    Gp = G/Nl/Qm;
-    GpmodC = Gp%C;
+  if (harq_process->C>1) {
+    for (int nb_seg =1 ; nb_seg<harq_process->C; nb_seg++) {
+      if ( (res_dl=tryPullTpool(&nf, &pool_dl)) != NULL ) {
+        pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
+      }
 
+      AssertFatal((msgToPush_dl=pullNotifiedFIFO_nothreadSafe(&freeBlocks_dl)) != NULL,"chained list failure");
+      nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(msgToPush_dl);
+      curMsg->UE=phy_vars_ue;
+      nbDlProcessing++;
+      memset(&curMsg->proc, 0, sizeof(curMsg->proc));
+      curMsg->proc.frame_rx   = proc->frame_rx;
+      curMsg->proc.nr_slot_rx = proc->nr_slot_rx;
+      curMsg->proc.thread_id  = proc->thread_id;
+      curMsg->proc.num_seg    = nb_seg;
+      curMsg->proc.eNB_id= eNB_id;
+      curMsg->proc.harq_pid=harq_pid;
+      curMsg->proc.llr8_flag = llr8_flag;
+      msgToPush_dl->key= (nr_slot_rx%2) ? (nb_seg+30): nb_seg;
+      pushTpool(&pool_dl, msgToPush_dl);
+      /*Qm= harq_process->Qm;
+        Nl=harq_process->Nl;
+        r_thread = harq_process->C/2-1;
+        C= harq_process->C;
+
+        Gp = G/Nl/Qm;
+        GpmodC = Gp%C;
+
+
+        if (r_thread < (C-(GpmodC)))
+          Er = Nl*Qm * (Gp/C);
+        else
+          Er = Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
+        printf("mthread Er %d\n", Er);
 
-    if (r_thread < (C-(GpmodC)))
-      Er = Nl*Qm * (Gp/C);
-    else
-      Er = Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
-    printf("mthread Er %d\n", Er);
+        printf("mthread instance_cnt_dlsch_td %d\n",  proc->instance_cnt_dlsch_td);*/
+    }
 
-    printf("mthread instance_cnt_dlsch_td %d\n",  proc->instance_cnt_dlsch_td);*/
-	  }
-  //proc->decoder_main_available = 1;
+    //proc->decoder_main_available = 1;
   }
 
-    r = 0;  
-    if (r==0) r_offset =0;
-
-    Kr = harq_process->K;
-    Kr_bytes = Kr>>3;
-    K_bits_F = Kr-harq_process->F;
+  r = 0;
 
-    E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
+  if (r==0) r_offset =0;
 
-    /*
-    printf("Subblock deinterleaving, dlsch_llr %p, w %p\n",
-     dlsch_llr+r_offset,
-     &harq_process->w[r]);
-    */
+  Kr = harq_process->K;
+  Kr_bytes = Kr>>3;
+  K_bits_F = Kr-harq_process->F;
+  E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
+  /*
+  printf("Subblock deinterleaving, dlsch_llr %p, w %p\n",
+   dlsch_llr+r_offset,
+   &harq_process->w[r]);
+  */
 #if UE_TIMING_TRACE
-    start_meas(dlsch_deinterleaving_stats);
+  start_meas(dlsch_deinterleaving_stats);
 #endif
-    nr_deinterleaving_ldpc(E,
-                           harq_process->Qm,
-                           harq_process->w[r],
-                           dlsch_llr+r_offset);
+  nr_deinterleaving_ldpc(E,
+                         harq_process->Qm,
+                         harq_process->w[r],
+                         dlsch_llr+r_offset);
 
-    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
-        for (int i =0; i<16; i++)
-              LOG_D(PHY,"rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+    for (int i =0; i<16; i++)
+      LOG_D(PHY,"rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
 
 #if UE_TIMING_TRACE
-    stop_meas(dlsch_deinterleaving_stats);
+  stop_meas(dlsch_deinterleaving_stats);
 #endif
-
 #if UE_TIMING_TRACE
-    start_meas(dlsch_rate_unmatching_stats);
+  start_meas(dlsch_rate_unmatching_stats);
 #endif
 
   if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
@@ -1003,137 +894,126 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
           harq_process->Nl,
           harq_process->rvidx,
           harq_process->round);
- 
 
-    // for tbslbrm calculation according to 5.4.2.1 of 38.212
-    if (harq_process->Nl < Nl)
-      Nl = harq_process->Nl;
-
-    Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
-
-    if (nr_rate_matching_ldpc_rx(Ilbrm,
-                                 Tbslbrm,
-                                 p_decParams->BG,
-                                 p_decParams->Z,
-                                 harq_process->d[r],
-                                 harq_process->w[r],
-                                 harq_process->C,
-                                 harq_process->rvidx,
-                                 (harq_process->round==0)?1:0,
-                                 E,
-				 harq_process->F,
-				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
+  // for tbslbrm calculation according to 5.4.2.1 of 38.212
+  if (harq_process->Nl < Nl)
+    Nl = harq_process->Nl;
+
+  Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
+
+  if (nr_rate_matching_ldpc_rx(Ilbrm,
+                               Tbslbrm,
+                               p_decParams->BG,
+                               p_decParams->Z,
+                               harq_process->d[r],
+                               harq_process->w[r],
+                               harq_process->C,
+                               harq_process->rvidx,
+                               (harq_process->round==0)?1:0,
+                               E,
+                               harq_process->F,
+                               Kr-harq_process->F-2*(p_decParams->Z))==-1) {
 #if UE_TIMING_TRACE
-      stop_meas(dlsch_rate_unmatching_stats);
+    stop_meas(dlsch_rate_unmatching_stats);
 #endif
-      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
-      return(dlsch->max_ldpc_iterations);
-    } else
-    {
+    LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
+    return(dlsch->max_ldpc_iterations);
+  } else {
 #if UE_TIMING_TRACE
-      stop_meas(dlsch_rate_unmatching_stats);
+    stop_meas(dlsch_rate_unmatching_stats);
 #endif
-    }
+  }
 
- 
-  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))   
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
     for (int i =0; i<16; i++)
       LOG_I(PHY,"rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset);
 
-
-  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) 
-    {
-
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
     if (r==0) {
       LOG_M("decoder_llr.m","decllr",dlsch_llr,G,1,0);
       LOG_M("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0);
     }
 
     LOG_D(PHY,"decoder input(segment %u) :",r);
-    for (int i=0;i<(3*8*Kr_bytes);i++)
+
+    for (int i=0; i<(3*8*Kr_bytes); i++)
       LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
-    LOG_D(PHY,"\n");
-   }
 
-    memset(harq_process->c[r],0,Kr_bytes);
+    LOG_D(PHY,"\n");
+  }
 
-    if (harq_process->C == 1){
-      if (A > NR_MAX_PDSCH_TBS)
-    	crc_type = CRC24_A;
-      else
-    	crc_type = CRC16;
+  memset(harq_process->c[r],0,Kr_bytes);
 
-      length_dec = harq_process->B;
-    }
-    else{
-      crc_type = CRC24_B;
-      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
-    }
+  if (harq_process->C == 1) {
+    if (A > NR_MAX_PDSCH_TBS)
+      crc_type = CRC24_A;
+    else
+      crc_type = CRC16;
 
-    //#ifndef __AVX2__
+    length_dec = harq_process->B;
+  } else {
+    crc_type = CRC24_B;
+    length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
+  }
 
-    if (err_flag == 0) {
-/*
-        LOG_D(PHY, "LDPC algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n",
-                            Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS,
-                            harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations);
-*/
+  //#ifndef __AVX2__
 
+  if (err_flag == 0) {
+    /*
+            LOG_D(PHY, "LDPC algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n",
+                                Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS,
+                                harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations);
+    */
 #if UE_TIMING_TRACE
-      start_meas(dlsch_turbo_decoding_stats);
+    start_meas(dlsch_turbo_decoding_stats);
 #endif
-      LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
-
-      /*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
-        inv_d[cnt] = (1)*harq_process->d[r][cnt];
-      }*/
-
-      //set first 2*Z_c bits to zeros
-      memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
-      //set Filler bits
-      memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t));
-      //Move coded bits before filler bits
-      memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t));
-      //skip filler bits
-      memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t));
-      //Saturate coded bits before decoding into 8 bits values
-      for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++)
-      {
-        pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
-      }
+    LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
+    /*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
+      inv_d[cnt] = (1)*harq_process->d[r][cnt];
+    }*/
+    //set first 2*Z_c bits to zeros
+    memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
+    //set Filler bits
+    memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t));
+    //Move coded bits before filler bits
+    memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t));
+    //skip filler bits
+    memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t));
+
+    //Saturate coded bits before decoding into 8 bits values
+    for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++) {
+      pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
+    }
 
-      no_iteration_ldpc = nrLDPC_decoder(p_decParams,
-               (int8_t*)&pl[0],
-               llrProcBuf,
-               p_nrLDPC_procBuf,
-               p_procTime);
+    no_iteration_ldpc = nrLDPC_decoder(p_decParams,
+                                       (int8_t *)&pl[0],
+                                       llrProcBuf,
+                                       p_nrLDPC_procBuf,
+                                       p_procTime);
+    nb_total_decod++;
 
-      nb_total_decod++;
-      if (no_iteration_ldpc > 10){
-        nb_error_decod++;
-        ret = 1+dlsch->max_ldpc_iterations;
-      }
-      else {
-        ret=2;
-      }
+    if (no_iteration_ldpc > 10) {
+      nb_error_decod++;
+      ret = 1+dlsch->max_ldpc_iterations;
+    } else {
+      ret=2;
+    }
 
-      if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
-        LOG_D(PHY,"Segment %u CRC OK\n",r);
-        ret = 2;
-      }
-      else {
-        LOG_D(PHY,"CRC NOK\n");
-        ret = 1+dlsch->max_ldpc_iterations;
-      }
+    if (check_crc((uint8_t *)llrProcBuf,length_dec,harq_process->F,crc_type)) {
+      LOG_D(PHY,"Segment %u CRC OK\n",r);
+      ret = 2;
+    } else {
+      ret = 1+dlsch->max_ldpc_iterations;
+    }
 
-    if (!nb_total_decod%10000){
-        printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout);
+    if (!nb_total_decod%10000) {
+      printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);
+      fflush(stdout);
     }
 
-      for (int m=0; m < Kr>>3; m ++)
-      {
-        harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
-      }
+    for (int m=0; m < Kr>>3; m ++) {
+      harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
+    }
 
     /*for (int u=0; u < Kr>>3; u ++)
       {
@@ -1151,30 +1031,27 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
     //printf("output channel decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
 
     //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
-     if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
-       for (int k=0;k<32;k++)
-         LOG_D(PHY,"output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
-
+    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+      for (int k=0; k<32; k++)
+        LOG_D(PHY,"output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
 
 #if UE_TIMING_TRACE
-      stop_meas(dlsch_turbo_decoding_stats);
+    stop_meas(dlsch_turbo_decoding_stats);
 #endif
-    }
+  }
 
+  if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
+    LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
+    err_flag = 1;
+  }
 
-    if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
-      LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
-      err_flag = 1;
-    }
   //} //loop r
 
   if (err_flag == 1) {
     if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
       LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
-        phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
-    harq_process->harq_ack.ack = 0;
-    harq_process->harq_ack.harq_id = harq_pid;
-    harq_process->harq_ack.send_harq_status = 1;
+            phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
+    harq_process->ack = 0;
     harq_process->errors[harq_process->round]++;
     harq_process->round++;
 
@@ -1182,130 +1059,112 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
       harq_process->status = SCH_IDLE;
       harq_process->round  = 0;
     }
-    if(is_crnti)
-    {
-    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
-               phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS);
+
+    if(is_crnti) {
+      LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
+            phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS);
     }
 
     return((1+dlsch->max_ldpc_iterations));
   } else {
-   if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
       LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d\n",
-           phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
+            phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
 
     harq_process->status = SCH_IDLE;
     harq_process->round  = 0;
-    harq_process->harq_ack.ack = 1;
-    harq_process->harq_ack.harq_id = harq_pid;
-    harq_process->harq_ack.send_harq_status = 1;
+    harq_process->ack = 1;
     //LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
-      //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);
+    //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);
 
-    if(is_crnti)
-    {
-    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->round,harq_process->TBS);
+    if(is_crnti) {
+      LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->round,harq_process->TBS);
     }
-    //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
 
+    //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
   }
 
   // Reassembly of Transport block here
   offset = 0;
-
   /*
   printf("harq_pid %d\n",harq_pid);
   printf("F %d, Fbytes %d\n",harq_process->F,harq_process->F>>3);
   printf("C %d\n",harq_process->C);
   */
   //uint32_t wait = 0;
-  
   /* while((proc->decoder_thread_available == 0) )
   {
           usleep(1);
   }
   proc->decoder_thread_available == 0;*/
-
   /*notifiedFIFO_elt_t *res1=tryPullTpool(&nf, Tpool);
   if (!res1) {
-	  printf("mthread trypull null\n");
-	  usleep(1);
-	  wait++;
+    printf("mthread trypull null\n");
+    usleep(1);
+    wait++;
   }*/
-  
   //usleep(50);
-
   proc->decoder_main_available = 0;
   Kr = harq_process->K; //to check if same K in all segments
   Kr_bytes = Kr>>3;
-  
-  for (r=0; r<harq_process->C; r++) {
 
-      memcpy(harq_process->b+offset,
-               harq_process->c[r],
-               Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
-      offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
+  for (r=0; r<harq_process->C; r++) {
+    memcpy(harq_process->b+offset,
+           harq_process->c[r],
+           Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
+    offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
 
-  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
-    {
-    LOG_I(PHY,"Segment %u : Kr= %u bytes\n",r,Kr_bytes);
-    LOG_I(PHY,"copied %d bytes to b sequence (harq_pid %d)\n",
-              (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
-     LOG_I(PHY,"b[0] = %p,c[%d] = %p\n",
-              (void *)(uint64_t)(harq_process->b[offset]),
-              harq_process->F>>3,
-               (void *)(uint64_t)(harq_process->c[r]));
+    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
+      LOG_I(PHY,"Segment %u : Kr= %u bytes\n",r,Kr_bytes);
+      LOG_I(PHY,"copied %d bytes to b sequence (harq_pid %d)\n",
+            (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
+      LOG_I(PHY,"b[0] = %p,c[%d] = %p\n",
+            (void *)(uint64_t)(harq_process->b[offset]),
+            harq_process->F>>3,
+            (void *)(uint64_t)(harq_process->c[r]));
     }
   }
-  
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
 
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
   dlsch->last_iteration_cnt = ret;
   //proc->decoder_thread_available = 0;
   //proc->decoder_main_available = 0;
-
   return(ret);
 }
 
 
 
-void nr_dlsch_decoding_process(void *arg)
-{
-	nr_rxtx_thread_data_t *rxtxD= (nr_rxtx_thread_data_t *)arg;
-    UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
-    PHY_VARS_NR_UE    *phy_vars_ue   = rxtxD->UE;
-    int llr8_flag1;
-    int32_t no_iteration_ldpc,length_dec;
-    t_nrLDPC_dec_params decParams;
-    t_nrLDPC_dec_params* p_decParams = &decParams;
-    t_nrLDPC_time_stats procTime;
-    t_nrLDPC_time_stats* p_procTime =&procTime ;
-    int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
-    t_nrLDPC_procBuf* p_nrLDPC_procBuf; 
-    int16_t z [68*384];
-    int8_t l [68*384];
-    //__m128i l;
-    //int16_t inv_d [68*384];
-    //int16_t *p_invd =&inv_d;
-    uint8_t  kc;
-    uint8_t Ilbrm = 1;
-    uint32_t Tbslbrm = 950984;
-    uint16_t nb_rb = 30; //to update
-    double Coderate = 0.0;
-    uint16_t nb_symb_sch = 12;
-    uint8_t nb_re_dmrs = 6;
-    uint16_t length_dmrs = 1;
-
-    uint32_t i,j;
-    __m128i *pv = (__m128i*)&z;
-    __m128i *pl = (__m128i*)&l;
-
-    proc->instance_cnt_dlsch_td=-1;
-    //proc->nr_slot_rx = proc->sub_frame_start * frame_parms->slots_per_subframe;
-
-    proc->decoder_thread_available = 1;
-    
-
+void nr_dlsch_decoding_process(void *arg) {
+  nr_rxtx_thread_data_t *rxtxD= (nr_rxtx_thread_data_t *)arg;
+  UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
+  PHY_VARS_NR_UE    *phy_vars_ue   = rxtxD->UE;
+  int llr8_flag1;
+  int32_t no_iteration_ldpc,length_dec;
+  t_nrLDPC_dec_params decParams;
+  t_nrLDPC_dec_params *p_decParams = &decParams;
+  t_nrLDPC_time_stats procTime;
+  t_nrLDPC_time_stats *p_procTime =&procTime ;
+  int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
+  t_nrLDPC_procBuf *p_nrLDPC_procBuf;
+  int16_t z [68*384];
+  int8_t l [68*384];
+  //__m128i l;
+  //int16_t inv_d [68*384];
+  //int16_t *p_invd =&inv_d;
+  uint8_t  kc;
+  uint8_t Ilbrm = 1;
+  uint32_t Tbslbrm = 950984;
+  uint16_t nb_rb = 30; //to update
+  double Coderate = 0.0;
+  uint16_t nb_symb_sch = 12;
+  uint8_t nb_re_dmrs = 6;
+  uint16_t length_dmrs = 1;
+  uint32_t i,j;
+  __m128i *pv = (__m128i *)&z;
+  __m128i *pl = (__m128i *)&l;
+  proc->instance_cnt_dlsch_td=-1;
+  //proc->nr_slot_rx = proc->sub_frame_start * frame_parms->slots_per_subframe;
+  proc->decoder_thread_available = 1;
 #if UE_TIMING_TRACE
   time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats;
   time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats;
@@ -1313,47 +1172,32 @@ void nr_dlsch_decoding_process(void *arg)
 #endif
   uint32_t A,E;
   uint32_t G;
-
   uint32_t ret;
   uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0,K_bits_F;
-
   uint8_t crc_type;
   uint8_t C,Cprime;
   uint8_t Qm;
   uint8_t Nl;
   //uint32_t Er;
-
   int eNB_id                = proc->eNB_id;
   int harq_pid              = proc->harq_pid;
   llr8_flag1                = proc->llr8_flag;
   int frame                 = proc->frame_rx;
-  r               	    = proc->num_seg;
-
+  r                     = proc->num_seg;
   NR_UE_DLSCH_t *dlsch      = phy_vars_ue->dlsch[proc->thread_id][eNB_id][0];
   NR_DL_UE_HARQ_t *harq_process  = dlsch->harq_processes[harq_pid];
   short *dlsch_llr        = phy_vars_ue->pdsch_vars[proc->thread_id][eNB_id]->llr[0];
-
   p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[r];
   nb_symb_sch = harq_process->nb_symbols;
   LOG_D(PHY,"dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_slot_rx, proc->num_seg, r, harq_process->nb_symbols);
-
-
   nb_rb = harq_process->nb_rb;
-
   harq_process->trials[harq_process->round]++;
-
   uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
-
   harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, 0, harq_process->Nl);
-
   A = harq_process->TBS; //2072 for QPSK 1/3
-
-
   ret = dlsch->max_ldpc_iterations;
-
   harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl);
   G = harq_process->G;
-
   LOG_D(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
 
   if ((harq_process->R)<1024)
@@ -1361,107 +1205,89 @@ void nr_dlsch_decoding_process(void *arg)
   else
     Coderate = (float) (harq_process->R) /(float) 2048;
 
-  if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25)
-  {
+  if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) {
     p_decParams->BG = 2;
     kc = 52;
-    if (Coderate < 0.3333){
+
+    if (Coderate < 0.3333) {
       p_decParams->R = 15;
-    }
-    else if (Coderate <0.6667){
+    } else if (Coderate <0.6667) {
       p_decParams->R = 13;
-    }
-    else {
+    } else {
       p_decParams->R = 23;
     }
-  }
-  else{
+  } else {
     p_decParams->BG = 1;
     kc = 68;
-    if (Coderate < 0.6667){
+
+    if (Coderate < 0.6667) {
       p_decParams->R = 13;
-    }
-    else if (Coderate <0.8889){
+    } else if (Coderate <0.8889) {
       p_decParams->R = 23;
-    }
-    else {
+    } else {
       p_decParams->R = 89;
     }
-  }    
+  }
 
   harq_process->round  =0;
- // if (harq_process->round == 0) {
-    // This is a new packet, so compute quantities regarding segmentation
-  if (A > NR_MAX_PDSCH_TBS)
-	  harq_process->B = A+24;
-	else
-	  harq_process->B = A+16;
-
-    nr_segmentation(NULL,
-                    NULL,
-                    harq_process->B,
-                    &harq_process->C,
-                    &harq_process->K,
-                    &harq_process->Z,
-                    &harq_process->F,
-                    p_decParams->BG);
-
-    p_decParams->Z = harq_process->Z;
-
-   // }
-    
-    LOG_D(PHY,"round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
-
 
+  // if (harq_process->round == 0) {
+  // This is a new packet, so compute quantities regarding segmentation
+  if (A > NR_MAX_PDSCH_TBS)
+    harq_process->B = A+24;
+  else
+    harq_process->B = A+16;
+
+  nr_segmentation(NULL,
+                  NULL,
+                  harq_process->B,
+                  &harq_process->C,
+                  &harq_process->K,
+                  &harq_process->Z,
+                  &harq_process->F,
+                  p_decParams->BG);
+  p_decParams->Z = harq_process->Z;
+  // }
+  LOG_D(PHY,"round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
   p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
   p_decParams->outMode= 0;
-
   err_flag = 0;
-
   opp_enabled=1;
-  
   Qm= harq_process->Qm;
   Nl=harq_process->Nl;
   //r_thread = harq_process->C/2-1;
   C= harq_process->C;
-
   Cprime = C; //assume CBGTI not present
 
   if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
     r_offset = Nl*Qm*(G/(Nl*Qm*Cprime));
   else
     r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
-          
-  //for (r=(harq_process->C/2); r<harq_process->C; r++) {
-     //    r=1; //(harq_process->C/2);
 
+  //for (r=(harq_process->C/2); r<harq_process->C; r++) {
+  //    r=1; //(harq_process->C/2);
   r_offset = r*r_offset;
-
   Kr = harq_process->K;
   Kr_bytes = Kr>>3;
   K_bits_F = Kr-harq_process->F;
-
   E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
-
 #if UE_TIMING_TRACE
-    start_meas(dlsch_deinterleaving_stats);
+  start_meas(dlsch_deinterleaving_stats);
 #endif
-    nr_deinterleaving_ldpc(E,
-                           harq_process->Qm,
-                           harq_process->w[r],
-                           dlsch_llr+r_offset);
+  nr_deinterleaving_ldpc(E,
+                         harq_process->Qm,
+                         harq_process->w[r],
+                         dlsch_llr+r_offset);
 
   if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
     for (int i =0; i<16; i++)
-              LOG_D(PHY,"rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
-
+      LOG_D(PHY,"rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
 
 #if UE_TIMING_TRACE
-    stop_meas(dlsch_deinterleaving_stats);
+  stop_meas(dlsch_deinterleaving_stats);
 #endif
-
 #if UE_TIMING_TRACE
-    start_meas(dlsch_rate_unmatching_stats);
+  start_meas(dlsch_rate_unmatching_stats);
 #endif
 
   if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
@@ -1475,134 +1301,128 @@ void nr_dlsch_decoding_process(void *arg)
           harq_process->rvidx,
           harq_process->round);
 
-
-    if (Nl<4)
-      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl);
-    else
-      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
-
-    if (nr_rate_matching_ldpc_rx(Ilbrm,
-                                 Tbslbrm,
-                                 p_decParams->BG,
-                                 p_decParams->Z,
-                                 harq_process->d[r],
-                                 harq_process->w[r],
-                                 harq_process->C,
-                                 harq_process->rvidx,
-                                 (harq_process->round==0)?1:0,
-                                 E,
-				 harq_process->F,
-				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
+  if (Nl<4)
+    Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl);
+  else
+    Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
+
+  if (nr_rate_matching_ldpc_rx(Ilbrm,
+                               Tbslbrm,
+                               p_decParams->BG,
+                               p_decParams->Z,
+                               harq_process->d[r],
+                               harq_process->w[r],
+                               harq_process->C,
+                               harq_process->rvidx,
+                               (harq_process->round==0)?1:0,
+                               E,
+                               harq_process->F,
+                               Kr-harq_process->F-2*(p_decParams->Z))==-1) {
 #if UE_TIMING_TRACE
-      stop_meas(dlsch_rate_unmatching_stats);
+    stop_meas(dlsch_rate_unmatching_stats);
 #endif
-      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
-      //return(dlsch->max_ldpc_iterations);
-    } else
-    {
+    LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
+    //return(dlsch->max_ldpc_iterations);
+  } else {
 #if UE_TIMING_TRACE
-      stop_meas(dlsch_rate_unmatching_stats);
+    stop_meas(dlsch_rate_unmatching_stats);
 #endif
-    }
+  }
 
-    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
-      LOG_D(PHY,"decoder input(segment %u) :",r);
-      for (int i=0;i<(3*8*Kr_bytes)+12;i++)
-        LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
-      LOG_D(PHY,"\n");
-    }
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
+    LOG_D(PHY,"decoder input(segment %u) :",r);
 
+    for (int i=0; i<(3*8*Kr_bytes)+12; i++)
+      LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
 
-    memset(harq_process->c[r],0,Kr_bytes);
+    LOG_D(PHY,"\n");
+  }
 
-    if (harq_process->C == 1){
-      if (A > NR_MAX_PDSCH_TBS)
-    	 	crc_type = CRC24_A;
-    	else
-    		crc_type = CRC16;
+  memset(harq_process->c[r],0,Kr_bytes);
 
-      length_dec = harq_process->B;
-    }
-    else{
-      crc_type = CRC24_B;
-      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
+  if (harq_process->C == 1) {
+    if (A > NR_MAX_PDSCH_TBS)
+      crc_type = CRC24_A;
+    else
+      crc_type = CRC16;
+
+    length_dec = harq_process->B;
+  } else {
+    crc_type = CRC24_B;
+    length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
+  }
+
+  if (err_flag == 0) {
+    /*
+            LOG_D(PHY, "LDPC algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n",
+                                Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS,
+                                harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations);
+    */
+    if (llr8_flag1) {
+      AssertFatal (Kr >= 256, "LDPC algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n",
+                   Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
     }
 
-    if (err_flag == 0) {
-/*
-        LOG_D(PHY, "LDPC algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n",
-                            Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS,
-                            harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations);
-*/
-      if (llr8_flag1) {
-        AssertFatal (Kr >= 256, "LDPC algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n",
-            Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
-      }
 #if UE_TIMING_TRACE
-        start_meas(dlsch_turbo_decoding_stats);
+    start_meas(dlsch_turbo_decoding_stats);
 #endif
-//      LOG_D(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
-/*
-        for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
-              inv_d[cnt] = (1)*harq_process->d[r][cnt];
-              }
-*/
-
-        //set first 2*Z_c bits to zeros
-        memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
-        //set Filler bits
-        memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t));
-        //Move coded bits before filler bits
-        memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t));
-        //skip filler bits
-        memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t));
-        //Saturate coded bits before decoding into 8 bits values
-        for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++)
-        {
-          pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
-        }
+    //      LOG_D(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
+    /*
+            for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
+                  inv_d[cnt] = (1)*harq_process->d[r][cnt];
+                  }
+    */
+    //set first 2*Z_c bits to zeros
+    memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
+    //set Filler bits
+    memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t));
+    //Move coded bits before filler bits
+    memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t));
+    //skip filler bits
+    memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t));
+
+    //Saturate coded bits before decoding into 8 bits values
+    for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++) {
+      pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
+    }
 
-        no_iteration_ldpc = nrLDPC_decoder(p_decParams,
-                                           (int8_t*)&pl[0],
-                                           llrProcBuf,
-                                           p_nrLDPC_procBuf,
-                                           p_procTime);
+    no_iteration_ldpc = nrLDPC_decoder(p_decParams,
+                                       (int8_t *)&pl[0],
+                                       llrProcBuf,
+                                       p_nrLDPC_procBuf,
+                                       p_procTime);
 
-        // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
-        if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
-          LOG_D(PHY,"Segment %u CRC OK\n",r);
-          ret = 2;
-        }
-        else {
-          LOG_D(PHY,"Segment %u CRC NOK\n",r);
-          ret = 1+dlsch->max_ldpc_iterations;
-        }
+    // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
+    if (check_crc((uint8_t *)llrProcBuf,length_dec,harq_process->F,crc_type)) {
+      LOG_D(PHY,"Segment %u CRC OK\n",r);
+      ret = 2;
+    } else {
+      LOG_D(PHY,"Segment %u CRC NOK\n",r);
+      ret = 1+dlsch->max_ldpc_iterations;
+    }
 
     if (no_iteration_ldpc > 10)
       LOG_D(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc);
 
+    for (int m=0; m < Kr>>3; m ++) {
+      harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
+    }
 
-    for (int m=0; m < Kr>>3; m ++)
-                    {
-                  harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
-                    }
-
-    if ( LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))       
-      for (int k=0;k<2;k++)
+    if ( LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+      for (int k=0; k<2; k++)
         LOG_D(PHY,"segment 1 output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
 
-    
 #if UE_TIMING_TRACE
-      stop_meas(dlsch_turbo_decoding_stats);
+    stop_meas(dlsch_turbo_decoding_stats);
 #endif
-    }
+  }
 
-    if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
-//      LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
-      err_flag = 1;
-    }
-  //}
+  if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
+    //      LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
+    err_flag = 1;
+  }
 
+  //}
   proc->decoder_thread_available = 1;
   //proc->decoder_main_available = 0;
 }
@@ -1614,12 +1434,12 @@ void *dlsch_thread(void *arg) {
   notifiedFIFO_elt_t *res_dl;
   initNotifiedFIFO_nothreadSafe(&freeBlocks_dl);
 
-  for (int i=0; i<tpool_nbthreads(pool_dl)+1; i++){
+  for (int i=0; i<tpool_nbthreads(pool_dl)+1; i++) {
     pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,
-                                  newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), 0,&nf,nr_dlsch_decoding_process));}
+                                  newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), 0,&nf,nr_dlsch_decoding_process));
+  }
 
   while (!oai_exit) {
-
     notifiedFIFO_elt_t *res;
 
     while (nbDlProcessing >= tpool_nbthreads(pool_dl)) {
@@ -1630,15 +1450,12 @@ void *dlsch_thread(void *arg) {
 
       usleep(200);
     }
-    
+
     res_dl=pullTpool(&nf, &pool_dl);
     nbDlProcessing--;
-	pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
-    
-
+    pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
     //msgToPush->key=0;
     //pushTpool(Tpool, msgToPush);
-
   } // while !oai_exit
 
   return NULL;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 9a312572446043504821cd77c152541d29e77f39..34eb29d4f1eaf498c6f725e8e737da45508dba90 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -52,7 +52,7 @@
  * set as command line argument, see lte-softmodem.c
  * default value: 0
  */
-int16_t nr_dlsch_demod_shift = 0;
+int32_t nr_dlsch_demod_shift = 0;
 //int16_t interf_unaw_shift = 13;
 
 //#define DEBUG_HARQ
@@ -84,8 +84,8 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{
  */
 //unsigned char offset_mumimo_llr_drange[29][3]= {{0, 6, 5},{0, 4, 5},{0, 4, 5},{0, 5, 4},{0, 5, 6},{0, 5, 3},{0, 4, 4},{0, 4, 4},{0, 3, 3},{0, 1, 2},{1, 1, 0},{1, 3, 2},{3, 4, 1},{2, 0, 0},{2, 2, 2},{1, 1, 1},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}};
 
-
-extern void print_shorts(char *s,int16_t *x);
+#define print_ints(s,x) printf("%s = %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3])
+#define print_shorts(s,x) printf("%s = [%d+j*%d, %d+j*%d, %d+j*%d, %d+j*%d]\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
 
 static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
 						  int **dl_ch_estimates_ext_i,
@@ -96,10 +96,24 @@ static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
 						  int length,
 						  int start_point);
 
+uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
+                                   int **dl_ch_mag,
+                                   int **dl_ch_magb,
+                                   int **dl_ch_magr,
+                                   int **dl_ch_estimates_ext,
+                                   unsigned short nb_rb,
+                                   unsigned char n_rx,
+                                   unsigned char mod_order,
+                                   int shift,
+                                   unsigned char symbol,
+                                   int length);
+
 static void nr_dlsch_layer_demapping(int16_t **llr_cw,
 				     uint8_t Nl,
 				     uint8_t mod_order,
-				     uint16_t length,
+				     uint32_t length,
+				     int32_t codeword_TB0,
+				     int32_t codeword_TB1,
 				     int16_t **llr_layers);
 
 
@@ -113,7 +127,7 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         RX_type_t rx_type,
                         unsigned char harq_pid,
                         unsigned char gNB_id,
-                        unsigned char eNB_id_i,
+                        unsigned char gNB_id_i,
                         unsigned char first_symbol_flag,
                         unsigned char symbol,
                         unsigned short nb_rb,
@@ -129,7 +143,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                 UE_nr_rxtx_proc_t *proc,
                 PDSCH_t type,
                 unsigned char gNB_id,
-                unsigned char eNB_id_i, //if this == ue->n_connected_gNB, we assume MU interference
+                unsigned char gNB_id_i,
                 uint32_t frame,
                 uint8_t nr_slot_rx,
                 unsigned char symbol,
@@ -145,7 +159,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   PHY_NR_MEASUREMENTS *measurements = &ue->measurements;
   NR_UE_DLSCH_t   **dlsch;
 
-  int avg[4];
+  int avg[16];
 //  int avg_0[2];
 //  int avg_1[2];
 
@@ -172,8 +186,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   //int16_t  *pllr_symbol_cw0_deint;
   //int16_t  *pllr_symbol_cw1_deint;
   //uint16_t bundle_L = 2;
-  uint8_t pilots=0;
-  uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
   uint16_t n_tx=1, n_rx=1;
   int32_t median[16];
   uint32_t len;
@@ -330,123 +342,79 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   printf("Demod  dlsch0_harq->pmi_alloc %d\n",  dlsch0_harq->pmi_alloc);
 #endif
 
-  pilots = ((1<<symbol)&dlsch0_harq->dlDmrsSymbPos)>0 ? 1 : 0;
-
-  if (frame_parms->nb_antenna_ports_gNB>1 && beamforming_mode==0) {
-#ifdef DEBUG_DLSCH_MOD
-    LOG_I(PHY,"dlsch: using pmi %x (%p)\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch[0]);
-#endif
+  uint8_t pilots = (dlsch0_harq->dlDmrsSymbPos >> symbol) & 1;
+  uint8_t config_type = dlsch0_harq->dmrsConfigType;
 
+  if (beamforming_mode==0) {//No beamforming
 #if UE_TIMING_TRACE
     start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
 #endif
-    nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
-				      pdsch_vars[gNB_id]->dl_ch_estimates,
-				      pdsch_vars[gNB_id]->rxdataF_ext,
-				      pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-				      dlsch0_harq->pmi_alloc,
-				      pdsch_vars[gNB_id]->pmi_ext,
-				      symbol,
-				      pilots,
-				      start_rb,
-				      nb_rb_pdsch,
-				      nr_slot_rx,
-				      ue->high_speed_flag,
-				      frame_parms,
-				      dlsch0_harq->mimo_mode);
-#ifdef DEBUG_DLSCH_MOD
-      printf("dlsch: using pmi %lx, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc));
-       for (rb=0;rb<nb_rb;rb++)
-          printf("%d",pdsch_vars[gNB_id]->pmi_ext[rb]);
-       printf("\n");
-#endif
-
-   if (rx_type >= rx_IC_single_stream) {
-      if (eNB_id_i < ue->n_connected_gNB) // we are in TM5
-      nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
-    		  	  	  	  	  	       pdsch_vars[gNB_id]->dl_ch_estimates,
-                                       pdsch_vars[eNB_id_i]->rxdataF_ext,
-                                       pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
-                                       dlsch0_harq->pmi_alloc,
-                                       pdsch_vars[eNB_id_i]->pmi_ext,
-                                       symbol,
-                                       pilots,
-                                       start_rb,
-                                       nb_rb_pdsch,
-                                       nr_slot_rx,
-                                       ue->high_speed_flag,
-                                       frame_parms,
-                                       dlsch0_harq->mimo_mode);
-      else
-        nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
-        							   pdsch_vars[gNB_id]->dl_ch_estimates,
-                                       pdsch_vars[eNB_id_i]->rxdataF_ext,
-                                       pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
-                                       dlsch0_harq->pmi_alloc,
-                                       pdsch_vars[eNB_id_i]->pmi_ext,
-                                       symbol,
-                                       pilots,
-                                       start_rb,
-                                       nb_rb_pdsch,
-                                       nr_slot_rx,
-                                       ue->high_speed_flag,
-                                       frame_parms,
-                                       dlsch0_harq->mimo_mode);
-    }
-  } else if (beamforming_mode==0) { //else if nb_antennas_ports_gNB==1 && beamforming_mode == 0
-		  //printf("start nr dlsch extract nr_slot_rx %d thread id %d \n", nr_slot_rx, proc->thread_id);
-    nb_rb = nr_dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
-					pdsch_vars[gNB_id]->dl_ch_estimates,
-					pdsch_vars[gNB_id]->rxdataF_ext,
-					pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-					dlsch0_harq->pmi_alloc,
-					pdsch_vars[gNB_id]->pmi_ext,
-					symbol,
-					pilots,
-					config_type,
-					start_rb + dlsch0_harq->BWPStart,
-					nb_rb_pdsch,
-					nr_slot_rx,
-					ue->high_speed_flag,
-                                        frame_parms,
-                                        dlsch0_harq->dlDmrsSymbPos);
-  
-  } /*else if(beamforming_mode>7) {
+    if (dlsch0_harq->Nl > 1)//More than or equal 2 layers
+      nb_rb = nr_dlsch_extract_rbs_multiple(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
+                                            pdsch_vars[gNB_id]->dl_ch_estimates,
+                                            pdsch_vars[gNB_id]->rxdataF_ext,
+                                            pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                                            symbol,
+                                            pilots,
+                                            config_type,
+                                            start_rb + dlsch0_harq->BWPStart,
+                                            nb_rb_pdsch,
+                                            dlsch0_harq->n_dmrs_cdm_groups,
+                                            dlsch0_harq->Nl,
+                                            frame_parms,
+                                            dlsch0_harq->dlDmrsSymbPos);
+    else// one layer
+      nb_rb = nr_dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
+                                          pdsch_vars[gNB_id]->dl_ch_estimates,
+                                          pdsch_vars[gNB_id]->rxdataF_ext,
+                                          pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                                          symbol,
+                                          pilots,
+                                          config_type,
+                                          start_rb + dlsch0_harq->BWPStart,
+                                          nb_rb_pdsch,
+                                          dlsch0_harq->n_dmrs_cdm_groups,
+                                          frame_parms,
+                                          dlsch0_harq->dlDmrsSymbPos);
+  }
+  else if(beamforming_mode>7) {
     LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n");
-  }*/
-
+  }
+  
   //printf("nb_rb = %d, gNB_id %d\n",nb_rb,gNB_id);
   if (nb_rb==0) {
     LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n");
     return(-1);
   }
 
-  len = (pilots==1)? ((config_type==pdsch_dmrs_type1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12);
+  len = (pilots==1)? ((config_type==NFAPI_NR_DMRS_TYPE1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12);
 
 #if UE_TIMING_TRACE
   stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
 #if DISABLE_LOG_X
-  printf("[AbsSFN %u.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",
-	 frame,nr_slot_rx,slot,symbol,ue->high_speed_flag,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
+  printf("[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n",
+	 frame,nr_slot_rx,slot,symbol,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
 #else
-  LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",
-	frame,nr_slot_rx,slot,symbol,ue->high_speed_flag,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
+  LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n",
+	frame,nr_slot_rx,slot,symbol,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
 #endif
 #endif
   
 #if UE_TIMING_TRACE
   start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
 #endif
-  n_tx = frame_parms->nb_antenna_ports_gNB;
+  n_tx = dlsch0_harq->Nl;
   n_rx = frame_parms->nb_antennas_rx;
   
   nr_dlsch_scale_channel(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-			 frame_parms,
-			 dlsch,
-			 symbol,
-			 pilots,
-			 len,
-			 nb_rb);
+                         frame_parms,
+                         n_tx,
+                         n_rx,
+                         dlsch,
+                         symbol,
+                         pilots,
+                         len,
+                         nb_rb_pdsch);
 
 #if UE_TIMING_TRACE
     stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
@@ -462,42 +430,40 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
 #endif
   if (first_symbol_flag==1) {
     if (beamforming_mode==0){
-      if (dlsch0_harq->mimo_mode<NR_DUALSTREAM) {
-        nr_dlsch_channel_level(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-			       frame_parms,
-			       avg,
-			       symbol,
-			       len,
-			       nb_rb);
-        avgs = 0;
-        for (aatx=0;aatx<frame_parms->nb_antenna_ports_gNB;aatx++)
-          for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
-            avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
-
-        pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2)+3;
-     }
-     else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM)
-     {
-    	 nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-    	                             median,
-    	                             n_tx,
-    	                             n_rx,
-    	                             2*len,// subcarriers Re Im
-    	                             0);
-
-    	  for (aatx = 0; aatx < n_tx; ++aatx)
-    	  {
-    	    for (aarx = 0; aarx < n_rx; ++aarx)
-    	    {
-    	      avgs = cmax(avgs, median[aatx*n_rx + aarx]);
-    	    }
-    	  }
-
-    	  pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; // this might need to be tuned
-
-     }
+      nr_dlsch_channel_level(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                             frame_parms,
+                             n_tx,
+                             avg,
+                             symbol,
+                             len,
+                             nb_rb_pdsch);
+      avgs = 0;
+      for (aatx=0;aatx<n_tx;aatx++)
+        for (aarx=0;aarx<n_rx;aarx++) {
+          //LOG_I(PHY, "nb_rb %d len %d avg_%d_%d Power per SC is %d\n",nb_rb, len,aarx, aatx,avg[aatx*frame_parms->nb_antennas_rx+aarx]);
+          avgs = cmax(avgs,avg[(aatx*frame_parms->nb_antennas_rx)+aarx]);
+          //LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
+          median[(aatx*frame_parms->nb_antennas_rx)+aarx] = avg[(aatx*frame_parms->nb_antennas_rx)+aarx];
+        }
+      pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
+      //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs,  pdsch_vars[gNB_id]->log2_maxh);
+
+      if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
+        nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                                      median,
+                                      n_tx,
+                                      n_rx,
+                                      len,
+                                      symbol*nb_rb*12);
+
+        for (aatx = 0; aatx < n_tx; aatx++) {
+          for (aarx = 0; aarx < n_rx; aarx++) {
+            avgs = cmax(avgs, median[aatx*n_rx + aarx]);
+          }
+        }
+        pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
+      }
     }
-    //#ifdef UE_DEBUG_TRACE
     LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",
           frame%1024,
           nr_slot_rx,
@@ -506,22 +472,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
           pdsch_vars[gNB_id]->log2_maxh1,
           avg[0],
           avgs);
-    //LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
-    //#endif
-
-    //wait until pdcch is decoded
-    //proc->channel_level = 1;
   }
 
-  /*
-  uint32_t wait = 0;
-  while(proc->channel_level == 0)
-  {
-      usleep(1);
-      wait++;
-  }
-  */
-
 #if T_TRACER
     if (type == PDSCH)
     {
@@ -546,58 +498,25 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
 // Now channel compensation
   if (dlsch0_harq->mimo_mode<NR_DUALSTREAM) {
     nr_dlsch_channel_compensation(pdsch_vars[gNB_id]->rxdataF_ext,
-                               pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                               pdsch_vars[gNB_id]->dl_ch_mag0,
-                               pdsch_vars[gNB_id]->dl_ch_magb0,
-                               pdsch_vars[gNB_id]->dl_ch_magr0,
-                               pdsch_vars[gNB_id]->rxdataF_comp0,
-                               (aatx>1) ? pdsch_vars[gNB_id]->rho : NULL,
-                               frame_parms,
-                               symbol,
-                               pilots,
-                               first_symbol_flag,
-                               dlsch0_harq->Qm,
-                               nb_rb,
-                               pdsch_vars[gNB_id]->log2_maxh,
-                               measurements); // log2_maxh+I0_shift
- /*if (symbol == 5) {
-     write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[gNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
- } */
-
-    /*if ((rx_type==rx_IC_single_stream) &&
-        (eNB_id_i<ue->n_connected_gNB)) {
-         nr_dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext,
-                                 pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
-                                 pdsch_vars[eNB_id_i]->dl_ch_mag0,
-                                 pdsch_vars[eNB_id_i]->dl_ch_magb0,
-                                 pdsch_vars[eNB_id_i]->rxdataF_comp0,
-                                 (aatx>1) ? pdsch_vars[eNB_id_i]->rho : NULL,
-                                 frame_parms,
-                                 symbol,
-                                 first_symbol_flag,
-                                 i_mod,
-                                 nb_rb,
-                                 pdsch_vars[gNB_id]->log2_maxh,
-                                 measurements); // log2_maxh+I0_shift
-#ifdef DEBUG_PHY
-      if (symbol == 5) {
-        write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[gNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
-        write_output("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
-      }
-#endif
-
-      dlsch_dual_stream_correlation(frame_parms,
-                                    symbol,
-                                    nb_rb,
-                                    pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                    pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
-                                    pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                    pdsch_vars[gNB_id]->log2_maxh);
-    }*/
-  }
+                                  pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                                  pdsch_vars[gNB_id]->dl_ch_mag0,
+                                  pdsch_vars[gNB_id]->dl_ch_magb0,
+                                  pdsch_vars[gNB_id]->dl_ch_magr0,
+                                  pdsch_vars[gNB_id]->rxdataF_comp0,
+                                  (n_tx>1) ? pdsch_vars[gNB_id]->rho : NULL,
+                                  frame_parms,
+                                  n_tx,
+                                  symbol,
+                                  len,
+                                  first_symbol_flag,
+                                  dlsch0_harq->Qm,
+                                  nb_rb_pdsch,
+                                  pdsch_vars[gNB_id]->log2_maxh,
+                                  measurements); // log2_maxh+I0_shift
+    }
 
-  else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){
-	  nr_dlsch_channel_compensation_core(pdsch_vars[gNB_id]->rxdataF_ext,
+  else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
+    nr_dlsch_channel_compensation_core(pdsch_vars[gNB_id]->rxdataF_ext,
                                        pdsch_vars[gNB_id]->dl_ch_estimates_ext,
                                        pdsch_vars[gNB_id]->dl_ch_mag0,
                                        pdsch_vars[gNB_id]->dl_ch_magb0,
@@ -609,40 +528,16 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                                        pdsch_vars[gNB_id]->log2_maxh,
                                        2*len, // subcarriers Re Im
                                        0); // we start from the beginning of the vector
-  /*   if (symbol == 5) {
-     write_output("rxF_comp_d00.m","rxF_c_d00",&pdsch_vars[gNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM
-     write_output("rxF_comp_d01.m","rxF_c_d01",&pdsch_vars[gNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
-     write_output("rxF_comp_d10.m","rxF_c_d10",&pdsch_vars[gNB_id]->rxdataF_comp1[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
-     write_output("rxF_comp_d11.m","rxF_c_d11",&pdsch_vars[gNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM
-        } */
-      // compute correlation between signal and interference channels (rho12 and rho21)
-        nr_dlsch_dual_stream_correlation_core(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                              &(pdsch_vars[gNB_id]->dl_ch_estimates_ext[2]),
-                                              pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                              n_tx,
-                                              n_rx,
-                                              pdsch_vars[gNB_id]->log2_maxh,
-                                              2*len,
-                                              0);
-        //printf("rho stream1 =%d\n", &pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round] );
-        nr_dlsch_dual_stream_correlation_core(&(pdsch_vars[gNB_id]->dl_ch_estimates_ext[2]),
-                                              pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                              pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                              n_tx,
-                                              n_rx,
-                                              pdsch_vars[gNB_id]->log2_maxh,
-                                              2*len,
-                                              0);
-    //  printf("rho stream2 =%d\n",&pdsch_vars[gNB_id]->dl_ch_rho2_ext );
-      //printf("TM3 log2_maxh : %d\n",pdsch_vars[gNB_id]->log2_maxh);
-  /*     if (symbol == 5) {
-     write_output("rho0_0.m","rho0_0",&pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM
-     write_output("rho2_0.m","rho2_0",&pdsch_vars[gNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
-     write_output("rho0_1.m.m","rho0_1",&pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
-     write_output("rho2_1.m","rho2_1",&pdsch_vars[gNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM
-        } */
-
-    }
+    // compute correlation between signal and interference channels (rho12 and rho21)
+    nr_dlsch_dual_stream_correlation_core(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                                          &(pdsch_vars[gNB_id]->dl_ch_estimates_ext[2]),
+                                          pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
+                                          n_tx,
+                                          n_rx,
+                                          pdsch_vars[gNB_id]->log2_maxh,
+                                          2*len,
+                                          0);
+  }
 
 #if UE_TIMING_TRACE
     stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
@@ -657,35 +552,54 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
 #endif
 
-    if (frame_parms->nb_antennas_rx > 1) {
-    if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){
-        nr_dlsch_detection_mrc_core(pdsch_vars[gNB_id]->rxdataF_comp0,
-                                    NULL,
-                                    pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                    pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                    pdsch_vars[gNB_id]->dl_ch_mag0,
-                                    pdsch_vars[gNB_id]->dl_ch_magb0,
-                                    NULL,
-                                    NULL,
-                                    n_tx,
-                                    n_rx,
-                                    2*len,
-                                    0);
-    /*   if (symbol == 5) {
-     write_output("rho0_mrc.m","rho0_0",&pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM
-     write_output("rho2_mrc.m","rho2_0",&pdsch_vars[gNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
-        } */
+  if (frame_parms->nb_antennas_rx > 1) {
+    if (dlsch0_harq->mimo_mode<NR_DUALSTREAM) {
+      nr_dlsch_detection_mrc(pdsch_vars[gNB_id]->rxdataF_comp0,
+                             (n_tx>1)? pdsch_vars[gNB_id]->rho : NULL,
+                             pdsch_vars[gNB_id]->dl_ch_mag0,
+                             pdsch_vars[gNB_id]->dl_ch_magb0,
+                             pdsch_vars[gNB_id]->dl_ch_magr0,
+                             n_tx,
+                             n_rx,
+                             symbol,
+                             nb_rb_pdsch,
+                             len);
+      if (n_tx == 2)//Apply zero forcing for 2 Tx layers
+        nr_zero_forcing_rx_2layers(pdsch_vars[gNB_id]->rxdataF_comp0,
+                                   pdsch_vars[gNB_id]->dl_ch_mag0,
+                                   pdsch_vars[gNB_id]->dl_ch_magb0,
+                                   pdsch_vars[gNB_id]->dl_ch_magr0,
+                                   pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                                   nb_rb_pdsch,
+                                   n_rx,
+                                   dlsch0_harq->Qm,
+                                   pdsch_vars[gNB_id]->log2_maxh,
+                                   symbol,
+                                   len);
     }
+    else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
+      nr_dlsch_detection_mrc_core(pdsch_vars[gNB_id]->rxdataF_comp0,
+                                  NULL,
+                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
+                                  pdsch_vars[gNB_id]->dl_ch_rho2_ext,
+                                  pdsch_vars[gNB_id]->dl_ch_mag0,
+                                  pdsch_vars[gNB_id]->dl_ch_magb0,
+                                  NULL,
+                                  NULL,
+                                  n_tx,
+                                  n_rx,
+                                  2*len,
+                                  0);
     }
-
-      //printf("start compute LLR\n");
+  }
+  //printf("start compute LLR\n");
   if (dlsch0_harq->mimo_mode == NR_DUALSTREAM)  {
     rxdataF_comp_ptr = pdsch_vars[gNB_id]->rxdataF_comp1[harq_pid][round];
     dl_ch_mag_ptr = pdsch_vars[gNB_id]->dl_ch_mag1[harq_pid][round];
   }
   else {
-    rxdataF_comp_ptr = pdsch_vars[eNB_id_i]->rxdataF_comp0;
-    dl_ch_mag_ptr = pdsch_vars[eNB_id_i]->dl_ch_mag0;
+    rxdataF_comp_ptr = pdsch_vars[gNB_id_i]->rxdataF_comp0;
+    dl_ch_mag_ptr = pdsch_vars[gNB_id_i]->dl_ch_mag0;
     //i_mod should have been passed as a parameter
   }
   
@@ -727,14 +641,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                                nr_slot_rx,
                                symbol,
                                (nb_rb*12),
-                               harq_pid,
                                dlsch[0]->rnti,rx_type);
       pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol];
     }
 
     /* at last symbol in a slot calculate LLR's for whole slot */
     if(symbol == (startSymbIdx + nbSymb -1)) {
-      for(uint8_t i =startSymbIdx; i <= nbSymb;i++) {
+      for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) {
         /* re evaluating the first symbol flag as LLR's are done in symbol loop  */
         if(i == startSymbIdx && i < 3) {
           first_symbol_flag =1;
@@ -747,23 +660,36 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                      rxdataF_comp_ptr, dl_ch_mag_ptr,
                      dlsch0_harq, dlsch1_harq,
                      rx_type, harq_pid,
-                     gNB_id, eNB_id_i,
+                     gNB_id, gNB_id_i,
                      first_symbol_flag,
                      i, nb_rb, round,
                      codeword_TB0, codeword_TB1,
                      pdsch_vars[gNB_id]->dl_valid_re[i-1],
                      nr_slot_rx, beamforming_mode);
       }
-    }
-
-  //nr_dlsch_deinterleaving(symbol,bundle_L,(int16_t*)pllr_symbol_cw0,(int16_t*)pllr_symbol_cw0_deint, nb_rb_pdsch);
 
-    if (rx_type==rx_IC_dual_stream) {
+      int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType;
+      uint8_t nb_re_dmrs;
+      uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos);
+      if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
+        nb_re_dmrs = 6*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
+      } else {
+        nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
+      }
+      dlsch[0]->harq_processes[harq_pid]->G = nr_get_G(dlsch[0]->harq_processes[harq_pid]->nb_rb,
+                                                       dlsch[0]->harq_processes[harq_pid]->nb_symbols,
+                                                       nb_re_dmrs,
+                                                       dmrs_len,
+                                                       dlsch[0]->harq_processes[harq_pid]->Qm,
+                                                       dlsch[0]->harq_processes[harq_pid]->Nl);
       nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr,
                                dlsch[0]->harq_processes[harq_pid]->Nl,
                                dlsch[0]->harq_processes[harq_pid]->Qm,
                                dlsch[0]->harq_processes[harq_pid]->G,
+                               codeword_TB0,
+                               codeword_TB1,
                                pdsch_vars[gNB_id]->layer_llr);
+
     }
 
 #if UE_TIMING_TRACE
@@ -868,10 +794,11 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
                                 int **dl_ch_magb,
                                 int **dl_ch_magr,
                                 int **rxdataF_comp,
-                                int **rho,
+                                int ***rho,
                                 NR_DL_FRAME_PARMS *frame_parms,
+                                uint8_t nb_aatx,
                                 unsigned char symbol,
-				uint8_t pilots,
+                                int length,
                                 uint8_t first_symbol_flag,
                                 unsigned char mod_order,
                                 unsigned short nb_rb,
@@ -882,12 +809,12 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
 #if defined(__i386) || defined(__x86_64)
 
   unsigned short rb;
-  unsigned char aatx,aarx;
+  unsigned char aatx,aarx,atx;
   __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*dl_ch_mag128r,*rxdataF128,*rxdataF_comp128,*rho128;
-  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b,QAM_amp128r;
-  QAM_amp128b = _mm_setzero_si128();
+  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0},QAM_amp128b={0},QAM_amp128r={0};
 
-  for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++) {
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
+  for (aatx=0; aatx<nb_aatx; aatx++) {
     if (mod_order == 4) {
       QAM_amp128 = _mm_set1_epi16(QAM16_n1);  // 2/sqrt(10)
       QAM_amp128b = _mm_setzero_si128();
@@ -906,15 +833,14 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
 
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
-      dl_ch128          = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12];
-      dl_ch_mag128      = (__m128i *)&dl_ch_mag[(aatx<<1)+aarx][symbol*nb_rb*12];
-      dl_ch_mag128b     = (__m128i *)&dl_ch_magb[(aatx<<1)+aarx][symbol*nb_rb*12];
-      dl_ch_mag128r     = (__m128i *)&dl_ch_magr[(aatx<<1)+aarx][symbol*nb_rb*12];
+      dl_ch128          = (__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
+      dl_ch_mag128      = (__m128i *)&dl_ch_mag[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
+      dl_ch_mag128b     = (__m128i *)&dl_ch_magb[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
+      dl_ch_mag128r     = (__m128i *)&dl_ch_magr[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
       rxdataF128        = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12];
-      rxdataF_comp128   = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*nb_rb*12];
+      rxdataF_comp128   = (__m128i *)&rxdataF_comp[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
 
-
-      for (rb=0; rb<nb_rb; rb++) {
+      for (rb=0; rb<nb_rb_0; rb++) {
         if (mod_order>2) {
           // get channel amplitude if not QPSK
 
@@ -924,7 +850,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
           mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]);
           mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
 
-          mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1);
+          mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); //|H[0]|^2 |H[1]|^2 |H[2]|^2 |H[3]|^2 |H[4]|^2 |H[5]|^2 |H[6]|^2 |H[7]|^2
 
           // store channel magnitude here in a new field of dlsch
 
@@ -933,6 +859,13 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
           dl_ch_mag128r[0] = dl_ch_mag128[0];
           dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128);
           dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1);
+
+          dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b);
+          dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1);
+
+          dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r);
+          dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1);
+
     //print_ints("Re(ch):",(int16_t*)&mmtmpD0);
     //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128);
     //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]);
@@ -942,39 +875,28 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
           dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128);
           dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1);
 
-          if (pilots==0) {
-            mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]);
-            mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
-            mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);
-
-            dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);
-            dl_ch_mag128b[2] = dl_ch_mag128[2];
-            dl_ch_mag128r[2] = dl_ch_mag128[2];
-
-            dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128);
-            dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1);
-          }
-
-          dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b);
-          dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1);
-
-
           dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b);
           dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1);
 
-          dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r);
-          dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1);
-
           dl_ch_mag128r[1] = _mm_mulhi_epi16(dl_ch_mag128r[1],QAM_amp128r);
           dl_ch_mag128r[1] = _mm_slli_epi16(dl_ch_mag128r[1],1);
 
-          if (pilots==0) {
-            dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b);
-            dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1);
+          mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]);//[H_I(0)^2+H_Q(0)^2 H_I(1)^2+H_Q(1)^2 H_I(2)^2+H_Q(2)^2 H_I(3)^2+H_Q(3)^2]
+          mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+          mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);//[|H(0)|^2 |H(1)|^2 |H(2)|^2 |H(3)|^2 |H(0)|^2 |H(1)|^2 |H(2)|^2 |H(3)|^2]
 
-            dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r);
-            dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1);
-          }
+          dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);//[|H(0)|^2 |H(0)|^2 |H(1)|^2 |H(1)|^2 |H(2)|^2 |H(2)|^2 |H(3)|^2 |H(3)|^2]
+          dl_ch_mag128b[2] = dl_ch_mag128[2];
+          dl_ch_mag128r[2] = dl_ch_mag128[2];
+
+          dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128);
+          dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1);
+
+          dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b);
+          dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1);
+
+          dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r);
+          dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1);
         }
 
         // multiply by conjugated channel
@@ -997,9 +919,16 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
         //        print_ints("c0",&mmtmpD2);
         //  print_ints("c1",&mmtmpD3);
         rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
-        //  print_shorts("rx:",rxdataF128);
-        //  print_shorts("ch:",dl_ch128);
-        //  print_shorts("pack:",rxdataF_comp128);
+
+#ifdef DEBUG_DLSCH_DEMOD
+        printf("%%arx%d atx%d rb_index %d symbol %d shift %d\n",aarx,aatx,rb,symbol,output_shift);
+        printf("rx_%d(%d,:)",aarx+1,rb+1);
+        print_shorts("  ",(int16_t *)&rxdataF128[0]);
+        printf("ch_%d%d(%d,:)",aarx+1,aatx+1,rb+1);
+        print_shorts("  ",(int16_t *)&dl_ch128[0]);
+        printf("rx_comp_%d%d(%d,:)",aarx+1,aatx+1,rb+1);
+        print_shorts("  ",(int16_t *)&rxdataF_comp128[0]);
+#endif
 
         // multiply by conjugated channel
         mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]);
@@ -1015,138 +944,166 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
         mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
 
         rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
-        //  print_shorts("rx:",rxdataF128+1);
-        //  print_shorts("ch:",dl_ch128+1);
-        //  print_shorts("pack:",rxdataF_comp128+1);
-
-        if (pilots==0) {
-          // multiply by conjugated channel
-          mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
-          // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
-          mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
-          mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
-          mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
-          mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]);
-          // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
-          mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
-          mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
-          mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
-          mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
-
-          rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
-          //  print_shorts("rx:",rxdataF128+2);
-          //  print_shorts("ch:",dl_ch128+2);
-          //        print_shorts("pack:",rxdataF_comp128+2);
-
-          dl_ch128+=3;
-          dl_ch_mag128+=3;
-          dl_ch_mag128b+=3;
-          dl_ch_mag128r+=3;
-          rxdataF128+=3;
-          rxdataF_comp128+=3;
-        } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
-          dl_ch128+=2;
-          dl_ch_mag128+=2;
-          dl_ch_mag128b+=2;
-          dl_ch_mag128r+=2;
-          rxdataF128+=2;
-          rxdataF_comp128+=2;
-        }
-
-      }
-    }
-  }
-
-  if (rho) {
-
-
-    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-      rho128        = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12];
-      dl_ch128      = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
-      dl_ch128_2    = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
-
-      for (rb=0; rb<nb_rb; rb++) {
-        // multiply by conjugated channel
-        mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]);
-        //  print_ints("re",&mmtmpD0);
-
-        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
-        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
-        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
-        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
-        //  print_ints("im",&mmtmpD1);
-        mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[0]);
-        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
-        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
-        //  print_ints("re(shift)",&mmtmpD0);
-        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
-        //  print_ints("im(shift)",&mmtmpD1);
-        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
-        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
-        //        print_ints("c0",&mmtmpD2);
-        //  print_ints("c1",&mmtmpD3);
-        rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
-
-        //print_shorts("rx:",dl_ch128_2);
-        //print_shorts("ch:",dl_ch128);
-        //print_shorts("pack:",rho128);
+        //print_shorts("rx:",(int16_t*)&rxdataF128[1]);
+        //print_shorts("ch:",(int16_t*)&dl_ch128[1]);
+        //print_shorts("pack:",(int16_t*)&rxdataF_comp128[1]);
 
         // multiply by conjugated channel
-        mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]);
-        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
-        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
-        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
-        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
-        mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[1]);
-        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
-        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
-        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
-        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
-        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
-
-
-        rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3);
-        //print_shorts("rx:",dl_ch128_2+1);
-        //print_shorts("ch:",dl_ch128+1);
-        //print_shorts("pack:",rho128+1);
-        // multiply by conjugated channel
-        mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]);
+        mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
         // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
         mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
         mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
         mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
-        mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[2]);
+        mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]);
         // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
         mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
         mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
         mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
         mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
 
-        rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
-        //print_shorts("rx:",dl_ch128_2+2);
-        //print_shorts("ch:",dl_ch128+2);
-        //print_shorts("pack:",rho128+2);
+        rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+        //print_shorts("rx:",(int16_t*)&rxdataF128[2]);
+        //print_shorts("ch:",(int16_t*)&dl_ch128[2]);
+        //print_shorts("pack:",(int16_t*)&rxdataF_comp128[2]);
 
         dl_ch128+=3;
-        dl_ch128_2+=3;
-        rho128+=3;
-
+        dl_ch_mag128+=3;
+        dl_ch_mag128b+=3;
+        dl_ch_mag128r+=3;
+        rxdataF128+=3;
+        rxdataF_comp128+=3;
       }
+    }
+  }
+  if (rho) {
+    //we compute the Tx correlation matrix for each Rx antenna
+    //As an example the 2x2 MIMO case requires
+    //rho[aarx][nb_aatx*nb_aatx] = [cov(H_aarx_0,H_aarx_0) cov(H_aarx_0,H_aarx_1)
+    //                              cov(H_aarx_1,H_aarx_0) cov(H_aarx_1,H_aarx_1)], aarx=0,...,nb_antennas_rx-1
 
-      if (first_symbol_flag==1) {
-        measurements->rx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*nb_rb*12],rb*12);
+    int avg_rho_re[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx];
+    int avg_rho_im[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx];
+
+    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+
+      for (aatx=0; aatx<nb_aatx; aatx++) {
+        dl_ch128      = (__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];
+
+        for (atx=0; atx<nb_aatx; atx++) {
+          avg_rho_re[aarx][aatx*nb_aatx+atx] = 0;
+          avg_rho_im[aarx][aatx*nb_aatx+atx] = 0;
+          rho128        = (__m128i *)&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12];
+          dl_ch128_2    = (__m128i *)&dl_ch_estimates_ext[atx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];
+
+          for (rb=0; rb<nb_rb_0; rb++) {
+            // multiply by conjugated channel
+            mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]);
+            //  print_ints("re",&mmtmpD0);
+            // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+            mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
+            mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
+            mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
+            //  print_ints("im",&mmtmpD1);
+            mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[0]);
+            // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
+            mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+            //  print_ints("re(shift)",&mmtmpD0);
+            mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
+            //  print_ints("im(shift)",&mmtmpD1);
+            mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
+            mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
+            //        print_ints("c0",&mmtmpD2);
+            //  print_ints("c1",&mmtmpD3);
+            rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+            //print_shorts("rx:",dl_ch128_2);
+            //print_shorts("ch:",dl_ch128);
+            //print_shorts("pack:",rho128);
+
+            avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[0])[0]+
+              ((int16_t*)&rho128[0])[2] +
+              ((int16_t*)&rho128[0])[4] +
+              ((int16_t*)&rho128[0])[6])/16;//
+
+            avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[0])[1]+
+              ((int16_t*)&rho128[0])[3] +
+              ((int16_t*)&rho128[0])[5] +
+              ((int16_t*)&rho128[0])[7])/16;//
+
+            // multiply by conjugated channel
+            mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]);
+            // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+            mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
+            mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
+            mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
+            mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[1]);
+            // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
+            mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+            mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
+            mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
+            mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
+            rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3);
+            //print_shorts("rx:",dl_ch128_2+1);
+            //print_shorts("ch:",dl_ch128+1);
+            //print_shorts("pack:",rho128+1);
+
+            // multiply by conjugated channel
+            avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[1])[0]+
+              ((int16_t*)&rho128[1])[2] +
+              ((int16_t*)&rho128[1])[4] +
+              ((int16_t*)&rho128[1])[6])/16;
+
+            avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[1])[1]+
+              ((int16_t*)&rho128[1])[3] +
+              ((int16_t*)&rho128[1])[5] +
+              ((int16_t*)&rho128[1])[7])/16;
+
+            mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]);
+            // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+            mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
+            mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
+            mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
+            mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[2]);
+            // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
+            mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+            mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
+            mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
+            mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
+
+            rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+            //print_shorts("rx:",dl_ch128_2+2);
+            //print_shorts("ch:",dl_ch128+2);
+            //print_shorts("pack:",rho128+2);
+            avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[2])[0]+
+              ((int16_t*)&rho128[2])[2] +
+              ((int16_t*)&rho128[2])[4] +
+              ((int16_t*)&rho128[2])[6])/16;
+
+            avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[2])[1]+
+              ((int16_t*)&rho128[2])[3] +
+              ((int16_t*)&rho128[2])[5] +
+              ((int16_t*)&rho128[2])[7])/16;
+
+            dl_ch128+=3;
+            dl_ch128_2+=3;
+            rho128+=3;
+          }
+          if (first_symbol_flag==1) {
+            //measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12],rb*12);
+            avg_rho_re[aarx][aatx*nb_aatx+atx] = 16*avg_rho_re[aarx][aatx*nb_aatx+atx]/(nb_rb*12);
+            avg_rho_im[aarx][aatx*nb_aatx+atx] = 16*avg_rho_im[aarx][aatx*nb_aatx+atx]/(nb_rb*12);
+            //printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]);
+          }
+        }
       }
     }
   }
-
   _mm_empty();
   _m_empty();
 
 #elif defined(__arm__)
 
-
   unsigned short rb;
-  unsigned char aatx,aarx,symbol_mod,pilots=0;
+  unsigned char aatx,aarx,symbol_mod;
 
   int16x4_t *dl_ch128,*dl_ch128_2,*rxdataF128;
   int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b;
@@ -1159,14 +1116,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
-  if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
-    if (frame_parms->nb_antenna_ports_gNB==1) { // 10 out of 12 so don't reduce size
-      nb_rb=1+(5*nb_rb/6);
-    }
-    else {
-      pilots=1;
-    }
-  }
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
 
   for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++) {
     if (mod_order == 4) {
@@ -1185,7 +1135,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
       rxdataF128        = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
       rxdataF_comp128   = (int16x4x2_t*)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
 
-      for (rb=0; rb<nb_rb; rb++) {
+      for (rb=0; rb<nb_rb_0; rb++) {
   if (mod_order>2) {
     // get channel amplitude if not QPSK
     mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128[0]);
@@ -1201,23 +1151,20 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
     mmtmpD1 = vmull_s16(dl_ch128[3], dl_ch128[3]);
     mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
     mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-    if (pilots==0) {
-      mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]);
-      mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
-      mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]);
-      mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
-      mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-    }
+
+    mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]);
+    mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+    mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]);
+    mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+    mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
 
     dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b);
     dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b);
     dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128);
     dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128);
 
-    if (pilots==0) {
-      dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
-      dl_ch_mag128[2]  = vqdmulhq_s16(mmtmpD4,QAM_amp128);
-    }
+    dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
+    dl_ch_mag128[2]  = vqdmulhq_s16(mmtmpD4,QAM_amp128);
   }
 
   mmtmpD0 = vmull_s16(dl_ch128[0], rxdataF128[0]);
@@ -1251,36 +1198,29 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
   mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
   rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
 
-  if (pilots==0) {
-    mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]);
-    mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]);
-    mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
-         vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
 
-    mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]);
-    mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]);
-    mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
-         vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+  mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]);
+  mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]);
+  mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
+                         vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+
+  mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]);
+  mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]);
+  mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
+                         vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
 
 
-    mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
-    mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
-    rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+  mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
+  mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
+  rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
 
 
-    dl_ch128+=6;
-    dl_ch_mag128+=3;
-    dl_ch_mag128b+=3;
-    rxdataF128+=6;
-    rxdataF_comp128+=3;
+  dl_ch128+=6;
+  dl_ch_mag128+=3;
+  dl_ch_mag128b+=3;
+  rxdataF128+=6;
+  rxdataF_comp128+=3;
 
-  } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
-    dl_ch128+=4;
-    dl_ch_mag128+=2;
-    dl_ch_mag128b+=2;
-    rxdataF128+=4;
-    rxdataF_comp128+=2;
-  }
       }
     }
   }
@@ -1290,7 +1230,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
       rho128        = (int16x4x2_t*)&rho[aarx][symbol*frame_parms->N_RB_DL*12];
       dl_ch128      = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
       dl_ch128_2    = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
-      for (rb=0; rb<nb_rb; rb++) {
+      for (rb=0; rb<nb_rb_0; rb++) {
   mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128_2[0]);
   mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128_2[1]);
   mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
@@ -1349,7 +1289,7 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
                                      int **dl_ch_mag,
                                      int **dl_ch_magb,
                                      int **rxdataF_comp,
-                                     int **rho,
+                                     int ***rho,
                                      unsigned char n_tx,
                                      unsigned char n_rx,
                                      unsigned char mod_order,
@@ -1363,7 +1303,7 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
   int length_mod8 = 0;
   int length2;
   __m128i *dl_ch128,*dl_ch_mag128,*dl_ch_mag128b, *dl_ch128_2, *rxdataF128,*rxdataF_comp128,*rho128;
-  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b;
+  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0},QAM_amp128b={0};
   int aatx = 0, aarx = 0;
 
   for (aatx=0; aatx<n_tx; aatx++) {
@@ -1486,7 +1426,7 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
 
 
     for (aarx=0; aarx<n_rx; aarx++) {
-      rho128        = (__m128i *)&rho[aarx][start_point];
+      rho128        = (__m128i *)&rho[aarx][0][start_point];
       dl_ch128      = (__m128i *)&dl_ch_estimates_ext[aarx][start_point];
       dl_ch128_2    = (__m128i *)&dl_ch_estimates_ext[2+aarx][start_point];
 
@@ -1550,6 +1490,8 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
 
 void nr_dlsch_scale_channel(int **dl_ch_estimates_ext,
 			    NR_DL_FRAME_PARMS *frame_parms,
+			    uint8_t n_tx,
+			    uint8_t n_rx,
 			    NR_UE_DLSCH_t **dlsch_ue,
 			    uint8_t symbol,
 			    uint8_t pilots,
@@ -1574,10 +1516,10 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext,
 
   ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13
 
-  for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++) {
-    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+  for (aatx=0; aatx<n_tx; aatx++) {
+    for (aarx=0; aarx<n_rx; aarx++) {
 
-      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12];
+      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx*n_rx)+aarx][symbol*nb_rb*12];
 
       for (rb=0;rb<nb_rb_0;rb++) {
 
@@ -1587,14 +1529,10 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext,
         dl_ch128[1] = _mm_mulhi_epi16(dl_ch128[1],ch_amp128);
         dl_ch128[1] = _mm_slli_epi16(dl_ch128[1],3);
 
-        if (pilots) {
-          dl_ch128+=2;
-        } else {
-          dl_ch128[2] = _mm_mulhi_epi16(dl_ch128[2],ch_amp128);
-          dl_ch128[2] = _mm_slli_epi16(dl_ch128[2],3);
-          dl_ch128+=3;
+        dl_ch128[2] = _mm_mulhi_epi16(dl_ch128[2],ch_amp128);
+        dl_ch128[2] = _mm_slli_epi16(dl_ch128[2],3);
+        dl_ch128+=3;
 
-        }
       }
     }
   }
@@ -1608,6 +1546,7 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext,
 //compute average channel_level on each (TX,RX) antenna pair
 void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
 			    NR_DL_FRAME_PARMS *frame_parms,
+			    uint8_t n_tx,
 			    int32_t *avg,
 			    uint8_t symbol,
 			    uint32_t len,
@@ -1625,25 +1564,25 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
   //x = (x>4) ? 4 : x;
   int16_t y = (len)>>x;
   //printf("len = %d = %d * 2^(%d)\n",len,y,x);
+  uint32_t nb_rb_0 = len/12 + ((len%12)?1:0);
 
   AssertFatal(y!=0,"Cannot divide by zero: in function %s of file %s\n", __func__, __FILE__);
 
-  for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++)
+  for (aatx=0; aatx<n_tx; aatx++)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
       //clear average level
       avg128D = _mm_setzero_si128();
-      // 5 is always a symbol with no pilots for both normal and extended prefix
 
-      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12];
+      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
 
-      for (rb=0;rb<nb_rb;rb++) {
-	avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x));
-	avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x));
-	avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x));
-	dl_ch128+=3;
+      for (rb=0;rb<nb_rb_0;rb++) {
+        avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x));
+        avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x));
+        avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x));
+        dl_ch128+=3;
       }
 
-      avg[(aatx<<1)+aarx] =(((int32_t*)&avg128D)[0] +
+      avg[(aatx*frame_parms->nb_antennas_rx)+aarx] =(((int32_t*)&avg128D)[0] +
                             ((int32_t*)&avg128D)[1] +
                             ((int32_t*)&avg128D)[2] +
 			      ((int32_t*)&avg128D)[3])/y;
@@ -1661,7 +1600,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
   int16x4_t *dl_ch128;
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
-
+  uint32_t nb_rb_0 = len/12 + ((len%12)?1:0);
   for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
       //clear average level
@@ -1670,7 +1609,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
 
       dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
 
-      for (rb=0; rb<nb_rb; rb++) {
+      for (rb=0; rb<nb_rb_0; rb++) {
         //  printf("rb %d : ",rb);
         //  print_shorts("ch",&dl_ch128[0]);
         avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[0],dl_ch128[0]));
@@ -1729,38 +1668,36 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
   int norm_pack;
   __m128i *dl_ch128, norm128D;
 
-  for (aatx=0; aatx<n_tx; aatx++){
+  for (aatx=0; aatx<n_tx; aatx++) {
     for (aarx=0; aarx<n_rx; aarx++) {
-      max = 0;
-      min = 0;
+      max = median[aatx*n_rx + aarx];//initialize the med point for max
+      min = median[aatx*n_rx + aarx];//initialize the med point for min
       norm128D = _mm_setzero_si128();
 
-      dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*2 + aarx][start_point];
+      dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*n_rx + aarx][start_point];
 
-      length2 = length>>2;
+      length2 = length>>2;//length = number of REs, hence length2=nb_REs*(32/128) in SIMD loop
 
       for (ii=0;ii<length2;ii++) {
-        norm128D = _mm_srai_epi32( _mm_madd_epi16(dl_ch128[0],dl_ch128[0]), 1);
-          //print_ints("norm128D",&norm128D[0]);
+        norm128D = _mm_srai_epi32( _mm_madd_epi16(dl_ch128[0],dl_ch128[0]), 2);//[|H_0|²/4 |H_1|²/4 |H_2|²/4 |H_3|²/4]
+        //print_ints("norm128D",&norm128D[0]);
 
         norm_pack = ((int32_t*)&norm128D)[0] +
-                    ((int32_t*)&norm128D)[1] +
-                    ((int32_t*)&norm128D)[2] +
-                    ((int32_t*)&norm128D)[3];
+            ((int32_t*)&norm128D)[1] +
+            ((int32_t*)&norm128D)[2] +
+            ((int32_t*)&norm128D)[3];// compute the sum
 
         if (norm_pack > max)
-          max = norm_pack;
+          max = norm_pack;//store values more than max
         if (norm_pack < min)
-          min = norm_pack;
-
+          min = norm_pack;//store values less than min
         dl_ch128+=1;
       }
 
-        median[aatx*n_rx + aarx]  = (max+min)>>1;
-
-     // printf("Channel level  median [%d]: %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx]);
+      median[aatx*n_rx + aarx]  = (max+min)>>1;
+      //printf("Channel level  median [%d]: %d max = %d min = %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx],max,min);
       }
-    }
+  }
 
   _mm_empty();
   _m_empty();
@@ -2100,37 +2037,37 @@ void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
 //==============================================================================================
 
 unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
-					   int **dl_ch_estimates,
-					   int **rxdataF_ext,
-					   int **dl_ch_estimates_ext,
-					   unsigned short pmi,
-					   unsigned char *pmi_ext,
-					   unsigned char symbol,
-					   uint8_t pilots,
-					   uint8_t config_type,
-					   unsigned short start_rb,
-					   unsigned short nb_rb_pdsch,
-					   unsigned char nr_slot_rx,
-					   uint32_t high_speed_flag,
+                                           int **dl_ch_estimates,
+                                           int **rxdataF_ext,
+                                           int **dl_ch_estimates_ext,
+                                           unsigned char symbol,
+                                           uint8_t pilots,
+                                           uint8_t config_type,
+                                           unsigned short start_rb,
+                                           unsigned short nb_rb_pdsch,
+                                           uint8_t n_dmrs_cdm_groups,
                                            NR_DL_FRAME_PARMS *frame_parms,
-                                           uint16_t dlDmrsSymbPos) {
-
-
+                                           uint16_t dlDmrsSymbPos)
+{
 
   unsigned short k,rb;
-  unsigned char i,aarx; //,nsymb,sss_symb,pss_symb=0,l;
+  unsigned char nushift,i,aarx;
   int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
 
   int8_t validDmrsEst = 0; //store last DMRS Symbol index
 
   unsigned char j=0;
 
-  if (config_type==pdsch_dmrs_type1)
-    AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 1,
-                "nushift %d is illegal\n",frame_parms->nushift);
-  else
-    AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 2 || frame_parms->nushift == 4,
-                "nushift %d is illegal\n",frame_parms->nushift);
+  if (config_type==NFAPI_NR_DMRS_TYPE1) {
+    AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2,
+                "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups);
+    nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1
+
+  } else {
+    AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3,
+                "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups);
+    nushift = (n_dmrs_cdm_groups -1)<<1;//delta in Table 7.4.1.1.2-2
+    }
 
   for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
@@ -2146,38 +2083,40 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
     rxF       = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))];
     
     for (rb = 0; rb < nb_rb_pdsch; rb++) {
-      if (k>frame_parms->ofdm_symbol_size) {
+      if (k>=frame_parms->ofdm_symbol_size) {
         k = k-frame_parms->ofdm_symbol_size;
         rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))];
       }
       if (pilots==0) {
-	memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext));
-	memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext));
-	dl_ch0_ext+=12;
-	rxF_ext+=12;
+        memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext));
+        memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext));
+        dl_ch0_ext+=12;
+        rxF_ext+=12;
       } else {//the symbol contains DMRS
         j=0;
-        if (config_type==pdsch_dmrs_type1){
-          for (i = (1-frame_parms->nushift); i<12; i+=2) {
-            rxF_ext[j]=rxF[i];
-            dl_ch0_ext[j]=dl_ch0[i];
-            j++;
+        if (config_type==NFAPI_NR_DMRS_TYPE1){
+          if (nushift == 0) {//data is multiplexed
+            for (i = (1-nushift); i<12; i+=2) {
+              rxF_ext[j]=rxF[i];
+              dl_ch0_ext[j]=dl_ch0[i];
+              j++;
+            }
+            dl_ch0_ext+=6;
+            rxF_ext+=6;
           }
-          dl_ch0_ext+=6;
-          rxF_ext+=6;
-        } else {
-          for (i = (2+frame_parms->nushift); i<6; i++) {
+        } else {//NFAPI_NR_DMRS_TYPE2
+          for (i = (2+nushift); i<6; i++) {
             rxF_ext[j]=rxF[i];
             dl_ch0_ext[j]=dl_ch0[i];
             j++;
           }
-          for (i = (8+frame_parms->nushift); i<12; i++) {
+          for (i = (8+nushift); i<12; i++) {
             rxF_ext[j]=rxF[i];
             dl_ch0_ext[j]=dl_ch0[i];
             j++;
           }
-          dl_ch0_ext+= 8;
-          rxF_ext+= 8;
+          dl_ch0_ext+= j;
+          rxF_ext+= j;
         }
       }
 
@@ -2190,115 +2129,881 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
       }
     }
   }
-  
-  
-  return(nb_rb_pdsch/frame_parms->nb_antennas_rx);
+  return(nb_rb_pdsch);
 }
 
-unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF,
-                                      int **dl_ch_estimates,
-                                      int **rxdataF_ext,
-                                      int **dl_ch_estimates_ext,
-                                      unsigned short pmi,
-                                      unsigned char *pmi_ext,
-                                      unsigned char symbol,
-									  uint8_t pilots,
-									  unsigned short start_rb,
-									  unsigned short nb_rb_pdsch,
-                                      unsigned char nr_slot_rx,
-                                      uint32_t high_speed_flag,
-                                      NR_DL_FRAME_PARMS *frame_parms,
-                                      MIMO_mode_t mimo_mode) {
-
-  int prb,nb_rb=0;
-  unsigned short k;
-  int i,j,aarx;
-  int32_t *dl_ch0=NULL,*dl_ch0_ext=NULL,*dl_ch1=NULL,*dl_ch1_ext=NULL,*rxF=NULL,*rxF_ext=NULL;
-
-  k = frame_parms->first_carrier_offset + 516; //0
+unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
+                                             int **dl_ch_estimates,
+                                             int **rxdataF_ext,
+                                             int **dl_ch_estimates_ext,
+                                             unsigned char symbol,
+                                             uint8_t pilots,
+                                             uint8_t config_type,
+                                             unsigned short start_rb,
+                                             unsigned short nb_rb_pdsch,
+                                             uint8_t n_dmrs_cdm_groups,
+                                             uint8_t Nl,
+                                             NR_DL_FRAME_PARMS *frame_parms,
+                                             uint16_t dlDmrsSymbPos)
+{
 
-  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+  unsigned short k,rb;
+  unsigned char nushift,j,i,aarx,aatx;
+  int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
+  int8_t validDmrsEst = 0; //store last DMRS Symbol index
 
-    if (high_speed_flag==1) {
-      dl_ch0     = &dl_ch_estimates[aarx][symbol*(frame_parms->ofdm_symbol_size)];
-      dl_ch1     = &dl_ch_estimates[2+aarx][symbol*(frame_parms->ofdm_symbol_size)];
-    } else {
-      dl_ch0     = &dl_ch_estimates[aarx][0];
-      dl_ch1     = &dl_ch_estimates[2+aarx][0];
-    }
+  if (config_type==NFAPI_NR_DMRS_TYPE1) {
+    AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2,
+                "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups);
+    nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1
+  } else {
+    AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3,
+                "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups);
+    nushift = (n_dmrs_cdm_groups -1)<<1;//delta in Table 7.4.1.1.2-2
+  }
 
-    //pmi_loc = pmi_ext;
+  validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol);
 
-    // pointers to extracted RX signals and channel estimates
-    rxF_ext    = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)];
-    dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(nb_rb_pdsch*12)];
-    dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(nb_rb_pdsch*12)];
+  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
-    for (prb=0; prb<frame_parms->N_RB_DL; prb++) {
-      //skip_half=0;
+    k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb;
+    if (k>=frame_parms->ofdm_symbol_size)
+      k = k-frame_parms->ofdm_symbol_size;
 
-      if ((frame_parms->N_RB_DL&1) == 0) {  // even number of RBs
+    rxF_ext   = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)];
+    rxF       = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))];
 
-        // For second half of RBs skip DC carrier
-        if (k>=frame_parms->ofdm_symbol_size) {
-          rxF = &rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))];
-          k=k-(frame_parms->ofdm_symbol_size);
-        }
+    for (aatx=0; aatx<Nl; aatx++) {
+
+      dl_ch0     = &dl_ch_estimates[(aatx*frame_parms->nb_antennas_rx)+aarx][(validDmrsEst*(frame_parms->ofdm_symbol_size))];
+      dl_ch0_ext = &dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*(nb_rb_pdsch*NR_NB_SC_PER_RB)];
 
-         /*
-         if (mimo_mode <= PUSCH_PRECODING1)
-          *pmi_loc = (pmi>>((prb>>2)<<1))&3;
-         else
-          *pmi_loc=(pmi>>prb)&1;*/
-
-        // *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb);
-        //  pmi_loc++;
-
-
-          if (pilots == 0) {
-
-            memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));
-            memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int));
-            memcpy(rxF_ext,rxF,12*sizeof(int));
-            dl_ch0_ext +=12;
-            dl_ch1_ext +=12;
-            rxF_ext    +=12;
-          } else { // pilots==1
-            j=0;
-            for (i=0; i<12; i++) {
-              if ((i&1)!=frame_parms->nushift) {
-                rxF_ext[j]=rxF[i];
-                //        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+      for (rb = 0; rb < nb_rb_pdsch; rb++)
+      {
+        if (pilots==0) {//data symbol only
+          if (aatx==0) {//Extract Rx signal only
+            memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext));
+            rxF_ext+=12;
+          }
+          memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext));//Extract Channel Estimate
+          dl_ch0_ext+=12;
+        }
+        else {//the symbol contains DMRS
+          j=0;
+          if (config_type==NFAPI_NR_DMRS_TYPE1) {
+            if (nushift == 0) {//data is multiplexed
+              for (i = (1-nushift); i<12; i+=2) {
+                if (aatx==0) rxF_ext[j]=rxF[i];
                 dl_ch0_ext[j]=dl_ch0[i];
-                dl_ch1_ext[j++]=dl_ch1[i];
+                j++;
               }
+              dl_ch0_ext+=6;
+              if (aatx==0) rxF_ext+=6;
             }
-            dl_ch0_ext+=6;
-            dl_ch1_ext+=6;
-            rxF_ext+=6;
-          } // pilots==1
+          }
+          else {//NFAPI_NR_DMRS_TYPE2
+            for (i = (2+nushift); i<6; i++) {
+              if (aatx==0) rxF_ext[j]=rxF[i];
+              dl_ch0_ext[j]=dl_ch0[i];
+              j++;
+            }
+            for (i = (8+nushift); i<12; i++) {
+              if (aatx==0) rxF_ext[j]=rxF[i];
+              dl_ch0_ext[j]=dl_ch0[i];
+              j++;
+            }
+            dl_ch0_ext+= j;
+            if (aatx==0) rxF_ext+= j;
+          }
+        }
 
-          dl_ch0+=12;
-          dl_ch1+=12;
+        dl_ch0+=12;
+        if (aatx==0) {
           rxF+=12;
           k+=12;
+          if (k>=frame_parms->ofdm_symbol_size) {
+            k=k-(frame_parms->ofdm_symbol_size);
+            rxF       = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))];
+          }
+        }
+      }//rb
+    }//aatx
+  }//aarx
+  return(nb_rb_pdsch);
+}
+
+void nr_dlsch_detection_mrc(int **rxdataF_comp,
+                            int ***rho,
+                            int **dl_ch_mag,
+                            int **dl_ch_magb,
+                            int **dl_ch_magr,
+                            short n_tx,
+                            short n_rx,
+                            unsigned char symbol,
+                            unsigned short nb_rb,
+                            int length) {
+#if defined(__x86_64__)||defined(__i386__)
+  unsigned char aatx, aarx;
+  int i;
+  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*dl_ch_mag128_0r,*dl_ch_mag128_1r;
+
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
+
+  if (n_rx>1) {
+    for (aatx=0; aatx<n_tx; aatx++) {
+      rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx*n_rx)][symbol*nb_rb*12];//aarx=0
+      dl_ch_mag128_0      = (__m128i *)&dl_ch_mag[(aatx*n_rx)][symbol*nb_rb*12];//aarx=0
+      dl_ch_mag128_0b     = (__m128i *)&dl_ch_magb[(aatx*n_rx)][symbol*nb_rb*12];
+      dl_ch_mag128_0r     = (__m128i *)&dl_ch_magr[(aatx*n_rx)][symbol*nb_rb*12];
+      for (aarx=1; aarx<n_rx; aarx++) {
+        rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx*n_rx)+aarx][symbol*nb_rb*12];// aarx=1,..., n_rx-1
+        dl_ch_mag128_1      = (__m128i *)&dl_ch_mag[(aatx*n_rx)+aarx][symbol*nb_rb*12];
+        dl_ch_mag128_1b     = (__m128i *)&dl_ch_magb[(aatx*n_rx)+aarx][symbol*nb_rb*12];
+        dl_ch_mag128_1r     = (__m128i *)&dl_ch_magr[(aatx*n_rx)+aarx][symbol*nb_rb*12];
+
+        // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM/256 llr computation)
+        for (i=0; i<nb_rb_0*3; i++) {
+          rxdataF_comp128_0[i] = _mm_adds_epi16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
+          dl_ch_mag128_0[i]    = _mm_adds_epi16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]);
+          dl_ch_mag128_0b[i]   = _mm_adds_epi16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]);
+          dl_ch_mag128_0r[i]   = _mm_adds_epi16(dl_ch_mag128_0r[i],dl_ch_mag128_1r[i]);
+        }
       }
-    } // for prb
-  } // for aarx
-  return(nb_rb/frame_parms->nb_antennas_rx);
+    }
+#ifdef DEBUG_DLSCH_DEMOD
+    for (i=0; i<nb_rb_0*3; i++) {
+    printf("symbol%d RB %d\n",symbol,i/3);
+    rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[0][symbol*nb_rb*12];
+    rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[n_rx][symbol*nb_rb*12];
+    print_shorts("tx 1 mrc_re/mrc_Im:",(int16_t*)&rxdataF_comp128_0[i]);
+    print_shorts("tx 2 mrc_re/mrc_Im:",(int16_t*)&rxdataF_comp128_1[i]);
+    // printf("mrc mag0 = %d = %d \n",((int16_t*)&dl_ch_mag128_0[0])[0],((int16_t*)&dl_ch_mag128_0[0])[1]);
+    // printf("mrc mag0b = %d = %d \n",((int16_t*)&dl_ch_mag128_0b[0])[0],((int16_t*)&dl_ch_mag128_0b[0])[1]);
+    }
+#endif
+    if (rho) {
+      /*rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12];
+      rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
+      for (i=0; i<nb_rb_0*3; i++) {
+        //      print_shorts("mrc rho0:",&rho128_0[i]);
+        //      print_shorts("mrc rho1:",&rho128_1[i]);
+        rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
+      }*/
+      }
+    _mm_empty();
+    _m_empty();
+  }
+#endif
+}
+
+/* Zero Forcing Rx function: nr_det_HhH()
+ *
+ *
+ * */
+void nr_det_HhH(int32_t *after_mf_00,//a
+                int32_t *after_mf_01,//b
+                int32_t *after_mf_10,//c
+                int32_t *after_mf_11,//d
+                int32_t *det_fin,//1/ad-bc
+                unsigned short nb_rb,
+                unsigned char symbol,
+                int32_t shift)
+{
+  int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
+  unsigned short rb;
+  __m128i *after_mf_00_128,*after_mf_01_128, *after_mf_10_128, *after_mf_11_128, ad_re_128, bc_re_128; //ad_im_128, bc_im_128;
+  __m128i *det_fin_128, det_re_128; //det_im_128, tmp_det0, tmp_det1;
+
+  after_mf_00_128 = (__m128i *)after_mf_00;
+  after_mf_01_128 = (__m128i *)after_mf_01;
+  after_mf_10_128 = (__m128i *)after_mf_10;
+  after_mf_11_128 = (__m128i *)after_mf_11;
+
+  det_fin_128 = (__m128i *)det_fin;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    //complex multiplication (I_a+jQ_a)(I_d+jQ_d) = (I_aI_d - Q_aQ_d) + j(Q_aI_d + I_aQ_d)
+    //The imag part is often zero, we compute only the real part
+    ad_re_128 = _mm_sign_epi16(after_mf_00_128[0],*(__m128i*)&nr_conjug2[0]);
+    ad_re_128 = _mm_madd_epi16(ad_re_128,after_mf_11_128[0]); //Re: I_a0*I_d0 - Q_a1*Q_d1
+    //ad_im_128 = _mm_shufflelo_epi16(after_mf_00_128[0],_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
+    //ad_im_128 = _mm_shufflehi_epi16(ad_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
+    //ad_im_128 = _mm_madd_epi16(ad_im_128,after_mf_11_128[0]);//Im: (Q_aI_d + I_aQ_d)
+
+    //complex multiplication (I_b+jQ_b)(I_c+jQ_c) = (I_bI_c - Q_bQ_c) + j(Q_bI_c + I_bQ_c)
+    //The imag part is often zero, we compute only the real part
+    bc_re_128 = _mm_sign_epi16(after_mf_01_128[0],*(__m128i*)&nr_conjug2[0]);
+    bc_re_128 = _mm_madd_epi16(bc_re_128,after_mf_10_128[0]); //Re: I_b0*I_c0 - Q_b1*Q_c1
+    //bc_im_128 = _mm_shufflelo_epi16(after_mf_01_128[0],_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_b0 Q_b1 I_b2 Q_b3]_64bits to [Q_b1 I_b0 Q_b3 I_b2]_64bits
+    //bc_im_128 = _mm_shufflehi_epi16(bc_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_b0 Q_b1 I_b2 Q_b3]_64bits to [Q_b1 I_b0 Q_b3 I_b2]_64bits
+    //bc_im_128 = _mm_madd_epi16(bc_im_128,after_mf_10_128[0]);//Im: (Q_bI_c + I_bQ_c)
+
+    det_re_128 = _mm_sub_epi32(ad_re_128, bc_re_128);
+    //det_im_128 = _mm_sub_epi32(ad_im_128, bc_im_128);
+
+    //det in Q30 format
+    det_fin_128[0] = _mm_abs_epi32(det_re_128);
+
+
+#ifdef DEBUG_DLSCH_DEMOD
+     printf("\n Computing det_HhH_inv \n");
+     //print_ints("det_re_128:",(int32_t*)&det_re_128);
+     //print_ints("det_im_128:",(int32_t*)&det_im_128);
+     print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]);
+#endif
+    det_fin_128+=1;
+    after_mf_00_128+=1;
+    after_mf_01_128+=1;
+    after_mf_10_128+=1;
+    after_mf_11_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
 }
 
+/* Zero Forcing Rx function: nr_inv_comp_muli
+ * Complex number multi: z = x*y
+ *                         = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im)
+ * */
+__m128i nr_inv_comp_muli(__m128i input_x,
+                         __m128i input_y)
+{
+  int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
+
+  __m128i xy_re_128, xy_im_128;
+  __m128i output_z, tmp_z0, tmp_z1;
+
+  // complex multiplication (x_re + jx_im)*(y_re + jy_im) = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im)
+
+  // the real part
+  xy_re_128 = _mm_sign_epi16(input_x,*(__m128i*)&nr_conjug2[0]);
+  xy_re_128 = _mm_madd_epi16(xy_re_128,input_y); //Re: (x_re*y_re - x_im*y_im)
+
+  // the imag part
+  xy_im_128 = _mm_shufflelo_epi16(input_x,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
+  xy_im_128 = _mm_shufflehi_epi16(xy_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
+  xy_im_128 = _mm_madd_epi16(xy_im_128,input_y);//Im: (x_im*y_re + x_re*y_im)
+
+  //convert back to Q15 before packing
+  xy_re_128 = _mm_srai_epi32(xy_re_128,4);//(2^15/64*2*16)
+  xy_im_128 = _mm_srai_epi32(xy_im_128,4);
+
+  tmp_z0  = _mm_unpacklo_epi32(xy_re_128,xy_im_128);
+  //print_ints("unpack lo:",&tmp_z0[0]);
+  tmp_z1  = _mm_unpackhi_epi32(xy_re_128,xy_im_128);
+  //print_ints("unpack hi:",&tmp_z1[0]);
+  output_z = _mm_packs_epi32(tmp_z0,tmp_z1);
+
+  _mm_empty();
+  _m_empty();
+  return(output_z);
+}
+
+/* Zero Forcing Rx function: nr_conjch0_mult_ch1()
+ *
+ *
+ * */
+void nr_conjch0_mult_ch1(int *ch0,
+                         int *ch1,
+                         int32_t *ch0conj_ch1,
+                         unsigned short nb_rb,
+                         unsigned char output_shift0)
+{
+  //This function is used to compute multiplications in H_hermitian * H matrix
+  short nr_conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
+  unsigned short rb;
+  __m128i *dl_ch0_128,*dl_ch1_128, *ch0conj_ch1_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
+
+  dl_ch0_128 = (__m128i *)ch0;
+  dl_ch1_128 = (__m128i *)ch1;
+
+  ch0conj_ch1_128 = (__m128i *)ch0conj_ch1;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]);
+    mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1));
+    mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
+    mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&nr_conjugate[0]);
+    mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch1_128[0]);
+    mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
+    mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0);
+    mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
+    mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
+
+    ch0conj_ch1_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+
+    /*printf("\n Computing conjugates \n");
+    print_shorts("ch0:",(int16_t*)&dl_ch0_128[0]);
+    print_shorts("ch1:",(int16_t*)&dl_ch1_128[0]);
+    print_shorts("pack:",(int16_t*)&ch0conj_ch1_128[0]);*/
+
+    dl_ch0_128+=1;
+    dl_ch1_128+=1;
+    ch0conj_ch1_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
+__m128i nr_comp_muli_sum(__m128i input_x,
+                         __m128i input_y,
+                         __m128i input_w,
+                         __m128i input_z,
+                         __m128i det)
+{
+  int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
+
+  __m128i xy_re_128, xy_im_128, wz_re_128, wz_im_128;
+  __m128i output, tmp_z0, tmp_z1;
+
+  // complex multiplication (x_re + jx_im)*(y_re + jy_im) = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im)
+  // the real part
+  xy_re_128 = _mm_sign_epi16(input_x,*(__m128i*)&nr_conjug2[0]);
+  xy_re_128 = _mm_madd_epi16(xy_re_128,input_y); //Re: (x_re*y_re - x_im*y_im)
+
+  // the imag part
+  xy_im_128 = _mm_shufflelo_epi16(input_x,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
+  xy_im_128 = _mm_shufflehi_epi16(xy_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
+  xy_im_128 = _mm_madd_epi16(xy_im_128,input_y);//Im: (x_im*y_re + x_re*y_im)
+
+  // complex multiplication (w_re + jw_im)*(z_re + jz_im) = (w_re*z_re - w_im*z_im) + j(w_im*z_re + w_re*z_im)
+  // the real part
+  wz_re_128 = _mm_sign_epi16(input_w,*(__m128i*)&nr_conjug2[0]);
+  wz_re_128 = _mm_madd_epi16(wz_re_128,input_z); //Re: (w_re*z_re - w_im*z_im)
+
+  // the imag part
+  wz_im_128 = _mm_shufflelo_epi16(input_w,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
+  wz_im_128 = _mm_shufflehi_epi16(wz_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
+  wz_im_128 = _mm_madd_epi16(wz_im_128,input_z);//Im: (w_im*z_re + w_re*z_im)
+
+
+  xy_re_128 = _mm_sub_epi32(xy_re_128, wz_re_128);
+  xy_im_128 = _mm_sub_epi32(xy_im_128, wz_im_128);
+  //print_ints("rx_re:",(int32_t*)&xy_re_128[0]);
+  //print_ints("rx_Img:",(int32_t*)&xy_im_128[0]);
+  //divide by matrix det and convert back to Q15 before packing
+  int sum_det =0;
+  for (int k=0; k<4;k++) {
+    sum_det += ((((int *)&det[0])[k])>>2);
+    //printf("det_%d = %d log2 =%d \n",k,(((int *)&det[0])[k]),log2_approx(((int *)&det[0])[k]));
+    }
+
+  xy_re_128 = _mm_slli_epi32(xy_re_128,5);
+  xy_re_128 = _mm_srai_epi32(xy_re_128,log2_approx(sum_det));
+  xy_re_128 = _mm_slli_epi32(xy_re_128,5);
+
+  xy_im_128 = _mm_slli_epi32(xy_im_128,5);
+  xy_im_128 = _mm_srai_epi32(xy_im_128,log2_approx(sum_det));
+  xy_im_128 = _mm_slli_epi32(xy_im_128,5);
+
+  tmp_z0  = _mm_unpacklo_epi32(xy_re_128,xy_im_128);
+  //print_ints("unpack lo:",&tmp_z0[0]);
+  tmp_z1  = _mm_unpackhi_epi32(xy_re_128,xy_im_128);
+  //print_ints("unpack hi:",&tmp_z1[0]);
+  output = _mm_packs_epi32(tmp_z0,tmp_z1);
+
+  _mm_empty();
+  _m_empty();
+  return(output);
+}
+/* Zero Forcing Rx function: nr_construct_HhH_elements()
+ *
+ *
+ * */
+void nr_construct_HhH_elements(int *conjch00_ch00,
+                               int *conjch01_ch01,
+                               int *conjch11_ch11,
+                               int *conjch10_ch10,//
+                               int *conjch20_ch20,
+                               int *conjch21_ch21,
+                               int *conjch30_ch30,
+                               int *conjch31_ch31,
+                               int *conjch00_ch01,//00_01
+                               int *conjch01_ch00,//01_00
+                               int *conjch10_ch11,//10_11
+                               int *conjch11_ch10,//11_10
+                               int *conjch20_ch21,
+                               int *conjch21_ch20,
+                               int *conjch30_ch31,
+                               int *conjch31_ch30,
+                               int32_t *after_mf_00,
+                               int32_t *after_mf_01,
+                               int32_t *after_mf_10,
+                               int32_t *after_mf_11,
+                               unsigned short nb_rb,
+                               unsigned char symbol)
+{
+  //This function is used to construct the (H_hermitian * H matrix) matrix elements
+  unsigned short rb;
+  __m128i *conjch00_ch00_128, *conjch01_ch01_128, *conjch11_ch11_128, *conjch10_ch10_128;
+  __m128i *conjch20_ch20_128, *conjch21_ch21_128, *conjch30_ch30_128, *conjch31_ch31_128;
+  __m128i *conjch00_ch01_128, *conjch01_ch00_128, *conjch10_ch11_128, *conjch11_ch10_128;
+  __m128i *conjch20_ch21_128, *conjch21_ch20_128, *conjch30_ch31_128, *conjch31_ch30_128;
+  __m128i *after_mf_00_128, *after_mf_01_128, *after_mf_10_128, *after_mf_11_128;
+
+  conjch00_ch00_128 = (__m128i *)conjch00_ch00;
+  conjch01_ch01_128 = (__m128i *)conjch01_ch01;
+  conjch11_ch11_128 = (__m128i *)conjch11_ch11;
+  conjch10_ch10_128 = (__m128i *)conjch10_ch10;
+
+  conjch20_ch20_128 = (__m128i *)conjch20_ch20;
+  conjch21_ch21_128 = (__m128i *)conjch21_ch21;
+  conjch30_ch30_128 = (__m128i *)conjch30_ch30;
+  conjch31_ch31_128 = (__m128i *)conjch31_ch31;
+
+  conjch00_ch01_128 = (__m128i *)conjch00_ch01;
+  conjch01_ch00_128 = (__m128i *)conjch01_ch00;
+  conjch10_ch11_128 = (__m128i *)conjch10_ch11;
+  conjch11_ch10_128 = (__m128i *)conjch11_ch10;
+
+  conjch20_ch21_128 = (__m128i *)conjch20_ch21;
+  conjch21_ch20_128 = (__m128i *)conjch21_ch20;
+  conjch30_ch31_128 = (__m128i *)conjch30_ch31;
+  conjch31_ch30_128 = (__m128i *)conjch31_ch30;
+
+  after_mf_00_128 = (__m128i *)after_mf_00;
+  after_mf_01_128 = (__m128i *)after_mf_01;
+  after_mf_10_128 = (__m128i *)after_mf_10;
+  after_mf_11_128 = (__m128i *)after_mf_11;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    after_mf_00_128[0] =_mm_adds_epi16(conjch00_ch00_128[0],conjch10_ch10_128[0]);//00_00 + 10_10
+    if (conjch20_ch20 != NULL) after_mf_00_128[0] =_mm_adds_epi16(after_mf_00_128[0],conjch20_ch20_128[0]);
+    if (conjch30_ch30 != NULL) after_mf_00_128[0] =_mm_adds_epi16(after_mf_00_128[0],conjch30_ch30_128[0]);
+
+    after_mf_11_128[0] =_mm_adds_epi16(conjch01_ch01_128[0], conjch11_ch11_128[0]); //01_01 + 11_11
+    if (conjch21_ch21 != NULL) after_mf_11_128[0] =_mm_adds_epi16(after_mf_11_128[0],conjch21_ch21_128[0]);
+    if (conjch31_ch31 != NULL) after_mf_11_128[0] =_mm_adds_epi16(after_mf_11_128[0],conjch31_ch31_128[0]);
+
+    after_mf_01_128[0] =_mm_adds_epi16(conjch00_ch01_128[0], conjch10_ch11_128[0]);//00_01 + 10_11
+    if (conjch20_ch21 != NULL) after_mf_01_128[0] =_mm_adds_epi16(after_mf_01_128[0],conjch20_ch21_128[0]);
+    if (conjch30_ch31 != NULL) after_mf_01_128[0] =_mm_adds_epi16(after_mf_01_128[0],conjch30_ch31_128[0]);
+
+    after_mf_10_128[0] =_mm_adds_epi16(conjch01_ch00_128[0], conjch11_ch10_128[0]);//01_00 + 11_10
+    if (conjch21_ch20 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch21_ch20_128[0]);
+    if (conjch31_ch30 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch31_ch30_128[0]);
+
+#ifdef DEBUG_DLSCH_DEMOD
+    if ((rb<=30))
+    {
+      printf(" \n construct_HhH_elements \n");
+      print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]);
+      print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]);
+      print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]);
+      print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]);
+    }
+#endif
+    conjch00_ch00_128+=1;
+    conjch10_ch10_128+=1;
+    conjch01_ch01_128+=1;
+    conjch11_ch11_128+=1;
+
+    if (conjch20_ch20 != NULL) conjch20_ch20_128+=1;
+    if (conjch21_ch21 != NULL) conjch21_ch21_128+=1;
+    if (conjch30_ch30 != NULL) conjch30_ch30_128+=1;
+    if (conjch31_ch31 != NULL) conjch31_ch31_128+=1;
+
+    conjch00_ch01_128+=1;
+    conjch01_ch00_128+=1;
+    conjch10_ch11_128+=1;
+    conjch11_ch10_128+=1;
+
+    if (conjch20_ch21 != NULL) conjch20_ch21_128+=1;
+    if (conjch21_ch20 != NULL) conjch21_ch20_128+=1;
+    if (conjch30_ch31 != NULL) conjch30_ch31_128+=1;
+    if (conjch31_ch30 != NULL) conjch31_ch30_128+=1;
+
+    after_mf_00_128 += 1;
+    after_mf_01_128 += 1;
+    after_mf_10_128 += 1;
+    after_mf_11_128 += 1;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+/* Zero Forcing Rx function: nr_zero_forcing_rx_2layers()
+ *
+ *
+ * */
+uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
+                                   int **dl_ch_mag,
+                                   int **dl_ch_magb,
+                                   int **dl_ch_magr,
+                                   int **dl_ch_estimates_ext,
+                                   unsigned short nb_rb,
+                                   unsigned char n_rx,
+                                   unsigned char mod_order,
+                                   int shift,
+                                   unsigned char symbol,
+                                   int length)
+{
+  int *ch00, *ch01, *ch10, *ch11;
+  int *ch20, *ch30, *ch21, *ch31;
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
+  /* we need at least alignment to 16 bytes, let's put 32 to be sure
+   * (maybe not necessary but doesn't hurt)
+   */
+  int32_t conjch00_ch01[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch01_ch00[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch10_ch11[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch11_ch10[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch00_ch00[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch01_ch01[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch10_ch10[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch11_ch11[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch20_ch20[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch21_ch21[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch30_ch30[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch31_ch31[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch20_ch21[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch30_ch31[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch21_ch20[12*nb_rb] __attribute__((aligned(32)));
+  int32_t conjch31_ch30[12*nb_rb] __attribute__((aligned(32)));
+
+  int32_t af_mf_00[12*nb_rb] __attribute__((aligned(32)));
+  int32_t af_mf_01[12*nb_rb] __attribute__((aligned(32)));
+  int32_t af_mf_10[12*nb_rb] __attribute__((aligned(32)));
+  int32_t af_mf_11[12*nb_rb] __attribute__((aligned(32)));
+  int32_t determ_fin[12*nb_rb] __attribute__((aligned(32)));
+
+  switch (n_rx) {
+    case 2://
+      ch00 = (int *)&dl_ch_estimates_ext[0][symbol*nb_rb*12];
+      ch01 = (int *)&dl_ch_estimates_ext[2][symbol*nb_rb*12];
+      ch10 = (int *)&dl_ch_estimates_ext[1][symbol*nb_rb*12];
+      ch11 = (int *)&dl_ch_estimates_ext[3][symbol*nb_rb*12];
+      ch20 = NULL;
+      ch21 = NULL;
+      ch30 = NULL;
+      ch31 = NULL;
+      break;
+
+    case 4://
+      ch00 = (int *)&dl_ch_estimates_ext[0][symbol*nb_rb*12];
+      ch01 = (int *)&dl_ch_estimates_ext[4][symbol*nb_rb*12];
+      ch10 = (int *)&dl_ch_estimates_ext[1][symbol*nb_rb*12];
+      ch11 = (int *)&dl_ch_estimates_ext[5][symbol*nb_rb*12];
+      ch20 = (int *)&dl_ch_estimates_ext[2][symbol*nb_rb*12];
+      ch21 = (int *)&dl_ch_estimates_ext[6][symbol*nb_rb*12];
+      ch30 = (int *)&dl_ch_estimates_ext[3][symbol*nb_rb*12];
+      ch31 = (int *)&dl_ch_estimates_ext[7][symbol*nb_rb*12];
+      break;
+
+    default:
+      return -1;
+      break;
+  }
+
+  /* 1- Compute the rx channel matrix after compensation: (1/2^log2_max)x(H_herm x H)
+   * for n_rx = 2
+   * |conj_H_00       conj_H_10|    | H_00         H_01|   |(conj_H_00xH_00+conj_H_10xH_10)   (conj_H_00xH_01+conj_H_10xH_11)|
+   * |                         |  x |                  | = |                                                                 |
+   * |conj_H_01       conj_H_11|    | H_10         H_11|   |(conj_H_01xH_00+conj_H_11xH_10)   (conj_H_01xH_01+conj_H_11xH_11)|
+   *
+   */
+
+  if (n_rx>=2){
+    // (1/2^log2_maxh)*conj_H_00xH_00: (1/(64*2))conjH_00*H_00*2^15
+    nr_conjch0_mult_ch1(ch00,
+                        ch00,
+                        conjch00_ch00,
+                        nb_rb_0,
+                        shift);
+    // (1/2^log2_maxh)*conj_H_10xH_10: (1/(64*2))conjH_10*H_10*2^15
+    nr_conjch0_mult_ch1(ch10,
+                        ch10,
+                        conjch10_ch10,
+                        nb_rb_0,
+                        shift);
+    // conj_H_00xH_01
+    nr_conjch0_mult_ch1(ch00,
+                        ch01,
+                        conjch00_ch01,
+                        nb_rb_0,
+                        shift); // this shift is equal to the channel level log2_maxh
+    // conj_H_10xH_11
+    nr_conjch0_mult_ch1(ch10,
+                        ch11,
+                        conjch10_ch11,
+                        nb_rb_0,
+                        shift);
+    // conj_H_01xH_01
+    nr_conjch0_mult_ch1(ch01,
+                        ch01,
+                        conjch01_ch01,
+                        nb_rb_0,
+                        shift);
+    // conj_H_11xH_11
+    nr_conjch0_mult_ch1(ch11,
+                        ch11,
+                        conjch11_ch11,
+                        nb_rb_0,
+                        shift);
+    // conj_H_01xH_00
+    nr_conjch0_mult_ch1(ch01,
+                        ch00,
+                        conjch01_ch00,
+                        nb_rb_0,
+                        shift);
+    // conj_H_11xH_10
+    nr_conjch0_mult_ch1(ch11,
+                        ch10,
+                        conjch11_ch10,
+                        nb_rb_0,
+                        shift);
+  }
+  if (n_rx==4){
+    // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2*16))conjH_20*H_20*2^15
+    nr_conjch0_mult_ch1(ch20,
+                        ch20,
+                        conjch20_ch20,
+                        nb_rb_0,
+                        shift);
+
+    // (1/2^log2_maxh)*conj_H_30xH_30: (1/(64*2*4))conjH_30*H_30*2^15
+    nr_conjch0_mult_ch1(ch30,
+                        ch30,
+                        conjch30_ch30,
+                        nb_rb_0,
+                        shift);
+
+    // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15
+    nr_conjch0_mult_ch1(ch20,
+                        ch21,
+                        conjch20_ch21,
+                        nb_rb_0,
+                        shift);
+
+    nr_conjch0_mult_ch1(ch30,
+                        ch31,
+                        conjch30_ch31,
+                        nb_rb_0,
+                        shift);
+
+    nr_conjch0_mult_ch1(ch21,
+                        ch21,
+                        conjch21_ch21,
+                        nb_rb_0,
+                        shift);
+
+    nr_conjch0_mult_ch1(ch31,
+                        ch31,
+                        conjch31_ch31,
+                        nb_rb_0,
+                        shift);
+
+    // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15
+    nr_conjch0_mult_ch1(ch21,
+                        ch20,
+                        conjch21_ch20,
+                        nb_rb_0,
+                        shift);
+
+    nr_conjch0_mult_ch1(ch31,
+                        ch30,
+                        conjch31_ch30,
+                        nb_rb_0,
+                        shift);
+
+    nr_construct_HhH_elements(conjch00_ch00,
+                              conjch01_ch01,
+                              conjch11_ch11,
+                              conjch10_ch10,//
+                              conjch20_ch20,
+                              conjch21_ch21,
+                              conjch30_ch30,
+                              conjch31_ch31,
+                              conjch00_ch01,
+                              conjch01_ch00,
+                              conjch10_ch11,
+                              conjch11_ch10,//
+                              conjch20_ch21,
+                              conjch21_ch20,
+                              conjch30_ch31,
+                              conjch31_ch30,
+                              af_mf_00,
+                              af_mf_01,
+                              af_mf_10,
+                              af_mf_11,
+                              nb_rb_0,
+                              symbol);
+  }
+  if (n_rx==2){
+    nr_construct_HhH_elements(conjch00_ch00,
+                              conjch01_ch01,
+                              conjch11_ch11,
+                              conjch10_ch10,//
+                              NULL,
+                              NULL,
+                              NULL,
+                              NULL,
+                              conjch00_ch01,
+                              conjch01_ch00,
+                              conjch10_ch11,
+                              conjch11_ch10,//
+                              NULL,
+                              NULL,
+                              NULL,
+                              NULL,
+                              af_mf_00,
+                              af_mf_01,
+                              af_mf_10,
+                              af_mf_11,
+                              nb_rb_0,
+                              symbol);
+  }
+  //det_HhH = ad -bc
+  nr_det_HhH(af_mf_00,//a
+             af_mf_01,//b
+             af_mf_10,//c
+             af_mf_11,//d
+             determ_fin,
+             nb_rb_0,
+             symbol,
+             shift);
+  /* 2- Compute the channel matrix inversion **********************************
+   *
+     *    |(conj_H_00xH_00+conj_H_10xH_10)   (conj_H_00xH_01+conj_H_10xH_11)|
+     * A= |                                                                 |
+     *    |(conj_H_01xH_00+conj_H_11xH_10)   (conj_H_01xH_01+conj_H_11xH_11)|
+     *
+     *
+     *
+     *inv(A) =(1/det)*[d  -b
+     *                 -c  a]
+     *
+     *
+     **************************************************************************/
+  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0=NULL,*dl_ch_mag128b_0=NULL,*dl_ch_mag128r_0=NULL,*determ_fin_128;//*dl_ch_mag128_1,*dl_ch_mag128b_1,*dl_ch_mag128r_1
+  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
+  __m128i *after_mf_a_128,*after_mf_b_128, *after_mf_c_128, *after_mf_d_128;
+  __m128i QAM_amp128={0},QAM_amp128b={0},QAM_amp128r={0};
+
+  determ_fin_128      = (__m128i *)&determ_fin[0];
+
+  rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[0][symbol*nb_rb*12];//aatx=0 @ aarx =0
+  rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[n_rx][symbol*nb_rb*12];//aatx=1 @ aarx =0
+
+  after_mf_a_128 = (__m128i *)af_mf_00;
+  after_mf_b_128 = (__m128i *)af_mf_01;
+  after_mf_c_128 = (__m128i *)af_mf_10;
+  after_mf_d_128 = (__m128i *)af_mf_11;
+
+  if (mod_order>2) {
+    if (mod_order == 4) {
+      QAM_amp128 = _mm_set1_epi16(QAM16_n1);  //2/sqrt(10)
+      QAM_amp128b = _mm_setzero_si128();
+      QAM_amp128r = _mm_setzero_si128();
+    } else if (mod_order == 6) {
+      QAM_amp128  = _mm_set1_epi16(QAM64_n1); //4/sqrt{42}
+      QAM_amp128b = _mm_set1_epi16(QAM64_n2); //2/sqrt{42}
+      QAM_amp128r = _mm_setzero_si128();
+    } else if (mod_order == 8) {
+      QAM_amp128 = _mm_set1_epi16(QAM256_n1); //8/sqrt{170}
+      QAM_amp128b = _mm_set1_epi16(QAM256_n2);//4/sqrt{170}
+      QAM_amp128r = _mm_set1_epi16(QAM256_n3);//2/sqrt{170}
+      }
+    dl_ch_mag128_0      = (__m128i *)&dl_ch_mag[0][symbol*nb_rb*12];
+    dl_ch_mag128b_0     = (__m128i *)&dl_ch_magb[0][symbol*nb_rb*12];
+    dl_ch_mag128r_0     = (__m128i *)&dl_ch_magr[0][symbol*nb_rb*12];
+  }
+
+  for (int rb=0; rb<3*nb_rb_0; rb++) {
+    if (mod_order>2) {
+      int sum_det =0;
+      for (int k=0; k<4;k++) {
+        sum_det += ((((int *)&determ_fin_128[0])[k])>>2);
+        //printf("det_%d = %d\n",k,sum_det);
+        }
+
+      mmtmpD2 = _mm_slli_epi32(determ_fin_128[0],5);
+      mmtmpD2 = _mm_srai_epi32(mmtmpD2,log2_approx(sum_det));
+      mmtmpD2 = _mm_slli_epi32(mmtmpD2,5);
+
+      mmtmpD3 = _mm_unpacklo_epi32(mmtmpD2,mmtmpD2);
+
+      mmtmpD2 = _mm_unpackhi_epi32(mmtmpD2,mmtmpD2);
+
+      mmtmpD2 = _mm_packs_epi32(mmtmpD3,mmtmpD2);
+
+      dl_ch_mag128_0[0] = mmtmpD2;
+      dl_ch_mag128b_0[0] = mmtmpD2;
+      dl_ch_mag128r_0[0] = mmtmpD2;
+
+      dl_ch_mag128_0[0] = _mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128);
+      dl_ch_mag128_0[0] = _mm_slli_epi16(dl_ch_mag128_0[0],1);
+
+      dl_ch_mag128b_0[0] = _mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b);
+      dl_ch_mag128b_0[0] = _mm_slli_epi16(dl_ch_mag128b_0[0],1);
+
+      dl_ch_mag128r_0[0] = _mm_mulhi_epi16(dl_ch_mag128r_0[0],QAM_amp128r);
+      dl_ch_mag128r_0[0] = _mm_slli_epi16(dl_ch_mag128r_0[0],1);
+
+      //print_shorts("mag layer 1:",(int16_t*)&dl_ch_mag128_0[0]);
+      //print_shorts("mag layer 2:",(int16_t*)&dl_ch_mag128_1[0]);
+      //print_shorts("magb layer 1:",(int16_t*)&dl_ch_mag128b_0[0]);
+      //print_shorts("magb layer 2:",(int16_t*)&dl_ch_mag128b_1[0]);
+      //print_shorts("magr layer 1:",(int16_t*)&dl_ch_mag128r_0[0]);
+      //print_shorts("magr layer 2:",(int16_t*)&dl_ch_mag128r_1[0]);
+    }
+    // multiply by channel Inv
+    //rxdataF_zf128_0 = rxdataF_comp128_0*d - b*rxdataF_comp128_1
+    //rxdataF_zf128_1 = rxdataF_comp128_1*a - c*rxdataF_comp128_0
+    //printf("layer_1 \n");
+    mmtmpD0 = nr_comp_muli_sum(rxdataF_comp128_0[0],
+                               after_mf_d_128[0],
+                               rxdataF_comp128_1[0],
+                               after_mf_b_128[0],
+                               determ_fin_128[0]);
+
+    //printf("layer_2 \n");
+    mmtmpD1 = nr_comp_muli_sum(rxdataF_comp128_1[0],
+                               after_mf_a_128[0],
+                               rxdataF_comp128_0[0],
+                               after_mf_c_128[0],
+                               determ_fin_128[0]);
+
+    rxdataF_comp128_0[0] = mmtmpD0;
+    rxdataF_comp128_1[0] = mmtmpD1;
+#ifdef DEBUG_DLSCH_DEMOD
+    printf("\n Rx signal after ZF l%d rb%d\n",symbol,rb);
+    print_shorts(" Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]);
+    print_shorts(" Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]);
+#endif
+    determ_fin_128 += 1;
+    dl_ch_mag128_0 += 1;
+    dl_ch_mag128b_0 += 1;
+    dl_ch_mag128r_0 += 1;
+    rxdataF_comp128_0 += 1;
+    rxdataF_comp128_1 += 1;
+    after_mf_a_128 += 1;
+    after_mf_b_128 += 1;
+    after_mf_c_128 += 1;
+    after_mf_d_128 += 1;
+  }
+  _mm_empty();
+  _m_empty();
+   return(0);
+}
 
 static void nr_dlsch_layer_demapping(int16_t **llr_cw,
 				     uint8_t Nl,
 				     uint8_t mod_order,
-				     uint16_t length,
+				     uint32_t length,
+				     int32_t codeword_TB0,
+				     int32_t codeword_TB1,
 				     int16_t **llr_layers) {
 
   switch (Nl) {
-
     case 1:
-      memcpy((void*)llr_layers[0], (void*)llr_cw[0], (length)*sizeof(int16_t));
+      if (codeword_TB1 == -1)
+        memcpy((void*)llr_cw[0], (void*)llr_layers[0], (length)*sizeof(int16_t));
+      else if (codeword_TB0 == -1)
+        memcpy((void*)llr_cw[1], (void*)llr_layers[0], (length)*sizeof(int16_t));
+
     break;
 
     case 2:
@@ -2306,11 +3011,15 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw,
     case 4:
       for (int i=0; i<(length/Nl/mod_order); i++){
         for (int l=0; l<Nl; l++) {
-        	for (int m=0; m<mod_order; m++){
-        		llr_cw[0][Nl*i+l*mod_order+m] = llr_layers[l][i*mod_order+m];
-        	}
+          for (int m=0; m<mod_order; m++){
+            if (codeword_TB1 == -1)
+              llr_cw[0][Nl*mod_order*i+l*mod_order+m] = llr_layers[l][i*mod_order+m];//i:0 -->0 1 2 3
+            else if (codeword_TB0 == -1)
+              llr_cw[1][Nl*mod_order*i+l*mod_order+m] = llr_layers[l][i*mod_order+m];//i:0 -->0 1 2 3
+            //if (i<4) printf("length%d: llr_layers[l%d][m%d]=%d: \n",length,l,m,llr_layers[l][i*mod_order+m]);
+            }
+          }
         }
-  	  }
     break;
 
   default:
@@ -2327,7 +3036,7 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         RX_type_t rx_type,
                         unsigned char harq_pid,
                         unsigned char gNB_id,
-                        unsigned char eNB_id_i,
+                        unsigned char gNB_id_i,
                         unsigned char first_symbol_flag,
                         unsigned char symbol,
                         unsigned short nb_rb,
@@ -2378,299 +3087,110 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
 
   switch (dlsch0_harq->Qm) {
   case 2 :
-    if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
-      nr_dlsch_qpsk_llr(frame_parms,
-                        pdsch_vars[gNB_id]->rxdataF_comp0,
-                        pllr_symbol_cw0,
-                        symbol,
-                        len,
-                        first_symbol_flag,
-                        nb_rb,
-                        beamforming_mode);
-
-    } else if (codeword_TB0 == -1){
-
-      nr_dlsch_qpsk_llr(frame_parms,
-                        pdsch_vars[gNB_id]->rxdataF_comp0,
-                        pllr_symbol_cw1,
-                        symbol,
-                        len,
-                        first_symbol_flag,
-                        nb_rb,
-                        beamforming_mode);
-    }
-    else if (rx_type >= rx_IC_single_stream) {
-      if (dlsch1_harq->Qm == 2) {
-        nr_dlsch_qpsk_qpsk_llr(frame_parms,
+    switch (rx_type) {
+      case rx_standard :
+        for(int l =0; l<dlsch0_harq->Nl; l++)
+          nr_dlsch_qpsk_llr(frame_parms,
+                            pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
+                            pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                            symbol,
+                            len,
+                            first_symbol_flag,
+                            nb_rb,
+                            beamforming_mode);
+        break;
+      case rx_IC_single_stream ://not implemented yet
+        /*nr_dlsch_qpsk_qpsk_llr(frame_parms,
                                pdsch_vars[gNB_id]->rxdataF_comp0,
                                rxdataF_comp_ptr,
                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
                                pdsch_vars[gNB_id]->layer_llr[0],
                                symbol,len,first_symbol_flag,nb_rb,
                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                               pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_qpsk_qpsk_llr(frame_parms,
-                                 rxdataF_comp_ptr,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                 pdsch_vars[gNB_id]->layer_llr[1],
-                                 symbol,len,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else if (dlsch1_harq->Qm == 4) {
-        nr_dlsch_qpsk_16qam_llr(frame_parms,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                rxdataF_comp_ptr,//i
-                                dl_ch_mag_ptr,//i
-                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                pdsch_vars[gNB_id]->layer_llr[0],
-                                symbol,first_symbol_flag,nb_rb,
-                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                                pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_16qam_qpsk_llr(frame_parms,
-                                  rxdataF_comp_ptr,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                  dl_ch_mag_ptr,
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->layer_llr[1],
-                                  symbol,first_symbol_flag,nb_rb,
-                                  adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                  pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else {
-        nr_dlsch_qpsk_64qam_llr(frame_parms,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                rxdataF_comp_ptr,//i
-                                dl_ch_mag_ptr,//i
-                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                pdsch_vars[gNB_id]->layer_llr[0],
-                                symbol,first_symbol_flag,nb_rb,
-                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                                pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_64qam_qpsk_llr(frame_parms,
-                                  rxdataF_comp_ptr,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                  dl_ch_mag_ptr,
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->layer_llr[1],
-                                  symbol,first_symbol_flag,nb_rb,
-                                  adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                  pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
+                               pdsch_vars[gNB_id]->llr128);*/
+        break;
+      case rx_IC_dual_stream ://not implemented yet
+        /*nr_dlsch_qpsk_qpsk_llr(frame_parms,
+                               rxdataF_comp_ptr,
+                               pdsch_vars[gNB_id]->rxdataF_comp0,
+                               pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
+                               pdsch_vars[gNB_id]->layer_llr[1],
+                               symbol,len,first_symbol_flag,nb_rb,
+                               adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
+                               pdsch_vars[gNB_id]->llr128_2ndstream);*/
+        break;
+      case rx_SIC_dual_stream ://not implemented yet
+        break;
     }
     break;
   case 4 :
-    if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) {
-      nr_dlsch_16qam_llr(frame_parms,
-                         pdsch_vars[gNB_id]->rxdataF_comp0,
-                         pdsch_vars[gNB_id]->llr[0],
-                         pdsch_vars[gNB_id]->dl_ch_mag0,
-                         symbol,len,first_symbol_flag,nb_rb,
-                         pdsch_vars[gNB_id]->llr128,
-                         beamforming_mode);
-    } else if (codeword_TB0 == -1){
-      nr_dlsch_16qam_llr(frame_parms,
-                         pdsch_vars[gNB_id]->rxdataF_comp0,
-                         pdsch_vars[gNB_id]->llr[1],
-                         pdsch_vars[gNB_id]->dl_ch_mag0,
-                         symbol,len,first_symbol_flag,nb_rb,
-                         pdsch_vars[gNB_id]->llr128_2ndstream,
-                         beamforming_mode);
-    }
-    else if (rx_type >= rx_IC_single_stream) {
-      if (dlsch1_harq->Qm == 2) {
-        nr_dlsch_16qam_qpsk_llr(frame_parms,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                rxdataF_comp_ptr,//i
-                                pdsch_vars[gNB_id]->dl_ch_mag0,
-                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                pdsch_vars[gNB_id]->layer_llr[0],
-                                symbol,first_symbol_flag,nb_rb,
-                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_qpsk_16qam_llr(frame_parms,
-                                  rxdataF_comp_ptr,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                  pdsch_vars[gNB_id]->dl_ch_mag0,//i
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->layer_llr[1],
-                                  symbol,first_symbol_flag,nb_rb,
-                                  adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                                  pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else if (dlsch1_harq->Qm == 4) {
-        nr_dlsch_16qam_16qam_llr(frame_parms,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 rxdataF_comp_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 dl_ch_mag_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                 pdsch_vars[gNB_id]->layer_llr[0],
-                                 symbol,len,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_16qam_16qam_llr(frame_parms,
-                                   rxdataF_comp_ptr,
-                                   pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                   dl_ch_mag_ptr,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,//i
-                                   pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                   pdsch_vars[gNB_id]->layer_llr[1],
-                                   symbol,len,first_symbol_flag,nb_rb,
-                                   adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                   pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else {
-        nr_dlsch_16qam_64qam_llr(frame_parms,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 rxdataF_comp_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 dl_ch_mag_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                 pdsch_vars[gNB_id]->layer_llr[0],
-                                 symbol,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_64qam_16qam_llr(frame_parms,
-                                   rxdataF_comp_ptr,
-                                   pdsch_vars[gNB_id]->rxdataF_comp0,
-                                   dl_ch_mag_ptr,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,
-                                   pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                   pdsch_vars[gNB_id]->layer_llr[1],
-                                   symbol,first_symbol_flag,nb_rb,
-                                   adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                   pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
+    switch (rx_type) {
+      case rx_standard :
+        for(int l =0; l<dlsch0_harq->Nl; l++)
+          nr_dlsch_16qam_llr(frame_parms,
+                             pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
+                             pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                             pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                             symbol,
+                             len,
+                             first_symbol_flag,
+                             nb_rb,
+                             beamforming_mode);
+        break;
+      case rx_IC_single_stream ://not implemented yet
+        break;
+      case rx_IC_dual_stream ://not implemented yet
+        break;
+      case rx_SIC_dual_stream ://not implemented yet
+        break;
     }
     break;
   case 6 :
-    if ((rx_type==rx_standard) || (codeword_TB1 == -1))  {
-      nr_dlsch_64qam_llr(frame_parms,
-                         pdsch_vars[gNB_id]->rxdataF_comp0,
-                         (int16_t*)pllr_symbol_cw0,
-                         pdsch_vars[gNB_id]->dl_ch_mag0,
-                         pdsch_vars[gNB_id]->dl_ch_magb0,
-                         symbol,len,first_symbol_flag,nb_rb,
-                         pdsch_vars[gNB_id]->llr_offset[symbol],
-                         beamforming_mode);
-    } else if (codeword_TB0 == -1){
-      nr_dlsch_64qam_llr(frame_parms,
-                         pdsch_vars[gNB_id]->rxdataF_comp0,
-                         pllr_symbol_cw1,
-                         pdsch_vars[gNB_id]->dl_ch_mag0,
-                         pdsch_vars[gNB_id]->dl_ch_magb0,
-                         symbol,len,first_symbol_flag,nb_rb,
-                         pdsch_vars[gNB_id]->llr_offset[symbol],
-                         beamforming_mode);
-    }
-    else if (rx_type >= rx_IC_single_stream) {
-      if (dlsch1_harq->Qm == 2) {
-        nr_dlsch_64qam_qpsk_llr(frame_parms,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                rxdataF_comp_ptr,//i
-                                pdsch_vars[gNB_id]->dl_ch_mag0,
-                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                pdsch_vars[gNB_id]->layer_llr[0],
-                                symbol,first_symbol_flag,nb_rb,
-                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_qpsk_64qam_llr(frame_parms,
-                                  rxdataF_comp_ptr,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                  pdsch_vars[gNB_id]->dl_ch_mag0,
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->layer_llr[1],
-                                  symbol,first_symbol_flag,nb_rb,
-                                  adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                                  pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else if (dlsch1_harq->Qm == 4) {
-        nr_dlsch_64qam_16qam_llr(frame_parms,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 rxdataF_comp_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 dl_ch_mag_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                 pdsch_vars[gNB_id]->layer_llr[0],
-                                 symbol,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_16qam_64qam_llr(frame_parms,
-                                   rxdataF_comp_ptr,
-                                   pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                   dl_ch_mag_ptr,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,//i
-                                   pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                   pdsch_vars[gNB_id]->layer_llr[1],
-                                   symbol,first_symbol_flag,nb_rb,
-                                   adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                   pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else {
-        nr_dlsch_64qam_64qam_llr(frame_parms,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 rxdataF_comp_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 dl_ch_mag_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                 (int16_t*)pllr_symbol_layer0,
-                                 symbol,len,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr_offset[symbol]);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_64qam_64qam_llr(frame_parms,
-                                   rxdataF_comp_ptr,
-                                   pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                   dl_ch_mag_ptr,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,//i
-                                   pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                   pllr_symbol_layer1,
-                                   symbol,len,first_symbol_flag,nb_rb,
-                                   adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                   pdsch_vars[gNB_id]->llr_offset[symbol]);
-        }
-      }
+    switch (rx_type) {
+      case rx_standard :
+        for(int l =0; l<dlsch0_harq->Nl; l++)
+          nr_dlsch_64qam_llr(frame_parms,
+                             pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
+                             pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                             pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                             pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                             symbol,
+                             len,
+                             first_symbol_flag,
+                             nb_rb,
+                             beamforming_mode);
+        break;
+      case rx_IC_single_stream ://not implemented yet
+        break;
+      case rx_IC_dual_stream ://not implemented yet
+        break;
+      case rx_SIC_dual_stream ://not implemented yet
+        break;
     }
+
     break;
   case 8:
-    if ((rx_type==rx_standard) || (codeword_TB1 == -1))  {
-      nr_dlsch_256qam_llr(frame_parms,
-                      pdsch_vars[gNB_id]->rxdataF_comp0,
-                      (int16_t*)pllr_symbol_cw0,
-                      pdsch_vars[gNB_id]->dl_ch_mag0,
-                      pdsch_vars[gNB_id]->dl_ch_magb0,
-                      pdsch_vars[gNB_id]->dl_ch_magr0,
-                      symbol,len,first_symbol_flag,nb_rb,
-                      pdsch_vars[gNB_id]->llr_offset[symbol],
-                      beamforming_mode);
-    } else if (codeword_TB0 == -1){
-      nr_dlsch_256qam_llr(frame_parms,
-                      pdsch_vars[gNB_id]->rxdataF_comp0,
-                      pllr_symbol_cw1,
-                      pdsch_vars[gNB_id]->dl_ch_mag0,
-                      pdsch_vars[gNB_id]->dl_ch_magb0,
-                      pdsch_vars[gNB_id]->dl_ch_magr0,
-                      symbol,len,first_symbol_flag,nb_rb,
-                      pdsch_vars[gNB_id]->llr_offset[symbol],
-                      beamforming_mode);
+    switch (rx_type) {
+      case rx_standard :
+        for(int l =0; l<dlsch0_harq->Nl; l++)
+          nr_dlsch_256qam_llr(frame_parms,
+                              pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
+                              pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                              pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                              pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                              pdsch_vars[gNB_id]->dl_ch_magr0[0],
+                              symbol,
+                              len,
+                              first_symbol_flag,
+                              nb_rb,
+                              beamforming_mode);
+        break;
+      case rx_IC_single_stream ://not implemented yet
+        break;
+      case rx_IC_dual_stream ://not implemented yet
+        break;
+      case rx_SIC_dual_stream ://not implemented yet
+        break;
     }
     break;
   default:
@@ -2684,45 +3204,54 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
     case 2 :
       if (rx_type==rx_standard) {
         nr_dlsch_qpsk_llr(frame_parms,
-                          pdsch_vars[gNB_id]->rxdataF_comp0,
-                          pllr_symbol_cw0,
-                          symbol,len,first_symbol_flag,nb_rb,
+                          pdsch_vars[gNB_id]->rxdataF_comp0[0],
+                          pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                          symbol,
+                          len,
+                          first_symbol_flag,
+                          nb_rb,
                           beamforming_mode);
       }
       break;
     case 4:
       if (rx_type==rx_standard) {
         nr_dlsch_16qam_llr(frame_parms,
-                           pdsch_vars[gNB_id]->rxdataF_comp0,
-                           pdsch_vars[gNB_id]->llr[0],
-                           pdsch_vars[gNB_id]->dl_ch_mag0,
-                           symbol,len,first_symbol_flag,nb_rb,
-                           pdsch_vars[gNB_id]->llr128,
+                           pdsch_vars[gNB_id]->rxdataF_comp0[0],
+                           pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                           pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                           symbol,
+                           len,
+                           first_symbol_flag,
+                           nb_rb,
                            beamforming_mode);
       }
       break;
     case 6 :
       if (rx_type==rx_standard) {
         nr_dlsch_64qam_llr(frame_parms,
-                           pdsch_vars[gNB_id]->rxdataF_comp0,
-                           pllr_symbol_cw0,
-                             pdsch_vars[gNB_id]->dl_ch_mag0,
-                             pdsch_vars[gNB_id]->dl_ch_magb0,
-                             symbol,len,first_symbol_flag,nb_rb,
-                             pdsch_vars[gNB_id]->llr_offset[symbol],
-                             beamforming_mode);
+                           pdsch_vars[gNB_id]->rxdataF_comp0[0],
+                           pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                           pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                           pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                           symbol,
+                           len,
+                           first_symbol_flag,
+                           nb_rb,
+                           beamforming_mode);
         }
         break;
     case 8 :
       if (rx_type==rx_standard) {
         nr_dlsch_256qam_llr(frame_parms,
-                            pdsch_vars[gNB_id]->rxdataF_comp0,
-                            pllr_symbol_cw0,
-                            pdsch_vars[gNB_id]->dl_ch_mag0,
-                            pdsch_vars[gNB_id]->dl_ch_magb0,
-                            pdsch_vars[gNB_id]->dl_ch_magr0,
-                            symbol,len,first_symbol_flag,nb_rb,
-                            pdsch_vars[gNB_id]->llr_offset[symbol],
+                            pdsch_vars[gNB_id]->rxdataF_comp0[0],
+                            pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                            pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                            pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                            pdsch_vars[gNB_id]->dl_ch_magr0[0],
+                            symbol,
+                            len,
+                            first_symbol_flag,
+                            nb_rb,
                             beamforming_mode);
       }
         break;
@@ -2736,99 +3265,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_dlsch_llr_computation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
index 68a206e7c746ec709312e4cb29bee5e7824ff4c3..a064a91d87eaee53622854dbecb986eadcd69ccb 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
@@ -629,16 +629,16 @@ __m128i tmp_result4 __attribute__ ((aligned(16)));
 //----------------------------------------------------------------------------------------------
 
 int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
-                   int32_t **rxdataF_comp,
+                   int32_t *rxdataF_comp,
                    int16_t *dlsch_llr,
                    uint8_t symbol,
-				   uint32_t len,
-				   uint8_t first_symbol_flag,
+                   uint32_t len,
+                   uint8_t first_symbol_flag,
                    uint16_t nb_rb,
                    uint8_t beamforming_mode)
 {
 
-  uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][((int32_t)symbol*nb_rb*12)];
+  uint32_t *rxF = (uint32_t *)&rxdataF_comp[((int32_t)symbol*nb_rb*12)];
   uint32_t *llr32;
   int i;
 
@@ -670,24 +670,23 @@ int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
 //----------------------------------------------------------------------------------------------
 
 void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
+                     int32_t *dl_ch_mag,
                      uint8_t symbol,
-					 uint32_t len,
+                     uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     int16_t **llr32p,
                      uint8_t beamforming_mode)
 {
 
 #if defined(__x86_64__) || defined(__i386__)
-  __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
   __m128i *ch_mag;
   __m128i llr128[2];
   uint32_t *llr32;
 #elif defined(__arm__)
-  int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[(symbol*nb_rb*12)];
   int16x8_t *ch_mag;
   int16x8_t xmm0;
   int16_t *llr16;
@@ -699,30 +698,17 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
 
 
 #if defined(__x86_64__) || defined(__i386__)
-  if (first_symbol_flag==1) {
     llr32 = (uint32_t*)dlsch_llr;
-  } else {
-    llr32 = (uint32_t*)*llr32p;
-  }
 #elif defined(__arm__)
-  if (first_symbol_flag==1) {
     llr16 = (int16_t*)dlsch_llr;
-  } else {
-    llr16 = (int16_t*)*llr32p;
-  }
 #endif
 
 #if defined(__x86_64__) || defined(__i386__)
-  ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)];
+  ch_mag = (__m128i*)&dl_ch_mag[(symbol*nb_rb*12)];
 #elif defined(__arm__)
-  ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*nb_rb*12)];
+  ch_mag = (int16x8_t*)&dl_ch_mag[(symbol*nb_rb*12)];
 #endif
 
-  // update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE)
-  if (first_symbol_flag == 1)
-    *llr32p = dlsch_llr + (len<<2);
-  else
-    *llr32p += (len<<2);
 
  // printf("len=%d\n", len);
   len_mod4 = len&3;
@@ -786,47 +772,35 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
 //----------------------------------------------------------------------------------------------
 
 void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-			int32_t **rxdataF_comp,
+			int32_t *rxdataF_comp,
 			int16_t *dlsch_llr,
-			int32_t **dl_ch_mag,
-			int32_t **dl_ch_magb,
+			int32_t *dl_ch_mag,
+			int32_t *dl_ch_magb,
 			uint8_t symbol,
 			uint32_t len,
 			uint8_t first_symbol_flag,
 			uint16_t nb_rb,
-			uint32_t llr_offset,
 			uint8_t beamforming_mode)
 {
 #if defined(__x86_64__) || defined(__i386__)
-  __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
   __m128i *ch_mag,*ch_magb;
 #elif defined(__arm__)
-  int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[(symbol*nb_rb*12)];
   int16x8_t *ch_mag,*ch_magb,xmm1,xmm2;
 #endif
   int i,len2;
   unsigned char len_mod4;
-  short *llr;
   int16_t *llr2;
-  int8_t *pllr_symbol;
-
-  /*
-  if (first_symbol_flag==1)
-    llr = dlsch_llr;
-  else
-    llr = *llr_save;
-  */
-  llr = dlsch_llr;
 
-  pllr_symbol = (int8_t*)dlsch_llr;
-  pllr_symbol += llr_offset;
+  llr2 = dlsch_llr;
 
 #if defined(__x86_64__) || defined(__i386__)
-  ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)];
-  ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*nb_rb*12)];
+  ch_mag = (__m128i*)&dl_ch_mag[(symbol*nb_rb*12)];
+  ch_magb = (__m128i*)&dl_ch_magb[(symbol*nb_rb*12)];
 #elif defined(__arm__)
-  ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*nb_rb*12)];
-  ch_magb = (int16x8_t*)&dl_ch_magb[0][(symbol*nb_rb*12)];
+  ch_mag = (int16x8_t*)&dl_ch_mag[(symbol*nb_rb*12)];
+  ch_magb = (int16x8_t*)&dl_ch_magb[(symbol*nb_rb*12)];
 #endif
 
 //  printf("nr_dlsch_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
@@ -838,9 +812,6 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
              dlsch_llr,
              pllr_symbol);*/
 
-  llr2 = llr;
-  llr += (len*6);
-
   len_mod4 =len&3;
   len2=len>>2;  // length in quad words (4 REs)
   len2+=((len_mod4==0)?0:1);
@@ -1095,43 +1066,29 @@ void nr_dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
 //----------------------------------------------------------------------------------------------
 
 void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
-                     int32_t **dl_ch_magb,
-                     int32_t **dl_ch_magr,
+                     int32_t *dl_ch_mag,
+                     int32_t *dl_ch_magb,
+                     int32_t *dl_ch_magr,
                      uint8_t symbol,
                      uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     uint32_t llr_offset,
                      uint8_t beamforming_mode)
 {
-  __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
   __m128i *ch_mag,*ch_magb,*ch_magr;
 
   int i,len2;
   unsigned char len_mod4;
-  short *llr;
   int16_t *llr2;
-  int8_t *pllr_symbol;
-
-  /*
-  if (first_symbol_flag==1)
-    llr = dlsch_llr;
-  else
-    llr = *llr_save;
-  */
-  llr = dlsch_llr;
 
-  pllr_symbol = (int8_t*)dlsch_llr;
-  pllr_symbol += llr_offset;
+  llr2 = dlsch_llr;
 
-  ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)];
-  ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*nb_rb*12)];
-  ch_magr = (__m128i*)&dl_ch_magr[0][(symbol*nb_rb*12)];
-  llr2 = llr;
-  llr += (len*8);
+  ch_mag = (__m128i*)&dl_ch_mag[(symbol*nb_rb*12)];
+  ch_magb = (__m128i*)&dl_ch_magb[(symbol*nb_rb*12)];
+  ch_magr = (__m128i*)&dl_ch_magr[(symbol*nb_rb*12)];
 
   len_mod4 =len&3;
   len2=len>>2;  // length in quad words (4 REs)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index 13270c5c4b4c06030566d45debb76e53f58b272a..d11a852a1ea95e38594a7de3cf21ca1b92e3824d 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -161,13 +161,12 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
 #endif
 
     ret = nr_rx_pbch(ue,
-	             proc,
-		     ue->pbch_vars[0],
-		     frame_parms,
-		     0,
-		     temp_ptr->i_ssb,
-                     SISO,
-                     ue->high_speed_flag);
+                     proc,
+                     ue->pbch_vars[0],
+                     frame_parms,
+                     0,
+                     temp_ptr->i_ssb,
+                     SISO);
 
     temp_ptr=temp_ptr->next_ssb;
   }
@@ -289,8 +288,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames)
                               proc,
                               i,
                               0,
-                              is*fp->samples_per_frame+ue->ssb_offset,
-                              0);
+                              is*fp->samples_per_frame+ue->ssb_offset);
 
 #ifdef DEBUG_INITIAL_SYNCH
       LOG_I(PHY,"Calling sss detection (normal CP)\n");
@@ -309,15 +307,17 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames)
         // every 7*(1<<mu) symbols there is a different prefix length (38.211 5.3.1)
         int n_symb_prefix0 = (ue->symbol_offset/(7*(1<<mu)))+1;
         sync_pos_frame = n_symb_prefix0*(fp->ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
-        if (ue->ssb_offset < sync_pos_frame)
+        // for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of the n_frames we got sync
+        ue->init_sync_frame = n_frames - 1 - is;
+        // we also need to take into account the shift by samples_per_frame in case the if is true
+        if (ue->ssb_offset < sync_pos_frame){
           ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset;
+          ue->init_sync_frame += 1;
+        }
         else
           ue->rx_offset = ue->ssb_offset - sync_pos_frame;
-
-        ue->init_sync_frame = is;
       }   
 
-      nr_gold_pdcch(ue,0, 2);
     /*
     int nb_prefix_samples0 = fp->nb_prefix_samples0;
     fp->nb_prefix_samples0 = fp->nb_prefix_samples;
@@ -374,8 +374,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames)
 #endif
     //#endif
 
-    ue->is_synchronized_on_frame = is; // to notify on which of the two frames sync was successful
-
     if (ue->UE_scan_carrier == 0) {
 
     #if UE_AUTOTEST_TRACE
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index e33693ce0e090ed2f45a63864a5511bcd99b6a7d..4d9e2dce3522f0cd6cdd531073bfaef0bddc48c4 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
@@ -54,22 +54,20 @@ uint16_t nr_pbch_extract(int **rxdataF,
                          int **dl_ch_estimates_ext,
                          uint32_t symbol,
                          uint32_t s_offset,
-                         uint32_t high_speed_flag,
                          NR_DL_FRAME_PARMS *frame_parms) {
   uint16_t rb;
   uint8_t i,j,aarx;
   int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
   int nushiftmod4 = frame_parms->nushift;
-  unsigned int  rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; //and
-
- // if (rx_offset>= frame_parms->ofdm_symbol_size) rx_offset-=frame_parms->ofdm_symbol_size;
- rx_offset=(rx_offset)%(frame_parms->ofdm_symbol_size);
 
   AssertFatal(symbol>=1 && symbol<5,
               "symbol %d illegal for PBCH extraction\n",
               symbol);
 
   for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+    unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
+    rx_offset = (rx_offset)%(frame_parms->ofdm_symbol_size);
+
     rxF        = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size];
     rxF_ext    = &rxdataF_ext[aarx][symbol*20*12];
 #ifdef DEBUG_PBCH
@@ -139,10 +137,7 @@ uint16_t nr_pbch_extract(int **rxdataF,
       }
     }
 
-    if (high_speed_flag == 1)
-      dl_ch0     = &dl_ch_estimates[aarx][((symbol+s_offset)*(frame_parms->ofdm_symbol_size))];
-    else
-      dl_ch0     = &dl_ch_estimates[aarx][0];
+    dl_ch0 = &dl_ch_estimates[aarx][((symbol+s_offset)*(frame_parms->ofdm_symbol_size))];
 
     //printf("dl_ch0 addr %p\n",dl_ch0);
     dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*20*12];
@@ -333,7 +328,7 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
 #endif
 }
 
-void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
+static void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
                           uint16_t Nid,
                           uint8_t nushift,
                           uint16_t M,
@@ -421,8 +416,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
                 NR_DL_FRAME_PARMS *frame_parms,
                 uint8_t gNB_id,
                 uint8_t i_ssb,
-                MIMO_mode_t mimo_mode,
-                uint32_t high_speed_flag) {
+                MIMO_mode_t mimo_mode) {
 
   NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
   int max_h=0;
@@ -471,7 +465,6 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
                     nr_ue_pbch_vars->dl_ch_estimates_ext,
                     symbol,
                     symbol_offset,
-                    high_speed_flag,
                     frame_parms);
 #ifdef DEBUG_PBCH
     LOG_I(PHY,"[PHY] PBCH Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size );
@@ -556,7 +549,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
 
   nr_ue_pbch_vars->pbch_a_prime = a_reversed;
   //payload un-scrambling
-  memset(&nr_ue_pbch_vars->pbch_a_interleaved, 0, sizeof(uint32_t) );
+  nr_ue_pbch_vars->pbch_a_interleaved=0;
   M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
   nushift = ((nr_ue_pbch_vars->pbch_a_prime>>24)&1) ^ (((nr_ue_pbch_vars->pbch_a_prime>>6)&1)<<1);
   nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_PAYLOAD_BITS,1,unscrambling_mask);
@@ -590,7 +583,9 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
       frame_parms->ssb_index += (((nr_ue_pbch_vars->xtra_byte>>(7-i))&0x01)<<(3+i));
   }
 
-  ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms);
+  ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,frame_parms->ssb_index);
+  if (frame_parms->half_frame_bit)
+    ue->symbol_offset += (frame_parms->slots_per_frame>>1)*frame_parms->symbols_per_slot;
 
   uint8_t frame_number_4lsb = 0;
   for (int i=0; i<4; i++)
@@ -612,7 +607,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, 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 3ab88dac0a5aeb804ec4e45667b3ef0ccdefd19c..e7cf3c15a913a3127a1516c9a80fc583d09f62b9 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=INT16_MAX, 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;
@@ -130,6 +130,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
     #endif
 
     not_found = 1;
+    nr_fill_du(N_ZC,prach_root_sequence_map);
     preamble_index0 = preamble_index;
     // set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
     // preamble index and find the corresponding cyclic shift
@@ -216,12 +217,13 @@ 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,
-    slot,
-    k,
-    n_ra_prb,
-    preamble_offset,
-    first_nonzero_root_idx);
+  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);
 
   Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx];
 
@@ -244,87 +246,83 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
    *********************************************************/
 
   if (mu==1) {
-  if (fp->N_RB_UL <= 100)
-    AssertFatal(1 == 0, "N_RB_UL %d not support for NR PRACH yet\n", fp->N_RB_UL);
-  else if (fp->N_RB_UL < 137) {
-    if (fp->threequarter_fs == 0) {
-      //40 MHz @ 61.44 Ms/s
-      //50 MHz @ 61.44 Ms/s
+    switch(fp->samples_per_subframe) {
+    case 15360:
+      // 10, 15 MHz @ 15.36 Ms/s
       if (prach_sequence_length == 0) {
         if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
-            dftlen = 49152;
+          dftlen = 12288;
         if (prach_fmt_id == 3)
-            dftlen = 12288;
-      } // 839 sequence
-      else {
-        switch (mu){
-          case 1:
-            dftlen = 2048;
-            break;
-          default:
-            AssertFatal(1 == 0, "Shouldn't get here\n");
-            break;
-        }
+          dftlen = 3072;
+      } else { // 839 sequence
+        dftlen = 512;
       }
-    } else { // threequarter sampling
-      //  40 MHz @ 46.08 Ms/s
+      break;
+
+    case 30720:
+      // 20, 25, 30 MHz @ 30.72 Ms/s
+      if (prach_sequence_length == 0) {
+        if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
+          dftlen = 24576;
+        if (prach_fmt_id == 3)
+          dftlen = 6144;
+      } else { // 839 sequence
+        dftlen = 1024;
+      }
+      break;
+
+    case 46080:
+      // 40 MHz @ 46.08 Ms/s
       if (prach_sequence_length == 0) {
-        AssertFatal(fp->N_RB_UL <= 107, "cannot do 108..136 PRBs with 3/4 sampling\n");
         if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
           dftlen = 36864;
         if (prach_fmt_id == 3)
           dftlen = 9216;
-      } else {
-        switch (mu){
-          case 1:
-            dftlen = 1536;
-          break;
-          default:
-            AssertFatal(1 == 0, "Shouldn't get here\n");
-            break;
-        }
-      } // short format
-    } // 3/4 sampling
-  } // <=50 MHz BW
-  else if (fp->N_RB_UL <= 273) {
-    if (fp->threequarter_fs == 0) {
-    //80,90,100 MHz @ 122.88 Ms/s
+      } else { // 839 sequence
+        dftlen = 1536;
+      }
+      break;
+
+    case 61440:
+      // 40, 50, 60 MHz @ 61.44 Ms/s
       if (prach_sequence_length == 0) {
         if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
-          dftlen = 98304;
+          dftlen = 49152;
         if (prach_fmt_id == 3)
-          dftlen = 24576;
+          dftlen = 12288;
+      } else { // 839 sequence
+        dftlen = 2048;
       }
-    } else { // threequarter sampling
-      switch (mu){
-        case 1:
-          dftlen = 4096;
-          break;
-        default:
-          AssertFatal(1 == 0, "Shouldn't get here\n");
-          break;
+      break;
+
+    case 92160:
+      // 50, 60, 70, 80, 90 MHz @ 92.16 Ms/s
+      if (prach_sequence_length == 0) {
+        if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
+          dftlen = 73728;
+        if (prach_fmt_id == 3)
+          dftlen = 18432;
+      } else { // 839 sequence
+        dftlen = 3072;
       }
-    }
-  } else {
-    AssertFatal(fp->N_RB_UL <= 217, "cannot do more than 217 PRBs with 3/4 sampling\n");
-    //  80 MHz @ 92.16 Ms/s
-    if (prach_sequence_length == 0) {
-      if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
-        dftlen = 73728;
-      if (prach_fmt_id == 3)
-        dftlen = 18432;
-    } else {
-      switch (mu){
-        case 1:
-          dftlen = 3072;
-          break;
-        default:
-          AssertFatal(1 == 0, "Shouldn't get here\n");
-          break;
+      break;
+
+    case 122880:
+      // 70, 80, 90, 100 MHz @ 122.88 Ms/s
+      if (prach_sequence_length == 0) {
+        if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
+          dftlen = 98304;
+        if (prach_fmt_id == 3)
+          dftlen = 24576;
+      } else { // 839 sequence
+        dftlen = 4096;
       }
+      break;
+
+    default:
+      AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu);
     }
   }
-  }
   else if (mu==3) {
     if (fp->threequarter_fs) 
       AssertFatal(1==0,"3/4 sampling not supported for numerology %d\n",mu);
@@ -425,15 +423,16 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
   uint8_t  use_extended_prach_prefix = 0;
   if(fp->numerology_index == 0) {
     if (prachStartSymbol == 0 || prachStartSymbol == 7)
-	  use_extended_prach_prefix = 1;
+      use_extended_prach_prefix = 1;
   }
   else {
     if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0)
-	  use_extended_prach_prefix = 1;
+      use_extended_prach_prefix = 1;
   }
-    
-  if (fp->N_RB_UL <= 34) { //32 PRB case 61.44Msps
-    if (fp->threequarter_fs == 0) {
+
+  if (mu == 3) {
+    switch (fp->samples_per_subframe) {
+    case 61440: // 32 PRB case, 61.44 Msps
       Ncp<<=1; //to account for 61.44Mbps
       // This is after cyclic prefix 
       prach2 = prach+(Ncp<<1); //times 2 for complex samples
@@ -491,13 +490,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
           prach_len = (512*12)+Ncp;
 	}		
       }
-    }
-    else
-      AssertFatal(1==0,"3/4 sampling not supported for this PRACH size %d\n",fp->N_RB_UL);
-   
-  }
-  else if (fp->N_RB_UL <= 68) {//66 PRB case, 122.88 Msps 
-    if (fp->threequarter_fs == 0) {
+      break;
+
+    case 122880: // 66 PRB case, 122.88 Msps
       Ncp<<=2; //to account for 122.88Mbps
       // This is after cyclic prefix 
       prach2 = prach+(Ncp<<1); //times 2 for complex samples
@@ -555,13 +550,211 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
           prach_len = (1024*12)+Ncp;
 	}	
       }
+      break;
+
+    default:
+      AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu);
     }
-    else
-      AssertFatal(1==0,"3/4 sampling not supported for this PRACH size %d\n",fp->N_RB_UL);
-  }
-  else if (fp->N_RB_UL < 137) { // 46.08 or 61.44 Ms/s
-    if (fp->threequarter_fs == 0) { // full sampling @ 61.44 Ms/s
-      Ncp<<=1; //to account for 61.44Mbps 
+  } else if (mu == 1) {
+    switch (fp->samples_per_subframe) {
+    case 15360: // full sampling @ 15.36 Ms/s
+      Ncp = Ncp/2; // to account for 15.36 Ms/s
+      // This is after cyclic prefix
+      prach2 = prach+(2*Ncp); // times 2 for complex samples
+      if (prach_sequence_length == 0){
+        if (prach_fmt_id == 0) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s
+          idft(IDFT_12288,prachF,prach2,1);
+          // here we have | empty  | Prach12288 |
+          memmove(prach,prach+(12288<<1),(Ncp<<2));
+          // here we have | Prefix | Prach12288 |
+          prach_len = 12288+Ncp;
+        } else if (prach_fmt_id == 1) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s
+          idft(IDFT_12288,prachF,prach2,1);
+          // here we have | empty  | Prach12288 | empty12288 |
+          memmove(prach2+(12288<<1),prach2,(12288<<2));
+          // here we have | empty  | Prach12288 | Prach12288 |
+          memmove(prach,prach+(12288<<2),(Ncp<<2));
+          // here we have | Prefix | Prach12288 | Prach12288 |
+          prach_len = (12288*2)+Ncp;
+        } else if (prach_fmt_id == 2) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s
+          idft(IDFT_12288,prachF,prach2,1);
+          // here we have | empty  | Prach12288 | empty12288 | empty12288 | empty12288 |
+          memmove(prach2+(12288<<1),prach2,(12288<<2));
+          // here we have | empty  | Prach12288 | Prach12288 | empty12288 | empty12288 |
+          memmove(prach2+(12288<<2),prach2,(12288<<3));
+          // here we have | empty  | Prach12288 | Prach12288 | Prach12288 | Prach12288 |
+          memmove(prach,prach+(12288<<3),(Ncp<<2));
+          // here we have | Prefix | Prach12288 | Prach12288 | Prach12288 | Prach12288 |
+          prach_len = (12288*4)+Ncp;
+        } else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s, 3072 samples @ 15.36 Ms/s
+          idft(IDFT_3072,prachF,prach2,1);
+          // here we have | empty  | Prach3072 | empty3072 | empty3072 | empty3072 |
+          memmove(prach2+(3072<<1),prach2,(3072<<2));
+          // here we have | empty  | Prach3072 | Prach3072 | empty3072 | empty3072 |
+          memmove(prach2+(3072<<2),prach2,(3072<<3));
+          // here we have | empty  | Prach3072 | Prach3072 | Prach3072 | Prach3072 |
+          memmove(prach,prach+(3072<<3),(Ncp<<2));
+          // here we have | Prefix | Prach3072 | Prach3072 | Prach3072 | Prach3072 |
+          prach_len = (3072*4)+Ncp;
+        }
+      } else { // short PRACH sequence
+	if (use_extended_prach_prefix)
+	  Ncp += 8; // 16*kappa, kappa=0.5 for 15.36 Ms/s
+	prach2 = prach+(2*Ncp); // times 2 for complex samples
+        if (prach_fmt_id == 9) {
+          idft(IDFT_512,prachF,prach2,1);
+          // here we have | empty  | Prach512 |
+          memmove(prach,prach+(512<<1),(Ncp<<2));
+          // here we have | Prefix | Prach512 |
+          prach_len = (512*1)+Ncp;
+        } else if (prach_fmt_id == 4 || prach_fmt_id == 7) {
+          idft(IDFT_512,prachF,prach2,1);
+          // here we have | empty  | Prach512 | empty512 |
+          memmove(prach2+(512<<1),prach2,(512<<2));
+          // here we have | empty  | Prach512 | Prach512 |
+          memmove(prach,prach+(512<<1),(Ncp<<2));
+          // here we have | Prefix | Prach512 | Prach512 |
+          prach_len = (512*2)+Ncp;
+        } else if (prach_fmt_id == 5) { // 4x512
+          idft(IDFT_512,prachF,prach2,1);
+          // here we have | empty  | Prach512 | empty512 | empty512 | empty512 |
+          memmove(prach2+(512<<1),prach2,(512<<2));
+          // here we have | empty  | Prach512 | Prach512 | empty512 | empty512 |
+          memmove(prach2+(512<<2),prach2,(512<<3));
+          // here we have | empty  | Prach512 | Prach512 | Prach512 | Prach512 |
+          memmove(prach,prach+(512<<1),(Ncp<<2));
+          // here we have | Prefix | Prach512 | Prach512 | Prach512 | Prach512 |
+          prach_len = (512*4)+Ncp;
+        } else if (prach_fmt_id == 6) { // 6x512
+          idft(IDFT_512,prachF,prach2,1);
+          // here we have | empty  | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 |
+          memmove(prach2+(512<<1),prach2,(512<<2));
+          // here we have | empty  | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 |
+          memmove(prach2+(512<<2),prach2,(512<<3));
+          // here we have | empty  | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 |
+          memmove(prach2+(512<<3),prach2,(512<<3));
+          // here we have | empty  | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 |
+          memmove(prach,prach+(512<<1),(Ncp<<2));
+          // here we have | Prefix | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 |
+          prach_len = (512*6)+Ncp;
+        } else if (prach_fmt_id == 8) { // 12x512
+          idft(IDFT_512,prachF,prach2,1);
+          // here we have | empty  | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 |
+          memmove(prach2+(512<<1),prach2,(512<<2));
+          // here we have | empty  | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 |
+          memmove(prach2+(512<<2),prach2,(512<<3));
+          // here we have | empty  | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 |
+          memmove(prach2+(512<<3),prach2,(512<<3));
+          // here we have | empty  | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 |
+          memmove(prach2+(512<<1)*6,prach2,(512<<2)*6);
+          // here we have | empty  | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 |
+          memmove(prach,prach+(512<<1),(Ncp<<2));
+          // here we have | Prefix | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 |
+          prach_len = (512*12)+Ncp;
+        }
+      }
+      break;
+
+    case 30720: // full sampling @ 30.72 Ms/s
+      Ncp = Ncp*1; // to account for 30.72 Ms/s
+      // This is after cyclic prefix
+      prach2 = prach+(2*Ncp); // times 2 for complex samples
+      if (prach_sequence_length == 0){
+        if (prach_fmt_id == 0) { // 24576 samples @ 30.72 Ms/s
+          idft(IDFT_24576,prachF,prach2,1);
+          // here we have | empty  | Prach24576 |
+          memmove(prach,prach+(24576<<1),(Ncp<<2));
+          // here we have | Prefix | Prach24576 |
+          prach_len = 24576+Ncp;
+        } else if (prach_fmt_id == 1) { // 24576 samples @ 30.72 Ms/s
+          idft(IDFT_24576,prachF,prach2,1);
+          // here we have | empty  | Prach24576 | empty24576 |
+          memmove(prach2+(24576<<1),prach2,(24576<<2));
+          // here we have | empty  | Prach24576 | Prach24576 |
+          memmove(prach,prach+(24576<<2),(Ncp<<2));
+          // here we have | Prefix | Prach24576 | Prach24576 |
+          prach_len = (24576*2)+Ncp;
+        } else if (prach_fmt_id == 2) { // 24576 samples @ 30.72 Ms/s
+          idft(IDFT_24576,prachF,prach2,1);
+          // here we have | empty  | Prach24576 | empty24576 | empty24576 | empty24576 |
+          memmove(prach2+(24576<<1),prach2,(24576<<2));
+          // here we have | empty  | Prach24576 | Prach24576 | empty24576 | empty24576 |
+          memmove(prach2+(24576<<2),prach2,(24576<<3));
+          // here we have | empty  | Prach24576 | Prach24576 | Prach24576 | Prach24576 |
+          memmove(prach,prach+(24576<<3),(Ncp<<2));
+          // here we have | Prefix | Prach24576 | Prach24576 | Prach24576 | Prach24576 |
+          prach_len = (24576*4)+Ncp;
+        } else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s
+          idft(IDFT_6144,prachF,prach2,1);
+          // here we have | empty  | Prach6144 | empty6144 | empty6144 | empty6144 |
+          memmove(prach2+(6144<<1),prach2,(6144<<2));
+          // here we have | empty  | Prach6144 | Prach6144 | empty6144 | empty6144 |
+          memmove(prach2+(6144<<2),prach2,(6144<<3));
+          // here we have | empty  | Prach6144 | Prach6144 | Prach6144 | Prach6144 |
+          memmove(prach,prach+(6144<<3),(Ncp<<2));
+          // here we have | Prefix | Prach6144 | Prach6144 | Prach6144 | Prach6144 |
+          prach_len = (6144*4)+Ncp;
+        }
+      } else { // short PRACH sequence
+	if (use_extended_prach_prefix)
+	  Ncp += 16; // 16*kappa, kappa=1 for 30.72Msps
+	prach2 = prach+(2*Ncp); // times 2 for complex samples
+        if (prach_fmt_id == 9) {
+          idft(IDFT_1024,prachF,prach2,1);
+          // here we have | empty  | Prach1024 |
+          memmove(prach,prach+(1024<<1),(Ncp<<2));
+          // here we have | Prefix | Prach1024 |
+          prach_len = (1024*1)+Ncp;
+        } else if (prach_fmt_id == 4 || prach_fmt_id == 7) {
+          idft(IDFT_1024,prachF,prach2,1);
+          // here we have | empty  | Prach1024 | empty1024 |
+          memmove(prach2+(1024<<1),prach2,(1024<<2));
+          // here we have | empty  | Prach1024 | Prach1024 |
+          memmove(prach,prach+(1024<<1),(Ncp<<2));
+          // here we have | Prefix | Prach1024 | Prach1024 |
+          prach_len = (1024*2)+Ncp;
+        } else if (prach_fmt_id == 5) { // 4x1024
+          idft(IDFT_1024,prachF,prach2,1);
+          // here we have | empty  | Prach1024 | empty1024 | empty1024 | empty1024 |
+          memmove(prach2+(1024<<1),prach2,(1024<<2));
+          // here we have | empty  | Prach1024 | Prach1024 | empty1024 | empty1024 |
+          memmove(prach2+(1024<<2),prach2,(1024<<3));
+          // here we have | empty  | Prach1024 | Prach1024 | Prach1024 | Prach1024 |
+          memmove(prach,prach+(1024<<1),(Ncp<<2));
+          // here we have | Prefix | Prach1024 | Prach1024 | Prach1024 | Prach1024 |
+          prach_len = (1024*4)+Ncp;
+        } else if (prach_fmt_id == 6) { // 6x1024
+          idft(IDFT_1024,prachF,prach2,1);
+          // here we have | empty  | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 |
+          memmove(prach2+(1024<<1),prach2,(1024<<2));
+          // here we have | empty  | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 |
+          memmove(prach2+(1024<<2),prach2,(1024<<3));
+          // here we have | empty  | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 |
+          memmove(prach2+(1024<<3),prach2,(1024<<3));
+          // here we have | empty  | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 |
+          memmove(prach,prach+(1024<<1),(Ncp<<2));
+          // here we have | Prefix | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 |
+          prach_len = (1024*6)+Ncp;
+        } else if (prach_fmt_id == 8) { // 12x1024
+          idft(IDFT_1024,prachF,prach2,1);
+          // here we have | empty  | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 |
+          memmove(prach2+(1024<<1),prach2,(1024<<2));
+          // here we have | empty  | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 |
+          memmove(prach2+(1024<<2),prach2,(1024<<3));
+          // here we have | empty  | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 |
+          memmove(prach2+(1024<<3),prach2,(1024<<3));
+          // here we have | empty  | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 |
+          memmove(prach2+(1024<<1)*6,prach2,(1024<<2)*6);
+          // here we have | empty  | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 |
+          memmove(prach,prach+(1024<<1),(Ncp<<2));
+          // here we have | Prefix | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 |
+          prach_len = (1024*12)+Ncp;
+        }
+      }
+      break;
+
+    case 61440: // full sampling @ 61.44 Ms/s
+      Ncp = Ncp*2; // to account for 61.44 Ms/s
       // This is after cyclic prefix 
       prach2 = prach+(Ncp<<1); //times 2 for complex samples
       if (prach_sequence_length == 0){
@@ -587,7 +780,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
           memmove(prach,prach+(49152<<3),(Ncp<<2));
           // here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152
           prach_len = (49152*4)+Ncp;
-        } else if (prach_fmt_id == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s
+        } else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s
           idft(IDFT_12288,prachF,prach2,1);
           memmove(prach2+(12288<<1),prach2,(12288<<2));
           // here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288
@@ -649,7 +842,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
           prach_len = (2048*12)+Ncp;
         }
       }
-    } else {  // threequarter sampling @ 46.08 Ms/s
+      break;
+
+    case 46080: // threequarter sampling @ 46.08 Ms/s
       Ncp = (Ncp*3)/2;
       prach2 = prach+(Ncp<<1);
       if (prach_sequence_length == 0){
@@ -738,9 +933,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
           prach_len = (1536*12)+Ncp;
         }
       }
-    }
-  } else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s
-    if (fp->threequarter_fs == 0) { // full sampling @ 122.88 Ms/s
+      break;
+
+    case 122880: // full sampling @ 122.88 Ms/s
       Ncp<<=2; //to account for 122.88Mbps
       // This is after cyclic prefix
       prach2 = prach+(Ncp<<1); //times 2 for complex samples
@@ -828,7 +1023,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
           prach_len = (4096*12)+Ncp;
         }
       }
-    } else { // three quarter sampling @ 92.16 Ms/s
+      break;
+
+    case 92160: // three quarter sampling @ 92.16 Ms/s
       Ncp = (Ncp*3); //to account for 92.16 Msps
       prach2 = prach+(Ncp<<1); //times 2 for complex samples
       if (prach_sequence_length == 0){
@@ -915,6 +1112,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
           prach_len = (3072*12)+Ncp;
         }
       }
+      break;
+
+    default:
+      AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu);
     }
   }
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
index 91274b908a686959ee5d8e24442347cf40e65a00..bb61e1a173dbd799d6a9ba8f6279c4c48d0b326d 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -471,7 +471,7 @@ int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
     @param beamforming_mode beamforming mode
 */
 int32_t nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
-                   int32_t **rxdataF_comp,
+                   int32_t *rxdataF_comp,
                    int16_t *dlsch_llr,
                    uint8_t symbol,
 				   uint32_t len,
@@ -505,14 +505,13 @@ int32_t nr_dlsch_qpsk_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
                            uint32_t rb_alloc);
 
 void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
+                     int32_t *dl_ch_mag,
                      uint8_t symbol,
-					 uint32_t len,
+                     uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     int16_t **llr32p,
                      uint8_t beamforming_mode);
 /**
    \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
@@ -553,28 +552,26 @@ void dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
                          uint32_t rb_alloc);
 
 void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
-                     int32_t **dl_ch_magb,
+                     int32_t *dl_ch_mag,
+                     int32_t *dl_ch_magb,
                      uint8_t symbol,
-					 uint32_t len,
+                     uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     uint32_t llr_offset,
                      uint8_t beamforming_mode);
 
 void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
-                     int32_t **dl_ch_magb,
-                     int32_t **dl_ch_magr,
+                     int32_t *dl_ch_mag,
+                     int32_t *dl_ch_magb,
+                     int32_t *dl_ch_magr,
                      uint8_t symbol,
                      uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     uint32_t llr_offset,
                      uint8_t beamforming_mode);
 
 /** \fn dlsch_siso(NR_DL_FRAME_PARMS *frame_parms,
@@ -686,11 +683,8 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms,
     int32_t **dl_ch_estimates,
     int32_t **rxdataF_ext,
     int32_t **dl_ch_estimates_ext,
-    uint16_t pmi,
-    uint8_t *pmi_ext,
     uint32_t *rb_alloc,
     uint8_t symbol,
-    uint8_t nr_slot_rx,
     NR_DL_FRAME_PARMS *frame_parms)
     \brief This function extracts the received resource blocks, both channel estimates and data symbols,
     for the current allocation and for single antenna eNB transmission.
@@ -698,67 +692,61 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms,
     @param dl_ch_estimates Channel estimates of current slot
     @param rxdataF_ext FFT output for RBs in this allocation
     @param dl_ch_estimates_ext Channel estimates for RBs in this allocation
-    @param pmi subband Precoding matrix indicator
-    @param pmi_ext Extracted PMI for chosen RBs
     @param rb_alloc RB allocation vector
     @param symbol Symbol to extract
-    @param nr_slot_rx Slot number
-    @param high_speed_flag
+    @param n_dmrs_cdm_groups
     @param frame_parms Pointer to frame descriptor
 */
 unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
                                         int **dl_ch_estimates,
                                         int **rxdataF_ext,
                                         int **dl_ch_estimates_ext,
-                                        unsigned short pmi,
-                                        unsigned char *pmi_ext,
                                         unsigned char symbol,
                                         uint8_t pilots,
                                         uint8_t config_type,
                                         unsigned short start_rb,
-                                        unsigned short nb_pdsch_rb,
-                                        unsigned char nr_slot_rx,
-                                        uint32_t high_speed_flag,
+                                        unsigned short nb_rb_pdsch,
+                                        uint8_t n_dmrs_cdm_groups,
                                         NR_DL_FRAME_PARMS *frame_parms,
                                         uint16_t dlDmrsSymbPos);
 
-/** \fn dlsch_extract_rbs_dual(int32_t **rxdataF,
+/** \fn dlsch_extract_rbs_multiple(int32_t **rxdataF,
     int32_t **dl_ch_estimates,
     int32_t **rxdataF_ext,
     int32_t **dl_ch_estimates_ext,
-    uint16_t pmi,
-    uint8_t *pmi_ext,
-    uint32_t *rb_alloc,
-    uint8_t symbol,
-    NR_DL_FRAME_PARMS *frame_parms)
+    unsigned char symbol
+    uint8_t pilots,
+    uint8_t config_type,
+    unsigned short start_rb,
+    unsigned short nb_rb_pdsch,
+    uint8_t n_dmrs_cdm_groups,
+    uint8_t Nl,
+    NR_DL_FRAME_PARMS *frame_parms,
+    uint16_t dlDmrsSymbPos)
     \brief This function extracts the received resource blocks, both channel estimates and data symbols,
-    for the current allocation and for dual antenna eNB transmission.
+    for the current allocation and for multiple layer antenna gNB transmission.
     @param rxdataF Raw FFT output of received signal
     @param dl_ch_estimates Channel estimates of current slot
     @param rxdataF_ext FFT output for RBs in this allocation
     @param dl_ch_estimates_ext Channel estimates for RBs in this allocation
-    @param pmi subband Precoding matrix indicator
-    @param pmi_ext Extracted PMI for chosen RBs
-    @param rb_alloc RB allocation vector
+    @param Nl nb of antenna layers
     @param symbol Symbol to extract
-    @param nr_slot_rx Slot index
-    @param high_speed_flag
+    @param n_dmrs_cdm_groups
     @param frame_parms Pointer to frame descriptor
 */
-unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF,
-                                      int **dl_ch_estimates,
-                                      int **rxdataF_ext,
-                                      int **dl_ch_estimates_ext,
-                                      unsigned short pmi,
-                                      unsigned char *pmi_ext,
-                                      unsigned char symbol,
-									  uint8_t pilots,
-									  unsigned short start_rb,
-									  unsigned short nb_rb_pdsch,
-                                      unsigned char nr_slot_rx,
-                                      uint32_t high_speed_flag,
-                                      NR_DL_FRAME_PARMS *frame_parms,
-                                      MIMO_mode_t mimo_mode);
+unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
+                                        int **dl_ch_estimates,
+                                        int **rxdataF_ext,
+                                        int **dl_ch_estimates_ext,
+                                        unsigned char symbol,
+                                        uint8_t pilots,
+                                        uint8_t config_type,
+                                        unsigned short start_rb,
+                                        unsigned short nb_rb_pdsch,
+                                        uint8_t n_dmrs_cdm_groups,
+                                        uint8_t Nl,
+                                        NR_DL_FRAME_PARMS *frame_parms,
+                                        uint16_t dlDmrsSymbPos);
 
 /** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
     int32_t **dl_bf_ch_estimates,
@@ -812,10 +800,11 @@ void nr_dlsch_channel_compensation(int32_t **rxdataF_ext,
                                 int32_t **dl_ch_magb,
                                 int32_t **dl_ch_magr,
                                 int32_t **rxdataF_comp,
-                                int32_t **rho,
+                                int32_t ***rho,
                                 NR_DL_FRAME_PARMS *frame_parms,
+                                uint8_t nb_aatx,
                                 uint8_t symbol,
-								uint8_t start_symbol,
+                                int length,
                                 uint8_t first_symbol_flag,
                                 uint8_t mod_order,
                                 uint16_t nb_rb,
@@ -827,7 +816,7 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
                                      int **dl_ch_mag,
                                      int **dl_ch_magb,
                                      int **rxdataF_comp,
-                                     int **rho,
+                                     int ***rho,
                                      unsigned char n_tx,
                                      unsigned char n_rx,
                                      unsigned char mod_order,
@@ -898,6 +887,17 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
                                 int length,
                                 int start_point);
 
+void nr_dlsch_detection_mrc(int **rxdataF_comp,
+                            int ***rho,
+                            int **dl_ch_mag,
+                            int **dl_ch_magb,
+                            int **dl_ch_magr,
+                            short n_tx,
+                            short n_rx,
+                            unsigned char symbol,
+                            unsigned short nb_rb,
+                            int length);
+
 void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
                               int **rxdataF_comp_i,
                               int **rho,
@@ -971,6 +971,7 @@ void dlsch_channel_compensation_TM34(NR_DL_FRAME_PARMS *frame_parms,
 */
 void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
                          NR_DL_FRAME_PARMS *frame_parms,
+                         uint8_t n_tx,
                          int32_t *avg,
                          uint8_t symbol,
 						 uint32_t len,
@@ -1002,6 +1003,8 @@ void dlsch_channel_level_TM7(int32_t **dl_bf_ch_estimates_ext,
 
 void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
                          NR_DL_FRAME_PARMS *frame_parms,
+                         uint8_t n_tx,
+                         uint8_t n_rx,
                          NR_UE_DLSCH_t **dlsch_ue,
                          uint8_t symbol,
                          uint8_t start_symbol,
@@ -1162,13 +1165,12 @@ int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uin
   \returns number of tx antennas or -1 if error
 */
 int nr_rx_pbch( PHY_VARS_NR_UE *ue,
-		     UE_nr_rxtx_proc_t *proc,
-		     NR_UE_PBCH *nr_ue_pbch_vars,
-		     NR_DL_FRAME_PARMS *frame_parms,
-		     uint8_t eNB_id,
-                     uint8_t i_ssb,
-		     MIMO_mode_t mimo_mode,
-		     uint32_t high_speed_flag);
+                UE_nr_rxtx_proc_t *proc,
+                NR_UE_PBCH *nr_ue_pbch_vars,
+                NR_DL_FRAME_PARMS *frame_parms,
+                uint8_t eNB_id,
+                uint8_t i_ssb,
+                MIMO_mode_t mimo_mode);
 
 int nr_pbch_detection(UE_nr_rxtx_proc_t *proc,
 		      PHY_VARS_NR_UE *ue,
@@ -1473,11 +1475,13 @@ void nr_get_carrier_frequencies(NR_DL_FRAME_PARMS *fp,
   @param dl_Carrier     DL carrier to be set
   @param freq_offset    Freq offset to be set
 */
-void nr_rf_card_config(openair0_config_t *openair0_cfg,
-                       double rx_gain_off,
-                       uint64_t ul_Carrier,
-                       uint64_t dl_Carrier,
-                       int freq_offset);
+void nr_rf_card_config_gain(openair0_config_t *openair0_cfg,
+                            double rx_gain_off);
+
+void nr_rf_card_config_freq(openair0_config_t *openair0_cfg,
+                            uint64_t ul_Carrier,
+                            uint64_t dl_Carrier,
+                            int freq_offset);
 
 
 void print_CQI(void *o,UCI_format_t uci_format,uint8_t eNB_id,int N_RB_DL);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index 464bcfcfbaddd92866d334bc8714d9c3bac508c0..e8a96062556b6ebd9015a809489699c999be1aa2 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -38,10 +38,10 @@
 
 //#include "PHY/defs_nr_UE.h"
 #include "../NR_TRANSPORT/nr_transport_common_proto.h"
-#ifndef STANDALONE_COMPILE
+/*#ifndef STANDALONE_COMPILE
 #include "UTIL/LISTS/list.h"
 #endif
-
+*/
 #include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h"
 
 
@@ -56,34 +56,6 @@ typedef enum {
  RETRANSMISSION_HARQ
 } harq_result_t;
 
-//#if defined(UPGRADE_RAT_NR)
-#if 1
-typedef struct {
-  /// HARQ process id
-  uint8_t harq_id;
-  /// HARQ rx status
-  harq_result_t rx_status;
-  /// ACK bits (after decoding) 0:NACK / 1:ACK / 2:DTX
-  uint8_t ack;
-  /// send status (for PUCCH)
-  uint8_t send_harq_status;
-  /// nCCE (for PUCCH)
-  uint8_t nCCE;
-  /// DAI value detected from DCI1/1a/1b/1d/2/2a/2b/2c. 0xff indicates not touched
-  uint8_t vDAI_DL;
-  /// DAI value detected from DCI0/4. 0xff indicates not touched
-  uint8_t vDAI_UL;
-  /// allow to define pucch parameters TS 38.213 9.2.3 UE procedure for reporting HARQ-ACK
-  uint8_t  pucch_resource_indicator;
-  /// slot on which feedback ack should be send to network
-  uint16_t slot_for_feedback_ack;
-  /// index of a first CCE for the PDCCH reception
-  uint8_t  n_CCE;
-  /// number of CCEs in a control resource set of a PDCCH reception conveying DCI format 1_0
-  uint8_t  N_CCE;
-} NR_UE_HARQ_STATUS_t;
-#endif
-
 typedef struct {
   /// NDAPI struct for UE
   nfapi_nr_ue_pusch_pdu_t pusch_pdu;
@@ -105,6 +77,8 @@ typedef struct {
   uint8_t O_ACK;
   /// Index of current HARQ round for this ULSCH
   uint8_t round;
+  /// Last Ndi for this harq process
+  uint8_t ndi;
   /// pointer to pdu from MAC interface (TS 36.212 V15.4.0, Sec 5.1 p. 8)
   unsigned char *a;
   /// Pointer to the payload + CRC 
@@ -317,7 +291,7 @@ typedef struct {
   /// codeword this transport block is mapped to
   uint8_t codeword;
   /// HARQ-ACKs
-  NR_UE_HARQ_STATUS_t harq_ack;
+  uint8_t ack;
   /// PTRS Frequency Density
   uint8_t PTRSFreqDensity;
   /// PTRS Time Density
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 7cf64b28bb3d13361f81df11b9de66a12b991595..29cccdcf8811dbc9605bf6c9a532a5d9d99abf85 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];
@@ -46,11 +48,9 @@ void nr_get_carrier_frequencies(NR_DL_FRAME_PARMS *fp, uint64_t *dl_carrier, uin
 
 }
 
-void nr_rf_card_config(openair0_config_t *openair0_cfg,
-                       double rx_gain_offset,
-                       uint64_t ul_carrier,
-                       uint64_t dl_carrier,
-                       int freq_offset){
+
+void nr_rf_card_config_gain(openair0_config_t *openair0_cfg,
+                            double rx_gain_off){
 
   uint8_t mod_id     = 0;
   uint8_t cc_id      = 0;
@@ -59,6 +59,36 @@ void nr_rf_card_config(openair0_config_t *openair0_cfg,
   double rx_gain     = ue->rx_total_gain_dB;
   double tx_gain     = ue->tx_total_gain_dB;
 
+  for (int i = rf_chain; i < rf_chain + 4; i++) {
+
+    if (tx_gain)
+      openair0_cfg->tx_gain[i] = tx_gain;
+    if (rx_gain)
+      openair0_cfg->rx_gain[i] = rx_gain - rx_gain_off;
+
+    openair0_cfg->autocal[i] = 1;
+
+    if (i < openair0_cfg->rx_num_channels) {
+      LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_gain %f, rx_gain %f\n",
+        i,
+        rf_chain,
+        openair0_cfg->tx_gain[i],
+        openair0_cfg->rx_gain[i]);
+    }
+
+  }
+}
+
+void nr_rf_card_config_freq(openair0_config_t *openair0_cfg,
+                            uint64_t ul_carrier,
+                            uint64_t dl_carrier,
+                            int freq_offset){
+
+  uint8_t mod_id     = 0;
+  uint8_t cc_id      = 0;
+  PHY_VARS_NR_UE *ue = PHY_vars_UE_g[mod_id][cc_id];
+  int rf_chain       = ue->rf_map.chain;
+
   for (int i = rf_chain; i < rf_chain + 4; i++) {
 
     if (i < openair0_cfg->rx_num_channels)
@@ -71,20 +101,15 @@ void nr_rf_card_config(openair0_config_t *openair0_cfg,
     else
       openair0_cfg->tx_freq[i] = 0.0;
 
-    if (tx_gain)
-      openair0_cfg->tx_gain[i] = tx_gain;
-    if (rx_gain)
-      openair0_cfg->rx_gain[i] = rx_gain - rx_gain_offset;
-
     openair0_cfg->autocal[i] = 1;
 
-    LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_gain %f, rx_gain %f, tx_freq %f Hz, rx_freq %f Hz\n",
-      i,
-      rf_chain,
-      openair0_cfg->tx_gain[i],
-      openair0_cfg->rx_gain[i],
-      openair0_cfg->tx_freq[i],
-      openair0_cfg->rx_freq[i]);
+    if (i < openair0_cfg->rx_num_channels) {
+      LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_freq %f Hz, rx_freq %f Hz\n",
+        i,
+        rf_chain,
+        openair0_cfg->tx_freq[i],
+        openair0_cfg->rx_freq[i]);
+    }
 
   }
-}
\ No newline at end of file
+}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index d9bea8a3ac0b00bff35247c80930e482dc2fc731..5733ef6eb3c3595481bdc9757a5877140e70e970 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -40,6 +40,7 @@
 #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include <openair2/UTIL/OPT/opt.h>
 
 //#define DEBUG_ULSCH_CODING
 
@@ -202,7 +203,6 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL,
       for (i=0; i<number_of_harq_pids; i++) {
         ulsch->harq_processes[i]->round=0;
       }
-
       return(ulsch);
     }
   }
@@ -257,8 +257,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
   Ilbrm = 0;
   Tbslbrm = 950984; //max tbs
   Coderate = 0.0;
-  harq_process->round = nr_rv_round_map_ue[harq_process->pusch_pdu.pusch_data.rv_index];
-
+  trace_NRpdu(DIRECTION_UPLINK, harq_process->a, harq_process->pusch_pdu.pusch_data.tb_size, 0, WS_C_RNTI, 0, 0, 0,0, 0);
 ///////////
 /////////////////////////////////////////////////////////////////////////////////////////  
 
@@ -266,22 +265,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 == 1) {  // this is a new packet
-  if (harq_process->round == 0) {  // 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
@@ -415,7 +416,8 @@ 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;
   Kr = harq_process->K;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 208901f289ce13ac05bb95b41fc2bcc2f7bb4a08..4ada19ba33108b8aa5804c12020c0edc35c0c1d2 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -114,7 +114,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
   NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
   NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
-  // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
 
   uint8_t  num_of_codewords = 1; // tmp assumption
   int      Nid_cell = 0;
@@ -137,7 +136,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
     uint8_t mod_order         = pusch_pdu->qam_mod_order;
     uint16_t rnti             = pusch_pdu->rnti;
     uint8_t cdm_grps_no_data  = pusch_pdu->num_dmrs_cdm_grps_no_data;
-    uint16_t start_sc         = frame_parms->first_carrier_offset + start_rb*NR_NB_SC_PER_RB;
+    uint16_t start_sc         = frame_parms->first_carrier_offset + (start_rb+pusch_pdu->bwp_start)*NR_NB_SC_PER_RB;
 
     if (start_sc >= frame_parms->ofdm_symbol_size)
       start_sc -= frame_parms->ofdm_symbol_size;
@@ -146,6 +145,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;
@@ -195,7 +197,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   /////////////////////////DMRS Modulation/////////////////////////
   ///////////
   uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
-  uint16_t n_dmrs = (start_rb+nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
+  uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
   int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16)));
   ///////////
   ////////////////////////////////////////////////////////////////////////
@@ -250,14 +252,15 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   uint8_t u = 0, v = 0;
   int16_t *dmrs_seq = NULL;
 
-  if (pusch_pdu->transform_precoding == transform_precoder_enabled) { 
+  // if  transform precoding is enbaled (value 0)
+  if (pusch_pdu->transform_precoding == 0) {
 
     uint32_t nb_re_pusch=nb_rb * NR_NB_SC_PER_RB;
     uint32_t y_offset = 0;
     uint16_t num_dmrs_res_per_symbol = nb_rb*(NR_NB_SC_PER_RB/2);
     
     // Calculate index to dmrs seq array based on number of DMRS Subcarriers on this symbol
-    index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol);    
+    index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol);
     u = pusch_pdu->dfts_ofdm.low_papr_group_number;
     v = pusch_pdu->dfts_ofdm.low_papr_sequence_number;
     dmrs_seq = dmrs_lowpaprtype1_ul_ref_sig[u][v][index];
@@ -295,7 +298,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
       }
       
       printf("NR_ULSCH_UE: numSym: %d, num_dmrs_sym: %d", number_of_symbols,number_dmrs_symbols);
-      for (int ll = 0; ll < (number_of_symbols-number_dmrs_symbols); ll++) {  
+      for (int ll = 0; ll < (number_of_symbols-number_dmrs_symbols); ll++) {
 
         nr_idft(&debug_symbols[offset], nb_re_pusch);
 
@@ -351,25 +354,27 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
       if ((ul_dmrs_symb_pos >> l) & 0x01) {
         is_dmrs_sym = 1;
 
-   
-        if (pusch_pdu->transform_precoding == transform_precoder_disabled){ 
+        // transform precoding disabled (value 1)
+        if (pusch_pdu->transform_precoding == 1){
         
           if (dmrs_type == pusch_dmrs_type1)
-            dmrs_idx = start_rb*6;
+            dmrs_idx = (pusch_pdu->bwp_start + start_rb)*6;
           else
-            dmrs_idx = start_rb*4;
-       
-          // Perform this on gold sequence, not required when SC FDMA operation is done,         
+            dmrs_idx = (pusch_pdu->bwp_start + start_rb)*4;
+
+          // 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 {
-            dmrs_idx = 0;
-          }
+          dmrs_idx = 0;
+        }
        
        
-      } else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {       
+      } else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
 
-        AssertFatal(pusch_pdu->transform_precoding == transform_precoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); 
+        AssertFatal(pusch_pdu->transform_precoding == 1, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n");
 
         if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) {
           is_ptrs_sym = 1;
@@ -400,8 +405,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
         }
 
         if (is_dmrs == 1) {
-
-          if (pusch_pdu->transform_precoding == transform_precoder_enabled) { 
+          // if transform precoding is enabled
+          if (pusch_pdu->transform_precoding == 0) {
           
             ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15;
             ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15;
@@ -496,13 +501,19 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
   int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
   for(ap = 0; ap < Nl; ap++) {
     for (int s=0;s<NR_NUMBER_OF_SYMBOLS_PER_SLOT;s++){
-      LOG_D(PHY,"rotating txdataF symbol %d (%d) => (%d.%d)\n",
-	    s,s+symb_offset,frame_parms->symbol_rotation[2*(s+symb_offset)],frame_parms->symbol_rotation[1+(2*(s+symb_offset))]);
-      rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size*s],
-			&frame_parms->symbol_rotation[2*(s+symb_offset)],
-			(int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size*s],
-			frame_parms->ofdm_symbol_size,
-			15);
+
+      LOG_D(PHY,"In %s: rotating txdataF symbol %d (%d) => (%d.%d)\n",
+        __FUNCTION__,
+        s,
+        s + symb_offset,
+        frame_parms->symbol_rotation[1][2 * (s + symb_offset)],
+        frame_parms->symbol_rotation[1][1 + (2 * (s + symb_offset))]);
+
+      rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s],
+                        &frame_parms->symbol_rotation[1][2 * (s + symb_offset)],
+                        (int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s],
+                        frame_parms->ofdm_symbol_size,
+                        15);
     }
   }
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
index 4ac1c47b02f5b48d39ce87ce41c0ea7e512e2ee0..28b6677b2ca9f0a5e7c77e9841b0246242ba6115 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -213,7 +213,7 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2)
   }
 
   for (int n=0; n < LENGTH_PSS_NR; n++) {
-	int m = (n + 43*N_ID_2)%(LENGTH_PSS_NR);
+    int m = (n + 43*N_ID_2)%(LENGTH_PSS_NR);
     d_pss[n] = 1 - 2*x[m];
   }
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
index 3560b235502de2d1e4927c2b7fa93fe2455d6bb8..61bca6f409a9fc97d9ceeb2f58333ab91bccc817 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
@@ -54,15 +54,10 @@
 void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
                         int32_t **txdataF,
                         NR_DL_FRAME_PARMS *frame_parms,
-                        long pucch_GroupHopping,
-                        long hoppingId,
                         int16_t amp,
                         int nr_slot_tx,
-                        uint8_t m0,
-			uint8_t mcs,
-                        uint8_t nrofSymbols,
-                        uint8_t startingSymbolIndex,
-                        uint16_t startingPRB) {
+                        fapi_nr_ul_config_pucch_pdu *pucch_pdu) {
+
 #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 +89,45 @@ 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};
+
+  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, 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->mcs);
+
+
 #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];
+
+  uint16_t startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start;
+  pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1);
 
   // we proceed to calculate alpha according to TS 38.211 Subclause 6.3.2.2.2
-  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);
+  int prb_offset[2]={startingPRB,startingPRB};
+  nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,0,nr_slot_tx,&u[0],&v[0]); // calculating u and v value
+  if (pucch_pdu->freq_hop_flag == 1) {
+    nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,1,nr_slot_tx,&u[1],&v[1]); // calculating u and v value
+    prb_offset[1] = pucch_pdu->second_hop_prb;
+  }
+  for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
+    alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,
+                                    pucch_pdu->initial_cyclic_shift,
+                                    pucch_pdu->mcs,l,
+                                    pucch_pdu->start_symbol_index,
+                                    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
     }
   }
@@ -137,17 +139,20 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
   uint32_t re_offset=0;
   uint8_t l2;
 
-  for (int l=0; l<nrofSymbols; l++) {
-    l2=l+startingSymbolIndex;
-    re_offset = (12*startingPRB) + frame_parms->first_carrier_offset;
+  for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
+    l2=l+pucch_pdu->start_symbol_index;
+    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];
@@ -167,20 +172,20 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
 void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
                         int32_t **txdataF,
                         NR_DL_FRAME_PARMS *frame_parms,
-                        PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
-                        uint64_t payload,
                         int16_t amp,
                         int nr_slot_tx,
-                        uint8_t m0,
-                        uint8_t nrofSymbols,
-                        uint8_t startingSymbolIndex,
-                        uint16_t startingPRB,
-                        uint16_t startingPRB_intraSlotHopping,
-                        uint8_t timeDomainOCC,
-                        uint8_t nr_bit) {
-#ifdef DEBUG_NR_PUCCH_TX
-  printf("\t [nr_generate_pucch1] start function at slot(nr_slot_tx)=%d payload=%lu m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n",
-         nr_slot_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
+                        fapi_nr_ul_config_pucch_pdu *pucch_pdu) {
+
+  uint16_t m0 = pucch_pdu->initial_cyclic_shift;
+  uint64_t payload = pucch_pdu->payload;
+  uint8_t startingSymbolIndex = pucch_pdu->start_symbol_index;
+  uint8_t nrofSymbols = pucch_pdu->nr_of_symbols;
+  uint16_t startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start;
+  uint8_t timeDomainOCC = pucch_pdu->time_domain_occ_idx;
+
+#ifdef DEBUG_NR_PUCCH_TX
+  printf("\t [nr_generate_pucch1] start function at slot(nr_slot_tx)=%d payload=%lu m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d second_hop_prb=%d timeDomainOCC=%d nr_bit=%d\n",
+         nr_slot_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,pucch_pdu->second_hop_prb,timeDomainOCC,pucch_pdu->n_bit);
 #endif
   /*
    * Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation
@@ -189,12 +194,12 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
   // complex-valued symbol d_re, d_im containing complex-valued symbol d(0):
   int16_t d_re=0, d_im=0;
 
-  if (nr_bit == 1) { // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2
+  if (pucch_pdu->n_bit == 1) { // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2
     d_re = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
     d_im = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
   }
 
-  if (nr_bit == 2) { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2
+  if (pucch_pdu->n_bit == 2) { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2
     if (((payload&1)==0) && (((payload>>1)&1)==0)) {
       d_re =  (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
       d_im =  (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
@@ -255,7 +260,7 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
   //uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers
   uint8_t intraSlotFrequencyHopping = 0;
 
-  if (startingPRB != startingPRB_intraSlotHopping) {
+  if (pucch_pdu->freq_hop_flag) {
     intraSlotFrequencyHopping=1;
   }
 
@@ -286,8 +291,9 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
     printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_slot_tx=%d\n",
            n_hop,nr_slot_tx);
 #endif
-    nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_slot_tx,&u,&v); // calculating u and v value
-    alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,lprime,nr_slot_tx);
+    pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1);
+    nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,n_hop,nr_slot_tx,&u,&v); // calculating u and v value
+    alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,m0,mcs,l,lprime,nr_slot_tx);
 
     for (int n=0; n<12; n++) {
       r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
@@ -440,7 +446,7 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
     }
 
     if ((intraSlotFrequencyHopping == 1) && (l<floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new offset PRB
-      startingPRB = startingPRB + startingPRB_intraSlotHopping;
+      startingPRB = startingPRB + pucch_pdu->second_hop_prb;
     }
 
     if ((startingPRB <  (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
@@ -833,7 +839,7 @@ inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,
       c = (uint8_t)((s>>i)&1);
       btildep[i] = (((B>>i)&1) ^ c);
 #ifdef DEBUG_NR_PUCCH_TX
-      printf("\t\t\t btilde[%d]=%lx from unscrambled bit %d and scrambling %d (%x)\n",i+(iprime<<5),btilde[i],((B>>i)&1),c,s>>i);
+      printf("\t\t\t btilde[%d]=%x from unscrambled bit %d and scrambling %d (%x)\n",i+(iprime<<5),btilde[i],((B>>i)&1),c,s>>i);
 #endif
     }
     M_bit3-=32;
@@ -847,7 +853,7 @@ inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,
 }
 void nr_uci_encoding(uint64_t payload,
                      uint8_t nr_bit,
-                     pucch_format_nr_t fmt,
+                     int fmt,
                      uint8_t is_pi_over_2_bpsk_enabled,
                      uint8_t nrofSymbols,
                      uint8_t nrofPRB,
@@ -867,9 +873,9 @@ void nr_uci_encoding(uint64_t payload,
   // E is the rate matching output sequence length as given in TS 38.212 subclause 6.3.1.4.1
   uint16_t E=0,E_init;
 
-  if (fmt == pucch_format2_nr) E = 16*nrofSymbols*nrofPRB;
+  if (fmt == 2) E = 16*nrofSymbols*nrofPRB;
 
-  if (fmt == pucch_format3_nr) {
+  if (fmt == 3) {
     E_init = (is_pi_over_2_bpsk_enabled == 0) ? 24:12;
 
     if (nrofSymbols == 4) {
@@ -894,7 +900,7 @@ void nr_uci_encoding(uint64_t payload,
     }
   }
 
-  if (fmt == pucch_format4_nr) {
+  if (fmt == 4) {
     E_init = (is_pi_over_2_bpsk_enabled == 0) ? 24:12;
 
     if (nrofSymbols == 4) {
@@ -952,28 +958,24 @@ void nr_uci_encoding(uint64_t payload,
 }
 //#if 0
 void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
-                        uint16_t crnti,
-			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,
-                        uint64_t payload,
                         int16_t amp,
                         int nr_slot_tx,
-                        uint8_t nrofSymbols,
-                        uint8_t startingSymbolIndex,
-                        uint8_t nrofPRB,
-                        uint16_t startingPRB,
-                        uint8_t nr_bit) {
+                        fapi_nr_ul_config_pucch_pdu *pucch_pdu) {
 #ifdef DEBUG_NR_PUCCH_TX
-  printf("\t [nr_generate_pucch2] start function at slot(nr_slot_tx)=%d  with payload=%lu and nr_bit=%d\n",nr_slot_tx, payload, nr_bit);
+  printf("\t [nr_generate_pucch2] start function at slot(nr_slot_tx)=%d  with payload=%lu and nr_bit=%d\n",nr_slot_tx, pucch_pdu->payload, pucch_pdu->n_bit);
 #endif
   // b is the block of bits transmitted on the physical channel after payload coding
   uint64_t b[16]; // limit to 1024-bit encoded length
   // M_bit is the number of bits of block b (payload after encoding)
   uint16_t M_bit;
-  nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,&b[0],&M_bit);
+  nr_uci_encoding(pucch_pdu->payload,
+                  pucch_pdu->n_bit,
+                  2,0,
+                  pucch_pdu->nr_of_symbols,
+                  pucch_pdu->prb_size,
+                  1,0,0,&b[0],&M_bit);
   /*
    * Implementing TS 38.211
    * Subclauses 6.3.2.5.1 Scrambling (PUCCH format 2)
@@ -988,14 +990,14 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
    */
   uint8_t *btilde = malloc(sizeof(int8_t)*M_bit);
   // rnti is given by the C-RNTI
-  uint16_t rnti=crnti;
+  uint16_t rnti=pucch_pdu->rnti;
 #ifdef DEBUG_NR_PUCCH_TX
   printf("\t [nr_generate_pucch2] rnti = %d ,\n",rnti);
 #endif
   /*
    * Implementing TS 38.211 Subclause 6.3.2.5.1 scrambling format 2
    */
-  nr_pucch2_3_4_scrambling(M_bit,rnti,data_scrambling_id,&b[0],btilde);
+  nr_pucch2_3_4_scrambling(M_bit,rnti,pucch_pdu->data_scrambling_id,&b[0],btilde);
   /*
    * Implementing TS 38.211 Subclause 6.3.2.5.2 modulation format 2
    * btilde shall be modulated as described in subclause 5.1 using QPSK
@@ -1041,9 +1043,12 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
   uint32_t x1, x2, s=0;
   int i=0;
   int m=0;
+  uint8_t  startingSymbolIndex = pucch_pdu->start_symbol_index;
+  uint16_t startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start;
 
-  for (int l=0; l<nrofSymbols; l++) {
-    x2 = (((1<<17)*((14*nr_slot_tx) + (l+startingSymbolIndex) + 1)*((2*dmrs_scrambling_id) + 1)) + (2*dmrs_scrambling_id))%(1U<<31); // c_init calculation according to TS38.211 subclause
+  for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
+    // c_init calculation according to TS38.211 subclause
+    x2 = (((1<<17)*((14*nr_slot_tx) + (l+startingSymbolIndex) + 1)*((2*pucch_pdu->dmrs_scrambling_id) + 1)) + (2*pucch_pdu->dmrs_scrambling_id))%(1U<<31); 
 
     int reset = 1;
     for (int ii=0; ii<=(startingPRB>>2); ii++) {
@@ -1051,7 +1056,7 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
       reset = 0;
     }
     m = 0;
-    for (int rb=0; rb<nrofPRB; rb++) {
+    for (int rb=0; rb<pucch_pdu->prb_size; rb++) {
       //startingPRB = startingPRB + rb;
       if (((rb+startingPRB) <  (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
         re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset;
@@ -1123,52 +1128,53 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
 }
 //#if 0
 void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
-                          uint16_t crnti,
                           int32_t **txdataF,
                           NR_DL_FRAME_PARMS *frame_parms,
-                          pucch_format_nr_t fmt,
-                          PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
-                          uint64_t payload,
                           int16_t amp,
                           int nr_slot_tx,
-                          uint8_t nrofSymbols,
-                          uint8_t startingSymbolIndex,
-                          uint8_t nrofPRB,
-                          uint16_t startingPRB,
-                          uint16_t startingPRB_intraSlotHopping,
-                          uint8_t nr_bit,
-                          uint8_t occ_length_format4,
-                          uint8_t occ_index_format4) {
+                          fapi_nr_ul_config_pucch_pdu *pucch_pdu) {
 #ifdef DEBUG_NR_PUCCH_TX
-  printf("\t [nr_generate_pucch3_4] start function at slot(nr_slot_tx)=%d with payload=%lu and nr_bit=%d\n", nr_slot_tx, payload, nr_bit);
+  printf("\t [nr_generate_pucch3_4] start function at slot(nr_slot_tx)=%d with payload=%lu and nr_bit=%d\n", nr_slot_tx, pucch_pdu->payload, pucch_pdu->n_bit);
 #endif
   // b is the block of bits transmitted on the physical channel after payload coding
   uint64_t b[16];
   // M_bit is the number of bits of block b (payload after encoding)
   uint16_t M_bit;
   // parameter PUCCH-F4-preDFT-OCC-length set of {2,4} -> to use table -1 or -2
-  uint8_t n_SF_PUCCH_s = 2; // in format 4, n_SF_PUCCH_s = {2,4}, provided by higher layer parameter PUCCH-F4-preDFT-OCC-length (in format 3 n_SF_PUCCH_s=1), FIXME!!!
-  uint8_t is_pi_over_2_bpsk_enabled = 0; // this value has to be provided by higher layers parameter
+  // in format 4, n_SF_PUCCH_s = {2,4}, provided by higher layer parameter PUCCH-F4-preDFT-OCC-length (in format 3 n_SF_PUCCH_s=1)
+  uint8_t n_SF_PUCCH_s;
+  if (pucch_pdu->format_type == 3)
+    n_SF_PUCCH_s = 1;
+  else
+    n_SF_PUCCH_s = pucch_pdu->pre_dft_occ_len;
+  uint8_t is_pi_over_2_bpsk_enabled = pucch_pdu->pi_2bpsk;
   // Intra-slot frequency hopping shall be assumed when the higher-layer parameter intraSlotFrequencyHopping is provided,
   // regardless of whether the frequency-hop distance is zero or not,
   // otherwise no intra-slot frequency hopping shall be assumed
   //uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers
   uint8_t intraSlotFrequencyHopping = 0;
 
-  if (startingPRB != startingPRB_intraSlotHopping) {
+  if (pucch_pdu->freq_hop_flag) {
     intraSlotFrequencyHopping=1;
 #ifdef DEBUG_NR_PUCCH_TX
     printf("\t [nr_generate_pucch3_4] intraSlotFrequencyHopping=%d \n",intraSlotFrequencyHopping);
 #endif
   }
 
-  // add_dmrs indicates if we are using or not Additional DM-RS for formats 3 and 4. From higher layers. FIXME!!!
-  uint8_t add_dmrs = 0;
-
-  //nrofPRB = 2; // only for test purposes
-  if (fmt == pucch_format4_nr) nrofPRB = 1;
-
-  nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,&b[0],&M_bit);
+  uint8_t nrofSymbols = pucch_pdu->nr_of_symbols;
+  uint16_t nrofPRB = pucch_pdu->prb_size;
+  uint16_t startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start;
+  uint8_t add_dmrs = pucch_pdu->add_dmrs_flag;
+
+  nr_uci_encoding(pucch_pdu->payload,
+                  pucch_pdu->n_bit,
+                  pucch_pdu->format_type,
+                  is_pi_over_2_bpsk_enabled,
+                  nrofSymbols,nrofPRB,
+                  n_SF_PUCCH_s,
+                  intraSlotFrequencyHopping,
+                  add_dmrs,
+                  &b[0],&M_bit);
   /*
    * Implementing TS 38.211
    * Subclauses 6.3.2.6.1 Scrambling (PUCCH formats 3 and 4)
@@ -1183,7 +1189,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
    */
   uint8_t *btilde = malloc(sizeof(int8_t)*M_bit);
   // rnti is given by the C-RNTI
-  uint16_t rnti=crnti, n_id=0;
+  uint16_t rnti=pucch_pdu->rnti, n_id=0;
 #ifdef DEBUG_NR_PUCCH_TX
   printf("\t [nr_generate_pucch3_4] rnti = %d ,\n",rnti);
 #endif
@@ -1299,12 +1305,11 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
     {0, 0, 0, 1, 1, 1, 0, 0, 0,-1,-1,-1}
   };
-  //uint8_t occ_Length = occ_length_format4; // higher layer parameter occ-Length
-  uint8_t occ_Index  = occ_index_format4;  // higher layer parameter occ-Index
+
+  uint8_t occ_Index  = pucch_pdu->pre_dft_occ_idx;  // higher layer parameter occ-Index
 
   //occ_Index = 1; //only for testing purposes; to be removed FIXME!!!
-  if (fmt == pucch_format3_nr) { // no block-wise spreading for format 3
-    n_SF_PUCCH_s = 1;
+  if (pucch_pdu->format_type == 3) { // no block-wise spreading for format 3
 
     for (int l=0; l < floor(m_symbol/(12*nrofPRB)); l++) {
       for (int k=0; k < (12*nrofPRB); k++) {
@@ -1318,7 +1323,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
     }
   }
 
-  if (fmt == pucch_format4_nr) {
+  if (pucch_pdu->format_type == 4) {
     nrofPRB = 1;
 
     for (int l=0; l < floor((n_SF_PUCCH_s*m_symbol)/(12*nrofPRB)); l++) {
@@ -1413,9 +1418,9 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
   uint8_t m0;
   uint8_t mcs=0;
 
-  if (fmt == pucch_format3_nr) m0 = 0;
+  if (pucch_pdu->format_type == 3) m0 = 0;
 
-  if (fmt == pucch_format4_nr) {
+  if (pucch_pdu->format_type == 4) {
     if (n_SF_PUCCH_s == 2) {
       m0 = (occ_Index == 0) ? 0 : 6;
     }
@@ -1455,7 +1460,8 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
   for (int l=0; l<nrofSymbols; l++) {
     if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop
 
-    nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_slot_tx,&u,&v); // calculating u and v value
+    pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1);
+    nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,n_hop,nr_slot_tx,&u,&v); // calculating u and v value
 
     // Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33
     if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies
@@ -1500,12 +1506,13 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
       }
     }
 
+    uint8_t  startingSymbolIndex = pucch_pdu->start_symbol_index;
     uint16_t j=0;
-    alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,startingSymbolIndex,nr_slot_tx);
+    alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,m0,mcs,l,startingSymbolIndex,nr_slot_tx);
 
     for (int rb=0; rb<nrofPRB; rb++) {
       if ((intraSlotFrequencyHopping == 1) && (l<floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new offset PRB
-        startingPRB = startingPRB + startingPRB_intraSlotHopping;
+        startingPRB = startingPRB + pucch_pdu->second_hop_prb;
       }
 
       //startingPRB = startingPRB + rb;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h
index c7f318f588e0be25d67d6d1b2c62d6f975537063..dcf7fb4a37eab55559ed4fbf6219242511ce30bd 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h
@@ -49,61 +49,30 @@
 void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
                         int32_t **txdataF,
                         NR_DL_FRAME_PARMS *frame_parms,
-                        long pucch_GroupHopping,
-                        long hoppingId,
                         int16_t amp,
                         int nr_slot_tx,
-                        uint8_t m0,
-			uint8_t mcs,
-                        uint8_t nrofSymbols,
-                        uint8_t startingSymbolIndex,
-                        uint16_t startingPRB);
+                        fapi_nr_ul_config_pucch_pdu *pucch_pdu);
+
 void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
                         int32_t **txdataF,
                         NR_DL_FRAME_PARMS *frame_parms,
-                        PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
-                        uint64_t payload,
                         int16_t amp,
                         int nr_slot_tx,
-                        uint8_t m0,
-                        uint8_t nrofSymbols,
-                        uint8_t startingSymbolIndex,
-                        uint16_t startingPRB,
-                        uint16_t startingPRB_intraSlotHopping,
-                        uint8_t timeDomainOCC,
-                        uint8_t nr_bit);
+                        fapi_nr_ul_config_pucch_pdu *pucch_pdu);
+
 void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
-                        uint16_t crnti,
-			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,
-                        uint64_t payload,
                         int16_t amp,
                         int nr_slot_tx,
-                        uint8_t nrofSymbols,
-                        uint8_t startingSymbolIndex,
-                        uint8_t nrofPRB,
-                        uint16_t startingPRB,
-                        uint8_t nr_bit);
+                        fapi_nr_ul_config_pucch_pdu *pucch_pdu);
+
 void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
-                          uint16_t crnti,
                           int32_t **txdataF,
                           NR_DL_FRAME_PARMS *frame_parms,
-                          pucch_format_nr_t fmt,
-                          PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
-                          uint64_t payload,
                           int16_t amp,
                           int nr_slot_tx,
-                          uint8_t nrofSymbols,
-                          uint8_t startingSymbolIndex,
-                          uint8_t nrofPRB,
-                          uint16_t startingPRB,
-                          uint16_t startingPRB_intraSlotHopping,
-                          uint8_t nr_bit,
-                          uint8_t occ_length_format4,
-                          uint8_t occ_index_format4);
+                          fapi_nr_ul_config_pucch_pdu *pucch_pdu);
 
 // tables for mcs values for different payloads 
  static const uint8_t table1_mcs[]={0,6,3,9};
diff --git a/openair1/PHY/TOOLS/calibration_scope.c b/openair1/PHY/TOOLS/calibration_scope.c
new file mode 100644
index 0000000000000000000000000000000000000000..da1acb517570e78fa352fcbb289def26fcc67064
--- /dev/null
+++ b/openair1/PHY/TOOLS/calibration_scope.c
@@ -0,0 +1,387 @@
+#include <stdlib.h>
+#include <openair1/PHY/impl_defs_top.h>
+#include "executables/softmodem-common.h"
+#include "executables/nr-softmodem-common.h"
+#include <forms.h>
+#include <openair1/PHY/TOOLS/calibration_scope.h>
+
+#define TPUT_WINDOW_LENGTH 100
+#define ScaleZone 4
+
+const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
+const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED};
+
+typedef struct {
+  int16_t r;
+  int16_t i;
+} scopeSample_t;
+#define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)
+typedef struct {
+  void ** samplesRx;
+  openair0_device *rfdevice;
+} calibData_t;
+
+typedef struct OAIgraph {
+  FL_OBJECT *graph;
+  FL_OBJECT *text;
+  float maxX;
+  float maxY;
+  float minX;
+  float minY;
+  int x;
+  int y;
+  int w;
+  int h;
+  int waterFallh;
+  double *waterFallAvg;
+  boolean_t initDone;
+  int iteration;
+  void (*funct) (struct OAIgraph *graph, calibData_t *);
+} OAIgraph_t;
+
+
+/* Forms and Objects */
+typedef struct {
+  calibData_t * context;
+  FL_FORM    *phy_scope;
+  OAIgraph_t graph[20];
+  FL_OBJECT *button_0;
+} OAI_phy_scope_t;
+
+typedef struct {
+  FL_FORM    *stats_form;
+  void       *vdata;
+  char       *cdata;
+  long        ldata;
+  FL_OBJECT *stats_text;
+  FL_OBJECT *stats_button;
+} FD_stats_form;
+
+static void drawsymbol(FL_OBJECT *obj, int id,
+                       FL_POINT *p, int n, int w, int h) {
+  fl_points( p, n, FL_YELLOW);
+}
+
+#define WATERFALL 10000
+
+static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
+  if (type==WATERFALL) {
+    graph->waterFallh=h-15;
+    graph->waterFallAvg=malloc(sizeof(*graph->waterFallAvg) * graph->waterFallh);
+
+    for (int i=0; i< graph->waterFallh; i++)
+      graph->waterFallAvg[i]=0;
+
+    graph->graph=fl_add_canvas(FL_NORMAL_CANVAS, x, y, w, graph->waterFallh, label);
+    graph->text=fl_add_text(FL_NORMAL_TEXT, x, y+graph->waterFallh, w, 15, label);
+    fl_set_object_lcolor(graph->text,FL_WHITE);
+    fl_set_object_color(graph->text, FL_BLACK, FL_BLACK);
+    fl_set_object_lalign(graph->text, FL_ALIGN_CENTER );
+  } else {
+    graph->graph=fl_add_xyplot(type, x, y, w, h, label);
+    fl_set_object_lcolor(graph->graph, FL_WHITE ); // Label color
+    fl_set_object_color(graph->graph, FL_BLACK, pointColor);
+
+    for (int i=0; i< FL_MAX_XYPLOTOVERLAY; i++)
+      fl_set_xyplot_symbol(graph->graph, i, drawsymbol);
+  }
+
+  graph->x=x;
+  graph->y=y;
+  graph->w=w;
+  graph->h=h;
+  graph->maxX=0;
+  graph->maxY=0;
+  graph->minX=0;
+  graph->minY=0;
+  graph->initDone=false;
+  graph->iteration=0;
+}
+
+static OAIgraph_t calibrationCommonGraph( void (*funct) (OAIgraph_t *graph, calibData_t *context),
+                                  int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
+  OAIgraph_t graph;
+  commonGraph(&graph, type, x, y, w, h, label, pointColor);
+  graph.funct=funct;
+  return graph;
+}
+
+
+static void setRange(OAIgraph_t *graph, float minX, float maxX, float minY, float maxY) {
+  if ( maxX > graph->maxX ||  minX < graph->minX ||
+       abs(maxX-graph->maxX)>abs(graph->maxX)/2 ||
+       abs(maxX-graph->maxX)>abs(graph->maxX)/2 ) {
+    graph->maxX/=2;
+    graph->minX/=2;
+    graph->maxX=max(graph->maxX,maxX);
+    graph->minX=min(graph->minX,minX);
+    fl_set_xyplot_xbounds(graph->graph, graph->minX*1.2, graph->maxX*1.2);
+  }
+
+  if ( maxY > graph->maxY || minY < graph->minY ||
+       abs(maxY-graph->maxY)>abs(graph->maxY)/2 ||
+       abs(maxY-graph->maxY)>abs(graph->maxY)/2 ) {
+    graph->maxY/=2;
+    graph->minY/=2;
+    graph->maxY=max(graph->maxY,maxY);
+    graph->minY=min(graph->minY,minY);
+    fl_set_xyplot_ybounds(graph->graph, graph->minY*1.2, graph->maxY*1.2);
+  }
+}
+
+static void oai_xygraph_getbuff(OAIgraph_t *graph, float **x, float **y, int len, int layer) {
+  float *old_x;
+  float *old_y;
+  int old_len=-1;
+
+  if (graph->iteration >1)
+    fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len);
+
+  if (old_len != len) {
+    LOG_W(HW,"allocating graph of %d scope\n", len);
+    float values[len];
+    float time[len];
+
+    // make time in case we will use it
+    for (int i=0; i<len; i++)
+      time[i] = values[i] = i;
+
+    if (layer==0)
+      fl_set_xyplot_data(graph->graph,time,values,len,"","","");
+    else
+      fl_add_xyplot_overlay(graph->graph,layer,time,values,len,rx_antenna_colors[layer]);
+
+    fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len);
+    AssertFatal(old_len==len,"");
+  }
+
+  *x=old_x;
+  *y=old_y;
+}
+
+static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, boolean_t NoAutoScale) {
+  fl_redraw_object(graph->graph);
+
+  if ( NoAutoScale && graph->iteration%NoAutoScale == 0) {
+    float maxX=0, maxY=0, minX=0, minY=0;
+
+    for (int k=0; k<len; k++) {
+      maxX=max(maxX,x[k]);
+      minX=min(minX,x[k]);
+      maxY=max(maxY,y[k]);
+      minY=min(minY,y[k]);
+    }
+
+    setRange(graph, minX-5, maxX+5, minY-5, maxY+5);
+  }
+
+  graph->iteration++;
+}
+
+static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) {
+  if ( values == NULL )
+     return;
+  fl_winset(FL_ObjWin(graph->graph));
+  const int samplesPerPixel=datasize/graph->w;
+  int displayPart=graph->waterFallh-ScaleZone;
+  int row=graph->iteration%displayPart;
+  double avg=0;
+
+  for (int i=0; i < displayPart; i++)
+    avg+=graph->waterFallAvg[i];
+
+  avg/=displayPart;
+  graph->waterFallAvg[row]=0;
+
+  for (int pix=0; pix<graph->w; pix++) {
+    scopeSample_t *end=values+(pix+1)*samplesPerPixel;
+    end-=2;
+    AssertFatal(end <= values+datasize,"diff : %ld", end-values+datasize);
+    double val=0;
+
+    for (scopeSample_t *s=values+(pix)*samplesPerPixel;
+         s <end;
+         s++)
+      val += SquaredNorm(*s);
+
+    val/=samplesPerPixel;
+    graph->waterFallAvg[row]+=val/graph->w;
+    int col=0;
+
+    if (val > avg*2 )
+      col=1;
+
+    if (val > avg*10 )
+      col=2;
+
+    if (val > avg*100 )
+      col=3;
+
+    fl_point(pix, graph->iteration%displayPart, water_colors[col]);
+  }
+
+  if (graph->initDone==false) {
+    for ( int i=0; i < graph->waterFallh; i++ )
+      for ( int j = 0 ; j < graph->w ; j++ )
+        fl_point(j, i, FL_BLACK);
+
+    for ( int i=1; i<divisions; i++)
+      for (int j= displayPart; j<graph->waterFallh; j++)
+        fl_point(i*(graph->w/divisions),j, FL_WHITE);
+
+    graph->initDone=true;
+  }
+
+  fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, sqrt(avg));
+  graph->iteration++;
+}
+
+static void genericPowerPerAntena(OAIgraph_t  *graph, const int nb_ant, const scopeSample_t **data, const int len) {
+  float *values, *time;
+  oai_xygraph_getbuff(graph, &time, &values, len, 0);
+
+  for (int ant=0; ant<nb_ant; ant++) {
+    if (data[ant] != NULL) {
+      for (int i=0; i<len; i++) {
+        values[i] = SquaredNorm(data[ant][i]);
+      }
+
+      oai_xygraph(graph,time,values, len, ant, 10);
+    }
+  }
+}
+
+static void gNBWaterFall (OAIgraph_t *graph, calibData_t *context) {
+  //use 1st antenna
+  genericWaterFall(graph, (scopeSample_t *)context->samplesRx[0],
+                   0, 0,
+                   "X axis:one frame in time");
+}
+static void gNBfreqWaterFall  (OAIgraph_t *graph, calibData_t *context) {
+  //use 1st antenna
+  genericWaterFall(graph, (scopeSample_t *)context->samplesRx[0],
+                   0, 0,
+                   "X axis:one frame in time");
+}
+static void timeResponse (OAIgraph_t *graph, calibData_t *context) {
+  #if 0
+  const int len=2*phy_vars_gnb->frame_parms.ofdm_symbol_size;
+  float *values, *time;
+  oai_xygraph_getbuff(graph, &time, &values, len, 0);
+  const int ant=0; // display antenna 0 for each UE
+
+  for (int ue=0; ue<nb_UEs; ue++) {
+    scopeSample_t *data= (scopeSample_t *)phy_vars_gnb->pusch_vars[ue]->ul_ch_estimates_time[ant];
+
+    if (data != NULL) {
+      for (int i=0; i<len; i++) {
+        values[i] = SquaredNorm(data[i]);
+      }
+
+      oai_xygraph(graph,time,values, len, ue, 10);
+    }
+  }
+  #endif
+}
+
+static void puschIQ (OAIgraph_t *graph, calibData_t *context) {
+  #if 0
+  NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
+  int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot;
+
+  for (int ue=0; ue<nb_UEs; ue++) {
+    scopeSample_t *pusch_comp = (scopeSample_t *) phy_vars_gnb->pusch_vars[ue]->rxdataF_comp[0];
+    float *I, *Q;
+    oai_xygraph_getbuff(graph, &I, &Q, sz, ue);
+
+    if (pusch_comp) {
+      for (int k=0; k<sz; k++ ) {
+        I[k] = pusch_comp[k].r;
+        Q[k] = pusch_comp[k].i;
+      }
+
+      oai_xygraph(graph,I,Q,sz,ue,10);
+    }
+  }
+  #endif
+}
+
+
+static OAI_phy_scope_t *createScopeCalibration(calibData_t * context) {
+  FL_OBJECT *obj;
+  OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1);
+  fdui->context=context;
+  // Define form
+  fdui->phy_scope = fl_bgn_form( FL_NO_BOX, 800, 800 );
+  // This the whole UI box
+  obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
+  fl_set_object_color( obj, FL_BLACK, FL_WHITE );
+  int curY=0,x,y,w,h;
+  // Received signal
+  fdui->graph[0] = calibrationCommonGraph( gNBWaterFall, WATERFALL, 0, curY, 400, 100,
+                                   "Received Signal (Time-Domain, one frame)", FL_RED );
+  
+  // Time-domain channel response
+  //fdui->graph[1] = calibrationCommonGraph( timeResponse, FL_NORMAL_XYPLOT, 410, curY, 400, 100, "SRS Frequency Response (samples, abs)", FL_RED );
+  fl_get_object_bbox(fdui->graph[0].graph,&x, &y,&w, &h);
+  curY+=h;
+  // Frequency-domain channel response
+  fdui->graph[1] = calibrationCommonGraph( gNBfreqWaterFall, WATERFALL, 0, curY, 800, 100,
+                                   "Channel Frequency domain (RE, one frame)", FL_RED );
+  fl_get_object_bbox(fdui->graph[1].graph,&x, &y,&w, &h);
+  curY+=h+20;
+  // LLR of PUSCH
+  //fdui->graph[3] = calibrationCommonGraph( puschLLR, FL_POINTS_XYPLOT, 0, curY, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
+  // I/Q PUSCH comp
+  fdui->graph[2] = calibrationCommonGraph( puschIQ, FL_POINTS_XYPLOT, 500, curY, 300, 200,
+                                   "PUSCH I/Q of MF Output", FL_YELLOW );
+  fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h);
+  curY+=h;
+  //fl_get_object_bbox(fdui->graph[6].graph,&x, &y,&w, &h);
+  curY+=h;
+  fdui->graph[3].graph=NULL;
+  fl_end_form( );
+  fdui->phy_scope->fdui = fdui;
+  fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, "LTE UL SCOPE gNB");
+  return fdui;
+}
+
+void calibrationScope(OAI_phy_scope_t  *form) {
+  int i=0;
+
+  while (form->graph[i].graph) {
+    form->graph[i].funct(form->graph+i, form->context);
+    i++;
+  }
+
+  //fl_check_forms();
+}
+
+static void *scopeThread(void *arg) {
+  calibData_t * context = (calibData_t *)arg;
+  size_t stksize=0;
+  pthread_attr_t atr;
+  pthread_attr_init(&atr);
+  pthread_attr_getstacksize(&atr, &stksize);
+  pthread_attr_setstacksize(&atr,32*1024*1024 );
+  sleep(3); // no clean interthread barriers
+  int fl_argc=1;
+  char *name="Calibration-scope";
+  fl_initialize (&fl_argc, &name, NULL, 0, 0);
+  OAI_phy_scope_t  *form = createScopeCalibration(context);
+
+  while (!oai_exit) {
+    calibrationScope(form);
+    usleep(99*1000);
+  }
+
+  return NULL;
+}
+
+void CalibrationInitScope(void ** samplesRx,openair0_device *rfdevice) {
+  pthread_t forms_thread;
+  calibData_t * tmp=(calibData_t *) malloc(sizeof(*tmp));
+  tmp->samplesRx=samplesRx;
+  tmp->rfdevice=rfdevice;
+  threadCreate(&forms_thread, scopeThread, (void*) tmp, "scope", -1, OAI_PRIORITY_RT_LOW);
+}
diff --git a/openair1/PHY/TOOLS/calibration_scope.h b/openair1/PHY/TOOLS/calibration_scope.h
new file mode 100644
index 0000000000000000000000000000000000000000..052a1a6b6e5d73e0ccd26db2fc35cfd5d02425f2
--- /dev/null
+++ b/openair1/PHY/TOOLS/calibration_scope.h
@@ -0,0 +1,5 @@
+#ifndef CALIB_SCOPE_H
+#define CALIB_SCOPE_H
+
+void CalibrationInitScope(void ** samplesRx,openair0_device *rfdevice);
+#endif
diff --git a/openair1/PHY/TOOLS/calibration_test.c b/openair1/PHY/TOOLS/calibration_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..53baf83d41dbaab0834f88219300ce6fabfe4c43
--- /dev/null
+++ b/openair1/PHY/TOOLS/calibration_test.c
@@ -0,0 +1,340 @@
+#include <stdint.h>
+#include <openair1/PHY/impl_defs_top.h>
+#include <targets/ARCH/COMMON/common_lib.h>
+#include <executables/softmodem-common.h>
+#include <openair1/PHY/TOOLS/calibration_scope.h>
+
+
+volatile int oai_exit=false;
+unsigned int mmapped_dma=0;
+int      single_thread_flag;
+uint32_t timing_advance;
+int8_t threequarter_fs;
+uint64_t downlink_frequency[MAX_NUM_CCs][4];
+int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+int opp_enabled;
+static double snr_dB=20;
+THREAD_STRUCT thread_struct;
+uint32_t target_ul_mcs = 9;
+uint32_t target_dl_mcs = 9;
+uint64_t dlsch_slot_bitmap = (1<<1);
+uint64_t ulsch_slot_bitmap = (1<<8);
+uint32_t target_ul_bw = 50;
+uint32_t target_dl_bw = 50;
+#include <executables/nr-softmodem.h>
+
+int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) {return 0;}
+void nfapi_setmode(nfapi_mode_t nfapi_mode) {}
+void set_taus_seed(unsigned int seed_init){};
+
+int main(int argc, char **argv) {
+  ///static configuration for NR at the moment
+  if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) {
+    exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
+  }
+  set_softmodem_sighandler();
+  setvbuf(stdout, NULL, _IONBF, 0);
+  setvbuf(stderr, NULL, _IONBF, 0);
+  logInit();
+   paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ;
+
+  CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
+  get_common_options(SOFTMODEM_GNB_BIT );
+  config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
+  CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
+  configure_linux();
+
+    
+  int N_RB=50;
+  int subCarrierFreq=30e3;
+  int sampling_rate=30.72e6;
+  int DFT=2048;
+  int TxAdvanceInDFTSize=12;
+  int antennas=1;
+  uint64_t freq=3619.200e6;
+  int rxGain=90;
+  int txGain=90;
+  int filterBand=40e6;
+  char * usrp_addrs="type=b200";
+
+  openair0_config_t openair0_cfg= {
+    //! Module ID for this configuration
+    .Mod_id=0,
+    //! device log level
+    .log_level=0,
+    //! duplexing mode
+    .duplex_mode=0,
+    //! number of downlink resource blocks
+    .num_rb_dl=N_RB,
+    //! number of samples per frame
+    .samples_per_frame=0,
+    //! the sample rate for both transmit and receive.
+    .sample_rate=sampling_rate,
+    //device is doing mmapped DMA transfers
+    .mmapped_dma=0,
+    //! offset in samples between TX and RX paths
+    .tx_sample_advance=0,
+    //! samples per packet on the fronthaul interface
+    .samples_per_packet=1024,
+    //! number of RX channels (=RX antennas)
+    .rx_num_channels=antennas,
+    //! number of TX channels (=TX antennas)
+    .tx_num_channels=antennas,
+    //! \brief Center frequency in Hz for RX.
+    //! index: [0..rx_num_channels[
+    .rx_freq={freq,freq,freq,freq},
+    //! \brief Center frequency in Hz for TX.
+    //! index: [0..rx_num_channels[ !!! see lte-ue.c:427 FIXME iterates over rx_num_channels
+    .tx_freq={freq,freq,freq,freq},
+    //! \brief memory
+    //! \brief Pointer to Calibration table for RX gains
+    .rx_gain_calib_table=NULL,
+    //! mode for rxgain (ExpressMIMO2)
+    .rxg_mode={0},
+    //! \brief Gain for RX in dB.
+    //! index: [0..rx_num_channels]
+    .rx_gain={rxGain,rxGain,rxGain,rxGain},
+    //! \brief Gain offset (for calibration) in dB
+    //! index: [0..rx_num_channels]
+    .rx_gain_offset={0},
+    //! gain for TX in dB
+    .tx_gain={txGain,txGain,txGain,txGain},
+    //! RX bandwidth in Hz
+    .rx_bw=filterBand,
+    //! TX bandwidth in Hz
+    .tx_bw=filterBand,
+    //! clock source
+    .clock_source=external,//internal gpsdo external
+    //! timing_source
+    .time_source=internal, //internal gpsdo external
+    //! Manual SDR IP address
+    //#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+    .sdr_addrs=usrp_addrs,
+    //! Auto calibration flag
+    .autocal={0},
+    //! rf devices work with x bits iqs when oai have its own iq format
+    //! the two following parameters are used to convert iqs
+    .iq_txshift=0,
+    .iq_rxrescale=0,
+    //! Configuration file for LMS7002M
+    .configFilename="",
+    //! remote IP/MAC addr for Ethernet interface
+    .remote_addr="",
+    //! remote port number for Ethernet interface
+    .remote_port=0,
+    //! local IP/MAC addr for Ethernet interface (eNB/BBU, UE)
+    .my_addr=0,
+    //! local port number for Ethernet interface (eNB/BBU, UE)
+    .my_port=0,
+    //! record player configuration, definition in record_player.h
+    .recplay_mode=0,
+    .recplay_conf=NULL,
+    //! number of samples per tti
+    .samples_per_tti=0,
+    //! check for threequarter sampling rate
+    .threequarter_fs=0,
+  };
+  //-----------------------
+  openair0_device rfdevice= {
+    /*!tx write thread*/
+    //.write_thread={0},
+    /*!brief Module ID of this device */
+    .Mod_id=0,
+    /*!brief Component Carrier ID of this device */
+    .CC_id=0,
+    /*!brief Type of this device */
+    .type=NONE_DEV,
+    /*!brief Transport protocol type that the device supports (in case I/Q samples need to be transported) */
+    .transp_type=NONE_TP,
+    /*!brief Type of the device's host (RAU/RRU) */
+    .host_type=MIN_HOST_TYPE,
+    /* !brief RF frontend parameters set by application */
+    .openair0_cfg=NULL, //set by device_init
+    /* !brief ETH params set by application */
+    .eth_params=NULL,
+    //! record player data, definition in record_player.h
+    .recplay_state=NULL,
+    /* !brief Indicates if device already initialized */
+    .is_init=0,
+    /*!brief Can be used by driver to hold internal structure*/
+    .priv=NULL,
+    /* Functions API, which are called by the application*/
+    /*! \brief Called to start the transceiver. Return 0 if OK, < 0 if error
+        @param device pointer to the device structure specific to the RF hardware target
+    */
+    .trx_start_func=NULL,
+
+    /*! \brief Called to configure the device
+         @param device pointer to the device structure specific to the RF hardware target
+     */
+    .trx_config_func=NULL,
+
+    /*! \brief Called to send a request message between RAU-RRU on control port
+        @param device pointer to the device structure specific to the RF hardware target
+        @param msg pointer to the message structure passed between RAU-RRU
+        @param msg_len length of the message
+    */
+    .trx_ctlsend_func=NULL,
+
+    /*! \brief Called to receive a reply  message between RAU-RRU on control port
+        @param device pointer to the device structure specific to the RF hardware target
+        @param msg pointer to the message structure passed between RAU-RRU
+        @param msg_len length of the message
+    */
+    .trx_ctlrecv_func=NULL,
+
+    /*! \brief Called to send samples to the RF target
+          @param device pointer to the device structure specific to the RF hardware target
+        @param timestamp The timestamp at whicch the first sample MUST be sent
+        @param buff Buffer which holds the samples (2 dimensional)
+        @param nsamps number of samples to be sent
+        @param number of antennas
+        @param flags flags must be set to TRUE if timestamp parameter needs to be applied
+    */
+    .trx_write_func=NULL,
+
+    /*! \brief Called to send samples to the RF target
+        @param device pointer to the device structure specific to the RF hardware target
+        @param timestamp The timestamp at whicch the first sample MUST be sent
+        @param buff Buffer which holds the samples (1 dimensional)
+        @param nsamps number of samples to be sent
+        @param antenna_id index of the antenna if the device has multiple anteannas
+        @param flags flags must be set to TRUE if timestamp parameter needs to be applied
+    */
+    .trx_write_func2=NULL,
+
+    /*! \brief Receive samples from hardware.
+     * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
+     * the first channel. *ptimestamp is the time at which the first sample
+     * was received.
+     * \param device the hardware to use
+     * \param[out] ptimestamp the time at which the first sample was received.
+     * \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps.
+     * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
+     * \param num_antennas number of antennas from which to receive samples
+     * \returns the number of sample read
+     */
+
+    .trx_read_func=NULL,
+
+    /*! \brief Receive samples from hardware, this version provides a single antenna at a time and returns.
+     * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
+     * the first channel. *ptimestamp is the time at which the first sample
+     * was received.
+     * \param device the hardware to use
+     * \param[out] ptimestamp the time at which the first sample was received.
+     * \param[out] buff A pointers to a buffer for received samples. The buffer must be large enough to hold the number of samples \ref nsamps.
+     * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
+     * \param antenna_id Index of antenna from which samples were received
+     * \returns the number of sample read
+     */
+    .trx_read_func2=NULL,
+
+    /*! \brief print the device statistics
+     * \param device the hardware to use
+     * \returns  0 on success
+     */
+    /*! \brief print the device statistics
+       * \param device the hardware to use
+       * \returns  0 on success
+       */
+    .trx_get_stats_func=NULL,
+
+    /*! \brief Reset device statistics
+     * \param device the hardware to use
+     * \returns 0 in success
+     */
+    .trx_reset_stats_func=NULL,
+
+    /*! \brief Terminate operation of the transceiver -- free all associated resources
+     * \param device the hardware to use
+     */
+    .trx_end_func=NULL,
+
+    /*! \brief Stop operation of the transceiver
+     */
+    .trx_stop_func=NULL,
+
+    /* Functions API related to UE*/
+
+    /*! \brief Set RX feaquencies
+     * \param device the hardware to use
+     * \param openair0_cfg RF frontend parameters set by application
+     * \param exmimo_dump_config  dump EXMIMO configuration
+     * \returns 0 in success
+     */
+    .trx_set_freq_func=NULL,
+
+    /*! \brief Set gains
+     * \param device the hardware to use
+     * \param openair0_cfg RF frontend parameters set by application
+     * \returns 0 in success
+     */
+    .trx_set_gains_func=NULL,
+
+    /*! \brief RRU Configuration callback
+     * \param idx RU index
+     * \param arg pointer to capabilities or configuration
+     */
+    .configure_rru=NULL,
+    /*! \brief Pointer to generic RRU private information
+       */
+    .thirdparty_priv=NULL,
+    .thirdparty_init=NULL,
+    /*! \brief Callback for Third-party RRU Cleanup routine
+       \param device the hardware configuration to use
+     */
+    .thirdparty_cleanup=NULL,
+
+    /*! \brief Callback for Third-party start streaming routine
+       \param device the hardware configuration to use
+     */
+    .thirdparty_startstreaming=NULL,
+
+    /*! \brief RRU Configuration callback
+     * \param idx RU index
+     * \param arg pointer to capabilities or configuration
+     */
+    .trx_write_init=NULL,
+    /* \brief Get internal parameter
+     * \param id parameter to get
+     * \return a pointer to the parameter
+     */
+    .get_internal_parameter=NULL,
+  };
+  
+  openair0_device_load(&rfdevice,&openair0_cfg);
+
+  void ** samplesRx = (void **)malloc16(antennas* sizeof(struct complex16 *) );
+  void ** samplesTx = (void **)malloc16(antennas* sizeof(struct complex16 *) );
+
+  int fd=open(getenv("rftestInputFile"),O_RDONLY);
+  AssertFatal(fd>=0,"%s",strerror(errno));
+  
+  for (int i=0; i<antennas; i++) {
+    samplesRx[i] = (int32_t *)malloc16_clear( DFT*sizeof(struct complex16) );
+    samplesTx[i] = (int32_t *)malloc16_clear( DFT*sizeof(struct complex16) );
+  }
+
+  CalibrationInitScope(samplesRx, &rfdevice);
+  openair0_timestamp timestamp=0;
+  rfdevice.trx_start_func(&rfdevice);
+  
+  while(!oai_exit) {
+    for (int i=0; i<antennas; i++)
+      read(fd, samplesTx[i], DFT*sizeof(struct complex16));
+    int readBlockSize = rfdevice.trx_read_func(&rfdevice,
+					       &timestamp,
+					       samplesRx,
+					       DFT,
+					       antennas);
+    int txs = rfdevice.trx_write_func(&rfdevice,
+					    timestamp+TxAdvanceInDFTSize*DFT,
+					    samplesTx,
+					    DFT,
+					    antennas,
+					    0);
+  }
+
+  return 0;
+}
diff --git a/openair1/PHY/TOOLS/lte_enb_scope.c b/openair1/PHY/TOOLS/lte_enb_scope.c
index 19e135ae56a9cfde9a8b92633bf20dfb8f24b59e..220df5b54a3c6629c8259fb6a75b43de141801aa 100644
--- a/openair1/PHY/TOOLS/lte_enb_scope.c
+++ b/openair1/PHY/TOOLS/lte_enb_scope.c
@@ -44,7 +44,6 @@ FD_stats_form        *form_stats=NULL,*form_stats_l2=NULL;
 char                 title[255];
 unsigned char        scope_enb_num_ue = 2;
 static pthread_t     forms_thread; //xforms
-int                  otg_enabled=0;
 
 void reset_stats(FL_OBJECT *button, long arg) {
   int i,j,k;
@@ -131,7 +130,7 @@ int enbscope_autoinit(void) {
       sprintf (title, "LTE UL SCOPE eNB for CC_id %d, UE %d",CC_id,UE_id);
       fl_show_form (form_enb[CC_id][UE_id]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
 
-      if (otg_enabled) {
+      if (0) {
         fl_set_button(form_enb[CC_id][UE_id]->button_0,1);
         fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic ON");
       } else {
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c
index acd22bc78d38cd5d1337d8c7e18623d14e99e23b..d28bb1b8ba221c952909e9e6110d04d5d6679cab 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope.c
@@ -27,7 +27,6 @@
 #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
 
 #define TPUT_WINDOW_LENGTH 100
-int otg_enabled;
 
 FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
 
@@ -57,11 +56,9 @@ static void ia_receiver_on_off( FL_OBJECT *button, long arg) {
 static void dl_traffic_on_off( FL_OBJECT *button, long arg) {
   if (fl_get_button(button)) {
     fl_set_object_label(button, "DL Traffic ON");
-    otg_enabled = 1;
     fl_set_object_color(button, FL_GREEN, FL_GREEN);
   } else {
     fl_set_object_label(button, "DL Traffic OFF");
-    otg_enabled = 0;
     fl_set_object_color(button, FL_RED, FL_RED);
   }
 }
@@ -131,7 +128,6 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) {
   fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" );
   fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
   fl_set_button(fdui->button_0,0);
-  otg_enabled = 0;
   fl_set_object_label(fdui->button_0, "DL Traffic OFF");
   fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
   fl_set_object_callback(fdui->button_0, dl_traffic_on_off, 0 );
@@ -153,7 +149,6 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
   int16_t **chest_t;
   int16_t **chest_f;
   int16_t *pusch_llr;
-  int32_t *pusch_comp;
   int32_t *pucch1_comp;
   int32_t *pucch1_thres;
   int32_t *pucch1ab_comp;
@@ -184,12 +179,11 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
   chest_f_abs = (float *) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
   llr = (float *) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
   bit = malloc(coded_bits_per_codeword*sizeof(float));
-
-  rxsig_t = (int16_t**) phy_vars_enb->RU_list[0]->common.rxdata;
+  rxsig_t = (int16_t **) phy_vars_enb->RU_list[0]->common.rxdata;
   chest_t = (int16_t **) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates;
   chest_f = (int16_t **) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates;
   pusch_llr = (int16_t *) phy_vars_enb->pusch_vars[UE_id]->llr;
-  pusch_comp = (int32_t *) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0];
+  int16_t *pusch_comp= (int16_t *) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0];
   pucch1_comp = (int32_t *) phy_vars_enb->pucch1_stats[UE_id];
   pucch1_thres = (int32_t *) phy_vars_enb->pucch1_stats_thres[UE_id];
   pucch1ab_comp = (int32_t *) phy_vars_enb->pucch1ab_stats[UE_id];
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.h b/openair1/PHY/TOOLS/lte_phy_scope.h
index af9858ebad97796def7d13b4d007171fd61ca920..1873fabea0e09c82c4a21dd74c04743320d82efc 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope.h
+++ b/openair1/PHY/TOOLS/lte_phy_scope.h
@@ -28,6 +28,7 @@
 #include "PHY/defs_eNB.h"
 #include "PHY/defs_UE.h"
 #include "PHY/impl_defs_top.h"
+#include <common/ran_context.h>
 
 
 /* Forms and Objects */
diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
index d44f8e325befb7ae2dc0fd6af11dfcdfb1e90fc9..a9caf8713bda520524a8949fab353fe2130624d2 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
@@ -32,8 +32,7 @@ float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
 float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
 float tput_ue_max[NUMBER_OF_UE_MAX] = {0};
 
-static void ia_receiver_on_off( FL_OBJECT *button, long arg)
-{
+static void ia_receiver_on_off( FL_OBJECT *button, long arg) {
   if (fl_get_button(button)) {
     fl_set_object_label(button, "IA Receiver ON");
     //    PHY_vars_UE_g[0][0]->use_ia_receiver = 1;
@@ -45,8 +44,7 @@ static void ia_receiver_on_off( FL_OBJECT *button, long arg)
   }
 }
 
-static void dl_traffic_on_off( FL_OBJECT *button, long arg)
-{
+static void dl_traffic_on_off( FL_OBJECT *button, long arg) {
   if (fl_get_button(button)) {
     fl_set_object_label(button, "DL Traffic ON");
     otg_enabled = 1;
@@ -58,9 +56,7 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg)
   }
 }
 
-static void sic_receiver_on_off( FL_OBJECT *button, long arg)
-{
-
+static void sic_receiver_on_off( FL_OBJECT *button, long arg) {
   if (fl_get_button(button)) {
     fl_set_object_label(button, "SIC Receiver ON");
     use_sic_receiver = 1;
@@ -72,8 +68,7 @@ static void sic_receiver_on_off( FL_OBJECT *button, long arg)
   }
 }
 
-FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
-{
+FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) {
   FL_OBJECT *obj;
   FD_lte_phy_scope_enb *fdui = fl_malloc( sizeof *fdui );
   // Define form
@@ -145,8 +140,7 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
 
 void phy_scope_eNB(FD_lte_phy_scope_enb *form,
                    PHY_VARS_eNB *phy_vars_enb,
-                   int UE_id)
-{
+                   int UE_id) {
   int eNB_id = 0;
   int i,i2,arx,atx,ind,k;
   LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_enb->frame_parms;
@@ -176,24 +170,27 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
   int coded_bits_per_codeword = 0;
   uint8_t harq_pid; // in TDD config 3 it is sf-2, i.e., can be 0,1,2
   int mcs = 0;
+
   // choose max MCS to compute coded_bits_per_codeword
   if (phy_vars_enb->ulsch[UE_id]!=NULL) {
     for (harq_pid=0; harq_pid<3; harq_pid++) {
       mcs = cmax(phy_vars_enb->ulsch[UE_id]->harq_processes[harq_pid]->mcs,mcs);
     }
   }
+
   coded_bits_per_codeword = frame_parms->N_RB_UL*12*get_Qm(mcs)*frame_parms->symbols_per_tti;
-  chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
-  llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
+  chest_f_abs = (float *) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
+  llr = (float *) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
   bit = malloc(coded_bits_per_codeword*sizeof(float));
-  rxsig_t = (int16_t**) phy_vars_enb->common_vars.rxdata[eNB_id];
-  chest_t = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id];
-  chest_f = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id];
-  pusch_llr = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->llr;
-  pusch_comp = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[eNB_id][0];
-  pucch1_comp = (int32_t*) phy_vars_enb->pucch1_stats[UE_id];
-  pucch1_thres = (int32_t*) phy_vars_enb->pucch1_stats_thres[UE_id];
-  pucch1ab_comp = (int32_t*) phy_vars_enb->pucch1ab_stats[UE_id];
+  rxsig_t = (int16_t **) phy_vars_enb->common_vars.rxdata[eNB_id];
+  chest_t = (int16_t **) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id];
+  chest_f = (int16_t **) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id];
+  pusch_llr = (int16_t *) phy_vars_enb->pusch_vars[UE_id]->llr;
+  pusch_comp = (int16_t *) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[eNB_id][0];
+  pucch1_comp = (int32_t *) phy_vars_enb->pucch1_stats[UE_id];
+  pucch1_thres = (int32_t *) phy_vars_enb->pucch1_stats_thres[UE_id];
+  pucch1ab_comp = (int32_t *) phy_vars_enb->pucch1ab_stats[UE_id];
+
   // Received signal in time domain of receive antenna 0
   if (rxsig_t != NULL) {
     if (rxsig_t[0] != NULL) {
@@ -201,48 +198,61 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
         rxsig_t_dB[0][i] = 10*log10(1.0+(float) ((rxsig_t[0][2*i])*(rxsig_t[0][2*i])+(rxsig_t[0][2*i+1])*(rxsig_t[0][2*i+1])));
         time[i] = (float) i;
       }
+
       fl_set_xyplot_data(form->rxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","","");
     }
+
     for (arx=1; arx<nb_antennas_rx; arx++) {
       if (rxsig_t[arx] != NULL) {
         for (i=0; i<FRAME_LENGTH_COMPLEX_SAMPLES; i++) {
           rxsig_t_dB[arx][i] = 10*log10(1.0+(float) ((rxsig_t[arx][2*i])*(rxsig_t[arx][2*i])+(rxsig_t[arx][2*i+1])*(rxsig_t[arx][2*i+1])));
         }
+
         fl_add_xyplot_overlay(form->rxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]);
       }
     }
   }
+
   // Channel Impulse Response
   if (chest_t != NULL) {
     ymax = 0;
+
     if (chest_t[0] !=NULL) {
       for (i=0; i<(frame_parms->ofdm_symbol_size); i++) {
-  i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size;
-  time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1));
+        i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size;
+        time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1));
         chest_t_abs[0][i] = 10*log10((float) (1+chest_t[0][2*i2]*chest_t[0][2*i2]+chest_t[0][2*i2+1]*chest_t[0][2*i2+1]));
+
         if (chest_t_abs[0][i] > ymax)
           ymax = chest_t_abs[0][i];
       }
+
       fl_set_xyplot_data(form->chest_t,time2,chest_t_abs[0],(frame_parms->ofdm_symbol_size),"","","");
     }
+
     for (arx=1; arx<nb_antennas_rx; arx++) {
       if (chest_t[arx] !=NULL) {
         for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
           chest_t_abs[arx][i] = 10*log10((float) (1+chest_t[arx][2*i]*chest_t[arx][2*i]+chest_t[arx][2*i+1]*chest_t[arx][2*i+1]));
+
           if (chest_t_abs[arx][i] > ymax)
             ymax = chest_t_abs[arx][i];
         }
+
         fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
         fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
       }
     }
+
     // Avoid flickering effect
     //        fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
     fl_set_xyplot_ybounds(form->chest_t,0,ymax);
   }
+
   // Channel Frequency Response
   if (chest_f != NULL) {
     ind = 0;
+
     for (atx=0; atx<nb_antennas_tx; atx++) {
       for (arx=0; arx<nb_antennas_rx; arx++) {
         if (chest_f[(atx<<1)+arx] != NULL) {
@@ -256,14 +266,17 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
         }
       }
     }
+
     // tx antenna 0
     fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
     fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,3);
     fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
     fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","","");
+
     for (arx=1; arx<nb_antennas_rx; arx++) {
       fl_add_xyplot_overlay(form->chest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
     }
+
     // other tx antennas
     if (nb_antennas_tx > 1) {
       if (nb_antennas_rx > 1) {
@@ -279,17 +292,21 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
       }
     }
   }
+
   // PUSCH LLRs
   if (pusch_llr != NULL) {
     for (i=0; i<coded_bits_per_codeword; i++) {
       llr[i] = (float) pusch_llr[i];
       bit[i] = (float) i;
     }
+
     fl_set_xyplot_data(form->pusch_llr,bit,llr,coded_bits_per_codeword,"","","");
   }
+
   // PUSCH I/Q of MF Output
   if (pusch_comp!=NULL) {
     ind=0;
+
     for (k=0; k<frame_parms->symbols_per_tti; k++) {
       for (i=0; i<12*frame_parms->N_RB_UL; i++) {
         I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i];
@@ -297,8 +314,10 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
         ind++;
       }
     }
+
     fl_set_xyplot_data(form->pusch_comp,I,Q,ind,"","","");
   }
+
   // PUSCH I/Q of MF Output
   if (pucch1ab_comp!=NULL) {
     for (ind=0; ind<10240; ind++) {
@@ -308,6 +327,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
       B_pucch[ind] = ind;
       C_pucch[ind] = (float)pucch1_thres[ind];
     }
+
     fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","","");
     fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","","");
     fl_add_xyplot_overlay(form->pucch_comp1,1,B_pucch,C_pucch,1024,FL_RED);
@@ -315,6 +335,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
     fl_set_xyplot_xbounds(form->pucch_comp,-5000,5000);
     fl_set_xyplot_ybounds(form->pucch_comp1,0,80);
   }
+
   // PUSCH Throughput
   memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
   memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
@@ -329,509 +350,564 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
   free(chest_f_abs);
 }
 
-FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void )
-{
-    FL_OBJECT *obj;
-    FD_lte_phy_scope_ue *fdui = fl_malloc( sizeof *fdui );
-    // Define form
-    fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 1000 );
-    // This the whole UI box
-    obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 1000, "" );
-    fl_set_object_color( obj, FL_BLACK, FL_BLACK );
-    // Received signal
-    fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
-    fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
-    fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
-    fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
-    fl_set_xyplot_ybounds(fdui->rxsig_t,30,70);
-    // Time-domain channel response
-    fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" );
-    fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
-    fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
-    fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
-    // Frequency-domain channel response
-    fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
-    fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
-    fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
-    fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
-    fl_set_xyplot_ybounds( fdui->chest_f,30,70);
-    /*
-    // LLR of PBCH
-    fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" );
-    fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX );
-    fl_set_object_color( fdui->pbch_llr, FL_BLACK, FL_GREEN );
-    fl_set_object_lcolor( fdui->pbch_llr, FL_WHITE ); // Label color
-    fl_set_xyplot_symbolsize( fdui->pbch_llr,2);
-    fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR);
-    fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920);
-    // I/Q PBCH comp
-    fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" );
-    fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX );
-    fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN );
-    fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color
-    fl_set_xyplot_symbolsize( fdui->pbch_comp,2);
-    fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100);
-    fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100);
-    // LLR of PDCCH
-    fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" );
-    fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX );
-    fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN );
-    fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color
-    fl_set_xyplot_symbolsize( fdui->pdcch_llr,2);
-    // I/Q PDCCH comp
-    fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" );
-    fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX );
-    fl_set_object_color( fdui->pdcch_comp, FL_BLACK, FL_CYAN );
-    fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color
-    fl_set_xyplot_symbolsize( fdui->pdcch_comp,2);
-    fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR);
-    */
-    int offset=240;
-    // LLR of PDSCH
-    fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
-    fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX );
-    fl_set_object_color( fdui->pdsch_llr, FL_BLACK, FL_YELLOW );
-    fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color
-    fl_set_xyplot_symbolsize( fdui->pdsch_llr,2);
-    fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR);
-    // I/Q PDSCH comp
-    fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500-offset, 240, 200, "PDSCH I/Q of MF Output" );
-    fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX );
-    fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW );
-    fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color
-    fl_set_xyplot_symbolsize( fdui->pdsch_comp,2);
-    // LLR of PDSCH
-    fdui->pdsch_llr1 = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 720-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
-    fl_set_object_boxtype( fdui->pdsch_llr1, FL_EMBOSSED_BOX );
-    fl_set_object_color( fdui->pdsch_llr1, FL_BLACK, FL_YELLOW );
-    fl_set_object_lcolor( fdui->pdsch_llr1, FL_WHITE ); // Label color
-    fl_set_xyplot_symbolsize( fdui->pdsch_llr1,2);
-    fl_set_xyplot_xgrid( fdui->pdsch_llr1,FL_GRID_MAJOR);
-    // I/Q PDSCH comp
-    fdui->pdsch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 720-offset, 240, 200, "PDSCH I/Q of MF Output" );
-    fl_set_object_boxtype( fdui->pdsch_comp1, FL_EMBOSSED_BOX );
-    fl_set_object_color( fdui->pdsch_comp1, FL_BLACK, FL_YELLOW );
-    fl_set_object_lcolor( fdui->pdsch_comp1, FL_WHITE ); // Label color
-    fl_set_xyplot_symbolsize( fdui->pdsch_comp1,2);
-    /*
-    // Throughput on PDSCH
-    fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" );
-    fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX );
-    fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE );
-    fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color
-    */
-    // Generic UE Button
-    fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
-    fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
-    //use_sic_receiver = 0;
-    fl_set_button(fdui->button_0,0);
-    fl_set_object_label(fdui->button_0, "SIC Receiver OFF");
-    fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
-    fl_set_object_callback(fdui->button_0, sic_receiver_on_off, 0 );
-    fl_hide_object(fdui->button_0);
-
-    fl_end_form( );
-    fdui->lte_phy_scope_ue->fdui = fdui;
-    return fdui;
+FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) {
+  FL_OBJECT *obj;
+  FD_lte_phy_scope_ue *fdui = fl_malloc( sizeof *fdui );
+  // Define form
+  fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 1000 );
+  // This the whole UI box
+  obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 1000, "" );
+  fl_set_object_color( obj, FL_BLACK, FL_BLACK );
+  // Received signal
+  fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
+  fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
+  fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
+  fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
+  fl_set_xyplot_ybounds(fdui->rxsig_t,30,70);
+  // Time-domain channel response
+  fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" );
+  fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
+  fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
+  fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
+  // Frequency-domain channel response
+  fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
+  fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
+  fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
+  fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
+  fl_set_xyplot_ybounds( fdui->chest_f,30,70);
+  /*
+  // LLR of PBCH
+  fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" );
+  fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX );
+  fl_set_object_color( fdui->pbch_llr, FL_BLACK, FL_GREEN );
+  fl_set_object_lcolor( fdui->pbch_llr, FL_WHITE ); // Label color
+  fl_set_xyplot_symbolsize( fdui->pbch_llr,2);
+  fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR);
+  fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920);
+  // I/Q PBCH comp
+  fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" );
+  fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX );
+  fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN );
+  fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color
+  fl_set_xyplot_symbolsize( fdui->pbch_comp,2);
+  fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100);
+  fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100);
+  // LLR of PDCCH
+  fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" );
+  fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX );
+  fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN );
+  fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color
+  fl_set_xyplot_symbolsize( fdui->pdcch_llr,2);
+  // I/Q PDCCH comp
+  fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" );
+  fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX );
+  fl_set_object_color( fdui->pdcch_comp, FL_BLACK, FL_CYAN );
+  fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color
+  fl_set_xyplot_symbolsize( fdui->pdcch_comp,2);
+  fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR);
+  */
+  int offset=240;
+  // LLR of PDSCH
+  fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
+  fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX );
+  fl_set_object_color( fdui->pdsch_llr, FL_BLACK, FL_YELLOW );
+  fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color
+  fl_set_xyplot_symbolsize( fdui->pdsch_llr,2);
+  fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR);
+  // I/Q PDSCH comp
+  fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500-offset, 240, 200, "PDSCH I/Q of MF Output" );
+  fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX );
+  fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW );
+  fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color
+  fl_set_xyplot_symbolsize( fdui->pdsch_comp,2);
+  // LLR of PDSCH
+  fdui->pdsch_llr1 = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 720-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
+  fl_set_object_boxtype( fdui->pdsch_llr1, FL_EMBOSSED_BOX );
+  fl_set_object_color( fdui->pdsch_llr1, FL_BLACK, FL_YELLOW );
+  fl_set_object_lcolor( fdui->pdsch_llr1, FL_WHITE ); // Label color
+  fl_set_xyplot_symbolsize( fdui->pdsch_llr1,2);
+  fl_set_xyplot_xgrid( fdui->pdsch_llr1,FL_GRID_MAJOR);
+  // I/Q PDSCH comp
+  fdui->pdsch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 720-offset, 240, 200, "PDSCH I/Q of MF Output" );
+  fl_set_object_boxtype( fdui->pdsch_comp1, FL_EMBOSSED_BOX );
+  fl_set_object_color( fdui->pdsch_comp1, FL_BLACK, FL_YELLOW );
+  fl_set_object_lcolor( fdui->pdsch_comp1, FL_WHITE ); // Label color
+  fl_set_xyplot_symbolsize( fdui->pdsch_comp1,2);
+  /*
+  // Throughput on PDSCH
+  fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" );
+  fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX );
+  fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE );
+  fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color
+  */
+  // Generic UE Button
+  fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
+  fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
+  //use_sic_receiver = 0;
+  fl_set_button(fdui->button_0,0);
+  fl_set_object_label(fdui->button_0, "SIC Receiver OFF");
+  fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
+  fl_set_object_callback(fdui->button_0, sic_receiver_on_off, 0 );
+  fl_hide_object(fdui->button_0);
+  fl_end_form( );
+  fdui->lte_phy_scope_ue->fdui = fdui;
+  return fdui;
 }
 
 void phy_scope_UE(FD_lte_phy_scope_ue *form,
                   PHY_VARS_UE *phy_vars_ue,
                   int eNB_id,
                   int UE_id,
-                  uint8_t subframe)
-{
-    int i,arx,atx,ind,k;
-    LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
-    int nsymb_ce = frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti;
-    uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
-    uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_eNB;
-    int16_t **rxsig_t;
-    int16_t **chest_t;
-    int16_t **chest_f;
-    int16_t *pdsch_llr,*pdsch_llr1;
-    int16_t *pdsch_comp,*pdsch_comp1;
-    int16_t *pdsch_mag0,*pdsch_mag1,*pdsch_magb0,*pdsch_magb1;
-    int8_t *pdcch_llr;
-    int16_t *pdcch_comp;
-    int8_t *pbch_llr;
-    int16_t *pbch_comp;
-    float Re,Im,ymax=1;
-    int num_pdcch_symbols=3;
-    float *llr0, *bit0, *llr1, *bit1, *chest_f_abs, llr_pbch[1920], bit_pbch[1920], *llr_pdcch, *bit_pdcch;
-    float *I, *Q;
-    float rxsig_t_dB[nb_antennas_rx][FRAME_LENGTH_COMPLEX_SAMPLES];
-    float **chest_t_abs;
-    float time[FRAME_LENGTH_COMPLEX_SAMPLES];
-    float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
-    int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx;
-    uint32_t total_dlsch_bitrate = phy_vars_ue->bitrate[eNB_id];
-    int coded_bits_per_codeword0=0,coded_bits_per_codeword1=1;
-    int mod0,mod1;
-    int mcs0 = 0;
-    int mcs1=0;
-    unsigned char harq_pid = 0;
-    int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
-    if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
-        harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
-  if (harq_pid>=8)
-    return;
+                  uint8_t subframe) {
+  int i,arx,atx,ind,k;
+  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
+  int nsymb_ce = frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti;
+  uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+  uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_eNB;
+  int16_t **rxsig_t;
+  int16_t **chest_t;
+  int16_t **chest_f;
+  int16_t *pdsch_llr,*pdsch_llr1;
+  int16_t *pdsch_comp,*pdsch_comp1;
+  int16_t *pdsch_mag0,*pdsch_mag1,*pdsch_magb0,*pdsch_magb1;
+  int8_t *pdcch_llr;
+  int16_t *pdcch_comp;
+  int8_t *pbch_llr;
+  int16_t *pbch_comp;
+  float Re,Im,ymax=1;
+  int num_pdcch_symbols=3;
+  float *llr0, *bit0, *llr1, *bit1, *chest_f_abs, llr_pbch[1920], bit_pbch[1920], *llr_pdcch, *bit_pdcch;
+  float *I, *Q;
+  float rxsig_t_dB[nb_antennas_rx][FRAME_LENGTH_COMPLEX_SAMPLES];
+  float **chest_t_abs;
+  float time[FRAME_LENGTH_COMPLEX_SAMPLES];
+  float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
+  int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx;
+  uint32_t total_dlsch_bitrate = phy_vars_ue->bitrate[eNB_id];
+  int coded_bits_per_codeword0=0,coded_bits_per_codeword1=1;
+  int mod0,mod1;
+  int mcs0 = 0;
+  int mcs1=0;
+  unsigned char harq_pid = 0;
+  int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
+
+  if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
+    harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
+
+    if (harq_pid>=8)
+      return;
+
     mcs0 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->mcs;
-        // Button 0
-  /*
-        if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
-            // we are in TM5
-            fl_show_object(form->button_0);
-        }
-  */
-    }
-    fl_show_object(form->button_0);
-      if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) {
-        harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->current_harq_pid;
-  if (harq_pid>=8)
-    return;
+    // Button 0
+    /*
+          if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
+              // we are in TM5
+              fl_show_object(form->button_0);
+          }
+    */
+  }
+
+  fl_show_object(form->button_0);
+
+  if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) {
+    harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->current_harq_pid;
+
+    if (harq_pid>=8)
+      return;
+
     mcs1 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->mcs;
+  }
+
+  if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) {
+    num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols;
+  }
+
+  //    coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
+  if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
+    mod0 = get_Qm(mcs0);
+    coded_bits_per_codeword0 = get_G(frame_parms,
+                                     phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
+                                     phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
+                                     get_Qm(mcs0),
+                                     phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
+                                     num_pdcch_symbols,
+                                     frame,
+                                     subframe,
+                                     beamforming_mode);
+  } else {
+    coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
+    mod0=0;
+  }
+
+  if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) {
+    mod1 = get_Qm(mcs1);
+    coded_bits_per_codeword1 = get_G(frame_parms,
+                                     phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->nb_rb,
+                                     phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even,
+                                     get_Qm(mcs1),
+                                     phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->Nl,
+                                     num_pdcch_symbols,
+                                     frame,
+                                     subframe,
+                                     beamforming_mode);
+  } else {
+    coded_bits_per_codeword1 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
+    mod1=0;
+  }
+
+  I = (float *) calloc(nsymb_ce*2,sizeof(float));
+  Q = (float *) calloc(nsymb_ce*2,sizeof(float));
+  chest_t_abs = (float **) malloc(nb_antennas_rx*sizeof(float *));
+
+  for (arx=0; arx<nb_antennas_rx; arx++) {
+    chest_t_abs[arx] = (float *) calloc(frame_parms->ofdm_symbol_size,sizeof(float));
+  }
+
+  chest_f_abs = (float *) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
+  //llr0 = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error.
+  llr0 = (float *) malloc(coded_bits_per_codeword0*sizeof(float));
+  memset((void *)llr0, 0,coded_bits_per_codeword0*sizeof(float)); // init to zero
+  bit0 = malloc(coded_bits_per_codeword0*sizeof(float));
+  //llr1 = (float*) calloc(coded_bits_per_codeword1,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error.
+  llr1 = (float *) malloc(coded_bits_per_codeword1*sizeof(float));
+  memset((void *)llr1, 0,coded_bits_per_codeword1*sizeof(float)); // init to zero
+  bit1 = malloc(coded_bits_per_codeword1*sizeof(float));
+  llr_pdcch = (float *) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
+  bit_pdcch = (float *) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
+  rxsig_t = (int16_t **) phy_vars_ue->common_vars.rxdata;
+  chest_t = (int16_t **) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id];
+  chest_f = (int16_t **) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
+  pbch_llr = (int8_t *) phy_vars_ue->pbch_vars[eNB_id]->llr;
+  pbch_comp = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
+  pdcch_llr = (int8_t *) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
+  pdcch_comp = (int16_t *) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
+  pdsch_llr = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
+  pdsch_llr1 = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[1]; // stream 1
+  pdsch_comp = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
+  //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0];
+  //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[1];
+  pdsch_comp1 = (int16_t *) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[0][0])[0];
+  //pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0])[0];
+  pdsch_mag0 = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
+  pdsch_mag1 = (int16_t *) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag1[0][0])[0];
+  pdsch_magb0 = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0];
+  pdsch_magb1 = (int16_t *) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb1[0][0])[0];
+  fl_freeze_form(form->lte_phy_scope_ue);
+
+  // Received signal in time domain of receive antenna 0
+  if (rxsig_t != NULL) {
+    if (rxsig_t[0] != NULL) {
+      for (i=0; i<FRAME_LENGTH_COMPLEX_SAMPLES; i++) {
+        rxsig_t_dB[0][i] = 10*log10(1.0+(float) ((rxsig_t[0][2*i])*(rxsig_t[0][2*i])+(rxsig_t[0][2*i+1])*(rxsig_t[0][2*i+1])));
+        time[i] = (float) i;
+      }
+
+      fl_set_xyplot_data(form->rxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","","");
     }
-    if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) {
-        num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols;
-    }
-    //    coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
-    if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
-      mod0 = get_Qm(mcs0);
-      coded_bits_per_codeword0 = get_G(frame_parms,
-                                       phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
-                                       phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
-                                       get_Qm(mcs0),
-                                       phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
-                                       num_pdcch_symbols,
-                                       frame,
-                                       subframe,
-                                       beamforming_mode);
-    } else {
-      coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
-      mod0=0;
-    }
-    if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) {
-      mod1 = get_Qm(mcs1);
-      coded_bits_per_codeword1 = get_G(frame_parms,
-                                       phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->nb_rb,
-                                       phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even,
-                                       get_Qm(mcs1),
-                                       phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->Nl,
-                                       num_pdcch_symbols,
-                                       frame,
-                                       subframe,
-                                       beamforming_mode);
-    } else {
-      coded_bits_per_codeword1 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
-      mod1=0;
-    }
-    I = (float*) calloc(nsymb_ce*2,sizeof(float));
-    Q = (float*) calloc(nsymb_ce*2,sizeof(float));
-    chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*));
-    for (arx=0;arx<nb_antennas_rx;arx++) {
-        chest_t_abs[arx] = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float));
-    }
-    chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
-    //llr0 = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error.
-    llr0 = (float*) malloc(coded_bits_per_codeword0*sizeof(float));
-    memset((void *)llr0, 0,coded_bits_per_codeword0*sizeof(float)); // init to zero
-    bit0 = malloc(coded_bits_per_codeword0*sizeof(float));
-
-    //llr1 = (float*) calloc(coded_bits_per_codeword1,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error.
-    llr1 = (float*) malloc(coded_bits_per_codeword1*sizeof(float));
-    memset((void *)llr1, 0,coded_bits_per_codeword1*sizeof(float)); // init to zero
-    bit1 = malloc(coded_bits_per_codeword1*sizeof(float));
-    llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
-    bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
-    rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata;
-    chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id];
-    chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
-    pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
-    pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
-    pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
-    pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
-    pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
-    pdsch_llr1 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[1]; // stream 1
-    pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
-    //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0];
-    //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[1];
-    pdsch_comp1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[0][0])[0];
-    //pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0])[0];
-    pdsch_mag0 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
-    pdsch_mag1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag1[0][0])[0];
-    pdsch_magb0 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0];
-    pdsch_magb1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb1[0][0])[0];
-    fl_freeze_form(form->lte_phy_scope_ue);
-    // Received signal in time domain of receive antenna 0
-    if (rxsig_t != NULL) {
-        if (rxsig_t[0] != NULL) {
-            for (i=0; i<FRAME_LENGTH_COMPLEX_SAMPLES; i++) {
-                rxsig_t_dB[0][i] = 10*log10(1.0+(float) ((rxsig_t[0][2*i])*(rxsig_t[0][2*i])+(rxsig_t[0][2*i+1])*(rxsig_t[0][2*i+1])));
-                time[i] = (float) i;
-            }
-            fl_set_xyplot_data(form->rxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","","");
-        }
-        for (arx=1;arx<nb_antennas_rx;arx++) {
-            if (rxsig_t[arx] != NULL) {
-                for (i=0; i<FRAME_LENGTH_COMPLEX_SAMPLES; i++) {
-                    rxsig_t_dB[arx][i] = 10*log10(1.0+(float) ((rxsig_t[arx][2*i])*(rxsig_t[arx][2*i])+(rxsig_t[arx][2*i+1])*(rxsig_t[arx][2*i+1])));
-                }
-                fl_add_xyplot_overlay(form->rxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]);
-            }
+
+    for (arx=1; arx<nb_antennas_rx; arx++) {
+      if (rxsig_t[arx] != NULL) {
+        for (i=0; i<FRAME_LENGTH_COMPLEX_SAMPLES; i++) {
+          rxsig_t_dB[arx][i] = 10*log10(1.0+(float) ((rxsig_t[arx][2*i])*(rxsig_t[arx][2*i])+(rxsig_t[arx][2*i+1])*(rxsig_t[arx][2*i+1])));
         }
+
+        fl_add_xyplot_overlay(form->rxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]);
+      }
     }
+  }
+
   // Channel Impulse Response (still repeated format)
   if (chest_t != NULL) {
     ymax = 0;
+
     if (chest_t[0] !=NULL) {
       for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
         chest_t_abs[0][i] = (float) (chest_t[0][4*i]*chest_t[0][4*i]+chest_t[0][4*i+1]*chest_t[0][4*i+1]);
+
         if (chest_t_abs[0][i] > ymax)
           ymax = chest_t_abs[0][i];
       }
+
       fl_set_xyplot_data(form->chest_t,time,chest_t_abs[0],(frame_parms->ofdm_symbol_size>>3),"","","");
     }
+
     for (arx=1; arx<nb_antennas_rx; arx++) {
       if (chest_t[arx] !=NULL) {
         for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
           chest_t_abs[arx][i] = (float) (chest_t[arx][4*i]*chest_t[arx][4*i]+chest_t[arx][4*i+1]*chest_t[arx][4*i+1]);
+
           if (chest_t_abs[arx][i] > ymax)
             ymax = chest_t_abs[arx][i];
         }
+
         fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
         fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
       }
     }
-     // Avoid flickering effect
-        //        fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
-        fl_set_xyplot_ybounds(form->chest_t,0,ymax);
-    }
-   // Channel Frequency Response (includes 5 complex sample for filter)
-    if (chest_f != NULL) {
-        ind = 0;
-        for (atx=0;atx<nb_antennas_tx;atx++) {
-            for (arx=0;arx<nb_antennas_rx;arx++) {
-                if (chest_f[(atx<<1)+arx] != NULL) {
-                    for (k=0; k<nsymb_ce; k++) {
-                        freq[ind] = (float)ind;
-                        Re = (float)(chest_f[(atx<<1)+arx][(2*k)]);
-                        Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]);
-                        chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im));
-                        ind++;
-                    }
-                }
-            }
-        }
-        // tx antenna 0
-        fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
-        //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
-        //        fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
-        fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
-        fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","","");
-        for (arx=1;arx<nb_antennas_rx;arx++) {
-            fl_add_xyplot_overlay(form->chest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
-        }
-        // other tx antennas
-        if (nb_antennas_tx > 1) {
-            if (nb_antennas_rx > 1) {
-                for (atx=1;atx<nb_antennas_tx;atx++) {
-                    for (arx=0;arx<nb_antennas_rx;arx++) {
-                        fl_add_xyplot_overlay(form->chest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
-                    }
-                }
-            } else { // 1 rx antenna
-                atx=1; arx=0;
-                fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
-            }
-        }
-    }
- /*
-    // PBCH LLRs
-    if (pbch_llr != NULL) {
-        for (i=0; i<1920;i++) {
-            llr_pbch[i] = (float) pbch_llr[i];
-            bit_pbch[i] = (float) i;
-        }
-        fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,1920,"","","");
-    }
-    // PBCH I/Q of MF Output
-    if (pbch_comp!=NULL) {
-        for (i=0; i<72*2; i++) {
-            I[i] = pbch_comp[2*i];
-            Q[i] = pbch_comp[2*i+1];
+
+    // Avoid flickering effect
+    //        fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
+    fl_set_xyplot_ybounds(form->chest_t,0,ymax);
+  }
+
+  // Channel Frequency Response (includes 5 complex sample for filter)
+  if (chest_f != NULL) {
+    ind = 0;
+
+    for (atx=0; atx<nb_antennas_tx; atx++) {
+      for (arx=0; arx<nb_antennas_rx; arx++) {
+        if (chest_f[(atx<<1)+arx] != NULL) {
+          for (k=0; k<nsymb_ce; k++) {
+            freq[ind] = (float)ind;
+            Re = (float)(chest_f[(atx<<1)+arx][(2*k)]);
+            Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]);
+            chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im));
+            ind++;
+          }
         }
-        fl_set_xyplot_data(form->pbch_comp,I,Q,72*2,"","","");
+      }
     }
-    // PDCCH LLRs
-    if (pdcch_llr != NULL) {
-        for (i=0; i<12*frame_parms->N_RB_DL*2*num_pdcch_symbols;i++) {
-            llr_pdcch[i] = (float) pdcch_llr[i];
-            bit_pdcch[i] = (float) i;
-        }
-        fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3);
-        fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","","");
+
+    // tx antenna 0
+    fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
+    //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
+    //        fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
+    fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
+    fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","","");
+
+    for (arx=1; arx<nb_antennas_rx; arx++) {
+      fl_add_xyplot_overlay(form->chest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
     }
-    // PDCCH I/Q of MF Output
-    if (pdcch_comp!=NULL) {
-        for (i=0; i<12*frame_parms->N_RB_DL*num_pdcch_symbols; i++) {
-            I[i] = pdcch_comp[2*i];
-            Q[i] = pdcch_comp[2*i+1];
+
+    // other tx antennas
+    if (nb_antennas_tx > 1) {
+      if (nb_antennas_rx > 1) {
+        for (atx=1; atx<nb_antennas_tx; atx++) {
+          for (arx=0; arx<nb_antennas_rx; arx++) {
+            fl_add_xyplot_overlay(form->chest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
+          }
         }
-        fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
+      } else { // 1 rx antenna
+        atx=1;
+        arx=0;
+        fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
+      }
     }
-    */
-    // PDSCH LLRs CW0
-    if (pdsch_llr != NULL) {
-        for (i=0; i<coded_bits_per_codeword0; i++) {
-            llr0[i] = (float) pdsch_llr[i];
-            bit0[i] = (float) i;
-        }
-        fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword0);
-        fl_set_xyplot_data(form->pdsch_llr,bit0,llr0,coded_bits_per_codeword0,"","","");
+  }
+
+  /*
+     // PBCH LLRs
+     if (pbch_llr != NULL) {
+         for (i=0; i<1920;i++) {
+             llr_pbch[i] = (float) pbch_llr[i];
+             bit_pbch[i] = (float) i;
+         }
+         fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,1920,"","","");
+     }
+     // PBCH I/Q of MF Output
+     if (pbch_comp!=NULL) {
+         for (i=0; i<72*2; i++) {
+             I[i] = pbch_comp[2*i];
+             Q[i] = pbch_comp[2*i+1];
+         }
+         fl_set_xyplot_data(form->pbch_comp,I,Q,72*2,"","","");
+     }
+     // PDCCH LLRs
+     if (pdcch_llr != NULL) {
+         for (i=0; i<12*frame_parms->N_RB_DL*2*num_pdcch_symbols;i++) {
+             llr_pdcch[i] = (float) pdcch_llr[i];
+             bit_pdcch[i] = (float) i;
+         }
+         fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3);
+         fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","","");
+     }
+     // PDCCH I/Q of MF Output
+     if (pdcch_comp!=NULL) {
+         for (i=0; i<12*frame_parms->N_RB_DL*num_pdcch_symbols; i++) {
+             I[i] = pdcch_comp[2*i];
+             Q[i] = pdcch_comp[2*i+1];
+         }
+         fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
+     }
+     */
+  // PDSCH LLRs CW0
+  if (pdsch_llr != NULL) {
+    for (i=0; i<coded_bits_per_codeword0; i++) {
+      llr0[i] = (float) pdsch_llr[i];
+      bit0[i] = (float) i;
     }
+
+    fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword0);
+    fl_set_xyplot_data(form->pdsch_llr,bit0,llr0,coded_bits_per_codeword0,"","","");
+  }
+
   // PDSCH I/Q of MF Output
-    if (pdsch_comp!=NULL) {
-        ind=0;
-        for (k=0; k<frame_parms->symbols_per_tti; k++) {
-            for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
-                I[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i];
-                Q[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i+1];
-                ind++;
-            }
-        }
-        fl_set_xyplot_data(form->pdsch_comp,I,Q,ind,"","","");
+  if (pdsch_comp!=NULL) {
+    ind=0;
+
+    for (k=0; k<frame_parms->symbols_per_tti; k++) {
+      for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+        I[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i];
+        Q[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i+1];
+        ind++;
+      }
     }
-    if (pdsch_mag0 != NULL) {
-        ind=0;
-        for (k=0; k<frame_parms->symbols_per_tti; k++) {
-            for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+
+    fl_set_xyplot_data(form->pdsch_comp,I,Q,ind,"","","");
+  }
+
+  if (pdsch_mag0 != NULL) {
+    ind=0;
+
+    for (k=0; k<frame_parms->symbols_per_tti; k++) {
+      for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
         I[ind] = pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
         Q[ind] = pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
         ind++;
-            }
-        }
-        fl_add_xyplot_overlay(form->pdsch_comp,1,I,Q,ind,FL_GREEN);
+      }
     }
-    if (pdsch_magb0 != NULL) {
-        ind=0;
-        for (k=0; k<frame_parms->symbols_per_tti; k++) {
-            for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+
+    fl_add_xyplot_overlay(form->pdsch_comp,1,I,Q,ind,FL_GREEN);
+  }
+
+  if (pdsch_magb0 != NULL) {
+    ind=0;
+
+    for (k=0; k<frame_parms->symbols_per_tti; k++) {
+      for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
         I[ind] = pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
         Q[ind] = pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
         ind++;
-            }
-        }
-        fl_add_xyplot_overlay(form->pdsch_comp,2,I,Q,ind,FL_RED);
+      }
     }
-    if ((pdsch_mag0 != NULL) && (pdsch_magb0 != NULL)) {
-        ind=0;
-        for (k=0; k<frame_parms->symbols_per_tti; k++) {
-            for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+
+    fl_add_xyplot_overlay(form->pdsch_comp,2,I,Q,ind,FL_RED);
+  }
+
+  if ((pdsch_mag0 != NULL) && (pdsch_magb0 != NULL)) {
+    ind=0;
+
+    for (k=0; k<frame_parms->symbols_per_tti; k++) {
+      for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
         I[ind] =
-    (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]+
-     pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i])*
-    cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+          (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]+
+           pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i])*
+          cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
         Q[ind] =
-    (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+
-     pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1])*
-    sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+          (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+
+           pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1])*
+          sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
         ind++;
-            }
-        }
-        fl_add_xyplot_overlay(form->pdsch_comp,3,I,Q,ind,FL_BLUE);
+      }
     }
-    // PDSCH LLRs CW1
-    if (pdsch_llr1 != NULL) {
-        for (i=0; i<coded_bits_per_codeword1; i++) {
-            llr1[i] = (float) pdsch_llr1[i];
-            bit1[i] = (float) i;
-        }
-        fl_set_xyplot_xbounds(form->pdsch_llr1,0,coded_bits_per_codeword1);
-        fl_set_xyplot_data(form->pdsch_llr1,bit1,llr1,coded_bits_per_codeword1,"","","");
+
+    fl_add_xyplot_overlay(form->pdsch_comp,3,I,Q,ind,FL_BLUE);
+  }
+
+  // PDSCH LLRs CW1
+  if (pdsch_llr1 != NULL) {
+    for (i=0; i<coded_bits_per_codeword1; i++) {
+      llr1[i] = (float) pdsch_llr1[i];
+      bit1[i] = (float) i;
     }
-    // PDSCH I/Q of MF Output
-    if (pdsch_comp1!=NULL) {
-        ind=0;
-        for (k=0; k<frame_parms->symbols_per_tti; k++) {
-            for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
-                I[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i];
-                Q[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i+1];
-                ind++;
-            }
-        }
-        fl_set_xyplot_data(form->pdsch_comp1,I,Q,ind,"","","");
+
+    fl_set_xyplot_xbounds(form->pdsch_llr1,0,coded_bits_per_codeword1);
+    fl_set_xyplot_data(form->pdsch_llr1,bit1,llr1,coded_bits_per_codeword1,"","","");
+  }
+
+  // PDSCH I/Q of MF Output
+  if (pdsch_comp1!=NULL) {
+    ind=0;
+
+    for (k=0; k<frame_parms->symbols_per_tti; k++) {
+      for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+        I[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i];
+        Q[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i+1];
+        ind++;
+      }
     }
-    if (pdsch_mag1 != NULL) {
-        ind=0;
-        for (k=0; k<frame_parms->symbols_per_tti; k++) {
-            for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+
+    fl_set_xyplot_data(form->pdsch_comp1,I,Q,ind,"","","");
+  }
+
+  if (pdsch_mag1 != NULL) {
+    ind=0;
+
+    for (k=0; k<frame_parms->symbols_per_tti; k++) {
+      for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
         I[ind] = pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
         Q[ind] = pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
         ind++;
-            }
-        }
-        fl_add_xyplot_overlay(form->pdsch_comp1,1,I,Q,ind,FL_GREEN);
+      }
     }
-    if (pdsch_magb1 != NULL) {
-        ind=0;
-        for (k=0; k<frame_parms->symbols_per_tti; k++) {
-            for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+
+    fl_add_xyplot_overlay(form->pdsch_comp1,1,I,Q,ind,FL_GREEN);
+  }
+
+  if (pdsch_magb1 != NULL) {
+    ind=0;
+
+    for (k=0; k<frame_parms->symbols_per_tti; k++) {
+      for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
         I[ind] = pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
         Q[ind] = pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
         ind++;
-            }
-        }
-        fl_add_xyplot_overlay(form->pdsch_comp1,2,I,Q,ind,FL_RED);
+      }
     }
-    if ((pdsch_mag1 != NULL) && (pdsch_magb1 != NULL)) {
-        ind=0;
-        for (k=0; k<frame_parms->symbols_per_tti; k++) {
-            for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+
+    fl_add_xyplot_overlay(form->pdsch_comp1,2,I,Q,ind,FL_RED);
+  }
+
+  if ((pdsch_mag1 != NULL) && (pdsch_magb1 != NULL)) {
+    ind=0;
+
+    for (k=0; k<frame_parms->symbols_per_tti; k++) {
+      for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
         I[ind] =
-    (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]+
-     pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i])*
-    cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+          (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]+
+           pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i])*
+          cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
         Q[ind] =
-    (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+
-     pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1])*
-    sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+          (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+
+           pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1])*
+          sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
         ind++;
-            }
-        }
-        fl_add_xyplot_overlay(form->pdsch_comp1,3,I,Q,ind,FL_BLUE);
-    }
-    /*
-    // PDSCH Throughput
-    memcpy((void*)tput_time_ue[UE_id],(void*)&tput_time_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float));
-    memcpy((void*)tput_ue[UE_id],(void*)&tput_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float));
-    tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1]  = (float) frame;
-    tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
-    if (tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] > tput_ue_max[UE_id]) {
-        tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1];
+      }
     }
-    fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","","");
-    fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]);
-    */
-    fl_unfreeze_form(form->lte_phy_scope_ue);
-    fl_check_forms();
-    free(I);
-    free(Q);
-    free(chest_f_abs);
-    free(llr0);
-    free(bit0);
-    free(llr1);
-    free(bit1);
-    free(bit_pdcch);
-    free(llr_pdcch);
-
-    //This is done to avoid plotting old data when TB0 is disabled, and TB1 is mapped onto CW0
-    /*if (phy_vars_ue->transmission_mode[eNB_id]==3 && phy_vars_ue->transmission_mode[eNB_id]==4){
-      for (int i = 0; i<8; ++i)
-        for (int j = 0; j < 7*2*frame_parms->N_RB_DL*12+4; ++j )
-          phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][0][i][j]=0;
-
-      for (int m=0; m<coded_bits_per_codeword1; ++m)
-          phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0][m]=0;
-      }*/
+
+    fl_add_xyplot_overlay(form->pdsch_comp1,3,I,Q,ind,FL_BLUE);
+  }
+
+  /*
+  // PDSCH Throughput
+  memcpy((void*)tput_time_ue[UE_id],(void*)&tput_time_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float));
+  memcpy((void*)tput_ue[UE_id],(void*)&tput_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float));
+  tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1]  = (float) frame;
+  tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
+  if (tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] > tput_ue_max[UE_id]) {
+      tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1];
+  }
+  fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","","");
+  fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]);
+  */
+  fl_unfreeze_form(form->lte_phy_scope_ue);
+  fl_check_forms();
+  free(I);
+  free(Q);
+  free(chest_f_abs);
+  free(llr0);
+  free(bit0);
+  free(llr1);
+  free(bit1);
+  free(bit_pdcch);
+  free(llr_pdcch);
+  //This is done to avoid plotting old data when TB0 is disabled, and TB1 is mapped onto CW0
+  /*if (phy_vars_ue->transmission_mode[eNB_id]==3 && phy_vars_ue->transmission_mode[eNB_id]==4){
+    for (int i = 0; i<8; ++i)
+      for (int j = 0; j < 7*2*frame_parms->N_RB_DL*12+4; ++j )
+        phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][0][i][j]=0;
+
+    for (int m=0; m<coded_bits_per_codeword1; ++m)
+        phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0][m]=0;
+    }*/
 }
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index cb6152385260942df9ebe89fd11ae3bd0f5cafa0..fc1fa4c297c5b5bafb244194cecd554ee093b69a 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -38,10 +38,7 @@ int otg_enabled;
 const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
 const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED};
 
-typedef struct {
-  int16_t r;
-  int16_t i;
-} scopeSample_t;
+typedef struct complex16 scopeSample_t;
 #define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)
 
 typedef struct OAIgraph {
@@ -59,7 +56,7 @@ typedef struct OAIgraph {
   double *waterFallAvg;
   boolean_t initDone;
   int iteration;
-  void (*gNBfunct) (struct OAIgraph *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id);
+  void (*gNBfunct) (struct OAIgraph *graph, scopeData_t *p, int UE_id);
   void (*nrUEfunct)(struct OAIgraph *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id);
 } OAIgraph_t;
 
@@ -135,7 +132,7 @@ static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_
   graph->iteration=0;
 }
 
-static OAIgraph_t gNBcommonGraph( void (*funct) (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id),
+static OAIgraph_t gNBcommonGraph( void (*funct) (OAIgraph_t *graph, scopeData_t *p, int UE_id),
                                   int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
   OAIgraph_t graph;
   commonGraph(&graph, type, x, y, w, h, label, pointColor);
@@ -226,7 +223,8 @@ static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int laye
 
 static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) {
   if ( values == NULL )
-     return;
+    return;
+
   fl_winset(FL_ObjWin(graph->graph));
   const int samplesPerPixel=datasize/graph->w;
   int displayPart=graph->waterFallh-ScaleZone;
@@ -278,34 +276,10 @@ static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const in
     graph->initDone=true;
   }
 
-  fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, sqrt(avg));
+  fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, 0/*sqrt(avg)*/);
   graph->iteration++;
 }
 
-static void genericLogPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) {
-  float *values, *time;
-  oai_xygraph_getbuff(graph, &time, &values, len, 0);
-
-  for (int ant=0; ant<nb_ant; ant++) {
-    if (data[ant] != NULL) {
-      float *values, *time;
-      oai_xygraph_getbuff(graph, &time, &values, len, ant);
-
-      for (int i=0; i<len; i+=8) {
-        float *vals=values+i;
-        const scopeSample_t *in=&(data[ant][i]);
-
-        // TRY AUTOMATIC simd BY GCC
-        for (int k=0; k<8; k++ ) {
-          vals[k] = 10*log10(1.0+SquaredNorm(in[k]));
-        }
-      }
-
-      oai_xygraph(graph,time,values, len, ant, 10);
-    }
-  }
-}
-
 static void genericPowerPerAntena(OAIgraph_t  *graph, const int nb_ant, const scopeSample_t **data, const int len) {
   float *values, *time;
   oai_xygraph_getbuff(graph, &time, &values, len, 0);
@@ -321,10 +295,10 @@ static void genericPowerPerAntena(OAIgraph_t  *graph, const int nb_ant, const sc
   }
 }
 
-static void gNBWaterFall (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
-  NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
+static void gNBWaterFall (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
+  NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms;
   //use 1st antenna
-  genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdata[0],
+  genericWaterFall(graph, (scopeSample_t *)p->ru->common.rxdata[0],
                    frame_parms->samples_per_frame,  frame_parms->slots_per_frame,
                    "X axis:one frame in time");
 }
@@ -342,31 +316,35 @@ static void timeSignal (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy
 }
 */
 
-static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
-  const int len=2*phy_vars_gnb->frame_parms.ofdm_symbol_size;
+static void timeResponse (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
+  const int len=2*p->gNB->frame_parms.ofdm_symbol_size;
   float *values, *time;
   oai_xygraph_getbuff(graph, &time, &values, len, 0);
   const int ant=0; // display antenna 0 for each UE
 
   for (int ue=0; ue<nb_UEs; ue++) {
-    scopeSample_t *data= (scopeSample_t *)phy_vars_gnb->pusch_vars[ue]->ul_ch_estimates_time[ant];
+    if ( p->gNB->pusch_vars && p->gNB->pusch_vars[ue] &&
+         p->gNB->pusch_vars[ue]->ul_ch_estimates_time &&
+         p->gNB->pusch_vars[ue]->ul_ch_estimates_time[ant] ) {
+      scopeSample_t *data= (scopeSample_t *)p->gNB->pusch_vars[ue]->ul_ch_estimates_time[ant];
+
+      if (data != NULL) {
+        for (int i=0; i<len; i++) {
+          values[i] = SquaredNorm(data[i]);
+        }
 
-    if (data != NULL) {
-      for (int i=0; i<len; i++) {
-        values[i] = SquaredNorm(data[i]);
+        oai_xygraph(graph,time,values, len, ue, 10);
       }
-
-      oai_xygraph(graph,time,values, len, ue, 10);
     }
   }
 }
 
-static void gNBfreqWaterFall (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
-  NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
+static void gNBfreqWaterFall (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
+  NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms;
   //use 1st antenna
-  genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdataF[0], frame_parms->samples_per_frame_wCP,
+  genericWaterFall(graph, (scopeSample_t *)p->rxdataF, frame_parms->samples_per_frame_wCP,
                    frame_parms->slots_per_frame,
-                   "X axis: Frequency domain, one frame");
+                   "X axis: Frequency domain, one subframe");
 }
 
 /*
@@ -378,16 +356,18 @@ static void frequencyResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU
 }
 */
 
-static void puschLLR (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
+static void puschLLR (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
   //int Qm = 2;
   int coded_bits_per_codeword =3*8*6144+12; // (8*((3*8*6144)+12)); // frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti;
 
   for (int ue=0; ue<nb_UEs; ue++) {
-    int16_t *pusch_llr = (int16_t *)phy_vars_gnb->pusch_vars[ue]->llr;
-    float *llr, *bit;
-    oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword, ue);
+    if ( p->gNB->pusch_vars &&
+         p->gNB->pusch_vars[ue] &&
+         p->gNB->pusch_vars[ue]->llr ) {
+      int16_t *pusch_llr = (int16_t *)p->gNB->pusch_vars[ue]->llr;
+      float *llr, *bit;
+      oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword, ue);
 
-    if (pusch_llr) {
       for (int i=0; i<coded_bits_per_codeword; i++) {
         llr[i] = (float) pusch_llr[i];
       }
@@ -397,16 +377,19 @@ static void puschLLR (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_v
   }
 }
 
-static void puschIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
-  NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
+static void puschIQ (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
+  NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms;
   int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot;
 
   for (int ue=0; ue<nb_UEs; ue++) {
-    scopeSample_t *pusch_comp = (scopeSample_t *) phy_vars_gnb->pusch_vars[ue]->rxdataF_comp[0];
-    float *I, *Q;
-    oai_xygraph_getbuff(graph, &I, &Q, sz, ue);
+    if ( p->gNB->pusch_vars &&
+         p->gNB->pusch_vars[ue] &&
+         p->gNB->pusch_vars[ue]->rxdataF_comp &&
+         p->gNB->pusch_vars[ue]->rxdataF_comp[0] ) {
+      scopeSample_t *pusch_comp = (scopeSample_t *) p->gNB->pusch_vars[ue]->rxdataF_comp[0];
+      float *I, *Q;
+      oai_xygraph_getbuff(graph, &I, &Q, sz, ue);
 
-    if (pusch_comp) {
       for (int k=0; k<sz; k++ ) {
         I[k] = pusch_comp[k].r;
         Q[k] = pusch_comp[k].i;
@@ -417,7 +400,7 @@ static void puschIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_va
   }
 }
 
-static void pucchEnergy (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
+static void pucchEnergy (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
   // PUSCH I/Q of MF Output
   /*
     int32_t *pucch1ab_comp = (int32_t *) NULL; //phy_vars_gnb->pucch1ab_stats[UE_id];
@@ -443,10 +426,10 @@ static void pucchEnergy (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *ph
   */
 }
 
-static void pucchIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
+static void pucchIQ (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
 }
 
-static void puschThroughtput (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
+static void puschThroughtput (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
   // PUSCH Throughput
   /*
   float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
@@ -461,7 +444,6 @@ static void puschThroughtput (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_
   //    fl_set_xyplot_ybounds(form->pusch_tput,0,ymax);
   */
 }
-
 static OAI_phy_scope_t *create_phy_scope_gnb(void) {
   FL_OBJECT *obj;
   OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1);
@@ -510,11 +492,9 @@ static OAI_phy_scope_t *create_phy_scope_gnb(void) {
   fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, "LTE UL SCOPE gNB");
   return fdui;
 }
-
 static const int scope_enb_num_ue = 1;
 void phy_scope_gNB(OAI_phy_scope_t *form,
-                   PHY_VARS_gNB *phy_vars_gnb,
-                   RU_t *phy_vars_ru,
+                   scopeData_t *p,
                    int UE_id) {
   static OAI_phy_scope_t *rememberForm=NULL;
 
@@ -529,15 +509,14 @@ void phy_scope_gNB(OAI_phy_scope_t *form,
   int i=0;
 
   while (form->graph[i].graph) {
-    form->graph[i].gNBfunct(form->graph+i, phy_vars_gnb, phy_vars_ru, UE_id);
+    form->graph[i].gNBfunct(form->graph+i, p, UE_id);
     i++;
   }
 
   //fl_check_forms();
 }
-
 static void *scope_thread_gNB(void *arg) {
-  scopeParms_t *p=(scopeParms_t *) arg;
+  scopeData_t *p=(scopeData_t *) arg;
   //# ifdef ENABLE_XFORMS_WRITE_STATS
   //  FILE *gNB_stats = fopen("gNB_stats.txt", "w");
   //#endif
@@ -554,20 +533,31 @@ static void *scope_thread_gNB(void *arg) {
   OAI_phy_scope_t  *form_gnb = create_phy_scope_gnb();
 
   while (!oai_exit) {
-    phy_scope_gNB(form_gnb, p->gNB, p->ru, nb_ue);
+    phy_scope_gNB(form_gnb, p, nb_ue);
     usleep(99*1000);
   }
 
   return NULL;
 }
+static void copyRxdataF(int32_t *data, int slot,  void *scopeData) {
+  scopeData_t *scope=(scopeData_t *)scopeData;
+  memcpy(scope->rxdataF + slot*scope->gNB->frame_parms.samples_per_slot_wCP,
+         data,
+         scope->gNB->frame_parms.samples_per_slot_wCP);
+}
 
 void gNBinitScope(scopeParms_t *p) {
-  static scopeParms_t parms;
-  memcpy(&parms,p,sizeof(parms));
+  AssertFatal(p->gNB->scopeData=malloc(sizeof(scopeData_t)),"");
+  scopeData_t *scope=(scopeData_t *) p->gNB->scopeData;
+  scope->argc=p->argc;
+  scope->argv=p->argv;
+  scope->ru=p->ru;
+  scope->gNB=p->gNB;
+  scope->slotFunc=copyRxdataF;
+  AssertFatal(scope->rxdataF=(int32_t *) calloc(p->gNB->frame_parms.samples_per_frame_wCP*sizeof(int32_t),1),"");
   pthread_t forms_thread;
-  threadCreate(&forms_thread, scope_thread_gNB, &parms, "scope", -1, OAI_PRIORITY_RT_LOW);
+  threadCreate(&forms_thread, scope_thread_gNB, p->gNB->scopeData, "scope", -1, OAI_PRIORITY_RT_LOW);
 }
-
 static void ueWaterFall  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // Received signal in time domain of receive antenna 0
   genericWaterFall(graph,
@@ -576,7 +566,6 @@ static void ueWaterFall  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eN
                    phy_vars_ue->frame_parms.slots_per_frame,
                    "X axis: one frame time");
 }
-
 /* replaced by waterfall
 static void ueTimeResponse  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // Received signal in time domain of receive antenna 0
@@ -585,14 +574,12 @@ static void ueTimeResponse  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int
                            phy_vars_ue->frame_parms.samples_per_frame);
 }
 */
-
 static void ueChannelResponse  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // Channel Impulse Response
   genericPowerPerAntena(graph, phy_vars_ue->frame_parms.nb_antennas_rx,
                         (const scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time,
                         phy_vars_ue->frame_parms.ofdm_symbol_size>>3);
 }
-
 static void ueFreqWaterFall (OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id ) {
   NR_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->frame_parms;
   //use 1st antenna
@@ -602,7 +589,6 @@ static void ueFreqWaterFall (OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int
                    phy_vars_ue->frame_parms.slots_per_frame,
                    "X axis: one frame frequency" );
 }
-
 /*
 static void uePbchFrequencyResp  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // Channel Frequency Response (includes 5 complex sample for filter)
@@ -638,7 +624,6 @@ static void uePbchFrequencyResp  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue
   oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10);
 }
 */
-
 static void uePbchLLR  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PBCH LLRs
   if ( !phy_vars_ue->pbch_vars[eNB_id]->llr)
@@ -654,7 +639,6 @@ static void uePbchLLR  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
 
   oai_xygraph(graph,bit_pbch,llr_pbch,864,0,10);
 }
-
 static void uePbchIQ  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PBCH I/Q of MF Output
   if (!phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0])
@@ -689,15 +673,14 @@ static void uePbchIQ  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
   AssertFatal(base <= 180*3,"");
   oai_xygraph(graph,I,Q,base,0, 10);
 }
-
 static void uePcchLLR  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PDCCH LLRs
   if (!phy_vars_ue->pdcch_vars[0][eNB_id]->llr)
     return;
 
-  int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
-  int Qm = 2;
-  int coded_bits_per_codeword = num_re*Qm;
+  //int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
+  //int Qm = 2;
+  int coded_bits_per_codeword = 2*4*100*12; //num_re*Qm;
   float *llr, *bit;
   oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0);
   int base=0;
@@ -715,7 +698,6 @@ static void uePcchLLR  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
   AssertFatal(base <= coded_bits_per_codeword*RX_NB_TH_MAX, "");
   oai_xygraph(graph,bit,llr,base,0,10);
 }
-
 static void uePcchIQ  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PDCCH I/Q of MF Output
   if (!phy_vars_ue->pdcch_vars[0][eNB_id]->rxdataF_comp[0])
@@ -740,7 +722,6 @@ static void uePcchIQ  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
   AssertFatal(base <= nb*RX_NB_TH_MAX, "");
   oai_xygraph(graph,I,Q,base,0,10);
 }
-
 static void uePdschLLR  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PDSCH LLRs
   if (!phy_vars_ue->pdsch_vars[0][eNB_id]->llr[0])
@@ -768,7 +749,6 @@ static void uePdschLLR  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB
   //fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword);
   oai_xygraph(graph,bit,llr,base,0,10);
 }
-
 static void uePdschIQ  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PDSCH I/Q of MF Output
   if (!phy_vars_ue->pdsch_vars[0][eNB_id]->rxdataF_comp0[0])
@@ -796,7 +776,6 @@ static void uePdschIQ  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
   AssertFatal(base <= sz*RX_NB_TH_MAX, "");
   oai_xygraph(graph,I,Q,sz*RX_NB_TH_MAX,0,10);
 }
-
 static void uePdschThroughput  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   /*
   float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
@@ -820,7 +799,6 @@ static void uePdschThroughput  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue,
   fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]);
   */
 }
-
 static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
   FL_OBJECT *obj;
   OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1);
@@ -890,7 +868,6 @@ static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
   fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, buf);
   return fdui;
 }
-
 void phy_scope_nrUE(OAI_phy_scope_t *form,
                     PHY_VARS_NR_UE *phy_vars_ue,
                     int eNB_id,
@@ -914,12 +891,10 @@ void phy_scope_nrUE(OAI_phy_scope_t *form,
 
   //fl_check_forms();
 }
-
-
 static void *nrUEscopeThread(void *arg) {
   PHY_VARS_NR_UE *ue=(PHY_VARS_NR_UE *)arg;
   size_t stksize;
-  pthread_attr_t atr;
+  pthread_attr_t atr={0};
   pthread_attr_getstacksize(&atr, &stksize);
   pthread_attr_setstacksize(&atr,32*1024*1024 );
   int fl_argc=1;
@@ -939,13 +914,10 @@ static void *nrUEscopeThread(void *arg) {
 
   pthread_exit((void *)arg);
 }
-
 void nrUEinitScope(PHY_VARS_NR_UE *ue) {
   pthread_t forms_thread;
   threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
 }
-
-
 void nrscope_autoinit(void *dataptr) {
   AssertFatal( (IS_SOFTMODEM_GNB_BIT||IS_SOFTMODEM_5GUE_BIT),"Scope cannot find NRUE or GNB context");
 
@@ -980,7 +952,6 @@ static void reset_stats_gNB(FL_OBJECT *button,
     }
   }
 }
-
 static FD_stats_form *create_form_stats_form(int ID) {
   FL_OBJECT *obj;
   FD_stats_form *fdui = calloc(( sizeof *fdui ),1);
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.h b/openair1/PHY/TOOLS/nr_phy_scope.h
index 84b9e66908bec48d048e3cee9f345ae5726cc1fd..e34ddf2c20a420230277a8e38d36fecf2bb9c6c1 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.h
+++ b/openair1/PHY/TOOLS/nr_phy_scope.h
@@ -33,13 +33,7 @@
 //#include "PHY/impl_defs_top.h"
 #include "PHY/defs_nr_UE.h"
 
-typedef struct {
-  int *argc;
-  char **argv;
-  RU_t *ru;
-  PHY_VARS_gNB *gNB;
-} scopeParms_t;
-
+#include <openair1/PHY/TOOLS/phy_scope_interface.h>
 
 extern RAN_CONTEXT_t RC;
 #endif
diff --git a/openair1/PHY/TOOLS/oai_dfts.c b/openair1/PHY/TOOLS/oai_dfts.c
index 6569f7eab5be3b4b92c92b951bd73ef360fd1329..83207426fde1a4906866a2bdc1b082debcaa6441 100644
--- a/openair1/PHY/TOOLS/oai_dfts.c
+++ b/openair1/PHY/TOOLS/oai_dfts.c
@@ -18,7 +18,7 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-
+ 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -32,17 +32,17 @@
 #define M_PI 3.14159265358979323846
 #endif
 #define OAIDFTS_MAIN
-#ifndef MR_MAIN
-#include "PHY/defs_common.h"
-#include "PHY/impl_defs_top.h"
-#else
+//#ifndef MR_MAIN
+//#include "PHY/defs_common.h"
+//#include "PHY/impl_defs_top.h"
+//#else
 #include "time_meas.h"
 #include "LOG/log.h"
 #define debug_msg
 #define ONE_OVER_SQRT2_Q15 23170
 
-int oai_exit=0;
-#endif
+//int oai_exit=0;
+//#endif
 
 #define ONE_OVER_SQRT3_Q15 18919
 
@@ -50,6 +50,8 @@ int oai_exit=0;
 
 #include "assertions.h"
 
+#include "tools_defs.h"
+
 #define print_shorts(s,x) printf("%s %d,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
 #define print_shorts256(s,x) printf("%s %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7],(x)[8],(x)[9],(x)[10],(x)[11],(x)[12],(x)[13],(x)[14],(x)[15])
 
@@ -3103,10 +3105,12 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale)
 
   dft64((int16_t*)(xtmp),(int16_t*)ytmp,1);
   dft64((int16_t*)(xtmp+32),(int16_t*)(ytmp+16),1);
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
     LOG_M("dft128a.m","dfta",ytmp,64,1,1);
     LOG_M("dft128b.m","dftb",ytmp+16,64,1,1);
   }
+#endif
   for (i=0; i<16; i++) {
     bfly2_16(ytmpp,ytmpp+16,
              y128p,y128p+16,
@@ -3155,10 +3159,12 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale)
 
 
   }
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
      LOG_M("dft128out.m","dft128",y,128,1,1);
      exit(-1);
   }
+#endif
   _mm_empty();
   _m_empty();
 
@@ -3183,18 +3189,20 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale)
   transpose4_ooff_simd256(x256+10,xtmp+5,8);
   transpose4_ooff_simd256(x256+12,xtmp+6,8);
   transpose4_ooff_simd256(x256+14,xtmp+7,8);
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {  
      LOG_M("dft128ina_256.m","dftina",xtmp,64,1,1);
      LOG_M("dft128inb_256.m","dftinb",xtmp+8,64,1,1);
   }
-
+#endif
   dft64((int16_t*)(xtmp),(int16_t*)ytmp,1);
   dft64((int16_t*)(xtmp+8),(int16_t*)(ytmp+8),1);
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {  
     LOG_M("dft128outa_256.m","dftouta",ytmp,64,1,1);
     LOG_M("dft128outb_256.m","dftoutb",ytmp+8,64,1,1);
   }
-
+#endif
   for (i=0; i<8; i++) {
     bfly2_16_256(ytmpp,ytmpp+8,
 		 y256p,y256p+8,
@@ -3226,10 +3234,12 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale)
     y256[15] = mulhi_int16_simd256(y256[15],ONE_OVER_SQRT2_Q15_256);
 
   }
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {  
    LOG_M("dft128.m","dft",y256,128,1,1);
    exit(-1);
   }
+#endif
 }
 
 #endif
@@ -6031,11 +6041,13 @@ void dft1536(int16_t *input, int16_t *output, unsigned char scale)
     tmpo[1][i] = tmpo[1][i<<1];
     tmpo[2][i] = tmpo[2][i<<1];
     }*/
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
     LOG_M("dft1536out0.m","o0",tmpo[0],2048,1,1);
     LOG_M("dft1536out1.m","o1",tmpo[1],2048,1,1);
     LOG_M("dft1536out2.m","o2",tmpo[2],2048,1,1);
   }
+#endif
   for (i=0,i2=0; i<1024; i+=8,i2+=4)  {
     bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
           (simd_q15_t*)(output+i),(simd_q15_t*)(output+1024+i),(simd_q15_t*)(output+2048+i),
@@ -6193,14 +6205,14 @@ void idft6144(int16_t *input, int16_t *output,unsigned char scale)
   idft2048((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
   idft2048((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
   idft2048((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
-
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
     LOG_M("idft6144in.m","in",input,6144,1,1);
     LOG_M("idft6144out0.m","o0",tmpo[0],2048,1,1);
     LOG_M("idft6144out1.m","o1",tmpo[1],2048,1,1);
     LOG_M("idft6144out2.m","o2",tmpo[2],2048,1,1);
   }
-
+#endif
   for (i=0,i2=0; i<4096; i+=8,i2+=4)  {
     ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
 	   (simd_q15_t*)(output+i),(simd_q15_t*)(output+4096+i),(simd_q15_t*)(output+8192+i),
@@ -6260,11 +6272,13 @@ void dft6144(int16_t *input, int16_t *output,unsigned char scale)
     tmpo[1][i] = tmpo[1][i<<1];
     tmpo[2][i] = tmpo[2][i<<1];
     }*/
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
     LOG_M("ft6144out0.m","o0",tmpo[0],2048,1,1);
     LOG_M("ft6144out1.m","o1",tmpo[1],2048,1,1);
     LOG_M("ft6144out2.m","o2",tmpo[2],2048,1,1);
   }
+#endif
   for (i=0,i2=0; i<4096; i+=8,i2+=4)  {
     bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
           (simd_q15_t*)(output+i),(simd_q15_t*)(output+4096+i),(simd_q15_t*)(output+8192+i),
@@ -6336,11 +6350,13 @@ void dft12288(int16_t *input, int16_t *output,unsigned char scale)
     tmpo[1][i] = tmpo[1][i<<1];
     tmpo[2][i] = tmpo[2][i<<1];
     }*/
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
     LOG_M("dft12288out0.m","o0",tmpo[0],4096,1,1);
     LOG_M("dft12288out1.m","o1",tmpo[1],4096,1,1);
     LOG_M("dft12288out2.m","o2",tmpo[2],4096,1,1);
   }
+#endif
   for (i=0,i2=0; i<8192; i+=8,i2+=4)  {
     bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
           (simd_q15_t*)(output+i),(simd_q15_t*)(output+8192+i),(simd_q15_t*)(output+16384+i),
@@ -6392,14 +6408,14 @@ void idft12288(int16_t *input, int16_t *output,unsigned char scale)
   idft4096((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),scale);
   idft4096((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),scale);
   idft4096((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),scale);
-
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
     LOG_M("idft12288in.m","in",input,12288,1,1);
     LOG_M("idft12288out0.m","o0",tmpo[0],4096,1,1);
     LOG_M("idft12288out1.m","o1",tmpo[1],4096,1,1);
     LOG_M("idft12288out2.m","o2",tmpo[2],4096,1,1);
   }
-
+#endif
   for (i=0,i2=0; i<8192; i+=8,i2+=4)  {
     ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
           (simd_q15_t*)(output+i),(simd_q15_t*)(output+8192+i),(simd_q15_t*)(output+16384+i),
@@ -6429,9 +6445,11 @@ void idft12288(int16_t *input, int16_t *output,unsigned char scale)
   }
   _mm_empty();
   _m_empty();
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
      LOG_M("idft12288out.m","out",output,6144,1,1);
   }
+#endif
 }
 
 int16_t twa18432[12288] __attribute__((aligned(32)));
@@ -6560,11 +6578,13 @@ void dft24576(int16_t *input, int16_t *output,unsigned char scale)
     tmpo[1][i] = tmpo[1][i<<1];
     tmpo[2][i] = tmpo[2][i<<1];
     }*/
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
     LOG_M("dft24576out0.m","o0",tmpo[0],8192,1,1);
     LOG_M("dft24576out1.m","o1",tmpo[1],8192,1,1);
     LOG_M("dft24576out2.m","o2",tmpo[2],8192,1,1);
   }
+#endif
   for (i=0,i2=0; i<16384; i+=8,i2+=4)  {
     bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
           (simd_q15_t*)(output+i),(simd_q15_t*)(output+16384+i),(simd_q15_t*)(output+32768+i),
@@ -6595,9 +6615,11 @@ void dft24576(int16_t *input, int16_t *output,unsigned char scale)
   }
   _mm_empty();
   _m_empty();
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
      LOG_M("out.m","out",output,24576,1,1);
   }
+#endif
 }
 
 void idft24576(int16_t *input, int16_t *output,unsigned char scale)
@@ -6617,14 +6639,14 @@ void idft24576(int16_t *input, int16_t *output,unsigned char scale)
   idft8192((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
   idft8192((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
   idft8192((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
-  
+ #ifndef MR_MAIN 
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
     LOG_M("idft24576in.m","in",input,24576,1,1);
     LOG_M("idft24576out0.m","o0",tmpo[0],8192,1,1);
     LOG_M("idft24576out1.m","o1",tmpo[1],8192,1,1);
     LOG_M("idft24576out2.m","o2",tmpo[2],8192,1,1);
   }
-
+#endif
   for (i=0,i2=0; i<16384; i+=8,i2+=4)  {
     ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
           (simd_q15_t*)(output+i),(simd_q15_t*)(output+16384+i),(simd_q15_t*)(output+32768+i),
@@ -6653,10 +6675,11 @@ void idft24576(int16_t *input, int16_t *output,unsigned char scale)
   }
   _mm_empty();
   _m_empty();
-
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
     LOG_M("idft24576out.m","out",output,24576,1,1);
   }
+#endif
 }
 
 int16_t twa36864[24576] __attribute__((aligned(32)));
@@ -6680,13 +6703,13 @@ void dft36864(int16_t *input, int16_t *output,uint8_t scale) {
   dft12288((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
   dft12288((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
   dft12288((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
-
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
     LOG_M("dft36864out0.m","o0",tmpo[0],12288,1,1);
     LOG_M("dft36864out1.m","o1",tmpo[1],12288,1,1);
     LOG_M("dft36864out2.m","o2",tmpo[2],12288,1,1);
   }
-
+#endif
   for (i=0,i2=0; i<24576; i+=8,i2+=4)  {
     bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
           (simd_q15_t*)(output+i),(simd_q15_t*)(output+24576+i),(simd_q15_t*)(output+49152+i),
@@ -6716,9 +6739,11 @@ void dft36864(int16_t *input, int16_t *output,uint8_t scale) {
   }
   _mm_empty();
   _m_empty();
+#ifndef MR_MAIN
   if (LOG_DUMPFLAG(DEBUG_DFT)) {
      LOG_M("out.m","out",output,36864,1,1);
   }
+#endif
 }
 
 void idft36864(int16_t *input, int16_t *output,uint8_t scale) {
diff --git a/openair1/PHY/TOOLS/phy_scope_interface.c b/openair1/PHY/TOOLS/phy_scope_interface.c
index af237b2325e8a3f2fc035478cff4df4f39974901..7cd68c53d23d4cc8df04786dfb7cd82349666d6f 100644
--- a/openair1/PHY/TOOLS/phy_scope_interface.c
+++ b/openair1/PHY/TOOLS/phy_scope_interface.c
@@ -35,6 +35,7 @@
 #include "phy_scope_interface.h"
 
 #define SOFTSCOPE_ENDFUNC_IDX 0
+
 static  loader_shlibfunc_t scope_fdesc[]= {{"end_forms",NULL}};
 
 int load_softscope(char *exectype, void *initarg) {
diff --git a/openair1/PHY/TOOLS/phy_scope_interface.h b/openair1/PHY/TOOLS/phy_scope_interface.h
index adf04d5ea4a6a7f664e23eab35c8bff82d46121e..8b747d575d1720f95ae192013a31dfe914ed7ad8 100644
--- a/openair1/PHY/TOOLS/phy_scope_interface.h
+++ b/openair1/PHY/TOOLS/phy_scope_interface.h
@@ -29,7 +29,26 @@
  * \note
  * \warning
  */
+#ifndef __PHY_SCOPE_INTERFACE_H__
+#define __PHY_SCOPE_INTERFACE_H__
+#include <openair1/PHY/defs_gNB.h>
+typedef struct {
+  int *argc;
+  char **argv;
+  RU_t *ru;
+  PHY_VARS_gNB *gNB;
+} scopeParms_t;
 
 
+typedef struct scopeData_s {
+  int *argc;
+  char **argv;
+  RU_t *ru;
+  PHY_VARS_gNB *gNB;
+  int32_t * rxdataF;
+  void (*slotFunc)(int32_t* data, int slot,  void * scopeData);
+} scopeData_t;
+
 int load_softscope(char *exectype, void *initarg);
 int end_forms(void) ;
+#endif
diff --git a/openair1/PHY/TOOLS/time_meas.c b/openair1/PHY/TOOLS/time_meas.c
index cfa3b93007f06d16ebe7aa42cf285dbe1b2fce26..001770c876f376dd03b404dd7e92816fcc8d8a9e 100644
--- a/openair1/PHY/TOOLS/time_meas.c
+++ b/openair1/PHY/TOOLS/time_meas.c
@@ -26,9 +26,12 @@
 
 // global var for openair performance profiler
 int opp_enabled = 0;
+double cpu_freq_GHz  __attribute__ ((aligned(32)));
 
+double cpu_freq_GHz  __attribute__ ((aligned(32)))=0.0;
 double get_cpu_freq_GHz(void)
 {
+  if (cpu_freq_GHz <1 ) {
   time_stats_t ts = {0};
   reset_meas(&ts);
   ts.trials++;
@@ -37,6 +40,7 @@ double get_cpu_freq_GHz(void)
   ts.diff = (rdtsc_oai()-ts.in);
   cpu_freq_GHz = (double)ts.diff/1000000000;
   printf("CPU Freq is %f \n", cpu_freq_GHz);
+  }
   return cpu_freq_GHz;
 }
 
@@ -99,10 +103,11 @@ void print_meas(time_stats_t *ts,
     if (ts->trials>0) {
       //printf("%20s: total: %10.3f ms, average: %10.3f us (%10d trials)\n", name, ts->diff/cpu_freq_GHz/1000000.0, ts->diff/ts->trials/cpu_freq_GHz/1000.0, ts->trials);
       if ((total_exec_time == NULL) || (sf_exec_time== NULL)) {
-        fprintf(stderr, "%25s:  %15.3f us; %15d;\n",
+        fprintf(stderr, "%25s:  %15.3f us; %15d; %15.3f us;\n",
                 name,
                 (ts->diff/ts->trials/cpu_freq_GHz/1000.0),
-                ts->trials);
+                ts->trials,
+                ts->max/cpu_freq_GHz/1000.0);
       } else {
         fprintf(stderr, "%25s:  %15.3f ms (%5.2f%%); %15.3f us (%5.2f%%); %15d;\n",
                 name,
diff --git a/openair1/PHY/TOOLS/time_meas.h b/openair1/PHY/TOOLS/time_meas.h
index 2deab40f27fef6bb44ee41327ffd6e38bd0901f0..e2ceef84050de9f7ddf3e8664948724aa2f50eb0 100644
--- a/openair1/PHY/TOOLS/time_meas.h
+++ b/openair1/PHY/TOOLS/time_meas.h
@@ -33,7 +33,7 @@
 #include <linux/types.h>
 // global var to enable openair performance profiler
 extern int opp_enabled;
-double cpu_freq_GHz  __attribute__ ((aligned(32)));;
+extern double cpu_freq_GHz  __attribute__ ((aligned(32)));;
 
 #if defined(__x86_64__) || defined(__i386__)
 typedef struct {
diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h
index db7ac3d813cb6266cc99b41dd0681db4a70d3d7c..4c68c15cb68fb60ee351c9cad227fb0ca63adef4 100644
--- a/openair1/PHY/TOOLS/tools_defs.h
+++ b/openair1/PHY/TOOLS/tools_defs.h
@@ -44,6 +44,11 @@ struct complex {
   double y;
 };
 
+struct complexd {
+  double r;
+  double i;
+};
+
 struct complexf {
   float r;
   float i;
diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h
index b465a51a2addf00ebc78da6e0c1d5f5cc079100c..66cb51adc607dabf4d08e661b582a19cbac042a3 100644
--- a/openair1/PHY/defs_RU.h
+++ b/openair1/PHY/defs_RU.h
@@ -92,17 +92,17 @@ typedef enum {
 
 
 typedef struct {
-  /// \brief Holds the transmit data in the frequency domain.
+  /// \brief Holds the transmit data in the frequency domain (1 frame).
   /// - first index: rx antenna [0..nb_antennas_rx[
-  /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[
+  /// - second index: ? [0..samples_per_frame[
   int32_t **txdata;
-  /// \brief holds the transmit data after beamforming in the frequency domain.
+  /// \brief holds the transmit data after beamforming in the frequency domain (1 slot).
   /// - first index: tx antenna [0..nb_antennas_tx[
-  /// - second index: sample [0..]
+  /// - second index: sample [0..samples_per_slot_woCP]
   int32_t **txdataF_BF;
-  /// \brief holds the transmit data before beamforming in the frequency domain.
-  /// - first index: tx antenna [0..nb_antennas_tx[
-  /// - second index: sample [0..]
+  /// \brief holds the transmit data before beamforming in the frequency domain (1 frame).
+  /// - first index: tx antenna [0..nb_antenna_ports[
+  /// - second index: sample [0..samples_per_frame_woCP]
   int32_t **txdataF;
   /// \brief holds the transmit data before beamforming for epdcch/mpdcch
   /// - first index : tx antenna [0..nb_epdcch_antenna_ports[
@@ -128,6 +128,10 @@ typedef struct {
   /// - second index: tx antenna [0..nb_antennas_tx[
   /// - third index: frequency [0..]
   int32_t **tdd_calib_coeffs;
+  /// \brief Anaglogue beam ID for each OFDM symbol (used when beamforming not done in RU)
+  /// - first index: antenna port
+  /// - second index: beam_id [0.. symbols_per_frame[
+  uint8_t **beam_id;
 } RU_COMMON;
 
 
@@ -432,6 +436,14 @@ typedef enum {
 typedef struct RU_t_s {
   /// index of this ru
   uint32_t idx;
+  /// pointer to first RU
+  struct RU_t_s *ru0;
+  /// pointer to ru_mask
+  uint64_t *ru_mask;
+  /// pointer to ru_mutex
+  pthread_mutex_t *ru_mutex;
+  /// pointer to ru_cond
+  pthread_cond_t *ru_cond;
   /// Pointer to configuration file
   char *rf_config_file;
   /// southbound interface
@@ -442,6 +454,12 @@ typedef struct RU_t_s {
   node_function_t function;
   /// Ethernet parameters for fronthaul interface
   eth_params_t eth_params;
+  /// flag to indicate RF emulation mode
+  int emulate_rf;
+  /// numerology index
+  int numerology;
+  /// flag to indicate basicsim operation
+  int basicsim;
   /// flag to indicate the RU is in sync with a master reference
   int in_synch;
   /// timing offset
@@ -741,4 +759,10 @@ typedef struct RRU_config_s {
   MBSFN_config_t MBSFN_config[8];
 } RRU_config_t;
 
+typedef struct processingData_RU {
+  int frame_tx;
+  int slot_tx;
+  openair0_timestamp timestamp_tx;
+  RU_t *ru;
+} processingData_RU_t;
 #endif //__PHY_DEFS_RU__H__
diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h
index 27765a854810ba30733b5cc6ffef7ac9f640c5ac..a371b2334ba4f008fcdf0a76dbda3cf4f9b0dd47 100644
--- a/openair1/PHY/defs_common.h
+++ b/openair1/PHY/defs_common.h
@@ -867,8 +867,10 @@ typedef enum {
   NOT_SYNCHED=0,
   PRACH=1,
   RA_RESPONSE=2,
-  PUSCH=3,
-  RESYNCH=4
+  RA_WAIT_CR=3,
+  PUSCH=4,
+  RESYNCH=5,
+  NUM_UE_MODE=6
 } UE_MODE_t;
 
 #define FOREACH_PARALLEL(GEN)   \
@@ -943,6 +945,23 @@ extern int sync_var;
 #define DECODE_NUM_FPTR              13
 
 
+// Mask for identifying subframe for MBMS
+#define MBSFN_TDD_SF3 0x80// for TDD
+#define MBSFN_TDD_SF4 0x40
+#define MBSFN_TDD_SF7 0x20
+#define MBSFN_TDD_SF8 0x10
+#define MBSFN_TDD_SF9 0x08
+
+
+
+#define MBSFN_FDD_SF1 0x80// for FDD
+#define MBSFN_FDD_SF2 0x40
+#define MBSFN_FDD_SF3 0x20
+#define MBSFN_FDD_SF6 0x10
+#define MBSFN_FDD_SF7 0x08
+#define MBSFN_FDD_SF8 0x04
+
+
 typedef uint8_t(decoder_if_t)(int16_t *y,
                               int16_t *y2,
                               uint8_t *decoded_bytes,
diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h
index 0f1bf75114b96b4f0d52f3de43ad2120f3f32dc4..030d50bc048f74190379cf184c5dae5c1eb87b38 100644
--- a/openair1/PHY/defs_eNB.h
+++ b/openair1/PHY/defs_eNB.h
@@ -164,10 +164,10 @@ typedef struct {
   /// - first index: rx antenna id [0..nb_antennas_rx[
   /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
   int32_t **ul_ch_magb;
-  /// measured RX power based on DRS
-  int ulsch_power[2];
-  /// measured Interference power based on DRS
-  int ulsch_interference_power[2];
+  /// measured RX power based on DMRS
+  int ulsch_power[4];
+  /// measured RX power of noise
+  int ulsch_noise_power[4];
   /// \brief llr values.
   /// - first index: ? [0..1179743] (hard coded)
   int16_t *llr;
@@ -217,6 +217,58 @@ typedef struct {
   int ret;
 } td_params;
 
+/// Context data structure for RX/TX portion of subframe processing
+typedef struct {
+  /// Component Carrier index
+  uint8_t              CC_id;
+  /// timestamp transmitted to HW
+  openair0_timestamp timestamp_tx;
+  openair0_timestamp timestamp_rx;
+  /// subframe to act upon for transmission
+  int subframe_tx;
+  /// subframe to act upon for reception
+  int subframe_rx;
+  /// frame to act upon for transmission
+  int frame_tx;
+  /// frame to act upon for reception
+  int frame_rx;
+  int frame_prach;
+  int subframe_prach;
+  int frame_prach_br;
+  int subframe_prach_br;
+  /// \brief Instance count for RXn-TXnp4 processing thread.
+  /// \internal This variable is protected by \ref mutex_rxtx.
+  int instance_cnt;
+  /// pthread structure for RXn-TXnp4 processing thread
+  pthread_t pthread;
+  /// pthread attributes for RXn-TXnp4 processing thread
+  pthread_attr_t attr;
+  /// condition variable for tx processing thread
+  pthread_cond_t cond;
+  /// mutex for RXn-TXnp4 processing thread
+  pthread_mutex_t mutex;
+  /// scheduling parameters for RXn-TXnp4 thread
+  struct sched_param sched_param_rxtx;
+
+  /// \internal This variable is protected by \ref mutex_RUs.
+  int instance_cnt_RUs;
+  /// condition variable for tx processing thread
+  pthread_cond_t cond_RUs;
+  /// mutex for RXn-TXnp4 processing thread
+  pthread_mutex_t mutex_RUs;
+  tpool_t *threadPool;
+  int nbEncode;
+  int nbDecode;
+  notifiedFIFO_t *respEncode;
+  notifiedFIFO_t *respDecode;
+    pthread_mutex_t mutex_emulateRF;
+  int instance_cnt_emulateRF;
+  pthread_t pthread_emulateRF;
+  pthread_attr_t attr_emulateRF;
+  pthread_cond_t cond_emulateRF;
+  int first_rx;
+} L1_rxtx_proc_t;
+
 typedef struct {
   struct PHY_VARS_eNB_s *eNB;
   LTE_eNB_DLSCH_t *dlsch;
@@ -362,8 +414,11 @@ typedef struct L1_proc_t_s {
   L1_rxtx_proc_t L1_proc,L1_proc_tx;
   /// stats thread pthread descriptor
   pthread_t process_stats_thread;
+  /// L1 stats pthread descriptor
+  pthread_t L1_stats_thread;
   /// for waking up tx procedure
   RU_proc_t *ru_proc;
+  struct PHY_VARS_eNB_s *eNB;
 } L1_proc_t;
 
 
@@ -395,36 +450,73 @@ typedef struct {
   short n0_subband_power_avg_dB;
   // eNB measurements (per user)
   //! estimated received spatial signal power (linear)
-  unsigned int   rx_spatial_power[NUMBER_OF_UE_MAX][2][2];
+  unsigned int   rx_spatial_power[NUMBER_OF_SRS_MAX][2][2];
   //! estimated received spatial signal power (dB)
-  unsigned short rx_spatial_power_dB[NUMBER_OF_UE_MAX][2][2];
+  unsigned short rx_spatial_power_dB[NUMBER_OF_SRS_MAX][2][2];
   //! estimated rssi (dBm)
-  short          rx_rssi_dBm[NUMBER_OF_UE_MAX];
+  short          rx_rssi_dBm[NUMBER_OF_SRS_MAX];
   //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation)
-  int            rx_correlation[NUMBER_OF_UE_MAX][2];
+  int            rx_correlation[NUMBER_OF_SRS_MAX][2];
   //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation)
-  int            rx_correlation_dB[NUMBER_OF_UE_MAX][2];
+  int            rx_correlation_dB[NUMBER_OF_SRS_MAX][2];
 
   /// Wideband CQI (= SINR)
-  int            wideband_cqi[NUMBER_OF_UE_MAX][MAX_NUM_RU_PER_eNB];
+  int            wideband_cqi[NUMBER_OF_SRS_MAX][MAX_NUM_RU_PER_eNB];
   /// Wideband CQI in dB (= SINR dB)
-  int            wideband_cqi_dB[NUMBER_OF_UE_MAX][MAX_NUM_RU_PER_eNB];
+  int            wideband_cqi_dB[NUMBER_OF_SRS_MAX][MAX_NUM_RU_PER_eNB];
   /// Wideband CQI (sum of all RX antennas, in dB)
-  char           wideband_cqi_tot[NUMBER_OF_UE_MAX];
+  char           wideband_cqi_tot[NUMBER_OF_SRS_MAX];
   /// Subband CQI per RX antenna and RB (= SINR)
-  int            subband_cqi[NUMBER_OF_UE_MAX][MAX_NUM_RU_PER_eNB][100];
+  int            subband_cqi[NUMBER_OF_SRS_MAX][MAX_NUM_RU_PER_eNB][100];
   /// Total Subband CQI and RB (= SINR)
   int            subband_cqi_tot[NUMBER_OF_UE_MAX][100];
   /// Subband CQI in dB and RB (= SINR dB)
-  int            subband_cqi_dB[NUMBER_OF_UE_MAX][MAX_NUM_RU_PER_eNB][100];
+  int            subband_cqi_dB[NUMBER_OF_SRS_MAX][MAX_NUM_RU_PER_eNB][100];
   /// Total Subband CQI and RB
-  int            subband_cqi_tot_dB[NUMBER_OF_UE_MAX][100];
+  int            subband_cqi_tot_dB[NUMBER_OF_SRS_MAX][100];
   /// PRACH background noise level
   int            prach_I0;
   /// PUCCH background noise level
   int            n0_pucch_dB;
 } PHY_MEASUREMENTS_eNB;
 
+typedef struct {
+  uint16_t rnti;
+  int frame;
+  int round_trials[8];
+  int total_bytes_tx;
+  int total_bytes_rx;
+  int current_G;
+  int current_TBS;
+  int current_Qm;
+  int current_mcs;
+  int current_RI;
+  int timing_offset;
+  int ulsch_power[4];
+  int ulsch_noise_power[4];
+} eNB_SCH_STATS_t;
+
+typedef struct {
+  uint16_t rnti;
+  int frame;
+  int pucch1_trials;
+  int pucch1_thres;
+  int current_pucch1_stat_pos;
+  int current_pucch1_stat_neg;
+  int pucch1_positive_SR;
+  int pucch1_low_stat[4];
+  int pucch1_high_stat[4];
+  int pucch1_phase;
+  int pucch1a_trials;
+  int current_pucch1a_stat_re;
+  int current_pucch1a_stat_im;
+  int pucch1ab_DTX;
+  int pucch1b_trials;
+  int current_pucch1b_stat_re;
+  int current_pucch1b_stat_im;
+  int pucch3_trials;
+  int current_pucch3_stat;
+} eNB_UCI_STATS_t;
 
 /// Top-level PHY Data Structure for eNB
 typedef struct PHY_VARS_eNB_s {
@@ -472,13 +564,13 @@ typedef struct PHY_VARS_eNB_s {
   LTE_eNB_MPDCCH       mpdcch_vars[2];
   LTE_eNB_PRACH        prach_vars_br;
   LTE_eNB_COMMON       common_vars;
-  LTE_eNB_UCI          uci_vars[NUMBER_OF_UCI_VARS_MAX];
-  LTE_eNB_SRS          srs_vars[NUMBER_OF_UE_MAX];
+  LTE_eNB_UCI          uci_vars[NUMBER_OF_UCI_MAX];
+  LTE_eNB_SRS          srs_vars[NUMBER_OF_SRS_MAX];
   LTE_eNB_PBCH         pbch;
-  LTE_eNB_PUSCH       *pusch_vars[NUMBER_OF_UE_MAX];
+  LTE_eNB_PUSCH       *pusch_vars[NUMBER_OF_ULSCH_MAX];
   LTE_eNB_PRACH        prach_vars;
-  LTE_eNB_DLSCH_t     *dlsch[NUMBER_OF_UE_MAX][2];   // Nusers times two spatial streams
-  LTE_eNB_ULSCH_t     *ulsch[NUMBER_OF_UE_MAX+1];      // Nusers + number of RA
+  LTE_eNB_DLSCH_t     *dlsch[NUMBER_OF_DLSCH_MAX][2];   // Num active DLSCH contexts times two spatial streams
+  LTE_eNB_ULSCH_t     *ulsch[NUMBER_OF_ULSCH_MAX];      // Num active ULSCH contexts
   LTE_eNB_DLSCH_t     *dlsch_SI,*dlsch_ra,*dlsch_p;
   LTE_eNB_DLSCH_t     *dlsch_MCH;
   LTE_eNB_DLSCH_t     *dlsch_PCH;
@@ -489,7 +581,7 @@ typedef struct PHY_VARS_eNB_s {
   uint32_t         lte_gold_table[20][2][14];
 
   /// UE-specific reference symbols (p=5), TM 7
-  uint32_t         lte_gold_uespec_port5_table[NUMBER_OF_UE_MAX][20][38];
+  uint32_t         lte_gold_uespec_port5_table[NUMBER_OF_DLSCH_MAX][20][38];
 
   /// UE-specific reference symbols (p=7...14), TM 8/9/10
   uint32_t         lte_gold_uespec_table[2][20][2][21];
@@ -521,6 +613,9 @@ typedef struct PHY_VARS_eNB_s {
   uint8_t pbch_pdu[4]; //PBCH_PDU_SIZE
   char eNB_generate_rar;
 
+  /// indicator that eNB signal generation uses DTX (i.e. signal is cleared in each subframe
+  int use_DTX;
+  int32_t **subframe_mask;
   /// Indicator set to 0 after first SR
   uint8_t first_sr[NUMBER_OF_UE_MAX];
 
@@ -592,7 +687,12 @@ typedef struct PHY_VARS_eNB_s {
   /// Information regarding TM5
   MU_MIMO_mode mu_mimo_mode[NUMBER_OF_UE_MAX];
 
-
+  /// statistics for DLSCH measurement collection
+  eNB_SCH_STATS_t dlsch_stats[NUMBER_OF_SCH_STATS_MAX];
+  /// statistics for ULSCH measurement collection
+  eNB_SCH_STATS_t ulsch_stats[NUMBER_OF_SCH_STATS_MAX];
+  /// statis for UCI (PUCCH) measurement collection
+  eNB_UCI_STATS_t uci_stats[NUMBER_OF_SCH_STATS_MAX];
   /// target_ue_dl_mcs : only for debug purposes
   uint32_t target_ue_dl_mcs;
   /// target_ue_ul_mcs : only for debug purposes
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index b7923adb0b2098734ab79623bb9cc997e6a777a0..d1fb886341ee5a494862525234fbe6b626eba548 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -120,6 +120,13 @@ typedef struct {
   nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu;
 } NR_gNB_PDCCH_t;
 
+typedef struct {
+  uint8_t active;
+  int frame;
+  int slot;
+  nfapi_nr_dl_tti_csi_rs_pdu csirs_pdu;
+} NR_gNB_CSIRS_t;
+
 typedef struct {
   int frame;
   int slot;
@@ -133,13 +140,39 @@ 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;
-  /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
+  /// TX buffers for UE-spec transmission (antenna layers 1,...,4 after to precoding)
   int32_t *txdataF[NR_MAX_NB_LAYERS];
+  /// TX buffers for UE-spec transmission (antenna ports 1000 or 1001,...,1007, before precoding)
+  int32_t *txdataF_precoding[NR_MAX_NB_LAYERS];
   /// Modulated symbols buffer
   int32_t *mod_symbs[NR_MAX_NB_CODEWORDS];
   /// beamforming weights for UE-spec transmission (antenna ports 5 or 7..14), for each codeword, maximum 4 layers?
@@ -180,7 +213,10 @@ typedef struct {
   int16_t sqrt_rho_b;
 } NR_gNB_DLSCH_t;
 
-
+typedef struct {
+  bool active;
+  nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
+} NR_gNB_SSB_t;
 
 typedef struct {
   int frame;
@@ -385,8 +421,12 @@ typedef struct {
   /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //?
   /// - first index: eNB id [0..2] (hard coded)
   /// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports.
-  /// - third index: sample [0..]
+  /// - third index: sample [0..samples_per_frame_woCP]
   int32_t **txdataF;
+  /// \brief Anaglogue beam ID for each OFDM symbol (used when beamforming not done in RU)
+  /// - first index: antenna port
+  /// - second index: beam_id [0.. symbols_per_frame[
+  uint8_t **beam_id;  
   int32_t *debugBuff;
   int32_t debugBuff_sample_offset;
 } NR_gNB_COMMON;
@@ -456,7 +496,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;
@@ -477,6 +523,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
@@ -553,8 +601,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
@@ -620,6 +670,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)
@@ -655,6 +707,7 @@ typedef struct {
   int            prach_I0;
 } PHY_MEASUREMENTS_gNB;
 
+#define MAX_NUM_NR_PRACH_PREAMBLES 64
 #define MAX_NUM_NR_RX_RACH_PDUS 4
 #define MAX_NUM_NR_RX_PRACH_PREAMBLES 4
 #define MAX_UL_PDUS_PER_SLOT 8
@@ -705,16 +758,16 @@ typedef struct PHY_VARS_gNB_s {
   
   //  nfapi_nr_dl_tti_pdcch_pdu    *pdcch_pdu;
   //  nfapi_nr_ul_dci_request_pdus_t  *ul_dci_pdu;
-  nfapi_nr_dl_tti_ssb_pdu      ssb_pdu;
-
   uint16_t num_pdsch_rnti[80];
-  NR_gNB_PBCH         pbch;
+  NR_gNB_SSB_t       ssb[64];
+  NR_gNB_PBCH        pbch;
   nr_cce_t           cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL];
   NR_gNB_COMMON      common_vars;
   NR_gNB_PRACH       prach_vars;
   NR_gNB_PUSCH       *pusch_vars[NUMBER_OF_NR_ULSCH_MAX];
   NR_gNB_PUCCH_t     *pucch[NUMBER_OF_NR_PUCCH_MAX];
   NR_gNB_PDCCH_t     pdcch_pdu[NUMBER_OF_NR_PDCCH_MAX];
+  NR_gNB_CSIRS_t     csirs_pdu[NUMBER_OF_NR_CSIRS_MAX];
   NR_gNB_UL_PDCCH_t  ul_pdcch_pdu[NUMBER_OF_NR_PDCCH_MAX];
   NR_gNB_DLSCH_t     *dlsch[NUMBER_OF_NR_DLSCH_MAX][2];    // Nusers times two spatial streams
   NR_gNB_ULSCH_t     *ulsch[NUMBER_OF_NR_ULSCH_MAX][2];  // [Nusers times][2 codewords] 
@@ -724,7 +777,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;
@@ -791,6 +844,9 @@ 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;
   */
@@ -813,6 +869,7 @@ typedef struct PHY_VARS_gNB_s {
   time_stats_t dlsch_segmentation_stats;
 
   time_stats_t rx_pusch_stats;
+  time_stats_t ul_indication_stats;
   time_stats_t ulsch_decoding_stats;
   time_stats_t ulsch_rate_unmatching_stats;
   time_stats_t ulsch_ldpc_decoding_stats;
@@ -830,10 +887,15 @@ typedef struct PHY_VARS_gNB_s {
   time_stats_t ulsch_freq_offset_estimation_stats;
   */
   notifiedFIFO_t *respDecode;
+  notifiedFIFO_t *resp_L1;
+  notifiedFIFO_t *resp_L1_tx;
+  notifiedFIFO_t *resp_RU_tx;
   tpool_t *threadPool;
   int nbDecode;
   uint8_t pusch_proc_threads;
-
+  int number_of_nr_dlsch_max;
+  int number_of_nr_ulsch_max;
+  void * scopeData;
 } PHY_VARS_gNB;
 
 typedef struct LDPCDecode_s {
@@ -871,4 +933,13 @@ union ldpcReqUnion {
   uint64_t p;
 };
 
+typedef struct processingData_L1 {
+  int frame_rx;
+  int frame_tx;
+  int slot_rx;
+  int slot_tx;
+  openair0_timestamp timestamp_tx;
+  PHY_VARS_gNB *gNB;
+} processingData_L1_t;
+
 #endif
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 390574a66b049c19648fc8ca6cf6573265467ba1..3b1c03f3773f956eab7d24bc7fdbb0572d7eb17a 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -142,6 +142,7 @@ typedef struct {
   uint32_t rsrp[7];
   float rsrp_filtered[7]; // after layer 3 filtering
   float rsrq_filtered[7];
+  short rsrp_dBm[7];
   // common measurements
   //! estimated noise power (linear)
   unsigned int   n0_power[NB_ANTENNAS_RX];
@@ -187,7 +188,7 @@ typedef struct {
   //! estimated rssi (dBm)
   short          rx_rssi_dBm[NUMBER_OF_CONNECTED_gNB_MAX];
   //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation)
-  int            rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][2];
+  int            rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][4][4];
   //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation)
   int            rx_correlation_dB[NUMBER_OF_CONNECTED_gNB_MAX][2];
 
@@ -234,6 +235,11 @@ typedef struct {
   int32_t *txdataF_layers[NR_MAX_NB_LAYERS];
   } NR_UE_PUSCH;
 
+typedef struct {
+  bool active[2];
+  fapi_nr_ul_config_pucch_pdu pucch_pdu[2];
+  } NR_UE_PUCCH;
+
 typedef struct {
   /// \brief Holds the transmit data in time domain.
   /// For IFFT_FPGA this points to the same memory as PHY_vars->tx_vars[a].TX_DMA_BUFFER.
@@ -332,12 +338,10 @@ typedef struct {
   int32_t **dl_ch_magb1[8][8];
   /// \brief Magnitude of Downlink Channel, first layer (256QAM level).
   int32_t **dl_ch_magr0;
-  /// \brief Cross-correlation of two gNB signals.
-  /// - first index: rx antenna [0..nb_antennas_rx[
+  /// \brief Cross-correlation Matrix of the gNB Tx channel signals.
+  /// - first index: aatx*n_rx+aarx for all aatx=[0..n_tx[ and aarx=[0..nb_rx[
   /// - second index: symbol [0..]
-  int32_t **rho;
-  /// never used... always send dl_ch_rho_ext instead...
-  int32_t **rho_i;
+  int32_t ***rho;
   /// \brief Pointers to llr vectors (2 TBs).
   /// - first index: ? [0..1] (hard coded)
   /// - second index: ? [0..1179743] (hard coded)
@@ -762,8 +766,8 @@ typedef struct {
   int UE_fo_compensation;
   /// \brief Indicator that UE is synchronized to a gNB
   int is_synchronized;
-  /// \brief Indicates on which frame is synchronized in a two frame synchronization
-  int is_synchronized_on_frame;
+  /// \brief Indicator that UE lost frame synchronization
+  int lost_sync;
   /// Data structure for UE process scheduling
   UE_nr_proc_t proc;
   /// Flag to indicate the UE shouldn't do timing correction at all
@@ -790,6 +794,8 @@ typedef struct {
   uint8_t ho_initiated;
   /// \brief indicator that Handover procedure has been triggered
   uint8_t ho_triggered;
+  /// threshold for false dci detection
+  int dci_thres;
   /// \brief Measurement variables.
   PHY_NR_MEASUREMENTS measurements;
   NR_DL_FRAME_PARMS  frame_parms;
@@ -807,6 +813,7 @@ typedef struct {
   NR_UE_PDCCH     *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_PRACH     *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_PUSCH     *pusch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX];
+  NR_UE_PUCCH     *pucch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_DLSCH_t   *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX][NR_MAX_NB_CODEWORDS]; // two RxTx Threads
   NR_UE_ULSCH_t   *ulsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX][NR_MAX_NB_CODEWORDS]; // two code words
   NR_UE_DLSCH_t   *dlsch_SI[NUMBER_OF_CONNECTED_gNB_MAX];
@@ -842,17 +849,23 @@ typedef struct {
   /// PDSCH DMRS
   uint32_t ****nr_gold_pdsch[NUMBER_OF_CONNECTED_eNB_MAX];
 
+  // Scrambling IDs used in PDSCH DMRS
+  uint16_t scramblingID[2];
+
   /// PDCCH DMRS
   uint32_t ***nr_gold_pdcch[NUMBER_OF_CONNECTED_eNB_MAX];
 
+  // Scrambling IDs used in PDCCH DMRS
+  uint16_t scramblingID_pdcch;
+
   /// PUSCH DMRS sequence
   uint32_t ****nr_gold_pusch_dmrs;
 
   uint32_t X_u[64][839];
 
-  uint32_t high_speed_flag;
+
   uint32_t perfect_ce;
-  int16_t ch_est_alpha;
+
   int generate_ul_signal[NUMBER_OF_CONNECTED_gNB_MAX];
 
   UE_NR_SCAN_INFO_t scan_info[NB_BANDS_MAX];
@@ -948,31 +961,10 @@ typedef struct {
   /// PUSCH contention-based access vars
   PUSCH_CA_CONFIG_DEDICATED  pusch_ca_config_dedicated[NUMBER_OF_eNB_MAX]; // lola
 
-  /// PUCCH variables
-
-  PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_gNB_MAX];
 
   //#if defined(UPGRADE_RAT_NR)
 #if 1
-
   SystemInformationBlockType1_nr_t systemInformationBlockType1_nr;
-
-  CellGroupConfig_t          cell_group_config;
-  PDSCH_ServingCellConfig_t  PDSCH_ServingCellConfig;
-  PDSCH_Config_t             PDSCH_Config;
-
-  PUCCH_ConfigCommon_nr_t    pucch_config_common_nr[NUMBER_OF_CONNECTED_gNB_MAX];
-  PUCCH_Config_t             pucch_config_dedicated_nr[NUMBER_OF_CONNECTED_gNB_MAX];
-
-  PUSCH_Config_t             pusch_config;
-  SRS_NR                     srs;
-
-  crossCarrierSchedulingConfig_t crossCarrierSchedulingConfig;
-  supplementaryUplink_t supplementaryUplink;
-  dmrs_DownlinkConfig_t dmrs_DownlinkConfig;
-  csi_MeasConfig_t csi_MeasConfig;
-  PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig;
-
 #endif
 
   uint8_t ncs_cell[20][7];
@@ -1075,6 +1067,8 @@ typedef struct {
 typedef struct nr_rxtx_thread_data_s {
   UE_nr_rxtx_proc_t proc;
   PHY_VARS_NR_UE    *UE;
+  NR_UE_SCHED_MODE_t ue_sched_mode;
+  notifiedFIFO_t txFifo;
 }  nr_rxtx_thread_data_t;
 
 #include "SIMULATION/ETH_TRANSPORT/defs.h"
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index 18c7dd413b5d8cc0c18cde16a2a017855ee9b59d..d333732d1fdbadb64e0a491e88177c493277e855 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -93,22 +93,24 @@
 #define NR_MAX_CSET_DURATION 3
 
 #define NR_MAX_NB_RBG 18
-#define NR_MAX_NB_LAYERS 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3)
+#define NR_MAX_NB_LAYERS 2 // 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3)
 #define NR_MAX_NB_CODEWORDS 2
 #define NR_MAX_NB_HARQ_PROCESSES 16
-#define NR_MAX_PDSCH_ENCODED_LENGTH NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS // 8 is the maximum modulation order (it was 950984 before !!) 
+#define NR_MAX_PDSCH_ENCODED_LENGTH (NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS) // 8 is the maximum modulation order (it was 950984 before !!)
 #define NR_MAX_PUSCH_ENCODED_LENGTH NR_MAX_PDSCH_ENCODED_LENGTH
 #define NR_MAX_PDSCH_TBS 3824
 #define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.
 
-#define MAX_NUM_NR_DLSCH_SEGMENTS 34
+#define MAX_NUM_NR_DLSCH_SEGMENTS (NR_MAX_NB_LAYERS*34)
 #define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
 
-#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS
+#define MAX_NUM_NR_ULSCH_SEGMENTS 34
 #define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056)
 
 #define MAX_NUM_NR_CHANNEL_BITS (14*273*12*8)  // 14 symbols, 273 RB
 #define MAX_NUM_NR_RE (14*273*12)
+#define NR_RX_NB_TH 1
+#define NR_NB_TH_SLOT 2
 
 extern const uint8_t nr_rv_round_map[4]; 
 extern const uint8_t nr_rv_round_map_ue[4]; 
@@ -327,7 +329,8 @@ struct NR_DL_FRAME_PARMS {
   /// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP)
   lte_prefix_type_t Ncp;
   /// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211
-  int16_t symbol_rotation[224*2];
+  /// First dimension is for the direction of the link (0 DL, 1 UL)
+  int16_t symbol_rotation[2][224*2];
   /// shift of pilot position in one RB
   uint8_t nushift;
   /// SRS configuration from TS 38.331 RRC
@@ -368,20 +371,4 @@ struct NR_DL_FRAME_PARMS {
 #define KHz (1000UL)
 #define MHz (1000*KHz)
 
-typedef struct nr_bandentry_s {
-  int16_t band;
-  uint64_t ul_min;
-  uint64_t ul_max;
-  uint64_t dl_min;
-  uint64_t dl_max;
-  uint64_t step_size;
-  uint64_t N_OFFs_DL;
-  uint8_t deltaf_raster;
-} nr_bandentry_t;
-
-typedef struct nr_band_info_s {
-  int nbands;
-  nr_bandentry_t band_info[100];
-} nr_band_info_t;
-
 #endif
diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h
index ceb75c255472d725cb13a07e03607fe476a9b820..59d82166790b791a6d6128f85da00d0488f238e9 100644
--- a/openair1/PHY/impl_defs_nr.h
+++ b/openair1/PHY/impl_defs_nr.h
@@ -36,7 +36,6 @@
 
 #include <stdbool.h>
 #include "types.h"
-#include "NR_PDSCH-TimeDomainResourceAllocation.h"
 
 #ifdef DEFINE_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
 #define EXTERN
@@ -214,10 +213,8 @@ typedef enum {
 
 #define NB_SRS_PERIOD         (17)
 
-const uint16_t srs_period[NB_SRS_PERIOD]
-#ifdef INIT_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
+static const uint16_t srs_period[NB_SRS_PERIOD]
 = { 1, 2, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 160, 320, 640, 1280, 2560}
-#endif
 ;
 
 /// SRS_Resource of SRS_Config information element from 38.331 RRC specifications
@@ -342,116 +339,22 @@ typedef struct {
 *
 ************************************************************************/
 
-/* FFS TODO_NR partial structure that should be complete */
-
-typedef enum {
-  semiStatic = 0,
-  dynamic =    1
-} pdsch_HARQ_ACK_Codebook_t;
-
-
-////////////////////////////////////////////////////////////////////////////////################################
 #define MAX_NR_RATE_MATCH_PATTERNS            4
 #define MAX_NR_ZP_CSI_RS_RESOURCES           32
 #define MAX_NR_OF_DL_ALLOCATIONS             16
 #define MAX_NR_OF_UL_ALLOCATIONS            (16)
 
-typedef enum{
-  dl_resourceAllocationType0 = 1,
-  dl_resourceAllocationType1 = 2,
-  dl_dynamicSwitch = 3
-} dl_resourceAllocation_t;
-typedef enum{
-  dl_rgb_config1 = 1,
-  dl_rgb_config2 = 2
-} dl_rgb_Size_t;
-typedef enum {
-  st_n4       = 1,
-  st_wideband = 2
-} static_bundleSize_t;
 typedef enum {
-  dy_1_n4       = 1,
-  dy_1_wideband = 2,
-  dy_1_n2_wideband = 3,
-  dy_1_n4_wideband = 4
-} bundleSizeSet1_t;
-typedef enum {
-  dy_2_n4       = 1,
-  dy_2_wideband = 2,
-} bundleSizeSet2_t;
-typedef struct{
-  bundleSizeSet1_t bundleSizeSet1;
-  bundleSizeSet2_t bundleSizeSet2;
-} dynamic_bundleSize_t;
-typedef struct {
-  static_bundleSize_t staticBundling;
-  dynamic_bundleSize_t dynamicBundlig;
-} prb_bundleType_t;
-typedef enum {
-  nb_code_n1 = 1,
-  nb_code_n2 = 2
-} maxNrofCodeWordsScheduledByDCI_t;
-typedef struct{
-// to be defined FIXME!!!
-}rateMatchPattern_t;
-typedef struct{
-// to be defined FIXME!!!
-}zp_CSI_RS_Resource_t;
-typedef struct {
-/*
- * resourceAllocation
- */
-  dl_resourceAllocation_t dl_resourceAllocation;
-/*
- * corresponds to I, where I the number of entries in the higher layer parameter pdsch-AllocationList
- */
-  uint8_t n_pdsh_alloc_list;
-/*
- * rateMatchPatternToAddModList
- */
-  rateMatchPattern_t rateMatchPatternToAddModList[MAX_NR_RATE_MATCH_PATTERNS];
-/*
- * rateMatchPatternToReleaseList
- */
-  uint8_t rateMatchPatternToReleaseList[MAX_NR_RATE_MATCH_PATTERNS];
-  /*
-   * n_rateMatchPatterns indicates the number of rateMatchPatterns defined currently
-   */
-  uint8_t n_rateMatchPatterns;
-  /*
-   * zp-CSI-RS-ResourceToAddModList
-   */
-  zp_CSI_RS_Resource_t zp_CSI_RS_Resource[MAX_NR_ZP_CSI_RS_RESOURCES];
-  /*
-   * zp-CSI-RS-ResourceToReleaseList
-   */
-  uint8_t zp_CSI_RS_ResourceId[MAX_NR_ZP_CSI_RS_RESOURCES];
-  /*
-   * n_zp-CSI-RS-Resource
-   */
-  uint8_t n_zp_CSI_RS_ResourceId;
-/*
- * rgb_Size
- */
-  dl_rgb_Size_t dl_rgbSize;
-/*
- * prb-BundlingType
- */
-  prb_bundleType_t prbBundleType;
-/*
- * pdsch-HARQ-ACK-Codebook: this is part of the IE PhysicalCellGroupConfig which is used to configure cell-group specific L1 parameters (TS 38.331)
- */
-  pdsch_HARQ_ACK_Codebook_t pdsch_HARQ_ACK_Codebook;
-  ////////////////////////////////////////////////////////////////////////////////################################
-
-/*
-  Maximum number of code words that a single DCI may schedule. This changes the number of MCS/RV/NDI bits in the DCI message from 1 to 2.
-*/
-  maxNrofCodeWordsScheduledByDCI_t maxNrofCodeWordsScheduledByDCI;
-
-  NR_PDSCH_TimeDomainResourceAllocation_t *pdsch_TimeDomainResourceAllocation[MAX_NR_OF_DL_ALLOCATIONS];
+  typeA = 0,
+  typeB = 1
+} mappingType_t;
 
-} PDSCH_Config_t;
+typedef enum {
+  pdsch_dmrs_pos0 = 0,
+  pdsch_dmrs_pos1 = 1,
+  pdsch_dmrs_pos2 = 2,
+  pdsch_dmrs_pos3 = 3,
+} pdsch_dmrs_AdditionalPosition_t;
 
 /***********************************************************************
 *
@@ -461,128 +364,20 @@ typedef struct {
 *
 ************************************************************************/
 
-
-typedef enum {
-  enable_tpc_accumulation = 0,  /* by default it is enable */
-  disable_tpc_accumulation = 1
-} tpc_Accumulation_t;
-
-typedef enum {
-  typeA = 0,
-  typeB = 1
-} mappingType_t;
-
-typedef struct {
-  tpc_Accumulation_t tpc_Accumulation;
-} PUSCH_PowerControl_t;
-
-typedef struct {
-
-  uint8_t         k2;
-  mappingType_t   mappingType;
-  uint8_t         startSymbolAndLength;
-} PUSCH_TimeDomainResourceAllocation_t;
-////////////////////////////////////////////////////////////////////////////////################################
-typedef enum{
-  maxCodeBlockGroupsPerTransportBlock_n2 = 2,
-  maxCodeBlockGroupsPerTransportBlock_n4 = 4,
-  maxCodeBlockGroupsPerTransportBlock_n6 = 6,
-  maxCodeBlockGroupsPerTransportBlock_n8 = 8
-} maxCodeBlockGroupsPerTransportBlock_t;
-typedef struct{ // The IE PUSCH-ServingCellConfig is used to configure UE specific PUSCH parameters that are common across the UE's BWPs of one serving cell
-	  maxCodeBlockGroupsPerTransportBlock_t maxCodeBlockGroupsPerTransportBlock;
-} PUSCH_ServingCellConfig_t;
-typedef struct{ // CSI-MeasConfig IE is used to configure CSI-RS (reference signals)
-  uint8_t reportTriggerSize;
-} csi_MeasConfig_t;
-typedef enum {
-  pdsch_dmrs_type1 = 0,
-  pdsch_dmrs_type2 = 1
-} pdsch_dmrs_type_t;
 typedef enum {
   pusch_dmrs_type1 = 0,
   pusch_dmrs_type2 = 1
 } pusch_dmrs_type_t;
-typedef enum {
-  pdsch_dmrs_pos0 = 0,
-  pdsch_dmrs_pos1 = 1,
-  pdsch_dmrs_pos3 = 3,
-} pdsch_dmrs_AdditionalPosition_t;
 typedef enum {
   pusch_dmrs_pos0 = 0,
   pusch_dmrs_pos1 = 1,
   pusch_dmrs_pos2 = 2,
   pusch_dmrs_pos3 = 3,
 } pusch_dmrs_AdditionalPosition_t;
-typedef enum {
-  offset00 = 0,
-  offset01 = 1,
-  offset10 = 2,
-  offset11 = 3,
-} ptrs_resource_elementoffset_t;
-typedef enum {
-  pdsch_len1 = 1,
-  pdsch_len2 = 2
-} pdsch_maxLength_t;
 typedef enum {
   pusch_len1 = 1,
   pusch_len2 = 2
 } pusch_maxLength_t;
-typedef struct {
-  uint8_t ptrs_mcs1;
-  uint8_t ptrs_mcs2;
-  uint8_t ptrs_mcs3;
-} ptrs_time_density_t;
-typedef struct {
-  uint16_t n_rb0;
-  uint16_t n_rb1;
-} ptrs_frequency_density_t;
-typedef struct { // The IE PTRS-UplinkConfig is used to configure uplink Phase-Tracking-Reference-Signals (PTRS)
-  uint8_t  num_ptrs_ports;
-  ptrs_resource_elementoffset_t resourceElementOffset;
-  ptrs_time_density_t  timeDensity;
-  ptrs_frequency_density_t  frequencyDensity;
-  uint32_t  ul_ptrs_power;
-} ptrs_UplinkConfig_t;
-typedef struct { // The IE DMRS-DownlinkConfig is used to configure downlink demodulation reference signals for PDSCH
-  pdsch_dmrs_type_t pdsch_dmrs_type;
-  pdsch_dmrs_AdditionalPosition_t pdsch_dmrs_AdditionalPosition;
-  pdsch_maxLength_t pdsch_maxLength;
-  uint16_t scramblingID0;
-  uint16_t scramblingID1;
-} dmrs_DownlinkConfig_t;
-typedef struct { // The IE DMRS-UplinkConfig is used to configure uplink demodulation reference signals for PUSCH
-  pusch_dmrs_type_t pusch_dmrs_type;
-  pusch_dmrs_AdditionalPosition_t pusch_dmrs_AdditionalPosition;
-  pusch_maxLength_t pusch_maxLength;
-  ptrs_UplinkConfig_t ptrs_UplinkConfig;
-  uint16_t scramblingID0;
-  uint16_t scramblingID1;
-} dmrs_UplinkConfig_t;
-typedef struct {
-/*
- * Serving cell ID of a PSCell. The PCell of the Master Cell Group uses ID = 0
- */
-  uint8_t servCellIndex;
-}servCellIndex_t;
-typedef struct{
-  uint8_t cif_presence;
-}own_t;
-typedef struct{
-  servCellIndex_t scheduling_cell_id;
-  uint8_t cif_InSchedulingCell;
-}other_t;
-typedef struct{
- own_t own;
- other_t other;
-}schedulingCellInfo_t;
-typedef struct{
- schedulingCellInfo_t schedulingCellInfo;
-} crossCarrierSchedulingConfig_t;
-typedef struct{
-  // this variable will be filled with '1' if SUL is supported and '0' if SUL is not supported
-  uint8_t supplementaryUplink;
-}supplementaryUplink_t;
 
 typedef enum {
   txConfig_codebook = 1,
@@ -623,57 +418,6 @@ typedef struct {
   betaOffset_type_t betaOffset_type;
   betaOffset_t betaOffset;
 } uci_onPusch_t;
-typedef struct {
-/*
- * txConfig
- */
-  txConfig_t txConfig;
-/*
- * frequencyHopping
- */
-	frequencyHopping_t frequencyHopping;
-/*
- * frequencyHoppingOffsetLists
- */
-  uint16_t frequencyHoppingOffsetLists[4];
-  // n_frequencyHoppingOffsetLists contains the number of offsets listed. We can list up to 4 offsets
-  uint8_t n_frequencyHoppingOffsetLists;
-/*
- * resourceAllocation
- */
-  ul_resourceAllocation_t ul_resourceAllocation;
-/*
- * DMRS-Uplinkconfig
- */
-  dmrs_UplinkConfig_t dmrs_UplinkConfig;
-/*
- * rgb_Size
- */
-  ul_rgb_Size_t ul_rgbSize;
-/*
- * corresponds to I, where I the number of entries in the higher layer parameter pusch-AllocationList
- */
-  uint8_t n_push_alloc_list;
-/*
- * transformPrecoder
- */
-transformPrecoder_t transformPrecoder;
-/*
- * codebookSubset
- */
-codebookSubset_t codebookSubset;
-/*
- * maxRank
- */
-uint8_t maxRank;
-/*
- * uci_onPusch
- */
-uci_onPusch_t uci_onPusch;
-////////////////////////////////////////////////////////////////////////////////################################
-  PUSCH_PowerControl_t                    pusch_PowerControl;
-  PUSCH_TimeDomainResourceAllocation_t    *pusch_TimeDomainResourceAllocation[MAX_NR_OF_UL_ALLOCATIONS];
-} PUSCH_Config_t;
 
 /***********************************************************************
 *
@@ -683,23 +427,10 @@ uci_onPusch_t uci_onPusch;
 *
 ************************************************************************/
 
-#define MAX_NR_OF_PUCCH_P0_PER_SET                (8)
 #define NUMBER_PUCCH_FORMAT_NR                    (5)
 
 typedef int8_t power_level_t;      /* INTEGER (-16..15) */
 
-typedef struct {
-  uint8_t         p0_PUCCH_Id;     /* INTEGER (1..8)     */
-  power_level_t   p0_PUCCH_Value;
-} P0_PUCCH_t;
-
-typedef struct {
-  power_level_t deltaF_PUCCH_f[NUMBER_PUCCH_FORMAT_NR];
-  P0_PUCCH_t    *p0_Set[MAX_NR_OF_PUCCH_P0_PER_SET];
-  // pathlossReferenceRSs        SEQUENCE (SIZE (1..maxNrofPUCCH-PathlossReferenceRSs)) OF PUCCH-PathlossReferenceRS OPTIONAL, -- Need M
-  int8_t        twoPUCCH_PC_AdjustmentStates;
-
-} PUCCH_PowerControl_t;
 
 /***********************************************************************
 *
@@ -796,7 +527,6 @@ typedef struct {
   uint8_t                initial_CS_indexes[MAX_NB_CYCLIC_SHIFT];
 } initial_pucch_resource_t;
 
-const initial_pucch_resource_t initial_pucch_resource[NB_INITIAL_PUCCH_RESOURCE]; /* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */
 
 /* structure with all possible fields for pucch format from 0 to 4  */
 typedef struct {
@@ -890,152 +620,9 @@ typedef struct {
   PUCCH_FormatConfig_t   *formatConfig[NUMBER_PUCCH_FORMAT_NR-1];   /* format 0 is not there */
   uint8_t                dl_DataToUL_ACK[NB_DL_DATA_TO_UL_ACK];     /* table TS 38.213 Table 9.2.3-1: Mapping of PSDCH-to-HARQ_feedback timing indicator field values to numbers of slots */
   void                   *spatial_Relation_Info[MAX_NR_OF_SPATIAL_RELATION_INFOS];
-  PUCCH_PowerControl_t   pucch_PowerControl;
 } PUCCH_Config_t;
 
-/***********************************************************************
-*
-* FUNCTIONALITY    :  PhysicalCellGroupConfig
-*
-* DESCRIPTION      :  Physical cell group configuration
-*
-************************************************************************/
-
-typedef uint16_t RNTI_value_t;
-
-typedef struct {
-/*
-  -- Enables spatial bundling of HARQ ACKs. It is configured per cell group (i.e. for all the cells within the cell group) for PUCCH
-  -- reporting of HARQ-ACK. It is only applicable when more than 4 layers are possible to schedule.
-  -- Corresponds to L1 parameter 'HARQ-ACK-spatial-bundling' (see 38.213, section FFS_Section)
-  -- Absence indicates that spatial bundling is disabled.
-*/
-  bool                          harq_ACK_SpatialBundlingPUCCH;
-/*
-  -- Enables spatial bundling of HARQ ACKs. It is configured per cell group (i.e. for all the cells within the cell group) for PUSCH
-  -- reporting of HARQ-ACK. It is only applicable when more than 4 layers are possible to schedule.
-  -- Corresponds to L1 parameter 'HARQ-ACK-spatial-bundling' (see 38.213, section FFS_Section)
-  -- Absence indicates that spatial bundling is disabled.
-*/
-  bool                          harq_ACK_SpatialBundlingPUSCH;
-/*
-  -- The maximum transmit power to be used by the UE in this NR cell group.
-*/
-  uint8_t                       p_NR;
-/*
-  -- The PDSCH HARQ-ACK codebook is either semi-static of dynamic. This is applicable to both CA and none CA operation.
-  -- Corresponds to L1 parameter 'HARQ-ACK-codebook' (see 38.213, section FFS_Section)
-*/
-  pdsch_HARQ_ACK_Codebook_t     pdsch_HARQ_ACK_Codebook;
-/*
-  -- RNTI used for SRS TPC commands on DCI. Corresponds to L1 parameter 'TPC-SRS-RNTI' (see 38.213, section 10)
-*/
-  RNTI_value_t                  tpc_SRS_RNTI;
-/*
-  -- RNTI used for PUCCH TPC commands on DCI. Corresponds to L1 parameter 'TPC-PUCCH-RNTI' (see 38.213, section 10).
-*/
-  RNTI_value_t                  tpc_PUCCH_RNTI;
-/*
-  -- RNTI used for PUSCH TPC commands on DCI. Corresponds to L1 parameter 'TPC-PUSCH-RNTI' (see 38.213, section 10)
-*/
-  RNTI_value_t                  tpc_PUSCH_RNTI;
-} PhysicalCellGroupConfig_t;
-
-/***********************************************************************
-*
-* FUNCTIONALITY    :  CellGroupConfig
-*
-* DESCRIPTION      :  Cell Group configuration
-*
-************************************************************************/
-
-/* FFS TODO_NR partial structure that should be complete */
 
-typedef struct {
-/*
-  cellGroupId                 CellGroupId,
-
-  -- Logical Channel configuration and association with radio bearers:
-  rlc-BearerToAddModList            SEQUENCE (SIZE(1..maxLC-ID)) OF RLC-Bearer-Config       OPTIONAL,   -- Need N
-  rlc-BearerToReleaseList           SEQUENCE (SIZE(1..maxLC-ID)) OF LogicalChannelIdentity      OPTIONAL,   -- Need N
-
-  -- Parameters applicable for the entire cell group:
-  mac-CellGroupConfig             MAC-CellGroupConfig                       OPTIONAL, -- Need M
-*/
-  PhysicalCellGroupConfig_t  physicalCellGroupConfig;
-/*
-  -- Serving Cell specific parameters (SpCell and SCells)
-  spCellConfig                SpCellConfig                          OPTIONAL,   -- Need M
-  sCellToAddModList             SEQUENCE (SIZE (1..maxNrofSCells)) OF SCellConfig       OPTIONAL, -- Need N
-  -- List of seconary serving cells to be released (not applicable for SpCells)
-  sCellToReleaseList              SEQUENCE (SIZE (1..maxNrofSCells)) OF SCellIndex        OPTIONAL, -- Need N
-  ...
-  */
-} CellGroupConfig_t;
-
-/***********************************************************************
-*
-* FUNCTIONALITY    :  PDSCH_ServingCellConfig
-*
-* DESCRIPTION      :  pdsch serving cell configuration
-*
-************************************************************************/
-
-/* FFS TODO_NR partial structure that should be complete */
-
-typedef int PDSCH_CodeBlockGroupTransmission_t;  /* dummy struct which should be change by correct structure */
-
-typedef enum {
-  xOh6  = 0,
-  xOh12 = 1,
-  xOh18 = 2
-} xOverhead_t;
-
-typedef enum {
-  n2_dl_harq  = 2,
-  n4_dl_harq  = 4,
-  n6_dl_harq  = 6,
-  n10_dl_harq = 10,
-  n12_dl_harq = 12,
-  n16_dl_harq = 16
-} nrofHARQ_ProcessesForPDSCH_t;
-typedef enum{
-  maxCodeBlockGroupsPerTransportBlock_dl_n2 = 2,
-  maxCodeBlockGroupsPerTransportBlock_dl_n4 = 4,
-  maxCodeBlockGroupsPerTransportBlock_dl_n6 = 6,
-  maxCodeBlockGroupsPerTransportBlock_dl_n8 = 8
-} maxCodeBlockGroupsPerTransportBlock_dl_t;
-
-typedef struct {
-/*
-  -- Enables and configures code-block-group (CBG) based transmission (see 38.213, section 9.1.1)
-*/
-  PDSCH_CodeBlockGroupTransmission_t  *codeBlockGroupTransmission;
-/*
-  -- Accounts for overhead from CSI-RS, CORESET, etc. If the field is absent, the UE applies value xOh0.
-  -- Corresponds to L1 parameter 'Xoh-PDSCH' (see 38.214, section 5.1.3.2)
-*/
-  xOverhead_t                         xOverhead;
-/*
-  -- The number of HARQ processes to be used on the PDSCH of a serving cell. n2 corresponds to 2 HARQ processes, n4 to 4 HARQ processes
-  -- and so on. If the field is absent, the UE uses 8 HARQ processes.
-  -- Corresponds to L1 parameter 'number-HARQ-process-PDSCH' (see 38.214, section REF)
-*/
-  nrofHARQ_ProcessesForPDSCH_t        nrofHARQ_ProcessesForPDSCH;
-/*
-  -- The ID of the serving cell (of the same cell group) to use for PUCCH.
-  -- If the field is absent, the UE sends the HARQ feedback on the PUCCH of the SpCell of this cell group.
-*/
-  uint8_t                            pucch_Cell;
-/*
- * maxCodeBlockGroupsPerTransportBlock_dl_t
- */
-  maxCodeBlockGroupsPerTransportBlock_dl_t maxCodeBlockGroupsPerTransportBlock_dl;
-/*
- * codeBlockGroupFlushIndicator (boolean)
- */
-  uint8_t codeBlockGroupFlushIndicator;
-} PDSCH_ServingCellConfig_t;
 
 /***********************************************************************
 *
@@ -1051,11 +638,6 @@ typedef struct {
 
 #define NB_SR_PERIOD    (15)
 
-const uint16_t scheduling_request_periodicity[NB_SR_PERIOD]
-#ifdef INIT_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
-= { 0, 0, 1, 2, 4, 5, 8, 10, 16, 20, 40, 80, 160, 320, 640 }
-#endif
-;
 
 typedef enum {
   sr_sym2     = 0,
diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h
index a8548af8dc983f1f5cc2490efa953a40dc7d0dc5..fa021ffe81860cba2a9ed26d5717a565ad156fda 100644
--- a/openair1/PHY/impl_defs_top.h
+++ b/openair1/PHY/impl_defs_top.h
@@ -275,6 +275,12 @@
 #define NR_UE_CAPABILITY_SLOT_RX_TO_TX           (6)                      /* FFS_NR_TODO it defines ue capability which is the number of slots */
                                                                           /* - between reception of pdsch and tarnsmission of its acknowlegment */
                                                                           /* - between reception of un uplink grant and its related transmission */
+#ifndef NO_RAT_NR
+  #define DURATION_RX_TO_TX           (NR_UE_CAPABILITY_SLOT_RX_TO_TX)  /* for NR this will certainly depends to such UE capability which is not yet defined */
+#else
+  #define DURATION_RX_TO_TX           (6)   /* For LTE, this duration is fixed to 4 and it is linked to LTE standard for both modes FDD/TDD */
+#endif
+
 
 #define NR_MAX_HARQ_PROCESSES                    (16)
 #define NR_MAX_ULSCH_HARQ_PROCESSES              (NR_MAX_HARQ_PROCESSES)  /* cf 38.214 6.1 UE procedure for receiving the physical uplink shared channel */
diff --git a/openair1/PHY/phy_extern.h b/openair1/PHY/phy_extern.h
index 165ed961b30f0a40a3723c2ca275a88152fef815..d5fea5aec66b0ce4d9acf4ac0f75c7275ca4b2eb 100644
--- a/openair1/PHY/phy_extern.h
+++ b/openair1/PHY/phy_extern.h
@@ -23,7 +23,6 @@
 #define __PHY_EXTERN_H__
 
 #include "PHY/defs_common.h"
-#include "common/ran_context.h"
 
 extern  char* namepointer_chMag ;
 extern char* namepointer_log2;
@@ -33,14 +32,13 @@ extern unsigned int RX_DMA_BUFFER[4][NB_ANTENNAS_RX];
 extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX];
 
 #include "PHY/LTE_TRANSPORT/transport_extern.h"
-//#include "SIMULATION/ETH_TRANSPORT/extern.h"
+#include "PHY/defs_RU.h"
 
 extern unsigned int DAQ_MBOX;
 extern int number_of_cards;
 
 extern const short conjugate[8],conjugate2[8];
 
-extern RAN_CONTEXT_t RC;
 
 extern short primary_synch0[144];
 extern short primary_synch1[144];
@@ -48,12 +46,6 @@ extern short primary_synch2[144];
 extern unsigned char primary_synch0_tab[72];
 extern unsigned char primary_synch1_tab[72];
 extern unsigned char primary_synch2_tab[72];
-extern int16_t *primary_synch0_time; //!< index: [0..ofdm_symbol_size*2[
-extern int16_t *primary_synch1_time; //!< index: [0..ofdm_symbol_size*2[
-extern int16_t *primary_synch2_time; //!< index: [0..ofdm_symbol_size*2[
-extern int *sync_corr_ue0; //!< index [0..10*samples_per_tti[
-extern int *sync_corr_ue1; //!< index [0..10*samples_per_tti[
-extern int *sync_corr_ue2; //!< index [0..10*samples_per_tti[
 
 extern int flagMag;
 //extern short **txdataF_rep_tmp;
diff --git a/openair1/PHY/phy_extern_nr_ue.h b/openair1/PHY/phy_extern_nr_ue.h
index 700419c61c9b9268978b78671c21d5fbbd871787..f1704a7902e26dd685ef3559c4b24c7f895bd522 100644
--- a/openair1/PHY/phy_extern_nr_ue.h
+++ b/openair1/PHY/phy_extern_nr_ue.h
@@ -55,9 +55,6 @@ extern unsigned char primary_synch2_tab[72];
 extern int16_t *primary_synch0_time; //!< index: [0..ofdm_symbol_size*2[
 extern int16_t *primary_synch1_time; //!< index: [0..ofdm_symbol_size*2[
 extern int16_t *primary_synch2_time; //!< index: [0..ofdm_symbol_size*2[
-extern int *sync_corr_ue0; //!< index [0..10*samples_per_tti[
-extern int *sync_corr_ue1; //!< index [0..10*samples_per_tti[
-extern int *sync_corr_ue2; //!< index [0..10*samples_per_tti[
 
 extern int flagMag;
 //extern short **txdataF_rep_tmp;
diff --git a/openair1/PHY/phy_extern_ue.h b/openair1/PHY/phy_extern_ue.h
index 622551c2fe9891ad7a77df04ef2de7ed9e0d5953..9f227806fd6b577a241a2708bc68e06041dc5e66 100644
--- a/openair1/PHY/phy_extern_ue.h
+++ b/openair1/PHY/phy_extern_ue.h
@@ -23,7 +23,6 @@
 #define __PHY_EXTERN_UE__H__
 
 #include "PHY/defs_UE.h"
-#include "common/ran_context.h"
 
 extern  char* namepointer_chMag ;
 extern char* namepointer_log2;
@@ -47,12 +46,6 @@ extern short primary_synch2[144];
 extern unsigned char primary_synch0_tab[72];
 extern unsigned char primary_synch1_tab[72];
 extern unsigned char primary_synch2_tab[72];
-extern int16_t *primary_synch0_time; //!< index: [0..ofdm_symbol_size*2[
-extern int16_t *primary_synch1_time; //!< index: [0..ofdm_symbol_size*2[
-extern int16_t *primary_synch2_time; //!< index: [0..ofdm_symbol_size*2[
-extern int *sync_corr_ue0; //!< index [0..10*samples_per_tti[
-extern int *sync_corr_ue1; //!< index [0..10*samples_per_tti[
-extern int *sync_corr_ue2; //!< index [0..10*samples_per_tti[
 
 extern int flagMag;
 //extern short **txdataF_rep_tmp;
diff --git a/openair1/PHY/phy_vars.h b/openair1/PHY/phy_vars.h
index 5e2be8bd8f76181ff7f660da8902ab2d1bf88415..9edb7031b95cf70370b90596ead42c977f4c3255 100644
--- a/openair1/PHY/phy_vars.h
+++ b/openair1/PHY/phy_vars.h
@@ -25,7 +25,6 @@
 #include "PHY/types.h"
 #include "PHY/defs_eNB.h"
 #include "PHY/defs_UE.h"
-#include "common/ran_context.h"
 
 char* namepointer_chMag ;
 char fmageren_name2[512];
@@ -33,17 +32,15 @@ char* namepointer_log2;
 
 
 #include "PHY/LTE_REFSIG/primary_synch.h"
-int16_t *primary_synch0_time;
-int16_t *primary_synch1_time;
-int16_t *primary_synch2_time;
 
 
 #include "PHY/LTE_TRANSPORT/transport_vars.h"
 #include "PHY/MODULATION/modulation_vars.h"
 
+#include "nfapi/oai_integration/vendor_ext.h"
+
 
 PHY_VARS_UE ***PHY_vars_UE_g;
-RAN_CONTEXT_t RC;
 UL_RCC_IND_t UL_RCC_INFO;
 
 unsigned short rev[2048],rev_times4[8192],rev_half[1024];
diff --git a/openair1/PHY/phy_vars_ue.h b/openair1/PHY/phy_vars_ue.h
index e90c2641aa7f852ff4e5cf5a855db0d6ecf0a2d5..469a5c475470fe044b27382bc1acfd9f3f60001c 100644
--- a/openair1/PHY/phy_vars_ue.h
+++ b/openair1/PHY/phy_vars_ue.h
@@ -33,9 +33,6 @@ char *namepointer_log2;
 
 
 #include "PHY/LTE_REFSIG/primary_synch.h"
-int16_t *primary_synch0_time;
-int16_t *primary_synch1_time;
-int16_t *primary_synch2_time;
 
 PHY_VARS_UE ***PHY_vars_UE_g;
 
diff --git a/openair1/PHY/types.h b/openair1/PHY/types.h
index c0a9af388cfcc02643e118851719e05364c60570..8d8d9db2de5c38e912327050f67cbcd79ddd7c94 100644
--- a/openair1/PHY/types.h
+++ b/openair1/PHY/types.h
@@ -23,6 +23,6 @@
 #define __openair_TYPES_H__
 
 #include <stdint.h>
-
+#define MAKE_VERSION(a,b,c) ((a)*256+(b)*16+c)
 
 #endif /*__openair_TYPES_H__ */
diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c
index 3f342802b4906d4d66c223ad9990d486266b1473..ecfec02193d498d9f167bb1e5278a46f3c5eafee 100644
--- a/openair1/SCHED/fapi_l1.c
+++ b/openair1/SCHED/fapi_l1.c
@@ -32,11 +32,15 @@
 
 #include "PHY/defs_eNB.h"
 #include "PHY/LTE_TRANSPORT/transport_proto.h"
+#include "PHY/LTE_TRANSPORT/transport_extern.h"
 #include "SCHED/sched_eNB.h"
 #include "nfapi/oai_integration/vendor_ext.h"
 #include "nfapi_pnf_interface.h"
 #include "fapi_l1.h"
 
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
+
 int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req);
 int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req);
 int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req);
@@ -209,13 +213,13 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
 
   UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE);
 
-  if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ) {
+  if( (UE_id<0) || (UE_id>=NUMBER_OF_DLSCH_MAX) ) {
     LOG_E(PHY,"illegal UE_id found!!! rnti %04x UE_id %d\n",rel8->rnti,UE_id);
     return;
   }
 
   //AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
-  //AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
+  //AssertFatal(UE_id<NUMBER_OF_DLSCH_MAX,"returned UE_id %d >= %d(NUMBER_OF_DLSCHMAX)\n",UE_id,NUMBER_OF_DLSCH_MAX);
   dlsch0 = eNB->dlsch[UE_id][0];
   dlsch1 = eNB->dlsch[UE_id][1];
 
@@ -291,7 +295,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
   if ((rel13->pdsch_payload_type <2) && (rel13->ue_type>0)) { // this is a BR/CE UE and SIB1-BR/SI-BR
     UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE);
     AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
-    AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
+    AssertFatal(UE_id<NUMBER_OF_DLSCH_MAX,"returned UE_id %d >= %d(NUMBER_OF_DLSCH_MAX)\n",UE_id,NUMBER_OF_DLSCH_MAX);
     dlsch0 = eNB->dlsch[UE_id][0];
     dlsch0->harq_mask = 1;
     dlsch0_harq     = dlsch0->harq_processes[0];
@@ -366,7 +370,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
   } else {
     UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE);
     AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
-    AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
+    AssertFatal(UE_id<NUMBER_OF_DLSCH_MAX,"returned UE_id %d >= %d(NUMBER_OF_DLSCH_MAX)\n",UE_id,NUMBER_OF_DLSCH_MAX);
     dlsch0 = eNB->dlsch[UE_id][0];
     dlsch1 = eNB->dlsch[UE_id][1];
     dlsch0->sib1_br_flag=0;
@@ -596,7 +600,7 @@ void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,
   uci->frame               = frame;
   uci->subframe            = subframe;
   uci->rnti                = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti;
-  uci->ue_id               = find_ulsch(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
+  uci->ue_id              = find_ulsch(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
   uci->type                = SR;
   uci->pucch_fmt           = pucch_format1;
   uci->num_antenna_ports   = 1;
@@ -622,7 +626,7 @@ void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_
   uci->frame               = frame;
   uci->subframe            = subframe;
   uci->rnti                = ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti;
-  uci->ue_id               = find_ulsch(ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
+  uci->ue_id              = find_ulsch(ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
   uci->type                = HARQ_SR;
   uci->num_antenna_ports   = 1;
   uci->num_pucch_resources = 1;
@@ -660,7 +664,7 @@ void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_p
 
   if (NFAPI_MODE==NFAPI_MODE_VNF) return;
 
-  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
+  for (i=0; i<NUMBER_OF_SRS_MAX; i++) {
     if (eNB->soundingrs_ul_config_dedicated[i].active==1) continue;
 
     eNB->soundingrs_ul_config_dedicated[i].active               = 1;
@@ -676,7 +680,7 @@ void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_p
     break;
   }
 
-  AssertFatal(i<NUMBER_OF_UE_MAX,"No room for SRS processing\n");
+  AssertFatal(i<NUMBER_OF_SRS_MAX,"No room for SRS processing\n");
 }
 
 void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
@@ -745,7 +749,8 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
   }
 }
 
-void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc) {
+void schedule_response(Sched_Rsp_t *Sched_INFO, void *arg) {
+  L1_rxtx_proc_t *proc = (L1_rxtx_proc_t *)arg;
   PHY_VARS_eNB *eNB;
   // copy data from L2 interface into L1 structures
   module_id_t               Mod_id       = Sched_INFO->module_id;
@@ -780,7 +785,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc) {
   nfapi_dl_config_request_pdu_t *dl_config_pdu;
   nfapi_hi_dci0_request_pdu_t   *hi_dci0_req_pdu;
   nfapi_ul_config_request_pdu_t *ul_config_pdu;
-  int i;
+
   eNB->pdcch_vars[subframe&1].num_pdcch_symbols = number_pdcch_ofdm_symbols;
   eNB->pdcch_vars[subframe&1].num_dci           = 0;
   eNB->phich_vars[subframe&1].num_hi            = 0;
@@ -811,8 +816,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc) {
 
     // clear DCI allocation maps for new subframe
     if (NFAPI_MODE!=NFAPI_MODE_VNF)
-      for (i=0; i<NUMBER_OF_UE_MAX; i++) {
-        if (eNB->ulsch[i]) {
+      for (int i=0; i<NUMBER_OF_ULSCH_MAX; i++) {
+        if (eNB->ulsch[i]!=NULL) {
           ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid];
           ulsch_harq->dci_alloc=0;
           ulsch_harq->rar_alloc=0;
@@ -820,7 +825,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc) {
       }
   }
 
-  for (i=0; i<number_dl_pdu; i++) {
+  for (int i=0; i<number_dl_pdu; i++) {
     dl_config_pdu = &DL_req->dl_config_request_body.dl_config_pdu_list[i];
 
     //LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type);
@@ -969,7 +974,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc) {
   }
 
   if (NFAPI_MODE!=NFAPI_MODE_VNF)
-    for (i=0; i<number_hi_dci0_pdu; i++) {
+    for (int i=0; i<number_hi_dci0_pdu; i++) {
       hi_dci0_req_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i];
       LOG_D(PHY,"NFAPI: hi_dci0_pdu %d : type %d\n",i,hi_dci0_req_pdu->pdu_type);
 
@@ -993,7 +998,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc) {
   if (NFAPI_MODE!=NFAPI_MONOLITHIC) {
     if (number_ul_pdu>0) {
       uint8_t ulsch_pdu_num = 0;
-      for (i=0; i<number_ul_pdu; i++) {
+      for (int i=0; i<number_ul_pdu; i++) {
         if((UL_req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) ||
            (UL_req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) ||
            (UL_req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) ||
@@ -1020,7 +1025,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc) {
       }
     }
   } else {
-    for (i=0; i<number_ul_pdu; i++) {
+    for (int i=0; i<number_ul_pdu; i++) {
       ul_config_pdu = &UL_req->ul_config_request_body.ul_config_pdu_list[i];
       LOG_D(PHY,"NFAPI: ul_pdu %d : type %d\n",i,ul_config_pdu->pdu_type);
       AssertFatal(ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE ||
diff --git a/openair1/SCHED/fapi_l1.h b/openair1/SCHED/fapi_l1.h
index 6b9121e17ff4acc088552ab1458431e8fd75a039..60ef5e764a4c40ef4415e91f45b3b2cc5f630ed0 100644
--- a/openair1/SCHED/fapi_l1.h
+++ b/openair1/SCHED/fapi_l1.h
@@ -31,8 +31,6 @@
  */
 
 #include "PHY/defs_eNB.h"
-#include "PHY/defs_gNB.h"
-#include "PHY/phy_extern.h"
 #include "PHY/LTE_TRANSPORT/transport_proto.h"
 #include "SCHED/sched_eNB.h"
 #include "SCHED/sched_common.h"
@@ -63,6 +61,8 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
 			 nfapi_ul_config_request_pdu_t *ul_config_pdu,
 			 uint16_t frame,uint8_t subframe,uint8_t srs_present);
 
+void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
+                                  nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu);
 void handle_ulsch_harq_pdu(
         PHY_VARS_eNB                           *eNB,
         int                                     UE_id,
@@ -70,7 +70,9 @@ void handle_ulsch_harq_pdu(
         nfapi_ul_config_ulsch_harq_information *harq_information,
         uint16_t                                frame,
         uint8_t                                 subframe);
-
+void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
+                          nfapi_dl_config_request_pdu_t *dl_config_pdu,
+                          uint8_t *sdu) ;
 void handle_ulsch_cqi_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe);
 
 void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_config_harq_information *harq_information);
@@ -82,4 +84,4 @@ void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu
 
 void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe);
 
-void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
+void schedule_response(Sched_Rsp_t *Sched_INFO, void *proc);
diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c
index 0b592b9c55ab60044c71ae1d053a6baf22e0285f..7033c5270138ee50f5527987b59c185d37e0738b 100644
--- a/openair1/SCHED/phy_procedures_lte_common.c
+++ b/openair1/SCHED/phy_procedures_lte_common.c
@@ -1085,73 +1085,3 @@ void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeri
 	
       }
 }
-
-// uint8_t eNB_id,uint8_t harq_pid, uint8_t UE_id,
-int16_t estimate_ue_tx_power(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs)
-{
-
-  /// The payload + CRC size in bits, "B"
-  uint32_t B;
-  /// Number of code segments
-  uint32_t C;
-  /// Number of "small" code segments
-  uint32_t Cminus;
-  /// Number of "large" code segments
-  uint32_t Cplus;
-  /// Number of bits in "small" code segments (<6144)
-  uint32_t Kminus;
-  /// Number of bits in "large" code segments (<6144)
-  uint32_t Kplus;
-  /// Total number of bits across all segments
-  uint32_t sumKr;
-  /// Number of "Filler" bits
-  uint32_t F;
-  // num resource elements
-  uint32_t num_re=0.0;
-  // num symbols
-  uint32_t num_symb=0.0;
-  /// effective spectral efficiency of the PUSCH
-  uint32_t MPR_x100=0;
-  /// beta_offset
-  uint16_t beta_offset_pusch_x8=8;
-  /// delta mcs
-  float delta_mcs=0.0;
-  /// bandwidth factor
-  float bw_factor=0.0;
-
-  B= tbs+24;
-  lte_segmentation(NULL,
-                   NULL,
-                   B,
-                   &C,
-                   &Cplus,
-                   &Cminus,
-                   &Kplus,
-                   &Kminus,
-                   &F);
-
-
-  sumKr = Cminus*Kminus + Cplus*Kplus;
-  num_symb = 12-(ncp<<1)-(use_srs==0?0:1);
-  num_re = num_symb * nb_rb * 12;
-
-  if (num_re == 0)
-    return(0);
-
-  MPR_x100 = 100*sumKr/num_re;
-
-  if (control_only == 1 )
-    beta_offset_pusch_x8=8; // fixme
-
-  //(beta_offset_pusch_x8=ue->ulsch[eNB_id]->harq_processes[harq_pid]->control_only == 1) ? ue->ulsch[eNB_id]->beta_offset_cqi_times8:8;
-
-  // if deltamcs_enabledm
-  delta_mcs = ((hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_x10((beta_offset_pusch_x8)>>3))/100.0);
-  bw_factor = (hundred_times_log10_NPRB[nb_rb-1]/100.0);
-#ifdef DEBUG_SEGMENTATION
-  printf("estimated ue tx power %d (num_re %d, sumKr %d, mpr_x100 %d, delta_mcs %f, bw_factor %f)\n",
-         (int16_t)ceil(delta_mcs + bw_factor), num_re, sumKr, MPR_x100, delta_mcs, bw_factor);
-#endif
-  return (int16_t)ceil(delta_mcs + bw_factor);
-
-}
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 38307a7b9ee8b477b6ec761219df0ba007eb3d17..973c921d2347d7c14f276af87255c83a067b5988 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -40,6 +40,7 @@
 #include "common/utils/LOG/log.h"
 #include <common/utils/system.h>
 #include "common/utils/LOG/vcd_signal_dumper.h"
+#include <nfapi/oai_integration/nfapi_pnf.h>
 
 #include "assertions.h"
 #include "msc.h"
@@ -51,22 +52,24 @@
 
 #define MBMS_NFAPI_SCHEDULER
 
-nfapi_ue_release_request_body_t release_rntis;
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
 
-int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor) {
+
+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;
   uint16_t beta_offset_pusch;
-  DevAssert( UE_id < NUMBER_OF_UE_MAX+1 );
+  DevAssert( ULSCH_id < NUMBER_OF_ULSCH_MAX+1 );
   DevAssert( harq_pid < 8 );
-  Nre = eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_initial *
-        eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12;
+  Nre = eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->Nsymb_initial *
+        eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->nb_rb*12;
   sumKr = 0;
 
-  for (r=0; r<eNB->ulsch[UE_id]->harq_processes[harq_pid]->C; r++) {
-    if (r<eNB->ulsch[UE_id]->harq_processes[harq_pid]->Cminus)
-      Kr = eNB->ulsch[UE_id]->harq_processes[harq_pid]->Kminus;
+  for (r=0; r<eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->C; r++) {
+    if (r<eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->Cminus)
+      Kr = eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->Kminus;
     else
-      Kr = eNB->ulsch[UE_id]->harq_processes[harq_pid]->Kplus;
+      Kr = eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->Kplus;
 
     sumKr += Kr;
   }
@@ -79,14 +82,14 @@ int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t
   // FK 20140908 sumKr is only set after the ulsch_encoding
   beta_offset_pusch = 8;
   //(eNB->ulsch[UE_id]->harq_processes[harq_pid]->control_only == 1) ? eNB->ulsch[UE_id]->beta_offset_cqi_times8:8;
-  DevAssert( UE_id < NUMBER_OF_UE_MAX );
+  DevAssert( ULSCH_id < NUMBER_OF_ULSCH_MAX );
   //#warning "This condition happens sometimes. Need more investigation" // navid
   //DevAssert( MPR_x100/6 < 100 );
 
   if (1==1) { //eNB->ul_power_control_dedicated[UE_id].deltaMCS_Enabled == 1) {
     // This is the formula from Section 5.1.1.1 in 36.213 10*log10(deltaIF_PUSCH = (2^(MPR*Ks)-1)*beta_offset_pusch)
     if (bw_factor == 1) {
-      uint8_t nb_rb = eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb;
+      uint8_t nb_rb = eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->nb_rb;
       return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_x10((beta_offset_pusch)>>3)) + hundred_times_log10_NPRB[nb_rb-1];
     } else
       return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_x10((beta_offset_pusch)>>3));
@@ -97,21 +100,21 @@ int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t
 
 
 int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid) {
-  int8_t UE_id;
+  int8_t ULSCH_id;
 
   if ((RC.eNB == NULL) || (module_idP > RC.nb_inst) || (CC_id > RC.nb_CC[module_idP])) {
     LOG_E(PHY,"get_UE_stats: No eNB found (or not allocated) for Mod_id %d,CC_id %d\n",module_idP,CC_id);
     return -1;
   }
 
-  UE_id = find_ulsch( rnti, RC.eNB[module_idP][CC_id],SEARCH_EXIST);
+  ULSCH_id = find_ulsch( rnti, RC.eNB[module_idP][CC_id],SEARCH_EXIST);
 
-  if (UE_id == -1) {
+  if (ULSCH_id == -1) {
     // not found
     return 0;
   }
 
-  return get_hundred_times_delta_IF_eNB( RC.eNB[module_idP][CC_id], UE_id, harq_pid, 0 );
+  return get_hundred_times_delta_IF_eNB( RC.eNB[module_idP][CC_id], ULSCH_id, harq_pid, 0 );
 }
 
 int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
@@ -499,9 +502,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
                            int do_meas) {
   int frame=proc->frame_tx;
   int subframe=proc->subframe_tx;
-  uint32_t i,aa;
   uint8_t harq_pid;
-  int16_t UE_id=0;
   uint8_t num_pdcch_symbols=0;
   uint8_t num_dci=0;
   uint8_t         num_mdci = 0;
@@ -516,12 +517,15 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+(eNB->CC_id),1);
 
   if (do_meas==1) start_meas(&eNB->phy_proc_tx);
-
   if (do_meas==1) start_meas(&eNB->dlsch_common_and_dci);
 
   // clear the transmit data array for the current subframe
-  for (aa = 0; aa < fp->nb_antenna_ports_eNB; aa++) {
-    memset (&eNB->common_vars.txdataF[aa][subframe * fp->ofdm_symbol_size * (fp->symbols_per_tti)], 0, fp->ofdm_symbol_size * (fp->symbols_per_tti) * sizeof (int32_t));
+  for (int aa = 0; aa < fp->nb_antenna_ports_eNB; aa++) {
+    if (eNB->use_DTX==0) 
+      memcpy(&eNB->common_vars.txdataF[aa][subframe * fp->ofdm_symbol_size * (fp->symbols_per_tti)],
+	     &eNB->subframe_mask[aa][subframe*fp->ofdm_symbol_size*fp->symbols_per_tti],
+	     fp->ofdm_symbol_size * (fp->symbols_per_tti) * sizeof (int32_t));
+    else memset(&eNB->common_vars.txdataF[aa][subframe * fp->ofdm_symbol_size * (fp->symbols_per_tti)], 0, fp->ofdm_symbol_size * (fp->symbols_per_tti) * sizeof (int32_t));
   }
 
   if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
@@ -556,7 +560,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   ul_frame = pdcch_alloc2ul_frame (fp, frame, subframe);
 
   // clear previous allocation information for all UEs
-  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
+  for (volatile int i = 0; i < NUMBER_OF_DLSCH_MAX; i++) {
     if (eNB->dlsch[i][0])
       eNB->dlsch[i][0]->subframe_tx[subframe] = 0;
   }
@@ -565,7 +569,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   //if ((ul_subframe < 10)&&
   //    (subframe_select(fp,ul_subframe)==SF_UL)) { // This means that there is a potential UL subframe that will be scheduled here
   if (ul_subframe < 10) { // This means that there is a potential UL subframe that will be scheduled here
-    for (i=0; i<NUMBER_OF_UE_MAX; i++) {
+    for (volatile int i=0; i<NUMBER_OF_DLSCH_MAX; i++) {
       if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type >0) harq_pid = 0;
 
       else
@@ -651,9 +655,9 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   // Now scan UE specific DLSCH
   LTE_eNB_DLSCH_t *dlsch0,*dlsch1;
 
-  for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
-    dlsch0 = eNB->dlsch[(uint8_t)UE_id][0];
-    dlsch1 = eNB->dlsch[(uint8_t)UE_id][1];
+  for (int DLSCH_id=0; DLSCH_id<NUMBER_OF_DLSCH_MAX; DLSCH_id++) {
+    dlsch0 = eNB->dlsch[(uint8_t)DLSCH_id][0];
+    dlsch1 = eNB->dlsch[(uint8_t)DLSCH_id][1];
 
     if ((dlsch0)&&(dlsch0->rnti>0)&&
 #ifdef PHY_TX_THREAD
@@ -663,12 +667,13 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 #endif
        ) {
       // get harq_pid
-      harq_pid = dlsch0->harq_ids[frame%2][subframe];
+        harq_pid = dlsch0->harq_ids[frame%2][subframe];
       //AssertFatal(harq_pid>=0,"harq_pid is negative\n");
 
       if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) {
+
         if (dlsch0->ue_type==0)
-          LOG_E(PHY,"harq_pid:%d corrupt must be 0-7 UE_id:%d frame:%d subframe:%d rnti:%x [ %1d.%1d.%1d.%1d.%1d.%1d.%1d.%1d\n", harq_pid,UE_id,frame,subframe,dlsch0->rnti,
+          LOG_E(PHY,"harq_pid:%d corrupt must be 0-7 DLSCH_id:%d frame:%d subframe:%d rnti:%x [ %1d.%1d.%1d.%1d.%1d.%1d.%1d.%1d\n", harq_pid,DLSCH_id,frame,subframe,dlsch0->rnti,
                 dlsch0->harq_ids[frame%2][0],
                 dlsch0->harq_ids[frame%2][1],
                 dlsch0->harq_ids[frame%2][2],
@@ -682,7 +687,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
                              proc,
                              harq_pid,
                              dlsch0,
-                             &eNB->UE_stats[(uint32_t)UE_id])) {
+                             &eNB->UE_stats[(uint32_t)DLSCH_id])) {
           // if we generate dlsch, we must generate pdsch
           pdsch_procedures(eNB,
                            proc,
@@ -717,6 +722,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   if (do_meas==1) stop_meas(&eNB->phy_proc_tx);
 }
 
+/* This has to be updated with FAPI structures*/
 
 void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
@@ -728,7 +734,7 @@ void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
     // Do SRS processing
     // check if there is SRS and we have to use shortened format
     // TODO: check for exceptions in transmission of SRS together with ACK/NACK
-    for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
+    for (i = 0; i < NUMBER_OF_SRS_MAX; i++) {
       if (eNB->soundingrs_ul_config_dedicated[i].active == 1) {
         if (lte_srs_channel_estimation (fp, &eNB->common_vars, &eNB->srs_vars[i], &eNB->soundingrs_ul_config_dedicated[i], subframe, 0 /*eNB_id */ )) {
           LOG_E (PHY, "problem processing SRS\n");
@@ -793,7 +799,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
 
   calc_pucch_1x_interference(eNB, frame, subframe, 0);
   
-  for (int i = 0; i < NUMBER_OF_UCI_VARS_MAX; i++) {
+  for (int i = 0; i < NUMBER_OF_UCI_MAX; i++) {
     uci = &(eNB->uci_vars[i]);
 
     if ((uci->active == 1) && (uci->frame == frame) && (uci->subframe == subframe)) {
@@ -850,7 +856,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
           int pucch1_thres = (uci->ue_type == 0) ? eNB->pucch1_DTX_threshold : eNB->pucch1_DTX_threshold_emtc[0];
           metric_SR = rx_pucch(eNB,
                                uci->pucch_fmt,
-                               uci->ue_id,
+                               i,//uci->ue_id,
                                uci->n_pucch_1_0_sr[0],
                                0, // n2_pucch
                                uci->srs_active, // shortened format
@@ -1275,7 +1281,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
 
 #ifdef DEBUG_PHY_PROC
             LOG_D (PHY, "[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, (%d,%d)\n", eNB->Mod_id,
-                   eNB->dlsch[UE_id][0]->rnti, frame, subframe, metric0, metric1, pucch_b0b1[0], pucch_b0b1[1]);
+                   eNB->dlsch[DLSCH_id][0]->rnti, frame, subframe, metric0, metric1, pucch_b0b1[0], pucch_b0b1[1]);
 #endif
           }
 
@@ -1298,7 +1304,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
           }
       }
     } // end if ((uci->active == 1) && (uci->frame == frame) && (uci->subframe == subframe)) {
-  } // end loop for (int i = 0; i < NUMBER_OF_UE_MAX; i++) {
+  } // end loop for (int i = 0; i < NUMBER_OF_UCI_MAX; i++) {
 }
 
 void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) {
@@ -1325,7 +1331,7 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) {
       int nb=abortTpool(proc->threadPool, req->key);
       nb+=abortNotifiedFIFO(proc->respDecode, req->key);
       proc->nbDecode-=nb;
-      LOG_I(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb);
+      LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb);
       AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
 		  ulsch_harq->processedSegments, nb, rdata->nbSegments);
       ulsch_harq->processedSegments=rdata->nbSegments;
@@ -1381,6 +1387,15 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) {
 	fill_rx_indication(eNB,i,rdata->frame,rdata->subframe);  // indicate SDU to MAC
 	ulsch_harq->status = SCH_IDLE;
 	ulsch->harq_mask &= ~(1 << rdata->harq_pid);
+	for (int j=0;j<NUMBER_OF_ULSCH_MAX;j++) 
+           if (eNB->ulsch_stats[j].rnti == ulsch->rnti) {
+              eNB->ulsch_stats[j].total_bytes_rx+=ulsch_harq->TBS;
+              for (int aa=0;aa<eNB->frame_parms.nb_antennas_rx;aa++) {
+                eNB->ulsch_stats[j].ulsch_power[aa] = dB_fixed_x10(eNB->pusch_vars[rdata->UEid]->ulsch_power[aa]);
+                eNB->ulsch_stats[j].ulsch_noise_power[aa] = dB_fixed_x10(eNB->pusch_vars[rdata->UEid]->ulsch_noise_power[aa]); 
+              }
+              break;
+           }
         T (T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(rdata->frame), T_INT(rdata->subframe), T_INT(ulsch->rnti),
            T_INT(rdata->harq_pid));
       }  // ulsch not in error
@@ -1401,8 +1416,9 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
   const int frame    = proc->frame_rx;
   uint32_t harq_pid0 = subframe2harq_pid(&eNB->frame_parms,frame,subframe);
 
-  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
+  for (i = 0; i < NUMBER_OF_ULSCH_MAX; i++) {
     ulsch = eNB->ulsch[i];
+    if (!ulsch) continue; 
 
     if (ulsch->ue_type > 0) harq_pid = 0;
     else harq_pid=harq_pid0;
@@ -1411,10 +1427,9 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
 
     if (ulsch->rnti>0) LOG_D(PHY,"eNB->ulsch[%d]->harq_processes[harq_pid:%d] SFN/SF:%04d%d: PUSCH procedures, UE %d/%x ulsch_harq[status:%d SFN/SF:%04d%d handled:%d]\n",
                                i, harq_pid, frame,subframe,i,ulsch->rnti,
-                               ulsch_harq->status, ulsch_harq->frame, ulsch_harq->subframe, ulsch_harq->handled);
+                              ulsch_harq->status, ulsch_harq->frame, ulsch_harq->subframe, ulsch_harq->handled);
 
-    if ((ulsch) &&
-        (ulsch->rnti>0) &&
+    if ((ulsch->rnti>0) &&
         (ulsch_harq->status == ACTIVE) &&
         ((ulsch_harq->frame == frame)	    || (ulsch_harq->repetition_number >1) ) &&
         ((ulsch_harq->subframe == subframe) || (ulsch_harq->repetition_number >1) ) &&
@@ -1459,6 +1474,17 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
                            ulsch_harq->V_UL_DAI,
                            ulsch_harq->nb_rb>20 ? 1 : 0);
       stop_meas(&eNB->ulsch_decoding_stats);
+/*
+      int ulsch_id=-1;
+      for  (ulsch_id=0;ulsch_id<NUMBER_OF_ULSCH_MAX;ulsch_id++)
+         if (ulsch->rnti == eNB->ulsch_stats[ulsch_id].rnti) break;
+      AssertFatal(ulsch_id>=0,"no ulsch_id found\n");
+
+      if (eNB->ulsch_stats[ulsch_id].round_trials[0]>100) {
+         dump_ulsch(eNB,frame,subframe,i,ulsch_harq->round);
+         AssertFatal(1==0,"exiting\n");
+      }
+*/
     }
     else if ((ulsch) &&
              (ulsch->rnti>0) &&
@@ -1472,7 +1498,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
       ulsch->harq_mask &= ~(1 << harq_pid);
       LOG_W (PHY, "Removing stale ULSCH config for UE %x harq_pid %d (harq_mask is now 0x%2.2x)\n", ulsch->rnti, harq_pid, ulsch->harq_mask);
     }
-  }   //   for (i=0; i<NUMBER_OF_UE_MAX; i++)
+  }   //   for (i=0; i<NUMBER_OF_ULSCH_MAX; i++)
   
   while (proc->nbDecode > 0) {
     notifiedFIFO_elt_t *req=pullTpool(proc->respDecode, proc->threadPool);
@@ -1537,7 +1563,7 @@ void kill_te_thread(PHY_VARS_eNB *eNB) {
 }
 
 void fill_rx_indication(PHY_VARS_eNB *eNB,
-                        int UE_id,
+                        int ULSCH_id,
                         int frame,
                         int subframe) {
   nfapi_rx_indication_pdu_t *pdu;
@@ -1545,7 +1571,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
   int             sync_pos;
   uint32_t        harq_pid;
 
-  if (eNB->ulsch[UE_id]->ue_type > 0) harq_pid = 0;
+  if (eNB->ulsch[ULSCH_id]->ue_type > 0) harq_pid = 0;
   else {
     harq_pid = subframe2harq_pid (&eNB->frame_parms,
                                   frame, subframe);
@@ -1555,19 +1581,22 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
   eNB->UL_INFO.rx_ind.sfn_sf                    = frame<<4| subframe;
   eNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG;
   pdu                                    = &eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus];
-  //  pdu->rx_ue_information.handle          = eNB->ulsch[UE_id]->handle;
+  //  pdu->rx_ue_information.handle          = eNB->ulsch[ULSCH_id]->handle;
   pdu->rx_ue_information.tl.tag          = NFAPI_RX_UE_INFORMATION_TAG;
-  pdu->rx_ue_information.rnti            = eNB->ulsch[UE_id]->rnti;
+  pdu->rx_ue_information.rnti            = eNB->ulsch[ULSCH_id]->rnti;
   pdu->rx_indication_rel8.tl.tag         = NFAPI_RX_INDICATION_REL8_TAG;
-  pdu->rx_indication_rel8.length         = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3;
+  pdu->rx_indication_rel8.length         = eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->TBS>>3;
   pdu->rx_indication_rel8.offset         = 1;   // DJP - I dont understand - but broken unless 1 ????  0;  // filled in at the end of the UL_INFO formation
-  pdu->data                              = eNB->ulsch[UE_id]->harq_processes[harq_pid]->decodedBytes;
+  pdu->data                              = eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->decodedBytes;
   // estimate timing advance for MAC
-  sync_pos                               = lte_est_timing_advance_pusch(&eNB->frame_parms, eNB->pusch_vars[UE_id]->drs_ch_estimates_time);
-  timing_advance_update                  = sync_pos; // - eNB->frame_parms.nb_prefix_samples/4; //to check
-
-  //  if (timing_advance_update > 10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);}
-  //  if (timing_advance_update < -10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);}
+  sync_pos                               = lte_est_timing_advance_pusch(&eNB->frame_parms, eNB->pusch_vars[ULSCH_id]->drs_ch_estimates_time);
+  timing_advance_update                  = sync_pos; 
+
+  for (int i=0;i<NUMBER_OF_SCH_STATS_MAX;i++) 
+      if (eNB->ulsch_stats[i].rnti == eNB->ulsch[ULSCH_id]->rnti) 
+         eNB->ulsch_stats[i].timing_offset = sync_pos;
+  //  if (timing_advance_update > 10) { dump_ulsch(eNB,frame,subframe,ULSCH_id); exit(-1);}
+  //  if (timing_advance_update < -10) { dump_ulsch(eNB,frame,subframe,ULSCH_id); exit(-1);}
   switch (eNB->frame_parms.N_RB_DL) {
     case 6:                      /* nothing to do */
       break;
@@ -1607,7 +1636,13 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
 
   pdu->rx_indication_rel8.timing_advance = timing_advance_update;
   // estimate UL_CQI for MAC 
-  int SNRtimes10 = dB_fixed_x10(eNB->pusch_vars[UE_id]->ulsch_power[0] + ((eNB->frame_parms.nb_antennas_rx>1) ?eNB->pusch_vars[UE_id]->ulsch_power[1] : 0 ) ) - dB_fixed_x10(eNB->pusch_vars[UE_id]->ulsch_interference_power[0]+((eNB->frame_parms.nb_antennas_rx>1) ?eNB->pusch_vars[UE_id]->ulsch_interference_power[1] : 0 ) );
+  int total_power=0, avg_noise_power=0;  
+  for (int i=0;i<eNB->frame_parms.nb_antennas_rx;i++) {
+     total_power+=(eNB->pusch_vars[ULSCH_id]->ulsch_power[i]);
+     avg_noise_power+=(eNB->pusch_vars[ULSCH_id]->ulsch_noise_power[i])/eNB->frame_parms.nb_antennas_rx;
+  }
+  int SNRtimes10 = dB_fixed_x10(total_power) - 
+                   dB_fixed_x10(avg_noise_power);
 
   if (SNRtimes10 < -640)
     pdu->rx_indication_rel8.ul_cqi = 0;
@@ -1616,9 +1651,11 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
   else
     pdu->rx_indication_rel8.ul_cqi = (640 + SNRtimes10) / 5;
 
-  LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d,%d), timing_advance %d (update %d)\n",
-        harq_pid,frame,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,eNB->measurements.n0_subband_power_avg_dB,pdu->rx_indication_rel8.timing_advance,
-        timing_advance_update);
+  LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d,%d,%d), timing_advance %d (update %d,sync_pos %d)\n",
+        harq_pid,frame,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,dB_fixed_x10(total_power),dB_fixed_x10(avg_noise_power),pdu->rx_indication_rel8.timing_advance,timing_advance_update,sync_pos);
+  for (int i=0;i<eNB->frame_parms.nb_antennas_rx;i++)
+	LOG_D(PHY,"antenna %d: ulsch_power %d, noise_power %d\n",i,dB_fixed_x10(eNB->pusch_vars[ULSCH_id]->ulsch_power[i]),dB_fixed_x10(eNB->pusch_vars[ULSCH_id]->ulsch_noise_power[i]));
+
   eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++;
   eNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | subframe;
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
@@ -1629,7 +1666,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
  * Release the harq process if its round is >= 'after_rounds'
  */
 static void do_release_harq(PHY_VARS_eNB *eNB,
-                            int UE_id,
+                            int DLSCH_id,
                             int tb,
                             uint16_t frame,
                             uint8_t subframe,
@@ -1644,10 +1681,10 @@ static void do_release_harq(PHY_VARS_eNB *eNB,
   int harq_pid;
   int subframe_tx;
   int frame_tx;
-  AssertFatal(UE_id != -1, "No existing dlsch context\n");
-  AssertFatal(UE_id < NUMBER_OF_UE_MAX, "Returned UE_id %d >= %d (NUMBER_OF_UE_MAX)\n", UE_id, NUMBER_OF_UE_MAX);
-  dlsch0 = eNB->dlsch[UE_id][0];
-  dlsch1 = eNB->dlsch[UE_id][1];
+  AssertFatal(DLSCH_id != -1, "No existing dlsch context\n");
+  AssertFatal(DLSCH_id < NUMBER_OF_DLSCH_MAX, "Returned DLSCH_id %d >= %d (NUMBER_OF_DLSCH_MAX)\n", DLSCH_id, NUMBER_OF_DLSCH_MAX);
+  dlsch0 = eNB->dlsch[DLSCH_id][0];
+  dlsch1 = eNB->dlsch[DLSCH_id][1];
 
   if (eNB->frame_parms.frame_type == FDD) {
     subframe_tx = (subframe + 6) % 10;
@@ -1746,13 +1783,13 @@ static void do_release_harq(PHY_VARS_eNB *eNB,
   } // end if TDD
 }
 
-static void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int is_ack) {
+static void release_harq(PHY_VARS_eNB *eNB,int DLSCH_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int is_ack) {
   /*
    * Maximum number of DL transmissions = 4.
    * TODO: get the value from configuration.
    * If is_ack is true then we release immediately. The value -1 can be used for that.
    */
-  do_release_harq(eNB, UE_id, tb, frame, subframe, mask, is_ack ? -1 : 4);
+  do_release_harq(eNB, DLSCH_id, tb, frame, subframe, mask, is_ack ? -1 : 4);
 }
 
 int getM(PHY_VARS_eNB *eNB,int frame,int subframe) {
@@ -1832,14 +1869,14 @@ void fill_ulsch_cqi_indication (PHY_VARS_eNB *eNB, uint16_t frame, uint8_t subfr
 }
 
 void fill_ulsch_harq_indication (PHY_VARS_eNB *eNB, LTE_UL_eNB_HARQ_t *ulsch_harq, uint16_t rnti, int frame, int subframe, int bundling) {
-  int UE_id = find_dlsch(rnti,eNB,SEARCH_EXIST);
+  int DLSCH_id = find_dlsch(rnti,eNB,SEARCH_EXIST);
 
-  if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ) {
-    LOG_E(PHY,"illegal UE_id found!!! rnti %04x UE_id %d\n",rnti,UE_id);
+  if( (DLSCH_id<0) || (DLSCH_id>=NUMBER_OF_DLSCH_MAX) ) {
+    LOG_E(PHY,"illegal DLSCH_id found!!! rnti %04x DLSCH_id %d\n",rnti,DLSCH_id);
     return;
   }
 
-  //AssertFatal(UE_id>=0,"UE_id doesn't exist\n");
+  //AssertFatal(DLSCH_id>=0,"DLSCH_id doesn't exist\n");
   pthread_mutex_lock(&eNB->UL_INFO_mutex);
   nfapi_harq_indication_pdu_t *pdu =   &eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs];
   int M;
@@ -1861,7 +1898,7 @@ void fill_ulsch_harq_indication (PHY_VARS_eNB *eNB, LTE_UL_eNB_HARQ_t *ulsch_har
       AssertFatal (ulsch_harq->o_ACK[i] == 0 || ulsch_harq->o_ACK[i] == 1, "harq_ack[%d] is %d, should be 1,2 or 4\n", i, ulsch_harq->o_ACK[i]);
       pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 2 - ulsch_harq->o_ACK[i];
       // release DLSCH if needed
-      release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
+      release_harq(eNB,DLSCH_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
     }
   } else {                      // TDD
     M = ul_ACK_subframe2_M (&eNB->frame_parms, subframe);
@@ -1877,14 +1914,14 @@ void fill_ulsch_harq_indication (PHY_VARS_eNB *eNB, LTE_UL_eNB_HARQ_t *ulsch_har
        * We have to release the proper HARQ in case of ACK or NACK if max retransmission reached.
        * Basically, call release_harq with 1 as last argument when ACK and 0 when NACK.
        */
-      release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
+      release_harq(eNB,DLSCH_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
 
-      if      (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
-      else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
+      if      (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,DLSCH_id,0,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
+      else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,DLSCH_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
       else if (M>1 && ulsch_harq->o_ACK[i] == 1) {
         // spatial bundling
-        release_harq(eNB,UE_id,0,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1);
-        release_harq(eNB,UE_id,1,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1);
+        release_harq(eNB,DLSCH_id,0,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1);
+        release_harq(eNB,DLSCH_id,1,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1);
       }
     }
   }
@@ -1900,10 +1937,10 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
     return;
   }
   
-  int UE_id=find_dlsch(uci->rnti,eNB,SEARCH_EXIST);
+  int DLSCH_id=find_dlsch(uci->rnti,eNB,SEARCH_EXIST);
 
-  //AssertFatal(UE_id>=0,"UE_id doesn't exist rnti:%x\n", uci->rnti);
-  if (UE_id < 0) {
+  //AssertFatal(DLSCH_id>=0,"DLSCH_id doesn't exist rnti:%x\n", uci->rnti);
+  if (DLSCH_id < 0) {
     LOG_E(PHY,"SFN/SF:%04d%d Unable to find rnti:%x do not send HARQ\n", frame, subframe, uci->rnti);
     return;
   }
@@ -1943,7 +1980,7 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
       AssertFatal (harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n", harq_ack[0]);
       pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0];
       // release DLSCH if needed
-      release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
+      release_harq(eNB,DLSCH_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
     } else if (uci->pucch_fmt == pucch_format1b) {
       pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG;
       pdu->harq_indication_fdd_rel13.mode = 0;
@@ -1953,8 +1990,8 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
       pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0];
       pdu->harq_indication_fdd_rel13.harq_tb_n[1] = harq_ack[1];
       // release DLSCH if needed
-      release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
-      release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
+      release_harq(eNB,DLSCH_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
+      release_harq(eNB,DLSCH_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
     } else AssertFatal(1==0,"only format 1a/b for now, received %d\n",uci->pucch_fmt);
   } else { // TDD
     AssertFatal (tdd_mapping_mode == 0 || tdd_mapping_mode == 1 || tdd_mapping_mode == 2, "Illegal tdd_mapping_mode %d\n", tdd_mapping_mode);
@@ -1972,7 +2009,7 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
           AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
           pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0];
           // release all bundled DLSCH if needed
-          release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
+          release_harq(eNB,DLSCH_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
         } else if (uci->pucch_fmt == pucch_format1b) {
           pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2;
           AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]);
@@ -1981,8 +2018,8 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
           pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0];
           pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = harq_ack[1];
           // release all DLSCH if needed
-          release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
-          release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
+          release_harq(eNB,DLSCH_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
+          release_harq(eNB,DLSCH_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
         }
 
         break;
@@ -1996,7 +2033,7 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
           AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
           pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
           // release all DLSCH if needed
-          release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
+          release_harq(eNB,DLSCH_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
         } else if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1b) {
           pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
           pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2;
@@ -2005,8 +2042,8 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
           pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
           pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1];
           // release all DLSCH if needed
-          release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
-          release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
+          release_harq(eNB,DLSCH_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
+          release_harq(eNB,DLSCH_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
         } else { // num_pucch_resources (M) > 1
           pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
           pdu->harq_indication_tdd_rel13.number_of_ack_nack = uci->num_pucch_resources;
@@ -2018,8 +2055,8 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
           if (uci->num_pucch_resources == 4)  pdu->harq_indication_tdd_rel13.harq_data[3].multiplex.value_0 = harq_ack[3];
 
           // spatial-bundling in this case so release both HARQ if necessary
-          release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */);
-          release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */);
+          release_harq(eNB,DLSCH_id,0,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */);
+          release_harq(eNB,DLSCH_id,1,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */);
         }
 
         break;
@@ -2043,8 +2080,8 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
             if (uci->num_pucch_resources == 1 || uci->num_pucch_resources == 4 ||
                 tdd_config5_sf2scheds == 1 || tdd_config5_sf2scheds == 4 || tdd_config5_sf2scheds == 7) {
               pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1;
-              release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
-              release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
+              release_harq(eNB,DLSCH_id,0,frame,subframe,0xffff, 1);
+              release_harq(eNB,DLSCH_id,1,frame,subframe,0xffff, 1);
             } else {
               pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0;
             }
@@ -2055,8 +2092,8 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
             if (uci->num_pucch_resources == 2 || tdd_config5_sf2scheds == 2 ||
                 tdd_config5_sf2scheds == 5 || tdd_config5_sf2scheds == 8) {
               pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1;
-              release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
-              release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
+              release_harq(eNB,DLSCH_id,0,frame,subframe,0xffff, 1);
+              release_harq(eNB,DLSCH_id,1,frame,subframe,0xffff, 1);
             } else {
               pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0;
             }
@@ -2067,8 +2104,8 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
             if (uci->num_pucch_resources == 3 || tdd_config5_sf2scheds == 3 ||
                 tdd_config5_sf2scheds == 6 || tdd_config5_sf2scheds == 9) {
               pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1;
-              release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
-              release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
+              release_harq(eNB,DLSCH_id,0,frame,subframe,0xffff, 1);
+              release_harq(eNB,DLSCH_id,1,frame,subframe,0xffff, 1);
             } else {
               pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0;
             }
@@ -2085,7 +2122,7 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
 }
 
-void fill_crc_indication (PHY_VARS_eNB *eNB, int UE_id, int frame, int subframe, uint8_t crc_flag) {
+void fill_crc_indication (PHY_VARS_eNB *eNB, int ULSCH_id, int frame, int subframe, uint8_t crc_flag) {
   pthread_mutex_lock(&eNB->UL_INFO_mutex);
   nfapi_crc_indication_pdu_t *pdu =   &eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs];
   eNB->UL_INFO.crc_ind.sfn_sf                         = frame<<4 | subframe;
@@ -2094,7 +2131,7 @@ void fill_crc_indication (PHY_VARS_eNB *eNB, int UE_id, int frame, int subframe,
   pdu->instance_length = 0;     // don't know what to do with this
   //  pdu->rx_ue_information.handle                       = handle;
   pdu->rx_ue_information.tl.tag                       = NFAPI_RX_UE_INFORMATION_TAG;
-  pdu->rx_ue_information.rnti                         = eNB->ulsch[UE_id]->rnti;
+  pdu->rx_ue_information.rnti                         = eNB->ulsch[ULSCH_id]->rnti;
   pdu->crc_indication_rel8.tl.tag                     = NFAPI_CRC_INDICATION_REL8_TAG;
   pdu->crc_indication_rel8.crc_flag                   = crc_flag;
   eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs++;
@@ -2133,20 +2170,24 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
   }
 
   lte_eNB_I0_measurements (eNB, subframe, 0, eNB->first_run_I0_measurements);
-  int min_I0=1000,max_I0=0;
-  int amin=0,amax=0;
-  if ((frame==0) && (subframe==3)) {
-    for (int i=0; i<eNB->frame_parms.N_RB_UL; i++) {
-      if (i==(eNB->frame_parms.N_RB_UL>>1) - 1) i+=2;
-
-      if (eNB->measurements.n0_subband_power_tot_dB[i]<min_I0) {min_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; amin=i;}
-
-      if (eNB->measurements.n0_subband_power_tot_dB[i]>max_I0) {max_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; amax=i;}
-    }
 
-    LOG_I (PHY, "max_I0 %d (rb %d), min_I0 %d (rb %d), avg I0 %d\n", max_I0, amax, min_I0, amin, eNB->measurements.n0_subband_power_avg_dB);
+  // clear unused statistics after 2 seconds
+  for (int i=0;i<NUMBER_OF_SCH_STATS_MAX;i++) {
+     if (eNB->ulsch_stats[i].frame <= frame) {
+         if ((eNB->ulsch_stats[i].frame + 200) < frame) memset(&eNB->ulsch_stats[i],0,sizeof(eNB->ulsch_stats[i]));
+     }
+     else {
+         if (eNB->ulsch_stats[i].frame + 200 < (frame+1024)) memset(&eNB->ulsch_stats[i],0,sizeof(eNB->ulsch_stats[i]));
+     }
+     if (eNB->uci_stats[i].frame <= frame) {
+         if ((eNB->uci_stats[i].frame + 200) < frame) memset(&eNB->uci_stats[i],0,sizeof(eNB->uci_stats[i]));
+     }
+     else {
+         if (eNB->uci_stats[i].frame + 200 < (frame+1024)) memset(&eNB->uci_stats[i],0,sizeof(eNB->uci_stats[i]));
+     }
   }
 
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 );
 }
 
@@ -2163,13 +2204,7 @@ void release_rnti_of_phy(module_id_t mod_id) {
       eNB_PHY = RC.eNB[mod_id][CC_id];
       rnti = release_rntis.ue_release_request_TLVs_list[i].rnti;
 
-      for (j=0; j<NUMBER_OF_UE_MAX; j++) {
-        ulsch = eNB_PHY->ulsch[j];
-
-        if((ulsch != NULL) && (ulsch->rnti == rnti)) {
-          LOG_I(PHY, "clean_eNb_ulsch ulsch[%d] UE %x\n", j, rnti);
-          clean_eNb_ulsch(ulsch);
-        }
+      for (j=0; j<NUMBER_OF_DLSCH_MAX; j++) {
 
         dlsch = eNB_PHY->dlsch[j][0];
 
@@ -2179,14 +2214,18 @@ void release_rnti_of_phy(module_id_t mod_id) {
         }
       }
 
-      ulsch = eNB_PHY->ulsch[j];
+      for (j=0;j<NUMBER_OF_ULSCH_MAX; j++) {
+        ulsch = eNB_PHY->ulsch[j];
 
-      if((ulsch != NULL) && (ulsch->rnti == rnti)) {
-        LOG_I(PHY, "clean_eNb_ulsch ulsch[%d] UE %x\n", j, rnti);
-        clean_eNb_ulsch(ulsch);
+        if((ulsch != NULL) && (ulsch->rnti == rnti)) {
+          LOG_I(PHY, "clean_eNb_ulsch ulsch[%d] UE %x\n", j, rnti);
+          clean_eNb_ulsch(ulsch);
+          for (j=0;j<NUMBER_OF_ULSCH_MAX;j++)
+             if (eNB_PHY->ulsch_stats[j].rnti == rnti) {eNB_PHY->ulsch_stats[j].rnti=0; break;}
+        }
       }
 
-      for(j=0; j<NUMBER_OF_UCI_VARS_MAX; j++) {
+      for(j=0; j<NUMBER_OF_UCI_MAX; j++) {
         if(eNB_PHY->uci_vars[j].rnti == rnti) {
           LOG_I(PHY, "clean eNb uci_vars[%d] UE %x \n",j, rnti);
           memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI));
diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c
index b99bb2ee7d742155f5384a47b3835383abbecc07..4d0fe428e84de72f10712063e27cb673f46c77e3 100644
--- a/openair1/SCHED/prach_procedures.c
+++ b/openair1/SCHED/prach_procedures.c
@@ -31,8 +31,6 @@
  */
 
 #include "PHY/defs_eNB.h"
-#include "PHY/phy_extern.h"
-#include "SCHED/sched_eNB.h"
 #include "nfapi_interface.h"
 #include "fapi_l1.h"
 #include "nfapi_pnf.h"
@@ -46,7 +44,6 @@
 
 #include <time.h>
 
-#include "intertask_interface.h"
 
 
 extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
@@ -188,7 +185,7 @@ void prach_procedures(PHY_VARS_eNB *eNB,
     else {
       eNB->measurements.prach_I0 = ((eNB->measurements.prach_I0*900)>>10) + ((avg_preamble_energy[0]*124)>>10);
 
-      if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",eNB->measurements.prach_I0/10,eNB->measurements.prach_I0%10);
+      if (frame==0) LOG_D(PHY,"prach_I0 = %d.%d dB\n",eNB->measurements.prach_I0/10,eNB->measurements.prach_I0%10);
 
       if (eNB->prach_energy_counter < 100) eNB->prach_energy_counter++;
     }
diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c
index 70399f0a23a14ab21fb6f1df72f8b201d551fc1f..15eba7b5bc4f59bfacbd13b83d6383c5451680e9 100644
--- a/openair1/SCHED/ru_procedures.c
+++ b/openair1/SCHED/ru_procedures.c
@@ -54,7 +54,6 @@
 
 
 #include "PHY/defs_eNB.h"
-#include "PHY/phy_extern.h"
 #include "SCHED/sched_eNB.h"
 #include "PHY/MODULATION/modulation_eNB.h"
 #include "PHY/LTE_TRANSPORT/if4_tools.h"
@@ -140,27 +139,26 @@ void feptx0(RU_t *ru,
 	      int num_symb = 7;
 
 	      if (subframe_select(fp,subframe) == SF_S)
-             num_symb = fp->dl_symbols_in_S_subframe+1;
+                num_symb = fp->dl_symbols_in_S_subframe+1;
 
-	      if (ru->generate_dmrs_sync == 1 && slot == 0 && subframe == 1 && aa==0) {
+	      if (ru->generate_dmrs_sync == 1 && slot == 2 && aa==0) {
             //int32_t dmrs[ru->frame_parms.ofdm_symbol_size*14] __attribute__((aligned(32)));
             //int32_t *dmrsp[2] ={dmrs,NULL}; //{&dmrs[(3-ru->frame_parms.Ncp)*ru->frame_parms.ofdm_symbol_size],NULL};
-
-            generate_drs_pusch((PHY_VARS_UE *)NULL,
-                               (UE_rxtx_proc_t*)NULL,
-                               fp,
-                               ru->common.txdataF_BF,
-                               0,
-                               AMP,
-                               0,
-                               0,
-                               fp->N_RB_DL,
-                               aa);
+                  generate_drs_pusch((PHY_VARS_UE *)NULL,
+                                     (UE_rxtx_proc_t*)NULL,
+                                     fp,
+                                     ru->common.txdataF_BF,
+                                     0,
+                                     AMP,
+                                     0,
+                                     0,
+                                     fp->N_RB_DL,
+                                     aa);
 	      } 
-          normal_prefix_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF],
-                            (int*)&ru->common.txdata[aa][slot_offset],
-                            num_symb,
-                            fp);
+              normal_prefix_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF],
+                                (int*)&ru->common.txdata[aa][slot_offset],
+                                num_symb,
+                                fp);
       }
     }
 
@@ -474,15 +472,16 @@ void feptx_prec(RU_t *ru,
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+ru->idx , 1);
 
     for (aa=0;aa<ru->nb_tx;aa++) {
-      memset(ru->common.txdataF_BF[aa],0,sizeof(int32_t)*fp->ofdm_symbol_size*fp->symbols_per_tti);
-      for (int p=0;p<NB_ANTENNA_PORTS_ENB;p++) {
-    	if (ru->do_precoding == 0) {
-	      if (p==0)
-	        memcpy((void*)ru->common.txdataF_BF[aa],
-	        (void*)&eNB->common_vars.txdataF[aa][subframe*fp->symbols_per_tti*fp->ofdm_symbol_size],
-	        sizeof(int32_t)*fp->ofdm_symbol_size*fp->symbols_per_tti);
-    	} else {
-    	  if (p<fp->nb_antenna_ports_eNB) {
+      if (ru->do_precoding == 0) {
+          memcpy((void*)ru->common.txdataF_BF[aa],
+                 (void*)&eNB->common_vars.txdataF[aa%fp->nb_antenna_ports_eNB][subframe*fp->symbols_per_tti*fp->ofdm_symbol_size],
+                 sizeof(int32_t)*fp->ofdm_symbol_size*fp->symbols_per_tti);
+
+      }
+      else {
+         memset(ru->common.txdataF_BF[aa],0,sizeof(int32_t)*fp->ofdm_symbol_size*fp->symbols_per_tti);
+         for (int p=0;p<NB_ANTENNA_PORTS_ENB;p++) {
+    	    if (p<fp->nb_antenna_ports_eNB) {
 	        // For the moment this does nothing different than below, except ignore antenna ports 5,7,8.
 	        for (l=0;l<pdcch_vars->num_pdcch_symbols;l++)
 	          beam_precoding(eNB->common_vars.txdataF,
@@ -494,10 +493,10 @@ void feptx_prec(RU_t *ru,
                              aa,
                              p,
                              eNB->Mod_id);
-	      } //if (p<fp->nb_antenna_ports_eNB)
+	    } //if (p<fp->nb_antenna_ports_eNB)
 	  
 	      // PDSCH region
-    	  if (p<fp->nb_antenna_ports_eNB || p==5 || p==7 || p==8) {
+    	    if (p<fp->nb_antenna_ports_eNB || p==5 || p==7 || p==8) {
 	        for (l=pdcch_vars->num_pdcch_symbols;l<fp->symbols_per_tti;l++) {
 	          beam_precoding(eNB->common_vars.txdataF,
                              ru->common.txdataF_BF,
@@ -510,8 +509,8 @@ void feptx_prec(RU_t *ru,
                              eNB->Mod_id);
 	        } // for (l=pdcch_vars ....)
 	      } // if (p<fp->nb_antenna_ports_eNB) ...
-	    } // ru->do_precoding!=0
-      } // for (p=0...)
+           } // for (p=0...)
+        } // if do_precoding
     } // for (aa=0 ...)
     
     if(ru->idx<2)
@@ -658,7 +657,7 @@ void ru_fep_full_2thread(RU_t *ru,
 
   struct timespec wait;
 
-  if ((fp->frame_type == TDD) && (subframe_select(fp,subframe) != SF_UL)) return;
+  if ((fp->frame_type == TDD) && (subframe_select(fp,subframe) == SF_DL)) return;
 
   if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
 
@@ -705,7 +704,7 @@ void ru_fep_full_2thread(RU_t *ru,
 
   if (proc->tti_rx/*proc->subframe_rx*/==1 && ru->is_slave==1/* && ru->state == RU_CHECK_SYNC*/)
   {
-    //LOG_I(PHY,"Running check synchronization procedure for frame %d\n", proc->frame_rx);
+    LOG_I(PHY,"Running check synchronization procedure for frame %d\n", proc->frame_rx);
   	ulsch_extract_rbs_single(ru->common.rxdataF,
                              calibration->rxdataF_ext,
                              0,
@@ -731,9 +730,10 @@ void ru_fep_full_2thread(RU_t *ru,
 	check_sync_pos = lte_est_timing_advance_pusch(ru->frame_parms, ru->calibration.drs_ch_estimates_time); 
         if (ru->state == RU_CHECK_SYNC) {
           if ((check_sync_pos >= 0 && check_sync_pos<8) || (check_sync_pos < 0 && check_sync_pos>-8)) {
-    		  LOG_I(PHY,"~~~~~~~~~~~    check_sync_pos %d, frame %d, cnt %d\n",check_sync_pos,proc->frame_rx,ru->wait_check); 
+//    		  LOG_I(PHY,"~~~~~~~~~~~    check_sync_pos %d, frame %d, cnt %d\n",check_sync_pos,proc->frame_rx,ru->wait_check); 
                   ru->wait_check++;
           }
+          LOG_I(PHY,"~~~~~~~~~~~    check_sync_pos %d, frame %d, cnt %d\n",check_sync_pos,proc->frame_rx,ru->wait_check);
 
           if (ru->wait_check==20) { 
             ru->state = RU_RUN;
@@ -743,10 +743,11 @@ void ru_fep_full_2thread(RU_t *ru,
             rru_config_msg.len  = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg len
             LOG_I(PHY,"Sending RRU_sync_ok to RAU\n");
             AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RAU %d\n",ru->idx);
+/*
                 //LOG_I(PHY,"~~~~~~~~~ RU_RUN\n");
-          	/*LOG_M("dmrs_time.m","dmrstime",calibration->drs_ch_estimates_time[0], (fp->ofdm_symbol_size),1,1);
+          	LOG_M("dmrs_time.m","dmrstime",calibration->drs_ch_estimates_time[0], (fp->ofdm_symbol_size),1,1);
 		LOG_M("rxdataF_ext.m","rxdataFext",&calibration->rxdataF_ext[0][36*fp->N_RB_DL], 12*(fp->N_RB_DL),1,1);		
-		LOG_M("drs_seq0.m","drsseq0",ul_ref_sigs_rx[0][0][23],600,1,1);
+		//LOG_M("drs_seq0.m","drsseq0",ul_ref_sigs_rx[0][0][23],600,1,1);
 		LOG_M("rxdata.m","rxdata",&ru->common.rxdata[0][0], fp->samples_per_tti*2,1,1);
 		exit(-1);*/
           }
diff --git a/openair1/SCHED/sched_common.h b/openair1/SCHED/sched_common.h
index f3e43d516ece342271860bad060b5669da6bb01b..c9fc3386865b6931fc7fdbb98f694f61d078806f 100644
--- a/openair1/SCHED/sched_common.h
+++ b/openair1/SCHED/sched_common.h
@@ -311,7 +311,7 @@ void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id);
 
 int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id, uint8_t eNB_index);
 
-void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
+void schedule_response(Sched_Rsp_t *Sched_INFO, void *proc);
 
 LTE_eNB_UE_stats* get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
 
diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h
index f04bec2e5c45f691d75fb0e39aeaae07c34d409f..de987b0ac7eece4820e24f208798954a658d7572 100644
--- a/openair1/SCHED/sched_eNB.h
+++ b/openair1/SCHED/sched_eNB.h
@@ -193,7 +193,7 @@ int8_t find_ue_ulsch(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
 
 
 
-void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
+void schedule_response(Sched_Rsp_t *Sched_INFO, void *proc);
 
 LTE_eNB_UE_stats *get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
 
diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c
index d65d3b54bb90ab6d264561e8a3071cd71c280f30..f04401aac5f7ebdb19d09d4e16c1215b23036109 100644
--- a/openair1/SCHED_NR/fapi_nr_l1.c
+++ b/openair1/SCHED_NR/fapi_nr_l1.c
@@ -50,8 +50,15 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
   AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n",
               dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag);
 
-  LOG_D(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
-  memcpy((void*)&gNB->ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
+  uint8_t i_ssb = dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
+
+  LOG_D(PHY,"%d.%d : ssb index %d pbch_pdu: %x\n",frame,slot,i_ssb,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
+  if (gNB->ssb[i_ssb].active)
+    AssertFatal(1==0,"SSB PDU with index %d already active\n",i_ssb);
+  else {
+    gNB->ssb[i_ssb].active = true;
+    memcpy((void*)&gNB->ssb[i_ssb].ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
+  }
 }
 
 /*void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int subframe,gNB_L1_rxtx_proc_t *proc,
@@ -104,10 +111,9 @@ void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
 
   nr_fill_dci(gNB,frame,slot,pdcch_pdu);
 
-
-
 }
 
+
 void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
 			       int frame, int slot,
 			       nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu) {
@@ -121,6 +127,30 @@ void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
 
 }
 
+
+void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
+			       int frame, int slot,
+			       nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu) {
+
+  int found = 0;
+
+  for (int id=0; id<NUMBER_OF_NR_CSIRS_MAX; id++) {
+    NR_gNB_CSIRS_t *csirs = &gNB->csirs_pdu[id];
+    if (csirs->active == 0) {
+      LOG_D(PHY,"Frame %d Slot %d CSI_RS with ID %d is now active\n",frame,slot,id);
+      csirs->frame = frame;
+      csirs->slot = slot;
+      csirs->active = 1;
+      memcpy((void*)&csirs->csirs_pdu, (void*)csirs_pdu, sizeof(nfapi_nr_dl_tti_csi_rs_pdu));
+      found = 1;
+      break;
+    }
+  }
+  if (found == 0)
+    LOG_E(MAC,"CSI-RS list is full\n");
+}
+
+
 void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
                             nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
                             uint8_t *sdu)
@@ -161,19 +191,16 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
 
   int pdcch_received=0;
   gNB->num_pdsch_rnti[slot]=0;
-  for (int i=0; i<NUMBER_OF_NR_DLSCH_MAX; i++) {
+  for (int i=0; i<gNB->number_of_nr_dlsch_max; i++) {
     gNB->dlsch[i][0]->rnti=0;
     gNB->dlsch[i][0]->harq_mask=0;
   }
 
-  gNB->pbch_configured=0;
-
   for (int i=0;i<number_dl_pdu;i++) {
     nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i];
     LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
     switch (dl_tti_pdu->PDUType) {
       case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
-	gNB->pbch_configured=1;
 
         if(NFAPI_MODE != NFAPI_MODE_VNF)
         handle_nr_nfapi_ssb_pdu(gNB,frame,slot,
@@ -191,6 +218,12 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
 	pdcch_received = 1;
 
       break;
+      case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
+        LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
+        handle_nfapi_nr_csirs_pdu(gNB,
+				  frame, slot,
+				  &dl_tti_pdu->csi_rs_pdu);
+      break;
       case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
 
       {
@@ -257,4 +290,4 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
     
   }
 
-}
\ No newline at end of file
+}
diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h
index ed90b9870b8bb4b5e0de4d58955cb4e9663f560f..19c98e4ec00515465bea4c99468a0fadcadfdac7 100644
--- a/openair1/SCHED_NR/fapi_nr_l1.h
+++ b/openair1/SCHED_NR/fapi_nr_l1.h
@@ -43,6 +43,10 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,
 
 void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO);
 
+void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
+			       int frame, int slot,
+			       nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu);
+
 void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
 			       int frame, int subframe,
 			       nfapi_nr_dl_tti_pdcch_pdu *dcl_dl_pdu);
diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c
index 5a98b17cea7a8b0b77b8629ac7b3b73e63c36064..cc51ce7fe3f594e84a3dc3892fbc7b572c10dca0 100644
--- a/openair1/SCHED_NR/nr_prach_procedures.c
+++ b/openair1/SCHED_NR/nr_prach_procedures.c
@@ -49,9 +49,6 @@
 
 extern uint8_t nfapi_mode;
 
-extern int oai_nfapi_nr_rach_ind(nfapi_rach_indication_t *rach_ind);
-
-
 void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) {
 
   uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={0};
@@ -114,23 +111,24 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) {
 		  &max_preamble_delay[0]
 		  );
       free_nr_prach_entry(gNB,prach_id);
-      LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n",
+      LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d (prach_energy counter %d)\n",
 	    frame,slot,prach_oc,prachStartSymbol,
 	    max_preamble[0],
 	    max_preamble_energy[0]/10,
+            max_preamble_energy[0]%10,
 	    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",
+	LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB (I0 %d, thres %d), delay %d start symbol %u freq index %u\n",
 	      gNB->Mod_id,
 	      frame,
 	      slot,
 	      max_preamble[0],
 	      max_preamble_energy[0]/10,
 	      max_preamble_energy[0]%10,
+              gNB->measurements.prach_I0,gNB->prach_thres,
 	      max_preamble_delay[0],
 	      prachStartSymbol,
 	      prach_pdu->num_ra);
diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c
index a78b1f48056ffa09963ef58045b1f7fd06852d30..827e986f1b20c9e3bded717c95dc4811811ff523 100644
--- a/openair1/SCHED_NR/nr_ru_procedures.c
+++ b/openair1/SCHED_NR/nr_ru_procedures.c
@@ -31,15 +31,12 @@
  */
 
 #include "PHY/defs_gNB.h"
-#include "PHY/phy_extern.h"
 #include "sched_nr.h"
 #include "PHY/MODULATION/modulation_common.h"
 #include "PHY/MODULATION/nr_modulation.h"
 #include "PHY/LTE_TRANSPORT/if4_tools.h"
 #include "PHY/LTE_TRANSPORT/if5_tools.h"
 
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
-#include "LAYER2/MAC/mac.h"
 #include "common/utils/LOG/log.h"
 #include "common/utils/system.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
@@ -200,17 +197,17 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) {
 
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 1);
         start_meas(&ru->txdataF_copy_stats);
-        if (ru->num_gNB == 1){
-          gNB = ru->gNB_list[0];
-          cfg = &gNB->gNB_config;
+        AssertFatal(ru->num_gNB==1,"num_gNB>1, help\n");
+        gNB = ru->gNB_list[0];
+        cfg = &gNB->gNB_config;
 
-          for(i=0; i<ru->nb_tx; ++i){
-            memcpy((void*)&ru->common.txdataF[i][j*fp->ofdm_symbol_size],
-                   (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset],
-                   fp->ofdm_symbol_size*sizeof(int32_t));
-          }
+        for(i=0; i<ru->nb_tx; ++i){
+          memcpy((void*)&ru->common.txdataF[i][j*fp->ofdm_symbol_size],
+                 (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset],
+                 fp->ofdm_symbol_size*sizeof(int32_t));
+	    
+        }
 
-        }//num_gNB == 1
         stop_meas(&ru->txdataF_copy_stats);
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 0);
 
@@ -279,13 +276,12 @@ static void *nr_feptx_thread(void *param) {
 
   RU_feptx_t *feptx = (RU_feptx_t *)param;
   RU_t       *ru;
-  int         aa, slot, start, l, nb_antenna_ports, ret;
+  int         aa, slot, start, l, ret;
   int         i;
   int32_t ***bw;
   NR_DL_FRAME_PARMS *fp;
   int ofdm_mask_full;
   int txdataF_offset;
-  int32_t *txdataF;
   while (!oai_exit) {
     ret = 0;
     if (wait_on_condition(&feptx->mutex_feptx,&feptx->cond_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break;
@@ -299,40 +295,55 @@ static void *nr_feptx_thread(void *param) {
     l     = feptx->symbol;
     fp    = ru->nr_frame_parms;
     start = feptx->symbol;
-    nb_antenna_ports = feptx->nb_antenna_ports;
     ofdm_mask_full   = (1<<(ru->nb_tx*2))-1;
 
     if(ru->num_gNB != 0){
       txdataF_offset = ((slot%2)*fp->samples_per_slot_wCP);
       ////////////precoding////////////
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 1);
-      start_meas(&ru->precoding_stats);
+      
+      if (aa==0 && l==0) start_meas(&ru->precoding_stats);
+
+      if (ru->do_precoding == 1) {
+        for(i=0; i<ru->nb_log_antennas; ++i) {
+          memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot+l],
+                 (void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot+l],
+                 (fp->symbols_per_slot>>1)*sizeof(uint8_t));
+         }
+      }
+
       if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) {
-            memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size],
-                 (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size],
-                 (fp->samples_per_slot_wCP>>1)*sizeof(int32_t));
+        memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size],
+               (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size],
+               (fp->samples_per_slot_wCP>>1)*sizeof(int32_t));
+      }
+      else if (ru->do_precoding == 0) {
+        int gNB_tx = ru->gNB_list[0]->frame_parms.nb_antennas_tx;
+        memcpy((void*)&ru->common.txdataF_BF[aa][l*fp->ofdm_symbol_size],
+               (void*)&ru->gNB_list[0]->common_vars.txdataF[aa%gNB_tx][txdataF_offset + l*fp->ofdm_symbol_size],
+               (fp->samples_per_slot_wCP>>1)*sizeof(int32_t));
       }
       else {
         bw  = ru->beam_weights[0];
-        txdataF = &ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset];
         for(i=0; i<fp->symbols_per_slot>>1; ++i){
-          nr_beam_precoding(&txdataF,
+          nr_beam_precoding(ru->gNB_list[0]->common_vars.txdataF,
                         ru->common.txdataF_BF,
                         fp,
                         bw,
                         slot,
                         l+i,
                         aa,
-                        nb_antenna_ports);
+                        ru->nb_log_antennas,
+                        txdataF_offset);//here
         }
       }
-      stop_meas(&ru->precoding_stats);
+      if (aa==0 && l==0) stop_meas(&ru->precoding_stats);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0);
 
       ////////////FEPTX////////////
-      start_meas(&ru->ofdm_mod_stats);
+      if (aa==0 && l==0) start_meas(&ru->ofdm_mod_stats);
       nr_feptx0(ru,slot,start,fp->symbols_per_slot>>1,aa);
-      stop_meas(&ru->ofdm_mod_stats);
+      if (aa==0 && l==0) stop_meas(&ru->ofdm_mod_stats);
 
       if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break;
 
@@ -362,7 +373,8 @@ static void *nr_feptx_thread(void *param) {
                         slot,
                         l,
                         aa,
-                        nb_antenna_ports);
+                        ru->nb_log_antennas,
+                        0);
       }
       stop_meas(&ru->precoding_stats);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0);
@@ -459,10 +471,14 @@ void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) {
 
     if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT) return;
 
-    for(i=0; i<ru->nb_log_antennas; ++i)
+    for(i=0; i<ru->nb_log_antennas; ++i) {
       memcpy((void*)ru->common.txdataF[i],
            (void*)&gNB->common_vars.txdataF[i][txdataF_offset],
            fp->samples_per_slot_wCP*sizeof(int32_t));
+      memcpy((void*)&ru->common.beam_id[i][slot_tx*fp->symbols_per_slot],
+	     (void*)&gNB->common_vars.beam_id[i][slot_tx*fp->symbols_per_slot],
+	     fp->symbols_per_slot*sizeof(uint8_t));
+    }
 
     if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) {
     
@@ -485,7 +501,8 @@ void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) {
                             tti_tx,
                             l,
                             aa,
-                            ru->nb_log_antennas);
+                            ru->nb_log_antennas,
+                            0);
         }// for (aa=0;aa<ru->nb_tx;aa++)
       }// for (l=0;l<fp->symbols_per_slot;l++)
     }// if (ru->nb_tx == 1)
@@ -520,8 +537,7 @@ void nr_fep0(RU_t *ru, int first_half) {
                      ru->common.rxdataF[aa],
                      l,
                      proc->tti_rx,
-                     ru->N_TA_offset,
-                     0);
+                     ru->N_TA_offset);
     }
   }
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 0);
@@ -657,8 +673,7 @@ void nr_fep_full(RU_t *ru, int slot) {
                      ru->common.rxdataF[aa],
                      l,
                      proc->tti_rx,
-                     ru->N_TA_offset,
-                     0);
+                     ru->N_TA_offset);
     }
   }
 
diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c
index 3864b2fcb20a0dc8bec2718984bcf4348e861233..9be678059710977f460be65f0aa2aa294ccf6ac0 100644
--- a/openair1/SCHED_NR/phy_frame_config_nr.c
+++ b/openair1/SCHED_NR/phy_frame_config_nr.c
@@ -41,7 +41,7 @@
 *
 * OUTPUT:        table of uplink symbol for each slot for 2 frames
 *
-* RETURN :       0 if tdd has been properly configurated
+* RETURN :       nb_periods_per_frame if tdd has been properly configurated
 *                -1 tdd configuration can not be done
 *
 * DESCRIPTION :  generate bit map for uplink symbol for each slot for several frames
@@ -179,7 +179,7 @@ int set_tdd_config_nr( nfapi_nr_config_request_scf_t *cfg,
     LOG_E(PHY,"set_tdd_configuration_nr: additionnal tdd configuration 2 is not supported for tdd configuration \n");
     return (-1);
   }*/
-  return (0);
+  return (nb_periods_per_frame);
 }
 
 /*******************************************************************
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 9d7422745eef7122e9ef501cddda5544cae8ba55..e0b7387ab9d96f6a1efa5d94a12fe66a46306bd1 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -67,74 +67,63 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME
   LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco);
 }
 
-void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) {
+void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu) {
 
   NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
   nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
   int **txdataF = gNB->common_vars.txdataF;
   uint8_t ssb_index, n_hf;
-  uint16_t ssb_start_symbol, rel_slot;
+  uint16_t ssb_start_symbol;
   int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP;
   uint16_t slots_per_hf = (fp->slots_per_frame)>>1;
 
-  n_hf = fp->half_frame_bit;
+  if (slot<slots_per_hf)
+    n_hf=0;
+  else
+    n_hf=1;
 
-  // if SSB periodicity is 5ms, they are transmitted in both half frames
-  if ( cfg->ssb_table.ssb_period.value == 0) {
-    if (slot<slots_per_hf)
-      n_hf=0;
-    else
-      n_hf=1;
-  }
+  ssb_index = ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
+  LOG_D(PHY,"common_signal_procedures: frame %d, slot %d ssb index %d\n",frame,slot,ssb_index);
 
-  // to set a effective slot number in the half frame where the SSB is supposed to be
-  rel_slot = (n_hf)? (slot-slots_per_hf) : slot; 
-
-  LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot);
-
-  if(rel_slot<38 && rel_slot>=0)  { // there is no SSB beyond slot 37
-
-    for (int i=0; i<2; i++)  {  // max two SSB per frame
-      
-      ssb_index = i + SSB_Table[rel_slot]; // computing the ssb_index
-
-      if ((ssb_index<64) && ((fp->L_ssb >> (63-ssb_index)) & 0x01))  { // generating the ssb only if the bit of L_ssb at current ssb index is 1
-        fp->ssb_index = ssb_index;
-        int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp); // computing the starting symbol for current ssb
-	ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot;  // start symbol wrt slot
-
-	nr_set_ssb_first_subcarrier(cfg, fp);  // setting the first subcarrier
-	
-	LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
-	nr_generate_pss(gNB->d_pss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
-	nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
-	
-        if (cfg->carrier_config.num_tx_ant.value <= 4)
-	  nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
-        else
-	  nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
-
-        if (T_ACTIVE(T_GNB_PHY_MIB)) {
-          unsigned char bch[3];
-          bch[0] = gNB->ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
-          bch[1] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
-          bch[2] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
-          T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
-        }
+  int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp,ssb_index); // computing the starting symbol for current ssb
+  ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot;  // start symbol wrt slot
 
-	nr_generate_pbch(&gNB->pbch,
-	                 &gNB->ssb_pdu,
-	                 gNB->nr_pbch_interleaver,
-			 &txdataF[0][txdataF_offset],
-			 AMP,
-			 ssb_start_symbol,
-			 n_hf, frame, cfg, fp);
+  nr_set_ssb_first_subcarrier(cfg, fp);  // setting the first subcarrier
 
-      }
-    }
+  LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
+  nr_generate_pss(gNB->d_pss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
+  nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
+
+  if (cfg->carrier_config.num_tx_ant.value <= 4)
+    nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
+  else
+    nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
+
+  if (T_ACTIVE(T_GNB_PHY_MIB)) {
+    unsigned char bch[3];
+    bch[0] = ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
+    bch[1] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
+    bch[2] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
+    T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
   }
+
+  // Beam_id is currently used only for FR2
+  if (fp->freq_range==nr_FR2){
+    LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value);
+    for (int j=0;j<fp->symbols_per_slot;j++) 
+      gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value;
+  }
+
+  nr_generate_pbch(&gNB->pbch,
+                   &ssb_pdu,
+                   gNB->nr_pbch_interleaver,
+                   &txdataF[0][txdataF_offset],
+                   AMP,
+                   ssb_start_symbol,
+                   n_hf, frame, cfg, fp);
 }
 
+
 void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
                            int frame,int slot,
                            int do_meas) {
@@ -142,11 +131,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
   NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
   nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
   int offset = gNB->CC_id;
-  uint8_t ssb_frame_periodicity = 1;  // every how many frames SSB are generated
   int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP;
-  
-  if (cfg->ssb_table.ssb_period.value > 1) 
-    ssb_frame_periodicity = 1 <<(cfg->ssb_table.ssb_period.value -1) ; 
 
   if ((cfg->cell_config.frame_duplex_type.value == TDD) &&
       (nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return;
@@ -155,15 +140,20 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
 
   if (do_meas==1) start_meas(&gNB->phy_proc_tx);
 
-  // clear the transmit data array for the current subframe
+  // clear the transmit data array and beam index for the current slot
   for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
     memset(&gNB->common_vars.txdataF[aa][txdataF_offset],0,fp->samples_per_slot_wCP*sizeof(int32_t));
+    memset(&gNB->common_vars.beam_id[aa][slot*fp->symbols_per_slot],255,fp->symbols_per_slot*sizeof(uint8_t));
   }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
   if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) { 
-    if ((!(frame%ssb_frame_periodicity)))  // generate SSB only for given frames according to SSB periodicity
-      nr_common_signal_procedures(gNB,frame, slot);
+    for (int i=0; i<fp->Lmax; i++) {
+      if (gNB->ssb[i].active) {
+        nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[i].ssb_pdu);
+        gNB->ssb[i].active = false;
+      }
+    }
   }
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
 
@@ -186,7 +176,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
 			ul_pdcch_pdu_id>=0 ? &gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu : NULL,
 			gNB->nr_gold_pdcch_dmrs[slot],
 			&gNB->common_vars.txdataF[0][txdataF_offset],
-			AMP, *fp);
+			AMP, fp);
 
     // free up entry in pdcch tables
     if (pdcch_pdu_id>=0) gNB->pdcch_pdu[pdcch_pdu_id].frame = -1;
@@ -204,11 +194,27 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0);
   }
 
+  for (int i=0;i<NUMBER_OF_NR_CSIRS_MAX;i++){
+    NR_gNB_CSIRS_t *csirs = &gNB->csirs_pdu[i];
+    if ((csirs->active == 1) &&
+	(csirs->frame == frame) &&
+	(csirs->slot == slot) ) {
+      LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot);
+      nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params = csirs->csirs_pdu.csi_rs_pdu_rel15;
+      nr_generate_csi_rs(gNB, AMP, csi_params, gNB->gNB_config.cell_config.phy_cell_id.value, slot);
+      csirs->active = 0;
+    }
+  }
+
+  if (do_meas==1) stop_meas(&gNB->phy_proc_tx);
+
   if ((frame&127) == 0) dump_pdsch_stats(gNB);
 
   //apply the OFDM symbol rotation here
-  apply_nr_rotation(fp,(int16_t*) &gNB->common_vars.txdataF[0][txdataF_offset],slot,0,fp->Ncp==EXTENDED?12:14,fp->ofdm_symbol_size);
-  
+  for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
+	  apply_nr_rotation(fp,(int16_t*) &gNB->common_vars.txdataF[aa][txdataF_offset],slot,0,fp->Ncp==EXTENDED?12:14,fp->ofdm_symbol_size);
+  }
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0);
 }
 
@@ -361,13 +367,12 @@ 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);
 
   int timing_advance_update, cqi;
   int sync_pos;
-  uint16_t mu = gNB->frame_parms.numerology_index;
   NR_gNB_ULSCH_t                       *ulsch                 = gNB->ulsch[ULSCH_id][0];
   NR_UL_gNB_HARQ_t                     *harq_process          = ulsch->harq_processes[harq_pid];
 
@@ -375,18 +380,10 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
 
   //  pdu->data                              = gNB->ulsch[ULSCH_id+1][0]->harq_processes[harq_pid]->b;
   sync_pos                               = nr_est_timing_advance_pusch(gNB, ULSCH_id); // estimate timing advance for MAC
-  timing_advance_update                  = sync_pos * (1 << mu);                    // scale by the used scs numerology
 
   // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
-  switch (gNB->frame_parms.N_RB_DL) {
-    case 106: timing_advance_update /= 16; break;
-    case 217: timing_advance_update /= 32; break;
-    case 245: timing_advance_update /= 32; break;
-    case 273: timing_advance_update /= 32; break;
-    case 66:  timing_advance_update /= 12; break;
-    case 32:  timing_advance_update /= 12; break;
-    default: AssertFatal(0==1,"No case defined for PRB %d to calculate timing_advance_update\n",gNB->frame_parms.N_RB_DL);
-  }
+  uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048;
+  timing_advance_update = sync_pos / bw_scaling;
 
   // put timing advance command in 0..63 range
   timing_advance_update += 31;
@@ -396,10 +393,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
+
+  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 = %d dB\n", SNRtimes10/10);
+  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;
@@ -460,14 +459,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[i].pucch_pdu;
+            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;
@@ -475,7 +474,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
           }
         }
       }
-      for (int ULSCH_id=0;ULSCH_id<NUMBER_OF_NR_ULSCH_MAX;ULSCH_id++) {
+      for (int ULSCH_id=0;ULSCH_id<gNB->number_of_nr_ulsch_max;ULSCH_id++) {
         NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id][0];
         int harq_pid;
         NR_UL_gNB_HARQ_t *ulsch_harq;
@@ -495,7 +494,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;
@@ -517,15 +516,12 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
   unsigned char aa;
 
   for(symbol = 0; symbol < (gNB->frame_parms.Ncp==EXTENDED?12:14); symbol++) {
-    // nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0);
-
     for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
       nr_slot_fep_ul(&gNB->frame_parms,
                      gNB->common_vars.rxdata[aa],
                      gNB->common_vars.rxdataF[aa],
                      symbol,
                      slot_rx,
-                     0,
                      0);
     }
   }
@@ -541,7 +537,10 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
 
 }
 
-void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
+int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
+  /* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */
+  int pucch_decode_done = 0;
+  int pusch_decode_done = 0;
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1);
   LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
@@ -549,19 +548,31 @@ void 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);
+
   for (int i=0;i<NUMBER_OF_NR_PUCCH_MAX;i++){
     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;
 
         nfapi_nr_pucch_pdu_t  *pucch_pdu = &pucch->pucch_pdu;
         uint16_t num_ucis;
@@ -575,14 +586,19 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
           gNB->uci_pdu_list[num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t);
           nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_0_1;
 
+          offset = pucch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size + (gNB->frame_parms.first_carrier_offset+pucch_pdu->prb_start*12);
+          power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset],12);
+          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];
@@ -601,13 +617,13 @@ void 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");
         }
       }
     }
   }
 
-  for (int ULSCH_id=0;ULSCH_id<NUMBER_OF_NR_ULSCH_MAX;ULSCH_id++) {
+  for (int ULSCH_id=0;ULSCH_id<gNB->number_of_nr_ulsch_max;ULSCH_id++) {
     NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id][0];
     int harq_pid;
     int no_sig;
@@ -617,15 +633,18 @@ void 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;
@@ -651,21 +670,39 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
           }
 #endif
 
-T(T_BENETEL, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], 2048*4*14));
+          pusch_decode_done = 1;
 
-          uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index;
-          uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols;
           VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1);
-	  start_meas(&gNB->rx_pusch_stats);
-	  for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) {
-	    no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid);
-            if (no_sig) {
-              LOG_I(PHY, "PUSCH not detected in symbol %d\n",symbol);
-              nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1);
-              return;
-            }
-	  }
-	  stop_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_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;
+             if (stats) 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);
           //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
@@ -677,8 +714,16 @@ T(T_BENETEL, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF
       }
     }
   }
+  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);
+  if ((frame_rx&127) == 0 && slot_rx==19) {
+    LOG_I(PHY, "Number of bad PUCCH received: %lu\n", gNB->bad_pucch);
+  }
+
+  if (pucch_decode_done || pusch_decode_done) {
+    T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4));
+  }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0);
+  return 0;
 }
diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h
index 24885f1bb4ee341ed1d4df8c200eaeedcdca53ec..5e31c08d389bfda7056b4ddc982d27277950b05e 100644
--- a/openair1/SCHED_NR/sched_nr.h
+++ b/openair1/SCHED_NR/sched_nr.h
@@ -38,9 +38,9 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
 void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp);
 void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas);
 void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
-void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
+int  phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
 void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot);
-void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot);
+void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu);
 void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
 void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
 void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa);
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
index f7f44a520d31d34fc6246a436214edb634d890ee..c4a3de1d5af3667cf17de6642eef6c1953c59553 100644
--- a/openair1/SCHED_NR_UE/defs.h
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -115,14 +115,17 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
   @param proc           Pointer to proc information
   @param gNB_id         Local id of eNB on which to act
   @param dlsch_parallel use multithreaded dlsch processing
+  @param txFifo         Result fifo if PDSCH is run in parallel
 */
 int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            uint8_t gNB_id,
-                           uint8_t dlsch_parallel);
+                           uint8_t dlsch_parallel,
+                           notifiedFIFO_t *txFifo);
 
 int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type);
 
+void processSlotTX(void *arg);
 
 #ifdef UE_SLOT_PARALLELISATION
   void *UE_thread_slot1_dl_processing(void *arg);
@@ -414,6 +417,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
                            uint8_t gNB_id,
                            PHY_VARS_NR_UE *ue,
                            NR_UE_DLSCH_t *dlsch0,
+                           NR_UE_DLSCH_t *dlsch1,
                            uint16_t n_pdus);
 
 
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index e70c353589554e45141b51abef271bfa9c1e3ede..ea1264639517b642310e1932f395333a085fbba7 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -42,11 +42,12 @@
 
 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){
 
+  bool found = false;
   if(scheduled_response != NULL){
 
     module_id_t module_id = scheduled_response->module_id;
@@ -59,7 +60,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
     NR_UE_DLSCH_t *dlsch0 = NULL;
     NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0];
     NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0][0];
-    NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms;
+    NR_UE_PUCCH *pucch_vars = PHY_vars_UE_g[module_id][cc_id]->pucch_vars[thread_id][0];
 
     if(scheduled_response->dl_config != NULL){
       fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
@@ -67,7 +68,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) {
@@ -79,29 +81,30 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
 
         } else {
 
+          fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
+          uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
+
           if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DLSCH){
             dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
           }
           else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH){
             dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0];
+            dlsch0->rnti_type = _RA_RNTI_;
+            dlsch0->harq_processes[current_harq_pid]->status = ACTIVE;
           }
           else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH){
             dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_SI[0];
             dlsch0->rnti_type = _SI_RNTI_;
-            dlsch0->harq_processes[dlsch0->current_harq_pid]->status = ACTIVE;
+            dlsch0->harq_processes[current_harq_pid]->status = ACTIVE;
           }
 
-          fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
-          uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
-          NR_DL_UE_HARQ_t *dlsch0_harq;
-
           dlsch0->current_harq_pid = current_harq_pid;
           dlsch0->active = 1;
           dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti;
-          dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
 
           LOG_D(PHY,"current_harq_pid = %d\n", current_harq_pid);
 
+          NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
           if (dlsch0_harq){
 
             dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
@@ -116,17 +119,19 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
             dlsch0_harq->mcs = dlsch_config_pdu->mcs;
             dlsch0_harq->rvidx = dlsch_config_pdu->rv;
             dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
-            dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id;
-            dlsch0_harq->harq_ack.slot_for_feedback_ack = (slot+dlsch_config_pdu->pdsch_to_harq_feedback_time_ind)%frame_parms.slots_per_frame;
-            dlsch0_harq->Nl=1;
+            //get nrOfLayers from DCI info
+            uint8_t Nl = 0;
+            for (i = 0; i < 4; i++) {
+              if (dlsch_config_pdu->dmrs_ports[i] >= i) Nl += 1;
+            }
+            dlsch0_harq->Nl = Nl;
             dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table;
-            dlsch0_harq->harq_ack.rx_status = downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type);
+            downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type);
             if (dlsch0_harq->status != ACTIVE) {
               // dlsch0_harq->status not ACTIVE may be due to false retransmission. Reset the 
               // following flag to skip PDSCH procedures in that case.
               dlsch0->active = 0;
             }
-            dlsch0_harq->harq_ack.vDAI_DL = dlsch_config_pdu->dai;
             /* PTRS */
             dlsch0_harq->PTRSFreqDensity = dlsch_config_pdu->PTRSFreqDensity;
             dlsch0_harq->PTRSTimeDensity = dlsch_config_pdu->PTRSTimeDensity;
@@ -134,7 +139,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
             dlsch0_harq->nEpreRatioOfPDSCHToPTRS = dlsch_config_pdu->nEpreRatioOfPDSCHToPTRS;
             dlsch0_harq->PTRSReOffset = dlsch_config_pdu->PTRSReOffset;
             dlsch0_harq->pduBitmap = dlsch_config_pdu->pduBitmap;
-            LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\tpdsch_to_harq_feedback_time_ind = %d\tslot_for_feedback_ack = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs, dlsch_config_pdu->pdsch_to_harq_feedback_time_ind, dlsch0_harq->harq_ack.slot_for_feedback_ack);
+            LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs);
           }
         }
       }
@@ -147,9 +152,10 @@ 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;
+        uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, current_harq_pid, gNB_id = 0;
         /* PRACH */
         //NR_PRACH_RESOURCES_t *prach_resources;
         fapi_nr_ul_config_prach_pdu *prach_config_pdu;
@@ -157,9 +163,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
         nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu;
         /* PUCCH */
         fapi_nr_ul_config_pucch_pdu *pucch_config_pdu;
-        PUCCH_ConfigCommon_nr_t *pucch_config_common_nr;
-        PUCCH_Config_t *pucch_config_dedicated_nr;
-        PUCCH_format_t *format_params;
 
         switch (pdu_type){
 
@@ -179,7 +182,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;
@@ -197,47 +200,19 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
         break;
 
         case (FAPI_NR_UL_CONFIG_TYPE_PUCCH):
-          // pucch config pdu
+          found = false;
           pucch_config_pdu = &ul_config->ul_config_list[i].pucch_config_pdu;
-          pucch_resource_id = 0; //FIXME!!!
-          format = 1; // FIXME!!!
-          pucch_config_common_nr = &PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0];
-          pucch_config_dedicated_nr = &PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0];
-          format_params = &pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->format_parameters;
-
-          format_params->initialCyclicShift = pucch_config_pdu->initialCyclicShift;
-          format_params->nrofSymbols = pucch_config_pdu->nrofSymbols;
-          format_params->startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
-          format_params->nrofPRBs = pucch_config_pdu->nrofPRBs;
-          format_params->timeDomainOCC = pucch_config_pdu->timeDomainOCC;
-          format_params->occ_length = pucch_config_pdu->occ_length;
-          format_params->occ_Index = pucch_config_pdu->occ_Index;
-
-          pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB;
-          pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping;
-          pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used
-          pucch_config_dedicated_nr->formatConfig[format - 1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used
-          pucch_config_dedicated_nr->formatConfig[format - 1]->pi2PBSK = pucch_config_pdu->pi2PBSK;
-
-          pucch_config_common_nr->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
-          pucch_config_common_nr->hoppingId = pucch_config_pdu->hoppingId;
-          pucch_config_common_nr->p0_nominal = pucch_config_pdu->p0_nominal;
-
-          /* pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift;
-          pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols;
-          pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
-          pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs;
-          pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB;
-          pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC;
-          pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length;
-          pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index;
-          pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping;
-          pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used
-          pucch_config_dedicated->formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used
-          pucch_config_dedicated->formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK;
-          pucch_config_common->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
-          pucch_config_common->hoppingId = pucch_config_pdu->hoppingId;
-          pucch_config_common->p0_nominal = pucch_config_pdu->p0_nominal;*/
+          for(int j=0; j<2; j++) {
+            if(pucch_vars->active[j] == false) {
+              LOG_D(PHY,"%d.%d Copying pucch pdu to UE PHY\n",scheduled_response->frame,slot);
+              memcpy((void*)&(pucch_vars->pucch_pdu[j]), (void*)pucch_config_pdu, sizeof(fapi_nr_ul_config_pucch_pdu));
+              pucch_vars->active[j] = true;
+              found = true;
+              break;
+            }
+          }
+          if (!found)
+            LOG_E(PHY, "Couldn't find allocation for PUCCH PDU in PUCCH VARS\n");
         break;
 
         case (FAPI_NR_UL_CONFIG_TYPE_PRACH):
@@ -265,9 +240,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/harq_nr.c b/openair1/SCHED_NR_UE/harq_nr.c
index 85f6d90bbedb3a62a07d7671289d5525dcbc24d1..3f528f02d4693d47711d251ea16ec09df1aff423 100644
--- a/openair1/SCHED_NR_UE/harq_nr.c
+++ b/openair1/SCHED_NR_UE/harq_nr.c
@@ -98,43 +98,6 @@
 #define DL_DCI              (1)
 #define UL_DCI              (0)
 
-/*******************************************************************
-*
-* NAME :         get_dci_info_for_harq
-*
-* PARAMETERS :   pointer to ue context
-*                id of current gNB
-*                number of uplink processes
-*                maximum number of uplink retransmissions
-* RETURN :       none
-*
-* DESCRIPTION :  update HARQ entity with information from DCI
-*                TS 38.212 7.3.1.2 DCI formats for scheduling PDSCH
-*
-*********************************************************************/
-
-void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted,
-		                   NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t slot, uint8_t tx_offset)
-{
-  if (nr_dci_info_extracted->identifier_dci_formats == DL_DCI) {
-
-	dlsch[0]->current_harq_pid = nr_dci_info_extracted->harq_process_number;
-
-	NR_DL_UE_HARQ_t *dl_harq = dlsch[0]->harq_processes[dlsch[0]->current_harq_pid];
-
-    dl_harq->harq_ack.vDAI_DL = nr_dci_info_extracted->dai+1;
-    dl_harq->harq_ack.pucch_resource_indicator = nr_dci_info_extracted->pucch_resource_ind;
-    dl_harq->harq_ack.slot_for_feedback_ack = (slot + nr_dci_info_extracted->pdsch_to_harq_feedback_time_ind)%ue->frame_parms.slots_per_subframe;
-    dl_harq->harq_ack.harq_id = nr_dci_info_extracted->harq_process_number;
-    dl_harq->harq_ack.rx_status = downlink_harq_process(dl_harq, dlsch[0]->current_harq_pid, nr_dci_info_extracted->ndi, dlsch[0]->rnti_type);
-  }
-  else if (nr_dci_info_extracted->identifier_dci_formats == UL_DCI) {
-
-	/* store harq id for which pusch should be transmitted at rx_slot + tx_offset */
-	set_tx_harq_id(ulsch, nr_dci_info_extracted->harq_process_number, (slot + tx_offset)%ue->frame_parms.slots_per_subframe);
-    ulsch->harq_processes[nr_dci_info_extracted->harq_process_number]->tx_status = uplink_harq_process(ulsch, nr_dci_info_extracted->harq_process_number, nr_dci_info_extracted->ndi, ulsch->rnti_type);
-  }
-}
 
 /*******************************************************************
 *
@@ -345,96 +308,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq)
   dl_harq->status = SCH_IDLE;
   dl_harq->first_tx = 1;
   dl_harq->round  = 0;
-  dl_harq->harq_ack.ack = DL_ACKNACK_NO_SET;
-  dl_harq->harq_ack.send_harq_status = 0;
-  dl_harq->harq_ack.vDAI_UL = UL_DAI_NO_SET;
-  dl_harq->harq_ack.vDAI_DL = DL_DAI_NO_SET;
-  dl_harq->harq_ack.slot_for_feedback_ack = NR_MAX_SLOTS_PER_FRAME;
-  dl_harq->harq_ack.pucch_resource_indicator = MAX_PUCCH_RESOURCE_INDICATOR;
-  dl_harq->harq_ack.n_CCE = 0;
-  dl_harq->harq_ack.N_CCE = 0;;
-}
-
-/*******************************************************************
-*
-* NAME :         config_downlink_harq_process
-*
-* PARAMETERS :   pointer to ue context
-*                id of current gNB
-*                number of downlink processes
-*
-* RETURN :       none
-*
-* DESCRIPTION :  configuration of downlink HARQ entity
-*
-*********************************************************************/
-
-void config_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, int execution_thread_number, uint8_t number_harq_processes_for_pdsch)
-{
-  NR_UE_DLSCH_t *dlsch;
-
-  dlsch = (NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t));
-
-  if (dlsch != NULL) {
-
-    memset(dlsch,0,sizeof(NR_UE_DLSCH_t));
-
-    ue->dlsch[execution_thread_number][gNB_id][TB_id] = dlsch;
-  }
-  else {
-    LOG_E(PHY, "Fatal memory allocation problem at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__);
-    assert(0);
-  }
-
-  dlsch->Mdlharq = number_harq_processes_for_pdsch; /* an additional HARQ is reserved for PBCCH */
-  dlsch->number_harq_processes_for_pdsch = number_harq_processes_for_pdsch;
-
-  /* allocation of HARQ process context */
-  for (int harq_pid = 0; harq_pid < number_harq_processes_for_pdsch; harq_pid++) {
-
-    //dlsch->harq_processes[harq_pid] = (NR_DL_UE_HARQ_t *)malloc16(sizeof(NR_DL_UE_HARQ_t));
-
-    /*if (dlsch->harq_processes[harq_pid] == NULL) {
-      LOG_E(PHY, "Fatal memory allocation problem at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__);
-      assert(0);
-    }*/
-
-    memset(&dlsch->harq_processes[harq_pid],0,sizeof(NR_DL_UE_HARQ_t));
-
-    NR_DL_UE_HARQ_t *dl_harq = dlsch->harq_processes[harq_pid];
-
-    init_downlink_harq_status(dl_harq);
-  }
-}
-
-/*******************************************************************
-*
-* NAME :         release_downlink_harq_process
-*
-* PARAMETERS :   pointer to ue context
-*                id of current gNB
-*                TB_id transport block identity 0 or 1
-*                execution_thread_number thread number for current downlink processing
-* RETURN :       none
-*
-* DESCRIPTION :  release of HARQ downlink entity
-*
-*********************************************************************/
-
-void release_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, int execution_thread_number)
-{
-  NR_UE_DLSCH_t *dlsch = ue->dlsch[execution_thread_number][gNB_id][TB_id];
-
-  /*for (int process_id = 0; process_id < dlsch->Mdlharq; process_id++) {
-
-    free16(dlsch->harq_processes[process_id],sizeof(NR_DL_UE_HARQ_t));
-
-    dlsch->harq_processes[process_id] = NULL;
-  }*/
-
-  free16(dlsch,sizeof(NR_UE_DLSCH_t));
-
-  ue->dlsch[execution_thread_number][gNB_id][TB_id] = NULL;
+  dl_harq->ack = DL_ACKNACK_NO_SET;
 }
 
 /*******************************************************************
@@ -454,18 +328,15 @@ void release_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, in
 *
 *********************************************************************/
 
-harq_result_t downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, uint8_t rnti_type)
-{
-  harq_result_t result_harq = RETRANSMISSION_HARQ;
+void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, uint8_t rnti_type) {
 
-  if (rnti_type == _CS_RNTI_)
-  {
+  if (rnti_type == _CS_RNTI_) {
     LOG_E(PHY, "Fatal error in HARQ entity due to not supported CS_RNTI at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__);
-	return(NEW_TRANSMISSION_HARQ);
+    return;
   }
   else if ((rnti_type != _C_RNTI_) && (rnti_type != _TC_RNTI_)) {
     /* harq mechanism is not relevant for other rnti */
-    return(NEW_TRANSMISSION_HARQ);
+    return;
   }
 
   if (dl_harq->first_tx == 1) {
@@ -474,8 +345,6 @@ harq_result_t downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int
     dl_harq->DCINdi = ndi;
     dl_harq->first_tx = 0;
 
-    result_harq = NEW_TRANSMISSION_HARQ;
-
     LOG_D(PHY, "[HARQ-DL-PDSCH harqId : %d] first new reception \n", harq_pid);
   }
   else if (dl_harq->DCINdi != ndi) {
@@ -483,20 +352,15 @@ harq_result_t downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int
     dl_harq->status = ACTIVE;
     dl_harq->DCINdi = ndi;
 
-    result_harq = NEW_TRANSMISSION_HARQ;
-
     LOG_D(PHY, "[HARQ-DL-PDSCH harqId : %d] new reception due to toogle of ndi \n", harq_pid);
   }
   else {
 
     dl_harq->round++;
 
-    if (dl_harq->harq_ack.ack) dl_harq->status = SCH_IDLE;
-
-    result_harq = RETRANSMISSION_HARQ;
+    if (dl_harq->ack) dl_harq->status = SCH_IDLE;
 
     LOG_D(PHY, "[HARQ-DL-PDSCH harqId : %d] reception of a retransmission \n", harq_pid);
   }
-
-  return (result_harq);
 }
+
diff --git a/openair1/SCHED_NR_UE/harq_nr.h b/openair1/SCHED_NR_UE/harq_nr.h
index c6d47a91ef9ab3df0fd60cbfc02f93abc5c14776..47d1de8a1155fc6e1d052e1c34cfd53000385bfb 100644
--- a/openair1/SCHED_NR_UE/harq_nr.h
+++ b/openair1/SCHED_NR_UE/harq_nr.h
@@ -46,8 +46,6 @@
 
 #define NR_DEFAULT_DLSCH_HARQ_PROCESSES          (8)                      /* TS 38.214 5.1 */
 
-#define NR_DL_MAX_DAI                            (4)                      /* TS 38.213 table 9.1.3-1 Value of counter DAI for DCI format 1_0 and 1_1 */
-#define NR_DL_MAX_NB_CW                          (2)                      /* number of downlink code word */
 #define DL_ACKNACK_NO_SET                        (2)
 #define DL_NACK                                  (0)
 #define DL_ACK                                   (1)
@@ -68,18 +66,6 @@
 /*************** FUNCTIONS ****************************************/
 
 
-/** \brief This function updates HARQ context according to dci
-    @param PHY_VARS_NR_UE ue context
-    @param nr_dci_info_extracted extracted information from dci
-    @param dlsch downlink context
-    @param ulsch uplink context
-    @param nr_slot_rx rx slot
-    @param tx_offset slot offset for tx
-    @returns none */
-
-void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted,
-		                   NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t nr_slot_rx, uint8_t tx_offset);
-
 /** \brief This function configures uplink HARQ context
     @param PHY_VARS_NR_UE ue context
     @param gNB_id gNodeB identifier
@@ -127,24 +113,6 @@ harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, int ndi, u
 
 void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq);
 
-/** \brief This function configures downlink HARQ context
-    @param PHY_VARS_NR_UE ue context
-    @param gNB_id gNodeB identifier
-    @param TB_id transport block identifier
-    @param execution_thread_number thread_number
-    @param number_harq_processes maximum number of downlink HARQ processes
-    @returns none */
-
-void config_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, int execution_thread_number, uint8_t number_harq_processes);
-
-/** \brief This function releases downlink HARQ context
-    @param PHY_VARS_NR_UE ue context
-    @param gNB_id gNodeB identifier
-    @param TB_id transport block identifier
-    @param execution_thread_number thread_number
-    @returns none */
-
-void release_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, int execution_thread_number);
 
 /** \brief This function update downlink harq context and return reception type (new transmission or retransmission)
     @param dlsch downlink harq context
@@ -152,7 +120,7 @@ void release_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, in
     @param rnti_type type of rnti
     @returns retransmission or new transmission */
 
-harq_result_t downlink_harq_process(NR_DL_UE_HARQ_t *dlsch, int harq_pid, int ndi, uint8_t rnti_type);
+void downlink_harq_process(NR_DL_UE_HARQ_t *dlsch, int harq_pid, int ndi, uint8_t rnti_type);
 
 #undef EXTERN
 #undef INIT_VARIABLES_HARQ_NR_H
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 f516ad863947d5c2d5e05d857adf43980f2db7e3..6ca02050b7e14cdb2210c56fd68a9eeaced38fa3 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};
 
@@ -122,9 +122,10 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
                            uint8_t gNB_id,
                            PHY_VARS_NR_UE *ue,
                            NR_UE_DLSCH_t *dlsch0,
+                           NR_UE_DLSCH_t *dlsch1,
                            uint16_t n_pdus){
 
-  int harq_pid;
+
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
 
   if (n_pdus > 1){
@@ -132,18 +133,37 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
   }
 
   switch (pdu_type){
+    case FAPI_NR_RX_PDU_TYPE_SIB:
+      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.harq_pid = dlsch0->current_harq_pid;
+      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.ack_nack = dlsch0->harq_processes[dlsch0->current_harq_pid]->ack;
+      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dlsch0->harq_processes[dlsch0->current_harq_pid]->b;
+      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS / 8;
+    break;
     case FAPI_NR_RX_PDU_TYPE_DLSCH:
+      if(dlsch0) {
+        rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.harq_pid = dlsch0->current_harq_pid;
+        rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.ack_nack = dlsch0->harq_processes[dlsch0->current_harq_pid]->ack;
+        rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dlsch0->harq_processes[dlsch0->current_harq_pid]->b;
+        rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS / 8;
+      }
+      if(dlsch1) {
+        AssertFatal(1==0,"Second codeword currently not supported\n");
+      }
+      break;
     case FAPI_NR_RX_PDU_TYPE_RAR:
-      harq_pid = dlsch0->current_harq_pid;
-      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;
+      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.harq_pid = dlsch0->current_harq_pid;
+      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.ack_nack = dlsch0->harq_processes[dlsch0->current_harq_pid]->ack;
+      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dlsch0->harq_processes[dlsch0->current_harq_pid]->b;
+      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->harq_processes[dlsch0->current_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;
-      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;
+      rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.rsrp_dBm = ue->measurements.rsrp_dBm[gNB_id];
     break;
     default:
     break;
@@ -202,20 +222,15 @@ uint8_t get_ra_PreambleIndex(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_id){
 
 }
 
-
-// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
-uint16_t get_bw_scaling(uint16_t nb_rb){
-  uint16_t bw_scaling;
-  switch (nb_rb) {
-    case 32:  bw_scaling =  4; break;
-    case 66:  bw_scaling =  8; break;
-    case 106: bw_scaling = 16; break;
-    case 217: bw_scaling = 32; break;
-    case 245: bw_scaling = 32; break;
-    case 273: bw_scaling = 32; break;
-    default: abort();
-  }
-  return bw_scaling;
+// convert time factor "16 * 64 * T_c / (2^mu)" in N_TA calculation in TS38.213 section 4.2 to samples by multiplying with samples per second
+//   16 * 64 * T_c            / (2^mu) * samples_per_second
+// = 16 * T_s                 / (2^mu) * samples_per_second
+// = 16 * 1 / (15 kHz * 2048) / (2^mu) * (15 kHz * 2^mu * ofdm_symbol_size)
+// = 16 * 1 /           2048           *                  ofdm_symbol_size
+// = 16 * ofdm_symbol_size / 2048
+static inline
+uint16_t get_bw_scaling(uint16_t ofdm_symbol_size){
+  return 16 * ofdm_symbol_size / 2048;
 }
 
 // UL time alignment procedures:
@@ -233,38 +248,18 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){
 
     if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) {
 
-      uint8_t numerology = ue->frame_parms.numerology_index;
-      uint16_t bwp_ul_NB_RB = ue->frame_parms.N_RB_UL;
-      int factor_mu = 1 << numerology;
-      uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB);
-
-      LOG_D(PHY, "In %s: applying timing advance -- frame %d -- slot %d -- UE_mode %d\n", __FUNCTION__, frame_tx, slot_tx, ue->UE_mode[gNB_id]);
+      uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size;
+      uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size);
 
-      if (ue->UE_mode[gNB_id] == RA_RESPONSE){
+      ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling;
 
-        ue->timing_advance = ul_time_alignment->ta_command * bw_scaling / factor_mu;
-
-        LOG_D(PHY, "In %s: [UE %d] [%d.%d] Received (RAR) timing advance command %d new value is %u \n",
-          __FUNCTION__,
-          ue->Mod_id,
-          frame_tx,
-          slot_tx,
-          ul_time_alignment->ta_command,
-          ue->timing_advance);
-
-      } else if (ue->UE_mode[gNB_id] == PUSCH){
-
-        ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling / factor_mu;
-
-        LOG_D(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n",
-          __FUNCTION__,
-          ue->Mod_id,
-          frame_tx,
-          slot_tx,
-          ul_time_alignment->ta_command,
-          ue->timing_advance);
-
-      }
+      LOG_D(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n",
+        __FUNCTION__,
+        ue->Mod_id,
+        frame_tx,
+        slot_tx,
+        ul_time_alignment->ta_command,
+        ue->timing_advance);
 
       ul_time_alignment->ta_frame = -1;
       ul_time_alignment->ta_slot = -1;
@@ -299,25 +294,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
         nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, proc->thread_id, gNB_id);
     }
 
-    if (get_softmodem_params()->usim_test==0) {
-      LOG_D(PHY, "Generating PUCCH\n");
-      pucch_procedures_ue_nr(ue,
-                             gNB_id,
-                             proc,
-                             FALSE);
-    }
-
-    LOG_D(PHY, "Sending Uplink data \n");
-    nr_ue_pusch_common_procedures(ue,
-                                  slot_tx,
-                                  &ue->frame_parms,1);
-
-  }
-
-  if (ue->UE_mode[gNB_id] > NOT_SYNCHED && ue->UE_mode[gNB_id] < PUSCH) {
-    nr_ue_prach_procedures(ue, proc, gNB_id);
   }
-  LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
 #if UE_TIMING_TRACE
@@ -329,7 +306,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
 void nr_ue_measurement_procedures(uint16_t l,
                                   PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
-                                  uint8_t eNB_id,
+                                  uint8_t gNB_id,
                                   uint16_t slot){
 
   NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
@@ -349,7 +326,7 @@ void nr_ue_measurement_procedures(uint16_t l,
 
 #if T_TRACER
     if(slot == 0)
-      T(T_UE_PHY_MEAS, T_INT(eNB_id),  T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx),
+      T(T_UE_PHY_MEAS, T_INT(gNB_id),  T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx),
 	T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)),
 	T_INT((int)ue->measurements.rx_rssi_dBm[0]),
 	T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)),
@@ -368,8 +345,8 @@ void nr_ue_measurement_procedures(uint16_t l,
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN);
 
 
-    //printf("start adjust gain power avg db %d\n", ue->measurements.rx_power_avg_dB[eNB_id]);
-    phy_adjust_gain_nr (ue,ue->measurements.rx_power_avg_dB[eNB_id],eNB_id);
+    //printf("start adjust gain power avg db %d\n", ue->measurements.rx_power_avg_dB[gNB_id]);
+    phy_adjust_gain_nr (ue,ue->measurements.rx_power_avg_dB[gNB_id],gNB_id);
     
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
 
@@ -392,15 +369,14 @@ void nr_ue_pbch_procedures(uint8_t gNB_id,
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
 
-  LOG_D(PHY,"[UE  %d] Frame %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,ue->frame_parms.Nid_cell,gNB_id);
+  LOG_D(PHY,"[UE  %d] Frame %d Slot %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,nr_slot_rx,ue->frame_parms.Nid_cell,gNB_id);
 
   ret = nr_rx_pbch(ue, proc,
-		   ue->pbch_vars[gNB_id],
-		   &ue->frame_parms,
-		   gNB_id,
-		   (ue->frame_parms.ssb_index)&7,
-		   SISO,
-		   ue->high_speed_flag);
+                   ue->pbch_vars[gNB_id],
+                   &ue->frame_parms,
+                   gNB_id,
+                   (ue->frame_parms.ssb_index)&7,
+                   SISO);
 
   if (ret==0) {
 
@@ -459,8 +435,13 @@ void nr_ue_pbch_procedures(uint8_t gNB_id,
     ue->pbch_vars[gNB_id]->pdu_errors++;
 
     if (ue->pbch_vars[gNB_id]->pdu_errors_conseq>=100) {
-      LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
-      exit_fun("More that 100 consecutive PBCH errors! Exiting!\n");
+      if (get_softmodem_params()->non_stop) {
+        LOG_E(PHY,"More that 100 consecutive PBCH errors! Going back to Sync mode!\n");
+        ue->lost_sync = 1;
+      } else {
+        LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
+        exit_fun("More that 100 consecutive PBCH errors! Exiting!\n");
+      }
     }
   }
 
@@ -774,12 +755,12 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
 }
 #endif // NR_PDCCH_SCHED
 
-int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) {
+int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) {
 
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
   int m;
-  int i_mod,eNB_id_i,dual_stream_UE;
+  int i_mod,gNB_id_i,dual_stream_UE;
   int first_symbol_flag=0;
 
   if (!dlsch0)
@@ -795,15 +776,17 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
     uint16_t pdsch_nb_rb    = dlsch0_harq->nb_rb;
     uint16_t s0             = dlsch0_harq->start_symbol;
     uint16_t s1             = dlsch0_harq->nb_symbols;
+    bool is_SI              = dlsch0->rnti_type == _SI_RNTI_;
 
-    LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos);
+    LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0_harq->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0_harq->dlDmrsSymbPos);
 
     for (m = s0; m < (s0 +s1); m++) {
-      if (((1<<m)&dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos) > 0) {
-        for (uint8_t aatx=0; aatx<1; aatx++) {//for MIMO Config: it shall loop over no_layers
+      if (dlsch0_harq->dlDmrsSymbPos & (1 << m)) {
+        for (uint8_t aatx=0; aatx<dlsch0_harq->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers
           nr_pdsch_channel_estimation(ue,
                                       proc,
-                                      0 /*eNB_id*/,
+                                      gNB_id,
+                                      is_SI,
                                       nr_slot_rx,
                                       aatx /*p*/,
                                       m,
@@ -817,20 +800,18 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
           char filename[100];
           for (uint8_t aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
             sprintf(filename,"PDSCH_CHANNEL_frame%d_slot%d_sym%d_port%d_rx%d.m", nr_frame_rx, nr_slot_rx, m, aatx,aarx);
-            int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_estimates;
+            int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
             LOG_M(filename,"channel_F",&dl_ch_estimates[aatx*ue->frame_parms.nb_antennas_rx+aarx][ue->frame_parms.ofdm_symbol_size*m],ue->frame_parms.ofdm_symbol_size, 1, 1);
           }
 #endif
         }
-        if ( ue->high_speed_flag == 0 ) //for slow speed case only estimate the channel once per slot
-          break;
       }
     }
 
     uint16_t first_symbol_with_data = s0;
     uint32_t dmrs_data_re;
 
-    if (ue->dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1)
+    if (dlsch0_harq->dmrsConfigType == NFAPI_NR_DMRS_TYPE1)
       dmrs_data_re = 12 - 6 * dlsch0_harq->n_dmrs_cdm_groups;
     else
       dmrs_data_re = 12 - 4 * dlsch0_harq->n_dmrs_cdm_groups;
@@ -842,7 +823,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
     for (m = s0; m < (s1 + s0); m++) {
  
       dual_stream_UE = 0;
-      eNB_id_i = eNB_id+1;
+      gNB_id_i = gNB_id+1;
       i_mod = 0;
       if (( m==first_symbol_with_data ) && (m<4))
         first_symbol_flag = 1;
@@ -855,43 +836,24 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
         slot = 1;
       start_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]);
 #endif
-      // process DLSCH received in first slot
-      // skip DMRS symbols (will have to check later if PDSCH/DMRS are multiplexed
-      if (((1<<m)&dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos) == 0) { 
+      // process DLSCH received symbols in the slot
+      // symbol by symbol processing (if data/DMRS are multiplexed is checked inside the function)
+      if (pdsch == PDSCH || pdsch == SI_PDSCH || pdsch == RA_PDSCH) {
         if (nr_rx_pdsch(ue,
-                    proc,
-                    pdsch,
-                    eNB_id,
-                    eNB_id_i,
-                    frame_rx,
-                    nr_slot_rx,
-                    m,
-                    first_symbol_flag,
-                    dual_stream_UE,
-                    i_mod,
-                    dlsch0->current_harq_pid) < 0)
-                      return -1;
-        }
-      else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS)
-        if (pdsch == RA_PDSCH) ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]=ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m-1];
-        else if (pdsch == PDSCH || pdsch == SI_PDSCH) {
-          if (nr_rx_pdsch(ue,
-                    proc,
-                    pdsch,
-                    eNB_id,
-                    eNB_id_i,
-                    frame_rx,
-                    nr_slot_rx,
-                    m,
-                    first_symbol_flag,
-                    dual_stream_UE,
-                    i_mod,
-                    dlsch0->current_harq_pid) < 0)
-                      return -1;
-        }
-        else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n");
-      }
-      if (pdsch == PDSCH)  LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]);
+                        proc,
+                        pdsch,
+                        gNB_id,
+                        gNB_id_i,
+                        frame_rx,
+                        nr_slot_rx,
+                        m,
+                        first_symbol_flag,
+                        dual_stream_UE,
+                        i_mod,
+                        harq_pid) < 0)
+          return -1;
+      } else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n");
+
 #if UE_TIMING_TRACE
       stop_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]);
 #if DISABLE_LOG_X
@@ -901,23 +863,22 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
 #endif
 #endif
 
-      if(first_symbol_flag)
-	{
-          proc->first_symbol_available = 1;
-	}
+      if(first_symbol_flag) {
+        proc->first_symbol_available = 1;
+      }
     } // CRNTI active
   }
   return 0;
 }
 
 void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
-       UE_nr_rxtx_proc_t *proc,
-       int eNB_id,
-       PDSCH_t pdsch,
-       NR_UE_DLSCH_t *dlsch0,
-       NR_UE_DLSCH_t *dlsch1,
-       int *dlsch_errors,
-       uint8_t dlsch_parallel) {
+                            UE_nr_rxtx_proc_t *proc,
+                            int gNB_id,
+                            PDSCH_t pdsch,
+                            NR_UE_DLSCH_t *dlsch0,
+                            NR_UE_DLSCH_t *dlsch1,
+                            int *dlsch_errors,
+                            uint8_t dlsch_parallel) {
 
   if (dlsch0==NULL)
     AssertFatal(0,"dlsch0 should be defined at this level \n");
@@ -925,35 +886,21 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
   int harq_pid = dlsch0->current_harq_pid;
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
-  int ret=0, ret1=0;
+  uint32_t ret = UINT32_MAX, ret1 = UINT32_MAX;
   NR_UE_PDSCH *pdsch_vars;
-  uint8_t is_cw0_active = 0;
-  uint8_t is_cw1_active = 0;
-  uint8_t dmrs_type, nb_re_dmrs;
   uint16_t dmrs_len = get_num_dmrs(dlsch0->harq_processes[dlsch0->current_harq_pid]->dlDmrsSymbPos);
-  uint16_t nb_symb_sch = 9;
   nr_downlink_indication_t dl_indication;
   fapi_nr_rx_indication_t rx_ind;
   uint16_t number_pdus = 1;
   // params for UL time alignment procedure
-  NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id];
-  uint16_t slots_per_frame = ue->frame_parms.slots_per_frame;
-  uint16_t slots_per_subframe = ue->frame_parms.slots_per_subframe;
-  uint8_t numerology = ue->frame_parms.numerology_index, mapping_type_ul, mapping_type_dl;
-  int ul_tx_timing_adjustment, N_TA_max, factor_mu, N_t_1, N_t_2, N_1, N_2, d_1_1 = 0, d_2_1, d;
-  uint8_t d_2_2 = 0;// set to 0 because there is only 1 BWP
-                    // TODO this should corresponds to the switching time as defined in
-                    // TS 38.133
-  uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size;
-  uint16_t nb_prefix_samples = ue->frame_parms.nb_prefix_samples;
-  uint32_t t_subframe = 1; // subframe duration of 1 msec
-  uint16_t start_symbol;
-  float tc_factor;
-
-  is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
-  nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
-  start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol;
-  dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
+  NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id];
+
+  uint8_t is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
+  uint16_t nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
+  uint16_t start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol;
+  uint8_t dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
+
+  uint8_t nb_re_dmrs;
   if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
     nb_re_dmrs = 6*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
   }
@@ -961,6 +908,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     nb_re_dmrs = 4*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
   }
 
+  uint8_t is_cw1_active = 0;
   if(dlsch1)
     is_cw1_active = dlsch1->harq_processes[harq_pid]->status;
 
@@ -982,7 +930,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     case RA_PDSCH:
     case P_PDSCH:
     case PDSCH:
-      pdsch_vars = ue->pdsch_vars[proc->thread_id][eNB_id];
+      pdsch_vars = ue->pdsch_vars[proc->thread_id][gNB_id];
       break;
     case PMCH:
     case PDSCH1:
@@ -1000,8 +948,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
       *dlsch_errors=0;
 
     if (pdsch == RA_PDSCH) {
-      if (ue->prach_resources[eNB_id]!=NULL)
-	      dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+      if (ue->prach_resources[gNB_id]!=NULL)
+	      dlsch0->rnti = ue->prach_resources[gNB_id]->ra_RNTI;
       else {
 	      LOG_E(PHY,"[UE %d] Frame %d, nr_slot_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_slot_rx);
 	      //mac_xface->macphy_exit("prach_resources is NULL");
@@ -1021,17 +969,17 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
                                                    dlsch0->harq_processes[harq_pid]->Qm,
                                                    dlsch0->harq_processes[harq_pid]->Nl);
 #if UE_TIMING_TRACE
-      start_meas(&ue->dlsch_unscrambling_stats);
+    start_meas(&ue->dlsch_unscrambling_stats);
 #endif
-      nr_dlsch_unscrambling(pdsch_vars->llr[0],
-                            dlsch0->harq_processes[harq_pid]->G,
-                            0,
-                            ue->frame_parms.Nid_cell,
-                            dlsch0->rnti);
+    nr_dlsch_unscrambling(pdsch_vars->llr[0],
+                          dlsch0->harq_processes[harq_pid]->G,
+                          0,
+                          ue->frame_parms.Nid_cell,
+                          dlsch0->rnti);
       
 
 #if UE_TIMING_TRACE
-      stop_meas(&ue->dlsch_unscrambling_stats);
+    stop_meas(&ue->dlsch_unscrambling_stats);
 #endif
 
 #if 0
@@ -1042,83 +990,103 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
       LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl);
       LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G);
       LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->Kmimo);
-      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols);
+      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][gNB_id]->num_pdcch_symbols);
 #endif
 
 #if UE_TIMING_TRACE
-      start_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
+    start_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
 #endif
 
-  if( dlsch_parallel)
-    {
-    ret = nr_dlsch_decoding_mthread(ue,
-			   proc,
-			   eNB_id,
-			   pdsch_vars->llr[0],
-			   &ue->frame_parms,
-			   dlsch0,
-			   dlsch0->harq_processes[harq_pid],
-			   frame_rx,
-			   nb_symb_sch,
-			   nr_slot_rx,
-			   harq_pid,
-			   pdsch==PDSCH?1:0,
-			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
-    LOG_T(PHY,"dlsch decoding is parallelized, ret = %d\n", ret);
+    if( dlsch_parallel) {
+      ret = nr_dlsch_decoding_mthread(ue,
+                                      proc,
+                                      gNB_id,
+                                      pdsch_vars->llr[0],
+                                      &ue->frame_parms,
+                                      dlsch0,
+                                      dlsch0->harq_processes[harq_pid],
+                                      frame_rx,
+                                      nb_symb_sch,
+                                      nr_slot_rx,
+                                      harq_pid,
+                                      pdsch==PDSCH?1:0,
+                                      dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
+
+      LOG_T(PHY,"dlsch decoding is parallelized, ret = %d\n", ret);
     }
-  else
-    {
-    ret = nr_dlsch_decoding(ue,
-			   proc,
-			   eNB_id,
-			   pdsch_vars->llr[0],
-			   &ue->frame_parms,
-			   dlsch0,
-			   dlsch0->harq_processes[harq_pid],
-			   frame_rx,
-			   nb_symb_sch,
-			   nr_slot_rx,
-			   harq_pid,
-			   pdsch==PDSCH?1:0,
-			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
+    else {
+      ret = nr_dlsch_decoding(ue,
+                              proc,
+                              gNB_id,
+                              pdsch_vars->llr[0],
+                              &ue->frame_parms,
+                              dlsch0,
+                              dlsch0->harq_processes[harq_pid],
+                              frame_rx,
+                              nb_symb_sch,
+                              nr_slot_rx,
+                              harq_pid,
+                              pdsch==PDSCH?1:0,
+                              dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
       LOG_T(PHY,"Sequential dlsch decoding , ret = %d\n", ret);
-     }
+    }
+
+
+    switch (pdsch) {
+      case RA_PDSCH:
+        nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
+        nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, NULL, number_pdus);
+        ue->UE_mode[gNB_id] = RA_RESPONSE;
+        break;
+      case PDSCH:
+        nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
+        nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, NULL, number_pdus);
+        break;
+      case SI_PDSCH:
+        nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
+        nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, NULL, number_pdus);
+        break;
+      default:
+        break;
+    }
+
+    LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch0->harq_processes[harq_pid]->TBS, dlsch0->harq_processes[harq_pid]->TBS / 8);
+
 
 
 #if UE_TIMING_TRACE
-      stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
+    stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
 #if DISABLE_LOG_X
-      printf(" --> Unscrambling for CW0 %5.3f\n",
-              (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
-      printf("AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n",
-              frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
+    printf(" --> Unscrambling for CW0 %5.3f\n",
+           (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+    printf("AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n",
+           frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
 #else
-      LOG_I(PHY, " --> Unscrambling for CW0 %5.3f\n",
-              (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
-      LOG_I(PHY, "AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n",
-              frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
+    LOG_I(PHY, " --> Unscrambling for CW0 %5.3f\n",
+          (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+    LOG_I(PHY, "AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n",
+          frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
 #endif
 
 #endif
-      if(is_cw1_active)
-      {
-          // start ldpc decode for CW 1
-        dlsch1->harq_processes[harq_pid]->G = nr_get_G(dlsch1->harq_processes[harq_pid]->nb_rb,
-                                                       nb_symb_sch,
-                                                       nb_re_dmrs,
-                                                       dmrs_len,
-                                                       dlsch1->harq_processes[harq_pid]->Qm,
-							 dlsch1->harq_processes[harq_pid]->Nl);
+    if(is_cw1_active) {
+      // start ldpc decode for CW 1
+      dlsch1->harq_processes[harq_pid]->G = nr_get_G(dlsch1->harq_processes[harq_pid]->nb_rb,
+                                                     nb_symb_sch,
+                                                     nb_re_dmrs,
+                                                     dmrs_len,
+                                                     dlsch1->harq_processes[harq_pid]->Qm,
+                                                     dlsch1->harq_processes[harq_pid]->Nl);
 #if UE_TIMING_TRACE
-          start_meas(&ue->dlsch_unscrambling_stats);
+      start_meas(&ue->dlsch_unscrambling_stats);
 #endif
-          nr_dlsch_unscrambling(pdsch_vars->llr[1],
-                                dlsch1->harq_processes[harq_pid]->G,
-                                0,
-                                ue->frame_parms.Nid_cell,
-                                dlsch1->rnti);
+      nr_dlsch_unscrambling(pdsch_vars->llr[1],
+                            dlsch1->harq_processes[harq_pid]->G,
+                            0,
+                            ue->frame_parms.Nid_cell,
+                            dlsch1->rnti);
 #if UE_TIMING_TRACE
-          stop_meas(&ue->dlsch_unscrambling_stats);
+      stop_meas(&ue->dlsch_unscrambling_stats);
 #endif
 
 #if 0
@@ -1128,211 +1096,207 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
           LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl);
           LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G);
           LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->Kmimo);
-          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols);
+          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][gNB_id]->num_pdcch_symbols);
 #endif
 
 #if UE_TIMING_TRACE
-          start_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
+      start_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
 #endif
 
-  if(dlsch_parallel)
-    {
-    ret1 = nr_dlsch_decoding_mthread(ue,
-                                     proc,
-                                     eNB_id,
-                                     pdsch_vars->llr[1],
-                                     &ue->frame_parms,
-                                     dlsch1,
-                                     dlsch1->harq_processes[harq_pid],
-                                     frame_rx,
-                                     nb_symb_sch,
-				     nr_slot_rx,
-                                     harq_pid,
-                                     pdsch==PDSCH?1:0,
-                                     dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
-          LOG_T(PHY,"CW dlsch decoding is parallelized, ret1 = %d\n", ret1);
-    }
-    else
-    {
-    ret1 = nr_dlsch_decoding(ue,
-			     proc,
-			     eNB_id,
-                             pdsch_vars->llr[1],
-                             &ue->frame_parms,
-                             dlsch1,
-                             dlsch1->harq_processes[harq_pid],
-                             frame_rx,
-                             nb_symb_sch,
-                             nr_slot_rx,
-                             harq_pid,
-                             pdsch==PDSCH?1:0,//proc->decoder_switch,
-                             dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
-    LOG_T(PHY,"CWW sequential dlsch decoding, ret1 = %d\n", ret1);
-    }
+      if(dlsch_parallel) {
+        ret1 = nr_dlsch_decoding_mthread(ue,
+                                         proc,
+                                         gNB_id,
+                                         pdsch_vars->llr[1],
+                                         &ue->frame_parms,
+                                         dlsch1,
+                                         dlsch1->harq_processes[harq_pid],
+                                         frame_rx,
+                                         nb_symb_sch,
+				         nr_slot_rx,
+                                         harq_pid,
+                                         pdsch==PDSCH?1:0,
+                                        dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
+        LOG_T(PHY,"CW dlsch decoding is parallelized, ret1 = %d\n", ret1);
+      }
+      else {
+        ret1 = nr_dlsch_decoding(ue,
+                                 proc,
+                                 gNB_id,
+                                 pdsch_vars->llr[1],
+                                 &ue->frame_parms,
+                                 dlsch1,
+                                 dlsch1->harq_processes[harq_pid],
+                                 frame_rx,
+                                 nb_symb_sch,
+                                 nr_slot_rx,
+                                 harq_pid,
+                                 pdsch==PDSCH?1:0,//proc->decoder_switch,
+                                 dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
+        LOG_T(PHY,"CWW sequential dlsch decoding, ret1 = %d\n", ret1);
+      }
 
 #if UE_TIMING_TRACE
-          stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
+      stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
 #if DISABLE_LOG_X
-          printf(" --> Unscrambling for CW1 %5.3f\n",
-                  (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
-          printf("AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
-                  frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
+      printf(" --> Unscrambling for CW1 %5.3f\n",
+             (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+      printf("AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
+             frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
 #else
-          LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n",
-                  (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
-          LOG_D(PHY, "AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
-                  frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
+      LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n",
+            (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+      LOG_D(PHY, "AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
+            frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
 #endif
 
 #endif
-          LOG_I(PHY,"AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
-                  frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
+      LOG_D(PHY,"AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
+            frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
 
-        LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch1->harq_processes[harq_pid]->TBS);
-      }
 
-      LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------  \n", frame_rx, nr_slot_rx);
-      LOG_D(PHY, "harq_pid: %d, TBS expected dlsch0: %d  \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS);
-
-      if(ret<dlsch0->max_ldpc_iterations+1){
-
-        switch (pdsch) {
-          case RA_PDSCH:
-            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id);
-            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, eNB_id, ue, dlsch0, number_pdus);
-
-            ue->UE_mode[eNB_id] = RA_RESPONSE;
-            break;
-          case PDSCH:
-            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id);
-            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, eNB_id, ue, dlsch0, number_pdus);
-            break;
-          case SI_PDSCH:
-            rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_SIB;
-            break;
-          default:
-            break;
-        }
+      LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch1->harq_processes[harq_pid]->TBS);
+    }
 
-        LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch0->harq_processes[harq_pid]->TBS, dlsch0->harq_processes[harq_pid]->TBS / 8);
+    LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ decoded in %d \n", frame_rx, nr_slot_rx, ret);
 
-        //  send to mac
-        if (ue->if_inst && ue->if_inst->dl_indication) {
-          ue->if_inst->dl_indication(&dl_indication, ul_time_alignment);
-        }
-      }
+    //  send to mac
+    if (ue->if_inst && ue->if_inst->dl_indication) {
+      ue->if_inst->dl_indication(&dl_indication, ul_time_alignment);
+    }
 
-      // TODO CRC check for CW0
-
-      // Check CRC for CW 0
-      /*if (ret == (1+dlsch0->max_turbo_iterations)) {
-        *dlsch_errors=*dlsch_errors+1;
-        if(dlsch0->rnti != 0xffff){
-          LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n",
-          ue->Mod_id,dlsch0->rnti,
-          harq_pid,frame_rx,nr_slot_rx,
-          dlsch0->harq_processes[harq_pid]->rvidx,
-          dlsch0->harq_processes[harq_pid]->round,
-          dlsch0->harq_processes[harq_pid]->mcs,
-          dlsch0->harq_processes[harq_pid]->TBS);
-        }
-      } else {
-        if(dlsch0->rnti != 0xffff){
-          LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n",
-          ue->Mod_id,dlsch0->rnti,
-          harq_pid,frame_rx,nr_slot_rx,
-          dlsch0->harq_processes[harq_pid]->rvidx,
-          dlsch0->harq_processes[harq_pid]->round,
-          dlsch0->harq_processes[harq_pid]->mcs,
-          dlsch0->harq_processes[harq_pid]->TBS);
-        }
-        if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){
-          int j;
-          LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid);
-
-          for (j=0; j<dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3; j++)
-            LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);
-          LOG_T(PHY,"\n");
-      }*/
-
-      if (ue->mac_enabled == 1) {
-
-        uint16_t bw_scaling = get_bw_scaling(ue->frame_parms.N_RB_DL);
-
-        /* Time Alignment procedure
-        // - UE processing capability 1
-        // - Setting the TA update to be applied after the reception of the TA command
-        // - Timing adjustment computed according to TS 38.213 section 4.2
-        // - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are
-        //   computed according to sections 5.3 and 6.4 of TS 38.214 */
-        factor_mu = 1 << numerology;
-        N_TA_max = 3846 * bw_scaling / factor_mu;
-
-        /* PDSCH decoding time N_1 for processing capability 1 */
-        if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos0)
-          N_1 = pdsch_N_1_capability_1[numerology][1];
-        else if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos1 || ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == 2) // TODO set to pdsch_dmrs_pos2 when available
-          N_1 = pdsch_N_1_capability_1[numerology][2];
+    if (ue->mac_enabled == 1) { // TODO: move this from PHY to MAC layer!
+
+      /* Time Alignment procedure
+      // - UE processing capability 1
+      // - Setting the TA update to be applied after the reception of the TA command
+      // - Timing adjustment computed according to TS 38.213 section 4.2
+      // - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are
+      //   computed according to sections 5.3 and 6.4 of TS 38.214 */
+      const int numerology = ue->frame_parms.numerology_index;
+      const int ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size;
+      const int nb_prefix_samples = ue->frame_parms.nb_prefix_samples;
+      const int samples_per_subframe = ue->frame_parms.samples_per_subframe;
+      const int slots_per_frame = ue->frame_parms.slots_per_frame;
+      const int slots_per_subframe = ue->frame_parms.slots_per_subframe;
+
+      const double tc_factor = 1.0 / samples_per_subframe;
+      const uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size);
+
+      const int Ta_max = 3846; // Max value of 12 bits TA Command
+      const double N_TA_max = Ta_max * bw_scaling * tc_factor;
+
+      NR_UE_MAC_INST_t *mac = get_mac_inst(0);
+
+      NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
+      if (mac->ULbwp[0] &&
+          mac->ULbwp[0]->bwp_Dedicated &&
+          mac->ULbwp[0]->bwp_Dedicated->pusch_Config &&
+          mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup &&
+          mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
+        pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
+      }
+      else if (mac->ULbwp[0] &&
+               mac->ULbwp[0]->bwp_Common &&
+               mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon &&
+               mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup &&
+               mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+        pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+      }
+      else if (mac->scc_SIB &&
+               mac->scc_SIB->uplinkConfigCommon &&
+               mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon &&
+               mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup &&
+               mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+        pusch_TimeDomainAllocationList = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+      }
+      long mapping_type_ul = pusch_TimeDomainAllocationList ? pusch_TimeDomainAllocationList->list.array[0]->mappingType : NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA;
+
+      NR_PDSCH_Config_t *pdsch_Config = (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup) ? mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup : NULL;
+      NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL;
+      if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
+        pdsch_TimeDomainAllocationList = pdsch_Config->pdsch_TimeDomainAllocationList->choice.setup;
+      else if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
+        pdsch_TimeDomainAllocationList = mac->DLbwp[0]->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;
+      long mapping_type_dl = pdsch_TimeDomainAllocationList ? pdsch_TimeDomainAllocationList->list.array[0]->mappingType : NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA;
+
+      NR_DMRS_DownlinkConfig_t *NR_DMRS_dlconfig = NULL;
+      if (pdsch_Config) {
+        if (mapping_type_dl == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA)
+          NR_DMRS_dlconfig = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup;
         else
-          N_1 = pdsch_N_1_capability_1[numerology][3];
+          NR_DMRS_dlconfig = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup;
+      }
+
+      pdsch_dmrs_AdditionalPosition_t add_pos_dl = pdsch_dmrs_pos2;
+      if (NR_DMRS_dlconfig && NR_DMRS_dlconfig->dmrs_AdditionalPosition)
+        add_pos_dl = *NR_DMRS_dlconfig->dmrs_AdditionalPosition;
 
-        /* PUSCH preapration time N_2 for processing capability 1 */
-        N_2 = pusch_N_2_timing_capability_1[numerology][1];
-        mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType;
-        mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
+      /* PDSCH decoding time N_1 for processing capability 1 */
+      int N_1;
 
-        /* d_1_1 depending on the number of PDSCH symbols allocated */
-        d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH
-        if (mapping_type_dl == typeA)
-         if (nb_symb_sch + start_symbol < 7)
+      if (add_pos_dl == pdsch_dmrs_pos0)
+        N_1 = pdsch_N_1_capability_1[numerology][1];
+      else if (add_pos_dl == pdsch_dmrs_pos1 || add_pos_dl == pdsch_dmrs_pos2)
+        N_1 = pdsch_N_1_capability_1[numerology][2];
+      else
+        N_1 = pdsch_N_1_capability_1[numerology][3];
+
+      /* PUSCH preapration time N_2 for processing capability 1 */
+      const int N_2 = pusch_N_2_timing_capability_1[numerology][1];
+
+      /* d_1_1 depending on the number of PDSCH symbols allocated */
+      const int d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH
+      int d_1_1 = 0;
+      if (mapping_type_dl == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA)
+       if (nb_symb_sch + start_symbol < 7)
           d_1_1 = 7 - (nb_symb_sch + start_symbol);
-         else
+        else
           d_1_1 = 0;
-        else // mapping type B
-          switch (nb_symb_sch){
-            case 7: d_1_1 = 0; break;
-            case 4: d_1_1 = 3; break;
-            case 2: d_1_1 = 3 + d; break;
-            default: break;
-          }
+      else // mapping type B
+        switch (nb_symb_sch){
+          case 7: d_1_1 = 0; break;
+          case 4: d_1_1 = 3; break;
+          case 2: d_1_1 = 3 + d; break;
+          default: break;
+        }
 
-        /* d_2_1 */
-        if (mapping_type_ul == typeB && start_symbol != 0)
-          d_2_1 = 0;
-        else
-          d_2_1 = 1;
-
-        /* N_t_1 time duration in msec of N_1 symbols corresponding to a PDSCH reception time
-        // N_t_2 time duration in msec of N_2 symbols corresponding to a PUSCH preparation time */
-        N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu;
-        N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu;
-        if (N_t_2 < d_2_2) N_t_2 = d_2_2;
-
-        /* Time alignment procedure */
-        // N_t_1 + N_t_2 + N_TA_max is in unit of Ts, therefore must be converted to Tc
-        // N_t_1 + N_t_2 + N_TA_max must be in msec
-        tc_factor = 64 * 0.509 * 10e-7;
-        ul_tx_timing_adjustment = 1 + ceil(slots_per_subframe*((N_t_1 + N_t_2 + N_TA_max)*tc_factor + 0.5)/t_subframe);
-
-        if (ul_time_alignment->apply_ta == 1){
-          ul_time_alignment->ta_slot = (nr_slot_rx + ul_tx_timing_adjustment) % slots_per_frame;
-          if (nr_slot_rx + ul_tx_timing_adjustment > slots_per_frame){
-            ul_time_alignment->ta_frame = (frame_rx + 1) % 1024;
-          } else {
-            ul_time_alignment->ta_frame = frame_rx;
-          }
-          // reset TA flag
-          ul_time_alignment->apply_ta = 0;
-          LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", frame_rx, nr_slot_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot);
+      /* d_2_1 */
+      int d_2_1;
+      if (mapping_type_ul == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB && start_symbol != 0)
+        d_2_1 = 0;
+      else
+        d_2_1 = 1;
+
+      /* d_2_2 */
+      const double d_2_2 = 0.0; // set to 0 because there is only 1 BWP: TODO this should corresponds to the switching time as defined in TS 38.133
+
+      /* N_t_1 time duration in msec of N_1 symbols corresponding to a PDSCH reception time
+      // N_t_2 time duration in msec of N_2 symbols corresponding to a PUSCH preparation time */
+      double N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor;
+      double N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor;
+      if (N_t_2 < d_2_2) N_t_2 = d_2_2;
+
+      /* Time alignment procedure */
+      // N_t_1 + N_t_2 + N_TA_max must be in msec
+      const double t_subframe = 1.0; // subframe duration of 1 msec
+      const int ul_tx_timing_adjustment = 1 + (int)ceil(slots_per_subframe*(N_t_1 + N_t_2 + N_TA_max + 0.5)/t_subframe);
+
+      if (ul_time_alignment->apply_ta == 1){
+        ul_time_alignment->ta_slot = (nr_slot_rx + ul_tx_timing_adjustment) % slots_per_frame;
+        if (nr_slot_rx + ul_tx_timing_adjustment > slots_per_frame){
+          ul_time_alignment->ta_frame = (frame_rx + 1) % 1024;
+        } else {
+          ul_time_alignment->ta_frame = frame_rx;
         }
+        // reset TA flag
+        ul_time_alignment->apply_ta = 0;
+        LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n",
+             frame_rx, nr_slot_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot);
       }
-
-      /*ue->total_TBS[eNB_id] =  ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
-      ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
-    }*/
-
-    // TODO CRC check for CW1
-
+    }
   }
 }
 
@@ -1526,9 +1490,9 @@ void *UE_thread_slot1_dl_processing(void *arg) {
 #endif
     // start slave thread for Pdsch Procedure (slot1)
     // do procedures for C-RNTI
-    uint8_t eNB_id = 0;
+    uint8_t gNB_id = 0;
 
-    if (ue->dlsch[proc->thread_id][eNB_id][0]->active == 1) {
+    if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) {
       //wait until first ofdm symbol is processed
       //wait = 0;
       //while(proc->first_symbol_available == 0)
@@ -1541,9 +1505,9 @@ void *UE_thread_slot1_dl_processing(void *arg) {
       //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
       ue_pdsch_procedures(ue,
 			  proc,
-			  eNB_id,
+			  gNB_id,
 			  PDSCH,
-			  ue->dlsch[proc->thread_id][eNB_id][0],
+			  ue->dlsch[proc->thread_id][gNB_id][0],
 			  NULL,
 			  (ue->frame_parms.symbols_per_slot>>1),
 			  ue->frame_parms.symbols_per_slot-1,
@@ -1553,12 +1517,12 @@ void *UE_thread_slot1_dl_processing(void *arg) {
     }
 
     // do procedures for SI-RNTI
-    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+    if ((ue->dlsch_SI[gNB_id]) && (ue->dlsch_SI[gNB_id]->active == 1)) {
       ue_pdsch_procedures(ue,
 			  proc,
-			  eNB_id,
+			  gNB_id,
 			  SI_PDSCH,
-			  ue->dlsch_SI[eNB_id],
+			  ue->dlsch_SI[gNB_id],
 			  NULL,
 			  (ue->frame_parms.symbols_per_slot>>1),
 			  ue->frame_parms.symbols_per_slot-1,
@@ -1566,24 +1530,24 @@ void *UE_thread_slot1_dl_processing(void *arg) {
     }
 
     // do procedures for P-RNTI
-    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+    if ((ue->dlsch_p[gNB_id]) && (ue->dlsch_p[gNB_id]->active == 1)) {
       ue_pdsch_procedures(ue,
 			  proc,
-			  eNB_id,
+			  gNB_id,
 			  P_PDSCH,
-			  ue->dlsch_p[eNB_id],
+			  ue->dlsch_p[gNB_id],
 			  NULL,
 			  (ue->frame_parms.symbols_per_slot>>1),
 			  ue->frame_parms.symbols_per_slot-1,
 			  abstraction_flag);
     }
     // do procedures for RA-RNTI
-    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1) && (UE_mode != PUSCH)) {
+    if ((ue->dlsch_ra[gNB_id]) && (ue->dlsch_ra[gNB_id]->active == 1) && (UE_mode != PUSCH)) {
       ue_pdsch_procedures(ue,
 			  proc,
-			  eNB_id,
+			  gNB_id,
 			  RA_PDSCH,
-			  ue->dlsch_ra[eNB_id],
+			  ue->dlsch_ra[gNB_id],
 			  NULL,
 			  (ue->frame_parms.symbols_per_slot>>1),
 			  ue->frame_parms.symbols_per_slot-1,
@@ -1696,7 +1660,8 @@ int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL
 int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            uint8_t gNB_id,
-                           uint8_t dlsch_parallel
+                           uint8_t dlsch_parallel,
+                           notifiedFIFO_t *txFifo
                            )
 {                                         
   int frame_rx = proc->frame_rx;
@@ -1730,20 +1695,19 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
 
   // looking for pbch only in slot where it is supposed to be
   if (slot_ssb) {
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_IN);
     LOG_D(PHY," ------  PBCH ChannelComp/LLR: frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
     for (int i=1; i<4; i++) {
 
       nr_slot_fep(ue,
                   proc,
                   (ue->symbol_offset+i)%(fp->symbols_per_slot),
-                  nr_slot_rx,
-                  0,
-                  0);
+                  nr_slot_rx);
 
 #if UE_TIMING_TRACE
       start_meas(&ue->dlsch_channel_estimation_stats);
 #endif
-      nr_pbch_channel_estimation(ue,proc,0,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit);
+      nr_pbch_channel_estimation(ue,proc,gNB_id,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit);
 #if UE_TIMING_TRACE
       stop_meas(&ue->dlsch_channel_estimation_stats);
 #endif
@@ -1769,31 +1733,29 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
 
       LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__);
       nr_ue_rrc_measurements(ue, proc, nr_slot_rx);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_OUT);
     }
   }
 
   if ((frame_rx%64 == 0) && (nr_slot_rx==0)) {
-    printf("============================================\n");
+    LOG_I(PHY,"============================================\n");
     LOG_I(PHY,"Harq round stats for Downlink: %d/%d/%d/%d DLSCH errors: %d\n",ue->dl_stats[0],ue->dl_stats[1],ue->dl_stats[2],ue->dl_stats[3],ue->dl_stats[4]);
-    printf("============================================\n");
+    LOG_I(PHY,"============================================\n");
   }
 
 #ifdef NR_PDCCH_SCHED
-  nr_gold_pdcch(ue, 0, 2);
 
   LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_IN);
   for (uint16_t l=0; l<nb_symb_pdcch; l++) {
 
 #if UE_TIMING_TRACE
     start_meas(&ue->ofdm_demod_stats);
 #endif
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
     nr_slot_fep(ue,
                 proc,
                 l,
-                nr_slot_rx,
-                0,
-                0);
+                nr_slot_rx);
 
     dci_cnt = 0;
     for(int n_ss = 0; n_ss<pdcch_vars->nb_search_space; n_ss++) {
@@ -1805,13 +1767,12 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
     if (coreset_nb_rb > 0)
       nr_pdcch_channel_estimation(ue,
                                   proc,
-                                  0,
+                                  gNB_id,
                                   nr_slot_rx,
                                   l,
                                   fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
                                   coreset_nb_rb);
 
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
 #if UE_TIMING_TRACE
     stop_meas(&ue->ofdm_demod_stats);
 #endif
@@ -1819,6 +1780,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
       dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc);
     }
   }
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
 
   if (dci_cnt > 0) {
 
@@ -1834,28 +1796,22 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
     }
 
     if (dlsch) {
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_IN);
       uint8_t harq_pid = dlsch->current_harq_pid;
       NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid];
       uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
       uint16_t start_symb_sch = dlsch0_harq->start_symbol;
-      int symb_dmrs = -1;
 
       LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
       //to update from pdsch config
 
-      for (int i=0;i<4;i++) if (((1<<i)&dlsch0_harq->dlDmrsSymbPos) > 0) {symb_dmrs=i;break;}
-      AssertFatal(symb_dmrs>=0,"no dmrs in 0..3\n");
-      LOG_D(PHY,"Initializing dmrs for slot %d DMRS mask %x\n", nr_slot_rx, dlsch0_harq->dlDmrsSymbPos);
-      nr_gold_pdsch(ue, nr_slot_rx, 0);
-    
       for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){
         nr_slot_fep(ue,
                     proc,
                     m,  //to be updated from higher layer
-                    nr_slot_rx,
-                    0,
-                    0);
+                    nr_slot_rx);
       }
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_OUT);
     }
   } else {
     LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_slot_rx);
@@ -1863,21 +1819,31 @@ 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);
+  curMsg->proc = *proc;
+  curMsg->UE = ue;
+  curMsg->ue_sched_mode = ONLY_PUSCH;
+  pushTpool(&(get_nrUE_params()->Tpool), newElt);
+
 #if UE_TIMING_TRACE
   start_meas(&ue->generic_stat);
 #endif
   // do procedures for C-RNTI
   int ret_pdsch = 0;
   if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) {
-    //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_IN);
     ret_pdsch = nr_ue_pdsch_procedures(ue,
-			   proc,
-			   gNB_id,
-			   PDSCH,
-			   ue->dlsch[proc->thread_id][gNB_id][0],
-			   NULL);
+                                       proc,
+                                       gNB_id,
+                                       PDSCH,
+                                       ue->dlsch[proc->thread_id][gNB_id][0],
+                                       NULL);
 
     nr_ue_measurement_procedures(2, ue, proc, gNB_id, nr_slot_rx);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_OUT);
   }
 
   // do procedures for SI-RNTI
@@ -1926,7 +1892,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
 
     // deactivate dlsch once dlsch proc is done
     ue->dlsch_p[gNB_id]->active = 0;
-
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
   }
 
@@ -1994,6 +1959,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
@@ -2155,19 +2121,18 @@ 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 == 1) {
+  if (nr_prach == GENERATE_PREAMBLE) {
 
     if (ue->mac_enabled == 1) {
       int16_t pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id);
-      int16_t ra_preamble_rx_power = (int16_t)(10*log10(pow(10, (double)(prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER)/10) + pow(10, (double)(pathloss)/10)));
+      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,"[UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d, 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,
@@ -2206,18 +2171,15 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
     if (ue->mac_enabled == 1)
       nr_Msg1_transmitted(mod_id, ue->CC_id, frame_tx, gNB_id);
 
-  } else if (nr_prach == 2) {
-
+  } else if (nr_prach == WAIT_CONTENTION_RESOLUTION) {
+    LOG_D(PHY, "In %s: [UE %d] RA waiting contention resolution\n", __FUNCTION__, mod_id);
+    ue->UE_mode[gNB_id] = RA_WAIT_CR;
+  } else if (nr_prach == RA_SUCCEEDED) {
     LOG_D(PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, mod_id);
-
     ue->UE_mode[gNB_id] = PUSCH;
-
-  } else if(nr_prach == 3){
-
+  } else if(nr_prach == RA_FAILED){
     LOG_D(PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, mod_id);
-
     ue->UE_mode[gNB_id] = PRACH;
-
   }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
deleted file mode 100644
index f43f4d98c99f9c33bd8504b3acd11face872df20..0000000000000000000000000000000000000000
--- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-/************************************************************************
-*
-* MODULE      :  PUCCH power control for UE NR
-*
-* DESCRIPTION :  functions related to PUCCH Transmit power
-*                TS 38.213 7.2.1 UE behaviour
-*
-**************************************************************************/
-
-#include "PHY/NR_REFSIG/ss_pbch_nr.h"
-#include "PHY/defs_nr_UE.h"
-#include "SCHED_NR_UE/pucch_uci_ue_nr.h"
-#include "SCHED_NR_UE/pucch_power_control_ue_nr.h"
-#include <openair1/PHY/LTE_ESTIMATION/lte_estimation.h>
-#include <openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h>
-
-/**************** defines **************************************/
-
-/**************** variables **************************************/
-
-
-/**************** functions **************************************/
-
-
-/*******************************************************************
-*
-* NAME :         get_pucch_tx_power_ue
-*
-* PARAMETERS :   ue context
-*                gNB_id identity
-*                slots for rx and tx
-*                pucch_format_nr_t pucch format
-*                nb_of_prbs number of prb allocated to pucch
-*                N_sc_ctrl_RB subcarrier control rb related to current pucch format
-*                N_symb_PUCCH number of pucch symbols excluding those reserved for dmrs
-*                O_UCI number of bits for UCI Uplink Control Information
-*                O_SR number of bits for SR scheduling Request
-*                O_UCI number of  bits for CSI Channel State Information
-*                O_ACK number of bits for HARQ-ACK
-*                O_CRC number of bits for CRC
-*                n_HARQ_ACK use for obtaining a PUCCH transmission power
-*
-* RETURN :       pucch power level in dBm
-*
-* DESCRIPTION :  determines pucch transmission power in dBm
-*                TS 38.213 7.2.1 UE behaviour
-*
-*********************************************************************/
-
-int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue,
-                              uint8_t gNB_id,
-                              UE_nr_rxtx_proc_t *proc,
-                              pucch_format_nr_t pucch_format,
-                              int nb_of_prbs,
-                              int N_sc_ctrl_RB,
-                              int N_symb_PUCCH,
-                              int O_UCI,
-                              int O_SR,
-                              int O_CSI,
-                              int O_ACK,
-                              int O_CRC,
-                              int n_HARQ_ACK) {
-
-  int16_t P_O_NOMINAL_PUCCH = ue->pucch_config_common_nr[gNB_id].p0_nominal;
-  PUCCH_PowerControl_t *power_config = &ue->pucch_config_dedicated_nr[gNB_id].pucch_PowerControl;
-  int16_t P_O_UE_PUCCH;
-  int16_t G_b_f_c = 0;
-
-  if (ue->pucch_config_dedicated_nr[gNB_id].spatial_Relation_Info[0] != NULL) {  /* FFS TODO NR */
-    LOG_E(PHY,"PUCCH Spatial relation infos are not yet implemented : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
-    return (PUCCH_POWER_DEFAULT);
-  }
-
-  if (power_config->p0_Set[0] != NULL) {
-    P_O_UE_PUCCH = power_config->p0_Set[0]->p0_PUCCH_Value; /* get from index 0 if no spatial relation set */
-    G_b_f_c = 0;
-  }
-  else {
-    G_b_f_c = ue->dlsch[proc->thread_id][gNB_id][0]->g_pucch;
-    LOG_D(PHY,"PUCCH Transmit power control command not yet implemented for NR : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
-    return (PUCCH_POWER_DEFAULT);
-  }
-
-  int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH;
-
-  int16_t PL = get_nr_PL(ue->Mod_id, ue->CC_id, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */
-
-  int16_t delta_F_PUCCH =  power_config->deltaF_PUCCH_f[pucch_format];
-
-  int DELTA_TF;
-  uint16_t N_ref_PUCCH;
-
-  /* computing of pucch transmission power adjustment */
-  switch (pucch_format) {
-    case pucch_format0_nr:
-    {
-      N_ref_PUCCH = 2;
-      DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH);
-      break;
-    }
-    case pucch_format1_nr:
-    {
-      N_ref_PUCCH = N_SYMB_SLOT;
-      DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH);
-      break;
-    }
-    case pucch_format2_nr:
-    case pucch_format3_nr:
-    case pucch_format4_nr:
-    {
-      float N_RE = nb_of_prbs * N_sc_ctrl_RB * N_symb_PUCCH;
-      float K1 = 6;
-      /* initial phase so no higher layer parameters */
-      if (ue->UE_mode[gNB_id] != PUSCH) {
-        if (O_ACK == 0) {
-          n_HARQ_ACK = 0;
-        }
-        else {
-          n_HARQ_ACK = 1;
-        }
-      }
-      if (O_UCI < 12) {
-
-        DELTA_TF = 10 * log10((double)(((K1 * (n_HARQ_ACK + O_SR + O_CSI))/N_RE)));
-      }
-      else {
-       float K2 = 2.4;
-       float BPRE = (O_ACK + O_SR + O_CSI + O_CRC)/N_RE;
-       DELTA_TF = 10 * log10((double)(pow(2,(K2*BPRE)) - 1));
-      }
-      break;
-    }
-    default:
-    {
-      LOG_E(PHY,"PUCCH unknown pucch format : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
-      return (0);
-    }
-  }
-
-  int k2;
-
-  if (power_config->twoPUCCH_PC_AdjustmentStates > 1) {
-    LOG_E(PHY,"PUCCH power control adjustment states with 2 states not yet implemented : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
-    return (PUCCH_POWER_DEFAULT);
-  }
-
-  /* response to a detection by the UE of a DCI format 1_0 or DCI format 1_1 */
-  //int K_PUCCH = 0;
-  if (O_ACK != 0) {
-    /* it assumes that PDCCH is in the first symbol of receive slot FFS TDDO NR */
-    //int slots_gap = (proc->nr_slot_tx > proc->nr_slot_rx ? (proc->nr_slot_tx - proc->nr_slot_rx - 1) : ((proc->nr_slot_tx + ue->frame_parms.slots_per_subframe) - proc->nr_slot_rx - 1));
-    //K_PUCCH = (slots_gap * (ue->frame_parms.symbols_per_tti)) - 1;
-  }
-  else {
-    /* field k2 is not present - to check k2 of pucch from upper layer FFS TDDO NR */
-    if (ue->pusch_config.pusch_TimeDomainResourceAllocation[0] == NULL) {
-      if (ue->frame_parms.numerology_index == 0) {
-        k2 = 1;
-      }
-      else {
-        k2 = ue->frame_parms.numerology_index;
-      }
-    }
-    else
-    {
-      /* get minimum value of k2 */
-      int i = 0;
-      int k2_min = 32;  /* max value of k2 */
-      do {
-        k2 = ue->pusch_config.pusch_TimeDomainResourceAllocation[i]->k2;
-        if (k2 < k2_min) {
-          k2_min = k2;
-        }
-        i++;
-        if (i >= MAX_NR_OF_UL_ALLOCATIONS) {
-          break;
-        }
-       } while(ue->pusch_config.pusch_TimeDomainResourceAllocation[i] != NULL);
-      k2 = k2_min;
-    }
-    //K_PUCCH = N_SYMB_SLOT * k2; /* the product of a number of symbols per slot and the minimum of the values provided by higher layer parameter k2 */
-  }
-
-  int contributor = (10 * log10((double)(pow(2,(ue->frame_parms.numerology_index)) * nb_of_prbs)));
-
-  int16_t pucch_power = P_O_PUCCH + contributor + PL + delta_F_PUCCH + DELTA_TF + G_b_f_c;
-
-  if (pucch_power > ue->tx_power_max_dBm) {
-    pucch_power = ue->tx_power_max_dBm;
-  }
-
-  NR_TST_PHY_PRINTF("PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n",
-                                    pucch_power,            contributor,            PL,                    delta_F_PUCCH,    DELTA_TF,        G_b_f_c);
-
-  return (pucch_power);
-}
-
diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.h b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.h
deleted file mode 100644
index 3ebd263c94b9f75af9900302a36b81fe833f1867..0000000000000000000000000000000000000000
--- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-/************************************************************************
-*
-* MODULE      :  PUCCH power control for UE NR
-*
-* DESCRIPTION :  functions related to PUCCH Transmit power
-*                TS 38.213 7.2.1 UE behaviour
-*
-**************************************************************************/
-
-#ifndef PUCCH_POWER_CONTROL_H
-#define PUCCH_POWER_CONTROL_H
-
-/*************** INCLUDE *******************************************/
-
-/*************** DEFINE ********************************************/
-
-#define PUCCH_POWER_DEFAULT         (0)       /* in dBm */
-
-/*************** VARIABLES *****************************************/
-
-/*************** FUNCTIONS *****************************************/
-
-
-/** \brief This function returns pucch power level in dBm
-    @param ue context
-    @param gNB_id identity
-    @param slots for rx and tx
-    @param pucch_format_nr_t pucch format
-    @param nb_of_prbs number of prb allocated to pucch
-    @param N_sc_ctrl_RB subcarrier control rb related to current pucch format
-    @param N_symb_PUCCH number of pucch symbols excluding those reserved for dmrs
-    @param O_UCI number of bits for UCI Uplink Control Information
-    @param O_SR number of bits for SR scheduling Request
-    @param int O_UCI number of  bits for CSI Channel State Information
-    @param O_ACK number of bits for HARQ-ACK
-    @param O_CRC number of bits for CRC
-    @param n_HARQ_ACK use for obtaining a PUCCH transmission power
-    @returns pucch power level in dBm */
-
-int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, pucch_format_nr_t pucch_format,
-                              int nb_of_prbs, int N_sc_ctrl_RB, int N_symb_PUCCH, int O_UCI, int O_SR, int O_CSI, int O_ACK,
-                              int O_CRC, int n_HARQ_ACK);
-
-#endif /* PUCCH_POWER_CONTROL_H */
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
index edb070f8735c479614fc10bb1362501e078976d1..2dbe6dcb9a6582cbea28e2a6242c02dc039d63a3 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
@@ -40,12 +40,13 @@
 #include <openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h>
 #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
 
 #include "SCHED_NR_UE/defs.h"
 #include "SCHED_NR_UE/harq_nr.h"
-#include "SCHED_NR_UE/pucch_power_control_ue_nr.h"
 
 #define DEFINE_VARIABLES_PUCCH_UE_NR_H
 #include "SCHED_NR_UE/pucch_uci_ue_nr.h"
@@ -54,10 +55,118 @@
 #endif
 
 
-
 uint8_t nr_is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id);
 uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id);
 
+/* TS 36.213 Table 9.2.5.2-1: Code rate  corresponding to higher layer parameter PUCCH-F2-maximum-coderate, */
+/* or PUCCH-F3-maximum-coderate, or PUCCH-F4-maximum-coderate */
+/* add one additional element set to 0 for parsing the array until this end */
+/* stored values are code rates * 100 */
+//static const int code_rate_r_time_100[8] = { (0.08 * 100), (0.15 * 100), (0.25*100), (0.35*100), (0.45*100), (0.60*100), (0.80*100), 0 } ;
+
+static float RSRP_meas_mapping_nr[98]
+= {
+  -140,
+    -139,
+    -138,
+    -137,
+    -136,
+    -135,
+    -134,
+    -133,
+    -132,
+    -131,
+    -130,
+    -129,
+    -128,
+    -127,
+    -126,
+    -125,
+    -124,
+    -123,
+    -122,
+    -121,
+    -120,
+    -119,
+    -118,
+    -117,
+    -116,
+    -115,
+    -114,
+    -113,
+    -112,
+    -111,
+    -110,
+    -109,
+    -108,
+    -107,
+    -106,
+    -105,
+    -104,
+    -103,
+    -102,
+    -101,
+    -100,
+    -99,
+    -98,
+    -97,
+    -96,
+    -95,
+    -94,
+    -93,
+    -92,
+    -91,
+    -90,
+    -89,
+    -88,
+    -87,
+    -86,
+    -85,
+    -84,
+    -83,
+    -82,
+    -81,
+    -80,
+    -79,
+    -78,
+    -77,
+    -76,
+    -75,
+    -74,
+    -73,
+    -72,
+    -71,
+    -70,
+    -69,
+    -68,
+    -67,
+    -66,
+    -65,
+    -64,
+    -63,
+    -62,
+    -61,
+    -60,
+    -59,
+    -58,
+    -57,
+    -56,
+    -55,
+    -54,
+    -53,
+    -52,
+    -51,
+    -50,
+    -49,
+    -48,
+    -47,
+    -46,
+    -45,
+    -44,
+    -43
+  }
+  ;
+  
 long
 binary_search_float_nr(
   float elements[],
@@ -202,947 +311,86 @@ void nr_generate_pucch3_4(int32_t **txdataF,
 *
 *********************************************************************/
 
-bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, bool reset_harq)
-{
-  uint8_t   sr_payload = 0;
-  uint32_t  pucch_ack_payload = 0; /* maximum number of bits for pucch payload is supposed to be 32 */
-  uint64_t  pucch_payload = 0;
-  uint32_t  csi_payload = 0;
-  int       frame_tx = proc->frame_tx;
-  int       nr_slot_tx = proc->nr_slot_tx;
-  int       Mod_id = ue->Mod_id;
-  int       CC_id = ue->CC_id;
-
-  int       O_SR = 0;
-  int       O_ACK = 0;
-  int       O_CSI = 0;      /* channel state information */
-  int       N_UCI = 0;      /* size in bits for Uplink Control Information */
-  int       cqi_status = 0;
-  int       ri_status = 0;
-  int       csi_status = 0;
-
-  int       initial_pucch_id = NB_INITIAL_PUCCH_RESOURCE;
-  int       pucch_resource_set = MAX_NB_OF_PUCCH_RESOURCE_SETS;
-  int       pucch_resource_id = MAX_NB_OF_PUCCH_RESOURCES;
-  int       pucch_resource_indicator = MAX_PUCCH_RESOURCE_INDICATOR;
-  int       n_HARQ_ACK;
-
-  int dmrs_scrambling_id=0,data_scrambling_id=0;
-
-  NR_UE_MAC_INST_t *mac = get_mac_inst(0);
-  NR_PUCCH_Resource_t *pucch_resource;
-  uint16_t crnti = mac->crnti;
-  NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
-
-  /* update current context */
-
-  int subframe_number = proc->nr_slot_rx / ue->frame_parms.slots_per_subframe;
-  nb_pucch_format_4_in_subframes[subframe_number] = 0; /* reset pucch format 4 counter at current rx position */
-
-  int dl_harq_pid = ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid;
-
-  if (dl_harq_pid < ue->dlsch[proc->thread_id][gNB_id][0]->number_harq_processes_for_pdsch) {
-    /* pucch indicator can be reseted in function get_downlink_ack so it should be get now */
-    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);
-
-  /* Part - I
-   * Collect feedback that should be transmitted at this nr_slot_tx :
-   * - ACK/NACK, SR, CSI (CQI, RI, ...)
-   */
-
-  sr_payload = 0;
-
-  if (trigger_periodic_scheduling_request( ue, gNB_id, proc ) == 1) {
-    O_SR = 1; /* sr should be transmitted */
-    if (ue->mac_enabled == 1) {
-
-      /* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */
-      sr_payload = nr_ue_get_SR(Mod_id,
-                                CC_id,
-                                frame_tx,
-                                gNB_id,
-                                0,//ue->pdcch_vars[proc->thread_id][gNB_id]->crnti,
-                                nr_slot_tx); // nr_slot_rx used for meas gap
-    }
-    else {
-      sr_payload = 1;
-    }
-  }
-
-  O_ACK = get_downlink_ack( ue, gNB_id, proc, &pucch_ack_payload,
-                            &n_HARQ_ACK, reset_harq); // 1 to reset ACK/NACK status : 0 otherwise
-
-  cqi_status = ((ue->cqi_report_config[gNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0) &&
-                                                         (nr_is_cqi_TXOp(ue,proc,gNB_id) == 1));
-
-  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;
-  //}
-
-  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;
-    if ((N_UCI == 0) || ((O_CSI == 0) && (sr_payload == 0))) {   /* TS 38.213 9.2.4 UE procedure for reporting SR */
-      NR_TST_PHY_PRINTF("PUCCH No feedback AbsSubframe %d.%d \n", frame_tx%1024, nr_slot_tx);
-      LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d \n", frame_tx%1024, nr_slot_tx);
-      return (FALSE);
-    }
-    else {
-      /* a resource set and a resource should be find according to payload size */
-      pucch_resource_set = find_pucch_resource_set( mac, gNB_id, N_UCI);
-      if (pucch_resource_set != MAX_NB_OF_PUCCH_RESOURCE_SETS) {
-        pucch_resource_indicator = 0;
-        pucch_resource_id = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set]->resourceList.list.array[pucch_resource_indicator][0]; /* get the first resource of the set */
-      }
-      else {
-        LOG_W(PHY,"PUCCH no resource set found for CSI at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-        O_CSI = 0;
-        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);
-        }
-      }
-    }
-  }
-  else {
-    N_UCI = O_SR + O_ACK + O_CSI;
-  }
-
-  /* Part - III */
-  /* Choice PUCCH format and its related parameters */
-  pucch_format_nr_t format = pucch_format0_nr;
-  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 */
-  uint8_t  nb_of_prbs = 0;
-  int m_0 = 0;                 /* format 0 only */
-  int m_CS = 0;                /* for all format except for format 0 */
-  int index_additional_dmrs = I_PUCCH_NO_ADDITIONAL_DMRS;
-  int index_hopping = I_PUCCH_NO_HOPPING;
-  int time_domain_occ = 0;
-  int occ_length = 0;
-  int occ_Index = 0;
-
-  NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack;
-
-  if (select_pucch_resource(ue, mac, gNB_id, N_UCI, pucch_resource_indicator, &initial_pucch_id, &pucch_resource_set,
-                            &pucch_resource_id, harq_status) == TRUE) {
-    /* use of initial pucch configuration provided by system information 1 */
-    /***********************************************************************/
-    if (initial_pucch_id != NB_INITIAL_PUCCH_RESOURCE) {
-      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 */
-      int RB_BWP_offset;
-      if (initial_pucch_id == 15) {
-        RB_BWP_offset = ue->systemInformationBlockType1_nr.N_BWP_SIZE/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);
-        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);
-        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)) {
-        O_ACK = 1;
-        pucch_ack_payload &= 0x1; /* take only first ack */
-        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);
-    }
-    /* 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)) {
-        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) {
-        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);
-      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;
-      if (format==pucch_format1_nr)
-        time_domain_occ = pucch_resource->format.choice.format1->timeDomainOCC;
-      if (format==pucch_format4_nr) {
-        occ_length = pucch_resource->format.choice.format4->occ_Length;
-        occ_Index  = pucch_resource->format.choice.format4->occ_Index;
-      }
-
-      m_0 = get_ics_pucch(pucch_resource, format);
-      AssertFatal(m_0 >= 0, "Invalid m_0\n");
-      if (format == pucch_format3_nr) {
-        if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format3->choice.setup->additionalDMRS[0] == 1) {
-          index_additional_dmrs = I_PUCCH_ADDITIONAL_DMRS;
-        }
-      }
-      else if (format == pucch_format4_nr) {
-        if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format4->choice.setup->additionalDMRS[0] == 1) {
-          index_additional_dmrs = I_PUCCH_ADDITIONAL_DMRS;
-        }
-      }
-
-      if ((format == pucch_format3_nr) || (format == pucch_format4_nr)) {
-        if (pucch_resource->intraSlotFrequencyHopping[0] == 1) {
-          index_hopping = I_PUCCH_HOPING;
-        }
-      }
-
-      NR_TST_PHY_PRINTF("PUCCH dedicated configuration with resource index %d \n", pucch_resource_id);
-    }
-  }
-  else {
-    LOG_W(PHY,"PUCCH No PUCCH resource found at AbsSubframe %d.%d \n", frame_tx%1024, nr_slot_tx);
-    return (FALSE);
-  }
-
-  //int max_code_rate = 0;
-  //int Q_m = BITS_PER_SYMBOL_QPSK; /* default pucch modulation type is QPSK with 2 bits per symbol */
-  int N_sc_ctrl_RB = 0;
-  int O_CRC = 0;
+void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, 
+                            uint8_t gNB_id,
+                            UE_nr_rxtx_proc_t *proc) {
 
-  nb_symbols = nb_symbols_total; /* by default, it can be reduced due to symbols reserved for dmrs */
-  pucch_resource = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList->list.array[pucch_resource_id];
-
-  switch(format) {
-    case pucch_format0_nr:
-    {
-      nb_of_prbs = 1;
-      N_sc_ctrl_RB = N_SC_RB;
-      break;
-    }
-    case pucch_format1_nr:
-    {
-      nb_of_prbs = 1;
-      N_sc_ctrl_RB = N_SC_RB;
-      break;
-    }
-    case pucch_format2_nr:
-    {
-      nb_of_prbs = pucch_resource->format.choice.format2->nrofPRBs;
-      N_sc_ctrl_RB = N_SC_RB - 4;
-      break;
-    }
-    case pucch_format3_nr:
-    {
-      nb_of_prbs = pucch_resource->format.choice.format3->nrofPRBs;
-      //if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format3->choice.setup->pi2BPSK[0] == 1) {
-      //  Q_m = BITS_PER_SYMBOL_BPSK; /* set bpsk modulation type with 1 bit per modulation symbol */
-      //}
-      N_sc_ctrl_RB = N_SC_RB;
-      nb_symbols = nb_symbols_excluding_dmrs[nb_symbols_total-4][index_additional_dmrs][index_hopping];
-      break;
-    }
-    case pucch_format4_nr:
-    {
-      //if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format4->choice.setup->pi2BPSK[0] == 1) {
-      //  Q_m = BITS_PER_SYMBOL_BPSK; /* set bpsk modulation type with 1 bit per modulation symbol */
-      //}
-      nb_symbols = nb_symbols_excluding_dmrs[nb_symbols_total-4][index_additional_dmrs][index_hopping];
-      nb_of_prbs = 1;
-      subframe_number = nr_slot_tx / ue->frame_parms.slots_per_subframe;
-      nb_pucch_format_4_in_subframes[subframe_number]++; /* increment number of transmit pucch 4 in current subframe */
-      NR_TST_PHY_PRINTF("PUCCH Number of pucch format 4 in subframe %d is %d \n", subframe_number, nb_pucch_format_4_in_subframes[subframe_number]);
-      N_sc_ctrl_RB = N_SC_RB/(nb_pucch_format_4_in_subframes[subframe_number]);
-      break;
-    }
-  }
-
-  /* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI */
-  /* drop CSI report if simultaneous HARQ-ACK/SR and periodic/semi-periodic CSI cannot be transmitted at the same time */
-  if (format !=  pucch_format0_nr) {
-
-    if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1 != NULL) {
-      //max_code_rate = code_rate_r_time_100[mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1->choice.setup->maxCodeRate[0]]; /* it is code rate * 10 */
-
-      if ((O_ACK != 0) && (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1->choice.setup->simultaneousHARQ_ACK_CSI[0] == 0)) {
-        N_UCI = N_UCI - O_CSI;
-        O_CSI = cqi_status = ri_status = 0;
-        csi_payload = 0; /* csi should be dropped in this case */
-      }
-    }
-
-    /* TS 38.212 6.3.1.2  Code block segmentation and CRC attachment */
-    /* crc attachment can be done depending of payload size */
-//    if (N_UCI < 11) {
-//      O_CRC = 0;  /* no additional crc bits */
-//    }
-//    else if ((N_UCI >= 12) && (N_UCI <= 19)) {
-//      O_CRC = 6;  /* number of additional crc bits */
-//    }
-//   else if (N_UCI >= 20) {
-//      O_CRC = 11; /* number of additional crc bits */
-//    }
-
-    N_UCI = N_UCI + O_CRC;
-
-    /* for format 2 and 3, number of prb should be adjusted to minimum value which cope to information size */
-    /*if (nb_of_prbs > 1 ) {
-      int nb_prb_min = 0;
-      int payload_in_bits;
-      do {
-        nb_prb_min++;
-        payload_in_bits = (nb_prb_min * N_sc_ctrl_RB * nb_symbols * Q_m * max_code_rate)/100; */ /* code rate has been multiplied by 100 */
-        
-        /*NR_TST_PHY_PRINTF("PUCCH Adjust number of prb : (N_UCI : %d ) (payload_in_bits : %d) (N_sc_ctrl_RB : %d) (nb_symbols : %d) (Q_m : %d) (max_code_rate*100 : %d) \n",
-                                               N_UCI,        payload_in_bits,       N_sc_ctrl_RB,       nb_symbols,       Q_m,       max_code_rate);
-      } while (N_UCI > payload_in_bits);
-
-      if (nb_prb_min > nb_of_prbs) {
-        LOG_E(PHY,"PUCCH Number of prbs too small for current pucch bits to transmit : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-        return (FALSE);
-      }
-      else {
-        nb_of_prbs = nb_prb_min;
-      }
-    }*/
-
-    /* TS 38.213 9.2.4 for a positive SR transmission, payload b(0) = 0 */
-    if ((O_SR == 1) && (format ==  pucch_format1_nr)) {
-      sr_payload = 0;
-    }
-  }
-  else {  /* only format 0 here */
-    if ((O_SR == 0) && (O_CSI == 0)) {  /* only ack is transmitted TS 36.213 9.2.3 UE procedure for reporting HARQ-ACK */
-      if (O_ACK == 1) {
-        m_CS = sequence_cyclic_shift_1_harq_ack_bit[pucch_ack_payload & 0x1];   /* only harq of 1 bit */
-      }
-      else {
-        m_CS = sequence_cyclic_shift_2_harq_ack_bits[pucch_ack_payload & 0x3];  /* only harq with 2 bits */
-      }
-    }
-    else if ((O_SR == 1) && (O_CSI == 0)) { /* SR + eventually ack are transmitted TS 36.213 9.2.5.1 UE procedure for multiplexing HARQ-ACK or CSI and SR */
-      if (sr_payload == 1) {                /* positive scheduling request */
-        if (O_ACK == 1) {
-          m_CS = sequence_cyclic_shift_1_harq_ack_bit_positive_sr[pucch_ack_payload & 0x1];   /* positive SR and harq of 1 bit */
-        }
-        else if (O_ACK == 2) {
-          m_CS = sequence_cyclic_shift_2_harq_ack_bits_positive_sr[pucch_ack_payload & 0x3];  /* positive SR and harq with 2 bits */
-        }
-        else {
-          m_CS = 0;  /* only positive SR */
-        }
-      }
-    }
-    N_UCI = O_SR = O_ACK = 0;
-    pucch_payload = sr_payload = pucch_ack_payload = 0; /* no data for format 0 */
-  }
-
-  /* TS 38.212 6.3.1  Uplink control information on PUCCH                                       */
-  /* information concatenation of payload                                                       */
-  /*                                                   CSI           SR          HARQ-ACK       */
-  /* bit order of payload of size n :           a(n)....................................a(0)    */
-  /* a(0) is the LSB and a(n) the MSB   <--------><--------------><------------><---------->    */
-  /*                                       O_CRC        O_CSI           O_SR         O_ACK      */
-  /*                                                                                            */
-  /* remark: crc is not part of payload, it is later added by block coding.                     */
-
-  if (N_UCI > (sizeof(uint64_t)*8)) {
-    LOG_E(PHY,"PUCCH number of UCI bits exceeds payload size : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-    return(0);
-  }
-
-  pucch_payload = pucch_payload | (csi_payload << (O_ACK + O_SR)) |  (sr_payload << O_ACK) | pucch_ack_payload;
-
-  NR_TST_PHY_PRINTF("PUCCH ( AbsSubframe : %d.%d ) ( total payload size %d data 0x%02x ) ( ack length %d data 0x%02x ) ( sr length %d value %d ) ( csi length %d data : 0x%02x ) \n",
-                         frame_tx%1024, nr_slot_tx, N_UCI,  pucch_payload, O_ACK, pucch_ack_payload, O_SR, sr_payload, csi_status, csi_payload);
-
-  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);
-
-  /* Part - IV */
-  /* Generate PUCCH signal according to its format and parameters */
-  ue->generate_ul_signal[gNB_id] = 1;
-
-  int16_t pucch_tx_power = get_pucch_tx_power_ue( ue, gNB_id, proc, format,
-                                                  nb_of_prbs, N_sc_ctrl_RB, nb_symbols, N_UCI, O_SR, O_CSI, O_ACK,
-                                                  O_CRC, n_HARQ_ACK);
-
-  /* set tx power */
-  ue->tx_power_dBm[nr_slot_tx] = pucch_tx_power;
-  ue->tx_total_RE[nr_slot_tx] = nb_of_prbs*N_SC_RB;
-
-  int tx_amp;
-
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
-
-  tx_amp = nr_get_tx_amp(pucch_tx_power,
-                      ue->tx_power_max_dBm,
-                      ue->frame_parms.N_RB_UL,
-                      nb_of_prbs);
-#else
-  tx_amp = AMP;
-#endif
-
-  switch(format) {
-    case pucch_format0_nr:
-    {
-      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],
-                         tx_amp,
-                         nr_slot_tx,
-                         (uint8_t)m_0,
-                         (uint8_t)m_CS,
-                         nb_symbols_total,
-                         starting_symbol_index,
-                         starting_prb);
-      break;
-    }
-    case pucch_format1_nr:
-    {
-      nr_generate_pucch1(ue,ue->common_vars.txdataF,
-                         &ue->frame_parms,
-                         &ue->pucch_config_dedicated[gNB_id],
-                         pucch_payload,
-                         tx_amp,
-                         nr_slot_tx,
-                         (uint8_t)m_0,
-                         nb_symbols_total,
-                         starting_symbol_index,
-                         starting_prb,
-                         second_hop,
-                         (uint8_t)time_domain_occ,
-                         (uint8_t)N_UCI);
-      break;
-    }
-    case pucch_format2_nr:
-    {
-      nr_generate_pucch2(ue,
-                         crnti,
-			 dmrs_scrambling_id,
-			 data_scrambling_id,
-                         ue->common_vars.txdataF,
-                         &ue->frame_parms,
-                         &ue->pucch_config_dedicated[gNB_id],
-                         pucch_payload,
-                         tx_amp,
-                         nr_slot_tx,
-                         nb_symbols_total,
-                         starting_symbol_index,
-                         nb_of_prbs,
-                         starting_prb,
-                         (uint8_t)N_UCI);
-      break;
-    }
-    case pucch_format3_nr:
-    case pucch_format4_nr:
-    {
-      nr_generate_pucch3_4(ue,
-                           0,//ue->pdcch_vars[proc->thread_id][gNB_id]->crnti,
-                           ue->common_vars.txdataF,
-                           &ue->frame_parms,
-                           format,
-                           &ue->pucch_config_dedicated[gNB_id],
-                           pucch_payload,
-                           tx_amp,
-                           nr_slot_tx,
-                           nb_symbols_total,
-                           starting_symbol_index,
-                           nb_of_prbs,
-                           starting_prb,
-                           second_hop,
-                           (uint8_t)N_UCI,
-                           (uint8_t)occ_length,
-                           (uint8_t)occ_Index);
-      break;
-    }
-  }
-  return (TRUE);
-}
-
-/*******************************************************************
-*
-* NAME :         get_downlink_ack
-*
-* PARAMETERS :   ue context
-*                processing slots of reception/transmission
-*                gNB_id identifier
-*
-* RETURN :       o_ACK acknowledgment data
-*                o_ACK_number_bits number of bits for acknowledgment
-*
-* DESCRIPTION :  return acknowledgment value
-*                TS 38.213 9.1.3 Type-2 HARQ-ACK codebook determination
-*
-*          --+--------+-------+--------+-------+---  ---+-------+--
-*            | PDCCH1 |       | PDCCH2 |PDCCH3 |        | PUCCH |
-*          --+--------+-------+--------+-------+---  ---+-------+--
-*    DAI_DL      1                 2       3              ACK for
-*                V                 V       V        PDCCH1, PDDCH2 and PCCH3
-*                |                 |       |               ^
-*                +-----------------+-------+---------------+
-*
-*                PDCCH1, PDCCH2 and PDCCH3 are PDCCH monitoring occasions
-*                M is the total of monitoring occasions
-*
-*********************************************************************/
-
-uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id,  UE_nr_rxtx_proc_t *proc,
-                         uint32_t *o_ACK, int *n_HARQ_ACK,
-                         bool do_reset) // 1 to reset ACK/NACK status : 0 otherwise
-{
-  NR_UE_HARQ_STATUS_t *harq_status;
-  uint32_t ack_data[NR_DL_MAX_NB_CW][NR_DL_MAX_DAI] = {{0},{0}};
-  uint32_t dai[NR_DL_MAX_NB_CW][NR_DL_MAX_DAI] = {{0},{0}};       /* for serving cell */
-  uint32_t dai_total[NR_DL_MAX_NB_CW][NR_DL_MAX_DAI] = {{0},{0}}; /* for multiple cells */
-  int number_harq_feedback = 0;
-  uint32_t dai_current = 0;
-  uint32_t dai_max = 0;
-  int number_pid_dl = ue->dlsch[proc->thread_id][gNB_id][0]->number_harq_processes_for_pdsch;
-  bool two_transport_blocks = FALSE;
-  int number_of_code_word = 1;
-  int U_DAI_c = 0;
-  int N_m_c_rx = 0;
-  int V_DAI_m_DL = 0;
-  NR_UE_MAC_INST_t *mac = get_mac_inst(0);
-
-  if (mac->DLbwp[0] == NULL) return 0;
-
-  if (mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI[0] == 2) {
-    two_transport_blocks = TRUE;
-    number_of_code_word = 2;
-  }
-  else {
-    number_of_code_word = 1;
-  }
-
-  if (ue->n_connected_gNB > 1) {
-    LOG_E(PHY,"PUCCH ACK feedback is not implemented for mutiple gNB cells : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-    return (0);
-  }
-
-  /* look for dl acknowledgment which should be done on current uplink slot */
-  for (int code_word = 0; code_word < number_of_code_word; code_word++) {
-
-    for (int dl_harq_pid = 0; dl_harq_pid < number_pid_dl; dl_harq_pid++) {
-
-      for (int thread_idx = 0; thread_idx < RX_NB_TH; thread_idx++) {
-
-        harq_status = &ue->dlsch[thread_idx][gNB_id][code_word]->harq_processes[dl_harq_pid]->harq_ack;
-
-        /* check if current tx slot should transmit downlink acknowlegment */
-        if (harq_status->slot_for_feedback_ack == proc->nr_slot_tx) {
-
-          if (harq_status->ack == DL_ACKNACK_NO_SET) {
-            LOG_E(PHY,"PUCCH Downlink acknowledgment has not been set : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-          }
-          else if (harq_status->vDAI_DL == DL_DAI_NO_SET) {
-            LOG_E(PHY,"PUCCH Downlink DAI has not been set : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-          }
-          else if (harq_status->vDAI_DL > NR_DL_MAX_DAI) {
-            LOG_E(PHY,"PUCCH Downlink DAI has an invalid value : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-          }
-          else if (harq_status->send_harq_status == 0) {
-            LOG_D(PHY,"PUCCH Downlink ack can not be transmitted : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-          }
-          else {
-
-            dai_current = harq_status->vDAI_DL+1; // DCI DAI to counter DAI conversion
-
-            if (dai_current == 0) {
-              LOG_E(PHY,"PUCCH Downlink dai is invalid : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-              return(0);
-            } else if (dai_current > dai_max) {
-              dai_max = dai_current;
-            }
-
-            number_harq_feedback++;
-            ack_data[code_word][dai_current - 1] = harq_status->ack;
-            dai[code_word][dai_current - 1] = dai_current;
-            harq_status->slot_for_feedback_ack = NR_MAX_SLOTS_PER_FRAME;
-            harq_status->send_harq_status = 0;
-          }
-          if (do_reset == TRUE) {
-            init_downlink_harq_status(ue->dlsch[thread_idx][gNB_id][code_word]->harq_processes[dl_harq_pid]);
-          }
-        }
-      }
-    }
-  }
-
-  /* no any ack to transmit */
-  if (number_harq_feedback == 0) {
-    *n_HARQ_ACK = 0;
-    return(0);
-  }
-  else  if (number_harq_feedback > (sizeof(uint32_t)*8)) {
-    LOG_E(PHY,"PUCCH number of ack bits exceeds payload size : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-    return(0);
-  }
-
-  /* for computing n_HARQ_ACK for power */
-   V_DAI_m_DL = dai_max;
-   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) {
-     int N_TB_max_DL = mac->DLbwp[0]->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);
-   }
-
-  /*
-  * For a monitoring occasion of a PDCCH with DCI format 1_0 or DCI format 1_1 in at least one serving cell,
-  * when a UE receives a PDSCH with one transport block and the value of higher layer parameter maxNrofCodeWordsScheduledByDCI is 2,
-  * the HARQ-ACK response is associated with the first transport block and the UE generates a NACK for the second transport block
-  * if spatial bundling is not applied (HARQ-ACK-spatial-bundling-PUCCH = FALSE) and generates HARQ-ACK value of ACK for the second
-  * transport block if spatial bundling is applied.
-  */
-
-  for (int code_word = 0; code_word < number_of_code_word; code_word++) {
-    for (uint32_t i = 0; i < dai_max ; i++ ) {
-      if (dai[code_word][i] != i + 1) { /* fill table with consistent value for each dai */
-        dai[code_word][i] = i + 1;      /* it covers case for which PDCCH DCI has not been successfully decoded and so it has been missed */
-        ack_data[code_word][i] = 0;     /* nack data transport block which has been missed */
-        number_harq_feedback++;
-      }
-      if (two_transport_blocks == TRUE) {
-        dai_total[code_word][i] = dai[code_word][i]; /* for a single cell, dai_total is the same as dai of first cell */
-      }
-    }
-  }
-
-  int M = dai_max;
-  int j = 0;
-  uint32_t V_temp = 0;
-  uint32_t V_temp2 = 0;
-  int O_ACK = 0;
-  int O_bit_number_cw0 = 0;
-  int O_bit_number_cw1 = 0;
-
-  for (int m = 0; m < M ; m++) {
-
-    if (dai[0][m] <= V_temp) {
-      j = j + 1;
-    }
-
-    V_temp = dai[0][m]; /* value of the counter DAI for format 1_0 and format 1_1 on serving cell c */
-
-    if (dai_total[0][m] == 0) {
-      V_temp2 = dai[0][m];
-    } else {
-      V_temp2 = dai[1][m];         /* second code word has been received */
-      O_bit_number_cw1 = (8 * j) + 2*(V_temp - 1) + 1;
-      *o_ACK = *o_ACK | (ack_data[1][m] << O_bit_number_cw1);
-    }
-
-    if (two_transport_blocks == TRUE) {
-      O_bit_number_cw0 = (8 * j) + 2*(V_temp - 1);
-    }
-    else {
-      O_bit_number_cw0 = (4 * j) + (V_temp - 1);
-    }
-
-    *o_ACK = *o_ACK | (ack_data[0][m] << O_bit_number_cw0);
-  }
-
-  if (V_temp2 < V_temp) {
-    j = j + 1;
-  }
-
-  if (two_transport_blocks == TRUE) {
-    O_ACK = 2 * ( 4 * j + V_temp2);  /* for two transport blocks */
-  }
-  else {
-    O_ACK = 4 * j + V_temp2;         /* only one transport block */
-  }
-
-  if (number_harq_feedback != O_ACK) {
-    LOG_E(PHY,"PUCCH Error for number of bits for acknowledgment : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-    return (0);
-  }
-
-  return(number_harq_feedback);
-}
-
-/*******************************************************************
-*
-* NAME :         select_pucch_format
-*
-* PARAMETERS :   ue context
-*                processing slots of reception/transmission
-*                gNB_id identifier
-*
-* RETURN :       TRUE a valid resource has been found
-*
-* DESCRIPTION :  return tx harq process identifier for given transmission slot
-*                TS 38.213 9.2.1  PUCCH Resource Sets
-*                TS 38.213 9.2.2  PUCCH Formats for UCI transmission
-*                In the case of pucch for scheduling request only, resource is already get from scheduling request configuration
-*
-*********************************************************************/
-
-boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size, int pucch_resource_indicator, 
-                                int *initial_pucch_id, int *resource_set_id, int *resource_id, NR_UE_HARQ_STATUS_t *harq_status)
-{
-  boolean_t resource_set_found = FALSE;
-  int nb_symbols_for_tx = 0;
-  int current_resource_id = MAX_NB_OF_PUCCH_RESOURCES;
-  pucch_format_nr_t format_pucch;
-  int ready_pucch_resource_id = FALSE; /* in the case that it is already given */
-  NR_PUCCH_Resource_t *pucch_resource;
-  NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
-
-  /* ini values to unset */
-  *initial_pucch_id = NB_INITIAL_PUCCH_RESOURCE;
-  //*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) {
-
-    /* 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];
-      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;
-        return (FALSE);
-      }
-    }
-    else  {
-      /* see TS 38.213 9.2.1  PUCCH Resource Sets */
-      int delta_PRI = harq_status->pucch_resource_indicator;
-      // n_CCE can be obtained from ue->dci_ind.dci_list[i].n_CCE. FIXME!!!
-      // N_CCE can be obtained from ue->dci_ind.dci_list[i].N_CCE. FIXME!!!
-      //int n_CCE = ue->dci_ind.dci_list[0].n_CCE;
-      //int N_CCE = ue->dci_ind.dci_list[0].N_CCE;
-      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);
-      }
-      int r_PUCCH = ((2 * n_CCE_0)/N_CCE_0) + (2 * delta_PRI);
-      *initial_pucch_id = r_PUCCH;
-    }
-    nb_symbols_for_tx = initial_pucch_resource[*initial_pucch_id].nrofSymbols;
-    format_pucch = initial_pucch_resource[*initial_pucch_id].format;
-    if (check_pucch_format(mac, gNB_id, format_pucch, nb_symbols_for_tx, uci_size) == TRUE) {
-      return (TRUE);
-    }
-    else {
-      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);
-    }
-  }
-  else {
-    /* dedicated resources have been configured */
-    int pucch_resource_set_id = 0;
-    if (*resource_set_id == MAX_NB_OF_PUCCH_RESOURCE_SETS) {
-      /* from TS 38.331 field maxPayloadMinus1
-        -- Maximum number of payload bits minus 1 that the UE may transmit using this PUCCH resource set. In a PUCCH occurrence, the UE
-        -- chooses the first of its PUCCH-ResourceSet which supports the number of bits that the UE wants to transmit.
-        -- The field is not present in the first set (Set0) since the maximum Size of Set0 is specified to be 3 bit.
-        -- The field is not present in the last configured set since the UE derives its maximum payload size as specified in 38.213.
-        -- This field can take integer values that are multiples of 4. Corresponds to L1 parameter 'N_2' or 'N_3' (see 38.213, section 9.2)
-      */
-      /* look for the first resource set which supports uci_size number of bits for payload */
-      pucch_resource_set_id = find_pucch_resource_set(mac, gNB_id, uci_size);
-      if (pucch_resource_set_id != MAX_NB_OF_PUCCH_RESOURCE_SETS) {
-        resource_set_found = TRUE;
-      }
-    }
-    else {
-      /* a valid resource has already be found outside this function */
-      resource_set_found = TRUE;
-      ready_pucch_resource_id = TRUE;
-      //pucch_resource_indicator = pucch_resource_indicator;
-    }
-
-    if (resource_set_found == TRUE) {
-      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)
-        {
-          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) {
-            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;
-            /* 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)) {
-              /* see TS 38.213 9.2.3  UE procedure for reporting HARQ-ACK */
-              int delta_PRI = pucch_resource_indicator;
-              int n_CCE_p = harq_status->n_CCE;
-              int N_CCE_p = harq_status->N_CCE;
-              int r_PUCCH;
-              if (N_CCE_p == 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);
-              }
-              if (pucch_resource_set_id < (R_PUCCH%8)) {
-                r_PUCCH = ((n_CCE_p * (R_PUCCH/8))/N_CCE_p) + (delta_PRI*(R_PUCCH/8));
-              }
-              else {
-                r_PUCCH = ((n_CCE_p * (R_PUCCH/8))/N_CCE_p) + (delta_PRI*(R_PUCCH/8)) + (R_PUCCH%8);
-              }
-              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;
-            }
-          }
-
-          /*uint8_t pucch_resource_count = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->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];
-          }*/
-
-          pucch_resource = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList->list.array[current_resource_id];
-          if (pucch_resource != NULL) {
-            format_pucch = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList->list.array[current_resource_id]->format.present;
-            nb_symbols_for_tx = get_nb_symbols_pucch(pucch_resource, format_pucch);
-
-            if (check_pucch_format(mac, gNB_id, format_pucch, nb_symbols_for_tx, uci_size) == TRUE) {
-              *resource_set_id = pucch_resource_set_id;
-              *resource_id = current_resource_id;
-              return (TRUE);
-            }
-            else {
-              LOG_E(PHY,"PUCCH Found format no compatible with payload size and symbol length : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-              return (FALSE);
-            }
-          }
-        }
-        else {
-          LOG_E(PHY,"PUCCH Undefined Resource related to pucch resource indicator: at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-          return (FALSE);
-        }
-      }
-      else {
-        LOG_E(PHY,"PUCCH Invalid pucch resource indicator: at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-        return (FALSE);
-      }
-    }
-
-    /* check that a resource has been found */
-    if (*resource_set_id == MAX_NB_OF_PUCCH_RESOURCES) {
-      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);
-    }
+  int       nr_slot_tx = proc->nr_slot_tx;
+  fapi_nr_ul_config_pucch_pdu *pucch_pdu;
+  NR_UE_PUCCH *pucch_vars = ue->pucch_vars[proc->thread_id][gNB_id];
+
+  for (int i=0; i<2; i++) {
+    if(pucch_vars->active[i]) {
+
+      pucch_pdu = &pucch_vars->pucch_pdu[i];
+      uint16_t nb_of_prbs = pucch_pdu->prb_size;
+      /* Generate PUCCH signal according to its format and parameters */
+      ue->generate_ul_signal[gNB_id] = 1;
+
+      int16_t PL = get_nr_PL(ue->Mod_id, ue->CC_id, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */
+      int contributor = (10 * log10((double)(pow(2,(ue->frame_parms.numerology_index)) * nb_of_prbs)));
+
+      int16_t pucch_tx_power = pucch_pdu->pucch_tx_power + contributor + PL;
+
+      if (pucch_tx_power > ue->tx_power_max_dBm)
+        pucch_tx_power = ue->tx_power_max_dBm;
+
+      /* set tx power */
+      ue->tx_power_dBm[nr_slot_tx] = pucch_tx_power;
+      ue->tx_total_RE[nr_slot_tx] = nb_of_prbs*N_SC_RB;
+
+      int tx_amp;
+
+      tx_amp = nr_get_tx_amp(pucch_tx_power,
+                             ue->tx_power_max_dBm,
+                             ue->frame_parms.N_RB_UL,
+                             nb_of_prbs);
+      if (tx_amp == 0)
+        tx_amp = AMP;
+
+
+      LOG_D(PHY,"Generation of PUCCH format %d at frame.slot %d.%d\n",pucch_pdu->format_type,proc->frame_tx,nr_slot_tx);
+
+      switch(pucch_pdu->format_type) {
+        case 0:
+          nr_generate_pucch0(ue,
+                             ue->common_vars.txdataF,
+                             &ue->frame_parms,
+                             tx_amp,
+                             nr_slot_tx,
+                             pucch_pdu);
+          break;
+        case 1:
+          nr_generate_pucch1(ue,
+                             ue->common_vars.txdataF,
+                             &ue->frame_parms,
+                             tx_amp,
+                             nr_slot_tx,
+                             pucch_pdu);
+          break;
+        case 2:
+          nr_generate_pucch2(ue,
+                             ue->common_vars.txdataF,
+                             &ue->frame_parms,
+                             tx_amp,
+                             nr_slot_tx,
+                             pucch_pdu);
+          break;
+        case 3:
+        case 4:
+          nr_generate_pucch3_4(ue,
+                               ue->common_vars.txdataF,
+                               &ue->frame_parms,
+                               tx_amp,
+                               nr_slot_tx,
+                               pucch_pdu);
+          break;
+      }
+    }
+    pucch_vars->active[i] = false;
   }
-  return (FALSE);
 }
 
-/*******************************************************************
-*
-* NAME :         find_pucch_resource_set
-*
-* PARAMETERS :   ue context
-*                gNB_id identifier
-*
-*
-* RETURN :       harq process identifier
-*
-* DESCRIPTION :  return tx harq process identifier for given transmission slot
-*                YS 38.213 9.2.2  PUCCH Formats for UCI transmission
-*
-*********************************************************************/
-
-int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size)
-{
-  int pucch_resource_set_id = 0;
-  NR_BWP_Id_t bwp_id = mac->DL_BWP_Id;
-
-  //long *pucch_max_pl_bits = NULL;
-
-  /* from TS 38.331 field maxPayloadMinus1
-    -- Maximum number of payload bits minus 1 that the UE may transmit using this PUCCH resource set. In a PUCCH occurrence, the UE
-    -- chooses the first of its PUCCH-ResourceSet which supports the number of bits that the UE wants to transmit.
-    -- The field is not present in the first set (Set0) since the maximum Size of Set0 is specified to be 3 bit.
-    -- The field is not present in the last configured set since the UE derives its maximum payload size as specified in 38.213.
-    -- This field can take integer values that are multiples of 4. Corresponds to L1 parameter 'N_2' or 'N_3' (see 38.213, section 9.2)
-  */
-  /* 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);
-        pucch_resource_set_id = 0;
-        return (pucch_resource_set_id);
-        break;
-      }
-      else {
-        pucch_resource_set_id = 1;
-        return (pucch_resource_set_id);
-        break;
-      }
-    }
-    pucch_resource_set_id++;
-  }
-
-  pucch_resource_set_id = MAX_NB_OF_PUCCH_RESOURCE_SETS;
-
-  return (pucch_resource_set_id);
-}
 
 /*******************************************************************
 *
@@ -1239,59 +487,7 @@ boolean_t check_pucch_format(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, pucch_format
   }
 }
 
-/*******************************************************************
-*
-* NAME :         trigger_periodic_scheduling_request
-*
-* PARAMETERS :   pointer to resource set
-*
-* RETURN :       1 if peridic scheduling request is triggered
-*                0 no periodic scheduling request
-*
-* DESCRIPTION :  TS 38.213 9.2.4 UE procedure for reporting SR
-*
-*********************************************************************/
-
-int trigger_periodic_scheduling_request(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc)
-{
-  const int max_sr_periodicity[NB_NUMEROLOGIES_NR] = { 80, 160, 320, 640, 640 };
-
-  int active_scheduling_request = ue->scheduling_request_config_nr[gNB_id].active_sr_id;
-
-  /* is there any valid scheduling request configuration */
-  if (ue->scheduling_request_config_nr[gNB_id].sr_ResourceConfig[active_scheduling_request] == NULL) {
-    return (0);
-  }
-
-  if (ue->scheduling_request_config_nr[gNB_id].sr_ResourceConfig[active_scheduling_request]->periodicity < 2) {
-    LOG_W(PHY,"PUCCH Not supported scheduling request period smaller than 1 slot : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-    return (0);
-  }
-
-  int16_t SR_periodicity = scheduling_request_periodicity[ue->scheduling_request_config_nr[gNB_id].sr_ResourceConfig[active_scheduling_request]->periodicity];
-  uint16_t SR_offset = ue->scheduling_request_config_nr[gNB_id].sr_ResourceConfig[active_scheduling_request]->offset;
-
-  if (SR_periodicity > max_sr_periodicity[ue->frame_parms.numerology_index]) {
-    LOG_W(PHY,"PUCCH Invalid scheduling request period : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
-    return (0);
-  }
-
-  if (SR_offset > SR_periodicity) {
-    LOG_E(PHY,"PUCCH SR offset %d is greater than SR periodicity %d : at line %d in function %s of file %s \n", SR_offset, SR_periodicity, LINE_FILE , __func__, FILE_NAME);
-    return (0);
-  }
-  else if (SR_periodicity == 1) {
-    return (1); /* period is slot */
-  }
 
-  int16_t N_slot_frame = ue->frame_parms.slots_per_frame;
-  if (((proc->frame_tx * N_slot_frame) + proc->nr_slot_tx - SR_offset)%SR_periodicity == 0) {
-    return (1);
-  }
-  else {
-    return (0);
-  }
-}
 
 /*******************************************************************
 *
@@ -1322,7 +518,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/SCHED_NR_UE/pucch_uci_ue_nr.h b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h
index 9b53331f503c9c7fb34b860b1834dba1982b5e58..101b80fb8d2d25274df9730dabb8d28a74c7b113 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h
@@ -58,253 +58,12 @@
 #define BITS_PER_SYMBOL_BPSK  (1)     /* 1 bit per symbol for bpsk modulation */
 #define BITS_PER_SYMBOL_QPSK  (2)     /* 2 bits per symbol for bpsk modulation */
 
-/************** VARIABLES *****************************************/
-
-float RSRP_meas_mapping_nr[98] 
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H 
-= {
-  -140,
-    -139,
-    -138,
-    -137,
-    -136,
-    -135,
-    -134,
-    -133,
-    -132,
-    -131,
-    -130,
-    -129,
-    -128,
-    -127,
-    -126,
-    -125,
-    -124,
-    -123,
-    -122,
-    -121,
-    -120,
-    -119,
-    -118,
-    -117,
-    -116,
-    -115,
-    -114,
-    -113,
-    -112,
-    -111,
-    -110,
-    -109,
-    -108,
-    -107,
-    -106,
-    -105,
-    -104,
-    -103,
-    -102,
-    -101,
-    -100,
-    -99,
-    -98,
-    -97,
-    -96,
-    -95,
-    -94,
-    -93,
-    -92,
-    -91,
-    -90,
-    -89,
-    -88,
-    -87,
-    -86,
-    -85,
-    -84,
-    -83,
-    -82,
-    -81,
-    -80,
-    -79,
-    -78,
-    -77,
-    -76,
-    -75,
-    -74,
-    -73,
-    -72,
-    -71,
-    -70,
-    -69,
-    -68,
-    -67,
-    -66,
-    -65,
-    -64,
-    -63,
-    -62,
-    -61,
-    -60,
-    -59,
-    -58,
-    -57,
-    -56,
-    -55,
-    -54,
-    -53,
-    -52,
-    -51,
-    -50,
-    -49,
-    -48,
-    -47,
-    -46,
-    -45,
-    -44,
-    -43
-  }
-  #endif
-  ;
-  
-/* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */
-const initial_pucch_resource_t initial_pucch_resource[NB_INITIAL_PUCCH_RESOURCE]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-=
-{
-/*              format           first symbol     Number of symbols        PRB offset    nb index for       set of initial CS */
-/*  0  */ {  pucch_format0_nr,      12,                  2,                   0,            2,       {    0,   3,    0,    0  }   },
-/*  1  */ {  pucch_format0_nr,      12,                  2,                   0,            3,       {    0,   4,    8,    0  }   },
-/*  2  */ {  pucch_format0_nr,      12,                  2,                   3,            3,       {    0,   4,    8,    0  }   },
-/*  3  */ {  pucch_format1_nr,      10,                  4,                   0,            2,       {    0,   6,    0,    0  }   },
-/*  4  */ {  pucch_format1_nr,      10,                  4,                   0,            4,       {    0,   3,    6,    9  }   },
-/*  5  */ {  pucch_format1_nr,      10,                  4,                   2,            4,       {    0,   3,    6,    9  }   },
-/*  6  */ {  pucch_format1_nr,      10,                  4,                   4,            4,       {    0,   3,    6,    9  }   },
-/*  7  */ {  pucch_format1_nr,       4,                 10,                   0,            2,       {    0,   6,    0,    0  }   },
-/*  8  */ {  pucch_format1_nr,       4,                 10,                   0,            4,       {    0,   3,    6,    9  }   },
-/*  9  */ {  pucch_format1_nr,       4,                 10,                   2,            4,       {    0,   3,    6,    9  }   },
-/* 10  */ {  pucch_format1_nr,       4,                 10,                   4,            4,       {    0,   3,    6,    9  }   },
-/* 11  */ {  pucch_format1_nr,       0,                 14,                   0,            2,       {    0,   6,    0,    0  }   },
-/* 12  */ {  pucch_format1_nr,       0,                 14,                   0,            4,       {    0,   3,    6,    9  }   },
-/* 13  */ {  pucch_format1_nr,       0,                 14,                   2,            4,       {    0,   3,    6,    9  }   },
-/* 14  */ {  pucch_format1_nr,       0,                 14,                   4,            4,       {    0,   3,    6,    9  }   },
-/* 15  */ {  pucch_format1_nr,       0,                 14,                   0,            4,       {    0,   3,    6,    9  }   },
-}
-#endif
-;
-
-/* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */
-const int sequence_cyclic_shift_1_harq_ack_bit[2]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-/*        HARQ-ACK Value        0    1 */
-/* Sequence cyclic shift */ = { 0,   6 }
-#endif
-;
-
-/* TS 38.213 Table 9.2.3-4: Mapping of values for two HARQ-ACK bits to sequences */
-const int sequence_cyclic_shift_2_harq_ack_bits[4]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-/*        HARQ-ACK Value       (0,0)  (0,1)  (1,0)  (1,1) */
-/* Sequence cyclic shift */ = {   0,     3,     9,     6 }
-#endif
-;
-
-/* TS 36.213 Table 9.2.5-1: Mapping of values for one HARQ-ACK bit and positive SR to sequences */
-const int sequence_cyclic_shift_1_harq_ack_bit_positive_sr[2]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-/*        HARQ-ACK Value        0    1 */
-/* Sequence cyclic shift */ = { 3,   9 }
-#endif
-;
-
-/* TS 36.213 Table 9.2.5-2: Mapping of values for two HARQ-ACK bits and positive SR to sequences */
-const int sequence_cyclic_shift_2_harq_ack_bits_positive_sr[4]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-/*        HARQ-ACK Value      (0,0)  (0,1)   (1,0)  (1,1) */
-/* Sequence cyclic shift */ = {  1,     4,     10,     7 }
-#endif
-;
-
-/* TS 36.213 Table 9.2.5.2-1: Code rate  corresponding to higher layer parameter PUCCH-F2-maximum-coderate, */
-/* or PUCCH-F3-maximum-coderate, or PUCCH-F4-maximum-coderate */
-/* add one additional element set to 0 for parsing the array until this end */
-/* stored values are code rates * 100 */
-const int code_rate_r_time_100[8]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-= { (0.08 * 100), (0.15 * 100), (0.25*100), (0.35*100), (0.45*100), (0.60*100), (0.80*100), 0 }
-#endif
-;
-
-#define  NB_SYMBOL_MINUS_FOUR             (11)
-#define  I_PUCCH_NO_ADDITIONAL_DMRS        (0)
-#define  I_PUCCH_ADDITIONAL_DMRS           (1)
-#define  I_PUCCH_NO_HOPPING                (0)
-#define  I_PUCCH_HOPING                    (1)
-
-/* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */
-const int nb_symbols_excluding_dmrs[NB_SYMBOL_MINUS_FOUR][2][2]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-= {
-/*                     No additional DMRS            Additional DMRS   */
-/* PUCCH length      No hopping   hopping         No hopping   hopping */
-/* index                  0          1                 0          1    */
-/*    4     */    {{      3    ,     2   }   ,  {      3     ,    2    }},
-/*    5     */    {{      3    ,     3   }   ,  {      3     ,    3    }},
-/*    6     */    {{      4    ,     4   }   ,  {      4     ,    4    }},
-/*    7     */    {{      5    ,     5   }   ,  {      5     ,    5    }},
-/*    8     */    {{      6    ,     6   }   ,  {      6     ,    6    }},
-/*    9     */    {{      7    ,     7   }   ,  {      7     ,    7    }},
-/*   10     */    {{      8    ,     8   }   ,  {      6     ,    6    }},
-/*   11     */    {{      9    ,     9   }   ,  {      7     ,    7    }},
-/*   12     */    {{     10    ,    10   }   ,  {      8     ,    8    }},
-/*   13     */    {{     11    ,    11   }   ,  {      9     ,    9    }},
-/*   14     */    {{     12    ,    12   }   ,  {     10     ,   10    }},
-}
-#endif
-;
-
-/* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI in a PUCCH */
-/* this is a counter of number of pucch format 4 per subframe */
-int nb_pucch_format_4_in_subframes[LTE_NUMBER_OF_SUBFRAMES_PER_FRAME]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-= { 0 }
-#endif
-;
 
 /*************** FUNCTIONS ****************************************/
 
-bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, bool reset_harq);
-
-/** \brief This function return number of downlink acknowledgement and its bitmap
-    @param ue context
-    @param gNB_id identity
-    @param slots for rx and tx
-    @param o_ACK HARQ-ACK information bits
-    @param n_HARQ_ACK use for obtaining a PUCCH transmission power
-    @param do_reset reset downlink HARQ context
-    @returns number of bits of o_ACK */
-
-uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id,  UE_nr_rxtx_proc_t *proc, uint32_t *o_ACK,
-                         int *n_HARQ_ACK, bool do_reset);
-
-/** \brief This function selects a pucch resource
-    @param ue context
-    @param gNB_id identity
-    @param uci size number of uci bits
-    @param pucch_resource_indicator is from downlink DCI
-    @param initial_pucch_id  pucch resource id for initial phase
-    @param resource_set_id   pucch resource set if any
-    @param resource_id       pucch resource id if any
-    @returns TRUE  a pucch resource has been found FALSE no valid pucch resource */
-
-boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size, int pucch_resource_indicator, 
-                                int *initial_pucch_id, int *resource_set_id, int *resource_id, NR_UE_HARQ_STATUS_t *harq_status);
-
-/** \brief This function select a pucch resource set
-    @param ue context
-    @param gNB_id identity
-    @param uci size number of uci bits
-    @returns number of the pucch resource set */
-
-int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size);
+void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, 
+                            uint8_t gNB_id,
+                            UE_nr_rxtx_proc_t *proc);
 
 /** \brief This function check pucch format
     @param ue context
@@ -317,14 +76,6 @@ int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size)
 boolean_t check_pucch_format(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, pucch_format_nr_t format_pucch, int nb_symbols_for_tx, 
                              int uci_size);
 
-/** \brief This function selects a pucch resource
-    @param ue context
-    @param gNB_id identity
-    @param slots for rx and tx
-    @returns TRUE  a scheduling request is triggered */
-                             
-int trigger_periodic_scheduling_request(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc);
-
 /** \brief This function reads current CSI
     @param ue context
     @param gNB_id identity
diff --git a/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c b/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c
index f71a8ee11727b06e7cd9379475afebe45739a99f..03fbfeffe0f2cf3e77b1324f3b7fe0050d2f42a3 100644
--- a/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c
+++ b/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c
@@ -231,7 +231,6 @@ void clear_UE_transport_info(uint8_t nb_UE)
 
   for (UE_id=0; UE_id<nb_UE; UE_id++)
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-      UE_transport_info_TB_index[UE_id][CC_id]=0;
       memset((void *)&UE_transport_info[UE_id][CC_id].cntl,0,sizeof(UE_cntl));
     }
 
diff --git a/openair1/SIMULATION/ETH_TRANSPORT/extern.h b/openair1/SIMULATION/ETH_TRANSPORT/extern.h
index 472a4545eb6d2ef8012b3f6c755caa46cc87cbdf..826317b5388ee56cb7cc196013bac3716234a1d9 100644
--- a/openair1/SIMULATION/ETH_TRANSPORT/extern.h
+++ b/openair1/SIMULATION/ETH_TRANSPORT/extern.h
@@ -57,7 +57,6 @@ extern eNB_transport_info_t eNB_transport_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
 extern uint16_t eNB_transport_info_TB_index[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
 
 extern UE_transport_info_t UE_transport_info[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
-extern uint16_t UE_transport_info_TB_index[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
 
 extern UE_cntl ue_cntl_delay[NUMBER_OF_UE_MAX][MAX_NUM_CCs][2];
 
diff --git a/openair1/SIMULATION/ETH_TRANSPORT/vars.h b/openair1/SIMULATION/ETH_TRANSPORT/vars.h
index f49678642ed19458f41b349034a5688de544161d..9368d622c65d71110e5b09aa61fef1343ffe38e3 100644
--- a/openair1/SIMULATION/ETH_TRANSPORT/vars.h
+++ b/openair1/SIMULATION/ETH_TRANSPORT/vars.h
@@ -58,7 +58,6 @@ eNB_transport_info_t eNB_transport_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
 uint16_t eNB_transport_info_TB_index[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
 
 UE_transport_info_t UE_transport_info[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
-uint16_t UE_transport_info_TB_index[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
 
 UE_cntl ue_cntl_delay[NUMBER_OF_UE_MAX][MAX_NUM_CCs][2];
 
diff --git a/openair1/SIMULATION/LTE_PHY/common_sim.h b/openair1/SIMULATION/LTE_PHY/common_sim.h
index 796a576aed8d2974a76c42b495a6938d988909ff..5e0be3de895bcfce53c3e643643f498e2a08eb8f 100644
--- a/openair1/SIMULATION/LTE_PHY/common_sim.h
+++ b/openair1/SIMULATION/LTE_PHY/common_sim.h
@@ -46,13 +46,13 @@ void sumUpStatsSlot(time_stats_t *res, time_stats_t src[RX_NB_TH][2], int lastAc
 }
 
 double squareRoot(time_stats_t *ptr) {
-  double timeBase=1/(1000*cpu_freq_GHz);
+  double timeBase=1/(1000*get_cpu_freq_GHz());
   return sqrt((double)ptr->diff_square*pow(timeBase,2)/ptr->trials -
               pow((double)ptr->diff/ptr->trials*timeBase,2));
 }
 
 void printDistribution(time_stats_t *ptr, varArray_t *sortedList, char *txt) {
-  double timeBase=1/(1000*cpu_freq_GHz);
+  double timeBase=1/(1000*get_cpu_freq_GHz());
   printf("%-43s %6.2f us (%d trials)\n",
          txt,
          (double)ptr->diff/ptr->trials*timeBase,
@@ -69,7 +69,7 @@ void printStatIndent(time_stats_t *ptr, char *txt) {
 }
 
 void printStatIndent2(time_stats_t *ptr, char *txt) {
-  double timeBase=1/(1000*cpu_freq_GHz);
+  double timeBase=1/(1000*get_cpu_freq_GHz());
   printf("    |__ %-34s %6.2f us (%3d trials)\n",
          txt,
          ptr->trials?((double)ptr->diff)/ptr->trials*timeBase:0,
@@ -77,7 +77,7 @@ void printStatIndent2(time_stats_t *ptr, char *txt) {
 }
 
 void printStatIndent3(time_stats_t *ptr, char *txt) {
-  double timeBase=1/(1000*cpu_freq_GHz);
+  double timeBase=1/(1000*get_cpu_freq_GHz());
   printf("        |__ %-30s %6.2f us (%3d trials)\n",
          txt,
          ptr->trials?((double)ptr->diff)/ptr->trials*timeBase:0,
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index 667913d377f9253b7f9ae08d5f2bab289a53125b..adfda7a0c85229dfa7ef9c153b7780c0c5685709 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -60,16 +60,19 @@
 #include "dummy_functions.c"
 #include "executables/thread-common.h"
 #include "executables/split_headers.h"
-
+#include "common/ran_context.h"
 void feptx_ofdm(RU_t *ru, int frame, int subframe);
 void feptx_prec(RU_t *ru, int frame, int subframe);
 
 double cpuf;
-#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
+#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0))
 //#define MCS_COUNT 23//added for PHY abstraction
 #include <openair1/SIMULATION/LTE_PHY/common_sim.h>
 
 int otg_enabled=0;
+THREAD_STRUCT thread_struct;
+nfapi_ue_release_request_body_t release_rntis;
+
 /*the following parameters are used to control the processing times calculations*/
 double t_tx_max = -1000000000; /*!< \brief initial max process time for tx */
 double t_rx_max = -1000000000; /*!< \brief initial max process time for rx */
@@ -82,6 +85,7 @@ double DS_TDL = .03;
 static int cmpdouble(const void *p1, const void *p2) {
   return *(double *)p1 > *(double *)p2;
 }
+RAN_CONTEXT_t RC;
 
 int emulate_rf = 0;
 int split73=0;
@@ -933,9 +937,10 @@ int main(int argc, char **argv) {
 
     NB_RB = conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL);
   } else {
-    if (rballocset==0) NB_RB = 8;
+    if (rballocset==0) NB_RB = 2+TPC;
     else               NB_RB = DLSCH_RB_ALLOC;
 
+    printf("Common PDSCH: NB_RB = %d\n",NB_RB);
     AssertFatal(NB_RB <= N_RB_DL,"illegal NB_RB %d\n",NB_RB);
   }
 
@@ -1179,7 +1184,7 @@ int main(int argc, char **argv) {
                                    DS_TDL,
                                    forgetting_factor,
                                    rx_sample_offset,
-                                   0);
+                                   0, 0);
   reset_meas(&eNB2UE[0]->random_channel);
   reset_meas(&eNB2UE[0]->interp_time);
 
@@ -1193,7 +1198,7 @@ int main(int argc, char **argv) {
                                        DS_TDL,
                                        forgetting_factor,
                                        rx_sample_offset,
-                                       0);
+                                       0, 0);
       reset_meas(&eNB2UE[n]->random_channel);
       reset_meas(&eNB2UE[n]->interp_time);
     }
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
index a585e8efc6971136895b0bba2ec1d9a22ae4eb8f..3b4e6782dac3b254bd9ae2dded483c7ed7f0c2e4 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
@@ -988,7 +988,7 @@ int main(int argc, char **argv)
                                    N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
                                    forgetting_factor,
                                    rx_sample_offset,
-                                   0);
+                                   0, 0);
 
   if(num_rounds>1) {
     for(n=1; n<8; n++)
@@ -999,7 +999,7 @@ int main(int argc, char **argv)
                                        N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
                                        forgetting_factor,
                                        rx_sample_offset,
-                                       0);
+                                       0, 0);
   }
 
   if (eNB2UE[0]==NULL) {
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
index 5973f80b55a59f662490e960cb5f295e3ae2267b..bd164150c598a260610f90a2f83ffe87a1ca7c2c 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
@@ -834,7 +834,7 @@ int main(int argc, char **argv) {
                                    N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
                                    forgetting_factor,
                                    rx_sample_offset,
-                                   0);
+                                   0, 0);
 
   if(num_rounds>1) {
     for(n=1; n<4; n++)
@@ -845,7 +845,7 @@ int main(int argc, char **argv) {
                                        N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
                                        forgetting_factor,
                                        rx_sample_offset,
-                                       0);
+                                       0, 0);
   }
 
   if (eNB2UE[0]==NULL) {
diff --git a/openair1/SIMULATION/LTE_PHY/mbmssim.c b/openair1/SIMULATION/LTE_PHY/mbmssim.c
index b1f4d933b3b5e393b2f2e5bc1e91294f1282ea08..78fd1a293e9c7fd7679ab050250e98f58a18efa2 100644
--- a/openair1/SIMULATION/LTE_PHY/mbmssim.c
+++ b/openair1/SIMULATION/LTE_PHY/mbmssim.c
@@ -1290,7 +1290,7 @@ int main(int argc, char **argv) {
                                    N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
                                    forgetting_factor,
                                    rx_sample_offset,
-                                   0);
+                                   0, 0);
   reset_meas(&eNB2UE[0]->random_channel);
   reset_meas(&eNB2UE[0]->interp_time);
 
@@ -1303,7 +1303,7 @@ int main(int argc, char **argv) {
                                        N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
                                        forgetting_factor,
                                        rx_sample_offset,
-                                       0);
+                                       0, 0);
       reset_meas(&eNB2UE[n]->random_channel);
       reset_meas(&eNB2UE[n]->interp_time);
     }
diff --git a/openair1/SIMULATION/LTE_PHY/pbchsim.c b/openair1/SIMULATION/LTE_PHY/pbchsim.c
index 00ad03c52dc8f0ffb038fe2b98328087bd6787e2..71286faafb45835a64da2a1c215bcfb780a4e889 100644
--- a/openair1/SIMULATION/LTE_PHY/pbchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pbchsim.c
@@ -386,7 +386,7 @@ int main(int argc, char **argv) {
                                 N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
                                 0,
                                 0,
-                                0);
+                                0, 0);
 
   if (interf1>-20)
     eNB2UE1 = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
@@ -396,7 +396,7 @@ int main(int argc, char **argv) {
                                    N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
                                    0,
                                    4,
-                                   0);
+                                   0, 0);
 
   if (interf2>-20)
     eNB2UE2 = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
@@ -406,7 +406,7 @@ int main(int argc, char **argv) {
                                    N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
                                    0,
                                    8,
-                                   0);
+                                   0, 0);
 
   if (eNB2UE==NULL) {
     msg("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
index 004eb24243bff7b6ab4272568e2281737f4e3364..bd2c2d66b9653f7daa9f71985df875c5f7cd0dc4 100644
--- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
@@ -708,7 +708,7 @@ int main(int argc, char **argv) {
                                 N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
                                 0,
                                 0,
-                                0);
+                                0, 0);
   L1_rxtx_proc_t *proc_rxtx = (subframe == 0)? &eNB->proc.L1_proc: &eNB->proc.L1_proc_tx;
   eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,N_RB_DL,0);
   UE->ulsch[0]   = new_ue_ulsch(N_RB_DL,0);
diff --git a/openair1/SIMULATION/LTE_PHY/prachsim.c b/openair1/SIMULATION/LTE_PHY/prachsim.c
index c997aa763938e820663134271fbe5d260754c87e..229764a8935cb064c1a736bb9961aa48f4dcb696 100644
--- a/openair1/SIMULATION/LTE_PHY/prachsim.c
+++ b/openair1/SIMULATION/LTE_PHY/prachsim.c
@@ -343,7 +343,7 @@ int main(int argc, char **argv) {
                                 N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL),
                                 0.0,
                                 delay,
-                                0);
+                                0, 0);
 
   if (UE2eNB==NULL) {
     msg("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c
index 127bfcb533c76a0496541db4ee763e38c278566d..083a756afb259beeb509f68aef383c4e2aa11dd3 100644
--- a/openair1/SIMULATION/LTE_PHY/pucchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c
@@ -323,7 +323,7 @@ int main(int argc, char **argv) {
                                 N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL),
                                 0.0,
                                 0,
-                                0);
+                                0, 0);
 
   if (UE2eNB==NULL) {
     printf("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/LTE_PHY/scansim.c b/openair1/SIMULATION/LTE_PHY/scansim.c
index 5ceeee7f2f5d5d16575183e05cb2d5185186ed1e..839d30a8dea5332f4497c533b5aba9205ad4ddc6 100644
--- a/openair1/SIMULATION/LTE_PHY/scansim.c
+++ b/openair1/SIMULATION/LTE_PHY/scansim.c
@@ -335,7 +335,7 @@ int main(int argc, char **argv) {
                                 N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL),
                                 0,
                                 0,
-                                0);
+                                0, 0);
 
   if (eNB2UE==NULL) {
     msg("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c
index 80598b37e46d481a5b7668402edce62c64f8d365..e8ee7d3d5e8b086a1804867772a2cffcf367bc94 100644
--- a/openair1/SIMULATION/LTE_PHY/syncsim.c
+++ b/openair1/SIMULATION/LTE_PHY/syncsim.c
@@ -724,7 +724,7 @@ int main(int argc, char **argv) {
                                 BW,
                                 0,
                                 0,
-                                0);
+                                0, 0);
 
   if (interf1>-20)
     eNB2UE1 = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx,
@@ -733,7 +733,7 @@ int main(int argc, char **argv) {
                                    BW,
                                    0,
                                    0,
-                                   0);
+                                   0, 0);
 
   if (interf2>-20)
     eNB2UE2 = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx,
@@ -742,7 +742,7 @@ int main(int argc, char **argv) {
                                    BW,
                                    0,
                                    0,
-                                   0);
+                                   0, 0);
 
   if (eNB2UE==NULL) {
     msg("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c
index 80beee4bed789249b134ef24ebd914f248895827..0d39e6e533fd4159dd23fd9528b8f7e4dfcad641 100644
--- a/openair1/SIMULATION/LTE_PHY/ulsim.c
+++ b/openair1/SIMULATION/LTE_PHY/ulsim.c
@@ -55,9 +55,11 @@
 #include "executables/thread-common.h"
 #include "targets/RT/USER/lte-softmodem.h"
 #include "executables/split_headers.h"
+#include "common/ran_context.h"
+#include "PHY/LTE_ESTIMATION/lte_estimation.h"
 
 double cpuf;
-#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
+#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0))
 //#define MCS_COUNT 23//added for PHY abstraction
 #include <openair1/SIMULATION/LTE_PHY/common_sim.h>
 channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];
@@ -70,6 +72,9 @@ node_desc_t *ue_data[NUMBER_OF_UE_MAX];
 extern uint16_t beta_ack[16],beta_ri[16],beta_cqi[16];
 //extern  char* namepointer_chMag ;
 int xforms=0;
+THREAD_STRUCT thread_struct;
+nfapi_ue_release_request_body_t release_rntis;
+
 FD_lte_phy_scope_enb *form_enb;
 char title[255];
 
@@ -84,7 +89,7 @@ static int cmpdouble(const void *p1, const void *p2) {
   return *(double *)p1 > *(double *)p2;
 }
 
-
+RAN_CONTEXT_t RC;
 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");
@@ -342,7 +347,6 @@ int main(int argc, char **argv) {
   int UE_id = 0;
   static int nb_rb=25,first_rb=0,mcs=0,round=0;
   //unsigned char l;
-  static int awgn_flag = 0 ;
   SCM_t channel_model=Rice1;
   unsigned char *input_buffer=0,harq_pid;
   unsigned short input_buffer_length;
@@ -404,7 +408,7 @@ int main(int argc, char **argv) {
   printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz);
   AssertFatal(load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) != NULL, "Cannot load configuration module, exiting\n");
   logInit();
-  set_glog(OAILOG_WARNING);
+  set_glog(OAILOG_INFO);
   T_stdout = 1;
   // enable these lines if you need debug info
   // however itti will catch all signals, so ctrl-c won't work anymore
@@ -734,7 +738,7 @@ int main(int argc, char **argv) {
                                 30e-9,
                                 forgetting_factor,
                                 delay,
-                                0);
+                                0, 0);
   // set Doppler
   UE2eNB->max_Doppler = maxDoppler;
 
@@ -1086,14 +1090,12 @@ int main(int argc, char **argv) {
             }
           }
 
-          if (awgn_flag == 0) {
-            if (UE2eNB->max_Doppler == 0) {
-              multipath_channel(UE2eNB,s_re,s_im,r_re,r_im,
-                                eNB->frame_parms.samples_per_tti,hold_channel,0);
-            } else {
-              multipath_tv_channel(UE2eNB,s_re,s_im,r_re,r_im,
-                                   2*eNB->frame_parms.samples_per_tti,hold_channel);
-            }
+          if (UE2eNB->max_Doppler == 0) {
+            multipath_channel(UE2eNB,s_re,s_im,r_re,r_im,
+                              eNB->frame_parms.samples_per_tti,hold_channel,0);
+          } else {
+            multipath_tv_channel(UE2eNB,s_re,s_im,r_re,r_im,
+                                 2*eNB->frame_parms.samples_per_tti,hold_channel);
           }
 
           if(abstx) {
@@ -1136,6 +1138,15 @@ int main(int argc, char **argv) {
                          sqrt(sigma2/2)*gaussdouble(0.0,1.0));
             }
           }
+          if (n_frames==1)
+            for (i=0; i<eNB->frame_parms.samples_per_tti; i++) {
+              for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) {
+                ((short *) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*(subframe+1)%10])[2*i] =
+                  (short) (sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+                ((short *) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*(subframe+1)%10])[2*i+1] =
+                  (short) (sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+              }
+            }
 
           if (n_frames<=10) {
             printf("rx_level Null symbol %f\n",10*log10((double)signal_energy((int *)
@@ -1161,9 +1172,10 @@ int main(int argc, char **argv) {
           start_meas(&eNB->phy_proc_rx);
           ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? ru_fep_full_2thread        : fep_full;
           ru->feprx(ru,subframe);
+          if (n_frames==1) lte_eNB_I0_measurements(eNB,(subframe+1)%10,0,1);
+
           phy_procedures_eNB_uespec_RX(eNB,proc_rxtx);
           stop_meas(&eNB->phy_proc_rx);
-
           if (cqi_flag > 0) {
             cqi_error = 0;
 
@@ -1203,6 +1215,9 @@ int main(int argc, char **argv) {
                           eNB->ulsch[0]->harq_processes[harq_pid]->uci_format,0,eNB->frame_parms.N_RB_DL);
 
               dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round);
+              dump_I0_stats(stdout,eNB);
+              dump_ulsch_stats(stdout,eNB,0);
+
               exit(-1);
             }
 
@@ -1263,14 +1278,16 @@ int main(int argc, char **argv) {
         if (t_rx > 2000 )
           n_rx_dropped++;
 
-        appendVarArray(table_tx, &t_tx);
-        appendVarArray(table_tx_ifft, &t_tx_ifft);
-        appendVarArray(table_tx_mod, &t_tx_mod );
-        appendVarArray(table_tx_enc, &t_tx_enc );
-        appendVarArray(table_rx, &t_rx );
-        appendVarArray(table_rx_fft, &t_rx_fft );
-        appendVarArray(table_rx_demod, &t_rx_demod );
-        appendVarArray(table_rx_dec, &t_rx_dec );
+        if (trials < 1000) {
+         appendVarArray(table_tx, &t_tx);
+         appendVarArray(table_tx_ifft, &t_tx_ifft);
+         appendVarArray(table_tx_mod, &t_tx_mod );
+         appendVarArray(table_tx_enc, &t_tx_enc );
+         appendVarArray(table_rx, &t_rx );
+         appendVarArray(table_rx_fft, &t_rx_fft );
+         appendVarArray(table_rx_demod, &t_rx_demod );
+         appendVarArray(table_rx_dec, &t_rx_dec );
+       }
       }   //trials
 
       // sort table
@@ -1289,6 +1306,7 @@ int main(int argc, char **argv) {
         LOG_UDUMPMSG(SIM,dataArray(table_rx),table_rx->size,LOG_DUMP_DOUBLE,"The receiver raw data: \n");
       }
 
+      dump_ulsch_stats(stdout,eNB,0);
       printf("\n**********rb: %d ***mcs : %d  *********SNR = %f dB (%f): TX %u dB (gain %f dB), N0W %f dB, I0 %u dB, delta_IF %d [ (%d,%d) dB / (%u,%u) dB ]**************************\n",
              nb_rb,mcs,SNR,SNR2,
              tx_lev_dB,
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index 00983553d8ff287582ac089b55f4877e8c642ffc..633a214699ae8bd82daff00d7356c0ac239becce 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -339,7 +339,7 @@ int main(int argc, char **argv)
 				      61.44e6, //N_RB2sampling_rate(N_RB_DL),
 				      40e6, //N_RB2channel_bandwidth(N_RB_DL),
                                       DS_TDL,
-				      0, 0, 0);
+				      0, 0, 0, 0);
 
 	if (gNB2UE == NULL) {
 		printf("Problem generating channel model. Exiting.\n");
@@ -357,7 +357,7 @@ int main(int argc, char **argv)
 	frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
 	crcTableInit();
 	nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell,SSB_positions);
-	phy_init_nr_gNB(gNB, 0, 0);
+	phy_init_nr_gNB(gNB, 0, 1); //lowmem
 	//init_eNB_afterRU();
 	frame_length_complex_samples = frame_parms->samples_per_subframe;
 	//frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP;
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 678453539143a1a76faaccfaecc1d674fc9124c6..f082c40fb8fc4c00e56b5bbd0bd83c8cb121dee2 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -63,12 +63,14 @@
 //#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
 #include "PHY/NR_REFSIG/ptrs_nr.h"
 #include "NR_RRCReconfiguration.h"
-#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
+#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0))
 #include "SIMULATION/LTE_PHY/common_sim.h"
 
 #include <openair2/LAYER2/MAC/mac_vars.h>
 #include <openair2/RRC/LTE/rrc_vars.h>
 
+#include <executables/softmodem-common.h>
+
 LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
 rlc_info_t Rlc_info_um,Rlc_info_am_config;
 
@@ -79,20 +81,41 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
 
 double cpuf;
 
-int sf_ahead=4 ;
-int sl_ahead=0;
+uint16_t sf_ahead=4 ;
+uint16_t sl_ahead=0;
 //uint8_t nfapi_mode = 0;
 uint64_t downlink_frequency[MAX_NUM_CCs][4];
+THREAD_STRUCT thread_struct;
+nfapi_ue_release_request_body_t release_rntis;
+uint32_t N_RB_DL = 106;
 
 // dummy functions
 int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info)              { return(0);  }
 
-int8_t nr_mac_rrc_data_ind_ue(const module_id_t     module_id,
-			      const int             CC_id,
-			      const uint8_t         gNB_index,
-			      const int8_t          channel,
-			      const uint8_t*        pduP,
-			      const sdu_size_t      pdu_len)
+int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
+                              const int CC_id,
+                              const uint8_t gNB_index,
+                              const frame_t frame,
+                              const sub_frame_t sub_frame,
+                              const rnti_t rnti,
+                              const channel_t channel,
+                              const uint8_t* pduP,
+                              const sdu_size_t pdu_len)
+{
+  return 0;
+}
+
+void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
+{
+  return;
+}
+
+int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
+                              const int         CC_id,
+                              const uint8_t     gNB_id,
+                              const frame_t     frameP,
+                              const rb_id_t     Srb_id,
+                              uint8_t           *buffer_pP)
 {
   return 0;
 }
@@ -107,6 +130,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,
@@ -142,6 +171,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,
@@ -158,7 +191,9 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
 }
 
 void config_common(int Mod_idP,
-                   int pdsch_AntennaPorts, 
+                   int ssb_SubcarrierOffset,
+                   int pdsch_AntennaPorts,
+                   int pusch_AntennaPorts,
 		   NR_ServingCellConfigCommon_t *scc
 		   );
 
@@ -178,6 +213,19 @@ 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
 
 int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0);  }
@@ -185,43 +233,66 @@ int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0);
 int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0);  }
 int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0);  }
 
-int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
-  return 0;
-}
-
 // needed for some functions
 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);
+void update_dmrs_config(NR_CellGroupConfig_t *scg, int8_t* dmrs_arg);
+extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
 
-/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs from command line of
+/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of
    dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */
-int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1;
+int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLayers = 1;
 void nr_dlsim_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;
   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;
 
-  sched_ctrl->rbStart = g_rbStart;
-  sched_ctrl->rbSize = g_rbSize;
-  sched_ctrl->mcs = g_mcsIndex;
-  sched_ctrl->time_domain_allocation = 2;
-  sched_ctrl->mcsTableIdx = g_mcsTableIdx;
+  NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
+
+  nr_set_pdsch_semi_static(scc,
+                           UE_info->CellGroup[0],
+                           sched_ctrl->active_bwp,
+                           /* tda = */ 2,
+                           /* num_dmrs_cdm_grps_no_data = */ 1,
+                           ps);
+
+  NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
+  sched_pdsch->rbStart = g_rbStart;
+  sched_pdsch->rbSize = g_rbSize;
+  sched_pdsch->mcs = g_mcsIndex;
+  /* the following might override the table that is mandated by RRC
+   * configuration */
+  ps->mcsTableIdx = g_mcsTableIdx;
+
+  sched_pdsch->nrOfLayers = g_nrOfLayers;
+  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->tb_size = nr_compute_tbs(sched_pdsch->Qm,
+                                        sched_pdsch->R,
+                                        sched_pdsch->rbSize,
+                                        ps->nrOfSymbols,
+                                        ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
+                                        0 /* N_PRB_oh, 0 for initialBWP */,
+                                        0 /* tb_scaling */,
+                                        sched_pdsch->nrOfLayers)
+                         >> 3;
+
   /* the simulator assumes the HARQ PID is equal to the slot number */
-  sched_ctrl->dl_harq_pid = slot;
+  sched_pdsch->dl_harq_pid = slot;
+
   /* The scheduler uses lists to track whether a HARQ process is
    * free/busy/awaiting retransmission, and updates the HARQ process states.
    * However, in the simulation, we never get ack or nack for any HARQ process,
@@ -234,13 +305,26 @@ void nr_dlsim_preprocessor(module_id_t module_id,
   else
     add_front_nr_list(&sched_ctrl->retrans_dl_harq, slot);   // ... make PID retransmission
   sched_ctrl->harq_processes[slot].is_waiting = false;
-  AssertFatal(sched_ctrl->rbStart >= 0, "invalid rbStart %d\n", sched_ctrl->rbStart);
-  AssertFatal(sched_ctrl->rbSize > 0, "invalid rbSize %d\n", sched_ctrl->rbSize);
-  AssertFatal(sched_ctrl->mcs >= 0, "invalid sched_ctrl->mcs %d\n", sched_ctrl->mcs);
-  AssertFatal(sched_ctrl->mcsTableIdx >= 0 && sched_ctrl->mcsTableIdx <= 2, "invalid sched_ctrl->mcsTableIdx %d\n", sched_ctrl->mcsTableIdx);
-  sched_ctrl->numDmrsCdmGrpsNoData = 1;
+  AssertFatal(sched_pdsch->rbStart >= 0, "invalid rbStart %d\n", sched_pdsch->rbStart);
+  AssertFatal(sched_pdsch->rbSize > 0, "invalid rbSize %d\n", sched_pdsch->rbSize);
+  AssertFatal(sched_pdsch->mcs >= 0, "invalid mcs %d\n", sched_pdsch->mcs);
+  AssertFatal(ps->mcsTableIdx >= 0 && ps->mcsTableIdx <= 2, "invalid mcsTableIdx %d\n", ps->mcsTableIdx);
+}
+
+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
+} nrUE_params_t;
+
+nrUE_params_t nrUE_params;
+
+nrUE_params_t *get_nrUE_params(void) {
+  return &nrUE_params;
 }
 
+void do_nothing(void *args) {
+}
 
 int main(int argc, char **argv)
 {
@@ -248,12 +332,15 @@ int main(int argc, char **argv)
   int i,aa;//,l;
   double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0;
   uint8_t snr1set=0;
-  float roundStats[50];
+  double roundStats[500] = {0};
+  double blerStats[500] = {0};
+  double berStats[500] = {0};
+  double snrStats[500] = {0};
   float effRate;
   //float psnr;
   float eff_tp_check = 0.7;
   uint8_t snrRun;
-  uint32_t TBS;
+  uint32_t TBS = 0;
   int **txdata;
   double **s_re,**s_im,**r_re,**r_im;
   //double iqim = 0.0;
@@ -268,7 +355,7 @@ int main(int argc, char **argv)
   //  char fname[40], vname[40];
   int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
   //int n_errors2, n_alamouti;
-  uint8_t transmission_mode = 1,n_tx=1,n_rx=1;
+  uint8_t n_tx=1,n_rx=1;
   uint8_t round;
   uint8_t num_rounds = 4;
 
@@ -282,7 +369,7 @@ int main(int argc, char **argv)
 
   //uint8_t frame_mod4,num_pdcch_symbols = 0;
 
-  SCM_t channel_model=AWGN;//Rayleigh1_anticorr;
+  SCM_t channel_model = AWGN; // AWGN Rayleigh1 Rayleigh1_anticorr;
 
   NB_UE_INST = 1;
   //double pbch_sinr;
@@ -301,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;
@@ -312,7 +397,7 @@ int main(int argc, char **argv)
   int8_t enable_ptrs = 0;
   int8_t modify_dmrs = 0;
 
-  int8_t dmrs_arg[2] = {-1,-1};// Invalid values
+  int8_t dmrs_arg[3] = {-1,-1,-1};// Invalid values
   /* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */
   int8_t ptrs_arg[2] = {-1,-1};// Invalid values
 
@@ -378,6 +463,10 @@ int main(int argc, char **argv)
         channel_model=ETU;
         break;
 
+      case 'R':
+        channel_model=Rayleigh1;
+        break;
+
       default:
         printf("Unsupported channel model!\n");
         exit(-1);
@@ -427,12 +516,11 @@ int main(int argc, char **argv)
       break;
       */
     case 'x':
-      transmission_mode=atoi(optarg);
+      g_nrOfLayers=atoi(optarg);
 
-      if ((transmission_mode!=1) &&
-          (transmission_mode!=2) &&
-          (transmission_mode!=6)) {
-        printf("Unsupported transmission mode %d\n",transmission_mode);
+      if ((g_nrOfLayers!=1) &&
+          (g_nrOfLayers!=2)) {
+        printf("Unsupported nr Of Layers %d\n",g_nrOfLayers);
         exit(-1);
       }
 
@@ -441,7 +529,7 @@ int main(int argc, char **argv)
     case 'y':
       n_tx=atoi(optarg);
 
-      if ((n_tx==0) || (n_tx>2)) {
+      if ((n_tx==0) || (n_tx>4)) {//extend gNB to support n_tx = 4
         printf("Unsupported number of tx antennas %d\n",n_tx);
         exit(-1);
       }
@@ -451,7 +539,7 @@ int main(int argc, char **argv)
     case 'z':
       n_rx=atoi(optarg);
 
-      if ((n_rx==0) || (n_rx>2)) {
+      if ((n_rx==0) || (n_rx>4)) {//extend UE to support n_tx = 4
         printf("Unsupported number of rx antennas %d\n",n_rx);
         exit(-1);
       }
@@ -549,7 +637,7 @@ int main(int argc, char **argv)
       printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB.  If n_frames is 1 then just SNR is simulated\n");
       printf("-S Ending SNR, runs from SNR0 to SNR1\n");
       printf("-t Delay spread for multipath channel\n");
-      printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
+      printf("-g [A,B,C,D,E,F,G,R] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models or R for MIMO model (ignores delay spread and Ricean factor)\n");
       printf("-y Number of TX antennas used in gNB\n");
       printf("-z Number of RX antennas used in UE\n");
       //printf("-i Relative strength of first intefering gNB (in dB) - cell_id mod 3 = 1\n");
@@ -570,7 +658,7 @@ int main(int argc, char **argv)
       printf("-q Use 2nd MCS table (256 QAM table) for PDSCH\n");
       printf("-t Acceptable effective throughput (in percentage)\n");
       printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
-      printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2}, e.g. -U 2 0 2 \n");
+      printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2} DMRS ConfType{1:2}, e.g. -U 3 0 2 1 \n");
       printf("-P Print DLSCH performances\n");
       printf("-w Write txdata to binary file (one frame)\n");
       printf("-d number of dlsch threads, 0: no dlsch parallelization\n");
@@ -586,7 +674,8 @@ int main(int argc, char **argv)
   InitSinLUT();
 
   get_softmodem_params()->phy_test = 1;
-  
+  get_softmodem_params()->do_ra = 0;
+
   if (snr1set==0)
     snr1 = snr0+10;
   init_dlsch_tpool(dlsch_threads);
@@ -609,7 +698,6 @@ int main(int argc, char **argv)
     RC.nb_nr_mac_CC[i] = 1;
   mac_top_init_gNB();
   gNB_mac = RC.nrmac[0];
-  gNB_mac->pre_processor_dl = nr_dlsim_preprocessor;
   gNB_RRC_INST rrc;
   memset((void*)&rrc,0,sizeof(rrc));
 
@@ -659,23 +747,23 @@ int main(int argc, char **argv)
   rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon));
 
   NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon;
+  NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
   NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup));
   prepare_scc(rrc.carrier.servingcellconfigcommon);
-  uint64_t ssb_bitmap;
+  uint64_t ssb_bitmap = 1;
   fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu);
-
+  ssb_bitmap = 1;// Enable only first SSB with index ssb_indx=0
   fix_scc(scc,ssb_bitmap);
 
-  fill_default_secondaryCellGroup(scc,
-				  secondaryCellGroup,
-				  0,
-				  1,
-				  n_tx,
-				  0);
+  prepare_scd(scd);
+
+  fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0, 0);
 
+  /* RRC parameter validation for secondaryCellGroup */
+  fix_scd(scd);
   /* -U option modify DMRS */
   if(modify_dmrs) {
-    update_dmrs_config(secondaryCellGroup, NULL,dmrs_arg);
+    update_dmrs_config(secondaryCellGroup, dmrs_arg);
   }
   /* -T option enable PTRS */
   if(enable_ptrs) {
@@ -688,10 +776,13 @@ 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,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,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
-  phy_init_nr_gNB(gNB,0,0);
+  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;
+  phy_init_nr_gNB(gNB,0,1);
   N_RB_DL = gNB->frame_parms.N_RB_DL;
   NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info;
   UE_info->num_UEs=1;
@@ -738,12 +829,12 @@ int main(int argc, char **argv)
   gNB2UE = new_channel_desc_scm(n_tx,
                                 n_rx,
                                 channel_model,
- 				fs,
+                                fs/1e6,//sampling frequency in MHz
 				bw,
 				30e-9,
                                 0,
                                 0,
-                                0);
+                                0, 0);
 
   if (gNB2UE==NULL) {
     printf("Problem generating channel model. Exiting.\n");
@@ -753,28 +844,28 @@ int main(int argc, char **argv)
   frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
   //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
 
-  s_re = malloc(2*sizeof(double*));
-  s_im = malloc(2*sizeof(double*));
-  r_re = malloc(2*sizeof(double*));
-  r_im = malloc(2*sizeof(double*));
-  txdata = malloc(2*sizeof(int*));
-
-  for (i=0; i<2; i++) {
+  s_re = malloc(n_tx*sizeof(double*));
+  s_im = malloc(n_tx*sizeof(double*));
+  r_re = malloc(n_rx*sizeof(double*));
+  r_im = malloc(n_rx*sizeof(double*));
+  txdata = malloc(n_tx*sizeof(int*));
 
+  for (i=0; i<n_tx; i++) {
     s_re[i] = malloc(frame_length_complex_samples*sizeof(double));
     bzero(s_re[i],frame_length_complex_samples*sizeof(double));
     s_im[i] = malloc(frame_length_complex_samples*sizeof(double));
     bzero(s_im[i],frame_length_complex_samples*sizeof(double));
 
+    printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
+    txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
+    bzero(txdata[i],frame_length_complex_samples*sizeof(int));
+  }
+
+  for (i=0; i<n_rx; i++) {
     r_re[i] = malloc(frame_length_complex_samples*sizeof(double));
     bzero(r_re[i],frame_length_complex_samples*sizeof(double));
     r_im[i] = malloc(frame_length_complex_samples*sizeof(double));
     bzero(r_im[i],frame_length_complex_samples*sizeof(double));
-
-    printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
-    txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
-    bzero(txdata[i],frame_length_complex_samples*sizeof(int));
-  
   }
 
   if (pbch_file_fd!=NULL) {
@@ -789,6 +880,7 @@ int main(int argc, char **argv)
   PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE*));
   PHY_vars_UE_g[0][0] = UE;
   memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
+  UE->frame_parms.nb_antennas_rx = n_rx;
 
   if (run_initial_sync==1)  UE->is_synchronized = 0;
   else                      {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;}
@@ -801,13 +893,10 @@ int main(int argc, char **argv)
     exit(-1);
   }
 
-  if(modify_dmrs) {
-    update_dmrs_config( NULL,UE,dmrs_arg);
-  }
   init_nr_ue_transport(UE,0);
 
   nr_gold_pbch(UE);
-  nr_gold_pdcch(UE,0,2);
+  nr_gold_pdcch(UE,0);
 
   nr_l2_init_ue(NULL);
   UE_mac = get_mac_inst(0);
@@ -827,6 +916,7 @@ int main(int argc, char **argv)
   unsigned int errors_bit    = 0;
   uint32_t errors_scrambling = 0;
 
+  initTpool("N", &(nrUE_params.Tpool), false);
 
   test_input_bit       = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
   estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
@@ -834,13 +924,13 @@ int main(int argc, char **argv)
   // generate signal
   AssertFatal(input_fd==NULL,"Not ready for input signal file\n");
   gNB->pbch_configured = 1;
-  gNB->ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
+  gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
+  gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
 
   //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;
@@ -858,7 +948,7 @@ int main(int argc, char **argv)
   scheduled_response.CC_id     = 0;
   scheduled_response.frame = frame;
   scheduled_response.slot  = slot;
-  scheduled_response.thread_id = UE_proc.thread_id;
+  scheduled_response.thread_id = 0;
 
   nr_ue_phy_config_request(&UE_mac->phy_config);
   //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
@@ -912,12 +1002,12 @@ int main(int argc, char **argv)
       NR_gNB_DLSCH_t *gNB_dlsch = gNB->dlsch[0][0];
       nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
       
-      UE_harq_process->harq_ack.ack = 0;
+      UE_harq_process->ack = 0;
       round = 0;
       UE_harq_process->round = round;
       UE_harq_process->first_tx = 1;
         
-      while ((round<num_rounds) && (UE_harq_process->harq_ack.ack==0)) {
+      while ((round<num_rounds) && (UE_harq_process->ack==0)) {
         memset(RC.nrmac[0]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int));
         memset(RC.nrmac[0]->cce_list[1][1],0,MAX_NUM_CCE*sizeof(int));
         clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
@@ -960,16 +1050,16 @@ int main(int argc, char **argv)
           printf("[DLSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
         }
         if (run_initial_sync)
-          nr_common_signal_procedures(gNB,frame,slot);
+          nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[0].ssb_pdu);
         else
-          phy_procedures_gNB_TX(gNB,frame,slot,0);
+          phy_procedures_gNB_TX(gNB,frame,slot,1);
             
         int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP;
         
         if (n_trials==1) {
-          LOG_M("txsigF0.m","txsF0", &gNB->common_vars.txdataF[0][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
+          LOG_M("txsigF0.m","txsF0=", &gNB->common_vars.txdataF[0][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
           if (gNB->frame_parms.nb_antennas_tx>1)
-          LOG_M("txsigF1.m","txsF1", &gNB->common_vars.txdataF[1][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
+            LOG_M("txsigF1.m","txsF1=", &gNB->common_vars.txdataF[1][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
         }
         int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
         if (n_trials==1) printf("tx_offset %d, txdataF_offset %d \n", tx_offset,txdataF_offset);
@@ -993,45 +1083,84 @@ int main(int argc, char **argv)
         }
        
         if (n_trials==1) {
-          LOG_M("txsig0.m","txs0", &txdata[0][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
-          if (gNB->frame_parms.nb_antennas_tx>1)
-            LOG_M("txsig1.m","txs1", &txdata[1][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
+          char filename[100];//LOG_M
+          for (aa=0;aa<n_tx;aa++) {
+            sprintf(filename,"txsig%d.m", aa);//LOG_M
+            LOG_M(filename,"txs", &txdata[aa][tx_offset+frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0],6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples),1,1);
+          }
         }
         if (output_fd) {
           printf("writing txdata to binary file\n");
           fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd);
         }
 
-        int txlev = signal_energy(&txdata[0][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
-        
-        //  if (n_trials==1) printf("txlev %d (%f)\n",txlev,10*log10((double)txlev));
+        int txlev[n_tx];
+        int txlev_sum = 0;
+        int l_ofdm = 6;
+        for (aa=0; aa<n_tx; aa++) {
+          txlev[aa] = signal_energy(&txdata[aa][tx_offset+l_ofdm*frame_parms->ofdm_symbol_size + (l_ofdm-1)*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
+          frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
+          txlev_sum += txlev[aa];
+          if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,txlev[aa],10*log10((double)txlev[aa]),txlev_sum);
+        }
         
         for (i=(frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)); 
              i<(frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0)); 
              i++) {
     
           for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-            r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
-            r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
+            s_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
+            s_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
           }
         }
+
         double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size); 
-        //AWGN
-        sigma2_dB = 10 * log10((double)txlev * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR;
+        //Compute AWGN variance
+        sigma2_dB = 10 * log10((double)txlev_sum * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR;
         sigma2    = pow(10, sigma2_dB/10);
-        if (n_trials==1) printf("sigma2 %f (%f dB), txlev %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize));
+        if (n_trials==1) printf("sigma2 %f (%f dB), txlev_sum %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev_sum),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize));
+
+        for (aa=0; aa<n_rx; aa++) {
+          bzero(r_re[aa],frame_length_complex_samples*sizeof(double));
+          bzero(r_im[aa],frame_length_complex_samples*sizeof(double));
+        }
         
+        // Apply MIMO Channel
+        if (channel_model != AWGN) multipath_tv_channel(gNB2UE,
+                             s_re,
+                             s_im,
+                             r_re,
+                             r_im,
+                             frame_length_complex_samples,
+                             0);
+
+        double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0
+                                   {0.5, 1.0, 0.5, 0.25},  //rx 1
+                                   {0.25, 0.5, 1.0, 0.5},  //rx 2
+                                   {0.125, 0.25, 0.5, 1.0}};//rx 3
+
         for (i=frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); 
              i<frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0);
              i++) {
 
-          for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-            ((short*) UE->common_vars.rxdata[aa])[2*i]   = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
-            ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
+          for (int aa_rx=0; aa_rx<n_rx; aa_rx++) {
+
+            if (channel_model == AWGN) {
+              // sum up signals from different Tx antennas
+              r_re[aa_rx][i] = 0;
+              r_im[aa_rx][i] = 0;
+             for (aa=0; aa<n_tx; aa++) {
+                r_re[aa_rx][i] += s_re[aa][i]*H_awgn_mimo[aa_rx][aa];
+                r_im[aa_rx][i] += s_im[aa][i]*H_awgn_mimo[aa_rx][aa];
+              }
+            }
+            // Add Gaussian noise
+            ((short*) UE->common_vars.rxdata[aa_rx])[2*i]   = (short) ((r_re[aa_rx][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
+            ((short*) UE->common_vars.rxdata[aa_rx])[2*i+1] = (short) ((r_im[aa_rx][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
             /* Add phase noise if enabled */
             if (pdu_bit_map & 0x1) {
-              phase_noise(ts, &((short*) UE->common_vars.rxdata[aa])[2*i],
-                          &((short*) UE->common_vars.rxdata[aa])[2*i+1]);
+              phase_noise(ts, &((short*) UE->common_vars.rxdata[aa_rx])[2*i],
+                          &((short*) UE->common_vars.rxdata[aa_rx])[2*i+1]);
             }
           }
         }
@@ -1042,7 +1171,8 @@ int main(int argc, char **argv)
         phy_procedures_nrUE_RX(UE,
                                &UE_proc,
                                0,
-                               dlsch_threads);
+                               dlsch_threads,
+                               NULL);
         
         //printf("dlsim round %d ends\n",round);
         round++;
@@ -1071,10 +1201,10 @@ int main(int argc, char **argv)
         available_bits-= (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2);
         printf("[DLSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5u \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2) );
       }
-      
+
       for (i = 0; i < available_bits; i++) {
-	
-	if(((gNB_dlsch->harq_process.f[i] == 0) && (UE_llr[i] <= 0)) || 
+
+	if(((gNB_dlsch->harq_process.f[i] == 0) && (UE_llr[i] <= 0)) ||
 	   ((gNB_dlsch->harq_process.f[i] == 1) && (UE_llr[i] >= 0)))
 	  {
 	    if(errors_scrambling == 0) {
@@ -1083,7 +1213,7 @@ int main(int argc, char **argv)
 	    }
 	    errors_scrambling++;
 	  }
-	
+
       }
       for (i = 0; i < TBS; i++) {
 
@@ -1111,10 +1241,12 @@ int main(int argc, char **argv)
 	  printf("errors_bit = %u (trial %d)\n", errors_bit, trial);
       }
       roundStats[snrRun]+=((float)round); 
-      if (UE_harq_process->harq_ack.ack==1) effRate += ((float)TBS)/round;
+      if (UE_harq_process->ack==1) effRate += ((float)TBS)/round;
     } // noise trials
 
+    blerStats[snrRun] = (float) n_errors / (float) n_trials;
     roundStats[snrRun]/=((float)n_trials);
+    berStats[snrRun] = (double)errors_scrambling/available_bits/n_trials;
     effRate /= n_trials;
     printf("*****************************************\n");
     printf("SNR %f, (false positive %f)\n", SNR,
@@ -1122,7 +1254,7 @@ int main(int argc, char **argv)
     printf("*****************************************\n");
     printf("\n");
     dump_pdsch_stats(gNB);
-    printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],(double)errors_scrambling/available_bits/n_trials,effRate,effRate/TBS*100,TBS);
+    printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, BLER %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],berStats[snrRun],blerStats[snrRun],effRate,effRate/TBS*100,TBS);
     printf("\n");
 
     if (print_perf==1) {
@@ -1187,15 +1319,19 @@ int main(int argc, char **argv)
       break;
     }
 
-    //if ((float)n_errors/(float)n_trials <= target_error_rate) {
     if (effRate > (eff_tp_check*TBS)) {
       printf("PDSCH test OK\n");
       break;
     }
 
+    snrStats[snrRun] = SNR;
     snrRun++;
   } // NSR
 
+  LOG_M("dlsimStats.m","SNR",snrStats,snrRun,1,7);
+  LOG_MM("dlsimStats.m","BLER",blerStats,snrRun,1,7);
+  LOG_MM("dlsimStats.m","BER",berStats,snrRun,1,7);
+  LOG_MM("dlsimStats.m","rounds",roundStats,snrRun,1,7);
   /*if (n_trials>1) {
     printf("HARQ stats:\nSNR\tRounds\n");
     psnr = snr0;
@@ -1205,12 +1341,16 @@ int main(int argc, char **argv)
     }
   }*/
 
-  for (i = 0; i < 2; i++) {
+  free_channel_desc_scm(gNB2UE);
+
+  for (i = 0; i < n_tx; i++) {
     free(s_re[i]);
     free(s_im[i]);
+    free(txdata[i]);
+  }
+  for (i = 0; i < n_rx; i++) {
     free(r_re[i]);
     free(r_im[i]);
-    free(txdata[i]);
   }
 
   free(s_re);
@@ -1278,33 +1418,90 @@ void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSi
   rrc_config_dl_ptrs_params(bwp, ptrsFreqDenst, ptrsTimeDenst, &epre_Ratio, &reOffset);
 }
 
-void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg)
+void update_dmrs_config(NR_CellGroupConfig_t *scg, int8_t* dmrs_arg)
 {
   int8_t  mapping_type = typeA;//default value
   int8_t  add_pos = pdsch_dmrs_pos0;//default value
+  int8_t  dmrs_config_type = NFAPI_NR_DMRS_TYPE1;//default value
+
   if(dmrs_arg[0] == 0) {
     mapping_type = typeA;
   }
   else if (dmrs_arg[0] == 1) {
     mapping_type = typeB;
+  } else {
+    AssertFatal(1==0,"Incorrect Mappingtype, valid options 0-typeA, 1-typeB\n");
   }
-  /* Additional DMRS positions 0 ,1 and 2 */
-  if(dmrs_arg[1] >= 0 && dmrs_arg[1] <3 ) {
+
+  /* Additional DMRS positions 0 ,1 ,2 and 3 */
+  if(dmrs_arg[1] >= 0 && dmrs_arg[1] <4 ) {
     add_pos = dmrs_arg[1];
+  } else {
+    AssertFatal(1==0,"Incorrect Additional Position, valid options 0-pos1, 1-pos1, 2-pos2, 3-pos3\n");
   }
 
-  if(scg != NULL) {
-    NR_BWP_Downlink_t *bwp = scg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0];
-    *bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = add_pos;
-    for (int i=0;i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;i++) {
-      bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType = mapping_type; 
-    }
+  /* DMRS Conf Type 1 or 2 */
+  if(dmrs_arg[2] == 1) {
+    dmrs_config_type = NFAPI_NR_DMRS_TYPE1;
+  } else if(dmrs_arg[2] == 2) {
+    dmrs_config_type = NFAPI_NR_DMRS_TYPE2;
+  }
+
+  NR_BWP_Downlink_t *bwp = scg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0];
+
+  AssertFatal((bwp->bwp_Dedicated->pdsch_Config != NULL && bwp->bwp_Dedicated->pdsch_Config->choice.setup != NULL), "Base RRC reconfig structures are not allocated.\n");
+
+  if(mapping_type == typeA) {
+    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));
+    if (dmrs_config_type == NFAPI_NR_DMRS_TYPE2)
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type));
+    else
+      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 = NULL;
+    printf("DLSIM: Allocated Mapping TypeA in RRC reconfig message\n");
+  }
+
+  if(mapping_type == typeB) {
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB));
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup));
+    if (dmrs_config_type == NFAPI_NR_DMRS_TYPE2)
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type));
+    else
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type = NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID0=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID1=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->phaseTrackingRS=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_AdditionalPosition = NULL;
+    printf("DLSIM: Allocated Mapping TypeB in RRC reconfig message\n");
   }
-  if(ue != NULL) {
-    for (int i=0;i<MAX_NR_OF_DL_ALLOCATIONS;i++) {
-      ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i]->mappingType = mapping_type;
+
+  struct NR_SetupRelease_DMRS_DownlinkConfig	*dmrs_MappingtypeA = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA;
+  struct NR_SetupRelease_DMRS_DownlinkConfig	*dmrs_MappingtypeB = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB;
+
+
+  NR_DMRS_DownlinkConfig_t *dmrs_config = (mapping_type == typeA) ? dmrs_MappingtypeA->choice.setup : dmrs_MappingtypeB->choice.setup;
+
+  if (add_pos != 2) { // pos0,pos1,pos3
+    if (dmrs_config->dmrs_AdditionalPosition == NULL) {
+      dmrs_config->dmrs_AdditionalPosition = calloc(1,sizeof(*dmrs_MappingtypeA->choice.setup->dmrs_AdditionalPosition));
     }
-    ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = add_pos;
+    *dmrs_config->dmrs_AdditionalPosition = add_pos;
+  } else { // if NULL, Value pos2
+    free(dmrs_config->dmrs_AdditionalPosition);
+    dmrs_config->dmrs_AdditionalPosition = NULL;
   }
-  printf("[DLSIM] DMRS Config is modified with Mapping Type %d, Additional Positions %d \n", dmrs_arg[0], dmrs_arg[1] );
+
+  for (int i=0;i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;i++) {
+    bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType = mapping_type;
+  }
+
+  printf("[DLSIM] DMRS Config is modified with Mapping Type %d, Additional Positions %d Config. Type %d \n", mapping_type, add_pos, dmrs_config_type);
 }
diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
index 32b6b104123aab8116c5dc2844c48396d357e2f0..70d65a3dc26cfdcf700b0a3b1496a6d397569190 100644
--- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
+++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
@@ -1,3 +1,5 @@
+#include "nfapi/oai_integration/vendor_ext.h"
+
 int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req)             { return(0);  }
 int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req)                            { return(0);  }
 int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req)       { return(0);  }
@@ -25,4 +27,5 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
                            uint8_t gNB_id,
                            PHY_VARS_NR_UE *ue,
                            NR_UE_DLSCH_t *dlsch0,
+                           NR_UE_DLSCH_t *dlsch1,
                            uint16_t n_pdus) {}
diff --git a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h
index 8004fbb6b5be4dce9e4d1d7f3dc24e44e0a9f1f0..8d4acd1af1f2b2726a6885f8f6e53d34b284e7aa 100644
--- a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h
+++ b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h
@@ -55,19 +55,6 @@ signed char quantize(double D, double x, unsigned char B) {
   return ((char) qxd);
 }
 
-
-int8_t
-mac_rrc_data_req_ue(
-  const module_id_t Mod_idP,
-  const int         CC_id,
-  const frame_t     frameP,
-  const rb_id_t     Srb_id,
-  const uint8_t     Nb_tb,
-  uint8_t    *const buffer_pP,
-  const mac_enb_index_t eNB_indexP,
-  const uint8_t     mbsfn_sync_area
-		    ) { return(0);}
-
 int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);}
 //NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);}
 int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
@@ -162,13 +149,13 @@ void fill_scc(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL
   scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present=NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139;
   scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139=0;
   scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig=NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet;
-  *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2=2;
+  *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2=6;
   scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB;
   scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength=55;
-  *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2=2;
+  *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2=6;
   scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB;
   scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength=69;
-  *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->k2=2;
+  *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->k2=6;
   scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB;
   scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->startSymbolAndLength=55;
   *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->k2=33;
@@ -235,6 +222,7 @@ void fill_scc(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL
 
 void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap);
 void prepare_scc(NR_ServingCellConfigCommon_t *scc);
+void prepare_scd(NR_ServingCellConfig_t *scd);
 ngap_gNB_config_t ngap_config;
 uint32_t ngap_generate_gNB_id(void) {return 0;}
 void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { return;}
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index 2512988371dc6bbab29b3ecb3b685df0322850c8..448e1e7799c9a84dc15f4441c189cd98efe1b172 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -47,7 +47,7 @@
 #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
 #include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
 #include "openair1/PHY/MODULATION/nr_modulation.h"
-
+#include <executables/softmodem-common.h>
 //#define DEBUG_NR_PBCHSIM
 
 PHY_VARS_gNB *gNB;
@@ -66,6 +66,7 @@ uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
 uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3};
 
 uint64_t get_softmodem_optmask(void) {return 0;}
+softmodem_params_t *get_softmodem_params(void) {return 0;}
 
 void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
 
@@ -101,8 +102,8 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
   //gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED;
 
   gNB->mac_enabled   = 1;
-  fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
-  fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
+  fp->dl_CarrierFreq = 3600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
+  fp->ul_CarrierFreq = 3600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
   if (mu>2) fp->nr_band = 257;
   else fp->nr_band = 78;
   fp->threequarter_fs= 0;
@@ -111,7 +112,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
 
   nr_init_frame_parms(gNB_config, fp);
 
-  init_symbol_rotation(fp,fp->dl_CarrierFreq);
+  init_symbol_rotation(fp);
 
   gNB->configured    = 1;
   LOG_I(PHY,"gNB configured\n");
@@ -119,7 +120,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
 int main(int argc, char **argv)
 {
   char c;
-  int i,aa;//,l;
+  int i,aa,start_symbol;
   double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0;
   double cfo=0;
   uint8_t snr1set=0;
@@ -414,7 +415,7 @@ int main(int argc, char **argv)
   frame_parms->ssb_type = nr_ssb_type_C;
 
   nr_phy_config_request_sim_pbchsim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
-  phy_init_nr_gNB(gNB,0,0);
+  phy_init_nr_gNB(gNB,0,1);
   nr_set_ssb_first_subcarrier(&gNB->gNB_config,frame_parms);
 
   uint8_t n_hf = 0;
@@ -426,29 +427,28 @@ int main(int argc, char **argv)
   
   switch (mu) {
     case 1:
-	scs = 30000;
-	if (N_RB_DL == 217) { 
-	    fs = 122.88e6;
-	    bw = 80e6;
-	    
-	}					       
-	else if (N_RB_DL == 245) {
-	    fs = 122.88e6;
-	    bw = 90e6;
-	}
-	else if (N_RB_DL == 273) {
-	    fs = 122.88e6;
-	    bw = 100e6;
-	}
-	else if (N_RB_DL == 106) { 
-	    fs = 61.44e6;
-	    bw = 40e6;
-	}
-	else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
-	break;
-  
-
+      scs = 30000;
+      frame_parms->Lmax = 8;
+      if (N_RB_DL == 217) {
+        fs = 122.88e6;
+        bw = 80e6;
+      }
+      else if (N_RB_DL == 245) {
+        fs = 122.88e6;
+        bw = 90e6;
+      }
+      else if (N_RB_DL == 273) {
+        fs = 122.88e6;
+        bw = 100e6;
+      }
+      else if (N_RB_DL == 106) {
+        fs = 61.44e6;
+        bw = 40e6;
+      }
+      else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
+      break;
     case 3:
+      frame_parms->Lmax = 64;
       scs = 120000;
       if (N_RB_DL == 66) {
         fs = 122.88e6;
@@ -457,6 +457,7 @@ int main(int argc, char **argv)
       else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
       break;
   }
+
   // cfo with respect to sub-carrier spacing
   eps = cfo/scs;
 
@@ -479,7 +480,7 @@ int main(int argc, char **argv)
 				300e-9,
                                 0,
                                 0,
-                                0);
+                                0, 0);
 
   if (gNB2UE==NULL) {
 	printf("Problem generating channel model. Exiting.\n");
@@ -510,7 +511,6 @@ int main(int argc, char **argv)
     printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
     txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
     bzero(r_re[i],frame_length_complex_samples*sizeof(int));
-  
   }
 
   if (pbch_file_fd!=NULL) {
@@ -536,60 +536,68 @@ int main(int argc, char **argv)
   }
 
   nr_gold_pbch(UE);
+
   // generate signal
   if (input_fd==NULL) {
-    gNB->pbch_configured = 1;
- 
-    gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0;
 
-    for (int slot=0;slot<frame_parms->slots_per_frame;slot++) {
-    	for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++)
-    		memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
-      
-    	nr_common_signal_procedures (gNB,frame,slot);
-
-    	for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
-    		if (cyclic_prefix_type == 1) {
-    			PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
-    			             &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
-				     frame_parms->ofdm_symbol_size,
-				     12,
-				     frame_parms->nb_prefix_samples,
-				     CYCLIC_PREFIX);
-    		} else {
-		  /*    			nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
-    			                     &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
-			                     14,
-			                     frame_parms);*/
-		  PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
-			       (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
-			       frame_parms->ofdm_symbol_size,
-			       1,
-			       frame_parms->nb_prefix_samples0,
-			       CYCLIC_PREFIX);
-		  
-		  apply_nr_rotation(frame_parms,
-				    (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
-				    slot,
-				    0,
-				    1,
-				    frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
-		  PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
-			       (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
-			       frame_parms->ofdm_symbol_size,
-			       13,
-			       frame_parms->nb_prefix_samples,
-			       CYCLIC_PREFIX);
-		  apply_nr_rotation(frame_parms,
-				    (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
-				    slot,
-				    1,
-				    13,
-				    frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
-    		}
-    	}
+    for (i=0; i<frame_parms->Lmax; i++) {
+      if((SSB_positions >> i) & 0x01) {
+
+        gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
+        gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i;
+
+        start_symbol = nr_get_ssb_start_symbol(frame_parms,i);
+        int slot = start_symbol/14;
+
+        for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++)
+          memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
+
+        nr_common_signal_procedures (gNB,frame,slot,gNB->ssb[i].ssb_pdu);
+
+        for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
+          if (cyclic_prefix_type == 1) {
+            PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
+            &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+            frame_parms->ofdm_symbol_size,
+            12,
+            frame_parms->nb_prefix_samples,
+            CYCLIC_PREFIX);
+          } else {
+            /*nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
+              &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+              14,
+              frame_parms);*/
+            PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
+                         (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+                         frame_parms->ofdm_symbol_size,
+                         1,
+                         frame_parms->nb_prefix_samples0,
+                         CYCLIC_PREFIX);
+
+            apply_nr_rotation(frame_parms,
+                              (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+                              slot,
+                              0,
+                              1,
+                              frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
+
+            PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
+                         (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
+                         frame_parms->ofdm_symbol_size,
+                         13,
+                         frame_parms->nb_prefix_samples,
+                         CYCLIC_PREFIX);
+
+            apply_nr_rotation(frame_parms,
+                              (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
+                              slot,
+                              1,
+                              13,
+                              frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
+          }
+        }
+      }
     }
-
     LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
     if (gNB->frame_parms.nb_antennas_tx>1)
       LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);
@@ -598,9 +606,9 @@ int main(int argc, char **argv)
     printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0);
     UE->UE_fo_compensation = 1; // perform fo compensation when samples from file are used
     if (fread(txdata[0],
-	      sizeof(int32_t),
-	      frame_length_complex_samples,
-	      input_fd) != frame_length_complex_samples) {
+        sizeof(int32_t),
+        frame_length_complex_samples,
+        input_fd) != frame_length_complex_samples) {
       printf("error reading from file\n");
       //exit(-1);
     }
@@ -684,30 +692,26 @@ int main(int argc, char **argv)
 	UE->rx_offset=0;
 	uint8_t ssb_index = 0;
         while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++;  // to select the first transmitted ssb
-        frame_parms->ssb_index = ssb_index;
-	UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms);
+	UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms,ssb_index);
 
-        int ssb_slot = (ssb_index>>1)+(n_hf*frame_parms->slots_per_frame);
+        int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1));
 	for (int i=UE->symbol_offset+1; i<UE->symbol_offset+4; i++) {
           nr_slot_fep(UE,
                       &proc,
                       i%frame_parms->symbols_per_slot,
-                      ssb_slot,
-                      0,
-                      0);
+                      ssb_slot);
 
           nr_pbch_channel_estimation(UE,&proc,0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf);
 
         }
 
         ret = nr_rx_pbch(UE,
-	                 &proc,
-		         UE->pbch_vars[0],
-		         frame_parms,
-		         0,
-		         ssb_index%8,
-                         SISO,
-                         UE->high_speed_flag);
+                         &proc,
+                         UE->pbch_vars[0],
+                         frame_parms,
+                         0,
+                         ssb_index%8,
+                         SISO);
 
 	if (ret==0) {
 	  //UE->rx_ind.rx_indication_body->mib_pdu.ssb_index;  //not yet detected automatically
@@ -718,9 +722,9 @@ int main(int argc, char **argv)
  
 	  payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte);
 	  for (i=0;i<3;i++){
-	    payload_ret += (UE->pbch_vars[0]->decoded_output[i] == (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)));
+	    payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
 	  } 
-	  //printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->rx_ind.rx_indication_body->mib_pdu.additional_bits);
+	  //printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte);
 	  //printf("ret %d\n", payload_ret);
 	  if (payload_ret!=4) 
 	    n_errors_payload++;
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index c90bcf1395d9dbd7755b30a3bd3b0b8c503de9e9..e601a0d7c1962a4dee3052d7ff7de535769d15eb 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -37,6 +37,7 @@
 #include "SCHED_NR_UE/phy_frame_config_nr.h"
 #include "PHY/phy_vars_nr_ue.h"
 #include "PHY/NR_REFSIG/refsig_defs_ue.h"
+#include "PHY/MODULATION/nr_modulation.h"
 #include "PHY/MODULATION/modulation_eNB.h"
 #include "PHY/MODULATION/modulation_UE.h"
 #include "PHY/INIT/phy_init.h"
@@ -47,9 +48,10 @@
 #include "OCG_vars.h"
 #include <openair2/LAYER2/MAC/mac_vars.h>
 #include <openair2/RRC/LTE/rrc_vars.h>
+#include <executables/softmodem-common.h>
+#include <openair2/RRC/NR_UE/rrc_defs.h>
 //#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
 
-
 #define NR_PRACH_DEBUG 1
 #define PRACH_WRITE_OUTPUT_DEBUG 1
 
@@ -64,11 +66,15 @@ double cpuf;
 extern uint16_t prach_root_sequence_map0_3[838];
 openair0_config_t openair0_cfg[MAX_CARDS];
 //uint8_t nfapi_mode=0;
-int sl_ahead = 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);
 
 /* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */
+msc_interface_t msc_interface;
 uint64_t get_softmodem_optmask(void) {return 0;}
 softmodem_params_t *get_softmodem_params(void) {return 0;}
 int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0);  }
@@ -86,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,
@@ -121,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,
@@ -130,15 +146,37 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
   return 0;
 }
 
-int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;}
+int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
+                              const int CC_id,
+                              const uint8_t gNB_index,
+                              const frame_t frame,
+                              const sub_frame_t sub_frame,
+                              const rnti_t rnti,
+                              const channel_t channel,
+                              const uint8_t* pduP,
+                              const sdu_size_t pdu_len)
+{
+  return 0;
+}
+
+void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
+{
+  return;
+}
 
-// Dummy function to avoid linking error at compilation of nr-prachsim
-int is_x2ap_enabled(void)
+int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
+                              const int         CC_id,
+                              const uint8_t     gNB_id,
+                              const frame_t     frameP,
+                              const rb_id_t     Srb_id,
+                              uint8_t           *buffer_pP)
 {
   return 0;
 }
 
-int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
+// Dummy function to avoid linking error at compilation of nr-prachsim
+int is_x2ap_enabled(void)
+{
   return 0;
 }
 
@@ -148,13 +186,38 @@ 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
+} nrUE_params_t;
+
+nrUE_params_t nrUE_params;
+
+nrUE_params_t *get_nrUE_params(void) {
+  return &nrUE_params;
+}
+
+void processSlotTX(void *arg) {}
+
 int main(int argc, char **argv){
 
   char c;
 
   double sigma2, sigma2_dB = 0, SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0;
-  double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs, bw;
-  int i, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1;
+  double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs=-1, bw;
+  int i, l, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1;
   int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0;
   uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0;
   uint8_t frame = 1, slot=19, slot_gNB=19, config_index = 98, prach_sequence_length = 1, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol;
@@ -194,7 +257,7 @@ int main(int argc, char **argv){
 
   randominit(0);
 
-  while ((c = getopt (argc, argv, "hHaA:Cc:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) {
+  while ((c = getopt (argc, argv, "hHaA:Cc:l:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) {
     switch (c) {
     case 'a':
       printf("Running AWGN simulation\n");
@@ -207,6 +270,10 @@ int main(int argc, char **argv){
       config_index = atoi(optarg);
       break;
 
+    case 'l':
+      loglvl = atoi(optarg);
+      break;
+
     case 'r':
       msg1_frequencystart = atoi(optarg);
       break;
@@ -454,7 +521,10 @@ int main(int argc, char **argv){
 
   nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions);
 
-  uint64_t absoluteFrequencyPointA = (mu==1 ? 640000 : 2070833);
+  uint64_t absoluteFrequencyPointA = to_nrarfcn(frame_parms->nr_band,
+				       frame_parms->dl_CarrierFreq,
+				       frame_parms->numerology_index,
+				       frame_parms->N_RB_UL*(180e3)*(1 << frame_parms->numerology_index));
 
   uint8_t subframe = slot/frame_parms->slots_per_subframe;
   
@@ -475,7 +545,8 @@ int main(int argc, char **argv){
   ru->if_south       = LOCAL_RF;
   ru->nb_tx          = n_tx;
   ru->nb_rx          = n_rx;
-
+  ru->num_gNB        = 1;
+  ru->gNB_list[0]    = gNB;
   gNB->gNB_config.carrier_config.num_tx_ant.value = 1;
   gNB->gNB_config.carrier_config.num_rx_ant.value = 1;
   if (mu==1)
@@ -576,7 +647,7 @@ int main(int argc, char **argv){
 
   memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
   RC.nb_nr_L1_inst=1;
-  phy_init_nr_gNB(gNB,0,0);
+  phy_init_nr_gNB(gNB,0,1); //lowmem
   nr_phy_init_RU(ru);
   gNB->common_vars.rxdata = ru->common.rxdata;
   set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
@@ -644,7 +715,7 @@ int main(int argc, char **argv){
                                 DS_TDL,
                                 0.0,
                                 delay,
-                                0);
+                                0, 0);
 
   if (UE2gNB==NULL) {
     printf("Problem generating channel model. Exiting.\n");
@@ -782,7 +853,17 @@ int main(int argc, char **argv){
 	  }
 	}
 
-
+	for (l = 0; l < frame_parms->symbols_per_slot; l++) {
+	  for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
+	    nr_slot_fep_ul(frame_parms,
+			   ru->common.rxdata[aa],
+			   ru->common.rxdataF[aa],
+			   l,
+			   slot,
+			   ru->N_TA_offset);
+	  }
+	}
+	
         rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, prachOccasion, frame, slot);
 
         gNB->prach_vars.rxsigF = ru->prach_rxsigF[prachOccasion];
@@ -805,7 +886,8 @@ int main(int argc, char **argv){
             LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0], N_ZC, 1, 1);
             LOG_M("rxsig0.m","rxs0", &gNB->common_vars.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
             LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
-            LOG_M("ru_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1);
+            LOG_M("ru_rxsigF0.m","rxsF0", ru->common.rxdataF[0], frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot, 1, 1);
+            LOG_M("ru_prach_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1);
             LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1);
             LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1);
           #endif
diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c
index 8d79633a6fb7543b2a4961ab8515211febf13f1a..a3eb4452d7396acf2fb4ba4238f3087607a7eea5 100644
--- a/openair1/SIMULATION/NR_PHY/pucchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pucchsim.c
@@ -46,6 +46,7 @@
 #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
 #include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
 
+
 PHY_VARS_gNB *gNB;
 PHY_VARS_NR_UE *UE;
 RAN_CONTEXT_t RC;
@@ -91,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
@@ -418,7 +420,7 @@ int main(int argc, char **argv)
 	printf("FFO = %lf; IFO = %d\n",eps-IFO,IFO);
   }
 
-  UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, bw, DS_TDL,0, 0, 0);
+  UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, bw, DS_TDL,0, 0, 0, 0);
 
   if (UE2gNB==NULL) {
     printf("Problem generating channel model. Exiting.\n");
@@ -455,32 +457,8 @@ int main(int argc, char **argv)
     bzero(rxdataF[i],14*frame_parms->ofdm_symbol_size*sizeof(int));
   }
 
-
-  //configure UE
-  UE = malloc(sizeof(PHY_VARS_NR_UE));
-  memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
-  UE->pucch_config_common_nr->hoppingId = Nid_cell;
-  //phy_init_nr_top(UE); //called from init_nr_ue_signal
-                      
-  UE->perfect_ce = 0;
-
-  if(eps!=0.0)
-	UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation
-
-  if (init_nr_ue_signal(UE, 1, 0) != 0)
-  {
-    printf("Error at UE NR initialisation\n");
-    exit(-1);
-  }
   uint8_t mcs=0;
-  startingPRB_intraSlotHopping=N_RB_DL-1;
-  pucch_GroupHopping_t PUCCH_GroupHopping=UE->pucch_config_common_nr->pucch_GroupHopping;
-  uint32_t hopping_id=UE->pucch_config_common_nr->hoppingId;
-  uint32_t dmrs_scrambling_id = 0, data_scrambling_id=0;
-  //t_nrPolar_params *currentPtr;
-
   int shift = 0;
-
   if(format==0){
     if (sr_flag)
       shift = 1<<nr_bit;
@@ -494,6 +472,63 @@ int main(int argc, char **argv)
   }
   else if (format == 2 && nr_bit > 11) gNB->uci_polarParams = nr_polar_params(2, nr_bit, nrofPRB, 1, NULL);
   
+  startingPRB_intraSlotHopping=N_RB_DL-1;
+  uint32_t hopping_id=Nid_cell;
+  uint32_t dmrs_scrambling_id = 0, data_scrambling_id=0;
+
+  //configure UE
+  UE = malloc(sizeof(PHY_VARS_NR_UE));
+  memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
+
+  fapi_nr_ul_config_pucch_pdu pucch_tx_pdu;
+  if (format==0) {
+    pucch_tx_pdu.format_type = 0;
+    pucch_tx_pdu.nr_of_symbols = nrofSymbols;
+    pucch_tx_pdu.start_symbol_index = startingSymbolIndex;
+    pucch_tx_pdu.bwp_start = 0;
+    pucch_tx_pdu.prb_start = startingPRB;
+    pucch_tx_pdu.hopping_id = hopping_id;
+    pucch_tx_pdu.group_hop_flag = 0;
+    pucch_tx_pdu.sequence_hop_flag = 0;
+    pucch_tx_pdu.freq_hop_flag = 0;
+    pucch_tx_pdu.mcs = mcs;
+    pucch_tx_pdu.initial_cyclic_shift = 0;
+    pucch_tx_pdu.second_hop_prb = startingPRB_intraSlotHopping;
+  }
+  if (format==2) {
+    pucch_tx_pdu.format_type = 2;
+    pucch_tx_pdu.rnti = 0x1234;
+    pucch_tx_pdu.n_bit = nr_bit;
+    pucch_tx_pdu.payload = actual_payload;
+    pucch_tx_pdu.nr_of_symbols = nrofSymbols;
+    pucch_tx_pdu.start_symbol_index = startingSymbolIndex;
+    pucch_tx_pdu.bwp_start = 0;
+    pucch_tx_pdu.prb_start = startingPRB;
+    pucch_tx_pdu.prb_size = nrofPRB;
+    pucch_tx_pdu.hopping_id = hopping_id;
+    pucch_tx_pdu.group_hop_flag = 0;
+    pucch_tx_pdu.sequence_hop_flag = 0;
+    pucch_tx_pdu.freq_hop_flag = 0;
+    pucch_tx_pdu.dmrs_scrambling_id = dmrs_scrambling_id;
+    pucch_tx_pdu.data_scrambling_id = data_scrambling_id;
+    pucch_tx_pdu.second_hop_prb = startingPRB_intraSlotHopping;
+  }
+
+  UE->perfect_ce = 0;
+
+  if(eps!=0.0)
+    UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation
+
+  if (init_nr_ue_signal(UE, 1, 0) != 0)
+  {
+    printf("Error at UE NR initialisation\n");
+    exit(-1);
+  }
+
+  pucch_GroupHopping_t PUCCH_GroupHopping = pucch_tx_pdu.group_hop_flag + (pucch_tx_pdu.sequence_hop_flag<<1);
+
+  //t_nrPolar_params *currentPtr;
+
   for(SNR=snr0;SNR<=snr1;SNR=SNR+1){
     ack_nack_errors=0;
     sr_errors=0;
@@ -501,13 +536,28 @@ 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,
+                           amp,
+                           nr_slot_tx,
+                           &pucch_tx_pdu);
       }
       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);
+        nr_generate_pucch1(UE,
+                           txdataF,
+                           frame_parms,
+                           amp,
+                           nr_slot_tx,
+                           &pucch_tx_pdu);
       }
       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,
+                           txdataF,
+                           frame_parms,
+                           amp,
+                           nr_slot_tx,
+                           &pucch_tx_pdu);
       }
       
       int txlev = signal_energy(&txdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size],
@@ -532,7 +582,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){
@@ -550,7 +600,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/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c
index 6f2af73a1dd33241c23c75c0aef41c00a285a0a4..c889e6dcb994803a39e906429178e2e0991fc3e7 100644
--- a/openair1/SIMULATION/NR_PHY/ulschsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c
@@ -364,7 +364,7 @@ int main(int argc, char **argv)
                                 61.44e6, //N_RB2sampling_rate(N_RB_DL),
                                 40e6, //N_RB2channel_bandwidth(N_RB_DL),
                                 DS_TDL,
-                                0,0,0);
+                                0,0,0, 0);
 
   if (gNB2UE == NULL) {
     printf("Problem generating channel model. Exiting.\n");
@@ -394,7 +394,7 @@ int main(int argc, char **argv)
 
   nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions);
 
-  phy_init_nr_gNB(gNB, 0, 0);
+  phy_init_nr_gNB(gNB, 0, 1); //lowmem
 
   //configure UE
   UE = malloc(sizeof(PHY_VARS_NR_UE));
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 443ee6e1c0ccef6c04e347c99f8365902dc456ee..b2e82060b83bb6ce2d6a00fbad4197957b6cbba2 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -57,14 +57,14 @@
 #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
 #include "common/utils/threadPool/thread-pool.h"
 #include "PHY/NR_REFSIG/ptrs_nr.h"
-#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
+#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0))
 #include "SIMULATION/LTE_PHY/common_sim.h"
 
 #include <openair2/LAYER2/MAC/mac_vars.h>
 #include <openair2/RRC/LTE/rrc_vars.h>
 
+#include <executables/softmodem-common.h>
 #include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
-
 //#define DEBUG_ULSIM
 
 LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
@@ -75,16 +75,31 @@ PHY_VARS_NR_UE *UE;
 RAN_CONTEXT_t RC;
 int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
 
-int sf_ahead=4 ;
+uint16_t sf_ahead=4 ;
 int slot_ahead=6 ;
-int sl_ahead=0;
+uint16_t sl_ahead=0;
 double cpuf;
 //uint8_t nfapi_mode = 0;
 uint64_t downlink_frequency[MAX_NUM_CCs][4];
+THREAD_STRUCT thread_struct;
+nfapi_ue_release_request_body_t release_rntis;
+uint32_t N_RB_DL = 106;
+
+extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
+
+int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
+                              const int CC_id,
+                              const uint8_t gNB_index,
+                              const frame_t frame,
+                              const sub_frame_t sub_frame,
+                              const rnti_t rnti,
+                              const channel_t channel,
+                              const uint8_t* pduP,
+                              const sdu_size_t pdu_len)
+{
+  return 0;
+}
 
-
-int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index,
-                              const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; }
 int generate_dlsch_header(unsigned char *mac_header,
                           unsigned char num_sdus,
                           unsigned short *sdu_lengths,
@@ -105,6 +120,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,
@@ -114,6 +135,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,
@@ -155,15 +180,38 @@ int is_x2ap_enabled(void)
   return 0;
 }
 
-//nFAPI P7 dummy functions 
+void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
+{
+  return;
+}
+
+int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
+                              const int         CC_id,
+                              const uint8_t     gNB_id,
+                              const frame_t     frameP,
+                              const rb_id_t     Srb_id,
+                              uint8_t           *buffer_pP)
+{
+  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);  }
 int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0);  }
 int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0);  }
 int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0);  }
-int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
-  return 0;
-}
 
 int nr_derive_key(int alg_type, uint8_t alg_id,
                const uint8_t key[32], uint8_t **out)
@@ -171,6 +219,19 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
   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 
+} nrUE_params_t;
+
+void processSlotTX(void *arg) {}
+
+nrUE_params_t nrUE_params;
+
+nrUE_params_t *get_nrUE_params(void) {
+  return &nrUE_params;
+}
 // needed for some functions
 uint16_t n_rnti = 0x1234;
 openair0_config_t openair0_cfg[MAX_CARDS];
@@ -182,6 +243,7 @@ double s_re1[122880],s_im1[122880],r_re1[122880],r_im1[122880];
 double r_re2[122880],r_im2[122880];
 double r_re3[122880],r_im3[122880];
 
+
 int main(int argc, char **argv)
 {
   char c;
@@ -223,7 +285,7 @@ int main(int argc, char **argv)
   int gNB_id = 0;
   int ap;
   int tx_offset;
-  int32_t txlev;
+  int32_t txlev=0;
   int start_rb = 0;
   int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault)
   float target_error_rate = 0.01;
@@ -246,7 +308,7 @@ int main(int argc, char **argv)
   uint16_t ptrsSymbPerSlot = 0;
   uint16_t ptrsRePerSymb = 0;
 
-  uint8_t transform_precoding = transform_precoder_disabled; // 0 - ENABLE, 1 - DISABLE
+  uint8_t transform_precoding = 1; // 0 - ENABLE, 1 - DISABLE
   uint8_t num_dmrs_cdm_grps_no_data = 1;
   uint8_t mcs_table = 0;
 
@@ -255,15 +317,13 @@ 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;
   if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
     exit_fun("[NR_ULSIM] Error, configuration module init failed\n");
   }
-
+  int ul_proc_error = 0; // uplink processing checking status flag
   //logInit();
   randominit(0);
 
@@ -505,7 +565,7 @@ int main(int argc, char **argv)
 
     case 'Z':
 
-      transform_precoding = transform_precoder_enabled; 
+      transform_precoding = 0; // enabled
       num_dmrs_cdm_grps_no_data = 2;
       mcs_table = 3;
       
@@ -580,7 +640,7 @@ int main(int argc, char **argv)
                                 sampling_frequency,
                                 bandwidth,
 				DS_TDL,
-                                0, 0, 0);
+                                0, 0, 0, 0);
 
   if (UE2gNB == NULL) {
     printf("Problem generating channel model. Exiting.\n");
@@ -607,8 +667,8 @@ int main(int argc, char **argv)
   frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
 
 
-  frame_parms->nb_antennas_tx = n_tx;
-  frame_parms->nb_antennas_rx = n_rx;
+  //frame_parms->nb_antennas_tx = n_tx;
+  //frame_parms->nb_antennas_rx = n_rx;
   frame_parms->N_RB_DL = N_RB_DL;
   frame_parms->N_RB_UL = N_RB_UL;
   frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
@@ -626,6 +686,7 @@ int main(int argc, char **argv)
   rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon));
 
   NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon;
+  NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
   NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup));
   prepare_scc(rrc.carrier.servingcellconfigcommon);
   uint64_t ssb_bitmap;
@@ -633,23 +694,23 @@ int main(int argc, char **argv)
 
   fix_scc(scc,ssb_bitmap);
 
-  fill_default_secondaryCellGroup(scc,
-				  secondaryCellGroup,
-				  0,
-				  1,
-				  n_tx,
-				  0);
+  prepare_scd(scd);
+
+  fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0, 0);
 
   // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
 
+  /* RRC parameter validation for secondaryCellGroup */
+  fix_scd(scd);
+
   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,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,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
-  phy_init_nr_gNB(gNB,0,0);
+  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;
 
 
@@ -706,7 +767,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);
 
@@ -774,11 +835,12 @@ int main(int argc, char **argv)
   }
 
   uint8_t  length_dmrs         = pusch_len1;
-  uint16_t l_prime_mask        = get_l_prime(nb_symb_sch, mapping_type, add_pos, length_dmrs);
+  uint16_t l_prime_mask        = get_l_prime(nb_symb_sch, mapping_type, add_pos, length_dmrs, start_symbol, NR_MIB__dmrs_TypeA_Position_pos2);
   uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch);
   uint8_t  nb_re_dmrs          = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4;
 
-  if (transform_precoding == transform_precoder_enabled) {  
+  // if transform precoding is enabled
+  if (transform_precoding == 0) {
 
     AssertFatal(enable_ptrs == 0, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n");
 
@@ -960,7 +1022,7 @@ int main(int argc, char **argv)
       pusch_pdu->transform_precoding = transform_precoding;
       pusch_pdu->data_scrambling_id = *scc->physCellId;
       pusch_pdu->nrOfLayers = 1;
-      pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << start_symbol;
+      pusch_pdu->ul_dmrs_symb_pos = l_prime_mask;
       pusch_pdu->dmrs_config_type = dmrs_config_type;
       pusch_pdu->ul_dmrs_scrambling_id =  *scc->physCellId;
       pusch_pdu->scid = 0;
@@ -983,7 +1045,8 @@ int main(int argc, char **argv)
       pusch_pdu->pusch_ptrs.ptrs_ports_list   = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
       pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
 
-      if (transform_precoding == transform_precoder_enabled) { 
+      // if transform precoding is enabled
+      if (transform_precoding == 0) {
 
         pusch_pdu->dfts_ofdm.low_papr_group_number = *scc->physCellId % 30; // U as defined in 38.211 section 6.4.1.1.1.2 
         pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0;     // V as defined in 38.211 section 6.4.1.1.1.2
@@ -1023,7 +1086,7 @@ int main(int argc, char **argv)
       ul_config.ul_config_list[0].pusch_config_pdu.rb_start = start_rb;
       ul_config.ul_config_list[0].pusch_config_pdu.nr_of_symbols = nb_symb_sch;
       ul_config.ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol;
-      ul_config.ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol;
+      ul_config.ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask;
       ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
       ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs;
       ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
@@ -1043,7 +1106,8 @@ int main(int argc, char **argv)
 
       ul_config.ul_config_list[0].pusch_config_pdu.transform_precoding = transform_precoding;
 
-      if (transform_precoding == transform_precoder_enabled) { 
+      // if transform precoding is enabled
+      if (transform_precoding == 0) {
    
         ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_group_number = *scc->physCellId % 30;// U as defined in 38.211 section 6.4.1.1.1.2 
         ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_sequence_number = 0;// V as defined in 38.211 section 6.4.1.1.1.2
@@ -1053,70 +1117,74 @@ int main(int argc, char **argv)
       }
 
 
-      nr_fill_ulsch(gNB,frame,slot,pusch_pdu);
+      //nr_fill_ulsch(gNB,frame,slot,pusch_pdu); // Not needed as its its already filled as apart of "nr_schedule_response(Sched_INFO);"
 
       for (int i=0;i<(TBS/8);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
       if (input_fd == NULL) {
 
-	  // set FAPI parameters for UE, put them in the scheduled response and call
-	  nr_ue_scheduled_response(&scheduled_response);
-	  
-	  
-	  /////////////////////////phy_procedures_nr_ue_TX///////////////////////
-	  ///////////
-	  
-	  phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id);
-	  
-	  
-	  if (n_trials==1) {
-	    LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1);
-	    LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1);
-	  }
-	  ///////////
-	  ////////////////////////////////////////////////////
-	  tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
-	  
-	  txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
-				frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
+        // set FAPI parameters for UE, put them in the scheduled response and call
+        nr_ue_scheduled_response(&scheduled_response);
+
+
+        /////////////////////////phy_procedures_nr_ue_TX///////////////////////
+        ///////////
+
+        phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id);
+
+        /* We need to call common sending function to send signal */
+        LOG_D(PHY, "Sending Uplink data \n");
+        nr_ue_pusch_common_procedures(UE,
+                                      slot,
+                                      &UE->frame_parms,1);
+
+        if (n_trials==1) {
+          LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1);
+          LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1);
+        }
+        ///////////
+        ////////////////////////////////////////////////////
+        tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
+
+        txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
+                              frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
       }	
       else n_trials = 1;
 
       if (input_fd == NULL ) {
 
-	sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
-	sigma    = pow(10,sigma_dB/10);
+        sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
+        sigma    = pow(10,sigma_dB/10);
 
 
-	if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double)frame_parms->ofdm_symbol_size/(12*nb_rb));
+        if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double)
+                                frame_parms->ofdm_symbol_size/(12*nb_rb));
 
-	for (i=0; i<slot_length; i++) {
-	  for (int aa=0; aa<1; aa++) {
-	    s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)]);
-	    s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]);
-	  }
-	}
-	
+        for (i=0; i<slot_length; i++) {
+          for (int aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
+            s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)]);
+            s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]);
+          }
+        }
 
-	if (UE2gNB->max_Doppler == 0) {
-	  multipath_channel(UE2gNB,s_re,s_im,r_re,r_im,
-			    slot_length,0,(n_trials==1)?1:0);
-	} else {
-	  multipath_tv_channel(UE2gNB,s_re,s_im,r_re,r_im,
-			       2*slot_length,0);
-	}
-	for (i=0; i<slot_length; i++) {
-	  for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
-	    ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)]   = (int16_t)((r_re[ap][i])   + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
-	    ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)]   = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
+
+        if (UE2gNB->max_Doppler == 0) {
+          multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0);
+        } else {
+          multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0);
+        }
+        for (i=0; i<slot_length; i++) {
+          for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
+            ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)   + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
+            ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
             /* Add phase noise if enabled */
             if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
               phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)],
                           &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1]);
             }
-	  }
-	}
+          }
+        }
 
-      }
+      } /*End input_fd */
 
 
       if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
@@ -1137,10 +1205,9 @@ int main(int argc, char **argv)
 	gNB->UL_INFO.rx_ind.number_of_pdus = 0;
 	gNB->UL_INFO.crc_ind.number_crcs = 0;
 
-        start_meas(&gNB->phy_proc_rx);
         phy_procedures_gNB_common_RX(gNB, frame, slot);
 
-        phy_procedures_gNB_uespec_RX(gNB, frame, slot);
+        ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot);
 
 	if (n_trials==1 && round==0) {
 	  LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][slot_offset],slot_length,1,1);
@@ -1150,7 +1217,7 @@ int main(int argc, char **argv)
 	}
 
 
-	if (n_trials == 1  && round==0) { 
+	if (n_trials == 1  && round==0) {
 #ifdef __AVX2__
 	  int off = ((nb_rb&1) == 1)? 4:0;
 #else
@@ -1169,11 +1236,10 @@ int main(int argc, char **argv)
 	  LOG_M("rxsigF0_llr.m","rxsF0_llr",
 		&gNB->pusch_vars[0]->llr[0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
 	}
-        start_meas(&gNB->phy_proc_rx);
         ////////////////////////////////////////////////////////////
-	
-	if (gNB->ulsch[0][0]->last_iteration_cnt >= 
-	    gNB->ulsch[0][0]->max_ldpc_iterations+1) {
+
+	if ((gNB->ulsch[0][0]->last_iteration_cnt >=
+	    gNB->ulsch[0][0]->max_ldpc_iterations+1) || ul_proc_error == 1) {
 	  error_flag = 1; 
 	  n_errors[round]++;
 	  crc_status = 1;
@@ -1262,7 +1328,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/openair1/SIMULATION/TOOLS/DOC/arch.md b/openair1/SIMULATION/TOOLS/DOC/arch.md
new file mode 100644
index 0000000000000000000000000000000000000000..30be337829d05000d6cfa42c5174c0bbd323d55a
--- /dev/null
+++ b/openair1/SIMULATION/TOOLS/DOC/arch.md
@@ -0,0 +1,9 @@
+# Channel simulation source files
+
+1. [random_channel.c](../random_channel.c) 
+1. [sim.h](../sim.h) 
+
+
+
+[channel simulation  main page](channel_simulation.md)
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
\ No newline at end of file
diff --git a/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md b/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md
new file mode 100644
index 0000000000000000000000000000000000000000..be2b987b409ed98363d516da1a11617b28409b65
--- /dev/null
+++ b/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md
@@ -0,0 +1,13 @@
+# OAI channel simulation feature
+
+oai includes a channel simulation feature that any component can use to alter time domain samples of a RF channel by applying pre-defined models as defined, for example, in 3GPP TR 36.873 or TR 38.901
+
+Definition, configuration and run-time modification of a channel model are implemented in common code included in UEs, gNb, eNB and  used when running with  the rfsimulator or the L1 simulator. Phy simulators are also using channel simulation but configuration is done via dedicated command line options. The rfsimulator is the only option to get access to all the configurations and run-time modifications features of oai channel simulation.
+
+## Documentation
+
+* [runtime usage](rtusage.md)
+* [developer usage](devusage.md)
+* [module architecture](arch.md)
+
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
diff --git a/openair1/SIMULATION/TOOLS/DOC/devusage.md b/openair1/SIMULATION/TOOLS/DOC/devusage.md
new file mode 100644
index 0000000000000000000000000000000000000000..8fa6b3fe7a4761c4a969d2072d784a10a874548a
--- /dev/null
+++ b/openair1/SIMULATION/TOOLS/DOC/devusage.md
@@ -0,0 +1,7 @@
+### channel simulation  developer usage
+
+
+[Configuring the channel simulation](rtusage.md)
+
+[channel simulation main page](channel_simulation.md)
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
\ No newline at end of file
diff --git a/openair1/SIMULATION/TOOLS/DOC/rtusage.md b/openair1/SIMULATION/TOOLS/DOC/rtusage.md
new file mode 100644
index 0000000000000000000000000000000000000000..37fc62b496e9aa9769de4e2285f481c5f7ebe2d1
--- /dev/null
+++ b/openair1/SIMULATION/TOOLS/DOC/rtusage.md
@@ -0,0 +1,69 @@
+## configuring the channel simulation
+Oai channel simulation is using the [config module](../../../config/config.md) to get its parameters at init time. The [telnet server](../../telnetsrv/DOC/telnetsrv.md) includes a set of commands which can be used to dynamically modify some channel model parameters
+
+All channel simulation parameters are defined in the `channelmod` section. Most parameters are specific to a channel model and  are only used by the rfsimulator.
+
+### global parameters
+
+| name | type | default | description |
+|:---:|:---:|:---:|:----|
+| `max_chan` | integer | `25` | Maximum number of channel model that can be defined in the system. Must be greater than the number of model definitions  in the model list loaded at init time. |
+| `modellist` | character string | `DefaultChannelList` | Name of the channel models list to load at init time. |
+
+### Model lists
+
+Several model lists can be defined in the oai configuration file. One, defined by the `modellist` parameter is loaded at init time. In the configuration file each model list item describes a channel model using a group of parameters:
+
+| parameter name | type | default | description |
+|:---:|:---:|:---:|:----|
+| `model name` | character string | mandatory |name of the model, as used in the code to retrieve a model definition|
+| `type` |                  | `AWGN` | name of the channel modelization algorithm applied on rf signal. The list of available model types can be listed via the [telnet server](../../telnetsrv/DOC/telnetsrv.md) or by entering an invalid type name |
+| `ploss_dB` |   real (float)   |  | path loss of the channel, in dB |
+| `noise_power_dB` |  real (double)   |  | noise of the channel in dB |
+| `forgetfact` |  real (double)   |  |  |
+| `offset` |     integer      |  |  |
+| `ds_tdl` |   real double    |  |  |
+
+Channel simulation parameters can also be specified on the command line:
+
+```bash
+./lte-softmodem -O ../../../ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf --noS1 --rfsim --rfsimulator.options chanmod --rfsimulator.serveraddr enb --telnetsrv --channelmod.modellist modellist_rfsimu_2 --channelmod.modellist_rfsimu_2.[1].offset 120
+```
+### Using the telnet server to modify channel simulator parameters
+The telnet server includes a `channelmod` command which can be used to dynamically modify some channel model parameters. This command is only available when channel simulation is enabled (via `rfsimulator.options chanmod` option when running the rfsimulator.  `channelmod` command has its own help:
+
+```
+$ telnet 127.0.0.1 9090
+Trying 127.0.0.1...
+Connected to 127.0.0.1.
+Escape character is '^]'.
+ 
+softmodem_enb> help
+.....................................
+   module 6 = channelmod:
+      channelmod help 
+      channelmod show <predef,current>
+      channelmod modify <channelid> <param> <value>
+   module 7 = rfsimu:
+      rfsimu setmodel <model name> <model type>
+softmodem_enb> channelmod help
+channelmod commands can be used to display or modify channel models parameters
+channelmod show predef: display predefined model algorithms available in oai
+channelmod show current: display the currently used models in the running executable
+channelmod modify <model index> <param name> <param value>: set the specified parameters in a current model to the given value
+                  <model index> specifies the model, the show current model command can be used to list the current models indexes
+                  <param name> can be one of "riceanf", "aoa", "randaoa", "ploss", "noise_power_dB", "offset", "forgetf"
+softmodem_enb> 
+
+```
+
+
+
+
+
+
+
+The [rfsimulator documentation](../../../../targets/ARCH/rfsimulator/README.md ) has also some specific information when using the channel simulation via this tool. 
+
+[channel simulation main page](channel_simulation.md)
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
\ No newline at end of file
diff --git a/openair1/SIMULATION/TOOLS/channel_sim.c b/openair1/SIMULATION/TOOLS/channel_sim.c
index 81949f40e6b334b2ca1b7231ee8ef48c174cb552..197a296a5125694f0fc5fe2c178aadfbb59852f6 100644
--- a/openair1/SIMULATION/TOOLS/channel_sim.c
+++ b/openair1/SIMULATION/TOOLS/channel_sim.c
@@ -70,16 +70,16 @@ void do_DL_sig(sim_t *sim,
 
   double s_re0[30720];
   double s_re1[30720];
-  double *s_re[2];
+  double *s_re[RC.nb_RU];
   double s_im0[30720];
   double s_im1[30720];
-  double *s_im[2];
+  double *s_im[RC.nb_RU];
   double r_re00[30720];
   double r_re01[30720];
-  double *r_re0[2];
+  double *r_re0[RC.nb_RU];
   double r_im00[30720];
   double r_im01[30720];
-  double *r_im0[2];
+  double *r_im0[RC.nb_RU];
   LTE_DL_FRAME_PARMS *frame_parms;
 
   s_re[0] = s_re0;
@@ -320,16 +320,16 @@ void do_UL_sig(sim_t *sim,
 
   double s_re0[30720];
   double s_re1[30720];
-  double *s_re[2];
+  double *s_re[NB_UE_INST];
   double s_im0[30720];
   double s_im1[30720];
-  double *s_im[2];
+  double *s_im[NB_UE_INST];
   double r_re00[30720];
   double r_re01[30720];
-  double *r_re0[2];
+  double *r_re0[NB_UE_INST];
   double r_im00[30720];
   double r_im01[30720];
-  double *r_im0[2];
+  double *r_im0[NB_UE_INST];
 
   s_re[0] = s_re0;
   s_im[0] = s_im0;
diff --git a/openair1/SIMULATION/TOOLS/corr_mat.m b/openair1/SIMULATION/TOOLS/corr_mat.m
index 6629030b7df92f88005e053da1be1f0ad0f9d4ef..783310e6e566d2046127d52d5188881a4569096b 100644
--- a/openair1/SIMULATION/TOOLS/corr_mat.m
+++ b/openair1/SIMULATION/TOOLS/corr_mat.m
@@ -57,11 +57,11 @@ R22_sqrt_int(2:2:end,:,:) = imag(R22_sqrt);
 
 %%
 fid = fopen('scm_corrmat.h','w');
-fprintf(fid,'double R22_sqrt[][] = {\n');
+fprintf(fid,'static double R22_sqrt[][] = {\n');
 for i=1:size(Gamma,3)
     fprintf(fid,'{');
     fprintf(fid,'%f, ',R22_sqrt_int(:,:,i)); 
     fprintf(fid,'\b\b},\n');
 end
 fprintf(fid,'};\n');
-fclose(fid)
\ No newline at end of file
+fclose(fid)
diff --git a/openair1/SIMULATION/TOOLS/multipath_channel.c b/openair1/SIMULATION/TOOLS/multipath_channel.c
index 683526a8f010c308d9eb433953aefca43faa295b..3608eb7da25d623cfaa5a87d69bc41c6de8abfb9 100644
--- a/openair1/SIMULATION/TOOLS/multipath_channel.c
+++ b/openair1/SIMULATION/TOOLS/multipath_channel.c
@@ -39,13 +39,13 @@ uint8_t multipath_channel_nosigconv(channel_desc_t *desc)
 //#define CHANNEL_SSE
 #ifdef CHANNEL_SSE
 void multipath_channel(channel_desc_t *desc,
-                       double tx_sig_re[2][30720*2],
-                       double tx_sig_im[2][30720*2],
-                       double rx_sig_re[2][30720*2],
-                       double rx_sig_im[2][30720*2],
+                       double tx_sig_re[NB_ANTENNAS_TX][30720*2],
+                       double tx_sig_im[NB_ANTENANS_TX][30720*2],
+                       double rx_sig_re[NB_ANTENNAS_RX][30720*2],
+                       double rx_sig_im[NB_ANTENNAS_RX][30720*2],
                        uint32_t length,
                        uint8_t keep_channel,
-		       int log_channel)
+             		       int log_channel)
 {
 
   int i,ii,j,l;
@@ -146,13 +146,13 @@ void multipath_channel(channel_desc_t *desc,
 
 #else
 void multipath_channel(channel_desc_t *desc,
-                       double *tx_sig_re[2],
-                       double *tx_sig_im[2],
-                       double *rx_sig_re[2],
-                       double *rx_sig_im[2],
+                       double *tx_sig_re[NB_ANTENNAS_TX],
+                       double *tx_sig_im[NB_ANTENNAS_TX],
+                       double *rx_sig_re[NB_ANTENNAS_RX],
+                       double *rx_sig_im[NB_ANTENNAS_RX],
                        uint32_t length,
                        uint8_t keep_channel,
-		       int log_channel)
+		                   int log_channel)
 {
 
   int i,ii,j,l;
@@ -198,21 +198,22 @@ void multipath_channel(channel_desc_t *desc,
 
           rx_tmp.x += (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].x) - (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].y);
           rx_tmp.y += (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].x) + (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].y);
-	  if (i==0 && log_channel == 1) {
-	    printf("channel[%d][%d][%d] = %f dB (%e,%e)\n",ii,j,l,10*log10(pow(desc->ch[ii+(j*desc->nb_rx)][l].x,2.0)+pow(desc->ch[ii+(j*desc->nb_rx)][l].y,2.0)),
-		   desc->ch[ii+(j*desc->nb_rx)][l].x,
-		   desc->ch[ii+(j*desc->nb_rx)][l].y);
-	  }
+
+          if (i==0 && log_channel == 1) {
+	           printf("channel[%d][%d][%d] = %f dB (%e,%e)\n",ii,j,l,10*log10(pow(desc->ch[ii+(j*desc->nb_rx)][l].x,2.0)+pow(desc->ch[ii+(j*desc->nb_rx)][l].y,2.0)),
+		         desc->ch[ii+(j*desc->nb_rx)][l].x,
+		         desc->ch[ii+(j*desc->nb_rx)][l].y);
+	        }
         } //l
       }  // j
 
       rx_sig_re[ii][i+dd] = rx_tmp.x*path_loss;
       rx_sig_im[ii][i+dd] = rx_tmp.y*path_loss;
-      
-      /*      if ((ii==0)&&((i%32)==0)) {
-	printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
-	}*/
-      
+#ifdef DEBUG_CHANNEL      
+      if ((i%32)==0) {
+	       printf("rx aa %d: %p %p %f,%f => %e,%e\n",ii,rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
+      }	
+#endif      
       //rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]);
       //rx_sig_im[ii][i] = sqrt(.5)*(tx_sig_im[0][i] + tx_sig_im[1][i]);
 
diff --git a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
index d344992586f85025abe01b356ccb021ba41a25b0..ece1f81335f4af9393b4a4df37cf08b10918d618 100644
--- a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
+++ b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
@@ -40,19 +40,17 @@ void multipath_tv_channel(channel_desc_t *desc,
                           uint8_t keep_channel)
 {
 
-  double complex **tx,**rx,***H_t,*rx_temp;//, *tv_H_t;
+  double complex **tx,**rx,***H_t;
   double path_loss = pow(10,desc->path_loss_dB/20);
-  int i,j,k,dd;
+  int i,j,dd;
   dd = abs(desc->channel_offset);
 #ifdef DEBUG_CH
   printf("[TV CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d max_doppler %g\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length,
          desc->max_Doppler);
 #endif
-  tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex));
-  rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex));
-  H_t= (double complex ** *) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **));
-  //  tv_H_t = (double complex *) malloc(length*sizeof(double complex));
-  rx_temp= (double complex *) calloc(length,sizeof(double complex));
+  tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex *));
+  rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex *));
+  H_t= (double complex ***) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **));
 
   for(i=0; i<desc->nb_tx; i++) {
     tx[i] = (double complex *)calloc(length,sizeof(double complex));
@@ -63,10 +61,10 @@ void multipath_tv_channel(channel_desc_t *desc,
   }
 
   for(i=0; i<desc->nb_tx*desc->nb_rx; i++) {
-    H_t[i] = (double complex **) malloc(length*sizeof(double complex *));
+    H_t[i] = (double complex **)malloc(desc->nb_taps*sizeof(double complex *));
 
-    for(j=0; j<length; j++) {
-      H_t[i][j] = (double complex *) calloc (desc->nb_taps,sizeof(double complex));
+    for(j=0; j<desc->nb_taps; j++) {
+      H_t[i][j] = (double complex *)calloc(length,sizeof(double complex));
     }
   }
 
@@ -84,11 +82,7 @@ void multipath_tv_channel(channel_desc_t *desc,
 
   for(i=0; i<desc->nb_rx; i++) {
     for(j=0; j<desc->nb_tx; j++) {
-      tv_conv(H_t[i+(j*desc->nb_rx)],tx[j],rx_temp,length,desc->nb_taps,dd);
-
-      for(k=0; k<length; k++) {
-        rx[i][k] += rx_temp[k];
-      }
+      tv_conv(H_t[i+(j*desc->nb_rx)],tx[j],rx[i],length,desc->nb_taps,dd);
     }
   }
 
@@ -99,10 +93,6 @@ void multipath_tv_channel(channel_desc_t *desc,
     }
   }
 
-  /*  for(k=0;k<length;k++) {
-      tv_H_t[k] = H_t[0][k][0];
-      }*/
-
   for(i=0; i<desc->nb_tx; i++) {
     free(tx[i]);
   }
@@ -116,7 +106,7 @@ void multipath_tv_channel(channel_desc_t *desc,
   free(rx);
 
   for(i=0; i<desc->nb_rx*desc->nb_tx; i++) {
-    for(j=0; j<length; j++) {
+    for(j=0; j<desc->nb_taps; j++) {
       free(H_t[i][j]);
     }
 
@@ -124,21 +114,35 @@ void multipath_tv_channel(channel_desc_t *desc,
   }
 
   free(H_t);
-  free(rx_temp);
 }
 
 //TODO: make phi_rad a parameter of this function
 void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){
 
   int i,j,p,l,k;
-  double *alpha,*phi_rad,pi=acos(-1),*w_Hz;
+  double *alpha,***phi_rad,pi=acos(-1),***w_Hz;
   alpha = (double *)calloc(desc->nb_paths,sizeof(double));
-  phi_rad = (double *)calloc(desc->nb_paths,sizeof(double));
-  w_Hz = (double *)calloc(desc->nb_paths,sizeof(double));
+  phi_rad = (double ***)malloc(desc->nb_rx*desc->nb_tx*sizeof(double **));
+  w_Hz = (double ***)malloc(desc->nb_rx*desc->nb_tx*sizeof(double **));
 
-  for(i=0; i<desc->nb_paths; i++) {
-    w_Hz[i]=desc->max_Doppler*cos(frand_a_b(0,2*pi));
-    phi_rad[i]=frand_a_b(0,2*pi);
+  for(i=0; i<desc->nb_tx*desc->nb_rx; i++) {
+    phi_rad[i]   = (double **) malloc(desc->nb_taps*sizeof(double *));
+    w_Hz[i]      = (double **) malloc(desc->nb_taps*sizeof(double *));
+    for(j=0; j<desc->nb_taps; j++) {
+      phi_rad[i][j]   = (double *) malloc(desc->nb_paths*sizeof(double));
+      w_Hz[i][j]      = (double *) malloc(desc->nb_paths*sizeof(double));
+    }
+  }
+
+  for(i=0; i<desc->nb_tx*desc->nb_rx; i++) {
+    for (j = 0; j<desc->nb_taps; j++) {
+      for(k=0; k<desc->nb_paths; k++) {
+        w_Hz[i][j][k] = desc->max_Doppler*cos(frand_a_b(0,2*M_PI));
+        phi_rad[i][j][k] = frand_a_b(0,2*M_PI);
+        //printf("w_hz[%d][%d][%d]=f_d*cos(theta) = %f\n",i,j,k,w_Hz[i][j][k]);
+        //printf("phi_rad[%d][%d][%d] = %f\n",i,j,k,phi_rad[i][j][k]);
+        }
+    }
   }
 
   if(desc->ricean_factor == 1) {
@@ -153,57 +157,45 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){
     }
   }
 
-  /*
-  // This is the code when we only consider a SISO case
-  for(i=0;i<length;i++)
-  {
-  for(j=0;j<desc->nb_taps;j++)
-     {
-    for(p=0;p<desc->nb_paths;p++)
-       {
-         H[i][j] += sqrt(desc->amps[j]/2)*alpha[p]*cexp(-I*(2*pi*w_Hz[p]*i*(1/(desc->sampling_rate*1e6))+phi_rad[p]));
-       }
-       }
-   }
-  for(j=0;j<desc->nb_paths;j++)
-   {
-  phi_rad[j] = fmod(2*pi*w_Hz[j]*(length-1)*(1/desc->sampling_rate)+phi_rad[j],2*pi);
-   }
-  */
-
-  // if MIMO
+  // SISO or MIMO
   for (i=0; i<desc->nb_rx; i++) {
     for(j=0; j<desc->nb_tx; j++) {
-      for(k=0; k<length; k++) {
-        for(l=0; l<desc->nb_taps; l++) {
-          H[i+(j*desc->nb_rx)][k][l] = 0;
-
+      for(k=0; k<desc->nb_taps; k++) {
+        for(l=0; l<length; l++) {
           for(p=0; p<desc->nb_paths; p++) {
-            H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[l]/2)*alpha[p]*cexp(I*(2*pi*w_Hz[p]*k*(1/(desc->sampling_rate*1e6))+phi_rad[p]));
+            H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[k])*alpha[p]*cexp(I*(2*pi*w_Hz[i+(j*desc->nb_rx)][k][p]*l*(1/(desc->sampling_rate*1e6))+phi_rad[i+(j*desc->nb_rx)][k][p]));
           }
         }
-      }
-
-      for(j=0; j<desc->nb_paths; j++) {
-        phi_rad[j] = fmod(2*pi*w_Hz[j]*(length-1)*(1/desc->sampling_rate)+phi_rad[j],2*pi);
+        //printf("H[tx%d][rx%d][k%d][l%d] = %f+j%f \n",j,i,k,0,creal(H[i+(j*desc->nb_rx)][k][0]),cimag(H[i+(j*desc->nb_rx)][k][0]));
       }
     }
   }
-
+  //accumlate the phase
+  /*for(k=0; k<desc->nb_taps; k++) {
+   * for(j=0; j<desc->nb_paths; j++) {
+   * desc->random_phase[k][j] = fmod(2*pi*w_Hz[k][j]*(length-1)*(1/(desc->sampling_rate*1e6))+phi_rad[k][j],2*pi);
+   * }
+   * }*/
   free(alpha);
+  for(i=0; i<desc->nb_rx*desc->nb_tx; i++) {
+    for (j=0; j<desc->nb_taps; j++) {
+      free(w_Hz[i][j]);
+      free(phi_rad[i][j]);
+    }
+    free(w_Hz[i]);
+    free(phi_rad[i]);
+  }
   free(w_Hz);
   free(phi_rad);
 }
 
 // time varying convolution
-void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int dd){
-
-  int i,j;
-
-  for(i=0; i<((int)nb_samples-dd); i++) {
-    for(j=0; j<nb_taps; j++) {
-      if(i>j)
-        y[i+dd] += creal(h[i][j])*creal(x[i-j])-cimag(h[i][j])*cimag(x[i-j]) + I*(creal(h[i][j])*cimag(x[i-j])+cimag(h[i][j])*creal(x[i-j]));
+void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int dd)
+{
+  for(int i = 0; i < ((int)nb_samples-dd); i++) {
+    for(int j = 0; j < nb_taps; j++) {
+      if(i >= j)
+        y[i+dd] += h[j][i] * x[i-j];
     }
   }
 }
diff --git a/openair1/SIMULATION/TOOLS/phase_noise.c b/openair1/SIMULATION/TOOLS/phase_noise.c
index 5958a0ccdd566ba032021baa9182fb394db6daf1..6cc24f23db15fa7571926a2bc685b89e3894ec04 100644
--- a/openair1/SIMULATION/TOOLS/phase_noise.c
+++ b/openair1/SIMULATION/TOOLS/phase_noise.c
@@ -26,6 +26,7 @@
 #include  "sim.h"
 
 
+static uint16_t LUTSin[ResolSinCos+1];
 /* linear phase noise model */
 void phase_noise(double ts, int16_t * InRe, int16_t * InIm)
 {
diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c
index 8c063fadc093540a0bb3474adef65e241df3dbf3..3acc3f485f9f03cb96ec7781301fa88aa98c6006 100644
--- a/openair1/SIMULATION/TOOLS/random_channel.c
+++ b/openair1/SIMULATION/TOOLS/random_channel.c
@@ -50,7 +50,7 @@ static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt)
 static telnetshell_cmddef_t channelmod_cmdarray[] = {
   {"help","",channelmod_print_help},
   {"show","<predef,current>",channelmod_show_cmd},
-  {"modify","<channelid> <param> <value>",channelmod_modify_cmd},  
+  {"modify","<channelid> <param> <value>",channelmod_modify_cmd},
   {"","",NULL},
 };
 
@@ -61,15 +61,18 @@ static telnetshell_vardef_t channelmod_vardef[] = {
 static double snr_dB=25;
 static double sinr_dB=0;
 static unsigned int max_chan;
-static channel_desc_t**  defined_channels;
+static channel_desc_t **defined_channels;
+static char modellist_name[MAX_OPTNAME_SIZE]= {0};
+
+
 void fill_channel_desc(channel_desc_t *chan_desc,
                        uint8_t nb_tx,
                        uint8_t nb_rx,
                        uint8_t nb_taps,
                        uint8_t channel_length,
                        double *amps,
-                       double *delays,                         
-                       struct complex **R_sqrt,
+                       double *delays,
+                       struct complex *R_sqrt,
                        double Td,
                        double sampling_rate,
                        double channel_bandwidth,
@@ -136,8 +139,10 @@ void fill_channel_desc(channel_desc_t *chan_desc,
   if (R_sqrt == NULL) {
     chan_desc->R_sqrt         = (struct complex **) calloc(nb_taps,sizeof(struct complex *));
     chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_NTAPS ;
+
     for (i = 0; i<nb_taps; i++) {
-      chan_desc->R_sqrt[i]    = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));      
+      chan_desc->R_sqrt[i]    = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));
+
       for (j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
         chan_desc->R_sqrt[i][j].x = 1.0;
         chan_desc->R_sqrt[i][j].y = 0.0;
@@ -145,12 +150,12 @@ void fill_channel_desc(channel_desc_t *chan_desc,
     }
   } else {
     chan_desc->R_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *));
-     
+
     for (i = 0; i<nb_taps; i++) {
       //chan_desc->R_sqrt[i]    = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));
       //chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0];
       /* all chan_desc share the same R_sqrt, coming from caller */
-      chan_desc->R_sqrt[i] = R_sqrt[0];
+      chan_desc->R_sqrt[i] = R_sqrt;
     }
   }
 
@@ -172,354 +177,406 @@ void fill_channel_desc(channel_desc_t *chan_desc,
   reset_meas(&chan_desc->convolution);
 }
 
-double mbsfn_delays[] = {0,.03,.15,.31,.37,1.09,12.490,12.52,12.64,12.80,12.86,13.58,27.49,27.52,27.64,27.80,27.86,28.58};
-double mbsfn_amps_dB[] = {0,-1.5,-1.4,-3.6,-0.6,-7.0,-10,-11.5,-11.4,-13.6,-10.6,-17.0,-20,-21.5,-21.4,-23.6,-20.6,-27};
-
-double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250};                
-double scm_c_amps_dB[] = {0.00, -2.22, -3.98, -1.86, -4.08, -5.84, -1.08, -3.30, -5.06, -9.08, -11.30, -13.06, -15.14, -17.36, -19.12, -20.64, -22.85, -24.62};
-
-double tdl_a_delays[] = {0.0000,
-			 0.3819,
-			 0.4025,
-			 0.5868,
-			 0.4610,
-			 0.5375,
-			 0.6708,
-			 0.5750,
-			 0.7618,
-			 1.5375,
-			 1.8978,
-			 2.2242,
-			 2.1718,
-			 2.4942,
-			 2.5119,
-			 3.0582,
-			 4.0810,
-			 4.4579,
-			 4.5695,
-			 4.7966,
-			 5.0066,
-			 5.3043,
-			 9.6586};
-double tdl_a_amps_dB[] = {-13.4,
-			  0,
-			  -2.2,
-			  -4,
-			  -6,
-			  -8.2,
-			  -9.9,
-			  -10.5,
-			  -7.5,
-			  -15.9,
-			  -6.6,
-			  -16.7,
-			  -12.4,
-			  -15.2,
-			  -10.8,
-			  -11.3,
-			  -12.7,
-			  -16.2,
-			  -18.3,
-			  -18.9,
-			  -16.6,
-			  -19.9,
-			  -29.7};
-#define TDL_A_PATHS 23
-
-double tdl_b_delays[] = {0.0000,
-			 0.1072,
-			 0.2155,
-			 0.2095,
-			 0.2870,
-			 0.2986,
-			 0.3752,
-			 0.5055,
-			 0.3681,
-			 0.3697,
-			 0.5700,
-			 0.5283,
-			 1.1021,
-			 1.2756,
-			 1.5474,
-			 1.7842,
-			 2.0169,
-			 2.8294,
-			 3.0219,
-			 3.6187,
-			 4.1067,
-			 4.2790,
-			 4.7834};
-
-double tdl_b_amps_dB[] = {0,
-			  -2.2,
-			  -4,
-			  -3.2,
-			  -9.8,
-			  -1.2,
-			  -3.4,
-			  -5.2,
-			  -7.6,
-			  -3,
-			  -8.9,
-			  -9,
-			  -4.8,
-			  -5.7,
-			  -7.5,
-			  -1.9,
-			  -7.6,
-			  -12.2,
-			  -9.8,
-			  -11.4,
-			  -14.9,
-			  -9.2,
-			  -11.3};
-#define TDL_B_PATHS 23
-
-double tdl_c_delays[] = {0,
-			 0.2099,
-			 0.2219,
-			 0.2329,
-			 0.2176,
-			 0.6366,
-			 0.6448,
-			 0.6560,
-			 0.6584,
-			 0.7935,
-			 0.8213,
-			 0.9336,
-			 1.2285,
-			 1.3083,
-			 2.1704,
-			 2.7105,
-			 4.2589,
-			 4.6003,
-			 5.4902,
-			 5.6077,
-			 6.3065,
-			 6.6374,
-			 7.0427,
-			 8.6523};
-
-double tdl_c_amps_dB[] = {-4.4,
-			  -1.2,
-			  -3.5,
-			  -5.2,
-			  -2.5,
-			  0,
-			  -2.2,
-			  -3.9,
-			  -7.4,
-			  -7.1,
-			  -10.7,
-			  -11.1,
-			  -5.1,
-			  -6.8,
-			  -8.7,
-			  -13.2,
-			  -13.9,
-			  -13.9,
-			  -15.8,
-			  -17.1,
-			  -16,
-			  -15.7,
-			  -21.6,
-			  -22.8};
-#define TDL_C_PATHS 24
-
-double tdl_d_delays[] = {//0,
-			 0,
-	  	         0.035,
-			 0.612,
-			 1.363,
-			 1.405,
-			 1.804,
-			 2.596,
-			 1.775,
-			 4.042,
-			 7.937,
-			 9.424,
-			 9.708,
-			 12.525};
-
-double tdl_d_amps_dB[] = {//-0.2,
-//-13.5,
-                          -.00147,
-			  -18.8,
-			  -21,
-			  -22.8,
-			  -17.9,
-			  -20.1,
-			  -21.9,
-			  -22.9,
-			  -27.8,
-			  -23.6,
-			  -24.8,
-			  -30.0,
-			  -27.7};
-
-#define TDL_D_PATHS 13
+static double mbsfn_delays[] = {0,.03,.15,.31,.37,1.09,12.490,12.52,12.64,12.80,12.86,13.58,27.49,27.52,27.64,27.80,27.86,28.58};
+static double mbsfn_amps_dB[] = {0,-1.5,-1.4,-3.6,-0.6,-7.0,-10,-11.5,-11.4,-13.6,-10.6,-17.0,-20,-21.5,-21.4,-23.6,-20.6,-27};
+
+static double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250};
+static double scm_c_amps_dB[] = {0.00, -2.22, -3.98, -1.86, -4.08, -5.84, -1.08, -3.30, -5.06, -9.08, -11.30, -13.06, -15.14, -17.36, -19.12, -20.64, -22.85, -24.62};
+
+static double tdl_a_delays[] = {0.0000,
+                         0.3819,
+                         0.4025,
+                         0.5868,
+                         0.4610,
+                         0.5375,
+                         0.6708,
+                         0.5750,
+                         0.7618,
+                         1.5375,
+                         1.8978,
+                         2.2242,
+                         2.1718,
+                         2.4942,
+                         2.5119,
+                         3.0582,
+                         4.0810,
+                         4.4579,
+                         4.5695,
+                         4.7966,
+                         5.0066,
+                         5.3043,
+                         9.6586
+                        };
+static double tdl_a_amps_dB[] = {-13.4,
+                          0,
+                          -2.2,
+                          -4,
+                          -6,
+                          -8.2,
+                          -9.9,
+                          -10.5,
+                          -7.5,
+                          -15.9,
+                          -6.6,
+                          -16.7,
+                          -12.4,
+                          -15.2,
+                          -10.8,
+                          -11.3,
+                          -12.7,
+                          -16.2,
+                          -18.3,
+                          -18.9,
+                          -16.6,
+                          -19.9,
+                          -29.7
+                          };
+
+static double tdl_b_delays[] = {0.0000,
+                         0.1072,
+                         0.2155,
+                         0.2095,
+                         0.2870,
+                         0.2986,
+                         0.3752,
+                         0.5055,
+                         0.3681,
+                         0.3697,
+                         0.5700,
+                         0.5283,
+                         1.1021,
+                         1.2756,
+                         1.5474,
+                         1.7842,
+                         2.0169,
+                         2.8294,
+                         3.0219,
+                         3.6187,
+                         4.1067,
+                         4.2790,
+                         4.7834
+                        };
+
+static double tdl_b_amps_dB[] = {0,
+                          -2.2,
+                          -4,
+                          -3.2,
+                          -9.8,
+                          -1.2,
+                          -3.4,
+                          -5.2,
+                          -7.6,
+                          -3,
+                          -8.9,
+                          -9,
+                          -4.8,
+                          -5.7,
+                          -7.5,
+                          -1.9,
+                          -7.6,
+                          -12.2,
+                          -9.8,
+                          -11.4,
+                          -14.9,
+                          -9.2,
+                          -11.3
+                          };
+
+static double tdl_c_delays[] = {0,
+                         0.2099,
+                         0.2219,
+                         0.2329,
+                         0.2176,
+                         0.6366,
+                         0.6448,
+                         0.6560,
+                         0.6584,
+                         0.7935,
+                         0.8213,
+                         0.9336,
+                         1.2285,
+                         1.3083,
+                         2.1704,
+                         2.7105,
+                         4.2589,
+                         4.6003,
+                         5.4902,
+                         5.6077,
+                         6.3065,
+                         6.6374,
+                         7.0427,
+                         8.6523
+                        };
+
+static double tdl_c_amps_dB[] = {-4.4,
+                          -1.2,
+                          -3.5,
+                          -5.2,
+                          -2.5,
+                          0,
+                          -2.2,
+                          -3.9,
+                          -7.4,
+                          -7.1,
+                          -10.7,
+                          -11.1,
+                          -5.1,
+                          -6.8,
+                          -8.7,
+                          -13.2,
+                          -13.9,
+                          -13.9,
+                          -15.8,
+                          -17.1,
+                          -16,
+                          -15.7,
+                          -21.6,
+                          -22.8
+                          };
+
+static double tdl_d_delays[] = {//0,
+  0,
+  0.035,
+  0.612,
+  1.363,
+  1.405,
+  1.804,
+  2.596,
+  1.775,
+  4.042,
+  7.937,
+  9.424,
+  9.708,
+  12.525
+};
+
+static double tdl_d_amps_dB[] = {//-0.2,
+  //-13.5,
+  -.00147,
+    -18.8,
+    -21,
+    -22.8,
+    -17.9,
+    -20.1,
+    -21.9,
+    -22.9,
+    -27.8,
+    -23.6,
+    -24.8,
+    -30.0,
+    -27.7
+  };
+
 #define TDL_D_RICEAN_FACTOR .046774
 
-double tdl_e_delays[] = {0,
-			 0.5133,
-			 0.5440,
-			 0.5630,
-			 0.5440,
-			 0.7112,
-			 1.9092,
-			 1.9293,
-			 1.9589,
-			 2.6426,
-			 3.7136,
-			 5.4524,
-			 12.0034,
-			 20.6519};
-
-double tdl_e_amps_dB[] = {//-0.03,
-			  //-22.03,
-                          -.00433,
-			  -15.8,
-			  -18.1,
-			  -19.8,
-			  -22.9,
-			  -22.4,
-			  -18.6,
-			  -20.8,
-			  -22.6,
-			  -22.3,
-			  -25.6,
-			  -20.2,
-			  -29.8,
-			  -29.2};
-
-#define TDL_E_PATHS 14
-#define TDL_E_RICEAN_FACTOR 0.0063096
+static double tdl_e_delays[] = {0,
+                         0.5133,
+                         0.5440,
+                         0.5630,
+                         0.5440,
+                         0.7112,
+                         1.9092,
+                         1.9293,
+                         1.9589,
+                         2.6426,
+                         3.7136,
+                         5.4524,
+                         12.0034,
+                         20.6519
+                        };
+
+static double tdl_e_amps_dB[] = {//-0.03,
+  //-22.03,
+  -.00433,
+    -15.8,
+    -18.1,
+    -19.8,
+    -22.9,
+    -22.4,
+    -18.6,
+    -20.8,
+    -22.6,
+    -22.3,
+    -25.6,
+    -20.2,
+    -29.8,
+    -29.2
+  };
 
-double epa_delays[] = { 0,.03,.07,.09,.11,.19,.41};
-double epa_amps_dB[] = {0.0,-1.0,-2.0,-3.0,-8.0,-17.2,-20.8};
+#define TDL_E_RICEAN_FACTOR 0.0063096
 
-double eva_delays[] = { 0,.03,.15,.31,.37,.71,1.09,1.73,2.51};
-double eva_amps_dB[] = {0.0,-1.5,-1.4,-3.6,-0.6,-9.1,-7.0,-12.0,-16.9};
+static double epa_delays[] = { 0,.03,.07,.09,.11,.19,.41};
+static double epa_amps_dB[] = {0.0,-1.0,-2.0,-3.0,-8.0,-17.2,-20.8};
 
-double etu_delays[] = { 0,.05,.12,.2,.23,.5,1.6,2.3,5.0};
-double etu_amps_dB[] = {-1.0,-1.0,-1.0,0.0,0.0,0.0,-3.0,-5.0,-7.0};
+static double eva_delays[] = { 0,.03,.15,.31,.37,.71,1.09,1.73,2.51};
+static double eva_amps_dB[] = {0.0,-1.5,-1.4,-3.6,-0.6,-9.1,-7.0,-12.0,-16.9};
 
-double default_amps_lin[] = {0.3868472, 0.3094778, 0.1547389, 0.0773694, 0.0386847, 0.0193424, 0.0096712, 0.0038685};
-double default_amp_lin[] = {1};
+static double etu_delays[] = { 0,.05,.12,.2,.23,.5,1.6,2.3,5.0};
+static double etu_amps_dB[] = {-1.0,-1.0,-1.0,0.0,0.0,0.0,-3.0,-5.0,-7.0};
 
-double ts_shift_delays[] = {0, 1/7.68};
-double ts_shift_amps[] = {0, 1};
+static double default_amps_lin[] = {0.3868472, 0.3094778, 0.1547389, 0.0773694, 0.0386847, 0.0193424, 0.0096712, 0.0038685};
+static double default_amp_lin[] = {1};
 
 //correlation matrix for a 2x2 channel with full Tx correlation
-struct complex R_sqrt_22_corr_tap[16] = {{0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0},
+static struct complex R_sqrt_22_corr[16] = {{0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0},
   {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0},
   {0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0},
   {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0}
 };
-struct complex *R_sqrt_22_corr[1]     = {R_sqrt_22_corr_tap};
 
 //correlation matrix for a fully correlated 2x1 channel (h1==h2)
-struct complex R_sqrt_21_corr_tap[4]  = {{0.70711,0}, {0.70711,0}, {0.70711,0}, {0.70711,0}};
-struct complex *R_sqrt_21_corr[1]      = {R_sqrt_21_corr_tap};
+static struct complex R_sqrt_21_corr[]  = {{0.70711,0}, {0.70711,0}, {0.70711,0}, {0.70711,0}};
 
 //correlation matrix for a 2x2 channel with full Tx anti-correlation
-struct complex R_sqrt_22_anticorr_tap[16] = {{0.70711,0}, {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0},
+static struct complex R_sqrt_22_anticorr[16] = {{0.70711,0}, {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0},
   {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {-0.70711,0},
   {-0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0},
   {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, {0.70711,0}
 };
-struct complex *R_sqrt_22_anticorr[1]     = {R_sqrt_22_anticorr_tap};
 
 //correlation matrix for a fully anti-correlated 2x1 channel (h1==-h2)
-struct complex R_sqrt_21_anticorr_tap[4]  = {{0.70711,0}, {-0.70711,0}, {-0.70711,0}, {0.70711,0}};
-struct complex *R_sqrt_21_anticorr[1]     = {R_sqrt_21_anticorr_tap};
-
-struct complex **R_sqrt_ptr2;
+static struct complex R_sqrt_21_anticorr[4]  = {{0.70711,0}, {-0.70711,0}, {-0.70711,0}, {0.70711,0}};
 
 // full correlation matrix in vectorized form for 2x2 channel, where h1 is  perfectly orthogonal to h2
 
-struct complex R_sqrt_22_orthogonal_tap[16] = {{0.70711,0.0}, {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0},
+static struct complex R_sqrt_22_orthogonal[16] = {{0.70711,0.0}, {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0},
   {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0}, {0.0,0.0},
   {0.0,0.0}, {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0},
   {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0}, {0.70711,0.0}
 };
-struct complex *R_sqrt_22_orthogonal[1]     = {R_sqrt_22_orthogonal_tap};
 
 // full correlation matrix for TM4 to make orthogonal effective channel
-
-
-
-
-struct complex R_sqrt_22_orth_eff_ch_TM4_prec_real_tap[16] = {{0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0},
+static struct complex R_sqrt_22_orth_eff_ch_TM4_prec_real[16] = {{0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0},
   {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {-0.70711,0.0},
   {0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0},
   {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}
 };
-struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_real[1]     = {R_sqrt_22_orth_eff_ch_TM4_prec_real_tap};
-
-
-
 
-struct complex R_sqrt_22_orth_eff_ch_TM4_prec_imag_tap[16] = {{0.70711,0.0}, {0.0,0.0}, {0.0, -0.70711}, {0.0,0.0},
+static struct complex R_sqrt_22_orth_eff_ch_TM4_prec_imag[16] = {{0.70711,0.0}, {0.0,0.0}, {0.0, -0.70711}, {0.0,0.0},
   {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {0.0,0.70711},
   {0.0,-0.70711}, {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0},
   {0.0, 0.0}, {0.0,0.70711}, {0.0, 0.0}, {-0.70711,0.0}
 };
-struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_imag[1]     = {R_sqrt_22_orth_eff_ch_TM4_prec_imag_tap};
 
 //Correlation matrix for EPA channel
-struct complex R_sqrt_22_EPA_low_tap[16] = {{1.0,0.0}, {0.0,0.0}, {0.0,0.0}, {0.0,0.0},
+static struct complex R_sqrt_22_EPA_low[16] = {{1.0,0.0}, {0.0,0.0}, {0.0,0.0}, {0.0,0.0},
   {0.0,0.0}, {1.0,0.0}, {0.0,0.0}, {0.0,0.0},
   {0.0,0.0}, {0.0,0.0}, {1.0,0.0}, {0.0,0.0},
   {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {1.0,0.0}
 };
-struct complex *R_sqrt_22_EPA_low[1]     = {R_sqrt_22_EPA_low_tap};
 
-struct complex R_sqrt_22_EPA_high_tap[16] = {
+static struct complex R_sqrt_22_EPA_high[16] = {
   {0.7179,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.2821,0.0},
   {0.4500,0.0}, {0.7179,0.0}, {0.2821,0.0}, {0.4500,0.0},
   {0.4500,0.0}, {0.2821,0.0}, {0.7179,0.0}, {0.4500,0.0},
   {0.2821,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.7179,0.0}
 };
-struct complex *R_sqrt_22_EPA_high[1]     = {R_sqrt_22_EPA_high_tap};
 
-struct complex R_sqrt_22_EPA_medium_tap[16] = {{0.8375,0.0}, {0.5249,0.0}, {0.1286,0.0}, {0.0806,0.0},
+static struct complex R_sqrt_22_EPA_medium[16] = {{0.8375,0.0}, {0.5249,0.0}, {0.1286,0.0}, {0.0806,0.0},
   {0.5249,0.0}, {0.8375,0.0}, {0.0806,0.0}, {0.1286,0.0},
   {0.1286,0.0}, {0.0806,0.0}, {0.8375,0.0}, {0.5249,0.0},
   {0.0806,0.0}, {0.1286,0.0}, {0.5249,0.0}, {0.8375,0.0}
 };
-struct complex *R_sqrt_22_EPA_medium[1]     = {R_sqrt_22_EPA_medium_tap};
 
+//Rayleigh1_orth_eff_ch_TM4
 
+void tdlModel(int  tdl_paths, double *tdl_delays, double *tdl_amps_dB, double DS_TDL, channel_desc_t *chan_desc ) {
+  int nb_rx=chan_desc-> nb_rx;
+  int nb_tx=chan_desc-> nb_tx;
+  int tdl_pathsby3 = tdl_paths/3;
+
+  if ((tdl_paths%3)>0)
+    tdl_pathsby3++;
+
+  chan_desc->nb_taps        = tdl_paths;
+  chan_desc->Td             = tdl_delays[tdl_paths-1]*DS_TDL;
+  printf("last path (%d) at %f * %e = %e\n",tdl_paths-1,tdl_delays[tdl_paths-1],DS_TDL,chan_desc->Td);
+  chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td +
+                                     1 +
+                                     2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
+  printf("TDL : %f Ms/s, nb_taps %d, Td %e, channel_length %d\n",chan_desc->sampling_rate,tdl_paths,chan_desc->Td,chan_desc->channel_length);
+  double sum_amps = 0;
+  chan_desc->amps           = (double *) malloc(chan_desc->nb_taps*sizeof(double));
+
+  for (int i = 0; i<chan_desc->nb_taps; i++) {
+    chan_desc->amps[i]      = pow(10,.1*tdl_amps_dB[i]);
+    sum_amps += chan_desc->amps[i];
+  }
 
-//Rayleigh1_orth_eff_ch_TM4
+  for (int i = 0; i<chan_desc->nb_taps; i++) {
+    chan_desc->amps[i] /= sum_amps;
+    tdl_delays[i] *= DS_TDL;
+  }
+
+  chan_desc->delays         = tdl_delays;
+  chan_desc->aoa            = 0;
+  chan_desc->random_aoa     = 0;
+  chan_desc->ch             = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *));
+  chan_desc->chF            = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *));
+  chan_desc->a              = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *));
+
+  for (int i = 0; i<nb_tx*nb_rx; i++)
+    chan_desc->ch[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex));
+
+  for (int i = 0; i<nb_tx*nb_rx; i++)
+    chan_desc->chF[i] = (struct complex *) malloc(1200 * sizeof(struct complex));
+
+  for (int i = 0; i<chan_desc->nb_taps; i++)
+    chan_desc->a[i]         = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex));
+
+  chan_desc->R_sqrt  = (struct complex **) malloc(6*sizeof(struct complex **));
+
+  if (nb_tx==2 && nb_rx==2) {
+    for (int i = 0; i<(tdl_pathsby3); i++)
+      chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0];
+  } else if (nb_tx==2 && nb_rx==1) {
+    for (int i = 0; i<(tdl_pathsby3); i++)
+      chan_desc->R_sqrt[i] = (struct complex *) &R21_sqrt[i][0];
+  } else if (nb_tx==1 && nb_rx==2) {
+    for (int i = 0; i<(tdl_pathsby3); i++)
+      chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
+  } else {
+    for (int i = 0; i<(tdl_pathsby3); i++) {
+      chan_desc->R_sqrt[i]    = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
+
+      for (int j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
+        chan_desc->R_sqrt[i][j].x = 1.0;
+        chan_desc->R_sqrt[i][j].y = 0.0;
+      }
+
+      LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx);
+    }
+  }
+}
 
 channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
                                      uint8_t nb_rx,
                                      SCM_t channel_model,
                                      double sampling_rate,
                                      double channel_bandwidth,
-				     double DS_TDL,
+                                     double DS_TDL,
                                      double forgetting_factor,
                                      int32_t channel_offset,
-                                     double path_loss_dB) {
+                                     double path_loss_dB,
+                                     float  noise_power_dB) {
   channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t));
-  for(int i=0; i<max_chan;i++) {
-  	  if (defined_channels[i] == NULL) {
-  	  	  defined_channels[i]=chan_desc;                             
-  	  	  chan_desc->chan_idx=i;
-  	      break;
-  	  }
-  	  else {
-  	  	 AssertFatal(i<(max_chan-1),
-              "No more channel descriptors available, increase channelmod.max_chan parameter above %u\n",max_chan);
-  	  }
+
+  for(int i=0; i<max_chan; i++) {
+    if (defined_channels[i] == NULL) {
+      defined_channels[i]=chan_desc;
+      chan_desc->chan_idx=i;
+      break;
+    } else {
+      AssertFatal(i<(max_chan-1),
+                  "No more channel descriptors available, increase channelmod.max_chan parameter above %u\n",max_chan);
+    }
   }
+
   uint16_t i,j;
   double sum_amps;
   double aoa,ricean_factor,Td,maxDoppler;
-
   int channel_length,nb_taps;
+  struct complex *R_sqrt_ptr2;
   chan_desc->modelid                   = channel_model;
   chan_desc->nb_tx                      = nb_tx;
   chan_desc->nb_rx                      = nb_rx;
@@ -530,13 +587,13 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
   chan_desc->path_loss_dB               = path_loss_dB;
   chan_desc->first_run                  = 1;
   chan_desc->ip                                 = 0.0;
+  chan_desc->noise_power_dB             = noise_power_dB;
   LOG_I(OCM,"Channel Model (inside of new_channel_desc_scm)=%d\n\n", channel_model);
-
   int tdl_paths=0;
-  double tdl_ricean_factor = 1;
   double *tdl_amps_dB;
   double *tdl_delays;
 
+  /*  Spatial Channel Models (SCM)  channel model from TR 38.901 Section 7.7.2 */
   switch (channel_model) {
     case SCM_A:
       LOG_W(OCM,"channel model not yet supported\n");
@@ -554,7 +611,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
       sum_amps = 0;
       chan_desc->amps           = (double *) malloc(chan_desc->nb_taps*sizeof(double));
-      chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;         
+      chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
       for (i = 0; i<chan_desc->nb_taps; i++) {
         chan_desc->amps[i]      = pow(10,.1*scm_c_amps_dB[i]);
         sum_amps += chan_desc->amps[i];
@@ -592,10 +650,11 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
         for (i = 0; i<6; i++)
           chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
       } else {
-      	chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; 
+        chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
+
         for (i = 0; i<6; i++) {
           chan_desc->R_sqrt[i]    = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
-           
+
           for (j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
             chan_desc->R_sqrt[i][j].x = 1.0;
             chan_desc->R_sqrt[i][j].y = 0.0;
@@ -615,6 +674,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       sum_amps = 0;
       chan_desc->amps           = (double *) malloc(chan_desc->nb_taps*sizeof(double));
       chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
       for (i = 0; i<chan_desc->nb_taps; i++) {
         chan_desc->amps[i]      = pow(10,.1*scm_c_amps_dB[i]);
         sum_amps += chan_desc->amps[i];
@@ -652,7 +712,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
         for (i = 0; i<6; i++)
           chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
       } else {
-      	chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
+        chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
+
         for (i = 0; i<6; i++) {
           chan_desc->R_sqrt[i]    = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
 
@@ -666,99 +727,41 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       }
 
       break;
-      
-    case TDL_A:
-    case TDL_B:
-    case TDL_C:  
-    case TDL_D:  
-    case TDL_E:
-      if (channel_model == TDL_A) {  
-	tdl_paths=TDL_A_PATHS;
-	tdl_delays=tdl_a_delays;
-	tdl_amps_dB=tdl_a_amps_dB;
-      }else if (channel_model == TDL_B) {
-	  tdl_paths=TDL_B_PATHS;
-	tdl_delays=tdl_b_delays;
-	tdl_amps_dB=tdl_b_amps_dB;      
-      }
-      else if (channel_model == TDL_C) {
-	tdl_paths=TDL_C_PATHS;
-	tdl_delays=tdl_c_delays;
-	tdl_amps_dB=tdl_c_amps_dB;
-	printf("Initializing TDL_C channel with %d paths\n",TDL_C_PATHS);
-      } else if (channel_model == TDL_D) {
-	tdl_paths=TDL_D_PATHS;
-	tdl_delays=tdl_d_delays;
-	tdl_amps_dB=tdl_d_amps_dB;
-	tdl_ricean_factor = TDL_D_RICEAN_FACTOR;
-      } else if (channel_model == TDL_E) {
-	tdl_paths=TDL_E_PATHS-1;
-	tdl_delays=tdl_e_delays+1;
-	tdl_amps_dB=tdl_e_amps_dB;
-	tdl_ricean_factor = TDL_E_RICEAN_FACTOR;
-      }
+      /*  tapped delay line (TDL)  channel model from TR 38.901 Section 7.7.2 */
+#define tdl_m(MoDel)\
+  DevAssert(sizeof(tdl_ ## MoDel ## _amps_dB) == sizeof(tdl_ ## MoDel ## _delays)); \
+  tdl_paths=sizeof(tdl_ ## MoDel ## _amps_dB)/sizeof(*tdl_ ## MoDel ## _amps_dB);\
+  tdl_delays=tdl_ ## MoDel ## _delays;\
+  tdl_amps_dB=tdl_ ## MoDel ## _amps_dB
 
-      int tdl_pathsby3 = tdl_paths/3;
-      if ((tdl_paths%3)>0) tdl_pathsby3++;
-
-      chan_desc->nb_taps        = tdl_paths;
-      chan_desc->Td             = tdl_delays[tdl_paths-1]*DS_TDL;
-      printf("last path (%d) at %f * %e = %e\n",tdl_paths-1,tdl_delays[tdl_paths-1],DS_TDL,chan_desc->Td);
-      chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
-      printf("TDL : %f Ms/s, nb_taps %d, Td %e, channel_length %d\n",chan_desc->sampling_rate,tdl_paths,chan_desc->Td,chan_desc->channel_length);
-      sum_amps = 0;
-      chan_desc->amps           = (double *) malloc(chan_desc->nb_taps*sizeof(double));
-
-      for (i = 0; i<chan_desc->nb_taps; i++) {
-        chan_desc->amps[i]      = pow(10,.1*tdl_amps_dB[i]);
-        sum_amps += chan_desc->amps[i];
-      }
-
-      for (i = 0; i<chan_desc->nb_taps; i++) {
-        chan_desc->amps[i] /= sum_amps;
-	tdl_delays[i] *= DS_TDL;
-      }
-      chan_desc->delays         = tdl_delays;
-      chan_desc->ricean_factor  = tdl_ricean_factor;
-      chan_desc->aoa            = 0;
-      chan_desc->random_aoa     = 0;
-      chan_desc->ch             = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *));
-      chan_desc->chF            = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *));
-      chan_desc->a              = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *));
-
-      for (i = 0; i<nb_tx*nb_rx; i++)
-        chan_desc->ch[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex));
-
-      for (i = 0; i<nb_tx*nb_rx; i++)
-        chan_desc->chF[i] = (struct complex *) malloc(1200 * sizeof(struct complex));
-
-      for (i = 0; i<chan_desc->nb_taps; i++)
-        chan_desc->a[i]         = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex));
-
-      chan_desc->R_sqrt  = (struct complex **) malloc(6*sizeof(struct complex **));
+    case TDL_A:
+      chan_desc->ricean_factor  = 1;
+      tdl_m(a);
+      tdlModel(tdl_paths,  tdl_delays, tdl_amps_dB,  DS_TDL, chan_desc);
+      break;
 
-      if (nb_tx==2 && nb_rx==2) {
-        for (i = 0; i<(tdl_pathsby3); i++)
-          chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0];
-      } else if (nb_tx==2 && nb_rx==1) {
-        for (i = 0; i<(tdl_pathsby3); i++)
-          chan_desc->R_sqrt[i] = (struct complex *) &R21_sqrt[i][0];
-      } else if (nb_tx==1 && nb_rx==2) {
-        for (i = 0; i<(tdl_pathsby3); i++)
-          chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
-      } else {
-        for (i = 0; i<(tdl_pathsby3); i++) {
-          chan_desc->R_sqrt[i]    = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
+    case TDL_B:
+      chan_desc->ricean_factor  = 1;
+      tdl_m(b);
+      tdlModel(tdl_paths,  tdl_delays, tdl_amps_dB,  DS_TDL, chan_desc);
+      break;
 
-          for (j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
-            chan_desc->R_sqrt[i][j].x = 1.0;
-            chan_desc->R_sqrt[i][j].y = 0.0;
-          }
+    case TDL_C:
+      chan_desc->ricean_factor  = 1;
+      tdl_m(c);
+      tdlModel(tdl_paths,  tdl_delays, tdl_amps_dB,  DS_TDL, chan_desc);
+      break;
 
-          LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx);
-        }
-      }
+    case TDL_D:
+      chan_desc->ricean_factor  = TDL_D_RICEAN_FACTOR;
+      tdl_m(d);
+      tdlModel(tdl_paths,  tdl_delays, tdl_amps_dB,  DS_TDL, chan_desc);
+      break;
 
+    case TDL_E:
+      chan_desc->ricean_factor  = TDL_E_RICEAN_FACTOR;
+      tdl_m(e);
+      tdlModel(tdl_paths,  tdl_delays, tdl_amps_dB,  DS_TDL, chan_desc);
       break;
 
     case EPA:
@@ -768,6 +771,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       sum_amps = 0;
       chan_desc->amps           = (double *) malloc(chan_desc->nb_taps*sizeof(double));
       chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
       for (i = 0; i<chan_desc->nb_taps; i++) {
         chan_desc->amps[i]      = pow(10,.1*epa_amps_dB[i]);
         sum_amps += chan_desc->amps[i];
@@ -786,7 +790,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
 
       for (i = 0; i<nb_tx*nb_rx; i++)
         chan_desc->ch[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex));
-                                                                                          
+
       for (i = 0; i<nb_tx*nb_rx; i++)
         chan_desc->chF[i] = (struct complex *) malloc(1200 * sizeof(struct complex));
 
@@ -801,6 +805,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       } else {
         chan_desc->R_sqrt         = (struct complex **) malloc(6*sizeof(struct complex **));
         chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
+
         for (i = 0; i<6; i++) {
           chan_desc->R_sqrt[i]    = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
 
@@ -822,6 +827,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       sum_amps = 0;
       chan_desc->amps           = (double *) malloc(chan_desc->nb_taps*sizeof(double));
       chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
       for (i = 0; i<chan_desc->nb_taps; i++) {
         chan_desc->amps[i]      = pow(10,.1*epa_amps_dB[i]);
         sum_amps += chan_desc->amps[i];
@@ -851,7 +857,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
         chan_desc->R_sqrt  = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex **));
 
         for (i = 0; i<chan_desc->nb_taps; i++)
-          chan_desc->R_sqrt[i] = R_sqrt_22_EPA_low[0];
+          chan_desc->R_sqrt[i] = R_sqrt_22_EPA_low;
       } else {
         printf("Correlation matrices are implemented for 2 x 2 only");
       }
@@ -867,7 +873,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
           LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n");
         }
       }*/
-      break;             
+      break;
 
     case EPA_high:
       chan_desc->nb_taps        = 7;
@@ -876,6 +882,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       sum_amps = 0;
       chan_desc->amps           = (double *) malloc(chan_desc->nb_taps*sizeof(double));
       chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
       for (i = 0; i<chan_desc->nb_taps; i++) {
         chan_desc->amps[i]      = pow(10,.1*epa_amps_dB[i]);
         sum_amps += chan_desc->amps[i];
@@ -905,7 +912,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
         chan_desc->R_sqrt  = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex **));
 
         for (i = 0; i<chan_desc->nb_taps; i++)
-          chan_desc->R_sqrt[i] = R_sqrt_22_EPA_high[0];
+          chan_desc->R_sqrt[i] = R_sqrt_22_EPA_high;
       } else {
         printf("Correlation matrices are implemented for 2 x 2 only");
       }
@@ -929,7 +936,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
       sum_amps = 0;
       chan_desc->amps           = (double *) malloc(chan_desc->nb_taps*sizeof(double));
-       chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+      chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
       for (i = 0; i<chan_desc->nb_taps; i++) {
         chan_desc->amps[i]      = pow(10,.1*epa_amps_dB[i]);
         sum_amps += chan_desc->amps[i];
@@ -959,7 +967,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
         chan_desc->R_sqrt  = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex **));
 
         for (i = 0; i<chan_desc->nb_taps; i++)
-          chan_desc->R_sqrt[i] = R_sqrt_22_EPA_medium[0];
+          chan_desc->R_sqrt[i] = R_sqrt_22_EPA_medium;
       } else {
         printf("Correlation matrices are implemented for 2 x 2 only");
       }
@@ -984,6 +992,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       sum_amps = 0;
       chan_desc->amps           = (double *) malloc(chan_desc->nb_taps*sizeof(double));
       chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
       for (i = 0; i<chan_desc->nb_taps; i++) {
         chan_desc->amps[i]      = pow(10,.1*eva_amps_dB[i]);
         sum_amps += chan_desc->amps[i];
@@ -1017,7 +1026,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       } else {
         chan_desc->R_sqrt         = (struct complex **) malloc(6*sizeof(struct complex **));
         chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
-        for (i = 0; i<6; i++) { 
+
+        for (i = 0; i<6; i++) {
           chan_desc->R_sqrt[i]    = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
 
           for (j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
@@ -1038,6 +1048,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       sum_amps = 0;
       chan_desc->amps           = (double *) malloc(chan_desc->nb_taps*sizeof(double));
       chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
       for (i = 0; i<chan_desc->nb_taps; i++) {
         chan_desc->amps[i]      = pow(10,.1*etu_amps_dB[i]);
         sum_amps += chan_desc->amps[i];
@@ -1071,6 +1082,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       } else {
         chan_desc->R_sqrt         = (struct complex **) malloc(6*sizeof(struct complex **));
         chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
+
         for (i = 0; i<6; i++) {
           chan_desc->R_sqrt[i]    = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
 
@@ -1092,6 +1104,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
       sum_amps = 0;
       chan_desc->amps           = (double *) malloc(chan_desc->nb_taps*sizeof(double));
       chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
       for (i = 0; i<chan_desc->nb_taps; i++) {
         chan_desc->amps[i]      = pow(10,.1*mbsfn_amps_dB[i]);
         sum_amps += chan_desc->amps[i];
@@ -1119,6 +1132,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
 
       chan_desc->R_sqrt  = (struct complex **) malloc(6*sizeof(struct complex *));
       chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6;
+
       for (i = 0; i<6; i++) {
         chan_desc->R_sqrt[i]    = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
 
@@ -1185,11 +1199,11 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
                         1);
       break;
 
-    case Rayleigh1:
+    case Rayleigh1://MIMO Test uses Rayleigh1
       nb_taps = 1;
       Td = 0;
       channel_length = 1;
-      ricean_factor = 1;
+      ricean_factor = 0.0;
       aoa = .03;
       maxDoppler = 0;
       fill_channel_desc(chan_desc,nb_tx,
@@ -1360,11 +1374,13 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
 
     case TS_SHIFT:
       nb_taps = 2;
+      double ts_shift_delays[] = {0, 1/7.68};
       Td = ts_shift_delays[1];
       channel_length = 10;
       ricean_factor = 0.0;
       aoa = 0.0;
       maxDoppler = 0;
+      double ts_shift_amps[] = {0, 1};
       fill_channel_desc(chan_desc,nb_tx,
                         nb_rx,
                         nb_taps,
@@ -1628,38 +1644,65 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
 
   chan_desc->nb_paths = 10;
   return(chan_desc);
-}
-     
+} /* channel_desc_t *new_channel_desc_scm  */
+
+channel_desc_t *find_channel_desc_fromname( char *modelname ) {
+  for(int i=0; i<max_chan; i++) {
+    if (defined_channels[i] != NULL) {
+      if (strcmp(defined_channels[i]->model_name,modelname) == 0)
+        return defined_channels[i];
+    }
+  }
+
+  LOG_E(OCM,"Model %s not found \n", modelname);
+  return NULL;
+} /* channel_desc_t * new_channel_desc_fromconfig */
+
+
+
 void free_channel_desc_scm(channel_desc_t *ch) {
   // Must be made cleanly, a lot of leaks...
-  defined_channels[ch->chan_idx]=NULL; 
+  if (max_chan != 0) defined_channels[ch->chan_idx]=NULL;
   if(ch->free_flags&CHANMODEL_FREE_AMPS)
     free(ch->amps);
-  for (int i = 0; i<ch->nb_tx*ch->nb_rx; i++) { 
+
+  for (int i = 0; i<ch->nb_tx*ch->nb_rx; i++) {
     free(ch->ch[i]);
     free(ch->chF[i]);
   }
-            
+
   for (int i = 0; i<ch->nb_taps; i++) {
-    free(ch->a[i]);              
-  }   
+    free(ch->a[i]);
+  }
+
   if(ch->free_flags&CHANMODEL_FREE_DELAY)
-    free(ch->delays);  
+    free(ch->delays);
+
   if(ch->free_flags&CHANMODEL_FREE_RSQRT_6)
-    for (int i = 0; i<6; i++)  
-      free(ch->R_sqrt[i]);             
+    for (int i = 0; i<6; i++)
+      free(ch->R_sqrt[i]);
+
   if(ch->free_flags&CHANMODEL_FREE_RSQRT_NTAPS)
-    for (int i = 0; i<ch->nb_taps;i++)  
-      free(ch->R_sqrt[i]); 
-  free(ch->R_sqrt);        
-  free(ch->ch); 
+    for (int i = 0; i<ch->nb_taps; i++)
+      free(ch->R_sqrt[i]);
+
+  free(ch->R_sqrt);
+  free(ch->ch);
   free(ch->chF);
-  free(ch->a);  
-  free(ch);                                          
+  free(ch->a);
+  free(ch->model_name);
+  free(ch);
 }
 
 void set_channeldesc_owner(channel_desc_t *cdesc, uint32_t module_id) {
-	cdesc->module_id=module_id;
+  cdesc->module_id=module_id;
+}
+
+void set_channeldesc_name(channel_desc_t *cdesc,char *modelname) {
+  if(cdesc->model_name != NULL)
+    free(cdesc->model_name);
+
+  cdesc->model_name=strdup(modelname);
 }
 
 int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
@@ -1780,14 +1823,14 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
 
               desc->ch[aarx+(aatx*desc->nb_rx)][k].x += s*desc->a[l][aarx+(aatx*desc->nb_rx)].x;
               desc->ch[aarx+(aatx*desc->nb_rx)][k].y += s*desc->a[l][aarx+(aatx*desc->nb_rx)].y;
-	      //	      printf("l %d : desc->ch.x %f, s %e, delay %f\n",l,desc->a[l][aarx+(aatx*desc->nb_rx)].x,s,desc->delays[l]);
+              //        printf("l %d : desc->ch.x %f, s %e, delay %f\n",l,desc->a[l][aarx+(aatx*desc->nb_rx)].x,s,desc->delays[l]);
             } //nb_taps
 
 #ifdef DEBUG_CH
             printf("(%d,%d,%d)->(%e,%e)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y);
 #endif
           } //channel_length
-        } 
+        }
       } //aatx
     } //aarx
 
@@ -1799,7 +1842,7 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
 
   return (0);
 }
-   
+
 double N_RB2sampling_rate(uint16_t N_RB) {
   double sampling_rate;
 
@@ -1848,128 +1891,143 @@ double N_RB2channel_bandwidth(uint16_t N_RB) {
       break;
 
     default:
-      LOG_E(PHY,"Unknown N_PRB\n");
+      LOG_E(OCM,"Unknown N_PRB\n");
       return(-1);
   }
+
   return(channel_bandwidth);
-}   
+}
+
 
-     
 static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt ) {
-	prnt("channelmod commands can be used to display or modify channel models parameters\n");
-	prnt("channelmod show predef: display predefined model algorithms available in oai\n");
-	prnt("channelmod show current: display the currently used models in the running executable\n");
-	prnt("channelmod modify <model index> <param name> <param value>: set the specified parameters in a current model to the given value\n");
-	prnt("                  <model index> specifies the model, the show current model command can be used to list the current models indexes\n");
-	prnt("                  <param name> can be one of \"riceanf\", \"aoa\", \"randaoa\", \"ploss\", \"offset\", \"forgetf\"\n");
-    return CMDSTATUS_FOUND;
+  prnt("channelmod commands can be used to display or modify channel models parameters\n");
+  prnt("channelmod show predef: display predefined model algorithms available in oai\n");
+  prnt("channelmod show current: display the currently used models in the running executable\n");
+  prnt("channelmod modify <model index> <param name> <param value>: set the specified parameters in a current model to the given value\n");
+  prnt("                  <model index> specifies the model, the show current model command can be used to list the current models indexes\n");
+  prnt("                  <param name> can be one of \"riceanf\", \"aoa\", \"randaoa\", \"ploss\", \"noise_power_dB\", \"offset\", \"forgetf\"\n");
+  return CMDSTATUS_FOUND;
 }
 
 
 static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_t prnt) {
-	char *module_id_str[]=MODULEID_STR_INIT;
-	if (cd->module_id != 0) {
-		prnt("model owner: %s\n",module_id_str[cd->module_id]);
-	}
-	prnt("nb_tx: %i    nb_rx: %i    taps: %i bandwidth: %lf    sampling: %lf\n",cd->nb_tx, cd->nb_rx, cd->nb_taps, cd->channel_bandwidth, cd->sampling_rate);
-	prnt("channel length: %i    Max path delay: %lf   ricean fact.: %lf    angle of arrival: %lf (randomized:%s)\n",
-		 cd->channel_length, cd->Td, cd->ricean_factor, cd->aoa, (cd->random_aoa?"Yes":"No"));
-	prnt("max Doppler: %lf    path loss: %lf   rchannel offset: %i    forget factor; %lf\n",
-		 cd->max_Doppler, cd->path_loss_dB, cd->channel_offset, cd->forgetting_factor);	
-	prnt("Initial phase: %lf   nb_path: %i \n",
-		 cd->ip, cd->nb_paths);		
-	for (int i=0; i<cd->nb_taps ; i++) {
-		prnt("taps: %i   lin. ampli. : %lf    delay: %lf \n",i,cd->amps[i], cd->delays[i]);
-	}                         
+  char *module_id_str[]=MODULEID_STR_INIT;
+  prnt("model owner: %s\n",(cd->module_id != 0)?module_id_str[cd->module_id]:"not set");
+  prnt("nb_tx: %i    nb_rx: %i    taps: %i bandwidth: %lf    sampling: %lf\n",cd->nb_tx, cd->nb_rx, cd->nb_taps, cd->channel_bandwidth, cd->sampling_rate);
+  prnt("channel length: %i    Max path delay: %lf   ricean fact.: %lf    angle of arrival: %lf (randomized:%s)\n",
+       cd->channel_length, cd->Td, cd->ricean_factor, cd->aoa, (cd->random_aoa?"Yes":"No"));
+  prnt("max Doppler: %lf    path loss: %lf  noise: %lf rchannel offset: %i    forget factor; %lf\n",
+       cd->max_Doppler, cd->path_loss_dB, cd->noise_power_dB, cd->channel_offset, cd->forgetting_factor);
+  prnt("Initial phase: %lf   nb_path: %i \n",
+       cd->ip, cd->nb_paths);
+
+  for (int i=0; i<cd->nb_taps ; i++) {
+    prnt("taps: %i   lin. ampli. : %lf    delay: %lf \n",i,cd->amps[i], cd->delays[i]);
+  }
 }
-   
-  
+
+
 static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
-  char *subcmd=NULL; 
+  char *subcmd=NULL;
   int s = sscanf(buff,"%ms\n",&subcmd);
 
   if (s>0) {
     if ( strcmp(subcmd,"predef") == 0) {
       for (int i=0; channelmod_names[i].name != NULL ; i++) {
         prnt("  %i %s\n", i, map_int_to_str(channelmod_names,i ));
-    } 
+      }
     } else if ( strcmp(subcmd,"current") == 0) {
       for (int i=0; i < max_chan ; i++) {
-      	if (defined_channels[i] != NULL) {
-      	  prnt("model %i %s: \n----------------\n", i, map_int_to_str(channelmod_names,defined_channels[i]->modelid));
-          display_channelmodel(defined_channels[i],debug,prnt); 
+        if (defined_channels[i] != NULL) {
+          prnt("model %i %s type %s: \n----------------\n", i, (defined_channels[i]->model_name !=NULL)?defined_channels[i]->model_name:"(no name set)",
+               map_int_to_str(channelmod_names,defined_channels[i]->modelid));
+          display_channelmodel(defined_channels[i],debug,prnt);
         }
       }
     } else {
-    	channelmod_print_help(buff, debug, prnt);
+      channelmod_print_help(buff, debug, prnt);
     }
-  free(subcmd);
+
+    free(subcmd);
   }
+
   return CMDSTATUS_FOUND;
 }
 
-      
+
 
 static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
-  char *param=NULL, *value=NULL; 
+  char *param=NULL, *value=NULL;
   int cd_id= -1;
   int s = sscanf(buff,"%i %ms %ms \n",&cd_id,&param, &value);
+
   if (cd_id<0 || cd_id >= max_chan) {
-  	  prnt("ERROR, %i: Channel model id outof range (0-%i)\n",cd_id,max_chan-1);
-  	  return CMDSTATUS_FOUND;
+    prnt("ERROR, %i: Channel model id outof range (0-%i)\n",cd_id,max_chan-1);
+    return CMDSTATUS_FOUND;
   }
+
   if (defined_channels[cd_id]==NULL) {
-  	  prnt("ERROR, %i: Channel model has not been set\n",cd_id);
-  	  return CMDSTATUS_FOUND;
-  }  
-  
+    prnt("ERROR, %i: Channel model has not been set\n",cd_id);
+    return CMDSTATUS_FOUND;
+  }
+
   if (s==3) {
     if ( strcmp(param,"riceanf") == 0) {
-        double dbl = atof(value);
-        if (dbl <0 || dbl > 1)
-        	prnt("ERROR: ricean factor range: 0 to 1, %lf is outof range\n",dbl);
-        else
-        	defined_channels[cd_id]->ricean_factor=dbl;
+      double dbl = atof(value);
+
+      if (dbl <0 || dbl > 1)
+        prnt("ERROR: ricean factor range: 0 to 1, %lf is outof range\n",dbl);
+      else
+        defined_channels[cd_id]->ricean_factor=dbl;
     } else if ( strcmp(param,"aoa") == 0) {
-        double dbl = atof(value);
-        if (dbl <0 || dbl >6.28)
-        	prnt("ERROR: angle of arrival range: 0 to 2*Pi,  %lf is outof range\n",dbl);
-        else
-        	defined_channels[cd_id]->aoa=dbl;    
+      double dbl = atof(value);
+
+      if (dbl <0 || dbl >6.28)
+        prnt("ERROR: angle of arrival range: 0 to 2*Pi,  %lf is outof range\n",dbl);
+      else
+        defined_channels[cd_id]->aoa=dbl;
     } else if ( strcmp(param,"randaoa") == 0) {
-        int i = atoi(value);
-        if (i!=0 && i!=1)
-        	prnt("ERROR: randaoa is a boolean, must be 0 or 1\n");
-        else
-        	defined_channels[cd_id]->random_aoa=i;
+      int i = atoi(value);
+
+      if (i!=0 && i!=1)
+        prnt("ERROR: randaoa is a boolean, must be 0 or 1\n");
+      else
+        defined_channels[cd_id]->random_aoa=i;
     } else if ( strcmp(param,"ploss") == 0) {
-        double dbl = atof(value);
-        defined_channels[cd_id]->path_loss_dB=dbl;     
+      double dbl = atof(value);
+      defined_channels[cd_id]->path_loss_dB=dbl;
+    } else if ( strcmp(param,"noise_power_dB") == 0) {
+      double dbl = atof(value);
+      defined_channels[cd_id]->noise_power_dB=dbl;
     } else if ( strcmp(param,"offset") == 0) {
-        int i = atoi(value);
-        defined_channels[cd_id]->channel_offset=i;     
+      int i = atoi(value);
+      defined_channels[cd_id]->channel_offset=i;
     } else if ( strcmp(param,"forgetf") == 0) {
-        double dbl = atof(value);
-        if (dbl <0 || dbl > 1)
-        	prnt("ERROR: forgetting factor range: 0 to 1 (disable variation), %lf is outof range\n",dbl);
-        else
-        	defined_channels[cd_id]->forgetting_factor=dbl;     
+      double dbl = atof(value);
+
+      if (dbl <0 || dbl > 1)
+        prnt("ERROR: forgetting factor range: 0 to 1 (disable variation), %lf is outof range\n",dbl);
+      else
+        defined_channels[cd_id]->forgetting_factor=dbl;
     } else {
-         prnt("ERROR: %s, unknown channel parameter\n",param);
-         return CMDSTATUS_FOUND;  
+      prnt("ERROR: %s, unknown channel parameter\n",param);
+      return CMDSTATUS_FOUND;
     }
-  display_channelmodel(defined_channels[cd_id],debug,prnt);  
-  free(param);   
-  free(value);
-  random_channel(defined_channels[cd_id],false);                 
+    display_channelmodel(defined_channels[cd_id],debug,prnt);
+    free(param);
+    free(value);
+    random_channel(defined_channels[cd_id],false);
   }
-  return CMDSTATUS_FOUND;           
+
+  return CMDSTATUS_FOUND;
 }
-   
-int modelid_fromname(char *modelname) {                                             
-  int modelid=map_str_to_int(channelmod_names,modelname);   
-  if (modelid < 0)   
-    LOG_E(OCM,"random_channel.c: Error channel model %s unknown\n",modelname);
+
+int modelid_fromstrtype(char *modeltype) {
+  int modelid=map_str_to_int(channelmod_names,modeltype);
+
+  if (modelid < 0)
+    LOG_E(OCM,"random_channel.c: Error channel model %s unknown\n",modeltype);
+
   return modelid;
 }
 
@@ -1983,18 +2041,61 @@ double channelmod_get_sinr_dB(void) {
 
 void init_channelmod(void) {
   paramdef_t channelmod_params[] = CHANNELMOD_PARAMS_DESC;
-  int ret = config_get( channelmod_params,sizeof(channelmod_params)/sizeof(paramdef_t),CHANNELMOD_SECTION);
+  int numparams=sizeof(channelmod_params)/sizeof(paramdef_t);
+  int ret = config_get( channelmod_params,numparams,CHANNELMOD_SECTION);
   AssertFatal(ret >= 0, "configuration couldn't be performed");
-    defined_channels=calloc(max_chan,sizeof( channel_desc_t*));
+  defined_channels=calloc(max_chan,sizeof( channel_desc_t *));
   AssertFatal(defined_channels!=NULL, "couldn't allocate %u channel descriptors\n",max_chan);
-  
   /* look for telnet server, if it is loaded, add the channel modeling commands to it */
   add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME);
 
   if (addcmd != NULL) {
     addcmd("channelmod",channelmod_vardef,channelmod_cmdarray);
   }
-}
+} /* init_channelmod */
+
+
+int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double channel_bandwidth) {
+  paramdef_t achannel_params[] = CHANNELMOD_MODEL_PARAMS_DESC;
+  paramlist_def_t channel_list;
+  memset(&channel_list,0,sizeof(paramlist_def_t));
+  memcpy(channel_list.listname,modellist_name,sizeof(channel_list.listname)-1);
+  int numparams = sizeof(achannel_params)/sizeof(paramdef_t);
+  config_getlist( &channel_list,achannel_params,numparams, CHANNELMOD_SECTION);
+  AssertFatal(channel_list.numelt>0, "List %s.%s not found in config file\n",CHANNELMOD_SECTION,channel_list.listname);
+  int pindex_NAME = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_NAME_PNAME);
+  int pindex_DT = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_DT_PNAME );
+  int pindex_FF = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_FF_PNAME );
+  int pindex_CO = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_CO_PNAME );
+  int pindex_PL = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_PL_PNAME );
+  int pindex_NP = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_NP_PNAME );
+  int pindex_TYPE = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_TYPE_PNAME);
+
+  for (int i=0; i<channel_list.numelt; i++) {
+    int modid = modelid_fromstrtype( *(channel_list.paramarray[i][pindex_TYPE].strptr) );
+
+    if (modid <0) {
+      LOG_E(OCM,"Valid channel model types:\n");
+
+      for (int m=0; channelmod_names[i].name != NULL ; m++) {
+        printf(" %s ", map_int_to_str(channelmod_names,m ));
+      }
+
+      AssertFatal(0, "\n  Choose a valid model type\n");
+    }
+
+    channel_desc_t *channeldesc_p = new_channel_desc_scm(nb_tx,nb_rx,modid,sampling_rate,channel_bandwidth,
+                                    *(channel_list.paramarray[i][pindex_DT].dblptr), *(channel_list.paramarray[i][pindex_FF].dblptr),
+                                    *(channel_list.paramarray[i][pindex_CO].iptr), *(channel_list.paramarray[i][pindex_PL].dblptr),
+                                    *(channel_list.paramarray[i][pindex_NP].dblptr) );
+    AssertFatal( (channeldesc_p!= NULL), "Could not allocate channel %s type %s \n",*(channel_list.paramarray[i][pindex_NAME].strptr), *(channel_list.paramarray[i][pindex_TYPE].strptr));
+    channeldesc_p->model_name = strdup(*(channel_list.paramarray[i][pindex_NAME].strptr));
+    LOG_I(OCM,"Model %s type %s allocated from config file, list %s\n",*(channel_list.paramarray[i][pindex_NAME].strptr),
+          *(channel_list.paramarray[i][pindex_TYPE].strptr), modellist_name);
+  } /* for loop on channel_list */
+
+  return channel_list.numelt;
+} /* load_channelist */
 
 #ifdef RANDOM_CHANNEL_MAIN
 #define sampling_rate 5.0
diff --git a/openair1/SIMULATION/TOOLS/scm_corrmat.h b/openair1/SIMULATION/TOOLS/scm_corrmat.h
index 6ee6567ce9a77d8dd76c5027d61a9818fd7aa929..5695e0bd0f8092ca2f493427f48f245bcfa0ffa2 100644
--- a/openair1/SIMULATION/TOOLS/scm_corrmat.h
+++ b/openair1/SIMULATION/TOOLS/scm_corrmat.h
@@ -19,7 +19,7 @@
  *      contact@openairinterface.org
  */
 
-double R22_sqrt[6][32] = {
+static double R22_sqrt[6][32] = {
   {0.921700, -0.000000, 0.010380, -0.027448, -0.250153, 0.294754, 0.005961, 0.010769, 0.010380, 0.027448, 0.921700, 0.000000, -0.011595, -0.004130, -0.250153, 0.294754, -0.250153, -0.294754, -0.011595, 0.004130, 0.921700, 0.000000, 0.010380, -0.027448, 0.005961, -0.010769, -0.250153, -0.294754, 0.010380, 0.027448, 0.921700, 0.000000},
   {0.923810, 0.000000, 0.004069, 0.027832, 0.151730, 0.350180, -0.009882, 0.006114, 0.004069, -0.027832, 0.923810, 0.000000, 0.011218, -0.003029, 0.151730, 0.350180, 0.151730, -0.350180, 0.011218, 0.003029, 0.923810, -0.000000, 0.004069, 0.027832, -0.009882, -0.006114, 0.151730, -0.350180, 0.004069, -0.027832, 0.923810, 0.000000},
   {0.927613, 0.000000, 0.014253, 0.025767, -0.061171, -0.367133, 0.009258, -0.007340, 0.014253, -0.025767, 0.927613, -0.000000, -0.011138, -0.003942, -0.061171, -0.367133, -0.061171, 0.367133, -0.011138, 0.003942, 0.927613, 0.000000, 0.014253, 0.025767, 0.009258, 0.007340, -0.061171, 0.367133, 0.014253, -0.025767, 0.927613, 0.000000},
@@ -27,7 +27,7 @@ double R22_sqrt[6][32] = {
   {0.919726, -0.000000, 0.038700, -0.111146, 0.217804, 0.300925, 0.045531, -0.013659, 0.038700, 0.111146, 0.919726, 0.000000, -0.027201, 0.038983, 0.217804, 0.300925, 0.217804, -0.300925, -0.027201, -0.038983, 0.919726, 0.000000, 0.038700, -0.111146, 0.045531, 0.013659, 0.217804, -0.300925, 0.038700, 0.111146, 0.919726, 0.000000},
   {0.867608, -0.000000, 0.194097, -0.112414, -0.418811, 0.095938, -0.081264, 0.075727, 0.194097, 0.112414, 0.867608, -0.000000, -0.106125, -0.032801, -0.418811, 0.095938, -0.418811, -0.095938, -0.106125, 0.032801, 0.867608, 0.000000, 0.194097, -0.112414, -0.081264, -0.075727, -0.418811, -0.095938, 0.194097, 0.112414, 0.867608, 0.000000},
 };
-double R21_sqrt[6][8] = {
+static double R21_sqrt[6][8] = {
   {0.922167, 0.000000,-0.250280, 0.294903,-0.250280, -0.294903,0.922167, 0.000000},
   {0.924238, 0.000000,0.151801, 0.350342,0.151801, -0.350342,0.924238, 0.000000},
   {0.928080, 0.000000,-0.061202, -0.367318,-0.061202, 0.367318,0.928080, 0.000000},
@@ -35,7 +35,7 @@ double R21_sqrt[6][8] = {
   {0.927225, 0.000000,0.219580, 0.303378,0.219580, -0.303378,0.927225, 0.000000},
   {0.896133, 0.000000,-0.432581, 0.099092,-0.432581, -0.099092,0.896133, 0.000000},
 };
-double R12_sqrt[6][8] = {
+static double R12_sqrt[6][8] = {
   {0.999494, 0.000000,0.011256, -0.029765,0.011256, 0.029765,0.999494, 0.000000},
   {0.999537, 0.000000,0.004402, 0.030114,0.004402, -0.030114,0.999537, 0.000000},
   {0.999497, 0.000000,0.015358, 0.027764,0.015358, -0.027764,0.999497, 0.000000},
diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h
index 55a78e977866ec9ed63a1a73c4e47c4c597352f6..78e260b73f196142dc9d08da8fbe401e011583aa 100644
--- a/openair1/SIMULATION/TOOLS/sim.h
+++ b/openair1/SIMULATION/TOOLS/sim.h
@@ -89,6 +89,7 @@ typedef struct {
   double path_loss_dB;
   ///additional delay of channel in samples.
   int32_t channel_offset;
+  float noise_power_dB;
   ///This parameter (0...1) allows for simple 1st order temporal variation. 0 means a new channel every call, 1 means keep channel constant all the time
   double forgetting_factor;
   ///needs to be set to 1 for the first call, 0 otherwise.
@@ -106,8 +107,10 @@ typedef struct {
   unsigned int chan_idx;
   /// id of the channel modeling algorithm
   int modelid;
-  /// identifies channel descriptor owner (the module which created this descriptor)
+  /// identifies channel descriptor owner (the module which created this descriptor
   channelmod_moduleid_t module_id;
+  /// name of this descriptor,used for model created from config file at init time
+  char *model_name;  
   /// flags to properly trigger memory free
   unsigned int free_flags;
 } channel_desc_t;
@@ -241,12 +244,37 @@ typedef enum {
 
 #define CONFIG_HLP_SNR     "Set average SNR in dB (for --siml1 option)\n"
 #define CHANNELMOD_SECTION "channelmod"
+
+/* global channel modelization parameters */
+#define CHANNELMOD_MODELLIST_PARANAME "modellist"
+
+#define CHANNELMOD_HELP_MODELLIST "<list name> channel list name in config file describing the model type and its parameters\n"
 #define CHANNELMOD_PARAMS_DESC {  \
-    {"s"      , CONFIG_HLP_SNR,         PARAMFLAG_CMDLINE_NOPREFIXENABLED, dblptr:&snr_dB,    defdblval:25, TYPE_DOUBLE, 0},\
-    {"sinr_dB", NULL,                   0                                , dblptr:&sinr_dB,   defdblval:0 , TYPE_DOUBLE, 0},\
-    {"max_chan, CONFIG_HLP_MAX_CHAN",   0,                                 uptr:&max_chan,    defintval:10,  TYPE_UINT,   0},\
+    {"s"      ,     CONFIG_HLP_SNR,                                     PARAMFLAG_CMDLINE_NOPREFIXENABLED,   dblptr:&snr_dB,                        defdblval:25,                    TYPE_DOUBLE, 0},\
+    {"sinr_dB",     NULL,                                               0,                                   dblptr:&sinr_dB,                       defdblval:0 ,                    TYPE_DOUBLE, 0},\
+    {"max_chan",    "Max number of runtime models",                     0,                                   uptr:&max_chan,                        defintval:10,                    TYPE_UINT,   0},\
+    {CHANNELMOD_MODELLIST_PARANAME, CHANNELMOD_HELP_MODELLIST,          0,                                   strptr:(char **)&modellist_name,       defstrval:"DefaultChannelList",  TYPE_STRING, 60 },\
   }
 
+/* parameters for one model */ 
+#define CHANNELMOD_MODEL_NAME_PNAME "model_name"
+#define CHANNELMOD_MODEL_TYPE_PNAME "type"
+#define CHANNELMOD_MODEL_PL_PNAME "ploss_dB"
+#define CHANNELMOD_MODEL_NP_PNAME "noise_power_dB"
+#define CHANNELMOD_MODEL_FF_PNAME "forgetfact"
+#define CHANNELMOD_MODEL_CO_PNAME "offset"
+#define CHANNELMOD_MODEL_DT_PNAME "ds_tdl"
+
+#define CHANNELMOD_MODEL_PARAMS_DESC {  \
+    {CHANNELMOD_MODEL_NAME_PNAME, "name of the model\n",               0,  strptr:NULL ,             defstrval:"",                    TYPE_STRING,    0 },\
+    {CHANNELMOD_MODEL_TYPE_PNAME, "name of the model type\n",          0,  strptr:NULL ,             defstrval:"AWGN",                TYPE_STRING,    0 },\
+    {CHANNELMOD_MODEL_PL_PNAME,   "channel path loss in dB\n",         0,  dblptr:NULL,              defdblval:0,                     TYPE_DOUBLE,    0 },\
+    {CHANNELMOD_MODEL_NP_PNAME,   "channel noise in dB\n",             0,  dblptr:NULL,              defdblval:-50,                     TYPE_DOUBLE,    0 },\
+    {CHANNELMOD_MODEL_FF_PNAME,   "channel forget factor ((0 to 1)\n", 0,  dblptr:NULL,              defdblval:0,                     TYPE_DOUBLE,    0 },\
+    {CHANNELMOD_MODEL_CO_PNAME,   "channel offset in samps\n",         0,  iptr:NULL,                defintval:0,                     TYPE_INT,       0 },\
+    {CHANNELMOD_MODEL_DT_PNAME,    "delay spread for TDL models\n",    0,  dblptr:NULL,              defdblval:0,                     TYPE_DOUBLE,    0 }\
+}
+
 #include "platform_constants.h"
 
 typedef struct {
@@ -275,12 +303,17 @@ typedef struct {
 channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
                                      uint8_t nb_rx,
                                      SCM_t channel_model,
-				     double sampling_rate,
+				                     double sampling_rate,
                                      double channel_bandwidth,
-				     double TDL_DS,
+				                     double TDL_DS,
                                      double forgetting_factor,
                                      int32_t channel_offset,
-                                     double path_loss_dB);
+                                     double path_loss_dB,
+				                     float noise_power_dB);
+
+channel_desc_t *find_channel_desc_fromname( char *modelname );
+
+
 /**
 \brief free memory allocated for a model descriptor
 \param ch points to the model, which cannot be used after calling this fuction
@@ -293,6 +326,12 @@ void free_channel_desc_scm(channel_desc_t *ch);
 \param module_id identifies the channel model. should be define as a macro in simu.h
 */
 void set_channeldesc_owner(channel_desc_t *cdesc, channelmod_moduleid_t module_id);
+/**
+\brief This function set a model name to a model descriptor, can be later used to identify a allocated channel model
+\param cdesc points to the model descriptor
+\param module_name is the C string to use as model name for the channel pointed by cdesc
+*/
+void set_channeldesc_name(channel_desc_t *cdesc,char *modelname);
 /** \fn void random_channel(channel_desc_t *desc)
 \brief This routine generates a random channel response (time domain) according to a tapped delay line model.
 \param desc Pointer to the channel descriptor
@@ -300,10 +339,10 @@ void set_channeldesc_owner(channel_desc_t *cdesc, channelmod_moduleid_t module_i
 int random_channel(channel_desc_t *desc, uint8_t abstraction_flag);
 
 /**\fn void multipath_channel(channel_desc_t *desc,
-           double tx_sig_re[2],
-           double tx_sig_im[2],
-           double rx_sig_re[2],
-           double rx_sig_im[2],
+           double tx_sig_re[NB_ANTENNAS_TX],
+           double tx_sig_im[NB_ANTENANS_TX],
+           double rx_sig_re[NB_ANTENNAS_RX],
+           double rx_sig_im[NB_ANTENNAS_RX],
            uint32_t length,
            uint8_t keep_channel,
 	   int log_channel)
@@ -320,10 +359,10 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag);
 */
 
 void multipath_channel(channel_desc_t *desc,
-                       double *tx_sig_re[2],
-                       double *tx_sig_im[2],
-                       double *rx_sig_re[2],
-                       double *rx_sig_im[2],
+                       double *tx_sig_re[NB_ANTENNAS_TX],
+                       double *tx_sig_im[NB_ANTENNAS_TX],
+                       double *rx_sig_re[NB_ANTENNAS_RX],
+                       double *rx_sig_im[NB_ANTENNAS_RX],
                        uint32_t length,
                        uint8_t keep_channel,
 		       int log_channel);
@@ -452,11 +491,11 @@ void multipath_tv_channel(channel_desc_t *desc,
 /**@} */
 /**@} */
 
-int modelid_fromname(char *modelname);
+int modelid_fromstrtype(char *modeltype);
 double channelmod_get_snr_dB(void);
 double channelmod_get_sinr_dB(void);
 void init_channelmod(void) ;
-
+int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double channel_bandwidth) ;
 double N_RB2sampling_rate(uint16_t N_RB);
 double N_RB2channel_bandwidth(uint16_t N_RB);
 
@@ -468,11 +507,9 @@ double N_RB2channel_bandwidth(uint16_t N_RB);
 */
 //look-up table for the sine (cosine) function
 #define ResolSinCos 100
-uint16_t LUTSin[ResolSinCos+1];
 void InitSinLUT( void );
 void phase_noise(double ts, int16_t * InRe, int16_t * InIm);
 
-#include "targets/RT/USER/rfsim.h"
 
 void do_DL_sig(sim_t *sim,
                uint16_t subframe,
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 8fde34300060ffc4264b40e24ca30b1098a56b83..3c820765103c917cdaaf7a54e3f36e4fd38b1061 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,25 +168,30 @@ 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];
 } 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;
   int                    num_tunnels;
   teid_t                 upf_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE];  ///< Tunnel Endpoint Identifier
   pdusessionid_t         pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
+  ebi_t                  incoming_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
   transport_layer_addr_t upf_addr[NR_GTPV1U_MAX_BEARERS_PER_UE];
 } gtpv1u_gnb_create_tunnel_req_t;
 
@@ -210,4 +216,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/mac_rrc_primitives.h b/openair2/COMMON/mac_rrc_primitives.h
index 4a0a6027bcabb253c02d8b2d21105909097b9458..5a45f2f19662698027edc215f6d435985c793bea 100644
--- a/openair2/COMMON/mac_rrc_primitives.h
+++ b/openair2/COMMON/mac_rrc_primitives.h
@@ -189,7 +189,7 @@ typedef struct MEAS_REQ_TABLE_ENTRY {
   MAC_MEAS_REQ Mac_meas_req;
   unsigned int Last_report_frame;
   unsigned int Next_check_frame;
-  uint8_t Status;
+  uint8_t StatusMeas;
   uint8_t Meas_req_status;
   uint8_t Rx_activity;
   //uint8_t Meas_Direction;//???
@@ -269,7 +269,7 @@ typedef struct {
   char Wideband_sinr;
   uint8_t Forg_fact;
   unsigned short Rep_interval;
-  uint8_t Status;
+  uint8_t StatusMeas;
   unsigned int Last_report_frame;
   unsigned int Next_check_frame;
   uint8_t Active;
@@ -299,7 +299,7 @@ typedef struct {
   unsigned short Rep_interval;
   unsigned int Last_report_frame;
   unsigned int Next_check_frame;
-  uint8_t Status; //IDLE,NEED_rADIO_CONFIG, RADIO_CONFIG_TX, RADIO_CONFIG_ok
+  uint8_t StatusMeas; //IDLE,NEED_rADIO_CONFIG, RADIO_CONFIG_TX, RADIO_CONFIG_ok
   uint8_t Active;
 } __attribute__ ((__packed__)) DEFAULT_CH_MEAS;
 #define DEFAULT_eNB_MEAS_SIZE sizeof(DEFAULT_eNB_MEAS)
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 3915f12bb9afeeba231a45240474f4307db97b1b..c56a31711a081d73465266abf3681cb94814427f 100644
--- a/openair2/COMMON/platform_constants.h
+++ b/openair2/COMMON/platform_constants.h
@@ -28,12 +28,14 @@
 
  ***************************************************************************/
 
-#include "LTE_asn_constant.h"
-#include "NR_asn_constant.h"
 
 #ifndef __PLATFORM_CONSTANTS_H__
 #    define __PLATFORM_CONSTANTS_H__
 
+#include "LTE_asn_constant.h"
+#include "NR_asn_constant.h"
+#define NR_MAXDRB 14
+
 #ifdef JUMBO_FRAME
   #define NL_MAX_PAYLOAD 18000  /* this should cover the max mtu size*/
 #else
@@ -87,13 +89,7 @@
   #define MAX_gNB                      2
 #endif
 
-#define NUMBER_OF_NR_DLSCH_MAX 2//16
-#define NUMBER_OF_NR_ULSCH_MAX 2//16
-#define NUMBER_OF_NR_SCH_STATS_MAX 16
-#define NUMBER_OF_NR_PUCCH_MAX 16
-#define NUMBER_OF_NR_SR_MAX 16
-#define NUMBER_OF_NR_PDCCH_MAX 16
-
+#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/COMMON/platform_types.h b/openair2/COMMON/platform_types.h
index d425b9e7d7a895eb8696db1b51b7ddfb8f2c47e0..23b33dd8b13ab1f8249942f2e304c5e800d72dd4 100644
--- a/openair2/COMMON/platform_types.h
+++ b/openair2/COMMON/platform_types.h
@@ -195,21 +195,13 @@ typedef uint8_t            mme_code_t;
 typedef uint32_t           m_tmsi_t;
 
 //Random UE identity length = 40 bits
-#if ! defined(NOT_A_RANDOM_UE_IDENTITY)
   #define NOT_A_RANDOM_UE_IDENTITY (uint64_t)0xFFFFFFFF
-#endif
-#if ! defined(NOT_A_RNTI)
   #define NOT_A_RNTI (rnti_t)0
-#endif
-#if ! defined(M_RNTI)
   #define M_RNTI     (rnti_t)0xFFFD
-#endif
-#if ! defined(P_RNTI)
   #define P_RNTI     (rnti_t)0xFFFE
-#endif
-#if ! defined(SI_RNTI)
   #define SI_RNTI    (rnti_t)0xFFFF
-#endif
+#define CBA_RNTI   (rnti_t)0xfff4
+#define OAI_C_RNTI (rnti_t)0x1234
 typedef enum config_action_e {
   CONFIG_ACTION_NULL              = 0,
   CONFIG_ACTION_ADD               = 1,
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index 02f878ee2e2e9c788e156bf827e89e792bc1aca9..ca4011231ac22ddba6482e1cbb792df15a5a3e87 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -42,6 +42,7 @@
 #include "LTE_SL-DiscResourcePool-r12.h"
 #include "NR_RACH-ConfigCommon.h"
 #include "NR_ServingCellConfigCommon.h"
+#include "NR_ServingCellConfig.h"
 //-------------------------------------------------------------------------------------------//
 // Messages for RRC logging
 #if defined(DISABLE_ITTI_XER_PRINT)
@@ -404,9 +405,13 @@ typedef struct NRRrcConfigurationReq_s {
   uint16_t                mcc[PLMN_LIST_MAX_SIZE];
   uint16_t                mnc[PLMN_LIST_MAX_SIZE];
   uint8_t                 mnc_digit_length[PLMN_LIST_MAX_SIZE];
+  uint8_t                 num_plmn;
   NR_ServingCellConfigCommon_t *scc;
+  NR_ServingCellConfig_t  *scd;
   int                     ssb_SubcarrierOffset;
   int                     pdsch_AntennaPorts;
+  int                     pusch_AntennaPorts;
+  int                     do_CSIRS;
   int                     pusch_TargetSNRx10;
   int                     pucch_TargetSNRx10;
 } gNB_RrcConfigurationReq;
diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h
index bd0788d2d0efd6353df7ea996e78dfddcbe62fa0..21513756867bf6b7d5769a689679d6b103e5cd6a 100644
--- a/openair2/COMMON/s1ap_messages_types.h
+++ b/openair2/COMMON/s1ap_messages_types.h
@@ -398,6 +398,11 @@ typedef struct s1ap_register_enb_req_s {
   /* Number of SCTP streams used for a mme association */
   uint16_t sctp_in_streams;
   uint16_t sctp_out_streams;
+  uint16_t s1_setuprsp_wait_timer;
+  uint16_t s1_setupreq_wait_timer;
+  uint16_t s1_setupreq_count;
+  uint16_t sctp_req_timer;
+  uint16_t sctp_req_count;
 } s1ap_register_enb_req_t;
 
 //-------------------------------------------------------------------------------------------//
diff --git a/openair2/COMMON/tasks_def.h b/openair2/COMMON/tasks_def.h
deleted file mode 100644
index 33b6d5f9d4670223009230f876405917050c3e2c..0000000000000000000000000000000000000000
--- a/openair2/COMMON/tasks_def.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-// This task is mandatory and must always be placed in first position
-TASK_DEF(TASK_TIMER,    TASK_PRIORITY_MAX,          10)
-
-// Other possible tasks in the process
-
-// Common tasks:
-
-///   Bearers Manager task
-TASK_DEF(TASK_BM,       TASK_PRIORITY_MED,          200)
-
-// eNodeB tasks and sub-tasks:
-
-///   Radio Resource Control task
-TASK_DEF(TASK_RRC_ENB,  TASK_PRIORITY_MED,          200)
-
-// Define here for now
-TASK_DEF(TASK_RRC_ENB_NB_IoT,  TASK_PRIORITY_MED,          200)
-
-TASK_DEF(TASK_RRC_GNB,  TASK_PRIORITY_MED,          200)
-
-///   S1ap task
-/// RAL task for ENB
-TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200)
-
-// UDP TASK
-TASK_DEF(TASK_UDP,      TASK_PRIORITY_MED,          1000)
-// GTP_V1U task
-TASK_DEF(TASK_GTPV1_U,  TASK_PRIORITY_MED,          1000)
-TASK_DEF(TASK_S1AP,     TASK_PRIORITY_MED,          200)
-TASK_DEF(TASK_CU_F1,     TASK_PRIORITY_MED,          200)
-TASK_DEF(TASK_DU_F1,     TASK_PRIORITY_MED,          200)
-///   M3ap task, acts as both source and target
-TASK_DEF(TASK_M3AP,     TASK_PRIORITY_MED,          200)
-///   M3ap task, acts as both source and target
-TASK_DEF(TASK_M3AP_MME,     TASK_PRIORITY_MED,          200)
-///   M3ap task, acts as both source and target
-TASK_DEF(TASK_M3AP_MCE,     TASK_PRIORITY_MED,          200)
-///   M2ap task, acts as both source and target
-TASK_DEF(TASK_M2AP_MCE,     TASK_PRIORITY_MED,          200)
-TASK_DEF(TASK_M2AP_ENB,     TASK_PRIORITY_MED,          200)
-///   X2ap task, acts as both source and target
-TASK_DEF(TASK_X2AP,     TASK_PRIORITY_MED,          200)
-///   Sctp task (Used by both S1AP and X2AP)
-TASK_DEF(TASK_SCTP,     TASK_PRIORITY_MED,          200)
-///   eNB APP task
-TASK_DEF(TASK_ENB_APP,  TASK_PRIORITY_MED,          200)
-///   gNB APP task
-TASK_DEF(TASK_GNB_APP,  TASK_PRIORITY_MED,          200)
-///   eNB Agent task
-TASK_DEF(TASK_FLEXRAN_AGENT,  TASK_PRIORITY_MED,          200)
-TASK_DEF(TASK_PROTO_AGENT,  TASK_PRIORITY_MED,          200)
-// UE tasks and sub-tasks:
-
-///   Radio Resource Control task
-TASK_DEF(TASK_RRC_UE,   TASK_PRIORITY_MED,          200)
-TASK_DEF(TASK_RRC_NRUE,   TASK_PRIORITY_MED,          200)
-///   Non Access Stratum task
-TASK_DEF(TASK_NAS_UE,   TASK_PRIORITY_MED,          200)
-TASK_DEF(TASK_RAL_UE,   TASK_PRIORITY_MED,          200)
-
-//MESSAGE GENERATOR TASK
-TASK_DEF(TASK_MSC,      TASK_PRIORITY_MED,          200)
-
-#ifdef ITTI_SIM
-TASK_DEF(TASK_RRC_GNB_SIM,   TASK_PRIORITY_MED,          200)
-TASK_DEF(TASK_RRC_UE_SIM,    TASK_PRIORITY_MED,          200)
-#endif
-
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
index 7ca466e8ffc654db733ee4e3b016d5b13b3df5c0..51e495b0278795b82f46d62f01daa3ee68db4955 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
@@ -42,6 +42,9 @@
 
 #include <dlfcn.h>
 
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
+
 /*Array containing the Agent-MAC interfaces*/
 AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB];
 
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
index 42246c3ebf165606037ec207ed49303ef216d09f..e05fa988542c6bb584103de8d467d292b01e0045 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
@@ -33,6 +33,9 @@
 #include "flexran_agent_mac_internal.h"
 #include "flexran_agent_mac_slice_verification.h"
 
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
+
 extern SLIST_HEAD(flexran_so_handle,
                   flexran_agent_so_handle_s) flexran_handles[NUM_MAX_ENB];
 
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h
index 9db5d61a11693ca899811628d9eb18d7592f716d..d6dd6e3b6f1f0a986258668835998c89b42cc4dc 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h
@@ -51,8 +51,6 @@ typedef struct {
   pthread_mutex_t *mutex;
 } mac_stats_updates_context_t;
 
-/*Array holding the last stats reports for each eNB. Used for continuous reporting*/
-mac_stats_updates_context_t mac_stats_context[NUM_MAX_ENB];
 
 /*Functions to initialize and destroy the struct required for the
  *continuous stats update report*/
diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h
index 5f6432732f486e1842068fa5b33e76e8a548f26c..a9236af80b601b030dae7ad67e09926eed3dddd5 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h
+++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h
@@ -49,8 +49,6 @@ typedef struct
    /*To Be Extended*/
 }rrc_meas_stats;
 
-/* RRC CMI statistics */
-rrc_meas_stats * meas_stats;
 
 
 /* FLEXRAN AGENT-RRC Interface */
diff --git a/openair2/ENB_APP/MACRLC_paramdef.h b/openair2/ENB_APP/MACRLC_paramdef.h
index fcee6142f0bc7cce1a0cec70f4b19e93267e669a..11cbe445b84a765d14f22f5b4b3e3f819bf79a1c 100644
--- a/openair2/ENB_APP/MACRLC_paramdef.h
+++ b/openair2/ENB_APP/MACRLC_paramdef.h
@@ -56,10 +56,14 @@
 #define CONFIG_STRING_MACRLC_LOCAL_S_PORTD                 "local_s_portd"
 #define CONFIG_STRING_MACRLC_REMOTE_S_PORTD                "remote_s_portd"
 #define CONFIG_STRING_MACRLC_SCHED_MODE                    "scheduler_mode"
-#define CONFIG_MACRLC_PUSCH10xSNR                          "puSch10xSnr"
-#define CONFIG_MACRLC_PUCCH10xSNR                          "puCch10xSnr"
+#define CONFIG_STRING_MACRLC_PUSCH10xSNR                   "puSch10xSnr"
+#define CONFIG_STRING_MACRLC_PUCCH10xSNR                   "puCch10xSnr"
 #define CONFIG_STRING_MACRLC_DEFAULT_SCHED_DL_ALGO         "default_sched_dl_algo"
-
+#define CONFIG_STRING_MACRLC_UE_MULTIPLE_MAX               "ue_multiple_max"
+#define CONFIG_STRING_MACRLC_USE_MCS_OFFSET                "use_mcs_offset"
+#define CONFIG_STRING_MACRLC_BLER_TARGET_LOWER             "bler_target_lower"
+#define CONFIG_STRING_MACRLC_BLER_TARGET_UPPER             "bler_target_upper"
+#define CONFIG_STRING_MACRLC_MAX_UL_RB_INDEX               "max_ul_rb_index"
 /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            MacRLC  configuration parameters                                                                           */
 /*   optname                                            helpstr   paramflags    XXXptr              defXXXval                  type           numelt     */
@@ -83,10 +87,15 @@
 {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_SCHED_MODE,                        NULL,     0,          strptr:NULL,         defstrval:"default",       TYPE_STRING,   0},        \
-{CONFIG_MACRLC_PUSCH10xSNR,  		                 NULL,     0,          iptr:NULL,           defintval:200,             TYPE_INT,      0},        \
-{CONFIG_MACRLC_PUCCH10xSNR,  		                 NULL,     0,          iptr:NULL,           defintval:200,             TYPE_INT,      0},        \
-{CONFIG_STRING_MACRLC_DEFAULT_SCHED_DL_ALGO,             NULL,     0,          strptr:NULL,         defstrval:"round_robin_dl", TYPE_STRING,   0},        \
-}
+{CONFIG_STRING_MACRLC_PUSCH10xSNR,                       NULL,     0,          iptr:NULL,           defintval:200,             TYPE_INT,      0},        \
+{CONFIG_STRING_MACRLC_PUCCH10xSNR,  	                 NULL,     0,          iptr:NULL,           defintval:200,             TYPE_INT,      0},        \
+{CONFIG_STRING_MACRLC_DEFAULT_SCHED_DL_ALGO,             NULL,     0,          strptr:NULL,         defstrval:"round_robin_dl", TYPE_STRING,  0},        \
+{CONFIG_STRING_MACRLC_UE_MULTIPLE_MAX,                   NULL,     0,          iptr:NULL,           defintval:4,               TYPE_INT,      0},        \
+{CONFIG_STRING_MACRLC_USE_MCS_OFFSET,                    NULL,     0,          iptr:NULL,           defintval:1,               TYPE_INT,      0},        \
+{CONFIG_STRING_MACRLC_BLER_TARGET_LOWER,                 NULL,     0,          dblptr:NULL,           defdblval:.5,               TYPE_DOUBLE,      0}, \
+{CONFIG_STRING_MACRLC_BLER_TARGET_UPPER,                 NULL,     0,          dblptr:NULL,           defdblval:2,               TYPE_DOUBLE,      0}, \
+{CONFIG_STRING_MACRLC_MAX_UL_RB_INDEX,                   NULL,     0,          iptr:NULL,           defintval:22,              TYPE_INT, 0}}
+
 #define MACRLC_CC_IDX                                          0
 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX                      1
 #define MACRLC_LOCAL_N_IF_NAME_IDX                             2
@@ -108,6 +117,11 @@
 #define MACRLC_PUSCH10xSNR_IDX                                 18
 #define MACRLC_PUCCH10xSNR_IDX                                 19 
 #define MACRLC_DEFAULT_SCHED_DL_ALGO_IDX                       20
+#define MACRLC_UE_MULTIPLE_MAX_IDX                             21
+#define MACRLC_USE_MCS_OFFSET_IDX                              22
+#define MACRLC_BLER_TARGET_LOWER_IDX                           23
+#define MACRLC_BLER_TARGET_UPPER_IDX                           24
+#define MACRLC_MAX_UL_RB_INDEX_IDX                             25
 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
 
 #endif
diff --git a/openair2/ENB_APP/NB_IoT_interface.c b/openair2/ENB_APP/NB_IoT_interface.c
index 7355233d71d766e033efac6efa2a1ab08e81aed3..8fc6de78afae35443d8be62161f0a26de73bed34 100644
--- a/openair2/ENB_APP/NB_IoT_interface.c
+++ b/openair2/ENB_APP/NB_IoT_interface.c
@@ -35,6 +35,9 @@
 #define NBIOT_INTERFACE_SOURCE
 #include "NB_IoT_interface.h"
 
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
+
 
 
 
diff --git a/openair2/ENB_APP/NB_IoT_interface.h b/openair2/ENB_APP/NB_IoT_interface.h
index b3454b077bc1cc64aa514c5abed78c7a8c53138e..c13f6dd1cb25905b2b766bd053a755adbc935429 100644
--- a/openair2/ENB_APP/NB_IoT_interface.h
+++ b/openair2/ENB_APP/NB_IoT_interface.h
@@ -31,6 +31,7 @@
 
 
 #define NBIOT_MODULENAME "NB_IoT"
+#include "common/ran_context.h"
 
 typedef void(*RCConfig_NbIoT_f_t)(RAN_CONTEXT_t *RC);
 #define NBIOT_RCCONFIG_FNAME "RCConfig_NbIoT"
diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c
index 5080157c3f77f4d3cd9fcd206b58a894c8b9f2f8..9f134f826ea26d0863892547e7f75fde30f2e3a6 100644
--- a/openair2/ENB_APP/enb_app.c
+++ b/openair2/ENB_APP/enb_app.c
@@ -244,6 +244,8 @@ void *eNB_app_task(void *args_p) {
 
   }
 
+  LOG_I(ENB_APP,"TASK_ENB_APP is ready\n");
+
   do {
     // Wait for a message
     itti_receive_msg (TASK_ENB_APP, &msg_p);
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 6c709ea63b8818f436d83af51add83231184c296..4751596931cbbb78d7acdb7162cdb37d8b15f5a8 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -57,12 +57,15 @@
 #include "enb_paramdef.h"
 #include "proto_agent.h"
 #include "executables/thread-common.h"
+#include <openair3/ocp-gtpu/gtp_itf.h>
 
 extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw);
 extern uint32_t to_earfcn_UL(int eutra_bandP, uint32_t ul_CarrierFreq, uint32_t bw);
 extern char *parallel_config;
 extern char *worker_config;
 
+RAN_CONTEXT_t RC;
+
 void RCconfig_flexran() {
   /* get number of eNBs */
   paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
@@ -217,13 +220,26 @@ void RCconfig_macrlc(int macrlc_has_f1[MAX_MAC_INST]) {
     for (j = 0; j < RC.nb_macrlc_inst; j++) {
       RC.mac[j]->puSch10xSnr = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCH10xSNR_IDX ].iptr);
       RC.mac[j]->puCch10xSnr = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCH10xSNR_IDX ].iptr);
+      RC.mac[j]->ue_multiple_max = *(MacRLC_ParamList.paramarray[j][MACRLC_UE_MULTIPLE_MAX_IDX ].iptr);
+      RC.mac[j]->use_mcs_offset = *(MacRLC_ParamList.paramarray[j][MACRLC_USE_MCS_OFFSET_IDX ].iptr);
+      RC.mac[j]->bler_lower = *(MacRLC_ParamList.paramarray[j][MACRLC_BLER_TARGET_LOWER_IDX ].dblptr);
+      RC.mac[j]->bler_upper = *(MacRLC_ParamList.paramarray[j][MACRLC_BLER_TARGET_UPPER_IDX ].dblptr);
+      RC.mac[j]->max_ul_rb_index = *(MacRLC_ParamList.paramarray[j][MACRLC_MAX_UL_RB_INDEX_IDX ].iptr);
       RC.nb_mac_CC[j] = *(MacRLC_ParamList.paramarray[j][MACRLC_CC_IDX].iptr);
-
+      LOG_I(ENB_APP,"MAC instance %d parameters : pusch_snr %lf, pucch_snr %lf, ue_multiple_max %d, use_mcs_offset %d, bler_lower %lf, bler_upper %lf,max_ul_rb_index %d\n",
+	j,
+	RC.mac[j]->puSch10xSnr/10.0,
+	RC.mac[j]->puCch10xSnr/10.0,
+	RC.mac[j]->ue_multiple_max,
+	RC.mac[j]->use_mcs_offset,
+	RC.mac[j]->bler_lower,
+	RC.mac[j]->bler_upper,
+	RC.mac[j]->max_ul_rb_index);
       if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) {
         // check number of instances is same as RRC/PDCP
-        printf("Configuring local RRC for MACRLC\n");
+        LOG_I(ENB_APP,"Configuring local RRC for MACRLC\n");
       } else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "f1") == 0) {
-        printf("Configuring F1 interfaces for MACRLC\n");
+        LOG_I(ENB_APP,"Configuring F1 interfaces for MACRLC\n");
         RC.mac[j]->eth_params_n.local_if_name            = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr));
         RC.mac[j]->eth_params_n.my_addr                  = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr));
         RC.mac[j]->eth_params_n.remote_addr              = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr));
@@ -1992,7 +2008,7 @@ int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i) {
           F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nrb                 = rrc->carrier[0].mib.message.dl_Bandwidth;
           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->carrier[0].sib1->freqBandIndicator;
-          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.sul_active          = 0;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.sul_active          = 0;
         } else {
           LOG_I(ENB_APP,"ngran_DU: Configuring Cell %d for FDD\n",k);
           F1AP_SETUP_REQ (msg_p).fdd_flag = 1;
@@ -2058,7 +2074,9 @@ int RCconfig_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 = enb_port_for_S1U;
-    itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
+    strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address);
+    sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", enb_port_for_S1U);
+    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 S1U\n");
 
@@ -2429,6 +2447,65 @@ int RCconfig_S1(
                         "to\n"
                         "    tracking_area_code  =  1; // no string!!\n"
                         "    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n");
+            if(*ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr <= 0xffff)
+            {
+              S1AP_REGISTER_ENB_REQ(msg_p).s1_setuprsp_wait_timer = *ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr;
+            }
+            else
+            {
+              LOG_E(S1AP, 
+                    "s1setup_rsp_timer value in conf file is invalid (%d). Default value is set.\n",
+                    *ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr);
+              S1AP_REGISTER_ENB_REQ(msg_p).s1_setuprsp_wait_timer = 5;
+            }
+
+            if(*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr <= 0xffff)
+            {
+              S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_wait_timer = *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr;
+            }
+            else
+            {
+              LOG_E(S1AP, 
+                    "s1setup_req_timer value in conf file is invalid (%d). Default value is set.\n",
+                    *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr);
+              S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_wait_timer = 5;
+            }
+
+            if(*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr <= 0xffff)
+            {
+              S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_count = *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr;
+            }
+            else
+            {
+              LOG_E(S1AP, 
+                    "s1setup_req_count value in conf file is invalid (%d). Default value is set.\n",
+                    *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr);
+              S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_count = 0xffff;
+            }
+
+            if(*ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr <= 0xffff)
+            {
+              S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_timer = *ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr;
+            }
+            else
+            {
+              LOG_E(S1AP, 
+                    "sctp_req_timer value in conf file is invalid (%d). Default value is set.\n",
+                    *ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr);
+              S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_timer = 180;
+            }
+
+            if(*ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr <= 0xffff)
+            {
+              S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_count = *ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr;
+            }
+            else
+            {
+              LOG_E(S1AP, 
+                    "sctp_req_count value in conf file is invalid (%d). Default value is set.\n",
+                    *ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr);
+              S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_count = 0xffff;
+            }
             config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
 
             if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) {
@@ -2717,12 +2794,13 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
                         "value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n",
                         X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS);
             X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0;
-
+            LOG_I(X2AP,"X2ParamList.numelt %d\n",X2ParamList.numelt);
             for (l = 0; l < X2ParamList.numelt; l++) {
               X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 += 1;
               strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr));
               strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6_address,*(X2ParamList.paramarray[l][ENB_X2_IPV6_ADDRESS_IDX].strptr));
 
+              LOG_I(X2AP,"registering with ip : %s\n",*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr));
               if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
                 X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1;
                 X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 0;
@@ -2902,7 +2980,7 @@ void extract_and_decode_SI(int inst,int si_ind,uint8_t *si_container,int si_cont
   eNB_RRC_INST *rrc = RC.rrc[inst];
   rrc_eNB_carrier_data_t *carrier = &rrc->carrier[0];
   LTE_BCCH_DL_SCH_Message_t *bcch_message ;
-  AssertFatal(si_ind==0,"Can only handle a single SI block for now\n");
+  AssertFatal(si_ind==2,"Can only handle a single SI block for now\n");
   LOG_I(ENB_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;
@@ -3083,21 +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=0; si_ind<resp->num_SI[j]; 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");
-          extract_and_decode_SI(i,
-                                si_ind,
-                                resp->SI_container[j][si_ind],
-                                resp->SI_container_length[j][si_ind]);
+          if (si_ind==6) si_ind=9;
+          if (resp->cells_to_activate[j].SI_container[si_ind] != NULL) {
+            extract_and_decode_SI(i,
+                                  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/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h
index 4bc4f5bf2244e306c998d95f8843880a13d324c3..b95bf90f70d918b65a6d5b8bc2f0657447ddb9bb 100644
--- a/openair2/ENB_APP/enb_config.h
+++ b/openair2/ENB_APP/enb_config.h
@@ -100,7 +100,6 @@ typedef struct ru_config_s {
   uint8_t   if_compress;
 } ru_config_t;
 
-extern void RCconfig_RU(void);
 extern void RCconfig_flexran(void);
 extern void RCconfig_L1(void);
 extern void RCconfig_macrlc(int macrlc_has_f1[MAX_MAC_INST]);
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index de7e0bbdad96ba7a65cfe2691486faf37026ed4e..79e66881b5c00ddd43a9fae3814bd3b5735a8f69 100644
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -98,6 +98,7 @@ typedef enum {
 #define CONFIG_STRING_RU_BF_WEIGHTS_LIST          "bf_weights"
 #define CONFIG_STRING_RU_IF_FREQUENCY             "if_freq"
 #define CONFIG_STRING_RU_IF_FREQ_OFFSET           "if_offset"
+#define CONFIG_STRING_RU_DO_PRECODING             "do_precoding"
 
 #define RU_LOCAL_IF_NAME_IDX          0
 #define RU_LOCAL_ADDRESS_IDX          1
@@ -127,7 +128,7 @@ typedef enum {
 #define RU_BF_WEIGHTS_LIST_IDX        25
 #define RU_IF_FREQUENCY               26
 #define RU_IF_FREQ_OFFSET             27
-
+#define RU_DO_PRECODING               28
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            RU configuration parameters                                                                  */
 /*   optname                                   helpstr   paramflags    XXXptr          defXXXval                   type      numelt        */
@@ -160,7 +161,8 @@ typedef enum {
     {CONFIG_STRING_RU_OTA_SYNC_ENABLE,             NULL,       0,       strptr:NULL,     defstrval:"no",          TYPE_STRING,      0}, \
     {CONFIG_STRING_RU_BF_WEIGHTS_LIST,             NULL,       0,       iptr:NULL,       defintarrayval:DEFBFW,   TYPE_INTARRAY,    0}, \
     {CONFIG_STRING_RU_IF_FREQUENCY,                NULL,       0,       u64ptr:NULL,     defuintval:0,            TYPE_UINT64,      0}, \
-    {CONFIG_STRING_RU_IF_FREQ_OFFSET,              NULL,       0,       iptr:NULL,     defintval:0,             TYPE_INT,         0}, \
+    {CONFIG_STRING_RU_IF_FREQ_OFFSET,              NULL,       0,       iptr:NULL,       defintval:0,             TYPE_INT,         0}, \
+    {CONFIG_STRING_RU_DO_PRECODING,                NULL,       0,       iptr:NULL,       defintval:0,             TYPE_INT,         0}, \
   }
 
 /*---------------------------------------------------------------------------------------------------------------------------------------*/
@@ -214,6 +216,11 @@ typedef enum {
 #define ENB_CONFIG_STRING_X2                            "enable_x2"
 #define ENB_CONFIG_STRING_ENB_M2                        "enable_enb_m2"
 #define ENB_CONFIG_STRING_MCE_M2                        "enable_mce_m2"
+#define ENB_CONFIG_STRING_S1SETUP_RSP_TIMER             "s1setup_rsp_timer"
+#define ENB_CONFIG_STRING_S1SETUP_REQ_TIMER             "s1setup_req_timer"
+#define ENB_CONFIG_STRING_S1SETUP_REQ_COUNT             "s1setup_req_count"
+#define ENB_CONFIG_STRING_SCTP_REQ_TIMER                "sctp_req_timer"
+#define ENB_CONFIG_STRING_SCTP_REQ_COUNT                "sctp_req_count"
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            cell configuration parameters                                                                */
 /*   optname                                   helpstr   paramflags    XXXptr        defXXXval                   type           numelt     */
@@ -239,6 +246,11 @@ typedef enum {
     {ENB_CONFIG_STRING_X2,                           NULL,   0,            strptr:NULL, defstrval:NULL,              TYPE_STRING,    0},  \
     {ENB_CONFIG_STRING_ENB_M2,                       NULL,   0,            strptr:NULL, defstrval:"no",              TYPE_STRING,    0},  \
     {ENB_CONFIG_STRING_MCE_M2,                       NULL,   0,            strptr:NULL, defstrval:"no",              TYPE_STRING,    0},  \
+    {ENB_CONFIG_STRING_S1SETUP_RSP_TIMER,            NULL,   0,            uptr:NULL,   defuintval:5,                TYPE_UINT,      0},  \
+    {ENB_CONFIG_STRING_S1SETUP_REQ_TIMER,            NULL,   0,            uptr:NULL,   defuintval:5,                TYPE_UINT,      0},  \
+    {ENB_CONFIG_STRING_S1SETUP_REQ_COUNT,            NULL,   0,            uptr:NULL,   defuintval:65535,            TYPE_UINT,      0},  \
+    {ENB_CONFIG_STRING_SCTP_REQ_TIMER,               NULL,   0,            uptr:NULL,   defuintval:180,              TYPE_UINT,      0},  \
+    {ENB_CONFIG_STRING_SCTP_REQ_COUNT,               NULL,   0,            uptr:NULL,   defuintval:65535,            TYPE_UINT,      0},  \
   }
 
 #define ENB_ENB_ID_IDX                  0
@@ -261,6 +273,11 @@ typedef enum {
 #define ENB_ENABLE_X2                   17
 #define ENB_ENABLE_ENB_M2               18
 #define ENB_ENABLE_MCE_M2               19
+#define ENB_S1SETUP_RSP_TIMER_IDX       20
+#define ENB_S1SETUP_REQ_TIMER_IDX       21
+#define ENB_S1SETUP_REQ_COUNT_IDX       22
+#define ENB_SCTP_REQ_TIMER_IDX          23
+#define ENB_SCTP_REQ_COUNT_IDX          24
 
 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
 #define ENBPARAMS_CHECK {                                           \
diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c
index 33182f3593a64db3a8a7a1e4f2d78c18b7fc1494..af7ff6ff6f06e6fb3876d6bdb8375d9e2865f2c9 100644
--- a/openair2/ENB_APP/flexran_agent.c
+++ b/openair2/ENB_APP/flexran_agent.c
@@ -33,6 +33,9 @@
 #include <pthread.h>
 #include <arpa/inet.h>
 
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
+
 int agent_task_created = 0;
 /* 
  * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller 
diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c
index abb5b57e0cbb58626de2dec1686aa75da6e4e1e9..55a1c61b254fadc6e9297e0b20d7dd5710c777c8 100644
--- a/openair2/ENB_APP/flexran_agent_common.c
+++ b/openair2/ENB_APP/flexran_agent_common.c
@@ -53,6 +53,9 @@
 #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
 #include "rrc_eNB_UE_context.h"
 
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
+
 /*
  * message primitives
  */
@@ -648,18 +651,6 @@ error:
  * ************************************
  */
 
-int sort_ue_config(const void *a, const void *b) {
-  const Protocol__FlexUeConfig *fa = a;
-  const Protocol__FlexUeConfig *fb = b;
-
-  if (fa->rnti < fb->rnti)
-    return -1;
-  else if (fa->rnti < fb->rnti)
-    return 1;
-
-  return 0;
-}
-
 int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
   xid_t xid;
   Protocol__FlexHeader *header = NULL;
diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h
index ae690c712496621ef0e1cd1dc69958ec11474966..18d32421dd10f49030121c4ccddd17d8c56dd4c0 100644
--- a/openair2/ENB_APP/flexran_agent_common.h
+++ b/openair2/ENB_APP/flexran_agent_common.h
@@ -70,7 +70,6 @@ typedef struct {
   pthread_mutex_t *mutex;
 } stats_updates_context_t;
 
-stats_updates_context_t stats_context[NUM_MAX_ENB];
 
 /**********************************
  * FlexRAN protocol messages helper 
diff --git a/openair2/ENB_APP/flexran_agent_net_comm.c b/openair2/ENB_APP/flexran_agent_net_comm.c
index 0d1c52096dce1bc277a217c0dac5e93ce60f8144..568a0e32cc91b73ff74c03e5112767a0c7891237 100644
--- a/openair2/ENB_APP/flexran_agent_net_comm.c
+++ b/openair2/ENB_APP/flexran_agent_net_comm.c
@@ -30,7 +30,7 @@
 #include "common/utils/LOG/log.h"
 
 flexran_agent_channel_t *agent_channel[NUM_MAX_ENB][FLEXRAN_AGENT_MAX];
-flexran_agent_channel_instance_t channel_instance;
+static flexran_agent_channel_instance_t channel_instance;
 int flexran_agent_channel_id = 0;
 
 int flexran_agent_msg_send(mid_t mod_id, agent_id_t agent_id, void *data, int size, int priority) {
diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c
index ff219718108304bd488db398590a9f088151c595..68d1f3311f261ab38f45250c35371b5f53d8cd39 100644
--- a/openair2/ENB_APP/flexran_agent_ran_api.c
+++ b/openair2/ENB_APP/flexran_agent_ran_api.c
@@ -32,6 +32,9 @@
 #include "s1ap_eNB_management_procedures.h"
 #include "openair2/LAYER2/MAC/slicing/slicing.h"
 
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
+
 static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) {
   return RC.eNB && RC.eNB[mod_id] && RC.eNB[mod_id][cc_id];
 }
@@ -885,7 +888,7 @@ uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti) {
 
   if (!ue_context_p) return RRC_INACTIVE;
 
-  return ue_context_p->ue_context.Status;
+  return ue_context_p->ue_context.StatusRrc;
 }
 
 uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id) {
diff --git a/openair2/ENB_APP/flexran_agent_ran_api_to_fix.c b/openair2/ENB_APP/flexran_agent_ran_api_to_fix.c
new file mode 100644
index 0000000000000000000000000000000000000000..a5eb8507128f5a93e1207f2cec379fa3047ece91
--- /dev/null
+++ b/openair2/ENB_APP/flexran_agent_ran_api_to_fix.c
@@ -0,0 +1,33 @@
+#include <stdint.h>
+#include <openair2/COMMON/platform_constants.h>
+#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
+pdcp_enb_t pdcp_enb[MAX_NUM_CCs];
+uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+
+uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+
diff --git a/openair2/F1AP/MESSAGES/ASN1/R16.3.1/38473-g31.asn b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/38473-g31.asn
new file mode 100644
index 0000000000000000000000000000000000000000..c821c520103780434b33e149df6fe38d455c24e4
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/38473-g31.asn
@@ -0,0 +1,10721 @@
+-- ASN1START 
+-- **************************************************************
+--
+-- Elementary Procedure definitions
+--
+-- **************************************************************
+
+F1AP-PDU-Descriptions  { 
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Descriptions (0)}
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	Criticality,
+	ProcedureCode
+
+FROM F1AP-CommonDataTypes
+	Reset,
+	ResetAcknowledge,
+	F1SetupRequest,
+	F1SetupResponse,
+	F1SetupFailure, 
+	GNBDUConfigurationUpdate,
+	GNBDUConfigurationUpdateAcknowledge,
+	GNBDUConfigurationUpdateFailure,
+	GNBCUConfigurationUpdate,
+	GNBCUConfigurationUpdateAcknowledge,
+	GNBCUConfigurationUpdateFailure,
+	UEContextSetupRequest,
+	UEContextSetupResponse,
+	UEContextSetupFailure,
+	UEContextReleaseCommand,
+	UEContextReleaseComplete,
+	UEContextModificationRequest,
+	UEContextModificationResponse,
+	UEContextModificationFailure,
+	UEContextModificationRequired,
+	UEContextModificationConfirm,
+	ErrorIndication,
+	UEContextReleaseRequest,
+	DLRRCMessageTransfer,
+	ULRRCMessageTransfer,
+	GNBDUResourceCoordinationRequest,
+	GNBDUResourceCoordinationResponse,
+	PrivateMessage,
+	UEInactivityNotification,
+	InitialULRRCMessageTransfer,
+	SystemInformationDeliveryCommand,
+	Paging,
+	Notify,
+	WriteReplaceWarningRequest,
+	WriteReplaceWarningResponse,
+	PWSCancelRequest,
+	PWSCancelResponse,
+	PWSRestartIndication,
+	PWSFailureIndication,
+	GNBDUStatusIndication,
+	RRCDeliveryReport,
+	UEContextModificationRefuse,
+	F1RemovalRequest,
+	F1RemovalResponse,
+	F1RemovalFailure,
+	NetworkAccessRateReduction,
+	TraceStart,
+	DeactivateTrace,
+	DUCURadioInformationTransfer,
+	CUDURadioInformationTransfer,
+	BAPMappingConfiguration,
+	BAPMappingConfigurationAcknowledge,
+	GNBDUResourceConfiguration,
+	GNBDUResourceConfigurationAcknowledge,
+	IABTNLAddressRequest,
+	IABTNLAddressResponse,
+	IABUPConfigurationUpdateRequest,
+	IABUPConfigurationUpdateResponse,
+	IABUPConfigurationUpdateFailure,
+	ResourceStatusRequest,
+	ResourceStatusResponse,
+	ResourceStatusFailure,
+	ResourceStatusUpdate,
+	AccessAndMobilityIndication,
+	ReferenceTimeInformationReportingControl,
+	ReferenceTimeInformationReport,
+	AccessSuccess,
+	CellTrafficTrace,
+	PositioningMeasurementRequest,
+	PositioningMeasurementResponse,
+	PositioningMeasurementFailure,
+	PositioningAssistanceInformationControl,
+	PositioningAssistanceInformationFeedback,
+	PositioningMeasurementReport,
+	PositioningMeasurementAbort,
+	PositioningMeasurementFailureIndication,
+	PositioningMeasurementUpdate,
+	TRPInformationRequest,
+	TRPInformationResponse,
+	TRPInformationFailure,
+	PositioningInformationRequest,
+	PositioningInformationResponse,
+	PositioningInformationFailure,
+	PositioningActivationRequest,
+	PositioningActivationResponse,
+	PositioningActivationFailure,
+	PositioningDeactivation,
+	PositioningInformationUpdate,
+	E-CIDMeasurementInitiationRequest,
+	E-CIDMeasurementInitiationResponse,
+	E-CIDMeasurementInitiationFailure,
+	E-CIDMeasurementFailureIndication,
+	E-CIDMeasurementReport,
+	E-CIDMeasurementTerminationCommand
+
+
+
+FROM F1AP-PDU-Contents
+	id-Reset,
+	id-F1Setup,
+	id-gNBDUConfigurationUpdate,
+	id-gNBCUConfigurationUpdate,
+	id-UEContextSetup,
+	id-UEContextRelease,
+	id-UEContextModification,
+	id-UEContextModificationRequired,
+	id-ErrorIndication, 
+	id-UEContextReleaseRequest,
+	id-DLRRCMessageTransfer,
+	id-ULRRCMessageTransfer,
+	id-GNBDUResourceCoordination,
+	id-privateMessage,
+	id-UEInactivityNotification,
+	id-InitialULRRCMessageTransfer,
+	id-SystemInformationDeliveryCommand,
+	id-Paging,
+	id-Notify,
+	id-WriteReplaceWarning,
+	id-PWSCancel,
+	id-PWSRestartIndication,
+	id-PWSFailureIndication,
+	id-GNBDUStatusIndication,
+	id-RRCDeliveryReport,
+	id-F1Removal,
+	id-NetworkAccessRateReduction,
+	id-TraceStart,
+	id-DeactivateTrace,
+	id-DUCURadioInformationTransfer,
+	id-CUDURadioInformationTransfer,
+	id-BAPMappingConfiguration,
+	id-GNBDUResourceConfiguration,
+	id-IABTNLAddressAllocation,
+	id-IABUPConfigurationUpdate,
+	id-resourceStatusReportingInitiation,
+	id-resourceStatusReporting,
+	id-accessAndMobilityIndication,
+	id-ReferenceTimeInformationReportingControl,
+	id-ReferenceTimeInformationReport,
+	id-accessSuccess,
+	id-cellTrafficTrace,
+	id-PositioningMeasurementExchange,
+	id-PositioningAssistanceInformationControl,
+	id-PositioningAssistanceInformationFeedback,
+	id-PositioningMeasurementReport,
+	id-PositioningMeasurementAbort,
+	id-PositioningMeasurementFailureIndication,
+	id-PositioningMeasurementUpdate,
+	id-TRPInformationExchange,
+	id-PositioningInformationExchange,
+	id-PositioningActivation,
+	id-PositioningDeactivation,
+	id-PositioningInformationUpdate,
+	id-E-CIDMeasurementInitiation,
+	id-E-CIDMeasurementFailureIndication,
+	id-E-CIDMeasurementReport,
+	id-E-CIDMeasurementTermination
+
+
+FROM F1AP-Constants
+
+	ProtocolIE-SingleContainer{},
+	F1AP-PROTOCOL-IES
+
+FROM F1AP-Containers;
+
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure Class
+--
+-- **************************************************************
+
+F1AP-ELEMENTARY-PROCEDURE ::= CLASS {
+	&InitiatingMessage				,
+	&SuccessfulOutcome							OPTIONAL,
+	&UnsuccessfulOutcome						OPTIONAL,
+	&procedureCode				ProcedureCode 	UNIQUE,
+	&criticality				Criticality 	DEFAULT ignore
+}
+WITH SYNTAX {
+	INITIATING MESSAGE			&InitiatingMessage
+	[SUCCESSFUL OUTCOME			&SuccessfulOutcome]
+	[UNSUCCESSFUL OUTCOME		&UnsuccessfulOutcome]
+	PROCEDURE CODE				&procedureCode
+	[CRITICALITY				&criticality]
+}
+
+-- **************************************************************
+--
+-- Interface PDU Definition
+--
+-- **************************************************************
+
+F1AP-PDU ::= CHOICE {
+	initiatingMessage	InitiatingMessage,
+	successfulOutcome	SuccessfulOutcome,
+	unsuccessfulOutcome	UnsuccessfulOutcome, 
+	choice-extension	ProtocolIE-SingleContainer { { F1AP-PDU-ExtIEs} }
+}
+
+F1AP-PDU-ExtIEs F1AP-PROTOCOL-IES ::= { -- this extension is not used
+	...
+}
+
+InitiatingMessage ::= SEQUENCE {
+	procedureCode	F1AP-ELEMENTARY-PROCEDURE.&procedureCode		({F1AP-ELEMENTARY-PROCEDURES}),
+	criticality		F1AP-ELEMENTARY-PROCEDURE.&criticality			({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+	value			F1AP-ELEMENTARY-PROCEDURE.&InitiatingMessage	({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+SuccessfulOutcome ::= SEQUENCE {
+	procedureCode	F1AP-ELEMENTARY-PROCEDURE.&procedureCode		({F1AP-ELEMENTARY-PROCEDURES}),
+	criticality		F1AP-ELEMENTARY-PROCEDURE.&criticality			({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+	value			F1AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome	({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+UnsuccessfulOutcome ::= SEQUENCE {
+	procedureCode	F1AP-ELEMENTARY-PROCEDURE.&procedureCode		({F1AP-ELEMENTARY-PROCEDURES}),
+	criticality		F1AP-ELEMENTARY-PROCEDURE.&criticality			({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+	value			F1AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome	({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure List
+--
+-- **************************************************************
+
+F1AP-ELEMENTARY-PROCEDURES F1AP-ELEMENTARY-PROCEDURE ::= {
+	F1AP-ELEMENTARY-PROCEDURES-CLASS-1			|
+	F1AP-ELEMENTARY-PROCEDURES-CLASS-2,	
+	...
+}
+
+
+F1AP-ELEMENTARY-PROCEDURES-CLASS-1 F1AP-ELEMENTARY-PROCEDURE ::= {
+	reset							|
+	f1Setup							|
+	gNBDUConfigurationUpdate		|
+	gNBCUConfigurationUpdate		|
+	uEContextSetup					|
+	uEContextRelease				|
+	uEContextModification			|
+	uEContextModificationRequired	|
+	writeReplaceWarning				|
+	pWSCancel					|
+	gNBDUResourceCoordination		|
+	f1Removal						|
+	bAPMappingConfiguration			|
+	gNBDUResourceConfiguration		|
+	iABTNLAddressAllocation			|
+	iABUPConfigurationUpdate		|
+	resourceStatusReportingInitiation	|
+	positioningMeasurementExchange	|
+	tRPInformationExchange			|
+	positioningInformationExchange	|
+	positioningActivation			|
+	e-CIDMeasurementInitiation,
+	...
+}
+
+F1AP-ELEMENTARY-PROCEDURES-CLASS-2 F1AP-ELEMENTARY-PROCEDURE ::= {	
+	errorIndication							|
+	uEContextReleaseRequest					|
+	dLRRCMessageTransfer					|
+	uLRRCMessageTransfer					|
+	uEInactivityNotification				|
+	privateMessage							|
+	initialULRRCMessageTransfer				|
+	systemInformationDelivery				|
+	paging									|
+	notify									|
+	pWSRestartIndication					|
+	pWSFailureIndication					|
+	gNBDUStatusIndication					|
+	rRCDeliveryReport						|
+	networkAccessRateReduction				|
+	traceStart								|
+	deactivateTrace							|
+	dUCURadioInformationTransfer			|
+	cUDURadioInformationTransfer			|
+	resourceStatusReporting					|
+	accessAndMobilityIndication				|
+	referenceTimeInformationReportingControl|
+	referenceTimeInformationReport			|
+	accessSuccess							|
+	cellTrafficTrace						|
+	positioningAssistanceInformationControl		|
+	positioningAssistanceInformationFeedback	|
+	positioningMeasurementReport				|
+	positioningMeasurementAbort					|
+	positioningMeasurementFailureIndication		|
+	positioningMeasurementUpdate				|
+	positioningDeactivation						|
+	e-CIDMeasurementFailureIndication			|
+	e-CIDMeasurementReport						|
+	e-CIDMeasurementTermination					|
+	positioningInformationUpdate,
+	...
+}
+-- **************************************************************
+--
+-- Interface Elementary Procedures
+--
+-- **************************************************************
+
+reset F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		Reset
+	SUCCESSFUL OUTCOME		ResetAcknowledge
+	PROCEDURE CODE			id-Reset
+	CRITICALITY				reject
+}
+
+f1Setup F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		F1SetupRequest
+	SUCCESSFUL OUTCOME		F1SetupResponse
+	UNSUCCESSFUL OUTCOME	F1SetupFailure
+	PROCEDURE CODE			id-F1Setup
+	CRITICALITY				reject
+}
+
+gNBDUConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBDUConfigurationUpdate
+	SUCCESSFUL OUTCOME		GNBDUConfigurationUpdateAcknowledge
+	UNSUCCESSFUL OUTCOME	GNBDUConfigurationUpdateFailure
+	PROCEDURE CODE			id-gNBDUConfigurationUpdate
+	CRITICALITY				reject
+}
+
+gNBCUConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBCUConfigurationUpdate
+	SUCCESSFUL OUTCOME		GNBCUConfigurationUpdateAcknowledge
+	UNSUCCESSFUL OUTCOME	GNBCUConfigurationUpdateFailure
+	PROCEDURE CODE			id-gNBCUConfigurationUpdate
+	CRITICALITY				reject
+}
+
+uEContextSetup F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextSetupRequest
+	SUCCESSFUL OUTCOME		UEContextSetupResponse
+	UNSUCCESSFUL OUTCOME	UEContextSetupFailure
+	PROCEDURE CODE			id-UEContextSetup
+	CRITICALITY				reject
+}
+
+uEContextRelease F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextReleaseCommand
+	SUCCESSFUL OUTCOME		UEContextReleaseComplete
+	PROCEDURE CODE			id-UEContextRelease
+	CRITICALITY				reject
+}
+
+uEContextModification F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextModificationRequest
+	SUCCESSFUL OUTCOME		UEContextModificationResponse
+	UNSUCCESSFUL OUTCOME	UEContextModificationFailure
+	PROCEDURE CODE			id-UEContextModification
+	CRITICALITY				reject
+}
+
+uEContextModificationRequired F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextModificationRequired
+	SUCCESSFUL OUTCOME		UEContextModificationConfirm
+	UNSUCCESSFUL OUTCOME	UEContextModificationRefuse
+	PROCEDURE CODE			id-UEContextModificationRequired
+	CRITICALITY				reject
+}
+
+writeReplaceWarning F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		WriteReplaceWarningRequest
+	SUCCESSFUL OUTCOME		WriteReplaceWarningResponse
+	PROCEDURE CODE			id-WriteReplaceWarning
+	CRITICALITY				reject
+}
+
+pWSCancel F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PWSCancelRequest
+	SUCCESSFUL OUTCOME		PWSCancelResponse
+	PROCEDURE CODE			id-PWSCancel
+	CRITICALITY				reject
+}
+
+errorIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ErrorIndication
+	PROCEDURE CODE			id-ErrorIndication
+	CRITICALITY				ignore
+}
+
+uEContextReleaseRequest F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextReleaseRequest
+	PROCEDURE CODE			id-UEContextReleaseRequest
+	CRITICALITY				ignore
+}
+
+
+initialULRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		InitialULRRCMessageTransfer
+	PROCEDURE CODE			id-InitialULRRCMessageTransfer
+	CRITICALITY				ignore
+}
+
+dLRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		DLRRCMessageTransfer
+	PROCEDURE CODE			id-DLRRCMessageTransfer
+	CRITICALITY				ignore
+}
+
+uLRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ULRRCMessageTransfer
+	PROCEDURE CODE			id-ULRRCMessageTransfer
+	CRITICALITY				ignore
+}
+
+
+uEInactivityNotification  F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEInactivityNotification
+	PROCEDURE CODE			id-UEInactivityNotification
+	CRITICALITY				ignore
+}
+
+gNBDUResourceCoordination F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBDUResourceCoordinationRequest
+	SUCCESSFUL OUTCOME		GNBDUResourceCoordinationResponse
+	PROCEDURE CODE			id-GNBDUResourceCoordination
+	CRITICALITY				reject
+}
+
+privateMessage F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PrivateMessage
+	PROCEDURE CODE			id-privateMessage
+	CRITICALITY				ignore
+}
+
+systemInformationDelivery F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		SystemInformationDeliveryCommand
+	PROCEDURE CODE			id-SystemInformationDeliveryCommand
+	CRITICALITY				ignore
+}
+
+
+paging F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		Paging
+	PROCEDURE CODE			id-Paging
+	CRITICALITY				ignore
+}
+
+notify F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		Notify
+	PROCEDURE CODE			id-Notify
+	CRITICALITY				ignore
+}
+
+networkAccessRateReduction F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		NetworkAccessRateReduction
+	PROCEDURE CODE			id-NetworkAccessRateReduction
+	CRITICALITY				ignore
+}
+
+
+pWSRestartIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PWSRestartIndication
+	PROCEDURE CODE			id-PWSRestartIndication
+	CRITICALITY				ignore
+}
+
+pWSFailureIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PWSFailureIndication
+	PROCEDURE CODE			id-PWSFailureIndication
+	CRITICALITY				ignore
+}
+
+gNBDUStatusIndication 	F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBDUStatusIndication
+	PROCEDURE CODE			id-GNBDUStatusIndication
+	CRITICALITY				ignore
+}
+
+
+rRCDeliveryReport F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		RRCDeliveryReport
+	PROCEDURE CODE			id-RRCDeliveryReport
+	CRITICALITY				ignore
+}
+
+f1Removal F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		F1RemovalRequest
+	SUCCESSFUL OUTCOME		F1RemovalResponse
+	UNSUCCESSFUL OUTCOME	F1RemovalFailure
+	PROCEDURE CODE			id-F1Removal
+	CRITICALITY				reject
+}
+
+traceStart F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		TraceStart
+	PROCEDURE CODE			id-TraceStart
+	CRITICALITY				ignore
+}
+
+deactivateTrace F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		DeactivateTrace
+	PROCEDURE CODE			id-DeactivateTrace
+	CRITICALITY				ignore
+}
+
+dUCURadioInformationTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		DUCURadioInformationTransfer
+	PROCEDURE CODE			id-DUCURadioInformationTransfer
+	CRITICALITY				ignore
+}
+
+cUDURadioInformationTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		CUDURadioInformationTransfer
+	PROCEDURE CODE			id-CUDURadioInformationTransfer
+	CRITICALITY				ignore
+}
+
+bAPMappingConfiguration F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		BAPMappingConfiguration
+	SUCCESSFUL OUTCOME		BAPMappingConfigurationAcknowledge
+	PROCEDURE CODE			id-BAPMappingConfiguration
+	CRITICALITY				reject
+}
+
+gNBDUResourceConfiguration F1AP-ELEMENTARY-PROCEDURE ::= { 
+	INITIATING MESSAGE		GNBDUResourceConfiguration
+	SUCCESSFUL OUTCOME		GNBDUResourceConfigurationAcknowledge
+	PROCEDURE CODE			id-GNBDUResourceConfiguration
+	CRITICALITY				reject
+}
+
+iABTNLAddressAllocation F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		IABTNLAddressRequest
+	SUCCESSFUL OUTCOME		IABTNLAddressResponse
+	PROCEDURE CODE			id-IABTNLAddressAllocation
+	CRITICALITY				reject
+}
+
+iABUPConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		IABUPConfigurationUpdateRequest
+	SUCCESSFUL OUTCOME		IABUPConfigurationUpdateResponse
+	UNSUCCESSFUL OUTCOME	IABUPConfigurationUpdateFailure
+	PROCEDURE CODE			id-IABUPConfigurationUpdate
+	CRITICALITY				reject
+}
+
+resourceStatusReportingInitiation F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ResourceStatusRequest
+	SUCCESSFUL OUTCOME		ResourceStatusResponse
+	UNSUCCESSFUL OUTCOME	ResourceStatusFailure
+	PROCEDURE CODE			id-resourceStatusReportingInitiation
+	CRITICALITY				reject
+}
+
+resourceStatusReporting F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ResourceStatusUpdate
+	PROCEDURE CODE			id-resourceStatusReporting
+	CRITICALITY				ignore
+}
+
+accessAndMobilityIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		AccessAndMobilityIndication
+	PROCEDURE CODE			id-accessAndMobilityIndication
+	CRITICALITY				ignore
+}
+
+referenceTimeInformationReportingControl F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ReferenceTimeInformationReportingControl
+	PROCEDURE CODE			id-ReferenceTimeInformationReportingControl
+	CRITICALITY				ignore
+}
+
+referenceTimeInformationReport F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ReferenceTimeInformationReport
+	PROCEDURE CODE			id-ReferenceTimeInformationReport
+	CRITICALITY				ignore
+}
+
+accessSuccess F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		AccessSuccess
+	PROCEDURE CODE			id-accessSuccess
+	CRITICALITY				ignore
+}
+
+cellTrafficTrace F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		CellTrafficTrace
+	PROCEDURE CODE			id-cellTrafficTrace
+	CRITICALITY				ignore
+}
+
+positioningAssistanceInformationControl F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningAssistanceInformationControl
+	PROCEDURE CODE			id-PositioningAssistanceInformationControl
+	CRITICALITY				ignore
+}
+
+positioningAssistanceInformationFeedback F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningAssistanceInformationFeedback
+	PROCEDURE CODE			id-PositioningAssistanceInformationFeedback
+	CRITICALITY				ignore
+}
+
+positioningMeasurementExchange F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningMeasurementRequest
+	SUCCESSFUL OUTCOME		PositioningMeasurementResponse
+	UNSUCCESSFUL OUTCOME	PositioningMeasurementFailure
+	PROCEDURE CODE			id-PositioningMeasurementExchange
+	CRITICALITY				reject
+}
+
+positioningMeasurementReport F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningMeasurementReport
+	PROCEDURE CODE			id-PositioningMeasurementReport
+	CRITICALITY				ignore
+}
+
+positioningMeasurementAbort F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningMeasurementAbort
+	PROCEDURE CODE			id-PositioningMeasurementAbort
+	CRITICALITY				ignore
+}
+
+positioningMeasurementFailureIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningMeasurementFailureIndication
+	PROCEDURE CODE			id-PositioningMeasurementFailureIndication
+	CRITICALITY				ignore
+}
+
+positioningMeasurementUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningMeasurementUpdate
+	PROCEDURE CODE			id-PositioningMeasurementUpdate
+	CRITICALITY				ignore
+}
+
+
+tRPInformationExchange F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		TRPInformationRequest
+	SUCCESSFUL OUTCOME		TRPInformationResponse
+	UNSUCCESSFUL OUTCOME	TRPInformationFailure
+	PROCEDURE CODE			id-TRPInformationExchange
+	CRITICALITY				reject
+}
+
+positioningInformationExchange F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningInformationRequest
+	SUCCESSFUL OUTCOME		PositioningInformationResponse
+	UNSUCCESSFUL OUTCOME	PositioningInformationFailure
+	PROCEDURE CODE			id-PositioningInformationExchange
+	CRITICALITY				reject
+}
+
+positioningActivation F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningActivationRequest
+	SUCCESSFUL OUTCOME		PositioningActivationResponse
+	UNSUCCESSFUL OUTCOME	PositioningActivationFailure
+	PROCEDURE CODE			id-PositioningActivation
+	CRITICALITY				reject
+}
+
+positioningDeactivation F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningDeactivation
+	PROCEDURE CODE			id-PositioningDeactivation
+	CRITICALITY				ignore
+}
+
+e-CIDMeasurementInitiation F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		E-CIDMeasurementInitiationRequest
+	SUCCESSFUL OUTCOME		E-CIDMeasurementInitiationResponse
+	UNSUCCESSFUL OUTCOME	E-CIDMeasurementInitiationFailure
+	PROCEDURE CODE			id-E-CIDMeasurementInitiation
+	CRITICALITY				reject
+}
+
+e-CIDMeasurementFailureIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		E-CIDMeasurementFailureIndication
+	PROCEDURE CODE			id-E-CIDMeasurementFailureIndication
+	CRITICALITY				ignore
+}
+
+e-CIDMeasurementReport F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		E-CIDMeasurementReport
+	PROCEDURE CODE			id-E-CIDMeasurementReport
+	CRITICALITY				ignore
+}
+
+e-CIDMeasurementTermination F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		E-CIDMeasurementTerminationCommand
+	PROCEDURE CODE			id-E-CIDMeasurementTermination
+	CRITICALITY				ignore
+}
+
+positioningInformationUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningInformationUpdate
+	PROCEDURE CODE			id-PositioningInformationUpdate
+	CRITICALITY				ignore
+}
+
+
+END
+-- ASN1STOP 
+
+-- ASN1START 
+-- **************************************************************
+--
+-- PDU definitions for F1AP.
+--
+-- **************************************************************
+
+F1AP-PDU-Contents { 
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Contents (1) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	Candidate-SpCell-Item,
+	Cause,
+	Cells-Failed-to-be-Activated-List-Item,
+	Cells-Status-Item,
+	Cells-to-be-Activated-List-Item,
+	Cells-to-be-Deactivated-List-Item, 
+	CellULConfigured,
+	CriticalityDiagnostics, 
+	C-RNTI,
+	CUtoDURRCInformation, 
+	DRB-Activity-Item,
+	DRBID,
+	DRBs-FailedToBeModified-Item,
+	DRBs-FailedToBeSetup-Item,
+	DRBs-FailedToBeSetupMod-Item,
+	DRB-Notify-Item,
+	DRBs-ModifiedConf-Item,
+	DRBs-Modified-Item,
+	DRBs-Required-ToBeModified-Item,
+	DRBs-Required-ToBeReleased-Item,
+	DRBs-Setup-Item,
+	DRBs-SetupMod-Item,
+	DRBs-ToBeModified-Item,
+	DRBs-ToBeReleased-Item,
+	DRBs-ToBeSetup-Item,
+	DRBs-ToBeSetupMod-Item,
+	DRXCycle,
+	DRXConfigurationIndicator,
+	DUtoCURRCInformation,
+	EUTRANQoS,
+	ExecuteDuplication,
+	FullConfiguration,
+	GNB-CU-UE-F1AP-ID,
+	GNB-DU-UE-F1AP-ID,
+	GNB-DU-ID,
+	GNB-DU-Served-Cells-Item,
+	GNB-DU-System-Information, 
+	GNB-CU-Name,
+	GNB-DU-Name,
+	InactivityMonitoringRequest,
+	InactivityMonitoringResponse,
+	LowerLayerPresenceStatusChange,
+	NotificationControl,
+	NRCGI,
+	NRPCI,
+	UEContextNotRetrievable,
+	Potential-SpCell-Item,
+	RAT-FrequencyPriorityInformation,
+	RequestedSRSTransmissionCharacteristics,
+	ResourceCoordinationTransferContainer,
+	RRCContainer,
+	RRCContainer-RRCSetupComplete,
+	RRCReconfigurationCompleteIndicator,
+	SCellIndex,
+	SCell-ToBeRemoved-Item,
+	SCell-ToBeSetup-Item,
+	SCell-ToBeSetupMod-Item,
+	SCell-FailedtoSetup-Item,
+	SCell-FailedtoSetupMod-Item, 
+	ServCellIndex,
+	Served-Cell-Information,
+	Served-Cells-To-Add-Item,
+	Served-Cells-To-Delete-Item,
+	Served-Cells-To-Modify-Item,
+	ServingCellMO,
+	SRBID,
+	SRBs-FailedToBeSetup-Item,
+	SRBs-FailedToBeSetupMod-Item,
+	SRBs-Required-ToBeReleased-Item,
+	SRBs-ToBeReleased-Item,
+	SRBs-ToBeSetup-Item,
+	SRBs-ToBeSetupMod-Item,
+	SRBs-Modified-Item,
+	SRBs-Setup-Item,
+	SRBs-SetupMod-Item,
+	TimeToWait,
+	TransactionID,
+	TransmissionActionIndicator,
+	UE-associatedLogicalF1-ConnectionItem,
+	DUtoCURRCContainer,
+	PagingCell-Item, 
+	SItype-List,
+	UEIdentityIndexValue,
+	GNB-CU-TNL-Association-Setup-Item,
+	GNB-CU-TNL-Association-Failed-To-Setup-Item,
+	GNB-CU-TNL-Association-To-Add-Item,
+	GNB-CU-TNL-Association-To-Remove-Item,
+	GNB-CU-TNL-Association-To-Update-Item,
+	MaskedIMEISV,
+	PagingDRX,
+	PagingPriority,
+	PagingIdentity,
+	Cells-to-be-Barred-Item,
+	PWSSystemInformation,
+	Broadcast-To-Be-Cancelled-Item,
+	Cells-Broadcast-Cancelled-Item,
+	NR-CGI-List-For-Restart-Item,
+	PWS-Failed-NR-CGI-Item,
+	RepetitionPeriod,
+	NumberofBroadcastRequest,
+	Cells-To-Be-Broadcast-Item,
+	Cells-Broadcast-Completed-Item,
+	Cancel-all-Warning-Messages-Indicator,
+	EUTRA-NR-CellResourceCoordinationReq-Container,
+	EUTRA-NR-CellResourceCoordinationReqAck-Container,
+	RequestType,
+	PLMN-Identity,
+	RLCFailureIndication, 
+	UplinkTxDirectCurrentListInformation,
+	SULAccessIndication,
+	Protected-EUTRA-Resources-Item,
+	GNB-DUConfigurationQuery,
+	BitRate,
+	RRC-Version,
+	GNBDUOverloadInformation,
+	RRCDeliveryStatusRequest,
+	NeedforGap,
+	RRCDeliveryStatus,
+	ResourceCoordinationTransferInformation,
+	Dedicated-SIDelivery-NeededUE-Item,
+	Associated-SCell-Item,
+	IgnoreResourceCoordinationContainer,
+	PagingOrigin,
+	UAC-Assistance-Info,
+	RANUEID,
+	GNB-DU-TNL-Association-To-Remove-Item,
+	NotificationInformation,
+	TraceActivation,
+	TraceID,
+	Neighbour-Cell-Information-Item,
+	SymbolAllocInSlot,
+	NumDLULSymbols,
+	AdditionalRRMPriorityIndex,
+	DUCURadioInformationType,
+	CUDURadioInformationType,
+	Transport-Layer-Address-Info,
+	BHChannels-ToBeSetup-Item,
+	BHChannels-Setup-Item,
+	BHChannels-FailedToBeSetup-Item,
+	BHChannels-ToBeModified-Item,
+	BHChannels-ToBeReleased-Item,
+	BHChannels-ToBeSetupMod-Item,
+	BHChannels-FailedToBeModified-Item,
+	BHChannels-FailedToBeSetupMod-Item,
+	BHChannels-Modified-Item,
+	BHChannels-SetupMod-Item,
+	BHChannels-Required-ToBeReleased-Item,
+	BAPAddress,
+	BAPPathID,
+	BAPRoutingID,
+	BH-Routing-Information-Added-List-Item,
+	BH-Routing-Information-Removed-List-Item,
+	Child-Nodes-List,
+	Child-Nodes-List-Item,
+	Child-Node-Cells-List,
+	Child-Node-Cells-List-Item,
+	Activated-Cells-to-be-Updated-List,
+	Activated-Cells-to-be-Updated-List-Item,
+	UL-BH-Non-UP-Traffic-Mapping,
+	IABTNLAddressesRequested,
+	IABIPv6RequestType,
+	IAB-TNL-Addresses-To-Remove-Item,
+	IABTNLAddress,
+	IAB-Allocated-TNL-Address-Item,
+	IABv4AddressesRequested,
+	TrafficMappingInfo,
+	UL-UP-TNL-Information-to-Update-List-Item,
+	UL-UP-TNL-Address-to-Update-List-Item,
+	DL-UP-TNL-Address-to-Update-List-Item,
+	NRV2XServicesAuthorized,
+	LTEV2XServicesAuthorized,
+	NRUESidelinkAggregateMaximumBitrate,
+	LTEUESidelinkAggregateMaximumBitrate,
+	SLDRBs-SetupMod-Item,
+	SLDRBs-ModifiedConf-Item,
+	SLDRBID,
+	SLDRBs-FailedToBeModified-Item,
+	SLDRBs-FailedToBeSetup-Item,
+	SLDRBs-FailedToBeSetupMod-Item,
+	SLDRBs-Modified-Item,
+	SLDRBs-Required-ToBeModified-Item,
+	SLDRBs-Required-ToBeReleased-Item,
+	SLDRBs-Setup-Item,
+	SLDRBs-ToBeModified-Item,
+	SLDRBs-ToBeReleased-Item,
+	SLDRBs-ToBeSetup-Item,
+	SLDRBs-ToBeSetupMod-Item,
+	GNBCUMeasurementID,
+	GNBDUMeasurementID,
+	RegistrationRequest,
+	ReportCharacteristics,
+	CellToReportList,
+	HardwareLoadIndicator,
+	CellMeasurementResultList,
+	ReportingPeriodicity,
+	TNLCapacityIndicator,
+	RACHReportInformationList,
+	RLFReportInformationList,
+	ReportingRequestType,
+	TimeReferenceInformation,
+	ConditionalInterDUMobilityInformation,
+	ConditionalIntraDUMobilityInformation,
+	TargetCellList,
+	MDTPLMNList,
+	PrivacyIndicator,
+	TransportLayerAddress,
+	URI-address,
+	NID,
+	PosAssistance-Information,
+	PosBroadcast,
+	PositioningBroadcastCells,
+	RoutingID,
+	PosAssistanceInformationFailureList,
+	PosMeasurementQuantities,
+	PosMeasurementResultList,
+	PosMeasurementPeriodicity,
+	PosReportCharacteristics,
+	TRPInformationTypeItem,
+	TRPInformationItem,
+	LMF-MeasurementID,
+	RAN-MeasurementID,
+	SRSResourceSetID,
+	SRSSpatialRelation,
+	SRSResourceTrigger,
+	SRSConfiguration,
+	TRPList,
+	E-CID-MeasurementQuantities,
+	E-CID-MeasurementPeriodicity,
+	E-CID-MeasurementResult,
+	Cell-Portion-ID,
+	LMF-UE-MeasurementID,
+	RAN-UE-MeasurementID,
+	SFNInitialisationTime,
+	SystemFrameNumber,
+	SlotNumber,
+	AbortTransmission,
+	TRP-MeasurementRequestList,
+	MeasurementBeamInfoRequest,
+	E-CID-ReportCharacteristics,
+	Extended-GNB-CU-Name,
+	Extended-GNB-DU-Name
+
+
+
+FROM F1AP-IEs
+
+	PrivateIE-Container{},
+	ProtocolExtensionContainer{},
+	ProtocolIE-Container{},
+	ProtocolIE-ContainerPair{},
+	ProtocolIE-SingleContainer{},
+	F1AP-PRIVATE-IES,
+	F1AP-PROTOCOL-EXTENSION,
+	F1AP-PROTOCOL-IES,
+	F1AP-PROTOCOL-IES-PAIR
+
+FROM F1AP-Containers
+
+	id-Candidate-SpCell-Item,
+	id-Candidate-SpCell-List,
+	id-Cause,
+	id-Cancel-all-Warning-Messages-Indicator,
+	id-Cells-Failed-to-be-Activated-List,
+	id-Cells-Failed-to-be-Activated-List-Item, 
+	id-Cells-Status-Item,
+	id-Cells-Status-List,
+	id-Cells-to-be-Activated-List,
+	id-Cells-to-be-Activated-List-Item,
+	id-Cells-to-be-Deactivated-List,
+	id-Cells-to-be-Deactivated-List-Item,
+	id-ConfirmedUEID,
+	id-CriticalityDiagnostics,
+	id-C-RNTI,
+	id-CUtoDURRCInformation,
+	id-DRB-Activity-Item,
+	id-DRB-Activity-List,
+	id-DRBs-FailedToBeModified-Item,
+	id-DRBs-FailedToBeModified-List,
+	id-DRBs-FailedToBeSetup-Item,
+	id-DRBs-FailedToBeSetup-List,
+	id-DRBs-FailedToBeSetupMod-Item,
+	id-DRBs-FailedToBeSetupMod-List,
+	id-DRBs-ModifiedConf-Item,
+	id-DRBs-ModifiedConf-List,
+	id-DRBs-Modified-Item,
+	id-DRBs-Modified-List,
+	id-DRB-Notify-Item,
+	id-DRB-Notify-List,
+	id-DRBs-Required-ToBeModified-Item,
+	id-DRBs-Required-ToBeModified-List,
+	id-DRBs-Required-ToBeReleased-Item,
+	id-DRBs-Required-ToBeReleased-List,
+	id-DRBs-Setup-Item,
+	id-DRBs-Setup-List,
+	id-DRBs-SetupMod-Item,
+	id-DRBs-SetupMod-List,
+	id-DRBs-ToBeModified-Item,
+	id-DRBs-ToBeModified-List,
+	id-DRBs-ToBeReleased-Item,
+	id-DRBs-ToBeReleased-List,
+	id-DRBs-ToBeSetup-Item,
+	id-DRBs-ToBeSetup-List,
+	id-DRBs-ToBeSetupMod-Item,
+	id-DRBs-ToBeSetupMod-List,
+	id-DRXCycle,
+	id-DUtoCURRCInformation,
+	id-ExecuteDuplication,
+	id-FullConfiguration,
+	id-gNB-CU-UE-F1AP-ID,
+	id-gNB-DU-UE-F1AP-ID,
+	id-gNB-DU-ID,
+	id-GNB-DU-Served-Cells-Item,
+	id-gNB-DU-Served-Cells-List, 
+	id-gNB-CU-Name,
+	id-gNB-DU-Name,
+	id-Extended-GNB-CU-Name,
+	id-Extended-GNB-DU-Name,
+	id-InactivityMonitoringRequest,
+	id-InactivityMonitoringResponse,
+	id-new-gNB-CU-UE-F1AP-ID,
+	id-new-gNB-DU-UE-F1AP-ID,
+	id-oldgNB-DU-UE-F1AP-ID,
+	id-PLMNAssistanceInfoForNetShar,
+	id-Potential-SpCell-Item,
+	id-Potential-SpCell-List,
+	id-RAT-FrequencyPriorityInformation, 
+	id-RedirectedRRCmessage,
+	id-ResetType,
+	id-RequestedSRSTransmissionCharacteristics,
+	id-ResourceCoordinationTransferContainer,
+	id-RRCContainer,
+	id-RRCContainer-RRCSetupComplete,
+	id-RRCReconfigurationCompleteIndicator,
+	id-SCell-FailedtoSetup-List,
+	id-SCell-FailedtoSetup-Item,
+	id-SCell-FailedtoSetupMod-List,
+	id-SCell-FailedtoSetupMod-Item,
+	id-SCell-ToBeRemoved-Item,
+	id-SCell-ToBeRemoved-List,
+	id-SCell-ToBeSetup-Item,
+	id-SCell-ToBeSetup-List,
+	id-SCell-ToBeSetupMod-Item,
+	id-SCell-ToBeSetupMod-List,
+	id-SelectedPLMNID,
+	id-Served-Cells-To-Add-Item,
+	id-Served-Cells-To-Add-List,
+	id-Served-Cells-To-Delete-Item,
+	id-Served-Cells-To-Delete-List,
+	id-Served-Cells-To-Modify-Item,
+	id-Served-Cells-To-Modify-List,
+	id-ServCellIndex,
+	id-ServingCellMO,
+	id-SpCell-ID,
+	id-SpCellULConfigured,
+	id-SRBID,
+	id-SRBs-FailedToBeSetup-Item,
+	id-SRBs-FailedToBeSetup-List,
+	id-SRBs-FailedToBeSetupMod-Item,
+	id-SRBs-FailedToBeSetupMod-List,
+	id-SRBs-Required-ToBeReleased-Item,
+	id-SRBs-Required-ToBeReleased-List,
+	id-SRBs-ToBeReleased-Item,
+	id-SRBs-ToBeReleased-List, 
+	id-SRBs-ToBeSetup-Item,
+	id-SRBs-ToBeSetup-List,
+	id-SRBs-ToBeSetupMod-Item,
+	id-SRBs-ToBeSetupMod-List,
+	id-SRBs-Modified-Item,
+	id-SRBs-Modified-List,
+	id-SRBs-Setup-Item,
+	id-SRBs-Setup-List,
+	id-SRBs-SetupMod-Item,
+	id-SRBs-SetupMod-List,
+	id-TimeToWait,
+	id-TransactionID,
+	id-TransmissionActionIndicator, 
+	id-UEContextNotRetrievable,
+	id-UE-associatedLogicalF1-ConnectionItem,
+	id-UE-associatedLogicalF1-ConnectionListResAck,
+	id-DUtoCURRCContainer,
+	id-NRCGI,
+	id-PagingCell-Item,
+	id-PagingCell-List,
+	id-PagingDRX,
+	id-PagingPriority,
+	id-SItype-List,
+	id-UEIdentityIndexValue,
+	id-GNB-CU-TNL-Association-Setup-List,
+	id-GNB-CU-TNL-Association-Setup-Item,
+	id-GNB-CU-TNL-Association-Failed-To-Setup-List,
+	id-GNB-CU-TNL-Association-Failed-To-Setup-Item,
+	id-GNB-CU-TNL-Association-To-Add-Item,
+	id-GNB-CU-TNL-Association-To-Add-List,
+	id-GNB-CU-TNL-Association-To-Remove-Item,
+	id-GNB-CU-TNL-Association-To-Remove-List,
+	id-GNB-CU-TNL-Association-To-Update-Item,
+	id-GNB-CU-TNL-Association-To-Update-List,
+	id-MaskedIMEISV,
+	id-PagingIdentity,
+	id-Cells-to-be-Barred-List,
+	id-Cells-to-be-Barred-Item,
+	id-PWSSystemInformation,
+	id-RepetitionPeriod,
+	id-NumberofBroadcastRequest,
+	id-Cells-To-Be-Broadcast-List,
+	id-Cells-To-Be-Broadcast-Item,
+	id-Cells-Broadcast-Completed-List,
+	id-Cells-Broadcast-Completed-Item,
+	id-Broadcast-To-Be-Cancelled-List,
+	id-Broadcast-To-Be-Cancelled-Item,
+	id-Cells-Broadcast-Cancelled-List,
+	id-Cells-Broadcast-Cancelled-Item,
+	id-NR-CGI-List-For-Restart-List,
+	id-NR-CGI-List-For-Restart-Item,
+	id-PWS-Failed-NR-CGI-List,
+	id-PWS-Failed-NR-CGI-Item,
+	id-EUTRA-NR-CellResourceCoordinationReq-Container,
+	id-EUTRA-NR-CellResourceCoordinationReqAck-Container,
+	id-Protected-EUTRA-Resources-List,
+	id-RequestType,
+	id-ServingPLMN,
+	id-DRXConfigurationIndicator,
+	id-RLCFailureIndication,
+	id-UplinkTxDirectCurrentListInformation,
+	id-SULAccessIndication,
+	id-Protected-EUTRA-Resources-Item,
+	id-GNB-DUConfigurationQuery,
+	id-GNB-DU-UE-AMBR-UL,
+	id-GNB-CU-RRC-Version,
+	id-GNB-DU-RRC-Version,
+	id-GNBDUOverloadInformation,
+	id-NeedforGap,
+	id-RRCDeliveryStatusRequest,
+	id-RRCDeliveryStatus,
+	id-Dedicated-SIDelivery-NeededUE-List,
+	id-Dedicated-SIDelivery-NeededUE-Item,
+	id-ResourceCoordinationTransferInformation,
+	id-Associated-SCell-List,
+	id-Associated-SCell-Item,
+	id-IgnoreResourceCoordinationContainer,
+	id-UAC-Assistance-Info,
+	id-RANUEID,
+	id-PagingOrigin,
+	id-GNB-DU-TNL-Association-To-Remove-Item,
+	id-GNB-DU-TNL-Association-To-Remove-List,
+	id-NotificationInformation,
+	id-TraceActivation,
+	id-TraceID,
+	id-Neighbour-Cell-Information-List,
+	id-Neighbour-Cell-Information-Item,
+	id-SymbolAllocInSlot,
+	id-NumDLULSymbols,
+	id-AdditionalRRMPriorityIndex,
+	id-DUCURadioInformationType,
+	id-CUDURadioInformationType,
+	id-LowerLayerPresenceStatusChange,
+	id-Transport-Layer-Address-Info,
+	id-BHChannels-ToBeSetup-List,
+	id-BHChannels-ToBeSetup-Item,
+	id-BHChannels-Setup-List,
+	id-BHChannels-Setup-Item,
+	id-BHChannels-ToBeModified-Item,
+	id-BHChannels-ToBeModified-List,
+	id-BHChannels-ToBeReleased-Item,
+	id-BHChannels-ToBeReleased-List,
+	id-BHChannels-ToBeSetupMod-Item,
+	id-BHChannels-ToBeSetupMod-List,
+	id-BHChannels-FailedToBeSetup-Item,
+	id-BHChannels-FailedToBeSetup-List,
+	id-BHChannels-FailedToBeModified-Item,
+	id-BHChannels-FailedToBeModified-List,
+	id-BHChannels-FailedToBeSetupMod-Item,
+	id-BHChannels-FailedToBeSetupMod-List,
+	id-BHChannels-Modified-Item,
+	id-BHChannels-Modified-List,
+	id-BHChannels-SetupMod-Item,
+	id-BHChannels-SetupMod-List,
+	id-BHChannels-Required-ToBeReleased-Item,
+	id-BHChannels-Required-ToBeReleased-List,
+	id-BAPAddress,
+	id-ConfiguredBAPAddress,
+	id-BH-Routing-Information-Added-List,
+	id-BH-Routing-Information-Added-List-Item,
+	id-BH-Routing-Information-Removed-List,
+	id-BH-Routing-Information-Removed-List-Item,
+	id-UL-BH-Non-UP-Traffic-Mapping,
+	id-Child-Nodes-List,
+	id-Activated-Cells-to-be-Updated-List, 
+	id-IABIPv6RequestType,
+	id-IAB-TNL-Addresses-To-Remove-List,
+	id-IAB-TNL-Addresses-To-Remove-Item,
+	id-IAB-Allocated-TNL-Address-List,
+	id-IAB-Allocated-TNL-Address-Item,
+	id-IABv4AddressesRequested,
+	id-TrafficMappingInformation,
+	id-UL-UP-TNL-Information-to-Update-List,
+	id-UL-UP-TNL-Information-to-Update-List-Item,
+	id-UL-UP-TNL-Address-to-Update-List,
+	id-UL-UP-TNL-Address-to-Update-List-Item,
+	id-DL-UP-TNL-Address-to-Update-List,
+	id-DL-UP-TNL-Address-to-Update-List-Item,
+	id-NRV2XServicesAuthorized,
+	id-LTEV2XServicesAuthorized,
+	id-NRUESidelinkAggregateMaximumBitrate,
+	id-LTEUESidelinkAggregateMaximumBitrate,
+	id-PC5LinkAMBR,
+	id-SLDRBs-FailedToBeModified-Item,
+	id-SLDRBs-FailedToBeModified-List,
+	id-SLDRBs-FailedToBeSetup-Item,
+	id-SLDRBs-FailedToBeSetup-List,
+	id-SLDRBs-Modified-Item,
+	id-SLDRBs-Modified-List,
+	id-SLDRBs-Required-ToBeModified-Item,
+	id-SLDRBs-Required-ToBeModified-List,
+	id-SLDRBs-Required-ToBeReleased-Item,
+	id-SLDRBs-Required-ToBeReleased-List,
+	id-SLDRBs-Setup-Item,
+	id-SLDRBs-Setup-List,
+	id-SLDRBs-ToBeModified-Item,
+	id-SLDRBs-ToBeModified-List,
+	id-SLDRBs-ToBeReleased-Item,
+	id-SLDRBs-ToBeReleased-List,
+	id-SLDRBs-ToBeSetup-Item,
+	id-SLDRBs-ToBeSetup-List,
+	id-SLDRBs-ToBeSetupMod-Item,
+	id-SLDRBs-ToBeSetupMod-List,
+	id-SLDRBs-SetupMod-List,
+	id-SLDRBs-FailedToBeSetupMod-List,
+	id-SLDRBs-SetupMod-Item,
+	id-SLDRBs-FailedToBeSetupMod-Item,
+	id-SLDRBs-ModifiedConf-List,
+	id-SLDRBs-ModifiedConf-Item,
+	id-gNBCUMeasurementID,
+	id-gNBDUMeasurementID,
+	id-RegistrationRequest,
+	id-ReportCharacteristics,
+	id-CellToReportList,
+	id-CellMeasurementResultList,
+	id-HardwareLoadIndicator,
+	id-ReportingPeriodicity, 
+	id-TNLCapacityIndicator, 
+	id-RACHReportInformationList,
+	id-RLFReportInformationList,
+	id-ReportingRequestType,
+	id-TimeReferenceInformation,
+	id-ConditionalInterDUMobilityInformation,
+	id-ConditionalIntraDUMobilityInformation,
+	id-targetCellsToCancel,
+	id-requestedTargetCellGlobalID,
+	id-TraceCollectionEntityIPAddress,
+	id-ManagementBasedMDTPLMNList,
+	id-PrivacyIndicator,
+	id-TraceCollectionEntityURI,
+	id-ServingNID,
+	id-PosAssistance-Information,
+	id-PosBroadcast,
+	id-PositioningBroadcastCells,
+	id-RoutingID,
+	id-PosAssistanceInformationFailureList,
+	id-PosMeasurementQuantities,
+	id-PosMeasurementResultList,
+	id-PosMeasurementPeriodicity,
+	id-PosReportCharacteristics,
+	id-TRPInformationTypeListTRPReq,
+	id-TRPInformationTypeItem,
+	id-TRPInformationListTRPResp,
+	id-TRPInformationItem,
+	id-LMF-MeasurementID,
+	id-RAN-MeasurementID,
+	id-SRSType,
+	id-ActivationTime,
+	id-AbortTransmission,
+	id-SRSConfiguration,
+	id-TRPList,
+	id-E-CID-MeasurementQuantities,
+	id-E-CID-MeasurementPeriodicity,
+	id-E-CID-MeasurementResult,
+	id-Cell-Portion-ID,
+	id-LMF-UE-MeasurementID,
+	id-RAN-UE-MeasurementID,
+	id-SFNInitialisationTime,
+	id-SystemFrameNumber,
+	id-SlotNumber,
+	id-TRP-MeasurementRequestList,
+	id-MeasurementBeamInfoRequest,
+	id-E-CID-ReportCharacteristics,
+
+	maxCellingNBDU,
+	maxnoofCandidateSpCells,
+	maxnoofDRBs,
+	maxnoofErrors,
+	maxnoofIndividualF1ConnectionsToReset,
+	maxnoofPotentialSpCells,
+	maxnoofSCells,
+	maxnoofSRBs,
+	maxnoofPagingCells,
+	maxnoofTNLAssociations,
+	maxCellineNB,
+	maxnoofUEIDs,
+	maxnoofBHRLCChannels,
+	maxnoofRoutingEntries,
+	maxnoofChildIABNodes,
+	maxnoofServedCellsIAB,
+	maxnoofTLAsIAB,
+	maxnoofULUPTNLInformationforIAB,
+	maxnoofUPTNLAddresses,
+	maxnoofSLDRBs,
+	maxnoofTRPInfoTypes,
+	maxnoofTRPs
+
+
+
+FROM F1AP-Constants;
+
+
+-- **************************************************************
+--
+-- RESET ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Reset
+--
+-- **************************************************************
+
+Reset ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {ResetIEs} },
+	...
+}
+
+ResetIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-ResetType					CRITICALITY reject	TYPE ResetType					PRESENCE mandatory	},
+	...
+}
+
+ResetType ::= CHOICE {
+	f1-Interface					ResetAll,
+	partOfF1-Interface				UE-associatedLogicalF1-ConnectionListRes, 
+	choice-extension				ProtocolIE-SingleContainer { { ResetType-ExtIEs} }
+}
+
+ResetType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+
+ResetAll ::= ENUMERATED {
+	reset-all,
+	...
+}
+
+UE-associatedLogicalF1-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxnoofIndividualF1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalF1-ConnectionItemRes } }
+
+UE-associatedLogicalF1-ConnectionItemRes F1AP-PROTOCOL-IES ::= {
+	{ ID id-UE-associatedLogicalF1-ConnectionItem	CRITICALITY reject	TYPE UE-associatedLogicalF1-ConnectionItem	PRESENCE mandatory},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Reset Acknowledge
+--
+-- **************************************************************
+
+ResetAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {ResetAcknowledgeIEs} },
+	...
+}
+
+ResetAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID									CRITICALITY reject	TYPE TransactionID													PRESENCE mandatory	}|
+	{ ID id-UE-associatedLogicalF1-ConnectionListResAck		CRITICALITY ignore	TYPE UE-associatedLogicalF1-ConnectionListResAck			PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+	...
+}
+
+UE-associatedLogicalF1-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxnoofIndividualF1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalF1-ConnectionItemResAck } }
+
+UE-associatedLogicalF1-ConnectionItemResAck 	F1AP-PROTOCOL-IES ::= {
+	{ ID id-UE-associatedLogicalF1-ConnectionItem	 CRITICALITY ignore 	TYPE UE-associatedLogicalF1-ConnectionItem  	PRESENCE mandatory },
+	...
+}
+
+-- **************************************************************
+--
+-- ERROR INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Error Indication
+--
+-- **************************************************************
+
+ErrorIndication ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ErrorIndicationIEs}},
+	...
+}
+
+ErrorIndicationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory}|
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID			PRESENCE optional	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID			PRESENCE optional	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- F1 SETUP ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- F1 Setup Request
+--
+-- **************************************************************
+
+F1SetupRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {F1SetupRequestIEs} },
+	...
+}
+
+F1SetupRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-gNB-DU-ID						CRITICALITY reject	TYPE GNB-DU-ID							PRESENCE mandatory	}|
+	{ ID id-gNB-DU-Name						CRITICALITY ignore	TYPE GNB-DU-Name						PRESENCE optional	}|
+	{ ID id-gNB-DU-Served-Cells-List		CRITICALITY reject	TYPE GNB-DU-Served-Cells-List			PRESENCE optional	}|
+	{ ID id-GNB-DU-RRC-Version				CRITICALITY reject	TYPE RRC-Version						PRESENCE mandatory	}|
+	{ ID id-Transport-Layer-Address-Info	CRITICALITY ignore	TYPE Transport-Layer-Address-Info		PRESENCE optional	}|
+	{ ID id-BAPAddress						CRITICALITY ignore	TYPE BAPAddress							PRESENCE optional	}|
+	{ ID id-Extended-GNB-CU-Name			CRITICALITY ignore	TYPE Extended-GNB-CU-Name				PRESENCE optional	},
+	...
+} 
+
+
+GNB-DU-Served-Cells-List 	::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { GNB-DU-Served-Cells-ItemIEs } }
+
+GNB-DU-Served-Cells-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-GNB-DU-Served-Cells-Item		CRITICALITY reject	TYPE		GNB-DU-Served-Cells-Item	PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- F1 Setup Response
+--
+-- **************************************************************
+
+F1SetupResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {F1SetupResponseIEs} },
+	...
+}
+
+
+F1SetupResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-gNB-CU-Name						CRITICALITY ignore	TYPE GNB-CU-Name						PRESENCE optional	}|
+	{ ID id-Cells-to-be-Activated-List		CRITICALITY reject	TYPE Cells-to-be-Activated-List			PRESENCE optional	}|
+	{ ID id-GNB-CU-RRC-Version				CRITICALITY reject	TYPE RRC-Version						PRESENCE mandatory	}|
+	{ ID id-Transport-Layer-Address-Info	CRITICALITY ignore	TYPE Transport-Layer-Address-Info		PRESENCE optional	}|
+	{ ID id-UL-BH-Non-UP-Traffic-Mapping	CRITICALITY reject	TYPE UL-BH-Non-UP-Traffic-Mapping		PRESENCE optional	}|
+	{ ID id-BAPAddress						CRITICALITY ignore	TYPE BAPAddress							PRESENCE optional	}|
+	{ ID id-Extended-GNB-DU-Name			CRITICALITY ignore	TYPE Extended-GNB-DU-Name				PRESENCE optional	},
+	...
+}
+
+
+Cells-to-be-Activated-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-to-be-Activated-List-ItemIEs } }
+
+Cells-to-be-Activated-List-ItemIEs	F1AP-PROTOCOL-IES::= {
+	{ ID id-Cells-to-be-Activated-List-Item				CRITICALITY reject	TYPE Cells-to-be-Activated-List-Item						PRESENCE mandatory},
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- F1 Setup Failure
+--
+-- **************************************************************
+
+F1SetupFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {F1SetupFailureIEs} },
+	...
+}
+
+F1SetupFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE
+--
+-- **************************************************************
+
+GNBDUConfigurationUpdate::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUConfigurationUpdateIEs} },
+	...
+}
+
+GNBDUConfigurationUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID												PRESENCE mandatory	}|
+	{ ID id-Served-Cells-To-Add-List				CRITICALITY reject	TYPE Served-Cells-To-Add-List								PRESENCE optional	}|
+	{ ID id-Served-Cells-To-Modify-List				CRITICALITY reject	TYPE Served-Cells-To-Modify-List							PRESENCE optional	}|
+	{ ID id-Served-Cells-To-Delete-List				CRITICALITY reject	TYPE Served-Cells-To-Delete-List							PRESENCE optional	}|
+	{ ID id-Cells-Status-List						CRITICALITY reject	TYPE Cells-Status-List											PRESENCE optional	}|
+	{ ID id-Dedicated-SIDelivery-NeededUE-List		CRITICALITY ignore	TYPE Dedicated-SIDelivery-NeededUE-List					PRESENCE optional	}|
+	{ ID id-gNB-DU-ID								CRITICALITY reject	TYPE GNB-DU-ID													PRESENCE optional	}|
+	{ ID id-GNB-DU-TNL-Association-To-Remove-List	CRITICALITY reject	TYPE GNB-DU-TNL-Association-To-Remove-List				PRESENCE optional	}|
+	{ ID id-Transport-Layer-Address-Info			CRITICALITY ignore	TYPE Transport-Layer-Address-Info							PRESENCE optional	},
+	...
+} 
+
+Served-Cells-To-Add-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Served-Cells-To-Add-ItemIEs } }
+Served-Cells-To-Modify-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Served-Cells-To-Modify-ItemIEs } }
+Served-Cells-To-Delete-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Served-Cells-To-Delete-ItemIEs } }
+Cells-Status-List	::= SEQUENCE (SIZE(0.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-Status-ItemIEs } }
+
+Dedicated-SIDelivery-NeededUE-List::= SEQUENCE (SIZE(1.. maxnoofUEIDs))	OF ProtocolIE-SingleContainer { { Dedicated-SIDelivery-NeededUE-ItemIEs } }
+
+GNB-DU-TNL-Association-To-Remove-List	::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-DU-TNL-Association-To-Remove-ItemIEs } }
+
+
+Served-Cells-To-Add-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Served-Cells-To-Add-Item		CRITICALITY reject	TYPE	Served-Cells-To-Add-Item				PRESENCE mandatory	},
+	...
+}
+
+Served-Cells-To-Modify-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Served-Cells-To-Modify-Item			CRITICALITY reject	TYPE		Served-Cells-To-Modify-Item							PRESENCE mandatory	},
+	...
+}
+
+Served-Cells-To-Delete-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Served-Cells-To-Delete-Item				CRITICALITY reject	TYPE		Served-Cells-To-Delete-Item					PRESENCE mandatory	},
+	...
+}
+
+Cells-Status-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-Status-Item				CRITICALITY reject	TYPE		Cells-Status-Item					PRESENCE mandatory	},
+	...
+}
+
+Dedicated-SIDelivery-NeededUE-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Dedicated-SIDelivery-NeededUE-Item		CRITICALITY ignore	TYPE	Dedicated-SIDelivery-NeededUE-Item				PRESENCE mandatory	},
+	...
+} 
+
+GNB-DU-TNL-Association-To-Remove-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-DU-TNL-Association-To-Remove-Item		CRITICALITY reject	TYPE	 GNB-DU-TNL-Association-To-Remove-Item			PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE ACKNOWLEDGE
+--
+-- **************************************************************
+
+GNBDUConfigurationUpdateAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUConfigurationUpdateAcknowledgeIEs} },
+	...
+}
+
+
+GNBDUConfigurationUpdateAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID								PRESENCE mandatory	}|
+	{ ID id-Cells-to-be-Activated-List			CRITICALITY reject	TYPE Cells-to-be-Activated-List				PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics				CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional	}|
+	{ ID id-Cells-to-be-Deactivated-List		CRITICALITY reject	TYPE Cells-to-be-Deactivated-List			PRESENCE optional	}|
+	{ ID id-Transport-Layer-Address-Info		CRITICALITY ignore	TYPE Transport-Layer-Address-Info			PRESENCE optional	}|
+	{ ID id-UL-BH-Non-UP-Traffic-Mapping		CRITICALITY reject	TYPE UL-BH-Non-UP-Traffic-Mapping			PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE FAILURE
+--
+-- **************************************************************
+
+GNBDUConfigurationUpdateFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUConfigurationUpdateFailureIEs} },
+	...
+}
+
+GNBDUConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE
+--
+-- **************************************************************
+
+GNBCUConfigurationUpdate ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { GNBCUConfigurationUpdateIEs} },
+	...
+}
+
+GNBCUConfigurationUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID												PRESENCE mandatory	}|
+	{ ID id-Cells-to-be-Activated-List				CRITICALITY reject	TYPE	 Cells-to-be-Activated-List						PRESENCE optional	}|
+	{ ID id-Cells-to-be-Deactivated-List			CRITICALITY reject	TYPE	 Cells-to-be-Deactivated-List						PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-To-Add-List		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Add-List				PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-To-Remove-List	CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Remove-List			PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-To-Update-List	CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Update-List			PRESENCE optional	}|
+	{ ID id-Cells-to-be-Barred-List					CRITICALITY ignore	TYPE	 Cells-to-be-Barred-List							PRESENCE optional	}|
+	{ ID id-Protected-EUTRA-Resources-List			CRITICALITY reject	TYPE	 Protected-EUTRA-Resources-List					PRESENCE optional	}|
+	{ ID id-Neighbour-Cell-Information-List			CRITICALITY ignore	TYPE	 Neighbour-Cell-Information-List					PRESENCE optional	}|
+	{ ID id-Transport-Layer-Address-Info			CRITICALITY ignore	TYPE	 Transport-Layer-Address-Info						PRESENCE optional	}|
+	{ ID id-UL-BH-Non-UP-Traffic-Mapping			CRITICALITY reject	TYPE	 UL-BH-Non-UP-Traffic-Mapping						PRESENCE optional	},
+	...
+} 
+
+Cells-to-be-Deactivated-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-to-be-Deactivated-List-ItemIEs } }
+GNB-CU-TNL-Association-To-Add-List		::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-To-Add-ItemIEs } }
+GNB-CU-TNL-Association-To-Remove-List	::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-To-Remove-ItemIEs } }
+GNB-CU-TNL-Association-To-Update-List	::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-To-Update-ItemIEs } }
+Cells-to-be-Barred-List			::= SEQUENCE(SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-to-be-Barred-ItemIEs } }
+
+
+Cells-to-be-Deactivated-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-to-be-Deactivated-List-Item						CRITICALITY reject	TYPE	Cells-to-be-Deactivated-List-Item					PRESENCE mandatory	},
+	...
+}
+
+
+GNB-CU-TNL-Association-To-Add-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-To-Add-Item		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Add-Item			PRESENCE mandatory	},
+	...
+}
+
+GNB-CU-TNL-Association-To-Remove-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-To-Remove-Item		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Remove-Item			PRESENCE mandatory	},
+	...
+}
+
+GNB-CU-TNL-Association-To-Update-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-To-Update-Item		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Update-Item			PRESENCE mandatory	},
+	...
+}
+
+Cells-to-be-Barred-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-to-be-Barred-Item		CRITICALITY ignore	TYPE	 Cells-to-be-Barred-Item				PRESENCE mandatory	},
+	...
+}
+
+Protected-EUTRA-Resources-List ::= SEQUENCE (SIZE(1.. maxCellineNB))	OF ProtocolIE-SingleContainer { { Protected-EUTRA-Resources-ItemIEs } }
+Protected-EUTRA-Resources-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Protected-EUTRA-Resources-Item 					CRITICALITY reject 	TYPE Protected-EUTRA-Resources-Item							PRESENCE mandatory},
+	...
+}
+
+Neighbour-Cell-Information-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Neighbour-Cell-Information-ItemIEs } }
+Neighbour-Cell-Information-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Neighbour-Cell-Information-Item 					CRITICALITY ignore 	TYPE Neighbour-Cell-Information-Item							PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE ACKNOWLEDGE
+--
+-- **************************************************************
+
+GNBCUConfigurationUpdateAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { GNBCUConfigurationUpdateAcknowledgeIEs} },
+	...
+}
+
+
+GNBCUConfigurationUpdateAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID								CRITICALITY reject	TYPE TransactionID											PRESENCE mandatory	}|
+	{ ID id-Cells-Failed-to-be-Activated-List			CRITICALITY reject	TYPE Cells-Failed-to-be-Activated-List				PRESENCE optional}|
+	{ ID id-CriticalityDiagnostics							CRITICALITY ignore	TYPE CriticalityDiagnostics								PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-Setup-List			CRITICALITY ignore	TYPE GNB-CU-TNL-Association-Setup-List				PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-Failed-To-Setup-List	CRITICALITY ignore	TYPE GNB-CU-TNL-Association-Failed-To-Setup-List	PRESENCE optional	}|
+	{ ID id-Dedicated-SIDelivery-NeededUE-List				CRITICALITY ignore	TYPE Dedicated-SIDelivery-NeededUE-List				PRESENCE optional	}|
+	{ ID id-Transport-Layer-Address-Info				CRITICALITY ignore	TYPE Transport-Layer-Address-Info						PRESENCE optional	},
+	...
+}
+
+Cells-Failed-to-be-Activated-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-Failed-to-be-Activated-List-ItemIEs } }
+GNB-CU-TNL-Association-Setup-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-Setup-ItemIEs } }
+GNB-CU-TNL-Association-Failed-To-Setup-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-Failed-To-Setup-ItemIEs } }
+
+Cells-Failed-to-be-Activated-List-ItemIEs F1AP-PROTOCOL-IES		::= {
+	{ ID id-Cells-Failed-to-be-Activated-List-Item		CRITICALITY reject	TYPE Cells-Failed-to-be-Activated-List-Item		PRESENCE mandatory	},
+	...
+}
+
+GNB-CU-TNL-Association-Setup-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-Setup-Item		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-Setup-Item			PRESENCE mandatory	},
+	...
+}
+
+
+GNB-CU-TNL-Association-Failed-To-Setup-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-Failed-To-Setup-Item		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-Failed-To-Setup-Item			PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE FAILURE
+--
+-- **************************************************************
+
+GNBCUConfigurationUpdateFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { GNBCUConfigurationUpdateFailureIEs} },
+	...
+}
+
+GNBCUConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU RESOURCE COORDINATION REQUEST 
+--
+-- **************************************************************
+
+GNBDUResourceCoordinationRequest ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{{GNBDUResourceCoordinationRequest-IEs}},
+	...
+}
+
+GNBDUResourceCoordinationRequest-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID									CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory	}|
+	{ ID id-RequestType										CRITICALITY reject	TYPE RequestType										PRESENCE mandatory	}|
+	{ ID id-EUTRA-NR-CellResourceCoordinationReq-Container	CRITICALITY reject	TYPE EUTRA-NR-CellResourceCoordinationReq-Container	PRESENCE mandatory}|
+	{ ID id-IgnoreResourceCoordinationContainer				CRITICALITY reject	TYPE IgnoreResourceCoordinationContainer		PRESENCE optional },
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU RESOURCE COORDINATION RESPONSE 
+--
+-- **************************************************************
+
+GNBDUResourceCoordinationResponse ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{{GNBDUResourceCoordinationResponse-IEs}},
+	...
+}
+
+GNBDUResourceCoordinationResponse-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID										CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-EUTRA-NR-CellResourceCoordinationReqAck-Container	CRITICALITY reject	TYPE EUTRA-NR-CellResourceCoordinationReqAck-Container		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Context Setup ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT SETUP REQUEST
+--
+-- **************************************************************
+
+UEContextSetupRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextSetupRequestIEs} },
+	...
+}
+
+UEContextSetupRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID									PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID									PRESENCE optional 	}|
+	{ ID id-SpCell-ID								CRITICALITY reject	TYPE NRCGI												PRESENCE mandatory	}|
+	{ ID id-ServCellIndex							CRITICALITY reject	TYPE ServCellIndex										PRESENCE mandatory	}|
+	{ ID id-SpCellULConfigured						CRITICALITY ignore	TYPE CellULConfigured									PRESENCE optional	}|
+	{ ID id-CUtoDURRCInformation					CRITICALITY reject	TYPE CUtoDURRCInformation								PRESENCE mandatory}|
+	{ ID id-Candidate-SpCell-List					CRITICALITY ignore	TYPE Candidate-SpCell-List							PRESENCE optional	}|
+	{ ID id-DRXCycle								CRITICALITY ignore	TYPE DRXCycle											PRESENCE optional	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer		PRESENCE optional	}|
+	{ ID id-SCell-ToBeSetup-List					CRITICALITY ignore	TYPE SCell-ToBeSetup-List								PRESENCE optional	}|
+	{ ID id-SRBs-ToBeSetup-List						CRITICALITY reject	TYPE SRBs-ToBeSetup-List								PRESENCE optional	}|
+	{ ID id-DRBs-ToBeSetup-List						CRITICALITY reject	TYPE DRBs-ToBeSetup-List								PRESENCE optional	}|
+	{ ID id-InactivityMonitoringRequest				CRITICALITY reject	TYPE InactivityMonitoringRequest					PRESENCE optional	}|
+	{ ID id-RAT-FrequencyPriorityInformation		CRITICALITY reject	TYPE RAT-FrequencyPriorityInformation				PRESENCE optional	}|
+	{ ID id-RRCContainer							CRITICALITY ignore	TYPE RRCContainer										PRESENCE optional	}|
+	{ ID id-MaskedIMEISV							CRITICALITY ignore	TYPE MaskedIMEISV										PRESENCE optional	}|
+	{ ID id-ServingPLMN								CRITICALITY ignore	TYPE PLMN-Identity										PRESENCE optional	}|
+	{ ID id-GNB-DU-UE-AMBR-UL						CRITICALITY ignore	TYPE BitRate											PRESENCE conditional }|
+	{ ID id-RRCDeliveryStatusRequest				CRITICALITY ignore	TYPE RRCDeliveryStatusRequest						PRESENCE optional }|
+	{ ID id-ResourceCoordinationTransferInformation	CRITICALITY ignore	TYPE ResourceCoordinationTransferInformation	PRESENCE optional	}|
+	{ ID id-ServingCellMO							CRITICALITY ignore	TYPE ServingCellMO										PRESENCE optional	}|
+	{ ID id-new-gNB-CU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID									PRESENCE optional }|
+	{ ID id-RANUEID									CRITICALITY ignore	TYPE RANUEID											PRESENCE optional	}|
+	{ ID id-TraceActivation							CRITICALITY ignore	TYPE TraceActivation									PRESENCE optional	}|
+	{ ID id-AdditionalRRMPriorityIndex				CRITICALITY ignore	TYPE AdditionalRRMPriorityIndex						PRESENCE optional }|
+	{ ID id-BHChannels-ToBeSetup-List				CRITICALITY reject	TYPE BHChannels-ToBeSetup-List						PRESENCE optional	}|
+	{ ID id-ConfiguredBAPAddress					CRITICALITY reject	TYPE BAPAddress											PRESENCE optional	}|
+	{ ID id-NRV2XServicesAuthorized					CRITICALITY ignore	TYPE NRV2XServicesAuthorized							PRESENCE optional }|
+	{ ID id-LTEV2XServicesAuthorized				CRITICALITY ignore	TYPE LTEV2XServicesAuthorized						PRESENCE optional }|
+	{ ID id-NRUESidelinkAggregateMaximumBitrate		CRITICALITY ignore	TYPE NRUESidelinkAggregateMaximumBitrate			PRESENCE optional }|
+	{ ID id-LTEUESidelinkAggregateMaximumBitrate	CRITICALITY ignore	TYPE LTEUESidelinkAggregateMaximumBitrate		PRESENCE optional }|
+	{ ID id-PC5LinkAMBR								CRITICALITY ignore	TYPE BitRate											PRESENCE optional}|
+	{ ID id-SLDRBs-ToBeSetup-List					CRITICALITY reject	TYPE SLDRBs-ToBeSetup-List							PRESENCE optional	}|
+	{ ID id-ConditionalInterDUMobilityInformation	CRITICALITY reject	TYPE ConditionalInterDUMobilityInformation		PRESENCE optional}|
+	{ ID id-ManagementBasedMDTPLMNList				CRITICALITY ignore	TYPE 		MDTPLMNList									PRESENCE optional }|
+	{ ID id-ServingNID								CRITICALITY reject	TYPE NID												PRESENCE optional },
+	...
+} 
+
+Candidate-SpCell-List::= SEQUENCE (SIZE(1..maxnoofCandidateSpCells)) OF ProtocolIE-SingleContainer { { Candidate-SpCell-ItemIEs} }
+SCell-ToBeSetup-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeSetup-ItemIEs} }
+SRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeSetup-ItemIEs} }
+DRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeSetup-ItemIEs} }
+BHChannels-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-ToBeSetup-ItemIEs} }
+SLDRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-ToBeSetup-ItemIEs} }
+
+Candidate-SpCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-Candidate-SpCell-Item					CRITICALITY ignore	TYPE Candidate-SpCell-Item						PRESENCE mandatory	},
+	...
+}
+
+
+SCell-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-ToBeSetup-Item						CRITICALITY ignore	TYPE SCell-ToBeSetup-Item					PRESENCE mandatory	},
+	...
+}
+
+SRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-ToBeSetup-Item		CRITICALITY reject		TYPE SRBs-ToBeSetup-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeSetup-Item					CRITICALITY reject	TYPE DRBs-ToBeSetup-Item					PRESENCE mandatory},
+	...
+}
+
+BHChannels-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-ToBeSetup-Item					CRITICALITY reject	TYPE BHChannels-ToBeSetup-Item					PRESENCE mandatory},
+	...
+}
+
+SLDRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-ToBeSetup-Item					CRITICALITY reject	TYPE SLDRBs-ToBeSetup-Item					PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT SETUP RESPONSE
+--
+-- **************************************************************
+
+UEContextSetupResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextSetupResponseIEs} },
+	...
+}
+
+
+UEContextSetupResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-DUtoCURRCInformation					CRITICALITY reject	TYPE DUtoCURRCInformation							PRESENCE mandatory }|
+	{ ID id-C-RNTI									CRITICALITY ignore	TYPE C-RNTI											PRESENCE optional	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer	PRESENCE optional	}|
+	{ ID id-FullConfiguration						CRITICALITY reject	TYPE FullConfiguration								PRESENCE optional	}|
+	{ ID id-DRBs-Setup-List							CRITICALITY ignore	TYPE DRBs-Setup-List								PRESENCE optional	}|
+	{ ID id-SRBs-FailedToBeSetup-List				CRITICALITY ignore	TYPE SRBs-FailedToBeSetup-List					PRESENCE optional	}|
+	{ ID id-DRBs-FailedToBeSetup-List				CRITICALITY ignore	TYPE DRBs-FailedToBeSetup-List					PRESENCE optional	}|
+	{ ID id-SCell-FailedtoSetup-List				CRITICALITY ignore	TYPE SCell-FailedtoSetup-List					PRESENCE optional	}|
+	{ ID id-InactivityMonitoringResponse			CRITICALITY reject	TYPE InactivityMonitoringResponse				PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics					CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional	}|
+	{ ID id-SRBs-Setup-List							CRITICALITY ignore	TYPE SRBs-Setup-List								PRESENCE optional	}|
+	{ ID id-BHChannels-Setup-List					CRITICALITY ignore	TYPE BHChannels-Setup-List						PRESENCE optional	}|
+	{ ID id-BHChannels-FailedToBeSetup-List			CRITICALITY ignore	TYPE BHChannels-FailedToBeSetup-List			PRESENCE optional	}|
+	{ ID id-SLDRBs-Setup-List						CRITICALITY ignore	TYPE SLDRBs-Setup-List								PRESENCE optional	}|
+	{ ID id-SLDRBs-FailedToBeSetup-List				CRITICALITY ignore	TYPE SLDRBs-FailedToBeSetup-List				PRESENCE optional	}|
+	{ ID id-requestedTargetCellGlobalID				CRITICALITY reject	TYPE NRCGI											PRESENCE optional},
+	...
+}
+
+DRBs-Setup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Setup-ItemIEs} }
+
+
+SRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-FailedToBeSetup-ItemIEs} }
+DRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeSetup-ItemIEs} }
+SCell-FailedtoSetup-List ::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-FailedtoSetup-ItemIEs} }
+SRBs-Setup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-Setup-ItemIEs} }
+BHChannels-Setup-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-Setup-ItemIEs} }
+BHChannels-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-FailedToBeSetup-ItemIEs} }
+
+DRBs-Setup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Setup-Item						CRITICALITY ignore	TYPE DRBs-Setup-Item						PRESENCE mandatory},
+	...
+}
+
+SRBs-Setup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-Setup-Item						CRITICALITY ignore	TYPE SRBs-Setup-Item						PRESENCE mandatory},
+	...
+}
+
+SRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-FailedToBeSetup-Item		CRITICALITY ignore		TYPE SRBs-FailedToBeSetup-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeSetup-Item		CRITICALITY ignore	TYPE DRBs-FailedToBeSetup-Item			PRESENCE mandatory},
+	...
+}
+
+SCell-FailedtoSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-FailedtoSetup-Item			CRITICALITY ignore	TYPE SCell-FailedtoSetup-Item			PRESENCE mandatory},
+	...
+}
+
+BHChannels-Setup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-Setup-Item						CRITICALITY ignore	TYPE BHChannels-Setup-Item						PRESENCE mandatory},
+	...
+}
+
+BHChannels-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-FailedToBeSetup-Item						CRITICALITY ignore	TYPE BHChannels-FailedToBeSetup-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-Setup-List ::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-Setup-ItemIEs} }
+
+SLDRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-FailedToBeSetup-ItemIEs} }
+
+SLDRBs-Setup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-Setup-Item						CRITICALITY ignore	TYPE SLDRBs-Setup-Item						PRESENCE mandatory},
+	...
+}
+
+SLDRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-FailedToBeSetup-Item		CRITICALITY ignore	TYPE SLDRBs-FailedToBeSetup-Item			PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT SETUP FAILURE
+--
+-- **************************************************************
+
+UEContextSetupFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextSetupFailureIEs} },
+	...
+}
+
+UEContextSetupFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID			PRESENCE optional	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	}|
+	{ ID id-Potential-SpCell-List		CRITICALITY ignore	TYPE Potential-SpCell-List		PRESENCE optional	}|
+	{ ID id-requestedTargetCellGlobalID	CRITICALITY reject	TYPE NRCGI						PRESENCE optional},
+	...
+}
+
+Potential-SpCell-List::= SEQUENCE (SIZE(0..maxnoofPotentialSpCells)) OF ProtocolIE-SingleContainer { { Potential-SpCell-ItemIEs} }
+
+Potential-SpCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-Potential-SpCell-Item				CRITICALITY ignore	TYPE Potential-SpCell-Item					PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Context Release Request ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE Context Release Request
+--
+-- **************************************************************
+
+UEContextReleaseRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ UEContextReleaseRequestIEs}},
+	...
+}
+
+UEContextReleaseRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-targetCellsToCancel				CRITICALITY reject	TYPE TargetCellList					PRESENCE optional		},
+	...
+}
+
+
+-- **************************************************************
+--
+-- UE Context Release (gNB-CU initiated) ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT RELEASE COMMAND 
+--
+-- **************************************************************
+
+UEContextReleaseCommand ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextReleaseCommandIEs} },
+	...
+}
+
+UEContextReleaseCommandIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-RRCContainer					CRITICALITY ignore	TYPE RRCContainer					PRESENCE optional	}|
+	{ ID id-SRBID							CRITICALITY ignore	TYPE SRBID							PRESENCE conditional	}|
+	{ ID id-oldgNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID				PRESENCE optional	}|
+	{ ID id-ExecuteDuplication				CRITICALITY ignore	TYPE ExecuteDuplication				PRESENCE optional}|
+	{ ID id-RRCDeliveryStatusRequest		CRITICALITY ignore	TYPE RRCDeliveryStatusRequest		PRESENCE optional }|
+	{ ID id-targetCellsToCancel				CRITICALITY reject	TYPE TargetCellList					PRESENCE optional},
+	...
+} 
+
+-- **************************************************************
+--
+-- UE CONTEXT RELEASE COMPLETE
+--
+-- **************************************************************
+
+UEContextReleaseComplete ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextReleaseCompleteIEs} },
+	...
+}
+
+
+UEContextReleaseCompleteIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Context Modification ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION REQUEST
+--
+-- **************************************************************
+
+UEContextModificationRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationRequestIEs} },
+	...
+}
+
+UEContextModificationRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID									PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID									PRESENCE mandatory	}|
+	{ ID id-SpCell-ID								CRITICALITY ignore	TYPE NRCGI												PRESENCE optional	}|
+	{ ID id-ServCellIndex							CRITICALITY reject	TYPE ServCellIndex										PRESENCE optional	}|
+	{ ID id-SpCellULConfigured						CRITICALITY ignore	TYPE CellULConfigured									PRESENCE optional	}|
+	{ ID id-DRXCycle								CRITICALITY ignore	TYPE DRXCycle											PRESENCE optional	}|
+	{ ID id-CUtoDURRCInformation					CRITICALITY reject	TYPE CUtoDURRCInformation								PRESENCE optional	}|
+	{ ID id-TransmissionActionIndicator				CRITICALITY ignore	TYPE TransmissionActionIndicator					PRESENCE optional	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer		PRESENCE optional	}|
+	{ ID id-RRCReconfigurationCompleteIndicator		CRITICALITY ignore	TYPE RRCReconfigurationCompleteIndicator			PRESENCE optional	}|
+	{ ID id-RRCContainer							CRITICALITY reject	TYPE RRCContainer										PRESENCE optional	}|
+	{ ID id-SCell-ToBeSetupMod-List					CRITICALITY ignore	TYPE SCell-ToBeSetupMod-List							PRESENCE optional	}|
+	{ ID id-SCell-ToBeRemoved-List					CRITICALITY ignore	TYPE SCell-ToBeRemoved-List 							PRESENCE optional }|
+	{ ID id-SRBs-ToBeSetupMod-List					CRITICALITY reject	TYPE SRBs-ToBeSetupMod-List							PRESENCE optional	}|
+	{ ID id-DRBs-ToBeSetupMod-List					CRITICALITY reject	TYPE DRBs-ToBeSetupMod-List							PRESENCE optional	}|
+	{ ID id-DRBs-ToBeModified-List					CRITICALITY reject	TYPE DRBs-ToBeModified-List							PRESENCE optional	}|
+	{ ID id-SRBs-ToBeReleased-List					CRITICALITY reject	TYPE SRBs-ToBeReleased-List							PRESENCE optional	}|
+	{ ID id-DRBs-ToBeReleased-List					CRITICALITY reject	TYPE DRBs-ToBeReleased-List							PRESENCE optional	}|
+	{ ID id-InactivityMonitoringRequest				CRITICALITY reject	TYPE InactivityMonitoringRequest					PRESENCE optional	}|
+	{ ID id-RAT-FrequencyPriorityInformation		CRITICALITY reject	TYPE RAT-FrequencyPriorityInformation				PRESENCE optional	}|
+	{ ID id-DRXConfigurationIndicator				CRITICALITY ignore	TYPE DRXConfigurationIndicator						PRESENCE optional	}|
+	{ ID id-RLCFailureIndication					CRITICALITY ignore	TYPE RLCFailureIndication								PRESENCE optional	}|
+	{ ID id-UplinkTxDirectCurrentListInformation	CRITICALITY ignore	TYPE UplinkTxDirectCurrentListInformation		PRESENCE optional	}|
+	{ ID id-GNB-DUConfigurationQuery				CRITICALITY reject	TYPE GNB-DUConfigurationQuery						PRESENCE optional	}|
+	{ ID id-GNB-DU-UE-AMBR-UL						CRITICALITY ignore	TYPE BitRate											PRESENCE optional	}|
+	{ ID id-ExecuteDuplication						CRITICALITY ignore	TYPE ExecuteDuplication									PRESENCE optional}|
+	{ ID id-RRCDeliveryStatusRequest				CRITICALITY ignore	TYPE RRCDeliveryStatusRequest						PRESENCE optional }|
+	{ ID id-ResourceCoordinationTransferInformation	CRITICALITY ignore	TYPE ResourceCoordinationTransferInformation	PRESENCE optional	}|
+	{ ID id-ServingCellMO							CRITICALITY ignore	TYPE ServingCellMO										PRESENCE optional	}|
+	{ ID id-NeedforGap								CRITICALITY ignore	TYPE NeedforGap											PRESENCE optional	}|
+	{ ID id-FullConfiguration						CRITICALITY reject	TYPE FullConfiguration									PRESENCE optional	}|
+	{ ID id-AdditionalRRMPriorityIndex				CRITICALITY ignore	TYPE AdditionalRRMPriorityIndex						PRESENCE optional }|
+	{ ID id-LowerLayerPresenceStatusChange			CRITICALITY ignore	TYPE LowerLayerPresenceStatusChange				PRESENCE optional	}|
+	{ ID id-BHChannels-ToBeSetupMod-List			CRITICALITY reject	TYPE BHChannels-ToBeSetupMod-List					PRESENCE optional	}|
+	{ ID id-BHChannels-ToBeModified-List			CRITICALITY reject	TYPE BHChannels-ToBeModified-List					PRESENCE optional	}|
+	{ ID id-BHChannels-ToBeReleased-List			CRITICALITY reject	TYPE BHChannels-ToBeReleased-List					PRESENCE optional	}|
+	{ ID id-NRV2XServicesAuthorized					CRITICALITY ignore	TYPE NRV2XServicesAuthorized							PRESENCE optional }|
+	{ ID id-LTEV2XServicesAuthorized				CRITICALITY ignore	TYPE LTEV2XServicesAuthorized						PRESENCE optional }|
+	{ ID id-NRUESidelinkAggregateMaximumBitrate		CRITICALITY ignore	TYPE NRUESidelinkAggregateMaximumBitrate			PRESENCE optional }|
+	{ ID id-LTEUESidelinkAggregateMaximumBitrate	CRITICALITY ignore	TYPE LTEUESidelinkAggregateMaximumBitrate		PRESENCE optional }|
+	{ ID id-PC5LinkAMBR								CRITICALITY ignore	TYPE BitRate											PRESENCE optional}|
+	{ ID id-SLDRBs-ToBeSetupMod-List				CRITICALITY reject	TYPE SLDRBs-ToBeSetupMod-List						PRESENCE optional	}|
+	{ ID id-SLDRBs-ToBeModified-List				CRITICALITY reject	TYPE SLDRBs-ToBeModified-List						PRESENCE optional	}|
+	{ ID id-SLDRBs-ToBeReleased-List				CRITICALITY reject	TYPE SLDRBs-ToBeReleased-List						PRESENCE optional	}|
+	{ ID id-ConditionalIntraDUMobilityInformation	CRITICALITY reject	TYPE ConditionalIntraDUMobilityInformation		PRESENCE optional},
+	...
+} 
+
+SCell-ToBeSetupMod-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeSetupMod-ItemIEs} }
+SCell-ToBeRemoved-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeRemoved-ItemIEs} }
+SRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeSetupMod-ItemIEs} }
+DRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeSetupMod-ItemIEs} }
+BHChannels-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-ToBeSetupMod-ItemIEs} }
+
+DRBs-ToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeModified-ItemIEs} }
+BHChannels-ToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-ToBeModified-ItemIEs} }
+SRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeReleased-ItemIEs} }
+DRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeReleased-ItemIEs} }
+BHChannels-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-ToBeReleased-ItemIEs} }
+
+SCell-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-ToBeSetupMod-Item			CRITICALITY ignore	TYPE SCell-ToBeSetupMod-Item			PRESENCE mandatory	},
+	...
+}
+
+SCell-ToBeRemoved-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-ToBeRemoved-Item			CRITICALITY ignore	TYPE SCell-ToBeRemoved-Item			PRESENCE mandatory	},
+	...
+}
+
+
+SRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-ToBeSetupMod-Item		CRITICALITY reject	TYPE SRBs-ToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeSetupMod-Item		CRITICALITY reject	TYPE DRBs-ToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeModified-Item		CRITICALITY reject	TYPE DRBs-ToBeModified-Item			PRESENCE mandatory},
+	...
+}
+
+
+SRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-ToBeReleased-Item	CRITICALITY reject	TYPE SRBs-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeReleased-Item		CRITICALITY reject	TYPE DRBs-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+BHChannels-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-ToBeSetupMod-Item		CRITICALITY reject	TYPE BHChannels-ToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+BHChannels-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-ToBeModified-Item		CRITICALITY reject	TYPE BHChannels-ToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+BHChannels-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-ToBeReleased-Item		CRITICALITY reject	TYPE BHChannels-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-ToBeSetupMod-ItemIEs} }
+SLDRBs-ToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-ToBeModified-ItemIEs} }
+SLDRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-ToBeReleased-ItemIEs} }
+
+SLDRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-ToBeSetupMod-Item		CRITICALITY reject	TYPE SLDRBs-ToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-ToBeModified-Item		CRITICALITY reject	TYPE SLDRBs-ToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-ToBeReleased-Item		CRITICALITY reject	TYPE SLDRBs-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION RESPONSE
+--
+-- **************************************************************
+
+UEContextModificationResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationResponseIEs} },
+	...
+}
+
+
+UEContextModificationResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer	PRESENCE optional	}|
+	{ ID id-DUtoCURRCInformation					CRITICALITY reject	TYPE DUtoCURRCInformation							PRESENCE optional}|
+	{ ID id-DRBs-SetupMod-List						CRITICALITY ignore	TYPE DRBs-SetupMod-List								PRESENCE optional}|
+	{ ID id-DRBs-Modified-List						CRITICALITY ignore	TYPE DRBs-Modified-List								PRESENCE optional}|
+	{ ID id-SRBs-FailedToBeSetupMod-List			CRITICALITY ignore	TYPE SRBs-FailedToBeSetupMod-List				PRESENCE optional	}|
+	{ ID id-DRBs-FailedToBeSetupMod-List			CRITICALITY ignore	TYPE DRBs-FailedToBeSetupMod-List				PRESENCE optional	}|
+	{ ID id-SCell-FailedtoSetupMod-List				CRITICALITY ignore	TYPE SCell-FailedtoSetupMod-List				PRESENCE optional	}|
+	{ ID id-DRBs-FailedToBeModified-List			CRITICALITY ignore	TYPE DRBs-FailedToBeModified-List				PRESENCE optional	}|
+	{ ID id-InactivityMonitoringResponse			CRITICALITY reject	TYPE InactivityMonitoringResponse				PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics					CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional	}|
+	{ ID id-C-RNTI									CRITICALITY ignore	TYPE C-RNTI											PRESENCE optional	}|
+	{ ID id-Associated-SCell-List					CRITICALITY ignore  TYPE Associated-SCell-List						PRESENCE optional	}|
+	{ ID id-SRBs-SetupMod-List						CRITICALITY ignore	TYPE SRBs-SetupMod-List								PRESENCE optional	}|
+	{ ID id-SRBs-Modified-List						CRITICALITY ignore	TYPE SRBs-Modified-List								PRESENCE optional	}|
+	{ ID id-FullConfiguration						CRITICALITY reject	TYPE FullConfiguration								PRESENCE optional	}|
+	{ ID id-BHChannels-SetupMod-List				CRITICALITY ignore	TYPE BHChannels-SetupMod-List					PRESENCE optional}|
+	{ ID id-BHChannels-Modified-List				CRITICALITY ignore	TYPE BHChannels-Modified-List					PRESENCE optional}|
+	{ ID id-BHChannels-FailedToBeSetupMod-List		CRITICALITY ignore	TYPE BHChannels-FailedToBeSetupMod-List		PRESENCE optional	}|
+	{ ID id-BHChannels-FailedToBeModified-List		CRITICALITY ignore	TYPE BHChannels-FailedToBeModified-List		PRESENCE optional	}|
+	{ ID id-SLDRBs-SetupMod-List					CRITICALITY ignore	TYPE SLDRBs-SetupMod-List							PRESENCE optional	}|
+	{ ID id-SLDRBs-Modified-List					CRITICALITY ignore	TYPE SLDRBs-Modified-List							PRESENCE optional	}|
+	{ ID id-SLDRBs-FailedToBeSetupMod-List			CRITICALITY ignore	TYPE SLDRBs-FailedToBeSetupMod-List			PRESENCE optional	}|
+	{ ID id-SLDRBs-FailedToBeModified-List			CRITICALITY ignore	TYPE SLDRBs-FailedToBeModified-List			PRESENCE optional	}|
+	{ ID id-requestedTargetCellGlobalID				CRITICALITY reject	TYPE NRCGI											PRESENCE optional},
+	...
+}
+
+
+DRBs-SetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-SetupMod-ItemIEs} }
+DRBs-Modified-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Modified-ItemIEs } } 
+SRBs-SetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-SetupMod-ItemIEs} }
+SRBs-Modified-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-Modified-ItemIEs } }
+DRBs-FailedToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeModified-ItemIEs} }
+SRBs-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-FailedToBeSetupMod-ItemIEs} }
+DRBs-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeSetupMod-ItemIEs} }
+SCell-FailedtoSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-FailedtoSetupMod-ItemIEs} }
+BHChannels-SetupMod-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-SetupMod-ItemIEs} }
+BHChannels-Modified-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-Modified-ItemIEs } } 
+BHChannels-FailedToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-FailedToBeModified-ItemIEs} }
+BHChannels-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-FailedToBeSetupMod-ItemIEs} }
+
+Associated-SCell-List ::= SEQUENCE (SIZE(1.. maxnoofSCells)) OF ProtocolIE-SingleContainer { { Associated-SCell-ItemIEs} }
+
+DRBs-SetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-SetupMod-Item		CRITICALITY ignore		TYPE DRBs-SetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-Modified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Modified-Item			CRITICALITY ignore	TYPE DRBs-Modified-Item		PRESENCE mandatory},
+	...
+}
+
+SRBs-SetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-SetupMod-Item		CRITICALITY ignore		TYPE SRBs-SetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+SRBs-Modified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-Modified-Item			CRITICALITY ignore	TYPE SRBs-Modified-Item		PRESENCE mandatory},
+	...
+}
+
+SRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-FailedToBeSetupMod-Item		CRITICALITY ignore	TYPE SRBs-FailedToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeSetupMod-Item		CRITICALITY ignore	TYPE DRBs-FailedToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-FailedToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeModified-Item		CRITICALITY ignore	TYPE DRBs-FailedToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+SCell-FailedtoSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-FailedtoSetupMod-Item			CRITICALITY ignore	TYPE SCell-FailedtoSetupMod-Item			PRESENCE mandatory},
+	...
+}
+
+Associated-SCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-Associated-SCell-Item			CRITICALITY ignore	TYPE Associated-SCell-Item			PRESENCE mandatory},
+	...
+}
+
+BHChannels-SetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-SetupMod-Item		CRITICALITY ignore		TYPE BHChannels-SetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+BHChannels-Modified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-Modified-Item		CRITICALITY ignore	TYPE BHChannels-Modified-Item		PRESENCE mandatory},
+	...
+}
+
+BHChannels-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-FailedToBeSetupMod-Item		CRITICALITY ignore	TYPE BHChannels-FailedToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+BHChannels-FailedToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-FailedToBeModified-Item		CRITICALITY ignore	TYPE BHChannels-FailedToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-SetupMod-List 			::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-SetupMod-ItemIEs} }
+SLDRBs-Modified-List				::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-Modified-ItemIEs } } 
+SLDRBs-FailedToBeModified-List 	::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-FailedToBeModified-ItemIEs} }
+SLDRBs-FailedToBeSetupMod-List 	::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-FailedToBeSetupMod-ItemIEs} }
+
+SLDRBs-SetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-SetupMod-Item		CRITICALITY ignore		TYPE SLDRBs-SetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-Modified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-Modified-Item			CRITICALITY ignore	TYPE SLDRBs-Modified-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-FailedToBeSetupMod-Item		CRITICALITY ignore	TYPE SLDRBs-FailedToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-FailedToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-FailedToBeModified-Item		CRITICALITY ignore	TYPE SLDRBs-FailedToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION FAILURE
+--
+-- **************************************************************
+
+UEContextModificationFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationFailureIEs} },
+	...
+}
+
+UEContextModificationFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	}|
+	{ ID id-requestedTargetCellGlobalID		CRITICALITY reject	TYPE NRCGI							PRESENCE optional},
+	...
+}
+
+
+-- **************************************************************
+--
+-- UE Context Modification Required (gNB-DU initiated) ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION REQUIRED
+--
+-- **************************************************************
+
+UEContextModificationRequired ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationRequiredIEs} },
+	...
+}
+
+UEContextModificationRequiredIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-ResourceCoordinationTransferContainer		CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer		PRESENCE optional	}|
+	{ ID id-DUtoCURRCInformation						CRITICALITY reject	TYPE DUtoCURRCInformation							PRESENCE optional}|
+	{ ID id-DRBs-Required-ToBeModified-List				CRITICALITY reject	TYPE DRBs-Required-ToBeModified-List				PRESENCE optional}|
+	{ ID id-SRBs-Required-ToBeReleased-List				CRITICALITY reject	TYPE SRBs-Required-ToBeReleased-List				PRESENCE optional}|
+	{ ID id-DRBs-Required-ToBeReleased-List				CRITICALITY reject	TYPE DRBs-Required-ToBeReleased-List				PRESENCE optional}|
+	{ ID id-Cause										CRITICALITY ignore	TYPE Cause												PRESENCE mandatory	}|
+	{ ID id-BHChannels-Required-ToBeReleased-List		CRITICALITY reject	TYPE BHChannels-Required-ToBeReleased-List		PRESENCE optional}|
+	{ ID id-SLDRBs-Required-ToBeModified-List			CRITICALITY reject	TYPE SLDRBs-Required-ToBeModified-List			PRESENCE optional}|
+	{ ID id-SLDRBs-Required-ToBeReleased-List			CRITICALITY reject	TYPE SLDRBs-Required-ToBeReleased-List			PRESENCE optional}|
+	{ ID id-targetCellsToCancel							CRITICALITY reject	TYPE TargetCellList										PRESENCE optional},
+	...
+} 
+
+DRBs-Required-ToBeModified-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Required-ToBeModified-ItemIEs } }
+DRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Required-ToBeReleased-ItemIEs } }
+
+SRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-Required-ToBeReleased-ItemIEs } }
+
+BHChannels-Required-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-Required-ToBeReleased-ItemIEs } }
+
+DRBs-Required-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Required-ToBeModified-Item			CRITICALITY reject	TYPE DRBs-Required-ToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Required-ToBeReleased-Item			CRITICALITY reject	TYPE DRBs-Required-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+SRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-Required-ToBeReleased-Item			CRITICALITY reject	TYPE SRBs-Required-ToBeReleased-Item			PRESENCE mandatory},
+	...
+}
+
+BHChannels-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-Required-ToBeReleased-Item			CRITICALITY reject	TYPE BHChannels-Required-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-Required-ToBeModified-List::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-Required-ToBeModified-ItemIEs } }
+SLDRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-Required-ToBeReleased-ItemIEs } }
+
+SLDRBs-Required-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-Required-ToBeModified-Item			CRITICALITY reject	TYPE SLDRBs-Required-ToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-Required-ToBeReleased-Item			CRITICALITY reject	TYPE SLDRBs-Required-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION CONFIRM
+--
+-- **************************************************************
+
+UEContextModificationConfirm::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationConfirmIEs} },
+	...
+}
+
+
+UEContextModificationConfirmIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-ResourceCoordinationTransferContainer		CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer		PRESENCE optional	}|
+	{ ID id-DRBs-ModifiedConf-List						CRITICALITY ignore	TYPE DRBs-ModifiedConf-List							PRESENCE optional}|
+	{ ID id-RRCContainer								CRITICALITY ignore	TYPE RRCContainer										PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics						CRITICALITY ignore	TYPE CriticalityDiagnostics							PRESENCE optional	}|
+	{ ID id-ExecuteDuplication							CRITICALITY ignore	TYPE ExecuteDuplication								PRESENCE optional}|
+	{ ID id-ResourceCoordinationTransferInformation		CRITICALITY ignore	TYPE ResourceCoordinationTransferInformation	PRESENCE optional	}|
+	{ ID id-SLDRBs-ModifiedConf-List					CRITICALITY ignore	TYPE SLDRBs-ModifiedConf-List						PRESENCE optional},
+	...
+}
+
+DRBs-ModifiedConf-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ModifiedConf-ItemIEs } }
+
+DRBs-ModifiedConf-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ModifiedConf-Item		CRITICALITY ignore	TYPE DRBs-ModifiedConf-Item			PRESENCE mandatory},
+	...
+}
+
+SLDRBs-ModifiedConf-List::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-ModifiedConf-ItemIEs } }
+
+SLDRBs-ModifiedConf-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-ModifiedConf-Item		CRITICALITY ignore	TYPE SLDRBs-ModifiedConf-Item			PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION REFUSE
+--
+-- **************************************************************
+
+UEContextModificationRefuse::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationRefuseIEs} },
+	...
+}
+
+
+UEContextModificationRefuseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+	...
+}
+
+
+-- ************************************************************** 
+-- 
+-- WRITE-REPLACE WARNING ELEMENTARY PROCEDURE 
+-- 
+-- ************************************************************** 
+
+-- ************************************************************** 
+-- 
+-- Write-Replace Warning Request 
+-- 
+-- ************************************************************** 
+
+WriteReplaceWarningRequest ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { {WriteReplaceWarningRequestIEs} }, 
+	... 
+} 
+
+WriteReplaceWarningRequestIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID								PRESENCE mandatory	}|
+	{ ID id-PWSSystemInformation 				CRITICALITY reject	TYPE PWSSystemInformation 						PRESENCE mandatory }| 
+	{ ID id-RepetitionPeriod 					CRITICALITY reject	TYPE RepetitionPeriod 							PRESENCE mandatory }| 
+	{ ID id-NumberofBroadcastRequest 			CRITICALITY reject	TYPE NumberofBroadcastRequest 				PRESENCE mandatory }| 
+	{ ID id-Cells-To-Be-Broadcast-List			CRITICALITY reject	TYPE Cells-To-Be-Broadcast-List				PRESENCE optional	},
+	... 
+}
+
+Cells-To-Be-Broadcast-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-To-Be-Broadcast-List-ItemIEs } }
+
+Cells-To-Be-Broadcast-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-To-Be-Broadcast-Item		CRITICALITY reject	TYPE	Cells-To-Be-Broadcast-Item		PRESENCE mandatory	},
+	...
+}
+
+-- ************************************************************** 
+-- 
+-- Write-Replace Warning Response 
+-- 
+-- ************************************************************** 
+
+WriteReplaceWarningResponse ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { {WriteReplaceWarningResponseIEs} }, 
+	... 
+} 
+
+WriteReplaceWarningResponseIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID										PRESENCE mandatory	}|
+	{ ID id-Cells-Broadcast-Completed-List			CRITICALITY reject	TYPE Cells-Broadcast-Completed-List				PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics					CRITICALITY ignore	TYPE CriticalityDiagnostics							PRESENCE optional	}|
+	{ ID id-Dedicated-SIDelivery-NeededUE-List		CRITICALITY ignore	TYPE Dedicated-SIDelivery-NeededUE-List			PRESENCE optional	},
+	...
+}
+
+Cells-Broadcast-Completed-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-Broadcast-Completed-List-ItemIEs } }
+
+Cells-Broadcast-Completed-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-Broadcast-Completed-Item		CRITICALITY reject	TYPE	Cells-Broadcast-Completed-Item		PRESENCE mandatory	},
+	...
+}
+
+
+-- ************************************************************** 
+-- 
+-- PWS CANCEL ELEMENTARY PROCEDURE 
+-- 
+-- ************************************************************** 
+
+-- ************************************************************** 
+-- 
+-- PWS Cancel Request 
+-- 
+-- ************************************************************** 
+
+PWSCancelRequest ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { {PWSCancelRequestIEs} }, 
+	... 
+} 
+
+PWSCancelRequestIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID							CRITICALITY reject TYPE TransactionID									PRESENCE mandatory	}|
+	{ ID id-NumberofBroadcastRequest 				CRITICALITY reject TYPE NumberofBroadcastRequest						PRESENCE mandatory }| 
+	{ ID id-Broadcast-To-Be-Cancelled-List			CRITICALITY reject TYPE Broadcast-To-Be-Cancelled-List				PRESENCE optional	}|
+	{ ID id-Cancel-all-Warning-Messages-Indicator	CRITICALITY reject TYPE Cancel-all-Warning-Messages-Indicator	PRESENCE optional	}|
+	{ ID id-NotificationInformation					CRITICALITY reject TYPE NotificationInformation						PRESENCE optional},
+	... 
+}
+
+Broadcast-To-Be-Cancelled-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Broadcast-To-Be-Cancelled-List-ItemIEs } }
+
+Broadcast-To-Be-Cancelled-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Broadcast-To-Be-Cancelled-Item		CRITICALITY reject	TYPE	Broadcast-To-Be-Cancelled-Item		PRESENCE mandatory	},
+	...
+}
+
+-- ************************************************************** 
+-- 
+-- PWS Cancel Response 
+-- 
+-- ************************************************************** 
+
+PWSCancelResponse ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { {PWSCancelResponseIEs} }, 
+	... 
+} 
+
+PWSCancelResponseIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-Cells-Broadcast-Cancelled-List	CRITICALITY reject	TYPE Cells-Broadcast-Cancelled-List	PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics				PRESENCE optional	},
+	... 
+}
+
+Cells-Broadcast-Cancelled-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-Broadcast-Cancelled-List-ItemIEs } }
+
+Cells-Broadcast-Cancelled-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-Broadcast-Cancelled-Item		CRITICALITY reject	TYPE	Cells-Broadcast-Cancelled-Item		PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Inactivity Notification ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE Inactivity Notification
+--
+-- **************************************************************
+
+UEInactivityNotification ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ UEInactivityNotificationIEs}},
+	...
+}
+
+UEInactivityNotificationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-DRB-Activity-List							CRITICALITY reject	TYPE DRB-Activity-List							PRESENCE mandatory	}	,
+	...
+}
+
+DRB-Activity-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRB-Activity-ItemIEs } }
+
+DRB-Activity-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRB-Activity-Item			CRITICALITY reject	TYPE DRB-Activity-Item		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- Initial UL RRC Message Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- INITIAL UL RRC Message Transfer
+--
+-- **************************************************************
+
+InitialULRRCMessageTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ InitialULRRCMessageTransferIEs}},
+	...
+}
+
+InitialULRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-DU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID						PRESENCE mandatory	}|
+	{ ID id-NRCGI								CRITICALITY reject	TYPE NRCGI									PRESENCE mandatory	}|
+	{ ID id-C-RNTI								CRITICALITY reject	TYPE C-RNTI									PRESENCE mandatory	}|
+	{ ID id-RRCContainer						CRITICALITY reject	TYPE RRCContainer							PRESENCE mandatory	}|
+	{ ID id-DUtoCURRCContainer					CRITICALITY reject	TYPE DUtoCURRCContainer						PRESENCE optional	}|
+	{ ID id-SULAccessIndication					CRITICALITY ignore	TYPE SULAccessIndication					PRESENCE optional	}|
+	{ ID id-TransactionID						CRITICALITY ignore	TYPE TransactionID							PRESENCE mandatory	}|
+	{ ID id-RANUEID								CRITICALITY ignore	TYPE RANUEID								PRESENCE optional	}|
+	{ ID id-RRCContainer-RRCSetupComplete		CRITICALITY ignore	TYPE RRCContainer-RRCSetupComplete 		PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- DL RRC Message Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- DL RRC Message Transfer
+--
+-- **************************************************************
+
+DLRRCMessageTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ DLRRCMessageTransferIEs}},
+	...
+}
+
+DLRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-oldgNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID							PRESENCE optional	}|
+	{ ID id-SRBID										CRITICALITY reject	TYPE SRBID											PRESENCE mandatory	}|
+	{ ID id-ExecuteDuplication							CRITICALITY ignore	TYPE ExecuteDuplication							PRESENCE optional}|
+	{ ID id-RRCContainer								CRITICALITY reject	TYPE RRCContainer									PRESENCE mandatory	}|
+	{ ID id-RAT-FrequencyPriorityInformation			CRITICALITY reject	TYPE RAT-FrequencyPriorityInformation		PRESENCE optional	}|
+	{ ID id-RRCDeliveryStatusRequest					CRITICALITY ignore	TYPE RRCDeliveryStatusRequest					PRESENCE optional }|
+	{ ID id-UEContextNotRetrievable						CRITICALITY reject	TYPE UEContextNotRetrievable					PRESENCE optional }|
+	{ ID id-RedirectedRRCmessage						CRITICALITY reject	TYPE OCTET STRING									PRESENCE optional }|
+	{ ID id-PLMNAssistanceInfoForNetShar				CRITICALITY ignore	TYPE PLMN-Identity									PRESENCE optional }|
+	{ ID id-new-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID							PRESENCE optional }|
+	{ ID id-AdditionalRRMPriorityIndex					CRITICALITY ignore	TYPE AdditionalRRMPriorityIndex				PRESENCE optional },
+	...
+}
+-- **************************************************************
+--
+-- UL RRC Message Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UL RRC Message Transfer
+--
+-- **************************************************************
+
+ULRRCMessageTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ ULRRCMessageTransferIEs}},
+	...
+}
+
+ULRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-SRBID							CRITICALITY reject	TYPE SRBID							PRESENCE mandatory	}|
+	{ ID id-RRCContainer					CRITICALITY reject	TYPE RRCContainer					PRESENCE mandatory	}|
+	{ ID id-SelectedPLMNID					CRITICALITY reject	TYPE PLMN-Identity					PRESENCE optional		}|
+	{ ID id-new-gNB-DU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE optional		},
+	...
+}
+
+-- **************************************************************
+--
+-- PRIVATE MESSAGE
+--
+-- **************************************************************
+
+PrivateMessage ::= SEQUENCE {
+	privateIEs		PrivateIE-Container	{{PrivateMessage-IEs}},
+	...
+}
+
+PrivateMessage-IEs F1AP-PRIVATE-IES ::= {
+	...
+}
+
+
+-- **************************************************************
+--
+-- System Information ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- System information Delivery Command
+--
+-- **************************************************************
+
+SystemInformationDeliveryCommand ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ SystemInformationDeliveryCommandIEs}},
+	...
+}
+
+SystemInformationDeliveryCommandIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID			CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-NRCGI					CRITICALITY reject	TYPE NRCGI							PRESENCE mandatory	}|
+	{ ID id-SItype-List				CRITICALITY reject	TYPE SItype-List					PRESENCE mandatory	}|
+	{ ID id-ConfirmedUEID 			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Paging PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Paging
+--
+-- **************************************************************
+
+Paging ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ PagingIEs}},
+	...
+}
+
+PagingIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-UEIdentityIndexValue	CRITICALITY reject	TYPE UEIdentityIndexValue		PRESENCE mandatory	}|
+	{ ID id-PagingIdentity			CRITICALITY reject	TYPE PagingIdentity				PRESENCE mandatory	}|
+	{ ID id-PagingDRX				CRITICALITY ignore	TYPE PagingDRX					PRESENCE optional	}|
+	{ ID id-PagingPriority			CRITICALITY ignore	TYPE PagingPriority				PRESENCE optional	}|
+	{ ID id-PagingCell-List			CRITICALITY ignore	TYPE PagingCell-list			PRESENCE mandatory	}|
+	{ ID id-PagingOrigin			CRITICALITY ignore	TYPE PagingOrigin				PRESENCE optional	},
+	...
+}
+
+PagingCell-list::= SEQUENCE (SIZE(1.. maxnoofPagingCells)) OF ProtocolIE-SingleContainer { { PagingCell-ItemIEs } }
+
+PagingCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-PagingCell-Item		CRITICALITY ignore	TYPE PagingCell-Item			PRESENCE mandatory}	,
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- Notify
+--
+-- **************************************************************
+
+Notify ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ NotifyIEs}},
+	...
+}
+
+NotifyIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID						PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID						PRESENCE mandatory	}|
+	{ ID id-DRB-Notify-List						CRITICALITY reject	TYPE DRB-Notify-List						PRESENCE mandatory	},
+	...
+}
+
+DRB-Notify-List::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRB-Notify-ItemIEs } }
+
+DRB-Notify-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRB-Notify-Item			CRITICALITY reject	TYPE DRB-Notify-Item		PRESENCE mandatory},
+	...
+}
+
+
+-- **************************************************************
+--
+-- NETWORK ACCESS RATE REDUCTION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Network Access Rate Reduction
+--
+-- **************************************************************
+
+NetworkAccessRateReduction ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ NetworkAccessRateReductionIEs }},
+	...
+}
+
+NetworkAccessRateReductionIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID 					CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-UAC-Assistance-Info				CRITICALITY reject	TYPE UAC-Assistance-Info			PRESENCE mandatory	},
+	...
+}
+
+-- ************************************************************** 
+-- 
+-- PWS RESTART INDICATION ELEMENTARY PROCEDURE 
+-- 
+-- ************************************************************** 
+
+-- ************************************************************** 
+-- 
+-- PWS Restart Indication 
+-- 
+-- ************************************************************** 
+
+PWSRestartIndication ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { { PWSRestartIndicationIEs} }, 
+	... 
+} 
+
+PWSRestartIndicationIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-NR-CGI-List-For-Restart-List	CRITICALITY reject	TYPE NR-CGI-List-For-Restart-List	PRESENCE mandatory	},
+	... 
+}
+
+NR-CGI-List-For-Restart-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { NR-CGI-List-For-Restart-List-ItemIEs } }
+
+NR-CGI-List-For-Restart-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-NR-CGI-List-For-Restart-Item		CRITICALITY reject	TYPE	NR-CGI-List-For-Restart-Item		PRESENCE mandatory	},
+	...
+}
+
+-- ************************************************************** 
+-- 
+-- PWS FAILURE INDICATION ELEMENTARY PROCEDURE 
+-- 
+-- ************************************************************** 
+
+-- ************************************************************** 
+-- 
+-- PWS Failure Indication 
+-- 
+-- ************************************************************** 
+
+PWSFailureIndication ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { { PWSFailureIndicationIEs} }, 
+	... 
+} 
+
+PWSFailureIndicationIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID			CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-PWS-Failed-NR-CGI-List	CRITICALITY reject	TYPE PWS-Failed-NR-CGI-List		PRESENCE optional	},
+	... 
+}
+
+PWS-Failed-NR-CGI-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { PWS-Failed-NR-CGI-List-ItemIEs } }
+
+PWS-Failed-NR-CGI-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-PWS-Failed-NR-CGI-Item		CRITICALITY reject	TYPE	PWS-Failed-NR-CGI-Item		PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- gNB-DU STATUS INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- gNB-DU Status Indication
+--
+-- **************************************************************
+
+GNBDUStatusIndication ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUStatusIndicationIEs} },
+	...
+}
+
+GNBDUStatusIndicationIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-GNBDUOverloadInformation		CRITICALITY reject	TYPE GNBDUOverloadInformation		PRESENCE mandatory	},
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- RRC Delivery Report ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- RRC Delivery Report
+--
+-- **************************************************************
+
+RRCDeliveryReport ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ RRCDeliveryReportIEs}},
+	...
+}
+
+RRCDeliveryReportIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID	CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID	PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID	CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID	PRESENCE mandatory	}|
+	{ ID id-RRCDeliveryStatus	CRITICALITY ignore	TYPE RRCDeliveryStatus	PRESENCE mandatory	}|
+	{ ID id-SRBID				CRITICALITY ignore	TYPE SRBID				PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- F1 Removal ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- F1 Removal Request
+--
+-- **************************************************************
+
+F1RemovalRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ F1RemovalRequestIEs }},
+	...
+}
+
+F1RemovalRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID			CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- F1 Removal Response
+--
+-- **************************************************************
+
+F1RemovalResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ F1RemovalResponseIEs }},
+	...
+}
+
+F1RemovalResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+
+	...
+}
+
+-- **************************************************************
+--
+-- F1 Removal Failure
+--
+-- **************************************************************
+
+F1RemovalFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ F1RemovalFailureIEs }},
+	...
+}
+
+F1RemovalFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+
+	...
+}
+
+
+-- **************************************************************
+--
+-- TRACE ELEMENTARY PROCEDURES
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- TRACE START
+--
+-- **************************************************************
+
+TraceStart ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ {TraceStartIEs} },
+	...
+}
+
+TraceStartIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-TraceActivation				CRITICALITY ignore	TYPE TraceActivation				PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- DEACTIVATE TRACE
+--
+-- **************************************************************
+
+DeactivateTrace ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ {DeactivateTraceIEs} },
+	...
+}
+
+DeactivateTraceIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-TraceID						CRITICALITY ignore	TYPE TraceID						PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- CELL TRAFFIC TRACE
+--
+-- **************************************************************
+
+CellTrafficTrace ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ {CellTrafficTraceIEs} },
+	...
+}
+
+CellTrafficTraceIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ID id-TraceID							CRITICALITY ignore	TYPE TraceID						PRESENCE mandatory	}|
+	{ID id-TraceCollectionEntityIPAddress	CRITICALITY ignore	TYPE TransportLayerAddress			PRESENCE mandatory	}|
+	{ID id-PrivacyIndicator					CRITICALITY ignore	TYPE PrivacyIndicator				PRESENCE optional	}|
+
+	{ID id-TraceCollectionEntityURI	CRITICALITY ignore	TYPE URI-address		PRESENCE optional	},
+	...
+
+}
+
+-- **************************************************************
+--
+-- DU-CU Radio Information Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- DU-CU Radio Information Transfer
+--
+-- **************************************************************
+
+DUCURadioInformationTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ DUCURadioInformationTransferIEs}},
+	...
+}
+
+DUCURadioInformationTransferIEs F1AP-PROTOCOL-IES ::= {
+		{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-DUCURadioInformationType		CRITICALITY ignore	TYPE DUCURadioInformationType				PRESENCE mandatory	},
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- CU-DU Radio Information Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- CU-DU Radio Information Transfer
+--
+-- **************************************************************
+
+CUDURadioInformationTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ CUDURadioInformationTransferIEs}},
+	...
+}
+
+CUDURadioInformationTransferIEs F1AP-PROTOCOL-IES ::= {
+		{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-CUDURadioInformationType	CRITICALITY ignore	TYPE CUDURadioInformationType				PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- IAB PROCEDURES 
+--
+-- **************************************************************
+-- **************************************************************
+--
+-- BAP Mapping Configuration ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- BAP MAPPING CONFIGURATION
+-- **************************************************************
+
+
+BAPMappingConfiguration ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container	{ {BAPMappingConfiguration-IEs} },
+	...
+ }
+
+BAPMappingConfiguration-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID		CRITICALITY reject	TYPE	TransactionID	PRESENCE mandatory}|
+	{ ID id-BH-Routing-Information-Added-List		CRITICALITY ignore	TYPE	BH-Routing-Information-Added-List	PRESENCE optional}|
+	{ ID id-BH-Routing-Information-Removed-List		CRITICALITY ignore	TYPE	BH-Routing-Information-Removed-List	PRESENCE optional}|
+	{ ID id-TrafficMappingInformation				CRITICALITY ignore	TYPE	TrafficMappingInfo						PRESENCE optional},
+	...
+}
+
+BH-Routing-Information-Added-List ::= SEQUENCE (SIZE(1.. maxnoofRoutingEntries))	OF ProtocolIE-SingleContainer { { BH-Routing-Information-Added-List-ItemIEs } }
+BH-Routing-Information-Removed-List ::= SEQUENCE (SIZE(1.. maxnoofRoutingEntries))	OF ProtocolIE-SingleContainer { { BH-Routing-Information-Removed-List-ItemIEs } }
+
+BH-Routing-Information-Added-List-ItemIEs	F1AP-PROTOCOL-IES ::= {
+	{ ID id-BH-Routing-Information-Added-List-Item				CRITICALITY ignore	TYPE BH-Routing-Information-Added-List-Item						PRESENCE optional},
+	...
+}
+
+BH-Routing-Information-Removed-List-ItemIEs	F1AP-PROTOCOL-IES ::= {
+	{ ID id-BH-Routing-Information-Removed-List-Item				CRITICALITY ignore	TYPE BH-Routing-Information-Removed-List-Item						PRESENCE optional},
+	...
+}
+
+
+-- **************************************************************
+--
+-- BAP MAPPING CONFIGURATION ACKNOWLEDGE
+-- **************************************************************
+
+BAPMappingConfigurationAcknowledge ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ {BAPMappingConfigurationAcknowledge-IEs} },
+	... 
+}
+
+BAPMappingConfigurationAcknowledge-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID			CRITICALITY reject	TYPE	TransactionID			PRESENCE mandatory}|
+	{ ID id-CriticalityDiagnostics	CRITICALITY ignore	TYPE	CriticalityDiagnostics	PRESENCE optional},
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- GNB-DU Configuration ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- GNB-DU RESOURCE CONFIGURATION
+-- **************************************************************
+
+
+GNBDUResourceConfiguration ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{{ GNBDUResourceConfigurationIEs}},
+	...
+}
+
+
+GNBDUResourceConfigurationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID								PRESENCE mandatory	}|
+	{ ID id-Activated-Cells-to-be-Updated-List		CRITICALITY reject	TYPE Activated-Cells-to-be-Updated-List	PRESENCE optional}|
+	{ ID id-Child-Nodes-List						CRITICALITY reject	TYPE Child-Nodes-List							PRESENCE optional},
+	...
+} 
+
+
+
+
+-- **************************************************************
+--
+-- GNB-DU RESOURCE CONFIGURATION ACKNOWLEDGE
+-- **************************************************************
+
+
+GNBDUResourceConfigurationAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{ { GNBDUResourceConfigurationAcknowledgeIEs} },
+	...
+}
+
+
+GNBDUResourceConfigurationAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics				CRITICALITY ignore	TYPE CriticalityDiagnostics					PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- IAB TNL Address Allocation ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- IAB TNL ADDRESS REQUEST
+-- **************************************************************
+
+
+
+IABTNLAddressRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{ {IABTNLAddressRequestIEs} },
+	...
+}
+
+IABTNLAddressRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID								PRESENCE mandatory	}|
+	{ ID id-IABv4AddressesRequested				CRITICALITY reject	TYPE IABv4AddressesRequested					PRESENCE optional	}|
+	{ ID id-IABIPv6RequestType					CRITICALITY reject	TYPE IABIPv6RequestType							PRESENCE optional	}|
+	{ ID id-IAB-TNL-Addresses-To-Remove-List	CRITICALITY reject	TYPE IAB-TNL-Addresses-To-Remove-List		PRESENCE optional	},
+	...
+}
+
+
+IAB-TNL-Addresses-To-Remove-List	::= SEQUENCE (SIZE(1..maxnoofTLAsIAB))	OF ProtocolIE-SingleContainer { { IAB-TNL-Addresses-To-Remove-ItemIEs } }
+
+IAB-TNL-Addresses-To-Remove-ItemIEs	F1AP-PROTOCOL-IES::= {
+	{ ID id-IAB-TNL-Addresses-To-Remove-Item			CRITICALITY reject	TYPE IAB-TNL-Addresses-To-Remove-Item					PRESENCE mandatory},
+	...
+}
+
+
+-- **************************************************************
+--
+-- IAB TNL ADDRESS RESPONSE
+-- **************************************************************
+
+
+IABTNLAddressResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{ {IABTNLAddressResponseIEs} },
+	...
+}
+
+
+IABTNLAddressResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID								CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory	}|
+	{ ID id-IAB-Allocated-TNL-Address-List				CRITICALITY reject	TYPE IAB-Allocated-TNL-Address-List			PRESENCE mandatory	},
+	...
+}
+
+
+IAB-Allocated-TNL-Address-List ::= SEQUENCE (SIZE(1.. maxnoofTLAsIAB))	OF ProtocolIE-SingleContainer { { IAB-Allocated-TNL-Address-List-ItemIEs } }
+
+
+IAB-Allocated-TNL-Address-List-ItemIEs	F1AP-PROTOCOL-IES::= {
+	{ ID id-IAB-Allocated-TNL-Address-Item			CRITICALITY reject	TYPE IAB-Allocated-TNL-Address-Item					PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- IAB UP Configuration Update ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- IAB UP Configuration Update Request
+--
+-- **************************************************************
+
+IABUPConfigurationUpdateRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{ { IABUPConfigurationUpdateRequestIEs} },
+	...
+}
+
+IABUPConfigurationUpdateRequestIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID										PRESENCE mandatory  }|
+	{ ID id-UL-UP-TNL-Information-to-Update-List	CRITICALITY ignore	TYPE UL-UP-TNL-Information-to-Update-List		PRESENCE optional	}|
+	{ ID id-UL-UP-TNL-Address-to-Update-List		CRITICALITY ignore	TYPE UL-UP-TNL-Address-to-Update-List				PRESENCE optional	},
+	...
+}
+
+UL-UP-TNL-Information-to-Update-List ::= SEQUENCE (SIZE(1.. maxnoofULUPTNLInformationforIAB))	OF ProtocolIE-SingleContainer { { UL-UP-TNL-Information-to-Update-List-ItemIEs } }
+
+UL-UP-TNL-Information-to-Update-List-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-UL-UP-TNL-Information-to-Update-List-Item	CRITICALITY ignore	TYPE UL-UP-TNL-Information-to-Update-List-Item PRESENCE optional},
+	...
+}
+
+UL-UP-TNL-Address-to-Update-List ::= SEQUENCE (SIZE(1.. maxnoofUPTNLAddresses))	OF ProtocolIE-SingleContainer { { UL-UP-TNL-Address-to-Update-List-ItemIEs } }
+
+UL-UP-TNL-Address-to-Update-List-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-UL-UP-TNL-Address-to-Update-List-Item	CRITICALITY ignore	TYPE UL-UP-TNL-Address-to-Update-List-Item PRESENCE optional},
+	...
+}
+
+
+-- **************************************************************
+--
+-- IAB UP Configuration Update Response
+--
+-- **************************************************************
+
+IABUPConfigurationUpdateResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{ { IABUPConfigurationUpdateResponseIEs} },
+	...
+}
+
+IABUPConfigurationUpdateResponseIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics				CRITICALITY ignore	TYPE CriticalityDiagnostics					PRESENCE optional	}|
+	{ ID id-DL-UP-TNL-Address-to-Update-List	CRITICALITY reject	TYPE DL-UP-TNL-Address-to-Update-List	PRESENCE optional	},
+	...
+}
+
+DL-UP-TNL-Address-to-Update-List ::= SEQUENCE (SIZE(1.. maxnoofUPTNLAddresses))	OF ProtocolIE-SingleContainer { { DL-UP-TNL-Address-to-Update-List-ItemIEs } }
+
+DL-UP-TNL-Address-to-Update-List-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DL-UP-TNL-Address-to-Update-List-Item	CRITICALITY ignore	TYPE DL-UP-TNL-Address-to-Update-List-Item	PRESENCE optional},
+	...
+}
+
+-- **************************************************************
+--
+-- IAB UP Configuration Update Failure
+--
+-- **************************************************************
+
+IABUPConfigurationUpdateFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{ { IABUPConfigurationUpdateFailureIEs} },
+	...
+}
+
+IABUPConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- Resource Status Reporting Initiation ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Resource Status Request
+--
+-- **************************************************************
+
+ResourceStatusRequest::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {ResourceStatusRequestIEs} },
+	...
+}
+
+ResourceStatusRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID			CRITICALITY reject	TYPE TransactionID			PRESENCE mandatory	}|
+	{ ID id-gNBCUMeasurementID		CRITICALITY reject	TYPE GNBCUMeasurementID		PRESENCE mandatory	}|
+	{ ID id-gNBDUMeasurementID		CRITICALITY ignore	TYPE GNBDUMeasurementID		PRESENCE conditional	}|
+	{ ID id-RegistrationRequest		CRITICALITY ignore	TYPE RegistrationRequest	PRESENCE mandatory	}|
+	{ ID id-ReportCharacteristics	CRITICALITY ignore	TYPE ReportCharacteristics	PRESENCE conditional	}|
+	{ ID id-CellToReportList		CRITICALITY ignore	TYPE CellToReportList		PRESENCE optional	}|
+	{ ID id-ReportingPeriodicity	CRITICALITY ignore	TYPE ReportingPeriodicity	PRESENCE  optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Resource Status Response
+--
+-- **************************************************************
+
+ResourceStatusResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { ResourceStatusResponseIEs} },
+	...
+}
+
+
+ResourceStatusResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID			CRITICALITY reject	TYPE TransactionID			PRESENCE mandatory	}|
+	{ ID id-gNBCUMeasurementID		CRITICALITY reject	TYPE GNBCUMeasurementID		PRESENCE mandatory	}|
+	{ ID id-gNBDUMeasurementID		CRITICALITY ignore	TYPE GNBDUMeasurementID		PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics	CRITICALITY ignore	TYPE CriticalityDiagnostics	PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Resource Status Failure
+--
+-- **************************************************************
+
+ResourceStatusFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { ResourceStatusFailureIEs} },
+	...
+}
+
+ResourceStatusFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID			CRITICALITY reject	TYPE TransactionID			PRESENCE mandatory	}|
+	{ ID id-gNBCUMeasurementID		CRITICALITY reject	TYPE GNBCUMeasurementID		PRESENCE mandatory	}|
+	{ ID id-gNBDUMeasurementID		CRITICALITY ignore	TYPE GNBDUMeasurementID		PRESENCE mandatory	}|
+	{ ID id-Cause					CRITICALITY ignore	TYPE Cause					PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics	CRITICALITY ignore	TYPE CriticalityDiagnostics	PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- Resource Status Reporting ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Resource Status Update 
+--
+-- **************************************************************
+
+ResourceStatusUpdate ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ ResourceStatusUpdateIEs}},
+	...
+}
+
+ResourceStatusUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID			PRESENCE mandatory	}|
+	{ ID id-gNBCUMeasurementID			CRITICALITY reject	TYPE GNBCUMeasurementID				PRESENCE mandatory	}|
+	{ ID id-gNBDUMeasurementID			CRITICALITY ignore	TYPE GNBDUMeasurementID			PRESENCE mandatory	}|
+	{ ID id-HardwareLoadIndicator			CRITICALITY ignore	TYPE HardwareLoadIndicator			PRESENCE optional	}|
+	{ ID id-TNLCapacityIndicator			CRITICALITY ignore	TYPE TNLCapacityIndicator		PRESENCE optional	}|
+	{ ID id-CellMeasurementResultList		CRITICALITY ignore	TYPE CellMeasurementResultList	PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+--  Access And Mobility Indication ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Access And Mobility Indication 
+--
+-- **************************************************************
+
+AccessAndMobilityIndication ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { AccessAndMobilityIndicationIEs} },
+	...
+}
+
+AccessAndMobilityIndicationIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory }|
+	{ ID id-RACHReportInformationList				CRITICALITY ignore	TYPE RACHReportInformationList			PRESENCE optional }|
+	{ ID id-RLFReportInformationList				CRITICALITY ignore	TYPE RLFReportInformationList				PRESENCE optional },
+	...
+}
+
+
+-- **************************************************************
+--
+-- REFERENCE TIME INFORMATION REPORTING CONTROL
+--
+-- **************************************************************
+
+ReferenceTimeInformationReportingControl::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { ReferenceTimeInformationReportingControlIEs} },
+	...
+}
+
+ReferenceTimeInformationReportingControlIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-ReportingRequestType		CRITICALITY reject	TYPE ReportingRequestType		PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- REFERENCE TIME INFORMATION REPORT
+--
+-- **************************************************************
+
+ReferenceTimeInformationReport::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { ReferenceTimeInformationReportIEs} },
+	...
+}
+
+ReferenceTimeInformationReportIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY ignore	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-TimeReferenceInformation	CRITICALITY ignore	TYPE TimeReferenceInformation		PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Access Success
+--
+-- **************************************************************
+
+AccessSuccess ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ AccessSuccessIEs}},
+	...
+}
+
+AccessSuccessIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID						PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID						PRESENCE mandatory	}|
+	{ ID id-NRCGI								CRITICALITY reject	TYPE NRCGI									PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- POSITIONING ASSISTANCE INFORMATION CONTROL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Assistance Information Control
+--
+-- **************************************************************
+
+PositioningAssistanceInformationControl ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ PositioningAssistanceInformationControlIEs}},
+	...
+}
+
+PositioningAssistanceInformationControlIEs F1AP-PROTOCOL-IES ::= {
+		{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+		{ ID id-PosAssistance-Information		CRITICALITY reject	TYPE PosAssistance-Information		PRESENCE optional}|
+		{ ID id-PosBroadcast					CRITICALITY reject	TYPE PosBroadcast				PRESENCE optional}|
+		{ ID id-PositioningBroadcastCells		CRITICALITY reject	TYPE PositioningBroadcastCells		PRESENCE optional}|
+		{ ID id-RoutingID						CRITICALITY reject	TYPE RoutingID				PRESENCE optional},
+	...
+}
+
+-- **************************************************************
+--
+-- POSITIONING ASSISTANCE INFORMATION FEEDBACK ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Assistance Information Feedback
+--
+-- **************************************************************
+
+PositioningAssistanceInformationFeedback ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ PositioningAssistanceInformationFeedbackIEs}},
+	...
+}
+
+PositioningAssistanceInformationFeedbackIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID							PRESENCE mandatory	}|
+	{ ID id-PosAssistanceInformationFailureList	CRITICALITY reject	TYPE PosAssistanceInformationFailureList	PRESENCE optional}|
+	{ ID id-PositioningBroadcastCells				CRITICALITY reject	TYPE PositioningBroadcastCells				PRESENCE optional}|
+	{ ID id-RoutingID								CRITICALITY reject	TYPE RoutingID									PRESENCE optional}|
+	{ ID id-CriticalityDiagnostics				CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional},
+	...
+}
+
+-- **************************************************************
+--
+-- POSITONING MEASUREMENT EXCHANGE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Measurement Request
+--
+-- **************************************************************
+
+PositioningMeasurementRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningMeasurementRequestIEs} },
+	...
+}
+
+PositioningMeasurementRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory}|
+	{ ID id-LMF-MeasurementID						CRITICALITY reject	TYPE LMF-MeasurementID								PRESENCE mandatory}|
+	{ ID id-RAN-MeasurementID						CRITICALITY reject	TYPE RAN-MeasurementID								PRESENCE mandatory}|
+	{ ID id-TRP-MeasurementRequestList				CRITICALITY reject	TYPE TRP-MeasurementRequestList					PRESENCE mandatory}|
+	{ ID id-PosReportCharacteristics				CRITICALITY reject	TYPE PosReportCharacteristics				PRESENCE mandatory}|
+	{ ID id-PosMeasurementPeriodicity				CRITICALITY reject	TYPE PosMeasurementPeriodicity					PRESENCE conditional }|
+	-- The above IE shall be present if the PosReportCharacteristics IE is set to “periodic” --
+	{ ID id-PosMeasurementQuantities				CRITICALITY reject	TYPE PosMeasurementQuantities					PRESENCE mandatory}|
+	{ ID id-SFNInitialisationTime					CRITICALITY ignore	TYPE SFNInitialisationTime	PRESENCE optional	}|
+	{ ID id-SRSConfiguration						CRITICALITY ignore	TYPE SRSConfiguration								PRESENCE optional}|
+	{ ID id-MeasurementBeamInfoRequest				CRITICALITY ignore	TYPE MeasurementBeamInfoRequest	PRESENCE optional	}|
+	{ ID id-SystemFrameNumber						CRITICALITY ignore	TYPE SystemFrameNumber		PRESENCE optional}|
+	{ ID id-SlotNumber								CRITICALITY ignore	TYPE SlotNumber				PRESENCE optional},
+	...
+} 
+
+
+-- **************************************************************
+--
+-- Positioning Measurement Response
+--
+-- **************************************************************
+
+PositioningMeasurementResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningMeasurementResponseIEs} },
+	...
+}
+
+
+PositioningMeasurementResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory}|
+	{ ID id-LMF-MeasurementID						CRITICALITY reject	TYPE LMF-MeasurementID								PRESENCE mandatory}|
+	{ ID id-RAN-MeasurementID						CRITICALITY reject	TYPE RAN-MeasurementID								PRESENCE mandatory}|
+	{ ID id-PosMeasurementResultList				CRITICALITY reject	TYPE PosMeasurementResultList					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics					CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Positioning Measurement Failure
+--
+-- **************************************************************
+
+PositioningMeasurementFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningMeasurementFailureIEs} },
+	...
+}
+
+PositioningMeasurementFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-LMF-MeasurementID				CRITICALITY reject	TYPE LMF-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-RAN-MeasurementID				CRITICALITY reject	TYPE RAN-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- POSITIONING MEASUREMENT REPORT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Measurement Report
+--
+-- **************************************************************
+
+PositioningMeasurementReport ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { PositioningMeasurementReportIEs} },
+	...
+}
+
+PositioningMeasurementReportIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-LMF-MeasurementID			CRITICALITY reject	TYPE LMF-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-RAN-MeasurementID			CRITICALITY reject	TYPE RAN-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-PosMeasurementResultList	CRITICALITY reject	TYPE PosMeasurementResultList	PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- POSITIONING MEASUREMENT ABORT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Measurement Abort
+--
+-- **************************************************************
+
+PositioningMeasurementAbort ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { PositioningMeasurementAbortIEs} },
+	...
+}
+
+PositioningMeasurementAbortIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|	
+	{ ID id-LMF-MeasurementID				CRITICALITY reject	TYPE LMF-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-RAN-MeasurementID				CRITICALITY reject	TYPE RAN-MeasurementID				PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- POSITIONING MEASUREMENT FAILURE INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Measurement Failure Indication
+--
+-- **************************************************************
+
+PositioningMeasurementFailureIndication ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { PositioningMeasurementFailureIndicationIEs} },
+	...
+}
+
+PositioningMeasurementFailureIndicationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-LMF-MeasurementID			CRITICALITY reject	TYPE LMF-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-RAN-MeasurementID			CRITICALITY reject	TYPE RAN-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- POSITIONING MEASUREMENT UPDATE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Measurement Update
+--
+-- **************************************************************
+
+PositioningMeasurementUpdate ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { PositioningMeasurementUpdateIEs} },
+	...
+}
+
+PositioningMeasurementUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-LMF-MeasurementID			CRITICALITY reject	TYPE LMF-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-RAN-MeasurementID			CRITICALITY reject	TYPE RAN-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-SRSConfiguration			CRITICALITY ignore	TYPE SRSConfiguration			PRESENCE optional},
+	...
+}
+
+
+-- **************************************************************
+--
+-- TRP INFORMATION EXCHANGE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- TRP Information Request
+--
+-- **************************************************************
+
+TRPInformationRequest ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { TRPInformationRequestIEs} },
+	...
+}
+
+TRPInformationRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID								PRESENCE mandatory	}|
+	{ ID id-TRPList								CRITICALITY ignore	TYPE TRPList									PRESENCE optional	}|
+	{ ID id-TRPInformationTypeListTRPReq		CRITICALITY reject	TYPE TRPInformationTypeListTRPReq			PRESENCE mandatory	},
+	...
+}
+
+TRPInformationTypeListTRPReq ::= SEQUENCE (SIZE(1.. maxnoofTRPInfoTypes)) OF ProtocolIE-SingleContainer { { TRPInformationTypeItemTRPReq } }
+
+TRPInformationTypeItemTRPReq 	F1AP-PROTOCOL-IES ::= {
+	{ ID id-TRPInformationTypeItem	 CRITICALITY reject		TYPE TRPInformationTypeItem  	PRESENCE mandatory },
+	...
+}
+
+
+-- **************************************************************
+--
+-- TRP Information Response
+--
+-- **************************************************************
+
+TRPInformationResponse ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { TRPInformationResponseIEs} },
+	...
+}
+
+TRPInformationResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-TRPInformationListTRPResp		CRITICALITY ignore	TYPE TRPInformationListTRPResp		PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+	...
+}
+
+TRPInformationListTRPResp ::= SEQUENCE (SIZE(1.. maxnoofTRPs)) OF ProtocolIE-SingleContainer { { TRPInformationItemTRPResp } }
+
+TRPInformationItemTRPResp 	F1AP-PROTOCOL-IES ::= {
+	{ ID id-TRPInformationItem	 CRITICALITY ignore		TYPE TRPInformationItem  	PRESENCE mandatory },
+	...
+}
+
+
+-- **************************************************************
+--
+-- TRP Information Failure
+--
+-- **************************************************************
+
+TRPInformationFailure ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { TRPInformationFailureIEs} },
+	...
+}
+
+TRPInformationFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- POSITIONING INFORMATION EXCHANGE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Information Request
+--
+-- **************************************************************
+
+PositioningInformationRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningInformationRequestIEs} },
+	...
+}
+
+PositioningInformationRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-RequestedSRSTransmissionCharacteristics	CRITICALITY ignore	TYPE RequestedSRSTransmissionCharacteristics	PRESENCE optional},
+	...
+} 
+
+
+-- **************************************************************
+--
+-- Positioning Information Response
+--
+-- **************************************************************
+
+PositioningInformationResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningInformationResponseIEs} },
+	...
+}
+
+
+PositioningInformationResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|	
+	{ ID id-SRSConfiguration			CRITICALITY ignore	TYPE SRSConfiguration			PRESENCE optional}|
+	{ ID id-SFNInitialisationTime		CRITICALITY ignore	TYPE SFNInitialisationTime		PRESENCE optional}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional },
+	...
+}
+
+
+-- **************************************************************
+--
+-- Positioning Information Failure
+--
+-- **************************************************************
+
+PositioningInformationFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningInformationFailureIEs} },
+	...
+}
+
+PositioningInformationFailureIEs F1AP-PROTOCOL-IES ::= {
+	
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional },
+	...
+}
+
+
+-- **************************************************************
+--
+-- POSITIONING ACTIVATION PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Activation Request
+--
+-- **************************************************************
+
+PositioningActivationRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningActivationRequestIEs} },
+	...
+}
+
+PositioningActivationRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-SRSType					CRITICALITY reject	TYPE SRSType					PRESENCE mandatory	}|
+	{ ID id-ActivationTime			CRITICALITY ignore	TYPE SFNInitialisationTime		PRESENCE optional	},
+	...
+} 
+
+SRSType ::= CHOICE {
+	semipersistentSRS				SemipersistentSRS,
+	aperiodicSRS					AperiodicSRS, 
+	choice-extension				ProtocolIE-SingleContainer { { SRSType-ExtIEs} }
+}
+
+SRSType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+SemipersistentSRS ::= SEQUENCE {
+	sRSResourceSetID			SRSResourceSetID,
+	sRSSpatialRelation			SRSSpatialRelation	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { {SemipersistentSRS-ExtIEs} } OPTIONAL,
+	...
+}
+
+SemipersistentSRS-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AperiodicSRS ::= SEQUENCE {
+	aperiodic					ENUMERATED {true, ...},
+	sRSResourceTrigger			SRSResourceTrigger		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { {AperiodicSRS-ExtIEs} } OPTIONAL,
+	...
+}
+
+AperiodicSRS-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+-- **************************************************************
+--
+-- Positioning Activation Response
+--
+-- **************************************************************
+
+PositioningActivationResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningActivationResponseIEs} },
+	...
+}
+
+
+PositioningActivationResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-SystemFrameNumber		CRITICALITY ignore	TYPE SystemFrameNumber			PRESENCE optional }|
+	{ ID id-SlotNumber				CRITICALITY ignore	TYPE SlotNumber					PRESENCE optional }|
+	{ ID id-CriticalityDiagnostics	CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional },
+	...
+}
+
+
+
+
+-- **************************************************************
+--
+-- Positioning Activation Failure
+--
+-- **************************************************************
+
+PositioningActivationFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningActivationFailureIEs} },
+	...
+}
+
+PositioningActivationFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional },
+	...
+}
+
+
+-- **************************************************************
+--
+-- POSITIONING DEACTIVATION PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Deactivation
+--
+-- **************************************************************
+
+PositioningDeactivation ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningDeactivationIEs} },
+	...
+}
+
+PositioningDeactivationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-AbortTransmission		CRITICALITY ignore	TYPE AbortTransmission			PRESENCE mandatory	},
+	...
+} 
+
+-- **************************************************************
+--
+-- POSITIONING INFORMATION UPDATE PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Information Update
+--
+-- **************************************************************
+
+PositioningInformationUpdate ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningInformationUpdateIEs} },
+	...
+}
+
+
+PositioningInformationUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-SRSConfiguration		CRITICALITY ignore	TYPE SRSConfiguration			PRESENCE optional}|
+	{ ID id-SFNInitialisationTime	CRITICALITY ignore	TYPE SFNInitialisationTime		PRESENCE optional},
+	...
+}
+
+-- **************************************************************
+--
+-- E-CID MEASUREMENT PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- E-CID Measurement Initiation Request
+--
+-- **************************************************************
+
+E-CIDMeasurementInitiationRequest ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container	{{E-CIDMeasurementInitiationRequest-IEs}},
+	...
+}
+
+E-CIDMeasurementInitiationRequest-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID					PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID					PRESENCE mandatory	}|
+	{ ID id-LMF-UE-MeasurementID			CRITICALITY reject	TYPE LMF-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-RAN-UE-MeasurementID			CRITICALITY reject	TYPE RAN-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-E-CID-ReportCharacteristics		CRITICALITY reject	TYPE E-CID-ReportCharacteristics		PRESENCE mandatory	}|
+	{ ID id-E-CID-MeasurementPeriodicity	CRITICALITY reject	TYPE E-CID-MeasurementPeriodicity		PRESENCE conditional	}|
+-- The above IE shall be present if the E-CID-ReportCharacteristics IE is set to “periodic” –-
+	{ ID id-E-CID-MeasurementQuantities		CRITICALITY reject	TYPE E-CID-MeasurementQuantities		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- E-CID Measurement Initiation Response
+--
+-- **************************************************************
+
+E-CIDMeasurementInitiationResponse ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container	{{E-CIDMeasurementInitiationResponse-IEs}},
+	...
+}
+
+E-CIDMeasurementInitiationResponse-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-LMF-UE-MeasurementID		CRITICALITY reject	TYPE LMF-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-RAN-UE-MeasurementID		CRITICALITY reject	TYPE RAN-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-E-CID-MeasurementResult		CRITICALITY ignore	TYPE E-CID-MeasurementResult		PRESENCE optional}|
+	{ ID id-Cell-Portion-ID				CRITICALITY ignore	TYPE Cell-Portion-ID				PRESENCE optional}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional},
+	...
+}
+
+-- **************************************************************
+--
+-- E-CID Measurement Initiation Failure
+--
+-- **************************************************************
+
+E-CIDMeasurementInitiationFailure ::= SEQUENCE {
+	protocolIEs						ProtocolIE-Container		{{E-CIDMeasurementInitiationFailure-IEs}},
+	...
+}
+
+
+E-CIDMeasurementInitiationFailure-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-LMF-UE-MeasurementID		CRITICALITY reject	TYPE LMF-UE-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-RAN-UE-MeasurementID		CRITICALITY reject	TYPE RAN-UE-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional},
+	...
+}
+
+-- **************************************************************
+--
+-- E-CID MEASUREMENT FAILURE INDICATION PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- E-CID Measurement Failure Indication
+--
+-- **************************************************************
+
+E-CIDMeasurementFailureIndication ::= SEQUENCE {
+	protocolIEs						ProtocolIE-Container		{{E-CIDMeasurementFailureIndication-IEs}},
+	...
+}
+
+
+E-CIDMeasurementFailureIndication-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-LMF-UE-MeasurementID		CRITICALITY reject	TYPE LMF-UE-MeasurementID		PRESENCE mandatory	}|
+	{ ID id-RAN-UE-MeasurementID		CRITICALITY reject	TYPE RAN-UE-MeasurementID		PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- E-CID MEASUREMENT REPORT PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- E-CID Measurement Report
+--
+-- **************************************************************
+
+E-CIDMeasurementReport ::= SEQUENCE {
+	protocolIEs						ProtocolIE-Container		{{E-CIDMeasurementReport-IEs}},
+	...
+}
+
+
+E-CIDMeasurementReport-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-LMF-UE-MeasurementID		CRITICALITY reject	TYPE LMF-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-RAN-UE-MeasurementID		CRITICALITY reject	TYPE RAN-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-E-CID-MeasurementResult		CRITICALITY ignore	TYPE E-CID-MeasurementResult		PRESENCE mandatory }|
+	{ ID id-Cell-Portion-ID				CRITICALITY ignore	TYPE Cell-Portion-ID				PRESENCE optional},
+
+	...
+}
+
+-- **************************************************************
+--
+-- E-CID MEASUREMENT TERMINATION PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- E-CID Measurement Termination Command
+--
+-- **************************************************************
+
+
+E-CIDMeasurementTerminationCommand ::= SEQUENCE {
+	protocolIEs						ProtocolIE-Container		{{E-CIDMeasurementTerminationCommand-IEs}},
+	...
+}
+
+
+E-CIDMeasurementTerminationCommand-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID					PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID					PRESENCE mandatory	}|
+	{ ID id-LMF-UE-MeasurementID		CRITICALITY reject	TYPE LMF-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-RAN-UE-MeasurementID		CRITICALITY reject	TYPE RAN-UE-MeasurementID				PRESENCE mandatory	},
+	...
+}
+
+
+
+END
+-- ASN1STOP 
+
+
+-- ASN1START 
+-- **************************************************************
+--
+-- Information Element Definitions
+--
+-- **************************************************************
+
+F1AP-IEs {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-IEs (2) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+IMPORTS
+	id-gNB-CUSystemInformation,
+	id-HandoverPreparationInformation,
+	id-TAISliceSupportList,
+	id-RANAC,
+	id-BearerTypeChange,
+	id-Cell-Direction,
+	id-Cell-Type,
+	id-CellGroupConfig,
+	id-AvailablePLMNList,
+	id-PDUSessionID,
+	id-ULPDUSessionAggregateMaximumBitRate, 
+	id-DC-Based-Duplication-Configured,
+	id-DC-Based-Duplication-Activation,
+	id-Duplication-Activation,
+	id-DLPDCPSNLength,
+	id-ULPDCPSNLength,
+	id-RLC-Status,
+	id-MeasurementTimingConfiguration,
+	id-DRB-Information,
+	id-QoSFlowMappingIndication,
+	id-ServingCellMO,
+	id-RLCMode,
+	id-ExtendedServedPLMNs-List,
+	id-ExtendedAvailablePLMN-List,
+	id-DRX-LongCycleStartOffset,
+	id-SelectedBandCombinationIndex,
+	id-SelectedFeatureSetEntryIndex,
+	id-Ph-InfoSCG,
+	id-latest-RRC-Version-Enhanced,
+	id-RequestedBandCombinationIndex,
+	id-RequestedFeatureSetEntryIndex,
+	id-DRX-Config,
+	id-UEAssistanceInformation,
+	id-PDCCH-BlindDetectionSCG,
+	id-Requested-PDCCH-BlindDetectionSCG,
+	id-BPLMN-ID-Info-List,
+	id-NotificationInformation,
+	id-TNLAssociationTransportLayerAddressgNBDU,
+	id-portNumber,
+	id-AdditionalSIBMessageList,
+	id-IgnorePRACHConfiguration,
+	id-CG-Config,
+	id-Ph-InfoMCG,
+	id-AggressorgNBSetID,
+	id-VictimgNBSetID,
+	id-MeasGapSharingConfig,
+	id-systemInformationAreaID,
+	id-areaScope,
+	id-IntendedTDD-DL-ULConfig,
+	id-QosMonitoringRequest,
+	id-BHInfo,
+	id-IAB-Info-IAB-DU,
+	id-IAB-Info-IAB-donor-CU,
+	id-IAB-Barred,
+	id-SIB12-message,
+	id-SIB13-message,
+	id-SIB14-message,
+	id-UEAssistanceInformationEUTRA,
+	id-SL-PHY-MAC-RLC-Config,
+	id-SL-ConfigDedicatedEUTRA,
+	id-AlternativeQoSParaSetList,
+	id-CurrentQoSParaSetIndex,
+	id-CarrierList,
+	id-ULCarrierList,
+	id-FrequencyShift7p5khz,
+	id-SSB-PositionsInBurst,
+	id-NRPRACHConfig, 
+	id-TDD-UL-DLConfigCommonNR,
+	id-CNPacketDelayBudgetDownlink,
+	id-CNPacketDelayBudgetUplink,
+	id-ExtendedPacketDelayBudget,
+	id-TSCTrafficCharacteristics,
+	id-AdditionalPDCPDuplicationTNL-List,
+	id-RLCDuplicationInformation,
+	id-AdditionalDuplicationIndication,
+	id-mdtConfiguration,
+	id-TraceCollectionEntityURI,
+	id-NID,
+	id-NPNSupportInfo,
+	id-NPNBroadcastInformation,
+	id-AvailableSNPN-ID-List,
+	id-SIB10-message,
+	id-RequestedP-MaxFR2,
+	id-DLCarrierList,
+	id-ExtendedTAISliceSupportList,
+	id-E-CID-MeasurementQuantities-Item,
+	id-ConfiguredTACIndication,
+	maxNRARFCN,
+	maxnoofErrors,
+	maxnoofBPLMNs,
+	maxnoofBPLMNsNR,
+	maxnoofDLUPTNLInformation,
+	maxnoofNrCellBands,
+	maxnoofULUPTNLInformation,
+	maxnoofQoSFlows,
+	maxnoofSliceItems,
+	maxnoofSIBTypes,
+	maxnoofSITypes,
+	maxCellineNB,
+	maxnoofExtendedBPLMNs,
+	maxnoofAdditionalSIBs,
+	maxnoofUACPLMNs,
+	maxnoofUACperPLMN,
+	maxCellingNBDU,
+	maxnoofTLAs,
+	maxnoofGTPTLAs,
+	maxnoofslots,
+	maxnoofNonUPTrafficMappings,
+	maxnoofServingCells,
+	maxnoofServedCellsIAB,
+	maxnoofChildIABNodes,
+	maxnoofIABSTCInfo,
+	maxnoofSymbols,
+	maxnoofDUFSlots,
+	maxnoofHSNASlots,
+	maxnoofEgressLinks,
+	maxnoofMappingEntries,
+	maxnoofDSInfo,
+	maxnoofQoSParaSets,
+	maxnoofPC5QoSFlows,
+	maxnoofSSBAreas,
+	maxnoofBPLMNsNR,
+	maxnoofNRSCSs,
+	maxnoofPhysicalResourceBlocks,
+	maxnoofPhysicalResourceBlocks-1,
+	maxnoofPRACHconfigs,
+	maxnoofRACHReports,
+	maxnoofRLFReports,
+	maxnoofAdditionalPDCPDuplicationTNL,
+	maxnoofRLCDuplicationState,
+	maxnoofCHOcells,
+	maxnoofMDTPLMNs,
+	maxnoofCAGsupported,
+	maxnoofNIDsupported,
+	maxnoofNRSCSs,
+	maxnoofPhysicalResourceBlocks,
+	maxnoofExtSliceItems,
+	maxnoofPosMeas,
+	maxnoofTRPInfoTypes,
+	maxnoofSRSTriggerStates,
+	maxnoofSpatialRelations,
+	maxnoBcastCell,
+	maxnoofTRPs,
+	maxnoofAngleInfo,
+	maxnooflcs-gcs-translation,
+	maxnoofPath,
+	maxnoofMeasE-CID,
+	maxnoofSSBs,
+	maxnoSRS-ResourceSets,
+	maxnoSRS-ResourcePerSet,
+	maxnoSRS-Carriers,
+	maxnoSCSs,
+	maxnoSRS-Resources,
+	maxnoSRS-PosResources,
+	maxnoSRS-PosResourceSets,
+	maxnoSRS-PosResourcePerSet,
+	maxnoofPRS-ResourceSets,
+	maxnoofPRS-ResourcesPerSet,
+	maxNoOfMeasTRPs,
+	maxnoofPRSresourceSets,
+	maxnoofPRSresources
+
+
+
+FROM F1AP-Constants
+
+	Criticality,
+	ProcedureCode,
+	ProtocolIE-ID,
+	TriggeringMessage
+
+FROM F1AP-CommonDataTypes
+
+	ProtocolExtensionContainer{},
+	F1AP-PROTOCOL-EXTENSION,
+	ProtocolIE-SingleContainer{},
+	F1AP-PROTOCOL-IES
+
+FROM F1AP-Containers;
+
+-- A
+
+AbortTransmission ::= CHOICE {
+	sRSResourceSetID		SRSResourceSetID,
+	releaseALL				NULL,
+	choice-extension		ProtocolIE-SingleContainer { { AbortTransmission-ExtIEs } }
+}
+
+AbortTransmission-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+AccessPointPosition ::= SEQUENCE {
+	latitudeSign				ENUMERATED {north, south},
+	latitude					INTEGER (0..8388607),
+	longitude					INTEGER (-8388608..8388607),
+	directionOfAltitude			ENUMERATED {height, depth},
+	altitude					INTEGER (0..32767),
+	uncertaintySemi-major		INTEGER (0..127),
+	uncertaintySemi-minor		INTEGER (0..127),
+	orientationOfMajorAxis		INTEGER (0..179),
+	uncertaintyAltitude			INTEGER (0..127),
+	confidence					INTEGER (0..100),
+	iE-Extensions				ProtocolExtensionContainer { { AccessPointPosition-ExtIEs} } OPTIONAL
+}
+
+AccessPointPosition-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Activated-Cells-to-be-Updated-List ::= SEQUENCE (SIZE(1..maxnoofServedCellsIAB)) OF Activated-Cells-to-be-Updated-List-Item
+
+Activated-Cells-to-be-Updated-List-Item ::=	SEQUENCE{
+	nRCGI								NRCGI,
+	iAB-DU-Cell-Resource-Configuration-Mode-Info	IAB-DU-Cell-Resource-Configuration-Mode-Info,
+	iE-Extensions						ProtocolExtensionContainer { { Activated-Cells-to-be-Updated-List-Item-ExtIEs} } OPTIONAL
+}
+
+Activated-Cells-to-be-Updated-List-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ActiveULBWP  ::= SEQUENCE {
+	locationAndBandwidth		INTEGER (0..37949,...),
+	subcarrierSpacing           ENUMERATED {kHz15, kHz30, kHz60, kHz120,...},
+	cyclicPrefix				ENUMERATED {normal, extended},
+	txDirectCurrentLocation		INTEGER (0..3301,...),
+	shift7dot5kHz				ENUMERATED {true, ...} OPTIONAL,
+	sRSConfig					SRSConfig,
+	iE-Extensions					ProtocolExtensionContainer { { ActiveULBWP-ExtIEs} } OPTIONAL
+}
+
+ActiveULBWP-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AdditionalDuplicationIndication ::= ENUMERATED { 
+	three,
+	four,
+	...
+}
+
+
+AdditionalPath-List::= SEQUENCE (SIZE(1..maxnoofPath)) OF AdditionalPath-Item
+
+AdditionalPath-Item ::=SEQUENCE {
+	relativePathDelay	RelativePathDelay, 
+	pathQuality			TRPMeasurementQuality 	OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { AdditionalPath-Item-ExtIEs } }	OPTIONAL
+}
+
+AdditionalPath-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+AdditionalPDCPDuplicationTNL-List ::= SEQUENCE (SIZE(1..maxnoofAdditionalPDCPDuplicationTNL)) OF AdditionalPDCPDuplicationTNL-Item
+
+AdditionalPDCPDuplicationTNL-Item ::=SEQUENCE {
+	additionalPDCPDuplicationUPTNLInformation		UPTransportLayerInformation, 
+	iE-Extensions	ProtocolExtensionContainer { { AdditionalPDCPDuplicationTNL-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+AdditionalPDCPDuplicationTNL-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AdditionalSIBMessageList ::= SEQUENCE (SIZE(1..maxnoofAdditionalSIBs)) OF AdditionalSIBMessageList-Item
+
+AdditionalSIBMessageList-Item ::= SEQUENCE {
+	additionalSIB			OCTET STRING,
+	iE-Extensions		ProtocolExtensionContainer { { AdditionalSIBMessageList-Item-ExtIEs} } OPTIONAL
+}
+
+AdditionalSIBMessageList-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AdditionalRRMPriorityIndex ::= BIT STRING (SIZE(32))
+
+AggressorCellList ::= SEQUENCE (SIZE(1..maxCellingNBDU)) OF AggressorCellList-Item
+
+AggressorCellList-Item ::= SEQUENCE {
+	aggressorCell-ID		NRCGI,
+	iE-Extensions	ProtocolExtensionContainer { { AggressorCellList-Item-ExtIEs } }		OPTIONAL
+}
+
+AggressorCellList-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AggressorgNBSetID ::= SEQUENCE {
+	aggressorgNBSetID		GNBSetID,
+	iE-Extensions	ProtocolExtensionContainer { { AggressorgNBSetID-ExtIEs } }	OPTIONAL
+}
+
+AggressorgNBSetID-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AllocationAndRetentionPriority ::= SEQUENCE {
+	priorityLevel				PriorityLevel,
+	pre-emptionCapability		Pre-emptionCapability,
+	pre-emptionVulnerability	Pre-emptionVulnerability,
+	iE-Extensions				ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL,
+	...
+}
+
+AllocationAndRetentionPriority-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AlternativeQoSParaSetList ::= SEQUENCE (SIZE(1..maxnoofQoSParaSets)) OF AlternativeQoSParaSetItem
+
+AlternativeQoSParaSetItem ::= SEQUENCE {
+	alternativeQoSParaSetIndex			QoSParaSetIndex,
+	guaranteedFlowBitRateDL				BitRate					OPTIONAL,
+	guaranteedFlowBitRateUL				BitRate					OPTIONAL,
+	packetDelayBudget					PacketDelayBudget		OPTIONAL,
+	packetErrorRate						PacketErrorRate			OPTIONAL,
+	iE-Extensions						ProtocolExtensionContainer { {AlternativeQoSParaSetItem-ExtIEs} }	OPTIONAL,
+	...
+}
+
+AlternativeQoSParaSetItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+AngleMeasurementQuality ::= SEQUENCE {
+	azimuthQuality	INTEGER(0..255),
+	zenithQuality	INTEGER(0..255) OPTIONAL,
+	resolution		ENUMERATED{deg0dot1,...},
+	iE-Extensions	ProtocolExtensionContainer { { AngleMeasurementQuality-ExtIEs } }	OPTIONAL
+}
+
+AngleMeasurementQuality-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+AperiodicSRSResourceTriggerList ::= SEQUENCE (SIZE(1..maxnoofSRSTriggerStates)) OF AperiodicSRSResourceTrigger
+
+AperiodicSRSResourceTrigger ::= INTEGER (0..3, ...)
+
+Associated-SCell-Item ::= SEQUENCE {
+	sCell-ID		NRCGI,
+	iE-Extensions	ProtocolExtensionContainer { { Associated-SCell-ItemExtIEs } }	OPTIONAL
+}
+
+Associated-SCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AvailablePLMNList ::= SEQUENCE (SIZE(1..maxnoofBPLMNs)) OF AvailablePLMNList-Item
+
+AvailablePLMNList-Item ::= SEQUENCE {
+	pLMNIdentity			PLMN-Identity,
+	iE-Extensions		ProtocolExtensionContainer { { AvailablePLMNList-Item-ExtIEs} } OPTIONAL
+}
+
+AvailablePLMNList-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AvailableSNPN-ID-List ::= SEQUENCE (SIZE(1..maxnoofNIDsupported)) OF AvailableSNPN-ID-List-Item
+
+AvailableSNPN-ID-List-Item ::= SEQUENCE {
+	pLMN-Identity				PLMN-Identity,
+	availableNIDList			BroadcastNIDList,
+	iE-Extensions				ProtocolExtensionContainer { { AvailableSNPN-ID-List-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+AvailableSNPN-ID-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AveragingWindow  ::= INTEGER (0..4095, ...) 
+
+AreaScope ::= ENUMERATED {true, ...}
+
+-- B
+
+BandwidthSRS ::= CHOICE { 
+	fR1								FR1-Bandwidth,
+	fR2								FR2-Bandwidth,
+	choice-extension				ProtocolIE-SingleContainer {{ BandwidthSRS-ExtIEs }}
+}
+
+BandwidthSRS-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+
+BAPAddress ::= BIT STRING (SIZE(10))
+
+BAPCtrlPDUChannel ::= ENUMERATED {true, ...}
+
+BAPlayerBHRLCchannelMappingInfo ::= SEQUENCE {
+	bAPlayerBHRLCchannelMappingInfoToAdd			BAPlayerBHRLCchannelMappingInfoList			OPTIONAL,
+	bAPlayerBHRLCchannelMappingInfoToRemove			MappingInformationtoRemove					OPTIONAL,
+	iE-Extensions									ProtocolExtensionContainer { { BAPlayerBHRLCchannelMappingInfo-ExtIEs} } OPTIONAL,
+	...
+}
+
+BAPlayerBHRLCchannelMappingInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BAPlayerBHRLCchannelMappingInfoList ::= SEQUENCE (SIZE(1..maxnoofMappingEntries)) OF BAPlayerBHRLCchannelMappingInfo-Item
+
+BAPlayerBHRLCchannelMappingInfo-Item ::= SEQUENCE {
+	mappingInformationIndex			MappingInformationIndex,		
+	priorHopBAPAddress				BAPAddress		OPTIONAL,		
+	ingressbHRLCChannelID			BHRLCChannelID		OPTIONAL,		
+	nextHopBAPAddress				BAPAddress		OPTIONAL,		
+	egressbHRLCChannelID			BHRLCChannelID		OPTIONAL,		
+	iE-Extensions					ProtocolExtensionContainer { { BAPlayerBHRLCchannelMappingInfo-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+BAPlayerBHRLCchannelMappingInfo-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BAPPathID ::= BIT STRING (SIZE(10))
+
+BAPRoutingID ::= SEQUENCE {
+	bAPAddress		BAPAddress,
+	bAPPathID		BAPPathID,
+	iE-Extensions	ProtocolExtensionContainer { { BAPRoutingIDExtIEs } }	OPTIONAL
+}
+
+BAPRoutingIDExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BitRate ::= INTEGER (0..4000000000000,...)
+
+BearerTypeChange ::= ENUMERATED {true, ...}
+
+BHRLCChannelID ::= BIT STRING (SIZE(16))
+
+BHChannels-FailedToBeModified-Item ::= SEQUENCE {
+	bHRLCChannelID		BHRLCChannelID,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-FailedToBeModified-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-FailedToBeModified-ItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-FailedToBeSetup-Item ::= SEQUENCE {
+	bHRLCChannelID		BHRLCChannelID,
+	cause	Cause	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-FailedToBeSetup-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-FailedToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-FailedToBeSetupMod-Item ::= SEQUENCE {
+	bHRLCChannelID		BHRLCChannelID,
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-FailedToBeSetupMod-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-FailedToBeSetupMod-ItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-Modified-Item ::= SEQUENCE {
+	bHRLCChannelID			BHRLCChannelID,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-Modified-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-Modified-ItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-Required-ToBeReleased-Item ::= SEQUENCE {
+	bHRLCChannelID		BHRLCChannelID,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-Required-ToBeReleased-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-Required-ToBeReleased-ItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-Setup-Item ::= SEQUENCE {
+	bHRLCChannelID							BHRLCChannelID,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-Setup-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-Setup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-SetupMod-Item ::= SEQUENCE {
+	bHRLCChannelID							BHRLCChannelID,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-SetupMod-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-SetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-ToBeModified-Item ::= SEQUENCE {
+	bHRLCChannelID					BHRLCChannelID,
+	bHQoSInformation				BHQoSInformation,
+	rLCmode				RLCMode	OPTIONAL,
+	bAPCtrlPDUChannel	BAPCtrlPDUChannel		OPTIONAL,
+	trafficMappingInfo	TrafficMappingInfo		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-ToBeModified-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-ToBeReleased-Item ::= SEQUENCE {
+	bHRLCChannelID		BHRLCChannelID,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-ToBeReleased-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-ToBeSetup-Item ::= SEQUENCE	{
+	bHRLCChannelID						BHRLCChannelID,
+	bHQoSInformation					BHQoSInformation,
+	rLCmode								RLCMode,
+	bAPCtrlPDUChannel					BAPCtrlPDUChannel		OPTIONAL,
+	trafficMappingInfo					TrafficMappingInfo		OPTIONAL,
+	iE-Extensions						ProtocolExtensionContainer { { BHChannels-ToBeSetup-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-ToBeSetupMod-Item ::= SEQUENCE {
+	bHRLCChannelID				BHRLCChannelID,
+	bHQoSInformation			BHQoSInformation,
+	rLCmode				RLCMode,
+	bAPCtrlPDUChannel	BAPCtrlPDUChannel		OPTIONAL,
+	trafficMappingInfo	TrafficMappingInfo		OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { BHChannels-ToBeSetupMod-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHInfo ::= SEQUENCE {
+	bAProutingID			BAPRoutingID 	OPTIONAL,
+	egressBHRLCCHList		EgressBHRLCCHList	OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { { BHInfo-ExtIEs} } OPTIONAL
+}
+
+BHInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHQoSInformation ::= CHOICE {
+	bHRLCCHQoS					QoSFlowLevelQoSParameters,	
+	eUTRANBHRLCCHQoS			EUTRANQoS,
+	cPTrafficType				CPTrafficType,
+	choice-extension			ProtocolIE-SingleContainer { { BHQoSInformation-ExtIEs} }
+}
+
+BHQoSInformation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+BH-Routing-Information-Added-List-Item ::= SEQUENCE {
+	bAPRoutingID				BAPRoutingID,
+	nextHopBAPAddress			BAPAddress,
+	iE-Extensions				ProtocolExtensionContainer { { BH-Routing-Information-Added-List-ItemExtIEs} }	OPTIONAL
+}
+
+BH-Routing-Information-Added-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BH-Routing-Information-Removed-List-Item ::= SEQUENCE {
+	bAPRoutingID				BAPRoutingID,
+	iE-Extensions				ProtocolExtensionContainer { { BH-Routing-Information-Removed-List-ItemExtIEs} }	OPTIONAL
+}
+
+BH-Routing-Information-Removed-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BPLMN-ID-Info-List ::= SEQUENCE (SIZE(1..maxnoofBPLMNsNR)) OF BPLMN-ID-Info-Item
+
+BPLMN-ID-Info-Item ::= SEQUENCE {
+	pLMN-Identity-List			AvailablePLMNList,
+	extended-PLMN-Identity-List	ExtendedAvailablePLMN-List	OPTIONAL,
+	fiveGS-TAC					FiveGS-TAC					OPTIONAL,
+	nr-cell-ID					NRCellIdentity,
+	ranac						RANAC						OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { BPLMN-ID-Info-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+BPLMN-ID-Info-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{	ID id-ConfiguredTACIndication		CRITICALITY ignore	EXTENSION ConfiguredTACIndication		PRESENCE optional }|
+	{	ID id-NPNBroadcastInformation		CRITICALITY reject EXTENSION NPNBroadcastInformation		PRESENCE optional},
+	...
+}
+
+ServedPLMNs-List ::= SEQUENCE (SIZE(1..maxnoofBPLMNs)) OF ServedPLMNs-Item
+
+ServedPLMNs-Item ::= SEQUENCE {
+	pLMN-Identity				PLMN-Identity,
+	iE-Extensions				ProtocolExtensionContainer { { ServedPLMNs-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+ServedPLMNs-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+{ ID id-TAISliceSupportList	CRITICALITY ignore	EXTENSION SliceSupportList		PRESENCE optional	}|
+{ ID id-NPNSupportInfo	CRITICALITY reject	EXTENSION NPNSupportInfo		PRESENCE optional	}|
+{ ID id-ExtendedTAISliceSupportList	CRITICALITY reject	EXTENSION ExtendedSliceSupportList		PRESENCE optional	},
+	...
+}
+
+BroadcastCAGList ::= SEQUENCE (SIZE(1..maxnoofCAGsupported)) OF CAGID
+
+BroadcastNIDList ::= SEQUENCE (SIZE(1..maxnoofNIDsupported)) OF NID
+
+BroadcastSNPN-ID-List ::= SEQUENCE (SIZE(1..maxnoofNIDsupported)) OF BroadcastSNPN-ID-List-Item
+
+BroadcastSNPN-ID-List-Item ::= SEQUENCE {
+	pLMN-Identity				PLMN-Identity,
+	broadcastNIDList			BroadcastNIDList,
+	iE-Extensions				ProtocolExtensionContainer { { BroadcastSNPN-ID-List-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+BroadcastSNPN-ID-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BroadcastPNI-NPN-ID-List ::= SEQUENCE (SIZE(1..maxnoofCAGsupported)) OF BroadcastPNI-NPN-ID-List-Item
+
+BroadcastPNI-NPN-ID-List-Item ::= SEQUENCE {
+	pLMN-Identity				PLMN-Identity,
+	broadcastCAGList			BroadcastCAGList,
+	iE-Extensions				ProtocolExtensionContainer { { BroadcastPNI-NPN-ID-List-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+BroadcastPNI-NPN-ID-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+BurstArrivalTime ::= OCTET STRING
+
+-- C
+CAGID ::= BIT STRING (SIZE(32))
+
+Cancel-all-Warning-Messages-Indicator ::= ENUMERATED {true, ...}
+
+Candidate-SpCell-Item ::= SEQUENCE {
+	candidate-SpCell-ID			NRCGI	,
+	iE-Extensions	ProtocolExtensionContainer { { Candidate-SpCell-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Candidate-SpCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CapacityValue::= SEQUENCE {
+	capacityValue				INTEGER (0..100),
+	sSBAreaCapacityValueList	SSBAreaCapacityValueList		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { CapacityValue-ExtIEs} } OPTIONAL
+}
+
+CapacityValue-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cause ::= CHOICE {
+	radioNetwork		CauseRadioNetwork,
+	transport			CauseTransport,
+	protocol			CauseProtocol,
+	misc				CauseMisc,
+	choice-extension	ProtocolIE-SingleContainer { { Cause-ExtIEs} }
+}
+
+Cause-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+CauseMisc ::= ENUMERATED {
+	control-processing-overload,
+	not-enough-user-plane-processing-resources,
+	hardware-failure,
+	om-intervention,
+	unspecified,
+	...
+}
+
+CauseProtocol ::= ENUMERATED {
+	transfer-syntax-error,
+	abstract-syntax-error-reject,
+	abstract-syntax-error-ignore-and-notify,
+	message-not-compatible-with-receiver-state,
+	semantic-error,
+	abstract-syntax-error-falsely-constructed-message,
+	unspecified,
+	...
+}
+
+CauseRadioNetwork ::= ENUMERATED {
+	unspecified,
+	rl-failure-rlc,
+	unknown-or-already-allocated-gnb-cu-ue-f1ap-id,
+	unknown-or-already-allocated-gnb-du-ue-f1ap-id,
+	unknown-or-inconsistent-pair-of-ue-f1ap-id,
+	interaction-with-other-procedure,
+	not-supported-qci-Value,
+	action-desirable-for-radio-reasons,
+	no-radio-resources-available,
+	procedure-cancelled,
+	normal-release,
+	...,
+	cell-not-available,
+	rl-failure-others,
+	ue-rejection,
+	resources-not-available-for-the-slice,
+	amf-initiated-abnormal-release,
+	release-due-to-pre-emption,
+	plmn-not-served-by-the-gNB-CU,
+	multiple-drb-id-instances,
+	unknown-drb-id,
+	multiple-bh-rlc-ch-id-instances,
+	unknown-bh-rlc-ch-id,
+	cho-cpc-resources-tobechanged,
+	nPN-not-supported, 
+	nPN-access-denied,
+	gNB-CU-Cell-Capacity-Exceeded,
+	report-characteristics-empty,
+	existing-measurement-ID,
+	measurement-temporarily-not-available,
+	measurement-not-supported-for-the-object
+
+}
+
+CauseTransport ::= ENUMERATED {
+	unspecified,
+	transport-resource-unavailable,
+	...,
+	unknown-TNL-address-for-IAB,
+	unknown-UP-TNL-information-for-IAB
+}
+
+CellGroupConfig ::= OCTET STRING
+
+CellCapacityClassValue ::= INTEGER (1..100,...)
+
+Cell-Direction ::= ENUMERATED {dl-only, ul-only}
+
+CellMeasurementResultList ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF CellMeasurementResultItem
+
+CellMeasurementResultItem ::= SEQUENCE {
+	cellID							NRCGI,
+	radioResourceStatus				RadioResourceStatus 			OPTIONAL, 
+	compositeAvailableCapacityGroup	CompositeAvailableCapacityGroup	OPTIONAL,
+	sliceAvailableCapacity			SliceAvailableCapacity 			OPTIONAL, 
+	numberofActiveUEs 				NumberofActiveUEs			OPTIONAL, 
+	iE-Extensions					ProtocolExtensionContainer { { CellMeasurementResultItem-ExtIEs} } OPTIONAL
+}
+
+CellMeasurementResultItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cell-Portion-ID ::= INTEGER (0..4095,...)
+
+Cells-Failed-to-be-Activated-List-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	cause				Cause,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-Failed-to-be-Activated-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-Failed-to-be-Activated-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-Status-Item ::= SEQUENCE {
+	nRCGI			NRCGI,
+	service-status		Service-Status,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-Status-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-Status-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-To-Be-Broadcast-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-To-Be-Broadcast-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-To-Be-Broadcast-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-Broadcast-Completed-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-Broadcast-Completed-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-Broadcast-Completed-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Broadcast-To-Be-Cancelled-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	iE-Extensions		ProtocolExtensionContainer { { Broadcast-To-Be-Cancelled-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Broadcast-To-Be-Cancelled-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+Cells-Broadcast-Cancelled-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	numberOfBroadcasts	NumberOfBroadcasts,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-Broadcast-Cancelled-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-Broadcast-Cancelled-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-to-be-Activated-List-Item ::= SEQUENCE {
+	nRCGI		NRCGI,
+	nRPCI		NRPCI		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-to-be-Activated-List-ItemExtIEs} }	OPTIONAL,
+	...
+}
+
+Cells-to-be-Activated-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-gNB-CUSystemInformation			CRITICALITY reject	EXTENSION GNB-CUSystemInformation			PRESENCE optional }|
+	{ ID id-AvailablePLMNList				CRITICALITY ignore	EXTENSION AvailablePLMNList					PRESENCE optional }|
+	{ ID id-ExtendedAvailablePLMN-List		CRITICALITY ignore	EXTENSION ExtendedAvailablePLMN-List		PRESENCE optional }|
+	{ ID id-IAB-Info-IAB-donor-CU			CRITICALITY ignore	EXTENSION IAB-Info-IAB-donor-CU				PRESENCE optional}|
+	{ ID id-AvailableSNPN-ID-List			CRITICALITY ignore	EXTENSION AvailableSNPN-ID-List				PRESENCE optional },
+	...
+}
+
+Cells-to-be-Deactivated-List-Item ::= SEQUENCE {
+	nRCGI			NRCGI	,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-to-be-Deactivated-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-to-be-Deactivated-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-to-be-Barred-Item::= SEQUENCE {
+	nRCGI			NRCGI	,
+	cellBarred		CellBarred,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-to-be-Barred-Item-ExtIEs } }	OPTIONAL
+}
+
+Cells-to-be-Barred-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-IAB-Barred	CRITICALITY ignore	EXTENSION IAB-Barred		PRESENCE optional },
+
+	...
+}
+
+
+CellBarred	::=	ENUMERATED {barred, not-barred, ...}
+
+CellSize ::= ENUMERATED {verysmall, small, medium, large, ...}
+
+CellToReportList ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF CellToReportItem
+
+CellToReportItem ::= SEQUENCE {
+	cellID		NRCGI,
+	sSBToReportList		SSBToReportList		 OPTIONAL,
+	sliceToReportList	SliceToReportList	 OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { CellToReportItem-ExtIEs} } OPTIONAL
+}
+
+CellToReportItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CellType ::= SEQUENCE {
+	cellSize		CellSize,
+	iE-Extensions		ProtocolExtensionContainer { {CellType-ExtIEs} }	OPTIONAL,
+	...
+}
+
+CellType-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CellULConfigured ::=  ENUMERATED {none, ul, sul, ul-and-sul, ...}
+
+Child-Node-Cells-List ::= SEQUENCE (SIZE(1..maxnoofChildIABNodes)) OF Child-Node-Cells-List-Item
+
+Child-Node-Cells-List-Item ::=	SEQUENCE{
+	nRCGI 								NRCGI,
+	iAB-DU-Cell-Resource-Configuration-Mode-Info 	IAB-DU-Cell-Resource-Configuration-Mode-Info	OPTIONAL,
+	iAB-STC-Info						IAB-STC-Info	OPTIONAL,
+	rACH-Config-Common					RACH-Config-Common	OPTIONAL,
+	rACH-Config-Common-IAB				RACH-Config-Common-IAB	OPTIONAL,
+	cSI-RS-Configuration				OCTET STRING	OPTIONAL,
+	sR-Configuration					OCTET STRING	OPTIONAL,
+	pDCCH-ConfigSIB1					OCTET STRING	OPTIONAL,
+	sCS-Common							OCTET STRING	OPTIONAL,
+	multiplexingInfo					MultiplexingInfo	OPTIONAL,
+	iE-Extensions						ProtocolExtensionContainer {{Child-Node-Cells-List-Item-ExtIEs}}		OPTIONAL
+}
+
+Child-Node-Cells-List-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Child-Nodes-List ::= SEQUENCE (SIZE(1..maxnoofChildIABNodes)) OF Child-Nodes-List-Item
+
+Child-Nodes-List-Item ::= SEQUENCE{
+	gNB-CU-UE-F1AP-ID	GNB-CU-UE-F1AP-ID,
+	gNB-DU-UE-F1AP-ID	GNB-DU-UE-F1AP-ID,
+	child-Node-Cells-List 	Child-Node-Cells-List	OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer {{Child-Nodes-List-Item-ExtIEs}}		OPTIONAL
+}
+
+Child-Nodes-List-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CHOtrigger-InterDU ::= ENUMERATED {
+	cho-initiation,
+	cho-replace,
+	...
+}
+
+CHOtrigger-IntraDU ::= ENUMERATED {
+	cho-initiation,
+	cho-replace,
+	cho-cancel,
+	...
+}
+
+CNUEPagingIdentity ::= CHOICE {
+	fiveG-S-TMSI			BIT STRING (SIZE(48)),
+	choice-extension			ProtocolIE-SingleContainer { { CNUEPagingIdentity-ExtIEs } }
+}
+
+CNUEPagingIdentity-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+CompositeAvailableCapacityGroup ::= SEQUENCE {
+	compositeAvailableCapacityDownlink	CompositeAvailableCapacity,
+	compositeAvailableCapacityUplink 	CompositeAvailableCapacity,
+	iE-Extensions	ProtocolExtensionContainer { { CompositeAvailableCapacityGroup-ExtIEs} } OPTIONAL
+}
+
+CompositeAvailableCapacityGroup-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CompositeAvailableCapacity ::= SEQUENCE {
+	cellCapacityClassValue 	CellCapacityClassValue		OPTIONAL,
+	capacityValue			CapacityValue,
+	iE-Extensions	ProtocolExtensionContainer { { CompositeAvailableCapacity-ExtIEs} } OPTIONAL
+}
+
+CompositeAvailableCapacity-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ConditionalInterDUMobilityInformation ::= SEQUENCE {
+	cho-trigger						CHOtrigger-InterDU,
+	targetgNB-DUUEF1APID			GNB-DU-UE-F1AP-ID							OPTIONAL
+		-- This IE shall be present if the cho-trigger IE is present and set to "cho-replace" --,
+	iE-Extensions					ProtocolExtensionContainer { { ConditionalInterDUMobilityInformation-ExtIEs} }	OPTIONAL,
+	...
+}
+
+ConditionalInterDUMobilityInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::={
+	...
+}
+
+ConditionalIntraDUMobilityInformation ::= SEQUENCE {
+	cho-trigger						CHOtrigger-IntraDU,
+	targetCellsTocancel				TargetCellList								OPTIONAL,
+	-- This IE may be present if the cho-trigger IE is present and set to "cho-cancel"
+	iE-Extensions					ProtocolExtensionContainer { { ConditionalIntraDUMobilityInformation-ExtIEs} }	OPTIONAL,
+	...
+}
+
+ConditionalIntraDUMobilityInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::={
+	...
+}
+
+ConfiguredTACIndication ::= ENUMERATED {
+	true,
+	...
+}
+
+
+CoordinateID ::= INTEGER (0..511, ...)
+
+CP-TransportLayerAddress ::= CHOICE {
+	endpoint-IP-address				TransportLayerAddress,
+	endpoint-IP-address-and-port	Endpoint-IP-address-and-port, 
+	choice-extension				ProtocolIE-SingleContainer { { CP-TransportLayerAddress-ExtIEs } }
+}
+
+CP-TransportLayerAddress-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+CPTrafficType ::= INTEGER (1..3,...)
+
+CriticalityDiagnostics ::= SEQUENCE {
+	procedureCode					ProcedureCode														OPTIONAL,
+	triggeringMessage				TriggeringMessage													OPTIONAL,
+	procedureCriticality			Criticality															OPTIONAL,
+	transactionID					TransactionID														OPTIONAL,
+	iEsCriticalityDiagnostics		CriticalityDiagnostics-IE-List										OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer {{CriticalityDiagnostics-ExtIEs}}		OPTIONAL,
+	...
+}
+
+CriticalityDiagnostics-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1.. maxnoofErrors)) OF CriticalityDiagnostics-IE-Item
+
+CriticalityDiagnostics-IE-Item ::= SEQUENCE {
+	iECriticality			Criticality,
+	iE-ID					ProtocolIE-ID,
+	typeOfError 			TypeOfError,
+	iE-Extensions			ProtocolExtensionContainer {{CriticalityDiagnostics-IE-Item-ExtIEs}}	OPTIONAL,
+	...
+}
+
+CriticalityDiagnostics-IE-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+C-RNTI ::= INTEGER (0..65535, ...)
+
+CUDURadioInformationType ::= CHOICE {
+	rIM								CUDURIMInformation,
+	choice-extension				ProtocolIE-SingleContainer { { CUDURadioInformationType-ExtIEs} }
+}
+
+CUDURadioInformationType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+CUDURIMInformation ::= SEQUENCE {
+	victimgNBSetID			GNBSetID, 
+	rIMRSDetectionStatus	RIMRSDetectionStatus,
+	iE-Extensions			ProtocolExtensionContainer { { CUDURIMInformation-ExtIEs} }	OPTIONAL
+}
+
+CUDURIMInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CUtoDURRCInformation ::= SEQUENCE {
+	cG-ConfigInfo						CG-ConfigInfo						OPTIONAL,
+	uE-CapabilityRAT-ContainerList		UE-CapabilityRAT-ContainerList		OPTIONAL,
+	measConfig							MeasConfig							OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { CUtoDURRCInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+CUtoDURRCInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-HandoverPreparationInformation	CRITICALITY ignore	EXTENSION HandoverPreparationInformation		PRESENCE optional }|
+	{ ID id-CellGroupConfig					CRITICALITY ignore	EXTENSION CellGroupConfig							PRESENCE optional }|
+	{ ID id-MeasurementTimingConfiguration	CRITICALITY ignore	EXTENSION MeasurementTimingConfiguration		PRESENCE optional }|
+	{ ID id-UEAssistanceInformation			CRITICALITY ignore	EXTENSION UEAssistanceInformation					PRESENCE optional }|
+	{ ID id-CG-Config						CRITICALITY ignore	EXTENSION CG-Config									PRESENCE optional }|
+	{ ID id-UEAssistanceInformationEUTRA	CRITICALITY ignore	EXTENSION UEAssistanceInformationEUTRA			PRESENCE optional },
+	...
+}
+
+-- D
+
+DCBasedDuplicationConfigured::= ENUMERATED{true,..., false}
+
+Dedicated-SIDelivery-NeededUE-Item ::= SEQUENCE {
+	gNB-CU-UE-F1AP-ID						GNB-CU-UE-F1AP-ID,
+	nRCGI									NRCGI,
+	iE-Extensions							ProtocolExtensionContainer { { DedicatedSIDeliveryNeededUE-Item-ExtIEs} } OPTIONAL,
+	...
+}
+
+DedicatedSIDeliveryNeededUE-Item-ExtIEs F1AP-PROTOCOL-EXTENSION::={
+	...
+}
+
+
+DL-PRS ::= SEQUENCE {
+	prsid 					INTEGER (0..255),
+	dl-PRSResourceSetID		PRS-Resource-Set-ID,
+	dl-PRSResourceID		PRS-Resource-ID	OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { {DL-PRS-ExtIEs} }	OPTIONAL
+}
+
+DL-PRS-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DL-PRSMutingPattern ::= CHOICE {
+	two					BIT STRING (SIZE(2)),
+	four				BIT STRING (SIZE(4)),
+	six					BIT STRING (SIZE(6)),
+	eight				BIT STRING (SIZE(8)),
+	sixteen				BIT STRING (SIZE(16)),
+	thirty-two			BIT STRING (SIZE(32)),
+	choice-extension							ProtocolIE-SingleContainer { { DL-PRSMutingPattern-ExtIEs } }
+}
+
+DL-PRSMutingPattern-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+DLPRSResourceCoordinates ::= SEQUENCE {
+	listofDL-PRSResourceSetARP		SEQUENCE (SIZE(1.. maxnoofPRS-ResourceSets)) OF DLPRSResourceSetARP,
+	iE-Extensions					ProtocolExtensionContainer { { DLPRSResourceCoordinates-ExtIEs } } OPTIONAL
+}
+
+DLPRSResourceCoordinates-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DLPRSResourceSetARP ::= SEQUENCE {
+	dl-PRSResourceSetID				INTEGER (0..7),
+	dL-PRSResourceSetARPLocation	DL-PRSResourceSetARPLocation,
+	listofDL-PRSResourceARP			SEQUENCE (SIZE(1.. maxnoofPRS-ResourcesPerSet)) OF DLPRSResourceARP,
+	iE-Extensions					ProtocolExtensionContainer { { DLPRSResourceSetARP-ExtIEs } } OPTIONAL
+}
+
+DLPRSResourceSetARP-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+DL-PRSResourceSetARPLocation ::= CHOICE {
+	relativeGeodeticLocation			RelativeGeodeticLocation,
+	relativeCartesianLocation			RelativeCartesianLocation,
+	choice-Extension					ProtocolIE-SingleContainer { { DL-PRSResourceSetARPLocation-ExtIEs } }
+}
+
+DL-PRSResourceSetARPLocation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+
+DLPRSResourceARP ::= SEQUENCE {
+	dl-PRSResourceID			INTEGER (0..63),
+	dL-PRSResourceARPLocation	DL-PRSResourceARPLocation,	
+	iE-Extensions				ProtocolExtensionContainer { { DLPRSResourceARP-ExtIEs } } OPTIONAL
+}
+
+DLPRSResourceARP-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DL-PRSResourceARPLocation ::= CHOICE {
+	relativeGeodeticLocation			RelativeGeodeticLocation,
+	relativeCartesianLocation			RelativeCartesianLocation,
+	choice-Extension					ProtocolIE-SingleContainer { { DL-PRSResourceARPLocation-ExtIEs } }
+}
+
+DL-PRSResourceARPLocation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+DL-UP-TNL-Address-to-Update-List-Item	::= SEQUENCE {
+	oldIPAdress						TransportLayerAddress,
+	newIPAdress						TransportLayerAddress,
+	iE-Extensions	ProtocolExtensionContainer { { DL-UP-TNL-Address-to-Update-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DL-UP-TNL-Address-to-Update-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DLUPTNLInformation-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDLUPTNLInformation)) OF DLUPTNLInformation-ToBeSetup-Item
+
+DLUPTNLInformation-ToBeSetup-Item ::= SEQUENCE {
+	dLUPTNLInformation	UPTransportLayerInformation	,
+	iE-Extensions	ProtocolExtensionContainer { { DLUPTNLInformation-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DLUPTNLInformation-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRB-Activity-Item ::= SEQUENCE {
+	dRBID			DRBID,
+	dRB-Activity	DRB-Activity		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRB-Activity-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRB-Activity-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRB-Activity ::= ENUMERATED {active, not-active}
+
+DRBID ::= INTEGER (1..32, ...)
+
+DRBs-FailedToBeModified-Item	::= SEQUENCE {
+	dRBID		DRBID		,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeModified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-FailedToBeSetup-Item	::= SEQUENCE {
+	dRBID	DRBID,
+	cause	Cause	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+DRBs-FailedToBeSetupMod-Item	::= SEQUENCE {
+	dRBID		DRBID	,
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRB-Information	::=	SEQUENCE {
+	dRB-QoS		QoSFlowLevelQoSParameters, 
+	sNSSAI		SNSSAI, 
+	notificationControl		NotificationControl		OPTIONAL,
+	flows-Mapped-To-DRB-List	Flows-Mapped-To-DRB-List,
+	iE-Extensions	ProtocolExtensionContainer { { DRB-Information-ItemExtIEs } }	OPTIONAL
+}
+
+DRB-Information-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-Modified-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	lCID								LCID		OPTIONAL,
+	dLUPTNLInformation-ToBeSetup-List		DLUPTNLInformation-ToBeSetup-List,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Modified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Modified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-RLC-Status							CRITICALITY ignore	EXTENSION RLC-Status									PRESENCE optional }|
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List		PRESENCE optional },
+	...
+}
+
+DRBs-ModifiedConf-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	uLUPTNLInformation-ToBeSetup-List		ULUPTNLInformation-ToBeSetup-List	,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ModifiedConf-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ModifiedConf-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List			PRESENCE optional },
+	...
+}
+
+DRB-Notify-Item ::= SEQUENCE {
+	dRBID			DRBID,
+	notification-Cause	Notification-Cause,
+	iE-Extensions	ProtocolExtensionContainer { { DRB-Notify-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRB-Notify-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-CurrentQoSParaSetIndex	CRITICALITY ignore	EXTENSION QoSParaSetNotifyIndex	PRESENCE optional	},
+	...
+}
+
+DRBs-Required-ToBeModified-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	dLUPTNLInformation-ToBeSetup-List		DLUPTNLInformation-ToBeSetup-List	,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Required-ToBeModified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Required-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-RLC-Status			CRITICALITY ignore			EXTENSION RLC-Status				PRESENCE optional }|
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List			PRESENCE optional },
+	...
+}
+
+DRBs-Required-ToBeReleased-Item	::= SEQUENCE {
+	dRBID		DRBID,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Required-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Required-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-Setup-Item ::= SEQUENCE {
+	dRBID							DRBID,
+	lCID								LCID		OPTIONAL,
+	dLUPTNLInformation-ToBeSetup-List		DLUPTNLInformation-ToBeSetup-List	, 
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Setup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Setup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List			PRESENCE optional }|
+	{ ID id-RLCDuplicationInformation			CRITICALITY ignore	EXTENSION RLCDuplicationInformation						PRESENCE optional},	...
+}
+
+DRBs-SetupMod-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	lCID								LCID		OPTIONAL,
+	dLUPTNLInformation-ToBeSetup-List		DLUPTNLInformation-ToBeSetup-List	,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-SetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-SetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List			PRESENCE optional },
+	...
+}
+
+
+DRBs-ToBeModified-Item	::= SEQUENCE {
+	dRBID						DRBID,
+	qoSInformation				QoSInformation	OPTIONAL,
+	uLUPTNLInformation-ToBeSetup-List	ULUPTNLInformation-ToBeSetup-List	, 
+	uLConfiguration				ULConfiguration	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeModified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-DLPDCPSNLength						CRITICALITY ignore	EXTENSION PDCPSNLength										PRESENCE optional }|
+	{ ID id-ULPDCPSNLength						CRITICALITY ignore	EXTENSION PDCPSNLength										PRESENCE optional }|
+	{ID id-BearerTypeChange						CRITICALITY ignore	EXTENSION BearerTypeChange									PRESENCE optional}|
+	{ ID id-RLCMode								CRITICALITY ignore	EXTENSION RLCMode											PRESENCE optional }|
+	{ ID id-Duplication-Activation				CRITICALITY reject	EXTENSION DuplicationActivation							PRESENCE optional }|
+	{ ID id-DC-Based-Duplication-Configured		CRITICALITY reject	EXTENSION DCBasedDuplicationConfigured					PRESENCE optional }|
+	{ ID id-DC-Based-Duplication-Activation		CRITICALITY reject	EXTENSION DuplicationActivation							PRESENCE optional }|
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List			PRESENCE optional }|
+	{ ID id-RLCDuplicationInformation			CRITICALITY ignore	EXTENSION RLCDuplicationInformation						PRESENCE optional},
+	...
+}
+
+DRBs-ToBeReleased-Item	::= SEQUENCE {
+	dRBID	DRBID,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-ToBeSetup-Item ::= SEQUENCE	{
+	dRBID						DRBID,
+	qoSInformation				QoSInformation,
+	uLUPTNLInformation-ToBeSetup-List	ULUPTNLInformation-ToBeSetup-List	, 
+	rLCMode						RLCMode, 
+	uLConfiguration				ULConfiguration	OPTIONAL,
+	duplicationActivation		DuplicationActivation	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-DC-Based-Duplication-Configured		CRITICALITY reject	EXTENSION DCBasedDuplicationConfigured				PRESENCE optional }|
+	{ ID id-DC-Based-Duplication-Activation		CRITICALITY reject	EXTENSION DuplicationActivation						PRESENCE optional }|
+	{ ID id-DLPDCPSNLength						CRITICALITY ignore	EXTENSION PDCPSNLength									PRESENCE mandatory }|
+	{ ID id-ULPDCPSNLength						CRITICALITY ignore	EXTENSION PDCPSNLength									PRESENCE optional }|
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List		PRESENCE optional },
+	...
+}
+
+
+DRBs-ToBeSetupMod-Item	::= SEQUENCE {
+	dRBID						DRBID,
+	qoSInformation				QoSInformation,
+	uLUPTNLInformation-ToBeSetup-List		ULUPTNLInformation-ToBeSetup-List,
+	rLCMode						RLCMode, 
+	uLConfiguration				ULConfiguration	OPTIONAL,
+	duplicationActivation		DuplicationActivation	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-DC-Based-Duplication-Configured		CRITICALITY reject	EXTENSION DCBasedDuplicationConfigured				PRESENCE optional }|
+	{ ID id-DC-Based-Duplication-Activation		CRITICALITY reject	EXTENSION DuplicationActivation						PRESENCE optional }|
+	{ ID id-DLPDCPSNLength						CRITICALITY ignore	EXTENSION PDCPSNLength									PRESENCE optional }|
+	{ ID id-ULPDCPSNLength						CRITICALITY ignore	EXTENSION PDCPSNLength									PRESENCE optional }|
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List		PRESENCE optional }|
+	{ ID id-RLCDuplicationInformation			CRITICALITY ignore	EXTENSION RLCDuplicationInformation					PRESENCE optional},
+	...
+}
+
+DRXCycle	::= SEQUENCE {
+	longDRXCycleLength	LongDRXCycleLength,
+	shortDRXCycleLength		ShortDRXCycleLength	OPTIONAL,
+	shortDRXCycleTimer	ShortDRXCycleTimer OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { DRXCycle-ExtIEs} } OPTIONAL,
+	...
+}
+
+DRXCycle-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRX-Config ::= OCTET STRING
+
+DRXConfigurationIndicator	::=	ENUMERATED{	release, ...}
+
+DRX-LongCycleStartOffset ::= INTEGER (0..10239)
+
+DSInformationList ::= SEQUENCE (SIZE(0..maxnoofDSInfo)) OF DSCP
+
+DSCP ::= BIT STRING (SIZE (6))
+
+DUtoCURRCContainer ::= OCTET STRING
+
+DUCURadioInformationType ::= CHOICE {
+	rIM								DUCURIMInformation,
+	choice-extension				ProtocolIE-SingleContainer { { DUCURadioInformationType-ExtIEs} }
+}
+
+DUCURadioInformationType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+DUCURIMInformation ::= SEQUENCE {
+	victimgNBSetID				GNBSetID, 
+	rIMRSDetectionStatus		RIMRSDetectionStatus,
+	aggressorCellList			AggressorCellList,
+	iE-Extensions				ProtocolExtensionContainer { { DUCURIMInformation-ExtIEs} }		OPTIONAL 
+}
+
+DUCURIMInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DUF-Slot-Config-Item 	::=	CHOICE {
+	explicitFormat				ExplicitFormat,
+	implicitFormat				ImplicitFormat,
+	choice-extension				ProtocolIE-SingleContainer { { DUF-Slot-Config-Item-ExtIEs} }
+}
+
+DUF-Slot-Config-Item-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+DUF-Slot-Config-List	::= SEQUENCE (SIZE(1..maxnoofDUFSlots)) OF DUF-Slot-Config-Item
+
+DUFSlotformatIndex ::= INTEGER(0..254)
+
+DUFTransmissionPeriodicity ::= ENUMERATED { ms0p5, ms0p625, ms1, ms1p25, ms2, ms2p5, ms5, ms10, ...}
+
+DU-RX-MT-RX ::= ENUMERATED {supported, not-supported}
+
+DU-TX-MT-TX ::= ENUMERATED {supported, not-supported}
+
+DU-RX-MT-TX ::= ENUMERATED {supported, not-supported}
+
+DU-TX-MT-RX ::= ENUMERATED {supported, not-supported}
+
+DUtoCURRCInformation ::= SEQUENCE {
+	cellGroupConfig		CellGroupConfig,
+	measGapConfig			MeasGapConfig	OPTIONAL,
+	requestedP-MaxFR1				OCTET STRING				OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { DUtoCURRCInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+DUtoCURRCInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-DRX-LongCycleStartOffset			CRITICALITY ignore	EXTENSION DRX-LongCycleStartOffset				PRESENCE optional }|
+	{ ID id-SelectedBandCombinationIndex		CRITICALITY ignore	EXTENSION SelectedBandCombinationIndex			PRESENCE optional }|
+	{ ID id-SelectedFeatureSetEntryIndex		CRITICALITY ignore	EXTENSION SelectedFeatureSetEntryIndex			PRESENCE optional }|
+	{ ID id-Ph-InfoSCG							CRITICALITY ignore	EXTENSION Ph-InfoSCG								PRESENCE optional }|
+	{ ID id-RequestedBandCombinationIndex		CRITICALITY ignore	EXTENSION RequestedBandCombinationIndex		PRESENCE optional }|
+	{ ID id-RequestedFeatureSetEntryIndex		CRITICALITY ignore	EXTENSION RequestedFeatureSetEntryIndex		PRESENCE optional }|
+	{ ID id-DRX-Config							CRITICALITY ignore	EXTENSION DRX-Config								PRESENCE optional }|
+	{ ID id-PDCCH-BlindDetectionSCG				CRITICALITY ignore	EXTENSION PDCCH-BlindDetectionSCG				PRESENCE optional }|
+	{ ID id-Requested-PDCCH-BlindDetectionSCG	CRITICALITY ignore	EXTENSION Requested-PDCCH-BlindDetectionSCG	PRESENCE optional }|
+	{ ID id-Ph-InfoMCG							CRITICALITY ignore	EXTENSION Ph-InfoMCG								PRESENCE optional }|
+	{ ID id-MeasGapSharingConfig				CRITICALITY ignore	EXTENSION MeasGapSharingConfig					PRESENCE optional }|
+	{ ID id-SL-PHY-MAC-RLC-Config				CRITICALITY ignore	EXTENSION SL-PHY-MAC-RLC-Config					PRESENCE optional }|
+	{ ID id-SL-ConfigDedicatedEUTRA				CRITICALITY ignore	EXTENSION SL-ConfigDedicatedEUTRA				PRESENCE optional }|
+	{ ID id-RequestedP-MaxFR2					CRITICALITY ignore	EXTENSION RequestedP-MaxFR2							PRESENCE optional },
+	...
+}
+
+DuplicationActivation ::= ENUMERATED{active,inactive,... }
+
+DuplicationIndication ::= ENUMERATED {true, ... , false }
+
+DuplicationState ::= ENUMERATED { 
+	active,
+	inactive,
+	...
+}
+
+Dynamic5QIDescriptor	::= SEQUENCE {
+	qoSPriorityLevel					INTEGER (1..127),
+	packetDelayBudget					PacketDelayBudget,
+	packetErrorRate						PacketErrorRate,
+	fiveQI								INTEGER (0..255, ...)								OPTIONAL,
+	delayCritical						ENUMERATED {delay-critical, non-delay-critical}		OPTIONAL,
+	-- C-ifGBRflow: This IE shall be present if the GBR QoS Flow Information IE is present in the QoS Flow Level QoS Parameters IE.
+	averagingWindow 					AveragingWindow										OPTIONAL,
+	-- C-ifGBRflow: This IE shall be present if the GBR QoS Flow Information IE is present in the QoS Flow Level QoS Parameters IE.
+	maxDataBurstVolume					MaxDataBurstVolume									OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { Dynamic5QIDescriptor-ExtIEs } } OPTIONAL
+}
+
+Dynamic5QIDescriptor-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-ExtendedPacketDelayBudget			CRITICALITY ignore	EXTENSION ExtendedPacketDelayBudget		PRESENCE optional		}|
+	{ ID id-CNPacketDelayBudgetDownlink			CRITICALITY ignore	EXTENSION ExtendedPacketDelayBudget		PRESENCE optional		}|
+	{ ID id-CNPacketDelayBudgetUplink			CRITICALITY ignore	EXTENSION ExtendedPacketDelayBudget		PRESENCE optional		},
+	...
+}
+
+DynamicPQIDescriptor	::= SEQUENCE {
+	resourceType						ENUMERATED {gbr, non-gbr, delay-critical-grb, ...}		OPTIONAL,
+	qoSPriorityLevel					INTEGER (1..8, ...),
+	packetDelayBudget					PacketDelayBudget,
+	packetErrorRate						PacketErrorRate,
+	averagingWindow 					AveragingWindow										OPTIONAL,
+	-- C-ifGBRflow: This IE shall be present if the GBR QoS Flow Information IE is present in the QoS Flow Level QoS Parameters IE.
+	maxDataBurstVolume					MaxDataBurstVolume									OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { DynamicPQIDescriptor-ExtIEs } } OPTIONAL
+}
+
+DynamicPQIDescriptor-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- E
+
+E-CID-MeasurementPeriodicity ::= ENUMERATED {
+	ms120,
+	ms240,
+	ms480,
+	ms640,
+	ms1024,
+	ms2048,
+	ms5120,
+	ms10240,
+	min1,
+	min6,
+	min12,
+	min30,
+	min60,
+	...
+}
+
+E-CID-MeasurementQuantities ::= SEQUENCE (SIZE (1.. maxnoofMeasE-CID)) OF ProtocolIE-SingleContainer { {E-CID-MeasurementQuantities-ItemIEs} }
+
+E-CID-MeasurementQuantities-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-E-CID-MeasurementQuantities-Item	CRITICALITY reject	TYPE E-CID-MeasurementQuantities-Item		PRESENCE mandatory}
+}
+
+E-CID-MeasurementQuantities-Item ::= SEQUENCE {
+	e-CIDmeasurementQuantitiesValue				E-CID-MeasurementQuantitiesValue,
+	iE-Extensions								ProtocolExtensionContainer { { E-CID-MeasurementQuantitiesValue-ExtIEs} } OPTIONAL
+}
+
+E-CID-MeasurementQuantitiesValue-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+E-CID-MeasurementQuantitiesValue ::= ENUMERATED {
+	cell-Portion,
+	angleOfArrivalNR,
+	... 
+}
+
+E-CID-MeasurementResult ::= SEQUENCE {
+	geographicalCoordinates		GeographicalCoordinates 	OPTIONAL,
+	measuredResults-List		E-CID-MeasuredResults-List 	OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { E-CID-MeasurementResult-ExtIEs} } OPTIONAL
+}
+
+E-CID-MeasurementResult-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+E-CID-MeasuredResults-List ::= SEQUENCE (SIZE(1..maxnoofMeasE-CID)) OF E-CID-MeasuredResults-Item
+
+E-CID-MeasuredResults-Item ::= SEQUENCE {
+	e-CID-MeasuredResults-Value 	E-CID-MeasuredResults-Value,
+	iE-Extensions			ProtocolExtensionContainer {{ E-CID-MeasuredResults-Item-ExtIEs }}	 OPTIONAL
+}
+
+E-CID-MeasuredResults-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+E-CID-MeasuredResults-Value ::= CHOICE {
+	valueAngleofArrivalNR	UL-AoA,
+	choice-extension		ProtocolIE-SingleContainer { { E-CID-MeasuredResults-Value-ExtIEs} }
+}
+
+E-CID-MeasuredResults-Value-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+E-CID-ReportCharacteristics ::= ENUMERATED {
+	onDemand,
+	periodic,
+	...
+}
+
+EgressBHRLCCHList ::= SEQUENCE (SIZE(1..maxnoofEgressLinks)) OF EgressBHRLCCHItem
+
+EgressBHRLCCHItem ::= SEQUENCE {
+	nextHopBAPAddress 		BAPAddress,
+	bHRLCChannelID			BHRLCChannelID,
+	iE-Extensions			ProtocolExtensionContainer {{EgressBHRLCCHItemExtIEs }}	 OPTIONAL
+}
+
+EgressBHRLCCHItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Endpoint-IP-address-and-port ::=SEQUENCE {
+	endpointIPAddress TransportLayerAddress,
+	iE-Extensions					ProtocolExtensionContainer { { Endpoint-IP-address-and-port-ExtIEs} } OPTIONAL
+}
+
+Endpoint-IP-address-and-port-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-portNumber	CRITICALITY reject	EXTENSION PortNumber		PRESENCE optional},
+	...
+}
+
+ExtendedAvailablePLMN-List ::= SEQUENCE (SIZE(1..maxnoofExtendedBPLMNs)) OF ExtendedAvailablePLMN-Item
+
+ExtendedAvailablePLMN-Item ::= SEQUENCE {
+	pLMNIdentity			PLMN-Identity,
+	iE-Extensions		ProtocolExtensionContainer { { ExtendedAvailablePLMN-Item-ExtIEs} } OPTIONAL
+}
+
+ExplicitFormat ::=	SEQUENCE {
+	permutation			Permutation,
+	noofDownlinkSymbols	NoofDownlinkSymbols		OPTIONAL,
+	noofUplinkSymbols	NoofUplinkSymbols		OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { ExplicitFormat-ExtIEs} } OPTIONAL
+}
+
+ExplicitFormat-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ExtendedAvailablePLMN-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ExtendedServedPLMNs-List ::= SEQUENCE (SIZE(1.. maxnoofExtendedBPLMNs)) OF ExtendedServedPLMNs-Item
+
+ExtendedServedPLMNs-Item ::= SEQUENCE {
+	pLMN-Identity				PLMN-Identity,
+	tAISliceSupportList 		SliceSupportList	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { ExtendedServedPLMNs-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+ExtendedServedPLMNs-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-NPNSupportInfo			CRITICALITY reject	EXTENSION NPNSupportInfo				PRESENCE optional	}|
+{ ID id-ExtendedTAISliceSupportList	CRITICALITY reject	EXTENSION ExtendedSliceSupportList		PRESENCE optional	},
+	...
+}
+
+ExtendedSliceSupportList ::= SEQUENCE (SIZE(1.. maxnoofExtSliceItems)) OF SliceSupportItem
+
+EUTRACells-List  ::= SEQUENCE (SIZE (1.. maxCellineNB)) OF EUTRACells-List-item
+
+EUTRACells-List-item ::= SEQUENCE {
+	eUTRA-Cell-ID					EUTRA-Cell-ID,
+	served-EUTRA-Cells-Information	Served-EUTRA-Cells-Information,
+	iE-Extensions ProtocolExtensionContainer { { EUTRACells-List-itemExtIEs } }    OPTIONAL
+}
+
+EUTRACells-List-itemExtIEs    F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+EUTRA-Cell-ID ::= BIT STRING (SIZE(28))
+
+EUTRA-Coex-FDD-Info ::= SEQUENCE {
+	uL-EARFCN						ExtendedEARFCN					OPTIONAL,
+	dL-EARFCN						ExtendedEARFCN,
+	uL-Transmission-Bandwidth		EUTRA-Transmission-Bandwidth	OPTIONAL,
+	dL-Transmission-Bandwidth		EUTRA-Transmission-Bandwidth,
+	iE-Extensions					ProtocolExtensionContainer { {EUTRA-Coex-FDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+EUTRA-Coex-FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-ULCarrierList				CRITICALITY ignore	EXTENSION NRCarrierList				PRESENCE optional }|
+	{	ID id-DLCarrierList				CRITICALITY ignore EXTENSION NRCarrierList				PRESENCE optional },
+	...
+}
+
+EUTRA-Coex-Mode-Info ::= CHOICE {
+	fDD		EUTRA-Coex-FDD-Info,
+	tDD		EUTRA-Coex-TDD-Info,
+	...
+}
+
+EUTRA-Coex-TDD-Info ::= SEQUENCE {
+	eARFCN							ExtendedEARFCN,
+	transmission-Bandwidth			EUTRA-Transmission-Bandwidth,
+	subframeAssignment				EUTRA-SubframeAssignment,
+	specialSubframe-Info			EUTRA-SpecialSubframe-Info,
+	iE-Extensions					ProtocolExtensionContainer { {EUTRA-Coex-TDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+EUTRA-Coex-TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+EUTRA-CyclicPrefixDL ::= ENUMERATED { 
+	normal,
+	extended,
+	...
+}
+
+EUTRA-CyclicPrefixUL ::= ENUMERATED { 
+	normal,
+	extended,
+	...
+}
+
+EUTRA-PRACH-Configuration ::= SEQUENCE {
+	rootSequenceIndex						INTEGER (0..837),
+	zeroCorrelationIndex					INTEGER (0..15),
+	highSpeedFlag							BOOLEAN,
+	prach-FreqOffset						INTEGER (0..94),
+	prach-ConfigIndex						INTEGER (0..63)		OPTIONAL,
+	-- C-ifTDD: This IE shall be present if the EUTRA-Mode-Info IE in the Resource Coordination E-UTRA Cell Information IE is set to the value "TDD"
+	iE-Extensions							ProtocolExtensionContainer { {EUTRA-PRACH-Configuration-ExtIEs} }	OPTIONAL,
+	...
+}
+
+EUTRA-PRACH-Configuration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+EUTRA-SpecialSubframe-Info ::= SEQUENCE {
+	specialSubframePatterns		EUTRA-SpecialSubframePatterns,
+	cyclicPrefixDL				EUTRA-CyclicPrefixDL,
+	cyclicPrefixUL				EUTRA-CyclicPrefixUL,
+	iE-Extensions				ProtocolExtensionContainer { { EUTRA-SpecialSubframe-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+EUTRA-SpecialSubframe-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+EUTRA-SpecialSubframePatterns ::= ENUMERATED { 
+	ssp0,
+	ssp1, 
+	ssp2,
+	ssp3,
+	ssp4,
+	ssp5,
+	ssp6,
+	ssp7,
+	ssp8,
+	ssp9,
+	ssp10,
+	...
+}
+
+EUTRA-SubframeAssignment ::= ENUMERATED { 
+	sa0,
+	sa1, 
+	sa2,
+	sa3,
+	sa4,
+	sa5,
+	sa6,
+	...
+}
+
+EUTRA-Transmission-Bandwidth ::= ENUMERATED {
+	bw6,
+	bw15,
+	bw25,
+	bw50,
+	bw75,
+	bw100,
+	...
+}
+
+EUTRANQoS	::= SEQUENCE {
+	qCI								QCI,
+	allocationAndRetentionPriority	AllocationAndRetentionPriority,
+	gbrQosInformation				GBR-QosInformation									OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { EUTRANQoS-ExtIEs} }	OPTIONAL,
+	...
+}
+
+EUTRANQoS-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ExecuteDuplication ::= ENUMERATED{true,...}
+
+ExtendedEARFCN ::= INTEGER (0..262143)
+
+EUTRA-Mode-Info ::= CHOICE {
+	eUTRAFDD		EUTRA-FDD-Info,
+	eUTRATDD		EUTRA-TDD-Info,
+	choice-extension	ProtocolIE-SingleContainer { { EUTRA-Mode-Info-ExtIEs} }
+}
+
+EUTRA-Mode-Info-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+EUTRA-NR-CellResourceCoordinationReq-Container	::= OCTET STRING
+
+EUTRA-NR-CellResourceCoordinationReqAck-Container	::= OCTET STRING
+
+EUTRA-FDD-Info ::= SEQUENCE {
+	uL-offsetToPointA				OffsetToPointA,
+	dL-offsetToPointA				OffsetToPointA,
+	iE-Extensions					ProtocolExtensionContainer { {EUTRA-FDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+EUTRA-FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+EUTRA-TDD-Info ::= SEQUENCE {
+	offsetToPointA					OffsetToPointA,
+	iE-Extensions					ProtocolExtensionContainer { {EUTRA-TDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+EUTRA-TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+EventType ::= ENUMERATED {
+	on-demand,
+	periodic,
+	stop,
+	...
+}
+
+ExtendedPacketDelayBudget ::= INTEGER (1..65535, ...)
+
+-- F
+
+FDD-Info ::= SEQUENCE {
+	uL-NRFreqInfo						NRFreqInfo,
+	dL-NRFreqInfo						NRFreqInfo,
+	uL-Transmission-Bandwidth		Transmission-Bandwidth,
+	dL-Transmission-Bandwidth		Transmission-Bandwidth,
+	iE-Extensions					ProtocolExtensionContainer { {FDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+Flows-Mapped-To-DRB-List	::=	SEQUENCE (SIZE(1.. maxnoofQoSFlows)) OF Flows-Mapped-To-DRB-Item
+
+Flows-Mapped-To-DRB-Item 	::= SEQUENCE {
+	qoSFlowIdentifier							QoSFlowIdentifier,
+	qoSFlowLevelQoSParameters				QoSFlowLevelQoSParameters,
+	iE-Extensions							ProtocolExtensionContainer { { Flows-Mapped-To-DRB-ItemExtIEs} } OPTIONAL
+}
+
+Flows-Mapped-To-DRB-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-QoSFlowMappingIndication		CRITICALITY ignore	EXTENSION QoSFlowMappingIndication			PRESENCE optional}|
+	{ID id-TSCTrafficCharacteristics	CRITICALITY ignore	EXTENSION TSCTrafficCharacteristics			PRESENCE optional},
+	...
+}
+
+FR1-Bandwidth ::= ENUMERATED {bw5, bw10, bw20, bw40, bw50, bw80, bw100, ...}
+
+FR2-Bandwidth ::= ENUMERATED {bw50, bw100, bw200, bw400, ...}
+
+FreqBandNrItem ::= SEQUENCE {
+	freqBandIndicatorNr 		INTEGER (1..1024,...), 
+	supportedSULBandList		SEQUENCE (SIZE(0..maxnoofNrCellBands)) OF SupportedSULFreqBandItem,
+	iE-Extensions				ProtocolExtensionContainer { {FreqBandNrItem-ExtIEs} } OPTIONAL,
+	...
+}
+
+FreqBandNrItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+FreqDomainLength ::= CHOICE {
+	l839							L839Info,
+	l139							L139Info,
+	choice-extension				ProtocolIE-SingleContainer { {FreqDomainLength-ExtIEs} }
+}
+
+FreqDomainLength-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+FrequencyShift7p5khz ::= ENUMERATED {false, true, ...}
+
+FullConfiguration ::= ENUMERATED {full, ...}
+
+FlowsMappedToSLDRB-List ::= SEQUENCE (SIZE(1.. maxnoofPC5QoSFlows)) OF FlowsMappedToSLDRB-Item 
+
+FlowsMappedToSLDRB-Item ::= SEQUENCE {
+	pc5QoSFlowIdentifier			PC5QoSFlowIdentifier,
+	iE-Extensions					ProtocolExtensionContainer { {FlowsMappedToSLDRB-Item-ExtIEs} } OPTIONAL,
+	...
+}
+
+FlowsMappedToSLDRB-Item-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- G
+
+
+GBR-QosInformation ::= SEQUENCE {
+	e-RAB-MaximumBitrateDL			BitRate,
+	e-RAB-MaximumBitrateUL			BitRate,
+	e-RAB-GuaranteedBitrateDL		BitRate,
+	e-RAB-GuaranteedBitrateUL		BitRate,
+	iE-Extensions					ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+GBR-QosInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GBR-QoSFlowInformation::= SEQUENCE {
+	maxFlowBitRateDownlink			BitRate,
+	maxFlowBitRateUplink			BitRate, 
+	guaranteedFlowBitRateDownlink	BitRate,
+	guaranteedFlowBitRateUplink		BitRate, 
+	maxPacketLossRateDownlink		MaxPacketLossRate		OPTIONAL,
+	maxPacketLossRateUplink			MaxPacketLossRate		OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { GBR-QosFlowInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+GBR-QosFlowInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ 	ID id-AlternativeQoSParaSetList	CRITICALITY ignore	EXTENSION AlternativeQoSParaSetList	PRESENCE optional	},
+	...
+}
+
+CG-Config ::= OCTET STRING
+
+GeographicalCoordinates ::= SEQUENCE {
+	tRPPositionDefinitionType	TRPPositionDefinitionType,
+	dLPRSResourceCoordinates	DLPRSResourceCoordinates	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { GeographicalCoordinates-ExtIEs } } OPTIONAL
+}
+
+GeographicalCoordinates-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNBCUMeasurementID ::= INTEGER (0.. 4095, ...)
+
+GNBDUMeasurementID ::= INTEGER (0.. 4095, ...)
+
+GNB-CUSystemInformation::= SEQUENCE {
+	sibtypetobeupdatedlist	SEQUENCE (SIZE(1.. maxnoofSIBTypes)) OF SibtypetobeupdatedListItem,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CUSystemInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+GNB-CUSystemInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-systemInformationAreaID  CRITICALITY ignore	EXTENSION SystemInformationAreaID PRESENCE optional},
+	...
+}
+
+GNB-CU-TNL-Association-Setup-Item::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CU-TNL-Association-Setup-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-Setup-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-CU-TNL-Association-Failed-To-Setup-Item ::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	cause									Cause,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CU-TNL-Association-Failed-To-Setup-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-Failed-To-Setup-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+GNB-CU-TNL-Association-To-Add-Item ::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	tNLAssociationUsage							TNLAssociationUsage,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CU-TNL-Association-To-Add-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-To-Add-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-CU-TNL-Association-To-Remove-Item::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	iE-Extensions							ProtocolExtensionContainer { { GNB-CU-TNL-Association-To-Remove-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-To-Remove-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-TNLAssociationTransportLayerAddressgNBDU	CRITICALITY reject	EXTENSION CP-TransportLayerAddress	PRESENCE optional},
+	...
+}
+
+
+GNB-CU-TNL-Association-To-Update-Item::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	tNLAssociationUsage						TNLAssociationUsage OPTIONAL,
+	iE-Extensions							ProtocolExtensionContainer { { GNB-CU-TNL-Association-To-Update-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-To-Update-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-CU-UE-F1AP-ID		::= INTEGER (0..4294967295)
+
+GNB-DU-Cell-Resource-Configuration	::= SEQUENCE { 
+	subcarrierSpacing				SubcarrierSpacing,
+	dUFTransmissionPeriodicity		DUFTransmissionPeriodicity	OPTIONAL,
+	dUF-Slot-Config-List			DUF-Slot-Config-List	OPTIONAL,
+	hSNATransmissionPeriodicity		HSNATransmissionPeriodicity,
+	hNSASlotConfigList				HSNASlotConfigList	OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-DU-Cell-Resource-Configuration-ExtIEs } } OPTIONAL
+}
+
+GNB-DU-Cell-Resource-Configuration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-DU-UE-F1AP-ID		::= INTEGER (0..4294967295)
+
+GNB-DU-ID			::= INTEGER (0..68719476735)
+
+GNB-CU-Name ::= PrintableString(SIZE(1..150,...))
+
+GNB-DU-Name ::= PrintableString(SIZE(1..150,...)) 
+
+Extended-GNB-CU-Name	 ::= SEQUENCE {
+	gNB-CU-NameVisibleString		GNB-CU-NameVisibleString					OPTIONAL,
+	gNB-CU-NameUTF8String			GNB-CU-NameUTF8String						OPTIONAL, 
+	iE-Extensions					ProtocolExtensionContainer { { Extended-GNB-CU-Name-ExtIEs } } OPTIONAL,
+	...
+}
+
+Extended-GNB-CU-Name-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-CU-NameVisibleString ::= VisibleString(SIZE(1..150,...))
+
+GNB-CU-NameUTF8String ::= UTF8String(SIZE(1..150,...))
+
+Extended-GNB-DU-Name	 ::= SEQUENCE {
+	gNB-DU-NameVisibleString		GNB-DU-NameVisibleString					OPTIONAL,
+	gNB-DU-NameUTF8String			GNB-DU-NameUTF8String						OPTIONAL, 
+	iE-Extensions					ProtocolExtensionContainer { { Extended-GNB-DU-Name-ExtIEs } } OPTIONAL,
+	...
+}
+
+Extended-GNB-DU-Name-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-DU-NameVisibleString ::= VisibleString(SIZE(1..150,...))
+
+GNB-DU-NameUTF8String ::= UTF8String(SIZE(1..150,...))
+
+
+GNB-DU-Served-Cells-Item ::= SEQUENCE {
+	served-Cell-Information		Served-Cell-Information,
+	gNB-DU-System-Information	GNB-DU-System-Information	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { GNB-DU-Served-Cells-ItemExtIEs} }	OPTIONAL,
+	...
+}
+
+GNB-DU-Served-Cells-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-DU-System-Information ::= SEQUENCE {
+	mIB-message		MIB-message,
+	sIB1-message		SIB1-message,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-DU-System-Information-ExtIEs } } OPTIONAL,
+	...
+}
+
+GNB-DU-System-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-SIB12-message		CRITICALITY ignore	EXTENSION SIB12-message		PRESENCE optional}|
+	{ ID id-SIB13-message		CRITICALITY ignore	EXTENSION SIB13-message		PRESENCE optional}|
+	{ ID id-SIB14-message		CRITICALITY ignore	EXTENSION SIB14-message		PRESENCE optional}|
+	{ ID id-SIB10-message		CRITICALITY ignore	EXTENSION SIB10-message		PRESENCE optional},
+	...
+}
+
+GNB-DUConfigurationQuery ::= ENUMERATED {true, ...}
+
+GNBDUOverloadInformation ::= ENUMERATED {overloaded, not-overloaded}
+
+GNB-DU-TNL-Association-To-Remove-Item::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	tNLAssociationTransportLayerAddressgNBCU		CP-TransportLayerAddress		OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-DU-TNL-Association-To-Remove-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-DU-TNL-Association-To-Remove-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-RxTxTimeDiff ::= SEQUENCE {
+	rxTxTimeDiff			GNBRxTxTimeDiffMeas,
+	additionalPath-List		AdditionalPath-List		OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { { GNB-RxTxTimeDiff-ExtIEs} }  OPTIONAL
+}
+
+GNB-RxTxTimeDiff-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+
+	...
+}
+
+GNBRxTxTimeDiffMeas ::= CHOICE {
+	k0			INTEGER (0.. 1970049),
+	k1			INTEGER (0.. 985025),
+	k2			INTEGER (0.. 492513),
+	k3			INTEGER (0.. 246257),
+	k4			INTEGER (0.. 123129),
+	k5			INTEGER (0.. 61565),
+	choice-extension		ProtocolIE-SingleContainer { { GNBRxTxTimeDiffMeas-ExtIEs } } 
+}
+
+GNBRxTxTimeDiffMeas-ExtIEs		F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+GNBSetID ::= BIT STRING (SIZE(22))
+
+GTP-TEID				::= OCTET STRING (SIZE (4))
+
+GTPTLAs	::= SEQUENCE (SIZE(1.. maxnoofGTPTLAs)) OF	GTPTLA-Item
+
+
+GTPTLA-Item	::= SEQUENCE {
+	gTPTransportLayerAddress				TransportLayerAddress,
+	iE-Extensions	ProtocolExtensionContainer { { GTPTLA-Item-ExtIEs } }			OPTIONAL
+}
+
+GTPTLA-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GTPTunnel				::= SEQUENCE {
+	transportLayerAddress		TransportLayerAddress,
+	gTP-TEID		GTP-TEID,
+	iE-Extensions					ProtocolExtensionContainer { { GTPTunnel-ExtIEs } } OPTIONAL,
+	...
+}
+
+GTPTunnel-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- H
+
+HandoverPreparationInformation ::= OCTET STRING
+
+HardwareLoadIndicator ::= SEQUENCE {
+	dLHardwareLoadIndicator			INTEGER (0..100, ...),
+	uLHardwareLoadIndicator			INTEGER (0..100, ...),
+	iE-Extensions					ProtocolExtensionContainer { { HardwareLoadIndicator-ExtIEs } } 	OPTIONAL,
+	...
+}
+
+HardwareLoadIndicator-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+HSNASlotConfigList ::= SEQUENCE (SIZE(1..maxnoofHSNASlots)) OF HSNASlotConfigItem
+
+HSNASlotConfigItem 	::=	SEQUENCE {
+	hSNADownlink			HSNADownlink 		OPTIONAL,
+	hSNAUplink				HSNAUplink 			OPTIONAL,
+	hSNAFlexible			HSNAFlexible 		OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { { HSNASlotConfigItem-ExtIEs } } OPTIONAL
+}
+
+HSNASlotConfigItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+HSNADownlink ::= ENUMERATED { hard, soft, notavailable }
+
+HSNAFlexible ::= ENUMERATED { hard, soft, notavailable }
+
+HSNAUplink ::= ENUMERATED { hard, soft, notavailable }
+
+HSNATransmissionPeriodicity ::=	ENUMERATED { ms0p5, ms0p625, ms1, ms1p25, ms2, ms2p5, ms5, ms10, ms20, ms40, ms80, ms160, ...}
+
+-- I
+
+IAB-Barred	::=	ENUMERATED {barred, not-barred, ...}
+
+IAB-Info-IAB-donor-CU ::=	SEQUENCE{
+	iAB-STC-Info	IAB-STC-Info	OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { IAB-Info-IAB-donor-CU-ExtIEs } } OPTIONAL
+}
+
+IAB-Info-IAB-donor-CU-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-Info-IAB-DU ::=	SEQUENCE{
+	multiplexingInfo		MultiplexingInfo	OPTIONAL,
+	iAB-STC-Info		IAB-STC-Info	OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { IAB-Info-IAB-DU-ExtIEs } } OPTIONAL
+}
+
+IAB-Info-IAB-DU-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-MT-Cell-List ::= SEQUENCE (SIZE(1..maxnoofServingCells)) OF IAB-MT-Cell-List-Item
+
+IAB-MT-Cell-List-Item ::= 	SEQUENCE {
+	nRCellIdentity				NRCellIdentity,
+	dU-RX-MT-RX					DU-RX-MT-RX,
+	dU-TX-MT-TX					DU-TX-MT-TX,
+	dU-RX-MT-TX					DU-RX-MT-TX,
+	dU-TX-MT-RX					DU-TX-MT-RX,
+	iE-Extensions				ProtocolExtensionContainer { { IAB-MT-Cell-List-Item-ExtIEs } } OPTIONAL
+}
+
+IAB-MT-Cell-List-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-STC-Info	::=	SEQUENCE{
+	iAB-STC-Info-List	IAB-STC-Info-List,
+	iE-Extensions		ProtocolExtensionContainer { { IAB-STC-Info-ExtIEs } } OPTIONAL
+}
+
+IAB-STC-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-STC-Info-List ::= 	SEQUENCE (SIZE(1..maxnoofIABSTCInfo)) OF IAB-STC-Info-Item
+
+IAB-STC-Info-Item::=	SEQUENCE {
+	sSB-freqInfo						SSB-freqInfo,
+	sSB-subcarrierSpacing				SSB-subcarrierSpacing,
+	sSB-transmissionPeriodicity			SSB-transmissionPeriodicity,
+	sSB-transmissionTimingOffset		SSB-transmissionTimingOffset,
+	sSB-transmissionBitmap				SSB-transmissionBitmap,
+	iE-Extensions		ProtocolExtensionContainer { { IAB-STC-Info-Item-ExtIEs } } OPTIONAL
+}
+
+IAB-STC-Info-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-Allocated-TNL-Address-Item	::= SEQUENCE {
+	iABTNLAddress				IABTNLAddress,
+	iABTNLAddressUsage			IABTNLAddressUsage	 	OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { IAB-Allocated-TNL-Address-Item-ExtIEs } } OPTIONAL
+}
+
+IAB-Allocated-TNL-Address-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-DU-Cell-Resource-Configuration-Mode-Info	::=	CHOICE {
+	fDD		IAB-DU-Cell-Resource-Configuration-FDD-Info,
+	tDD		IAB-DU-Cell-Resource-Configuration-TDD-Info,
+	choice-extension			ProtocolIE-SingleContainer { { IAB-DU-Cell-Resource-Configuration-Mode-Info-ExtIEs} }
+}
+
+IAB-DU-Cell-Resource-Configuration-Mode-Info-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+IAB-DU-Cell-Resource-Configuration-FDD-Info ::= SEQUENCE {
+	gNB-DU-Cell-Resource-Configuration-FDD-UL				GNB-DU-Cell-Resource-Configuration,
+	gNB-DU-Cell-Resource-Configuration-FDD-DL				GNB-DU-Cell-Resource-Configuration,
+	iE-Extensions					ProtocolExtensionContainer { {IAB-DU-Cell-Resource-Configuration-FDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+IAB-DU-Cell-Resource-Configuration-FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-DU-Cell-Resource-Configuration-TDD-Info ::= SEQUENCE {
+	gNB-DU-Cell-Resourc-Configuration-TDD				GNB-DU-Cell-Resource-Configuration,
+	iE-Extensions					ProtocolExtensionContainer { {IAB-DU-Cell-Resource-Configuration-TDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+IAB-DU-Cell-Resource-Configuration-TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IABIPv6RequestType	 ::= CHOICE {
+	iPv6Address						IABTNLAddressesRequested,
+	iPv6Prefix						IABTNLAddressesRequested, 
+	choice-extension				ProtocolIE-SingleContainer { { IABIPv6RequestType-ExtIEs} }
+}
+
+IABIPv6RequestType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+IABTNLAddress ::= CHOICE {
+	iPv4Address						BIT STRING (SIZE(32)), 
+	iPv6Address						BIT STRING (SIZE(128)), 
+	iPv6Prefix						BIT STRING (SIZE(64)), 
+	choice-extension				ProtocolIE-SingleContainer { { IABTNLAddress-ExtIEs} }
+}
+
+IABTNLAddress-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+IABTNLAddressesRequested ::= SEQUENCE {
+	tNLAddressesOrPrefixesRequestedAllTraffic	INTEGER (1..256) 	OPTIONAL,
+	tNLAddressesOrPrefixesRequestedF1-C			INTEGER (1..256) 	OPTIONAL,
+	tNLAddressesOrPrefixesRequestedF1-U			INTEGER (1..256) 	OPTIONAL,
+	tNLAddressesOrPrefixesRequestedNoNF1		INTEGER (1..256) 	OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { IABTNLAddressesRequested-ExtIEs } } OPTIONAL
+}
+
+IABTNLAddressesRequested-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-TNL-Addresses-To-Remove-Item ::= SEQUENCE {
+	iABTNLAddress			IABTNLAddress,
+	iE-Extensions		ProtocolExtensionContainer { { IAB-TNL-Addresses-To-Remove-Item-ExtIEs} } OPTIONAL
+}
+
+IAB-TNL-Addresses-To-Remove-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IABTNLAddressUsage ::= ENUMERATED {
+	f1-c,
+	f1-u,
+	non-f1,
+	...
+}
+
+
+IABv4AddressesRequested ::= SEQUENCE {
+	iABv4AddressesRequested			IABTNLAddressesRequested,
+	iE-Extensions		ProtocolExtensionContainer { { IABv4AddressesRequested-ExtIEs} } OPTIONAL
+}
+
+IABv4AddressesRequested-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ImplicitFormat	::= SEQUENCE	{ 
+	dUFSlotformatIndex 			DUFSlotformatIndex,
+	iE-Extensions		ProtocolExtensionContainer { { ImplicitFormat-ExtIEs } } OPTIONAL
+}
+
+ImplicitFormat-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IgnorePRACHConfiguration::= ENUMERATED { true,...}
+
+IgnoreResourceCoordinationContainer ::= ENUMERATED { yes,...}
+InactivityMonitoringRequest ::= ENUMERATED { true,...}
+InactivityMonitoringResponse ::= ENUMERATED { not-supported,...}
+InterfacesToTrace ::= BIT STRING (SIZE(8))
+
+IntendedTDD-DL-ULConfig ::= SEQUENCE {
+	nRSCS						ENUMERATED { scs15, scs30, scs60, scs120,...},
+	nRCP						ENUMERATED { normal, extended,...},
+	nRDLULTxPeriodicity			ENUMERATED { ms0p5, ms0p625, ms1, ms1p25, ms2, ms2p5, ms3, ms4, ms5, ms10, ms20, ms40, ms60, ms80, ms100, ms120, ms140, ms160, ...},
+	slot-Configuration-List 	Slot-Configuration-List,
+	iE-Extensions						ProtocolExtensionContainer { {IntendedTDD-DL-ULConfig-ExtIEs} } OPTIONAL
+}
+
+IntendedTDD-DL-ULConfig-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IPHeaderInformation ::= SEQUENCE {
+	destinationIABTNLAddress			IABTNLAddress,
+	dsInformationList					DSInformationList	OPTIONAL,
+	iPv6FlowLabel						BIT STRING (SIZE (20))	OPTIONAL,
+	iE-Extensions						ProtocolExtensionContainer { { IPHeaderInformation-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+IPHeaderInformation-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IPtolayer2TrafficMappingInfo ::= SEQUENCE {
+	iPtolayer2TrafficMappingInfoToAdd					IPtolayer2TrafficMappingInfoList		OPTIONAL,
+	iPtolayer2TrafficMappingInfoToRemove				MappingInformationtoRemove				OPTIONAL,
+	iE-Extensions										ProtocolExtensionContainer { { IPtolayer2TrafficMappingInfo-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+IPtolayer2TrafficMappingInfoList ::= SEQUENCE (SIZE(1..maxnoofMappingEntries)) OF IPtolayer2TrafficMappingInfo-Item
+
+IPtolayer2TrafficMappingInfo-Item ::= SEQUENCE {
+	mappingInformationIndex		MappingInformationIndex,		
+	iPHeaderInformation			IPHeaderInformation,
+	bHInfo	 					BHInfo,	iE-Extensions				ProtocolExtensionContainer { { IPtolayer2TrafficMappingInfo-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+IPtolayer2TrafficMappingInfo-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- J
+
+-- K
+
+-- L
+
+L139Info ::= SEQUENCE {
+	msg1SCS						ENUMERATED {scs15, scs30, scs60, scs120, ...},
+	rootSequenceIndex			INTEGER (0..137)								OPTIONAL,
+	iE-Extension				ProtocolExtensionContainer { {L139Info-ExtIEs} } 		OPTIONAL,
+	...
+}
+
+L139Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+L839Info ::= SEQUENCE {
+	rootSequenceIndex			INTEGER (0..837),
+	restrictedSetConfig			ENUMERATED {unrestrictedSet, restrictedSetTypeA,
+											restrictedSetTypeB, ...},
+	iE-Extension		ProtocolExtensionContainer { {L839Info-ExtIEs} } 		OPTIONAL,
+	...
+}
+
+L839Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+LCID ::= INTEGER (1..32, ...)
+
+
+LCStoGCSTranslationList ::= SEQUENCE (SIZE (1.. maxnooflcs-gcs-translation)) OF LCStoGCSTranslation
+
+LCStoGCSTranslation ::= SEQUENCE {
+	alpha			INTEGER (0..359),
+	alpha-fine		INTEGER (0..9),
+	beta			INTEGER (0..359),
+	beta-fine		INTEGER (0..9),
+	gamma			INTEGER (0..359),
+	gamma-fine		INTEGER (0..9),
+	iE-Extensions				ProtocolExtensionContainer { {LCStoGCSTranslation-ExtIEs} } OPTIONAL
+}
+
+LCStoGCSTranslation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+LMF-MeasurementID ::= INTEGER (1.. 65536, ...)
+
+LMF-UE-MeasurementID ::= INTEGER (1.. 256, ...)
+
+LocationUncertainty ::= SEQUENCE {
+	horizontalUncertainty		INTEGER (0..255),
+	horizontalConfidence		INTEGER (0..100),
+	verticalUncertainty			INTEGER (0..255),
+	verticalConfidence			INTEGER (0..100),
+	iE-Extensions				ProtocolExtensionContainer { { LocationUncertainty-ExtIEs} } OPTIONAL
+}
+
+LocationUncertainty-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+LongDRXCycleLength ::= 	ENUMERATED
+{ms10, ms20, ms32, ms40, ms60, ms64, ms70, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ms1024, ms1280, ms2048, ms2560, ms5120, ms10240, ...}
+
+LowerLayerPresenceStatusChange ::= ENUMERATED {
+	suspend-lower-layers,
+	resume-lower-layers,
+	...
+
+}
+
+LTEUESidelinkAggregateMaximumBitrate ::= SEQUENCE {
+	uELTESidelinkAggregateMaximumBitrate		BitRate,
+	iE-Extensions					ProtocolExtensionContainer { {LTEUESidelinkAggregateMaximumBitrate-ExtIEs} } OPTIONAL
+}
+
+LTEUESidelinkAggregateMaximumBitrate-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+LTEV2XServicesAuthorized ::= SEQUENCE {
+	vehicleUE			VehicleUE														OPTIONAL,
+	pedestrianUE 		PedestrianUE													OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { {LTEV2XServicesAuthorized-ExtIEs} }		OPTIONAL
+}
+
+LTEV2XServicesAuthorized-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- M
+
+MappingInformationIndex	::= BIT STRING (SIZE (26))
+
+MappingInformationtoRemove	::= SEQUENCE (SIZE(1..maxnoofMappingEntries)) OF MappingInformationIndex
+
+MaskedIMEISV ::= 	BIT STRING (SIZE (64))
+
+MaxDataBurstVolume  ::= INTEGER (0..4095, ..., 4096.. 2000000) 
+MaxPacketLossRate ::= INTEGER (0..1000)
+
+MIB-message ::= OCTET STRING
+
+MeasConfig ::= OCTET STRING
+
+MeasGapConfig ::= OCTET STRING
+
+MeasGapSharingConfig ::= OCTET STRING
+
+MeasurementBeamInfoRequest ::= ENUMERATED {true, ...}
+
+MeasurementBeamInfo	 ::= SEQUENCE {
+	pRS-Resource-ID				PRS-Resource-ID		OPTIONAL,
+	pRS-Resource-Set-ID			PRS-Resource-Set-ID	OPTIONAL,
+	sSB-Index					SSB-Index			OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { MeasurementBeamInfo-ExtIEs} } OPTIONAL
+}
+
+MeasurementBeamInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+MeasurementTimingConfiguration ::= OCTET STRING
+
+MessageIdentifier ::= BIT STRING (SIZE (16))
+
+MultiplexingInfo 	::=	SEQUENCE{
+	iAB-MT-Cell-List 	IAB-MT-Cell-List,
+	iE-Extensions		ProtocolExtensionContainer { {MultiplexingInfo-ExtIEs} } OPTIONAL
+}
+
+MultiplexingInfo-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+M2Configuration ::= ENUMERATED {true, ...}
+
+
+M5Configuration ::= SEQUENCE {
+	m5period			M5period,
+	m5-links-to-log		M5-Links-to-log,
+	iE-Extensions		ProtocolExtensionContainer { { M5Configuration-ExtIEs} } OPTIONAL,
+	...
+}
+
+M5Configuration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+M5period ::= ENUMERATED { ms1024, ms2048, ms5120, ms10240, min1, ... } 
+
+M5-Links-to-log	::= ENUMERATED {uplink, downlink, both-uplink-and-downlink, ...}
+
+
+M6Configuration ::= SEQUENCE {
+	m6report-Interval	M6report-Interval,
+	m6-links-to-log		M6-Links-to-log,
+	iE-Extensions		ProtocolExtensionContainer { { M6Configuration-ExtIEs} } OPTIONAL,
+	...
+}
+
+M6Configuration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+M6report-Interval ::= ENUMERATED { ms120, ms240, ms640, ms1024, ms2048, ms5120, ms10240, ms20480, ms40960, min1, min6, min12, min30, ... }
+
+
+
+M6-Links-to-log	::= ENUMERATED {uplink, downlink, both-uplink-and-downlink, ...}
+
+
+M7Configuration ::= SEQUENCE {
+	m7period			M7period,
+	m7-links-to-log		M7-Links-to-log,
+	iE-Extensions		ProtocolExtensionContainer { { M7Configuration-ExtIEs} } OPTIONAL,
+	...
+}
+
+M7Configuration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+M7period	::= INTEGER(1..60, ...)
+
+M7-Links-to-log	::= ENUMERATED {downlink, ...}
+
+MDT-Activation ::= ENUMERATED { 
+	immediate-MDT-only,
+	immediate-MDT-and-Trace,
+	...
+}
+
+MDTConfiguration ::= SEQUENCE {
+	mdt-Activation				MDT-Activation,
+	measurementsToActivate		MeasurementsToActivate,
+	m2Configuration				M2Configuration		OPTIONAL,
+	--  C-ifM2: This IE shall be present if the Measurements to Activate IE has the second bit set to "1".
+	m5Configuration				M5Configuration		OPTIONAL,
+	--  C-ifM5: This IE shall be present if the Measurements to Activate IE has the fifth bit set to "1".
+	m6Configuration				M6Configuration		OPTIONAL,
+	--  C-ifM6: This IE shall be present if the Measurements to Activate IE has the seventh bit set to "1".
+	m7Configuration				M7Configuration		OPTIONAL,
+	--  C-ifM7: This IE shall be present if the Measurements to Activate IE has the eighth bit set to "1".
+	iE-Extensions				ProtocolExtensionContainer { { MDTConfiguration-ExtIEs} } OPTIONAL,
+	...
+}
+MDTConfiguration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+MDTPLMNList ::= SEQUENCE (SIZE(1..maxnoofMDTPLMNs)) OF PLMN-Identity
+
+
+MeasuredResultsValue ::= CHOICE {
+	uL-AngleOfArrival	UL-AoA,
+	uL-SRS-RSRP			UL-SRS-RSRP,
+	uL-RTOA				UL-RTOA-Measurement,
+	gNB-RxTxTimeDiff	GNB-RxTxTimeDiff,
+	choice-extension	ProtocolIE-SingleContainer { { MeasuredResultsValue-ExtIEs } }
+}
+
+MeasuredResultsValue-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+MeasurementsToActivate ::= BIT STRING (SIZE (8))
+
+-- N
+
+NeedforGap::= ENUMERATED {true, ...}
+
+Neighbour-Cell-Information-Item ::= SEQUENCE {
+	nRCGI				NRCGI, 
+	intendedTDD-DL-ULConfig		IntendedTDD-DL-ULConfig OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { Neighbour-Cell-Information-ItemExtIEs } }	OPTIONAL
+}
+
+Neighbour-Cell-Information-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NGRANAllocationAndRetentionPriority ::= SEQUENCE {
+	priorityLevel				PriorityLevel,
+	pre-emptionCapability		Pre-emptionCapability,
+	pre-emptionVulnerability	Pre-emptionVulnerability,
+	iE-Extensions				ProtocolExtensionContainer { {NGRANAllocationAndRetentionPriority-ExtIEs} } OPTIONAL
+}
+
+NGRANAllocationAndRetentionPriority-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+NGRANHighAccuracyAccessPointPosition ::= SEQUENCE {
+	latitude					INTEGER (-2147483648.. 2147483647),
+	longitude					INTEGER (-2147483648.. 2147483647),
+	altitude					INTEGER (-64000..1280000),
+	uncertaintySemi-major		INTEGER (0..255),
+	uncertaintySemi-minor		INTEGER (0..255),
+	orientationOfMajorAxis		INTEGER (0..179),
+	horizontalConfidence		INTEGER (0..100),
+	uncertaintyAltitude			INTEGER (0..255),
+	verticalConfidence			INTEGER (0..100), 
+
+	iE-Extensions				ProtocolExtensionContainer { { NGRANHighAccuracyAccessPointPosition-ExtIEs} } OPTIONAL
+}
+
+NGRANHighAccuracyAccessPointPosition-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NID ::= BIT STRING (SIZE(44))
+
+NR-CGI-List-For-Restart-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	iE-Extensions		ProtocolExtensionContainer { { NR-CGI-List-For-Restart-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+NR-CGI-List-For-Restart-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NR-PRSBeamInformation ::= SEQUENCE {
+	nR-PRSBeamInformationList		NR-PRSBeamInformationList,
+	lCStoGCSTranslationList 		LCStoGCSTranslationList,
+	iE-Extensions	ProtocolExtensionContainer { { NR-PRSBeamInformation-ExtIEs } } OPTIONAL
+}
+
+NR-PRSBeamInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NR-PRSBeamInformationList ::= SEQUENCE (SIZE(1.. maxnoofPRS-ResourceSets)) OF NR-PRSBeamInformationItem
+
+NR-PRSBeamInformationItem ::= SEQUENCE {
+	pRSResourceSetID	INTEGER (0..7),
+	pRSAngleList		PRSAngleList,
+	iE-Extensions	ProtocolExtensionContainer { { NR-PRSBeamInformationItem-ExtIEs } } OPTIONAL
+}
+
+NR-PRSBeamInformationItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NonDynamic5QIDescriptor	::= SEQUENCE {
+	fiveQI						INTEGER (0..255, ...),
+	qoSPriorityLevel			INTEGER (1..127)				OPTIONAL,
+	averagingWindow 			AveragingWindow					OPTIONAL,
+	maxDataBurstVolume			MaxDataBurstVolume				OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { NonDynamic5QIDescriptor-ExtIEs } } OPTIONAL
+}
+
+NonDynamic5QIDescriptor-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-CNPacketDelayBudgetDownlink	CRITICALITY ignore	EXTENSION ExtendedPacketDelayBudget		PRESENCE optional	}|
+	{ ID id-CNPacketDelayBudgetUplink	CRITICALITY ignore	EXTENSION ExtendedPacketDelayBudget		PRESENCE optional	},
+	...
+}
+
+NonDynamicPQIDescriptor	::= SEQUENCE {
+	fiveQI						INTEGER (0..255, ...),
+	qoSPriorityLevel			INTEGER (1..8, ...)				OPTIONAL,
+	averagingWindow 			AveragingWindow					OPTIONAL,
+	maxDataBurstVolume			MaxDataBurstVolume				OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { NonDynamicPQIDescriptor-ExtIEs } } OPTIONAL
+}
+
+NonDynamicPQIDescriptor-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NonUPTrafficType ::=	ENUMERATED {ue-associated, non-ue-associated, non-f1, bap-control-pdu,...}
+
+NoofDownlinkSymbols	::= INTEGER (0..14)
+
+NoofUplinkSymbols	::= INTEGER (0..14)
+
+Notification-Cause ::= ENUMERATED {fulfilled, not-fulfilled, ...}
+
+NotificationControl ::= ENUMERATED {active, not-active, ...}
+
+NotificationInformation ::= SEQUENCE {
+	message-Identifier	MessageIdentifier,
+	serialNumber		SerialNumber,
+	iE-Extensions	ProtocolExtensionContainer { { NotificationInformationExtIEs} } OPTIONAL,
+	...
+}
+
+NotificationInformationExtIEs		F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NPNBroadcastInformation ::= CHOICE {
+	sNPN-Broadcast-Information					NPN-Broadcast-Information-SNPN,
+	pNI-NPN-Broadcast-Information				NPN-Broadcast-Information-PNI-NPN,
+	choice-extension					ProtocolIE-SingleContainer { {NPNBroadcastInformation-ExtIEs} }
+}
+
+NPNBroadcastInformation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+NPN-Broadcast-Information-SNPN ::= SEQUENCE {
+	broadcastSNPNID-List		BroadcastSNPN-ID-List,
+	iE-Extension				ProtocolExtensionContainer { {NPN-Broadcast-Information-SNPN-ExtIEs} }	OPTIONAL,
+	...
+}
+
+NPN-Broadcast-Information-SNPN-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+NPN-Broadcast-Information-PNI-NPN ::= SEQUENCE {
+	broadcastPNI-NPN-ID-Information		BroadcastPNI-NPN-ID-List,
+	iE-Extension							ProtocolExtensionContainer { {NPN-Broadcast-Information-PNI-NPN-ExtIEs} }	OPTIONAL,
+	...
+}
+
+NPN-Broadcast-Information-PNI-NPN-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+NPNSupportInfo ::= CHOICE {
+	sNPN-Information		NID,
+	choice-extension		ProtocolIE-SingleContainer { { NPNSupportInfo-ExtIEs } } 
+}
+
+NPNSupportInfo-ExtIEs		F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+NRCarrierList ::= SEQUENCE (SIZE(1..maxnoofNRSCSs)) OF NRCarrierItem
+
+NRCarrierItem ::= SEQUENCE {
+	carrierSCS						NRSCS,
+	offsetToCarrier					INTEGER (0..2199, ...),
+	carrierBandwidth				INTEGER (0..maxnoofPhysicalResourceBlocks, ...),
+	iE-Extension			ProtocolExtensionContainer { {NRCarrierItem-ExtIEs} } 				OPTIONAL,
+	...
+}
+
+NRCarrierItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NRFreqInfo ::=  SEQUENCE {
+	nRARFCN			INTEGER (0..maxNRARFCN),
+	sul-Information	SUL-Information		OPTIONAL,
+	freqBandListNr	SEQUENCE (SIZE(1..maxnoofNrCellBands)) OF FreqBandNrItem,
+	iE-Extensions	ProtocolExtensionContainer { { NRFreqInfoExtIEs} } OPTIONAL,
+	...
+}
+
+NRFreqInfoExtIEs		F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-FrequencyShift7p5khz	CRITICALITY ignore	EXTENSION FrequencyShift7p5khz	PRESENCE optional },
+	...
+}
+
+NRCGI ::= SEQUENCE {
+	pLMN-Identity			PLMN-Identity,
+	nRCellIdentity			NRCellIdentity,
+	iE-Extensions			ProtocolExtensionContainer { {NRCGI-ExtIEs} } OPTIONAL,
+	...
+}
+
+NRCGI-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NR-Mode-Info ::= CHOICE {
+	fDD		FDD-Info,
+	tDD		TDD-Info,
+	choice-extension			ProtocolIE-SingleContainer { { NR-Mode-Info-ExtIEs} }
+}
+
+NR-Mode-Info-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+
+
+NRPRACHConfig ::= SEQUENCE {
+	ulPRACHConfigList			NRPRACHConfigList									OPTIONAL,
+	sulPRACHConfigList			NRPRACHConfigList									OPTIONAL,
+	iE-Extension				ProtocolExtensionContainer { {NRPRACHConfig-ExtIEs} } 	OPTIONAL,
+	...
+}
+
+NRPRACHConfig-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NRCellIdentity ::= BIT STRING (SIZE(36))
+
+NRNRB ::= ENUMERATED { nrb11, nrb18, nrb24, nrb25, nrb31, nrb32, nrb38, nrb51, nrb52, nrb65, nrb66, nrb78, nrb79, nrb93, nrb106, nrb107, nrb121, nrb132, nrb133, nrb135, nrb160, nrb162, nrb189, nrb216, nrb217, nrb245, nrb264, nrb270, nrb273, ...}
+
+NRPCI ::= INTEGER(0..1007)
+
+
+NRPRACHConfigList ::= SEQUENCE (SIZE(0..maxnoofPRACHconfigs)) OF NRPRACHConfigItem
+
+NRPRACHConfigItem ::= SEQUENCE {
+	nRSCS					NRSCS,
+	prachFreqStartfromCarrier	INTEGER (0..maxnoofPhysicalResourceBlocks-1, ...),
+	msg1FDM						ENUMERATED {one, two, four, eight, ...},
+	parchConfigIndex			INTEGER (0..255, ...),
+	ssb-perRACH-Occasion		ENUMERATED {oneEighth, oneFourth, oneHalf, one, 
+											two, four, eight, sixteen, ...},
+	freqDomainLength			FreqDomainLength, 
+	zeroCorrelZoneConfig		INTEGER (0..15),
+	iE-Extension		ProtocolExtensionContainer { { NRPRACHConfigItem-ExtIEs} } 		OPTIONAL,
+	...
+}
+
+NRPRACHConfigItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NRSCS ::= ENUMERATED { scs15, scs30, scs60, scs120, ...}
+
+NRUERLFReportContainer ::= OCTET STRING
+
+NumberofActiveUEs ::= INTEGER(0..16777215, ...)
+
+NumberOfBroadcasts ::= INTEGER (0..65535)
+
+NumberofBroadcastRequest ::= INTEGER (0..65535)
+
+NumDLULSymbols ::= SEQUENCE {
+	numDLSymbols	INTEGER (0..13, ...),
+	numULSymbols	INTEGER (0..13, ...),
+	iE-Extensions			ProtocolExtensionContainer { { NumDLULSymbols-ExtIEs} } OPTIONAL
+}
+
+NumDLULSymbols-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NRV2XServicesAuthorized ::= SEQUENCE {
+	vehicleUE			VehicleUE														OPTIONAL,
+	pedestrianUE 		PedestrianUE													OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { {NRV2XServicesAuthorized-ExtIEs} }	OPTIONAL
+}
+
+NRV2XServicesAuthorized-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NRUESidelinkAggregateMaximumBitrate ::= SEQUENCE {
+	uENRSidelinkAggregateMaximumBitrate		BitRate,
+	iE-Extensions					ProtocolExtensionContainer { {NRUESidelinkAggregateMaximumBitrate-ExtIEs} } OPTIONAL
+}
+
+NRUESidelinkAggregateMaximumBitrate-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NZP-CSI-RS-ResourceID::= INTEGER  (0..191, ...)
+
+
+-- O
+
+OffsetToPointA	::= INTEGER (0..2199,...)
+
+
+-- P
+
+PacketDelayBudget ::= INTEGER (0..1023, ...) 
+
+PacketErrorRate ::= SEQUENCE {
+	pER-Scalar			PER-Scalar,
+	pER-Exponent		PER-Exponent,
+	iE-Extensions		ProtocolExtensionContainer { {PacketErrorRate-ExtIEs} }	OPTIONAL,
+	...
+}
+
+PacketErrorRate-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PER-Scalar ::= INTEGER (0..9, ...)
+PER-Exponent ::= INTEGER (0..9, ...)
+
+PagingCell-Item ::= SEQUENCE {
+	nRCGI		NRCGI	,
+	iE-Extensions	ProtocolExtensionContainer { { PagingCell-ItemExtIEs } }	OPTIONAL
+}
+
+PagingCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PagingDRX ::= ENUMERATED {
+	v32,
+	v64,
+	v128,
+	v256,
+	...
+}
+
+PagingIdentity ::=	CHOICE {
+	rANUEPagingIdentity	RANUEPagingIdentity,
+	cNUEPagingIdentity	CNUEPagingIdentity, 
+	choice-extension			ProtocolIE-SingleContainer { { PagingIdentity-ExtIEs } }
+}
+
+PagingIdentity-ExtIEs F1AP-PROTOCOL-IES::= {
+	...
+}
+
+PagingOrigin ::= ENUMERATED { non-3gpp,	...}
+
+PagingPriority ::= ENUMERATED { priolevel1, priolevel2, priolevel3, priolevel4, priolevel5, priolevel6, priolevel7, priolevel8,...} 
+
+
+RelativePathDelay ::= CHOICE {
+	k0					INTEGER (0..16351,...),
+	k1					INTEGER (0..8176,...),
+	k2					INTEGER (0..4088,...),
+	k3					INTEGER (0..2044,...),
+	k4					INTEGER (0..1022,...),
+	k5					INTEGER (0..511,...),	 
+	choice-extension			ProtocolIE-SingleContainer { { RelativePathDelay-ExtIEs } }
+}
+
+RelativePathDelay-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+PathlossReferenceInfo ::= SEQUENCE {
+	pathlossReferenceSignal			PathlossReferenceSignal,
+	iE-Extensions					ProtocolExtensionContainer { {PathlossReferenceInfo-ExtIEs} }	OPTIONAL
+}
+
+PathlossReferenceInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PathlossReferenceSignal ::= CHOICE { 
+	sSB										SSB,
+	dL-PRS									DL-PRS,
+	choice-extension						ProtocolIE-SingleContainer {{PathlossReferenceSignal-ExtIEs }}
+}
+
+PathlossReferenceSignal-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+PC5QoSFlowIdentifier ::= INTEGER (1..2048) 
+
+PC5-QoS-Characteristics ::= CHOICE {
+	non-Dynamic-PQI				NonDynamicPQIDescriptor,
+	dynamic-PQI					DynamicPQIDescriptor, 
+	choice-extension			ProtocolIE-SingleContainer { { PC5-QoS-Characteristics-ExtIEs } }
+}
+
+PC5-QoS-Characteristics-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+
+PC5QoSParameters	::= SEQUENCE {
+    pC5-QoS-Characteristics				PC5-QoS-Characteristics,
+	pC5-QoS-Flow-Bit-Rates				PC5FlowBitRates				OPTIONAL,
+	iE-Extensions						ProtocolExtensionContainer { { PC5QoSParameters-ExtIEs } }	OPTIONAL,
+	...
+}
+
+PC5QoSParameters-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PC5FlowBitRates ::= SEQUENCE {
+	guaranteedFlowBitRate		BitRate,
+	maximumFlowBitRate			BitRate,
+	iE-Extensions				ProtocolExtensionContainer { { PC5FlowBitRates-ExtIEs } }	OPTIONAL,
+	...
+}
+
+PC5FlowBitRates-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PDCCH-BlindDetectionSCG ::= OCTET STRING
+
+PDCP-SN ::= INTEGER (0..4095)
+
+PDCPSNLength	::= ENUMERATED { twelve-bits,eighteen-bits,...}
+
+PDUSessionID ::= INTEGER (0..255)
+
+ReportingPeriodicityValue ::= INTEGER (0..512, ...)
+
+Periodicity ::= INTEGER (0..640000, ...) 
+
+PeriodicitySRS ::= ENUMERATED { ms0p125, ms0p25, ms0p5, ms0p625, ms1, ms1p25, ms2, ms2p5, ms4, ms5, ms8, ms10, ms16, ms20, ms32, ms40, ms64, ms80, ms160, ms320, ms640, ms1280, ms2560, ms5120, ms10240, ...}
+
+PeriodicityList ::= SEQUENCE (SIZE(1.. maxnoSRS-ResourcePerSet)) OF PeriodicityList-Item
+
+PeriodicityList-Item ::= SEQUENCE {
+	periodicitySRS				PeriodicitySRS,
+	iE-Extensions				ProtocolExtensionContainer { { PeriodicityList-ItemExtIEs} } OPTIONAL
+}
+
+PeriodicityList-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+Permutation ::= ENUMERATED {dfu, ufd, ...}
+
+Ph-InfoMCG  ::= OCTET STRING
+
+Ph-InfoSCG  ::= OCTET STRING
+
+PLMN-Identity ::= OCTET STRING (SIZE(3))
+
+PortNumber ::= BIT STRING (SIZE (16))
+
+
+PosAssistance-Information ::= OCTET STRING
+
+PosAssistanceInformationFailureList ::= OCTET STRING
+
+PosBroadcast ::= ENUMERATED {
+	start,
+	stop,
+	...
+}
+
+PositioningBroadcastCells ::= SEQUENCE (SIZE (1..maxnoBcastCell)) OF NRCGI
+
+PosMeasurementPeriodicity ::= ENUMERATED
+{ms120, ms240, ms480, ms640, ms1024, ms2048, ms5120, ms10240, min1, min6, min12, min30, min60, ...}
+
+
+PosMeasurementQuantities ::= SEQUENCE (SIZE(1.. maxnoofPosMeas)) OF PosMeasurementQuantities-Item
+
+PosMeasurementQuantities-Item ::= SEQUENCE {
+	posMeasurementType					PosMeasurementType,
+	timingReportingGranularityFactor	INTEGER (0..5) OPTIONAL,
+	iE-Extensions						ProtocolExtensionContainer { { PosMeasurementQuantities-ItemExtIEs} } OPTIONAL
+}
+
+PosMeasurementQuantities-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosMeasurementResult ::= SEQUENCE (SIZE (1.. maxnoofPosMeas)) OF PosMeasurementResultItem 
+
+PosMeasurementResultItem ::= SEQUENCE {
+	measuredResultsValue				MeasuredResultsValue,
+	timeStamp							TimeStamp,
+	measurementQuality					TRPMeasurementQuality	OPTIONAL,
+	measurementBeamInfo					MeasurementBeamInfo		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { PosMeasurementResultItemExtIEs } }	OPTIONAL
+}
+
+PosMeasurementResultItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosMeasurementResultList ::= SEQUENCE (SIZE(1.. maxNoOfMeasTRPs)) OF PosMeasurementResultList-Item
+
+PosMeasurementResultList-Item ::= SEQUENCE {
+	posMeasurementResult			PosMeasurementResult,
+	tRPID							TRPID,
+	iE-Extensions					ProtocolExtensionContainer { { PosMeasurementResultList-ItemExtIEs} } OPTIONAL
+}
+
+PosMeasurementResultList-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosMeasurementType ::= ENUMERATED {
+	gnb-rx-tx,
+	ul-srs-rsrp,
+	ul-aoa,
+	ul-rtoa, 
+	...
+}
+
+PosReportCharacteristics ::= ENUMERATED {
+	ondemand, 
+	periodic, 
+	...
+}
+
+PosResourceSetType  ::= CHOICE {
+	periodic			PosResourceSetTypePR,
+	semi-persistent		PosResourceSetTypeSP,
+	aperiodic			PosResourceSetTypeAP,
+	choice-extension	ProtocolIE-SingleContainer {{ PosResourceSetType-ExtIEs }}
+}
+
+PosResourceSetType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+PosResourceSetTypePR ::= SEQUENCE {
+	posperiodicSet		ENUMERATED{true, ...},
+	iE-Extensions		ProtocolExtensionContainer { { PosResourceSetTypePR-ExtIEs} }	OPTIONAL
+}
+
+PosResourceSetTypePR-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosResourceSetTypeSP ::= SEQUENCE {
+	possemi-persistentSet		ENUMERATED{true, ...},
+	iE-Extensions		ProtocolExtensionContainer { { PosResourceSetTypeSP-ExtIEs} }	OPTIONAL
+}
+
+PosResourceSetTypeSP-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosResourceSetTypeAP ::= SEQUENCE {
+	sRSResourceTrigger-List 	INTEGER(1..3),
+	iE-Extensions		ProtocolExtensionContainer { { PosResourceSetTypeAP-ExtIEs} }	OPTIONAL
+}
+
+PosResourceSetTypeAP-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosSRSResourceID-List ::= SEQUENCE (SIZE (1..maxnoSRS-PosResourcePerSet)) OF SRSPosResourceID
+
+PosSRSResource-Item ::= SEQUENCE {
+	srs-PosResourceId				SRSPosResourceID,
+	transmissionCombPos				TransmissionCombPos,
+	startPosition                   INTEGER (0..13),
+	nrofSymbols                     ENUMERATED {n1, n2, n4, n8, n12},
+	freqDomainShift                 INTEGER (0..268),
+	c-SRS	                        INTEGER (0..63),
+	groupOrSequenceHopping          ENUMERATED { neither, groupHopping, sequenceHopping },
+	resourceTypePos					ResourceTypePos,
+	sequenceId                      INTEGER (0.. 65535),
+	spatialRelationPos				SpatialRelationPos 	OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { PosSRSResource-Item-ExtIEs} }	OPTIONAL
+}
+
+PosSRSResource-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosSRSResource-List ::= SEQUENCE (SIZE (1..maxnoSRS-PosResources)) OF PosSRSResource-Item
+
+PosSRSResourceSet-Item ::= SEQUENCE {
+	possrsResourceSetID				INTEGER(0..15),
+	possRSResourceID-List			PosSRSResourceID-List,
+	posresourceSetType				PosResourceSetType,
+	iE-Extensions		ProtocolExtensionContainer { { PosSRSResourceSet-Item-ExtIEs} }	OPTIONAL
+}
+
+PosSRSResourceSet-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosSRSResourceSet-List ::= SEQUENCE (SIZE (1..maxnoSRS-PosResourceSets)) OF PosSRSResourceSet-Item
+
+PrimaryPathIndication ::= ENUMERATED { 
+	true,
+	false,
+	...
+}
+
+Pre-emptionCapability ::= ENUMERATED {
+	shall-not-trigger-pre-emption,
+	may-trigger-pre-emption
+}
+
+Pre-emptionVulnerability ::= ENUMERATED {
+	not-pre-emptable,
+	pre-emptable
+}
+
+PriorityLevel	::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15)
+
+ProtectedEUTRAResourceIndication		::= OCTET STRING
+
+Protected-EUTRA-Resources-Item ::= SEQUENCE {
+	spectrumSharingGroupID					SpectrumSharingGroupID, 
+	eUTRACells-List		EUTRACells-List,
+	iE-Extensions	ProtocolExtensionContainer { { Protected-EUTRA-Resources-ItemExtIEs } }	OPTIONAL
+}
+
+Protected-EUTRA-Resources-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSConfiguration ::= SEQUENCE {
+	pRSResourceSet-List			PRSResourceSet-List,
+	iE-Extensions	ProtocolExtensionContainer { { PRSConfiguration-ExtIEs } }	OPTIONAL
+}
+
+PRSConfiguration-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSInformationPos  ::= SEQUENCE {
+	pRS-IDPos					INTEGER(0..255) OPTIONAL,	
+	pRS-Resource-Set-IDPos		INTEGER(0..7),
+	pRS-Resource-IDPos			INTEGER(0..63),
+	iE-Extensions					ProtocolExtensionContainer { { PRSInformationPos-ExtIEs} } OPTIONAL
+}
+
+PRSInformationPos-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Potential-SpCell-Item ::= SEQUENCE {
+	potential-SpCell-ID			NRCGI	,
+	iE-Extensions	ProtocolExtensionContainer { { Potential-SpCell-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Potential-SpCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+PRSAngleList ::= SEQUENCE (SIZE(1.. maxnoofPRS-ResourcesPerSet)) OF PRSAngleItem
+
+PRSAngleItem ::= SEQUENCE {
+	nR-PRS-Azimuth			INTEGER (0..359),
+	nR-PRS-Azimuth-fine		INTEGER (0..9),
+	nR-PRS-Elevation		INTEGER (0..180),
+	nR-PRS-Elevation-fine	INTEGER (0..9),
+	iE-Extensions		ProtocolExtensionContainer { { PRSAngleItem-ItemExtIEs } }	OPTIONAL
+}
+
+PRSAngleItem-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSMuting::= SEQUENCE {
+	pRSMutingOption1			PRSMutingOption1,
+	pRSMutingOption2			PRSMutingOption2,
+	iE-Extensions					ProtocolExtensionContainer { { PRSMuting-ExtIEs} } OPTIONAL
+}
+
+PRSMuting-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSMutingOption1 ::= SEQUENCE {
+	mutingPattern					DL-PRSMutingPattern,
+	mutingBitRepetitionFactor		ENUMERATED{rf1,rf2,rf4,rf8,...},
+	iE-Extensions					ProtocolExtensionContainer { { PRSMutingOption1-ExtIEs} } OPTIONAL
+}
+
+PRSMutingOption1-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSMutingOption2 ::= SEQUENCE {
+	mutingPattern					DL-PRSMutingPattern,
+	iE-Extensions					ProtocolExtensionContainer { { PRSMutingOption2-ExtIEs} } OPTIONAL
+}
+
+PRSMutingOption2-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRS-Resource-ID ::= INTEGER (0..63)
+
+PRSResource-List::= SEQUENCE (SIZE (1..maxnoofPRSresources)) OF PRSResource-Item
+
+PRSResource-Item  ::= SEQUENCE {
+	pRSResourceID			INTEGER(0..63),
+	sequenceID				INTEGER(0..4095,...),
+	rEOffset				INTEGER(0..11),
+	resourceSlotOffset		INTEGER(0..511,...),
+	resourceSymbolOffset	INTEGER(0..12,...),
+	qCLInfo					PRSResource-QCLInfo		OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { { PRSResource-Item-ExtIEs} } OPTIONAL
+}
+
+PRSResource-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSResource-QCLInfo  ::= SEQUENCE {
+	qCLSourceSSBIndex		INTEGER(0..63) OPTIONAL,
+	qCLSourcePRSInfo		PRSResource-QCLSourcePRSInfo	OPTIONAL,		
+	iE-Extensions					ProtocolExtensionContainer { { PRSResource-QCLInfo-ExtIEs} } OPTIONAL,
+	...
+}
+PRSResource-QCLInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSResource-QCLSourcePRSInfo ::= SEQUENCE {
+	qCLSourcePRSResourceSetID		INTEGER(0..7),
+	qCLSourcePRSResourceID 			INTEGER(0..63) OPTIONAL,		
+	iE-Extensions					ProtocolExtensionContainer { { PRSResource-QCLSourcePRSInfo-ExtIEs} } OPTIONAL
+}
+
+PRSResource-QCLSourcePRSInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRS-Resource-Set-ID ::= INTEGER(0..7)
+
+PRSResourceSet-List ::= SEQUENCE (SIZE (1.. maxnoofPRSresourceSets)) OF PRSResourceSet-Item
+PRSResourceSet-Item ::= SEQUENCE {
+	pRSResourceSetID				PRS-Resource-Set-ID,
+	subcarrierSpacing				ENUMERATED{kHz15, kHz30, kHz60, kHz120, ...},
+	pRSbandwidth					INTEGER(1..63),
+	startPRB						INTEGER(0..2176),
+	pointA							INTEGER (0..3279165),
+	combSize						ENUMERATED{n2, n4, n6, n12, ...},
+	cPType							ENUMERATED{normal, extended, ...},
+	resourceSetPeriodicity			ENUMERATED{n4,n5,n8,n10,n16,n20,n32,n40,n64,n80,n160,n320,n640,n1280,n2560,n5120,n10240,n20480,n40960, n81920,...},
+	resourceSetSlotOffset			INTEGER(0..81919,...),
+	resourceRepetitionFactor		ENUMERATED{rf1,rf2,rf4,rf6,rf8,rf16,rf32,...},
+	resourceTimeGap					ENUMERATED{tg1,tg2,tg4,tg8,tg16,tg32,...},
+	resourceNumberofSymbols			ENUMERATED{n2,n4,n6,n12,...},
+	pRSMuting						PRSMuting 		OPTIONAL,
+	pRSResourceTransmitPower		INTEGER(-60..50),
+	pRSResource-List				PRSResource-List,	
+	iE-Extensions					ProtocolExtensionContainer { { PRSResourceSet-Item-ExtIEs} } OPTIONAL
+}
+
+PRSResourceSet-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PWS-Failed-NR-CGI-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	numberOfBroadcasts	NumberOfBroadcasts,
+	iE-Extensions		ProtocolExtensionContainer { { PWS-Failed-NR-CGI-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+PWS-Failed-NR-CGI-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PWSSystemInformation ::= SEQUENCE {
+	sIBtype 				SIBType-PWS,
+	sIBmessage			OCTET STRING, 
+	iE-Extensions		ProtocolExtensionContainer { { PWSSystemInformationExtIEs } }	OPTIONAL,
+	...
+}
+
+PWSSystemInformationExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-NotificationInformation		CRITICALITY ignore	EXTENSION NotificationInformation		PRESENCE optional}|
+	{ ID id-AdditionalSIBMessageList	CRITICALITY reject	EXTENSION AdditionalSIBMessageList		PRESENCE optional},
+	...
+}
+
+PrivacyIndicator ::= ENUMERATED {immediate-MDT,	logged-MDT,	...}
+
+-- Q
+
+QCI ::= INTEGER (0..255)
+
+QoS-Characteristics ::= CHOICE {
+	non-Dynamic-5QI				NonDynamic5QIDescriptor,
+	dynamic-5QI					Dynamic5QIDescriptor, 
+	choice-extension			ProtocolIE-SingleContainer { { QoS-Characteristics-ExtIEs } }
+}
+
+QoS-Characteristics-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+QoSFlowIdentifier ::= INTEGER (0..63) 
+
+QoSFlowLevelQoSParameters	::= SEQUENCE {
+	qoS-Characteristics					QoS-Characteristics,
+	nGRANallocationRetentionPriority		NGRANAllocationAndRetentionPriority,
+	gBR-QoS-Flow-Information				GBR-QoSFlowInformation				OPTIONAL,
+	reflective-QoS-Attribute				ENUMERATED {subject-to, ...}				OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { QoSFlowLevelQoSParameters-ExtIEs } }	OPTIONAL
+}
+
+QoSFlowLevelQoSParameters-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-PDUSessionID								CRITICALITY ignore	EXTENSION PDUSessionID			PRESENCE optional}|
+	{ ID id-ULPDUSessionAggregateMaximumBitRate			CRITICALITY ignore	EXTENSION BitRate					PRESENCE optional}|
+	{ ID id-QosMonitoringRequest						CRITICALITY ignore	EXTENSION QosMonitoringRequest	PRESENCE optional},
+	...
+}
+
+QoSFlowMappingIndication ::= ENUMERATED {ul,dl,...}
+
+QoSInformation	::=	CHOICE {
+	eUTRANQoS					EUTRANQoS,
+	choice-extension			ProtocolIE-SingleContainer { { QoSInformation-ExtIEs} }
+}
+
+QoSInformation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	{	ID id-DRB-Information		CRITICALITY ignore TYPE DRB-Information		PRESENCE mandatory},
+	...
+}
+
+QosMonitoringRequest ::= ENUMERATED {ul, dl, both, ...}
+
+QoSParaSetIndex ::= INTEGER (1..8, ...) 
+
+QoSParaSetNotifyIndex ::= INTEGER (0..8, ...)
+
+-- R
+
+RACH-Config-Common	::= OCTET STRING
+
+RACH-Config-Common-IAB	::= OCTET STRING
+
+RACHReportContainer::= OCTET STRING
+
+RACHReportInformationList	::= SEQUENCE (SIZE(1.. maxnoofRACHReports)) OF RACHReportInformationItem
+
+RACHReportInformationItem	::= SEQUENCE {
+	rACHReportContainer				RACHReportContainer,
+	uEAssitantIdentifier			GNB-DU-UE-F1AP-ID		OPTIONAL, 
+	iE-Extensions			ProtocolExtensionContainer { { RACHReportInformationItem-ExtIEs} }	OPTIONAL,
+	...
+}
+
+RACHReportInformationItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+
+RadioResourceStatus ::= SEQUENCE {
+	sSBAreaRadioResourceStatusList		SSBAreaRadioResourceStatusList,
+	iE-Extensions	ProtocolExtensionContainer { { RadioResourceStatus-ExtIEs} } OPTIONAL
+}
+
+RadioResourceStatus-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RANAC ::= INTEGER (0..255) 
+
+RAN-MeasurementID ::= INTEGER (1.. 65536, ...)
+
+RAN-UE-MeasurementID ::= INTEGER (1.. 256, ...)
+
+RANUEID ::= OCTET STRING (SIZE (8))
+
+RANUEPagingIdentity ::= SEQUENCE	{
+	iRNTI						BIT STRING (SIZE(40)),
+	iE-Extensions				ProtocolExtensionContainer { { RANUEPagingIdentity-ExtIEs } }	OPTIONAL}
+
+RANUEPagingIdentity-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RAT-FrequencyPriorityInformation::= CHOICE {
+	eNDC		SubscriberProfileIDforRFP,
+	nGRAN		RAT-FrequencySelectionPriority,
+	choice-extension			ProtocolIE-SingleContainer { { RAT-FrequencyPriorityInformation-ExtIEs} }
+}
+
+RAT-FrequencyPriorityInformation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+RAT-FrequencySelectionPriority::= INTEGER (1.. 256, ...)
+
+Reestablishment-Indication	::=	ENUMERATED  {
+	reestablished,
+	...
+}
+
+ReferencePoint ::= CHOICE {
+	coordinateID					CoordinateID,
+	referencePointCoordinate		AccessPointPosition,
+	referencePointCoordinateHA		NGRANHighAccuracyAccessPointPosition,
+	choice-Extension				ProtocolIE-SingleContainer { { ReferencePoint-ExtIEs} }
+}
+
+ReferencePoint-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+ReferenceSFN ::= INTEGER (0..1023)
+
+ReferenceSignal ::= CHOICE { 
+	nZP-CSI-RS								NZP-CSI-RS-ResourceID,
+	sSB										SSB,
+	sRS										SRSResourceID,
+	positioningSRS							SRSPosResourceID,
+	dL-PRS									DL-PRS,
+	choice-extension						ProtocolIE-SingleContainer {{ReferenceSignal-ExtIEs }}
+}
+
+ReferenceSignal-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+RelativeCartesianLocation ::= SEQUENCE {
+	xYZunit						ENUMERATED {mm, cm, dm, ...},
+	xvalue						INTEGER (-65536..65535),
+	yvalue						INTEGER (-65536..65535),
+	zvalue						INTEGER (-32768..32767),
+	locationUncertainty			LocationUncertainty,
+	iE-Extensions				ProtocolExtensionContainer { { RelativeCartesianLocation-ExtIEs} } OPTIONAL
+}
+
+RelativeCartesianLocation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RelativeGeodeticLocation ::= SEQUENCE { 
+	milli-Arc-SecondUnits		ENUMERATED {zerodot03, zerodot3, three, ...},	
+	heightUnits					ENUMERATED {mm, cm, m, ...}, 
+	deltaLatitude				INTEGER (-1024.. 1023),
+	deltaLongitude				INTEGER (-1024.. 1023),
+	deltaHeight					INTEGER (-1024.. 1023),
+	locationUncertainty			LocationUncertainty,
+	iE-extensions				ProtocolExtensionContainer {{RelativeGeodeticLocation-ExtIEs }} OPTIONAL
+}
+
+RelativeGeodeticLocation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ReferenceTime ::= OCTET STRING
+
+RegistrationRequest ::= ENUMERATED{start, stop, add, ...}
+
+ReportCharacteristics ::= BIT STRING (SIZE(32))
+
+ReportingPeriodicity ::= ENUMERATED{ms500, ms1000, ms2000, ms5000, ms10000, ...}
+
+RequestedBandCombinationIndex ::= OCTET STRING
+
+RequestedFeatureSetEntryIndex ::= OCTET STRING
+
+RequestedP-MaxFR2 ::= OCTET STRING
+
+Requested-PDCCH-BlindDetectionSCG ::= OCTET STRING
+
+
+RequestedSRSTransmissionCharacteristics ::= SEQUENCE {
+	numberOfTransmissions		INTEGER (0..500, ...)		OPTIONAL,
+	resourceType				ENUMERATED  {periodic, semi-persistent, aperiodic,...},
+	bandwidthSRS				BandwidthSRS,
+	sRSResourceSetList 			SRSResourceSetList				OPTIONAL,
+	sSBInformation				SSBInformation				OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { { RequestedSRSTransmissionCharacteristics-ExtIEs} } OPTIONAL
+}
+
+RequestedSRSTransmissionCharacteristics-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RequestType	::= ENUMERATED {offer, execution, ...}
+
+ResourceCoordinationEUTRACellInfo ::= SEQUENCE {
+	eUTRA-Mode-Info 						EUTRA-Coex-Mode-Info,
+	eUTRA-PRACH-Configuration 				EUTRA-PRACH-Configuration,
+	iE-Extensions	ProtocolExtensionContainer { { ResourceCoordinationEUTRACellInfo-ExtIEs } }	OPTIONAL,
+	...
+}
+
+ResourceCoordinationEUTRACellInfo-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-IgnorePRACHConfiguration		CRITICALITY reject EXTENSION IgnorePRACHConfiguration		PRESENCE optional },
+	...
+}
+
+ResourceCoordinationTransferInformation ::= SEQUENCE {
+	meNB-Cell-ID								EUTRA-Cell-ID,
+	resourceCoordinationEUTRACellInfo		ResourceCoordinationEUTRACellInfo	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { ResourceCoordinationTransferInformation-ExtIEs } }	OPTIONAL,
+	...
+}
+
+ResourceCoordinationTransferInformation-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceCoordinationTransferContainer ::= OCTET STRING
+
+ResourceSetType  ::= CHOICE {
+	periodic			ResourceSetTypePeriodic,
+	semi-persistent		ResourceSetTypeSemi-persistent,
+	aperiodic			ResourceSetTypeAperiodic,
+	choice-extension				ProtocolIE-SingleContainer {{ ResourceSetType-ExtIEs }}
+}
+
+ResourceSetType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+ResourceSetTypePeriodic ::= SEQUENCE {
+	periodicSet			ENUMERATED{true, ...},
+	iE-Extensions		ProtocolExtensionContainer { { ResourceSetTypePeriodic-ExtIEs} }	OPTIONAL
+}
+
+ResourceSetTypePeriodic-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceSetTypeSemi-persistent ::= SEQUENCE {
+	semi-persistentSet	ENUMERATED{true, ...},
+	iE-Extensions		ProtocolExtensionContainer { { ResourceSetTypeSemi-persistent-ExtIEs} }	OPTIONAL
+}
+
+ResourceSetTypeSemi-persistent-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceSetTypeAperiodic ::= SEQUENCE {
+	sRSResourceTrigger-List 	INTEGER(1..3),
+	slotoffset					INTEGER(1..32),
+	iE-Extensions		ProtocolExtensionContainer { { ResourceSetTypeAperiodic-ExtIEs} }	OPTIONAL
+}
+
+ResourceSetTypeAperiodic-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RepetitionPeriod ::= INTEGER (0..131071, ...)
+
+ReportingRequestType ::= SEQUENCE {
+	eventType						EventType,
+	reportingPeriodicityValue						ReportingPeriodicityValue		OPTIONAL,
+	-- C-ifEventTypeisPeriodic: This IE shall be present if the Event Type IE is set to "periodic" in the Event Type IE.
+	iE-Extensions					ProtocolExtensionContainer { {ReportingRequestType-ExtIEs} }	OPTIONAL
+}
+
+ReportingRequestType-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceType ::= CHOICE {
+	periodic			ResourceTypePeriodic,
+	semi-persistent		ResourceTypeSemi-persistent,
+	aperiodic			ResourceTypeAperiodic,
+	choice-extension				ProtocolIE-SingleContainer {{ ResourceType-ExtIEs }}
+}
+
+ResourceType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+ResourceTypePeriodic ::= SEQUENCE {
+	periodicity		   ENUMERATED{slot1, slot2, slot4, slot5, slot8, slot10, slot16, slot20, slot32, slot40, slot64, slot80, slot160, slot320, slot640, slot1280, slot2560, ...},
+	offset				INTEGER(0..2559, ...),
+	iE-Extensions		ProtocolExtensionContainer { { ResourceTypePeriodic-ExtIEs} }	OPTIONAL
+}
+
+ResourceTypePeriodic-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceTypeSemi-persistent ::= SEQUENCE {
+	periodicity		   ENUMERATED{slot1, slot2, slot4, slot5, slot8, slot10, slot16, slot20, slot32, slot40, slot64, slot80, slot160, slot320, slot640, slot1280, slot2560, ...},
+	offset				INTEGER(0..2559, ...),
+	iE-Extensions		ProtocolExtensionContainer { { ResourceTypeSemi-persistent-ExtIEs} }	OPTIONAL
+}
+
+ResourceTypeSemi-persistent-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceTypeAperiodic ::= SEQUENCE {
+	aperiodicResourceType	   ENUMERATED{true, ...},
+	iE-Extensions		ProtocolExtensionContainer { { ResourceTypeAperiodic-ExtIEs} }	OPTIONAL
+}
+
+ResourceTypeAperiodic-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceTypePos ::= CHOICE {
+	periodic			ResourceTypePeriodicPos,
+	semi-persistent		ResourceTypeSemi-persistentPos,
+	aperiodic			ResourceTypeAperiodicPos,
+	choice-extension	ProtocolIE-SingleContainer {{ ResourceTypePos-ExtIEs }}
+}
+
+ResourceTypePos-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+ResourceTypePeriodicPos ::= SEQUENCE {
+	periodicity		   ENUMERATED{slot1, slot2, slot4, slot5, slot8, slot10, slot16, slot20, slot32, slot40, slot64, slot80, slot160, slot320, slot640, slot1280, slot2560, slot5120, slot10240, slot20480, slot40960, slot81920, ...},
+	offset				INTEGER(0..81919, ...),
+	iE-Extensions		ProtocolExtensionContainer { { ResourceTypePeriodicPos-ExtIEs} }	OPTIONAL
+}
+
+ResourceTypePeriodicPos-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceTypeSemi-persistentPos ::= SEQUENCE {
+	periodicity		   ENUMERATED{slot1, slot2, slot4, slot5, slot8, slot10, slot16, slot20, slot32, slot40, slot64, slot80, slot160, slot320, slot640, slot1280, slot2560, slot5120, slot10240, slot20480, slot40960, slot81920, ...},
+	offset				INTEGER(0..81919, ...),
+	iE-Extensions		ProtocolExtensionContainer { { ResourceTypeSemi-persistentPos-ExtIEs} }	OPTIONAL
+}
+
+ResourceTypeSemi-persistentPos-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceTypeAperiodicPos ::= SEQUENCE {
+	slotOffset          INTEGER (1..32),
+	iE-Extensions		ProtocolExtensionContainer { { ResourceTypeAperiodicPos-ExtIEs} }	OPTIONAL
+}
+
+ResourceTypeAperiodicPos-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RLCDuplicationInformation ::= SEQUENCE {
+	rLCDuplicationStateList 		RLCDuplicationStateList,
+	primaryPathIndication			PrimaryPathIndication	OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { {RLCDuplicationInformation-ExtIEs} }	OPTIONAL
+}
+
+RLCDuplicationInformation-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RLCDuplicationStateList	::= SEQUENCE (SIZE(1..maxnoofRLCDuplicationState)) OF RLCDuplicationState-Item
+
+RLCDuplicationState-Item ::=SEQUENCE {
+	duplicationState		DuplicationState, 
+	iE-Extensions	ProtocolExtensionContainer { {RLCDuplicationState-Item-ExtIEs } }	OPTIONAL,
+	...
+}
+
+
+RLCDuplicationState-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RLCFailureIndication ::= SEQUENCE {
+	assocatedLCID				LCID,
+	iE-Extensions				ProtocolExtensionContainer { {RLCFailureIndication-ExtIEs} } OPTIONAL
+}
+
+RLCFailureIndication-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RLCMode ::= ENUMERATED {
+	rlc-am,
+	rlc-um-bidirectional,
+	rlc-um-unidirectional-ul,
+	rlc-um-unidirectional-dl,
+	...
+}
+
+RLC-Status ::= SEQUENCE {
+	reestablishment-Indication 	Reestablishment-Indication,
+	iE-Extensions				ProtocolExtensionContainer { { RLC-Status-ExtIEs } } OPTIONAL,
+	...
+}
+
+RLC-Status-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RLFReportInformationList	::= SEQUENCE (SIZE(1.. maxnoofRLFReports)) OF RLFReportInformationItem
+
+RLFReportInformationItem	::= SEQUENCE {
+	nRUERLFReportContainer		NRUERLFReportContainer,
+	uEAssitantIdentifier			GNB-DU-UE-F1AP-ID		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { RLFReportInformationItem-ExtIEs} }	OPTIONAL,
+	...
+}
+
+RLFReportInformationItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RIMRSDetectionStatus ::= ENUMERATED {rs-detected, rs-disappeared, ...}
+
+RRCContainer ::= OCTET STRING
+
+RRCContainer-RRCSetupComplete ::= OCTET STRING
+
+RRCDeliveryStatus ::= SEQUENCE	{
+	delivery-status 			PDCP-SN,
+	triggering-message			PDCP-SN,
+	iE-Extensions				ProtocolExtensionContainer { { RRCDeliveryStatus-ExtIEs } }	OPTIONAL}
+
+RRCDeliveryStatus-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+RRCDeliveryStatusRequest ::= ENUMERATED {true, ...}
+
+RRCReconfigurationCompleteIndicator	::= ENUMERATED {
+	true,
+	 ...,
+	failure
+}
+
+RRC-Version ::= SEQUENCE	{
+	latest-RRC-Version			BIT STRING (SIZE(3)),
+	iE-Extensions				ProtocolExtensionContainer { { RRC-Version-ExtIEs } }	OPTIONAL}
+
+RRC-Version-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-latest-RRC-Version-Enhanced		CRITICALITY ignore EXTENSION OCTET STRING (SIZE(3))		PRESENCE optional },
+	...
+}
+
+RoutingID ::= OCTET STRING
+
+-- S
+
+SCell-FailedtoSetup-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-FailedtoSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-FailedtoSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-FailedtoSetupMod-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-FailedtoSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-FailedtoSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-ToBeRemoved-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	iE-Extensions	ProtocolExtensionContainer { { SCell-ToBeRemoved-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-ToBeRemoved-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-ToBeSetup-Item ::= SEQUENCE {
+	sCell-ID			NRCGI	,
+	sCellIndex			SCellIndex, 
+	sCellULConfigured		CellULConfigured 	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-ServingCellMO		CRITICALITY ignore	EXTENSION ServingCellMO		PRESENCE optional	},
+	...
+}
+
+SCell-ToBeSetupMod-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	sCellIndex			SCellIndex,
+	sCellULConfigured		CellULConfigured 	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-ToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-ServingCellMO		CRITICALITY ignore	EXTENSION ServingCellMO		PRESENCE optional	},
+	...
+}
+
+SCellIndex ::=INTEGER (1..31, ...) 
+
+SCS-SpecificCarrier ::=            SEQUENCE {
+    offsetToCarrier                     INTEGER (0..2199,...),
+    subcarrierSpacing                   ENUMERATED {kHz15, kHz30, kHz60, kHz120,...},
+    carrierBandwidth                    INTEGER (0..275,...),
+	iE-Extensions						ProtocolExtensionContainer { { SCS-SpecificCarrier-ExtIEs } } OPTIONAL
+}
+
+SCS-SpecificCarrier-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Search-window-information ::= SEQUENCE {
+	expectedPropagationDelay		INTEGER (-3841..3841,...),
+	delayUncertainty				INTEGER (1..246,...),
+	iE-Extensions					ProtocolExtensionContainer { { Search-window-information-ExtIEs } } OPTIONAL
+}
+
+Search-window-information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SerialNumber ::= BIT STRING (SIZE (16))
+
+SIBType-PWS ::=INTEGER (6..8, ...)
+
+SelectedBandCombinationIndex ::= OCTET STRING
+
+SelectedFeatureSetEntryIndex ::= OCTET STRING
+
+CG-ConfigInfo ::= OCTET STRING
+
+ServCellIndex ::= INTEGER (0..31, ...)
+
+ServingCellMO ::= INTEGER (1..64, ...)
+
+Served-Cell-Information ::= SEQUENCE {
+	nRCGI							NRCGI,
+	nRPCI							NRPCI,
+	fiveGS-TAC							FiveGS-TAC			OPTIONAL,
+	configured-EPS-TAC				Configured-EPS-TAC 		OPTIONAL,
+	servedPLMNs					ServedPLMNs-List,
+	nR-Mode-Info					NR-Mode-Info, 
+	measurementTimingConfiguration	OCTET STRING,
+	iE-Extensions		ProtocolExtensionContainer { {Served-Cell-Information-ExtIEs} } OPTIONAL,
+	...
+}
+
+Served-Cell-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{	ID id-RANAC							CRITICALITY ignore	EXTENSION RANAC							PRESENCE optional }|
+	{	ID id-ExtendedServedPLMNs-List		CRITICALITY ignore	EXTENSION ExtendedServedPLMNs-List	PRESENCE optional }|
+	{	ID id-Cell-Direction				CRITICALITY ignore	EXTENSION Cell-Direction				PRESENCE optional }|
+	{	ID id-BPLMN-ID-Info-List			CRITICALITY ignore	EXTENSION BPLMN-ID-Info-List			PRESENCE optional }|
+	{	ID id-Cell-Type						CRITICALITY ignore	EXTENSION CellType						PRESENCE optional}|
+	{	ID id-ConfiguredTACIndication		CRITICALITY ignore	EXTENSION ConfiguredTACIndication		PRESENCE optional }|
+	{	ID id-AggressorgNBSetID				CRITICALITY ignore	EXTENSION AggressorgNBSetID				PRESENCE optional}|
+	{	ID id-VictimgNBSetID				CRITICALITY ignore	EXTENSION VictimgNBSetID				PRESENCE optional}|
+	{	ID id-IAB-Info-IAB-DU				CRITICALITY ignore	EXTENSION IAB-Info-IAB-DU				PRESENCE optional}|
+	{	ID id-SSB-PositionsInBurst			CRITICALITY ignore	EXTENSION SSB-PositionsInBurst			PRESENCE optional }|
+	{	ID id-NRPRACHConfig					CRITICALITY ignore	EXTENSION NRPRACHConfig					PRESENCE optional },
+	...
+}
+
+Served-Cells-To-Add-Item ::= SEQUENCE {
+	served-Cell-Information		Served-Cell-Information,
+	gNB-DU-System-Information	GNB-DU-System-Information	 OPTIONAL, 
+	iE-Extensions				ProtocolExtensionContainer { { Served-Cells-To-Add-ItemExtIEs} }	OPTIONAL,
+	...
+}
+
+Served-Cells-To-Add-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Served-Cells-To-Delete-Item ::= SEQUENCE {
+	oldNRCGI					NRCGI	,
+	iE-Extensions				ProtocolExtensionContainer { { Served-Cells-To-Delete-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Served-Cells-To-Delete-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Served-Cells-To-Modify-Item ::= SEQUENCE {
+	oldNRCGI					NRCGI							,
+	served-Cell-Information		Served-Cell-Information		,
+	gNB-DU-System-Information	GNB-DU-System-Information 	OPTIONAL	,
+	iE-Extensions				ProtocolExtensionContainer { { Served-Cells-To-Modify-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Served-Cells-To-Modify-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Served-EUTRA-Cells-Information::= SEQUENCE {
+	eUTRA-Mode-Info						EUTRA-Mode-Info,
+	protectedEUTRAResourceIndication	ProtectedEUTRAResourceIndication,
+	iE-Extensions						ProtocolExtensionContainer { {Served-EUTRA-Cell-Information-ExtIEs} } OPTIONAL,
+	...
+}
+
+Served-EUTRA-Cell-Information-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Service-State ::= ENUMERATED {
+	in-service,
+	out-of-service,
+	...
+}
+
+Service-Status ::= SEQUENCE {
+	service-state				Service-State,
+	switchingOffOngoing			ENUMERATED {true, ...}	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { Service-Status-ExtIEs } }	OPTIONAL,
+	...
+}
+
+Service-Status-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+SFNInitialisationTime ::= 	BIT STRING (SIZE (64))
+
+ShortDRXCycleLength ::=  ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms7, ms8, ms10, ms14, ms16, ms20, ms30, ms32, ms35, ms40, ms64, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ...}
+
+ShortDRXCycleTimer ::= INTEGER (1..16)
+
+SIB1-message ::= OCTET STRING
+
+SIB10-message ::= OCTET STRING
+
+SIB12-message ::= OCTET STRING
+
+SIB13-message ::= OCTET STRING
+
+SIB14-message ::= OCTET STRING
+
+SItype ::= INTEGER (1..32, ...)
+
+SItype-List ::= SEQUENCE (SIZE(1.. maxnoofSITypes)) OF SItype-Item
+
+SItype-Item ::= SEQUENCE {
+	sItype		SItype	,
+	iE-Extensions	ProtocolExtensionContainer { { SItype-ItemExtIEs } }	OPTIONAL
+}
+
+SItype-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SibtypetobeupdatedListItem ::= SEQUENCE {
+	sIBtype 			INTEGER (2..32,...), 
+	sIBmessage			OCTET STRING, 
+	valueTag			INTEGER (0..31,...), 
+	iE-Extensions	ProtocolExtensionContainer { { SibtypetobeupdatedListItem-ExtIEs } }	OPTIONAL,
+	...
+}
+
+SibtypetobeupdatedListItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ID	id-areaScope	CRITICALITY ignore	EXTENSION	AreaScope	PRESENCE optional},
+	...
+}
+
+SLDRBID ::= INTEGER (1..512, ...)
+
+SLDRBInformation ::= SEQUENCE {
+	sLDRB-QoS				PC5QoSParameters,
+	flowsMappedToSLDRB-List	FlowsMappedToSLDRB-List,
+	...
+}
+
+SLDRBs-FailedToBeModified-Item	::= SEQUENCE {
+	sLDRBID		SLDRBID		,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-FailedToBeModified-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-FailedToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-FailedToBeSetup-Item	::= SEQUENCE {
+	sLDRBID	SLDRBID,
+	cause	Cause	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-FailedToBeSetup-ItemExtIEs } }		OPTIONAL
+}
+
+SLDRBs-FailedToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-FailedToBeSetupMod-Item	::= SEQUENCE {
+	sLDRBID		SLDRBID	,
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-FailedToBeSetupMod-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-FailedToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-Modified-Item	::= SEQUENCE {
+	sLDRBID							SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-Modified-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-Modified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-ModifiedConf-Item	::= SEQUENCE {
+	sLDRBID							SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-ModifiedConf-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-ModifiedConf-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-Required-ToBeModified-Item	::= SEQUENCE {
+	sLDRBID							SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-Required-ToBeModified-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-Required-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-Required-ToBeReleased-Item	::= SEQUENCE {
+	sLDRBID		SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-Required-ToBeReleased-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-Required-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-Setup-Item ::= SEQUENCE {
+	sLDRBID							SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-Setup-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-Setup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-SetupMod-Item	::= SEQUENCE {
+	sLDRBID							SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-SetupMod-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-SetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-ToBeModified-Item	::= SEQUENCE {
+	sLDRBID						SLDRBID,
+	sLDRBInformation				SLDRBInformation		OPTIONAL,
+	rLCMode						RLCMode			OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-ToBeModified-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-ToBeReleased-Item	::= SEQUENCE {
+	sLDRBID	        SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-ToBeReleased-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-ToBeSetup-Item ::= SEQUENCE	{
+	sLDRBID						SLDRBID,
+	sLDRBInformation				SLDRBInformation,
+	rLCMode						RLCMode, 
+
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-ToBeSetup-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-ToBeSetupMod-Item	::= SEQUENCE {
+	sLDRBID						SLDRBID,
+	sLDRBInformation				SLDRBInformation,
+	rLCMode						RLCMode			OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-ToBeSetupMod-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SL-PHY-MAC-RLC-Config ::= OCTET STRING
+
+SL-ConfigDedicatedEUTRA ::= OCTET STRING
+
+SliceAvailableCapacity ::= SEQUENCE {
+	sliceAvailableCapacityList	SliceAvailableCapacityList,
+	iE-Extensions				ProtocolExtensionContainer { { SliceAvailableCapacity-ExtIEs} } OPTIONAL
+}
+
+SliceAvailableCapacity-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SliceAvailableCapacityList ::= SEQUENCE (SIZE(1.. maxnoofBPLMNsNR)) OF SliceAvailableCapacityItem
+
+SliceAvailableCapacityItem ::= SEQUENCE {
+	pLMNIdentity					PLMN-Identity, 
+	sNSSAIAvailableCapacity-List	SNSSAIAvailableCapacity-List,
+	iE-Extensions	ProtocolExtensionContainer { { SliceAvailableCapacityItem-ExtIEs} } OPTIONAL
+}
+
+SliceAvailableCapacityItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SNSSAIAvailableCapacity-List ::= SEQUENCE (SIZE(1.. maxnoofSliceItems)) OF SNSSAIAvailableCapacity-Item
+
+SNSSAIAvailableCapacity-Item ::= SEQUENCE {
+	sNSSAI		SNSSAI,
+	sliceAvailableCapacityValueDownlink	INTEGER (0..100)	OPTIONAL, 
+	sliceAvailableCapacityValueUplink	INTEGER (0..100)	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { SNSSAIAvailableCapacity-Item-ExtIEs } }	OPTIONAL
+}
+
+SNSSAIAvailableCapacity-Item-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SliceSupportList ::= SEQUENCE (SIZE(1.. maxnoofSliceItems)) OF SliceSupportItem
+
+SliceSupportItem ::= SEQUENCE {
+	sNSSAI	SNSSAI,
+	iE-Extensions				ProtocolExtensionContainer { { SliceSupportItem-ExtIEs } }	OPTIONAL
+}
+
+SliceSupportItem-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SliceToReportList ::= SEQUENCE (SIZE(1.. maxnoofBPLMNsNR)) OF SliceToReportItem
+
+SliceToReportItem ::= SEQUENCE {
+	pLMNIdentity				PLMN-Identity, 
+	sNSSAIlist					SNSSAI-list,
+	iE-Extensions				ProtocolExtensionContainer { { SliceToReportItem-ExtIEs} } OPTIONAL
+}
+
+SliceToReportItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SlotNumber ::= INTEGER (0..79)
+
+SNSSAI-list ::= SEQUENCE (SIZE(1.. maxnoofSliceItems)) OF SNSSAI-Item
+
+SNSSAI-Item ::= SEQUENCE {
+	sNSSAI		SNSSAI,
+	iE-Extensions				ProtocolExtensionContainer { { SNSSAI-Item-ExtIEs } }	OPTIONAL
+}
+
+SNSSAI-Item-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Slot-Configuration-List ::= SEQUENCE (SIZE(1.. maxnoofslots)) OF Slot-Configuration-Item
+
+Slot-Configuration-Item ::= SEQUENCE {
+	slotIndex				INTEGER (0..5119, ...),
+	symbolAllocInSlot		SymbolAllocInSlot,
+	iE-Extensions	ProtocolExtensionContainer { { Slot-Configuration-ItemExtIEs } }	OPTIONAL
+}
+
+Slot-Configuration-ItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+SNSSAI ::= SEQUENCE {
+	sST			OCTET STRING (SIZE(1)),
+	sD			OCTET STRING (SIZE(3)) 	OPTIONAL	,
+	iE-Extensions				ProtocolExtensionContainer { { SNSSAI-ExtIEs } }	OPTIONAL
+}
+
+SNSSAI-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SpatialDirectionInformation ::= SEQUENCE {
+	nR-PRSBeamInformation			NR-PRSBeamInformation,
+	iE-Extensions					ProtocolExtensionContainer { { SpatialDirectionInformation-ExtIEs } } OPTIONAL
+}
+
+SpatialDirectionInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SpatialRelationInfo ::= SEQUENCE {
+	spatialRelationforResourceID					SpatialRelationforResourceID,
+	iE-Extensions		ProtocolExtensionContainer { {SpatialRelationInfo-ExtIEs} }	OPTIONAL
+}
+
+SpatialRelationInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SpatialRelationforResourceID ::= SEQUENCE (SIZE(1..maxnoofSpatialRelations)) OF SpatialRelationforResourceIDItem
+
+SpatialRelationforResourceIDItem ::= SEQUENCE {
+	referenceSignal		ReferenceSignal,
+	iE-Extensions		ProtocolExtensionContainer { {SpatialRelationforResourceIDItem-ExtIEs} }	OPTIONAL
+}
+
+SpatialRelationforResourceIDItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SpatialRelationPos ::= CHOICE {
+	sSBPos					SSBPos,
+	pRSInformationPos		PRSInformationPos,
+	choice-extension		ProtocolIE-SingleContainer {{ SpatialInformationPos-ExtIEs }}
+}
+
+SpatialInformationPos-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+SpectrumSharingGroupID ::= INTEGER (1..maxCellineNB)
+
+SRBID ::= INTEGER (0..3, ...)
+
+SRBs-FailedToBeSetup-Item	::= SEQUENCE {
+	sRBID		SRBID	,
+	cause		Cause	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-FailedToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-FailedToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-FailedToBeSetupMod-Item	::= SEQUENCE {
+	sRBID		SRBID		,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-FailedToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-FailedToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-Modified-Item ::= SEQUENCE {
+	sRBID							SRBID,
+	lCID							LCID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-Modified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-Modified-ItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-Required-ToBeReleased-Item	::= SEQUENCE {
+	sRBID	SRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-Required-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-Required-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-Setup-Item ::= SEQUENCE {
+	sRBID							SRBID,
+	lCID								LCID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-Setup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-Setup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-SetupMod-Item ::= SEQUENCE {
+	sRBID						SRBID,
+	lCID							LCID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-SetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-SetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-ToBeReleased-Item	::= SEQUENCE {
+	sRBID		SRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-ToBeSetup-Item ::= SEQUENCE {
+	sRBID	 SRBID	,
+	duplicationIndication	DuplicationIndication	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-AdditionalDuplicationIndication	CRITICALITY ignore	EXTENSION AdditionalDuplicationIndication		PRESENCE optional	},
+	...
+}
+
+SRBs-ToBeSetupMod-Item	::= SEQUENCE {
+	sRBID	SRBID,
+	duplicationIndication	DuplicationIndication	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-ToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-AdditionalDuplicationIndication	CRITICALITY ignore	EXTENSION AdditionalDuplicationIndication		PRESENCE optional	},
+	...
+}
+
+SRSCarrier-List ::= SEQUENCE (SIZE(1.. maxnoSRS-Carriers)) OF SRSCarrier-List-Item
+
+SRSCarrier-List-Item ::= SEQUENCE {
+	pointA							INTEGER (0..3279165,...),
+	uplinkChannelBW-PerSCS-List		UplinkChannelBW-PerSCS-List,
+	activeULBWP						ActiveULBWP,
+	pci								NRPCI,
+	iE-Extensions					ProtocolExtensionContainer { { SRSCarrier-List-Item-ExtIEs } } OPTIONAL
+}
+
+SRSCarrier-List-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRSConfig  ::= SEQUENCE {
+	sRSResource-List			SRSResource-List 		OPTIONAL,
+	posSRSResource-List			PosSRSResource-List 	OPTIONAL,
+	sRSResourceSet-List			SRSResourceSet-List 	OPTIONAL,
+	posSRSResourceSet-List		PosSRSResourceSet-List 	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { SRSConfig-ExtIEs } } OPTIONAL
+}
+
+SRSConfig-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRSConfiguration ::= SEQUENCE {
+	sRSCarrier-List		SRSCarrier-List,
+	iE-Extensions		ProtocolExtensionContainer { { SRSConfiguration-ExtIEs } } OPTIONAL
+}
+
+SRSConfiguration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+} 
+
+SRSPosResourceID ::= INTEGER (0..63, ...)
+
+SRSResource::= SEQUENCE {
+	sRSResourceID                  	SRSResourceID,
+	nrofSRS-Ports                   ENUMERATED {port1, ports2, ports4},
+	transmissionComb				TransmissionComb,
+	startPosition                   INTEGER (0..13),
+    nrofSymbols                     ENUMERATED {n1, n2, n4},
+    repetitionFactor              	ENUMERATED {n1, n2, n4},
+    freqDomainPosition              INTEGER (0..67),
+	freqDomainShift                 INTEGER (0..268),
+	c-SRS                           INTEGER (0..63),
+	b-SRS                           INTEGER (0..3),
+	b-hop                           INTEGER (0..3),
+	groupOrSequenceHopping          ENUMERATED { neither, groupHopping, sequenceHopping },
+	resourceType					ResourceType,
+	slotOffset						INTEGER (0..2559),
+	sequenceId                      INTEGER (0..1023),
+	iE-Extensions					ProtocolExtensionContainer { { SRSResource-ExtIEs } } OPTIONAL
+}
+
+SRSResource-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRSResourceID ::= INTEGER (0..63, ...)
+
+SRSResourceID-List::= SEQUENCE (SIZE (1..maxnoSRS-ResourcePerSet)) OF SRSResourceID
+
+SRSResource-List ::= SEQUENCE (SIZE (1..maxnoSRS-Resources)) OF SRSResource
+
+SRSResourceSet::= SEQUENCE {
+	sRSResourceSetID                SRSResourceSetID,
+	sRSResourceID-List				SRSResourceID-List,
+	resourceSetType					ResourceSetType,
+	iE-Extensions					ProtocolExtensionContainer { { SRSResourceSet-ExtIEs } } OPTIONAL
+}
+
+SRSResourceSet-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRSResourceSetID ::= INTEGER (0..15, ...)
+
+SRSResourceSetList ::= SEQUENCE (SIZE(1.. maxnoSRS-ResourceSets)) OF SRSResourceSetItem
+
+SRSResourceSetItem ::= SEQUENCE {
+	numSRSresourcesperset		INTEGER (1..16, ...)	OPTIONAL,
+	periodicityList				PeriodicityList			OPTIONAL,
+	spatialRelationInfo			SpatialRelationInfo		OPTIONAL,
+	pathlossReferenceInfo		PathlossReferenceInfo	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRSResourceSetItemExtIEs } }	OPTIONAL
+}
+
+SRSResourceSetItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRSResourceSet-List ::= SEQUENCE (SIZE (1..maxnoSRS-ResourceSets)) OF SRSResourceSet 
+
+SRSResourceTrigger ::= SEQUENCE {
+	aperiodicSRSResourceTriggerList					AperiodicSRSResourceTriggerList,
+	iE-Extensions		ProtocolExtensionContainer { {SRSResourceTrigger-ExtIEs} }	OPTIONAL
+}
+
+SRSResourceTrigger-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRSSpatialRelation ::= SEQUENCE {
+	spatialRelationforResourceID				SpatialRelationforResourceID,
+	iE-Extensions		ProtocolExtensionContainer { {SRSSpatialRelation-ExtIEs} }	OPTIONAL
+}
+
+SRSSpatialRelation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSB ::= SEQUENCE {
+	pCI-NR				NRPCI,
+	ssb-index			SSB-Index	OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { {SSB-ExtIEs} }	OPTIONAL
+}
+
+SSB-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSB-freqInfo ::= INTEGER (0..maxNRARFCN) 
+
+SSB-Index ::= INTEGER(0..63)
+
+SSBPos ::= SEQUENCE {
+	pCI-NR				NRPCI		OPTIONAL,
+	ssb-index			SSB-Index,
+	iE-Extensions		ProtocolExtensionContainer { {SSBPos-ExtIEs} }	OPTIONAL
+}
+
+SSBPos-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSB-subcarrierSpacing ::=  ENUMERATED {kHz15, kHz30, kHz120, kHz240, spare3, spare2, spare1, ...}
+
+SSB-transmissionPeriodicity	::= ENUMERATED {sf10, sf20, sf40, sf80, sf160, sf320, sf640, ...}
+
+SSB-transmissionTimingOffset ::= INTEGER (0..127, ...)
+
+SSB-transmissionBitmap ::= CHOICE {
+	shortBitmap			BIT STRING (SIZE (4)),
+	mediumBitmap		BIT STRING (SIZE (8)),
+	longBitmap			BIT STRING (SIZE (64)),
+	choice-extension	ProtocolIE-SingleContainer { { SSB-transmisisonBitmap-ExtIEs} }
+}
+
+SSB-transmisisonBitmap-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+SSBAreaCapacityValueList ::= SEQUENCE (SIZE(1.. maxnoofSSBAreas)) OF	SSBAreaCapacityValueItem
+
+SSBAreaCapacityValueItem ::= SEQUENCE {
+	sSBIndex				INTEGER(0..63),
+	sSBAreaCapacityValue	INTEGER (0..100),
+	iE-Extensions	ProtocolExtensionContainer { { SSBAreaCapacityValueItem-ExtIEs} } OPTIONAL
+}
+
+SSBAreaCapacityValueItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSBAreaRadioResourceStatusList::= SEQUENCE (SIZE(1.. maxnoofSSBAreas)) OF	SSBAreaRadioResourceStatusItem
+
+SSBAreaRadioResourceStatusItem::= SEQUENCE {
+	sSBIndex					INTEGER(0..63),
+	sSBAreaDLGBRPRBusage		INTEGER (0..100),
+	sSBAreaULGBRPRBusage		INTEGER (0..100),
+	sSBAreaDLnon-GBRPRBusage	INTEGER (0..100),
+	sSBAreaULnon-GBRPRBusage	INTEGER (0..100),
+	sSBAreaDLTotalPRBusage		INTEGER (0..100),
+	sSBAreaULTotalPRBusage		INTEGER (0..100),
+	dLschedulingPDCCHCCEusage	INTEGER (0..100)		OPTIONAL,
+	uLschedulingPDCCHCCEusage	INTEGER (0..100) 		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { SSBAreaRadioResourceStatusItem-ExtIEs} } OPTIONAL
+}
+
+SSBAreaRadioResourceStatusItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSBInformation ::= SEQUENCE {
+	sSBInformationList	SSBInformationList,
+	iE-Extensions	ProtocolExtensionContainer { { SSBInformation-ExtIEs } }	OPTIONAL
+}
+
+SSBInformation-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSBInformationList ::= SEQUENCE (SIZE(1.. maxnoofSSBs)) OF SSBInformationItem
+
+SSBInformationItem ::= SEQUENCE {
+	sSB-Configuration	SSB-TF-Configuration,
+	pCI-NR				NRPCI,
+	iE-Extensions	ProtocolExtensionContainer { { SSBInformationItem-ExtIEs } }	OPTIONAL
+}
+
+SSBInformationItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSB-PositionsInBurst ::= CHOICE {
+	shortBitmap						BIT STRING (SIZE (4)),
+	mediumBitmap					BIT STRING (SIZE (8)),
+	longBitmap						BIT STRING (SIZE (64)),
+	choice-extension				ProtocolIE-SingleContainer { {SSB-PositionsInBurst-ExtIEs} }
+}
+
+SSB-PositionsInBurst-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+SSB-TF-Configuration ::= SEQUENCE {
+	sSB-frequency				INTEGER (0..3279165),
+	sSB-subcarrier-spacing		ENUMERATED {kHz15, kHz30, kHz60, kHz120, kHz240, ...},
+	sSB-Transmit-power			INTEGER (-60..50),
+	sSB-periodicity				ENUMERATED {ms5, ms10, ms20, ms40, ms80, ms160, ...},
+	sSB-half-frame-offset		INTEGER(0..1),
+	sSB-SFN-offset				INTEGER(0..15),
+	sSB-position-in-burst		SSB-PositionsInBurst		OPTIONAL,
+	sFNInitialisationTime		SFNInitialisationTime		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { SSB-TF-Configuration-ExtIEs} } OPTIONAL
+}
+
+SSB-TF-Configuration-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+SSBToReportList ::= SEQUENCE (SIZE(1.. maxnoofSSBAreas)) OF SSBToReportItem
+
+SSBToReportItem ::= SEQUENCE {
+	sSBIndex					INTEGER(0..63),
+	iE-Extensions				ProtocolExtensionContainer { { SSBToReportItem-ExtIEs} } OPTIONAL
+}
+
+SSBToReportItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SUL-Information ::= SEQUENCE {
+	sUL-NRARFCN							INTEGER (0..maxNRARFCN),
+	sUL-transmission-Bandwidth			Transmission-Bandwidth,
+	iE-Extensions				ProtocolExtensionContainer { { SUL-InformationExtIEs} } OPTIONAL,
+	...
+}
+
+SUL-InformationExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-CarrierList				CRITICALITY ignore	EXTENSION NRCarrierList			PRESENCE optional }|
+	{ ID id-FrequencyShift7p5khz	CRITICALITY ignore	EXTENSION FrequencyShift7p5khz	PRESENCE optional },
+	...
+}
+
+SubcarrierSpacing ::=	ENUMERATED { kHz15, kHz30, kHz60, kHz120, kHz240, spare3, spare2, spare1, ...}
+
+SubscriberProfileIDforRFP ::= INTEGER (1..256, ...)
+
+SULAccessIndication ::= ENUMERATED {true,...}
+
+
+SupportedSULFreqBandItem ::= SEQUENCE {
+	freqBandIndicatorNr 			INTEGER (1..1024,...),
+	iE-Extensions				ProtocolExtensionContainer { { SupportedSULFreqBandItem-ExtIEs} } OPTIONAL,
+	...
+}
+
+SupportedSULFreqBandItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SymbolAllocInSlot ::= CHOICE {
+	all-DL				NULL,
+	all-UL				NULL, 
+	both-DL-and-UL			NumDLULSymbols,	
+	choice-extension			ProtocolIE-SingleContainer { { SymbolAllocInSlot-ExtIEs } }
+}
+
+SymbolAllocInSlot-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+SystemFrameNumber ::= INTEGER (0..1023)
+
+SystemInformationAreaID ::=BIT STRING (SIZE (24))
+
+-- T
+
+FiveGS-TAC ::= OCTET STRING (SIZE(3))
+
+Configured-EPS-TAC ::= OCTET STRING (SIZE(2))
+
+TargetCellList ::= SEQUENCE (SIZE(1..maxnoofCHOcells)) OF TargetCellList-Item
+
+TargetCellList-Item ::= SEQUENCE {
+	target-cell								NRCGI,
+	iE-Extensions							ProtocolExtensionContainer { { TargetCellList-Item-ExtIEs} } OPTIONAL
+}
+
+TargetCellList-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TDD-Info ::= SEQUENCE {
+	nRFreqInfo							NRFreqInfo,
+	transmission-Bandwidth			Transmission-Bandwidth,
+	iE-Extensions				ProtocolExtensionContainer { {TDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ID	id-IntendedTDD-DL-ULConfig	CRITICALITY ignore	EXTENSION	IntendedTDD-DL-ULConfig	PRESENCE optional}|
+	{ID id-TDD-UL-DLConfigCommonNR	CRITICALITY ignore	EXTENSION TDD-UL-DLConfigCommonNR	PRESENCE optional }|
+	{ID id-CarrierList				CRITICALITY ignore	EXTENSION NRCarrierList				PRESENCE optional },
+	...
+}
+
+TDD-UL-DLConfigCommonNR ::= OCTET STRING
+
+TimeReferenceInformation ::= SEQUENCE {
+	referenceTime					ReferenceTime,
+	referenceSFN					ReferenceSFN,
+	uncertainty						Uncertainty,
+	timeInformationType				TimeInformationType,
+	iE-Extensions		ProtocolExtensionContainer { {TimeReferenceInformation-ExtIEs} }	OPTIONAL
+}
+
+TimeReferenceInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TimeInformationType ::= ENUMERATED {localClock}
+
+TimeStamp ::= SEQUENCE {
+	systemFrameNumber		SystemFrameNumber,
+	slotIndex				TimeStampSlotIndex,
+	measurementTime			SFNInitialisationTime	OPTIONAL,
+	iE-Extension			ProtocolExtensionContainer { { TimeStamp-ExtIEs} }	OPTIONAL
+}
+
+TimeStamp-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TimeStampSlotIndex ::= CHOICE {
+	sCS-15			INTEGER(0..9),
+	sCS-30			INTEGER(0..19),
+	sCS-60			INTEGER(0..39),
+	sCS-120			INTEGER(0..79),
+	choice-extension		ProtocolIE-SingleContainer { { TimeStampSlotIndex-ExtIEs} }
+}
+
+TimeStampSlotIndex-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...}
+
+TimingMeasurementQuality ::= SEQUENCE {
+	measurementQuality		INTEGER(0..31),
+	resolution				ENUMERATED{m0dot1, m1, m10, m30, ...},
+	iE-Extensions		ProtocolExtensionContainer { { TimingMeasurementQuality-ExtIEs} }	OPTIONAL
+}
+
+TimingMeasurementQuality-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TNLAssociationUsage ::= ENUMERATED {
+	ue,
+	non-ue,
+	both, 
+	...
+}
+
+TNLCapacityIndicator::= SEQUENCE {
+	dLTNLOfferedCapacity		INTEGER (1.. 16777216,...),
+	dLTNLAvailableCapacity		INTEGER (0.. 100,...),
+	uLTNLOfferedCapacity		INTEGER (1.. 16777216,...),
+	uLTNLAvailableCapacity		INTEGER (0.. 100,...),
+	iE-Extensions	ProtocolExtensionContainer { { TNLCapacityIndicator-ExtIEs} } OPTIONAL
+}
+
+TNLCapacityIndicator-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TraceActivation ::= SEQUENCE {
+	traceID								TraceID,
+	interfacesToTrace					InterfacesToTrace,
+	traceDepth							TraceDepth,
+	traceCollectionEntityIPAddress		TransportLayerAddress,
+	iE-Extensions		ProtocolExtensionContainer { {TraceActivation-ExtIEs} }	OPTIONAL
+}
+
+TraceActivation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-mdtConfiguration	CRITICALITY ignore	EXTENSION	MDTConfiguration		PRESENCE optional}|
+	{ID id-TraceCollectionEntityURI	CRITICALITY ignore	EXTENSION URI-address		PRESENCE optional	},
+	...
+}
+
+TraceDepth ::= ENUMERATED { 
+	minimum,
+	medium,
+	maximum,
+	minimumWithoutVendorSpecificExtension,
+	mediumWithoutVendorSpecificExtension,
+	maximumWithoutVendorSpecificExtension,
+	...
+}
+
+TraceID ::= OCTET STRING (SIZE(8))
+
+TrafficMappingInfo	::= CHOICE {
+	iPtolayer2TrafficMappingInfo					IPtolayer2TrafficMappingInfo,
+	bAPlayerBHRLCchannelMappingInfo					BAPlayerBHRLCchannelMappingInfo,
+	choice-extension								ProtocolIE-SingleContainer { { TrafficMappingInfo-ExtIEs} }
+}
+
+TrafficMappingInfo-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TransportLayerAddress		::= BIT STRING (SIZE(1..160, ...))
+
+TransactionID				::= INTEGER (0..255, ...)
+
+Transmission-Bandwidth ::= SEQUENCE {
+	nRSCS	NRSCS,
+	nRNRB	NRNRB,
+	iE-Extensions				ProtocolExtensionContainer { { Transmission-Bandwidth-ExtIEs} } OPTIONAL,
+	...
+}
+
+Transmission-Bandwidth-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TransmissionComb ::= CHOICE {
+	n2    SEQUENCE {
+            combOffset-n2              INTEGER (0..1),
+            cyclicShift-n2             INTEGER (0..7)
+        },
+    n4    SEQUENCE {
+            combOffset-n4              INTEGER (0..3),
+            cyclicShift-n4             INTEGER (0..11)
+        },
+	choice-extension				ProtocolIE-SingleContainer { { TransmissionComb-ExtIEs} }
+}
+TransmissionComb-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TransmissionCombPos ::= CHOICE {
+	n2    SEQUENCE {
+            combOffset-n2              INTEGER (0..1),
+            cyclicShift-n2             INTEGER (0..7)
+        },
+    n4    SEQUENCE {
+            combOffset-n4              INTEGER (0..3),
+            cyclicShift-n4             INTEGER (0..11)
+        },
+    n8    SEQUENCE {
+            combOffset-n8              INTEGER (0..7),
+            cyclicShift-n8             INTEGER (0..5)
+        },
+
+	choice-extension				ProtocolIE-SingleContainer { { TransmissionCombPos-ExtIEs} }
+}
+TransmissionCombPos-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+Transport-UP-Layer-Address-Info-To-Add-List	::= SEQUENCE (SIZE(1.. maxnoofTLAs)) OF Transport-UP-Layer-Address-Info-To-Add-Item
+
+Transport-UP-Layer-Address-Info-To-Add-Item ::= SEQUENCE {
+	iP-SecTransportLayerAddress		TransportLayerAddress,
+	gTPTransportLayerAddressToAdd			GTPTLAs							OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { Transport-UP-Layer-Address-Info-To-Add-ItemExtIEs } }	OPTIONAL
+}
+
+Transport-UP-Layer-Address-Info-To-Add-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { 
+	...
+}
+
+Transport-UP-Layer-Address-Info-To-Remove-List	::= SEQUENCE (SIZE(1.. maxnoofTLAs)) OF Transport-UP-Layer-Address-Info-To-Remove-Item
+
+Transport-UP-Layer-Address-Info-To-Remove-Item ::= SEQUENCE {
+	iP-SecTransportLayerAddress		TransportLayerAddress,
+	gTPTransportLayerAddressToRemove			GTPTLAs							OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { Transport-UP-Layer-Address-Info-To-Remove-ItemExtIEs } }	OPTIONAL
+}
+
+Transport-UP-Layer-Address-Info-To-Remove-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { 
+	...
+}
+
+TransmissionActionIndicator ::= ENUMERATED {stop, ..., restart }
+
+TRPID ::= INTEGER (0.. maxnoofTRPs, ...)
+
+TRPInformation ::= SEQUENCE {
+	tRPID							TRPID,
+	tRPInformationTypeResponseList	TRPInformationTypeResponseList,
+	iE-Extensions					ProtocolExtensionContainer { { TRPInformation-ExtIEs } }		OPTIONAL
+}
+
+TRPInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TRPInformationItem ::= SEQUENCE {
+	tRPInformation					TRPInformation,
+	iE-Extensions					ProtocolExtensionContainer { { TRPInformationItem-ExtIEs } }	OPTIONAL
+}
+
+TRPInformationItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { 
+	...
+}
+
+TRPInformationTypeItem ::= ENUMERATED { 
+		nrPCI,
+		nG-RAN-CGI,
+		arfcn, 
+		pRSConfig,
+		sSBConfig,
+		sFNInitTime,
+		spatialDirectInfo,
+		geoCoord,
+...}
+
+
+TRPInformationTypeResponseList ::= SEQUENCE (SIZE(1.. maxnoofTRPInfoTypes)) OF TRPInformationTypeResponseItem 
+
+TRPInformationTypeResponseItem ::= CHOICE {
+	pCI-NR								NRPCI,
+	nG-RAN-CGI							NRCGI,
+	nRARFCN								INTEGER (0..maxNRARFCN),
+	pRSConfiguration					PRSConfiguration,
+	sSBinformation						SSBInformation,
+	sFNInitialisationTime				SFNInitialisationTime,
+	spatialDirectionInformation			SpatialDirectionInformation,
+	geographicalCoordinates				GeographicalCoordinates,
+	choice-extension					ProtocolIE-SingleContainer { { TRPInformationTypeResponseItem-ExtIEs} }
+}
+
+TRPInformationTypeResponseItem-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+
+TRPList ::= SEQUENCE (SIZE(1.. maxnoofTRPs)) OF TRPListItem
+
+TRPListItem ::= SEQUENCE {
+	tRPID							TRPID,
+	iE-Extensions					ProtocolExtensionContainer { { TRPListItem-ExtIEs } }	OPTIONAL
+}
+
+TRPListItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { 
+	...
+}
+
+TRPMeasurementQuality ::= SEQUENCE {
+	tRPmeasurementQuality-Item 	TRPMeasurementQuality-Item,
+	iE-Extensions				ProtocolExtensionContainer { {TRPMeasurementQuality-ExtIEs} } OPTIONAL
+}
+
+TRPMeasurementQuality-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TRPMeasurementQuality-Item ::= CHOICE {
+	timingMeasurementQuality	TimingMeasurementQuality,
+	angleMeasurementQuality		AngleMeasurementQuality,
+	choice-extension			ProtocolIE-SingleContainer { { TRPMeasurementQuality-Item-ExtIEs } }
+}
+
+TRPMeasurementQuality-Item-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TRP-MeasurementRequestList ::= SEQUENCE (SIZE (1..maxNoOfMeasTRPs)) OF TRP-MeasurementRequestItem
+
+TRP-MeasurementRequestItem ::= SEQUENCE {
+	tRPID							TRPID, 
+	search-window-information		Search-window-information	OPTIONAL, 
+	iE-extensions		ProtocolExtensionContainer { { TRP-MeasurementRequestItem-ExtIEs } } OPTIONAL
+}
+
+TRP-MeasurementRequestItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TRPPositionDefinitionType ::= CHOICE {
+	direct		TRPPositionDirect,
+	referenced	TRPPositionReferenced,
+	choice-extension							ProtocolIE-SingleContainer { { TRPPositionDefinitionType-ExtIEs } }
+}
+
+TRPPositionDefinitionType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TRPPositionDirect ::= SEQUENCE {
+	accuracy	TRPPositionDirectAccuracy,
+	iE-extensions		ProtocolExtensionContainer { { TRPPositionDirect-ExtIEs } }	OPTIONAL
+}
+
+TRPPositionDirect-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TRPPositionDirectAccuracy ::= CHOICE {
+	tRPPosition				AccessPointPosition,
+	tRPHAposition			NGRANHighAccuracyAccessPointPosition,
+	choice-extension		ProtocolIE-SingleContainer { { TRPPositionDirectAccuracy-ExtIEs } }
+}
+
+TRPPositionDirectAccuracy-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TRPPositionReferenced ::= SEQUENCE {
+	referencePoint					ReferencePoint,
+	referencePointType				TRPReferencePointType,
+	iE-extensions					ProtocolExtensionContainer { { TRPPositionReferenced-ExtIEs } } 	OPTIONAL
+}
+
+TRPPositionReferenced-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TRPReferencePointType ::= CHOICE {
+	tRPPositionRelativeGeodetic			RelativeGeodeticLocation,
+	tRPPositionRelativeCartesian		RelativeCartesianLocation,
+	choice-extension					ProtocolIE-SingleContainer { { TRPReferencePointType-ExtIEs } }
+}
+
+TRPReferencePointType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TypeOfError ::= ENUMERATED {
+	not-understood,
+	missing,
+	...
+}
+
+Transport-Layer-Address-Info ::= SEQUENCE {
+	transport-UP-Layer-Address-Info-To-Add-List		Transport-UP-Layer-Address-Info-To-Add-List							OPTIONAL,
+	transport-UP-Layer-Address-Info-To-Remove-List	Transport-UP-Layer-Address-Info-To-Remove-List					OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { Transport-Layer-Address-Info-ExtIEs } }								OPTIONAL
+}
+
+Transport-Layer-Address-Info-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TSCAssistanceInformation ::= SEQUENCE {
+	periodicity				Periodicity,
+	burstArrivalTime		BurstArrivalTime													OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { {TSCAssistanceInformation-ExtIEs} }	OPTIONAL,
+	...
+}
+
+TSCAssistanceInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TSCTrafficCharacteristics ::= SEQUENCE {
+	tSCAssistanceInformationDL		TSCAssistanceInformation								OPTIONAL,
+	tSCAssistanceInformationUL		TSCAssistanceInformation								OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { {TSCTrafficCharacteristics-ExtIEs} }	OPTIONAL,
+	...
+}
+
+TSCTrafficCharacteristics-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- U
+UAC-Assistance-Info ::= SEQUENCE {
+	uACPLMN-List		UACPLMN-List,
+	iE-Extensions		ProtocolExtensionContainer { { UAC-Assistance-InfoExtIEs} } OPTIONAL
+}
+
+UAC-Assistance-InfoExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UACPLMN-List ::= SEQUENCE (SIZE(1..maxnoofUACPLMNs)) OF UACPLMN-Item
+
+UACPLMN-Item::= SEQUENCE {
+	pLMNIdentity				PLMN-Identity,
+	uACType-List				UACType-List,	iE-Extensions		ProtocolExtensionContainer { { UACPLMN-Item-ExtIEs} } OPTIONAL
+}
+
+UACPLMN-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-NID	CRITICALITY ignore	EXTENSION NID	PRESENCE optional },
+	...
+}
+
+UACType-List ::= SEQUENCE (SIZE(1..maxnoofUACperPLMN)) OF UACType-Item
+
+UACType-Item::= SEQUENCE {
+	uACReductionIndication 		UACReductionIndication,
+	uACCategoryType				UACCategoryType,
+	iE-Extensions		ProtocolExtensionContainer { { UACType-Item-ExtIEs } } OPTIONAL
+}
+
+UACType-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UACCategoryType ::= CHOICE {
+	uACstandardized				UACAction,
+	uACOperatorDefined			UACOperatorDefined, 
+	choice-extension			ProtocolIE-SingleContainer { { UACCategoryType-ExtIEs } }
+}
+
+UACCategoryType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+UACOperatorDefined ::= SEQUENCE {
+	accessCategory					INTEGER (32..63,...),
+	accessIdentity					BIT STRING (SIZE(7)),
+	iE-Extensions		ProtocolExtensionContainer { { UACOperatorDefined-ExtIEs} } OPTIONAL
+}
+
+UACOperatorDefined-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+UACAction ::= ENUMERATED {
+	reject-non-emergency-mo-dt,
+	reject-rrc-cr-signalling,
+	permit-emergency-sessions-and-mobile-terminated-services-only,
+	permit-high-priority-sessions-and-mobile-terminated-services-only,
+	...
+}
+
+UACReductionIndication ::= INTEGER (0..100)
+
+
+UE-associatedLogicalF1-ConnectionItem ::= SEQUENCE {
+	gNB-CU-UE-F1AP-ID		GNB-CU-UE-F1AP-ID	 OPTIONAL,
+	gNB-DU-UE-F1AP-ID		GNB-DU-UE-F1AP-ID	 OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { UE-associatedLogicalF1-ConnectionItemExtIEs} } OPTIONAL,
+	...
+}
+
+UEAssistanceInformation ::= OCTET STRING
+
+UEAssistanceInformationEUTRA ::= OCTET STRING
+
+UE-associatedLogicalF1-ConnectionItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UE-CapabilityRAT-ContainerList::= OCTET STRING
+
+UEContextNotRetrievable ::= ENUMERATED {true, ...}
+
+UEIdentityIndexValue ::= CHOICE {
+	indexLength10			BIT STRING (SIZE (10)),
+	choice-extension		ProtocolIE-SingleContainer { {UEIdentityIndexValueChoice-ExtIEs} }	
+}
+
+UEIdentityIndexValueChoice-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+UL-AoA ::= SEQUENCE {
+	azimuthAoA				INTEGER (0..3599),
+	zenithAoA				INTEGER (0..1799)	OPTIONAL,
+	angleCoordinateSystem	ENUMERATED {lCS, gCS}	OPTIONAL,
+	iE-extensions			ProtocolExtensionContainer { { UL-AoA-ExtIEs } }
+}
+
+UL-AoA-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UL-BH-Non-UP-Traffic-Mapping ::= SEQUENCE {
+	uL-BH-Non-UP-Traffic-Mapping-List			UL-BH-Non-UP-Traffic-Mapping-List,
+	iE-Extensions	ProtocolExtensionContainer { { UL-BH-Non-UP-Traffic-Mapping-ExtIEs } } OPTIONAL
+}
+
+UL-BH-Non-UP-Traffic-Mapping-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UL-BH-Non-UP-Traffic-Mapping-List ::= SEQUENCE (SIZE(1..maxnoofNonUPTrafficMappings)) OF UL-BH-Non-UP-Traffic-Mapping-Item
+
+UL-BH-Non-UP-Traffic-Mapping-Item ::= SEQUENCE {
+	nonUPTrafficType				NonUPTrafficType,
+	bHInfo						BHInfo,
+	iE-Extensions					ProtocolExtensionContainer { { UL-BH-Non-UP-Traffic-Mapping-ItemExtIEs } }	OPTIONAL
+}
+
+UL-BH-Non-UP-Traffic-Mapping-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { 
+	...
+}
+
+ULConfiguration ::= SEQUENCE	{
+	uLUEConfiguration		ULUEConfiguration,
+	iE-Extensions	ProtocolExtensionContainer { { ULConfigurationExtIEs } }	OPTIONAL,
+	...
+}
+ULConfigurationExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UL-RTOA-Measurement ::= SEQUENCE {
+	uL-RTOA-MeasurementItem		UL-RTOA-MeasurementItem,
+	additionalPath-List			AdditionalPath-List OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { UL-RTOA-Measurement-ExtIEs } }	OPTIONAL
+}
+
+UL-RTOA-Measurement-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UL-RTOA-MeasurementItem ::= CHOICE {
+	k0					INTEGER (0..1970049),
+	k1					INTEGER (0..985025),
+	k2					INTEGER (0..492513),
+	k3					INTEGER (0..246257),
+	k4					INTEGER (0..123129),
+	k5					INTEGER (0..61565),	 
+	choice-extension			ProtocolIE-SingleContainer { { UL-RTOA-MeasurementItem-ExtIEs } }
+}
+
+UL-RTOA-MeasurementItem-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+UL-SRS-RSRP ::= INTEGER (0..127)
+
+ULUEConfiguration ::= ENUMERATED {no-data, shared, only, ...}
+
+UL-UP-TNL-Information-to-Update-List-Item	::= SEQUENCE {
+	uLUPTNLInformation		UPTransportLayerInformation,
+	newULUPTNLInformation	UPTransportLayerInformation		OPTIONAL,
+	bHInfo	BHInfo,
+	iE-Extensions	ProtocolExtensionContainer { { UL-UP-TNL-Information-to-Update-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+UL-UP-TNL-Information-to-Update-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UL-UP-TNL-Address-to-Update-List-Item	::= SEQUENCE {
+	oldIPAdress						TransportLayerAddress,
+	newIPAdress						TransportLayerAddress,
+	iE-Extensions	ProtocolExtensionContainer { { UL-UP-TNL-Address-to-Update-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+UL-UP-TNL-Address-to-Update-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ULUPTNLInformation-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofULUPTNLInformation)) OF ULUPTNLInformation-ToBeSetup-Item
+
+ULUPTNLInformation-ToBeSetup-Item ::=SEQUENCE {
+	uLUPTNLInformation		UPTransportLayerInformation, 
+	iE-Extensions	ProtocolExtensionContainer { { ULUPTNLInformation-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+ULUPTNLInformation-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-BHInfo		CRITICALITY ignore	EXTENSION BHInfo		PRESENCE optional	},
+	...
+}
+
+Uncertainty ::= INTEGER (0..32767, ...)
+
+UplinkChannelBW-PerSCS-List ::= SEQUENCE (SIZE (1..maxnoSCSs)) OF SCS-SpecificCarrier
+
+UplinkTxDirectCurrentListInformation ::= OCTET STRING
+
+UPTransportLayerInformation		::= CHOICE {
+	gTPTunnel		GTPTunnel,
+	choice-extension			ProtocolIE-SingleContainer { { UPTransportLayerInformation-ExtIEs} }
+}
+
+UPTransportLayerInformation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+URI-address ::= VisibleString
+
+-- V
+
+VictimgNBSetID ::= SEQUENCE {
+	victimgNBSetID		GNBSetID,
+	iE-Extensions	ProtocolExtensionContainer { { VictimgNBSetID-ExtIEs } }		OPTIONAL
+}
+
+VictimgNBSetID-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+VehicleUE ::= ENUMERATED { 
+	authorized,
+	not-authorized,
+	...
+}
+
+PedestrianUE ::= ENUMERATED { 
+	authorized,
+	not-authorized,
+	...
+}
+
+-- W
+
+-- X
+
+-- Y
+
+-- Z
+
+END
+-- ASN1STOP 
+
+-- ASN1START 
+-- **************************************************************
+--
+-- Common definitions
+--
+-- **************************************************************
+
+F1AP-CommonDataTypes {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-CommonDataTypes (3) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+Criticality		::= ENUMERATED { reject, ignore, notify }
+
+Presence		::= ENUMERATED { optional, conditional, mandatory }
+
+PrivateIE-ID	::= CHOICE {
+	local				INTEGER (0..65535),
+	global				OBJECT IDENTIFIER
+}
+
+ProcedureCode		::= INTEGER (0..255)
+
+ProtocolExtensionID	::= INTEGER (0..65535)
+
+ProtocolIE-ID		::= INTEGER (0..65535)
+
+TriggeringMessage	::= ENUMERATED { initiating-message, successful-outcome, unsuccessful-outcome }
+
+END
+-- ASN1STOP 
+
+-- ASN1START 
+-- **************************************************************
+--
+-- Constant definitions
+--
+-- **************************************************************
+
+F1AP-Constants { 
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-Constants (4) } 
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	ProcedureCode,
+	ProtocolIE-ID
+
+FROM F1AP-CommonDataTypes;
+
+
+-- **************************************************************
+--
+-- Elementary Procedures
+--
+-- **************************************************************
+
+id-Reset									ProcedureCode ::= 0
+id-F1Setup									ProcedureCode ::= 1
+id-ErrorIndication							ProcedureCode ::= 2
+id-gNBDUConfigurationUpdate					ProcedureCode ::= 3
+id-gNBCUConfigurationUpdate					ProcedureCode ::= 4
+id-UEContextSetup							ProcedureCode ::= 5
+id-UEContextRelease							ProcedureCode ::= 6
+id-UEContextModification					ProcedureCode ::= 7
+id-UEContextModificationRequired			ProcedureCode ::= 8
+id-UEMobilityCommand						ProcedureCode ::= 9
+id-UEContextReleaseRequest					ProcedureCode ::= 10
+id-InitialULRRCMessageTransfer				ProcedureCode ::= 11
+id-DLRRCMessageTransfer						ProcedureCode ::= 12
+id-ULRRCMessageTransfer						ProcedureCode ::= 13
+id-privateMessage							ProcedureCode ::= 14
+id-UEInactivityNotification					ProcedureCode ::= 15
+id-GNBDUResourceCoordination				ProcedureCode ::= 16
+id-SystemInformationDeliveryCommand			ProcedureCode ::= 17
+id-Paging									ProcedureCode ::= 18
+id-Notify									ProcedureCode ::= 19
+id-WriteReplaceWarning						ProcedureCode ::= 20
+id-PWSCancel								ProcedureCode ::= 21
+id-PWSRestartIndication						ProcedureCode ::= 22
+id-PWSFailureIndication						ProcedureCode ::= 23
+id-GNBDUStatusIndication 					ProcedureCode ::= 24
+id-RRCDeliveryReport		 				ProcedureCode ::= 25
+id-F1Removal								ProcedureCode ::= 26
+id-NetworkAccessRateReduction				ProcedureCode ::= 27
+id-TraceStart								ProcedureCode ::= 28
+id-DeactivateTrace							ProcedureCode ::= 29
+id-DUCURadioInformationTransfer				ProcedureCode ::= 30
+id-CUDURadioInformationTransfer				ProcedureCode ::= 31
+id-BAPMappingConfiguration					ProcedureCode ::= 32
+id-GNBDUResourceConfiguration				ProcedureCode ::= 33
+id-IABTNLAddressAllocation					ProcedureCode ::= 34
+id-IABUPConfigurationUpdate					ProcedureCode ::= 35
+id-resourceStatusReportingInitiation		ProcedureCode ::= 36
+id-resourceStatusReporting					ProcedureCode ::= 37
+id-accessAndMobilityIndication				ProcedureCode ::= 38
+id-accessSuccess							ProcedureCode ::= 39
+id-cellTrafficTrace 						ProcedureCode ::= 40 
+id-PositioningMeasurementExchange			ProcedureCode ::= 41
+id-PositioningAssistanceInformationControl	ProcedureCode ::= 42
+id-PositioningAssistanceInformationFeedback	ProcedureCode ::= 43
+id-PositioningMeasurementReport				ProcedureCode ::= 44
+id-PositioningMeasurementAbort				ProcedureCode ::= 45
+id-PositioningMeasurementFailureIndication	ProcedureCode ::= 46
+id-PositioningMeasurementUpdate				ProcedureCode ::= 47
+id-TRPInformationExchange					ProcedureCode ::= 48
+id-PositioningInformationExchange			ProcedureCode ::= 49
+id-PositioningActivation					ProcedureCode ::= 50
+id-PositioningDeactivation					ProcedureCode ::= 51
+id-E-CIDMeasurementInitiation				ProcedureCode ::= 52
+id-E-CIDMeasurementFailureIndication		ProcedureCode ::= 53
+id-E-CIDMeasurementReport					ProcedureCode ::= 54
+id-E-CIDMeasurementTermination				ProcedureCode ::= 55
+id-PositioningInformationUpdate				ProcedureCode ::= 56
+id-ReferenceTimeInformationReport			ProcedureCode ::= 57
+id-ReferenceTimeInformationReportingControl	ProcedureCode ::= 58
+
+
+
+-- **************************************************************
+--
+-- Extension constants
+--
+-- **************************************************************
+
+maxPrivateIEs							INTEGER ::= 65535
+maxProtocolExtensions					INTEGER ::= 65535
+maxProtocolIEs							INTEGER ::= 65535
+-- **************************************************************
+--
+-- Lists
+--
+-- **************************************************************
+
+maxNRARFCN								INTEGER ::= 3279165
+maxnoofErrors							INTEGER ::= 256
+maxnoofIndividualF1ConnectionsToReset	INTEGER ::= 65536
+maxCellingNBDU							INTEGER ::= 512
+maxnoofSCells							INTEGER ::= 32
+maxnoofSRBs								INTEGER ::= 8
+maxnoofDRBs								INTEGER ::= 64
+maxnoofULUPTNLInformation				INTEGER ::= 2
+maxnoofDLUPTNLInformation				INTEGER ::= 2
+maxnoofBPLMNs							INTEGER ::= 6
+maxnoofCandidateSpCells					INTEGER ::= 64
+maxnoofPotentialSpCells					INTEGER ::= 64
+maxnoofNrCellBands						INTEGER ::= 32
+maxnoofSIBTypes							INTEGER ::= 32
+maxnoofSITypes							INTEGER ::= 32
+maxnoofPagingCells						INTEGER ::= 512
+maxnoofTNLAssociations					INTEGER ::= 32
+maxnoofQoSFlows							INTEGER ::= 64
+maxnoofSliceItems						INTEGER ::= 1024
+maxCellineNB							INTEGER ::= 256
+maxnoofExtendedBPLMNs					INTEGER ::= 6
+maxnoofUEIDs							INTEGER ::= 65536
+maxnoofBPLMNsNR							INTEGER ::= 12
+maxnoofUACPLMNs							INTEGER ::= 12
+maxnoofUACperPLMN						INTEGER ::= 64
+maxnoofAdditionalSIBs					INTEGER ::= 63
+maxnoofslots							INTEGER ::= 5120
+maxnoofTLAs								INTEGER ::=	16
+maxnoofGTPTLAs							INTEGER ::=	16
+maxnoofBHRLCChannels					INTEGER ::= 65536
+maxnoofRoutingEntries					INTEGER ::= 1024
+maxnoofIABSTCInfo						INTEGER ::= 45
+maxnoofSymbols							INTEGER ::= 14
+maxnoofServingCells						INTEGER ::= 32
+maxnoofDUFSlots							INTEGER ::= 320
+maxnoofHSNASlots						INTEGER ::= 5120
+maxnoofServedCellsIAB					INTEGER ::= 512 
+maxnoofChildIABNodes					INTEGER ::= 1024
+maxnoofNonUPTrafficMappings				INTEGER ::= 32
+maxnoofTLAsIAB							INTEGER ::= 1024
+maxnoofMappingEntries					INTEGER ::= 67108864
+maxnoofDSInfo							INTEGER ::= 64
+maxnoofEgressLinks						INTEGER ::= 2
+maxnoofULUPTNLInformationforIAB			INTEGER ::= 32678
+maxnoofUPTNLAddresses					INTEGER ::= 8
+maxnoofSLDRBs							INTEGER ::= 512
+maxnoofQoSParaSets						INTEGER ::= 8
+maxnoofPC5QoSFlows						INTEGER ::= 2048
+maxnoofSSBAreas							INTEGER ::=	64
+maxnoofPhysicalResourceBlocks			INTEGER ::= 275
+maxnoofPhysicalResourceBlocks-1			INTEGER ::= 274
+maxnoofPRACHconfigs						INTEGER ::= 16
+maxnoofRACHReports						INTEGER ::= 64
+maxnoofRLFReports						INTEGER ::= 64
+maxnoofAdditionalPDCPDuplicationTNL		INTEGER ::=	2
+maxnoofRLCDuplicationState				INTEGER ::=	3
+maxnoofCHOcells							INTEGER ::= 8
+maxnoofMDTPLMNs							INTEGER ::=	16
+maxnoofCAGsupported						INTEGER ::= 12
+maxnoofNIDsupported						INTEGER ::= 12
+maxnoofNRSCSs							INTEGER ::= 5
+maxnoofExtSliceItems					INTEGER ::= 65535 
+maxnoofPosMeas							INTEGER ::=	16384
+maxnoofTRPInfoTypes						INTEGER ::=	64 
+maxnoofTRPs								INTEGER ::=	65535 
+maxnoofSRSTriggerStates					INTEGER ::= 3
+maxnoofSpatialRelations					INTEGER ::= 64
+maxnoBcastCell							INTEGER ::= 16384
+maxnoofAngleInfo						INTEGER ::= 65535
+maxnooflcs-gcs-translation				INTEGER ::= 3
+maxnoofPath								INTEGER ::= 2
+maxnoofMeasE-CID						INTEGER ::= 64
+maxnoofSSBs								INTEGER ::= 255
+maxnoSRS-ResourceSets					INTEGER ::= 16
+maxnoSRS-ResourcePerSet					INTEGER ::= 16
+maxnoSRS-Carriers						INTEGER ::= 32
+maxnoSCSs								INTEGER ::= 5
+maxnoSRS-Resources						INTEGER ::= 64
+maxnoSRS-PosResources					INTEGER ::= 64
+maxnoSRS-PosResourceSets				INTEGER ::= 16
+maxnoSRS-PosResourcePerSet				INTEGER ::= 16
+maxnoofPRS-ResourceSets					INTEGER ::= 2
+maxnoofPRS-ResourcesPerSet				INTEGER ::= 64
+maxNoOfMeasTRPs							INTEGER ::= 64
+maxnoofPRSresourceSets					INTEGER ::= 8
+maxnoofPRSresources						INTEGER ::= 64
+
+
+
+-- **************************************************************
+--
+-- IEs
+--
+-- **************************************************************
+
+id-Cause											ProtocolIE-ID ::= 0
+id-Cells-Failed-to-be-Activated-List				ProtocolIE-ID ::= 1
+id-Cells-Failed-to-be-Activated-List-Item			ProtocolIE-ID ::= 2
+id-Cells-to-be-Activated-List						ProtocolIE-ID ::= 3
+id-Cells-to-be-Activated-List-Item					ProtocolIE-ID ::= 4
+id-Cells-to-be-Deactivated-List						ProtocolIE-ID ::= 5
+id-Cells-to-be-Deactivated-List-Item				ProtocolIE-ID ::= 6
+id-CriticalityDiagnostics							ProtocolIE-ID ::= 7
+id-CUtoDURRCInformation								ProtocolIE-ID ::= 9
+id-DRBs-FailedToBeModified-Item						ProtocolIE-ID ::= 12
+id-DRBs-FailedToBeModified-List						ProtocolIE-ID ::= 13
+id-DRBs-FailedToBeSetup-Item						ProtocolIE-ID ::= 14
+id-DRBs-FailedToBeSetup-List						ProtocolIE-ID ::= 15
+id-DRBs-FailedToBeSetupMod-Item						ProtocolIE-ID ::= 16
+id-DRBs-FailedToBeSetupMod-List						ProtocolIE-ID ::= 17
+id-DRBs-ModifiedConf-Item							ProtocolIE-ID ::= 18
+id-DRBs-ModifiedConf-List							ProtocolIE-ID ::= 19
+id-DRBs-Modified-Item								ProtocolIE-ID ::= 20
+id-DRBs-Modified-List								ProtocolIE-ID ::= 21
+id-DRBs-Required-ToBeModified-Item					ProtocolIE-ID ::= 22
+id-DRBs-Required-ToBeModified-List					ProtocolIE-ID ::= 23
+id-DRBs-Required-ToBeReleased-Item					ProtocolIE-ID ::= 24
+id-DRBs-Required-ToBeReleased-List					ProtocolIE-ID ::= 25
+id-DRBs-Setup-Item									ProtocolIE-ID ::= 26
+id-DRBs-Setup-List									ProtocolIE-ID ::= 27
+id-DRBs-SetupMod-Item								ProtocolIE-ID ::= 28
+id-DRBs-SetupMod-List								ProtocolIE-ID ::= 29
+id-DRBs-ToBeModified-Item							ProtocolIE-ID ::= 30
+id-DRBs-ToBeModified-List							ProtocolIE-ID ::= 31
+id-DRBs-ToBeReleased-Item							ProtocolIE-ID ::= 32
+id-DRBs-ToBeReleased-List							ProtocolIE-ID ::= 33
+id-DRBs-ToBeSetup-Item								ProtocolIE-ID ::= 34
+id-DRBs-ToBeSetup-List								ProtocolIE-ID ::= 35
+id-DRBs-ToBeSetupMod-Item							ProtocolIE-ID ::= 36
+id-DRBs-ToBeSetupMod-List							ProtocolIE-ID ::= 37
+id-DRXCycle											ProtocolIE-ID ::= 38
+id-DUtoCURRCInformation								ProtocolIE-ID ::= 39
+id-gNB-CU-UE-F1AP-ID								ProtocolIE-ID ::= 40
+id-gNB-DU-UE-F1AP-ID								ProtocolIE-ID ::= 41
+id-gNB-DU-ID										ProtocolIE-ID ::= 42
+id-GNB-DU-Served-Cells-Item							ProtocolIE-ID ::= 43
+id-gNB-DU-Served-Cells-List							ProtocolIE-ID ::= 44
+id-gNB-DU-Name										ProtocolIE-ID ::= 45
+id-NRCellID											ProtocolIE-ID ::= 46
+id-oldgNB-DU-UE-F1AP-ID								ProtocolIE-ID ::= 47
+id-ResetType										ProtocolIE-ID ::= 48
+id-ResourceCoordinationTransferContainer			ProtocolIE-ID ::= 49
+id-RRCContainer										ProtocolIE-ID ::= 50
+id-SCell-ToBeRemoved-Item							ProtocolIE-ID ::= 51
+id-SCell-ToBeRemoved-List							ProtocolIE-ID ::= 52
+id-SCell-ToBeSetup-Item								ProtocolIE-ID ::= 53
+id-SCell-ToBeSetup-List								ProtocolIE-ID ::= 54
+id-SCell-ToBeSetupMod-Item							ProtocolIE-ID ::= 55
+id-SCell-ToBeSetupMod-List							ProtocolIE-ID ::= 56
+id-Served-Cells-To-Add-Item							ProtocolIE-ID ::= 57
+id-Served-Cells-To-Add-List							ProtocolIE-ID ::= 58
+id-Served-Cells-To-Delete-Item						ProtocolIE-ID ::= 59
+id-Served-Cells-To-Delete-List						ProtocolIE-ID ::= 60
+id-Served-Cells-To-Modify-Item						ProtocolIE-ID ::= 61
+id-Served-Cells-To-Modify-List						ProtocolIE-ID ::= 62
+id-SpCell-ID										ProtocolIE-ID ::= 63
+id-SRBID											ProtocolIE-ID ::= 64
+id-SRBs-FailedToBeSetup-Item						ProtocolIE-ID ::= 65
+id-SRBs-FailedToBeSetup-List						ProtocolIE-ID ::= 66
+id-SRBs-FailedToBeSetupMod-Item						ProtocolIE-ID ::= 67
+id-SRBs-FailedToBeSetupMod-List						ProtocolIE-ID ::= 68
+id-SRBs-Required-ToBeReleased-Item					ProtocolIE-ID ::= 69
+id-SRBs-Required-ToBeReleased-List					ProtocolIE-ID ::= 70
+id-SRBs-ToBeReleased-Item							ProtocolIE-ID ::= 71
+id-SRBs-ToBeReleased-List							ProtocolIE-ID ::= 72
+id-SRBs-ToBeSetup-Item								ProtocolIE-ID ::= 73
+id-SRBs-ToBeSetup-List								ProtocolIE-ID ::= 74
+id-SRBs-ToBeSetupMod-Item							ProtocolIE-ID ::= 75
+id-SRBs-ToBeSetupMod-List							ProtocolIE-ID ::= 76
+id-TimeToWait										ProtocolIE-ID ::= 77
+id-TransactionID									ProtocolIE-ID ::= 78
+id-TransmissionActionIndicator						ProtocolIE-ID ::= 79
+id-UE-associatedLogicalF1-ConnectionItem 			ProtocolIE-ID ::= 80
+id-UE-associatedLogicalF1-ConnectionListResAck		ProtocolIE-ID ::= 81
+id-gNB-CU-Name										ProtocolIE-ID ::= 82
+id-SCell-FailedtoSetup-List							ProtocolIE-ID ::= 83
+id-SCell-FailedtoSetup-Item							ProtocolIE-ID ::= 84
+id-SCell-FailedtoSetupMod-List						ProtocolIE-ID ::= 85
+id-SCell-FailedtoSetupMod-Item						ProtocolIE-ID ::= 86
+id-RRCReconfigurationCompleteIndicator 				ProtocolIE-ID ::= 87
+id-Cells-Status-Item								ProtocolIE-ID ::= 88
+id-Cells-Status-List								ProtocolIE-ID ::= 89
+id-Candidate-SpCell-List							ProtocolIE-ID ::= 90
+id-Candidate-SpCell-Item							ProtocolIE-ID ::= 91
+id-Potential-SpCell-List							ProtocolIE-ID ::= 92
+id-Potential-SpCell-Item							ProtocolIE-ID ::= 93
+id-FullConfiguration								ProtocolIE-ID ::= 94
+id-C-RNTI											ProtocolIE-ID ::= 95
+id-SpCellULConfigured								ProtocolIE-ID ::= 96
+id-InactivityMonitoringRequest						ProtocolIE-ID ::= 97
+id-InactivityMonitoringResponse						ProtocolIE-ID ::= 98
+id-DRB-Activity-Item								ProtocolIE-ID ::= 99
+id-DRB-Activity-List								ProtocolIE-ID ::= 100
+id-EUTRA-NR-CellResourceCoordinationReq-Container 		ProtocolIE-ID ::= 101
+id-EUTRA-NR-CellResourceCoordinationReqAck-Container 	ProtocolIE-ID ::= 102
+id-Protected-EUTRA-Resources-List					ProtocolIE-ID ::= 105
+id-RequestType 										ProtocolIE-ID ::= 106
+id-ServCellIndex									ProtocolIE-ID ::= 107 
+id-RAT-FrequencyPriorityInformation					ProtocolIE-ID ::= 108
+id-ExecuteDuplication								ProtocolIE-ID ::= 109
+id-NRCGI											ProtocolIE-ID ::= 111
+id-PagingCell-Item									ProtocolIE-ID ::= 112
+id-PagingCell-List									ProtocolIE-ID ::= 113
+id-PagingDRX										ProtocolIE-ID ::= 114
+id-PagingPriority 									ProtocolIE-ID ::= 115
+id-SItype-List										ProtocolIE-ID ::= 116
+id-UEIdentityIndexValue								ProtocolIE-ID ::= 117
+id-gNB-CUSystemInformation							ProtocolIE-ID ::= 118
+id-HandoverPreparationInformation					ProtocolIE-ID ::= 119
+id-GNB-CU-TNL-Association-To-Add-Item				ProtocolIE-ID ::= 120
+id-GNB-CU-TNL-Association-To-Add-List				ProtocolIE-ID ::= 121
+id-GNB-CU-TNL-Association-To-Remove-Item			ProtocolIE-ID ::= 122
+id-GNB-CU-TNL-Association-To-Remove-List			ProtocolIE-ID ::= 123
+id-GNB-CU-TNL-Association-To-Update-Item			ProtocolIE-ID ::= 124
+id-GNB-CU-TNL-Association-To-Update-List			ProtocolIE-ID ::= 125
+id-MaskedIMEISV										ProtocolIE-ID ::= 126
+id-PagingIdentity									ProtocolIE-ID ::= 127
+id-DUtoCURRCContainer								ProtocolIE-ID ::= 128
+id-Cells-to-be-Barred-List							ProtocolIE-ID ::= 129
+id-Cells-to-be-Barred-Item							ProtocolIE-ID ::= 130
+id-TAISliceSupportList								ProtocolIE-ID ::= 131
+id-GNB-CU-TNL-Association-Setup-List				ProtocolIE-ID ::= 132
+id-GNB-CU-TNL-Association-Setup-Item				ProtocolIE-ID ::= 133
+id-GNB-CU-TNL-Association-Failed-To-Setup-List		ProtocolIE-ID ::= 134
+id-GNB-CU-TNL-Association-Failed-To-Setup-Item		ProtocolIE-ID ::= 135
+id-DRB-Notify-Item									ProtocolIE-ID ::= 136
+id-DRB-Notify-List									ProtocolIE-ID ::= 137
+id-NotficationControl								ProtocolIE-ID ::= 138
+id-RANAC											ProtocolIE-ID ::= 139
+id-PWSSystemInformation								ProtocolIE-ID ::= 140
+id-RepetitionPeriod									ProtocolIE-ID ::= 141
+id-NumberofBroadcastRequest							ProtocolIE-ID ::= 142
+id-Cells-To-Be-Broadcast-List						ProtocolIE-ID ::= 144
+id-Cells-To-Be-Broadcast-Item						ProtocolIE-ID ::= 145
+id-Cells-Broadcast-Completed-List 					ProtocolIE-ID ::= 146
+id-Cells-Broadcast-Completed-Item 					ProtocolIE-ID ::= 147
+id-Broadcast-To-Be-Cancelled-List 					ProtocolIE-ID ::= 148
+id-Broadcast-To-Be-Cancelled-Item 					ProtocolIE-ID ::= 149
+id-Cells-Broadcast-Cancelled-List 					ProtocolIE-ID ::= 150
+id-Cells-Broadcast-Cancelled-Item 					ProtocolIE-ID ::= 151
+id-NR-CGI-List-For-Restart-List 					ProtocolIE-ID ::= 152
+id-NR-CGI-List-For-Restart-Item 					ProtocolIE-ID ::= 153
+id-PWS-Failed-NR-CGI-List 							ProtocolIE-ID ::= 154
+id-PWS-Failed-NR-CGI-Item 							ProtocolIE-ID ::= 155
+id-ConfirmedUEID									ProtocolIE-ID ::= 156
+id-Cancel-all-Warning-Messages-Indicator			ProtocolIE-ID ::= 157
+id-GNB-DU-UE-AMBR-UL								ProtocolIE-ID ::= 158
+id-DRXConfigurationIndicator						ProtocolIE-ID ::= 159
+id-RLC-Status										ProtocolIE-ID ::= 160
+id-DLPDCPSNLength									ProtocolIE-ID ::= 161
+id-GNB-DUConfigurationQuery							ProtocolIE-ID ::= 162
+id-MeasurementTimingConfiguration					ProtocolIE-ID ::= 163
+id-DRB-Information									ProtocolIE-ID ::= 164
+id-ServingPLMN										ProtocolIE-ID ::= 165
+id-Protected-EUTRA-Resources-Item					ProtocolIE-ID ::= 168
+id-GNB-CU-RRC-Version								ProtocolIE-ID ::= 170
+id-GNB-DU-RRC-Version								ProtocolIE-ID ::= 171
+id-GNBDUOverloadInformation							ProtocolIE-ID ::= 172
+id-CellGroupConfig									ProtocolIE-ID ::= 173
+id-RLCFailureIndication								ProtocolIE-ID ::= 174
+id-UplinkTxDirectCurrentListInformation				ProtocolIE-ID ::= 175
+id-DC-Based-Duplication-Configured					ProtocolIE-ID ::= 176
+id-DC-Based-Duplication-Activation					ProtocolIE-ID ::= 177
+id-SULAccessIndication								ProtocolIE-ID ::= 178
+id-AvailablePLMNList								ProtocolIE-ID ::= 179
+id-PDUSessionID										ProtocolIE-ID ::= 180
+id-ULPDUSessionAggregateMaximumBitRate				ProtocolIE-ID ::= 181
+id-ServingCellMO									ProtocolIE-ID ::= 182
+id-QoSFlowMappingIndication							ProtocolIE-ID ::= 183
+id-RRCDeliveryStatusRequest							ProtocolIE-ID ::= 184
+id-RRCDeliveryStatus								ProtocolIE-ID ::= 185
+id-BearerTypeChange									ProtocolIE-ID ::= 186
+id-RLCMode											ProtocolIE-ID ::= 187
+id-Duplication-Activation							ProtocolIE-ID ::= 188
+id-Dedicated-SIDelivery-NeededUE-List				ProtocolIE-ID ::= 189
+id-Dedicated-SIDelivery-NeededUE-Item				ProtocolIE-ID ::= 190
+id-DRX-LongCycleStartOffset							ProtocolIE-ID ::= 191
+id-ULPDCPSNLength									ProtocolIE-ID ::= 192
+id-SelectedBandCombinationIndex						ProtocolIE-ID ::= 193
+id-SelectedFeatureSetEntryIndex						ProtocolIE-ID ::= 194
+id-ResourceCoordinationTransferInformation			ProtocolIE-ID ::= 195
+id-ExtendedServedPLMNs-List							ProtocolIE-ID ::= 196
+id-ExtendedAvailablePLMN-List						ProtocolIE-ID ::= 197
+id-Associated-SCell-List							ProtocolIE-ID ::= 198
+id-latest-RRC-Version-Enhanced						ProtocolIE-ID ::= 199
+id-Associated-SCell-Item							ProtocolIE-ID ::= 200
+id-Cell-Direction									ProtocolIE-ID ::= 201
+id-SRBs-Setup-List									ProtocolIE-ID ::= 202
+id-SRBs-Setup-Item									ProtocolIE-ID ::= 203
+id-SRBs-SetupMod-List								ProtocolIE-ID ::= 204
+id-SRBs-SetupMod-Item								ProtocolIE-ID ::= 205
+id-SRBs-Modified-List								ProtocolIE-ID ::= 206
+id-SRBs-Modified-Item								ProtocolIE-ID ::= 207
+id-Ph-InfoSCG										ProtocolIE-ID ::= 208
+id-RequestedBandCombinationIndex					ProtocolIE-ID ::= 209
+id-RequestedFeatureSetEntryIndex					ProtocolIE-ID ::= 210
+id-RequestedP-MaxFR2								ProtocolIE-ID ::= 211
+id-DRX-Config										ProtocolIE-ID ::= 212
+id-IgnoreResourceCoordinationContainer				ProtocolIE-ID ::= 213
+id-UEAssistanceInformation							ProtocolIE-ID ::= 214
+id-NeedforGap										ProtocolIE-ID ::= 215
+id-PagingOrigin										ProtocolIE-ID ::= 216
+id-new-gNB-CU-UE-F1AP-ID							ProtocolIE-ID ::= 217
+id-RedirectedRRCmessage								ProtocolIE-ID ::= 218
+id-new-gNB-DU-UE-F1AP-ID							ProtocolIE-ID ::= 219
+id-NotificationInformation							ProtocolIE-ID ::= 220
+id-PLMNAssistanceInfoForNetShar						ProtocolIE-ID ::= 221
+id-UEContextNotRetrievable							ProtocolIE-ID ::= 222
+id-BPLMN-ID-Info-List								ProtocolIE-ID ::= 223
+id-SelectedPLMNID									ProtocolIE-ID ::= 224
+id-UAC-Assistance-Info								ProtocolIE-ID ::= 225
+id-RANUEID											ProtocolIE-ID ::= 226
+id-GNB-DU-TNL-Association-To-Remove-Item			ProtocolIE-ID ::= 227
+id-GNB-DU-TNL-Association-To-Remove-List			ProtocolIE-ID ::= 228
+id-TNLAssociationTransportLayerAddressgNBDU			ProtocolIE-ID ::= 229
+id-portNumber										ProtocolIE-ID ::= 230
+id-AdditionalSIBMessageList							ProtocolIE-ID ::= 231
+id-Cell-Type										ProtocolIE-ID ::= 232
+id-IgnorePRACHConfiguration							ProtocolIE-ID ::= 233
+id-CG-Config										ProtocolIE-ID ::= 234
+id-PDCCH-BlindDetectionSCG							ProtocolIE-ID ::= 235
+id-Requested-PDCCH-BlindDetectionSCG				ProtocolIE-ID ::= 236
+id-Ph-InfoMCG										ProtocolIE-ID ::= 237
+id-MeasGapSharingConfig								ProtocolIE-ID ::= 238
+id-systemInformationAreaID							ProtocolIE-ID ::= 239
+id-areaScope										ProtocolIE-ID ::= 240
+id-RRCContainer-RRCSetupComplete					ProtocolIE-ID ::= 241
+id-TraceActivation									ProtocolIE-ID ::= 242
+id-TraceID											ProtocolIE-ID ::= 243
+id-Neighbour-Cell-Information-List					ProtocolIE-ID ::= 244
+id-SymbolAllocInSlot								ProtocolIE-ID ::= 246
+id-NumDLULSymbols									ProtocolIE-ID ::= 247
+id-AdditionalRRMPriorityIndex						ProtocolIE-ID ::= 248
+id-DUCURadioInformationType							ProtocolIE-ID ::= 249
+id-CUDURadioInformationType 						ProtocolIE-ID ::= 250
+id-AggressorgNBSetID								ProtocolIE-ID ::= 251
+id-VictimgNBSetID									ProtocolIE-ID ::= 252
+id-LowerLayerPresenceStatusChange					ProtocolIE-ID ::= 253
+id-Transport-Layer-Address-Info						ProtocolIE-ID ::= 254
+id-Neighbour-Cell-Information-Item					ProtocolIE-ID ::= 255
+id-IntendedTDD-DL-ULConfig							ProtocolIE-ID ::= 256
+id-QosMonitoringRequest								ProtocolIE-ID ::= 257
+id-BHChannels-ToBeSetup-List						ProtocolIE-ID ::= 258
+id-BHChannels-ToBeSetup-Item						ProtocolIE-ID ::= 259
+id-BHChannels-Setup-List							ProtocolIE-ID ::= 260
+id-BHChannels-Setup-Item							ProtocolIE-ID ::= 261
+id-BHChannels-ToBeModified-Item						ProtocolIE-ID ::= 262
+id-BHChannels-ToBeModified-List						ProtocolIE-ID ::= 263
+id-BHChannels-ToBeReleased-Item						ProtocolIE-ID ::= 264
+id-BHChannels-ToBeReleased-List						ProtocolIE-ID ::= 265
+id-BHChannels-ToBeSetupMod-Item						ProtocolIE-ID ::= 266
+id-BHChannels-ToBeSetupMod-List						ProtocolIE-ID ::= 267
+id-BHChannels-FailedToBeModified-Item				ProtocolIE-ID ::= 268
+id-BHChannels-FailedToBeModified-List				ProtocolIE-ID ::= 269
+id-BHChannels-FailedToBeSetupMod-Item				ProtocolIE-ID ::= 270
+id-BHChannels-FailedToBeSetupMod-List				ProtocolIE-ID ::= 271
+id-BHChannels-Modified-Item							ProtocolIE-ID ::= 272
+id-BHChannels-Modified-List							ProtocolIE-ID ::= 273
+id-BHChannels-SetupMod-Item							ProtocolIE-ID ::= 274
+id-BHChannels-SetupMod-List							ProtocolIE-ID ::= 275
+id-BHChannels-Required-ToBeReleased-Item			ProtocolIE-ID ::= 276
+id-BHChannels-Required-ToBeReleased-List			ProtocolIE-ID ::= 277
+id-BHChannels-FailedToBeSetup-Item					ProtocolIE-ID ::= 278
+id-BHChannels-FailedToBeSetup-List					ProtocolIE-ID ::= 279
+id-BHInfo											ProtocolIE-ID ::= 280
+id-BAPAddress										ProtocolIE-ID ::= 281
+id-ConfiguredBAPAddress								ProtocolIE-ID ::= 282
+id-BH-Routing-Information-Added-List				ProtocolIE-ID ::= 283
+id-BH-Routing-Information-Added-List-Item			ProtocolIE-ID ::= 284
+id-BH-Routing-Information-Removed-List				ProtocolIE-ID ::= 285
+id-BH-Routing-Information-Removed-List-Item			ProtocolIE-ID ::= 286
+id-UL-BH-Non-UP-Traffic-Mapping						ProtocolIE-ID ::= 287
+id-Activated-Cells-to-be-Updated-List				ProtocolIE-ID ::= 288
+id-Child-Nodes-List									ProtocolIE-ID ::= 289
+id-IAB-Info-IAB-DU									ProtocolIE-ID ::= 290
+id-IAB-Info-IAB-donor-CU							ProtocolIE-ID ::= 291
+id-IAB-TNL-Addresses-To-Remove-List					ProtocolIE-ID ::= 292
+id-IAB-TNL-Addresses-To-Remove-Item					ProtocolIE-ID ::= 293
+id-IAB-Allocated-TNL-Address-List					ProtocolIE-ID ::= 294
+id-IAB-Allocated-TNL-Address-Item					ProtocolIE-ID ::= 295
+id-IABIPv6RequestType								ProtocolIE-ID ::= 296
+id-IABv4AddressesRequested							ProtocolIE-ID ::= 297
+id-IAB-Barred										ProtocolIE-ID ::= 298
+id-TrafficMappingInformation						ProtocolIE-ID ::= 299
+id-UL-UP-TNL-Information-to-Update-List				ProtocolIE-ID ::= 300
+id-UL-UP-TNL-Information-to-Update-List-Item		ProtocolIE-ID ::= 301
+id-UL-UP-TNL-Address-to-Update-List					ProtocolIE-ID ::= 302
+id-UL-UP-TNL-Address-to-Update-List-Item			ProtocolIE-ID ::= 303
+id-DL-UP-TNL-Address-to-Update-List					ProtocolIE-ID ::= 304
+id-DL-UP-TNL-Address-to-Update-List-Item			ProtocolIE-ID ::= 305
+id-NRV2XServicesAuthorized							ProtocolIE-ID ::= 306
+id-LTEV2XServicesAuthorized							ProtocolIE-ID ::= 307
+id-NRUESidelinkAggregateMaximumBitrate				ProtocolIE-ID ::= 308
+id-LTEUESidelinkAggregateMaximumBitrate				ProtocolIE-ID ::= 309
+id-SIB12-message									ProtocolIE-ID ::= 310
+id-SIB13-message									ProtocolIE-ID ::= 311
+id-SIB14-message									ProtocolIE-ID ::= 312
+id-SLDRBs-FailedToBeModified-Item					ProtocolIE-ID ::= 313
+id-SLDRBs-FailedToBeModified-List					ProtocolIE-ID ::= 314
+id-SLDRBs-FailedToBeSetup-Item						ProtocolIE-ID ::= 315
+id-SLDRBs-FailedToBeSetup-List						ProtocolIE-ID ::= 316
+id-SLDRBs-Modified-Item								ProtocolIE-ID ::= 317
+id-SLDRBs-Modified-List								ProtocolIE-ID ::= 318
+id-SLDRBs-Required-ToBeModified-Item				ProtocolIE-ID ::= 319
+id-SLDRBs-Required-ToBeModified-List				ProtocolIE-ID ::= 320
+id-SLDRBs-Required-ToBeReleased-Item				ProtocolIE-ID ::= 321
+id-SLDRBs-Required-ToBeReleased-List				ProtocolIE-ID ::= 322
+id-SLDRBs-Setup-Item								ProtocolIE-ID ::= 323
+id-SLDRBs-Setup-List								ProtocolIE-ID ::= 324
+id-SLDRBs-ToBeModified-Item							ProtocolIE-ID ::= 325
+id-SLDRBs-ToBeModified-List							ProtocolIE-ID ::= 326
+id-SLDRBs-ToBeReleased-Item							ProtocolIE-ID ::= 327
+id-SLDRBs-ToBeReleased-List							ProtocolIE-ID ::= 328
+id-SLDRBs-ToBeSetup-Item							ProtocolIE-ID ::= 329
+id-SLDRBs-ToBeSetup-List							ProtocolIE-ID ::= 330
+id-SLDRBs-ToBeSetupMod-Item							ProtocolIE-ID ::= 331
+id-SLDRBs-ToBeSetupMod-List							ProtocolIE-ID ::= 332
+id-SLDRBs-SetupMod-List								ProtocolIE-ID ::= 333
+id-SLDRBs-FailedToBeSetupMod-List					ProtocolIE-ID ::= 334
+id-SLDRBs-SetupMod-Item								ProtocolIE-ID ::= 335
+id-SLDRBs-FailedToBeSetupMod-Item					ProtocolIE-ID ::= 336
+id-SLDRBs-ModifiedConf-List							ProtocolIE-ID ::= 337
+id-SLDRBs-ModifiedConf-Item							ProtocolIE-ID ::= 338
+id-UEAssistanceInformationEUTRA						ProtocolIE-ID ::= 339
+id-PC5LinkAMBR										ProtocolIE-ID ::= 340
+id-SL-PHY-MAC-RLC-Config							ProtocolIE-ID ::= 341
+id-SL-ConfigDedicatedEUTRA							ProtocolIE-ID ::= 342
+id-AlternativeQoSParaSetList						ProtocolIE-ID ::= 343
+id-CurrentQoSParaSetIndex							ProtocolIE-ID ::= 344
+id-gNBCUMeasurementID								ProtocolIE-ID ::= 345
+id-gNBDUMeasurementID								ProtocolIE-ID ::= 346
+id-RegistrationRequest								ProtocolIE-ID ::= 347
+id-ReportCharacteristics							ProtocolIE-ID ::= 348
+id-CellToReportList									ProtocolIE-ID ::= 349
+id-CellMeasurementResultList						ProtocolIE-ID ::= 350
+id-HardwareLoadIndicator							ProtocolIE-ID ::= 351
+id-ReportingPeriodicity								ProtocolIE-ID ::= 352
+id-TNLCapacityIndicator								ProtocolIE-ID ::= 353
+id-CarrierList										ProtocolIE-ID ::= 354
+id-ULCarrierList									ProtocolIE-ID ::= 355
+id-FrequencyShift7p5khz								ProtocolIE-ID ::= 356
+id-SSB-PositionsInBurst								ProtocolIE-ID ::= 357
+id-NRPRACHConfig									ProtocolIE-ID ::= 358
+id-RACHReportInformationList						ProtocolIE-ID ::= 359
+id-RLFReportInformationList							ProtocolIE-ID ::= 360
+id-TDD-UL-DLConfigCommonNR							ProtocolIE-ID ::= 361
+id-CNPacketDelayBudgetDownlink						ProtocolIE-ID ::= 362
+id-ExtendedPacketDelayBudget						ProtocolIE-ID ::= 363
+id-TSCTrafficCharacteristics						ProtocolIE-ID ::= 364
+id-ReportingRequestType								ProtocolIE-ID ::= 365
+id-TimeReferenceInformation							ProtocolIE-ID ::= 366
+id-CNPacketDelayBudgetUplink						ProtocolIE-ID ::= 369
+id-AdditionalPDCPDuplicationTNL-List				ProtocolIE-ID ::= 370
+id-RLCDuplicationInformation						ProtocolIE-ID ::= 371
+id-AdditionalDuplicationIndication					ProtocolIE-ID ::= 372
+id-ConditionalInterDUMobilityInformation			ProtocolIE-ID ::= 373
+id-ConditionalIntraDUMobilityInformation			ProtocolIE-ID ::= 374
+id-targetCellsToCancel								ProtocolIE-ID ::= 375
+id-requestedTargetCellGlobalID						ProtocolIE-ID ::= 376
+id-ManagementBasedMDTPLMNList						ProtocolIE-ID ::= 377
+id-TraceCollectionEntityIPAddress 					ProtocolIE-ID ::= 378
+id-PrivacyIndicator									ProtocolIE-ID ::= 379
+id-TraceCollectionEntityURI							ProtocolIE-ID ::= 380
+id-mdtConfiguration									ProtocolIE-ID ::= 381
+id-ServingNID										ProtocolIE-ID ::= 382
+id-NPNBroadcastInformation							ProtocolIE-ID ::= 383
+id-NPNSupportInfo									ProtocolIE-ID ::= 384
+id-NID												ProtocolIE-ID ::= 385
+id-AvailableSNPN-ID-List							ProtocolIE-ID ::= 386
+id-SIB10-message									ProtocolIE-ID ::= 387
+id-DLCarrierList									ProtocolIE-ID ::= 389
+	id-ExtendedTAISliceSupportList					ProtocolIE-ID ::= 390 
+id-RequestedSRSTransmissionCharacteristics			ProtocolIE-ID ::= 391
+id-PosAssistance-Information						ProtocolIE-ID ::= 392
+id-PosBroadcast										ProtocolIE-ID ::= 393
+id-RoutingID										ProtocolIE-ID ::= 394
+id-PosAssistanceInformationFailureList				ProtocolIE-ID ::= 395
+id-PosMeasurementQuantities							ProtocolIE-ID ::= 396
+id-PosMeasurementResultList							ProtocolIE-ID ::= 397
+id-TRPInformationTypeListTRPReq						ProtocolIE-ID ::= 398
+id-TRPInformationTypeItem							ProtocolIE-ID ::= 399
+id-TRPInformationListTRPResp						ProtocolIE-ID ::= 400
+id-TRPInformationItem								ProtocolIE-ID ::= 401
+id-LMF-MeasurementID								ProtocolIE-ID ::= 402
+id-SRSType											ProtocolIE-ID ::= 403
+id-ActivationTime									ProtocolIE-ID ::= 404
+id-AbortTransmission								ProtocolIE-ID ::= 405
+id-PositioningBroadcastCells						ProtocolIE-ID ::= 406
+id-SRSConfiguration									ProtocolIE-ID ::= 407
+id-PosReportCharacteristics						ProtocolIE-ID ::= 408
+id-PosMeasurementPeriodicity						ProtocolIE-ID ::= 409
+id-TRPList											ProtocolIE-ID ::= 410
+id-RAN-MeasurementID								ProtocolIE-ID ::= 411
+id-LMF-UE-MeasurementID								ProtocolIE-ID ::= 412
+id-RAN-UE-MeasurementID								ProtocolIE-ID ::= 413
+id-E-CID-MeasurementQuantities						ProtocolIE-ID ::= 414
+id-E-CID-MeasurementQuantities-Item					ProtocolIE-ID ::= 415
+id-E-CID-MeasurementPeriodicity						ProtocolIE-ID ::= 416
+id-E-CID-MeasurementResult							ProtocolIE-ID ::= 417
+id-Cell-Portion-ID									ProtocolIE-ID ::= 418
+id-SFNInitialisationTime							ProtocolIE-ID ::= 419
+id-SystemFrameNumber								ProtocolIE-ID ::= 420
+id-SlotNumber										ProtocolIE-ID ::= 421
+id-TRP-MeasurementRequestList						ProtocolIE-ID ::= 422
+id-MeasurementBeamInfoRequest						ProtocolIE-ID ::= 423
+id-E-CID-ReportCharacteristics						ProtocolIE-ID ::= 424
+id-ConfiguredTACIndication							ProtocolIE-ID ::= 425
+id-Extended-GNB-DU-Name								ProtocolIE-ID ::= 426
+id-Extended-GNB-CU-Name								ProtocolIE-ID ::= 427
+
+
+END
+-- ASN1STOP 
+
+-- ASN1START 
+-- **************************************************************
+--
+-- Container definitions
+--
+-- **************************************************************
+
+F1AP-Containers {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-Containers (5) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	Criticality,
+	Presence,
+	PrivateIE-ID,
+	ProtocolExtensionID,
+	ProtocolIE-ID
+
+FROM F1AP-CommonDataTypes
+	maxPrivateIEs,
+	maxProtocolExtensions,
+	maxProtocolIEs
+
+FROM F1AP-Constants;
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+F1AP-PROTOCOL-IES ::= CLASS {
+	&id				ProtocolIE-ID 					UNIQUE,
+	&criticality	Criticality,
+	&Value,
+	&presence		Presence
+}
+WITH SYNTAX {
+	ID				&id
+	CRITICALITY		&criticality
+	TYPE			&Value
+	PRESENCE		&presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+F1AP-PROTOCOL-IES-PAIR ::= CLASS {
+	&id					ProtocolIE-ID 				UNIQUE,
+	&firstCriticality	Criticality,
+	&FirstValue,
+	&secondCriticality	Criticality,
+	&SecondValue,
+	&presence			Presence
+}
+WITH SYNTAX {
+	ID				&id
+	FIRST CRITICALITY		&firstCriticality
+	FIRST TYPE				&FirstValue
+	SECOND CRITICALITY		&secondCriticality
+	SECOND TYPE				&SecondValue
+	PRESENCE				&presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol Extensions
+--
+-- **************************************************************
+
+F1AP-PROTOCOL-EXTENSION ::= CLASS {
+	&id				ProtocolExtensionID			UNIQUE,
+	&criticality	Criticality,
+	&Extension,
+	&presence		Presence
+}
+WITH SYNTAX {
+	ID				&id
+	CRITICALITY		&criticality
+	EXTENSION		&Extension
+	PRESENCE		&presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Private IEs
+--
+-- **************************************************************
+
+F1AP-PRIVATE-IES ::= CLASS {
+	&id				PrivateIE-ID,
+	&criticality	Criticality,
+	&Value,
+	&presence		Presence
+}
+WITH SYNTAX {
+	ID				&id
+	CRITICALITY		&criticality
+	TYPE			&Value
+	PRESENCE		&presence
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IEs
+--
+-- **************************************************************
+
+ProtocolIE-Container {F1AP-PROTOCOL-IES : IEsSetParam} ::= 
+	SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+	ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-SingleContainer {F1AP-PROTOCOL-IES : IEsSetParam} ::= 
+	ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-Field {F1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE {
+	id				F1AP-PROTOCOL-IES.&id				({IEsSetParam}),
+	criticality		F1AP-PROTOCOL-IES.&criticality		({IEsSetParam}{@id}),
+	value			F1AP-PROTOCOL-IES.&Value			({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IE Pairs
+--
+-- **************************************************************
+
+ProtocolIE-ContainerPair {F1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= 
+	SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+	ProtocolIE-FieldPair {{IEsSetParam}}
+
+ProtocolIE-FieldPair {F1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE {
+	id					F1AP-PROTOCOL-IES-PAIR.&id					({IEsSetParam}),
+	firstCriticality	F1AP-PROTOCOL-IES-PAIR.&firstCriticality	({IEsSetParam}{@id}),
+	firstValue			F1AP-PROTOCOL-IES-PAIR.&FirstValue			({IEsSetParam}{@id}),
+	secondCriticality	F1AP-PROTOCOL-IES-PAIR.&secondCriticality	({IEsSetParam}{@id}),
+	secondValue			F1AP-PROTOCOL-IES-PAIR.&SecondValue			({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol Extensions
+--
+-- **************************************************************
+
+ProtocolExtensionContainer {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= 
+	SEQUENCE (SIZE (1..maxProtocolExtensions)) OF
+	ProtocolExtensionField {{ExtensionSetParam}}
+
+ProtocolExtensionField {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE {
+	id					F1AP-PROTOCOL-EXTENSION.&id				({ExtensionSetParam}),
+	criticality			F1AP-PROTOCOL-EXTENSION.&criticality	({ExtensionSetParam}{@id}),
+	extensionValue		F1AP-PROTOCOL-EXTENSION.&Extension		({ExtensionSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Private IEs
+--
+-- **************************************************************
+
+PrivateIE-Container {F1AP-PRIVATE-IES : IEsSetParam } ::= 
+	SEQUENCE (SIZE (1.. maxPrivateIEs)) OF
+	PrivateIE-Field {{IEsSetParam}}
+
+PrivateIE-Field {F1AP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE {
+	id					F1AP-PRIVATE-IES.&id				({IEsSetParam}),
+	criticality			F1AP-PRIVATE-IES.&criticality		({IEsSetParam}{@id}),
+	value				F1AP-PRIVATE-IES.&Value				({IEsSetParam}{@id})
+}
+
+END
+-- ASN1STOP 
diff --git a/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-CommonDataTypes.asn b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-CommonDataTypes.asn
new file mode 100644
index 0000000000000000000000000000000000000000..da3092376eb76a13281ef91adcfe001c1bcda040
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-CommonDataTypes.asn
@@ -0,0 +1,32 @@
+-- **************************************************************
+--
+-- Common definitions
+--
+-- **************************************************************
+
+F1AP-CommonDataTypes {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-CommonDataTypes (3) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+Criticality		::= ENUMERATED { reject, ignore, notify }
+
+Presence		::= ENUMERATED { optional, conditional, mandatory }
+
+PrivateIE-ID	::= CHOICE {
+	local				INTEGER (0..65535),
+	global				OBJECT IDENTIFIER
+}
+
+ProcedureCode		::= INTEGER (0..255)
+
+ProtocolExtensionID	::= INTEGER (0..65535)
+
+ProtocolIE-ID		::= INTEGER (0..65535)
+
+TriggeringMessage	::= ENUMERATED { initiating-message, successful-outcome, unsuccessful-outcome }
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-Constants.asn b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-Constants.asn
new file mode 100644
index 0000000000000000000000000000000000000000..9b5a3dd6246d47a59d35760e55cbe4339b89746a
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-Constants.asn
@@ -0,0 +1,622 @@
+-- **************************************************************
+--
+-- Constant definitions
+--
+-- **************************************************************
+
+F1AP-Constants { 
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-Constants (4) } 
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	ProcedureCode,
+	ProtocolIE-ID
+
+FROM F1AP-CommonDataTypes;
+
+
+-- **************************************************************
+--
+-- Elementary Procedures
+--
+-- **************************************************************
+
+id-Reset									ProcedureCode ::= 0
+id-F1Setup									ProcedureCode ::= 1
+id-ErrorIndication							ProcedureCode ::= 2
+id-gNBDUConfigurationUpdate					ProcedureCode ::= 3
+id-gNBCUConfigurationUpdate					ProcedureCode ::= 4
+id-UEContextSetup							ProcedureCode ::= 5
+id-UEContextRelease							ProcedureCode ::= 6
+id-UEContextModification					ProcedureCode ::= 7
+id-UEContextModificationRequired			ProcedureCode ::= 8
+id-UEMobilityCommand						ProcedureCode ::= 9
+id-UEContextReleaseRequest					ProcedureCode ::= 10
+id-InitialULRRCMessageTransfer				ProcedureCode ::= 11
+id-DLRRCMessageTransfer						ProcedureCode ::= 12
+id-ULRRCMessageTransfer						ProcedureCode ::= 13
+id-privateMessage							ProcedureCode ::= 14
+id-UEInactivityNotification					ProcedureCode ::= 15
+id-GNBDUResourceCoordination				ProcedureCode ::= 16
+id-SystemInformationDeliveryCommand			ProcedureCode ::= 17
+id-Paging									ProcedureCode ::= 18
+id-Notify									ProcedureCode ::= 19
+id-WriteReplaceWarning						ProcedureCode ::= 20
+id-PWSCancel								ProcedureCode ::= 21
+id-PWSRestartIndication						ProcedureCode ::= 22
+id-PWSFailureIndication						ProcedureCode ::= 23
+id-GNBDUStatusIndication 					ProcedureCode ::= 24
+id-RRCDeliveryReport		 				ProcedureCode ::= 25
+id-F1Removal								ProcedureCode ::= 26
+id-NetworkAccessRateReduction				ProcedureCode ::= 27
+id-TraceStart								ProcedureCode ::= 28
+id-DeactivateTrace							ProcedureCode ::= 29
+id-DUCURadioInformationTransfer				ProcedureCode ::= 30
+id-CUDURadioInformationTransfer				ProcedureCode ::= 31
+id-BAPMappingConfiguration					ProcedureCode ::= 32
+id-GNBDUResourceConfiguration				ProcedureCode ::= 33
+id-IABTNLAddressAllocation					ProcedureCode ::= 34
+id-IABUPConfigurationUpdate					ProcedureCode ::= 35
+id-resourceStatusReportingInitiation		ProcedureCode ::= 36
+id-resourceStatusReporting					ProcedureCode ::= 37
+id-accessAndMobilityIndication				ProcedureCode ::= 38
+id-accessSuccess							ProcedureCode ::= 39
+id-cellTrafficTrace 						ProcedureCode ::= 40 
+id-PositioningMeasurementExchange			ProcedureCode ::= 41
+id-PositioningAssistanceInformationControl	ProcedureCode ::= 42
+id-PositioningAssistanceInformationFeedback	ProcedureCode ::= 43
+id-PositioningMeasurementReport				ProcedureCode ::= 44
+id-PositioningMeasurementAbort				ProcedureCode ::= 45
+id-PositioningMeasurementFailureIndication	ProcedureCode ::= 46
+id-PositioningMeasurementUpdate				ProcedureCode ::= 47
+id-TRPInformationExchange					ProcedureCode ::= 48
+id-PositioningInformationExchange			ProcedureCode ::= 49
+id-PositioningActivation					ProcedureCode ::= 50
+id-PositioningDeactivation					ProcedureCode ::= 51
+id-E-CIDMeasurementInitiation				ProcedureCode ::= 52
+id-E-CIDMeasurementFailureIndication		ProcedureCode ::= 53
+id-E-CIDMeasurementReport					ProcedureCode ::= 54
+id-E-CIDMeasurementTermination				ProcedureCode ::= 55
+id-PositioningInformationUpdate				ProcedureCode ::= 56
+id-ReferenceTimeInformationReport			ProcedureCode ::= 57
+id-ReferenceTimeInformationReportingControl	ProcedureCode ::= 58
+
+
+
+-- **************************************************************
+--
+-- Extension constants
+--
+-- **************************************************************
+
+maxPrivateIEs							INTEGER ::= 65535
+maxProtocolExtensions					INTEGER ::= 65535
+maxProtocolIEs							INTEGER ::= 65535
+-- **************************************************************
+--
+-- Lists
+--
+-- **************************************************************
+
+maxNRARFCN								INTEGER ::= 3279165
+maxnoofErrors							INTEGER ::= 256
+maxnoofIndividualF1ConnectionsToReset	INTEGER ::= 65536
+maxCellingNBDU							INTEGER ::= 512
+maxnoofSCells							INTEGER ::= 32
+maxnoofSRBs								INTEGER ::= 8
+maxnoofDRBs								INTEGER ::= 64
+maxnoofULUPTNLInformation				INTEGER ::= 2
+maxnoofDLUPTNLInformation				INTEGER ::= 2
+maxnoofBPLMNs							INTEGER ::= 6
+maxnoofCandidateSpCells					INTEGER ::= 64
+maxnoofPotentialSpCells					INTEGER ::= 64
+maxnoofNrCellBands						INTEGER ::= 32
+maxnoofSIBTypes							INTEGER ::= 32
+maxnoofSITypes							INTEGER ::= 32
+maxnoofPagingCells						INTEGER ::= 512
+maxnoofTNLAssociations					INTEGER ::= 32
+maxnoofQoSFlows							INTEGER ::= 64
+maxnoofSliceItems						INTEGER ::= 1024
+maxCellineNB							INTEGER ::= 256
+maxnoofExtendedBPLMNs					INTEGER ::= 6
+maxnoofUEIDs							INTEGER ::= 65536
+maxnoofBPLMNsNR							INTEGER ::= 12
+maxnoofUACPLMNs							INTEGER ::= 12
+maxnoofUACperPLMN						INTEGER ::= 64
+maxnoofAdditionalSIBs					INTEGER ::= 63
+maxnoofslots							INTEGER ::= 5120
+maxnoofTLAs								INTEGER ::=	16
+maxnoofGTPTLAs							INTEGER ::=	16
+maxnoofBHRLCChannels					INTEGER ::= 65536
+maxnoofRoutingEntries					INTEGER ::= 1024
+maxnoofIABSTCInfo						INTEGER ::= 45
+maxnoofSymbols							INTEGER ::= 14
+maxnoofServingCells						INTEGER ::= 32
+maxnoofDUFSlots							INTEGER ::= 320
+maxnoofHSNASlots						INTEGER ::= 5120
+maxnoofServedCellsIAB					INTEGER ::= 512 
+maxnoofChildIABNodes					INTEGER ::= 1024
+maxnoofNonUPTrafficMappings				INTEGER ::= 32
+maxnoofTLAsIAB							INTEGER ::= 1024
+maxnoofMappingEntries					INTEGER ::= 67108864
+maxnoofDSInfo							INTEGER ::= 64
+maxnoofEgressLinks						INTEGER ::= 2
+maxnoofULUPTNLInformationforIAB			INTEGER ::= 32678
+maxnoofUPTNLAddresses					INTEGER ::= 8
+maxnoofSLDRBs							INTEGER ::= 512
+maxnoofQoSParaSets						INTEGER ::= 8
+maxnoofPC5QoSFlows						INTEGER ::= 2048
+maxnoofSSBAreas							INTEGER ::=	64
+maxnoofPhysicalResourceBlocks			INTEGER ::= 275
+maxnoofPhysicalResourceBlocks-1			INTEGER ::= 274
+maxnoofPRACHconfigs						INTEGER ::= 16
+maxnoofRACHReports						INTEGER ::= 64
+maxnoofRLFReports						INTEGER ::= 64
+maxnoofAdditionalPDCPDuplicationTNL		INTEGER ::=	2
+maxnoofRLCDuplicationState				INTEGER ::=	3
+maxnoofCHOcells							INTEGER ::= 8
+maxnoofMDTPLMNs							INTEGER ::=	16
+maxnoofCAGsupported						INTEGER ::= 12
+maxnoofNIDsupported						INTEGER ::= 12
+maxnoofNRSCSs							INTEGER ::= 5
+maxnoofExtSliceItems					INTEGER ::= 65535 
+maxnoofPosMeas							INTEGER ::=	16384
+maxnoofTRPInfoTypes						INTEGER ::=	64 
+maxnoofTRPs								INTEGER ::=	65535 
+maxnoofSRSTriggerStates					INTEGER ::= 3
+maxnoofSpatialRelations					INTEGER ::= 64
+maxnoBcastCell							INTEGER ::= 16384
+maxnoofAngleInfo						INTEGER ::= 65535
+maxnooflcs-gcs-translation				INTEGER ::= 3
+maxnoofPath								INTEGER ::= 2
+maxnoofMeasE-CID						INTEGER ::= 64
+maxnoofSSBs								INTEGER ::= 255
+maxnoSRS-ResourceSets					INTEGER ::= 16
+maxnoSRS-ResourcePerSet					INTEGER ::= 16
+maxnoSRS-Carriers						INTEGER ::= 32
+maxnoSCSs								INTEGER ::= 5
+maxnoSRS-Resources						INTEGER ::= 64
+maxnoSRS-PosResources					INTEGER ::= 64
+maxnoSRS-PosResourceSets				INTEGER ::= 16
+maxnoSRS-PosResourcePerSet				INTEGER ::= 16
+maxnoofPRS-ResourceSets					INTEGER ::= 2
+maxnoofPRS-ResourcesPerSet				INTEGER ::= 64
+maxNoOfMeasTRPs							INTEGER ::= 64
+maxnoofPRSresourceSets					INTEGER ::= 8
+maxnoofPRSresources						INTEGER ::= 64
+
+
+
+-- **************************************************************
+--
+-- IEs
+--
+-- **************************************************************
+
+id-Cause											ProtocolIE-ID ::= 0
+id-Cells-Failed-to-be-Activated-List				ProtocolIE-ID ::= 1
+id-Cells-Failed-to-be-Activated-List-Item			ProtocolIE-ID ::= 2
+id-Cells-to-be-Activated-List						ProtocolIE-ID ::= 3
+id-Cells-to-be-Activated-List-Item					ProtocolIE-ID ::= 4
+id-Cells-to-be-Deactivated-List						ProtocolIE-ID ::= 5
+id-Cells-to-be-Deactivated-List-Item				ProtocolIE-ID ::= 6
+id-CriticalityDiagnostics							ProtocolIE-ID ::= 7
+id-CUtoDURRCInformation								ProtocolIE-ID ::= 9
+id-DRBs-FailedToBeModified-Item						ProtocolIE-ID ::= 12
+id-DRBs-FailedToBeModified-List						ProtocolIE-ID ::= 13
+id-DRBs-FailedToBeSetup-Item						ProtocolIE-ID ::= 14
+id-DRBs-FailedToBeSetup-List						ProtocolIE-ID ::= 15
+id-DRBs-FailedToBeSetupMod-Item						ProtocolIE-ID ::= 16
+id-DRBs-FailedToBeSetupMod-List						ProtocolIE-ID ::= 17
+id-DRBs-ModifiedConf-Item							ProtocolIE-ID ::= 18
+id-DRBs-ModifiedConf-List							ProtocolIE-ID ::= 19
+id-DRBs-Modified-Item								ProtocolIE-ID ::= 20
+id-DRBs-Modified-List								ProtocolIE-ID ::= 21
+id-DRBs-Required-ToBeModified-Item					ProtocolIE-ID ::= 22
+id-DRBs-Required-ToBeModified-List					ProtocolIE-ID ::= 23
+id-DRBs-Required-ToBeReleased-Item					ProtocolIE-ID ::= 24
+id-DRBs-Required-ToBeReleased-List					ProtocolIE-ID ::= 25
+id-DRBs-Setup-Item									ProtocolIE-ID ::= 26
+id-DRBs-Setup-List									ProtocolIE-ID ::= 27
+id-DRBs-SetupMod-Item								ProtocolIE-ID ::= 28
+id-DRBs-SetupMod-List								ProtocolIE-ID ::= 29
+id-DRBs-ToBeModified-Item							ProtocolIE-ID ::= 30
+id-DRBs-ToBeModified-List							ProtocolIE-ID ::= 31
+id-DRBs-ToBeReleased-Item							ProtocolIE-ID ::= 32
+id-DRBs-ToBeReleased-List							ProtocolIE-ID ::= 33
+id-DRBs-ToBeSetup-Item								ProtocolIE-ID ::= 34
+id-DRBs-ToBeSetup-List								ProtocolIE-ID ::= 35
+id-DRBs-ToBeSetupMod-Item							ProtocolIE-ID ::= 36
+id-DRBs-ToBeSetupMod-List							ProtocolIE-ID ::= 37
+id-DRXCycle											ProtocolIE-ID ::= 38
+id-DUtoCURRCInformation								ProtocolIE-ID ::= 39
+id-gNB-CU-UE-F1AP-ID								ProtocolIE-ID ::= 40
+id-gNB-DU-UE-F1AP-ID								ProtocolIE-ID ::= 41
+id-gNB-DU-ID										ProtocolIE-ID ::= 42
+id-GNB-DU-Served-Cells-Item							ProtocolIE-ID ::= 43
+id-gNB-DU-Served-Cells-List							ProtocolIE-ID ::= 44
+id-gNB-DU-Name										ProtocolIE-ID ::= 45
+id-NRCellID											ProtocolIE-ID ::= 46
+id-oldgNB-DU-UE-F1AP-ID								ProtocolIE-ID ::= 47
+id-ResetType										ProtocolIE-ID ::= 48
+id-ResourceCoordinationTransferContainer			ProtocolIE-ID ::= 49
+id-RRCContainer										ProtocolIE-ID ::= 50
+id-SCell-ToBeRemoved-Item							ProtocolIE-ID ::= 51
+id-SCell-ToBeRemoved-List							ProtocolIE-ID ::= 52
+id-SCell-ToBeSetup-Item								ProtocolIE-ID ::= 53
+id-SCell-ToBeSetup-List								ProtocolIE-ID ::= 54
+id-SCell-ToBeSetupMod-Item							ProtocolIE-ID ::= 55
+id-SCell-ToBeSetupMod-List							ProtocolIE-ID ::= 56
+id-Served-Cells-To-Add-Item							ProtocolIE-ID ::= 57
+id-Served-Cells-To-Add-List							ProtocolIE-ID ::= 58
+id-Served-Cells-To-Delete-Item						ProtocolIE-ID ::= 59
+id-Served-Cells-To-Delete-List						ProtocolIE-ID ::= 60
+id-Served-Cells-To-Modify-Item						ProtocolIE-ID ::= 61
+id-Served-Cells-To-Modify-List						ProtocolIE-ID ::= 62
+id-SpCell-ID										ProtocolIE-ID ::= 63
+id-SRBID											ProtocolIE-ID ::= 64
+id-SRBs-FailedToBeSetup-Item						ProtocolIE-ID ::= 65
+id-SRBs-FailedToBeSetup-List						ProtocolIE-ID ::= 66
+id-SRBs-FailedToBeSetupMod-Item						ProtocolIE-ID ::= 67
+id-SRBs-FailedToBeSetupMod-List						ProtocolIE-ID ::= 68
+id-SRBs-Required-ToBeReleased-Item					ProtocolIE-ID ::= 69
+id-SRBs-Required-ToBeReleased-List					ProtocolIE-ID ::= 70
+id-SRBs-ToBeReleased-Item							ProtocolIE-ID ::= 71
+id-SRBs-ToBeReleased-List							ProtocolIE-ID ::= 72
+id-SRBs-ToBeSetup-Item								ProtocolIE-ID ::= 73
+id-SRBs-ToBeSetup-List								ProtocolIE-ID ::= 74
+id-SRBs-ToBeSetupMod-Item							ProtocolIE-ID ::= 75
+id-SRBs-ToBeSetupMod-List							ProtocolIE-ID ::= 76
+id-TimeToWait										ProtocolIE-ID ::= 77
+id-TransactionID									ProtocolIE-ID ::= 78
+id-TransmissionActionIndicator						ProtocolIE-ID ::= 79
+id-UE-associatedLogicalF1-ConnectionItem 			ProtocolIE-ID ::= 80
+id-UE-associatedLogicalF1-ConnectionListResAck		ProtocolIE-ID ::= 81
+id-gNB-CU-Name										ProtocolIE-ID ::= 82
+id-SCell-FailedtoSetup-List							ProtocolIE-ID ::= 83
+id-SCell-FailedtoSetup-Item							ProtocolIE-ID ::= 84
+id-SCell-FailedtoSetupMod-List						ProtocolIE-ID ::= 85
+id-SCell-FailedtoSetupMod-Item						ProtocolIE-ID ::= 86
+id-RRCReconfigurationCompleteIndicator 				ProtocolIE-ID ::= 87
+id-Cells-Status-Item								ProtocolIE-ID ::= 88
+id-Cells-Status-List								ProtocolIE-ID ::= 89
+id-Candidate-SpCell-List							ProtocolIE-ID ::= 90
+id-Candidate-SpCell-Item							ProtocolIE-ID ::= 91
+id-Potential-SpCell-List							ProtocolIE-ID ::= 92
+id-Potential-SpCell-Item							ProtocolIE-ID ::= 93
+id-FullConfiguration								ProtocolIE-ID ::= 94
+id-C-RNTI											ProtocolIE-ID ::= 95
+id-SpCellULConfigured								ProtocolIE-ID ::= 96
+id-InactivityMonitoringRequest						ProtocolIE-ID ::= 97
+id-InactivityMonitoringResponse						ProtocolIE-ID ::= 98
+id-DRB-Activity-Item								ProtocolIE-ID ::= 99
+id-DRB-Activity-List								ProtocolIE-ID ::= 100
+id-EUTRA-NR-CellResourceCoordinationReq-Container 		ProtocolIE-ID ::= 101
+id-EUTRA-NR-CellResourceCoordinationReqAck-Container 	ProtocolIE-ID ::= 102
+id-Protected-EUTRA-Resources-List					ProtocolIE-ID ::= 105
+id-RequestType 										ProtocolIE-ID ::= 106
+id-ServCellIndex									ProtocolIE-ID ::= 107 
+id-RAT-FrequencyPriorityInformation					ProtocolIE-ID ::= 108
+id-ExecuteDuplication								ProtocolIE-ID ::= 109
+id-NRCGI											ProtocolIE-ID ::= 111
+id-PagingCell-Item									ProtocolIE-ID ::= 112
+id-PagingCell-List									ProtocolIE-ID ::= 113
+id-PagingDRX										ProtocolIE-ID ::= 114
+id-PagingPriority 									ProtocolIE-ID ::= 115
+id-SItype-List										ProtocolIE-ID ::= 116
+id-UEIdentityIndexValue								ProtocolIE-ID ::= 117
+id-gNB-CUSystemInformation							ProtocolIE-ID ::= 118
+id-HandoverPreparationInformation					ProtocolIE-ID ::= 119
+id-GNB-CU-TNL-Association-To-Add-Item				ProtocolIE-ID ::= 120
+id-GNB-CU-TNL-Association-To-Add-List				ProtocolIE-ID ::= 121
+id-GNB-CU-TNL-Association-To-Remove-Item			ProtocolIE-ID ::= 122
+id-GNB-CU-TNL-Association-To-Remove-List			ProtocolIE-ID ::= 123
+id-GNB-CU-TNL-Association-To-Update-Item			ProtocolIE-ID ::= 124
+id-GNB-CU-TNL-Association-To-Update-List			ProtocolIE-ID ::= 125
+id-MaskedIMEISV										ProtocolIE-ID ::= 126
+id-PagingIdentity									ProtocolIE-ID ::= 127
+id-DUtoCURRCContainer								ProtocolIE-ID ::= 128
+id-Cells-to-be-Barred-List							ProtocolIE-ID ::= 129
+id-Cells-to-be-Barred-Item							ProtocolIE-ID ::= 130
+id-TAISliceSupportList								ProtocolIE-ID ::= 131
+id-GNB-CU-TNL-Association-Setup-List				ProtocolIE-ID ::= 132
+id-GNB-CU-TNL-Association-Setup-Item				ProtocolIE-ID ::= 133
+id-GNB-CU-TNL-Association-Failed-To-Setup-List		ProtocolIE-ID ::= 134
+id-GNB-CU-TNL-Association-Failed-To-Setup-Item		ProtocolIE-ID ::= 135
+id-DRB-Notify-Item									ProtocolIE-ID ::= 136
+id-DRB-Notify-List									ProtocolIE-ID ::= 137
+id-NotficationControl								ProtocolIE-ID ::= 138
+id-RANAC											ProtocolIE-ID ::= 139
+id-PWSSystemInformation								ProtocolIE-ID ::= 140
+id-RepetitionPeriod									ProtocolIE-ID ::= 141
+id-NumberofBroadcastRequest							ProtocolIE-ID ::= 142
+id-Cells-To-Be-Broadcast-List						ProtocolIE-ID ::= 144
+id-Cells-To-Be-Broadcast-Item						ProtocolIE-ID ::= 145
+id-Cells-Broadcast-Completed-List 					ProtocolIE-ID ::= 146
+id-Cells-Broadcast-Completed-Item 					ProtocolIE-ID ::= 147
+id-Broadcast-To-Be-Cancelled-List 					ProtocolIE-ID ::= 148
+id-Broadcast-To-Be-Cancelled-Item 					ProtocolIE-ID ::= 149
+id-Cells-Broadcast-Cancelled-List 					ProtocolIE-ID ::= 150
+id-Cells-Broadcast-Cancelled-Item 					ProtocolIE-ID ::= 151
+id-NR-CGI-List-For-Restart-List 					ProtocolIE-ID ::= 152
+id-NR-CGI-List-For-Restart-Item 					ProtocolIE-ID ::= 153
+id-PWS-Failed-NR-CGI-List 							ProtocolIE-ID ::= 154
+id-PWS-Failed-NR-CGI-Item 							ProtocolIE-ID ::= 155
+id-ConfirmedUEID									ProtocolIE-ID ::= 156
+id-Cancel-all-Warning-Messages-Indicator			ProtocolIE-ID ::= 157
+id-GNB-DU-UE-AMBR-UL								ProtocolIE-ID ::= 158
+id-DRXConfigurationIndicator						ProtocolIE-ID ::= 159
+id-RLC-Status										ProtocolIE-ID ::= 160
+id-DLPDCPSNLength									ProtocolIE-ID ::= 161
+id-GNB-DUConfigurationQuery							ProtocolIE-ID ::= 162
+id-MeasurementTimingConfiguration					ProtocolIE-ID ::= 163
+id-DRB-Information									ProtocolIE-ID ::= 164
+id-ServingPLMN										ProtocolIE-ID ::= 165
+id-Protected-EUTRA-Resources-Item					ProtocolIE-ID ::= 168
+id-GNB-CU-RRC-Version								ProtocolIE-ID ::= 170
+id-GNB-DU-RRC-Version								ProtocolIE-ID ::= 171
+id-GNBDUOverloadInformation							ProtocolIE-ID ::= 172
+id-CellGroupConfig									ProtocolIE-ID ::= 173
+id-RLCFailureIndication								ProtocolIE-ID ::= 174
+id-UplinkTxDirectCurrentListInformation				ProtocolIE-ID ::= 175
+id-DC-Based-Duplication-Configured					ProtocolIE-ID ::= 176
+id-DC-Based-Duplication-Activation					ProtocolIE-ID ::= 177
+id-SULAccessIndication								ProtocolIE-ID ::= 178
+id-AvailablePLMNList								ProtocolIE-ID ::= 179
+id-PDUSessionID										ProtocolIE-ID ::= 180
+id-ULPDUSessionAggregateMaximumBitRate				ProtocolIE-ID ::= 181
+id-ServingCellMO									ProtocolIE-ID ::= 182
+id-QoSFlowMappingIndication							ProtocolIE-ID ::= 183
+id-RRCDeliveryStatusRequest							ProtocolIE-ID ::= 184
+id-RRCDeliveryStatus								ProtocolIE-ID ::= 185
+id-BearerTypeChange									ProtocolIE-ID ::= 186
+id-RLCMode											ProtocolIE-ID ::= 187
+id-Duplication-Activation							ProtocolIE-ID ::= 188
+id-Dedicated-SIDelivery-NeededUE-List				ProtocolIE-ID ::= 189
+id-Dedicated-SIDelivery-NeededUE-Item				ProtocolIE-ID ::= 190
+id-DRX-LongCycleStartOffset							ProtocolIE-ID ::= 191
+id-ULPDCPSNLength									ProtocolIE-ID ::= 192
+id-SelectedBandCombinationIndex						ProtocolIE-ID ::= 193
+id-SelectedFeatureSetEntryIndex						ProtocolIE-ID ::= 194
+id-ResourceCoordinationTransferInformation			ProtocolIE-ID ::= 195
+id-ExtendedServedPLMNs-List							ProtocolIE-ID ::= 196
+id-ExtendedAvailablePLMN-List						ProtocolIE-ID ::= 197
+id-Associated-SCell-List							ProtocolIE-ID ::= 198
+id-latest-RRC-Version-Enhanced						ProtocolIE-ID ::= 199
+id-Associated-SCell-Item							ProtocolIE-ID ::= 200
+id-Cell-Direction									ProtocolIE-ID ::= 201
+id-SRBs-Setup-List									ProtocolIE-ID ::= 202
+id-SRBs-Setup-Item									ProtocolIE-ID ::= 203
+id-SRBs-SetupMod-List								ProtocolIE-ID ::= 204
+id-SRBs-SetupMod-Item								ProtocolIE-ID ::= 205
+id-SRBs-Modified-List								ProtocolIE-ID ::= 206
+id-SRBs-Modified-Item								ProtocolIE-ID ::= 207
+id-Ph-InfoSCG										ProtocolIE-ID ::= 208
+id-RequestedBandCombinationIndex					ProtocolIE-ID ::= 209
+id-RequestedFeatureSetEntryIndex					ProtocolIE-ID ::= 210
+id-RequestedP-MaxFR2								ProtocolIE-ID ::= 211
+id-DRX-Config										ProtocolIE-ID ::= 212
+id-IgnoreResourceCoordinationContainer				ProtocolIE-ID ::= 213
+id-UEAssistanceInformation							ProtocolIE-ID ::= 214
+id-NeedforGap										ProtocolIE-ID ::= 215
+id-PagingOrigin										ProtocolIE-ID ::= 216
+id-new-gNB-CU-UE-F1AP-ID							ProtocolIE-ID ::= 217
+id-RedirectedRRCmessage								ProtocolIE-ID ::= 218
+id-new-gNB-DU-UE-F1AP-ID							ProtocolIE-ID ::= 219
+id-NotificationInformation							ProtocolIE-ID ::= 220
+id-PLMNAssistanceInfoForNetShar						ProtocolIE-ID ::= 221
+id-UEContextNotRetrievable							ProtocolIE-ID ::= 222
+id-BPLMN-ID-Info-List								ProtocolIE-ID ::= 223
+id-SelectedPLMNID									ProtocolIE-ID ::= 224
+id-UAC-Assistance-Info								ProtocolIE-ID ::= 225
+id-RANUEID											ProtocolIE-ID ::= 226
+id-GNB-DU-TNL-Association-To-Remove-Item			ProtocolIE-ID ::= 227
+id-GNB-DU-TNL-Association-To-Remove-List			ProtocolIE-ID ::= 228
+id-TNLAssociationTransportLayerAddressgNBDU			ProtocolIE-ID ::= 229
+id-portNumber										ProtocolIE-ID ::= 230
+id-AdditionalSIBMessageList							ProtocolIE-ID ::= 231
+id-Cell-Type										ProtocolIE-ID ::= 232
+id-IgnorePRACHConfiguration							ProtocolIE-ID ::= 233
+id-CG-Config										ProtocolIE-ID ::= 234
+id-PDCCH-BlindDetectionSCG							ProtocolIE-ID ::= 235
+id-Requested-PDCCH-BlindDetectionSCG				ProtocolIE-ID ::= 236
+id-Ph-InfoMCG										ProtocolIE-ID ::= 237
+id-MeasGapSharingConfig								ProtocolIE-ID ::= 238
+id-systemInformationAreaID							ProtocolIE-ID ::= 239
+id-areaScope										ProtocolIE-ID ::= 240
+id-RRCContainer-RRCSetupComplete					ProtocolIE-ID ::= 241
+id-TraceActivation									ProtocolIE-ID ::= 242
+id-TraceID											ProtocolIE-ID ::= 243
+id-Neighbour-Cell-Information-List					ProtocolIE-ID ::= 244
+id-SymbolAllocInSlot								ProtocolIE-ID ::= 246
+id-NumDLULSymbols									ProtocolIE-ID ::= 247
+id-AdditionalRRMPriorityIndex						ProtocolIE-ID ::= 248
+id-DUCURadioInformationType							ProtocolIE-ID ::= 249
+id-CUDURadioInformationType 						ProtocolIE-ID ::= 250
+id-AggressorgNBSetID								ProtocolIE-ID ::= 251
+id-VictimgNBSetID									ProtocolIE-ID ::= 252
+id-LowerLayerPresenceStatusChange					ProtocolIE-ID ::= 253
+id-Transport-Layer-Address-Info						ProtocolIE-ID ::= 254
+id-Neighbour-Cell-Information-Item					ProtocolIE-ID ::= 255
+id-IntendedTDD-DL-ULConfig							ProtocolIE-ID ::= 256
+id-QosMonitoringRequest								ProtocolIE-ID ::= 257
+id-BHChannels-ToBeSetup-List						ProtocolIE-ID ::= 258
+id-BHChannels-ToBeSetup-Item						ProtocolIE-ID ::= 259
+id-BHChannels-Setup-List							ProtocolIE-ID ::= 260
+id-BHChannels-Setup-Item							ProtocolIE-ID ::= 261
+id-BHChannels-ToBeModified-Item						ProtocolIE-ID ::= 262
+id-BHChannels-ToBeModified-List						ProtocolIE-ID ::= 263
+id-BHChannels-ToBeReleased-Item						ProtocolIE-ID ::= 264
+id-BHChannels-ToBeReleased-List						ProtocolIE-ID ::= 265
+id-BHChannels-ToBeSetupMod-Item						ProtocolIE-ID ::= 266
+id-BHChannels-ToBeSetupMod-List						ProtocolIE-ID ::= 267
+id-BHChannels-FailedToBeModified-Item				ProtocolIE-ID ::= 268
+id-BHChannels-FailedToBeModified-List				ProtocolIE-ID ::= 269
+id-BHChannels-FailedToBeSetupMod-Item				ProtocolIE-ID ::= 270
+id-BHChannels-FailedToBeSetupMod-List				ProtocolIE-ID ::= 271
+id-BHChannels-Modified-Item							ProtocolIE-ID ::= 272
+id-BHChannels-Modified-List							ProtocolIE-ID ::= 273
+id-BHChannels-SetupMod-Item							ProtocolIE-ID ::= 274
+id-BHChannels-SetupMod-List							ProtocolIE-ID ::= 275
+id-BHChannels-Required-ToBeReleased-Item			ProtocolIE-ID ::= 276
+id-BHChannels-Required-ToBeReleased-List			ProtocolIE-ID ::= 277
+id-BHChannels-FailedToBeSetup-Item					ProtocolIE-ID ::= 278
+id-BHChannels-FailedToBeSetup-List					ProtocolIE-ID ::= 279
+id-BHInfo											ProtocolIE-ID ::= 280
+id-BAPAddress										ProtocolIE-ID ::= 281
+id-ConfiguredBAPAddress								ProtocolIE-ID ::= 282
+id-BH-Routing-Information-Added-List				ProtocolIE-ID ::= 283
+id-BH-Routing-Information-Added-List-Item			ProtocolIE-ID ::= 284
+id-BH-Routing-Information-Removed-List				ProtocolIE-ID ::= 285
+id-BH-Routing-Information-Removed-List-Item			ProtocolIE-ID ::= 286
+id-UL-BH-Non-UP-Traffic-Mapping						ProtocolIE-ID ::= 287
+id-Activated-Cells-to-be-Updated-List				ProtocolIE-ID ::= 288
+id-Child-Nodes-List									ProtocolIE-ID ::= 289
+id-IAB-Info-IAB-DU									ProtocolIE-ID ::= 290
+id-IAB-Info-IAB-donor-CU							ProtocolIE-ID ::= 291
+id-IAB-TNL-Addresses-To-Remove-List					ProtocolIE-ID ::= 292
+id-IAB-TNL-Addresses-To-Remove-Item					ProtocolIE-ID ::= 293
+id-IAB-Allocated-TNL-Address-List					ProtocolIE-ID ::= 294
+id-IAB-Allocated-TNL-Address-Item					ProtocolIE-ID ::= 295
+id-IABIPv6RequestType								ProtocolIE-ID ::= 296
+id-IABv4AddressesRequested							ProtocolIE-ID ::= 297
+id-IAB-Barred										ProtocolIE-ID ::= 298
+id-TrafficMappingInformation						ProtocolIE-ID ::= 299
+id-UL-UP-TNL-Information-to-Update-List				ProtocolIE-ID ::= 300
+id-UL-UP-TNL-Information-to-Update-List-Item		ProtocolIE-ID ::= 301
+id-UL-UP-TNL-Address-to-Update-List					ProtocolIE-ID ::= 302
+id-UL-UP-TNL-Address-to-Update-List-Item			ProtocolIE-ID ::= 303
+id-DL-UP-TNL-Address-to-Update-List					ProtocolIE-ID ::= 304
+id-DL-UP-TNL-Address-to-Update-List-Item			ProtocolIE-ID ::= 305
+id-NRV2XServicesAuthorized							ProtocolIE-ID ::= 306
+id-LTEV2XServicesAuthorized							ProtocolIE-ID ::= 307
+id-NRUESidelinkAggregateMaximumBitrate				ProtocolIE-ID ::= 308
+id-LTEUESidelinkAggregateMaximumBitrate				ProtocolIE-ID ::= 309
+id-SIB12-message									ProtocolIE-ID ::= 310
+id-SIB13-message									ProtocolIE-ID ::= 311
+id-SIB14-message									ProtocolIE-ID ::= 312
+id-SLDRBs-FailedToBeModified-Item					ProtocolIE-ID ::= 313
+id-SLDRBs-FailedToBeModified-List					ProtocolIE-ID ::= 314
+id-SLDRBs-FailedToBeSetup-Item						ProtocolIE-ID ::= 315
+id-SLDRBs-FailedToBeSetup-List						ProtocolIE-ID ::= 316
+id-SLDRBs-Modified-Item								ProtocolIE-ID ::= 317
+id-SLDRBs-Modified-List								ProtocolIE-ID ::= 318
+id-SLDRBs-Required-ToBeModified-Item				ProtocolIE-ID ::= 319
+id-SLDRBs-Required-ToBeModified-List				ProtocolIE-ID ::= 320
+id-SLDRBs-Required-ToBeReleased-Item				ProtocolIE-ID ::= 321
+id-SLDRBs-Required-ToBeReleased-List				ProtocolIE-ID ::= 322
+id-SLDRBs-Setup-Item								ProtocolIE-ID ::= 323
+id-SLDRBs-Setup-List								ProtocolIE-ID ::= 324
+id-SLDRBs-ToBeModified-Item							ProtocolIE-ID ::= 325
+id-SLDRBs-ToBeModified-List							ProtocolIE-ID ::= 326
+id-SLDRBs-ToBeReleased-Item							ProtocolIE-ID ::= 327
+id-SLDRBs-ToBeReleased-List							ProtocolIE-ID ::= 328
+id-SLDRBs-ToBeSetup-Item							ProtocolIE-ID ::= 329
+id-SLDRBs-ToBeSetup-List							ProtocolIE-ID ::= 330
+id-SLDRBs-ToBeSetupMod-Item							ProtocolIE-ID ::= 331
+id-SLDRBs-ToBeSetupMod-List							ProtocolIE-ID ::= 332
+id-SLDRBs-SetupMod-List								ProtocolIE-ID ::= 333
+id-SLDRBs-FailedToBeSetupMod-List					ProtocolIE-ID ::= 334
+id-SLDRBs-SetupMod-Item								ProtocolIE-ID ::= 335
+id-SLDRBs-FailedToBeSetupMod-Item					ProtocolIE-ID ::= 336
+id-SLDRBs-ModifiedConf-List							ProtocolIE-ID ::= 337
+id-SLDRBs-ModifiedConf-Item							ProtocolIE-ID ::= 338
+id-UEAssistanceInformationEUTRA						ProtocolIE-ID ::= 339
+id-PC5LinkAMBR										ProtocolIE-ID ::= 340
+id-SL-PHY-MAC-RLC-Config							ProtocolIE-ID ::= 341
+id-SL-ConfigDedicatedEUTRA							ProtocolIE-ID ::= 342
+id-AlternativeQoSParaSetList						ProtocolIE-ID ::= 343
+id-CurrentQoSParaSetIndex							ProtocolIE-ID ::= 344
+id-gNBCUMeasurementID								ProtocolIE-ID ::= 345
+id-gNBDUMeasurementID								ProtocolIE-ID ::= 346
+id-RegistrationRequest								ProtocolIE-ID ::= 347
+id-ReportCharacteristics							ProtocolIE-ID ::= 348
+id-CellToReportList									ProtocolIE-ID ::= 349
+id-CellMeasurementResultList						ProtocolIE-ID ::= 350
+id-HardwareLoadIndicator							ProtocolIE-ID ::= 351
+id-ReportingPeriodicity								ProtocolIE-ID ::= 352
+id-TNLCapacityIndicator								ProtocolIE-ID ::= 353
+id-CarrierList										ProtocolIE-ID ::= 354
+id-ULCarrierList									ProtocolIE-ID ::= 355
+id-FrequencyShift7p5khz								ProtocolIE-ID ::= 356
+id-SSB-PositionsInBurst								ProtocolIE-ID ::= 357
+id-NRPRACHConfig									ProtocolIE-ID ::= 358
+id-RACHReportInformationList						ProtocolIE-ID ::= 359
+id-RLFReportInformationList							ProtocolIE-ID ::= 360
+id-TDD-UL-DLConfigCommonNR							ProtocolIE-ID ::= 361
+id-CNPacketDelayBudgetDownlink						ProtocolIE-ID ::= 362
+id-ExtendedPacketDelayBudget						ProtocolIE-ID ::= 363
+id-TSCTrafficCharacteristics						ProtocolIE-ID ::= 364
+id-ReportingRequestType								ProtocolIE-ID ::= 365
+id-TimeReferenceInformation							ProtocolIE-ID ::= 366
+id-CNPacketDelayBudgetUplink						ProtocolIE-ID ::= 369
+id-AdditionalPDCPDuplicationTNL-List				ProtocolIE-ID ::= 370
+id-RLCDuplicationInformation						ProtocolIE-ID ::= 371
+id-AdditionalDuplicationIndication					ProtocolIE-ID ::= 372
+id-ConditionalInterDUMobilityInformation			ProtocolIE-ID ::= 373
+id-ConditionalIntraDUMobilityInformation			ProtocolIE-ID ::= 374
+id-targetCellsToCancel								ProtocolIE-ID ::= 375
+id-requestedTargetCellGlobalID						ProtocolIE-ID ::= 376
+id-ManagementBasedMDTPLMNList						ProtocolIE-ID ::= 377
+id-TraceCollectionEntityIPAddress 					ProtocolIE-ID ::= 378
+id-PrivacyIndicator									ProtocolIE-ID ::= 379
+id-TraceCollectionEntityURI							ProtocolIE-ID ::= 380
+id-mdtConfiguration									ProtocolIE-ID ::= 381
+id-ServingNID										ProtocolIE-ID ::= 382
+id-NPNBroadcastInformation							ProtocolIE-ID ::= 383
+id-NPNSupportInfo									ProtocolIE-ID ::= 384
+id-NID												ProtocolIE-ID ::= 385
+id-AvailableSNPN-ID-List							ProtocolIE-ID ::= 386
+id-SIB10-message									ProtocolIE-ID ::= 387
+id-DLCarrierList									ProtocolIE-ID ::= 389
+	id-ExtendedTAISliceSupportList					ProtocolIE-ID ::= 390 
+id-RequestedSRSTransmissionCharacteristics			ProtocolIE-ID ::= 391
+id-PosAssistance-Information						ProtocolIE-ID ::= 392
+id-PosBroadcast										ProtocolIE-ID ::= 393
+id-RoutingID										ProtocolIE-ID ::= 394
+id-PosAssistanceInformationFailureList				ProtocolIE-ID ::= 395
+id-PosMeasurementQuantities							ProtocolIE-ID ::= 396
+id-PosMeasurementResultList							ProtocolIE-ID ::= 397
+id-TRPInformationTypeListTRPReq						ProtocolIE-ID ::= 398
+id-TRPInformationTypeItem							ProtocolIE-ID ::= 399
+id-TRPInformationListTRPResp						ProtocolIE-ID ::= 400
+id-TRPInformationItem								ProtocolIE-ID ::= 401
+id-LMF-MeasurementID								ProtocolIE-ID ::= 402
+id-SRSType									ProtocolIE-ID ::= 403
+id-ActivationTime								ProtocolIE-ID ::= 404
+id-AbortTransmission								ProtocolIE-ID ::= 405
+id-PositioningBroadcastCells							ProtocolIE-ID ::= 406
+id-SRSConfiguration								ProtocolIE-ID ::= 407
+id-PosReportCharacteristics							ProtocolIE-ID ::= 408
+id-PosMeasurementPeriodicity							ProtocolIE-ID ::= 409
+id-TRPList									ProtocolIE-ID ::= 410
+id-RAN-MeasurementID								ProtocolIE-ID ::= 411
+id-LMF-UE-MeasurementID								ProtocolIE-ID ::= 412
+id-RAN-UE-MeasurementID								ProtocolIE-ID ::= 413
+id-E-CID-MeasurementQuantities							ProtocolIE-ID ::= 414
+id-E-CID-MeasurementQuantities-Item						ProtocolIE-ID ::= 415
+id-E-CID-MeasurementPeriodicity							ProtocolIE-ID ::= 416
+id-E-CID-MeasurementResult							ProtocolIE-ID ::= 417
+id-Cell-Portion-ID								ProtocolIE-ID ::= 418
+id-SFNInitialisationTime							ProtocolIE-ID ::= 419
+id-SystemFrameNumber								ProtocolIE-ID ::= 420
+id-SlotNumber									ProtocolIE-ID ::= 421
+id-TRP-MeasurementRequestList							ProtocolIE-ID ::= 422
+id-MeasurementBeamInfoRequest							ProtocolIE-ID ::= 423
+id-E-CID-ReportCharacteristics							ProtocolIE-ID ::= 424
+id-ConfiguredTACIndication							ProtocolIE-ID ::= 425
+id-Extended-GNB-DU-Name								ProtocolIE-ID ::= 426
+id-Extended-GNB-CU-Name								ProtocolIE-ID ::= 427
+
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-Containers.asn b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-Containers.asn
new file mode 100644
index 0000000000000000000000000000000000000000..72c6d6e5512777355ab2e5f0dcb5db06dd4a0450
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-Containers.asn
@@ -0,0 +1,178 @@
+F1AP-Containers {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-Containers (5) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	Criticality,
+	Presence,
+	PrivateIE-ID,
+	ProtocolExtensionID,
+	ProtocolIE-ID
+
+FROM F1AP-CommonDataTypes
+	maxPrivateIEs,
+	maxProtocolExtensions,
+	maxProtocolIEs
+
+FROM F1AP-Constants;
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+F1AP-PROTOCOL-IES ::= CLASS {
+	&id				ProtocolIE-ID 					UNIQUE,
+	&criticality	Criticality,
+	&Value,
+	&presence		Presence
+}
+WITH SYNTAX {
+	ID				&id
+	CRITICALITY		&criticality
+	TYPE			&Value
+	PRESENCE		&presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+F1AP-PROTOCOL-IES-PAIR ::= CLASS {
+	&id					ProtocolIE-ID 				UNIQUE,
+	&firstCriticality	Criticality,
+	&FirstValue,
+	&secondCriticality	Criticality,
+	&SecondValue,
+	&presence			Presence
+}
+WITH SYNTAX {
+	ID				&id
+	FIRST CRITICALITY		&firstCriticality
+	FIRST TYPE				&FirstValue
+	SECOND CRITICALITY		&secondCriticality
+	SECOND TYPE				&SecondValue
+	PRESENCE				&presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol Extensions
+--
+-- **************************************************************
+
+F1AP-PROTOCOL-EXTENSION ::= CLASS {
+	&id				ProtocolExtensionID			UNIQUE,
+	&criticality	Criticality,
+	&Extension,
+	&presence		Presence
+}
+WITH SYNTAX {
+	ID				&id
+	CRITICALITY		&criticality
+	EXTENSION		&Extension
+	PRESENCE		&presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Private IEs
+--
+-- **************************************************************
+
+F1AP-PRIVATE-IES ::= CLASS {
+	&id				PrivateIE-ID,
+	&criticality	Criticality,
+	&Value,
+	&presence		Presence
+}
+WITH SYNTAX {
+	ID				&id
+	CRITICALITY		&criticality
+	TYPE			&Value
+	PRESENCE		&presence
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IEs
+--
+-- **************************************************************
+
+ProtocolIE-Container {F1AP-PROTOCOL-IES : IEsSetParam} ::= 
+	SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+	ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-SingleContainer {F1AP-PROTOCOL-IES : IEsSetParam} ::= 
+	ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-Field {F1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE {
+	id				F1AP-PROTOCOL-IES.&id				({IEsSetParam}),
+	criticality		F1AP-PROTOCOL-IES.&criticality		({IEsSetParam}{@id}),
+	value			F1AP-PROTOCOL-IES.&Value			({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IE Pairs
+--
+-- **************************************************************
+
+ProtocolIE-ContainerPair {F1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= 
+	SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+	ProtocolIE-FieldPair {{IEsSetParam}}
+
+ProtocolIE-FieldPair {F1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE {
+	id					F1AP-PROTOCOL-IES-PAIR.&id					({IEsSetParam}),
+	firstCriticality	F1AP-PROTOCOL-IES-PAIR.&firstCriticality	({IEsSetParam}{@id}),
+	firstValue			F1AP-PROTOCOL-IES-PAIR.&FirstValue			({IEsSetParam}{@id}),
+	secondCriticality	F1AP-PROTOCOL-IES-PAIR.&secondCriticality	({IEsSetParam}{@id}),
+	secondValue			F1AP-PROTOCOL-IES-PAIR.&SecondValue			({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol Extensions
+--
+-- **************************************************************
+
+ProtocolExtensionContainer {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= 
+	SEQUENCE (SIZE (1..maxProtocolExtensions)) OF
+	ProtocolExtensionField {{ExtensionSetParam}}
+
+ProtocolExtensionField {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE {
+	id					F1AP-PROTOCOL-EXTENSION.&id				({ExtensionSetParam}),
+	criticality			F1AP-PROTOCOL-EXTENSION.&criticality	({ExtensionSetParam}{@id}),
+	extensionValue		F1AP-PROTOCOL-EXTENSION.&Extension		({ExtensionSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Private IEs
+--
+-- **************************************************************
+
+PrivateIE-Container {F1AP-PRIVATE-IES : IEsSetParam } ::= 
+	SEQUENCE (SIZE (1.. maxPrivateIEs)) OF
+	PrivateIE-Field {{IEsSetParam}}
+
+PrivateIE-Field {F1AP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE {
+	id					F1AP-PRIVATE-IES.&id				({IEsSetParam}),
+	criticality			F1AP-PRIVATE-IES.&criticality		({IEsSetParam}{@id}),
+	value				F1AP-PRIVATE-IES.&Value				({IEsSetParam}{@id})
+}
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-IEs.asn b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-IEs.asn
new file mode 100644
index 0000000000000000000000000000000000000000..3e02e1b27ee2d62c7d629766d062670636e838be
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-IEs.asn
@@ -0,0 +1,5509 @@
+-- **************************************************************
+--
+-- Information Element Definitions
+--
+-- **************************************************************
+
+F1AP-IEs {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-IEs (2) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+IMPORTS
+	id-gNB-CUSystemInformation,
+	id-HandoverPreparationInformation,
+	id-TAISliceSupportList,
+	id-RANAC,
+	id-BearerTypeChange,
+	id-Cell-Direction,
+	id-Cell-Type,
+	id-CellGroupConfig,
+	id-AvailablePLMNList,
+	id-PDUSessionID,
+	id-ULPDUSessionAggregateMaximumBitRate, 
+	id-DC-Based-Duplication-Configured,
+	id-DC-Based-Duplication-Activation,
+	id-Duplication-Activation,
+	id-DLPDCPSNLength,
+	id-ULPDCPSNLength,
+	id-RLC-Status,
+	id-MeasurementTimingConfiguration,
+	id-DRB-Information,
+	id-QoSFlowMappingIndication,
+	id-ServingCellMO,
+	id-RLCMode,
+	id-ExtendedServedPLMNs-List,
+	id-ExtendedAvailablePLMN-List,
+	id-DRX-LongCycleStartOffset,
+	id-SelectedBandCombinationIndex,
+	id-SelectedFeatureSetEntryIndex,
+	id-Ph-InfoSCG,
+	id-latest-RRC-Version-Enhanced,
+	id-RequestedBandCombinationIndex,
+	id-RequestedFeatureSetEntryIndex,
+	id-DRX-Config,
+	id-UEAssistanceInformation,
+	id-PDCCH-BlindDetectionSCG,
+	id-Requested-PDCCH-BlindDetectionSCG,
+	id-BPLMN-ID-Info-List,
+	id-NotificationInformation,
+	id-TNLAssociationTransportLayerAddressgNBDU,
+	id-portNumber,
+	id-AdditionalSIBMessageList,
+	id-IgnorePRACHConfiguration,
+	id-CG-Config,
+	id-Ph-InfoMCG,
+	id-AggressorgNBSetID,
+	id-VictimgNBSetID,
+	id-MeasGapSharingConfig,
+	id-systemInformationAreaID,
+	id-areaScope,
+	id-IntendedTDD-DL-ULConfig,
+	id-QosMonitoringRequest,
+	id-BHInfo,
+	id-IAB-Info-IAB-DU,
+	id-IAB-Info-IAB-donor-CU,
+	id-IAB-Barred,
+	id-SIB12-message,
+	id-SIB13-message,
+	id-SIB14-message,
+	id-UEAssistanceInformationEUTRA,
+	id-SL-PHY-MAC-RLC-Config,
+	id-SL-ConfigDedicatedEUTRA,
+	id-AlternativeQoSParaSetList,
+	id-CurrentQoSParaSetIndex,
+	id-CarrierList,
+	id-ULCarrierList,
+	id-FrequencyShift7p5khz,
+	id-SSB-PositionsInBurst,
+	id-NRPRACHConfig, 
+	id-TDD-UL-DLConfigCommonNR,
+	id-CNPacketDelayBudgetDownlink,
+	id-CNPacketDelayBudgetUplink,
+	id-ExtendedPacketDelayBudget,
+	id-TSCTrafficCharacteristics,
+	id-AdditionalPDCPDuplicationTNL-List,
+	id-RLCDuplicationInformation,
+	id-AdditionalDuplicationIndication,
+	id-mdtConfiguration,
+	id-TraceCollectionEntityURI,
+	id-NID,
+	id-NPNSupportInfo,
+	id-NPNBroadcastInformation,
+	id-AvailableSNPN-ID-List,
+	id-SIB10-message,
+	id-RequestedP-MaxFR2,
+	id-DLCarrierList,
+	id-ExtendedTAISliceSupportList,
+	id-E-CID-MeasurementQuantities-Item,
+	id-ConfiguredTACIndication,
+	maxNRARFCN,
+	maxnoofErrors,
+	maxnoofBPLMNs,
+	maxnoofBPLMNsNR,
+	maxnoofDLUPTNLInformation,
+	maxnoofNrCellBands,
+	maxnoofULUPTNLInformation,
+	maxnoofQoSFlows,
+	maxnoofSliceItems,
+	maxnoofSIBTypes,
+	maxnoofSITypes,
+	maxCellineNB,
+	maxnoofExtendedBPLMNs,
+	maxnoofAdditionalSIBs,
+	maxnoofUACPLMNs,
+	maxnoofUACperPLMN,
+	maxCellingNBDU,
+	maxnoofTLAs,
+	maxnoofGTPTLAs,
+	maxnoofslots,
+	maxnoofNonUPTrafficMappings,
+	maxnoofServingCells,
+	maxnoofServedCellsIAB,
+	maxnoofChildIABNodes,
+	maxnoofIABSTCInfo,
+	maxnoofSymbols,
+	maxnoofDUFSlots,
+	maxnoofHSNASlots,
+	maxnoofEgressLinks,
+	maxnoofMappingEntries,
+	maxnoofDSInfo,
+	maxnoofQoSParaSets,
+	maxnoofPC5QoSFlows,
+	maxnoofSSBAreas,
+	maxnoofBPLMNsNR,
+	maxnoofNRSCSs,
+	maxnoofPhysicalResourceBlocks,
+	maxnoofPhysicalResourceBlocks-1,
+	maxnoofPRACHconfigs,
+	maxnoofRACHReports,
+	maxnoofRLFReports,
+	maxnoofAdditionalPDCPDuplicationTNL,
+	maxnoofRLCDuplicationState,
+	maxnoofCHOcells,
+	maxnoofMDTPLMNs,
+	maxnoofCAGsupported,
+	maxnoofNIDsupported,
+	maxnoofNRSCSs,
+	maxnoofPhysicalResourceBlocks,
+	maxnoofExtSliceItems,
+	maxnoofPosMeas,
+	maxnoofTRPInfoTypes,
+	maxnoofSRSTriggerStates,
+	maxnoofSpatialRelations,
+	maxnoBcastCell,
+	maxnoofTRPs,
+	maxnoofAngleInfo,
+	maxnooflcs-gcs-translation,
+	maxnoofPath,
+	maxnoofMeasE-CID,
+	maxnoofSSBs,
+	maxnoSRS-ResourceSets,
+	maxnoSRS-ResourcePerSet,
+	maxnoSRS-Carriers,
+	maxnoSCSs,
+	maxnoSRS-Resources,
+	maxnoSRS-PosResources,
+	maxnoSRS-PosResourceSets,
+	maxnoSRS-PosResourcePerSet,
+	maxnoofPRS-ResourceSets,
+	maxnoofPRS-ResourcesPerSet,
+	maxNoOfMeasTRPs,
+	maxnoofPRSresourceSets,
+	maxnoofPRSresources
+
+
+
+FROM F1AP-Constants
+
+	Criticality,
+	ProcedureCode,
+	ProtocolIE-ID,
+	TriggeringMessage
+
+FROM F1AP-CommonDataTypes
+
+	ProtocolExtensionContainer{},
+	F1AP-PROTOCOL-EXTENSION,
+	ProtocolIE-SingleContainer{},
+	F1AP-PROTOCOL-IES
+
+FROM F1AP-Containers;
+
+-- A
+
+AbortTransmission ::= CHOICE {
+	sRSResourceSetID		SRSResourceSetID,
+	releaseALL				NULL,
+	choice-extension		ProtocolIE-SingleContainer { { AbortTransmission-ExtIEs } }
+}
+
+AbortTransmission-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+AccessPointPosition ::= SEQUENCE {
+	latitudeSign				ENUMERATED {north, south},
+	latitude					INTEGER (0..8388607),
+	longitude					INTEGER (-8388608..8388607),
+	directionOfAltitude			ENUMERATED {height, depth},
+	altitude					INTEGER (0..32767),
+	uncertaintySemi-major		INTEGER (0..127),
+	uncertaintySemi-minor		INTEGER (0..127),
+	orientationOfMajorAxis		INTEGER (0..179),
+	uncertaintyAltitude			INTEGER (0..127),
+	confidence					INTEGER (0..100),
+	iE-Extensions				ProtocolExtensionContainer { { AccessPointPosition-ExtIEs} } OPTIONAL
+}
+
+AccessPointPosition-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Activated-Cells-to-be-Updated-List ::= SEQUENCE (SIZE(1..maxnoofServedCellsIAB)) OF Activated-Cells-to-be-Updated-List-Item
+
+Activated-Cells-to-be-Updated-List-Item ::=	SEQUENCE{
+	nRCGI								NRCGI,
+	iAB-DU-Cell-Resource-Configuration-Mode-Info	IAB-DU-Cell-Resource-Configuration-Mode-Info,
+	iE-Extensions						ProtocolExtensionContainer { { Activated-Cells-to-be-Updated-List-Item-ExtIEs} } OPTIONAL
+}
+
+Activated-Cells-to-be-Updated-List-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ActiveULBWP  ::= SEQUENCE {
+	locationAndBandwidth		INTEGER (0..37949,...),
+	subcarrierSpacing           ENUMERATED {kHz15, kHz30, kHz60, kHz120,...},
+	cyclicPrefix				ENUMERATED {normal, extended},
+	txDirectCurrentLocation		INTEGER (0..3301,...),
+	shift7dot5kHz				ENUMERATED {true, ...} OPTIONAL,
+	sRSConfig					SRSConfig,
+	iE-Extensions					ProtocolExtensionContainer { { ActiveULBWP-ExtIEs} } OPTIONAL
+}
+
+ActiveULBWP-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AdditionalDuplicationIndication ::= ENUMERATED { 
+	three,
+	four,
+	...
+}
+
+
+AdditionalPath-List::= SEQUENCE (SIZE(1..maxnoofPath)) OF AdditionalPath-Item
+
+AdditionalPath-Item ::=SEQUENCE {
+	relativePathDelay	RelativePathDelay, 
+	pathQuality			TRPMeasurementQuality 	OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { AdditionalPath-Item-ExtIEs } }	OPTIONAL
+}
+
+AdditionalPath-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+AdditionalPDCPDuplicationTNL-List ::= SEQUENCE (SIZE(1..maxnoofAdditionalPDCPDuplicationTNL)) OF AdditionalPDCPDuplicationTNL-Item
+
+AdditionalPDCPDuplicationTNL-Item ::=SEQUENCE {
+	additionalPDCPDuplicationUPTNLInformation		UPTransportLayerInformation, 
+	iE-Extensions	ProtocolExtensionContainer { { AdditionalPDCPDuplicationTNL-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+AdditionalPDCPDuplicationTNL-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AdditionalSIBMessageList ::= SEQUENCE (SIZE(1..maxnoofAdditionalSIBs)) OF AdditionalSIBMessageList-Item
+
+AdditionalSIBMessageList-Item ::= SEQUENCE {
+	additionalSIB			OCTET STRING,
+	iE-Extensions		ProtocolExtensionContainer { { AdditionalSIBMessageList-Item-ExtIEs} } OPTIONAL
+}
+
+AdditionalSIBMessageList-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AdditionalRRMPriorityIndex ::= BIT STRING (SIZE(32))
+
+AggressorCellList ::= SEQUENCE (SIZE(1..maxCellingNBDU)) OF AggressorCellList-Item
+
+AggressorCellList-Item ::= SEQUENCE {
+	aggressorCell-ID		NRCGI,
+	iE-Extensions	ProtocolExtensionContainer { { AggressorCellList-Item-ExtIEs } }		OPTIONAL
+}
+
+AggressorCellList-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AggressorgNBSetID ::= SEQUENCE {
+	aggressorgNBSetID		GNBSetID,
+	iE-Extensions	ProtocolExtensionContainer { { AggressorgNBSetID-ExtIEs } }	OPTIONAL
+}
+
+AggressorgNBSetID-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AllocationAndRetentionPriority ::= SEQUENCE {
+	priorityLevel				PriorityLevel,
+	pre-emptionCapability		Pre-emptionCapability,
+	pre-emptionVulnerability	Pre-emptionVulnerability,
+	iE-Extensions				ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL,
+	...
+}
+
+AllocationAndRetentionPriority-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AlternativeQoSParaSetList ::= SEQUENCE (SIZE(1..maxnoofQoSParaSets)) OF AlternativeQoSParaSetItem
+
+AlternativeQoSParaSetItem ::= SEQUENCE {
+	alternativeQoSParaSetIndex			QoSParaSetIndex,
+	guaranteedFlowBitRateDL				BitRate					OPTIONAL,
+	guaranteedFlowBitRateUL				BitRate					OPTIONAL,
+	packetDelayBudget					PacketDelayBudget		OPTIONAL,
+	packetErrorRate						PacketErrorRate			OPTIONAL,
+	iE-Extensions						ProtocolExtensionContainer { {AlternativeQoSParaSetItem-ExtIEs} }	OPTIONAL,
+	...
+}
+
+AlternativeQoSParaSetItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+AngleMeasurementQuality ::= SEQUENCE {
+	azimuthQuality	INTEGER(0..255),
+	zenithQuality	INTEGER(0..255) OPTIONAL,
+	resolution		ENUMERATED{deg0dot1,...},
+	iE-Extensions	ProtocolExtensionContainer { { AngleMeasurementQuality-ExtIEs } }	OPTIONAL
+}
+
+AngleMeasurementQuality-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+AperiodicSRSResourceTriggerList ::= SEQUENCE (SIZE(1..maxnoofSRSTriggerStates)) OF AperiodicSRSResourceTrigger
+
+AperiodicSRSResourceTrigger ::= INTEGER (0..3, ...)
+
+Associated-SCell-Item ::= SEQUENCE {
+	sCell-ID		NRCGI,
+	iE-Extensions	ProtocolExtensionContainer { { Associated-SCell-ItemExtIEs } }	OPTIONAL
+}
+
+Associated-SCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AvailablePLMNList ::= SEQUENCE (SIZE(1..maxnoofBPLMNs)) OF AvailablePLMNList-Item
+
+AvailablePLMNList-Item ::= SEQUENCE {
+	pLMNIdentity			PLMN-Identity,
+	iE-Extensions		ProtocolExtensionContainer { { AvailablePLMNList-Item-ExtIEs} } OPTIONAL
+}
+
+AvailablePLMNList-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AvailableSNPN-ID-List ::= SEQUENCE (SIZE(1..maxnoofNIDsupported)) OF AvailableSNPN-ID-List-Item
+
+AvailableSNPN-ID-List-Item ::= SEQUENCE {
+	pLMN-Identity				PLMN-Identity,
+	availableNIDList			BroadcastNIDList,
+	iE-Extensions				ProtocolExtensionContainer { { AvailableSNPN-ID-List-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+AvailableSNPN-ID-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AveragingWindow  ::= INTEGER (0..4095, ...) 
+
+AreaScope ::= ENUMERATED {true, ...}
+
+-- B
+
+BandwidthSRS ::= CHOICE { 
+	fR1								FR1-Bandwidth,
+	fR2								FR2-Bandwidth,
+	choice-extension				ProtocolIE-SingleContainer {{ BandwidthSRS-ExtIEs }}
+}
+
+BandwidthSRS-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+
+BAPAddress ::= BIT STRING (SIZE(10))
+
+BAPCtrlPDUChannel ::= ENUMERATED {true, ...}
+
+BAPlayerBHRLCchannelMappingInfo ::= SEQUENCE {
+	bAPlayerBHRLCchannelMappingInfoToAdd			BAPlayerBHRLCchannelMappingInfoList			OPTIONAL,
+	bAPlayerBHRLCchannelMappingInfoToRemove			MappingInformationtoRemove					OPTIONAL,
+	iE-Extensions									ProtocolExtensionContainer { { BAPlayerBHRLCchannelMappingInfo-ExtIEs} } OPTIONAL,
+	...
+}
+
+BAPlayerBHRLCchannelMappingInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BAPlayerBHRLCchannelMappingInfoList ::= SEQUENCE (SIZE(1..maxnoofMappingEntries)) OF BAPlayerBHRLCchannelMappingInfo-Item
+
+BAPlayerBHRLCchannelMappingInfo-Item ::= SEQUENCE {
+	mappingInformationIndex			MappingInformationIndex,		
+	priorHopBAPAddress				BAPAddress		OPTIONAL,		
+	ingressbHRLCChannelID			BHRLCChannelID		OPTIONAL,		
+	nextHopBAPAddress				BAPAddress		OPTIONAL,		
+	egressbHRLCChannelID			BHRLCChannelID		OPTIONAL,		
+	iE-Extensions					ProtocolExtensionContainer { { BAPlayerBHRLCchannelMappingInfo-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+BAPlayerBHRLCchannelMappingInfo-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BAPPathID ::= BIT STRING (SIZE(10))
+
+BAPRoutingID ::= SEQUENCE {
+	bAPAddress		BAPAddress,
+	bAPPathID		BAPPathID,
+	iE-Extensions	ProtocolExtensionContainer { { BAPRoutingIDExtIEs } }	OPTIONAL
+}
+
+BAPRoutingIDExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BitRate ::= INTEGER (0..4000000000000,...)
+
+BearerTypeChange ::= ENUMERATED {true, ...}
+
+BHRLCChannelID ::= BIT STRING (SIZE(16))
+
+BHChannels-FailedToBeModified-Item ::= SEQUENCE {
+	bHRLCChannelID		BHRLCChannelID,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-FailedToBeModified-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-FailedToBeModified-ItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-FailedToBeSetup-Item ::= SEQUENCE {
+	bHRLCChannelID		BHRLCChannelID,
+	cause	Cause	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-FailedToBeSetup-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-FailedToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-FailedToBeSetupMod-Item ::= SEQUENCE {
+	bHRLCChannelID		BHRLCChannelID,
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-FailedToBeSetupMod-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-FailedToBeSetupMod-ItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-Modified-Item ::= SEQUENCE {
+	bHRLCChannelID			BHRLCChannelID,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-Modified-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-Modified-ItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-Required-ToBeReleased-Item ::= SEQUENCE {
+	bHRLCChannelID		BHRLCChannelID,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-Required-ToBeReleased-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-Required-ToBeReleased-ItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-Setup-Item ::= SEQUENCE {
+	bHRLCChannelID							BHRLCChannelID,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-Setup-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-Setup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-SetupMod-Item ::= SEQUENCE {
+	bHRLCChannelID							BHRLCChannelID,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-SetupMod-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-SetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-ToBeModified-Item ::= SEQUENCE {
+	bHRLCChannelID					BHRLCChannelID,
+	bHQoSInformation				BHQoSInformation,
+	rLCmode				RLCMode	OPTIONAL,
+	bAPCtrlPDUChannel	BAPCtrlPDUChannel		OPTIONAL,
+	trafficMappingInfo	TrafficMappingInfo		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-ToBeModified-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-ToBeReleased-Item ::= SEQUENCE {
+	bHRLCChannelID		BHRLCChannelID,
+	iE-Extensions	ProtocolExtensionContainer { { BHChannels-ToBeReleased-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-ToBeSetup-Item ::= SEQUENCE	{
+	bHRLCChannelID						BHRLCChannelID,
+	bHQoSInformation					BHQoSInformation,
+	rLCmode								RLCMode,
+	bAPCtrlPDUChannel					BAPCtrlPDUChannel		OPTIONAL,
+	trafficMappingInfo					TrafficMappingInfo		OPTIONAL,
+	iE-Extensions						ProtocolExtensionContainer { { BHChannels-ToBeSetup-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHChannels-ToBeSetupMod-Item ::= SEQUENCE {
+	bHRLCChannelID				BHRLCChannelID,
+	bHQoSInformation			BHQoSInformation,
+	rLCmode				RLCMode,
+	bAPCtrlPDUChannel	BAPCtrlPDUChannel		OPTIONAL,
+	trafficMappingInfo	TrafficMappingInfo		OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { BHChannels-ToBeSetupMod-ItemExtIEs } }	OPTIONAL
+}
+
+BHChannels-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHInfo ::= SEQUENCE {
+	bAProutingID			BAPRoutingID 	OPTIONAL,
+	egressBHRLCCHList		EgressBHRLCCHList	OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { { BHInfo-ExtIEs} } OPTIONAL
+}
+
+BHInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BHQoSInformation ::= CHOICE {
+	bHRLCCHQoS					QoSFlowLevelQoSParameters,	
+	eUTRANBHRLCCHQoS			EUTRANQoS,
+	cPTrafficType				CPTrafficType,
+	choice-extension			ProtocolIE-SingleContainer { { BHQoSInformation-ExtIEs} }
+}
+
+BHQoSInformation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+BH-Routing-Information-Added-List-Item ::= SEQUENCE {
+	bAPRoutingID				BAPRoutingID,
+	nextHopBAPAddress			BAPAddress,
+	iE-Extensions				ProtocolExtensionContainer { { BH-Routing-Information-Added-List-ItemExtIEs} }	OPTIONAL
+}
+
+BH-Routing-Information-Added-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BH-Routing-Information-Removed-List-Item ::= SEQUENCE {
+	bAPRoutingID				BAPRoutingID,
+	iE-Extensions				ProtocolExtensionContainer { { BH-Routing-Information-Removed-List-ItemExtIEs} }	OPTIONAL
+}
+
+BH-Routing-Information-Removed-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BPLMN-ID-Info-List ::= SEQUENCE (SIZE(1..maxnoofBPLMNsNR)) OF BPLMN-ID-Info-Item
+
+BPLMN-ID-Info-Item ::= SEQUENCE {
+	pLMN-Identity-List			AvailablePLMNList,
+	extended-PLMN-Identity-List	ExtendedAvailablePLMN-List	OPTIONAL,
+	fiveGS-TAC					FiveGS-TAC					OPTIONAL,
+	nr-cell-ID					NRCellIdentity,
+	ranac						RANAC						OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { BPLMN-ID-Info-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+BPLMN-ID-Info-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{	ID id-ConfiguredTACIndication		CRITICALITY ignore	EXTENSION ConfiguredTACIndication		PRESENCE optional }|
+	{	ID id-NPNBroadcastInformation		CRITICALITY reject EXTENSION NPNBroadcastInformation		PRESENCE optional},
+	...
+}
+
+ServedPLMNs-List ::= SEQUENCE (SIZE(1..maxnoofBPLMNs)) OF ServedPLMNs-Item
+
+ServedPLMNs-Item ::= SEQUENCE {
+	pLMN-Identity				PLMN-Identity,
+	iE-Extensions				ProtocolExtensionContainer { { ServedPLMNs-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+ServedPLMNs-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+{ ID id-TAISliceSupportList	CRITICALITY ignore	EXTENSION SliceSupportList		PRESENCE optional	}|
+{ ID id-NPNSupportInfo	CRITICALITY reject	EXTENSION NPNSupportInfo		PRESENCE optional	}|
+{ ID id-ExtendedTAISliceSupportList	CRITICALITY reject	EXTENSION ExtendedSliceSupportList		PRESENCE optional	},
+	...
+}
+
+BroadcastCAGList ::= SEQUENCE (SIZE(1..maxnoofCAGsupported)) OF CAGID
+
+BroadcastNIDList ::= SEQUENCE (SIZE(1..maxnoofNIDsupported)) OF NID
+
+BroadcastSNPN-ID-List ::= SEQUENCE (SIZE(1..maxnoofNIDsupported)) OF BroadcastSNPN-ID-List-Item
+
+BroadcastSNPN-ID-List-Item ::= SEQUENCE {
+	pLMN-Identity				PLMN-Identity,
+	broadcastNIDList			BroadcastNIDList,
+	iE-Extensions				ProtocolExtensionContainer { { BroadcastSNPN-ID-List-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+BroadcastSNPN-ID-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+BroadcastPNI-NPN-ID-List ::= SEQUENCE (SIZE(1..maxnoofCAGsupported)) OF BroadcastPNI-NPN-ID-List-Item
+
+BroadcastPNI-NPN-ID-List-Item ::= SEQUENCE {
+	pLMN-Identity				PLMN-Identity,
+	broadcastCAGList			BroadcastCAGList,
+	iE-Extensions				ProtocolExtensionContainer { { BroadcastPNI-NPN-ID-List-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+BroadcastPNI-NPN-ID-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+BurstArrivalTime ::= OCTET STRING
+
+-- C
+CAGID ::= BIT STRING (SIZE(32))
+
+Cancel-all-Warning-Messages-Indicator ::= ENUMERATED {true, ...}
+
+Candidate-SpCell-Item ::= SEQUENCE {
+	candidate-SpCell-ID			NRCGI	,
+	iE-Extensions	ProtocolExtensionContainer { { Candidate-SpCell-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Candidate-SpCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CapacityValue::= SEQUENCE {
+	capacityValue				INTEGER (0..100),
+	sSBAreaCapacityValueList	SSBAreaCapacityValueList		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { CapacityValue-ExtIEs} } OPTIONAL
+}
+
+CapacityValue-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cause ::= CHOICE {
+	radioNetwork		CauseRadioNetwork,
+	transport			CauseTransport,
+	protocol			CauseProtocol,
+	misc				CauseMisc,
+	choice-extension	ProtocolIE-SingleContainer { { Cause-ExtIEs} }
+}
+
+Cause-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+CauseMisc ::= ENUMERATED {
+	control-processing-overload,
+	not-enough-user-plane-processing-resources,
+	hardware-failure,
+	om-intervention,
+	unspecified,
+	...
+}
+
+CauseProtocol ::= ENUMERATED {
+	transfer-syntax-error,
+	abstract-syntax-error-reject,
+	abstract-syntax-error-ignore-and-notify,
+	message-not-compatible-with-receiver-state,
+	semantic-error,
+	abstract-syntax-error-falsely-constructed-message,
+	unspecified,
+	...
+}
+
+CauseRadioNetwork ::= ENUMERATED {
+	unspecified,
+	rl-failure-rlc,
+	unknown-or-already-allocated-gnb-cu-ue-f1ap-id,
+	unknown-or-already-allocated-gnb-du-ue-f1ap-id,
+	unknown-or-inconsistent-pair-of-ue-f1ap-id,
+	interaction-with-other-procedure,
+	not-supported-qci-Value,
+	action-desirable-for-radio-reasons,
+	no-radio-resources-available,
+	procedure-cancelled,
+	normal-release,
+	...,
+	cell-not-available,
+	rl-failure-others,
+	ue-rejection,
+	resources-not-available-for-the-slice,
+	amf-initiated-abnormal-release,
+	release-due-to-pre-emption,
+	plmn-not-served-by-the-gNB-CU,
+	multiple-drb-id-instances,
+	unknown-drb-id,
+	multiple-bh-rlc-ch-id-instances,
+	unknown-bh-rlc-ch-id,
+	cho-cpc-resources-tobechanged,
+	nPN-not-supported, 
+	nPN-access-denied,
+	gNB-CU-Cell-Capacity-Exceeded,
+	report-characteristics-empty,
+	existing-measurement-ID,
+	measurement-temporarily-not-available,
+	measurement-not-supported-for-the-object
+
+}
+
+CauseTransport ::= ENUMERATED {
+	unspecified,
+	transport-resource-unavailable,
+	...,
+	unknown-TNL-address-for-IAB,
+	unknown-UP-TNL-information-for-IAB
+}
+
+CellGroupConfig ::= OCTET STRING
+
+CellCapacityClassValue ::= INTEGER (1..100,...)
+
+Cell-Direction ::= ENUMERATED {dl-only, ul-only}
+
+CellMeasurementResultList ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF CellMeasurementResultItem
+
+CellMeasurementResultItem ::= SEQUENCE {
+	cellID							NRCGI,
+	radioResourceStatus				RadioResourceStatus 			OPTIONAL, 
+	compositeAvailableCapacityGroup	CompositeAvailableCapacityGroup	OPTIONAL,
+	sliceAvailableCapacity			SliceAvailableCapacity 			OPTIONAL, 
+	numberofActiveUEs 				NumberofActiveUEs			OPTIONAL, 
+	iE-Extensions					ProtocolExtensionContainer { { CellMeasurementResultItem-ExtIEs} } OPTIONAL
+}
+
+CellMeasurementResultItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cell-Portion-ID ::= INTEGER (0..4095,...)
+
+Cells-Failed-to-be-Activated-List-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	cause				Cause,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-Failed-to-be-Activated-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-Failed-to-be-Activated-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-Status-Item ::= SEQUENCE {
+	nRCGI			NRCGI,
+	service-status		Service-Status,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-Status-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-Status-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-To-Be-Broadcast-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-To-Be-Broadcast-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-To-Be-Broadcast-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-Broadcast-Completed-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-Broadcast-Completed-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-Broadcast-Completed-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Broadcast-To-Be-Cancelled-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	iE-Extensions		ProtocolExtensionContainer { { Broadcast-To-Be-Cancelled-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Broadcast-To-Be-Cancelled-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+Cells-Broadcast-Cancelled-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	numberOfBroadcasts	NumberOfBroadcasts,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-Broadcast-Cancelled-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-Broadcast-Cancelled-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-to-be-Activated-List-Item ::= SEQUENCE {
+	nRCGI		NRCGI,
+	nRPCI		NRPCI		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-to-be-Activated-List-ItemExtIEs} }	OPTIONAL,
+	...
+}
+
+Cells-to-be-Activated-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-gNB-CUSystemInformation			CRITICALITY reject	EXTENSION GNB-CUSystemInformation			PRESENCE optional }|
+	{ ID id-AvailablePLMNList				CRITICALITY ignore	EXTENSION AvailablePLMNList					PRESENCE optional }|
+	{ ID id-ExtendedAvailablePLMN-List		CRITICALITY ignore	EXTENSION ExtendedAvailablePLMN-List		PRESENCE optional }|
+	{ ID id-IAB-Info-IAB-donor-CU			CRITICALITY ignore	EXTENSION IAB-Info-IAB-donor-CU				PRESENCE optional}|
+	{ ID id-AvailableSNPN-ID-List			CRITICALITY ignore	EXTENSION AvailableSNPN-ID-List				PRESENCE optional },
+	...
+}
+
+Cells-to-be-Deactivated-List-Item ::= SEQUENCE {
+	nRCGI			NRCGI	,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-to-be-Deactivated-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-to-be-Deactivated-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-to-be-Barred-Item::= SEQUENCE {
+	nRCGI			NRCGI	,
+	cellBarred		CellBarred,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-to-be-Barred-Item-ExtIEs } }	OPTIONAL
+}
+
+Cells-to-be-Barred-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-IAB-Barred	CRITICALITY ignore	EXTENSION IAB-Barred		PRESENCE optional },
+
+	...
+}
+
+
+CellBarred	::=	ENUMERATED {barred, not-barred, ...}
+
+CellSize ::= ENUMERATED {verysmall, small, medium, large, ...}
+
+CellToReportList ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF CellToReportItem
+
+CellToReportItem ::= SEQUENCE {
+	cellID		NRCGI,
+	sSBToReportList		SSBToReportList		 OPTIONAL,
+	sliceToReportList	SliceToReportList	 OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { CellToReportItem-ExtIEs} } OPTIONAL
+}
+
+CellToReportItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CellType ::= SEQUENCE {
+	cellSize		CellSize,
+	iE-Extensions		ProtocolExtensionContainer { {CellType-ExtIEs} }	OPTIONAL,
+	...
+}
+
+CellType-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CellULConfigured ::=  ENUMERATED {none, ul, sul, ul-and-sul, ...}
+
+Child-Node-Cells-List ::= SEQUENCE (SIZE(1..maxnoofChildIABNodes)) OF Child-Node-Cells-List-Item
+
+Child-Node-Cells-List-Item ::=	SEQUENCE{
+	nRCGI 								NRCGI,
+	iAB-DU-Cell-Resource-Configuration-Mode-Info 	IAB-DU-Cell-Resource-Configuration-Mode-Info	OPTIONAL,
+	iAB-STC-Info						IAB-STC-Info	OPTIONAL,
+	rACH-Config-Common					RACH-Config-Common	OPTIONAL,
+	rACH-Config-Common-IAB				RACH-Config-Common-IAB	OPTIONAL,
+	cSI-RS-Configuration				OCTET STRING	OPTIONAL,
+	sR-Configuration					OCTET STRING	OPTIONAL,
+	pDCCH-ConfigSIB1					OCTET STRING	OPTIONAL,
+	sCS-Common							OCTET STRING	OPTIONAL,
+	multiplexingInfo					MultiplexingInfo	OPTIONAL,
+	iE-Extensions						ProtocolExtensionContainer {{Child-Node-Cells-List-Item-ExtIEs}}		OPTIONAL
+}
+
+Child-Node-Cells-List-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Child-Nodes-List ::= SEQUENCE (SIZE(1..maxnoofChildIABNodes)) OF Child-Nodes-List-Item
+
+Child-Nodes-List-Item ::= SEQUENCE{
+	gNB-CU-UE-F1AP-ID	GNB-CU-UE-F1AP-ID,
+	gNB-DU-UE-F1AP-ID	GNB-DU-UE-F1AP-ID,
+	child-Node-Cells-List 	Child-Node-Cells-List	OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer {{Child-Nodes-List-Item-ExtIEs}}		OPTIONAL
+}
+
+Child-Nodes-List-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CHOtrigger-InterDU ::= ENUMERATED {
+	cho-initiation,
+	cho-replace,
+	...
+}
+
+CHOtrigger-IntraDU ::= ENUMERATED {
+	cho-initiation,
+	cho-replace,
+	cho-cancel,
+	...
+}
+
+CNUEPagingIdentity ::= CHOICE {
+	fiveG-S-TMSI			BIT STRING (SIZE(48)),
+	choice-extension			ProtocolIE-SingleContainer { { CNUEPagingIdentity-ExtIEs } }
+}
+
+CNUEPagingIdentity-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+CompositeAvailableCapacityGroup ::= SEQUENCE {
+	compositeAvailableCapacityDownlink	CompositeAvailableCapacity,
+	compositeAvailableCapacityUplink 	CompositeAvailableCapacity,
+	iE-Extensions	ProtocolExtensionContainer { { CompositeAvailableCapacityGroup-ExtIEs} } OPTIONAL
+}
+
+CompositeAvailableCapacityGroup-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CompositeAvailableCapacity ::= SEQUENCE {
+	cellCapacityClassValue 	CellCapacityClassValue		OPTIONAL,
+	capacityValue			CapacityValue,
+	iE-Extensions	ProtocolExtensionContainer { { CompositeAvailableCapacity-ExtIEs} } OPTIONAL
+}
+
+CompositeAvailableCapacity-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ConditionalInterDUMobilityInformation ::= SEQUENCE {
+	cho-trigger						CHOtrigger-InterDU,
+	targetgNB-DUUEF1APID			GNB-DU-UE-F1AP-ID							OPTIONAL
+		-- This IE shall be present if the cho-trigger IE is present and set to "cho-replace" --,
+	iE-Extensions					ProtocolExtensionContainer { { ConditionalInterDUMobilityInformation-ExtIEs} }	OPTIONAL,
+	...
+}
+
+ConditionalInterDUMobilityInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::={
+	...
+}
+
+ConditionalIntraDUMobilityInformation ::= SEQUENCE {
+	cho-trigger						CHOtrigger-IntraDU,
+	targetCellsTocancel				TargetCellList								OPTIONAL,
+	-- This IE may be present if the cho-trigger IE is present and set to "cho-cancel"
+	iE-Extensions					ProtocolExtensionContainer { { ConditionalIntraDUMobilityInformation-ExtIEs} }	OPTIONAL,
+	...
+}
+
+ConditionalIntraDUMobilityInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::={
+	...
+}
+
+ConfiguredTACIndication ::= ENUMERATED {
+	true,
+	...
+}
+
+
+CoordinateID ::= INTEGER (0..511, ...)
+
+CP-TransportLayerAddress ::= CHOICE {
+	endpoint-IP-address				TransportLayerAddress,
+	endpoint-IP-address-and-port	Endpoint-IP-address-and-port, 
+	choice-extension				ProtocolIE-SingleContainer { { CP-TransportLayerAddress-ExtIEs } }
+}
+
+CP-TransportLayerAddress-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+CPTrafficType ::= INTEGER (1..3,...)
+
+CriticalityDiagnostics ::= SEQUENCE {
+	procedureCode					ProcedureCode														OPTIONAL,
+	triggeringMessage				TriggeringMessage													OPTIONAL,
+	procedureCriticality			Criticality															OPTIONAL,
+	transactionID					TransactionID														OPTIONAL,
+	iEsCriticalityDiagnostics		CriticalityDiagnostics-IE-List										OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer {{CriticalityDiagnostics-ExtIEs}}		OPTIONAL,
+	...
+}
+
+CriticalityDiagnostics-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1.. maxnoofErrors)) OF CriticalityDiagnostics-IE-Item
+
+CriticalityDiagnostics-IE-Item ::= SEQUENCE {
+	iECriticality			Criticality,
+	iE-ID					ProtocolIE-ID,
+	typeOfError 			TypeOfError,
+	iE-Extensions			ProtocolExtensionContainer {{CriticalityDiagnostics-IE-Item-ExtIEs}}	OPTIONAL,
+	...
+}
+
+CriticalityDiagnostics-IE-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+C-RNTI ::= INTEGER (0..65535, ...)
+
+CUDURadioInformationType ::= CHOICE {
+	rIM								CUDURIMInformation,
+	choice-extension				ProtocolIE-SingleContainer { { CUDURadioInformationType-ExtIEs} }
+}
+
+CUDURadioInformationType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+CUDURIMInformation ::= SEQUENCE {
+	victimgNBSetID			GNBSetID, 
+	rIMRSDetectionStatus	RIMRSDetectionStatus,
+	iE-Extensions			ProtocolExtensionContainer { { CUDURIMInformation-ExtIEs} }	OPTIONAL
+}
+
+CUDURIMInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CUtoDURRCInformation ::= SEQUENCE {
+	cG-ConfigInfo						CG-ConfigInfo						OPTIONAL,
+	uE-CapabilityRAT-ContainerList		UE-CapabilityRAT-ContainerList		OPTIONAL,
+	measConfig							MeasConfig							OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { CUtoDURRCInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+CUtoDURRCInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-HandoverPreparationInformation	CRITICALITY ignore	EXTENSION HandoverPreparationInformation		PRESENCE optional }|
+	{ ID id-CellGroupConfig					CRITICALITY ignore	EXTENSION CellGroupConfig							PRESENCE optional }|
+	{ ID id-MeasurementTimingConfiguration	CRITICALITY ignore	EXTENSION MeasurementTimingConfiguration		PRESENCE optional }|
+	{ ID id-UEAssistanceInformation			CRITICALITY ignore	EXTENSION UEAssistanceInformation					PRESENCE optional }|
+	{ ID id-CG-Config						CRITICALITY ignore	EXTENSION CG-Config									PRESENCE optional }|
+	{ ID id-UEAssistanceInformationEUTRA	CRITICALITY ignore	EXTENSION UEAssistanceInformationEUTRA			PRESENCE optional },
+	...
+}
+
+-- D
+
+DCBasedDuplicationConfigured::= ENUMERATED{true,..., false}
+
+Dedicated-SIDelivery-NeededUE-Item ::= SEQUENCE {
+	gNB-CU-UE-F1AP-ID						GNB-CU-UE-F1AP-ID,
+	nRCGI									NRCGI,
+	iE-Extensions							ProtocolExtensionContainer { { DedicatedSIDeliveryNeededUE-Item-ExtIEs} } OPTIONAL,
+	...
+}
+
+DedicatedSIDeliveryNeededUE-Item-ExtIEs F1AP-PROTOCOL-EXTENSION::={
+	...
+}
+
+
+DL-PRS ::= SEQUENCE {
+	prsid 					INTEGER (0..255),
+	dl-PRSResourceSetID		PRS-Resource-Set-ID,
+	dl-PRSResourceID		PRS-Resource-ID	OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { {DL-PRS-ExtIEs} }	OPTIONAL
+}
+
+DL-PRS-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DL-PRSMutingPattern ::= CHOICE {
+	two					BIT STRING (SIZE(2)),
+	four				BIT STRING (SIZE(4)),
+	six					BIT STRING (SIZE(6)),
+	eight				BIT STRING (SIZE(8)),
+	sixteen				BIT STRING (SIZE(16)),
+	thirty-two			BIT STRING (SIZE(32)),
+	choice-extension							ProtocolIE-SingleContainer { { DL-PRSMutingPattern-ExtIEs } }
+}
+
+DL-PRSMutingPattern-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+DLPRSResourceCoordinates ::= SEQUENCE {
+	listofDL-PRSResourceSetARP		SEQUENCE (SIZE(1.. maxnoofPRS-ResourceSets)) OF DLPRSResourceSetARP,
+	iE-Extensions					ProtocolExtensionContainer { { DLPRSResourceCoordinates-ExtIEs } } OPTIONAL
+}
+
+DLPRSResourceCoordinates-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DLPRSResourceSetARP ::= SEQUENCE {
+	dl-PRSResourceSetID				INTEGER (0..7),
+	dL-PRSResourceSetARPLocation	DL-PRSResourceSetARPLocation,
+	listofDL-PRSResourceARP			SEQUENCE (SIZE(1.. maxnoofPRS-ResourcesPerSet)) OF DLPRSResourceARP,
+	iE-Extensions					ProtocolExtensionContainer { { DLPRSResourceSetARP-ExtIEs } } OPTIONAL
+}
+
+DLPRSResourceSetARP-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+DL-PRSResourceSetARPLocation ::= CHOICE {
+	relativeGeodeticLocation			RelativeGeodeticLocation,
+	relativeCartesianLocation			RelativeCartesianLocation,
+	choice-Extension					ProtocolIE-SingleContainer { { DL-PRSResourceSetARPLocation-ExtIEs } }
+}
+
+DL-PRSResourceSetARPLocation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+
+DLPRSResourceARP ::= SEQUENCE {
+	dl-PRSResourceID			INTEGER (0..63),
+	dL-PRSResourceARPLocation	DL-PRSResourceARPLocation,	
+	iE-Extensions				ProtocolExtensionContainer { { DLPRSResourceARP-ExtIEs } } OPTIONAL
+}
+
+DLPRSResourceARP-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DL-PRSResourceARPLocation ::= CHOICE {
+	relativeGeodeticLocation			RelativeGeodeticLocation,
+	relativeCartesianLocation			RelativeCartesianLocation,
+	choice-Extension					ProtocolIE-SingleContainer { { DL-PRSResourceARPLocation-ExtIEs } }
+}
+
+DL-PRSResourceARPLocation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+DL-UP-TNL-Address-to-Update-List-Item	::= SEQUENCE {
+	oldIPAdress						TransportLayerAddress,
+	newIPAdress						TransportLayerAddress,
+	iE-Extensions	ProtocolExtensionContainer { { DL-UP-TNL-Address-to-Update-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DL-UP-TNL-Address-to-Update-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DLUPTNLInformation-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDLUPTNLInformation)) OF DLUPTNLInformation-ToBeSetup-Item
+
+DLUPTNLInformation-ToBeSetup-Item ::= SEQUENCE {
+	dLUPTNLInformation	UPTransportLayerInformation	,
+	iE-Extensions	ProtocolExtensionContainer { { DLUPTNLInformation-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DLUPTNLInformation-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRB-Activity-Item ::= SEQUENCE {
+	dRBID			DRBID,
+	dRB-Activity	DRB-Activity		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRB-Activity-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRB-Activity-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRB-Activity ::= ENUMERATED {active, not-active}
+
+DRBID ::= INTEGER (1..32, ...)
+
+DRBs-FailedToBeModified-Item	::= SEQUENCE {
+	dRBID		DRBID		,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeModified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-FailedToBeSetup-Item	::= SEQUENCE {
+	dRBID	DRBID,
+	cause	Cause	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+DRBs-FailedToBeSetupMod-Item	::= SEQUENCE {
+	dRBID		DRBID	,
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRB-Information	::=	SEQUENCE {
+	dRB-QoS		QoSFlowLevelQoSParameters, 
+	sNSSAI		SNSSAI, 
+	notificationControl		NotificationControl		OPTIONAL,
+	flows-Mapped-To-DRB-List	Flows-Mapped-To-DRB-List,
+	iE-Extensions	ProtocolExtensionContainer { { DRB-Information-ItemExtIEs } }	OPTIONAL
+}
+
+DRB-Information-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-Modified-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	lCID								LCID		OPTIONAL,
+	dLUPTNLInformation-ToBeSetup-List		DLUPTNLInformation-ToBeSetup-List,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Modified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Modified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-RLC-Status							CRITICALITY ignore	EXTENSION RLC-Status									PRESENCE optional }|
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List		PRESENCE optional },
+	...
+}
+
+DRBs-ModifiedConf-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	uLUPTNLInformation-ToBeSetup-List		ULUPTNLInformation-ToBeSetup-List	,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ModifiedConf-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ModifiedConf-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List			PRESENCE optional },
+	...
+}
+
+DRB-Notify-Item ::= SEQUENCE {
+	dRBID			DRBID,
+	notification-Cause	Notification-Cause,
+	iE-Extensions	ProtocolExtensionContainer { { DRB-Notify-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRB-Notify-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-CurrentQoSParaSetIndex	CRITICALITY ignore	EXTENSION QoSParaSetNotifyIndex	PRESENCE optional	},
+	...
+}
+
+DRBs-Required-ToBeModified-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	dLUPTNLInformation-ToBeSetup-List		DLUPTNLInformation-ToBeSetup-List	,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Required-ToBeModified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Required-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-RLC-Status			CRITICALITY ignore			EXTENSION RLC-Status				PRESENCE optional }|
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List			PRESENCE optional },
+	...
+}
+
+DRBs-Required-ToBeReleased-Item	::= SEQUENCE {
+	dRBID		DRBID,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Required-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Required-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-Setup-Item ::= SEQUENCE {
+	dRBID							DRBID,
+	lCID								LCID		OPTIONAL,
+	dLUPTNLInformation-ToBeSetup-List		DLUPTNLInformation-ToBeSetup-List	, 
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Setup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Setup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List			PRESENCE optional }|
+	{ ID id-RLCDuplicationInformation			CRITICALITY ignore	EXTENSION RLCDuplicationInformation						PRESENCE optional},	...
+}
+
+DRBs-SetupMod-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	lCID								LCID		OPTIONAL,
+	dLUPTNLInformation-ToBeSetup-List		DLUPTNLInformation-ToBeSetup-List	,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-SetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-SetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List			PRESENCE optional },
+	...
+}
+
+
+DRBs-ToBeModified-Item	::= SEQUENCE {
+	dRBID						DRBID,
+	qoSInformation				QoSInformation	OPTIONAL,
+	uLUPTNLInformation-ToBeSetup-List	ULUPTNLInformation-ToBeSetup-List	, 
+	uLConfiguration				ULConfiguration	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeModified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-DLPDCPSNLength						CRITICALITY ignore	EXTENSION PDCPSNLength										PRESENCE optional }|
+	{ ID id-ULPDCPSNLength						CRITICALITY ignore	EXTENSION PDCPSNLength										PRESENCE optional }|
+	{ID id-BearerTypeChange						CRITICALITY ignore	EXTENSION BearerTypeChange									PRESENCE optional}|
+	{ ID id-RLCMode								CRITICALITY ignore	EXTENSION RLCMode											PRESENCE optional }|
+	{ ID id-Duplication-Activation				CRITICALITY reject	EXTENSION DuplicationActivation							PRESENCE optional }|
+	{ ID id-DC-Based-Duplication-Configured		CRITICALITY reject	EXTENSION DCBasedDuplicationConfigured					PRESENCE optional }|
+	{ ID id-DC-Based-Duplication-Activation		CRITICALITY reject	EXTENSION DuplicationActivation							PRESENCE optional }|
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List			PRESENCE optional }|
+	{ ID id-RLCDuplicationInformation			CRITICALITY ignore	EXTENSION RLCDuplicationInformation						PRESENCE optional},
+	...
+}
+
+DRBs-ToBeReleased-Item	::= SEQUENCE {
+	dRBID	DRBID,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-ToBeSetup-Item ::= SEQUENCE	{
+	dRBID						DRBID,
+	qoSInformation				QoSInformation,
+	uLUPTNLInformation-ToBeSetup-List	ULUPTNLInformation-ToBeSetup-List	, 
+	rLCMode						RLCMode, 
+	uLConfiguration				ULConfiguration	OPTIONAL,
+	duplicationActivation		DuplicationActivation	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-DC-Based-Duplication-Configured		CRITICALITY reject	EXTENSION DCBasedDuplicationConfigured				PRESENCE optional }|
+	{ ID id-DC-Based-Duplication-Activation		CRITICALITY reject	EXTENSION DuplicationActivation						PRESENCE optional }|
+	{ ID id-DLPDCPSNLength						CRITICALITY ignore	EXTENSION PDCPSNLength									PRESENCE mandatory }|
+	{ ID id-ULPDCPSNLength						CRITICALITY ignore	EXTENSION PDCPSNLength									PRESENCE optional }|
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List		PRESENCE optional },
+	...
+}
+
+
+DRBs-ToBeSetupMod-Item	::= SEQUENCE {
+	dRBID						DRBID,
+	qoSInformation				QoSInformation,
+	uLUPTNLInformation-ToBeSetup-List		ULUPTNLInformation-ToBeSetup-List,
+	rLCMode						RLCMode, 
+	uLConfiguration				ULConfiguration	OPTIONAL,
+	duplicationActivation		DuplicationActivation	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-DC-Based-Duplication-Configured		CRITICALITY reject	EXTENSION DCBasedDuplicationConfigured				PRESENCE optional }|
+	{ ID id-DC-Based-Duplication-Activation		CRITICALITY reject	EXTENSION DuplicationActivation						PRESENCE optional }|
+	{ ID id-DLPDCPSNLength						CRITICALITY ignore	EXTENSION PDCPSNLength									PRESENCE optional }|
+	{ ID id-ULPDCPSNLength						CRITICALITY ignore	EXTENSION PDCPSNLength									PRESENCE optional }|
+	{ ID id-AdditionalPDCPDuplicationTNL-List	CRITICALITY ignore	EXTENSION AdditionalPDCPDuplicationTNL-List		PRESENCE optional }|
+	{ ID id-RLCDuplicationInformation			CRITICALITY ignore	EXTENSION RLCDuplicationInformation					PRESENCE optional},
+	...
+}
+
+DRXCycle	::= SEQUENCE {
+	longDRXCycleLength	LongDRXCycleLength,
+	shortDRXCycleLength		ShortDRXCycleLength	OPTIONAL,
+	shortDRXCycleTimer	ShortDRXCycleTimer OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { DRXCycle-ExtIEs} } OPTIONAL,
+	...
+}
+
+DRXCycle-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRX-Config ::= OCTET STRING
+
+DRXConfigurationIndicator	::=	ENUMERATED{	release, ...}
+
+DRX-LongCycleStartOffset ::= INTEGER (0..10239)
+
+DSInformationList ::= SEQUENCE (SIZE(0..maxnoofDSInfo)) OF DSCP
+
+DSCP ::= BIT STRING (SIZE (6))
+
+DUtoCURRCContainer ::= OCTET STRING
+
+DUCURadioInformationType ::= CHOICE {
+	rIM								DUCURIMInformation,
+	choice-extension				ProtocolIE-SingleContainer { { DUCURadioInformationType-ExtIEs} }
+}
+
+DUCURadioInformationType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+DUCURIMInformation ::= SEQUENCE {
+	victimgNBSetID				GNBSetID, 
+	rIMRSDetectionStatus		RIMRSDetectionStatus,
+	aggressorCellList			AggressorCellList,
+	iE-Extensions				ProtocolExtensionContainer { { DUCURIMInformation-ExtIEs} }		OPTIONAL 
+}
+
+DUCURIMInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DUF-Slot-Config-Item 	::=	CHOICE {
+	explicitFormat				ExplicitFormat,
+	implicitFormat				ImplicitFormat,
+	choice-extension				ProtocolIE-SingleContainer { { DUF-Slot-Config-Item-ExtIEs} }
+}
+
+DUF-Slot-Config-Item-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+DUF-Slot-Config-List	::= SEQUENCE (SIZE(1..maxnoofDUFSlots)) OF DUF-Slot-Config-Item
+
+DUFSlotformatIndex ::= INTEGER(0..254)
+
+DUFTransmissionPeriodicity ::= ENUMERATED { ms0p5, ms0p625, ms1, ms1p25, ms2, ms2p5, ms5, ms10, ...}
+
+DU-RX-MT-RX ::= ENUMERATED {supported, not-supported}
+
+DU-TX-MT-TX ::= ENUMERATED {supported, not-supported}
+
+DU-RX-MT-TX ::= ENUMERATED {supported, not-supported}
+
+DU-TX-MT-RX ::= ENUMERATED {supported, not-supported}
+
+DUtoCURRCInformation ::= SEQUENCE {
+	cellGroupConfig		CellGroupConfig,
+	measGapConfig			MeasGapConfig	OPTIONAL,
+	requestedP-MaxFR1				OCTET STRING				OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { DUtoCURRCInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+DUtoCURRCInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-DRX-LongCycleStartOffset			CRITICALITY ignore	EXTENSION DRX-LongCycleStartOffset				PRESENCE optional }|
+	{ ID id-SelectedBandCombinationIndex		CRITICALITY ignore	EXTENSION SelectedBandCombinationIndex			PRESENCE optional }|
+	{ ID id-SelectedFeatureSetEntryIndex		CRITICALITY ignore	EXTENSION SelectedFeatureSetEntryIndex			PRESENCE optional }|
+	{ ID id-Ph-InfoSCG							CRITICALITY ignore	EXTENSION Ph-InfoSCG								PRESENCE optional }|
+	{ ID id-RequestedBandCombinationIndex		CRITICALITY ignore	EXTENSION RequestedBandCombinationIndex		PRESENCE optional }|
+	{ ID id-RequestedFeatureSetEntryIndex		CRITICALITY ignore	EXTENSION RequestedFeatureSetEntryIndex		PRESENCE optional }|
+	{ ID id-DRX-Config							CRITICALITY ignore	EXTENSION DRX-Config								PRESENCE optional }|
+	{ ID id-PDCCH-BlindDetectionSCG				CRITICALITY ignore	EXTENSION PDCCH-BlindDetectionSCG				PRESENCE optional }|
+	{ ID id-Requested-PDCCH-BlindDetectionSCG	CRITICALITY ignore	EXTENSION Requested-PDCCH-BlindDetectionSCG	PRESENCE optional }|
+	{ ID id-Ph-InfoMCG							CRITICALITY ignore	EXTENSION Ph-InfoMCG								PRESENCE optional }|
+	{ ID id-MeasGapSharingConfig				CRITICALITY ignore	EXTENSION MeasGapSharingConfig					PRESENCE optional }|
+	{ ID id-SL-PHY-MAC-RLC-Config				CRITICALITY ignore	EXTENSION SL-PHY-MAC-RLC-Config					PRESENCE optional }|
+	{ ID id-SL-ConfigDedicatedEUTRA				CRITICALITY ignore	EXTENSION SL-ConfigDedicatedEUTRA				PRESENCE optional }|
+	{ ID id-RequestedP-MaxFR2					CRITICALITY ignore	EXTENSION RequestedP-MaxFR2							PRESENCE optional },
+	...
+}
+
+DuplicationActivation ::= ENUMERATED{active,inactive,... }
+
+DuplicationIndication ::= ENUMERATED {true, ... , false }
+
+DuplicationState ::= ENUMERATED { 
+	active,
+	inactive,
+	...
+}
+
+Dynamic5QIDescriptor	::= SEQUENCE {
+	qoSPriorityLevel					INTEGER (1..127),
+	packetDelayBudget					PacketDelayBudget,
+	packetErrorRate						PacketErrorRate,
+	fiveQI								INTEGER (0..255, ...)								OPTIONAL,
+	delayCritical						ENUMERATED {delay-critical, non-delay-critical}		OPTIONAL,
+	-- C-ifGBRflow: This IE shall be present if the GBR QoS Flow Information IE is present in the QoS Flow Level QoS Parameters IE.
+	averagingWindow 					AveragingWindow										OPTIONAL,
+	-- C-ifGBRflow: This IE shall be present if the GBR QoS Flow Information IE is present in the QoS Flow Level QoS Parameters IE.
+	maxDataBurstVolume					MaxDataBurstVolume									OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { Dynamic5QIDescriptor-ExtIEs } } OPTIONAL
+}
+
+Dynamic5QIDescriptor-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-ExtendedPacketDelayBudget			CRITICALITY ignore	EXTENSION ExtendedPacketDelayBudget		PRESENCE optional		}|
+	{ ID id-CNPacketDelayBudgetDownlink			CRITICALITY ignore	EXTENSION ExtendedPacketDelayBudget		PRESENCE optional		}|
+	{ ID id-CNPacketDelayBudgetUplink			CRITICALITY ignore	EXTENSION ExtendedPacketDelayBudget		PRESENCE optional		},
+	...
+}
+
+DynamicPQIDescriptor	::= SEQUENCE {
+	resourceType						ENUMERATED {gbr, non-gbr, delay-critical-grb, ...}		OPTIONAL,
+	qoSPriorityLevel					INTEGER (1..8, ...),
+	packetDelayBudget					PacketDelayBudget,
+	packetErrorRate						PacketErrorRate,
+	averagingWindow 					AveragingWindow										OPTIONAL,
+	-- C-ifGBRflow: This IE shall be present if the GBR QoS Flow Information IE is present in the QoS Flow Level QoS Parameters IE.
+	maxDataBurstVolume					MaxDataBurstVolume									OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { DynamicPQIDescriptor-ExtIEs } } OPTIONAL
+}
+
+DynamicPQIDescriptor-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- E
+
+E-CID-MeasurementPeriodicity ::= ENUMERATED {
+	ms120,
+	ms240,
+	ms480,
+	ms640,
+	ms1024,
+	ms2048,
+	ms5120,
+	ms10240,
+	min1,
+	min6,
+	min12,
+	min30,
+	min60,
+	...
+}
+
+E-CID-MeasurementQuantities ::= SEQUENCE (SIZE (1.. maxnoofMeasE-CID)) OF ProtocolIE-SingleContainer { {E-CID-MeasurementQuantities-ItemIEs} }
+
+E-CID-MeasurementQuantities-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-E-CID-MeasurementQuantities-Item	CRITICALITY reject	TYPE E-CID-MeasurementQuantities-Item		PRESENCE mandatory}
+}
+
+E-CID-MeasurementQuantities-Item ::= SEQUENCE {
+	e-CIDmeasurementQuantitiesValue				E-CID-MeasurementQuantitiesValue,
+	iE-Extensions								ProtocolExtensionContainer { { E-CID-MeasurementQuantitiesValue-ExtIEs} } OPTIONAL
+}
+
+E-CID-MeasurementQuantitiesValue-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+E-CID-MeasurementQuantitiesValue ::= ENUMERATED {
+	cell-Portion,
+	angleOfArrivalNR,
+	... 
+}
+
+E-CID-MeasurementResult ::= SEQUENCE {
+	geographicalCoordinates		GeographicalCoordinates 	OPTIONAL,
+	measuredResults-List		E-CID-MeasuredResults-List 	OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { E-CID-MeasurementResult-ExtIEs} } OPTIONAL
+}
+
+E-CID-MeasurementResult-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+E-CID-MeasuredResults-List ::= SEQUENCE (SIZE(1..maxnoofMeasE-CID)) OF E-CID-MeasuredResults-Item
+
+E-CID-MeasuredResults-Item ::= SEQUENCE {
+	e-CID-MeasuredResults-Value 	E-CID-MeasuredResults-Value,
+	iE-Extensions			ProtocolExtensionContainer {{ E-CID-MeasuredResults-Item-ExtIEs }}	 OPTIONAL
+}
+
+E-CID-MeasuredResults-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+E-CID-MeasuredResults-Value ::= CHOICE {
+	valueAngleofArrivalNR	UL-AoA,
+	choice-extension		ProtocolIE-SingleContainer { { E-CID-MeasuredResults-Value-ExtIEs} }
+}
+
+E-CID-MeasuredResults-Value-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+E-CID-ReportCharacteristics ::= ENUMERATED {
+	onDemand,
+	periodic,
+	...
+}
+
+EgressBHRLCCHList ::= SEQUENCE (SIZE(1..maxnoofEgressLinks)) OF EgressBHRLCCHItem
+
+EgressBHRLCCHItem ::= SEQUENCE {
+	nextHopBAPAddress 		BAPAddress,
+	bHRLCChannelID			BHRLCChannelID,
+	iE-Extensions			ProtocolExtensionContainer {{EgressBHRLCCHItemExtIEs }}	 OPTIONAL
+}
+
+EgressBHRLCCHItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Endpoint-IP-address-and-port ::=SEQUENCE {
+	endpointIPAddress TransportLayerAddress,
+	iE-Extensions					ProtocolExtensionContainer { { Endpoint-IP-address-and-port-ExtIEs} } OPTIONAL
+}
+
+Endpoint-IP-address-and-port-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-portNumber	CRITICALITY reject	EXTENSION PortNumber		PRESENCE optional},
+	...
+}
+
+ExtendedAvailablePLMN-List ::= SEQUENCE (SIZE(1..maxnoofExtendedBPLMNs)) OF ExtendedAvailablePLMN-Item
+
+ExtendedAvailablePLMN-Item ::= SEQUENCE {
+	pLMNIdentity			PLMN-Identity,
+	iE-Extensions		ProtocolExtensionContainer { { ExtendedAvailablePLMN-Item-ExtIEs} } OPTIONAL
+}
+
+ExplicitFormat ::=	SEQUENCE {
+	permutation			Permutation,
+	noofDownlinkSymbols	NoofDownlinkSymbols		OPTIONAL,
+	noofUplinkSymbols	NoofUplinkSymbols		OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { ExplicitFormat-ExtIEs} } OPTIONAL
+}
+
+ExplicitFormat-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ExtendedAvailablePLMN-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ExtendedServedPLMNs-List ::= SEQUENCE (SIZE(1.. maxnoofExtendedBPLMNs)) OF ExtendedServedPLMNs-Item
+
+ExtendedServedPLMNs-Item ::= SEQUENCE {
+	pLMN-Identity				PLMN-Identity,
+	tAISliceSupportList 		SliceSupportList	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { ExtendedServedPLMNs-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+ExtendedServedPLMNs-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-NPNSupportInfo			CRITICALITY reject	EXTENSION NPNSupportInfo				PRESENCE optional	}|
+{ ID id-ExtendedTAISliceSupportList	CRITICALITY reject	EXTENSION ExtendedSliceSupportList		PRESENCE optional	},
+	...
+}
+
+ExtendedSliceSupportList ::= SEQUENCE (SIZE(1.. maxnoofExtSliceItems)) OF SliceSupportItem
+
+EUTRACells-List  ::= SEQUENCE (SIZE (1.. maxCellineNB)) OF EUTRACells-List-item
+
+EUTRACells-List-item ::= SEQUENCE {
+	eUTRA-Cell-ID					EUTRA-Cell-ID,
+	served-EUTRA-Cells-Information	Served-EUTRA-Cells-Information,
+	iE-Extensions ProtocolExtensionContainer { { EUTRACells-List-itemExtIEs } }    OPTIONAL
+}
+
+EUTRACells-List-itemExtIEs    F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+EUTRA-Cell-ID ::= BIT STRING (SIZE(28))
+
+EUTRA-Coex-FDD-Info ::= SEQUENCE {
+	uL-EARFCN						ExtendedEARFCN					OPTIONAL,
+	dL-EARFCN						ExtendedEARFCN,
+	uL-Transmission-Bandwidth		EUTRA-Transmission-Bandwidth	OPTIONAL,
+	dL-Transmission-Bandwidth		EUTRA-Transmission-Bandwidth,
+	iE-Extensions					ProtocolExtensionContainer { {EUTRA-Coex-FDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+EUTRA-Coex-FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-ULCarrierList				CRITICALITY ignore	EXTENSION NRCarrierList				PRESENCE optional }|
+	{	ID id-DLCarrierList				CRITICALITY ignore EXTENSION NRCarrierList				PRESENCE optional },
+	...
+}
+
+EUTRA-Coex-Mode-Info ::= CHOICE {
+	fDD		EUTRA-Coex-FDD-Info,
+	tDD		EUTRA-Coex-TDD-Info,
+	...
+}
+
+EUTRA-Coex-TDD-Info ::= SEQUENCE {
+	eARFCN							ExtendedEARFCN,
+	transmission-Bandwidth			EUTRA-Transmission-Bandwidth,
+	subframeAssignment				EUTRA-SubframeAssignment,
+	specialSubframe-Info			EUTRA-SpecialSubframe-Info,
+	iE-Extensions					ProtocolExtensionContainer { {EUTRA-Coex-TDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+EUTRA-Coex-TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+EUTRA-CyclicPrefixDL ::= ENUMERATED { 
+	normal,
+	extended,
+	...
+}
+
+EUTRA-CyclicPrefixUL ::= ENUMERATED { 
+	normal,
+	extended,
+	...
+}
+
+EUTRA-PRACH-Configuration ::= SEQUENCE {
+	rootSequenceIndex						INTEGER (0..837),
+	zeroCorrelationIndex					INTEGER (0..15),
+	highSpeedFlag							BOOLEAN,
+	prach-FreqOffset						INTEGER (0..94),
+	prach-ConfigIndex						INTEGER (0..63)		OPTIONAL,
+	-- C-ifTDD: This IE shall be present if the EUTRA-Mode-Info IE in the Resource Coordination E-UTRA Cell Information IE is set to the value "TDD"
+	iE-Extensions							ProtocolExtensionContainer { {EUTRA-PRACH-Configuration-ExtIEs} }	OPTIONAL,
+	...
+}
+
+EUTRA-PRACH-Configuration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+EUTRA-SpecialSubframe-Info ::= SEQUENCE {
+	specialSubframePatterns		EUTRA-SpecialSubframePatterns,
+	cyclicPrefixDL				EUTRA-CyclicPrefixDL,
+	cyclicPrefixUL				EUTRA-CyclicPrefixUL,
+	iE-Extensions				ProtocolExtensionContainer { { EUTRA-SpecialSubframe-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+EUTRA-SpecialSubframe-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+EUTRA-SpecialSubframePatterns ::= ENUMERATED { 
+	ssp0,
+	ssp1, 
+	ssp2,
+	ssp3,
+	ssp4,
+	ssp5,
+	ssp6,
+	ssp7,
+	ssp8,
+	ssp9,
+	ssp10,
+	...
+}
+
+EUTRA-SubframeAssignment ::= ENUMERATED { 
+	sa0,
+	sa1, 
+	sa2,
+	sa3,
+	sa4,
+	sa5,
+	sa6,
+	...
+}
+
+EUTRA-Transmission-Bandwidth ::= ENUMERATED {
+	bw6,
+	bw15,
+	bw25,
+	bw50,
+	bw75,
+	bw100,
+	...
+}
+
+EUTRANQoS	::= SEQUENCE {
+	qCI								QCI,
+	allocationAndRetentionPriority	AllocationAndRetentionPriority,
+	gbrQosInformation				GBR-QosInformation									OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { EUTRANQoS-ExtIEs} }	OPTIONAL,
+	...
+}
+
+EUTRANQoS-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ExecuteDuplication ::= ENUMERATED{true,...}
+
+ExtendedEARFCN ::= INTEGER (0..262143)
+
+EUTRA-Mode-Info ::= CHOICE {
+	eUTRAFDD		EUTRA-FDD-Info,
+	eUTRATDD		EUTRA-TDD-Info,
+	choice-extension	ProtocolIE-SingleContainer { { EUTRA-Mode-Info-ExtIEs} }
+}
+
+EUTRA-Mode-Info-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+EUTRA-NR-CellResourceCoordinationReq-Container	::= OCTET STRING
+
+EUTRA-NR-CellResourceCoordinationReqAck-Container	::= OCTET STRING
+
+EUTRA-FDD-Info ::= SEQUENCE {
+	uL-offsetToPointA				OffsetToPointA,
+	dL-offsetToPointA				OffsetToPointA,
+	iE-Extensions					ProtocolExtensionContainer { {EUTRA-FDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+EUTRA-FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+EUTRA-TDD-Info ::= SEQUENCE {
+	offsetToPointA					OffsetToPointA,
+	iE-Extensions					ProtocolExtensionContainer { {EUTRA-TDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+EUTRA-TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+EventType ::= ENUMERATED {
+	on-demand,
+	periodic,
+	stop,
+	...
+}
+
+ExtendedPacketDelayBudget ::= INTEGER (1..65535, ...)
+
+-- F
+
+FDD-Info ::= SEQUENCE {
+	uL-NRFreqInfo						NRFreqInfo,
+	dL-NRFreqInfo						NRFreqInfo,
+	uL-Transmission-Bandwidth		Transmission-Bandwidth,
+	dL-Transmission-Bandwidth		Transmission-Bandwidth,
+	iE-Extensions					ProtocolExtensionContainer { {FDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+Flows-Mapped-To-DRB-List	::=	SEQUENCE (SIZE(1.. maxnoofQoSFlows)) OF Flows-Mapped-To-DRB-Item
+
+Flows-Mapped-To-DRB-Item 	::= SEQUENCE {
+	qoSFlowIdentifier							QoSFlowIdentifier,
+	qoSFlowLevelQoSParameters				QoSFlowLevelQoSParameters,
+	iE-Extensions							ProtocolExtensionContainer { { Flows-Mapped-To-DRB-ItemExtIEs} } OPTIONAL
+}
+
+Flows-Mapped-To-DRB-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-QoSFlowMappingIndication		CRITICALITY ignore	EXTENSION QoSFlowMappingIndication			PRESENCE optional}|
+	{ID id-TSCTrafficCharacteristics	CRITICALITY ignore	EXTENSION TSCTrafficCharacteristics			PRESENCE optional},
+	...
+}
+
+FR1-Bandwidth ::= ENUMERATED {bw5, bw10, bw20, bw40, bw50, bw80, bw100, ...}
+
+FR2-Bandwidth ::= ENUMERATED {bw50, bw100, bw200, bw400, ...}
+
+FreqBandNrItem ::= SEQUENCE {
+	freqBandIndicatorNr 		INTEGER (1..1024,...), 
+	supportedSULBandList		SEQUENCE (SIZE(0..maxnoofNrCellBands)) OF SupportedSULFreqBandItem,
+	iE-Extensions				ProtocolExtensionContainer { {FreqBandNrItem-ExtIEs} } OPTIONAL,
+	...
+}
+
+FreqBandNrItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+FreqDomainLength ::= CHOICE {
+	l839							L839Info,
+	l139							L139Info,
+	choice-extension				ProtocolIE-SingleContainer { {FreqDomainLength-ExtIEs} }
+}
+
+FreqDomainLength-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+FrequencyShift7p5khz ::= ENUMERATED {false, true, ...}
+
+FullConfiguration ::= ENUMERATED {full, ...}
+
+FlowsMappedToSLDRB-List ::= SEQUENCE (SIZE(1.. maxnoofPC5QoSFlows)) OF FlowsMappedToSLDRB-Item 
+
+FlowsMappedToSLDRB-Item ::= SEQUENCE {
+	pc5QoSFlowIdentifier			PC5QoSFlowIdentifier,
+	iE-Extensions					ProtocolExtensionContainer { {FlowsMappedToSLDRB-Item-ExtIEs} } OPTIONAL,
+	...
+}
+
+FlowsMappedToSLDRB-Item-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- G
+
+
+GBR-QosInformation ::= SEQUENCE {
+	e-RAB-MaximumBitrateDL			BitRate,
+	e-RAB-MaximumBitrateUL			BitRate,
+	e-RAB-GuaranteedBitrateDL		BitRate,
+	e-RAB-GuaranteedBitrateUL		BitRate,
+	iE-Extensions					ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+GBR-QosInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GBR-QoSFlowInformation::= SEQUENCE {
+	maxFlowBitRateDownlink			BitRate,
+	maxFlowBitRateUplink			BitRate, 
+	guaranteedFlowBitRateDownlink	BitRate,
+	guaranteedFlowBitRateUplink		BitRate, 
+	maxPacketLossRateDownlink		MaxPacketLossRate		OPTIONAL,
+	maxPacketLossRateUplink			MaxPacketLossRate		OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { GBR-QosFlowInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+GBR-QosFlowInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ 	ID id-AlternativeQoSParaSetList	CRITICALITY ignore	EXTENSION AlternativeQoSParaSetList	PRESENCE optional	},
+	...
+}
+
+CG-Config ::= OCTET STRING
+
+GeographicalCoordinates ::= SEQUENCE {
+	tRPPositionDefinitionType	TRPPositionDefinitionType,
+	dLPRSResourceCoordinates	DLPRSResourceCoordinates	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { GeographicalCoordinates-ExtIEs } } OPTIONAL
+}
+
+GeographicalCoordinates-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNBCUMeasurementID ::= INTEGER (0.. 4095, ...)
+
+GNBDUMeasurementID ::= INTEGER (0.. 4095, ...)
+
+GNB-CUSystemInformation::= SEQUENCE {
+	sibtypetobeupdatedlist	SEQUENCE (SIZE(1.. maxnoofSIBTypes)) OF SibtypetobeupdatedListItem,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CUSystemInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+GNB-CUSystemInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-systemInformationAreaID  CRITICALITY ignore	EXTENSION SystemInformationAreaID PRESENCE optional},
+	...
+}
+
+GNB-CU-TNL-Association-Setup-Item::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CU-TNL-Association-Setup-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-Setup-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-CU-TNL-Association-Failed-To-Setup-Item ::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	cause									Cause,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CU-TNL-Association-Failed-To-Setup-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-Failed-To-Setup-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+GNB-CU-TNL-Association-To-Add-Item ::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	tNLAssociationUsage							TNLAssociationUsage,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CU-TNL-Association-To-Add-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-To-Add-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-CU-TNL-Association-To-Remove-Item::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	iE-Extensions							ProtocolExtensionContainer { { GNB-CU-TNL-Association-To-Remove-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-To-Remove-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-TNLAssociationTransportLayerAddressgNBDU	CRITICALITY reject	EXTENSION CP-TransportLayerAddress	PRESENCE optional},
+	...
+}
+
+
+GNB-CU-TNL-Association-To-Update-Item::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	tNLAssociationUsage						TNLAssociationUsage OPTIONAL,
+	iE-Extensions							ProtocolExtensionContainer { { GNB-CU-TNL-Association-To-Update-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-To-Update-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-CU-UE-F1AP-ID		::= INTEGER (0..4294967295)
+
+GNB-DU-Cell-Resource-Configuration	::= SEQUENCE { 
+	subcarrierSpacing				SubcarrierSpacing,
+	dUFTransmissionPeriodicity		DUFTransmissionPeriodicity	OPTIONAL,
+	dUF-Slot-Config-List			DUF-Slot-Config-List	OPTIONAL,
+	hSNATransmissionPeriodicity		HSNATransmissionPeriodicity,
+	hNSASlotConfigList				HSNASlotConfigList	OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-DU-Cell-Resource-Configuration-ExtIEs } } OPTIONAL
+}
+
+GNB-DU-Cell-Resource-Configuration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-DU-UE-F1AP-ID		::= INTEGER (0..4294967295)
+
+GNB-DU-ID			::= INTEGER (0..68719476735)
+
+GNB-CU-Name ::= PrintableString(SIZE(1..150,...))
+
+GNB-DU-Name ::= PrintableString(SIZE(1..150,...)) 
+
+Extended-GNB-CU-Name	 ::= SEQUENCE {
+	gNB-CU-NameVisibleString		GNB-CU-NameVisibleString					OPTIONAL,
+	gNB-CU-NameUTF8String			GNB-CU-NameUTF8String						OPTIONAL, 
+	iE-Extensions					ProtocolExtensionContainer { { Extended-GNB-CU-Name-ExtIEs } } OPTIONAL,
+	...
+}
+
+Extended-GNB-CU-Name-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-CU-NameVisibleString ::= VisibleString(SIZE(1..150,...))
+
+GNB-CU-NameUTF8String ::= UTF8String(SIZE(1..150,...))
+
+Extended-GNB-DU-Name	 ::= SEQUENCE {
+	gNB-DU-NameVisibleString		GNB-DU-NameVisibleString					OPTIONAL,
+	gNB-DU-NameUTF8String			GNB-DU-NameUTF8String						OPTIONAL, 
+	iE-Extensions					ProtocolExtensionContainer { { Extended-GNB-DU-Name-ExtIEs } } OPTIONAL,
+	...
+}
+
+Extended-GNB-DU-Name-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-DU-NameVisibleString ::= VisibleString(SIZE(1..150,...))
+
+GNB-DU-NameUTF8String ::= UTF8String(SIZE(1..150,...))
+
+
+GNB-DU-Served-Cells-Item ::= SEQUENCE {
+	served-Cell-Information		Served-Cell-Information,
+	gNB-DU-System-Information	GNB-DU-System-Information	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { GNB-DU-Served-Cells-ItemExtIEs} }	OPTIONAL,
+	...
+}
+
+GNB-DU-Served-Cells-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-DU-System-Information ::= SEQUENCE {
+	mIB-message		MIB-message,
+	sIB1-message		SIB1-message,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-DU-System-Information-ExtIEs } } OPTIONAL,
+	...
+}
+
+GNB-DU-System-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-SIB12-message		CRITICALITY ignore	EXTENSION SIB12-message		PRESENCE optional}|
+	{ ID id-SIB13-message		CRITICALITY ignore	EXTENSION SIB13-message		PRESENCE optional}|
+	{ ID id-SIB14-message		CRITICALITY ignore	EXTENSION SIB14-message		PRESENCE optional}|
+	{ ID id-SIB10-message		CRITICALITY ignore	EXTENSION SIB10-message		PRESENCE optional},
+	...
+}
+
+GNB-DUConfigurationQuery ::= ENUMERATED {true, ...}
+
+GNBDUOverloadInformation ::= ENUMERATED {overloaded, not-overloaded}
+
+GNB-DU-TNL-Association-To-Remove-Item::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	tNLAssociationTransportLayerAddressgNBCU		CP-TransportLayerAddress		OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-DU-TNL-Association-To-Remove-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-DU-TNL-Association-To-Remove-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-RxTxTimeDiff ::= SEQUENCE {
+	rxTxTimeDiff			GNBRxTxTimeDiffMeas,
+	additionalPath-List		AdditionalPath-List		OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { { GNB-RxTxTimeDiff-ExtIEs} }  OPTIONAL
+}
+
+GNB-RxTxTimeDiff-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+
+	...
+}
+
+GNBRxTxTimeDiffMeas ::= CHOICE {
+	k0			INTEGER (0.. 1970049),
+	k1			INTEGER (0.. 985025),
+	k2			INTEGER (0.. 492513),
+	k3			INTEGER (0.. 246257),
+	k4			INTEGER (0.. 123129),
+	k5			INTEGER (0.. 61565),
+	choice-extension		ProtocolIE-SingleContainer { { GNBRxTxTimeDiffMeas-ExtIEs } } 
+}
+
+GNBRxTxTimeDiffMeas-ExtIEs		F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+GNBSetID ::= BIT STRING (SIZE(22))
+
+GTP-TEID				::= OCTET STRING (SIZE (4))
+
+GTPTLAs	::= SEQUENCE (SIZE(1.. maxnoofGTPTLAs)) OF	GTPTLA-Item
+
+
+GTPTLA-Item	::= SEQUENCE {
+	gTPTransportLayerAddress				TransportLayerAddress,
+	iE-Extensions	ProtocolExtensionContainer { { GTPTLA-Item-ExtIEs } }			OPTIONAL
+}
+
+GTPTLA-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GTPTunnel				::= SEQUENCE {
+	transportLayerAddress		TransportLayerAddress,
+	gTP-TEID		GTP-TEID,
+	iE-Extensions					ProtocolExtensionContainer { { GTPTunnel-ExtIEs } } OPTIONAL,
+	...
+}
+
+GTPTunnel-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- H
+
+HandoverPreparationInformation ::= OCTET STRING
+
+HardwareLoadIndicator ::= SEQUENCE {
+	dLHardwareLoadIndicator			INTEGER (0..100, ...),
+	uLHardwareLoadIndicator			INTEGER (0..100, ...),
+	iE-Extensions					ProtocolExtensionContainer { { HardwareLoadIndicator-ExtIEs } } 	OPTIONAL,
+	...
+}
+
+HardwareLoadIndicator-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+HSNASlotConfigList ::= SEQUENCE (SIZE(1..maxnoofHSNASlots)) OF HSNASlotConfigItem
+
+HSNASlotConfigItem 	::=	SEQUENCE {
+	hSNADownlink			HSNADownlink 		OPTIONAL,
+	hSNAUplink				HSNAUplink 			OPTIONAL,
+	hSNAFlexible			HSNAFlexible 		OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { { HSNASlotConfigItem-ExtIEs } } OPTIONAL
+}
+
+HSNASlotConfigItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+HSNADownlink ::= ENUMERATED { hard, soft, notavailable }
+
+HSNAFlexible ::= ENUMERATED { hard, soft, notavailable }
+
+HSNAUplink ::= ENUMERATED { hard, soft, notavailable }
+
+HSNATransmissionPeriodicity ::=	ENUMERATED { ms0p5, ms0p625, ms1, ms1p25, ms2, ms2p5, ms5, ms10, ms20, ms40, ms80, ms160, ...}
+
+-- I
+
+IAB-Barred	::=	ENUMERATED {barred, not-barred, ...}
+
+IAB-Info-IAB-donor-CU ::=	SEQUENCE{
+	iAB-STC-Info	IAB-STC-Info	OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { IAB-Info-IAB-donor-CU-ExtIEs } } OPTIONAL
+}
+
+IAB-Info-IAB-donor-CU-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-Info-IAB-DU ::=	SEQUENCE{
+	multiplexingInfo		MultiplexingInfo	OPTIONAL,
+	iAB-STC-Info		IAB-STC-Info	OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { IAB-Info-IAB-DU-ExtIEs } } OPTIONAL
+}
+
+IAB-Info-IAB-DU-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-MT-Cell-List ::= SEQUENCE (SIZE(1..maxnoofServingCells)) OF IAB-MT-Cell-List-Item
+
+IAB-MT-Cell-List-Item ::= 	SEQUENCE {
+	nRCellIdentity				NRCellIdentity,
+	dU-RX-MT-RX					DU-RX-MT-RX,
+	dU-TX-MT-TX					DU-TX-MT-TX,
+	dU-RX-MT-TX					DU-RX-MT-TX,
+	dU-TX-MT-RX					DU-TX-MT-RX,
+	iE-Extensions				ProtocolExtensionContainer { { IAB-MT-Cell-List-Item-ExtIEs } } OPTIONAL
+}
+
+IAB-MT-Cell-List-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-STC-Info	::=	SEQUENCE{
+	iAB-STC-Info-List	IAB-STC-Info-List,
+	iE-Extensions		ProtocolExtensionContainer { { IAB-STC-Info-ExtIEs } } OPTIONAL
+}
+
+IAB-STC-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-STC-Info-List ::= 	SEQUENCE (SIZE(1..maxnoofIABSTCInfo)) OF IAB-STC-Info-Item
+
+IAB-STC-Info-Item::=	SEQUENCE {
+	sSB-freqInfo						SSB-freqInfo,
+	sSB-subcarrierSpacing				SSB-subcarrierSpacing,
+	sSB-transmissionPeriodicity			SSB-transmissionPeriodicity,
+	sSB-transmissionTimingOffset		SSB-transmissionTimingOffset,
+	sSB-transmissionBitmap				SSB-transmissionBitmap,
+	iE-Extensions		ProtocolExtensionContainer { { IAB-STC-Info-Item-ExtIEs } } OPTIONAL
+}
+
+IAB-STC-Info-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-Allocated-TNL-Address-Item	::= SEQUENCE {
+	iABTNLAddress				IABTNLAddress,
+	iABTNLAddressUsage			IABTNLAddressUsage	 	OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { IAB-Allocated-TNL-Address-Item-ExtIEs } } OPTIONAL
+}
+
+IAB-Allocated-TNL-Address-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-DU-Cell-Resource-Configuration-Mode-Info	::=	CHOICE {
+	fDD		IAB-DU-Cell-Resource-Configuration-FDD-Info,
+	tDD		IAB-DU-Cell-Resource-Configuration-TDD-Info,
+	choice-extension			ProtocolIE-SingleContainer { { IAB-DU-Cell-Resource-Configuration-Mode-Info-ExtIEs} }
+}
+
+IAB-DU-Cell-Resource-Configuration-Mode-Info-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+IAB-DU-Cell-Resource-Configuration-FDD-Info ::= SEQUENCE {
+	gNB-DU-Cell-Resource-Configuration-FDD-UL				GNB-DU-Cell-Resource-Configuration,
+	gNB-DU-Cell-Resource-Configuration-FDD-DL				GNB-DU-Cell-Resource-Configuration,
+	iE-Extensions					ProtocolExtensionContainer { {IAB-DU-Cell-Resource-Configuration-FDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+IAB-DU-Cell-Resource-Configuration-FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-DU-Cell-Resource-Configuration-TDD-Info ::= SEQUENCE {
+	gNB-DU-Cell-Resourc-Configuration-TDD				GNB-DU-Cell-Resource-Configuration,
+	iE-Extensions					ProtocolExtensionContainer { {IAB-DU-Cell-Resource-Configuration-TDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+IAB-DU-Cell-Resource-Configuration-TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IABIPv6RequestType	 ::= CHOICE {
+	iPv6Address						IABTNLAddressesRequested,
+	iPv6Prefix						IABTNLAddressesRequested, 
+	choice-extension				ProtocolIE-SingleContainer { { IABIPv6RequestType-ExtIEs} }
+}
+
+IABIPv6RequestType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+IABTNLAddress ::= CHOICE {
+	iPv4Address						BIT STRING (SIZE(32)), 
+	iPv6Address						BIT STRING (SIZE(128)), 
+	iPv6Prefix						BIT STRING (SIZE(64)), 
+	choice-extension				ProtocolIE-SingleContainer { { IABTNLAddress-ExtIEs} }
+}
+
+IABTNLAddress-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+IABTNLAddressesRequested ::= SEQUENCE {
+	tNLAddressesOrPrefixesRequestedAllTraffic	INTEGER (1..256) 	OPTIONAL,
+	tNLAddressesOrPrefixesRequestedF1-C			INTEGER (1..256) 	OPTIONAL,
+	tNLAddressesOrPrefixesRequestedF1-U			INTEGER (1..256) 	OPTIONAL,
+	tNLAddressesOrPrefixesRequestedNoNF1		INTEGER (1..256) 	OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { IABTNLAddressesRequested-ExtIEs } } OPTIONAL
+}
+
+IABTNLAddressesRequested-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IAB-TNL-Addresses-To-Remove-Item ::= SEQUENCE {
+	iABTNLAddress			IABTNLAddress,
+	iE-Extensions		ProtocolExtensionContainer { { IAB-TNL-Addresses-To-Remove-Item-ExtIEs} } OPTIONAL
+}
+
+IAB-TNL-Addresses-To-Remove-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IABTNLAddressUsage ::= ENUMERATED {
+	f1-c,
+	f1-u,
+	non-f1,
+	...
+}
+
+
+IABv4AddressesRequested ::= SEQUENCE {
+	iABv4AddressesRequested			IABTNLAddressesRequested,
+	iE-Extensions		ProtocolExtensionContainer { { IABv4AddressesRequested-ExtIEs} } OPTIONAL
+}
+
+IABv4AddressesRequested-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ImplicitFormat	::= SEQUENCE	{ 
+	dUFSlotformatIndex 			DUFSlotformatIndex,
+	iE-Extensions		ProtocolExtensionContainer { { ImplicitFormat-ExtIEs } } OPTIONAL
+}
+
+ImplicitFormat-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IgnorePRACHConfiguration::= ENUMERATED { true,...}
+
+IgnoreResourceCoordinationContainer ::= ENUMERATED { yes,...}
+InactivityMonitoringRequest ::= ENUMERATED { true,...}
+InactivityMonitoringResponse ::= ENUMERATED { not-supported,...}
+InterfacesToTrace ::= BIT STRING (SIZE(8))
+
+IntendedTDD-DL-ULConfig ::= SEQUENCE {
+	nRSCS						ENUMERATED { scs15, scs30, scs60, scs120,...},
+	nRCP						ENUMERATED { normal, extended,...},
+	nRDLULTxPeriodicity			ENUMERATED { ms0p5, ms0p625, ms1, ms1p25, ms2, ms2p5, ms3, ms4, ms5, ms10, ms20, ms40, ms60, ms80, ms100, ms120, ms140, ms160, ...},
+	slot-Configuration-List 	Slot-Configuration-List,
+	iE-Extensions						ProtocolExtensionContainer { {IntendedTDD-DL-ULConfig-ExtIEs} } OPTIONAL
+}
+
+IntendedTDD-DL-ULConfig-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IPHeaderInformation ::= SEQUENCE {
+	destinationIABTNLAddress			IABTNLAddress,
+	dsInformationList					DSInformationList	OPTIONAL,
+	iPv6FlowLabel						BIT STRING (SIZE (20))	OPTIONAL,
+	iE-Extensions						ProtocolExtensionContainer { { IPHeaderInformation-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+IPHeaderInformation-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+IPtolayer2TrafficMappingInfo ::= SEQUENCE {
+	iPtolayer2TrafficMappingInfoToAdd					IPtolayer2TrafficMappingInfoList		OPTIONAL,
+	iPtolayer2TrafficMappingInfoToRemove				MappingInformationtoRemove				OPTIONAL,
+	iE-Extensions										ProtocolExtensionContainer { { IPtolayer2TrafficMappingInfo-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+IPtolayer2TrafficMappingInfoList ::= SEQUENCE (SIZE(1..maxnoofMappingEntries)) OF IPtolayer2TrafficMappingInfo-Item
+
+IPtolayer2TrafficMappingInfo-Item ::= SEQUENCE {
+	mappingInformationIndex		MappingInformationIndex,		
+	iPHeaderInformation			IPHeaderInformation,
+	bHInfo	 					BHInfo,	iE-Extensions				ProtocolExtensionContainer { { IPtolayer2TrafficMappingInfo-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+IPtolayer2TrafficMappingInfo-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- J
+
+-- K
+
+-- L
+
+L139Info ::= SEQUENCE {
+	msg1SCS						ENUMERATED {scs15, scs30, scs60, scs120, ...},
+	rootSequenceIndex			INTEGER (0..137)								OPTIONAL,
+	iE-Extension				ProtocolExtensionContainer { {L139Info-ExtIEs} } 		OPTIONAL,
+	...
+}
+
+L139Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+L839Info ::= SEQUENCE {
+	rootSequenceIndex			INTEGER (0..837),
+	restrictedSetConfig			ENUMERATED {unrestrictedSet, restrictedSetTypeA,
+											restrictedSetTypeB, ...},
+	iE-Extension		ProtocolExtensionContainer { {L839Info-ExtIEs} } 		OPTIONAL,
+	...
+}
+
+L839Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+LCID ::= INTEGER (1..32, ...)
+
+
+LCStoGCSTranslationList ::= SEQUENCE (SIZE (1.. maxnooflcs-gcs-translation)) OF LCStoGCSTranslation
+
+LCStoGCSTranslation ::= SEQUENCE {
+	alpha			INTEGER (0..359),
+	alpha-fine		INTEGER (0..9),
+	beta			INTEGER (0..359),
+	beta-fine		INTEGER (0..9),
+	gamma			INTEGER (0..359),
+	gamma-fine		INTEGER (0..9),
+	iE-Extensions				ProtocolExtensionContainer { {LCStoGCSTranslation-ExtIEs} } OPTIONAL
+}
+
+LCStoGCSTranslation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+LMF-MeasurementID ::= INTEGER (1.. 65536, ...)
+
+LMF-UE-MeasurementID ::= INTEGER (1.. 256, ...)
+
+LocationUncertainty ::= SEQUENCE {
+	horizontalUncertainty		INTEGER (0..255),
+	horizontalConfidence		INTEGER (0..100),
+	verticalUncertainty			INTEGER (0..255),
+	verticalConfidence			INTEGER (0..100),
+	iE-Extensions				ProtocolExtensionContainer { { LocationUncertainty-ExtIEs} } OPTIONAL
+}
+
+LocationUncertainty-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+LongDRXCycleLength ::= 	ENUMERATED
+{ms10, ms20, ms32, ms40, ms60, ms64, ms70, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ms1024, ms1280, ms2048, ms2560, ms5120, ms10240, ...}
+
+LowerLayerPresenceStatusChange ::= ENUMERATED {
+	suspend-lower-layers,
+	resume-lower-layers,
+	...
+
+}
+
+LTEUESidelinkAggregateMaximumBitrate ::= SEQUENCE {
+	uELTESidelinkAggregateMaximumBitrate		BitRate,
+	iE-Extensions					ProtocolExtensionContainer { {LTEUESidelinkAggregateMaximumBitrate-ExtIEs} } OPTIONAL
+}
+
+LTEUESidelinkAggregateMaximumBitrate-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+LTEV2XServicesAuthorized ::= SEQUENCE {
+	vehicleUE			VehicleUE														OPTIONAL,
+	pedestrianUE 		PedestrianUE													OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { {LTEV2XServicesAuthorized-ExtIEs} }		OPTIONAL
+}
+
+LTEV2XServicesAuthorized-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- M
+
+MappingInformationIndex	::= BIT STRING (SIZE (26))
+
+MappingInformationtoRemove	::= SEQUENCE (SIZE(1..maxnoofMappingEntries)) OF MappingInformationIndex
+
+MaskedIMEISV ::= 	BIT STRING (SIZE (64))
+
+MaxDataBurstVolume  ::= INTEGER (0..4095, ..., 4096.. 2000000) 
+MaxPacketLossRate ::= INTEGER (0..1000)
+
+MIB-message ::= OCTET STRING
+
+MeasConfig ::= OCTET STRING
+
+MeasGapConfig ::= OCTET STRING
+
+MeasGapSharingConfig ::= OCTET STRING
+
+MeasurementBeamInfoRequest ::= ENUMERATED {true, ...}
+
+MeasurementBeamInfo	 ::= SEQUENCE {
+	pRS-Resource-ID				PRS-Resource-ID		OPTIONAL,
+	pRS-Resource-Set-ID			PRS-Resource-Set-ID	OPTIONAL,
+	sSB-Index					SSB-Index			OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { MeasurementBeamInfo-ExtIEs} } OPTIONAL
+}
+
+MeasurementBeamInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+MeasurementTimingConfiguration ::= OCTET STRING
+
+MessageIdentifier ::= BIT STRING (SIZE (16))
+
+MultiplexingInfo 	::=	SEQUENCE{
+	iAB-MT-Cell-List 	IAB-MT-Cell-List,
+	iE-Extensions		ProtocolExtensionContainer { {MultiplexingInfo-ExtIEs} } OPTIONAL
+}
+
+MultiplexingInfo-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+M2Configuration ::= ENUMERATED {true, ...}
+
+
+M5Configuration ::= SEQUENCE {
+	m5period			M5period,
+	m5-links-to-log		M5-Links-to-log,
+	iE-Extensions		ProtocolExtensionContainer { { M5Configuration-ExtIEs} } OPTIONAL,
+	...
+}
+
+M5Configuration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+M5period ::= ENUMERATED { ms1024, ms2048, ms5120, ms10240, min1, ... } 
+
+M5-Links-to-log	::= ENUMERATED {uplink, downlink, both-uplink-and-downlink, ...}
+
+
+M6Configuration ::= SEQUENCE {
+	m6report-Interval	M6report-Interval,
+	m6-links-to-log		M6-Links-to-log,
+	iE-Extensions		ProtocolExtensionContainer { { M6Configuration-ExtIEs} } OPTIONAL,
+	...
+}
+
+M6Configuration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+M6report-Interval ::= ENUMERATED { ms120, ms240, ms640, ms1024, ms2048, ms5120, ms10240, ms20480, ms40960, min1, min6, min12, min30, ... }
+
+
+
+M6-Links-to-log	::= ENUMERATED {uplink, downlink, both-uplink-and-downlink, ...}
+
+
+M7Configuration ::= SEQUENCE {
+	m7period			M7period,
+	m7-links-to-log		M7-Links-to-log,
+	iE-Extensions		ProtocolExtensionContainer { { M7Configuration-ExtIEs} } OPTIONAL,
+	...
+}
+
+M7Configuration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+M7period	::= INTEGER(1..60, ...)
+
+M7-Links-to-log	::= ENUMERATED {downlink, ...}
+
+MDT-Activation ::= ENUMERATED { 
+	immediate-MDT-only,
+	immediate-MDT-and-Trace,
+	...
+}
+
+MDTConfiguration ::= SEQUENCE {
+	mdt-Activation				MDT-Activation,
+	measurementsToActivate		MeasurementsToActivate,
+	m2Configuration				M2Configuration		OPTIONAL,
+	--  C-ifM2: This IE shall be present if the Measurements to Activate IE has the second bit set to "1".
+	m5Configuration				M5Configuration		OPTIONAL,
+	--  C-ifM5: This IE shall be present if the Measurements to Activate IE has the fifth bit set to "1".
+	m6Configuration				M6Configuration		OPTIONAL,
+	--  C-ifM6: This IE shall be present if the Measurements to Activate IE has the seventh bit set to "1".
+	m7Configuration				M7Configuration		OPTIONAL,
+	--  C-ifM7: This IE shall be present if the Measurements to Activate IE has the eighth bit set to "1".
+	iE-Extensions				ProtocolExtensionContainer { { MDTConfiguration-ExtIEs} } OPTIONAL,
+	...
+}
+MDTConfiguration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+MDTPLMNList ::= SEQUENCE (SIZE(1..maxnoofMDTPLMNs)) OF PLMN-Identity
+
+
+MeasuredResultsValue ::= CHOICE {
+	uL-AngleOfArrival	UL-AoA,
+	uL-SRS-RSRP			UL-SRS-RSRP,
+	uL-RTOA				UL-RTOA-Measurement,
+	gNB-RxTxTimeDiff	GNB-RxTxTimeDiff,
+	choice-extension	ProtocolIE-SingleContainer { { MeasuredResultsValue-ExtIEs } }
+}
+
+MeasuredResultsValue-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+MeasurementsToActivate ::= BIT STRING (SIZE (8))
+
+-- N
+
+NeedforGap::= ENUMERATED {true, ...}
+
+Neighbour-Cell-Information-Item ::= SEQUENCE {
+	nRCGI				NRCGI, 
+	intendedTDD-DL-ULConfig		IntendedTDD-DL-ULConfig OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { Neighbour-Cell-Information-ItemExtIEs } }	OPTIONAL
+}
+
+Neighbour-Cell-Information-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NGRANAllocationAndRetentionPriority ::= SEQUENCE {
+	priorityLevel				PriorityLevel,
+	pre-emptionCapability		Pre-emptionCapability,
+	pre-emptionVulnerability	Pre-emptionVulnerability,
+	iE-Extensions				ProtocolExtensionContainer { {NGRANAllocationAndRetentionPriority-ExtIEs} } OPTIONAL
+}
+
+NGRANAllocationAndRetentionPriority-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+NGRANHighAccuracyAccessPointPosition ::= SEQUENCE {
+	latitude					INTEGER (-2147483648.. 2147483647),
+	longitude					INTEGER (-2147483648.. 2147483647),
+	altitude					INTEGER (-64000..1280000),
+	uncertaintySemi-major		INTEGER (0..255),
+	uncertaintySemi-minor		INTEGER (0..255),
+	orientationOfMajorAxis		INTEGER (0..179),
+	horizontalConfidence		INTEGER (0..100),
+	uncertaintyAltitude			INTEGER (0..255),
+	verticalConfidence			INTEGER (0..100), 
+
+	iE-Extensions				ProtocolExtensionContainer { { NGRANHighAccuracyAccessPointPosition-ExtIEs} } OPTIONAL
+}
+
+NGRANHighAccuracyAccessPointPosition-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NID ::= BIT STRING (SIZE(44))
+
+NR-CGI-List-For-Restart-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	iE-Extensions		ProtocolExtensionContainer { { NR-CGI-List-For-Restart-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+NR-CGI-List-For-Restart-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NR-PRSBeamInformation ::= SEQUENCE {
+	nR-PRSBeamInformationList		NR-PRSBeamInformationList,
+	lCStoGCSTranslationList 		LCStoGCSTranslationList,
+	iE-Extensions	ProtocolExtensionContainer { { NR-PRSBeamInformation-ExtIEs } } OPTIONAL
+}
+
+NR-PRSBeamInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NR-PRSBeamInformationList ::= SEQUENCE (SIZE(1.. maxnoofPRS-ResourceSets)) OF NR-PRSBeamInformationItem
+
+NR-PRSBeamInformationItem ::= SEQUENCE {
+	pRSResourceSetID	INTEGER (0..7),
+	pRSAngleList		PRSAngleList,
+	iE-Extensions	ProtocolExtensionContainer { { NR-PRSBeamInformationItem-ExtIEs } } OPTIONAL
+}
+
+NR-PRSBeamInformationItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NonDynamic5QIDescriptor	::= SEQUENCE {
+	fiveQI						INTEGER (0..255, ...),
+	qoSPriorityLevel			INTEGER (1..127)				OPTIONAL,
+	averagingWindow 			AveragingWindow					OPTIONAL,
+	maxDataBurstVolume			MaxDataBurstVolume				OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { NonDynamic5QIDescriptor-ExtIEs } } OPTIONAL
+}
+
+NonDynamic5QIDescriptor-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-CNPacketDelayBudgetDownlink	CRITICALITY ignore	EXTENSION ExtendedPacketDelayBudget		PRESENCE optional	}|
+	{ ID id-CNPacketDelayBudgetUplink	CRITICALITY ignore	EXTENSION ExtendedPacketDelayBudget		PRESENCE optional	},
+	...
+}
+
+NonDynamicPQIDescriptor	::= SEQUENCE {
+	fiveQI						INTEGER (0..255, ...),
+	qoSPriorityLevel			INTEGER (1..8, ...)				OPTIONAL,
+	averagingWindow 			AveragingWindow					OPTIONAL,
+	maxDataBurstVolume			MaxDataBurstVolume				OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { NonDynamicPQIDescriptor-ExtIEs } } OPTIONAL
+}
+
+NonDynamicPQIDescriptor-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NonUPTrafficType ::=	ENUMERATED {ue-associated, non-ue-associated, non-f1, bap-control-pdu,...}
+
+NoofDownlinkSymbols	::= INTEGER (0..14)
+
+NoofUplinkSymbols	::= INTEGER (0..14)
+
+Notification-Cause ::= ENUMERATED {fulfilled, not-fulfilled, ...}
+
+NotificationControl ::= ENUMERATED {active, not-active, ...}
+
+NotificationInformation ::= SEQUENCE {
+	message-Identifier	MessageIdentifier,
+	serialNumber		SerialNumber,
+	iE-Extensions	ProtocolExtensionContainer { { NotificationInformationExtIEs} } OPTIONAL,
+	...
+}
+
+NotificationInformationExtIEs		F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NPNBroadcastInformation ::= CHOICE {
+	sNPN-Broadcast-Information					NPN-Broadcast-Information-SNPN,
+	pNI-NPN-Broadcast-Information				NPN-Broadcast-Information-PNI-NPN,
+	choice-extension					ProtocolIE-SingleContainer { {NPNBroadcastInformation-ExtIEs} }
+}
+
+NPNBroadcastInformation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+NPN-Broadcast-Information-SNPN ::= SEQUENCE {
+	broadcastSNPNID-List		BroadcastSNPN-ID-List,
+	iE-Extension				ProtocolExtensionContainer { {NPN-Broadcast-Information-SNPN-ExtIEs} }	OPTIONAL,
+	...
+}
+
+NPN-Broadcast-Information-SNPN-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+NPN-Broadcast-Information-PNI-NPN ::= SEQUENCE {
+	broadcastPNI-NPN-ID-Information		BroadcastPNI-NPN-ID-List,
+	iE-Extension							ProtocolExtensionContainer { {NPN-Broadcast-Information-PNI-NPN-ExtIEs} }	OPTIONAL,
+	...
+}
+
+NPN-Broadcast-Information-PNI-NPN-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+NPNSupportInfo ::= CHOICE {
+	sNPN-Information		NID,
+	choice-extension		ProtocolIE-SingleContainer { { NPNSupportInfo-ExtIEs } } 
+}
+
+NPNSupportInfo-ExtIEs		F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+NRCarrierList ::= SEQUENCE (SIZE(1..maxnoofNRSCSs)) OF NRCarrierItem
+
+NRCarrierItem ::= SEQUENCE {
+	carrierSCS						NRSCS,
+	offsetToCarrier					INTEGER (0..2199, ...),
+	carrierBandwidth				INTEGER (0..maxnoofPhysicalResourceBlocks, ...),
+	iE-Extension			ProtocolExtensionContainer { {NRCarrierItem-ExtIEs} } 				OPTIONAL,
+	...
+}
+
+NRCarrierItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NRFreqInfo ::=  SEQUENCE {
+	nRARFCN			INTEGER (0..maxNRARFCN),
+	sul-Information	SUL-Information		OPTIONAL,
+	freqBandListNr	SEQUENCE (SIZE(1..maxnoofNrCellBands)) OF FreqBandNrItem,
+	iE-Extensions	ProtocolExtensionContainer { { NRFreqInfoExtIEs} } OPTIONAL,
+	...
+}
+
+NRFreqInfoExtIEs		F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-FrequencyShift7p5khz	CRITICALITY ignore	EXTENSION FrequencyShift7p5khz	PRESENCE optional },
+	...
+}
+
+NRCGI ::= SEQUENCE {
+	pLMN-Identity			PLMN-Identity,
+	nRCellIdentity			NRCellIdentity,
+	iE-Extensions			ProtocolExtensionContainer { {NRCGI-ExtIEs} } OPTIONAL,
+	...
+}
+
+NRCGI-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NR-Mode-Info ::= CHOICE {
+	fDD		FDD-Info,
+	tDD		TDD-Info,
+	choice-extension			ProtocolIE-SingleContainer { { NR-Mode-Info-ExtIEs} }
+}
+
+NR-Mode-Info-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+
+
+NRPRACHConfig ::= SEQUENCE {
+	ulPRACHConfigList			NRPRACHConfigList									OPTIONAL,
+	sulPRACHConfigList			NRPRACHConfigList									OPTIONAL,
+	iE-Extension				ProtocolExtensionContainer { {NRPRACHConfig-ExtIEs} } 	OPTIONAL,
+	...
+}
+
+NRPRACHConfig-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NRCellIdentity ::= BIT STRING (SIZE(36))
+
+NRNRB ::= ENUMERATED { nrb11, nrb18, nrb24, nrb25, nrb31, nrb32, nrb38, nrb51, nrb52, nrb65, nrb66, nrb78, nrb79, nrb93, nrb106, nrb107, nrb121, nrb132, nrb133, nrb135, nrb160, nrb162, nrb189, nrb216, nrb217, nrb245, nrb264, nrb270, nrb273, ...}
+
+NRPCI ::= INTEGER(0..1007)
+
+
+NRPRACHConfigList ::= SEQUENCE (SIZE(0..maxnoofPRACHconfigs)) OF NRPRACHConfigItem
+
+NRPRACHConfigItem ::= SEQUENCE {
+	nRSCS					NRSCS,
+	prachFreqStartfromCarrier	INTEGER (0..maxnoofPhysicalResourceBlocks-1, ...),
+	msg1FDM						ENUMERATED {one, two, four, eight, ...},
+	parchConfigIndex			INTEGER (0..255, ...),
+	ssb-perRACH-Occasion		ENUMERATED {oneEighth, oneFourth, oneHalf, one, 
+											two, four, eight, sixteen, ...},
+	freqDomainLength			FreqDomainLength, 
+	zeroCorrelZoneConfig		INTEGER (0..15),
+	iE-Extension		ProtocolExtensionContainer { { NRPRACHConfigItem-ExtIEs} } 		OPTIONAL,
+	...
+}
+
+NRPRACHConfigItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NRSCS ::= ENUMERATED { scs15, scs30, scs60, scs120, ...}
+
+NRUERLFReportContainer ::= OCTET STRING
+
+NumberofActiveUEs ::= INTEGER(0..16777215, ...)
+
+NumberOfBroadcasts ::= INTEGER (0..65535)
+
+NumberofBroadcastRequest ::= INTEGER (0..65535)
+
+NumDLULSymbols ::= SEQUENCE {
+	numDLSymbols	INTEGER (0..13, ...),
+	numULSymbols	INTEGER (0..13, ...),
+	iE-Extensions			ProtocolExtensionContainer { { NumDLULSymbols-ExtIEs} } OPTIONAL
+}
+
+NumDLULSymbols-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NRV2XServicesAuthorized ::= SEQUENCE {
+	vehicleUE			VehicleUE														OPTIONAL,
+	pedestrianUE 		PedestrianUE													OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { {NRV2XServicesAuthorized-ExtIEs} }	OPTIONAL
+}
+
+NRV2XServicesAuthorized-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NRUESidelinkAggregateMaximumBitrate ::= SEQUENCE {
+	uENRSidelinkAggregateMaximumBitrate		BitRate,
+	iE-Extensions					ProtocolExtensionContainer { {NRUESidelinkAggregateMaximumBitrate-ExtIEs} } OPTIONAL
+}
+
+NRUESidelinkAggregateMaximumBitrate-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NZP-CSI-RS-ResourceID::= INTEGER  (0..191, ...)
+
+
+-- O
+
+OffsetToPointA	::= INTEGER (0..2199,...)
+
+
+-- P
+
+PacketDelayBudget ::= INTEGER (0..1023, ...) 
+
+PacketErrorRate ::= SEQUENCE {
+	pER-Scalar			PER-Scalar,
+	pER-Exponent		PER-Exponent,
+	iE-Extensions		ProtocolExtensionContainer { {PacketErrorRate-ExtIEs} }	OPTIONAL,
+	...
+}
+
+PacketErrorRate-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PER-Scalar ::= INTEGER (0..9, ...)
+PER-Exponent ::= INTEGER (0..9, ...)
+
+PagingCell-Item ::= SEQUENCE {
+	nRCGI		NRCGI	,
+	iE-Extensions	ProtocolExtensionContainer { { PagingCell-ItemExtIEs } }	OPTIONAL
+}
+
+PagingCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PagingDRX ::= ENUMERATED {
+	v32,
+	v64,
+	v128,
+	v256,
+	...
+}
+
+PagingIdentity ::=	CHOICE {
+	rANUEPagingIdentity	RANUEPagingIdentity,
+	cNUEPagingIdentity	CNUEPagingIdentity, 
+	choice-extension			ProtocolIE-SingleContainer { { PagingIdentity-ExtIEs } }
+}
+
+PagingIdentity-ExtIEs F1AP-PROTOCOL-IES::= {
+	...
+}
+
+PagingOrigin ::= ENUMERATED { non-3gpp,	...}
+
+PagingPriority ::= ENUMERATED { priolevel1, priolevel2, priolevel3, priolevel4, priolevel5, priolevel6, priolevel7, priolevel8,...} 
+
+
+RelativePathDelay ::= CHOICE {
+	k0					INTEGER (0..16351,...),
+	k1					INTEGER (0..8176,...),
+	k2					INTEGER (0..4088,...),
+	k3					INTEGER (0..2044,...),
+	k4					INTEGER (0..1022,...),
+	k5					INTEGER (0..511,...),	 
+	choice-extension			ProtocolIE-SingleContainer { { RelativePathDelay-ExtIEs } }
+}
+
+RelativePathDelay-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+PathlossReferenceInfo ::= SEQUENCE {
+	pathlossReferenceSignal			PathlossReferenceSignal,
+	iE-Extensions					ProtocolExtensionContainer { {PathlossReferenceInfo-ExtIEs} }	OPTIONAL
+}
+
+PathlossReferenceInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PathlossReferenceSignal ::= CHOICE { 
+	sSB										SSB,
+	dL-PRS									DL-PRS,
+	choice-extension						ProtocolIE-SingleContainer {{PathlossReferenceSignal-ExtIEs }}
+}
+
+PathlossReferenceSignal-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+PC5QoSFlowIdentifier ::= INTEGER (1..2048) 
+
+PC5-QoS-Characteristics ::= CHOICE {
+	non-Dynamic-PQI				NonDynamicPQIDescriptor,
+	dynamic-PQI					DynamicPQIDescriptor, 
+	choice-extension			ProtocolIE-SingleContainer { { PC5-QoS-Characteristics-ExtIEs } }
+}
+
+PC5-QoS-Characteristics-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+
+PC5QoSParameters	::= SEQUENCE {
+    pC5-QoS-Characteristics				PC5-QoS-Characteristics,
+	pC5-QoS-Flow-Bit-Rates				PC5FlowBitRates				OPTIONAL,
+	iE-Extensions						ProtocolExtensionContainer { { PC5QoSParameters-ExtIEs } }	OPTIONAL,
+	...
+}
+
+PC5QoSParameters-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PC5FlowBitRates ::= SEQUENCE {
+	guaranteedFlowBitRate		BitRate,
+	maximumFlowBitRate			BitRate,
+	iE-Extensions				ProtocolExtensionContainer { { PC5FlowBitRates-ExtIEs } }	OPTIONAL,
+	...
+}
+
+PC5FlowBitRates-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PDCCH-BlindDetectionSCG ::= OCTET STRING
+
+PDCP-SN ::= INTEGER (0..4095)
+
+PDCPSNLength	::= ENUMERATED { twelve-bits,eighteen-bits,...}
+
+PDUSessionID ::= INTEGER (0..255)
+
+ReportingPeriodicityValue ::= INTEGER (0..512, ...)
+
+Periodicity ::= INTEGER (0..640000, ...) 
+
+PeriodicitySRS ::= ENUMERATED { ms0p125, ms0p25, ms0p5, ms0p625, ms1, ms1p25, ms2, ms2p5, ms4, ms5, ms8, ms10, ms16, ms20, ms32, ms40, ms64, ms80, ms160, ms320, ms640, ms1280, ms2560, ms5120, ms10240, ...}
+
+PeriodicityList ::= SEQUENCE (SIZE(1.. maxnoSRS-ResourcePerSet)) OF PeriodicityList-Item
+
+PeriodicityList-Item ::= SEQUENCE {
+	periodicitySRS				PeriodicitySRS,
+	iE-Extensions				ProtocolExtensionContainer { { PeriodicityList-ItemExtIEs} } OPTIONAL
+}
+
+PeriodicityList-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+Permutation ::= ENUMERATED {dfu, ufd, ...}
+
+Ph-InfoMCG  ::= OCTET STRING
+
+Ph-InfoSCG  ::= OCTET STRING
+
+PLMN-Identity ::= OCTET STRING (SIZE(3))
+
+PortNumber ::= BIT STRING (SIZE (16))
+
+
+PosAssistance-Information ::= OCTET STRING
+
+PosAssistanceInformationFailureList ::= OCTET STRING
+
+PosBroadcast ::= ENUMERATED {
+	start,
+	stop,
+	...
+}
+
+PositioningBroadcastCells ::= SEQUENCE (SIZE (1..maxnoBcastCell)) OF NRCGI
+
+PosMeasurementPeriodicity ::= ENUMERATED
+{ms120, ms240, ms480, ms640, ms1024, ms2048, ms5120, ms10240, min1, min6, min12, min30, min60, ...}
+
+
+PosMeasurementQuantities ::= SEQUENCE (SIZE(1.. maxnoofPosMeas)) OF PosMeasurementQuantities-Item
+
+PosMeasurementQuantities-Item ::= SEQUENCE {
+	posMeasurementType					PosMeasurementType,
+	timingReportingGranularityFactor	INTEGER (0..5) OPTIONAL,
+	iE-Extensions						ProtocolExtensionContainer { { PosMeasurementQuantities-ItemExtIEs} } OPTIONAL
+}
+
+PosMeasurementQuantities-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosMeasurementResult ::= SEQUENCE (SIZE (1.. maxnoofPosMeas)) OF PosMeasurementResultItem 
+
+PosMeasurementResultItem ::= SEQUENCE {
+	measuredResultsValue				MeasuredResultsValue,
+	timeStamp							TimeStamp,
+	measurementQuality					TRPMeasurementQuality	OPTIONAL,
+	measurementBeamInfo					MeasurementBeamInfo		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { PosMeasurementResultItemExtIEs } }	OPTIONAL
+}
+
+PosMeasurementResultItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosMeasurementResultList ::= SEQUENCE (SIZE(1.. maxNoOfMeasTRPs)) OF PosMeasurementResultList-Item
+
+PosMeasurementResultList-Item ::= SEQUENCE {
+	posMeasurementResult			PosMeasurementResult,
+	tRPID							TRPID,
+	iE-Extensions					ProtocolExtensionContainer { { PosMeasurementResultList-ItemExtIEs} } OPTIONAL
+}
+
+PosMeasurementResultList-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosMeasurementType ::= ENUMERATED {
+	gnb-rx-tx,
+	ul-srs-rsrp,
+	ul-aoa,
+	ul-rtoa, 
+	...
+}
+
+PosReportCharacteristics ::= ENUMERATED {
+	ondemand, 
+	periodic, 
+	...
+}
+
+PosResourceSetType  ::= CHOICE {
+	periodic			PosResourceSetTypePR,
+	semi-persistent		PosResourceSetTypeSP,
+	aperiodic			PosResourceSetTypeAP,
+	choice-extension	ProtocolIE-SingleContainer {{ PosResourceSetType-ExtIEs }}
+}
+
+PosResourceSetType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+PosResourceSetTypePR ::= SEQUENCE {
+	posperiodicSet		ENUMERATED{true, ...},
+	iE-Extensions		ProtocolExtensionContainer { { PosResourceSetTypePR-ExtIEs} }	OPTIONAL
+}
+
+PosResourceSetTypePR-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosResourceSetTypeSP ::= SEQUENCE {
+	possemi-persistentSet		ENUMERATED{true, ...},
+	iE-Extensions		ProtocolExtensionContainer { { PosResourceSetTypeSP-ExtIEs} }	OPTIONAL
+}
+
+PosResourceSetTypeSP-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosResourceSetTypeAP ::= SEQUENCE {
+	sRSResourceTrigger-List 	INTEGER(1..3),
+	iE-Extensions		ProtocolExtensionContainer { { PosResourceSetTypeAP-ExtIEs} }	OPTIONAL
+}
+
+PosResourceSetTypeAP-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosSRSResourceID-List ::= SEQUENCE (SIZE (1..maxnoSRS-PosResourcePerSet)) OF SRSPosResourceID
+
+PosSRSResource-Item ::= SEQUENCE {
+	srs-PosResourceId				SRSPosResourceID,
+	transmissionCombPos				TransmissionCombPos,
+	startPosition                   INTEGER (0..13),
+	nrofSymbols                     ENUMERATED {n1, n2, n4, n8, n12},
+	freqDomainShift                 INTEGER (0..268),
+	c-SRS	                        INTEGER (0..63),
+	groupOrSequenceHopping          ENUMERATED { neither, groupHopping, sequenceHopping },
+	resourceTypePos					ResourceTypePos,
+	sequenceId                      INTEGER (0.. 65535),
+	spatialRelationPos				SpatialRelationPos 	OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { PosSRSResource-Item-ExtIEs} }	OPTIONAL
+}
+
+PosSRSResource-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosSRSResource-List ::= SEQUENCE (SIZE (1..maxnoSRS-PosResources)) OF PosSRSResource-Item
+
+PosSRSResourceSet-Item ::= SEQUENCE {
+	possrsResourceSetID				INTEGER(0..15),
+	possRSResourceID-List			PosSRSResourceID-List,
+	posresourceSetType				PosResourceSetType,
+	iE-Extensions		ProtocolExtensionContainer { { PosSRSResourceSet-Item-ExtIEs} }	OPTIONAL
+}
+
+PosSRSResourceSet-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PosSRSResourceSet-List ::= SEQUENCE (SIZE (1..maxnoSRS-PosResourceSets)) OF PosSRSResourceSet-Item
+
+PrimaryPathIndication ::= ENUMERATED { 
+	true,
+	false,
+	...
+}
+
+Pre-emptionCapability ::= ENUMERATED {
+	shall-not-trigger-pre-emption,
+	may-trigger-pre-emption
+}
+
+Pre-emptionVulnerability ::= ENUMERATED {
+	not-pre-emptable,
+	pre-emptable
+}
+
+PriorityLevel	::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15)
+
+ProtectedEUTRAResourceIndication		::= OCTET STRING
+
+Protected-EUTRA-Resources-Item ::= SEQUENCE {
+	spectrumSharingGroupID					SpectrumSharingGroupID, 
+	eUTRACells-List		EUTRACells-List,
+	iE-Extensions	ProtocolExtensionContainer { { Protected-EUTRA-Resources-ItemExtIEs } }	OPTIONAL
+}
+
+Protected-EUTRA-Resources-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSConfiguration ::= SEQUENCE {
+	pRSResourceSet-List			PRSResourceSet-List,
+	iE-Extensions	ProtocolExtensionContainer { { PRSConfiguration-ExtIEs } }	OPTIONAL
+}
+
+PRSConfiguration-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSInformationPos  ::= SEQUENCE {
+	pRS-IDPos					INTEGER(0..255) OPTIONAL,	
+	pRS-Resource-Set-IDPos		INTEGER(0..7),
+	pRS-Resource-IDPos			INTEGER(0..63),
+	iE-Extensions					ProtocolExtensionContainer { { PRSInformationPos-ExtIEs} } OPTIONAL
+}
+
+PRSInformationPos-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Potential-SpCell-Item ::= SEQUENCE {
+	potential-SpCell-ID			NRCGI	,
+	iE-Extensions	ProtocolExtensionContainer { { Potential-SpCell-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Potential-SpCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+PRSAngleList ::= SEQUENCE (SIZE(1.. maxnoofPRS-ResourcesPerSet)) OF PRSAngleItem
+
+PRSAngleItem ::= SEQUENCE {
+	nR-PRS-Azimuth			INTEGER (0..359),
+	nR-PRS-Azimuth-fine		INTEGER (0..9),
+	nR-PRS-Elevation		INTEGER (0..180),
+	nR-PRS-Elevation-fine	INTEGER (0..9),
+	iE-Extensions		ProtocolExtensionContainer { { PRSAngleItem-ItemExtIEs } }	OPTIONAL
+}
+
+PRSAngleItem-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSMuting::= SEQUENCE {
+	pRSMutingOption1			PRSMutingOption1,
+	pRSMutingOption2			PRSMutingOption2,
+	iE-Extensions					ProtocolExtensionContainer { { PRSMuting-ExtIEs} } OPTIONAL
+}
+
+PRSMuting-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSMutingOption1 ::= SEQUENCE {
+	mutingPattern					DL-PRSMutingPattern,
+	mutingBitRepetitionFactor		ENUMERATED{rf1,rf2,rf4,rf8,...},
+	iE-Extensions					ProtocolExtensionContainer { { PRSMutingOption1-ExtIEs} } OPTIONAL
+}
+
+PRSMutingOption1-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSMutingOption2 ::= SEQUENCE {
+	mutingPattern					DL-PRSMutingPattern,
+	iE-Extensions					ProtocolExtensionContainer { { PRSMutingOption2-ExtIEs} } OPTIONAL
+}
+
+PRSMutingOption2-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRS-Resource-ID ::= INTEGER (0..63)
+
+PRSResource-List::= SEQUENCE (SIZE (1..maxnoofPRSresources)) OF PRSResource-Item
+
+PRSResource-Item  ::= SEQUENCE {
+	pRSResourceID			INTEGER(0..63),
+	sequenceID				INTEGER(0..4095,...),
+	rEOffset				INTEGER(0..11),
+	resourceSlotOffset		INTEGER(0..511,...),
+	resourceSymbolOffset	INTEGER(0..12,...),
+	qCLInfo					PRSResource-QCLInfo		OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { { PRSResource-Item-ExtIEs} } OPTIONAL
+}
+
+PRSResource-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSResource-QCLInfo  ::= SEQUENCE {
+	qCLSourceSSBIndex		INTEGER(0..63) OPTIONAL,
+	qCLSourcePRSInfo		PRSResource-QCLSourcePRSInfo	OPTIONAL,		
+	iE-Extensions					ProtocolExtensionContainer { { PRSResource-QCLInfo-ExtIEs} } OPTIONAL,
+	...
+}
+PRSResource-QCLInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRSResource-QCLSourcePRSInfo ::= SEQUENCE {
+	qCLSourcePRSResourceSetID		INTEGER(0..7),
+	qCLSourcePRSResourceID 			INTEGER(0..63) OPTIONAL,		
+	iE-Extensions					ProtocolExtensionContainer { { PRSResource-QCLSourcePRSInfo-ExtIEs} } OPTIONAL
+}
+
+PRSResource-QCLSourcePRSInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PRS-Resource-Set-ID ::= INTEGER(0..7)
+
+PRSResourceSet-List ::= SEQUENCE (SIZE (1.. maxnoofPRSresourceSets)) OF PRSResourceSet-Item
+PRSResourceSet-Item ::= SEQUENCE {
+	pRSResourceSetID				PRS-Resource-Set-ID,
+	subcarrierSpacing				ENUMERATED{kHz15, kHz30, kHz60, kHz120, ...},
+	pRSbandwidth					INTEGER(1..63),
+	startPRB						INTEGER(0..2176),
+	pointA							INTEGER (0..3279165),
+	combSize						ENUMERATED{n2, n4, n6, n12, ...},
+	cPType							ENUMERATED{normal, extended, ...},
+	resourceSetPeriodicity			ENUMERATED{n4,n5,n8,n10,n16,n20,n32,n40,n64,n80,n160,n320,n640,n1280,n2560,n5120,n10240,n20480,n40960, n81920,...},
+	resourceSetSlotOffset			INTEGER(0..81919,...),
+	resourceRepetitionFactor		ENUMERATED{rf1,rf2,rf4,rf6,rf8,rf16,rf32,...},
+	resourceTimeGap					ENUMERATED{tg1,tg2,tg4,tg8,tg16,tg32,...},
+	resourceNumberofSymbols			ENUMERATED{n2,n4,n6,n12,...},
+	pRSMuting						PRSMuting 		OPTIONAL,
+	pRSResourceTransmitPower		INTEGER(-60..50),
+	pRSResource-List				PRSResource-List,	
+	iE-Extensions					ProtocolExtensionContainer { { PRSResourceSet-Item-ExtIEs} } OPTIONAL
+}
+
+PRSResourceSet-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PWS-Failed-NR-CGI-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	numberOfBroadcasts	NumberOfBroadcasts,
+	iE-Extensions		ProtocolExtensionContainer { { PWS-Failed-NR-CGI-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+PWS-Failed-NR-CGI-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PWSSystemInformation ::= SEQUENCE {
+	sIBtype 				SIBType-PWS,
+	sIBmessage			OCTET STRING, 
+	iE-Extensions		ProtocolExtensionContainer { { PWSSystemInformationExtIEs } }	OPTIONAL,
+	...
+}
+
+PWSSystemInformationExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-NotificationInformation		CRITICALITY ignore	EXTENSION NotificationInformation		PRESENCE optional}|
+	{ ID id-AdditionalSIBMessageList	CRITICALITY reject	EXTENSION AdditionalSIBMessageList		PRESENCE optional},
+	...
+}
+
+PrivacyIndicator ::= ENUMERATED {immediate-MDT,	logged-MDT,	...}
+
+-- Q
+
+QCI ::= INTEGER (0..255)
+
+QoS-Characteristics ::= CHOICE {
+	non-Dynamic-5QI				NonDynamic5QIDescriptor,
+	dynamic-5QI					Dynamic5QIDescriptor, 
+	choice-extension			ProtocolIE-SingleContainer { { QoS-Characteristics-ExtIEs } }
+}
+
+QoS-Characteristics-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+QoSFlowIdentifier ::= INTEGER (0..63) 
+
+QoSFlowLevelQoSParameters	::= SEQUENCE {
+	qoS-Characteristics					QoS-Characteristics,
+	nGRANallocationRetentionPriority		NGRANAllocationAndRetentionPriority,
+	gBR-QoS-Flow-Information				GBR-QoSFlowInformation				OPTIONAL,
+	reflective-QoS-Attribute				ENUMERATED {subject-to, ...}				OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { QoSFlowLevelQoSParameters-ExtIEs } }	OPTIONAL
+}
+
+QoSFlowLevelQoSParameters-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-PDUSessionID								CRITICALITY ignore	EXTENSION PDUSessionID			PRESENCE optional}|
+	{ ID id-ULPDUSessionAggregateMaximumBitRate			CRITICALITY ignore	EXTENSION BitRate					PRESENCE optional}|
+	{ ID id-QosMonitoringRequest						CRITICALITY ignore	EXTENSION QosMonitoringRequest	PRESENCE optional},
+	...
+}
+
+QoSFlowMappingIndication ::= ENUMERATED {ul,dl,...}
+
+QoSInformation	::=	CHOICE {
+	eUTRANQoS					EUTRANQoS,
+	choice-extension			ProtocolIE-SingleContainer { { QoSInformation-ExtIEs} }
+}
+
+QoSInformation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	{	ID id-DRB-Information		CRITICALITY ignore TYPE DRB-Information		PRESENCE mandatory},
+	...
+}
+
+QosMonitoringRequest ::= ENUMERATED {ul, dl, both, ...}
+
+QoSParaSetIndex ::= INTEGER (1..8, ...) 
+
+QoSParaSetNotifyIndex ::= INTEGER (0..8, ...)
+
+-- R
+
+RACH-Config-Common	::= OCTET STRING
+
+RACH-Config-Common-IAB	::= OCTET STRING
+
+RACHReportContainer::= OCTET STRING
+
+RACHReportInformationList	::= SEQUENCE (SIZE(1.. maxnoofRACHReports)) OF RACHReportInformationItem
+
+RACHReportInformationItem	::= SEQUENCE {
+	rACHReportContainer				RACHReportContainer,
+	uEAssitantIdentifier			GNB-DU-UE-F1AP-ID		OPTIONAL, 
+	iE-Extensions			ProtocolExtensionContainer { { RACHReportInformationItem-ExtIEs} }	OPTIONAL,
+	...
+}
+
+RACHReportInformationItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+
+RadioResourceStatus ::= SEQUENCE {
+	sSBAreaRadioResourceStatusList		SSBAreaRadioResourceStatusList,
+	iE-Extensions	ProtocolExtensionContainer { { RadioResourceStatus-ExtIEs} } OPTIONAL
+}
+
+RadioResourceStatus-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RANAC ::= INTEGER (0..255) 
+
+RAN-MeasurementID ::= INTEGER (1.. 65536, ...)
+
+RAN-UE-MeasurementID ::= INTEGER (1.. 256, ...)
+
+RANUEID ::= OCTET STRING (SIZE (8))
+
+RANUEPagingIdentity ::= SEQUENCE	{
+	iRNTI						BIT STRING (SIZE(40)),
+	iE-Extensions				ProtocolExtensionContainer { { RANUEPagingIdentity-ExtIEs } }	OPTIONAL}
+
+RANUEPagingIdentity-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RAT-FrequencyPriorityInformation::= CHOICE {
+	eNDC		SubscriberProfileIDforRFP,
+	nGRAN		RAT-FrequencySelectionPriority,
+	choice-extension			ProtocolIE-SingleContainer { { RAT-FrequencyPriorityInformation-ExtIEs} }
+}
+
+RAT-FrequencyPriorityInformation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+RAT-FrequencySelectionPriority::= INTEGER (1.. 256, ...)
+
+Reestablishment-Indication	::=	ENUMERATED  {
+	reestablished,
+	...
+}
+
+ReferencePoint ::= CHOICE {
+	coordinateID					CoordinateID,
+	referencePointCoordinate		AccessPointPosition,
+	referencePointCoordinateHA		NGRANHighAccuracyAccessPointPosition,
+	choice-Extension				ProtocolIE-SingleContainer { { ReferencePoint-ExtIEs} }
+}
+
+ReferencePoint-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+ReferenceSFN ::= INTEGER (0..1023)
+
+ReferenceSignal ::= CHOICE { 
+	nZP-CSI-RS								NZP-CSI-RS-ResourceID,
+	sSB										SSB,
+	sRS										SRSResourceID,
+	positioningSRS							SRSPosResourceID,
+	dL-PRS									DL-PRS,
+	choice-extension						ProtocolIE-SingleContainer {{ReferenceSignal-ExtIEs }}
+}
+
+ReferenceSignal-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+RelativeCartesianLocation ::= SEQUENCE {
+	xYZunit						ENUMERATED {mm, cm, dm, ...},
+	xvalue						INTEGER (-65536..65535),
+	yvalue						INTEGER (-65536..65535),
+	zvalue						INTEGER (-32768..32767),
+	locationUncertainty			LocationUncertainty,
+	iE-Extensions				ProtocolExtensionContainer { { RelativeCartesianLocation-ExtIEs} } OPTIONAL
+}
+
+RelativeCartesianLocation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RelativeGeodeticLocation ::= SEQUENCE { 
+	milli-Arc-SecondUnits		ENUMERATED {zerodot03, zerodot3, three, ...},	
+	heightUnits					ENUMERATED {mm, cm, m, ...}, 
+	deltaLatitude				INTEGER (-1024.. 1023),
+	deltaLongitude				INTEGER (-1024.. 1023),
+	deltaHeight					INTEGER (-1024.. 1023),
+	locationUncertainty			LocationUncertainty,
+	iE-extensions				ProtocolExtensionContainer {{RelativeGeodeticLocation-ExtIEs }} OPTIONAL
+}
+
+RelativeGeodeticLocation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ReferenceTime ::= OCTET STRING
+
+RegistrationRequest ::= ENUMERATED{start, stop, add, ...}
+
+ReportCharacteristics ::= BIT STRING (SIZE(32))
+
+ReportingPeriodicity ::= ENUMERATED{ms500, ms1000, ms2000, ms5000, ms10000, ...}
+
+RequestedBandCombinationIndex ::= OCTET STRING
+
+RequestedFeatureSetEntryIndex ::= OCTET STRING
+
+RequestedP-MaxFR2 ::= OCTET STRING
+
+Requested-PDCCH-BlindDetectionSCG ::= OCTET STRING
+
+
+RequestedSRSTransmissionCharacteristics ::= SEQUENCE {
+	numberOfTransmissions		INTEGER (0..500, ...)		OPTIONAL,
+	resourceType				ENUMERATED  {periodic, semi-persistent, aperiodic,...},
+	bandwidthSRS				BandwidthSRS,
+	sRSResourceSetList 			SRSResourceSetList				OPTIONAL,
+	sSBInformation				SSBInformation				OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { { RequestedSRSTransmissionCharacteristics-ExtIEs} } OPTIONAL
+}
+
+RequestedSRSTransmissionCharacteristics-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RequestType	::= ENUMERATED {offer, execution, ...}
+
+ResourceCoordinationEUTRACellInfo ::= SEQUENCE {
+	eUTRA-Mode-Info 						EUTRA-Coex-Mode-Info,
+	eUTRA-PRACH-Configuration 				EUTRA-PRACH-Configuration,
+	iE-Extensions	ProtocolExtensionContainer { { ResourceCoordinationEUTRACellInfo-ExtIEs } }	OPTIONAL,
+	...
+}
+
+ResourceCoordinationEUTRACellInfo-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-IgnorePRACHConfiguration		CRITICALITY reject EXTENSION IgnorePRACHConfiguration		PRESENCE optional },
+	...
+}
+
+ResourceCoordinationTransferInformation ::= SEQUENCE {
+	meNB-Cell-ID								EUTRA-Cell-ID,
+	resourceCoordinationEUTRACellInfo		ResourceCoordinationEUTRACellInfo	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { ResourceCoordinationTransferInformation-ExtIEs } }	OPTIONAL,
+	...
+}
+
+ResourceCoordinationTransferInformation-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceCoordinationTransferContainer ::= OCTET STRING
+
+ResourceSetType  ::= CHOICE {
+	periodic			ResourceSetTypePeriodic,
+	semi-persistent		ResourceSetTypeSemi-persistent,
+	aperiodic			ResourceSetTypeAperiodic,
+	choice-extension				ProtocolIE-SingleContainer {{ ResourceSetType-ExtIEs }}
+}
+
+ResourceSetType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+ResourceSetTypePeriodic ::= SEQUENCE {
+	periodicSet			ENUMERATED{true, ...},
+	iE-Extensions		ProtocolExtensionContainer { { ResourceSetTypePeriodic-ExtIEs} }	OPTIONAL
+}
+
+ResourceSetTypePeriodic-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceSetTypeSemi-persistent ::= SEQUENCE {
+	semi-persistentSet	ENUMERATED{true, ...},
+	iE-Extensions		ProtocolExtensionContainer { { ResourceSetTypeSemi-persistent-ExtIEs} }	OPTIONAL
+}
+
+ResourceSetTypeSemi-persistent-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceSetTypeAperiodic ::= SEQUENCE {
+	sRSResourceTrigger-List 	INTEGER(1..3),
+	slotoffset					INTEGER(1..32),
+	iE-Extensions		ProtocolExtensionContainer { { ResourceSetTypeAperiodic-ExtIEs} }	OPTIONAL
+}
+
+ResourceSetTypeAperiodic-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RepetitionPeriod ::= INTEGER (0..131071, ...)
+
+ReportingRequestType ::= SEQUENCE {
+	eventType						EventType,
+	reportingPeriodicityValue						ReportingPeriodicityValue		OPTIONAL,
+	-- C-ifEventTypeisPeriodic: This IE shall be present if the Event Type IE is set to "periodic" in the Event Type IE.
+	iE-Extensions					ProtocolExtensionContainer { {ReportingRequestType-ExtIEs} }	OPTIONAL
+}
+
+ReportingRequestType-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceType ::= CHOICE {
+	periodic			ResourceTypePeriodic,
+	semi-persistent		ResourceTypeSemi-persistent,
+	aperiodic			ResourceTypeAperiodic,
+	choice-extension				ProtocolIE-SingleContainer {{ ResourceType-ExtIEs }}
+}
+
+ResourceType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+ResourceTypePeriodic ::= SEQUENCE {
+	periodicity		   ENUMERATED{slot1, slot2, slot4, slot5, slot8, slot10, slot16, slot20, slot32, slot40, slot64, slot80, slot160, slot320, slot640, slot1280, slot2560, ...},
+	offset				INTEGER(0..2559, ...),
+	iE-Extensions		ProtocolExtensionContainer { { ResourceTypePeriodic-ExtIEs} }	OPTIONAL
+}
+
+ResourceTypePeriodic-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceTypeSemi-persistent ::= SEQUENCE {
+	periodicity		   ENUMERATED{slot1, slot2, slot4, slot5, slot8, slot10, slot16, slot20, slot32, slot40, slot64, slot80, slot160, slot320, slot640, slot1280, slot2560, ...},
+	offset				INTEGER(0..2559, ...),
+	iE-Extensions		ProtocolExtensionContainer { { ResourceTypeSemi-persistent-ExtIEs} }	OPTIONAL
+}
+
+ResourceTypeSemi-persistent-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceTypeAperiodic ::= SEQUENCE {
+	aperiodicResourceType	   ENUMERATED{true, ...},
+	iE-Extensions		ProtocolExtensionContainer { { ResourceTypeAperiodic-ExtIEs} }	OPTIONAL
+}
+
+ResourceTypeAperiodic-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceTypePos ::= CHOICE {
+	periodic			ResourceTypePeriodicPos,
+	semi-persistent		ResourceTypeSemi-persistentPos,
+	aperiodic			ResourceTypeAperiodicPos,
+	choice-extension	ProtocolIE-SingleContainer {{ ResourceTypePos-ExtIEs }}
+}
+
+ResourceTypePos-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+ResourceTypePeriodicPos ::= SEQUENCE {
+	periodicity		   ENUMERATED{slot1, slot2, slot4, slot5, slot8, slot10, slot16, slot20, slot32, slot40, slot64, slot80, slot160, slot320, slot640, slot1280, slot2560, slot5120, slot10240, slot20480, slot40960, slot81920, ...},
+	offset				INTEGER(0..81919, ...),
+	iE-Extensions		ProtocolExtensionContainer { { ResourceTypePeriodicPos-ExtIEs} }	OPTIONAL
+}
+
+ResourceTypePeriodicPos-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceTypeSemi-persistentPos ::= SEQUENCE {
+	periodicity		   ENUMERATED{slot1, slot2, slot4, slot5, slot8, slot10, slot16, slot20, slot32, slot40, slot64, slot80, slot160, slot320, slot640, slot1280, slot2560, slot5120, slot10240, slot20480, slot40960, slot81920, ...},
+	offset				INTEGER(0..81919, ...),
+	iE-Extensions		ProtocolExtensionContainer { { ResourceTypeSemi-persistentPos-ExtIEs} }	OPTIONAL
+}
+
+ResourceTypeSemi-persistentPos-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ResourceTypeAperiodicPos ::= SEQUENCE {
+	slotOffset          INTEGER (1..32),
+	iE-Extensions		ProtocolExtensionContainer { { ResourceTypeAperiodicPos-ExtIEs} }	OPTIONAL
+}
+
+ResourceTypeAperiodicPos-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RLCDuplicationInformation ::= SEQUENCE {
+	rLCDuplicationStateList 		RLCDuplicationStateList,
+	primaryPathIndication			PrimaryPathIndication	OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { {RLCDuplicationInformation-ExtIEs} }	OPTIONAL
+}
+
+RLCDuplicationInformation-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RLCDuplicationStateList	::= SEQUENCE (SIZE(1..maxnoofRLCDuplicationState)) OF RLCDuplicationState-Item
+
+RLCDuplicationState-Item ::=SEQUENCE {
+	duplicationState		DuplicationState, 
+	iE-Extensions	ProtocolExtensionContainer { {RLCDuplicationState-Item-ExtIEs } }	OPTIONAL,
+	...
+}
+
+
+RLCDuplicationState-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RLCFailureIndication ::= SEQUENCE {
+	assocatedLCID				LCID,
+	iE-Extensions				ProtocolExtensionContainer { {RLCFailureIndication-ExtIEs} } OPTIONAL
+}
+
+RLCFailureIndication-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RLCMode ::= ENUMERATED {
+	rlc-am,
+	rlc-um-bidirectional,
+	rlc-um-unidirectional-ul,
+	rlc-um-unidirectional-dl,
+	...
+}
+
+RLC-Status ::= SEQUENCE {
+	reestablishment-Indication 	Reestablishment-Indication,
+	iE-Extensions				ProtocolExtensionContainer { { RLC-Status-ExtIEs } } OPTIONAL,
+	...
+}
+
+RLC-Status-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RLFReportInformationList	::= SEQUENCE (SIZE(1.. maxnoofRLFReports)) OF RLFReportInformationItem
+
+RLFReportInformationItem	::= SEQUENCE {
+	nRUERLFReportContainer		NRUERLFReportContainer,
+	uEAssitantIdentifier			GNB-DU-UE-F1AP-ID		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { RLFReportInformationItem-ExtIEs} }	OPTIONAL,
+	...
+}
+
+RLFReportInformationItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RIMRSDetectionStatus ::= ENUMERATED {rs-detected, rs-disappeared, ...}
+
+RRCContainer ::= OCTET STRING
+
+RRCContainer-RRCSetupComplete ::= OCTET STRING
+
+RRCDeliveryStatus ::= SEQUENCE	{
+	delivery-status 			PDCP-SN,
+	triggering-message			PDCP-SN,
+	iE-Extensions				ProtocolExtensionContainer { { RRCDeliveryStatus-ExtIEs } }	OPTIONAL}
+
+RRCDeliveryStatus-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+RRCDeliveryStatusRequest ::= ENUMERATED {true, ...}
+
+RRCReconfigurationCompleteIndicator	::= ENUMERATED {
+	true,
+	 ...,
+	failure
+}
+
+RRC-Version ::= SEQUENCE	{
+	latest-RRC-Version			BIT STRING (SIZE(3)),
+	iE-Extensions				ProtocolExtensionContainer { { RRC-Version-ExtIEs } }	OPTIONAL}
+
+RRC-Version-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-latest-RRC-Version-Enhanced		CRITICALITY ignore EXTENSION OCTET STRING (SIZE(3))		PRESENCE optional },
+	...
+}
+
+RoutingID ::= OCTET STRING
+
+-- S
+
+SCell-FailedtoSetup-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-FailedtoSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-FailedtoSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-FailedtoSetupMod-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-FailedtoSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-FailedtoSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-ToBeRemoved-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	iE-Extensions	ProtocolExtensionContainer { { SCell-ToBeRemoved-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-ToBeRemoved-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-ToBeSetup-Item ::= SEQUENCE {
+	sCell-ID			NRCGI	,
+	sCellIndex			SCellIndex, 
+	sCellULConfigured		CellULConfigured 	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-ServingCellMO		CRITICALITY ignore	EXTENSION ServingCellMO		PRESENCE optional	},
+	...
+}
+
+SCell-ToBeSetupMod-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	sCellIndex			SCellIndex,
+	sCellULConfigured		CellULConfigured 	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-ToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-ServingCellMO		CRITICALITY ignore	EXTENSION ServingCellMO		PRESENCE optional	},
+	...
+}
+
+SCellIndex ::=INTEGER (1..31, ...) 
+
+SCS-SpecificCarrier ::=            SEQUENCE {
+    offsetToCarrier                     INTEGER (0..2199,...),
+    subcarrierSpacing                   ENUMERATED {kHz15, kHz30, kHz60, kHz120,...},
+    carrierBandwidth                    INTEGER (0..275,...),
+	iE-Extensions						ProtocolExtensionContainer { { SCS-SpecificCarrier-ExtIEs } } OPTIONAL
+}
+
+SCS-SpecificCarrier-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Search-window-information ::= SEQUENCE {
+	expectedPropagationDelay		INTEGER (-3841..3841,...),
+	delayUncertainty				INTEGER (1..246,...),
+	iE-Extensions					ProtocolExtensionContainer { { Search-window-information-ExtIEs } } OPTIONAL
+}
+
+Search-window-information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SerialNumber ::= BIT STRING (SIZE (16))
+
+SIBType-PWS ::=INTEGER (6..8, ...)
+
+SelectedBandCombinationIndex ::= OCTET STRING
+
+SelectedFeatureSetEntryIndex ::= OCTET STRING
+
+CG-ConfigInfo ::= OCTET STRING
+
+ServCellIndex ::= INTEGER (0..31, ...)
+
+ServingCellMO ::= INTEGER (1..64, ...)
+
+Served-Cell-Information ::= SEQUENCE {
+	nRCGI							NRCGI,
+	nRPCI							NRPCI,
+	fiveGS-TAC							FiveGS-TAC			OPTIONAL,
+	configured-EPS-TAC				Configured-EPS-TAC 		OPTIONAL,
+	servedPLMNs					ServedPLMNs-List,
+	nR-Mode-Info					NR-Mode-Info, 
+	measurementTimingConfiguration	OCTET STRING,
+	iE-Extensions		ProtocolExtensionContainer { {Served-Cell-Information-ExtIEs} } OPTIONAL,
+	...
+}
+
+Served-Cell-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{	ID id-RANAC							CRITICALITY ignore	EXTENSION RANAC							PRESENCE optional }|
+	{	ID id-ExtendedServedPLMNs-List		CRITICALITY ignore	EXTENSION ExtendedServedPLMNs-List	PRESENCE optional }|
+	{	ID id-Cell-Direction				CRITICALITY ignore	EXTENSION Cell-Direction				PRESENCE optional }|
+	{	ID id-BPLMN-ID-Info-List			CRITICALITY ignore	EXTENSION BPLMN-ID-Info-List			PRESENCE optional }|
+	{	ID id-Cell-Type						CRITICALITY ignore	EXTENSION CellType						PRESENCE optional}|
+	{	ID id-ConfiguredTACIndication		CRITICALITY ignore	EXTENSION ConfiguredTACIndication		PRESENCE optional }|
+	{	ID id-AggressorgNBSetID				CRITICALITY ignore	EXTENSION AggressorgNBSetID				PRESENCE optional}|
+	{	ID id-VictimgNBSetID				CRITICALITY ignore	EXTENSION VictimgNBSetID				PRESENCE optional}|
+	{	ID id-IAB-Info-IAB-DU				CRITICALITY ignore	EXTENSION IAB-Info-IAB-DU				PRESENCE optional}|
+	{	ID id-SSB-PositionsInBurst			CRITICALITY ignore	EXTENSION SSB-PositionsInBurst			PRESENCE optional }|
+	{	ID id-NRPRACHConfig					CRITICALITY ignore	EXTENSION NRPRACHConfig					PRESENCE optional },
+	...
+}
+
+Served-Cells-To-Add-Item ::= SEQUENCE {
+	served-Cell-Information		Served-Cell-Information,
+	gNB-DU-System-Information	GNB-DU-System-Information	 OPTIONAL, 
+	iE-Extensions				ProtocolExtensionContainer { { Served-Cells-To-Add-ItemExtIEs} }	OPTIONAL,
+	...
+}
+
+Served-Cells-To-Add-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Served-Cells-To-Delete-Item ::= SEQUENCE {
+	oldNRCGI					NRCGI	,
+	iE-Extensions				ProtocolExtensionContainer { { Served-Cells-To-Delete-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Served-Cells-To-Delete-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Served-Cells-To-Modify-Item ::= SEQUENCE {
+	oldNRCGI					NRCGI							,
+	served-Cell-Information		Served-Cell-Information		,
+	gNB-DU-System-Information	GNB-DU-System-Information 	OPTIONAL	,
+	iE-Extensions				ProtocolExtensionContainer { { Served-Cells-To-Modify-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Served-Cells-To-Modify-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Served-EUTRA-Cells-Information::= SEQUENCE {
+	eUTRA-Mode-Info						EUTRA-Mode-Info,
+	protectedEUTRAResourceIndication	ProtectedEUTRAResourceIndication,
+	iE-Extensions						ProtocolExtensionContainer { {Served-EUTRA-Cell-Information-ExtIEs} } OPTIONAL,
+	...
+}
+
+Served-EUTRA-Cell-Information-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Service-State ::= ENUMERATED {
+	in-service,
+	out-of-service,
+	...
+}
+
+Service-Status ::= SEQUENCE {
+	service-state				Service-State,
+	switchingOffOngoing			ENUMERATED {true, ...}	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { Service-Status-ExtIEs } }	OPTIONAL,
+	...
+}
+
+Service-Status-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+SFNInitialisationTime ::= 	BIT STRING (SIZE (64))
+
+ShortDRXCycleLength ::=  ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms7, ms8, ms10, ms14, ms16, ms20, ms30, ms32, ms35, ms40, ms64, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ...}
+
+ShortDRXCycleTimer ::= INTEGER (1..16)
+
+SIB1-message ::= OCTET STRING
+
+SIB10-message ::= OCTET STRING
+
+SIB12-message ::= OCTET STRING
+
+SIB13-message ::= OCTET STRING
+
+SIB14-message ::= OCTET STRING
+
+SItype ::= INTEGER (1..32, ...)
+
+SItype-List ::= SEQUENCE (SIZE(1.. maxnoofSITypes)) OF SItype-Item
+
+SItype-Item ::= SEQUENCE {
+	sItype		SItype	,
+	iE-Extensions	ProtocolExtensionContainer { { SItype-ItemExtIEs } }	OPTIONAL
+}
+
+SItype-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SibtypetobeupdatedListItem ::= SEQUENCE {
+	sIBtype 			INTEGER (2..32,...), 
+	sIBmessage			OCTET STRING, 
+	valueTag			INTEGER (0..31,...), 
+	iE-Extensions	ProtocolExtensionContainer { { SibtypetobeupdatedListItem-ExtIEs } }	OPTIONAL,
+	...
+}
+
+SibtypetobeupdatedListItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ID	id-areaScope	CRITICALITY ignore	EXTENSION	AreaScope	PRESENCE optional},
+	...
+}
+
+SLDRBID ::= INTEGER (1..512, ...)
+
+SLDRBInformation ::= SEQUENCE {
+	sLDRB-QoS				PC5QoSParameters,
+	flowsMappedToSLDRB-List	FlowsMappedToSLDRB-List,
+	...
+}
+
+SLDRBs-FailedToBeModified-Item	::= SEQUENCE {
+	sLDRBID		SLDRBID		,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-FailedToBeModified-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-FailedToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-FailedToBeSetup-Item	::= SEQUENCE {
+	sLDRBID	SLDRBID,
+	cause	Cause	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-FailedToBeSetup-ItemExtIEs } }		OPTIONAL
+}
+
+SLDRBs-FailedToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-FailedToBeSetupMod-Item	::= SEQUENCE {
+	sLDRBID		SLDRBID	,
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-FailedToBeSetupMod-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-FailedToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-Modified-Item	::= SEQUENCE {
+	sLDRBID							SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-Modified-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-Modified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-ModifiedConf-Item	::= SEQUENCE {
+	sLDRBID							SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-ModifiedConf-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-ModifiedConf-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-Required-ToBeModified-Item	::= SEQUENCE {
+	sLDRBID							SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-Required-ToBeModified-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-Required-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-Required-ToBeReleased-Item	::= SEQUENCE {
+	sLDRBID		SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-Required-ToBeReleased-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-Required-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-Setup-Item ::= SEQUENCE {
+	sLDRBID							SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-Setup-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-Setup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-SetupMod-Item	::= SEQUENCE {
+	sLDRBID							SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-SetupMod-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-SetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-ToBeModified-Item	::= SEQUENCE {
+	sLDRBID						SLDRBID,
+	sLDRBInformation				SLDRBInformation		OPTIONAL,
+	rLCMode						RLCMode			OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-ToBeModified-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-ToBeReleased-Item	::= SEQUENCE {
+	sLDRBID	        SLDRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-ToBeReleased-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-ToBeSetup-Item ::= SEQUENCE	{
+	sLDRBID						SLDRBID,
+	sLDRBInformation				SLDRBInformation,
+	rLCMode						RLCMode, 
+
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-ToBeSetup-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SLDRBs-ToBeSetupMod-Item	::= SEQUENCE {
+	sLDRBID						SLDRBID,
+	sLDRBInformation				SLDRBInformation,
+	rLCMode						RLCMode			OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SLDRBs-ToBeSetupMod-ItemExtIEs } }	OPTIONAL
+}
+
+SLDRBs-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SL-PHY-MAC-RLC-Config ::= OCTET STRING
+
+SL-ConfigDedicatedEUTRA ::= OCTET STRING
+
+SliceAvailableCapacity ::= SEQUENCE {
+	sliceAvailableCapacityList	SliceAvailableCapacityList,
+	iE-Extensions				ProtocolExtensionContainer { { SliceAvailableCapacity-ExtIEs} } OPTIONAL
+}
+
+SliceAvailableCapacity-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SliceAvailableCapacityList ::= SEQUENCE (SIZE(1.. maxnoofBPLMNsNR)) OF SliceAvailableCapacityItem
+
+SliceAvailableCapacityItem ::= SEQUENCE {
+	pLMNIdentity					PLMN-Identity, 
+	sNSSAIAvailableCapacity-List	SNSSAIAvailableCapacity-List,
+	iE-Extensions	ProtocolExtensionContainer { { SliceAvailableCapacityItem-ExtIEs} } OPTIONAL
+}
+
+SliceAvailableCapacityItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SNSSAIAvailableCapacity-List ::= SEQUENCE (SIZE(1.. maxnoofSliceItems)) OF SNSSAIAvailableCapacity-Item
+
+SNSSAIAvailableCapacity-Item ::= SEQUENCE {
+	sNSSAI		SNSSAI,
+	sliceAvailableCapacityValueDownlink	INTEGER (0..100)	OPTIONAL, 
+	sliceAvailableCapacityValueUplink	INTEGER (0..100)	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { SNSSAIAvailableCapacity-Item-ExtIEs } }	OPTIONAL
+}
+
+SNSSAIAvailableCapacity-Item-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SliceSupportList ::= SEQUENCE (SIZE(1.. maxnoofSliceItems)) OF SliceSupportItem
+
+SliceSupportItem ::= SEQUENCE {
+	sNSSAI	SNSSAI,
+	iE-Extensions				ProtocolExtensionContainer { { SliceSupportItem-ExtIEs } }	OPTIONAL
+}
+
+SliceSupportItem-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SliceToReportList ::= SEQUENCE (SIZE(1.. maxnoofBPLMNsNR)) OF SliceToReportItem
+
+SliceToReportItem ::= SEQUENCE {
+	pLMNIdentity				PLMN-Identity, 
+	sNSSAIlist					SNSSAI-list,
+	iE-Extensions				ProtocolExtensionContainer { { SliceToReportItem-ExtIEs} } OPTIONAL
+}
+
+SliceToReportItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SlotNumber ::= INTEGER (0..79)
+
+SNSSAI-list ::= SEQUENCE (SIZE(1.. maxnoofSliceItems)) OF SNSSAI-Item
+
+SNSSAI-Item ::= SEQUENCE {
+	sNSSAI		SNSSAI,
+	iE-Extensions				ProtocolExtensionContainer { { SNSSAI-Item-ExtIEs } }	OPTIONAL
+}
+
+SNSSAI-Item-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Slot-Configuration-List ::= SEQUENCE (SIZE(1.. maxnoofslots)) OF Slot-Configuration-Item
+
+Slot-Configuration-Item ::= SEQUENCE {
+	slotIndex				INTEGER (0..5119, ...),
+	symbolAllocInSlot		SymbolAllocInSlot,
+	iE-Extensions	ProtocolExtensionContainer { { Slot-Configuration-ItemExtIEs } }	OPTIONAL
+}
+
+Slot-Configuration-ItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+SNSSAI ::= SEQUENCE {
+	sST			OCTET STRING (SIZE(1)),
+	sD			OCTET STRING (SIZE(3)) 	OPTIONAL	,
+	iE-Extensions				ProtocolExtensionContainer { { SNSSAI-ExtIEs } }	OPTIONAL
+}
+
+SNSSAI-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SpatialDirectionInformation ::= SEQUENCE {
+	nR-PRSBeamInformation			NR-PRSBeamInformation,
+	iE-Extensions					ProtocolExtensionContainer { { SpatialDirectionInformation-ExtIEs } } OPTIONAL
+}
+
+SpatialDirectionInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SpatialRelationInfo ::= SEQUENCE {
+	spatialRelationforResourceID					SpatialRelationforResourceID,
+	iE-Extensions		ProtocolExtensionContainer { {SpatialRelationInfo-ExtIEs} }	OPTIONAL
+}
+
+SpatialRelationInfo-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SpatialRelationforResourceID ::= SEQUENCE (SIZE(1..maxnoofSpatialRelations)) OF SpatialRelationforResourceIDItem
+
+SpatialRelationforResourceIDItem ::= SEQUENCE {
+	referenceSignal		ReferenceSignal,
+	iE-Extensions		ProtocolExtensionContainer { {SpatialRelationforResourceIDItem-ExtIEs} }	OPTIONAL
+}
+
+SpatialRelationforResourceIDItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SpatialRelationPos ::= CHOICE {
+	sSBPos					SSBPos,
+	pRSInformationPos		PRSInformationPos,
+	choice-extension		ProtocolIE-SingleContainer {{ SpatialInformationPos-ExtIEs }}
+}
+
+SpatialInformationPos-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+SpectrumSharingGroupID ::= INTEGER (1..maxCellineNB)
+
+SRBID ::= INTEGER (0..3, ...)
+
+SRBs-FailedToBeSetup-Item	::= SEQUENCE {
+	sRBID		SRBID	,
+	cause		Cause	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-FailedToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-FailedToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-FailedToBeSetupMod-Item	::= SEQUENCE {
+	sRBID		SRBID		,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-FailedToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-FailedToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-Modified-Item ::= SEQUENCE {
+	sRBID							SRBID,
+	lCID							LCID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-Modified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-Modified-ItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-Required-ToBeReleased-Item	::= SEQUENCE {
+	sRBID	SRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-Required-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-Required-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-Setup-Item ::= SEQUENCE {
+	sRBID							SRBID,
+	lCID								LCID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-Setup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-Setup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-SetupMod-Item ::= SEQUENCE {
+	sRBID						SRBID,
+	lCID							LCID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-SetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-SetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-ToBeReleased-Item	::= SEQUENCE {
+	sRBID		SRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-ToBeSetup-Item ::= SEQUENCE {
+	sRBID	 SRBID	,
+	duplicationIndication	DuplicationIndication	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-AdditionalDuplicationIndication	CRITICALITY ignore	EXTENSION AdditionalDuplicationIndication		PRESENCE optional	},
+	...
+}
+
+SRBs-ToBeSetupMod-Item	::= SEQUENCE {
+	sRBID	SRBID,
+	duplicationIndication	DuplicationIndication	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-ToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-AdditionalDuplicationIndication	CRITICALITY ignore	EXTENSION AdditionalDuplicationIndication		PRESENCE optional	},
+	...
+}
+
+SRSCarrier-List ::= SEQUENCE (SIZE(1.. maxnoSRS-Carriers)) OF SRSCarrier-List-Item
+
+SRSCarrier-List-Item ::= SEQUENCE {
+	pointA							INTEGER (0..3279165,...),
+	uplinkChannelBW-PerSCS-List		UplinkChannelBW-PerSCS-List,
+	activeULBWP						ActiveULBWP,
+	pci								NRPCI,
+	iE-Extensions					ProtocolExtensionContainer { { SRSCarrier-List-Item-ExtIEs } } OPTIONAL
+}
+
+SRSCarrier-List-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRSConfig  ::= SEQUENCE {
+	sRSResource-List			SRSResource-List 		OPTIONAL,
+	posSRSResource-List			PosSRSResource-List 	OPTIONAL,
+	sRSResourceSet-List			SRSResourceSet-List 	OPTIONAL,
+	posSRSResourceSet-List		PosSRSResourceSet-List 	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { SRSConfig-ExtIEs } } OPTIONAL
+}
+
+SRSConfig-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRSConfiguration ::= SEQUENCE {
+	sRSCarrier-List		SRSCarrier-List,
+	iE-Extensions		ProtocolExtensionContainer { { SRSConfiguration-ExtIEs } } OPTIONAL
+}
+
+SRSConfiguration-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+} 
+
+SRSPosResourceID ::= INTEGER (0..63, ...)
+
+SRSResource::= SEQUENCE {
+	sRSResourceID                  	SRSResourceID,
+	nrofSRS-Ports                   ENUMERATED {port1, ports2, ports4},
+	transmissionComb				TransmissionComb,
+	startPosition                   INTEGER (0..13),
+    nrofSymbols                     ENUMERATED {n1, n2, n4},
+    repetitionFactor              	ENUMERATED {n1, n2, n4},
+    freqDomainPosition              INTEGER (0..67),
+	freqDomainShift                 INTEGER (0..268),
+	c-SRS                           INTEGER (0..63),
+	b-SRS                           INTEGER (0..3),
+	b-hop                           INTEGER (0..3),
+	groupOrSequenceHopping          ENUMERATED { neither, groupHopping, sequenceHopping },
+	resourceType					ResourceType,
+	slotOffset						INTEGER (0..2559),
+	sequenceId                      INTEGER (0..1023),
+	iE-Extensions					ProtocolExtensionContainer { { SRSResource-ExtIEs } } OPTIONAL
+}
+
+SRSResource-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRSResourceID ::= INTEGER (0..63, ...)
+
+SRSResourceID-List::= SEQUENCE (SIZE (1..maxnoSRS-ResourcePerSet)) OF SRSResourceID
+
+SRSResource-List ::= SEQUENCE (SIZE (1..maxnoSRS-Resources)) OF SRSResource
+
+SRSResourceSet::= SEQUENCE {
+	sRSResourceSetID                SRSResourceSetID,
+	sRSResourceID-List				SRSResourceID-List,
+	resourceSetType					ResourceSetType,
+	iE-Extensions					ProtocolExtensionContainer { { SRSResourceSet-ExtIEs } } OPTIONAL
+}
+
+SRSResourceSet-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRSResourceSetID ::= INTEGER (0..15, ...)
+
+SRSResourceSetList ::= SEQUENCE (SIZE(1.. maxnoSRS-ResourceSets)) OF SRSResourceSetItem
+
+SRSResourceSetItem ::= SEQUENCE {
+	numSRSresourcesperset		INTEGER (1..16, ...)	OPTIONAL,
+	periodicityList				PeriodicityList			OPTIONAL,
+	spatialRelationInfo			SpatialRelationInfo		OPTIONAL,
+	pathlossReferenceInfo		PathlossReferenceInfo	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRSResourceSetItemExtIEs } }	OPTIONAL
+}
+
+SRSResourceSetItemExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRSResourceSet-List ::= SEQUENCE (SIZE (1..maxnoSRS-ResourceSets)) OF SRSResourceSet 
+
+SRSResourceTrigger ::= SEQUENCE {
+	aperiodicSRSResourceTriggerList					AperiodicSRSResourceTriggerList,
+	iE-Extensions		ProtocolExtensionContainer { {SRSResourceTrigger-ExtIEs} }	OPTIONAL
+}
+
+SRSResourceTrigger-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRSSpatialRelation ::= SEQUENCE {
+	spatialRelationforResourceID				SpatialRelationforResourceID,
+	iE-Extensions		ProtocolExtensionContainer { {SRSSpatialRelation-ExtIEs} }	OPTIONAL
+}
+
+SRSSpatialRelation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSB ::= SEQUENCE {
+	pCI-NR				NRPCI,
+	ssb-index			SSB-Index	OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { {SSB-ExtIEs} }	OPTIONAL
+}
+
+SSB-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSB-freqInfo ::= INTEGER (0..maxNRARFCN) 
+
+SSB-Index ::= INTEGER(0..63)
+
+SSBPos ::= SEQUENCE {
+	pCI-NR				NRPCI		OPTIONAL,
+	ssb-index			SSB-Index,
+	iE-Extensions		ProtocolExtensionContainer { {SSBPos-ExtIEs} }	OPTIONAL
+}
+
+SSBPos-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSB-subcarrierSpacing ::=  ENUMERATED {kHz15, kHz30, kHz120, kHz240, spare3, spare2, spare1, ...}
+
+SSB-transmissionPeriodicity	::= ENUMERATED {sf10, sf20, sf40, sf80, sf160, sf320, sf640, ...}
+
+SSB-transmissionTimingOffset ::= INTEGER (0..127, ...)
+
+SSB-transmissionBitmap ::= CHOICE {
+	shortBitmap			BIT STRING (SIZE (4)),
+	mediumBitmap		BIT STRING (SIZE (8)),
+	longBitmap			BIT STRING (SIZE (64)),
+	choice-extension	ProtocolIE-SingleContainer { { SSB-transmisisonBitmap-ExtIEs} }
+}
+
+SSB-transmisisonBitmap-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+SSBAreaCapacityValueList ::= SEQUENCE (SIZE(1.. maxnoofSSBAreas)) OF	SSBAreaCapacityValueItem
+
+SSBAreaCapacityValueItem ::= SEQUENCE {
+	sSBIndex				INTEGER(0..63),
+	sSBAreaCapacityValue	INTEGER (0..100),
+	iE-Extensions	ProtocolExtensionContainer { { SSBAreaCapacityValueItem-ExtIEs} } OPTIONAL
+}
+
+SSBAreaCapacityValueItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSBAreaRadioResourceStatusList::= SEQUENCE (SIZE(1.. maxnoofSSBAreas)) OF	SSBAreaRadioResourceStatusItem
+
+SSBAreaRadioResourceStatusItem::= SEQUENCE {
+	sSBIndex					INTEGER(0..63),
+	sSBAreaDLGBRPRBusage		INTEGER (0..100),
+	sSBAreaULGBRPRBusage		INTEGER (0..100),
+	sSBAreaDLnon-GBRPRBusage	INTEGER (0..100),
+	sSBAreaULnon-GBRPRBusage	INTEGER (0..100),
+	sSBAreaDLTotalPRBusage		INTEGER (0..100),
+	sSBAreaULTotalPRBusage		INTEGER (0..100),
+	dLschedulingPDCCHCCEusage	INTEGER (0..100)		OPTIONAL,
+	uLschedulingPDCCHCCEusage	INTEGER (0..100) 		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { SSBAreaRadioResourceStatusItem-ExtIEs} } OPTIONAL
+}
+
+SSBAreaRadioResourceStatusItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSBInformation ::= SEQUENCE {
+	sSBInformationList	SSBInformationList,
+	iE-Extensions	ProtocolExtensionContainer { { SSBInformation-ExtIEs } }	OPTIONAL
+}
+
+SSBInformation-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSBInformationList ::= SEQUENCE (SIZE(1.. maxnoofSSBs)) OF SSBInformationItem
+
+SSBInformationItem ::= SEQUENCE {
+	sSB-Configuration	SSB-TF-Configuration,
+	pCI-NR				NRPCI,
+	iE-Extensions	ProtocolExtensionContainer { { SSBInformationItem-ExtIEs } }	OPTIONAL
+}
+
+SSBInformationItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SSB-PositionsInBurst ::= CHOICE {
+	shortBitmap						BIT STRING (SIZE (4)),
+	mediumBitmap					BIT STRING (SIZE (8)),
+	longBitmap						BIT STRING (SIZE (64)),
+	choice-extension				ProtocolIE-SingleContainer { {SSB-PositionsInBurst-ExtIEs} }
+}
+
+SSB-PositionsInBurst-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+SSB-TF-Configuration ::= SEQUENCE {
+	sSB-frequency				INTEGER (0..3279165),
+	sSB-subcarrier-spacing		ENUMERATED {kHz15, kHz30, kHz60, kHz120, kHz240, ...},
+	sSB-Transmit-power			INTEGER (-60..50),
+	sSB-periodicity				ENUMERATED {ms5, ms10, ms20, ms40, ms80, ms160, ...},
+	sSB-half-frame-offset		INTEGER(0..1),
+	sSB-SFN-offset				INTEGER(0..15),
+	sSB-position-in-burst		SSB-PositionsInBurst		OPTIONAL,
+	sFNInitialisationTime		SFNInitialisationTime		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { SSB-TF-Configuration-ExtIEs} } OPTIONAL
+}
+
+SSB-TF-Configuration-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+SSBToReportList ::= SEQUENCE (SIZE(1.. maxnoofSSBAreas)) OF SSBToReportItem
+
+SSBToReportItem ::= SEQUENCE {
+	sSBIndex					INTEGER(0..63),
+	iE-Extensions				ProtocolExtensionContainer { { SSBToReportItem-ExtIEs} } OPTIONAL
+}
+
+SSBToReportItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SUL-Information ::= SEQUENCE {
+	sUL-NRARFCN							INTEGER (0..maxNRARFCN),
+	sUL-transmission-Bandwidth			Transmission-Bandwidth,
+	iE-Extensions				ProtocolExtensionContainer { { SUL-InformationExtIEs} } OPTIONAL,
+	...
+}
+
+SUL-InformationExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-CarrierList				CRITICALITY ignore	EXTENSION NRCarrierList			PRESENCE optional }|
+	{ ID id-FrequencyShift7p5khz	CRITICALITY ignore	EXTENSION FrequencyShift7p5khz	PRESENCE optional },
+	...
+}
+
+SubcarrierSpacing ::=	ENUMERATED { kHz15, kHz30, kHz60, kHz120, kHz240, spare3, spare2, spare1, ...}
+
+SubscriberProfileIDforRFP ::= INTEGER (1..256, ...)
+
+SULAccessIndication ::= ENUMERATED {true,...}
+
+
+SupportedSULFreqBandItem ::= SEQUENCE {
+	freqBandIndicatorNr 			INTEGER (1..1024,...),
+	iE-Extensions				ProtocolExtensionContainer { { SupportedSULFreqBandItem-ExtIEs} } OPTIONAL,
+	...
+}
+
+SupportedSULFreqBandItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SymbolAllocInSlot ::= CHOICE {
+	all-DL				NULL,
+	all-UL				NULL, 
+	both-DL-and-UL			NumDLULSymbols,	
+	choice-extension			ProtocolIE-SingleContainer { { SymbolAllocInSlot-ExtIEs } }
+}
+
+SymbolAllocInSlot-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+SystemFrameNumber ::= INTEGER (0..1023)
+
+SystemInformationAreaID ::=BIT STRING (SIZE (24))
+
+-- T
+
+FiveGS-TAC ::= OCTET STRING (SIZE(3))
+
+Configured-EPS-TAC ::= OCTET STRING (SIZE(2))
+
+TargetCellList ::= SEQUENCE (SIZE(1..maxnoofCHOcells)) OF TargetCellList-Item
+
+TargetCellList-Item ::= SEQUENCE {
+	target-cell								NRCGI,
+	iE-Extensions							ProtocolExtensionContainer { { TargetCellList-Item-ExtIEs} } OPTIONAL
+}
+
+TargetCellList-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TDD-Info ::= SEQUENCE {
+	nRFreqInfo							NRFreqInfo,
+	transmission-Bandwidth			Transmission-Bandwidth,
+	iE-Extensions				ProtocolExtensionContainer { {TDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ID	id-IntendedTDD-DL-ULConfig	CRITICALITY ignore	EXTENSION	IntendedTDD-DL-ULConfig	PRESENCE optional}|
+	{ID id-TDD-UL-DLConfigCommonNR	CRITICALITY ignore	EXTENSION TDD-UL-DLConfigCommonNR	PRESENCE optional }|
+	{ID id-CarrierList				CRITICALITY ignore	EXTENSION NRCarrierList				PRESENCE optional },
+	...
+}
+
+TDD-UL-DLConfigCommonNR ::= OCTET STRING
+
+TimeReferenceInformation ::= SEQUENCE {
+	referenceTime					ReferenceTime,
+	referenceSFN					ReferenceSFN,
+	uncertainty						Uncertainty,
+	timeInformationType				TimeInformationType,
+	iE-Extensions		ProtocolExtensionContainer { {TimeReferenceInformation-ExtIEs} }	OPTIONAL
+}
+
+TimeReferenceInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TimeInformationType ::= ENUMERATED {localClock}
+
+TimeStamp ::= SEQUENCE {
+	systemFrameNumber		SystemFrameNumber,
+	slotIndex				TimeStampSlotIndex,
+	measurementTime			SFNInitialisationTime	OPTIONAL,
+	iE-Extension			ProtocolExtensionContainer { { TimeStamp-ExtIEs} }	OPTIONAL
+}
+
+TimeStamp-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TimeStampSlotIndex ::= CHOICE {
+	sCS-15			INTEGER(0..9),
+	sCS-30			INTEGER(0..19),
+	sCS-60			INTEGER(0..39),
+	sCS-120			INTEGER(0..79),
+	choice-extension		ProtocolIE-SingleContainer { { TimeStampSlotIndex-ExtIEs} }
+}
+
+TimeStampSlotIndex-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...}
+
+TimingMeasurementQuality ::= SEQUENCE {
+	measurementQuality		INTEGER(0..31),
+	resolution				ENUMERATED{m0dot1, m1, m10, m30, ...},
+	iE-Extensions		ProtocolExtensionContainer { { TimingMeasurementQuality-ExtIEs} }	OPTIONAL
+}
+
+TimingMeasurementQuality-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TNLAssociationUsage ::= ENUMERATED {
+	ue,
+	non-ue,
+	both, 
+	...
+}
+
+TNLCapacityIndicator::= SEQUENCE {
+	dLTNLOfferedCapacity		INTEGER (1.. 16777216,...),
+	dLTNLAvailableCapacity		INTEGER (0.. 100,...),
+	uLTNLOfferedCapacity		INTEGER (1.. 16777216,...),
+	uLTNLAvailableCapacity		INTEGER (0.. 100,...),
+	iE-Extensions	ProtocolExtensionContainer { { TNLCapacityIndicator-ExtIEs} } OPTIONAL
+}
+
+TNLCapacityIndicator-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TraceActivation ::= SEQUENCE {
+	traceID								TraceID,
+	interfacesToTrace					InterfacesToTrace,
+	traceDepth							TraceDepth,
+	traceCollectionEntityIPAddress		TransportLayerAddress,
+	iE-Extensions		ProtocolExtensionContainer { {TraceActivation-ExtIEs} }	OPTIONAL
+}
+
+TraceActivation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ID id-mdtConfiguration	CRITICALITY ignore	EXTENSION	MDTConfiguration		PRESENCE optional}|
+	{ID id-TraceCollectionEntityURI	CRITICALITY ignore	EXTENSION URI-address		PRESENCE optional	},
+	...
+}
+
+TraceDepth ::= ENUMERATED { 
+	minimum,
+	medium,
+	maximum,
+	minimumWithoutVendorSpecificExtension,
+	mediumWithoutVendorSpecificExtension,
+	maximumWithoutVendorSpecificExtension,
+	...
+}
+
+TraceID ::= OCTET STRING (SIZE(8))
+
+TrafficMappingInfo	::= CHOICE {
+	iPtolayer2TrafficMappingInfo					IPtolayer2TrafficMappingInfo,
+	bAPlayerBHRLCchannelMappingInfo					BAPlayerBHRLCchannelMappingInfo,
+	choice-extension								ProtocolIE-SingleContainer { { TrafficMappingInfo-ExtIEs} }
+}
+
+TrafficMappingInfo-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TransportLayerAddress		::= BIT STRING (SIZE(1..160, ...))
+
+TransactionID				::= INTEGER (0..255, ...)
+
+Transmission-Bandwidth ::= SEQUENCE {
+	nRSCS	NRSCS,
+	nRNRB	NRNRB,
+	iE-Extensions				ProtocolExtensionContainer { { Transmission-Bandwidth-ExtIEs} } OPTIONAL,
+	...
+}
+
+Transmission-Bandwidth-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TransmissionComb ::= CHOICE {
+	n2    SEQUENCE {
+            combOffset-n2              INTEGER (0..1),
+            cyclicShift-n2             INTEGER (0..7)
+        },
+    n4    SEQUENCE {
+            combOffset-n4              INTEGER (0..3),
+            cyclicShift-n4             INTEGER (0..11)
+        },
+	choice-extension				ProtocolIE-SingleContainer { { TransmissionComb-ExtIEs} }
+}
+TransmissionComb-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TransmissionCombPos ::= CHOICE {
+	n2    SEQUENCE {
+            combOffset-n2              INTEGER (0..1),
+            cyclicShift-n2             INTEGER (0..7)
+        },
+    n4    SEQUENCE {
+            combOffset-n4              INTEGER (0..3),
+            cyclicShift-n4             INTEGER (0..11)
+        },
+    n8    SEQUENCE {
+            combOffset-n8              INTEGER (0..7),
+            cyclicShift-n8             INTEGER (0..5)
+        },
+
+	choice-extension				ProtocolIE-SingleContainer { { TransmissionCombPos-ExtIEs} }
+}
+TransmissionCombPos-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+Transport-UP-Layer-Address-Info-To-Add-List	::= SEQUENCE (SIZE(1.. maxnoofTLAs)) OF Transport-UP-Layer-Address-Info-To-Add-Item
+
+Transport-UP-Layer-Address-Info-To-Add-Item ::= SEQUENCE {
+	iP-SecTransportLayerAddress		TransportLayerAddress,
+	gTPTransportLayerAddressToAdd			GTPTLAs							OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { Transport-UP-Layer-Address-Info-To-Add-ItemExtIEs } }	OPTIONAL
+}
+
+Transport-UP-Layer-Address-Info-To-Add-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { 
+	...
+}
+
+Transport-UP-Layer-Address-Info-To-Remove-List	::= SEQUENCE (SIZE(1.. maxnoofTLAs)) OF Transport-UP-Layer-Address-Info-To-Remove-Item
+
+Transport-UP-Layer-Address-Info-To-Remove-Item ::= SEQUENCE {
+	iP-SecTransportLayerAddress		TransportLayerAddress,
+	gTPTransportLayerAddressToRemove			GTPTLAs							OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { Transport-UP-Layer-Address-Info-To-Remove-ItemExtIEs } }	OPTIONAL
+}
+
+Transport-UP-Layer-Address-Info-To-Remove-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { 
+	...
+}
+
+TransmissionActionIndicator ::= ENUMERATED {stop, ..., restart }
+
+TRPID ::= INTEGER (0.. maxnoofTRPs, ...)
+
+TRPInformation ::= SEQUENCE {
+	tRPID							TRPID,
+	tRPInformationTypeResponseList	TRPInformationTypeResponseList,
+	iE-Extensions					ProtocolExtensionContainer { { TRPInformation-ExtIEs } }		OPTIONAL
+}
+
+TRPInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TRPInformationItem ::= SEQUENCE {
+	tRPInformation					TRPInformation,
+	iE-Extensions					ProtocolExtensionContainer { { TRPInformationItem-ExtIEs } }	OPTIONAL
+}
+
+TRPInformationItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { 
+	...
+}
+
+TRPInformationTypeItem ::= ENUMERATED { 
+		nrPCI,
+		nG-RAN-CGI,
+		arfcn, 
+		pRSConfig,
+		sSBConfig,
+		sFNInitTime,
+		spatialDirectInfo,
+		geoCoord,
+...}
+
+
+TRPInformationTypeResponseList ::= SEQUENCE (SIZE(1.. maxnoofTRPInfoTypes)) OF TRPInformationTypeResponseItem 
+
+TRPInformationTypeResponseItem ::= CHOICE {
+	pCI-NR								NRPCI,
+	nG-RAN-CGI							NRCGI,
+	nRARFCN								INTEGER (0..maxNRARFCN),
+	pRSConfiguration					PRSConfiguration,
+	sSBinformation						SSBInformation,
+	sFNInitialisationTime				SFNInitialisationTime,
+	spatialDirectionInformation			SpatialDirectionInformation,
+	geographicalCoordinates				GeographicalCoordinates,
+	choice-extension					ProtocolIE-SingleContainer { { TRPInformationTypeResponseItem-ExtIEs} }
+}
+
+TRPInformationTypeResponseItem-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+
+TRPList ::= SEQUENCE (SIZE(1.. maxnoofTRPs)) OF TRPListItem
+
+TRPListItem ::= SEQUENCE {
+	tRPID							TRPID,
+	iE-Extensions					ProtocolExtensionContainer { { TRPListItem-ExtIEs } }	OPTIONAL
+}
+
+TRPListItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { 
+	...
+}
+
+TRPMeasurementQuality ::= SEQUENCE {
+	tRPmeasurementQuality-Item 	TRPMeasurementQuality-Item,
+	iE-Extensions				ProtocolExtensionContainer { {TRPMeasurementQuality-ExtIEs} } OPTIONAL
+}
+
+TRPMeasurementQuality-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TRPMeasurementQuality-Item ::= CHOICE {
+	timingMeasurementQuality	TimingMeasurementQuality,
+	angleMeasurementQuality		AngleMeasurementQuality,
+	choice-extension			ProtocolIE-SingleContainer { { TRPMeasurementQuality-Item-ExtIEs } }
+}
+
+TRPMeasurementQuality-Item-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TRP-MeasurementRequestList ::= SEQUENCE (SIZE (1..maxNoOfMeasTRPs)) OF TRP-MeasurementRequestItem
+
+TRP-MeasurementRequestItem ::= SEQUENCE {
+	tRPID							TRPID, 
+	search-window-information		Search-window-information	OPTIONAL, 
+	iE-extensions		ProtocolExtensionContainer { { TRP-MeasurementRequestItem-ExtIEs } } OPTIONAL
+}
+
+TRP-MeasurementRequestItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TRPPositionDefinitionType ::= CHOICE {
+	direct		TRPPositionDirect,
+	referenced	TRPPositionReferenced,
+	choice-extension							ProtocolIE-SingleContainer { { TRPPositionDefinitionType-ExtIEs } }
+}
+
+TRPPositionDefinitionType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TRPPositionDirect ::= SEQUENCE {
+	accuracy	TRPPositionDirectAccuracy,
+	iE-extensions		ProtocolExtensionContainer { { TRPPositionDirect-ExtIEs } }	OPTIONAL
+}
+
+TRPPositionDirect-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TRPPositionDirectAccuracy ::= CHOICE {
+	tRPPosition				AccessPointPosition,
+	tRPHAposition			NGRANHighAccuracyAccessPointPosition,
+	choice-extension		ProtocolIE-SingleContainer { { TRPPositionDirectAccuracy-ExtIEs } }
+}
+
+TRPPositionDirectAccuracy-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TRPPositionReferenced ::= SEQUENCE {
+	referencePoint					ReferencePoint,
+	referencePointType				TRPReferencePointType,
+	iE-extensions					ProtocolExtensionContainer { { TRPPositionReferenced-ExtIEs } } 	OPTIONAL
+}
+
+TRPPositionReferenced-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TRPReferencePointType ::= CHOICE {
+	tRPPositionRelativeGeodetic			RelativeGeodeticLocation,
+	tRPPositionRelativeCartesian		RelativeCartesianLocation,
+	choice-extension					ProtocolIE-SingleContainer { { TRPReferencePointType-ExtIEs } }
+}
+
+TRPReferencePointType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+TypeOfError ::= ENUMERATED {
+	not-understood,
+	missing,
+	...
+}
+
+Transport-Layer-Address-Info ::= SEQUENCE {
+	transport-UP-Layer-Address-Info-To-Add-List		Transport-UP-Layer-Address-Info-To-Add-List							OPTIONAL,
+	transport-UP-Layer-Address-Info-To-Remove-List	Transport-UP-Layer-Address-Info-To-Remove-List					OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { Transport-Layer-Address-Info-ExtIEs } }								OPTIONAL
+}
+
+Transport-Layer-Address-Info-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TSCAssistanceInformation ::= SEQUENCE {
+	periodicity				Periodicity,
+	burstArrivalTime		BurstArrivalTime													OPTIONAL,
+	iE-Extensions			ProtocolExtensionContainer { {TSCAssistanceInformation-ExtIEs} }	OPTIONAL,
+	...
+}
+
+TSCAssistanceInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TSCTrafficCharacteristics ::= SEQUENCE {
+	tSCAssistanceInformationDL		TSCAssistanceInformation								OPTIONAL,
+	tSCAssistanceInformationUL		TSCAssistanceInformation								OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { {TSCTrafficCharacteristics-ExtIEs} }	OPTIONAL,
+	...
+}
+
+TSCTrafficCharacteristics-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- U
+UAC-Assistance-Info ::= SEQUENCE {
+	uACPLMN-List		UACPLMN-List,
+	iE-Extensions		ProtocolExtensionContainer { { UAC-Assistance-InfoExtIEs} } OPTIONAL
+}
+
+UAC-Assistance-InfoExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UACPLMN-List ::= SEQUENCE (SIZE(1..maxnoofUACPLMNs)) OF UACPLMN-Item
+
+UACPLMN-Item::= SEQUENCE {
+	pLMNIdentity				PLMN-Identity,
+	uACType-List				UACType-List,	iE-Extensions		ProtocolExtensionContainer { { UACPLMN-Item-ExtIEs} } OPTIONAL
+}
+
+UACPLMN-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-NID	CRITICALITY ignore	EXTENSION NID	PRESENCE optional },
+	...
+}
+
+UACType-List ::= SEQUENCE (SIZE(1..maxnoofUACperPLMN)) OF UACType-Item
+
+UACType-Item::= SEQUENCE {
+	uACReductionIndication 		UACReductionIndication,
+	uACCategoryType				UACCategoryType,
+	iE-Extensions		ProtocolExtensionContainer { { UACType-Item-ExtIEs } } OPTIONAL
+}
+
+UACType-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UACCategoryType ::= CHOICE {
+	uACstandardized				UACAction,
+	uACOperatorDefined			UACOperatorDefined, 
+	choice-extension			ProtocolIE-SingleContainer { { UACCategoryType-ExtIEs } }
+}
+
+UACCategoryType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+UACOperatorDefined ::= SEQUENCE {
+	accessCategory					INTEGER (32..63,...),
+	accessIdentity					BIT STRING (SIZE(7)),
+	iE-Extensions		ProtocolExtensionContainer { { UACOperatorDefined-ExtIEs} } OPTIONAL
+}
+
+UACOperatorDefined-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+UACAction ::= ENUMERATED {
+	reject-non-emergency-mo-dt,
+	reject-rrc-cr-signalling,
+	permit-emergency-sessions-and-mobile-terminated-services-only,
+	permit-high-priority-sessions-and-mobile-terminated-services-only,
+	...
+}
+
+UACReductionIndication ::= INTEGER (0..100)
+
+
+UE-associatedLogicalF1-ConnectionItem ::= SEQUENCE {
+	gNB-CU-UE-F1AP-ID		GNB-CU-UE-F1AP-ID	 OPTIONAL,
+	gNB-DU-UE-F1AP-ID		GNB-DU-UE-F1AP-ID	 OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { UE-associatedLogicalF1-ConnectionItemExtIEs} } OPTIONAL,
+	...
+}
+
+UEAssistanceInformation ::= OCTET STRING
+
+UEAssistanceInformationEUTRA ::= OCTET STRING
+
+UE-associatedLogicalF1-ConnectionItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UE-CapabilityRAT-ContainerList::= OCTET STRING
+
+UEContextNotRetrievable ::= ENUMERATED {true, ...}
+
+UEIdentityIndexValue ::= CHOICE {
+	indexLength10			BIT STRING (SIZE (10)),
+	choice-extension		ProtocolIE-SingleContainer { {UEIdentityIndexValueChoice-ExtIEs} }	
+}
+
+UEIdentityIndexValueChoice-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+UL-AoA ::= SEQUENCE {
+	azimuthAoA				INTEGER (0..3599),
+	zenithAoA				INTEGER (0..1799)	OPTIONAL,
+	angleCoordinateSystem	ENUMERATED {lCS, gCS}	OPTIONAL,
+	iE-extensions			ProtocolExtensionContainer { { UL-AoA-ExtIEs } }
+}
+
+UL-AoA-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UL-BH-Non-UP-Traffic-Mapping ::= SEQUENCE {
+	uL-BH-Non-UP-Traffic-Mapping-List			UL-BH-Non-UP-Traffic-Mapping-List,
+	iE-Extensions	ProtocolExtensionContainer { { UL-BH-Non-UP-Traffic-Mapping-ExtIEs } } OPTIONAL
+}
+
+UL-BH-Non-UP-Traffic-Mapping-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UL-BH-Non-UP-Traffic-Mapping-List ::= SEQUENCE (SIZE(1..maxnoofNonUPTrafficMappings)) OF UL-BH-Non-UP-Traffic-Mapping-Item
+
+UL-BH-Non-UP-Traffic-Mapping-Item ::= SEQUENCE {
+	nonUPTrafficType				NonUPTrafficType,
+	bHInfo						BHInfo,
+	iE-Extensions					ProtocolExtensionContainer { { UL-BH-Non-UP-Traffic-Mapping-ItemExtIEs } }	OPTIONAL
+}
+
+UL-BH-Non-UP-Traffic-Mapping-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { 
+	...
+}
+
+ULConfiguration ::= SEQUENCE	{
+	uLUEConfiguration		ULUEConfiguration,
+	iE-Extensions	ProtocolExtensionContainer { { ULConfigurationExtIEs } }	OPTIONAL,
+	...
+}
+ULConfigurationExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UL-RTOA-Measurement ::= SEQUENCE {
+	uL-RTOA-MeasurementItem		UL-RTOA-MeasurementItem,
+	additionalPath-List			AdditionalPath-List OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { UL-RTOA-Measurement-ExtIEs } }	OPTIONAL
+}
+
+UL-RTOA-Measurement-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UL-RTOA-MeasurementItem ::= CHOICE {
+	k0					INTEGER (0..1970049),
+	k1					INTEGER (0..985025),
+	k2					INTEGER (0..492513),
+	k3					INTEGER (0..246257),
+	k4					INTEGER (0..123129),
+	k5					INTEGER (0..61565),	 
+	choice-extension			ProtocolIE-SingleContainer { { UL-RTOA-MeasurementItem-ExtIEs } }
+}
+
+UL-RTOA-MeasurementItem-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+UL-SRS-RSRP ::= INTEGER (0..127)
+
+ULUEConfiguration ::= ENUMERATED {no-data, shared, only, ...}
+
+UL-UP-TNL-Information-to-Update-List-Item	::= SEQUENCE {
+	uLUPTNLInformation		UPTransportLayerInformation,
+	newULUPTNLInformation	UPTransportLayerInformation		OPTIONAL,
+	bHInfo	BHInfo,
+	iE-Extensions	ProtocolExtensionContainer { { UL-UP-TNL-Information-to-Update-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+UL-UP-TNL-Information-to-Update-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UL-UP-TNL-Address-to-Update-List-Item	::= SEQUENCE {
+	oldIPAdress						TransportLayerAddress,
+	newIPAdress						TransportLayerAddress,
+	iE-Extensions	ProtocolExtensionContainer { { UL-UP-TNL-Address-to-Update-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+UL-UP-TNL-Address-to-Update-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ULUPTNLInformation-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofULUPTNLInformation)) OF ULUPTNLInformation-ToBeSetup-Item
+
+ULUPTNLInformation-ToBeSetup-Item ::=SEQUENCE {
+	uLUPTNLInformation		UPTransportLayerInformation, 
+	iE-Extensions	ProtocolExtensionContainer { { ULUPTNLInformation-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+ULUPTNLInformation-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	{ ID id-BHInfo		CRITICALITY ignore	EXTENSION BHInfo		PRESENCE optional	},
+	...
+}
+
+Uncertainty ::= INTEGER (0..32767, ...)
+
+UplinkChannelBW-PerSCS-List ::= SEQUENCE (SIZE (1..maxnoSCSs)) OF SCS-SpecificCarrier
+
+UplinkTxDirectCurrentListInformation ::= OCTET STRING
+
+UPTransportLayerInformation		::= CHOICE {
+	gTPTunnel		GTPTunnel,
+	choice-extension			ProtocolIE-SingleContainer { { UPTransportLayerInformation-ExtIEs} }
+}
+
+UPTransportLayerInformation-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+URI-address ::= VisibleString
+
+-- V
+
+VictimgNBSetID ::= SEQUENCE {
+	victimgNBSetID		GNBSetID,
+	iE-Extensions	ProtocolExtensionContainer { { VictimgNBSetID-ExtIEs } }		OPTIONAL
+}
+
+VictimgNBSetID-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+VehicleUE ::= ENUMERATED { 
+	authorized,
+	not-authorized,
+	...
+}
+
+PedestrianUE ::= ENUMERATED { 
+	authorized,
+	not-authorized,
+	...
+}
+
+-- W
+
+-- X
+
+-- Y
+
+-- Z
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-PDU-Contents.asn b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-PDU-Contents.asn
new file mode 100644
index 0000000000000000000000000000000000000000..ba6351eddd286d9b17df7eb2b9a17819d40802f5
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-PDU-Contents.asn
@@ -0,0 +1,3633 @@
+-- **************************************************************
+--
+-- PDU definitions for F1AP.
+--
+-- **************************************************************
+
+F1AP-PDU-Contents { 
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Contents (1) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	Candidate-SpCell-Item,
+	Cause,
+	Cells-Failed-to-be-Activated-List-Item,
+	Cells-Status-Item,
+	Cells-to-be-Activated-List-Item,
+	Cells-to-be-Deactivated-List-Item, 
+	CellULConfigured,
+	CriticalityDiagnostics, 
+	C-RNTI,
+	CUtoDURRCInformation, 
+	DRB-Activity-Item,
+	DRBID,
+	DRBs-FailedToBeModified-Item,
+	DRBs-FailedToBeSetup-Item,
+	DRBs-FailedToBeSetupMod-Item,
+	DRB-Notify-Item,
+	DRBs-ModifiedConf-Item,
+	DRBs-Modified-Item,
+	DRBs-Required-ToBeModified-Item,
+	DRBs-Required-ToBeReleased-Item,
+	DRBs-Setup-Item,
+	DRBs-SetupMod-Item,
+	DRBs-ToBeModified-Item,
+	DRBs-ToBeReleased-Item,
+	DRBs-ToBeSetup-Item,
+	DRBs-ToBeSetupMod-Item,
+	DRXCycle,
+	DRXConfigurationIndicator,
+	DUtoCURRCInformation,
+	EUTRANQoS,
+	ExecuteDuplication,
+	FullConfiguration,
+	GNB-CU-UE-F1AP-ID,
+	GNB-DU-UE-F1AP-ID,
+	GNB-DU-ID,
+	GNB-DU-Served-Cells-Item,
+	GNB-DU-System-Information, 
+	GNB-CU-Name,
+	GNB-DU-Name,
+	InactivityMonitoringRequest,
+	InactivityMonitoringResponse,
+	LowerLayerPresenceStatusChange,
+	NotificationControl,
+	NRCGI,
+	NRPCI,
+	UEContextNotRetrievable,
+	Potential-SpCell-Item,
+	RAT-FrequencyPriorityInformation,
+	RequestedSRSTransmissionCharacteristics,
+	ResourceCoordinationTransferContainer,
+	RRCContainer,
+	RRCContainer-RRCSetupComplete,
+	RRCReconfigurationCompleteIndicator,
+	SCellIndex,
+	SCell-ToBeRemoved-Item,
+	SCell-ToBeSetup-Item,
+	SCell-ToBeSetupMod-Item,
+	SCell-FailedtoSetup-Item,
+	SCell-FailedtoSetupMod-Item, 
+	ServCellIndex,
+	Served-Cell-Information,
+	Served-Cells-To-Add-Item,
+	Served-Cells-To-Delete-Item,
+	Served-Cells-To-Modify-Item,
+	ServingCellMO,
+	SRBID,
+	SRBs-FailedToBeSetup-Item,
+	SRBs-FailedToBeSetupMod-Item,
+	SRBs-Required-ToBeReleased-Item,
+	SRBs-ToBeReleased-Item,
+	SRBs-ToBeSetup-Item,
+	SRBs-ToBeSetupMod-Item,
+	SRBs-Modified-Item,
+	SRBs-Setup-Item,
+	SRBs-SetupMod-Item,
+	TimeToWait,
+	TransactionID,
+	TransmissionActionIndicator,
+	UE-associatedLogicalF1-ConnectionItem,
+	DUtoCURRCContainer,
+	PagingCell-Item, 
+	SItype-List,
+	UEIdentityIndexValue,
+	GNB-CU-TNL-Association-Setup-Item,
+	GNB-CU-TNL-Association-Failed-To-Setup-Item,
+	GNB-CU-TNL-Association-To-Add-Item,
+	GNB-CU-TNL-Association-To-Remove-Item,
+	GNB-CU-TNL-Association-To-Update-Item,
+	MaskedIMEISV,
+	PagingDRX,
+	PagingPriority,
+	PagingIdentity,
+	Cells-to-be-Barred-Item,
+	PWSSystemInformation,
+	Broadcast-To-Be-Cancelled-Item,
+	Cells-Broadcast-Cancelled-Item,
+	NR-CGI-List-For-Restart-Item,
+	PWS-Failed-NR-CGI-Item,
+	RepetitionPeriod,
+	NumberofBroadcastRequest,
+	Cells-To-Be-Broadcast-Item,
+	Cells-Broadcast-Completed-Item,
+	Cancel-all-Warning-Messages-Indicator,
+	EUTRA-NR-CellResourceCoordinationReq-Container,
+	EUTRA-NR-CellResourceCoordinationReqAck-Container,
+	RequestType,
+	PLMN-Identity,
+	RLCFailureIndication, 
+	UplinkTxDirectCurrentListInformation,
+	SULAccessIndication,
+	Protected-EUTRA-Resources-Item,
+	GNB-DUConfigurationQuery,
+	BitRate,
+	RRC-Version,
+	GNBDUOverloadInformation,
+	RRCDeliveryStatusRequest,
+	NeedforGap,
+	RRCDeliveryStatus,
+	ResourceCoordinationTransferInformation,
+	Dedicated-SIDelivery-NeededUE-Item,
+	Associated-SCell-Item,
+	IgnoreResourceCoordinationContainer,
+	PagingOrigin,
+	UAC-Assistance-Info,
+	RANUEID,
+	GNB-DU-TNL-Association-To-Remove-Item,
+	NotificationInformation,
+	TraceActivation,
+	TraceID,
+	Neighbour-Cell-Information-Item,
+	SymbolAllocInSlot,
+	NumDLULSymbols,
+	AdditionalRRMPriorityIndex,
+	DUCURadioInformationType,
+	CUDURadioInformationType,
+	Transport-Layer-Address-Info,
+	BHChannels-ToBeSetup-Item,
+	BHChannels-Setup-Item,
+	BHChannels-FailedToBeSetup-Item,
+	BHChannels-ToBeModified-Item,
+	BHChannels-ToBeReleased-Item,
+	BHChannels-ToBeSetupMod-Item,
+	BHChannels-FailedToBeModified-Item,
+	BHChannels-FailedToBeSetupMod-Item,
+	BHChannels-Modified-Item,
+	BHChannels-SetupMod-Item,
+	BHChannels-Required-ToBeReleased-Item,
+	BAPAddress,
+	BAPPathID,
+	BAPRoutingID,
+	BH-Routing-Information-Added-List-Item,
+	BH-Routing-Information-Removed-List-Item,
+	Child-Nodes-List,
+	Child-Nodes-List-Item,
+	Child-Node-Cells-List,
+	Child-Node-Cells-List-Item,
+	Activated-Cells-to-be-Updated-List,
+	Activated-Cells-to-be-Updated-List-Item,
+	UL-BH-Non-UP-Traffic-Mapping,
+	IABTNLAddressesRequested,
+	IABIPv6RequestType,
+	IAB-TNL-Addresses-To-Remove-Item,
+	IABTNLAddress,
+	IAB-Allocated-TNL-Address-Item,
+	IABv4AddressesRequested,
+	TrafficMappingInfo,
+	UL-UP-TNL-Information-to-Update-List-Item,
+	UL-UP-TNL-Address-to-Update-List-Item,
+	DL-UP-TNL-Address-to-Update-List-Item,
+	NRV2XServicesAuthorized,
+	LTEV2XServicesAuthorized,
+	NRUESidelinkAggregateMaximumBitrate,
+	LTEUESidelinkAggregateMaximumBitrate,
+	SLDRBs-SetupMod-Item,
+	SLDRBs-ModifiedConf-Item,
+	SLDRBID,
+	SLDRBs-FailedToBeModified-Item,
+	SLDRBs-FailedToBeSetup-Item,
+	SLDRBs-FailedToBeSetupMod-Item,
+	SLDRBs-Modified-Item,
+	SLDRBs-Required-ToBeModified-Item,
+	SLDRBs-Required-ToBeReleased-Item,
+	SLDRBs-Setup-Item,
+	SLDRBs-ToBeModified-Item,
+	SLDRBs-ToBeReleased-Item,
+	SLDRBs-ToBeSetup-Item,
+	SLDRBs-ToBeSetupMod-Item,
+	GNBCUMeasurementID,
+	GNBDUMeasurementID,
+	RegistrationRequest,
+	ReportCharacteristics,
+	CellToReportList,
+	HardwareLoadIndicator,
+	CellMeasurementResultList,
+	ReportingPeriodicity,
+	TNLCapacityIndicator,
+	RACHReportInformationList,
+	RLFReportInformationList,
+	ReportingRequestType,
+	TimeReferenceInformation,
+	ConditionalInterDUMobilityInformation,
+	ConditionalIntraDUMobilityInformation,
+	TargetCellList,
+	MDTPLMNList,
+	PrivacyIndicator,
+	TransportLayerAddress,
+	URI-address,
+	NID,
+	PosAssistance-Information,
+	PosBroadcast,
+	PositioningBroadcastCells,
+	RoutingID,
+	PosAssistanceInformationFailureList,
+	PosMeasurementQuantities,
+	PosMeasurementResultList,
+	PosMeasurementPeriodicity,
+	PosReportCharacteristics,
+	TRPInformationTypeItem,
+	TRPInformationItem,
+	LMF-MeasurementID,
+	RAN-MeasurementID,
+	SRSResourceSetID,
+	SRSSpatialRelation,
+	SRSResourceTrigger,
+	SRSConfiguration,
+	TRPList,
+	E-CID-MeasurementQuantities,
+	E-CID-MeasurementPeriodicity,
+	E-CID-MeasurementResult,
+	Cell-Portion-ID,
+	LMF-UE-MeasurementID,
+	RAN-UE-MeasurementID,
+	SFNInitialisationTime,
+	SystemFrameNumber,
+	SlotNumber,
+	AbortTransmission,
+	TRP-MeasurementRequestList,
+	MeasurementBeamInfoRequest,
+	E-CID-ReportCharacteristics,
+	Extended-GNB-CU-Name,
+	Extended-GNB-DU-Name
+
+
+
+FROM F1AP-IEs
+
+	PrivateIE-Container{},
+	ProtocolExtensionContainer{},
+	ProtocolIE-Container{},
+	ProtocolIE-ContainerPair{},
+	ProtocolIE-SingleContainer{},
+	F1AP-PRIVATE-IES,
+	F1AP-PROTOCOL-EXTENSION,
+	F1AP-PROTOCOL-IES,
+	F1AP-PROTOCOL-IES-PAIR
+
+FROM F1AP-Containers
+
+	id-Candidate-SpCell-Item,
+	id-Candidate-SpCell-List,
+	id-Cause,
+	id-Cancel-all-Warning-Messages-Indicator,
+	id-Cells-Failed-to-be-Activated-List,
+	id-Cells-Failed-to-be-Activated-List-Item, 
+	id-Cells-Status-Item,
+	id-Cells-Status-List,
+	id-Cells-to-be-Activated-List,
+	id-Cells-to-be-Activated-List-Item,
+	id-Cells-to-be-Deactivated-List,
+	id-Cells-to-be-Deactivated-List-Item,
+	id-ConfirmedUEID,
+	id-CriticalityDiagnostics,
+	id-C-RNTI,
+	id-CUtoDURRCInformation,
+	id-DRB-Activity-Item,
+	id-DRB-Activity-List,
+	id-DRBs-FailedToBeModified-Item,
+	id-DRBs-FailedToBeModified-List,
+	id-DRBs-FailedToBeSetup-Item,
+	id-DRBs-FailedToBeSetup-List,
+	id-DRBs-FailedToBeSetupMod-Item,
+	id-DRBs-FailedToBeSetupMod-List,
+	id-DRBs-ModifiedConf-Item,
+	id-DRBs-ModifiedConf-List,
+	id-DRBs-Modified-Item,
+	id-DRBs-Modified-List,
+	id-DRB-Notify-Item,
+	id-DRB-Notify-List,
+	id-DRBs-Required-ToBeModified-Item,
+	id-DRBs-Required-ToBeModified-List,
+	id-DRBs-Required-ToBeReleased-Item,
+	id-DRBs-Required-ToBeReleased-List,
+	id-DRBs-Setup-Item,
+	id-DRBs-Setup-List,
+	id-DRBs-SetupMod-Item,
+	id-DRBs-SetupMod-List,
+	id-DRBs-ToBeModified-Item,
+	id-DRBs-ToBeModified-List,
+	id-DRBs-ToBeReleased-Item,
+	id-DRBs-ToBeReleased-List,
+	id-DRBs-ToBeSetup-Item,
+	id-DRBs-ToBeSetup-List,
+	id-DRBs-ToBeSetupMod-Item,
+	id-DRBs-ToBeSetupMod-List,
+	id-DRXCycle,
+	id-DUtoCURRCInformation,
+	id-ExecuteDuplication,
+	id-FullConfiguration,
+	id-gNB-CU-UE-F1AP-ID,
+	id-gNB-DU-UE-F1AP-ID,
+	id-gNB-DU-ID,
+	id-GNB-DU-Served-Cells-Item,
+	id-gNB-DU-Served-Cells-List, 
+	id-gNB-CU-Name,
+	id-gNB-DU-Name,
+	id-Extended-GNB-CU-Name,
+	id-Extended-GNB-DU-Name,
+	id-InactivityMonitoringRequest,
+	id-InactivityMonitoringResponse,
+	id-new-gNB-CU-UE-F1AP-ID,
+	id-new-gNB-DU-UE-F1AP-ID,
+	id-oldgNB-DU-UE-F1AP-ID,
+	id-PLMNAssistanceInfoForNetShar,
+	id-Potential-SpCell-Item,
+	id-Potential-SpCell-List,
+	id-RAT-FrequencyPriorityInformation, 
+	id-RedirectedRRCmessage,
+	id-ResetType,
+	id-RequestedSRSTransmissionCharacteristics,
+	id-ResourceCoordinationTransferContainer,
+	id-RRCContainer,
+	id-RRCContainer-RRCSetupComplete,
+	id-RRCReconfigurationCompleteIndicator,
+	id-SCell-FailedtoSetup-List,
+	id-SCell-FailedtoSetup-Item,
+	id-SCell-FailedtoSetupMod-List,
+	id-SCell-FailedtoSetupMod-Item,
+	id-SCell-ToBeRemoved-Item,
+	id-SCell-ToBeRemoved-List,
+	id-SCell-ToBeSetup-Item,
+	id-SCell-ToBeSetup-List,
+	id-SCell-ToBeSetupMod-Item,
+	id-SCell-ToBeSetupMod-List,
+	id-SelectedPLMNID,
+	id-Served-Cells-To-Add-Item,
+	id-Served-Cells-To-Add-List,
+	id-Served-Cells-To-Delete-Item,
+	id-Served-Cells-To-Delete-List,
+	id-Served-Cells-To-Modify-Item,
+	id-Served-Cells-To-Modify-List,
+	id-ServCellIndex,
+	id-ServingCellMO,
+	id-SpCell-ID,
+	id-SpCellULConfigured,
+	id-SRBID,
+	id-SRBs-FailedToBeSetup-Item,
+	id-SRBs-FailedToBeSetup-List,
+	id-SRBs-FailedToBeSetupMod-Item,
+	id-SRBs-FailedToBeSetupMod-List,
+	id-SRBs-Required-ToBeReleased-Item,
+	id-SRBs-Required-ToBeReleased-List,
+	id-SRBs-ToBeReleased-Item,
+	id-SRBs-ToBeReleased-List, 
+	id-SRBs-ToBeSetup-Item,
+	id-SRBs-ToBeSetup-List,
+	id-SRBs-ToBeSetupMod-Item,
+	id-SRBs-ToBeSetupMod-List,
+	id-SRBs-Modified-Item,
+	id-SRBs-Modified-List,
+	id-SRBs-Setup-Item,
+	id-SRBs-Setup-List,
+	id-SRBs-SetupMod-Item,
+	id-SRBs-SetupMod-List,
+	id-TimeToWait,
+	id-TransactionID,
+	id-TransmissionActionIndicator, 
+	id-UEContextNotRetrievable,
+	id-UE-associatedLogicalF1-ConnectionItem,
+	id-UE-associatedLogicalF1-ConnectionListResAck,
+	id-DUtoCURRCContainer,
+	id-NRCGI,
+	id-PagingCell-Item,
+	id-PagingCell-List,
+	id-PagingDRX,
+	id-PagingPriority,
+	id-SItype-List,
+	id-UEIdentityIndexValue,
+	id-GNB-CU-TNL-Association-Setup-List,
+	id-GNB-CU-TNL-Association-Setup-Item,
+	id-GNB-CU-TNL-Association-Failed-To-Setup-List,
+	id-GNB-CU-TNL-Association-Failed-To-Setup-Item,
+	id-GNB-CU-TNL-Association-To-Add-Item,
+	id-GNB-CU-TNL-Association-To-Add-List,
+	id-GNB-CU-TNL-Association-To-Remove-Item,
+	id-GNB-CU-TNL-Association-To-Remove-List,
+	id-GNB-CU-TNL-Association-To-Update-Item,
+	id-GNB-CU-TNL-Association-To-Update-List,
+	id-MaskedIMEISV,
+	id-PagingIdentity,
+	id-Cells-to-be-Barred-List,
+	id-Cells-to-be-Barred-Item,
+	id-PWSSystemInformation,
+	id-RepetitionPeriod,
+	id-NumberofBroadcastRequest,
+	id-Cells-To-Be-Broadcast-List,
+	id-Cells-To-Be-Broadcast-Item,
+	id-Cells-Broadcast-Completed-List,
+	id-Cells-Broadcast-Completed-Item,
+	id-Broadcast-To-Be-Cancelled-List,
+	id-Broadcast-To-Be-Cancelled-Item,
+	id-Cells-Broadcast-Cancelled-List,
+	id-Cells-Broadcast-Cancelled-Item,
+	id-NR-CGI-List-For-Restart-List,
+	id-NR-CGI-List-For-Restart-Item,
+	id-PWS-Failed-NR-CGI-List,
+	id-PWS-Failed-NR-CGI-Item,
+	id-EUTRA-NR-CellResourceCoordinationReq-Container,
+	id-EUTRA-NR-CellResourceCoordinationReqAck-Container,
+	id-Protected-EUTRA-Resources-List,
+	id-RequestType,
+	id-ServingPLMN,
+	id-DRXConfigurationIndicator,
+	id-RLCFailureIndication,
+	id-UplinkTxDirectCurrentListInformation,
+	id-SULAccessIndication,
+	id-Protected-EUTRA-Resources-Item,
+	id-GNB-DUConfigurationQuery,
+	id-GNB-DU-UE-AMBR-UL,
+	id-GNB-CU-RRC-Version,
+	id-GNB-DU-RRC-Version,
+	id-GNBDUOverloadInformation,
+	id-NeedforGap,
+	id-RRCDeliveryStatusRequest,
+	id-RRCDeliveryStatus,
+	id-Dedicated-SIDelivery-NeededUE-List,
+	id-Dedicated-SIDelivery-NeededUE-Item,
+	id-ResourceCoordinationTransferInformation,
+	id-Associated-SCell-List,
+	id-Associated-SCell-Item,
+	id-IgnoreResourceCoordinationContainer,
+	id-UAC-Assistance-Info,
+	id-RANUEID,
+	id-PagingOrigin,
+	id-GNB-DU-TNL-Association-To-Remove-Item,
+	id-GNB-DU-TNL-Association-To-Remove-List,
+	id-NotificationInformation,
+	id-TraceActivation,
+	id-TraceID,
+	id-Neighbour-Cell-Information-List,
+	id-Neighbour-Cell-Information-Item,
+	id-SymbolAllocInSlot,
+	id-NumDLULSymbols,
+	id-AdditionalRRMPriorityIndex,
+	id-DUCURadioInformationType,
+	id-CUDURadioInformationType,
+	id-LowerLayerPresenceStatusChange,
+	id-Transport-Layer-Address-Info,
+	id-BHChannels-ToBeSetup-List,
+	id-BHChannels-ToBeSetup-Item,
+	id-BHChannels-Setup-List,
+	id-BHChannels-Setup-Item,
+	id-BHChannels-ToBeModified-Item,
+	id-BHChannels-ToBeModified-List,
+	id-BHChannels-ToBeReleased-Item,
+	id-BHChannels-ToBeReleased-List,
+	id-BHChannels-ToBeSetupMod-Item,
+	id-BHChannels-ToBeSetupMod-List,
+	id-BHChannels-FailedToBeSetup-Item,
+	id-BHChannels-FailedToBeSetup-List,
+	id-BHChannels-FailedToBeModified-Item,
+	id-BHChannels-FailedToBeModified-List,
+	id-BHChannels-FailedToBeSetupMod-Item,
+	id-BHChannels-FailedToBeSetupMod-List,
+	id-BHChannels-Modified-Item,
+	id-BHChannels-Modified-List,
+	id-BHChannels-SetupMod-Item,
+	id-BHChannels-SetupMod-List,
+	id-BHChannels-Required-ToBeReleased-Item,
+	id-BHChannels-Required-ToBeReleased-List,
+	id-BAPAddress,
+	id-ConfiguredBAPAddress,
+	id-BH-Routing-Information-Added-List,
+	id-BH-Routing-Information-Added-List-Item,
+	id-BH-Routing-Information-Removed-List,
+	id-BH-Routing-Information-Removed-List-Item,
+	id-UL-BH-Non-UP-Traffic-Mapping,
+	id-Child-Nodes-List,
+	id-Activated-Cells-to-be-Updated-List, 
+	id-IABIPv6RequestType,
+	id-IAB-TNL-Addresses-To-Remove-List,
+	id-IAB-TNL-Addresses-To-Remove-Item,
+	id-IAB-Allocated-TNL-Address-List,
+	id-IAB-Allocated-TNL-Address-Item,
+	id-IABv4AddressesRequested,
+	id-TrafficMappingInformation,
+	id-UL-UP-TNL-Information-to-Update-List,
+	id-UL-UP-TNL-Information-to-Update-List-Item,
+	id-UL-UP-TNL-Address-to-Update-List,
+	id-UL-UP-TNL-Address-to-Update-List-Item,
+	id-DL-UP-TNL-Address-to-Update-List,
+	id-DL-UP-TNL-Address-to-Update-List-Item,
+	id-NRV2XServicesAuthorized,
+	id-LTEV2XServicesAuthorized,
+	id-NRUESidelinkAggregateMaximumBitrate,
+	id-LTEUESidelinkAggregateMaximumBitrate,
+	id-PC5LinkAMBR,
+	id-SLDRBs-FailedToBeModified-Item,
+	id-SLDRBs-FailedToBeModified-List,
+	id-SLDRBs-FailedToBeSetup-Item,
+	id-SLDRBs-FailedToBeSetup-List,
+	id-SLDRBs-Modified-Item,
+	id-SLDRBs-Modified-List,
+	id-SLDRBs-Required-ToBeModified-Item,
+	id-SLDRBs-Required-ToBeModified-List,
+	id-SLDRBs-Required-ToBeReleased-Item,
+	id-SLDRBs-Required-ToBeReleased-List,
+	id-SLDRBs-Setup-Item,
+	id-SLDRBs-Setup-List,
+	id-SLDRBs-ToBeModified-Item,
+	id-SLDRBs-ToBeModified-List,
+	id-SLDRBs-ToBeReleased-Item,
+	id-SLDRBs-ToBeReleased-List,
+	id-SLDRBs-ToBeSetup-Item,
+	id-SLDRBs-ToBeSetup-List,
+	id-SLDRBs-ToBeSetupMod-Item,
+	id-SLDRBs-ToBeSetupMod-List,
+	id-SLDRBs-SetupMod-List,
+	id-SLDRBs-FailedToBeSetupMod-List,
+	id-SLDRBs-SetupMod-Item,
+	id-SLDRBs-FailedToBeSetupMod-Item,
+	id-SLDRBs-ModifiedConf-List,
+	id-SLDRBs-ModifiedConf-Item,
+	id-gNBCUMeasurementID,
+	id-gNBDUMeasurementID,
+	id-RegistrationRequest,
+	id-ReportCharacteristics,
+	id-CellToReportList,
+	id-CellMeasurementResultList,
+	id-HardwareLoadIndicator,
+	id-ReportingPeriodicity, 
+	id-TNLCapacityIndicator, 
+	id-RACHReportInformationList,
+	id-RLFReportInformationList,
+	id-ReportingRequestType,
+	id-TimeReferenceInformation,
+	id-ConditionalInterDUMobilityInformation,
+	id-ConditionalIntraDUMobilityInformation,
+	id-targetCellsToCancel,
+	id-requestedTargetCellGlobalID,
+	id-TraceCollectionEntityIPAddress,
+	id-ManagementBasedMDTPLMNList,
+	id-PrivacyIndicator,
+	id-TraceCollectionEntityURI,
+	id-ServingNID,
+	id-PosAssistance-Information,
+	id-PosBroadcast,
+	id-PositioningBroadcastCells,
+	id-RoutingID,
+	id-PosAssistanceInformationFailureList,
+	id-PosMeasurementQuantities,
+	id-PosMeasurementResultList,
+	id-PosMeasurementPeriodicity,
+	id-PosReportCharacteristics,
+	id-TRPInformationTypeListTRPReq,
+	id-TRPInformationTypeItem,
+	id-TRPInformationListTRPResp,
+	id-TRPInformationItem,
+	id-LMF-MeasurementID,
+	id-RAN-MeasurementID,
+	id-SRSType,
+	id-ActivationTime,
+	id-AbortTransmission,
+	id-SRSConfiguration,
+	id-TRPList,
+	id-E-CID-MeasurementQuantities,
+	id-E-CID-MeasurementPeriodicity,
+	id-E-CID-MeasurementResult,
+	id-Cell-Portion-ID,
+	id-LMF-UE-MeasurementID,
+	id-RAN-UE-MeasurementID,
+	id-SFNInitialisationTime,
+	id-SystemFrameNumber,
+	id-SlotNumber,
+	id-TRP-MeasurementRequestList,
+	id-MeasurementBeamInfoRequest,
+	id-E-CID-ReportCharacteristics,
+
+	maxCellingNBDU,
+	maxnoofCandidateSpCells,
+	maxnoofDRBs,
+	maxnoofErrors,
+	maxnoofIndividualF1ConnectionsToReset,
+	maxnoofPotentialSpCells,
+	maxnoofSCells,
+	maxnoofSRBs,
+	maxnoofPagingCells,
+	maxnoofTNLAssociations,
+	maxCellineNB,
+	maxnoofUEIDs,
+	maxnoofBHRLCChannels,
+	maxnoofRoutingEntries,
+	maxnoofChildIABNodes,
+	maxnoofServedCellsIAB,
+	maxnoofTLAsIAB,
+	maxnoofULUPTNLInformationforIAB,
+	maxnoofUPTNLAddresses,
+	maxnoofSLDRBs,
+	maxnoofTRPInfoTypes,
+	maxnoofTRPs
+
+
+
+FROM F1AP-Constants;
+
+
+-- **************************************************************
+--
+-- RESET ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Reset
+--
+-- **************************************************************
+
+Reset ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {ResetIEs} },
+	...
+}
+
+ResetIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-ResetType					CRITICALITY reject	TYPE ResetType					PRESENCE mandatory	},
+	...
+}
+
+ResetType ::= CHOICE {
+	f1-Interface					ResetAll,
+	partOfF1-Interface				UE-associatedLogicalF1-ConnectionListRes, 
+	choice-extension				ProtocolIE-SingleContainer { { ResetType-ExtIEs} }
+}
+
+ResetType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+
+ResetAll ::= ENUMERATED {
+	reset-all,
+	...
+}
+
+UE-associatedLogicalF1-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxnoofIndividualF1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalF1-ConnectionItemRes } }
+
+UE-associatedLogicalF1-ConnectionItemRes F1AP-PROTOCOL-IES ::= {
+	{ ID id-UE-associatedLogicalF1-ConnectionItem	CRITICALITY reject	TYPE UE-associatedLogicalF1-ConnectionItem	PRESENCE mandatory},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Reset Acknowledge
+--
+-- **************************************************************
+
+ResetAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {ResetAcknowledgeIEs} },
+	...
+}
+
+ResetAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID									CRITICALITY reject	TYPE TransactionID													PRESENCE mandatory	}|
+	{ ID id-UE-associatedLogicalF1-ConnectionListResAck		CRITICALITY ignore	TYPE UE-associatedLogicalF1-ConnectionListResAck			PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+	...
+}
+
+UE-associatedLogicalF1-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxnoofIndividualF1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalF1-ConnectionItemResAck } }
+
+UE-associatedLogicalF1-ConnectionItemResAck 	F1AP-PROTOCOL-IES ::= {
+	{ ID id-UE-associatedLogicalF1-ConnectionItem	 CRITICALITY ignore 	TYPE UE-associatedLogicalF1-ConnectionItem  	PRESENCE mandatory },
+	...
+}
+
+-- **************************************************************
+--
+-- ERROR INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Error Indication
+--
+-- **************************************************************
+
+ErrorIndication ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ErrorIndicationIEs}},
+	...
+}
+
+ErrorIndicationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory}|
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID			PRESENCE optional	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID			PRESENCE optional	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- F1 SETUP ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- F1 Setup Request
+--
+-- **************************************************************
+
+F1SetupRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {F1SetupRequestIEs} },
+	...
+}
+
+F1SetupRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-gNB-DU-ID						CRITICALITY reject	TYPE GNB-DU-ID							PRESENCE mandatory	}|
+	{ ID id-gNB-DU-Name						CRITICALITY ignore	TYPE GNB-DU-Name						PRESENCE optional	}|
+	{ ID id-gNB-DU-Served-Cells-List		CRITICALITY reject	TYPE GNB-DU-Served-Cells-List			PRESENCE optional	}|
+	{ ID id-GNB-DU-RRC-Version				CRITICALITY reject	TYPE RRC-Version						PRESENCE mandatory	}|
+	{ ID id-Transport-Layer-Address-Info	CRITICALITY ignore	TYPE Transport-Layer-Address-Info		PRESENCE optional	}|
+	{ ID id-BAPAddress						CRITICALITY ignore	TYPE BAPAddress							PRESENCE optional	}|
+	{ ID id-Extended-GNB-CU-Name			CRITICALITY ignore	TYPE Extended-GNB-CU-Name				PRESENCE optional	},
+	...
+} 
+
+
+GNB-DU-Served-Cells-List 	::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { GNB-DU-Served-Cells-ItemIEs } }
+
+GNB-DU-Served-Cells-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-GNB-DU-Served-Cells-Item		CRITICALITY reject	TYPE		GNB-DU-Served-Cells-Item	PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- F1 Setup Response
+--
+-- **************************************************************
+
+F1SetupResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {F1SetupResponseIEs} },
+	...
+}
+
+
+F1SetupResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-gNB-CU-Name						CRITICALITY ignore	TYPE GNB-CU-Name						PRESENCE optional	}|
+	{ ID id-Cells-to-be-Activated-List		CRITICALITY reject	TYPE Cells-to-be-Activated-List			PRESENCE optional	}|
+	{ ID id-GNB-CU-RRC-Version				CRITICALITY reject	TYPE RRC-Version						PRESENCE mandatory	}|
+	{ ID id-Transport-Layer-Address-Info	CRITICALITY ignore	TYPE Transport-Layer-Address-Info		PRESENCE optional	}|
+	{ ID id-UL-BH-Non-UP-Traffic-Mapping	CRITICALITY reject	TYPE UL-BH-Non-UP-Traffic-Mapping		PRESENCE optional	}|
+	{ ID id-BAPAddress						CRITICALITY ignore	TYPE BAPAddress							PRESENCE optional	}|
+	{ ID id-Extended-GNB-DU-Name			CRITICALITY ignore	TYPE Extended-GNB-DU-Name				PRESENCE optional	},
+	...
+}
+
+
+Cells-to-be-Activated-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-to-be-Activated-List-ItemIEs } }
+
+Cells-to-be-Activated-List-ItemIEs	F1AP-PROTOCOL-IES::= {
+	{ ID id-Cells-to-be-Activated-List-Item				CRITICALITY reject	TYPE Cells-to-be-Activated-List-Item						PRESENCE mandatory},
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- F1 Setup Failure
+--
+-- **************************************************************
+
+F1SetupFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {F1SetupFailureIEs} },
+	...
+}
+
+F1SetupFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE
+--
+-- **************************************************************
+
+GNBDUConfigurationUpdate::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUConfigurationUpdateIEs} },
+	...
+}
+
+GNBDUConfigurationUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID												PRESENCE mandatory	}|
+	{ ID id-Served-Cells-To-Add-List				CRITICALITY reject	TYPE Served-Cells-To-Add-List								PRESENCE optional	}|
+	{ ID id-Served-Cells-To-Modify-List				CRITICALITY reject	TYPE Served-Cells-To-Modify-List							PRESENCE optional	}|
+	{ ID id-Served-Cells-To-Delete-List				CRITICALITY reject	TYPE Served-Cells-To-Delete-List							PRESENCE optional	}|
+	{ ID id-Cells-Status-List						CRITICALITY reject	TYPE Cells-Status-List											PRESENCE optional	}|
+	{ ID id-Dedicated-SIDelivery-NeededUE-List		CRITICALITY ignore	TYPE Dedicated-SIDelivery-NeededUE-List					PRESENCE optional	}|
+	{ ID id-gNB-DU-ID								CRITICALITY reject	TYPE GNB-DU-ID													PRESENCE optional	}|
+	{ ID id-GNB-DU-TNL-Association-To-Remove-List	CRITICALITY reject	TYPE GNB-DU-TNL-Association-To-Remove-List				PRESENCE optional	}|
+	{ ID id-Transport-Layer-Address-Info			CRITICALITY ignore	TYPE Transport-Layer-Address-Info							PRESENCE optional	},
+	...
+} 
+
+Served-Cells-To-Add-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Served-Cells-To-Add-ItemIEs } }
+Served-Cells-To-Modify-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Served-Cells-To-Modify-ItemIEs } }
+Served-Cells-To-Delete-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Served-Cells-To-Delete-ItemIEs } }
+Cells-Status-List	::= SEQUENCE (SIZE(0.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-Status-ItemIEs } }
+
+Dedicated-SIDelivery-NeededUE-List::= SEQUENCE (SIZE(1.. maxnoofUEIDs))	OF ProtocolIE-SingleContainer { { Dedicated-SIDelivery-NeededUE-ItemIEs } }
+
+GNB-DU-TNL-Association-To-Remove-List	::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-DU-TNL-Association-To-Remove-ItemIEs } }
+
+
+Served-Cells-To-Add-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Served-Cells-To-Add-Item		CRITICALITY reject	TYPE	Served-Cells-To-Add-Item				PRESENCE mandatory	},
+	...
+}
+
+Served-Cells-To-Modify-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Served-Cells-To-Modify-Item			CRITICALITY reject	TYPE		Served-Cells-To-Modify-Item							PRESENCE mandatory	},
+	...
+}
+
+Served-Cells-To-Delete-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Served-Cells-To-Delete-Item				CRITICALITY reject	TYPE		Served-Cells-To-Delete-Item					PRESENCE mandatory	},
+	...
+}
+
+Cells-Status-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-Status-Item				CRITICALITY reject	TYPE		Cells-Status-Item					PRESENCE mandatory	},
+	...
+}
+
+Dedicated-SIDelivery-NeededUE-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Dedicated-SIDelivery-NeededUE-Item		CRITICALITY ignore	TYPE	Dedicated-SIDelivery-NeededUE-Item				PRESENCE mandatory	},
+	...
+} 
+
+GNB-DU-TNL-Association-To-Remove-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-DU-TNL-Association-To-Remove-Item		CRITICALITY reject	TYPE	 GNB-DU-TNL-Association-To-Remove-Item			PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE ACKNOWLEDGE
+--
+-- **************************************************************
+
+GNBDUConfigurationUpdateAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUConfigurationUpdateAcknowledgeIEs} },
+	...
+}
+
+
+GNBDUConfigurationUpdateAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID								PRESENCE mandatory	}|
+	{ ID id-Cells-to-be-Activated-List			CRITICALITY reject	TYPE Cells-to-be-Activated-List				PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics				CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional	}|
+	{ ID id-Cells-to-be-Deactivated-List		CRITICALITY reject	TYPE Cells-to-be-Deactivated-List			PRESENCE optional	}|
+	{ ID id-Transport-Layer-Address-Info		CRITICALITY ignore	TYPE Transport-Layer-Address-Info			PRESENCE optional	}|
+	{ ID id-UL-BH-Non-UP-Traffic-Mapping		CRITICALITY reject	TYPE UL-BH-Non-UP-Traffic-Mapping			PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE FAILURE
+--
+-- **************************************************************
+
+GNBDUConfigurationUpdateFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUConfigurationUpdateFailureIEs} },
+	...
+}
+
+GNBDUConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE
+--
+-- **************************************************************
+
+GNBCUConfigurationUpdate ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { GNBCUConfigurationUpdateIEs} },
+	...
+}
+
+GNBCUConfigurationUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID												PRESENCE mandatory	}|
+	{ ID id-Cells-to-be-Activated-List				CRITICALITY reject	TYPE	 Cells-to-be-Activated-List						PRESENCE optional	}|
+	{ ID id-Cells-to-be-Deactivated-List			CRITICALITY reject	TYPE	 Cells-to-be-Deactivated-List						PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-To-Add-List		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Add-List				PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-To-Remove-List	CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Remove-List			PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-To-Update-List	CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Update-List			PRESENCE optional	}|
+	{ ID id-Cells-to-be-Barred-List					CRITICALITY ignore	TYPE	 Cells-to-be-Barred-List							PRESENCE optional	}|
+	{ ID id-Protected-EUTRA-Resources-List			CRITICALITY reject	TYPE	 Protected-EUTRA-Resources-List					PRESENCE optional	}|
+	{ ID id-Neighbour-Cell-Information-List			CRITICALITY ignore	TYPE	 Neighbour-Cell-Information-List					PRESENCE optional	}|
+	{ ID id-Transport-Layer-Address-Info			CRITICALITY ignore	TYPE	 Transport-Layer-Address-Info						PRESENCE optional	}|
+	{ ID id-UL-BH-Non-UP-Traffic-Mapping			CRITICALITY reject	TYPE	 UL-BH-Non-UP-Traffic-Mapping						PRESENCE optional	},
+	...
+} 
+
+Cells-to-be-Deactivated-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-to-be-Deactivated-List-ItemIEs } }
+GNB-CU-TNL-Association-To-Add-List		::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-To-Add-ItemIEs } }
+GNB-CU-TNL-Association-To-Remove-List	::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-To-Remove-ItemIEs } }
+GNB-CU-TNL-Association-To-Update-List	::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-To-Update-ItemIEs } }
+Cells-to-be-Barred-List			::= SEQUENCE(SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-to-be-Barred-ItemIEs } }
+
+
+Cells-to-be-Deactivated-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-to-be-Deactivated-List-Item						CRITICALITY reject	TYPE	Cells-to-be-Deactivated-List-Item					PRESENCE mandatory	},
+	...
+}
+
+
+GNB-CU-TNL-Association-To-Add-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-To-Add-Item		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Add-Item			PRESENCE mandatory	},
+	...
+}
+
+GNB-CU-TNL-Association-To-Remove-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-To-Remove-Item		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Remove-Item			PRESENCE mandatory	},
+	...
+}
+
+GNB-CU-TNL-Association-To-Update-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-To-Update-Item		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Update-Item			PRESENCE mandatory	},
+	...
+}
+
+Cells-to-be-Barred-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-to-be-Barred-Item		CRITICALITY ignore	TYPE	 Cells-to-be-Barred-Item				PRESENCE mandatory	},
+	...
+}
+
+Protected-EUTRA-Resources-List ::= SEQUENCE (SIZE(1.. maxCellineNB))	OF ProtocolIE-SingleContainer { { Protected-EUTRA-Resources-ItemIEs } }
+Protected-EUTRA-Resources-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Protected-EUTRA-Resources-Item 					CRITICALITY reject 	TYPE Protected-EUTRA-Resources-Item							PRESENCE mandatory},
+	...
+}
+
+Neighbour-Cell-Information-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Neighbour-Cell-Information-ItemIEs } }
+Neighbour-Cell-Information-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Neighbour-Cell-Information-Item 					CRITICALITY ignore 	TYPE Neighbour-Cell-Information-Item							PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE ACKNOWLEDGE
+--
+-- **************************************************************
+
+GNBCUConfigurationUpdateAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { GNBCUConfigurationUpdateAcknowledgeIEs} },
+	...
+}
+
+
+GNBCUConfigurationUpdateAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID								CRITICALITY reject	TYPE TransactionID											PRESENCE mandatory	}|
+	{ ID id-Cells-Failed-to-be-Activated-List			CRITICALITY reject	TYPE Cells-Failed-to-be-Activated-List				PRESENCE optional}|
+	{ ID id-CriticalityDiagnostics							CRITICALITY ignore	TYPE CriticalityDiagnostics								PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-Setup-List			CRITICALITY ignore	TYPE GNB-CU-TNL-Association-Setup-List				PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-Failed-To-Setup-List	CRITICALITY ignore	TYPE GNB-CU-TNL-Association-Failed-To-Setup-List	PRESENCE optional	}|
+	{ ID id-Dedicated-SIDelivery-NeededUE-List				CRITICALITY ignore	TYPE Dedicated-SIDelivery-NeededUE-List				PRESENCE optional	}|
+	{ ID id-Transport-Layer-Address-Info				CRITICALITY ignore	TYPE Transport-Layer-Address-Info						PRESENCE optional	},
+	...
+}
+
+Cells-Failed-to-be-Activated-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-Failed-to-be-Activated-List-ItemIEs } }
+GNB-CU-TNL-Association-Setup-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-Setup-ItemIEs } }
+GNB-CU-TNL-Association-Failed-To-Setup-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-Failed-To-Setup-ItemIEs } }
+
+Cells-Failed-to-be-Activated-List-ItemIEs F1AP-PROTOCOL-IES		::= {
+	{ ID id-Cells-Failed-to-be-Activated-List-Item		CRITICALITY reject	TYPE Cells-Failed-to-be-Activated-List-Item		PRESENCE mandatory	},
+	...
+}
+
+GNB-CU-TNL-Association-Setup-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-Setup-Item		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-Setup-Item			PRESENCE mandatory	},
+	...
+}
+
+
+GNB-CU-TNL-Association-Failed-To-Setup-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-Failed-To-Setup-Item		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-Failed-To-Setup-Item			PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE FAILURE
+--
+-- **************************************************************
+
+GNBCUConfigurationUpdateFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { GNBCUConfigurationUpdateFailureIEs} },
+	...
+}
+
+GNBCUConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU RESOURCE COORDINATION REQUEST 
+--
+-- **************************************************************
+
+GNBDUResourceCoordinationRequest ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{{GNBDUResourceCoordinationRequest-IEs}},
+	...
+}
+
+GNBDUResourceCoordinationRequest-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID									CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory	}|
+	{ ID id-RequestType										CRITICALITY reject	TYPE RequestType										PRESENCE mandatory	}|
+	{ ID id-EUTRA-NR-CellResourceCoordinationReq-Container	CRITICALITY reject	TYPE EUTRA-NR-CellResourceCoordinationReq-Container	PRESENCE mandatory}|
+	{ ID id-IgnoreResourceCoordinationContainer				CRITICALITY reject	TYPE IgnoreResourceCoordinationContainer		PRESENCE optional },
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU RESOURCE COORDINATION RESPONSE 
+--
+-- **************************************************************
+
+GNBDUResourceCoordinationResponse ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{{GNBDUResourceCoordinationResponse-IEs}},
+	...
+}
+
+GNBDUResourceCoordinationResponse-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID										CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-EUTRA-NR-CellResourceCoordinationReqAck-Container	CRITICALITY reject	TYPE EUTRA-NR-CellResourceCoordinationReqAck-Container		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Context Setup ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT SETUP REQUEST
+--
+-- **************************************************************
+
+UEContextSetupRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextSetupRequestIEs} },
+	...
+}
+
+UEContextSetupRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID									PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID									PRESENCE optional 	}|
+	{ ID id-SpCell-ID								CRITICALITY reject	TYPE NRCGI												PRESENCE mandatory	}|
+	{ ID id-ServCellIndex							CRITICALITY reject	TYPE ServCellIndex										PRESENCE mandatory	}|
+	{ ID id-SpCellULConfigured						CRITICALITY ignore	TYPE CellULConfigured									PRESENCE optional	}|
+	{ ID id-CUtoDURRCInformation					CRITICALITY reject	TYPE CUtoDURRCInformation								PRESENCE mandatory}|
+	{ ID id-Candidate-SpCell-List					CRITICALITY ignore	TYPE Candidate-SpCell-List							PRESENCE optional	}|
+	{ ID id-DRXCycle								CRITICALITY ignore	TYPE DRXCycle											PRESENCE optional	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer		PRESENCE optional	}|
+	{ ID id-SCell-ToBeSetup-List					CRITICALITY ignore	TYPE SCell-ToBeSetup-List								PRESENCE optional	}|
+	{ ID id-SRBs-ToBeSetup-List						CRITICALITY reject	TYPE SRBs-ToBeSetup-List								PRESENCE optional	}|
+	{ ID id-DRBs-ToBeSetup-List						CRITICALITY reject	TYPE DRBs-ToBeSetup-List								PRESENCE optional	}|
+	{ ID id-InactivityMonitoringRequest				CRITICALITY reject	TYPE InactivityMonitoringRequest					PRESENCE optional	}|
+	{ ID id-RAT-FrequencyPriorityInformation		CRITICALITY reject	TYPE RAT-FrequencyPriorityInformation				PRESENCE optional	}|
+	{ ID id-RRCContainer							CRITICALITY ignore	TYPE RRCContainer										PRESENCE optional	}|
+	{ ID id-MaskedIMEISV							CRITICALITY ignore	TYPE MaskedIMEISV										PRESENCE optional	}|
+	{ ID id-ServingPLMN								CRITICALITY ignore	TYPE PLMN-Identity										PRESENCE optional	}|
+	{ ID id-GNB-DU-UE-AMBR-UL						CRITICALITY ignore	TYPE BitRate											PRESENCE conditional }|
+	{ ID id-RRCDeliveryStatusRequest				CRITICALITY ignore	TYPE RRCDeliveryStatusRequest						PRESENCE optional }|
+	{ ID id-ResourceCoordinationTransferInformation	CRITICALITY ignore	TYPE ResourceCoordinationTransferInformation	PRESENCE optional	}|
+	{ ID id-ServingCellMO							CRITICALITY ignore	TYPE ServingCellMO										PRESENCE optional	}|
+	{ ID id-new-gNB-CU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID									PRESENCE optional }|
+	{ ID id-RANUEID									CRITICALITY ignore	TYPE RANUEID											PRESENCE optional	}|
+	{ ID id-TraceActivation							CRITICALITY ignore	TYPE TraceActivation									PRESENCE optional	}|
+	{ ID id-AdditionalRRMPriorityIndex				CRITICALITY ignore	TYPE AdditionalRRMPriorityIndex						PRESENCE optional }|
+	{ ID id-BHChannels-ToBeSetup-List				CRITICALITY reject	TYPE BHChannels-ToBeSetup-List						PRESENCE optional	}|
+	{ ID id-ConfiguredBAPAddress					CRITICALITY reject	TYPE BAPAddress											PRESENCE optional	}|
+	{ ID id-NRV2XServicesAuthorized					CRITICALITY ignore	TYPE NRV2XServicesAuthorized							PRESENCE optional }|
+	{ ID id-LTEV2XServicesAuthorized				CRITICALITY ignore	TYPE LTEV2XServicesAuthorized						PRESENCE optional }|
+	{ ID id-NRUESidelinkAggregateMaximumBitrate		CRITICALITY ignore	TYPE NRUESidelinkAggregateMaximumBitrate			PRESENCE optional }|
+	{ ID id-LTEUESidelinkAggregateMaximumBitrate	CRITICALITY ignore	TYPE LTEUESidelinkAggregateMaximumBitrate		PRESENCE optional }|
+	{ ID id-PC5LinkAMBR								CRITICALITY ignore	TYPE BitRate											PRESENCE optional}|
+	{ ID id-SLDRBs-ToBeSetup-List					CRITICALITY reject	TYPE SLDRBs-ToBeSetup-List							PRESENCE optional	}|
+	{ ID id-ConditionalInterDUMobilityInformation	CRITICALITY reject	TYPE ConditionalInterDUMobilityInformation		PRESENCE optional}|
+	{ ID id-ManagementBasedMDTPLMNList				CRITICALITY ignore	TYPE 		MDTPLMNList									PRESENCE optional }|
+	{ ID id-ServingNID								CRITICALITY reject	TYPE NID												PRESENCE optional },
+	...
+} 
+
+Candidate-SpCell-List::= SEQUENCE (SIZE(1..maxnoofCandidateSpCells)) OF ProtocolIE-SingleContainer { { Candidate-SpCell-ItemIEs} }
+SCell-ToBeSetup-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeSetup-ItemIEs} }
+SRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeSetup-ItemIEs} }
+DRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeSetup-ItemIEs} }
+BHChannels-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-ToBeSetup-ItemIEs} }
+SLDRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-ToBeSetup-ItemIEs} }
+
+Candidate-SpCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-Candidate-SpCell-Item					CRITICALITY ignore	TYPE Candidate-SpCell-Item						PRESENCE mandatory	},
+	...
+}
+
+
+SCell-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-ToBeSetup-Item						CRITICALITY ignore	TYPE SCell-ToBeSetup-Item					PRESENCE mandatory	},
+	...
+}
+
+SRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-ToBeSetup-Item		CRITICALITY reject		TYPE SRBs-ToBeSetup-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeSetup-Item					CRITICALITY reject	TYPE DRBs-ToBeSetup-Item					PRESENCE mandatory},
+	...
+}
+
+BHChannels-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-ToBeSetup-Item					CRITICALITY reject	TYPE BHChannels-ToBeSetup-Item					PRESENCE mandatory},
+	...
+}
+
+SLDRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-ToBeSetup-Item					CRITICALITY reject	TYPE SLDRBs-ToBeSetup-Item					PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT SETUP RESPONSE
+--
+-- **************************************************************
+
+UEContextSetupResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextSetupResponseIEs} },
+	...
+}
+
+
+UEContextSetupResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-DUtoCURRCInformation					CRITICALITY reject	TYPE DUtoCURRCInformation							PRESENCE mandatory }|
+	{ ID id-C-RNTI									CRITICALITY ignore	TYPE C-RNTI											PRESENCE optional	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer	PRESENCE optional	}|
+	{ ID id-FullConfiguration						CRITICALITY reject	TYPE FullConfiguration								PRESENCE optional	}|
+	{ ID id-DRBs-Setup-List							CRITICALITY ignore	TYPE DRBs-Setup-List								PRESENCE optional	}|
+	{ ID id-SRBs-FailedToBeSetup-List				CRITICALITY ignore	TYPE SRBs-FailedToBeSetup-List					PRESENCE optional	}|
+	{ ID id-DRBs-FailedToBeSetup-List				CRITICALITY ignore	TYPE DRBs-FailedToBeSetup-List					PRESENCE optional	}|
+	{ ID id-SCell-FailedtoSetup-List				CRITICALITY ignore	TYPE SCell-FailedtoSetup-List					PRESENCE optional	}|
+	{ ID id-InactivityMonitoringResponse			CRITICALITY reject	TYPE InactivityMonitoringResponse				PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics					CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional	}|
+	{ ID id-SRBs-Setup-List							CRITICALITY ignore	TYPE SRBs-Setup-List								PRESENCE optional	}|
+	{ ID id-BHChannels-Setup-List					CRITICALITY ignore	TYPE BHChannels-Setup-List						PRESENCE optional	}|
+	{ ID id-BHChannels-FailedToBeSetup-List			CRITICALITY ignore	TYPE BHChannels-FailedToBeSetup-List			PRESENCE optional	}|
+	{ ID id-SLDRBs-Setup-List						CRITICALITY ignore	TYPE SLDRBs-Setup-List								PRESENCE optional	}|
+	{ ID id-SLDRBs-FailedToBeSetup-List				CRITICALITY ignore	TYPE SLDRBs-FailedToBeSetup-List				PRESENCE optional	}|
+	{ ID id-requestedTargetCellGlobalID				CRITICALITY reject	TYPE NRCGI											PRESENCE optional},
+	...
+}
+
+DRBs-Setup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Setup-ItemIEs} }
+
+
+SRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-FailedToBeSetup-ItemIEs} }
+DRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeSetup-ItemIEs} }
+SCell-FailedtoSetup-List ::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-FailedtoSetup-ItemIEs} }
+SRBs-Setup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-Setup-ItemIEs} }
+BHChannels-Setup-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-Setup-ItemIEs} }
+BHChannels-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-FailedToBeSetup-ItemIEs} }
+
+DRBs-Setup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Setup-Item						CRITICALITY ignore	TYPE DRBs-Setup-Item						PRESENCE mandatory},
+	...
+}
+
+SRBs-Setup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-Setup-Item						CRITICALITY ignore	TYPE SRBs-Setup-Item						PRESENCE mandatory},
+	...
+}
+
+SRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-FailedToBeSetup-Item		CRITICALITY ignore		TYPE SRBs-FailedToBeSetup-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeSetup-Item		CRITICALITY ignore	TYPE DRBs-FailedToBeSetup-Item			PRESENCE mandatory},
+	...
+}
+
+SCell-FailedtoSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-FailedtoSetup-Item			CRITICALITY ignore	TYPE SCell-FailedtoSetup-Item			PRESENCE mandatory},
+	...
+}
+
+BHChannels-Setup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-Setup-Item						CRITICALITY ignore	TYPE BHChannels-Setup-Item						PRESENCE mandatory},
+	...
+}
+
+BHChannels-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-FailedToBeSetup-Item						CRITICALITY ignore	TYPE BHChannels-FailedToBeSetup-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-Setup-List ::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-Setup-ItemIEs} }
+
+SLDRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-FailedToBeSetup-ItemIEs} }
+
+SLDRBs-Setup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-Setup-Item						CRITICALITY ignore	TYPE SLDRBs-Setup-Item						PRESENCE mandatory},
+	...
+}
+
+SLDRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-FailedToBeSetup-Item		CRITICALITY ignore	TYPE SLDRBs-FailedToBeSetup-Item			PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT SETUP FAILURE
+--
+-- **************************************************************
+
+UEContextSetupFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextSetupFailureIEs} },
+	...
+}
+
+UEContextSetupFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID			PRESENCE optional	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	}|
+	{ ID id-Potential-SpCell-List		CRITICALITY ignore	TYPE Potential-SpCell-List		PRESENCE optional	}|
+	{ ID id-requestedTargetCellGlobalID	CRITICALITY reject	TYPE NRCGI						PRESENCE optional},
+	...
+}
+
+Potential-SpCell-List::= SEQUENCE (SIZE(0..maxnoofPotentialSpCells)) OF ProtocolIE-SingleContainer { { Potential-SpCell-ItemIEs} }
+
+Potential-SpCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-Potential-SpCell-Item				CRITICALITY ignore	TYPE Potential-SpCell-Item					PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Context Release Request ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE Context Release Request
+--
+-- **************************************************************
+
+UEContextReleaseRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ UEContextReleaseRequestIEs}},
+	...
+}
+
+UEContextReleaseRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-targetCellsToCancel				CRITICALITY reject	TYPE TargetCellList					PRESENCE optional		},
+	...
+}
+
+
+-- **************************************************************
+--
+-- UE Context Release (gNB-CU initiated) ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT RELEASE COMMAND 
+--
+-- **************************************************************
+
+UEContextReleaseCommand ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextReleaseCommandIEs} },
+	...
+}
+
+UEContextReleaseCommandIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-RRCContainer					CRITICALITY ignore	TYPE RRCContainer					PRESENCE optional	}|
+	{ ID id-SRBID							CRITICALITY ignore	TYPE SRBID							PRESENCE conditional	}|
+	{ ID id-oldgNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID				PRESENCE optional	}|
+	{ ID id-ExecuteDuplication				CRITICALITY ignore	TYPE ExecuteDuplication				PRESENCE optional}|
+	{ ID id-RRCDeliveryStatusRequest		CRITICALITY ignore	TYPE RRCDeliveryStatusRequest		PRESENCE optional }|
+	{ ID id-targetCellsToCancel				CRITICALITY reject	TYPE TargetCellList					PRESENCE optional},
+	...
+} 
+
+-- **************************************************************
+--
+-- UE CONTEXT RELEASE COMPLETE
+--
+-- **************************************************************
+
+UEContextReleaseComplete ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextReleaseCompleteIEs} },
+	...
+}
+
+
+UEContextReleaseCompleteIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Context Modification ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION REQUEST
+--
+-- **************************************************************
+
+UEContextModificationRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationRequestIEs} },
+	...
+}
+
+UEContextModificationRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID									PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID									PRESENCE mandatory	}|
+	{ ID id-SpCell-ID								CRITICALITY ignore	TYPE NRCGI												PRESENCE optional	}|
+	{ ID id-ServCellIndex							CRITICALITY reject	TYPE ServCellIndex										PRESENCE optional	}|
+	{ ID id-SpCellULConfigured						CRITICALITY ignore	TYPE CellULConfigured									PRESENCE optional	}|
+	{ ID id-DRXCycle								CRITICALITY ignore	TYPE DRXCycle											PRESENCE optional	}|
+	{ ID id-CUtoDURRCInformation					CRITICALITY reject	TYPE CUtoDURRCInformation								PRESENCE optional	}|
+	{ ID id-TransmissionActionIndicator				CRITICALITY ignore	TYPE TransmissionActionIndicator					PRESENCE optional	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer		PRESENCE optional	}|
+	{ ID id-RRCReconfigurationCompleteIndicator		CRITICALITY ignore	TYPE RRCReconfigurationCompleteIndicator			PRESENCE optional	}|
+	{ ID id-RRCContainer							CRITICALITY reject	TYPE RRCContainer										PRESENCE optional	}|
+	{ ID id-SCell-ToBeSetupMod-List					CRITICALITY ignore	TYPE SCell-ToBeSetupMod-List							PRESENCE optional	}|
+	{ ID id-SCell-ToBeRemoved-List					CRITICALITY ignore	TYPE SCell-ToBeRemoved-List 							PRESENCE optional }|
+	{ ID id-SRBs-ToBeSetupMod-List					CRITICALITY reject	TYPE SRBs-ToBeSetupMod-List							PRESENCE optional	}|
+	{ ID id-DRBs-ToBeSetupMod-List					CRITICALITY reject	TYPE DRBs-ToBeSetupMod-List							PRESENCE optional	}|
+	{ ID id-DRBs-ToBeModified-List					CRITICALITY reject	TYPE DRBs-ToBeModified-List							PRESENCE optional	}|
+	{ ID id-SRBs-ToBeReleased-List					CRITICALITY reject	TYPE SRBs-ToBeReleased-List							PRESENCE optional	}|
+	{ ID id-DRBs-ToBeReleased-List					CRITICALITY reject	TYPE DRBs-ToBeReleased-List							PRESENCE optional	}|
+	{ ID id-InactivityMonitoringRequest				CRITICALITY reject	TYPE InactivityMonitoringRequest					PRESENCE optional	}|
+	{ ID id-RAT-FrequencyPriorityInformation		CRITICALITY reject	TYPE RAT-FrequencyPriorityInformation				PRESENCE optional	}|
+	{ ID id-DRXConfigurationIndicator				CRITICALITY ignore	TYPE DRXConfigurationIndicator						PRESENCE optional	}|
+	{ ID id-RLCFailureIndication					CRITICALITY ignore	TYPE RLCFailureIndication								PRESENCE optional	}|
+	{ ID id-UplinkTxDirectCurrentListInformation	CRITICALITY ignore	TYPE UplinkTxDirectCurrentListInformation		PRESENCE optional	}|
+	{ ID id-GNB-DUConfigurationQuery				CRITICALITY reject	TYPE GNB-DUConfigurationQuery						PRESENCE optional	}|
+	{ ID id-GNB-DU-UE-AMBR-UL						CRITICALITY ignore	TYPE BitRate											PRESENCE optional	}|
+	{ ID id-ExecuteDuplication						CRITICALITY ignore	TYPE ExecuteDuplication									PRESENCE optional}|
+	{ ID id-RRCDeliveryStatusRequest				CRITICALITY ignore	TYPE RRCDeliveryStatusRequest						PRESENCE optional }|
+	{ ID id-ResourceCoordinationTransferInformation	CRITICALITY ignore	TYPE ResourceCoordinationTransferInformation	PRESENCE optional	}|
+	{ ID id-ServingCellMO							CRITICALITY ignore	TYPE ServingCellMO										PRESENCE optional	}|
+	{ ID id-NeedforGap								CRITICALITY ignore	TYPE NeedforGap											PRESENCE optional	}|
+	{ ID id-FullConfiguration						CRITICALITY reject	TYPE FullConfiguration									PRESENCE optional	}|
+	{ ID id-AdditionalRRMPriorityIndex				CRITICALITY ignore	TYPE AdditionalRRMPriorityIndex						PRESENCE optional }|
+	{ ID id-LowerLayerPresenceStatusChange			CRITICALITY ignore	TYPE LowerLayerPresenceStatusChange				PRESENCE optional	}|
+	{ ID id-BHChannels-ToBeSetupMod-List			CRITICALITY reject	TYPE BHChannels-ToBeSetupMod-List					PRESENCE optional	}|
+	{ ID id-BHChannels-ToBeModified-List			CRITICALITY reject	TYPE BHChannels-ToBeModified-List					PRESENCE optional	}|
+	{ ID id-BHChannels-ToBeReleased-List			CRITICALITY reject	TYPE BHChannels-ToBeReleased-List					PRESENCE optional	}|
+	{ ID id-NRV2XServicesAuthorized					CRITICALITY ignore	TYPE NRV2XServicesAuthorized							PRESENCE optional }|
+	{ ID id-LTEV2XServicesAuthorized				CRITICALITY ignore	TYPE LTEV2XServicesAuthorized						PRESENCE optional }|
+	{ ID id-NRUESidelinkAggregateMaximumBitrate		CRITICALITY ignore	TYPE NRUESidelinkAggregateMaximumBitrate			PRESENCE optional }|
+	{ ID id-LTEUESidelinkAggregateMaximumBitrate	CRITICALITY ignore	TYPE LTEUESidelinkAggregateMaximumBitrate		PRESENCE optional }|
+	{ ID id-PC5LinkAMBR								CRITICALITY ignore	TYPE BitRate											PRESENCE optional}|
+	{ ID id-SLDRBs-ToBeSetupMod-List				CRITICALITY reject	TYPE SLDRBs-ToBeSetupMod-List						PRESENCE optional	}|
+	{ ID id-SLDRBs-ToBeModified-List				CRITICALITY reject	TYPE SLDRBs-ToBeModified-List						PRESENCE optional	}|
+	{ ID id-SLDRBs-ToBeReleased-List				CRITICALITY reject	TYPE SLDRBs-ToBeReleased-List						PRESENCE optional	}|
+	{ ID id-ConditionalIntraDUMobilityInformation	CRITICALITY reject	TYPE ConditionalIntraDUMobilityInformation		PRESENCE optional},
+	...
+} 
+
+SCell-ToBeSetupMod-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeSetupMod-ItemIEs} }
+SCell-ToBeRemoved-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeRemoved-ItemIEs} }
+SRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeSetupMod-ItemIEs} }
+DRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeSetupMod-ItemIEs} }
+BHChannels-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-ToBeSetupMod-ItemIEs} }
+
+DRBs-ToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeModified-ItemIEs} }
+BHChannels-ToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-ToBeModified-ItemIEs} }
+SRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeReleased-ItemIEs} }
+DRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeReleased-ItemIEs} }
+BHChannels-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-ToBeReleased-ItemIEs} }
+
+SCell-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-ToBeSetupMod-Item			CRITICALITY ignore	TYPE SCell-ToBeSetupMod-Item			PRESENCE mandatory	},
+	...
+}
+
+SCell-ToBeRemoved-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-ToBeRemoved-Item			CRITICALITY ignore	TYPE SCell-ToBeRemoved-Item			PRESENCE mandatory	},
+	...
+}
+
+
+SRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-ToBeSetupMod-Item		CRITICALITY reject	TYPE SRBs-ToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeSetupMod-Item		CRITICALITY reject	TYPE DRBs-ToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeModified-Item		CRITICALITY reject	TYPE DRBs-ToBeModified-Item			PRESENCE mandatory},
+	...
+}
+
+
+SRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-ToBeReleased-Item	CRITICALITY reject	TYPE SRBs-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeReleased-Item		CRITICALITY reject	TYPE DRBs-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+BHChannels-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-ToBeSetupMod-Item		CRITICALITY reject	TYPE BHChannels-ToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+BHChannels-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-ToBeModified-Item		CRITICALITY reject	TYPE BHChannels-ToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+BHChannels-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-ToBeReleased-Item		CRITICALITY reject	TYPE BHChannels-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-ToBeSetupMod-ItemIEs} }
+SLDRBs-ToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-ToBeModified-ItemIEs} }
+SLDRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-ToBeReleased-ItemIEs} }
+
+SLDRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-ToBeSetupMod-Item		CRITICALITY reject	TYPE SLDRBs-ToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-ToBeModified-Item		CRITICALITY reject	TYPE SLDRBs-ToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-ToBeReleased-Item		CRITICALITY reject	TYPE SLDRBs-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION RESPONSE
+--
+-- **************************************************************
+
+UEContextModificationResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationResponseIEs} },
+	...
+}
+
+
+UEContextModificationResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer	PRESENCE optional	}|
+	{ ID id-DUtoCURRCInformation					CRITICALITY reject	TYPE DUtoCURRCInformation							PRESENCE optional}|
+	{ ID id-DRBs-SetupMod-List						CRITICALITY ignore	TYPE DRBs-SetupMod-List								PRESENCE optional}|
+	{ ID id-DRBs-Modified-List						CRITICALITY ignore	TYPE DRBs-Modified-List								PRESENCE optional}|
+	{ ID id-SRBs-FailedToBeSetupMod-List			CRITICALITY ignore	TYPE SRBs-FailedToBeSetupMod-List				PRESENCE optional	}|
+	{ ID id-DRBs-FailedToBeSetupMod-List			CRITICALITY ignore	TYPE DRBs-FailedToBeSetupMod-List				PRESENCE optional	}|
+	{ ID id-SCell-FailedtoSetupMod-List				CRITICALITY ignore	TYPE SCell-FailedtoSetupMod-List				PRESENCE optional	}|
+	{ ID id-DRBs-FailedToBeModified-List			CRITICALITY ignore	TYPE DRBs-FailedToBeModified-List				PRESENCE optional	}|
+	{ ID id-InactivityMonitoringResponse			CRITICALITY reject	TYPE InactivityMonitoringResponse				PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics					CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional	}|
+	{ ID id-C-RNTI									CRITICALITY ignore	TYPE C-RNTI											PRESENCE optional	}|
+	{ ID id-Associated-SCell-List					CRITICALITY ignore  TYPE Associated-SCell-List						PRESENCE optional	}|
+	{ ID id-SRBs-SetupMod-List						CRITICALITY ignore	TYPE SRBs-SetupMod-List								PRESENCE optional	}|
+	{ ID id-SRBs-Modified-List						CRITICALITY ignore	TYPE SRBs-Modified-List								PRESENCE optional	}|
+	{ ID id-FullConfiguration						CRITICALITY reject	TYPE FullConfiguration								PRESENCE optional	}|
+	{ ID id-BHChannels-SetupMod-List				CRITICALITY ignore	TYPE BHChannels-SetupMod-List					PRESENCE optional}|
+	{ ID id-BHChannels-Modified-List				CRITICALITY ignore	TYPE BHChannels-Modified-List					PRESENCE optional}|
+	{ ID id-BHChannels-FailedToBeSetupMod-List		CRITICALITY ignore	TYPE BHChannels-FailedToBeSetupMod-List		PRESENCE optional	}|
+	{ ID id-BHChannels-FailedToBeModified-List		CRITICALITY ignore	TYPE BHChannels-FailedToBeModified-List		PRESENCE optional	}|
+	{ ID id-SLDRBs-SetupMod-List					CRITICALITY ignore	TYPE SLDRBs-SetupMod-List							PRESENCE optional	}|
+	{ ID id-SLDRBs-Modified-List					CRITICALITY ignore	TYPE SLDRBs-Modified-List							PRESENCE optional	}|
+	{ ID id-SLDRBs-FailedToBeSetupMod-List			CRITICALITY ignore	TYPE SLDRBs-FailedToBeSetupMod-List			PRESENCE optional	}|
+	{ ID id-SLDRBs-FailedToBeModified-List			CRITICALITY ignore	TYPE SLDRBs-FailedToBeModified-List			PRESENCE optional	}|
+	{ ID id-requestedTargetCellGlobalID				CRITICALITY reject	TYPE NRCGI											PRESENCE optional},
+	...
+}
+
+
+DRBs-SetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-SetupMod-ItemIEs} }
+DRBs-Modified-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Modified-ItemIEs } } 
+SRBs-SetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-SetupMod-ItemIEs} }
+SRBs-Modified-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-Modified-ItemIEs } }
+DRBs-FailedToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeModified-ItemIEs} }
+SRBs-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-FailedToBeSetupMod-ItemIEs} }
+DRBs-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeSetupMod-ItemIEs} }
+SCell-FailedtoSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-FailedtoSetupMod-ItemIEs} }
+BHChannels-SetupMod-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-SetupMod-ItemIEs} }
+BHChannels-Modified-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-Modified-ItemIEs } } 
+BHChannels-FailedToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-FailedToBeModified-ItemIEs} }
+BHChannels-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-FailedToBeSetupMod-ItemIEs} }
+
+Associated-SCell-List ::= SEQUENCE (SIZE(1.. maxnoofSCells)) OF ProtocolIE-SingleContainer { { Associated-SCell-ItemIEs} }
+
+DRBs-SetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-SetupMod-Item		CRITICALITY ignore		TYPE DRBs-SetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-Modified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Modified-Item			CRITICALITY ignore	TYPE DRBs-Modified-Item		PRESENCE mandatory},
+	...
+}
+
+SRBs-SetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-SetupMod-Item		CRITICALITY ignore		TYPE SRBs-SetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+SRBs-Modified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-Modified-Item			CRITICALITY ignore	TYPE SRBs-Modified-Item		PRESENCE mandatory},
+	...
+}
+
+SRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-FailedToBeSetupMod-Item		CRITICALITY ignore	TYPE SRBs-FailedToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeSetupMod-Item		CRITICALITY ignore	TYPE DRBs-FailedToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-FailedToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeModified-Item		CRITICALITY ignore	TYPE DRBs-FailedToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+SCell-FailedtoSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-FailedtoSetupMod-Item			CRITICALITY ignore	TYPE SCell-FailedtoSetupMod-Item			PRESENCE mandatory},
+	...
+}
+
+Associated-SCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-Associated-SCell-Item			CRITICALITY ignore	TYPE Associated-SCell-Item			PRESENCE mandatory},
+	...
+}
+
+BHChannels-SetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-SetupMod-Item		CRITICALITY ignore		TYPE BHChannels-SetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+BHChannels-Modified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-Modified-Item		CRITICALITY ignore	TYPE BHChannels-Modified-Item		PRESENCE mandatory},
+	...
+}
+
+BHChannels-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-FailedToBeSetupMod-Item		CRITICALITY ignore	TYPE BHChannels-FailedToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+BHChannels-FailedToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-FailedToBeModified-Item		CRITICALITY ignore	TYPE BHChannels-FailedToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-SetupMod-List 			::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-SetupMod-ItemIEs} }
+SLDRBs-Modified-List				::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-Modified-ItemIEs } } 
+SLDRBs-FailedToBeModified-List 	::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-FailedToBeModified-ItemIEs} }
+SLDRBs-FailedToBeSetupMod-List 	::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-FailedToBeSetupMod-ItemIEs} }
+
+SLDRBs-SetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-SetupMod-Item		CRITICALITY ignore		TYPE SLDRBs-SetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-Modified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-Modified-Item			CRITICALITY ignore	TYPE SLDRBs-Modified-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-FailedToBeSetupMod-Item		CRITICALITY ignore	TYPE SLDRBs-FailedToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-FailedToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-FailedToBeModified-Item		CRITICALITY ignore	TYPE SLDRBs-FailedToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION FAILURE
+--
+-- **************************************************************
+
+UEContextModificationFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationFailureIEs} },
+	...
+}
+
+UEContextModificationFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	}|
+	{ ID id-requestedTargetCellGlobalID		CRITICALITY reject	TYPE NRCGI							PRESENCE optional},
+	...
+}
+
+
+-- **************************************************************
+--
+-- UE Context Modification Required (gNB-DU initiated) ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION REQUIRED
+--
+-- **************************************************************
+
+UEContextModificationRequired ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationRequiredIEs} },
+	...
+}
+
+UEContextModificationRequiredIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-ResourceCoordinationTransferContainer		CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer		PRESENCE optional	}|
+	{ ID id-DUtoCURRCInformation						CRITICALITY reject	TYPE DUtoCURRCInformation							PRESENCE optional}|
+	{ ID id-DRBs-Required-ToBeModified-List				CRITICALITY reject	TYPE DRBs-Required-ToBeModified-List				PRESENCE optional}|
+	{ ID id-SRBs-Required-ToBeReleased-List				CRITICALITY reject	TYPE SRBs-Required-ToBeReleased-List				PRESENCE optional}|
+	{ ID id-DRBs-Required-ToBeReleased-List				CRITICALITY reject	TYPE DRBs-Required-ToBeReleased-List				PRESENCE optional}|
+	{ ID id-Cause										CRITICALITY ignore	TYPE Cause												PRESENCE mandatory	}|
+	{ ID id-BHChannels-Required-ToBeReleased-List		CRITICALITY reject	TYPE BHChannels-Required-ToBeReleased-List		PRESENCE optional}|
+	{ ID id-SLDRBs-Required-ToBeModified-List			CRITICALITY reject	TYPE SLDRBs-Required-ToBeModified-List			PRESENCE optional}|
+	{ ID id-SLDRBs-Required-ToBeReleased-List			CRITICALITY reject	TYPE SLDRBs-Required-ToBeReleased-List			PRESENCE optional}|
+	{ ID id-targetCellsToCancel							CRITICALITY reject	TYPE TargetCellList										PRESENCE optional},
+	...
+} 
+
+DRBs-Required-ToBeModified-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Required-ToBeModified-ItemIEs } }
+DRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Required-ToBeReleased-ItemIEs } }
+
+SRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-Required-ToBeReleased-ItemIEs } }
+
+BHChannels-Required-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofBHRLCChannels)) OF ProtocolIE-SingleContainer { { BHChannels-Required-ToBeReleased-ItemIEs } }
+
+DRBs-Required-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Required-ToBeModified-Item			CRITICALITY reject	TYPE DRBs-Required-ToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Required-ToBeReleased-Item			CRITICALITY reject	TYPE DRBs-Required-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+SRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-Required-ToBeReleased-Item			CRITICALITY reject	TYPE SRBs-Required-ToBeReleased-Item			PRESENCE mandatory},
+	...
+}
+
+BHChannels-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-BHChannels-Required-ToBeReleased-Item			CRITICALITY reject	TYPE BHChannels-Required-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-Required-ToBeModified-List::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-Required-ToBeModified-ItemIEs } }
+SLDRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-Required-ToBeReleased-ItemIEs } }
+
+SLDRBs-Required-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-Required-ToBeModified-Item			CRITICALITY reject	TYPE SLDRBs-Required-ToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+SLDRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-Required-ToBeReleased-Item			CRITICALITY reject	TYPE SLDRBs-Required-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION CONFIRM
+--
+-- **************************************************************
+
+UEContextModificationConfirm::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationConfirmIEs} },
+	...
+}
+
+
+UEContextModificationConfirmIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-ResourceCoordinationTransferContainer		CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer		PRESENCE optional	}|
+	{ ID id-DRBs-ModifiedConf-List						CRITICALITY ignore	TYPE DRBs-ModifiedConf-List							PRESENCE optional}|
+	{ ID id-RRCContainer								CRITICALITY ignore	TYPE RRCContainer										PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics						CRITICALITY ignore	TYPE CriticalityDiagnostics							PRESENCE optional	}|
+	{ ID id-ExecuteDuplication							CRITICALITY ignore	TYPE ExecuteDuplication								PRESENCE optional}|
+	{ ID id-ResourceCoordinationTransferInformation		CRITICALITY ignore	TYPE ResourceCoordinationTransferInformation	PRESENCE optional	}|
+	{ ID id-SLDRBs-ModifiedConf-List					CRITICALITY ignore	TYPE SLDRBs-ModifiedConf-List						PRESENCE optional},
+	...
+}
+
+DRBs-ModifiedConf-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ModifiedConf-ItemIEs } }
+
+DRBs-ModifiedConf-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ModifiedConf-Item		CRITICALITY ignore	TYPE DRBs-ModifiedConf-Item			PRESENCE mandatory},
+	...
+}
+
+SLDRBs-ModifiedConf-List::= SEQUENCE (SIZE(1..maxnoofSLDRBs)) OF ProtocolIE-SingleContainer { { SLDRBs-ModifiedConf-ItemIEs } }
+
+SLDRBs-ModifiedConf-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SLDRBs-ModifiedConf-Item		CRITICALITY ignore	TYPE SLDRBs-ModifiedConf-Item			PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION REFUSE
+--
+-- **************************************************************
+
+UEContextModificationRefuse::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationRefuseIEs} },
+	...
+}
+
+
+UEContextModificationRefuseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+	...
+}
+
+
+-- ************************************************************** 
+-- 
+-- WRITE-REPLACE WARNING ELEMENTARY PROCEDURE 
+-- 
+-- ************************************************************** 
+
+-- ************************************************************** 
+-- 
+-- Write-Replace Warning Request 
+-- 
+-- ************************************************************** 
+
+WriteReplaceWarningRequest ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { {WriteReplaceWarningRequestIEs} }, 
+	... 
+} 
+
+WriteReplaceWarningRequestIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID								PRESENCE mandatory	}|
+	{ ID id-PWSSystemInformation 				CRITICALITY reject	TYPE PWSSystemInformation 						PRESENCE mandatory }| 
+	{ ID id-RepetitionPeriod 					CRITICALITY reject	TYPE RepetitionPeriod 							PRESENCE mandatory }| 
+	{ ID id-NumberofBroadcastRequest 			CRITICALITY reject	TYPE NumberofBroadcastRequest 				PRESENCE mandatory }| 
+	{ ID id-Cells-To-Be-Broadcast-List			CRITICALITY reject	TYPE Cells-To-Be-Broadcast-List				PRESENCE optional	},
+	... 
+}
+
+Cells-To-Be-Broadcast-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-To-Be-Broadcast-List-ItemIEs } }
+
+Cells-To-Be-Broadcast-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-To-Be-Broadcast-Item		CRITICALITY reject	TYPE	Cells-To-Be-Broadcast-Item		PRESENCE mandatory	},
+	...
+}
+
+-- ************************************************************** 
+-- 
+-- Write-Replace Warning Response 
+-- 
+-- ************************************************************** 
+
+WriteReplaceWarningResponse ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { {WriteReplaceWarningResponseIEs} }, 
+	... 
+} 
+
+WriteReplaceWarningResponseIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID										PRESENCE mandatory	}|
+	{ ID id-Cells-Broadcast-Completed-List			CRITICALITY reject	TYPE Cells-Broadcast-Completed-List				PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics					CRITICALITY ignore	TYPE CriticalityDiagnostics							PRESENCE optional	}|
+	{ ID id-Dedicated-SIDelivery-NeededUE-List		CRITICALITY ignore	TYPE Dedicated-SIDelivery-NeededUE-List			PRESENCE optional	},
+	...
+}
+
+Cells-Broadcast-Completed-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-Broadcast-Completed-List-ItemIEs } }
+
+Cells-Broadcast-Completed-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-Broadcast-Completed-Item		CRITICALITY reject	TYPE	Cells-Broadcast-Completed-Item		PRESENCE mandatory	},
+	...
+}
+
+
+-- ************************************************************** 
+-- 
+-- PWS CANCEL ELEMENTARY PROCEDURE 
+-- 
+-- ************************************************************** 
+
+-- ************************************************************** 
+-- 
+-- PWS Cancel Request 
+-- 
+-- ************************************************************** 
+
+PWSCancelRequest ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { {PWSCancelRequestIEs} }, 
+	... 
+} 
+
+PWSCancelRequestIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID							CRITICALITY reject TYPE TransactionID									PRESENCE mandatory	}|
+	{ ID id-NumberofBroadcastRequest 				CRITICALITY reject TYPE NumberofBroadcastRequest						PRESENCE mandatory }| 
+	{ ID id-Broadcast-To-Be-Cancelled-List			CRITICALITY reject TYPE Broadcast-To-Be-Cancelled-List				PRESENCE optional	}|
+	{ ID id-Cancel-all-Warning-Messages-Indicator	CRITICALITY reject TYPE Cancel-all-Warning-Messages-Indicator	PRESENCE optional	}|
+	{ ID id-NotificationInformation					CRITICALITY reject TYPE NotificationInformation						PRESENCE optional},
+	... 
+}
+
+Broadcast-To-Be-Cancelled-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Broadcast-To-Be-Cancelled-List-ItemIEs } }
+
+Broadcast-To-Be-Cancelled-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Broadcast-To-Be-Cancelled-Item		CRITICALITY reject	TYPE	Broadcast-To-Be-Cancelled-Item		PRESENCE mandatory	},
+	...
+}
+
+-- ************************************************************** 
+-- 
+-- PWS Cancel Response 
+-- 
+-- ************************************************************** 
+
+PWSCancelResponse ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { {PWSCancelResponseIEs} }, 
+	... 
+} 
+
+PWSCancelResponseIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-Cells-Broadcast-Cancelled-List	CRITICALITY reject	TYPE Cells-Broadcast-Cancelled-List	PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics				PRESENCE optional	},
+	... 
+}
+
+Cells-Broadcast-Cancelled-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-Broadcast-Cancelled-List-ItemIEs } }
+
+Cells-Broadcast-Cancelled-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-Broadcast-Cancelled-Item		CRITICALITY reject	TYPE	Cells-Broadcast-Cancelled-Item		PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Inactivity Notification ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE Inactivity Notification
+--
+-- **************************************************************
+
+UEInactivityNotification ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ UEInactivityNotificationIEs}},
+	...
+}
+
+UEInactivityNotificationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-DRB-Activity-List							CRITICALITY reject	TYPE DRB-Activity-List							PRESENCE mandatory	}	,
+	...
+}
+
+DRB-Activity-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRB-Activity-ItemIEs } }
+
+DRB-Activity-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRB-Activity-Item			CRITICALITY reject	TYPE DRB-Activity-Item		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- Initial UL RRC Message Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- INITIAL UL RRC Message Transfer
+--
+-- **************************************************************
+
+InitialULRRCMessageTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ InitialULRRCMessageTransferIEs}},
+	...
+}
+
+InitialULRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-DU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID						PRESENCE mandatory	}|
+	{ ID id-NRCGI								CRITICALITY reject	TYPE NRCGI									PRESENCE mandatory	}|
+	{ ID id-C-RNTI								CRITICALITY reject	TYPE C-RNTI									PRESENCE mandatory	}|
+	{ ID id-RRCContainer						CRITICALITY reject	TYPE RRCContainer							PRESENCE mandatory	}|
+	{ ID id-DUtoCURRCContainer					CRITICALITY reject	TYPE DUtoCURRCContainer						PRESENCE optional	}|
+	{ ID id-SULAccessIndication					CRITICALITY ignore	TYPE SULAccessIndication					PRESENCE optional	}|
+	{ ID id-TransactionID						CRITICALITY ignore	TYPE TransactionID							PRESENCE mandatory	}|
+	{ ID id-RANUEID								CRITICALITY ignore	TYPE RANUEID								PRESENCE optional	}|
+	{ ID id-RRCContainer-RRCSetupComplete		CRITICALITY ignore	TYPE RRCContainer-RRCSetupComplete 		PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- DL RRC Message Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- DL RRC Message Transfer
+--
+-- **************************************************************
+
+DLRRCMessageTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ DLRRCMessageTransferIEs}},
+	...
+}
+
+DLRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-oldgNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID							PRESENCE optional	}|
+	{ ID id-SRBID										CRITICALITY reject	TYPE SRBID											PRESENCE mandatory	}|
+	{ ID id-ExecuteDuplication							CRITICALITY ignore	TYPE ExecuteDuplication							PRESENCE optional}|
+	{ ID id-RRCContainer								CRITICALITY reject	TYPE RRCContainer									PRESENCE mandatory	}|
+	{ ID id-RAT-FrequencyPriorityInformation			CRITICALITY reject	TYPE RAT-FrequencyPriorityInformation		PRESENCE optional	}|
+	{ ID id-RRCDeliveryStatusRequest					CRITICALITY ignore	TYPE RRCDeliveryStatusRequest					PRESENCE optional }|
+	{ ID id-UEContextNotRetrievable						CRITICALITY reject	TYPE UEContextNotRetrievable					PRESENCE optional }|
+	{ ID id-RedirectedRRCmessage						CRITICALITY reject	TYPE OCTET STRING									PRESENCE optional }|
+	{ ID id-PLMNAssistanceInfoForNetShar				CRITICALITY ignore	TYPE PLMN-Identity									PRESENCE optional }|
+	{ ID id-new-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID							PRESENCE optional }|
+	{ ID id-AdditionalRRMPriorityIndex					CRITICALITY ignore	TYPE AdditionalRRMPriorityIndex				PRESENCE optional },
+	...
+}
+-- **************************************************************
+--
+-- UL RRC Message Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UL RRC Message Transfer
+--
+-- **************************************************************
+
+ULRRCMessageTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ ULRRCMessageTransferIEs}},
+	...
+}
+
+ULRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-SRBID							CRITICALITY reject	TYPE SRBID							PRESENCE mandatory	}|
+	{ ID id-RRCContainer					CRITICALITY reject	TYPE RRCContainer					PRESENCE mandatory	}|
+	{ ID id-SelectedPLMNID					CRITICALITY reject	TYPE PLMN-Identity					PRESENCE optional		}|
+	{ ID id-new-gNB-DU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE optional		},
+	...
+}
+
+-- **************************************************************
+--
+-- PRIVATE MESSAGE
+--
+-- **************************************************************
+
+PrivateMessage ::= SEQUENCE {
+	privateIEs		PrivateIE-Container	{{PrivateMessage-IEs}},
+	...
+}
+
+PrivateMessage-IEs F1AP-PRIVATE-IES ::= {
+	...
+}
+
+
+-- **************************************************************
+--
+-- System Information ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- System information Delivery Command
+--
+-- **************************************************************
+
+SystemInformationDeliveryCommand ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ SystemInformationDeliveryCommandIEs}},
+	...
+}
+
+SystemInformationDeliveryCommandIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID			CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-NRCGI					CRITICALITY reject	TYPE NRCGI							PRESENCE mandatory	}|
+	{ ID id-SItype-List				CRITICALITY reject	TYPE SItype-List					PRESENCE mandatory	}|
+	{ ID id-ConfirmedUEID 			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Paging PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Paging
+--
+-- **************************************************************
+
+Paging ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ PagingIEs}},
+	...
+}
+
+PagingIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-UEIdentityIndexValue	CRITICALITY reject	TYPE UEIdentityIndexValue		PRESENCE mandatory	}|
+	{ ID id-PagingIdentity			CRITICALITY reject	TYPE PagingIdentity				PRESENCE mandatory	}|
+	{ ID id-PagingDRX				CRITICALITY ignore	TYPE PagingDRX					PRESENCE optional	}|
+	{ ID id-PagingPriority			CRITICALITY ignore	TYPE PagingPriority				PRESENCE optional	}|
+	{ ID id-PagingCell-List			CRITICALITY ignore	TYPE PagingCell-list			PRESENCE mandatory	}|
+	{ ID id-PagingOrigin			CRITICALITY ignore	TYPE PagingOrigin				PRESENCE optional	},
+	...
+}
+
+PagingCell-list::= SEQUENCE (SIZE(1.. maxnoofPagingCells)) OF ProtocolIE-SingleContainer { { PagingCell-ItemIEs } }
+
+PagingCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-PagingCell-Item		CRITICALITY ignore	TYPE PagingCell-Item			PRESENCE mandatory}	,
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- Notify
+--
+-- **************************************************************
+
+Notify ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ NotifyIEs}},
+	...
+}
+
+NotifyIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID						PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID						PRESENCE mandatory	}|
+	{ ID id-DRB-Notify-List						CRITICALITY reject	TYPE DRB-Notify-List						PRESENCE mandatory	},
+	...
+}
+
+DRB-Notify-List::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRB-Notify-ItemIEs } }
+
+DRB-Notify-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRB-Notify-Item			CRITICALITY reject	TYPE DRB-Notify-Item		PRESENCE mandatory},
+	...
+}
+
+
+-- **************************************************************
+--
+-- NETWORK ACCESS RATE REDUCTION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Network Access Rate Reduction
+--
+-- **************************************************************
+
+NetworkAccessRateReduction ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ NetworkAccessRateReductionIEs }},
+	...
+}
+
+NetworkAccessRateReductionIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID 					CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-UAC-Assistance-Info				CRITICALITY reject	TYPE UAC-Assistance-Info			PRESENCE mandatory	},
+	...
+}
+
+-- ************************************************************** 
+-- 
+-- PWS RESTART INDICATION ELEMENTARY PROCEDURE 
+-- 
+-- ************************************************************** 
+
+-- ************************************************************** 
+-- 
+-- PWS Restart Indication 
+-- 
+-- ************************************************************** 
+
+PWSRestartIndication ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { { PWSRestartIndicationIEs} }, 
+	... 
+} 
+
+PWSRestartIndicationIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-NR-CGI-List-For-Restart-List	CRITICALITY reject	TYPE NR-CGI-List-For-Restart-List	PRESENCE mandatory	},
+	... 
+}
+
+NR-CGI-List-For-Restart-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { NR-CGI-List-For-Restart-List-ItemIEs } }
+
+NR-CGI-List-For-Restart-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-NR-CGI-List-For-Restart-Item		CRITICALITY reject	TYPE	NR-CGI-List-For-Restart-Item		PRESENCE mandatory	},
+	...
+}
+
+-- ************************************************************** 
+-- 
+-- PWS FAILURE INDICATION ELEMENTARY PROCEDURE 
+-- 
+-- ************************************************************** 
+
+-- ************************************************************** 
+-- 
+-- PWS Failure Indication 
+-- 
+-- ************************************************************** 
+
+PWSFailureIndication ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { { PWSFailureIndicationIEs} }, 
+	... 
+} 
+
+PWSFailureIndicationIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID			CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-PWS-Failed-NR-CGI-List	CRITICALITY reject	TYPE PWS-Failed-NR-CGI-List		PRESENCE optional	},
+	... 
+}
+
+PWS-Failed-NR-CGI-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { PWS-Failed-NR-CGI-List-ItemIEs } }
+
+PWS-Failed-NR-CGI-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-PWS-Failed-NR-CGI-Item		CRITICALITY reject	TYPE	PWS-Failed-NR-CGI-Item		PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- gNB-DU STATUS INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- gNB-DU Status Indication
+--
+-- **************************************************************
+
+GNBDUStatusIndication ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUStatusIndicationIEs} },
+	...
+}
+
+GNBDUStatusIndicationIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-GNBDUOverloadInformation		CRITICALITY reject	TYPE GNBDUOverloadInformation		PRESENCE mandatory	},
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- RRC Delivery Report ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- RRC Delivery Report
+--
+-- **************************************************************
+
+RRCDeliveryReport ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ RRCDeliveryReportIEs}},
+	...
+}
+
+RRCDeliveryReportIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID	CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID	PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID	CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID	PRESENCE mandatory	}|
+	{ ID id-RRCDeliveryStatus	CRITICALITY ignore	TYPE RRCDeliveryStatus	PRESENCE mandatory	}|
+	{ ID id-SRBID				CRITICALITY ignore	TYPE SRBID				PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- F1 Removal ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- F1 Removal Request
+--
+-- **************************************************************
+
+F1RemovalRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ F1RemovalRequestIEs }},
+	...
+}
+
+F1RemovalRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID			CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- F1 Removal Response
+--
+-- **************************************************************
+
+F1RemovalResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ F1RemovalResponseIEs }},
+	...
+}
+
+F1RemovalResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+
+	...
+}
+
+-- **************************************************************
+--
+-- F1 Removal Failure
+--
+-- **************************************************************
+
+F1RemovalFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ F1RemovalFailureIEs }},
+	...
+}
+
+F1RemovalFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+
+	...
+}
+
+
+-- **************************************************************
+--
+-- TRACE ELEMENTARY PROCEDURES
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- TRACE START
+--
+-- **************************************************************
+
+TraceStart ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ {TraceStartIEs} },
+	...
+}
+
+TraceStartIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-TraceActivation				CRITICALITY ignore	TYPE TraceActivation				PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- DEACTIVATE TRACE
+--
+-- **************************************************************
+
+DeactivateTrace ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ {DeactivateTraceIEs} },
+	...
+}
+
+DeactivateTraceIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-TraceID						CRITICALITY ignore	TYPE TraceID						PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- CELL TRAFFIC TRACE
+--
+-- **************************************************************
+
+CellTrafficTrace ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ {CellTrafficTraceIEs} },
+	...
+}
+
+CellTrafficTraceIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ID id-TraceID							CRITICALITY ignore	TYPE TraceID						PRESENCE mandatory	}|
+	{ID id-TraceCollectionEntityIPAddress	CRITICALITY ignore	TYPE TransportLayerAddress			PRESENCE mandatory	}|
+	{ID id-PrivacyIndicator					CRITICALITY ignore	TYPE PrivacyIndicator				PRESENCE optional	}|
+
+	{ID id-TraceCollectionEntityURI	CRITICALITY ignore	TYPE URI-address		PRESENCE optional	},
+	...
+
+}
+
+-- **************************************************************
+--
+-- DU-CU Radio Information Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- DU-CU Radio Information Transfer
+--
+-- **************************************************************
+
+DUCURadioInformationTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ DUCURadioInformationTransferIEs}},
+	...
+}
+
+DUCURadioInformationTransferIEs F1AP-PROTOCOL-IES ::= {
+		{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-DUCURadioInformationType		CRITICALITY ignore	TYPE DUCURadioInformationType				PRESENCE mandatory	},
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- CU-DU Radio Information Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- CU-DU Radio Information Transfer
+--
+-- **************************************************************
+
+CUDURadioInformationTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ CUDURadioInformationTransferIEs}},
+	...
+}
+
+CUDURadioInformationTransferIEs F1AP-PROTOCOL-IES ::= {
+		{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-CUDURadioInformationType	CRITICALITY ignore	TYPE CUDURadioInformationType				PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- IAB PROCEDURES 
+--
+-- **************************************************************
+-- **************************************************************
+--
+-- BAP Mapping Configuration ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- BAP MAPPING CONFIGURATION
+-- **************************************************************
+
+
+BAPMappingConfiguration ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container	{ {BAPMappingConfiguration-IEs} },
+	...
+ }
+
+BAPMappingConfiguration-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID		CRITICALITY reject	TYPE	TransactionID	PRESENCE mandatory}|
+	{ ID id-BH-Routing-Information-Added-List		CRITICALITY ignore	TYPE	BH-Routing-Information-Added-List	PRESENCE optional}|
+	{ ID id-BH-Routing-Information-Removed-List		CRITICALITY ignore	TYPE	BH-Routing-Information-Removed-List	PRESENCE optional}|
+	{ ID id-TrafficMappingInformation				CRITICALITY ignore	TYPE	TrafficMappingInfo						PRESENCE optional},
+	...
+}
+
+BH-Routing-Information-Added-List ::= SEQUENCE (SIZE(1.. maxnoofRoutingEntries))	OF ProtocolIE-SingleContainer { { BH-Routing-Information-Added-List-ItemIEs } }
+BH-Routing-Information-Removed-List ::= SEQUENCE (SIZE(1.. maxnoofRoutingEntries))	OF ProtocolIE-SingleContainer { { BH-Routing-Information-Removed-List-ItemIEs } }
+
+BH-Routing-Information-Added-List-ItemIEs	F1AP-PROTOCOL-IES ::= {
+	{ ID id-BH-Routing-Information-Added-List-Item				CRITICALITY ignore	TYPE BH-Routing-Information-Added-List-Item						PRESENCE optional},
+	...
+}
+
+BH-Routing-Information-Removed-List-ItemIEs	F1AP-PROTOCOL-IES ::= {
+	{ ID id-BH-Routing-Information-Removed-List-Item				CRITICALITY ignore	TYPE BH-Routing-Information-Removed-List-Item						PRESENCE optional},
+	...
+}
+
+
+-- **************************************************************
+--
+-- BAP MAPPING CONFIGURATION ACKNOWLEDGE
+-- **************************************************************
+
+BAPMappingConfigurationAcknowledge ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ {BAPMappingConfigurationAcknowledge-IEs} },
+	... 
+}
+
+BAPMappingConfigurationAcknowledge-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID			CRITICALITY reject	TYPE	TransactionID			PRESENCE mandatory}|
+	{ ID id-CriticalityDiagnostics	CRITICALITY ignore	TYPE	CriticalityDiagnostics	PRESENCE optional},
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- GNB-DU Configuration ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- GNB-DU RESOURCE CONFIGURATION
+-- **************************************************************
+
+
+GNBDUResourceConfiguration ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{{ GNBDUResourceConfigurationIEs}},
+	...
+}
+
+
+GNBDUResourceConfigurationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID								PRESENCE mandatory	}|
+	{ ID id-Activated-Cells-to-be-Updated-List		CRITICALITY reject	TYPE Activated-Cells-to-be-Updated-List	PRESENCE optional}|
+	{ ID id-Child-Nodes-List						CRITICALITY reject	TYPE Child-Nodes-List							PRESENCE optional},
+	...
+} 
+
+
+
+
+-- **************************************************************
+--
+-- GNB-DU RESOURCE CONFIGURATION ACKNOWLEDGE
+-- **************************************************************
+
+
+GNBDUResourceConfigurationAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{ { GNBDUResourceConfigurationAcknowledgeIEs} },
+	...
+}
+
+
+GNBDUResourceConfigurationAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics				CRITICALITY ignore	TYPE CriticalityDiagnostics					PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- IAB TNL Address Allocation ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- IAB TNL ADDRESS REQUEST
+-- **************************************************************
+
+
+
+IABTNLAddressRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{ {IABTNLAddressRequestIEs} },
+	...
+}
+
+IABTNLAddressRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID								PRESENCE mandatory	}|
+	{ ID id-IABv4AddressesRequested				CRITICALITY reject	TYPE IABv4AddressesRequested					PRESENCE optional	}|
+	{ ID id-IABIPv6RequestType					CRITICALITY reject	TYPE IABIPv6RequestType							PRESENCE optional	}|
+	{ ID id-IAB-TNL-Addresses-To-Remove-List	CRITICALITY reject	TYPE IAB-TNL-Addresses-To-Remove-List		PRESENCE optional	},
+	...
+}
+
+
+IAB-TNL-Addresses-To-Remove-List	::= SEQUENCE (SIZE(1..maxnoofTLAsIAB))	OF ProtocolIE-SingleContainer { { IAB-TNL-Addresses-To-Remove-ItemIEs } }
+
+IAB-TNL-Addresses-To-Remove-ItemIEs	F1AP-PROTOCOL-IES::= {
+	{ ID id-IAB-TNL-Addresses-To-Remove-Item			CRITICALITY reject	TYPE IAB-TNL-Addresses-To-Remove-Item					PRESENCE mandatory},
+	...
+}
+
+
+-- **************************************************************
+--
+-- IAB TNL ADDRESS RESPONSE
+-- **************************************************************
+
+
+IABTNLAddressResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{ {IABTNLAddressResponseIEs} },
+	...
+}
+
+
+IABTNLAddressResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID								CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory	}|
+	{ ID id-IAB-Allocated-TNL-Address-List				CRITICALITY reject	TYPE IAB-Allocated-TNL-Address-List			PRESENCE mandatory	},
+	...
+}
+
+
+IAB-Allocated-TNL-Address-List ::= SEQUENCE (SIZE(1.. maxnoofTLAsIAB))	OF ProtocolIE-SingleContainer { { IAB-Allocated-TNL-Address-List-ItemIEs } }
+
+
+IAB-Allocated-TNL-Address-List-ItemIEs	F1AP-PROTOCOL-IES::= {
+	{ ID id-IAB-Allocated-TNL-Address-Item			CRITICALITY reject	TYPE IAB-Allocated-TNL-Address-Item					PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- IAB UP Configuration Update ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- IAB UP Configuration Update Request
+--
+-- **************************************************************
+
+IABUPConfigurationUpdateRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{ { IABUPConfigurationUpdateRequestIEs} },
+	...
+}
+
+IABUPConfigurationUpdateRequestIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID										PRESENCE mandatory  }|
+	{ ID id-UL-UP-TNL-Information-to-Update-List	CRITICALITY ignore	TYPE UL-UP-TNL-Information-to-Update-List		PRESENCE optional	}|
+	{ ID id-UL-UP-TNL-Address-to-Update-List		CRITICALITY ignore	TYPE UL-UP-TNL-Address-to-Update-List				PRESENCE optional	},
+	...
+}
+
+UL-UP-TNL-Information-to-Update-List ::= SEQUENCE (SIZE(1.. maxnoofULUPTNLInformationforIAB))	OF ProtocolIE-SingleContainer { { UL-UP-TNL-Information-to-Update-List-ItemIEs } }
+
+UL-UP-TNL-Information-to-Update-List-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-UL-UP-TNL-Information-to-Update-List-Item	CRITICALITY ignore	TYPE UL-UP-TNL-Information-to-Update-List-Item PRESENCE optional},
+	...
+}
+
+UL-UP-TNL-Address-to-Update-List ::= SEQUENCE (SIZE(1.. maxnoofUPTNLAddresses))	OF ProtocolIE-SingleContainer { { UL-UP-TNL-Address-to-Update-List-ItemIEs } }
+
+UL-UP-TNL-Address-to-Update-List-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-UL-UP-TNL-Address-to-Update-List-Item	CRITICALITY ignore	TYPE UL-UP-TNL-Address-to-Update-List-Item PRESENCE optional},
+	...
+}
+
+
+-- **************************************************************
+--
+-- IAB UP Configuration Update Response
+--
+-- **************************************************************
+
+IABUPConfigurationUpdateResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{ { IABUPConfigurationUpdateResponseIEs} },
+	...
+}
+
+IABUPConfigurationUpdateResponseIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics				CRITICALITY ignore	TYPE CriticalityDiagnostics					PRESENCE optional	}|
+	{ ID id-DL-UP-TNL-Address-to-Update-List	CRITICALITY reject	TYPE DL-UP-TNL-Address-to-Update-List	PRESENCE optional	},
+	...
+}
+
+DL-UP-TNL-Address-to-Update-List ::= SEQUENCE (SIZE(1.. maxnoofUPTNLAddresses))	OF ProtocolIE-SingleContainer { { DL-UP-TNL-Address-to-Update-List-ItemIEs } }
+
+DL-UP-TNL-Address-to-Update-List-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DL-UP-TNL-Address-to-Update-List-Item	CRITICALITY ignore	TYPE DL-UP-TNL-Address-to-Update-List-Item	PRESENCE optional},
+	...
+}
+
+-- **************************************************************
+--
+-- IAB UP Configuration Update Failure
+--
+-- **************************************************************
+
+IABUPConfigurationUpdateFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container		{ { IABUPConfigurationUpdateFailureIEs} },
+	...
+}
+
+IABUPConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- Resource Status Reporting Initiation ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Resource Status Request
+--
+-- **************************************************************
+
+ResourceStatusRequest::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {ResourceStatusRequestIEs} },
+	...
+}
+
+ResourceStatusRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID			CRITICALITY reject	TYPE TransactionID			PRESENCE mandatory	}|
+	{ ID id-gNBCUMeasurementID		CRITICALITY reject	TYPE GNBCUMeasurementID		PRESENCE mandatory	}|
+	{ ID id-gNBDUMeasurementID		CRITICALITY ignore	TYPE GNBDUMeasurementID		PRESENCE conditional	}|
+	{ ID id-RegistrationRequest		CRITICALITY ignore	TYPE RegistrationRequest	PRESENCE mandatory	}|
+	{ ID id-ReportCharacteristics	CRITICALITY ignore	TYPE ReportCharacteristics	PRESENCE conditional	}|
+	{ ID id-CellToReportList		CRITICALITY ignore	TYPE CellToReportList		PRESENCE optional	}|
+	{ ID id-ReportingPeriodicity	CRITICALITY ignore	TYPE ReportingPeriodicity	PRESENCE  optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Resource Status Response
+--
+-- **************************************************************
+
+ResourceStatusResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { ResourceStatusResponseIEs} },
+	...
+}
+
+
+ResourceStatusResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID			CRITICALITY reject	TYPE TransactionID			PRESENCE mandatory	}|
+	{ ID id-gNBCUMeasurementID		CRITICALITY reject	TYPE GNBCUMeasurementID		PRESENCE mandatory	}|
+	{ ID id-gNBDUMeasurementID		CRITICALITY ignore	TYPE GNBDUMeasurementID		PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics	CRITICALITY ignore	TYPE CriticalityDiagnostics	PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Resource Status Failure
+--
+-- **************************************************************
+
+ResourceStatusFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { ResourceStatusFailureIEs} },
+	...
+}
+
+ResourceStatusFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID			CRITICALITY reject	TYPE TransactionID			PRESENCE mandatory	}|
+	{ ID id-gNBCUMeasurementID		CRITICALITY reject	TYPE GNBCUMeasurementID		PRESENCE mandatory	}|
+	{ ID id-gNBDUMeasurementID		CRITICALITY ignore	TYPE GNBDUMeasurementID		PRESENCE mandatory	}|
+	{ ID id-Cause					CRITICALITY ignore	TYPE Cause					PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics	CRITICALITY ignore	TYPE CriticalityDiagnostics	PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- Resource Status Reporting ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Resource Status Update 
+--
+-- **************************************************************
+
+ResourceStatusUpdate ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ ResourceStatusUpdateIEs}},
+	...
+}
+
+ResourceStatusUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID			PRESENCE mandatory	}|
+	{ ID id-gNBCUMeasurementID			CRITICALITY reject	TYPE GNBCUMeasurementID				PRESENCE mandatory	}|
+	{ ID id-gNBDUMeasurementID			CRITICALITY ignore	TYPE GNBDUMeasurementID			PRESENCE mandatory	}|
+	{ ID id-HardwareLoadIndicator			CRITICALITY ignore	TYPE HardwareLoadIndicator			PRESENCE optional	}|
+	{ ID id-TNLCapacityIndicator			CRITICALITY ignore	TYPE TNLCapacityIndicator		PRESENCE optional	}|
+	{ ID id-CellMeasurementResultList		CRITICALITY ignore	TYPE CellMeasurementResultList	PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+--  Access And Mobility Indication ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Access And Mobility Indication 
+--
+-- **************************************************************
+
+AccessAndMobilityIndication ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { AccessAndMobilityIndicationIEs} },
+	...
+}
+
+AccessAndMobilityIndicationIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory }|
+	{ ID id-RACHReportInformationList				CRITICALITY ignore	TYPE RACHReportInformationList			PRESENCE optional }|
+	{ ID id-RLFReportInformationList				CRITICALITY ignore	TYPE RLFReportInformationList				PRESENCE optional },
+	...
+}
+
+
+-- **************************************************************
+--
+-- REFERENCE TIME INFORMATION REPORTING CONTROL
+--
+-- **************************************************************
+
+ReferenceTimeInformationReportingControl::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { ReferenceTimeInformationReportingControlIEs} },
+	...
+}
+
+ReferenceTimeInformationReportingControlIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-ReportingRequestType		CRITICALITY reject	TYPE ReportingRequestType		PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- REFERENCE TIME INFORMATION REPORT
+--
+-- **************************************************************
+
+ReferenceTimeInformationReport::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { ReferenceTimeInformationReportIEs} },
+	...
+}
+
+ReferenceTimeInformationReportIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY ignore	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-TimeReferenceInformation	CRITICALITY ignore	TYPE TimeReferenceInformation		PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Access Success
+--
+-- **************************************************************
+
+AccessSuccess ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ AccessSuccessIEs}},
+	...
+}
+
+AccessSuccessIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID						PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID						PRESENCE mandatory	}|
+	{ ID id-NRCGI								CRITICALITY reject	TYPE NRCGI									PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- POSITIONING ASSISTANCE INFORMATION CONTROL ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Assistance Information Control
+--
+-- **************************************************************
+
+PositioningAssistanceInformationControl ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ PositioningAssistanceInformationControlIEs}},
+	...
+}
+
+PositioningAssistanceInformationControlIEs F1AP-PROTOCOL-IES ::= {
+		{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+		{ ID id-PosAssistance-Information		CRITICALITY reject	TYPE PosAssistance-Information		PRESENCE optional}|
+		{ ID id-PosBroadcast					CRITICALITY reject	TYPE PosBroadcast				PRESENCE optional}|
+		{ ID id-PositioningBroadcastCells		CRITICALITY reject	TYPE PositioningBroadcastCells		PRESENCE optional}|
+		{ ID id-RoutingID						CRITICALITY reject	TYPE RoutingID				PRESENCE optional},
+	...
+}
+
+-- **************************************************************
+--
+-- POSITIONING ASSISTANCE INFORMATION FEEDBACK ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Assistance Information Feedback
+--
+-- **************************************************************
+
+PositioningAssistanceInformationFeedback ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ PositioningAssistanceInformationFeedbackIEs}},
+	...
+}
+
+PositioningAssistanceInformationFeedbackIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID							PRESENCE mandatory	}|
+	{ ID id-PosAssistanceInformationFailureList	CRITICALITY reject	TYPE PosAssistanceInformationFailureList	PRESENCE optional}|
+	{ ID id-PositioningBroadcastCells				CRITICALITY reject	TYPE PositioningBroadcastCells				PRESENCE optional}|
+	{ ID id-RoutingID								CRITICALITY reject	TYPE RoutingID									PRESENCE optional}|
+	{ ID id-CriticalityDiagnostics				CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional},
+	...
+}
+
+-- **************************************************************
+--
+-- POSITONING MEASUREMENT EXCHANGE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Measurement Request
+--
+-- **************************************************************
+
+PositioningMeasurementRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningMeasurementRequestIEs} },
+	...
+}
+
+PositioningMeasurementRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory}|
+	{ ID id-LMF-MeasurementID						CRITICALITY reject	TYPE LMF-MeasurementID								PRESENCE mandatory}|
+	{ ID id-RAN-MeasurementID						CRITICALITY reject	TYPE RAN-MeasurementID								PRESENCE mandatory}|
+	{ ID id-TRP-MeasurementRequestList				CRITICALITY reject	TYPE TRP-MeasurementRequestList					PRESENCE mandatory}|
+	{ ID id-PosReportCharacteristics				CRITICALITY reject	TYPE PosReportCharacteristics				PRESENCE mandatory}|
+	{ ID id-PosMeasurementPeriodicity				CRITICALITY reject	TYPE PosMeasurementPeriodicity					PRESENCE conditional }|
+	-- The above IE shall be present if the PosReportCharacteristics IE is set to “periodic” --
+	{ ID id-PosMeasurementQuantities				CRITICALITY reject	TYPE PosMeasurementQuantities					PRESENCE mandatory}|
+	{ ID id-SFNInitialisationTime					CRITICALITY ignore	TYPE SFNInitialisationTime	PRESENCE optional	}|
+	{ ID id-SRSConfiguration						CRITICALITY ignore	TYPE SRSConfiguration								PRESENCE optional}|
+	{ ID id-MeasurementBeamInfoRequest				CRITICALITY ignore	TYPE MeasurementBeamInfoRequest	PRESENCE optional	}|
+	{ ID id-SystemFrameNumber						CRITICALITY ignore	TYPE SystemFrameNumber		PRESENCE optional}|
+	{ ID id-SlotNumber								CRITICALITY ignore	TYPE SlotNumber				PRESENCE optional},
+	...
+} 
+
+
+-- **************************************************************
+--
+-- Positioning Measurement Response
+--
+-- **************************************************************
+
+PositioningMeasurementResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningMeasurementResponseIEs} },
+	...
+}
+
+
+PositioningMeasurementResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID							CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory}|
+	{ ID id-LMF-MeasurementID						CRITICALITY reject	TYPE LMF-MeasurementID								PRESENCE mandatory}|
+	{ ID id-RAN-MeasurementID						CRITICALITY reject	TYPE RAN-MeasurementID								PRESENCE mandatory}|
+	{ ID id-PosMeasurementResultList				CRITICALITY reject	TYPE PosMeasurementResultList					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics					CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Positioning Measurement Failure
+--
+-- **************************************************************
+
+PositioningMeasurementFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningMeasurementFailureIEs} },
+	...
+}
+
+PositioningMeasurementFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-LMF-MeasurementID				CRITICALITY reject	TYPE LMF-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-RAN-MeasurementID				CRITICALITY reject	TYPE RAN-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- POSITIONING MEASUREMENT REPORT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Measurement Report
+--
+-- **************************************************************
+
+PositioningMeasurementReport ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { PositioningMeasurementReportIEs} },
+	...
+}
+
+PositioningMeasurementReportIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-LMF-MeasurementID			CRITICALITY reject	TYPE LMF-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-RAN-MeasurementID			CRITICALITY reject	TYPE RAN-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-PosMeasurementResultList	CRITICALITY reject	TYPE PosMeasurementResultList	PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- POSITIONING MEASUREMENT ABORT ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Measurement Abort
+--
+-- **************************************************************
+
+PositioningMeasurementAbort ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { PositioningMeasurementAbortIEs} },
+	...
+}
+
+PositioningMeasurementAbortIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|	
+	{ ID id-LMF-MeasurementID				CRITICALITY reject	TYPE LMF-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-RAN-MeasurementID				CRITICALITY reject	TYPE RAN-MeasurementID				PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- POSITIONING MEASUREMENT FAILURE INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Measurement Failure Indication
+--
+-- **************************************************************
+
+PositioningMeasurementFailureIndication ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { PositioningMeasurementFailureIndicationIEs} },
+	...
+}
+
+PositioningMeasurementFailureIndicationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-LMF-MeasurementID			CRITICALITY reject	TYPE LMF-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-RAN-MeasurementID			CRITICALITY reject	TYPE RAN-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- POSITIONING MEASUREMENT UPDATE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Measurement Update
+--
+-- **************************************************************
+
+PositioningMeasurementUpdate ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { PositioningMeasurementUpdateIEs} },
+	...
+}
+
+PositioningMeasurementUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-LMF-MeasurementID			CRITICALITY reject	TYPE LMF-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-RAN-MeasurementID			CRITICALITY reject	TYPE RAN-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-SRSConfiguration			CRITICALITY ignore	TYPE SRSConfiguration			PRESENCE optional},
+	...
+}
+
+
+-- **************************************************************
+--
+-- TRP INFORMATION EXCHANGE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- TRP Information Request
+--
+-- **************************************************************
+
+TRPInformationRequest ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { TRPInformationRequestIEs} },
+	...
+}
+
+TRPInformationRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID								PRESENCE mandatory	}|
+	{ ID id-TRPList								CRITICALITY ignore	TYPE TRPList									PRESENCE optional	}|
+	{ ID id-TRPInformationTypeListTRPReq		CRITICALITY reject	TYPE TRPInformationTypeListTRPReq			PRESENCE mandatory	},
+	...
+}
+
+TRPInformationTypeListTRPReq ::= SEQUENCE (SIZE(1.. maxnoofTRPInfoTypes)) OF ProtocolIE-SingleContainer { { TRPInformationTypeItemTRPReq } }
+
+TRPInformationTypeItemTRPReq 	F1AP-PROTOCOL-IES ::= {
+	{ ID id-TRPInformationTypeItem	 CRITICALITY reject		TYPE TRPInformationTypeItem  	PRESENCE mandatory },
+	...
+}
+
+
+-- **************************************************************
+--
+-- TRP Information Response
+--
+-- **************************************************************
+
+TRPInformationResponse ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { TRPInformationResponseIEs} },
+	...
+}
+
+TRPInformationResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-TRPInformationListTRPResp		CRITICALITY ignore	TYPE TRPInformationListTRPResp		PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+	...
+}
+
+TRPInformationListTRPResp ::= SEQUENCE (SIZE(1.. maxnoofTRPs)) OF ProtocolIE-SingleContainer { { TRPInformationItemTRPResp } }
+
+TRPInformationItemTRPResp 	F1AP-PROTOCOL-IES ::= {
+	{ ID id-TRPInformationItem	 CRITICALITY ignore		TYPE TRPInformationItem  	PRESENCE mandatory },
+	...
+}
+
+
+-- **************************************************************
+--
+-- TRP Information Failure
+--
+-- **************************************************************
+
+TRPInformationFailure ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{ { TRPInformationFailureIEs} },
+	...
+}
+
+TRPInformationFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- POSITIONING INFORMATION EXCHANGE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Information Request
+--
+-- **************************************************************
+
+PositioningInformationRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningInformationRequestIEs} },
+	...
+}
+
+PositioningInformationRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-RequestedSRSTransmissionCharacteristics	CRITICALITY ignore	TYPE RequestedSRSTransmissionCharacteristics	PRESENCE optional},
+	...
+} 
+
+
+-- **************************************************************
+--
+-- Positioning Information Response
+--
+-- **************************************************************
+
+PositioningInformationResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningInformationResponseIEs} },
+	...
+}
+
+
+PositioningInformationResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|	
+	{ ID id-SRSConfiguration			CRITICALITY ignore	TYPE SRSConfiguration			PRESENCE optional}|
+	{ ID id-SFNInitialisationTime		CRITICALITY ignore	TYPE SFNInitialisationTime		PRESENCE optional}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional },
+	...
+}
+
+
+-- **************************************************************
+--
+-- Positioning Information Failure
+--
+-- **************************************************************
+
+PositioningInformationFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningInformationFailureIEs} },
+	...
+}
+
+PositioningInformationFailureIEs F1AP-PROTOCOL-IES ::= {
+	
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional },
+	...
+}
+
+
+-- **************************************************************
+--
+-- POSITIONING ACTIVATION PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Activation Request
+--
+-- **************************************************************
+
+PositioningActivationRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningActivationRequestIEs} },
+	...
+}
+
+PositioningActivationRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-SRSType					CRITICALITY reject	TYPE SRSType					PRESENCE mandatory	}|
+	{ ID id-ActivationTime			CRITICALITY ignore	TYPE SFNInitialisationTime		PRESENCE optional	},
+	...
+} 
+
+SRSType ::= CHOICE {
+	semipersistentSRS				SemipersistentSRS,
+	aperiodicSRS					AperiodicSRS, 
+	choice-extension				ProtocolIE-SingleContainer { { SRSType-ExtIEs} }
+}
+
+SRSType-ExtIEs F1AP-PROTOCOL-IES ::= {
+	...
+}
+
+SemipersistentSRS ::= SEQUENCE {
+	sRSResourceSetID			SRSResourceSetID,
+	sRSSpatialRelation			SRSSpatialRelation	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { {SemipersistentSRS-ExtIEs} } OPTIONAL,
+	...
+}
+
+SemipersistentSRS-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+AperiodicSRS ::= SEQUENCE {
+	aperiodic					ENUMERATED {true, ...},
+	sRSResourceTrigger			SRSResourceTrigger		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { {AperiodicSRS-ExtIEs} } OPTIONAL,
+	...
+}
+
+AperiodicSRS-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+-- **************************************************************
+--
+-- Positioning Activation Response
+--
+-- **************************************************************
+
+PositioningActivationResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningActivationResponseIEs} },
+	...
+}
+
+
+PositioningActivationResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-SystemFrameNumber		CRITICALITY ignore	TYPE SystemFrameNumber			PRESENCE optional }|
+	{ ID id-SlotNumber				CRITICALITY ignore	TYPE SlotNumber					PRESENCE optional }|
+	{ ID id-CriticalityDiagnostics	CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional },
+	...
+}
+
+
+
+
+-- **************************************************************
+--
+-- Positioning Activation Failure
+--
+-- **************************************************************
+
+PositioningActivationFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningActivationFailureIEs} },
+	...
+}
+
+PositioningActivationFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional },
+	...
+}
+
+
+-- **************************************************************
+--
+-- POSITIONING DEACTIVATION PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Deactivation
+--
+-- **************************************************************
+
+PositioningDeactivation ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningDeactivationIEs} },
+	...
+}
+
+PositioningDeactivationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-AbortTransmission		CRITICALITY ignore	TYPE AbortTransmission			PRESENCE mandatory	},
+	...
+} 
+
+-- **************************************************************
+--
+-- POSITIONING INFORMATION UPDATE PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Positioning Information Update
+--
+-- **************************************************************
+
+PositioningInformationUpdate ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { PositioningInformationUpdateIEs} },
+	...
+}
+
+
+PositioningInformationUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-SRSConfiguration		CRITICALITY ignore	TYPE SRSConfiguration			PRESENCE optional}|
+	{ ID id-SFNInitialisationTime	CRITICALITY ignore	TYPE SFNInitialisationTime		PRESENCE optional},
+	...
+}
+
+-- **************************************************************
+--
+-- E-CID MEASUREMENT PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- E-CID Measurement Initiation Request
+--
+-- **************************************************************
+
+E-CIDMeasurementInitiationRequest ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container	{{E-CIDMeasurementInitiationRequest-IEs}},
+	...
+}
+
+E-CIDMeasurementInitiationRequest-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID					PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID					PRESENCE mandatory	}|
+	{ ID id-LMF-UE-MeasurementID			CRITICALITY reject	TYPE LMF-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-RAN-UE-MeasurementID			CRITICALITY reject	TYPE RAN-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-E-CID-ReportCharacteristics		CRITICALITY reject	TYPE E-CID-ReportCharacteristics		PRESENCE mandatory	}|
+	{ ID id-E-CID-MeasurementPeriodicity	CRITICALITY reject	TYPE E-CID-MeasurementPeriodicity		PRESENCE conditional	}|
+-- The above IE shall be present if the E-CID-ReportCharacteristics IE is set to “periodic” –-
+	{ ID id-E-CID-MeasurementQuantities		CRITICALITY reject	TYPE E-CID-MeasurementQuantities		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- E-CID Measurement Initiation Response
+--
+-- **************************************************************
+
+E-CIDMeasurementInitiationResponse ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container	{{E-CIDMeasurementInitiationResponse-IEs}},
+	...
+}
+
+E-CIDMeasurementInitiationResponse-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-LMF-UE-MeasurementID		CRITICALITY reject	TYPE LMF-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-RAN-UE-MeasurementID		CRITICALITY reject	TYPE RAN-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-E-CID-MeasurementResult		CRITICALITY ignore	TYPE E-CID-MeasurementResult		PRESENCE optional}|
+	{ ID id-Cell-Portion-ID				CRITICALITY ignore	TYPE Cell-Portion-ID				PRESENCE optional}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional},
+	...
+}
+
+-- **************************************************************
+--
+-- E-CID Measurement Initiation Failure
+--
+-- **************************************************************
+
+E-CIDMeasurementInitiationFailure ::= SEQUENCE {
+	protocolIEs						ProtocolIE-Container		{{E-CIDMeasurementInitiationFailure-IEs}},
+	...
+}
+
+
+E-CIDMeasurementInitiationFailure-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-LMF-UE-MeasurementID		CRITICALITY reject	TYPE LMF-UE-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-RAN-UE-MeasurementID		CRITICALITY reject	TYPE RAN-UE-MeasurementID			PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional},
+	...
+}
+
+-- **************************************************************
+--
+-- E-CID MEASUREMENT FAILURE INDICATION PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- E-CID Measurement Failure Indication
+--
+-- **************************************************************
+
+E-CIDMeasurementFailureIndication ::= SEQUENCE {
+	protocolIEs						ProtocolIE-Container		{{E-CIDMeasurementFailureIndication-IEs}},
+	...
+}
+
+
+E-CIDMeasurementFailureIndication-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-LMF-UE-MeasurementID		CRITICALITY reject	TYPE LMF-UE-MeasurementID		PRESENCE mandatory	}|
+	{ ID id-RAN-UE-MeasurementID		CRITICALITY reject	TYPE RAN-UE-MeasurementID		PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- E-CID MEASUREMENT REPORT PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- E-CID Measurement Report
+--
+-- **************************************************************
+
+E-CIDMeasurementReport ::= SEQUENCE {
+	protocolIEs						ProtocolIE-Container		{{E-CIDMeasurementReport-IEs}},
+	...
+}
+
+
+E-CIDMeasurementReport-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-LMF-UE-MeasurementID		CRITICALITY reject	TYPE LMF-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-RAN-UE-MeasurementID		CRITICALITY reject	TYPE RAN-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-E-CID-MeasurementResult		CRITICALITY ignore	TYPE E-CID-MeasurementResult		PRESENCE mandatory }|
+	{ ID id-Cell-Portion-ID				CRITICALITY ignore	TYPE Cell-Portion-ID				PRESENCE optional},
+
+	...
+}
+
+-- **************************************************************
+--
+-- E-CID MEASUREMENT TERMINATION PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- E-CID Measurement Termination Command
+--
+-- **************************************************************
+
+
+E-CIDMeasurementTerminationCommand ::= SEQUENCE {
+	protocolIEs						ProtocolIE-Container		{{E-CIDMeasurementTerminationCommand-IEs}},
+	...
+}
+
+
+E-CIDMeasurementTerminationCommand-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID					PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID					PRESENCE mandatory	}|
+	{ ID id-LMF-UE-MeasurementID		CRITICALITY reject	TYPE LMF-UE-MeasurementID				PRESENCE mandatory	}|
+	{ ID id-RAN-UE-MeasurementID		CRITICALITY reject	TYPE RAN-UE-MeasurementID				PRESENCE mandatory	},
+	...
+}
+
+
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-PDU-Descriptions.asn b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-PDU-Descriptions.asn
new file mode 100644
index 0000000000000000000000000000000000000000..6ec795ab10078f7c86a976e35a6b93f62af01fe6
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R16.3.1/F1AP-PDU-Descriptions.asn
@@ -0,0 +1,723 @@
+-- **************************************************************
+--
+-- Elementary Procedure definitions
+--
+-- **************************************************************
+
+F1AP-PDU-Descriptions  { 
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Descriptions (0)}
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	Criticality,
+	ProcedureCode
+
+FROM F1AP-CommonDataTypes
+	Reset,
+	ResetAcknowledge,
+	F1SetupRequest,
+	F1SetupResponse,
+	F1SetupFailure, 
+	GNBDUConfigurationUpdate,
+	GNBDUConfigurationUpdateAcknowledge,
+	GNBDUConfigurationUpdateFailure,
+	GNBCUConfigurationUpdate,
+	GNBCUConfigurationUpdateAcknowledge,
+	GNBCUConfigurationUpdateFailure,
+	UEContextSetupRequest,
+	UEContextSetupResponse,
+	UEContextSetupFailure,
+	UEContextReleaseCommand,
+	UEContextReleaseComplete,
+	UEContextModificationRequest,
+	UEContextModificationResponse,
+	UEContextModificationFailure,
+	UEContextModificationRequired,
+	UEContextModificationConfirm,
+	ErrorIndication,
+	UEContextReleaseRequest,
+	DLRRCMessageTransfer,
+	ULRRCMessageTransfer,
+	GNBDUResourceCoordinationRequest,
+	GNBDUResourceCoordinationResponse,
+	PrivateMessage,
+	UEInactivityNotification,
+	InitialULRRCMessageTransfer,
+	SystemInformationDeliveryCommand,
+	Paging,
+	Notify,
+	WriteReplaceWarningRequest,
+	WriteReplaceWarningResponse,
+	PWSCancelRequest,
+	PWSCancelResponse,
+	PWSRestartIndication,
+	PWSFailureIndication,
+	GNBDUStatusIndication,
+	RRCDeliveryReport,
+	UEContextModificationRefuse,
+	F1RemovalRequest,
+	F1RemovalResponse,
+	F1RemovalFailure,
+	NetworkAccessRateReduction,
+	TraceStart,
+	DeactivateTrace,
+	DUCURadioInformationTransfer,
+	CUDURadioInformationTransfer,
+	BAPMappingConfiguration,
+	BAPMappingConfigurationAcknowledge,
+	GNBDUResourceConfiguration,
+	GNBDUResourceConfigurationAcknowledge,
+	IABTNLAddressRequest,
+	IABTNLAddressResponse,
+	IABUPConfigurationUpdateRequest,
+	IABUPConfigurationUpdateResponse,
+	IABUPConfigurationUpdateFailure,
+	ResourceStatusRequest,
+	ResourceStatusResponse,
+	ResourceStatusFailure,
+	ResourceStatusUpdate,
+	AccessAndMobilityIndication,
+	ReferenceTimeInformationReportingControl,
+	ReferenceTimeInformationReport,
+	AccessSuccess,
+	CellTrafficTrace,
+	PositioningMeasurementRequest,
+	PositioningMeasurementResponse,
+	PositioningMeasurementFailure,
+	PositioningAssistanceInformationControl,
+	PositioningAssistanceInformationFeedback,
+	PositioningMeasurementReport,
+	PositioningMeasurementAbort,
+	PositioningMeasurementFailureIndication,
+	PositioningMeasurementUpdate,
+	TRPInformationRequest,
+	TRPInformationResponse,
+	TRPInformationFailure,
+	PositioningInformationRequest,
+	PositioningInformationResponse,
+	PositioningInformationFailure,
+	PositioningActivationRequest,
+	PositioningActivationResponse,
+	PositioningActivationFailure,
+	PositioningDeactivation,
+	PositioningInformationUpdate,
+	E-CIDMeasurementInitiationRequest,
+	E-CIDMeasurementInitiationResponse,
+	E-CIDMeasurementInitiationFailure,
+	E-CIDMeasurementFailureIndication,
+	E-CIDMeasurementReport,
+	E-CIDMeasurementTerminationCommand
+
+
+
+FROM F1AP-PDU-Contents
+	id-Reset,
+	id-F1Setup,
+	id-gNBDUConfigurationUpdate,
+	id-gNBCUConfigurationUpdate,
+	id-UEContextSetup,
+	id-UEContextRelease,
+	id-UEContextModification,
+	id-UEContextModificationRequired,
+	id-ErrorIndication, 
+	id-UEContextReleaseRequest,
+	id-DLRRCMessageTransfer,
+	id-ULRRCMessageTransfer,
+	id-GNBDUResourceCoordination,
+	id-privateMessage,
+	id-UEInactivityNotification,
+	id-InitialULRRCMessageTransfer,
+	id-SystemInformationDeliveryCommand,
+	id-Paging,
+	id-Notify,
+	id-WriteReplaceWarning,
+	id-PWSCancel,
+	id-PWSRestartIndication,
+	id-PWSFailureIndication,
+	id-GNBDUStatusIndication,
+	id-RRCDeliveryReport,
+	id-F1Removal,
+	id-NetworkAccessRateReduction,
+	id-TraceStart,
+	id-DeactivateTrace,
+	id-DUCURadioInformationTransfer,
+	id-CUDURadioInformationTransfer,
+	id-BAPMappingConfiguration,
+	id-GNBDUResourceConfiguration,
+	id-IABTNLAddressAllocation,
+	id-IABUPConfigurationUpdate,
+	id-resourceStatusReportingInitiation,
+	id-resourceStatusReporting,
+	id-accessAndMobilityIndication,
+	id-ReferenceTimeInformationReportingControl,
+	id-ReferenceTimeInformationReport,
+	id-accessSuccess,
+	id-cellTrafficTrace,
+	id-PositioningMeasurementExchange,
+	id-PositioningAssistanceInformationControl,
+	id-PositioningAssistanceInformationFeedback,
+	id-PositioningMeasurementReport,
+	id-PositioningMeasurementAbort,
+	id-PositioningMeasurementFailureIndication,
+	id-PositioningMeasurementUpdate,
+	id-TRPInformationExchange,
+	id-PositioningInformationExchange,
+	id-PositioningActivation,
+	id-PositioningDeactivation,
+	id-PositioningInformationUpdate,
+	id-E-CIDMeasurementInitiation,
+	id-E-CIDMeasurementFailureIndication,
+	id-E-CIDMeasurementReport,
+	id-E-CIDMeasurementTermination
+
+
+FROM F1AP-Constants
+
+	ProtocolIE-SingleContainer{},
+	F1AP-PROTOCOL-IES
+
+FROM F1AP-Containers;
+
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure Class
+--
+-- **************************************************************
+
+F1AP-ELEMENTARY-PROCEDURE ::= CLASS {
+	&InitiatingMessage				,
+	&SuccessfulOutcome							OPTIONAL,
+	&UnsuccessfulOutcome						OPTIONAL,
+	&procedureCode				ProcedureCode 	UNIQUE,
+	&criticality				Criticality 	DEFAULT ignore
+}
+WITH SYNTAX {
+	INITIATING MESSAGE			&InitiatingMessage
+	[SUCCESSFUL OUTCOME			&SuccessfulOutcome]
+	[UNSUCCESSFUL OUTCOME		&UnsuccessfulOutcome]
+	PROCEDURE CODE				&procedureCode
+	[CRITICALITY				&criticality]
+}
+
+-- **************************************************************
+--
+-- Interface PDU Definition
+--
+-- **************************************************************
+
+F1AP-PDU ::= CHOICE {
+	initiatingMessage	InitiatingMessage,
+	successfulOutcome	SuccessfulOutcome,
+	unsuccessfulOutcome	UnsuccessfulOutcome, 
+	choice-extension	ProtocolIE-SingleContainer { { F1AP-PDU-ExtIEs} }
+}
+
+F1AP-PDU-ExtIEs F1AP-PROTOCOL-IES ::= { -- this extension is not used
+	...
+}
+
+InitiatingMessage ::= SEQUENCE {
+	procedureCode	F1AP-ELEMENTARY-PROCEDURE.&procedureCode		({F1AP-ELEMENTARY-PROCEDURES}),
+	criticality		F1AP-ELEMENTARY-PROCEDURE.&criticality			({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+	value			F1AP-ELEMENTARY-PROCEDURE.&InitiatingMessage	({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+SuccessfulOutcome ::= SEQUENCE {
+	procedureCode	F1AP-ELEMENTARY-PROCEDURE.&procedureCode		({F1AP-ELEMENTARY-PROCEDURES}),
+	criticality		F1AP-ELEMENTARY-PROCEDURE.&criticality			({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+	value			F1AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome	({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+UnsuccessfulOutcome ::= SEQUENCE {
+	procedureCode	F1AP-ELEMENTARY-PROCEDURE.&procedureCode		({F1AP-ELEMENTARY-PROCEDURES}),
+	criticality		F1AP-ELEMENTARY-PROCEDURE.&criticality			({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+	value			F1AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome	({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure List
+--
+-- **************************************************************
+
+F1AP-ELEMENTARY-PROCEDURES F1AP-ELEMENTARY-PROCEDURE ::= {
+	F1AP-ELEMENTARY-PROCEDURES-CLASS-1			|
+	F1AP-ELEMENTARY-PROCEDURES-CLASS-2,	
+	...
+}
+
+
+F1AP-ELEMENTARY-PROCEDURES-CLASS-1 F1AP-ELEMENTARY-PROCEDURE ::= {
+	reset							|
+	f1Setup							|
+	gNBDUConfigurationUpdate		|
+	gNBCUConfigurationUpdate		|
+	uEContextSetup					|
+	uEContextRelease				|
+	uEContextModification			|
+	uEContextModificationRequired	|
+	writeReplaceWarning				|
+	pWSCancel					|
+	gNBDUResourceCoordination		|
+	f1Removal						|
+	bAPMappingConfiguration			|
+	gNBDUResourceConfiguration		|
+	iABTNLAddressAllocation			|
+	iABUPConfigurationUpdate		|
+	resourceStatusReportingInitiation	|
+	positioningMeasurementExchange	|
+	tRPInformationExchange			|
+	positioningInformationExchange	|
+	positioningActivation			|
+	e-CIDMeasurementInitiation,
+	...
+}
+
+F1AP-ELEMENTARY-PROCEDURES-CLASS-2 F1AP-ELEMENTARY-PROCEDURE ::= {	
+	errorIndication							|
+	uEContextReleaseRequest					|
+	dLRRCMessageTransfer					|
+	uLRRCMessageTransfer					|
+	uEInactivityNotification				|
+	privateMessage							|
+	initialULRRCMessageTransfer				|
+	systemInformationDelivery				|
+	paging									|
+	notify									|
+	pWSRestartIndication					|
+	pWSFailureIndication					|
+	gNBDUStatusIndication					|
+	rRCDeliveryReport						|
+	networkAccessRateReduction				|
+	traceStart								|
+	deactivateTrace							|
+	dUCURadioInformationTransfer			|
+	cUDURadioInformationTransfer			|
+	resourceStatusReporting					|
+	accessAndMobilityIndication				|
+	referenceTimeInformationReportingControl|
+	referenceTimeInformationReport			|
+	accessSuccess							|
+	cellTrafficTrace						|
+	positioningAssistanceInformationControl		|
+	positioningAssistanceInformationFeedback	|
+	positioningMeasurementReport				|
+	positioningMeasurementAbort					|
+	positioningMeasurementFailureIndication		|
+	positioningMeasurementUpdate				|
+	positioningDeactivation						|
+	e-CIDMeasurementFailureIndication			|
+	e-CIDMeasurementReport						|
+	e-CIDMeasurementTermination					|
+	positioningInformationUpdate,
+	...
+}
+-- **************************************************************
+--
+-- Interface Elementary Procedures
+--
+-- **************************************************************
+
+reset F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		Reset
+	SUCCESSFUL OUTCOME		ResetAcknowledge
+	PROCEDURE CODE			id-Reset
+	CRITICALITY				reject
+}
+
+f1Setup F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		F1SetupRequest
+	SUCCESSFUL OUTCOME		F1SetupResponse
+	UNSUCCESSFUL OUTCOME	F1SetupFailure
+	PROCEDURE CODE			id-F1Setup
+	CRITICALITY				reject
+}
+
+gNBDUConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBDUConfigurationUpdate
+	SUCCESSFUL OUTCOME		GNBDUConfigurationUpdateAcknowledge
+	UNSUCCESSFUL OUTCOME	GNBDUConfigurationUpdateFailure
+	PROCEDURE CODE			id-gNBDUConfigurationUpdate
+	CRITICALITY				reject
+}
+
+gNBCUConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBCUConfigurationUpdate
+	SUCCESSFUL OUTCOME		GNBCUConfigurationUpdateAcknowledge
+	UNSUCCESSFUL OUTCOME	GNBCUConfigurationUpdateFailure
+	PROCEDURE CODE			id-gNBCUConfigurationUpdate
+	CRITICALITY				reject
+}
+
+uEContextSetup F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextSetupRequest
+	SUCCESSFUL OUTCOME		UEContextSetupResponse
+	UNSUCCESSFUL OUTCOME	UEContextSetupFailure
+	PROCEDURE CODE			id-UEContextSetup
+	CRITICALITY				reject
+}
+
+uEContextRelease F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextReleaseCommand
+	SUCCESSFUL OUTCOME		UEContextReleaseComplete
+	PROCEDURE CODE			id-UEContextRelease
+	CRITICALITY				reject
+}
+
+uEContextModification F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextModificationRequest
+	SUCCESSFUL OUTCOME		UEContextModificationResponse
+	UNSUCCESSFUL OUTCOME	UEContextModificationFailure
+	PROCEDURE CODE			id-UEContextModification
+	CRITICALITY				reject
+}
+
+uEContextModificationRequired F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextModificationRequired
+	SUCCESSFUL OUTCOME		UEContextModificationConfirm
+	UNSUCCESSFUL OUTCOME	UEContextModificationRefuse
+	PROCEDURE CODE			id-UEContextModificationRequired
+	CRITICALITY				reject
+}
+
+writeReplaceWarning F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		WriteReplaceWarningRequest
+	SUCCESSFUL OUTCOME		WriteReplaceWarningResponse
+	PROCEDURE CODE			id-WriteReplaceWarning
+	CRITICALITY				reject
+}
+
+pWSCancel F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PWSCancelRequest
+	SUCCESSFUL OUTCOME		PWSCancelResponse
+	PROCEDURE CODE			id-PWSCancel
+	CRITICALITY				reject
+}
+
+errorIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ErrorIndication
+	PROCEDURE CODE			id-ErrorIndication
+	CRITICALITY				ignore
+}
+
+uEContextReleaseRequest F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextReleaseRequest
+	PROCEDURE CODE			id-UEContextReleaseRequest
+	CRITICALITY				ignore
+}
+
+
+initialULRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		InitialULRRCMessageTransfer
+	PROCEDURE CODE			id-InitialULRRCMessageTransfer
+	CRITICALITY				ignore
+}
+
+dLRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		DLRRCMessageTransfer
+	PROCEDURE CODE			id-DLRRCMessageTransfer
+	CRITICALITY				ignore
+}
+
+uLRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ULRRCMessageTransfer
+	PROCEDURE CODE			id-ULRRCMessageTransfer
+	CRITICALITY				ignore
+}
+
+
+uEInactivityNotification  F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEInactivityNotification
+	PROCEDURE CODE			id-UEInactivityNotification
+	CRITICALITY				ignore
+}
+
+gNBDUResourceCoordination F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBDUResourceCoordinationRequest
+	SUCCESSFUL OUTCOME		GNBDUResourceCoordinationResponse
+	PROCEDURE CODE			id-GNBDUResourceCoordination
+	CRITICALITY				reject
+}
+
+privateMessage F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PrivateMessage
+	PROCEDURE CODE			id-privateMessage
+	CRITICALITY				ignore
+}
+
+systemInformationDelivery F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		SystemInformationDeliveryCommand
+	PROCEDURE CODE			id-SystemInformationDeliveryCommand
+	CRITICALITY				ignore
+}
+
+
+paging F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		Paging
+	PROCEDURE CODE			id-Paging
+	CRITICALITY				ignore
+}
+
+notify F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		Notify
+	PROCEDURE CODE			id-Notify
+	CRITICALITY				ignore
+}
+
+networkAccessRateReduction F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		NetworkAccessRateReduction
+	PROCEDURE CODE			id-NetworkAccessRateReduction
+	CRITICALITY				ignore
+}
+
+
+pWSRestartIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PWSRestartIndication
+	PROCEDURE CODE			id-PWSRestartIndication
+	CRITICALITY				ignore
+}
+
+pWSFailureIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PWSFailureIndication
+	PROCEDURE CODE			id-PWSFailureIndication
+	CRITICALITY				ignore
+}
+
+gNBDUStatusIndication 	F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBDUStatusIndication
+	PROCEDURE CODE			id-GNBDUStatusIndication
+	CRITICALITY				ignore
+}
+
+
+rRCDeliveryReport F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		RRCDeliveryReport
+	PROCEDURE CODE			id-RRCDeliveryReport
+	CRITICALITY				ignore
+}
+
+f1Removal F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		F1RemovalRequest
+	SUCCESSFUL OUTCOME		F1RemovalResponse
+	UNSUCCESSFUL OUTCOME	F1RemovalFailure
+	PROCEDURE CODE			id-F1Removal
+	CRITICALITY				reject
+}
+
+traceStart F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		TraceStart
+	PROCEDURE CODE			id-TraceStart
+	CRITICALITY				ignore
+}
+
+deactivateTrace F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		DeactivateTrace
+	PROCEDURE CODE			id-DeactivateTrace
+	CRITICALITY				ignore
+}
+
+dUCURadioInformationTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		DUCURadioInformationTransfer
+	PROCEDURE CODE			id-DUCURadioInformationTransfer
+	CRITICALITY				ignore
+}
+
+cUDURadioInformationTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		CUDURadioInformationTransfer
+	PROCEDURE CODE			id-CUDURadioInformationTransfer
+	CRITICALITY				ignore
+}
+
+bAPMappingConfiguration F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		BAPMappingConfiguration
+	SUCCESSFUL OUTCOME		BAPMappingConfigurationAcknowledge
+	PROCEDURE CODE			id-BAPMappingConfiguration
+	CRITICALITY				reject
+}
+
+gNBDUResourceConfiguration F1AP-ELEMENTARY-PROCEDURE ::= { 
+	INITIATING MESSAGE		GNBDUResourceConfiguration
+	SUCCESSFUL OUTCOME		GNBDUResourceConfigurationAcknowledge
+	PROCEDURE CODE			id-GNBDUResourceConfiguration
+	CRITICALITY				reject
+}
+
+iABTNLAddressAllocation F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		IABTNLAddressRequest
+	SUCCESSFUL OUTCOME		IABTNLAddressResponse
+	PROCEDURE CODE			id-IABTNLAddressAllocation
+	CRITICALITY				reject
+}
+
+iABUPConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		IABUPConfigurationUpdateRequest
+	SUCCESSFUL OUTCOME		IABUPConfigurationUpdateResponse
+	UNSUCCESSFUL OUTCOME	IABUPConfigurationUpdateFailure
+	PROCEDURE CODE			id-IABUPConfigurationUpdate
+	CRITICALITY				reject
+}
+
+resourceStatusReportingInitiation F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ResourceStatusRequest
+	SUCCESSFUL OUTCOME		ResourceStatusResponse
+	UNSUCCESSFUL OUTCOME	ResourceStatusFailure
+	PROCEDURE CODE			id-resourceStatusReportingInitiation
+	CRITICALITY				reject
+}
+
+resourceStatusReporting F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ResourceStatusUpdate
+	PROCEDURE CODE			id-resourceStatusReporting
+	CRITICALITY				ignore
+}
+
+accessAndMobilityIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		AccessAndMobilityIndication
+	PROCEDURE CODE			id-accessAndMobilityIndication
+	CRITICALITY				ignore
+}
+
+referenceTimeInformationReportingControl F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ReferenceTimeInformationReportingControl
+	PROCEDURE CODE			id-ReferenceTimeInformationReportingControl
+	CRITICALITY				ignore
+}
+
+referenceTimeInformationReport F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ReferenceTimeInformationReport
+	PROCEDURE CODE			id-ReferenceTimeInformationReport
+	CRITICALITY				ignore
+}
+
+accessSuccess F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		AccessSuccess
+	PROCEDURE CODE			id-accessSuccess
+	CRITICALITY				ignore
+}
+
+cellTrafficTrace F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		CellTrafficTrace
+	PROCEDURE CODE			id-cellTrafficTrace
+	CRITICALITY				ignore
+}
+
+positioningAssistanceInformationControl F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningAssistanceInformationControl
+	PROCEDURE CODE			id-PositioningAssistanceInformationControl
+	CRITICALITY				ignore
+}
+
+positioningAssistanceInformationFeedback F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningAssistanceInformationFeedback
+	PROCEDURE CODE			id-PositioningAssistanceInformationFeedback
+	CRITICALITY				ignore
+}
+
+positioningMeasurementExchange F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningMeasurementRequest
+	SUCCESSFUL OUTCOME		PositioningMeasurementResponse
+	UNSUCCESSFUL OUTCOME	PositioningMeasurementFailure
+	PROCEDURE CODE			id-PositioningMeasurementExchange
+	CRITICALITY				reject
+}
+
+positioningMeasurementReport F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningMeasurementReport
+	PROCEDURE CODE			id-PositioningMeasurementReport
+	CRITICALITY				ignore
+}
+
+positioningMeasurementAbort F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningMeasurementAbort
+	PROCEDURE CODE			id-PositioningMeasurementAbort
+	CRITICALITY				ignore
+}
+
+positioningMeasurementFailureIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningMeasurementFailureIndication
+	PROCEDURE CODE			id-PositioningMeasurementFailureIndication
+	CRITICALITY				ignore
+}
+
+positioningMeasurementUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningMeasurementUpdate
+	PROCEDURE CODE			id-PositioningMeasurementUpdate
+	CRITICALITY				ignore
+}
+
+
+tRPInformationExchange F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		TRPInformationRequest
+	SUCCESSFUL OUTCOME		TRPInformationResponse
+	UNSUCCESSFUL OUTCOME	TRPInformationFailure
+	PROCEDURE CODE			id-TRPInformationExchange
+	CRITICALITY				reject
+}
+
+positioningInformationExchange F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningInformationRequest
+	SUCCESSFUL OUTCOME		PositioningInformationResponse
+	UNSUCCESSFUL OUTCOME	PositioningInformationFailure
+	PROCEDURE CODE			id-PositioningInformationExchange
+	CRITICALITY				reject
+}
+
+positioningActivation F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningActivationRequest
+	SUCCESSFUL OUTCOME		PositioningActivationResponse
+	UNSUCCESSFUL OUTCOME	PositioningActivationFailure
+	PROCEDURE CODE			id-PositioningActivation
+	CRITICALITY				reject
+}
+
+positioningDeactivation F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningDeactivation
+	PROCEDURE CODE			id-PositioningDeactivation
+	CRITICALITY				ignore
+}
+
+e-CIDMeasurementInitiation F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		E-CIDMeasurementInitiationRequest
+	SUCCESSFUL OUTCOME		E-CIDMeasurementInitiationResponse
+	UNSUCCESSFUL OUTCOME	E-CIDMeasurementInitiationFailure
+	PROCEDURE CODE			id-E-CIDMeasurementInitiation
+	CRITICALITY				reject
+}
+
+e-CIDMeasurementFailureIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		E-CIDMeasurementFailureIndication
+	PROCEDURE CODE			id-E-CIDMeasurementFailureIndication
+	CRITICALITY				ignore
+}
+
+e-CIDMeasurementReport F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		E-CIDMeasurementReport
+	PROCEDURE CODE			id-E-CIDMeasurementReport
+	CRITICALITY				ignore
+}
+
+e-CIDMeasurementTermination F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		E-CIDMeasurementTerminationCommand
+	PROCEDURE CODE			id-E-CIDMeasurementTermination
+	CRITICALITY				ignore
+}
+
+positioningInformationUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PositioningInformationUpdate
+	PROCEDURE CODE			id-PositioningInformationUpdate
+	CRITICALITY				ignore
+}
+
+
+END
diff --git a/targets/RT/USER/rfsim.h b/openair2/F1AP/dummy_enb.c
similarity index 71%
rename from targets/RT/USER/rfsim.h
rename to openair2/F1AP/dummy_enb.c
index 801ab5eb564a0837379846f17552d9d6a86d1098..fe6dfb6a06af9f3130cc418a4136ac6f1e487fc6 100644
--- a/targets/RT/USER/rfsim.h
+++ b/openair2/F1AP/dummy_enb.c
@@ -18,23 +18,17 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-#ifndef __RFSIM__H__
-#define __RFSIM__H__
-#include "lte-softmodem.h"
-#include "openair1/SIMULATION/TOOLS/sim.h"
-#include "platform_constants.h"
-#include "common/ran_context.h"
-#include "PHY/defs_UE.h"
-#include "PHY/defs_eNB.h"
-
-void init_ocm(void);
 
-void update_ocm(double snr_dB,double sinr_dB);
-
-//extern pthread_mutex_t async_server_lock;
-//extern pthread_cond_t async_server_notify;
-//extern int async_server_shutdown;
+#include "COMMON/platform_types.h"
+#include "common/ran_context.h"
+#include "common/utils/LOG/log.h"
+#include "NR_BCCH-BCH-Message.h"
+#include "NR_ServingCellConfigCommon.h"
+#include "NR_MIB.h"
 
-void init_channel_vars(void);
+void apply_macrlc_config(gNB_RRC_INST *rrc,
+                         rrc_gNB_ue_context_t         *const ue_context_pP,
+                         const protocol_ctxt_t        *const ctxt_pP ) {
+abort();
+}
 
-#endif
diff --git a/openair2/F1AP/f1ap_common.h b/openair2/F1AP/f1ap_common.h
index ee57a7ec838e41ca4374e03a1fc1e762b1a3f345..7781a78412ecb4e1c9caf08d805c62995a9c79ed 100644
--- a/openair2/F1AP/f1ap_common.h
+++ b/openair2/F1AP/f1ap_common.h
@@ -46,7 +46,6 @@
 inline void ASN_DEBUG(const char *fmt, ...);
 #endif
 
-#include "F1AP_Active-Cells-List.h"
 #include "F1AP_RAT-FrequencyPriorityInformation.h"
 #include "F1AP_DLUPTNLInformation-ToBeSetup-Item.h"
 #include "F1AP_PrivateMessage.h"
@@ -55,6 +54,7 @@ inline void ASN_DEBUG(const char *fmt, ...);
 #include "F1AP_NRPCI.h"
 #include "F1AP_Transmission-Bandwidth.h"
 #include "F1AP_SIB1-message.h"
+#include "F1AP_SibtypetobeupdatedListItem.h"
 #include "F1AP_GNBCUConfigurationUpdateAcknowledge.h"
 #include "F1AP_DRBs-Setup-Item.h"
 #include "F1AP_EUTRA-NR-CellResourceCoordinationReqAck-Container.h"
@@ -75,7 +75,6 @@ inline void ASN_DEBUG(const char *fmt, ...);
 #include "F1AP_DRBs-Required-ToBeModified-Item.h"
 #include "F1AP_BitRate.h"
 #include "F1AP_SRBs-ToBeSetup-List.h"
-#include "F1AP_ConcurrentWarningMessageIndicator.h"
 #include "F1AP_CriticalityDiagnostics-IE-Item.h"
 #include "F1AP_GNB-CU-TNL-Association-To-Update-List.h"
 #include "F1AP_DRB-Notify-List.h"
@@ -85,6 +84,7 @@ inline void ASN_DEBUG(const char *fmt, ...);
 #include "F1AP_PWS-Failed-NR-CGI-List.h"
 #include "F1AP_InitialULRRCMessageTransfer.h"
 #include "F1AP_Served-Cell-Information.h"
+#include "F1AP_ServedPLMNs-Item.h"
 #include "F1AP_Served-EUTRA-Cells-Information.h"
 #include "F1AP_Cells-Broadcast-Cancelled-Item.h"
 #include "F1AP_F1SetupRequest.h"
@@ -128,13 +128,11 @@ inline void ASN_DEBUG(const char *fmt, ...);
 #include "F1AP_TransactionID.h"
 #include "F1AP_AllocationAndRetentionPriority.h"
 #include "F1AP_ShortDRXCycleLength.h"
-#include "F1AP_BroadcastPLMNs-Item.h"
 #include "F1AP_DRB-Information.h"
 #include "F1AP_TimeToWait.h"
 #include "F1AP_NonDynamic5QIDescriptor.h"
 #include "F1AP_C-RNTI.h"
 #include "F1AP_MIB-message.h"
-#include "F1AP_SIBtype-Item.h"
 #include "F1AP_Served-Cells-To-Modify-List.h"
 #include "F1AP_NRCGI.h"
 #include "F1AP_DuplicationActivation.h"
@@ -187,6 +185,7 @@ inline void ASN_DEBUG(const char *fmt, ...);
 #include "F1AP_CellULConfigured.h"
 #include "F1AP_DRB-Activity.h"
 #include "F1AP_GNB-CU-TNL-Association-Failed-To-Setup-Item.h"
+#include "F1AP_ProtocolIE-ID.h"
 #include "F1AP_PrivateIE-ID.h"
 #include "F1AP_WriteReplaceWarningResponse.h"
 #include "F1AP_CauseMisc.h"
@@ -231,9 +230,7 @@ inline void ASN_DEBUG(const char *fmt, ...);
 #include "F1AP_SUL-Information.h"
 #include "F1AP_CriticalityDiagnostics-IE-List.h"
 #include "F1AP_EUTRA-FDD-Info.h"
-#include "F1AP_BroadcastPLMNs-List.h"
 #include "F1AP_Served-Cells-To-Delete-Item.h"
-#include "F1AP_ListofEUTRACellsinGNBDUCoordination.h"
 #include "F1AP_Candidate-SpCell-Item.h"
 #include "F1AP_Cells-To-Be-Broadcast-List.h"
 #include "F1AP_ULRRCMessageTransfer.h"
@@ -255,7 +252,6 @@ inline void ASN_DEBUG(const char *fmt, ...);
 #include "F1AP_SRBs-ToBeReleased-List.h"
 #include "F1AP_MeasGapConfig.h"
 #include "F1AP_NR-Mode-Info.h"
-#include "F1AP_Active-Cells-Item.h"
 #include "F1AP_Protected-EUTRA-Resources-List.h"
 #include "F1AP_SRBs-FailedToBeSetup-Item.h"
 #include "F1AP_ResetAll.h"
@@ -287,7 +283,6 @@ inline void ASN_DEBUG(const char *fmt, ...);
 #include "F1AP_UEContextReleaseRequest.h"
 #include "F1AP_GNB-DU-Name.h"
 #include "F1AP_DRBs-ToBeModified-Item.h"
-#include "F1AP_SIBtype-List.h"
 #include "F1AP_EUTRA-NR-CellResourceCoordinationReq-Container.h"
 #include "F1AP_DRBs-SetupMod-List.h"
 #include "F1AP_DRBs-Required-ToBeModified-List.h"
@@ -296,7 +291,6 @@ inline void ASN_DEBUG(const char *fmt, ...);
 #include "F1AP_PacketDelayBudget.h"
 #include "F1AP_GNBCUConfigurationUpdate.h"
 #include "F1AP_Cells-Broadcast-Completed-Item.h"
-#include "F1AP_RRCRconfigurationCompleteIndicator.h"
 #include "F1AP_PagingPriority.h"
 #include "F1AP_Cells-Failed-to-be-Activated-List.h"
 #include "F1AP_Endpoint-IP-address-and-port.h"
@@ -306,7 +300,6 @@ inline void ASN_DEBUG(const char *fmt, ...);
 #include "F1AP_ResetType.h"
 #include "F1AP_FDD-Info.h"
 #include "F1AP_DLUPTNLInformation-ToBeSetup-List.h"
-#include "F1AP_QoSFlowIndicator.h"
 #include "F1AP_NR-CGI-List-For-Restart-List.h"
 #include "F1AP_F1SetupResponse.h"
 #include "F1AP_UEContextSetupResponse.h"
@@ -325,7 +318,6 @@ inline void ASN_DEBUG(const char *fmt, ...);
 #include "F1AP_Cells-to-be-Barred-List.h"
 #include "F1AP_Presence.h"
 #include "F1AP_CellBarred.h"
-#include "F1AP_SIBtype.h"
 #include "F1AP_RequestType.h"
 #include "F1AP_NRFreqInfo.h"
 #include "F1AP_Potential-SpCell-Item.h"
@@ -348,7 +340,6 @@ inline void ASN_DEBUG(const char *fmt, ...);
 #include "F1AP_GBR-QoSFlowInformation.h"
 #include "F1AP_SCellIndex.h"
 #include "F1AP_DRBs-SetupMod-Item.h"
-#include "F1AP_TransmissionStopIndicator.h"
 #include "F1AP_UEContextSetupFailure.h"
 #include "F1AP_DRBs-FailedToBeModified-List.h"
 #include "F1AP_DRBs-FailedToBeSetupMod-Item.h"
diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c
index 01cd4aa9e029793870aac5b071d99ce1954e67b6..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,57 +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 */
-    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]);
   }
@@ -245,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;
@@ -305,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
-    }
-
-    /* optional */
-    /* - gNB-CU System Information */
-    if (1) {
+  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) {
       /* 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));
@@ -355,35 +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");
-      OCTET_STRING_fromBuf(&gNB_CUSystemInformation->sImessage,
-                           (const char*)f1ap_setup_resp->SI_container[i][0], 
-                           f1ap_setup_resp->SI_container_length[i][0]);
-
-      LOG_D(F1AP, "f1ap_setup_resp->SI_container_length = %d \n", f1ap_setup_resp->SI_container_length[0][0]);
+          //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));
+          memset((void*)sib_item,0,sizeof(*sib_item));
+          sib_item->sIBtype = sIBtype;
+          OCTET_STRING_fromBuf(&sib_item->sIBmessage,
+             (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));
 
-      F1AP_ProtocolExtensionContainer_160P9_t p_160P9_t;
-      memset((void *)&p_160P9_t, 0, sizeof(F1AP_ProtocolExtensionContainer_160P9_t));
-
-      ASN_SEQUENCE_ADD(&p_160P9_t.list,
-                      cells_to_be_activated_list_itemExtIEs);
-      cells_to_be_activated_list_item.iE_Extensions = (struct F1AP_ProtocolExtensionContainer*)&p_160P9_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);
     }
-    /* 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;
   }
 
@@ -469,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;
   }
 
@@ -508,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;
@@ -517,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 */
@@ -538,308 +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 */
+    /* 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;
 
-  /* 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);
+    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));
 
-  /* 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;
-   
 
-       /* 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);
+      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;
 
-  /* 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;
-   
+      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);
 
-       /* 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);
 
+    /* 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++) {
 
-  /* 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);
+      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;
+      // 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);
 
-  for (i=0;
-       i<1;
-       i++) {
+      // 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;
 
-       F1AP_Protected_EUTRA_Resources_ItemIEs_t *protected_eutra_resources_item_ies;
+      // 4.1.2 tNLAssociationUsage
+      gnb_cu_tnl_association_to_add_item.tNLAssociationUsage = F1AP_TNLAssociationUsage_non_ue;
 
-       /* 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_SpectrumSharingGroupID;
-       protected_eutra_resources_item_ies->value.choice.SpectrumSharingGroupID = 1L;
 
-       ASN_SEQUENCE_ADD(&ie->value.choice.Protected_EUTRA_Resources_List.list, protected_eutra_resources_item_ies);
 
-       /* 8.2 ListofEUTRACellsinGNBDUCoordination */
-       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_ListofEUTRACellsinGNBDUCoordination;
+      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));
 
@@ -870,16 +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;
 }
@@ -895,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 306a1fe14bb73216444dbab6d878f8bf925fba5b..8a5b9785b50f50c95beea62d6f93cbd540db0724 100644
--- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
+++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
@@ -38,13 +38,6 @@
 #include "common/ran_context.h"
 #include "openair3/UTILS/conversions.h"
 
-// undefine C_RNTI from
-// openair1/PHY/LTE_TRANSPORT/transport_common.h which
-// replaces in ie->value.choice.C_RNTI, causing
-// a compile error
-#undef C_RNTI 
-
-
 // Bing Kai: create CU and DU context, and put all the information there.
 uint64_t        du_ue_f1ap_id = 0;
 uint32_t        f1ap_assoc_id = 0;
@@ -109,33 +102,67 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t             instance,
   /* RNTI */
   F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
                              F1AP_ProtocolIE_ID_id_C_RNTI, true);
-  BUFFER_TO_INT16(ie->value.choice.C_RNTI.buf, rnti);
+  rnti = ie->value.choice.C_RNTI;
 
   /* 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 +175,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 +206,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,31 +288,36 @@ 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 */
   /* TODO */ 
-  if (0) {
-    ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
-    ie->id                            = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation;
-    ie->criticality                   = F1AP_Criticality_reject;
-    ie->value.present                 = F1AP_DLRRCMessageTransferIEs__value_PR_RAT_FrequencyPriorityInformation;
-
-    ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_subscriberProfileIDforRFP;
-    ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP = 123L;
-
+  int endc=1;
+  ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
+  ie->id                            = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation;
+  ie->criticality                   = F1AP_Criticality_reject;
+  ie->value.present                 = F1AP_DLRRCMessageTransferIEs__value_PR_RAT_FrequencyPriorityInformation;
+  if (endc==1) {
+    ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_eNDC;
+    ie->value.choice.RAT_FrequencyPriorityInformation.choice.eNDC = 123L;
+  }
+  else {
+    ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN;
+    ie->value.choice.RAT_FrequencyPriorityInformation.choice.nGRAN = 11L;
+  }
     //ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority;
     //ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority = 123L;
-    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 DL RRC MESSAGE TRANSFER \n");
     return -1;
   }
 
@@ -299,7 +340,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;
@@ -348,6 +388,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);
@@ -370,6 +411,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 789ce4c715b3dd5336e866786b5fd5c150ce4962..da723ba5a38f8612efb899afb1b2532a8be0d0f3 100644
--- a/openair2/F1AP/f1ap_cu_ue_context_management.c
+++ b/openair2/F1AP/f1ap_cu_ue_context_management.c
@@ -39,12 +39,15 @@
 
 #include "rrc_extern.h"
 #include "rrc_eNB_UE_context.h"
+#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
 #include "rrc_eNB_S1AP.h"
 #include "rrc_eNB_GTPV1U.h"
+#include "openair2/RRC/NR/rrc_gNB_NGAP.h"
 
 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) {
@@ -108,7 +111,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
   /* mandatory */
   /* c4. ServCellIndex */
   ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
-  ie->id                             = F1AP_ProtocolIE_ID_id_ServCellndex;
+  ie->id                             = F1AP_ProtocolIE_ID_id_ServCellIndex;
   ie->criticality                    = F1AP_Criticality_reject;
   ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_ServCellIndex;
   ie->value.choice.ServCellIndex = 2;
@@ -263,7 +266,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 */
@@ -379,75 +382,86 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
       }
 
     } else { 
-      /* 12.1.2 dRB_Information */
-      drbs_toBeSetup_item.qoSInformation.present = F1AP_QoSInformation_PR_dRB_Information;
-      drbs_toBeSetup_item.qoSInformation.choice.dRB_Information = (F1AP_DRB_Information_t *)calloc(1, sizeof(F1AP_DRB_Information_t));
-      
+      /* 12.1.2 DRB_Information */
+      drbs_toBeSetup_item.qoSInformation.present = F1AP_QoSInformation_PR_choice_extension;
+
+      F1AP_QoSInformation_ExtIEs_t *ie;
+      ie = (F1AP_QoSInformation_ExtIEs_t *)calloc(1, sizeof(F1AP_QoS_Characteristics_ExtIEs_t));
+      ie->id                             = F1AP_ProtocolIE_ID_id_DRB_Information;
+      ie->criticality                    = F1AP_Criticality_reject;
+      ie->value.present                  = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information;
+      F1AP_DRB_Information_t   *DRB_Information = &ie->value.choice.DRB_Information;
+
+      drbs_toBeSetup_item.qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer*)ie;
+
+
       /* 12.1.2.1 dRB_QoS */
       {
         /* qoS_Characteristics */
         {
           int some_decide_qoS_characteristics = 1; // BK: Need Check
           if (some_decide_qoS_characteristics) {
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI = (F1AP_NonDynamic5QIDescriptor_t *)calloc(1, sizeof(F1AP_NonDynamic5QIDescriptor_t));
+            DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
+            DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI = (F1AP_NonDynamic5QIDescriptor_t *)calloc(1, sizeof(F1AP_NonDynamic5QIDescriptor_t));
             
             /* fiveQI */
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI = 1L;
+            DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI = 1L;
 
             /* OPTIONAL */
             /* qoSPriorityLevel */
             if (0) {
-              drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->qoSPriorityLevel = (long *)calloc(1, sizeof(long));
-              *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->qoSPriorityLevel = 1L;
+              DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->qoSPriorityLevel = (long *)calloc(1, sizeof(long));
+              *DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->qoSPriorityLevel = 1L;
             }
 
             /* OPTIONAL */
             /* averagingWindow */
             if (0) {
-              drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow = (F1AP_AveragingWindow_t *)calloc(1, sizeof(F1AP_AveragingWindow_t));
-              *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow = 1L;
+              DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow = (F1AP_AveragingWindow_t *)calloc(1, sizeof(F1AP_AveragingWindow_t));
+              *DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow = 1L;
             }
 
             /* OPTIONAL */
             /* maxDataBurstVolume */
             if (0) {
-              drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume = (F1AP_MaxDataBurstVolume_t *)calloc(1, sizeof(F1AP_MaxDataBurstVolume_t));
-              *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume = 1L;
+              DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume = (F1AP_MaxDataBurstVolume_t *)calloc(1, sizeof(F1AP_MaxDataBurstVolume_t));
+              *DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume = 1L;
             }
 
           } else {
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI;
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI = (F1AP_Dynamic5QIDescriptor_t *)calloc(1, sizeof(F1AP_Dynamic5QIDescriptor_t));
+            DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI;
+            DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI = (F1AP_Dynamic5QIDescriptor_t *)calloc(1, sizeof(F1AP_Dynamic5QIDescriptor_t));
             
             /* qoSPriorityLevel */
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->qoSPriorityLevel = 1L;
+            DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->qoSPriorityLevel = 1L;
 
             /* packetDelayBudget */
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->packetDelayBudget = 1L;
+            DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->packetDelayBudget = 1L;
 
             /* packetErrorRate */
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->packetErrorRate = 1L;
+            DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->packetErrorRate.pER_Scalar = 1L;
+            DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->packetErrorRate.pER_Exponent = 6L;
+
 
             /* OPTIONAL */
             /* delayCritical */
             if (0) {
-              drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical = (long *)calloc(1, sizeof(long));
-              *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical = 1L;
+              DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical = (long *)calloc(1, sizeof(long));
+              *DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical = 1L;
             }
 
             /* OPTIONAL */
             /* averagingWindow */
             if (0) {
-              drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow = (F1AP_AveragingWindow_t *)calloc(1, sizeof(F1AP_AveragingWindow_t));
-              *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow = 1L;
+              DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow = (F1AP_AveragingWindow_t *)calloc(1, sizeof(F1AP_AveragingWindow_t));
+              *DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow = 1L;
             }
 
             /* OPTIONAL */
             /* maxDataBurstVolume */
             if (0) {
-              drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume = (F1AP_MaxDataBurstVolume_t *)calloc(1, sizeof(F1AP_MaxDataBurstVolume_t));
-              *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume = 1L;
+              DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume = (F1AP_MaxDataBurstVolume_t *)calloc(1, sizeof(F1AP_MaxDataBurstVolume_t));
+              *DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume = 1L;
             }
 
           } // if some_decide_qoS_characteristics
@@ -456,32 +470,32 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
 
         /* nGRANallocationRetentionPriority */
         {
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum
+            DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum
+            DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum
+            DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum
         } // nGRANallocationRetentionPriority
 
         /* OPTIONAL */
         /* gBR_QoS_Flow_Information */
         if (0) {
-          drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information = (F1AP_GBR_QoSFlowInformation_t *)calloc(1, sizeof(F1AP_GBR_QoSFlowInformation_t)); 
-          asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxFlowBitRateDownlink, 1L);
-          asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxFlowBitRateUplink, 1L);
-          asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->guaranteedFlowBitRateDownlink, 1L);
-          asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->guaranteedFlowBitRateUplink, 1L);
+          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);
+          asn_long2INTEGER(&DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->guaranteedFlowBitRateUplink, 1L);
 
           /* OPTIONAL */
           /* maxPacketLossRateDownlink */
           if (0) {
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t)); 
-            *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = 1L;
+            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) {
-            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t)); 
-            *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink = 1L;
+            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;
           }
 
         }
@@ -489,8 +503,8 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
         /* OPTIONAL */
         /* reflective_QoS_Attribute */
         if (0) {
-          drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.reflective_QoS_Attribute = (long *)calloc(1, sizeof(long)); 
-          *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.reflective_QoS_Attribute = 1L;
+          DRB_Information->dRB_QoS.reflective_QoS_Attribute = (long *)calloc(1, sizeof(long));
+          *DRB_Information->dRB_QoS.reflective_QoS_Attribute = 1L;
         }
 
       } // dRB_QoS
@@ -498,21 +512,21 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
       /* 12.1.2.2 sNSSAI */
       {
         /* sST */
-        OCTET_STRING_fromBuf(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->sNSSAI.sST, "asdsa1d32sa1d31asd31as",
+        OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, "asdsa1d32sa1d31asd31as",
                            strlen("asdsa1d32sa1d31asd31as"));
         /* OPTIONAL */
         /* sD */
         if (0) {
-          drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->sNSSAI.sD = (OCTET_STRING_t *)calloc(1, sizeof(OCTET_STRING_t));
-          OCTET_STRING_fromBuf(drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->sNSSAI.sD, "asdsa1d32sa1d31asd31as",
+          DRB_Information->sNSSAI.sD = (OCTET_STRING_t *)calloc(1, sizeof(OCTET_STRING_t));
+          OCTET_STRING_fromBuf(DRB_Information->sNSSAI.sD, "asdsa1d32sa1d31asd31as",
                            strlen("asdsa1d32sa1d31asd31as"));
         }
       }
       /* OPTIONAL */
       /* 12.1.2.3 notificationControl */
       if (0) {
-        drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->notificationControl = (F1AP_NotificationControl_t *)calloc(1, sizeof(F1AP_NotificationControl_t));
-        *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->notificationControl = F1AP_NotificationControl_active; // enum
+        DRB_Information->notificationControl = (F1AP_NotificationControl_t *)calloc(1, sizeof(F1AP_NotificationControl_t));
+        *DRB_Information->notificationControl = F1AP_NotificationControl_active; // enum
       }
 
       /* 12.1.2.4 flows_Mapped_To_DRB_List */  // BK: need verifiy
@@ -523,7 +537,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
         memset((void *)&flows_mapped_to_drb_item, 0, sizeof(F1AP_Flows_Mapped_To_DRB_Item_t));
         
         /* qoSFlowIndicator */
-        flows_mapped_to_drb_item.qoSFlowIndicator = 1L;
+        flows_mapped_to_drb_item.qoSFlowIdentifier = 1L;
 
         /* qoSFlowLevelQoSParameters */
         {  
@@ -569,9 +583,10 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
               flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->packetDelayBudget = 1L;
 
               /* packetErrorRate */
-              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->packetErrorRate = 1L;
+              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 */
+	            /* OPTIONAL */
               /* delayCritical */
               if (0) {
                 flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->delayCritical = (long *)calloc(1, sizeof(long));
@@ -637,7 +652,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
 
         } // qoSFlowLevelQoSParameters
         // BK: need check
-        ASN_SEQUENCE_ADD(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->flows_Mapped_To_DRB_List.list, &flows_mapped_to_drb_item);
+        ASN_SEQUENCE_ADD(&DRB_Information->flows_Mapped_To_DRB_List.list, &flows_mapped_to_drb_item);
       }
 
     } // if some_decide_qos
@@ -672,7 +687,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
         drbs_toBeSetup_item.rLCMode = F1AP_RLCMode_rlc_am;
         break;
       default:
-        drbs_toBeSetup_item.rLCMode = F1AP_RLCMode_rlc_um;
+        drbs_toBeSetup_item.rLCMode = F1AP_RLCMode_rlc_um_bidirectional;
     }
 
     /* OPTIONAL */
@@ -716,26 +731,26 @@ 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 some_decide_rat = 1; // BK: Need Check
-    if (some_decide_rat) {
-      ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_subscriberProfileIDforRFP;
-      ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP = 11L;
+    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;
     } else {
-      ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority;
-      ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority = 11L;
+      ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN;
+      ie->value.choice.RAT_FrequencyPriorityInformation.choice.nGRAN = 11L;
     }
     ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
   }
 
   /* 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);
   }
 
@@ -752,10 +767,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;
 }
 
@@ -763,7 +796,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,
@@ -963,35 +1031,55 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t       instance,
     // F1AP_CriticalityDiagnostics_IE_List
   }
 
-  struct rrc_eNB_ue_context_s *ue_context_p =
-      rrc_eNB_get_ue_context(RC.rrc[instance], rnti);
   protocol_ctxt_t ctxt;
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, ENB_FLAG_YES, rnti, 0, 0, instance);
 
-  if (ue_context_p) {
-    /* The following is normally done in the function rrc_rx_tx() */
-    rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(instance,
-        ue_context_p->ue_context.eNB_ue_s1ap_id);
-
-    rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(instance, ue_context_p);
-    // erase data of GTP tunnels in UE context
-    for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
-      ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
-      memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
-             0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
-      ue_context_p->ue_context.enb_gtp_ebi[e_rab]  = 0;
-    }
+  if (RC.nrrrc[instance]->node_type == ngran_gNB_CU) {
+    struct rrc_gNB_ue_context_s *ue_context_p =
+        rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti);
+
+    if (ue_context_p) {
+      MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
+      NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.gNB_ue_ngap_id;
+      itti_send_msg_to_task(TASK_NGAP, instance, msg);
 
-    struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids =
-        rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], 0,
-                                ue_context_p->ue_context.eNB_ue_s1ap_id);
-    if (rrc_ue_s1ap_ids)
-        rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids);
+      rrc_gNB_remove_ue_context(&ctxt, RC.nrrrc[instance], ue_context_p);
+    } else {
+      LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
+    }
+#ifdef ITTI_SIM
+    return 0;
+#endif
 
-    /* trigger UE release in RRC */
-    rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_p);
   } else {
-    LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
+    struct rrc_eNB_ue_context_s *ue_context_p =
+        rrc_eNB_get_ue_context(RC.rrc[instance], rnti);
+
+    if (ue_context_p) {
+      /* The following is normally done in the function rrc_rx_tx() */
+      rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(instance,
+          ue_context_p->ue_context.eNB_ue_s1ap_id);
+
+      rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(instance, ue_context_p);
+      // erase data of GTP tunnels in UE context
+      for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
+        ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
+        memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
+              0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
+        ue_context_p->ue_context.enb_gtp_ebi[e_rab]  = 0;
+      }
+
+      struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids =
+          rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], 0,
+                                  ue_context_p->ue_context.eNB_ue_s1ap_id);
+      if (rrc_ue_s1ap_ids)
+          rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids);
+
+      /* trigger UE release in RRC */
+      rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_p);
+    } else {
+      LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
+    }
   }
 
   pdcp_remove_UE(&ctxt);
@@ -1019,8 +1107,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 */
@@ -1061,7 +1149,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);
@@ -1070,7 +1158,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
   /* mandatory */
   /* c4. ServCellIndex */
   ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
-  ie->id                             = F1AP_ProtocolIE_ID_id_ServCellndex;
+  ie->id                             = F1AP_ProtocolIE_ID_id_ServCellIndex;
   ie->criticality                    = F1AP_Criticality_reject;
   ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_ServCellIndex;
   ie->value.choice.ServCellIndex     = 5L;
@@ -1114,13 +1202,13 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
   }
 
   /* optional */
-  /* c6. TransmissionStopIndicator */
+  /* c6. TransmissionActionIndicator */
   if (1) {
     ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
-    ie->id                                     = F1AP_ProtocolIE_ID_id_TransmissionStopIndicator;
+    ie->id                                     = F1AP_ProtocolIE_ID_id_TransmissionActionIndicator;
     ie->criticality                            = F1AP_Criticality_ignore;
-    ie->value.present                          = F1AP_UEContextModificationRequestIEs__value_PR_TransmissionStopIndicator;
-    ie->value.choice.TransmissionStopIndicator = F1AP_TransmissionStopIndicator_true;
+    ie->value.present                          = F1AP_UEContextModificationRequestIEs__value_PR_TransmissionActionIndicator;
+    ie->value.choice.TransmissionActionIndicator = F1AP_TransmissionActionIndicator_stop;
     ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
   }
 
@@ -1140,10 +1228,10 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
   /* c7. RRCRconfigurationCompleteIndicator */
   if (1) {
     ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
-    ie->id                             = F1AP_ProtocolIE_ID_id_RRCRconfigurationCompleteIndicator;
+    ie->id                             = F1AP_ProtocolIE_ID_id_RRCReconfigurationCompleteIndicator;
     ie->criticality                    = F1AP_Criticality_ignore;
-    ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_RRCRconfigurationCompleteIndicator;
-    ie->value.choice.RRCRconfigurationCompleteIndicator = F1AP_RRCRconfigurationCompleteIndicator_true;
+    ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_RRCReconfigurationCompleteIndicator;
+    ie->value.choice.RRCReconfigurationCompleteIndicator = F1AP_RRCReconfigurationCompleteIndicator_true;
     ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
   }
 
@@ -1186,7 +1274,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 */
@@ -1226,7 +1314,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 */
@@ -1325,7 +1413,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
     }
 
     /* rLCMode */
-    drbs_toBeSetupMod_item.rLCMode = F1AP_RLCMode_rlc_um; // enum
+    drbs_toBeSetupMod_item.rLCMode = F1AP_RLCMode_rlc_um_bidirectional; // enum
 
     /* OPTIONAL */
     /* ULConfiguration */
@@ -1366,9 +1454,10 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
     drbs_toBeModified_item.dRBID = 30L;
 
     /* qoSInformation */
-    drbs_toBeModified_item.qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS;
-    drbs_toBeModified_item.qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t));
-    drbs_toBeModified_item.qoSInformation.choice.eUTRANQoS->qCI = 254L;
+    drbs_toBeModified_item.qoSInformation =calloc(1,sizeof(*drbs_toBeModified_item.qoSInformation));
+    drbs_toBeModified_item.qoSInformation->present = F1AP_QoSInformation_PR_eUTRANQoS;
+    drbs_toBeModified_item.qoSInformation->choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t));
+    drbs_toBeModified_item.qoSInformation->choice.eUTRANQoS->qCI = 254L;
 
     /* ULTunnels_ToBeModified_List */
     int j = 0;
@@ -1472,7 +1561,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 86b5b1cb77748c836525e84a5911b3e6b11837a4..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,
@@ -95,7 +106,6 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
   uint8_t  *buffer;
   uint32_t  len;
   int       i = 0;
-  int       j = 0;
 
   /* Create */
   /* 0. pdu Type */
@@ -189,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){
@@ -201,19 +221,11 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
                              2);
         }
 
-        /* - broadcast PLMNs */
-        // RK: add the num_available_broadcast_PLMNs to the message 
-        int num_available_broadcast_PLMNs = 1; //f1ap_du_data->num_available_broadcast_PLMNs;
-        LOG_D(F1AP, "num_available_broadcast_PLMNs = %d \n", num_available_broadcast_PLMNs);
-        for (j=0;
-            j<num_available_broadcast_PLMNs;    // num_available_broadcast_PLMNs
-            j++) {
-            /* > PLMN BroadcastPLMNs Item */
-            F1AP_BroadcastPLMNs_Item_t *broadcastPLMNs_Item = (F1AP_BroadcastPLMNs_Item_t *)calloc(1, sizeof(F1AP_BroadcastPLMNs_Item_t));
-            //MCC_MNC_TO_PLMNID(208, 95, 2, &broadcastPLMNs_Item->pLMN_Identity);
-            MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i], &broadcastPLMNs_Item->pLMN_Identity);
-            ASN_SEQUENCE_ADD(&served_cell_information.servedPLMNs.list, broadcastPLMNs_Item);
-        }
+        /* servedPLMN information */
+        F1AP_ServedPLMNs_Item_t *servedPLMN_item = calloc(1,sizeof(*servedPLMN_item));
+        memset(servedPLMN_item,0,sizeof(*servedPLMN_item));
+        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;
@@ -237,7 +249,7 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
 
             /* FDD.1.3 freqBandListNr */
             int fdd_ul_num_available_freq_Bands = f1ap_du_data->nr_mode_info[i].fdd.ul_num_frequency_bands;
-            LOG_D(F1AP, "fdd_ul_num_available_freq_Bands = %d \n", fdd_ul_num_available_freq_Bands);
+            LOG_I(F1AP, "fdd_ul_num_available_freq_Bands = %d \n", fdd_ul_num_available_freq_Bands);
             int fdd_ul_j;
             for (fdd_ul_j=0;
                  fdd_ul_j<fdd_ul_num_available_freq_Bands;
@@ -279,7 +291,7 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
 
             /* FDD.2.3 freqBandListNr */
             int fdd_dl_num_available_freq_Bands = f1ap_du_data->nr_mode_info[i].fdd.dl_num_frequency_bands;
-            LOG_D(F1AP, "fdd_dl_num_available_freq_Bands = %d \n", fdd_dl_num_available_freq_Bands);
+            LOG_I(F1AP, "fdd_dl_num_available_freq_Bands = %d \n", fdd_dl_num_available_freq_Bands);
             int fdd_dl_j;
             for (fdd_dl_j=0;
                  fdd_dl_j<fdd_dl_num_available_freq_Bands;
@@ -308,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
@@ -333,7 +345,8 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
 
             /* TDD.1.3 freqBandListNr */
             int tdd_num_available_freq_Bands = f1ap_du_data->nr_mode_info[i].tdd.num_frequency_bands;
-            LOG_D(F1AP, "tdd_num_available_freq_Bands = %d \n", tdd_num_available_freq_Bands);
+            LOG_I(F1AP, "tdd_num_available_freq_Bands = %d \n", tdd_num_available_freq_Bands);
+            AssertFatal(tdd_num_available_freq_Bands > 0, "should have at least one TDD band available\n");
             int j;
             for (j=0;
                  j<tdd_num_available_freq_Bands;
@@ -362,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
@@ -384,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]);
@@ -399,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");
@@ -425,126 +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_160P9_t *ext = (F1AP_ProtocolExtensionContainer_160P9_t *)cell->iE_Extensions;
-	 AssertFatal(ext!=NULL,"Extension for SI is null\n");
-	 F1AP_SETUP_RESP (msg_p).num_SI[i] = ext->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 < ext->list.count;si++) {
-	   size_t size = ext->list.array[si]->extensionValue.choice.GNB_CUSystemInformation.sImessage.size;
-	   F1AP_SETUP_RESP (msg_p).SI_container_length[i][si] = size;
-     LOG_D(F1AP, "F1AP: F1Setup-Resp SI_container_length[%d][%d] %ld bytes\n", i, si, size);
-	   F1AP_SETUP_RESP (msg_p).SI_container[i][si] = malloc(F1AP_SETUP_RESP (msg_p).SI_container_length[i][si]);
-
-	   memcpy((void*)F1AP_SETUP_RESP (msg_p).SI_container[i][si],
-		  (void*)ext->list.array[si]->extensionValue.choice.GNB_CUSystemInformation.sImessage.buf,
-		  F1AP_SETUP_RESP (msg_p).SI_container_length[i][si]);
-	 }
-       }
-       break;
-     }
-   }
-   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",
+  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_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...
+        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, ENB_MODULE_ID_TO_INSTANCE(assoc_id), 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
@@ -553,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;
 }
 
@@ -635,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){
@@ -647,17 +754,10 @@ int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
                              2);
         }
 
-        /* - broadcast PLMNs */
-        int maxnoofBPLMNS = 1;
-        for (i=0;
-            i<maxnoofBPLMNS;
-            i++) {
-            /* > PLMN BroadcastPLMNs Item */
-            F1AP_BroadcastPLMNs_Item_t *broadcastPLMNs_Item = (F1AP_BroadcastPLMNs_Item_t *)calloc(1, sizeof(F1AP_BroadcastPLMNs_Item_t));
-            //memset((void *)&broadcastPLMNs_Item, 0, sizeof(F1AP_BroadcastPLMNs_Item_t));
-            MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i], &broadcastPLMNs_Item->pLMN_Identity);
-            ASN_SEQUENCE_ADD(&served_cell_information.servedPLMNs.list, broadcastPLMNs_Item);
-        }
+        F1AP_ServedPLMNs_Item_t *servedPLMN_item = calloc(1,sizeof(*servedPLMN_item));
+        memset(servedPLMN_item,0,sizeof(*servedPLMN_item));
+        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;
@@ -803,7 +903,7 @@ 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,
+        OCTET_STRING_fromBuf(served_cell_information.fiveGS_TAC,
                              (const char *) &f1ap_setup_req->tac[i],
                              3);
 
@@ -815,17 +915,10 @@ int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
                              2);
         }
 
-        /* - broadcast PLMNs */
-        int maxnoofBPLMNS = 1;
-        for (i=0;
-            i<maxnoofBPLMNS;
-            i++) {
-            /* > PLMN BroadcastPLMNs Item */
-            F1AP_BroadcastPLMNs_Item_t *broadcastPLMNs_Item = (F1AP_BroadcastPLMNs_Item_t *)calloc(1, sizeof(F1AP_BroadcastPLMNs_Item_t));
-            //memset((void *)&broadcastPLMNs_Item, 0, sizeof(F1AP_BroadcastPLMNs_Item_t));
-            MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i], &broadcastPLMNs_Item->pLMN_Identity);
-            ASN_SEQUENCE_ADD(&served_cell_information.servedPLMNs.list, broadcastPLMNs_Item);
-        }
+        F1AP_ServedPLMNs_Item_t *servedPLMN_item = calloc(1,sizeof(*servedPLMN_item));
+        memset(servedPLMN_item,0,sizeof(*servedPLMN_item));
+        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;
@@ -963,45 +1056,9 @@ int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
   ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
 
-  /* mandatory */
-  /* c5. Active_Cells_List */
-  ie = (F1AP_GNBDUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBDUConfigurationUpdateIEs_t));
-  ie->id                        = F1AP_ProtocolIE_ID_id_Active_Cells_List;
-  ie->criticality               = F1AP_Criticality_reject;
-  ie->value.present             = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Active_Cells_List;
-
-  for (i=0;
-       i<1;
-       i++) {
-        //
-        F1AP_Active_Cells_ItemIEs_t *active_cells_item_ies;
-        active_cells_item_ies = (F1AP_Active_Cells_ItemIEs_t *)calloc(1, sizeof(F1AP_Active_Cells_ItemIEs_t));
-        active_cells_item_ies->id            = F1AP_ProtocolIE_ID_id_Active_Cells_Item;
-        active_cells_item_ies->criticality   = F1AP_Criticality_reject;
-        active_cells_item_ies->value.present = F1AP_Active_Cells_ItemIEs__value_PR_Active_Cells_Item;
-        
-        F1AP_Active_Cells_Item_t active_cells_item;
-        memset((void *)&active_cells_item, 0, sizeof(F1AP_Active_Cells_Item_t));
-
-        /* 3.1 oldNRCGI */
-        F1AP_NRCGI_t nRCGI;
-        memset(&nRCGI, 0, sizeof(F1AP_NRCGI_t));
-        MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i],
-                                         &nRCGI.pLMN_Identity);
-        NR_CELL_ID_TO_BIT_STRING(f1ap_setup_req->nr_cellid[i], &nRCGI.nRCellIdentity);
-        active_cells_item.nRCGI = nRCGI;
-        
-        /* ADD */
-        active_cells_item_ies->value.choice.Active_Cells_Item = active_cells_item;
-
-        ASN_SEQUENCE_ADD(&ie->value.choice.Active_Cells_List.list, 
-                         active_cells_item_ies);
-  }
-  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
-
 
   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;
   }
 
@@ -1029,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 ee096337ddb508ca0ed6ec4f24a444976f4a35ac..0c8f566fd669fc2e30a189b352cf5e7bc7c8230c 100644
--- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c
+++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
@@ -42,32 +42,50 @@
 #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"
-
-// undefine C_RNTI from
-// openair1/PHY/LTE_TRANSPORT/transport_common.h which
-// replaces in ie->value.choice.C_RNTI, causing
-// a compile error
-
-#undef C_RNTI 
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
 
 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;
@@ -161,10 +179,10 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t       instance,
                              F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation, true);
 
     switch(ie->value.choice.RAT_FrequencyPriorityInformation.present) {
-      case F1AP_RAT_FrequencyPriorityInformation_PR_subscriberProfileIDforRFP:
+      case F1AP_RAT_FrequencyPriorityInformation_PR_eNDC:
         //subscriberProfileIDforRFP = ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP;
         break;
-      case F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority:
+      case F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN:
         //rAT_FrequencySelectionPriority = ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority;
         break;
       default:
@@ -454,36 +472,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
@@ -721,7 +739,7 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
 
         } else {
           LOG_I(F1AP, "Processing RRCConnectionSetupComplete UE %x\n", rnti);
-          ue_context_p->ue_context.Status = RRC_CONNECTED;
+          ue_context_p->ue_context.StatusRrc = RRC_CONNECTED;
         }
         break;
 
@@ -765,7 +783,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 +798,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;
@@ -836,7 +857,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t     module_idP,
   ie->id                             = F1AP_ProtocolIE_ID_id_C_RNTI;
   ie->criticality                    = F1AP_Criticality_reject;
   ie->value.present                  = F1AP_InitialULRRCMessageTransferIEs__value_PR_C_RNTI;
-  C_RNTI_TO_BIT_STRING(rntiP, &ie->value.choice.C_RNTI);
+  ie->value.choice.C_RNTI=rntiP;
   ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
   /* mandatory */
@@ -850,29 +871,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 +912,473 @@ 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);
+
+    /* 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);
+
+  gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
+  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");
+
+        apply_macrlc_config(rrc,ue_context_p,&ctxt);
+
+        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;
+
+          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 b66141250b5f117d22b4e58986f7106733eb37a3..50f7cdff805ec3811ab4bd70fc958da1bec101ef 100644
--- a/openair2/F1AP/f1ap_du_task.c
+++ b/openair2/F1AP/f1ap_du_task.c
@@ -86,9 +86,9 @@ void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat
   DevAssert(sctp_new_association_resp != NULL);
 
   if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
-    LOG_W(F1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
+    LOG_E(F1AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
               sctp_new_association_resp->sctp_state,
-              instance,
+              (int)instance,
               sctp_new_association_resp->ulp_cnx_id);
 
       //f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
@@ -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 841c77eef5f906896ffb44af3cb51b33fef5c9ca..131dbce8efad12aa46f060c12ee2f51b4ba62e8a 100644
--- a/openair2/F1AP/f1ap_du_ue_context_management.c
+++ b/openair2/F1AP/f1ap_du_ue_context_management.c
@@ -38,13 +38,8 @@
 
 #include "rrc_extern.h"
 #include "rrc_eNB_UE_context.h"
-
-// undefine C_RNTI from
-// openair1/PHY/LTE_TRANSPORT/transport_common.h which
-// replaces in ie->value.choice.C_RNTI, causing
-// a compile error
-
-#undef C_RNTI
+#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
+#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
 
 extern f1ap_setup_req_t *f1ap_du_data;
 extern f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB];
@@ -91,7 +86,7 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t       instance,
   BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity, f1ap_ue_context_setup_req->nr_cellid);
   /* ServCellIndex */
   F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
-                             F1AP_ProtocolIE_ID_id_ServCellndex, true);
+                             F1AP_ProtocolIE_ID_id_ServCellIndex, true);
   f1ap_ue_context_setup_req->servCellIndex = ie->value.choice.ServCellIndex;
   /* optional */
   /* CellULConfigured */
@@ -108,51 +103,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;
 }
 
@@ -227,7 +253,8 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance) {
     ie->id                             = F1AP_ProtocolIE_ID_id_C_RNTI;
     ie->criticality                    = F1AP_Criticality_ignore;
     ie->value.present                  = F1AP_UEContextSetupResponseIEs__value_PR_C_RNTI;
-    C_RNTI_TO_BIT_STRING(rntiP, &ie->value.choice.C_RNTI);
+    //C_RNTI_TO_BIT_STRING(rntiP, &ie->value.choice.C_RNTI);
+    ie->value.choice.C_RNTI=rntiP;
     ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
   }
 
@@ -510,7 +537,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;
   }
 
@@ -632,11 +659,21 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t       instance,
               rnti, ctxt.rnti);
   int UE_out_of_sync = 0;
 
-  for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
-    if (RC.mac[instance]->UE_info.active[n] == TRUE
-        && rnti == UE_RNTI(instance, n)) {
-      UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync;
-      break;
+  if (RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
+    for (int n = 0; n < MAX_MOBILES_PER_GNB; ++n) {
+      if (RC.nrmac[instance]->UE_info.active[n] == TRUE
+          && rnti == RC.nrmac[instance]->UE_info.rnti[n]) {
+        UE_out_of_sync = 0;
+        break;
+      }
+    }
+  } else {
+    for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
+      if (RC.mac[instance]->UE_info.active[n] == TRUE
+          && rnti == UE_RNTI(instance, n)) {
+        UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync;
+        break;
+      }
     }
   }
 
@@ -686,6 +723,15 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t       instance,
     }
   }
 
+  if (RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
+    // struct rrc_gNB_ue_context_s *ue_context_p;
+
+    f1ap_ue_context_release_cplt_t cplt;
+    cplt.rnti = ctxt.rnti;
+    DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt);
+    return 0;
+  }
+
   struct rrc_eNB_ue_context_s *ue_context_p;
 
   ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id], ctxt.rnti);
@@ -1016,7 +1062,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) {
     srbs_failedToBeSetupMod_item.sRBID = 50L;
     srbs_failedToBeSetupMod_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t));
     srbs_failedToBeSetupMod_item.cause->present = F1AP_Cause_PR_radioNetwork;
-    srbs_failedToBeSetupMod_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnd_du_ue_f1ap_id;
+    srbs_failedToBeSetupMod_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id;
     /* ADD */
     srbs_failedToBeSetupMod_item_ies->value.choice.SRBs_FailedToBeSetupMod_Item = srbs_failedToBeSetupMod_item;
     ASN_SEQUENCE_ADD(&ie->value.choice.SRBs_FailedToBeSetupMod_List.list,
@@ -1047,7 +1093,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) {
     drbs_failedToBeSetupMod_item.dRBID = 30L;
     drbs_failedToBeSetupMod_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t));
     drbs_failedToBeSetupMod_item.cause->present = F1AP_Cause_PR_radioNetwork;
-    drbs_failedToBeSetupMod_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnd_du_ue_f1ap_id;
+    drbs_failedToBeSetupMod_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id;
     /* ADD */
     drbs_failedToBeSetupMod_item_ies->value.choice.DRBs_FailedToBeSetupMod_Item = drbs_failedToBeSetupMod_item;
     ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_FailedToBeSetupMod_List.list,
@@ -1083,7 +1129,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) {
     scell_failedtoSetupMod_item.sCell_ID = nRCGI;
     scell_failedtoSetupMod_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t));
     scell_failedtoSetupMod_item.cause->present = F1AP_Cause_PR_radioNetwork;
-    scell_failedtoSetupMod_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnd_du_ue_f1ap_id;
+    scell_failedtoSetupMod_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id;
     /* ADD */
     scell_failedtoSetupMod_item_ies->value.choice.SCell_FailedtoSetupMod_Item = scell_failedtoSetupMod_item;
     ASN_SEQUENCE_ADD(&ie->value.choice.SCell_FailedtoSetupMod_List.list,
@@ -1114,7 +1160,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) {
     drbs_failedToBeModified_item.dRBID = 30L;
     drbs_failedToBeModified_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t));
     drbs_failedToBeModified_item.cause->present = F1AP_Cause_PR_radioNetwork;
-    drbs_failedToBeModified_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnd_du_ue_f1ap_id;
+    drbs_failedToBeModified_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id;
     /* ADD */
     drbs_failedToBeModified_item_ies->value.choice.DRBs_FailedToBeModified_Item = drbs_failedToBeModified_item;
     ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_FailedToBeModified_List.list,
@@ -1180,7 +1226,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_encoder.c b/openair2/F1AP/f1ap_encoder.c
index e448690139f64ebb62a4a34394ffa29bf35d0683..6e5f0f4e493ed63a12498d617fe7fb59fb1e4e2e 100644
--- a/openair2/F1AP/f1ap_encoder.c
+++ b/openair2/F1AP/f1ap_encoder.c
@@ -84,12 +84,8 @@ int f1ap_encode_pdu(F1AP_F1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *length)
     LOG_E(F1AP, "----------------- ASN1 ENCODER PRINT END----------------- \n");
   }
 
-  encoded = aper_encode_to_new_buffer(&asn_DEF_F1AP_F1AP_PDU, 0, pdu, (void **)buffer);
-
-  if (encoded < 0) {
-    LOG_E(F1AP, "Failed to encode F1AP message\n");
-    return -1;
-  }
+  AssertFatal((encoded = aper_encode_to_new_buffer(&asn_DEF_F1AP_F1AP_PDU, 0, pdu, (void **)buffer))>0,
+	      "Failed to encode F1AP message\n");
 
   *length = encoded;
 
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 67be560778b9848ffe29e254d75f788988b06be6..fc2bca19d5e25718e1c464e17da62565d353b541 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:1,               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:150,             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 308af2eeb916b760f5643f19c0e84b4874d5dc7d..aca88b9ea79904484ec0ec9a5bcb7fee4812045b 100644
--- a/openair2/GNB_APP/MACRLC_nr_paramdef.h
+++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h
@@ -55,7 +55,11 @@
 #define CONFIG_STRING_MACRLC_REMOTE_S_PORTC                "remote_s_portc"
 #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                                                                           */
@@ -79,6 +83,11 @@
 {CONFIG_STRING_MACRLC_REMOTE_S_PORTC,                    NULL,     0,          uptr:NULL,           defintval:50020,           TYPE_UINT,     0},        \
 {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
@@ -97,5 +106,10 @@
 #define MACRLC_REMOTE_S_PORTC_IDX                              14
 #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                           18
+#define MACRLC_PUCCHTARGETSNRX10_IDX                           19
+#define MACRLC_PUCCHFAILURETHRES_IDX                           20
+#define MACRLC_PUSCHFAILURETHRES_IDX                           21
 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #endif
diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h
index 1f1d076e9d2c002ee21cf74e8f18798fcd6b604d..70295b1c313ada7c60650c4106f9b5f8dcd08ece 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"
@@ -211,6 +212,24 @@
 
 #define CARRIERBANDWIDTH_OKVALUES {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}
 
+/* Serving Cell Config Dedicated */
+#define GNB_CONFIG_STRING_SERVINGCELLCONFIGDEDICATED                     "servingCellConfigDedicated"
+#define GNB_CONFIG_STRING_DLPTRSFREQDENSITY0_0                           "dl_ptrsFreqDensity0_0"
+#define GNB_CONFIG_STRING_DLPTRSFREQDENSITY1_0                           "dl_ptrsFreqDensity1_0"
+#define GNB_CONFIG_STRING_DLPTRSTIMEDENSITY0_0                           "dl_ptrsTimeDensity0_0"
+#define GNB_CONFIG_STRING_DLPTRSTIMEDENSITY1_0                           "dl_ptrsTimeDensity1_0"
+#define GNB_CONFIG_STRING_DLPTRSTIMEDENSITY2_0                           "dl_ptrsTimeDensity2_0"
+#define GNB_CONFIG_STRING_DLPTRSEPRERATIO_0                              "dl_ptrsEpreRatio_0"
+#define GNB_CONFIG_STRING_DLPTRSREOFFSET_0                               "dl_ptrsReOffset_0"
+#define GNB_CONFIG_STRING_ULPTRSFREQDENSITY0_0                           "ul_ptrsFreqDensity0_0"
+#define GNB_CONFIG_STRING_ULPTRSFREQDENSITY1_0                           "ul_ptrsFreqDensity1_0"
+#define GNB_CONFIG_STRING_ULPTRSTIMEDENSITY0_0                           "ul_ptrsTimeDensity0_0"
+#define GNB_CONFIG_STRING_ULPTRSTIMEDENSITY1_0                           "ul_ptrsTimeDensity1_0"
+#define GNB_CONFIG_STRING_ULPTRSTIMEDENSITY2_0                           "ul_ptrsTimeDensity2_0"
+#define GNB_CONFIG_STRING_ULPTRSREOFFSET_0                               "ul_ptrsReOffset_0"
+#define GNB_CONFIG_STRING_ULPTRSMAXPORTS_0                               "ul_ptrsMaxPorts_0"
+#define GNB_CONFIG_STRING_ULPTRSPOWER_0                                  "ul_ptrsPower_0"
+
 /*--------------------------------------------------------------------------------------------------------------------*/
 /*                                            pdcch_ConfigSIB1 parameters                                             */
 /*--------------------------------------------------------------------------------------------------------------------*/
@@ -379,6 +398,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},\
@@ -395,6 +415,26 @@
 {GNB_CONFIG_STRING_SSPBCHBLOCKPOWER,NULL,0,i64ptr:&scc->ss_PBCH_BlockPower,defint64val:20,TYPE_INT64,0}, \
 {GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,defintval:-1,TYPE_INT64,0}}
 
+/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                     Serving Cell Config Dedicated configuration parameters                                                                                                     */
+/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+#define SCDPARAMS_DESC(scd) { \
+{GNB_CONFIG_STRING_DLPTRSFREQDENSITY0_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list.array[0],defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_DLPTRSFREQDENSITY1_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list.array[1],defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_DLPTRSTIMEDENSITY0_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.array[0],defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_DLPTRSTIMEDENSITY1_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.array[1],defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_DLPTRSTIMEDENSITY2_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.array[2],defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_DLPTRSEPRERATIO_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->epre_Ratio,defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_DLPTRSREOFFSET_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->resourceElementOffset,defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_ULPTRSFREQDENSITY0_0,NULL,0,i64ptr:scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.array[0],defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_ULPTRSFREQDENSITY1_0,NULL,0,i64ptr:scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.array[1],defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_ULPTRSTIMEDENSITY0_0,NULL,0,i64ptr:scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[0],defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_ULPTRSTIMEDENSITY1_0,NULL,0,i64ptr:scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[1],defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_ULPTRSTIMEDENSITY2_0,NULL,0,i64ptr:scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[2],defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_ULPTRSREOFFSET_0,NULL,0,i64ptr:scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->resourceElementOffset,defint64val:-1,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_ULPTRSMAXPORTS_0,NULL,0,i64ptr:&scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->maxNrofPorts,defint64val:0,TYPE_INT64,0}, \
+{GNB_CONFIG_STRING_ULPTRSPOWER_0,NULL,0,i64ptr:&scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->ptrs_Power,defint64val:0,TYPE_INT64,0}}
 
 
 
diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c
index 77e456463266660ef8bf4202a37eb3aebba700a8..b1dc59f2e27bb816df2dd6c053955a2a9952e115 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,10 @@
 #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"
+#include <openair2/LAYER2/nr_pdcp/nr_pdcp.h>
 extern unsigned char NB_gNB_INST;
 
 extern RAN_CONTEXT_t RC;
@@ -61,7 +68,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 +89,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 +132,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,13 +176,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_L1();
-
-  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);
 
@@ -171,19 +203,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 {
@@ -247,6 +303,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 957485a9923341f75b8373efc4a05fbd3a183d66..7ce5b542c90809ed782e0132e50a2f439077749d 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -35,6 +35,7 @@
 #include "assertions.h"
 #include "gnb_config.h"
 #include "gnb_paramdef.h"
+#include "enb_paramdef.h"
 #include "UTIL/OTG/otg.h"
 #include "UTIL/OTG/otg_externs.h"
 #include "intertask_interface.h"
@@ -42,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"
@@ -53,11 +55,12 @@
 
 //#include "L1_paramdef.h"
 #include "L1_nr_paramdef.h"
-#include "MACRLC_paramdef.h"
+#include "MACRLC_nr_paramdef.h"
 #include "common/config/config_userapi.h"
 //#include "RRC_config_tools.h"
 #include "gnb_paramdef.h"
 #include "NR_MAC_gNB/mac_proto.h"
+#include <openair3/ocp-gtpu/gtp_itf.h>
 
 #include "NR_asn_constant.h"
 #include "executables/thread-common.h"
@@ -77,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);
@@ -123,7 +131,8 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) {
   scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup  = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon));
   scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero    = CALLOC(1,sizeof(long));
   scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero           = CALLOC(1,sizeof(long));
-  //  scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet  = CALLOC(1,sizeof(struct NR_ControlResourceSet));
+
+  scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = NULL;
 
   //  scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList     = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon__commonSearchSpaceList));
   //  scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1                    = CALLOC(1,sizeof(NR_SearchSpaceId_t));
@@ -291,6 +300,167 @@ 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 */
+void prepare_scd(NR_ServingCellConfig_t *scd) {
+  // Allocate downlink structures
+
+  scd->downlinkBWP_ToAddModList = CALLOC(1, sizeof(*scd->downlinkBWP_ToAddModList));
+
+  // Downlink bandwidth part
+  NR_BWP_Downlink_t *bwp = calloc(1, sizeof(*bwp));
+  bwp->bwp_Id = 1;
+
+  // Allocate downlink dedicated bandwidth part and PDSCH structures
+  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->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;
+
+  // Allocate DL DMRS and PTRS configuration
+  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));
+  NR_DMRS_DownlinkConfig_t *NR_DMRS_DownlinkCfg = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup;
+  NR_DMRS_DownlinkCfg->phaseTrackingRS=CALLOC(1, sizeof(*NR_DMRS_DownlinkCfg->phaseTrackingRS));
+  NR_DMRS_DownlinkCfg->phaseTrackingRS->present = NR_SetupRelease_PTRS_DownlinkConfig_PR_setup;
+  NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup = CALLOC(1, sizeof(*NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup));
+  NR_PTRS_DownlinkConfig_t *NR_PTRS_DownlinkCfg = NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup;
+  NR_PTRS_DownlinkCfg->frequencyDensity = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->frequencyDensity));
+  long *dl_rbs = CALLOC(2, sizeof(long));
+  for (int i=0;i<2;i++) {
+    ASN_SEQUENCE_ADD(&NR_PTRS_DownlinkCfg->frequencyDensity->list, &dl_rbs[i]);
+  }
+  NR_PTRS_DownlinkCfg->timeDensity = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->timeDensity));
+  long *dl_mcs = CALLOC(3, sizeof(long));
+  for (int i=0;i<3;i++) {
+    ASN_SEQUENCE_ADD(&NR_PTRS_DownlinkCfg->timeDensity->list, &dl_mcs[i]);
+  }
+  NR_PTRS_DownlinkCfg->epre_Ratio = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->epre_Ratio));
+  NR_PTRS_DownlinkCfg->resourceElementOffset = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->resourceElementOffset));
+  *NR_PTRS_DownlinkCfg->resourceElementOffset = 0;
+  ASN_SEQUENCE_ADD(&scd->downlinkBWP_ToAddModList->list,bwp);
+
+  // Allocate uplink structures
+
+  scd->uplinkConfig = CALLOC(1, sizeof(*scd->uplinkConfig));
+  scd->uplinkConfig->uplinkBWP_ToAddModList = CALLOC(1, sizeof(*scd->uplinkConfig->uplinkBWP_ToAddModList));
+
+  NR_PUSCH_Config_t *pusch_Config = CALLOC(1, sizeof(*pusch_Config));
+
+  // Allocate UL DMRS and PTRS structures
+  pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB = CALLOC(1, sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB));
+  pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->present = NR_SetupRelease_DMRS_UplinkConfig_PR_setup;
+  pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup = CALLOC(1, sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup));
+  NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
+  NR_DMRS_UplinkConfig->phaseTrackingRS = CALLOC(1, sizeof(*NR_DMRS_UplinkConfig->phaseTrackingRS));
+  NR_DMRS_UplinkConfig->phaseTrackingRS->present = NR_SetupRelease_PTRS_UplinkConfig_PR_setup;
+  NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup = CALLOC(1, sizeof(*NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup));
+  NR_PTRS_UplinkConfig_t *NR_PTRS_UplinkConfig = NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup;
+  NR_PTRS_UplinkConfig->transformPrecoderDisabled = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled));
+  NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity));
+  long *n_rbs = CALLOC(2, sizeof(long));
+  for (int i=0;i<2;i++) {
+    ASN_SEQUENCE_ADD(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity->list, &n_rbs[i]);
+  }
+  NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity));
+  long *ptrs_mcs = CALLOC(3, sizeof(long));
+  for (int i = 0; i < 3; i++) {
+    ASN_SEQUENCE_ADD(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity->list, &ptrs_mcs[i]);
+  }
+  NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset));
+  *NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset = 0;
+
+  // UL bandwidth part
+  NR_BWP_Uplink_t *ubwp = CALLOC(1, sizeof(*ubwp));
+  ubwp->bwp_Id = 1;
+  ubwp->bwp_Dedicated = CALLOC(1, sizeof(*ubwp->bwp_Dedicated));
+
+  ubwp->bwp_Dedicated->pusch_Config = CALLOC(1, sizeof(*ubwp->bwp_Dedicated->pusch_Config));
+  ubwp->bwp_Dedicated->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup;
+  ubwp->bwp_Dedicated->pusch_Config->choice.setup = pusch_Config;
+
+  ASN_SEQUENCE_ADD(&scd->uplinkConfig->uplinkBWP_ToAddModList->list,ubwp);
+}
+
+/* This function checks dedicated serving cell configuration and performs fixes as needed */ 
+void fix_scd(NR_ServingCellConfig_t *scd) {
+  // Check for DL PTRS parameters validity
+  if (scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS) {
+    // If any of the frequencyDensity values are not set or are out of bounds, PTRS is assumed to be not present
+    for (int i = scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list.count-1; i >= 0; i--) {
+      if ((*scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list.array[i] < 1)
+          || (*scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list.array[i] > 276)) {
+        LOG_I(RRC, "DL PTRS frequencyDensity %d not set. Assuming PTRS not present! \n", i);
+        free(scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS);
+        scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS = NULL;
+        break;
+      }
+    }
+  }
+  if (scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS) {
+    // If any of the timeDensity values are not set or are out of bounds, PTRS is assumed to be not present
+    for (int i = scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.count-1; i >= 0; i--) {
+      if ((*scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.array[i] < 0)
+          || (*scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.array[i] > 29)) {
+        LOG_I(RRC, "DL PTRS timeDensity %d not set. Assuming PTRS not present! \n", i);
+        free(scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS);
+        scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS = NULL;
+        break;
+      }
+    }
+  }
+  if (scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS) {
+    if (*scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->resourceElementOffset > 2) {
+      LOG_I(RRC, "Freeing DL PTRS resourceElementOffset \n");
+      free(scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->resourceElementOffset);
+      scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->resourceElementOffset = NULL;
+    }
+    if (*scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->epre_Ratio > 1) {
+      LOG_I(RRC, "Freeing DL PTRS epre_Ratio \n");
+      free(scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->epre_Ratio);
+      scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->epre_Ratio = NULL;
+    }
+  }
+
+  if (scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) {
+    // If any of the frequencyDensity values are not set or are out of bounds, PTRS is assumed to be not present
+    for (int i = scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.count-1; i >= 0; i--) {
+      if ((*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.array[i] < 1) 
+          || (*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.array[i] > 276)) {
+        LOG_I(RRC, "UL PTRS frequencyDensity %d not set. Assuming PTRS not present! \n", i);
+        free(scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS);
+        scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS = NULL;
+        break;
+      }
+    }
+  }
+
+  if (scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) {
+    // If any of the timeDensity values are not set or are out of bounds, PTRS is assumed to be not present
+    for (int i = scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.count-1; i >= 0; i--) {
+      if ((*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[i] < 0)
+          || (*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[i] > 29)) {
+        LOG_I(RRC, "UL PTRS timeDensity %d not set. Assuming PTRS not present! \n", i);
+        free(scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS);
+        scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS = NULL;
+        break;
+      }
+    }
+  }
+  if (scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) {
+    // Check for UL PTRS parameters validity
+    if (*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->resourceElementOffset > 2) {
+      LOG_I(RRC, "Freeing UL PTRS resourceElementOffset \n");
+      free(scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->resourceElementOffset);
+      scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->resourceElementOffset = NULL;
+    }
+  }
 }
 
 void RCconfig_nr_flexran()
@@ -399,11 +569,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) {
@@ -424,15 +596,17 @@ void RCconfig_NR_L1(void) {
         RC.nb_nr_CC = (int *)malloc((1+RC.nb_nr_inst)*sizeof(int));
         RC.nb_nr_CC[0]=1;
 
-        RC.nb_nr_inst =1; // DJP - feptx_prec uses num_gNB but phy_init_RU uses nb_nr_inst
-
         LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_nr_inst=1 this is because phy_init_RU() uses that to index and not RC.num_gNB - why the 2 similar variables?\n", __FUNCTION__);
         LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_nr_CC[0]=%d for init_gNB_afterRU()\n", __FUNCTION__, RC.nb_nr_CC[0]);
         LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_nr_macrlc_inst:%d because used by mac_top_init_gNB()\n", __FUNCTION__, RC.nb_nr_macrlc_inst);
 
         mac_top_init_gNB();
 
-        configure_nr_nfapi_pnf(RC.gNB[j]->eth_params_n.remote_addr, RC.gNB[j]->eth_params_n.remote_portc, RC.gNB[j]->eth_params_n.my_addr, RC.gNB[j]->eth_params_n.my_portd, RC.gNB[j]->eth_params_n     .remote_portd);
+        configure_nr_nfapi_pnf(RC.gNB[j]->eth_params_n.remote_addr,
+                               RC.gNB[j]->eth_params_n.remote_portc,
+                               RC.gNB[j]->eth_params_n.my_addr,
+                               RC.gNB[j]->eth_params_n.my_portd,
+                               RC.gNB[j]->eth_params_n.remote_portd);
       }else { // other midhaul
       } 
     }// for (j = 0; j < RC.nb_nr_L1_inst; j++)
@@ -471,10 +645,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));
@@ -500,17 +689,17 @@ 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);
       }else { // other midhaul
         AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
       } 
+      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");     
   }
 
 }
@@ -615,7 +804,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;
@@ -627,6 +817,13 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
   prepare_scc(scc);
   paramdef_t SCCsParams[] = SCCPARAMS_DESC(scc);
   paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0};
+
+  // Serving Cell Config Dedicated
+  NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
+  memset((void*)scd,0,sizeof(NR_ServingCellConfig_t));
+  prepare_scd(scd);
+  paramdef_t SCDsParams[] = SCDPARAMS_DESC(scd);
+  paramlist_def_t SCDsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGDEDICATED, NULL, 0};
    ////////// Physical parameters
 
 
@@ -700,7 +897,59 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
 	    (int)scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleReceivedTargetPower);
       fix_scc(scc,ssb_bitmap);
     }
+
+    sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
+
+    config_getlist(&SCDsParamList, NULL, 0, aprefix);
+    if (SCDsParamList.numelt > 0) {    
+      sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_SERVINGCELLCONFIGDEDICATED, 0);
+      config_get( SCDsParams,sizeof(SCDsParams)/sizeof(paramdef_t),aprefix);  
+      LOG_I(RRC,"Read in ServingCellConfigDedicated UL (FreqDensity_0 %d, FreqDensity_1 %d, TimeDensity_0 %d, TimeDensity_1 %d, TimeDensity_2 %d, RE offset %d \n",
+      (int)*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.array[0],
+      (int)*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.array[1],
+      (int)*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[0],
+      (int)*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[1],
+      (int)*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[2],
+      (int)*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->resourceElementOffset);
+    }
+    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) {
@@ -750,7 +999,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
           AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
                       PLMNParamList.numelt);
 
-        RRC_CONFIGURATION_REQ(msg_p).num_plmn = PLMNParamList.numelt;
+        NRRRC_CONFIGURATION_REQ(msg_p).num_plmn = PLMNParamList.numelt;
 
         for (int l = 0; l < PLMNParamList.numelt; ++l) {
 	
@@ -765,15 +1014,17 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
         NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = *GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr;
         printf("pdsch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr);
         NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PDSCH_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;
+        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("Do CSI-RS %d\n",*GNBParamList.paramarray[i][GNB_DO_CSIRS_IDX].iptr);
+        NRRRC_CONFIGURATION_REQ (msg_p).do_CSIRS = *GNBParamList.paramarray[i][GNB_DO_CSIRS_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);
@@ -828,20 +1079,25 @@ int RCconfig_nr_gtpu(void ) {
       MessageDef *message;
 
       if (gnb_mode == 1) { // NSA
-        AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_ENB_S1_REQ))!=NULL,"");
+        message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_ENB_S1_REQ);
+        AssertFatal(message!=NULL,"");
         // IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->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,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
         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
-        AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_GNB_NG_REQ))!=NULL,"");
+        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);
       }
-
-     itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
+     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");
 
@@ -1019,10 +1275,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 "
@@ -1129,7 +1387,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;
@@ -1348,3 +1606,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 0d965171ef081599c8eb0c37a95209aefccc6701..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"
@@ -92,7 +93,7 @@ typedef struct ru_config_s {
   uint8_t   if_compress;
 } ru_config_t;
 */
-extern void RCconfig_RU(void);
+extern void NRRCconfig_RU(void);
 extern void RCconfig_nr_flexran(void);
 extern void RCconfig_NR_L1(void);
 extern void RCconfig_nr_macrlc(void);
@@ -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 403602c109ff6ce4899c02268223bee6b610be44..e2a666c16aa60b3c2f3e9d96ebe2c5c53f8d8ebd 100644
--- a/openair2/GNB_APP/gnb_paramdef.h
+++ b/openair2/GNB_APP/gnb_paramdef.h
@@ -115,8 +115,9 @@ typedef enum {
 #define GNB_CONFIG_STRING_REMOTE_S_PORTD                "remote_s_portd"
 #define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET           "ssb_SubcarrierOffset"
 #define GNB_CONFIG_STRING_PDSCHANTENNAPORTS             "pdsch_AntennaPorts"
-#define GNB_CONFIG_STRING_PUSCHTARGETPOWX10             "pusch_TargetSNRx10"
-#define GNB_CONFIG_STRING_PUCCHTARGETPOWX10             "pucch_TargetSNRx10"
+#define GNB_CONFIG_STRING_PUSCHANTENNAPORTS             "pusch_AntennaPorts"
+#define GNB_CONFIG_STRING_DOCSIRS                       "do_CSIRS"
+#define GNB_CONFIG_STRING_NRCELLID                      "nr_cellid"
 
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            cell configuration parameters                                                                */
@@ -139,8 +140,9 @@ typedef enum {
 {GNB_CONFIG_STRING_REMOTE_S_PORTD,               NULL,   0,            uptr:NULL,   defuintval:50001,            TYPE_UINT,      0},  \
 {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_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_PUSCHANTENNAPORTS,            NULL,   0,            iptr:NULL,   defintval:1,                 TYPE_INT,       0},  \
+{GNB_CONFIG_STRING_DOCSIRS,                      NULL,   0,            iptr:NULL,   defintval:0,                 TYPE_INT,       0},  \
+{GNB_CONFIG_STRING_NRCELLID         ,            NULL,   0,            u64ptr:NULL, defint64val:1,               TYPE_UINT64,    0},  \
 }															     	
 
 #define GNB_GNB_ID_IDX                  0
@@ -159,8 +161,9 @@ typedef enum {
 #define GNB_REMOTE_S_PORTD_IDX          13
 #define GNB_SSB_SUBCARRIEROFFSET_IDX    14
 #define GNB_PDSCH_ANTENNAPORTS_IDX      15
-#define GNB_PUSCH_TARGETPOW_X10_IDX     16
-#define GNB_PUCCH_TARGETPOW_X10_IDX     17
+#define GNB_PUSCH_ANTENNAPORTS_IDX      16
+#define GNB_DO_CSIRS_IDX                17
+#define GNB_NRCELLID_IDX                18
 
 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
 #define GNBPARAMS_CHECK {                                         \
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index 781347abaaea42610de39f573ff1a4385af2d5d3..8d4a53da6c21cad4d1e0d49ad7b2f91addde0a5f 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -51,7 +51,7 @@
 #include "LTE_MBSFN-SubframeConfigList.h"
 #include "LTE_MBSFN-SubframeConfig.h"
 #include "LTE_PMCH-InfoList-r9.h"
-
+#include <openair2/LAYER2/MAC/mac_proto.h>
 
 extern RAN_CONTEXT_t RC;
 extern int l2_init_eNB(void);
@@ -337,7 +337,8 @@ config_sib2(int Mod_idP,
             LTE_ARFCN_ValueEUTRA_t *ul_CArrierFreqP,
             long *ul_BandwidthP,
             LTE_AdditionalSpectrumEmission_t *additionalSpectrumEmissionP,
-            struct LTE_MBSFN_SubframeConfigList  *mbsfn_SubframeConfigListP) {
+            struct LTE_MBSFN_SubframeConfigList  *mbsfn_SubframeConfigListP,
+            int dl_Bandwidth) {
   nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP];
   cfg->subframe_config.pb.value               = radioResourceConfigCommonP->pdsch_ConfigCommon.p_b;
   cfg->subframe_config.pb.tl.tag = NFAPI_SUBFRAME_CONFIG_PB_TAG;
@@ -345,7 +346,7 @@ config_sib2(int Mod_idP,
   cfg->rf_config.reference_signal_power.value = radioResourceConfigCommonP->pdsch_ConfigCommon.referenceSignalPower;
   cfg->rf_config.reference_signal_power.tl.tag = NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG;
   cfg->num_tlv++;
-  cfg->nfapi_config.max_transmit_power.value  = cfg->rf_config.reference_signal_power.value + power_off_dB[cfg->rf_config.dl_channel_bandwidth.value];
+  cfg->nfapi_config.max_transmit_power.value  = cfg->rf_config.reference_signal_power.value + power_off_dB[dl_Bandwidth];
   cfg->nfapi_config.max_transmit_power.tl.tag = NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG;
   cfg->num_tlv++;
   cfg->prach_config.configuration_index.value                 = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_ConfigIndex;
@@ -870,7 +871,8 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
     config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon,
                 radioResourceConfigCommon_BR,
                 NULL, ul_Bandwidth, additionalSpectrumEmission,
-                mbsfn_SubframeConfigList);
+                mbsfn_SubframeConfigList,
+                mib->message.dl_Bandwidth);
   } // mib != NULL
 
   if (mobilityControlInfo !=NULL) {
diff --git a/openair2/LAYER2/MAC/config_ue.c b/openair2/LAYER2/MAC/config_ue.c
index 1c5e70621803a3ad8dec8b80aead42b771b11ac3..f5c12e710d35103c2056206dfe28247e9d329c68 100644
--- a/openair2/LAYER2/MAC/config_ue.c
+++ b/openair2/LAYER2/MAC/config_ue.c
@@ -57,6 +57,7 @@
 #include "LTE_PMCH-InfoList-r9.h"
 
 
+#include <openair2/LAYER2/MAC/mac_proto.h>
 extern void mac_init_cell_params(int Mod_idP,int CC_idP);
 extern void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
 
@@ -85,10 +86,6 @@ void ue_mac_reset(module_id_t module_idP, uint8_t eNB_index) {
   ue_init_mac(module_idP);  //This will hopefully do the rest of the MAC reset procedure
 }
 
-int32_t **rxdata;
-int32_t **txdata;
-
-
 int
 rrc_mac_config_req_ue(module_id_t Mod_idP,
                       int CC_idP,
diff --git a/openair2/LAYER2/MAC/defs_NB_IoT.h b/openair2/LAYER2/MAC/defs_NB_IoT.h
index 517f01d1b932be33b345681118ed69a6ee5f2150..78524e104d2895eca07b67d3eff9dd453bac5d8f 100644
--- a/openair2/LAYER2/MAC/defs_NB_IoT.h
+++ b/openair2/LAYER2/MAC/defs_NB_IoT.h
@@ -537,9 +537,6 @@ typedef  struct {
 
 // global variables
 
-nprach_parameters_NB_IoT_t nprach_list[3];
 
-//DLSF Table
-DLSF_INFO_t DLSF_information;
 
 #endif /*__LAYER2_MAC_DEFS_NB_IoT_H__ */
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index ccbff6a5eb59a4ea151a8bad4ba60a2e889d2d16..9d07018e2feddeea160bd9af1b94e6f20122e7e4 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -556,10 +556,7 @@ copy_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
   }
 }
 
-extern int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
-extern int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
-extern void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
-extern void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch);
+#include <openair1/PHY/LTE_TRANSPORT/transport_proto.h>
 
 void
 eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
@@ -586,6 +583,23 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
     memset(cc[CC_id].vrb_map_UL, 0, 100);
     cc[CC_id].mcch_active = 0;
     clear_nfapi_information(RC.mac[module_idP], CC_id, frameP, subframeP);
+
+    /* hack: skip BCH RBs in subframe 0 for DL scheduling,
+     *       because with high MCS we may exceed code rate 0.93
+     *       when using those RBs (36.213 7.1.7 says the UE may
+     *       skip decoding if the code rate is higher than 0.93)
+     * TODO: remove this hack, deal with physical bits properly
+     *       i.e. reduce MCS in the scheduler if code rate > 0.93
+     */
+    if (subframeP == 0) {
+      int i;
+      int bw = cc[CC_id].mib->message.dl_Bandwidth;
+      /* start and count defined for RBs: 6, 15, 25, 50, 75, 100 */
+      int start[6] = { 0, 4, 9, 22, 34, 47 };
+      int count[6] = { 6, 7, 7,  6,  7,  6 };
+      for (i = 0; i < count[bw]; i++)
+        cc[CC_id].vrb_map[start[bw] + i] = 1;
+    }
   }
 
   /* Refresh UE list based on UEs dropped by PHY in previous subframe */
@@ -595,6 +609,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
       CC_id = UE_PCCID(module_idP, UE_id);
       UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]);
 
+/* to be merged with MAC_stats.log generation. probably redundant
       if (((frameP & 127) == 0) && (subframeP == 0)) {
         double total_bler;
         if(UE_scheduling_control->pusch_rx_num[CC_id] == 0 && UE_scheduling_control->pusch_rx_error_num[CC_id] == 0) {
@@ -632,7 +647,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
               UE_scheduling_control->aperiodic_ri_received[CC_id]
         );
       }
-
+*/
       RC.eNB[module_idP][CC_id]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = -63;
 
       if (UE_id == UE_info->list.head) {
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
index 3dea211dbcbeb75b56f46114e351684b3a5ddd48..8a400af1f30a4b7576aad53ad6062c4ae013c9aa 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
@@ -476,8 +476,8 @@ void generate_Msg2(module_id_t module_idP,
       first_rb = 0;
       vrb_map[first_rb] = 1;
       vrb_map[first_rb + 1] = 1;
-      vrb_map[first_rb + 2] = 1;
-      vrb_map[first_rb + 3] = 1;
+      //vrb_map[first_rb + 2] = 1;
+      //vrb_map[first_rb + 3] = 1;
       memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t));
       dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
       dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
@@ -488,12 +488,12 @@ void generate_Msg2(module_id_t module_idP,
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2;  // RA-RNTI : see Table 4-10 from SCF082 - nFAPI specifications
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000;  // equal to RS power
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0;
-      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1;  // no TPC
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 0;  // no TPC
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1;
-      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 1;
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0;
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
-      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4);
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 2);
 
       // This checks if the above DCI allocation is feasible in current subframe
       if (!CCE_allocation_infeasible(module_idP, CC_idP, 0, subframeP,
@@ -512,7 +512,7 @@ void generate_Msg2(module_id_t module_idP,
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = ra->RA_rnti;
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 2; // format 1A/1B/1D
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
-        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(N_RB_DL, first_rb, 4);
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(N_RB_DL, first_rb, 2);
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation                             = 2; //QPSK
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version                     = 0;
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks                       = 1; // first block
@@ -901,7 +901,7 @@ generate_Msg4(module_id_t module_idP,
   }                             // rach_resource_type > 0
   else {
     // This is normal LTE case
-    LOG_I(MAC, "generate_Msg4 ra->Msg4_frame SFN/SF: %d.%d,  frameP SFN/SF: %d.%d FOR eNB_Mod: %d \n", ra->Msg4_frame, ra->Msg4_subframe, frameP, subframeP, module_idP);
+    LOG_D(MAC, "generate_Msg4 ra->Msg4_frame SFN/SF: %d.%d,  frameP SFN/SF: %d.%d FOR eNB_Mod: %d \n", ra->Msg4_frame, ra->Msg4_subframe, frameP, subframeP, module_idP);
 
     if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) {
       // Get RRCConnectionSetup for Piggyback
@@ -918,7 +918,7 @@ generate_Msg4(module_id_t module_idP,
               module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length);
         //          AssertFatal(rrc_sdu_length > 0,
         //          "[MAC][eNB Scheduler] CCCH not allocated, rrc_sdu_length: %d\n", rrc_sdu_length);
-        LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
+        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
               module_idP, CC_idP, frameP, subframeP, ra->rnti);
         /// Choose first 4 RBs for Msg4, should really check that these are free!
         first_rb = 0;
@@ -1086,7 +1086,7 @@ generate_Msg4(module_id_t module_idP,
           }
         }     // CCE Allocation feasible
       } else {
-        LOG_I(MAC,
+        LOG_D(MAC,
               "eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Delaying Msg4 for RRC Piggyback (RNTI %x)\n",
               module_idP, CC_idP, frameP, subframeP, ra->rnti);
         ra->Msg4_subframe ++;
@@ -1289,8 +1289,8 @@ initiate_ra_proc(module_id_t module_idP,
   }
 
   LOG_D(MAC,
-        "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d  Initiating RA procedure for preamble index %d\n",
-        module_idP, CC_id, frameP, subframeP, preamble_index);
+        "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d  Initiating RA procedure for preamble index %d, timing offset %d\n",
+        module_idP, CC_id, frameP, subframeP, preamble_index, timing_offset);
   LOG_D(MAC,
         "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d  PRACH resource type %d\n",
         module_idP, CC_id, frameP, subframeP, rach_resource_type);
@@ -1332,6 +1332,9 @@ initiate_ra_proc(module_id_t module_idP,
             abort();
 
           case 1 :
+	  case 3 :
+	  case 4 :
+          case 5 :
             offset = 6;
             break;
         }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index b516b04e03d6c990516e98d7f7dd09b03712b78d..596d978a98900184c5ea0840ba701858ae11a84e 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -651,7 +651,7 @@ schedule_ue_spec(module_id_t module_idP,
     eNB_UE_stats->rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
     eNB_UE_stats->harq_pid = harq_pid;
     eNB_UE_stats->harq_round = round_DL;
-
+    eNB_UE_stats->dlsch_rounds[round_DL&7]++;
     if (eNB_UE_stats->rrc_status < RRC_RECONFIGURED) {
       ue_sched_ctrl->uplane_inactivity_timer = 0;
     }
@@ -792,7 +792,6 @@ schedule_ue_spec(module_id_t module_idP,
           // No TX request for retransmission (check if null request for FAPI)
       }
 
-      //eNB_UE_stats->dlsch_trials[round]++;
       eNB_UE_stats->num_retransmission += 1;
       eNB_UE_stats->rbs_used_retx = nb_rb;
       eNB_UE_stats->total_rbs_used_retx += nb_rb;
@@ -1065,20 +1064,23 @@ schedule_ue_spec(module_id_t module_idP,
             ue_template->pucch_tpc_tx_frame = frameP;
             ue_template->pucch_tpc_tx_subframe = subframeP;
 
-            if (snr > target_snr + 4) {
+            if (snr > target_snr + PUCCH_PCHYST) {
               tpc = 0;  //-1
-            } else if (snr < target_snr - 4) {
+	      ue_sched_ctrl->pucch_tpc_accumulated[CC_id]--;
+            } else if (snr < target_snr - PUCCH_PCHYST) {
               tpc = 2;  //+1
+              ue_sched_ctrl->pucch_tpc_accumulated[CC_id]--;
             } else {
               tpc = 1;  //0
             }
 
-            LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, snr/target snr %d/%d (normal case)\n",
+            LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d (accumulated %d), snr/target snr %d/%d (normal case)\n",
                   module_idP,
                   frameP,
                   subframeP,
                   harq_pid,
                   tpc,
+		  ue_sched_ctrl->pucch_tpc_accumulated[CC_id],
                   snr,
                   target_snr);
           } // Po_PUCCH has been updated
@@ -1700,9 +1702,9 @@ schedule_ue_spec_br(module_id_t module_idP,
               UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP;
               UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP;
 
-              if (snr > target_snr + 4) {
+              if (snr > target_snr + PUCCH_PCHYST) {
                 tpc = 0; //-1
-              } else if (snr < target_snr - 4) {
+              } else if (snr < target_snr - PUCCH_PCHYST) {
                 tpc = 2; //+1
               } else {
                 tpc = 1; //0
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
index 23137b78875023fde361a1e6fb68141c404d7bab..e9f0b807c4f7d44f9a0360fd4b22e6a5b924d5b0 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
@@ -47,7 +47,7 @@
 #include "OCG_extern.h"
 #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
 #include "rlc.h"
-
+#include "common/utils/lte/prach_utils.h"
 #include "T.h"
 
 
@@ -195,7 +195,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
 
   // Initialization
   for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-    dlsch_ue_max_num[CC_id] = (uint16_t)RC.rrc[module_idP]->configuration.radioresourceconfig[CC_id].ue_multiple_max;
+    dlsch_ue_max_num[CC_id] = eNB->ue_multiple_max;
     // save origin DL PDU number
     DL_req          = &eNB->DL_req[CC_id].dl_config_request_body;
     saved_dlsch_dci[CC_id] = DL_req->number_pdu;
@@ -1044,48 +1044,6 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t   Mod_id,
     }
   }
 
-#ifdef TM5
-
-  // This has to be revisited!!!!
-  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-    i1 = 0;
-    i2 = 0;
-    i3 = 0;
-
-    for (j = 0; j < N_RBG[CC_id]; j++) {
-      if (MIMO_mode_indicator[CC_id][j] == 2) {
-        i1 = i1 + 1;
-      } else if (MIMO_mode_indicator[CC_id][j] == 1) {
-        i2 = i2 + 1;
-      } else if (MIMO_mode_indicator[CC_id][j] == 0) {
-        i3 = i3 + 1;
-      }
-    }
-
-    if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) {
-      PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions =
-        PHY_vars_eNB_g[Mod_id][CC_id]->
-        check_for_SUMIMO_transmissions + 1;
-    }
-
-    if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) {
-      PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions =
-        PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions +
-        1;
-    }
-
-    if((i1 < N_RBG[CC_id]) && (i3 > 0)) {
-      PHY_vars_eNB_g[Mod_id][CC_id]->
-      check_for_MUMIMO_transmissions + 1;
-    }
-
-    PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions =
-      PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions +
-      1;
-  }
-
-#endif
-
   for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
     for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) {
       if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2) {
@@ -1154,7 +1112,6 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
   // int continue_flag = 0;
   int32_t snr, target_snr;
   int32_t tpc = 1;
-  static int32_t tpc_accumulated = 0;
   UE_sched_ctrl_t *ue_sched_ctl;
   int mcs;
   int i;
@@ -1540,7 +1497,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                             subframeP,
                             S_DL_SCHEDULED,
                             rnti);
-          //eNB_UE_stats->dlsch_trials[round]++;
+          UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_rounds[round]++;
           UE_info->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1;
           UE_info->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = nb_rb;
           UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx += nb_rb;
@@ -1982,6 +1939,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
           // store stats
           eNB->eNB_stats[CC_id].dlsch_bytes_tx+=sdu_length_total;
           eNB->eNB_stats[CC_id].dlsch_pdus_tx+=1;
+          UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_rounds[0]++;
           UE_info->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb;
           UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb;
           UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1;
@@ -2015,19 +1973,19 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
               UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP;
               UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP;
 
-              if (snr > target_snr + 4) {
+              if (snr > target_snr + PUCCH_PCHYST) {
                 tpc = 0; //-1
-                tpc_accumulated--;
-              } else if (snr < target_snr - 4) {
+                ue_sched_ctl->pucch_tpc_accumulated[CC_id]--;
+              } else if (snr < target_snr - PUCCH_PCHYST) {
                 tpc = 2; //+1
-                tpc_accumulated++;
+                ue_sched_ctl->pucch_tpc_accumulated[CC_id]++;
               } else {
                 tpc = 1; //0
               }
 
               LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n",
                     module_idP,frameP, subframeP,harq_pid,tpc,
-                    tpc_accumulated,snr,target_snr);
+                    ue_sched_ctl->pucch_tpc_accumulated[CC_id],snr,target_snr);
             } // Po_PUCCH has been updated
             else {
               tpc = 1; //0
@@ -2245,7 +2203,6 @@ void ulsch_scheduler_pre_ue_select_fairRR(
   uint8_t first_ue_id[MAX_NUM_CCs][20];
   uint8_t ul_inactivity_num[MAX_NUM_CCs];
   uint8_t ul_inactivity_id[MAX_NUM_CCs][20]={{0}};
-  //  LTE_DL_FRAME_PARMS *frame_parms;
   uint8_t ulsch_ue_max_num[MAX_NUM_CCs];
   uint16_t saved_ulsch_dci[MAX_NUM_CCs];
   rnti_t rnti;
@@ -2263,7 +2220,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
     //save ulsch dci number
     saved_ulsch_dci[CC_id] = eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body.number_of_dci;
     // maximum multiplicity number
-    ulsch_ue_max_num[CC_id] =RC.rrc[module_idP]->configuration.radioresourceconfig[CC_id].ue_multiple_max;
+    ulsch_ue_max_num[CC_id] =eNB->ue_multiple_max;
     cc_id_flag[CC_id] = 0;
     ue_first_num[CC_id] = 0;
     ul_inactivity_num[CC_id] = 0;
@@ -2290,6 +2247,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
     // UL DCI
     HI_DCI0_req   = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body;
 
+
     if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) {
       cc_id_flag[CC_id] = 1;
       HI_DCI0_req->number_of_dci = saved_ulsch_dci[CC_id];
@@ -2322,6 +2280,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
     //round
     round = UE_info->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid];
 
+
     if ( round > 0 ) {
       hi_dci0_pdu   = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
       format_flag = 2;
@@ -2352,6 +2311,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
       UE_info->UE_template[CC_id][UE_id].scheduled_ul_bytes = 0;
     }
 
+
     if ( UE_id > last_ulsch_ue_id[CC_id] && ((ulsch_ue_select[CC_id].ue_num+ue_first_num[CC_id]) < ulsch_ue_max_num[CC_id]) ) {
       if ( bytes_to_schedule > 0 ) {
         first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id;
@@ -2369,9 +2329,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
 
       UE_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
       rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
-
-      if ( ((UE_sched_ctl->ul_inactivity_timer>64)&&(UE_sched_ctl->ul_scheduled==0))  ||
-           ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(rrc_status < RRC_CONNECTED)) ||
+      if ( ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(rrc_status < RRC_CONNECTED)) ||
            ((UE_sched_ctl->cqi_req_timer>64)&&((rrc_status >= RRC_CONNECTED))) ) {
         first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id;
         first_ue_total[CC_id] [ue_first_num[CC_id]] = 0;
@@ -2482,6 +2440,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
     }
     rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
 
+
     if ( (bytes_to_schedule > 0) || (UE_info->UE_template[CC_id][UE_id].ul_SR > 0) ||
          ((UE_sched_ctl->ul_inactivity_timer>64)&&(UE_sched_ctl->ul_scheduled==0))  ||
          ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(rrc_status < RRC_CONNECTED)) ||
@@ -2595,7 +2554,6 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
   eNB_MAC_INST       *eNB = RC.mac[module_idP];
   UE_info_t          *UE_info= &eNB->UE_info;
   UE_TEMPLATE        *UE_template = NULL;
-  LTE_DL_FRAME_PARMS *frame_parms = NULL;
   uint8_t            ue_num_temp;
   uint8_t            total_rbs=0;
   uint8_t            average_rbs;
@@ -2617,18 +2575,17 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
   // MCS and RB assgin
   for ( CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++ ) {
     cc = &RC.mac[module_idP]->common_channels[CC_id];
-    frame_parms = &(RC.eNB[module_idP][CC_id]->frame_parms);
-
+    int N_RB_UL = to_prb(cc->ul_Bandwidth);
     if (cc->tdd_Config) { //TDD
-      if (frame_parms->N_RB_UL == 25) {
+      if (N_RB_UL == 25) {
         num_pucch_rb = 1;
-      } else if (frame_parms->N_RB_UL == 50) {
+      } else if (N_RB_UL == 50) {
         num_pucch_rb = 2;
       } else {
         num_pucch_rb = 3;
       }
     } else {//FDD
-      if (frame_parms->N_RB_UL == 25) {
+      if (N_RB_UL == 25) {
         num_pucch_rb = 1;
       } else {
         num_pucch_rb = 2;
@@ -2653,13 +2610,13 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
         continue;
       }
 
-      if (first_rb[CC_id] >= frame_parms->N_RB_UL-num_pucch_rb ) {
+      if (first_rb[CC_id] >= N_RB_UL-num_pucch_rb ) {
         LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n",
               module_idP,frameP,subframeP,UE_id,UE_RNTI(CC_id,UE_id),CC_id);
         break;
       }
 
-      total_rbs = frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id];
+      total_rbs = N_RB_UL-num_pucch_rb-first_rb[CC_id];
       average_rbs = (int)round((double)total_rbs/(double)ue_num_temp);
 
       if ( average_rbs < 3 ) {
@@ -2727,19 +2684,20 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
           UE_info->UE_sched_ctrl[UE_id].pusch_rx_num_old[CC_id] = UE_info->UE_sched_ctrl[UE_id].pusch_rx_num[CC_id];
           UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num_old[CC_id] = UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id];
 
-          if(bler < 0.5) {
-            if(UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id] !=0) {
-              UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]--;
+          if (eNB->use_mcs_offset == 1) {
+            if(bler < eNB->bler_lower) {
+              if(UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id] !=0) {
+                UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]--;
+              }
             }
-          }
-          if(bler >= 2) {
-            UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]++;
-            if(UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id] >= 20) {
-              UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]=20;
+            if(bler >= eNB->bler_upper) {
+              UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]++;
+              if(UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id] >= 20) {
+                UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]=20;
+              }
             }
           }
         }
-
         snr = UE_info->UE_sched_ctrl[UE_id].pusch_snr_avg[CC_id];
  
         mcs = 20 - UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id];
@@ -2758,15 +2716,20 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
           if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ul_total_buffer > 0 ) {
             rb_table_index = 2;
             tbs = get_TBS_UL(mcs,rb_table[rb_table_index]);
-            tx_power = (int8_t)(hundred_times_log10_NPRB[rb_table[rb_table_index] - 1] / 100);
+            tx_power= estimate_ue_tx_power(0,tbs*8,rb_table[rb_table_index],0,cc->Ncp,0);
 
-            while ( (tbs < bytes_to_schedule) && (rb_table[rb_table_index]<(frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id])) &&
-                    ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) {
-              rb_table_index++;
+            while ( (((UE_template->phr_info - tx_power) < 0 ) || (tbs > bytes_to_schedule)) && (mcs > 3) ) {
+              mcs--;
               tbs = get_TBS_UL(mcs,rb_table[rb_table_index]);
-              tx_power = (int8_t)(hundred_times_log10_NPRB[rb_table[rb_table_index] - 1] / 100);
+              tx_power= estimate_ue_tx_power(0,tbs*8,rb_table[rb_table_index],0,cc->Ncp,0);
             }
 
+            while ( (tbs < bytes_to_schedule) && (rb_table[rb_table_index]<(N_RB_UL-num_pucch_rb-first_rb[CC_id])) &&
+                    ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < eNB->max_ul_rb_index )) {
+              rb_table_index++;
+              tbs = get_TBS_UL(mcs,rb_table[rb_table_index]);
+              tx_power= estimate_ue_tx_power(0,tbs*8,rb_table[rb_table_index],0,cc->Ncp,0);
+            }
             if ( rb_table[rb_table_index]<3 ) {
               rb_table_index=2;
             }
@@ -2807,11 +2770,12 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
               UE_info->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
             } else {
               // assigne RBS( 3 RBs)
+/*
               first_rb[CC_id] = first_rb[CC_id] + 3;
               UE_info->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul = 3;
               UE_info->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2;
-              UE_info->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
-            }
+              UE_info->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10; 
+*/            }
           }
         } else if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority  == SCH_UL_INACTIVE ) {
           // assigne RBS( 3 RBs)
@@ -2913,12 +2877,10 @@ schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP,
 
   ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs];
   memset(ulsch_ue_select, 0, sizeof(ulsch_ue_select));
-  LTE_DL_FRAME_PARMS *frame_parms ;
 
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     cc = &mac->common_channels[CC_id];
-    frame_parms= &RC.eNB[module_idP][CC_id]->frame_parms;
-
+    int N_RB_UL=to_prb(cc->ul_Bandwidth);
     // output of scheduling, the UE numbers in RBs, where it is in the code???
     // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3
     // Msg3 is using 1 PRB so we need to increase first_rb accordingly
@@ -2928,13 +2890,13 @@ schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP,
         ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_MSG3;
 
         if (cc->tdd_Config == NULL) {
-          if(frame_parms->N_RB_UL == 25) {
+          if(N_RB_UL == 25) {
             ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 1;
           } else {
             ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 2;
           }
         } else {
-          switch(frame_parms->N_RB_UL) {
+          switch(N_RB_UL) {
             case 25:
             default:
               ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 1;
@@ -2958,14 +2920,18 @@ schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP,
     }
 
     //PRACH
-    if (is_prach_subframe(frame_parms,sched_frame,sched_subframe)==1) {
+    if (is_prach_subframe0(cc->tdd_Config!=NULL ? cc->tdd_Config->subframeAssignment : 0,cc->tdd_Config!=NULL ? 1 : 0,
+                           cc->radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex,
+                           sched_frame,sched_subframe)==1) {
       ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_PRACH;
-      ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = get_prach_prb_offset(
-            frame_parms,
-            frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
-            frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset,
-            0,//tdd_mapindex
-            frameP); //Nf --> shouldn't it be sched_frame ???
+      ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 
+           get_prach_prb_offset(cc->tdd_Config!=NULL ? 1 : 0, 
+                                cc->tdd_Config!=NULL ? cc->tdd_Config->subframeAssignment : 0,
+                                to_prb(cc->ul_Bandwidth),
+                                cc->radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex,
+                                cc->radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset,
+                                0,
+                                sched_frame);
       ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].nb_rb = 6;
       ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = -1;
       ulsch_ue_select[CC_id].ue_num++;
@@ -2993,7 +2959,6 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
   uint32_t          cqi_req,cshift,ndi,tpc;
   int32_t           snr;
   int32_t           target_snr=0;
-  static int32_t    tpc_accumulated=0;
   int               CC_id,ulsch_ue_num;
   int               N_RB_UL;
   eNB_MAC_INST      *eNB = RC.mac[module_idP];
@@ -3012,7 +2977,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
   nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;
   nfapi_ul_config_request_body_t *ul_req_tmp;
   nfapi_ul_config_ulsch_harq_information *ulsch_harq_information;
-  LOG_D(MAC,"entering ulsch preprocesor\n");
+  LOG_D(MAC,"entering ulsch preprocesor for %d.%d\n",sched_frame,sched_subframeP);
   ulsch_scheduler_pre_processor_fairRR(module_idP,
                                        frameP,
                                        subframeP,
@@ -3185,12 +3150,12 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
         UE_template->pusch_tpc_tx_frame=frameP;
         UE_template->pusch_tpc_tx_subframe=subframeP;
 
-        if (snr > target_snr + 4) {
+        if (snr > target_snr + PUSCH_PCHYST) {
           tpc = 0; //-1
-          tpc_accumulated--;
-        } else if (snr < target_snr - 4) {
+          UE_sched_ctrl->pusch_tpc_accumulated[CC_id]--;
+        } else if (snr < target_snr - PUSCH_PCHYST) {
           tpc = 2; //+1
-          tpc_accumulated++;
+          UE_sched_ctrl->pusch_tpc_accumulated[CC_id]++;
         } else {
           tpc = 1; //0
         }
@@ -3201,7 +3166,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
       if (tpc!=1) {
         LOG_D(MAC,"[eNB %d] ULSCH schedulerRR: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n",
               module_idP,frameP,subframeP,harq_pid,tpc,
-              tpc_accumulated,snr,target_snr);
+              UE_sched_ctrl->pusch_tpc_accumulated[CC_id],snr,target_snr);
       }
 
       // new transmission
@@ -3214,6 +3179,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
               UE_sched_ctrl->cqi_req_timer);
         ndi = 1-UE_template->oldNDI_UL[harq_pid];
         UE_template->oldNDI_UL[harq_pid]=ndi;
+        UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_rounds[0]++;
         UE_info->eNB_UE_stats[CC_id][UE_id].snr = snr;
         UE_info->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
         UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul;
@@ -3402,6 +3368,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
           T_INT(round));
         UE_info->eNB_UE_stats[CC_id][UE_id].snr = snr;
         UE_info->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
+
         uint8_t mcs_rv = 0;
 
         if(rvidx_tab[round&3]==1) {
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
index f3a77ed7030e86615b738a8dafe795f4f115313f..1272b16ec06d3ce915a1bf9e99e993a25daac342 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
@@ -84,7 +84,7 @@ get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id,
 
 static uint32_t bytes_in_buffer=0;
 static uint32_t msi_pmch_stop=0;
-uint16_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047};
+rb_id_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047};
 static uint32_t msi_sfs=0;
 
 
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index bd3c428828a4b92401514a133df87051d93205e0..d53e0cadd3fa5db23506c815ef4c3bb32ed373c1 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -1985,10 +1985,13 @@ find_UE_id(module_id_t mod_idP,
 {
   int UE_id;
   UE_info_t *UE_info = &RC.mac[mod_idP]->UE_info;
+  if(!UE_info)
+    return -1;
 
   for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
     if (UE_info->active[UE_id] == TRUE) {
-      if (UE_info->UE_template[UE_PCCID(mod_idP, UE_id)][UE_id].rnti == rntiP) {
+      int CC_id = UE_PCCID(mod_idP, UE_id);
+      if (CC_id>=0 && CC_id<NFAPI_CC_MAX && UE_info->UE_template[CC_id][UE_id].rnti == rntiP) {
         return UE_id;
       }
     }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 47c27798bfa445e52e3b9536cf4fc68fedc43fe1..d4f486f76162e683fd5f2c327767eddbc4e769b6 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -57,7 +57,7 @@
 #include "flexran_agent_mac.h"
 #include <dlfcn.h>
 #include <openair2/LAYER2/MAC/mac.h>
-
+#include "common/utils/lte/prach_utils.h"
 
 #include "T.h"
 
@@ -144,16 +144,18 @@ rx_sdu(const module_id_t enb_mod_idP,
   if (UE_id != -1) {
     UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id];
     UE_template_ptr = &UE_info->UE_template[CC_idP][UE_id];
-    LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
+    LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH (%s) sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d, timing_advance %d\n",
           enb_mod_idP,
           harq_pid,
           CC_idP,
           frameP,
           subframeP,
+          sduP==NULL ? "in error" : "OK",
           UE_scheduling_control->round_UL[CC_idP][harq_pid],
           current_rnti,
           UE_id,
-          ul_cqi);
+          ul_cqi,
+	  timing_advance);
     AssertFatal(UE_scheduling_control->round_UL[CC_idP][harq_pid] < 8, "round >= 8\n");
 
     if (sduP != NULL) {
@@ -219,7 +221,7 @@ rx_sdu(const module_id_t enb_mod_idP,
       if (UE_scheduling_control->round_UL[CC_idP][harq_pid] == 3) {
         UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid));
         UE_scheduling_control->round_UL[CC_idP][harq_pid] = 0;
-
+        UE_info->eNB_UE_stats[CC_idP][UE_id].ulsch_errors++;
         if (UE_scheduling_control->ul_consecutive_errors++ == 10) {
           UE_scheduling_control->ul_failure_timer = 1;
         }
@@ -236,6 +238,7 @@ rx_sdu(const module_id_t enb_mod_idP,
         }
       } else {
         UE_scheduling_control->round_UL[CC_idP][harq_pid]++;
+        UE_info->eNB_UE_stats[CC_idP][UE_id].ulsch_rounds[UE_scheduling_control->round_UL[CC_idP][harq_pid]]++;
       }
 
       /* CDRX UL HARQ timers */
@@ -287,17 +290,35 @@ rx_sdu(const module_id_t enb_mod_idP,
     AssertFatal(mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx > 1,
                 "maxHARQ %d should be greater than 1\n",
                 (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
-    LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n",
+    LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu (%s) round %d from PHY (rnti %x, RA_id %d) ul_cqi %d, timing advance %d\n",
           enb_mod_idP,
           harq_pid,
           CC_idP,
+	  sduP!=NULL ? "OK" : "in error",
           ra->msg3_round,
           current_rnti,
           RA_id,
-          ul_cqi);
+          ul_cqi,
+	  timing_advance);
+
     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,
@@ -306,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);
@@ -403,7 +438,8 @@ rx_sdu(const module_id_t enb_mod_idP,
     switch (rx_ces[i]) {  // implement and process PHR + CRNTI + BSR
       case POWER_HEADROOM:
         if (UE_id != -1) {
-          UE_template_ptr->phr_info = (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + (int8_t)(hundred_times_log10_NPRB[UE_template_ptr->nb_rb_ul[harq_pid] - 1] / 100);
+          /*UE_template_ptr->phr_info = (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + (int8_t)(hundred_times_log10_NPRB[UE_template_ptr->nb_rb_ul[harq_pid] - 1] / 100);i*/
+	  UE_template_ptr->phr_info = (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + estimate_ue_tx_power(0,sdu_lenP*8,UE_template_ptr->nb_rb_ul[harq_pid],0,mac->common_channels[CC_idP].Ncp,0);
 
           if (UE_template_ptr->phr_info > 40) {
             UE_template_ptr->phr_info = 40;
@@ -424,7 +460,7 @@ rx_sdu(const module_id_t enb_mod_idP,
       case CRNTI:
         old_rnti = (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1];
         old_UE_id = find_UE_id(enb_mod_idP, old_rnti);
-        LOG_D(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n",
+        LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n",
               enb_mod_idP,
               frameP,
               subframeP,
@@ -438,7 +474,7 @@ rx_sdu(const module_id_t enb_mod_idP,
         /* Receiving CRNTI means that the current rnti has to go away */
         if (old_UE_id != -1) {
           if (mac_eNB_get_rrc_status(enb_mod_idP,old_rnti) ==  RRC_HO_EXECUTION) {
-            LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Handover case\n",
+            LOG_D(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Handover case\n",
                   enb_mod_idP,
                   frameP,
                   subframeP,
@@ -683,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,
@@ -1293,16 +1342,19 @@ schedule_ulsch(module_id_t module_idP,
 
   /* Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX */
   for (int CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++, cc++) {
-    LTE_DL_FRAME_PARMS *frame_parms = &RC.eNB[module_idP][CC_id]->frame_parms;
-    if (is_prach_subframe(frame_parms, sched_frame, sched_subframe)) {
-      int start_rb = get_prach_prb_offset(
-          frame_parms,
-          frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
-          frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset,
-          0, // tdd_mapindex
-          sched_frame); // Nf
+    
+    if (is_prach_subframe0(cc->tdd_Config!=NULL ? cc->tdd_Config->subframeAssignment : 0,cc->tdd_Config!=NULL ? 1 : 0,
+                           cc->radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex, 
+                           sched_frame, sched_subframe)) {
+      int start_rb = get_prach_prb_offset(cc->tdd_Config!=NULL ? 1 : 0,
+                                          cc->tdd_Config!=NULL ? cc->tdd_Config->subframeAssignment : 0,
+                                          to_prb(cc->ul_Bandwidth),
+                                          cc->radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex,
+                                          cc->radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset,
+                                          0, // tdd_mapindex
+                                          sched_frame); // Nf
       for (int i = 0; i < 6; i++)
-        cc[CC_id].vrb_map_UL[start_rb + i] = 1;
+        cc->vrb_map_UL[start_rb + i] = 1;
     }
 
     /* HACK: let's remove the PUCCH from available RBs
@@ -1314,24 +1366,24 @@ schedule_ulsch(module_id_t module_idP,
      */
     switch (to_prb(cc[CC_id].ul_Bandwidth)) {
       case 25:
-        cc[CC_id].vrb_map_UL[0] = 1;
-        cc[CC_id].vrb_map_UL[24] = 1;
+        cc->vrb_map_UL[0] = 1;
+        cc->vrb_map_UL[24] = 1;
         break;
 
       case 50:
-        cc[CC_id].vrb_map_UL[0] = 1;
-        cc[CC_id].vrb_map_UL[1] = 1;
-        cc[CC_id].vrb_map_UL[48] = 1;
-        cc[CC_id].vrb_map_UL[49] = 1;
+        cc->vrb_map_UL[0] = 1;
+        cc->vrb_map_UL[1] = 1;
+        cc->vrb_map_UL[48] = 1;
+        cc->vrb_map_UL[49] = 1;
         break;
 
       case 100:
-        cc[CC_id].vrb_map_UL[0] = 1;
-        cc[CC_id].vrb_map_UL[1] = 1;
-        cc[CC_id].vrb_map_UL[2] = 1;
-        cc[CC_id].vrb_map_UL[97] = 1;
-        cc[CC_id].vrb_map_UL[98] = 1;
-        cc[CC_id].vrb_map_UL[99] = 1;
+        cc->vrb_map_UL[0] = 1;
+        cc->vrb_map_UL[1] = 1;
+        cc->vrb_map_UL[2] = 1;
+        cc->vrb_map_UL[97] = 1;
+        cc->vrb_map_UL[98] = 1;
+        cc->vrb_map_UL[99] = 1;
         break;
 
       default:
@@ -1349,6 +1401,8 @@ schedule_ulsch(module_id_t module_idP,
 /*
 * Schedule the DCI0 for ULSCH
 */
+
+
 void
 schedule_ulsch_rnti(module_id_t   module_idP,
                     int           CC_id,
@@ -1356,7 +1410,6 @@ schedule_ulsch_rnti(module_id_t   module_idP,
                     sub_frame_t   subframeP,
                     unsigned char sched_subframeP) {
   /* TODO: does this need to be static? */
-  static int32_t tpc_accumulated = 0;
   /* values from 0 to 7 can be used for mapping the cyclic shift
    * (36.211 , Table 5.5.2.1.1-1) */
   const uint32_t cshift = 0;
@@ -1481,8 +1534,7 @@ schedule_ulsch_rnti(module_id_t   module_idP,
     /* Power control */
     /*
      * Compute the expected ULSCH RX snr (for the stats)
-     * This is the normalized RX snr and this should be constant (regardless
-     * of mcs) Is not in dBm, unit from nfapi, converting to dBm
+     * 
      */
     const int32_t snr = UE_sched_ctrl_ptr->pusch_snr[CC_id];
     const int32_t target_snr = mac->puSch10xSnr / 10;
@@ -1501,12 +1553,12 @@ schedule_ulsch_rnti(module_id_t   module_idP,
       UE_template_ptr->pusch_tpc_tx_frame = frameP;
       UE_template_ptr->pusch_tpc_tx_subframe = subframeP;
 
-      if (snr > target_snr + 4) {
+      if (snr > target_snr + PUSCH_PCHYST) {
         tpc = 0; // -1
-        tpc_accumulated--;
-      } else if (snr < target_snr - 4) {
+        UE_sched_ctrl_ptr->pusch_tpc_accumulated[CC_id]--;
+      } else if (snr < target_snr - PUSCH_PCHYST) {
         tpc = 2; // +1
-        tpc_accumulated++;
+        UE_sched_ctrl_ptr->pusch_tpc_accumulated[CC_id]++;
       }
     }
     if (tpc != 1) {
@@ -1518,7 +1570,7 @@ schedule_ulsch_rnti(module_id_t   module_idP,
             subframeP,
             harq_pid,
             tpc,
-            tpc_accumulated,
+            UE_sched_ctrl_ptr->pusch_tpc_accumulated[CC_id],
             snr,
             target_snr);
     }
@@ -1572,6 +1624,7 @@ schedule_ulsch_rnti(module_id_t   module_idP,
       const uint8_t ndi = 1 - UE_template_ptr->oldNDI_UL[harq_pid]; // NDI: new data indicator
       const uint8_t mcs = UE_template_ptr->pre_assigned_mcs_ul;
       UE_template_ptr->oldNDI_UL[harq_pid] = ndi;
+      UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_rounds[0]++;
       UE_info->eNB_UE_stats[CC_id][UE_id].snr = snr;
       UE_info->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
       UE_template_ptr->mcs_UL[harq_pid] = mcs;
@@ -1593,8 +1646,6 @@ schedule_ulsch_rnti(module_id_t   module_idP,
 
       UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = mcs;
 
-      while (rb_table[rb_table_index] > 45 && rb_table_index > 0)
-        rb_table_index--;
 
       UE_template_ptr->TBS_UL[harq_pid] = get_TBS_UL(mcs, rb_table[rb_table_index]);
       UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index];
@@ -2080,10 +2131,10 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
 
             if (snr > target_snr + 4) {
               tpc = 0; //-1
-              UE_sched_ctrl->tpc_accumulated[CC_id]--;
+              UE_sched_ctrl->pusch_tpc_accumulated[CC_id]--;
             } else if (snr < target_snr - 4) {
               tpc = 2; //+1
-              UE_sched_ctrl->tpc_accumulated[CC_id]++;
+              UE_sched_ctrl->pusch_tpc_accumulated[CC_id]++;
             } else {
               tpc = 1; //0
             }
@@ -2098,7 +2149,7 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
                   subframeP,
                   harq_pid,
                   tpc,
-                  UE_sched_ctrl->tpc_accumulated[CC_id],
+                  UE_sched_ctrl->pusch_tpc_accumulated[CC_id],
                   snr,
                   target_snr);
           }
diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h
index 1bae590a596ee5f9a72de893f695af6587cc6e0c..cb93c2feb8839668a1c36cbe6ae3fcdb767ecc3a 100644
--- a/openair2/LAYER2/MAC/mac.h
+++ b/openair2/LAYER2/MAC/mac.h
@@ -83,7 +83,7 @@
 
 #define MAX_MAC_INST 16
 #define BCCH_PAYLOAD_SIZE_MAX 128
-#define CCCH_PAYLOAD_SIZE_MAX 128
+#define CCCH_PAYLOAD_SIZE_MAX 512 
 #define PCCH_PAYLOAD_SIZE_MAX 128
 #define RAR_PAYLOAD_SIZE_MAX 128
 
@@ -143,7 +143,10 @@
 #define MAX_SUPPORTED_BW  4
 /*!\brief CQI values range from 1 to 15 (4 bits) */
 #define CQI_VALUE_RANGE 16
-
+/*!\brief Hysteresis of PUSCH power control loop */
+#define PUSCH_PCHYST 1
+/*!\brief Hysteresis of PUCCH power control loop */
+#define PUCCH_PCHYST 1
 /*!\brief value for indicating BSR Timer is not running */
 #define MAC_UE_BSR_TIMER_NOT_RUNNING   (0xFFFF)
 
@@ -490,7 +493,7 @@ typedef struct {
 
 /*! \brief Uplink SCH PDU Structure */
 typedef struct {
-  int8_t payload[SCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */
+  uint8_t payload[SCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */
   uint16_t Pdu_size;
 } __attribute__ ((__packed__)) ULSCH_PDU;
 
@@ -615,6 +618,8 @@ typedef struct {
 
   // here for RX
   //
+
+  uint32_t ulsch_rounds[4];
   uint32_t ulsch_bitrate;
   //
   uint32_t ulsch_bytes_rx;
@@ -684,6 +689,17 @@ typedef struct {
   // Length of SDU Got from LC DL
   uint32_t sdu_length_tx[NB_RB_MAX];
 
+  int lc_bytes_tx[64];
+  int dlsch_rounds[8];
+  int dlsch_errors;
+  int dlsch_total_bytes;
+
+  int lc_bytes_rx[64];
+  int ulsch_rounds[8];
+  int ulsch_errors;
+  int ulsch_total_bytes_scheduled;
+  int ulsch_total_bytes_rx;
+
 
   /// overall
   //
@@ -776,7 +792,6 @@ typedef struct {
   uint32_t num_mac_sdu_rx;
   // Length of SDU Got from LC UL - Size array can be refined
   uint32_t      sdu_length_rx[NB_RB_MAX];
-
 } eNB_UE_STATS;
 /*! \brief eNB template for UE context information  */
 
@@ -982,7 +997,8 @@ typedef struct {
   uint16_t feedback_cnt[NFAPI_CC_MAX];
   uint16_t timing_advance;
   uint16_t timing_advance_r9;
-  uint8_t tpc_accumulated[NFAPI_CC_MAX];
+  int8_t pusch_tpc_accumulated[NFAPI_CC_MAX];
+  int8_t pucch_tpc_accumulated[NFAPI_CC_MAX];
   uint8_t periodic_wideband_cqi[NFAPI_CC_MAX];
   uint8_t periodic_wideband_spatial_diffcqi[NFAPI_CC_MAX];
   uint8_t periodic_wideband_pmi[NFAPI_CC_MAX];
@@ -1176,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 {
@@ -1342,6 +1360,7 @@ typedef struct {
   uint8_t FeMBMS_flag;
 } COMMON_channels_t;
 /*! \brief top level eNB MAC structure */
+
 typedef struct eNB_MAC_INST_s {
   /// Ethernet parameters for northbound midhaul interface
   eth_params_t eth_params_n;
@@ -1435,6 +1454,17 @@ typedef struct eNB_MAC_INST_s {
 
   int32_t puSch10xSnr;
   int32_t puCch10xSnr;
+
+  int max_ul_rb_index;
+
+  int ue_multiple_max;
+
+  int use_mcs_offset;
+
+  double bler_lower;
+
+  double bler_upper;
+  pthread_t mac_stats_thread;
 } eNB_MAC_INST;
 
 /*
diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h
index cee6066a9ebb174119b3fe6b22ce4ed6c9ae738a..522dc2721ff0674ba4cb4d29a431a43f7f40458d 100644
--- a/openair2/LAYER2/MAC/mac_extern.h
+++ b/openair2/LAYER2/MAC/mac_extern.h
@@ -58,13 +58,13 @@ extern unsigned char NB_eNB_INST;
 extern uint16_t NB_UE_INST;
 extern uint16_t NB_THREAD_INST;
 extern unsigned char NB_RN_INST;
-extern unsigned short NODE_ID[1];
 
 extern const int cqi_to_mcs[16];
 
 extern uint32_t RRC_CONNECTION_FLAG;
 
 extern uint8_t rb_table[34];
+extern rb_id_t mbms_rab_id;
 
 
 #if defined(PRE_SCD_THREAD)
@@ -77,4 +77,8 @@ extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
 
 extern mac_rlc_am_muilist_t rlc_am_mui;
 extern SCHEDULER_MODES global_scheduler_mode;
+
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
+extern rb_id_t mbms_rab_id;
 #endif //DEF_H
diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c
index 59554425ccac2709ee25386df2a6a69ebd300176..a4e924c68b7abc1474cb8e276346b3dffe0a3594 100644
--- a/openair2/LAYER2/MAC/main.c
+++ b/openair2/LAYER2/MAC/main.c
@@ -40,8 +40,84 @@
 #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
 #include "common/ran_context.h"
 #include "intertask_interface.h"
+#include <pthread.h>
 
 extern RAN_CONTEXT_t RC;
+extern int oai_exit;
+
+void *mac_stats_thread(void *param) {
+  eNB_MAC_INST     *mac      = (eNB_MAC_INST *)param;
+  FILE *fd;
+  UE_info_t        *UE_info  = &(mac->UE_info);
+
+  while (!oai_exit) {
+    sleep(1);
+    fd=fopen("MAC_stats.log","w+");
+    AssertFatal(fd!=NULL,"Cannot open MAC_stats.log\n");
+
+    for (int UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
+      if (UE_info->active[UE_id]) {
+        int rnti = UE_RNTI(mac->Mod_id, UE_id);
+        int CC_id = UE_PCCID(mac->Mod_id, UE_id);
+        UE_sched_ctrl_t *UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]);
+
+        double total_bler;
+        if(UE_scheduling_control->pusch_rx_num[CC_id] == 0 && UE_scheduling_control->pusch_rx_error_num[CC_id] == 0) {
+          total_bler = 0;
+        }
+        else {
+          total_bler = (double)UE_scheduling_control->pusch_rx_error_num[CC_id] / (double)(UE_scheduling_control->pusch_rx_error_num[CC_id] + UE_scheduling_control->pusch_rx_num[CC_id]) * 100;
+        }
+        fprintf(fd,"MAC UE rnti %x : %s, PHR %d DLCQI %d PUSCH %d PUCCH %d RLC disc %d UL-stat rcv %lu err %lu bler %lf (%lf/%lf) total_bler %lf mcsoff %d pre_allocated nb_rb %d, mcs %d, bsr %u sched %u tbs %lu cnt %u , DL-stat tbs %lu cnt %u rb %u buf %u 1st %u ret %u ri %d\n",
+              rnti,
+              UE_scheduling_control->ul_out_of_sync == 0 ? "in synch" : "out of sync",
+              UE_info->UE_template[CC_id][UE_id].phr_info,
+              UE_scheduling_control->dl_cqi[CC_id],
+              UE_scheduling_control->pusch_snr/*_avg*/[CC_id],
+              UE_scheduling_control->pucch1_snr[CC_id],
+              UE_scheduling_control->rlc_out_of_resources_cnt,
+              UE_scheduling_control->pusch_rx_num[CC_id],
+              UE_scheduling_control->pusch_rx_error_num[CC_id],
+              UE_scheduling_control->pusch_bler[CC_id],
+              mac->bler_lower,mac->bler_upper,total_bler,
+              UE_scheduling_control->mcs_offset[CC_id],
+              UE_info->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul,
+              UE_info->UE_template[CC_id][UE_id].pre_assigned_mcs_ul,
+              UE_info->UE_template[CC_id][UE_id].estimated_ul_buffer,
+              UE_info->UE_template[CC_id][UE_id].scheduled_ul_bytes,
+              UE_info->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes_rx,
+              UE_info->eNB_UE_stats[CC_id][UE_id].total_num_pdus_rx,
+              UE_info->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes,
+              UE_info->eNB_UE_stats[CC_id][UE_id].total_num_pdus,
+              UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used,
+#if defined(PRE_SCD_THREAD)
+              UE_info->UE_template[CC_id][UE_id].dl_buffer_total,
+#else
+              0,
+#endif
+              UE_scheduling_control->first_cnt[CC_id],
+              UE_scheduling_control->ret_cnt[CC_id],
+              UE_scheduling_control->aperiodic_ri_received[CC_id]
+        );
+        fprintf(fd,"              ULSCH rounds %d/%d/%d/%d, DLSCH rounds %d/%d/%d/%d, ULSCH errors %d, DLSCH errors %d\n",
+              UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_rounds[0],
+              UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_rounds[1],
+              UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_rounds[2],
+              UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_rounds[3],
+              UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_rounds[0],
+              UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_rounds[1],
+              UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_rounds[2],
+              UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_rounds[3],
+              UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_errors,
+              UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_errors);
+
+
+      }
+    }
+    fclose(fd);
+  }
+  return(NULL);
+}
 
 void init_UE_info(UE_info_t *UE_info)
 {
@@ -128,6 +204,9 @@ void mac_top_init_eNB(void)
   pdcp_layer_init();
 
   rrc_init_global_param();
+
+  for (i=0;i<RC.nb_macrlc_inst; i++) pthread_create(&mac[i]->mac_stats_thread,NULL,mac_stats_thread,(void*)mac[i]);
+
 }
 
 void mac_init_cell_params(int Mod_idP, int CC_idP)
diff --git a/openair2/LAYER2/MAC/main_ue.c b/openair2/LAYER2/MAC/main_ue.c
index 2868d9493029ee7a88df34536b61533a3f2a4f2b..2140d66a1024e93ebeefc908c042c8371e9e6442 100644
--- a/openair2/LAYER2/MAC/main_ue.c
+++ b/openair2/LAYER2/MAC/main_ue.c
@@ -44,8 +44,7 @@
 
 
 #include "common/ran_context.h"
-extern void openair_rrc_top_init_ue( int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active);
-
+#include <openair2/RRC/LTE/rrc_proto.h>
 void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) { //init as MR
   LOG_D(MAC, "[UE %d] Frame %d: PHY Sync to eNB_index %d successful \n",
         module_idP, frameP, eNB_index);
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index bf8202f62290c783e5899644417c604788f15c91..bb969668d6b32bf3cfdd44e9f0809bfc220bc28a 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -113,10 +113,29 @@ bool try_allocate_harq_retransmission(module_id_t Mod_id,
     LOG_D(MAC, "cannot allocate UE %d: no CCE can be allocated\n", UE_id);
     return false;
   }
+  /* if nb_rb is not multiple of RBGsize, then last RBG must be free
+   * (it will be allocated just below)
+   */
+  if (nb_rb % RBGsize && !rbgalloc_mask[N_RBG-1]) {
+    LOG_E(MAC, "retransmission: last RBG already allocated (this should not happen)\n");
+    return false;
+  }
   ue_ctrl->pre_dci_dl_pdu_idx = idx;
   // retransmissions: directly allocate
   *n_rbg_sched -= nb_rbg;
   ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb;
+  if (nb_rb % RBGsize) {
+    /* special case: if nb_rb is not multiple of RBGsize, then allocate last RBG.
+     * If we instead allocated another RBG then we will retransmit with more
+     * RBs and the UE will not accept it.
+     * (This has been seen in a test with cots UEs, if not true, then change
+     * code as needed.)
+     * At this point rbgalloc_mask[N_RBG-1] == 1 due to the test above.
+     */
+    ue_ctrl->rballoc_sub_UE[CC_id][N_RBG-1] = 1;
+    rbgalloc_mask[N_RBG-1] = 0;
+    nb_rbg--;
+  }
   for (; nb_rbg > 0; start_rbg++) {
     if (!rbgalloc_mask[start_rbg])
       continue;
@@ -730,13 +749,13 @@ void calculate_max_mcs_min_rb(module_id_t mod_id,
   int tbs = get_TBS_UL(*mcs, rb_table[*rb_index]);
 
   // fixme: set use_srs flag
-  *tx_power = estimate_ue_tx_power(tbs * 8, rb_table[*rb_index], 0, Ncp, 0);
+  *tx_power = estimate_ue_tx_power(0,tbs * 8, rb_table[*rb_index], 0, Ncp, 0);
 
   /* find maximum MCS */
   while ((phr - *tx_power < 0 || tbs > bytes) && *mcs > 3) {
     (*mcs)--;
     tbs = get_TBS_UL(*mcs, rb_table[*rb_index]);
-    *tx_power = estimate_ue_tx_power(tbs * 8, rb_table[*rb_index], 0, Ncp, 0);
+    *tx_power = estimate_ue_tx_power(0,tbs * 8, rb_table[*rb_index], 0, Ncp, 0);
   }
 
   /* find minimum necessary RBs */
@@ -746,7 +765,7 @@ void calculate_max_mcs_min_rb(module_id_t mod_id,
          && phr - *tx_power > 0) {
     (*rb_index)++;
     tbs = get_TBS_UL(*mcs, rb_table[*rb_index]);
-    *tx_power = estimate_ue_tx_power(tbs * 8, rb_table[*rb_index], 0, Ncp, 0);
+    *tx_power = estimate_ue_tx_power(0,tbs * 8, rb_table[*rb_index], 0, Ncp, 0);
   }
 
   /* Decrease if we went to far in last iteration */
@@ -801,7 +820,7 @@ int rr_ul_run(module_id_t Mod_id,
   AssertFatal(num_contig_rb <= 2, "cannot handle more than two contiguous RB regions\n");
   UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
   const int max_rb = num_contig_rb > 1 ? MAX(rbs[0].length, rbs[1].length) : rbs[0].length;
-
+  eNB_MAC_INST *mac = RC.mac[Mod_id];
   /* for every UE: check whether we have to handle a retransmission (and
    * allocate, if so). If not, compute how much RBs this UE would need */
   int rb_idx_required[MAX_MOBILES_PER_ENB];
@@ -809,7 +828,7 @@ int rr_ul_run(module_id_t Mod_id,
   int num_ue_req = 0;
   for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
     UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id];
-    uint8_t harq_pid = subframe2harqpid(&RC.mac[Mod_id]->common_channels[CC_id],
+    uint8_t harq_pid = subframe2harqpid(&mac->common_channels[CC_id],
                                         sched_frame, sched_subframe);
     if (UE_info->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid] > 0) {
       /* this UE has a retransmission, allocate it right away */
@@ -845,11 +864,11 @@ int rr_ul_run(module_id_t Mod_id,
         }
       } else {
         LOG_W(MAC,
-              "cannot allocate UL retransmission for UE %d (nb_rb %d)\n",
-              UE_id,
-              nb_rb);
+              "%d.%d cannot allocate UL retransmission for UE %d (nb_rb %d, rbs0.length %d, rbs1.length %d,rbs0.start %d,rbs1.start %d)\n",
+              sched_frame,sched_subframe,UE_id,
+              nb_rb, rbs[0].length,rbs[1].length,rbs[0].start,rbs[1].start);
         UE_template->pre_dci_ul_pdu_idx = -1; // do not need CCE
-        RC.mac[Mod_id]->HI_DCI0_req[CC_id][subframe].hi_dci0_request_body.number_of_dci--;
+        mac->HI_DCI0_req[CC_id][subframe].hi_dci0_request_body.number_of_dci--;
         continue;
       }
       LOG_D(MAC, "%4d.%d UE %d retx %d RBs at start %d\n",
@@ -895,10 +914,9 @@ int rr_ul_run(module_id_t Mod_id,
         &tx_power);
 
     UE_template->pre_assigned_mcs_ul = mcs;
-    /* rb_idx_given >= 22: apparently the PHY cannot support more than 48
-     * RBs in the uplink. Hence, we limit every UE to 48 RBs, which is at
-     * index 22 */
-    rb_idx_required[UE_id] = min(22, rb_table_index);
+    /* rb_idx_given >= MAX index: limit RBs to value in configuration file 
+     * RBs in the uplink.  */
+    rb_idx_required[UE_id] = min(mac->max_ul_rb_index, rb_table_index);
     //UE_template->pre_allocated_nb_rb_ul = rb_table[rb_table_index];
     /* only print log when PHR changed */
     static int phr = 0;
diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c
index 23ac209389be0d314a56975b98869a2896ed4d28..740923cc08769072c043d2395d89aa7af63324c7 100644
--- a/openair2/LAYER2/MAC/rar_tools.c
+++ b/openair2/LAYER2/MAC/rar_tools.c
@@ -41,7 +41,6 @@
 #define DEBUG_RAR
 
 extern unsigned int localRIV2alloc_LUT25[512];
-extern unsigned int distRIV2alloc_LUT25[512];
 extern unsigned short RIV2nb_rb_LUT25[512];
 extern unsigned short RIV2first_rb_LUT25[512];
 extern RAN_CONTEXT_t RC;
@@ -67,8 +66,10 @@ fill_rar(const module_id_t module_idP,
   rar[5] = (uint8_t) (ra->rnti & 0xff);
   //ra->timing_offset = 0;
   ra->timing_offset /= 16;  //T_A = N_TA/16, where N_TA should be on a 30.72Msps
-  rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4));  // 7 MSBs of timing advance + divide by 4
-  rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0; // 4 LSBs of timing advance + divide by 4
+  //rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4));  // 7 MSBs of timing advance + divide by 4
+  //rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0; // 4 LSBs of timing advance + divide by 4
+  rar[0] = (uint8_t) (ra->timing_offset >> (4));  // 7 MSBs of timing advance + divide by 4
+  rar[1] = (uint8_t) (ra->timing_offset << (4)) & 0xf0; // 4 LSBs of timing advance + divide by 4
   COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id];
 
   if(N_RB_UL == 25) {
diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
index 0dedacb11ffc2aa7d16daa2051905c750ed2e0a4..9ae8f82a00cd2d0363c4cb4c644bd36ce2051c5e 100644
--- a/openair2/LAYER2/MAC/ue_procedures.c
+++ b/openair2/LAYER2/MAC/ue_procedures.c
@@ -72,7 +72,7 @@ extern UL_IND_t *UL_INFO;
 extern int next_ra_frame;
 extern module_id_t next_Mod_id;
 
-int mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047};
+rb_id_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047};
 static int mbms_mch_i=0;
 //static int num_msi_per_CSA[28];
 
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.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
index 381dce11b2cddce03c9633c17add5dc24d3ad7e6..6bb7970be66d72ed4a1f67498af3dcdaad6001b4 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
@@ -36,6 +36,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 
 #define TABLE_38213_13_1_NUM_INDEXES 15
 #define TABLE_38213_13_2_NUM_INDEXES 14
@@ -53,7 +54,7 @@
 // Definitions for MAC control and data
 #define NR_BCCH_DL_SCH 3 // SI
 #define NR_BCCH_BCH 5    // MIB
-#define CCCH_PAYLOAD_SIZE_MAX 128
+#define CCCH_PAYLOAD_SIZE_MAX 512 
 #define RAR_PAYLOAD_SIZE_MAX  128
 #define MAX_BWP_SIZE          275
 
@@ -148,10 +149,10 @@ typedef struct {
 // single Entry PHR MAC CE
 // TS 38.321 ch. 6.1.3.8
 typedef struct {
-  uint8_t PH: 6;
-  uint8_t R1: 2;
-  uint8_t PCMAX: 6;
-  uint8_t R2: 6;
+  uint8_t PH: 6;    // octet 1 [5:0]
+  uint8_t R1: 2;    // octet 1 [7:6]
+  uint8_t PCMAX: 6; // octet 2 [5:0]
+  uint8_t R2: 2;    // octet 2 [7:6]
 } __attribute__ ((__packed__)) NR_SINGLE_ENTRY_PHR_MAC_CE;
 
 
@@ -334,12 +335,12 @@ typedef struct {
 #define DL_SCH_LCID_CON_RES_ID                     0x3E
 #define DL_SCH_LCID_PADDING                        0x3F
 
-#define UL_SCH_LCID_CCCH                           0x00
+#define UL_SCH_LCID_CCCH1                          0x00
 #define UL_SCH_LCID_SRB1                           0x01
 #define UL_SCH_LCID_SRB2                           0x02
 #define UL_SCH_LCID_SRB3                           0x03
 #define UL_SCH_LCID_DTCH                           0x04
-#define UL_SCH_LCID_CCCH_MSG3                      0x21
+#define UL_SCH_LCID_CCCH                           0x34
 #define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY      0x35
 #define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT          0x36
 #define UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION  0x37
@@ -418,14 +419,6 @@ typedef enum {
   NR_RNTI_MCS_C,
 } nr_rnti_type_t;
 
-typedef enum subcarrier_spacing_e {
-  scs_15kHz  = 0x1,
-  scs_30kHz  = 0x2,
-  scs_60kHz  = 0x4,
-  scs_120kHz = 0x8,
-  scs_240kHz = 0x16
-} subcarrier_spacing_t;
-
 typedef enum channel_bandwidth_e {
   bw_5MHz   = 0x1,
   bw_10MHz  = 0x2,
@@ -462,6 +455,7 @@ typedef struct Type0_PDCCH_CSS_config_s {
   uint32_t ssb_length;
   uint32_t ssb_index;
   uint32_t cset_start_rb;
+  bool active;
 } NR_Type0_PDCCH_CSS_config_t;
 
 #endif /*__LAYER2_MAC_H__ */
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index 5d1b08bcf67450e29f2ac3f0d97e9f1ba9739d68..7fcc9b2297a73a43cff891f79dd3b5e219691d78 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -31,10 +31,31 @@
  */
 
 #include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "common/utils/nr/nr_common.h"
 #include <limits.h>
 
 #define reserved 0xffff
 
+
+void reverse_n_bits(uint8_t *value, uint16_t bitlen) {
+  uint16_t j;
+  uint8_t i;
+  for(j = bitlen - 1,i = 0; j > i; j--, i++) {
+    if(((*value>>j)&1) != ((*value>>i)&1)) {
+      *value ^= (1<<j);
+      *value ^= (1<<i);
+    }
+  }
+}
+
+
+// start symbols for SSB types A,B,C,D,E
+uint16_t symbol_ssb_AC[8]={2,8,16,22,30,36,44,50};
+uint16_t symbol_ssb_BD[64]={4,8,16,20,32,36,44,48,60,64,72,76,88,92,100,104,144,148,156,160,172,176,184,188,200,204,212,216,228,232,240,244,284,288,
+                            296,300,312,316,324,328,340,344,352,356,368,372,380,384,424,428,436,440,452,456,464,468,480,484,492,496,508,512,520,524};
+uint16_t symbol_ssb_E[64]={8,12,16,20,32,36,40,44,64,68,72,76,88,92,96,100,120,124,128,132,144,148,152,156,176,180,184,188,200,204,208,212,288,292,
+                           296,300,312,316,320,324,344,348,352,356,368,372,376,380,400,404,408,412,424,428,432,436,456,460,464,468,480,484,488,492};
+
 const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
 
 // Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz
@@ -117,6 +138,152 @@ const float   table_38213_13_12_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 0.5f, 0.5f
 
 const int32_t table_38213_10_1_1_c2[5] = { 0, 0, 4, 2, 1 };
 
+// for PDSCH from TS 38.214 subclause 5.1.2.1.1
+const uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[16][3]={
+    {0,2,12},   // row index 1
+    {0,2,10},   // row index 2
+    {0,2,9},    // row index 3
+    {0,2,7},    // row index 4
+    {0,2,5},    // row index 5
+    {0,9,4},    // row index 6
+    {0,4,4},    // row index 7
+    {0,5,7},    // row index 8
+    {0,5,2},    // row index 9
+    {0,9,2},    // row index 10
+    {0,12,2},   // row index 11
+    {0,1,13},   // row index 12
+    {0,1,6},    // row index 13
+    {0,2,4},    // row index 14
+    {0,4,7},    // row index 15
+    {0,8,4}     // row index 16
+};
+const uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[16][3]={
+    {0,3,11},   // row index 1
+    {0,3,9},    // row index 2
+    {0,3,8},    // row index 3
+    {0,3,6},    // row index 4
+    {0,3,4},    // row index 5
+    {0,10,4},   // row index 6
+    {0,6,4},    // row index 7
+    {0,5,7},    // row index 8
+    {0,5,2},    // row index 9
+    {0,9,2},    // row index 10
+    {0,12,2},   // row index 11
+    {0,1,13},   // row index 12
+    {0,1,6},    // row index 13
+    {0,2,4},    // row index 14
+    {0,4,7},    // row index 15
+    {0,8,4}     // row index 16
+};
+const uint8_t table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP_dmrs_typeA_pos2[16][3]={
+    {0,2,6},    // row index 1
+    {0,2,10},   // row index 2
+    {0,2,9},    // row index 3
+    {0,2,7},    // row index 4
+    {0,2,5},    // row index 5
+    {0,6,4},    // row index 6
+    {0,4,4},    // row index 7
+    {0,5,6},    // row index 8
+    {0,5,2},    // row index 9
+    {0,9,2},    // row index 10
+    {0,10,2},   // row index 11
+    {0,1,11},   // row index 12
+    {0,1,6},    // row index 13
+    {0,2,4},    // row index 14
+    {0,4,6},    // row index 15
+    {0,8,4}     // row index 16
+};
+const uint8_t table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP_dmrs_typeA_pos3[16][3]={
+    {0,3,5},    // row index 1
+    {0,3,9},    // row index 2
+    {0,3,8},    // row index 3
+    {0,3,6},    // row index 4
+    {0,3,4},    // row index 5
+    {0,8,2},    // row index 6
+    {0,6,4},    // row index 7
+    {0,5,6},    // row index 8
+    {0,5,2},    // row index 9
+    {0,9,2},    // row index 10
+    {0,10,2},   // row index 11
+    {0,1,11},   // row index 12
+    {0,1,6},    // row index 13
+    {0,2,4},    // row index 14
+    {0,4,6},    // row index 15
+    {0,8,4}     // row index 16
+};
+const uint8_t table_5_1_2_1_1_4_time_dom_res_alloc_B_dmrs_typeA_pos2[16][3]={
+    {0,2,2},    // row index 1
+    {0,4,2},    // row index 2
+    {0,6,2},    // row index 3
+    {0,8,2},    // row index 4
+    {0,10,2},   // row index 5
+    {1,2,2},    // row index 6
+    {1,4,2},    // row index 7
+    {0,2,4},    // row index 8
+    {0,4,4},    // row index 9
+    {0,6,4},    // row index 10
+    {0,8,4},    // row index 11
+    {0,10,4},   // row index 12
+    {0,2,7},    // row index 13
+    {0,2,12},   // row index 14
+    {1,2,4},    // row index 15
+    {0,0,0}     // row index 16
+};
+const uint8_t table_5_1_2_1_1_4_time_dom_res_alloc_B_dmrs_typeA_pos3[16][3]={
+    {0,2,2},    // row index 1
+    {0,4,2},    // row index 2
+    {0,6,2},    // row index 3
+    {0,8,2},    // row index 4
+    {0,10,2},   // row index 5
+    {1,2,2},    // row index 6
+    {1,4,2},    // row index 7
+    {0,2,4},    // row index 8
+    {0,4,4},    // row index 9
+    {0,6,4},    // row index 10
+    {0,8,4},    // row index 11
+    {0,10,4},   // row index 12
+    {0,2,7},    // row index 13
+    {0,3,11},   // row index 14
+    {1,2,4},    // row index 15
+    {0,0,0}     // row index 16
+};
+const uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C_dmrs_typeA_pos2[16][3]={
+    {0,2,2},  // row index 1
+    {0,4,2},  // row index 2
+    {0,6,2},  // row index 3
+    {0,8,2},  // row index 4
+    {0,10,2}, // row index 5
+    {0,0,0},  // row index 6
+    {0,0,0},  // row index 7
+    {0,2,4},  // row index 8
+    {0,4,4},  // row index 9
+    {0,6,4},  // row index 10
+    {0,8,4},  // row index 11
+    {0,10,4}, // row index 12
+    {0,2,7},  // row index 13
+    {0,2,12},  // row index 14
+    {0,0,6},  // row index 15
+    {0,2,6}   // row index 16
+};
+const uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C_dmrs_typeA_pos3[16][3]={
+    {0,2,2},  // row index 1
+    {0,4,2},  // row index 2
+    {0,6,2},  // row index 3
+    {0,8,2},  // row index 4
+    {0,10,2}, // row index 5
+    {0,0,0},  // row index 6
+    {0,0,0},  // row index 7
+    {0,2,4},  // row index 8
+    {0,4,4},  // row index 9
+    {0,6,4},  // row index 10
+    {0,8,4},  // row index 11
+    {0,10,4}, // row index 12
+    {0,2,7},  // row index 13
+    {0,3,11},  // row index 14
+    {0,0,6},  // row index 15
+    {0,2,6}   // row index 16
+};
+
 const char *prachfmt[]={"0","1","2","3", "A1","A2","A3","B1","B4","C0","C2","A1/B1","A2/B2","A3/B3"};
 const char *duplex_mode[]={"FDD","TDD"};
 
@@ -1009,7 +1176,7 @@ int get_format0(uint8_t index,
                 uint8_t unpaired,
 		frequency_range_t frequency_range){
 
-  uint16_t format;
+  uint16_t format=0;
   if (unpaired) {
     if (frequency_range==FR1)
       format = table_6_3_3_2_3_prachConfig_Index[index][0];
@@ -1025,12 +1192,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
@@ -1220,6 +1387,11 @@ int get_nr_prach_occasion_info_from_index(uint8_t index,
     else { // FDD
       x = table_6_3_3_2_2_prachConfig_Index[index][2];
       s_map = table_6_3_3_2_2_prachConfig_Index[index][4];
+      for(int i = 0; i < 64 ; i++) {
+        if ( (s_map >> i) & 0x01) {
+          (*N_RA_sfn)++;
+        }
+      }
       *N_RA_slot = table_6_3_3_2_2_prachConfig_Index[index][6];
       if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
         *start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5];
@@ -1396,19 +1568,17 @@ int get_nr_prach_info_from_index(uint8_t index,
             if (table_6_3_3_2_3_prachConfig_Index[index][1] != -1)
               format2 = (uint8_t) table_6_3_3_2_3_prachConfig_Index[index][1];
             *format = ((uint8_t) table_6_3_3_2_3_prachConfig_Index[index][0]) | (format2<<8);
-            LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d (col 6 %lu) absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u N_RA_slot %u RA_sfn_index %u \n",
-                  frame,
-                  slot,
-                  index,
-                  table_6_3_3_2_3_prachConfig_Index[index][6],
-                  pointa,
-                  mu,
-                  unpaired,
-                  *start_symbol,
-                  *N_t_slot,
-                  *N_dur,
-                  *N_RA_slot,
-                  *RA_sfn_index);
+            LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d (col 6 %lu) absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u N_RA_slot %u RA_sfn_index %u \n", frame,
+              slot,
+              index, table_6_3_3_2_3_prachConfig_Index[index][6],
+              pointa,
+              mu,
+              unpaired,
+              *start_symbol,
+              *N_t_slot,
+              *N_dur,
+              *N_RA_slot,
+              *RA_sfn_index);
           }
           return 1;
         }
@@ -1429,6 +1599,11 @@ int get_nr_prach_info_from_index(uint8_t index,
             if ( (table_6_3_3_2_2_prachConfig_Index[index][6] <= 1) && (slot%2 == 0) )
               return 0; // no prach in even slots @ 30kHz for 1 prach per subframe
           }
+          for(int i = 0; i <= subframe ; i++) {
+            if ( (s_map >> i) & 0x01) {
+              (*RA_sfn_index)++;
+            }
+          }
           if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
             *start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5];
             *N_t_slot = table_6_3_3_2_2_prachConfig_Index[index][7];
@@ -1567,79 +1742,47 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
   }
 }
 
-// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101)
-// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
-// Notes:
-// - N_OFFs for bands from 80 to 89 and band 95 is referred to UL
-// - Frequencies are expressed in KHz
-// - col: NR_band ul_min  ul_max  dl_min  dl_max  step  N_OFFs_DL  deltaf_raster
-nr_bandentry_t nr_bandtable[] = {
-  {1,   1920000, 1980000, 2110000, 2170000, 20, 422000, 100},
-  {2,   1850000, 1910000, 1930000, 1990000, 20, 386000, 100},
-  {3,   1710000, 1785000, 1805000, 1880000, 20, 361000, 100},
-  {5,    824000,  849000,  869000,  894000, 20, 173800, 100},
-  {7,   2500000, 2570000, 2620000, 2690000, 20, 524000, 100},
-  {8,    880000,  915000,  925000,  960000, 20, 185000, 100},
-  {12,   698000,  716000,  729000,  746000, 20, 145800, 100},
-  {14,   788000,  798000,  758000,  768000, 20, 151600, 100},
-  {18,   815000,  830000,  860000,  875000, 20, 172000, 100},
-  {20,   832000,  862000,  791000,  821000, 20, 158200, 100},
-  {25,  1850000, 1915000, 1930000, 1995000, 20, 386000, 100},
-  {26,   814000,  849000,  859000,  894000, 20, 171800, 100},
-  {28,   703000,  758000,  758000,  813000, 20, 151600, 100},
-  {29,      000,     000,  717000,  728000, 20, 143400, 100},
-  {30,  2305000, 2315000, 2350000, 2360000, 20, 470000, 100},
-  {34,  2010000, 2025000, 2010000, 2025000, 20, 402000, 100},
-  {38,  2570000, 2620000, 2570000, 2630000, 20, 514000, 100},
-  {39,  1880000, 1920000, 1880000, 1920000, 20, 376000, 100},
-  {40,  2300000, 2400000, 2300000, 2400000, 20, 460000, 100},
-  {41,  2496000, 2690000, 2496000, 2690000,  3, 499200,  15},
-  {41,  2496000, 2690000, 2496000, 2690000,  6, 499200,  30},
-  {47,  5855000, 5925000, 5855000, 5925000,  1, 790334,  15},
-  //{48,  3550000, 3700000, 3550000, 3700000,  1, 636667,  15},
-  //{48,  3550000, 3700000, 3550000, 3700000,  2, 636668,  30},
-  {50,  1432000, 1517000, 1432000, 1517000, 20, 286400, 100},
-  {51,  1427000, 1432000, 1427000, 1432000, 20, 285400, 100},
-  {53,  2483500, 2495000, 2483500, 2495000, 20, 496700, 100},
-  {65,  1920000, 2010000, 2110000, 2200000, 20, 422000, 100},
-  {66,  1710000, 1780000, 2110000, 2200000, 20, 422000, 100},
-  {70,  1695000, 1710000, 1995000, 2020000, 20, 399000, 100},
-  {71,   663000,  698000,  617000,  652000, 20, 123400, 100},
-  {74,  1427000, 1470000, 1475000, 1518000, 20, 295000, 100},
-  {75,      000,     000, 1432000, 1517000, 20, 286400, 100},
-  {76,      000,     000, 1427000, 1432000, 20, 285400, 100},
-  {77,  3300000, 4200000, 3300000, 4200000,  1, 620000,  15},
-  {77,  3300000, 4200000, 3300000, 4200000,  2, 620000,  30},
-  {78,  3300000, 3800000, 3300000, 3800000,  1, 620000,  15},
-  {78,  3300000, 3800000, 3300000, 3800000,  2, 620000,  30},
-  {79,  4400010, 5000000, 4400010, 5000000,  1, 693334,  15},
-  {79,  4400010, 5000000, 4400010, 5000000,  2, 693334,  30},
-  {80,  1710000, 1785000,     000,     000, 20, 342000, 100},
-  {81,   880000,  915000,     000,     000, 20, 176000, 100},
-  {82,   832000,  862000,     000,     000, 20, 166400, 100},
-  {83,   703000,  748000,     000,     000, 20, 140600, 100},
-  {84,  1920000, 1980000,     000,     000, 20, 384000, 100},
-  {86,  1710000, 1785000,     000,     000, 20, 342000, 100},
-  {89,   824000,  849000,     000,     000, 20, 342000, 100},
-  {90,  2496000, 2690000, 2496000, 2690000, 3,  499200,  15},
-  {90,  2496000, 2690000, 2496000, 2690000, 6,  499200,  30},
-  {90,  2496000, 2690000, 2496000, 2690000, 20, 499200, 100},
-  {91,   832000,  862000, 1427000, 1432000, 20, 285400, 100},
-  {92,   832000,  862000, 1432000, 1517000, 20, 286400, 100},
-  {93,   880000,  915000, 1427000, 1432000, 20, 285400, 100},
-  {94,   880000,  915000, 1432000, 1517000, 20, 286400, 100},
-  {95,  2010000, 2025000,     000,     000, 20, 402000, 100},
-  {257,26500020,29500000,26500020,29500000,  1,2054166,  60},
-  {257,26500080,29500000,26500080,29500000,  2,2054167, 120},
-  {258,24250080,27500000,24250080,27500000,  1,2016667,  60},
-  {258,24250080,27500000,24250080,27500000,  2,2016667, 120},
-  {260,37000020,40000000,37000020,40000000,  1,2229166,  60},
-  {260,37000080,40000000,37000080,40000000,  2,2229167, 120},
-  {261,27500040,28350000,27500040,28350000,  1,2070833,  60},
-  {261,27500040,28350000,27500040,28350000,  2,2070833, 120}
+// TS 38.211 Table 7.4.1.1.2-3: PDSCH DMRS positions l' within a slot for single-symbol DMRS and intra-slot frequency hopping disabled.
+// The first 4 colomns are PDSCH mapping type A and the last 4 colomns are PDSCH mapping type B.
+// When l' = l0, it is represented by 1
+// E.g. when symbol duration is 12 in colomn 7, value 1057 ('10000100001') which means l' =  l0, 5, 10.
+
+int32_t table_7_4_1_1_2_3_pdsch_dmrs_positions_l [13][8] = {                             // Duration in symbols
+{-1,          -1,          -1,         -1,          1,          1,         1,         1},       //2              // (DMRS l' position)
+{0,            0,           0,          0,          1,          1,         1,         1},       //3              // (DMRS l' position)
+{0,            0,           0,          0,          1,          1,         1,         1},       //4               // (DMRS l' position)
+{0,            0,           0,          0,          1,          17,        17,       17},       //5               // (DMRS l' position)
+{0,            0,           0,          0,          1,          17,        17,       17},       //6               // (DMRS l' position)
+{0,            0,           0,          0,          1,          17,        17,       17},       //7               // (DMRS l' position)
+{0,          128,         128,        128,          1,          65,        73,       73},       //8               // (DMRS l' position)
+{0,          128,         128,        128,          1,         129,       145,      145},       //9               // (DMRS l' position)
+{0,          512,         576,        576,          1,         129,       145,      145},       //10              // (DMRS l' position)
+{0,          512,         576,        576,          1,         257,       273,      585},       //11              // (DMRS l' position)
+{0,          512,         576,       2336,          1,         513,       545,      585},       //12              // (DMRS l' position)
+{0,         2048,        2176,       2336,          1,         513,       545,      585},       //13              // (DMRS l' position)
+{0,         2048,        2176,       2336,         -1,          -1,       -1,        -1},       //14              // (DMRS l' position)
 };
 
 
+// TS 38.211 Table 7.4.1.1.2-4: PDSCH DMRS positions l' within a slot for double-symbol DMRS and intra-slot frequency hopping disabled.
+// The first 4 colomns are PDSCH mapping type A and the last 4 colomns are PDSCH mapping type B.
+// When l' = l0, it is represented by 1
+
+int32_t table_7_4_1_1_2_4_pdsch_dmrs_positions_l [12][8] = {                             // Duration in symbols
+{-1,          -1,          -1,         -1,         -1,         -1,        -1,         -1},       //<4              // (DMRS l' position)
+{0,            0,          -1,         -1,         -1,         -1,        -1,         -1},       //4               // (DMRS l' position)
+{0,            0,          -1,         -1,          3,          3,        -1,         -1},       //5               // (DMRS l' position)
+{0,            0,          -1,         -1,          3,          3,        -1,         -1},       //6               // (DMRS l' position)
+{0,            0,          -1,         -1,          3,          3,        -1,         -1},       //7               // (DMRS l' position)
+{0,            0,          -1,         -1,          3,         99,        -1,         -1},       //8               // (DMRS l' position)
+{0,            0,          -1,         -1,          3,         99,        -1,         -1},       //9               // (DMRS l' position)
+{0,          768,          -1,         -1,          3,        387,        -1,         -1},       //10              // (DMRS l' position)
+{0,          768,          -1,         -1,          3,        387,        -1,         -1},       //11              // (DMRS l' position)
+{0,          768,          -1,         -1,          3,        771,        -1,         -1},       //12              // (DMRS l' position)
+{0,         3072,          -1,         -1,          3,        771,        -1,         -1},       //13              // (DMRS l' position)
+{0,         3072,          -1,         -1,          -1,        -1,        -1,         -1},       //14              // (DMRS l' position)
+};
+
 // TS 38.211 Table 6.4.1.1.3-3: PUSCH DMRS positions l' within a slot for single-symbol DMRS and intra-slot frequency hopping disabled.
 // The first 4 colomns are PUSCH mapping type A and the last 4 colomns are PUSCH mapping type B.
 // When l' = l0, it is represented by 1
@@ -1647,17 +1790,17 @@ nr_bandentry_t nr_bandtable[] = {
 
 int32_t table_6_4_1_1_3_3_pusch_dmrs_positions_l [12][8] = {                             // Duration in symbols
 {-1,          -1,          -1,         -1,          1,          1,         1,         1},       //<4              // (DMRS l' position)
-{1,            1,           1,          1,          1,          1,         1,         1},       //4               // (DMRS l' position)
-{1,            1,           1,          1,          1,          5,         5,         5},       //5               // (DMRS l' position)
-{1,            1,           1,          1,          1,          5,         5,         5},       //6               // (DMRS l' position)
-{1,            1,           1,          1,          1,          5,         5,         5},       //7               // (DMRS l' position)
-{1,          129,         129,        129,          1,         65,        73,        73},       //8               // (DMRS l' position)
-{1,          129,         129,        129,          1,         65,        73,        73},       //9               // (DMRS l' position)
-{1,          513,         577,        577,          1,        257,       273,       585},       //10              // (DMRS l' position)
-{1,          513,         577,        577,          1,        257,       273,       585},       //11              // (DMRS l' position)
-{1,          513,         577,       2337,          1,       1025,      1057,       585},       //12              // (DMRS l' position)
-{1,         2049,        2177,       2337,          1,       1025,      1057,       585},       //13              // (DMRS l' position)
-{1,         2049,        2177,       2337,          1,       1025,      1057,       585},       //14              // (DMRS l' position)
+{0,            0,           0,          0,          1,          1,         1,         1},       //4               // (DMRS l' position)
+{0,            0,           0,          0,          1,         17,        17,        17},       //5               // (DMRS l' position)
+{0,            0,           0,          0,          1,         17,        17,        17},       //6               // (DMRS l' position)
+{0,            0,           0,          0,          1,         17,        17,        17},       //7               // (DMRS l' position)
+{0,          128,         128,        128,          1,         65,        73,        73},       //8               // (DMRS l' position)
+{0,          128,         128,        128,          1,         65,        73,        73},       //9               // (DMRS l' position)
+{0,          512,         576,        576,          1,        257,       273,       585},       //10              // (DMRS l' position)
+{0,          512,         576,        576,          1,        257,       273,       585},       //11              // (DMRS l' position)
+{0,          512,         576,       2336,          1,       1025,      1057,       585},       //12              // (DMRS l' position)
+{0,         2048,        2176,       2336,          1,       1025,      1057,       585},       //13              // (DMRS l' position)
+{0,         2048,        2176,       2336,          1,       1025,      1057,       585},       //14              // (DMRS l' position)
 };
 
 
@@ -1667,24 +1810,22 @@ int32_t table_6_4_1_1_3_3_pusch_dmrs_positions_l [12][8] = {
 
 int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = {                             // Duration in symbols
 {-1,          -1,          -1,         -1,         -1,         -1,        -1,         -1},       //<4              // (DMRS l' position)
-{1,            1,          -1,         -1,         -1,         -1,        -1,         -1},       //4               // (DMRS l' position)
-{1,            1,          -1,         -1,          1,          1,        -1,         -1},       //5               // (DMRS l' position)
-{1,            1,          -1,         -1,          1,          1,        -1,         -1},       //6               // (DMRS l' position)
-{1,            1,          -1,         -1,          1,          1,        -1,         -1},       //7               // (DMRS l' position)
-{1,            1,          -1,         -1,          1,         33,        -1,         -1},       //8               // (DMRS l' position)
-{1,            1,          -1,         -1,          1,         33,        -1,         -1},       //9               // (DMRS l' position)
-{1,          257,          -1,         -1,          1,        129,        -1,         -1},       //10              // (DMRS l' position)
-{1,          257,          -1,         -1,          1,        129,        -1,         -1},       //11              // (DMRS l' position)
-{1,          257,          -1,         -1,          1,        513,        -1,         -1},       //12              // (DMRS l' position)
-{1,         1025,          -1,         -1,          1,        513,        -1,         -1},       //13              // (DMRS l' position)
-{1,         1025,          -1,         -1,          1,        513,        -1,         -1},       //14              // (DMRS l' position)
+{0,            0,          -1,         -1,         -1,         -1,        -1,         -1},       //4               // (DMRS l' position)
+{0,            0,          -1,         -1,          3,          3,        -1,         -1},       //5               // (DMRS l' position)
+{0,            0,          -1,         -1,          3,          3,        -1,         -1},       //6               // (DMRS l' position)
+{0,            0,          -1,         -1,          3,          3,        -1,         -1},       //7               // (DMRS l' position)
+{0,            0,          -1,         -1,          3,         99,        -1,         -1},       //8               // (DMRS l' position)
+{0,            0,          -1,         -1,          3,         99,        -1,         -1},       //9               // (DMRS l' position)
+{0,          768,          -1,         -1,          3,        387,        -1,         -1},       //10              // (DMRS l' position)
+{0,          768,          -1,         -1,          3,        387,        -1,         -1},       //11              // (DMRS l' position)
+{0,          768,          -1,         -1,          3,       1539,        -1,         -1},       //12              // (DMRS l' position)
+{0,         3072,          -1,         -1,          3,       1539,        -1,         -1},       //13              // (DMRS l' position)
+{0,         3072,          -1,         -1,          3,       1539,        -1,         -1},       //14              // (DMRS l' position)
 };
 
-#define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t))
-
 // Returns the corresponding row index of the NR table
-int get_nr_table_idx(int nr_bandP, uint8_t scs_index){
-
+int get_nr_table_idx(int nr_bandP, uint8_t scs_index)
+{
   int i, j;
   int scs_khz = 15 << scs_index;
   int supplementary_bands[] = {29,75,76,80,81,82,83,84,86,89,95};
@@ -1695,8 +1836,8 @@ int get_nr_table_idx(int nr_bandP, uint8_t scs_index){
       AssertFatal(0 == 1, "Band %d is a supplementary band (%d). This is not supported yet.\n", nr_bandP, supplementary_bands[j]);
   }
 
-  AssertFatal(nr_bandP <= nr_bandtable[NR_BANDTABLE_SIZE-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[NR_BANDTABLE_SIZE-1].band);
-  for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++);
+  AssertFatal(nr_bandP <= nr_bandtable[nr_bandtable_size-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[nr_bandtable_size-1].band);
+  for (i = 0; i < nr_bandtable_size && nr_bandtable[i].band != nr_bandP; i++);
 
   // selection of correct Deltaf raster according to SCS
   if ((nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz))
@@ -1705,35 +1846,33 @@ int get_nr_table_idx(int nr_bandP, uint8_t scs_index){
   LOG_D(PHY, "NR band table index %d (Band %d, dl_min %lu, ul_min %lu)\n", i, nr_bandtable[i].band, nr_bandtable[i].dl_min,nr_bandtable[i].ul_min);
 
   return i;
-
 }
 
 // Computes the duplex spacing (either positive or negative) in KHz
-void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex){
-
+int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index)
+{
   int nr_table_idx = get_nr_table_idx(nr_bandP, scs_index);
 
-  *delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min);
+  int32_t delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min);
 
-  LOG_D(PHY, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", *delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band);
+  LOG_I(PHY, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band);
 
+  return delta_duplex;
 }
 
-void get_frame_type(uint16_t current_band,
-                    uint8_t scs_index,
-                    lte_frame_type_t *current_type){
-
-  int32_t current_offset;
-  get_delta_duplex(current_band, scs_index, &current_offset);
+lte_frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index)
+{
+  lte_frame_type_t current_type;
+  int32_t delta_duplex = get_delta_duplex(current_band, scs_index);
 
-  current_offset *= 1000;
-  if (current_offset == 0)
-    *current_type = TDD;
+  if (delta_duplex == 0)
+    current_type = TDD;
   else
-    *current_type = FDD;
+    current_type = FDD;
 
-  LOG_I(MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[*current_type], current_offset);
+  LOG_I(MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[current_type], delta_duplex);
 
+  return current_type;
 }
 
 uint16_t config_bandwidth(int mu, int nb_rb, int nr_band)
@@ -1911,7 +2050,6 @@ uint64_t from_nrarfcn(int nr_bandP,
   int deltaFglobal = 5;
   uint32_t N_REF_Offs = 0;
   uint64_t F_REF_Offs_khz = 0;
-  int32_t delta_duplex;
   uint64_t N_OFFs, frequency, freq_min;
   int i = get_nr_table_idx(nr_bandP, scs_index);
 
@@ -1926,7 +2064,7 @@ uint64_t from_nrarfcn(int nr_bandP,
     F_REF_Offs_khz = 24250080;
   }
 
-  get_delta_duplex(nr_bandP, scs_index, &delta_duplex);
+  int32_t delta_duplex = get_delta_duplex(nr_bandP, scs_index);
 
   if (delta_duplex <= 0){ // DL band >= UL band
     if (nrarfcn >= nr_bandtable[i].N_OFFs_DL){ // is TDD of FDD DL
@@ -2228,8 +2366,8 @@ int get_num_dmrs(uint16_t dmrs_mask ) {
   return(num_dmrs);
 }
 /* returns the total DMRS symbols in a slot*/
-uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols){
-  return get_num_dmrs(fill_dmrs_mask(pdsch_Config,dmrs_TypeA_Position,NrOfSymbols));
+uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols, int startSymbol, int mappingtype){
+  return get_num_dmrs(fill_dmrs_mask(pdsch_Config,dmrs_TypeA_Position,NrOfSymbols, startSymbol, mappingtype));
 }
 
 // Table 5.1.2.2.1-1 38.214
@@ -2293,29 +2431,46 @@ uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position) {
 
 }
 
-int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength) {
+int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength, uint8_t start_symbol, uint8_t dmrs_typeA_position) {
 
   uint8_t row, colomn;
   int32_t l_prime;
 
+  LOG_D(MAC, "PUSCH: NrofSymbols:%d, startSymbol:%d, mappingtype:%d, dmrs_TypeA_Position:%d\n", duration_in_symbols, start_symbol, mapping_type, dmrs_typeA_position);
+
+  // Section 6.4.1.1.3 in Spec 38.211
+  // For PDSCH Mapping TypeA, ld is duration between first OFDM of the slot and last OFDM symbol of the scheduled PUSCH resources
+  // For TypeB, ld is the duration of the scheduled PUSCH resources
+  uint8_t ld = (mapping_type == typeA) ? (duration_in_symbols + start_symbol) : duration_in_symbols;
+  uint8_t l0 = (dmrs_typeA_position == NR_MIB__dmrs_TypeA_Position_pos2) ? 2 : 3 ;
+
   colomn = additional_pos;
 
   if (mapping_type == typeB)
     colomn += 4;
 
-  if (duration_in_symbols < 4)
+  if (ld < 4)
     row = 0;
   else
-    row = duration_in_symbols - 3;
+    row = ld - 3;
 
-  if (pusch_maxLength == pusch_len1)
+  if (pusch_maxLength == pusch_len1) {
     l_prime = table_6_4_1_1_3_3_pusch_dmrs_positions_l[row][colomn];
-  else
+    l0 = 1 << l0;
+  }
+  else {
     l_prime = table_6_4_1_1_3_4_pusch_dmrs_positions_l[row][colomn];
+    l0 = 1<<l0 | 1<<(l0+1);
+  }
+
+  LOG_D(MAC, "PUSCH - l0:%d, ld:%d,row:%d, column:%d, addpos:%d, maxlen:%d\n", l0, ld, row, colomn, additional_pos, pusch_maxLength);
+  AssertFatal(l_prime>=0,"invalid l_prime < 0\n");
 
-  AssertFatal(l_prime>0,"invalid l_prime < 0\n");
+  l_prime = (mapping_type == typeA) ? (l_prime | l0) : (l_prime << start_symbol);
+  LOG_D(MAC, " PUSCH DMRS MASK in HEX:%x\n", l_prime);
 
   return l_prime;
+
 }
 
 /*******************************************************************
@@ -2342,7 +2497,7 @@ uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint
     mcs4 = 28;
 
   if (I_mcs < mcs1) {
-    LOG_I(PHY, "PUSH PT-RS is not present.\n");
+    LOG_D(PHY, "PUSH PT-RS is not present.\n");
     return -1;
   } else if (I_mcs >= mcs1 && I_mcs < mcs2)
     return 2;
@@ -2360,7 +2515,7 @@ uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint
 *
 * NAME :         get_K_ptrs
 *
-* PARAMETERS :   ptrs_UplinkConfig      PTRS uplink configuration
+* PARAMETERS :   nrb0, nrb1             PTRS uplink configuration
 *                N_RB                   number of RBs scheduled for PUSCH
 *
 * RETURN :       the parameter K_ptrs
@@ -2372,7 +2527,7 @@ uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint
 uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB) {
 
   if (N_RB < nrb0) {
-    LOG_I(PHY,"PUSH PT-RS is not present.\n");
+    LOG_D(PHY,"PUSH PT-RS is not present.\n");
     return -1;
   } else if (N_RB >= nrb0 && N_RB < nrb1)
     return 2;
@@ -2382,7 +2537,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,
@@ -2397,7 +2552,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;
@@ -2405,7 +2560,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");
@@ -2416,8 +2571,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,
@@ -2436,8 +2591,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;
@@ -2449,7 +2605,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;
 
@@ -2457,24 +2613,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;
@@ -2505,13 +2661,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;
       }
@@ -2531,9 +2687,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");
           }
@@ -2553,7 +2709,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){
@@ -2597,21 +2753,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;
       }
@@ -2644,7 +2800,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:
@@ -2652,19 +2807,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);
@@ -2720,7 +2875,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;
       }
@@ -2744,20 +2899,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;
         }
@@ -2808,144 +2963,150 @@ 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) {
+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;
 
-  if (scc->tdd_UL_DL_ConfigurationCommon==NULL) return(1);
+  // Note: condition on frame_type
+  // goal: the UL scheduler assumes mode is TDD therefore this hack is needed to make FDD work
+  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) {
+int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols, int startSymbol, int mappingtype_fromDCI) {
+
+  int l0;int dmrs_AdditionalPosition = 0;int maxLength = 0;
+  NR_DMRS_DownlinkConfig_t *dmrs_config = NULL;
+
+  LOG_D(MAC, "NrofSymbols:%d, startSymbol:%d, mappingtype:%d, dmrs_TypeA_Position:%d\n", NrOfSymbols, startSymbol, mappingtype_fromDCI, dmrs_TypeA_Position);
 
-  int l0;
   if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2) l0=2;
   else if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos3) l0=3;
   else AssertFatal(1==0,"Illegal dmrs_TypeA_Position %d\n",(int)dmrs_TypeA_Position);
-  if (pdsch_Config == NULL) { // Initial BWP
-    return(1<<l0);
+
+  // in case of DCI FORMAT 1_0 or dedicated pdsch config not received additionposition = pos2, len1 should be used
+  // referred to section 5.1.6.2 in 38.214
+  dmrs_AdditionalPosition = 2;
+  maxLength = 1;
+
+  if (pdsch_Config != NULL) {
+    if (mappingtype_fromDCI == typeA) { // Type A
+      if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA && pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup)
+        dmrs_config = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup;
+    } else if (mappingtype_fromDCI == typeB) {
+      if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB && pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup)
+        dmrs_config = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup;
+    } else {
+      AssertFatal(1==0,"Incorrect Mappingtype\n");
+    }
+
+    AssertFatal(dmrs_config != NULL," DMRS configs not present in PDSCH DMRS Downlink config\n");
+
+    // default values of maxlength = len2, additionalposition is pos2
+    if (dmrs_config->maxLength != NULL) maxLength = 2;
+    if (dmrs_config->dmrs_AdditionalPosition != NULL) dmrs_AdditionalPosition = *dmrs_config->dmrs_AdditionalPosition;
+  }
+
+  uint8_t ld, row, column;
+  int32_t l_prime = -1;
+
+  // columns 0-3 for TypeA, 4-7 for TypeB
+  column = (mappingtype_fromDCI == typeA) ? dmrs_AdditionalPosition : (dmrs_AdditionalPosition + 4);
+
+  // Section 7.4.1.1.2 in Spec 38.211
+  // For PDSCH Mapping TypeA, ld is duration between first OFDM of the slot and last OFDM symbol of the scheduled PDSCH resources
+  // For TypeB, ld is the duration of the scheduled PDSCH resources
+  ld = (mappingtype_fromDCI == typeA) ? (NrOfSymbols + startSymbol) : NrOfSymbols;
+
+  // Section 7.4.1.1.2 in Spec 38.211
+  //For PDSCH Mapping typeB, if PDSCH duration ld <=4, only single symbol DMRS is supported
+  if (mappingtype_fromDCI == typeB && ld <= 4)
+    maxLength = 1;
+
+  AssertFatal(ld > 2 && ld < 15,"Illegal NrOfSymbols according to Table 5.1.2.1-1 Spec 38.214 %d\n",ld);
+  AssertFatal((NrOfSymbols + startSymbol) < 15,"Illegal S+L according to Table 5.1.2.1-1 Spec 38.214 S:%d L:%d\n",startSymbol, NrOfSymbols);
+
+  if (mappingtype_fromDCI == typeA) {
+
+    // Section 7.4.1.1.2 in Spec 38.211
+    AssertFatal((l0 == 2) || (l0 == 3 && dmrs_AdditionalPosition != 3),"Wrong config, If dmrs_TypeA_Position POS3, ADD POS cannot be POS3 \n");
+
+    // Table 5.1.2.1-1 in Spec 38.214
+    AssertFatal(startSymbol <= l0, "Wrong config, Start symbol %d cannot be later than dmrs_TypeA_Position %d \n", startSymbol, l0);
+
+    // Section 7.4.1.1.2 in Spec 38.211
+    AssertFatal(l0 == 2 || (l0 == 3 && (ld != 3 || ld != 4)), "ld 3 or 4 symbols only possible with dmrs_TypeA_Position POS2 \n");
+
+  }
+
+  if (maxLength == 1) {
+    row = ld - 2;
+    l_prime = table_7_4_1_1_2_3_pdsch_dmrs_positions_l[row][column];
+    l0 = 1 << l0;
   }
   else {
-    if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA &&
-	pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) {
-      // Relative to start of slot
-      NR_DMRS_DownlinkConfig_t *dmrs_config = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup;
-      AssertFatal(NrOfSymbols>1 && NrOfSymbols < 15,"Illegal NrOfSymbols %d\n",NrOfSymbols);
-      int pos2=0;
-      if (dmrs_config->maxLength == NULL) {
-	// this is Table 7.4.1.1.2-3: PDSCH DM-RS positions l for single-symbol DM-RS
-	if (dmrs_config->dmrs_AdditionalPosition == NULL) pos2=1;
-	else if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition == NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0 )
-	  return(1<<l0);
-	
-	
-	switch (NrOfSymbols) {
-	case 2 :
-	case 3 :
-	case 4 :
-	case 5 :
-	case 6 :
-	case 7 :
-    return(1<<l0);
-	  break;
-	case 8 :
-	case 9:
-	  return(1<<l0 | 1<<7);
-	  break;
-	case 10:
-	case 11:
-	  if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1)
-	    return(1<<l0 | 1<<9);
-	  else
-	    return(1<<l0 | 1<<6 | 1<<9);
-	  break;
-	case 12:
-	  if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1)
-	    return(1<<l0 | 1<<9);
-	  else if (pos2==1)
-	    return(1<<l0 | 1<<6 | 1<<9);
-	  else if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3)
-	    return(1<<l0 | 1<<5 | 1<<8 | 1<<11);
-	  break;
-	case 13:
-	case 14:
-	  if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1)
-	    return(1<<l0 | 1<<11);
-	  else if (pos2==1)
-	    return(1<<l0 | 1<<7 | 1<<11);
-	  else if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3)
-	    return(1<<l0 | 1<<5 | 1<<8 | 1<<11);
-	  break;
-	}
-      }
-      else {
-	// Table 7.4.1.1.2-4: PDSCH DM-RS positions l for double-symbol DM-RS.
-	AssertFatal(NrOfSymbols>3,"Illegal NrOfSymbols %d for len2 DMRS\n",NrOfSymbols);
-	if (NrOfSymbols < 10) return(1<<l0);
-	if (NrOfSymbols < 13 && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<<l0);
-	if (NrOfSymbols < 13 && *dmrs_config->dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<<l0 | 1<<8);
-	if (*dmrs_config->dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<<l0);
-	if (*dmrs_config->dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) return(1<<l0 | 1<<10);
-        if (*dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<<l0);
-	if (*dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) return(1<<l0 | 1<<10);
-      }
-    }
-    else if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB &&
-	     pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) {
-      // Relative to start of PDSCH resource
-      AssertFatal(1==0,"TypeB DMRS not supported yet\n");
-    }
+    row = (ld < 4) ? 0 : (ld - 3);
+    l_prime = table_7_4_1_1_2_4_pdsch_dmrs_positions_l[row][column];
+    l0 = 1<<l0 | 1<<(l0+1);
   }
-  AssertFatal(1==0,"Shouldn't get here\n");
-  return(-1);
+
+  LOG_D(MAC, "l0:%d, ld:%d,row:%d, column:%d, addpos:%d, maxlen:%d\n", l0, ld, row, column, dmrs_AdditionalPosition, maxLength);
+  AssertFatal(l_prime>=0,"ERROR in configuration.Check Time Domain allocation of this Grant. l_prime < 1. row:%d, column:%d\n", row, column);
+
+  l_prime = (mappingtype_fromDCI == typeA) ? (l_prime | l0) : (l_prime << startSymbol);
+  LOG_D(MAC, " PDSCH DMRS MASK in HEX:%x\n", l_prime);
+
+  return l_prime;
 }
 
 uint8_t get_pusch_mcs_table(long *mcs_Table,
@@ -3064,102 +3225,187 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
     valid = false;
     return valid;
   }
-  //printf("[MAC] PTRS is set  K= %u L= %u\n", *K_ptrs,1<<*L_ptrs);
+
+  /* Moved below check from scheduler function to here */
+  if (*L_ptrs >= NrOfSymbols) {
+    valid = false;
+    return valid;
+  }
   return valid;
 }
-void get_band(uint64_t downlink_frequency,
-              uint16_t *current_band,
-              int32_t *current_offset,
-              lte_frame_type_t *current_type)
-{
-    int ind;
-    uint64_t center_frequency_khz;
-    uint64_t center_freq_diff_khz;
-    uint64_t dl_freq_khz = downlink_frequency/1000;
-
-    center_freq_diff_khz = 999999999999999999; // 2^64
-    *current_band = 0;
-
-    for ( ind=0;
-          ind < sizeof(nr_bandtable) / sizeof(nr_bandtable[0]);
-          ind++) {
 
-      LOG_I(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min,nr_bandtable[ind].ul_min);
+uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb) {
 
-      if ( nr_bandtable[ind].dl_min <= dl_freq_khz && nr_bandtable[ind].dl_max >= dl_freq_khz ) {
+  switch (scs) {
+    case NR_SubcarrierSpacing_kHz15:
+      return symbol_ssb_AC[i_ssb];  //type A
+    case NR_SubcarrierSpacing_kHz30:
+      if (band == 5 || band == 66)
+        return symbol_ssb_BD[i_ssb];  //type B
+      else
+        return symbol_ssb_AC[i_ssb];  //type C
+    case NR_SubcarrierSpacing_kHz120:
+      return symbol_ssb_BD[i_ssb];  //type D
+    case NR_SubcarrierSpacing_kHz240:
+      return symbol_ssb_E[i_ssb];
+    default:
+      AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n",scs);
+  }
+}
 
-        center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min)/2;
-        if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){
-          *current_band = nr_bandtable[ind].band;
-	  *current_offset = (nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min)*1000;
-          center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz);
 
-	  if (*current_offset == 0)
-	    *current_type = TDD;
-	  else
-	    *current_type = FDD;
-        }
-      }
+void csi_period_offset(NR_CSI_ReportConfig_t *csirep,
+                       NR_NZP_CSI_RS_Resource_t *nzpcsi,
+                       int *period, int *offset) {
+
+  if(nzpcsi != NULL) {
+
+    NR_CSI_ResourcePeriodicityAndOffset_PR p_and_o = nzpcsi->periodicityAndOffset->present;
+
+    switch(p_and_o){
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots4:
+        *period = 4;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots4;
+        break;
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots5:
+        *period = 5;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots5;
+        break;
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots8:
+        *period = 8;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots8;
+        break;
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots10:
+        *period = 10;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots10;
+        break;
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots16:
+        *period = 16;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots16;
+        break;
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots20:
+        *period = 20;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots20;
+        break;
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots32:
+        *period = 32;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots32;
+        break;
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots40:
+        *period = 40;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots40;
+        break;
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots64:
+        *period = 64;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots64;
+        break;
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots80:
+        *period = 80;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots80;
+        break;
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots160:
+        *period = 160;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots160;
+        break;
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots320:
+        *period = 320;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots320;
+        break;
+      case NR_CSI_ResourcePeriodicityAndOffset_PR_slots640:
+        *period = 640;
+        *offset = nzpcsi->periodicityAndOffset->choice.slots640;
+        break;
+    default:
+      AssertFatal(1==0,"No periodicity and offset found in CSI resource");
     }
 
-    LOG_I( PHY, "DL frequency %"PRIu64": band %d, frame_type %d, UL frequency %"PRIu64"\n",
-         downlink_frequency, *current_band, *current_type, downlink_frequency+*current_offset);
+  }
 
-    AssertFatal(*current_band != 0,
-	    "Can't find EUTRA band for frequency %lu\n", downlink_frequency);
+  if(csirep != NULL) {
+
+    NR_CSI_ReportPeriodicityAndOffset_PR p_and_o = csirep->reportConfigType.choice.periodic->reportSlotConfig.present;
+
+    switch(p_and_o){
+      case NR_CSI_ReportPeriodicityAndOffset_PR_slots4:
+        *period = 4;
+        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots4;
+        break;
+      case NR_CSI_ReportPeriodicityAndOffset_PR_slots5:
+        *period = 5;
+        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots5;
+        break;
+      case NR_CSI_ReportPeriodicityAndOffset_PR_slots8:
+        *period = 8;
+        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots8;
+        break;
+      case NR_CSI_ReportPeriodicityAndOffset_PR_slots10:
+        *period = 10;
+        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots10;
+        break;
+      case NR_CSI_ReportPeriodicityAndOffset_PR_slots16:
+        *period = 16;
+        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots16;
+        break;
+      case NR_CSI_ReportPeriodicityAndOffset_PR_slots20:
+        *period = 20;
+        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots20;
+        break;
+      case NR_CSI_ReportPeriodicityAndOffset_PR_slots40:
+        *period = 40;
+        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots40;
+        break;
+      case NR_CSI_ReportPeriodicityAndOffset_PR_slots80:
+        *period = 80;
+        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots80;
+        break;
+      case NR_CSI_ReportPeriodicityAndOffset_PR_slots160:
+        *period = 160;
+        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots160;
+        break;
+      case NR_CSI_ReportPeriodicityAndOffset_PR_slots320:
+        *period = 320;
+        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320;
+        break;
+    default:
+      AssertFatal(1==0,"No periodicity and offset resource found in CSI report");
+    }
+  }
 }
 
 
-uint32_t get_ssb_slot(uint32_t ssb_index){
-  //  this function now only support f <= 3GHz
-  return ssb_index & 0x3 ;
-
-  //  return first_symbol(case, freq, ssb_index) / 14
-}
-
-int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
-                                          NR_MIB_t *mib,
-                                          uint8_t extra_bits,
-                                          uint32_t ssb_length,
-                                          uint32_t ssb_index,
-                                          uint32_t ssb_offset_point_a) {
+void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
+                                           frame_t frameP,
+                                           NR_MIB_t *mib,
+                                           uint8_t num_slot_per_frame,
+                                           uint8_t ssb_subcarrier_offset,
+                                           uint16_t ssb_start_symbol,
+                                           NR_SubcarrierSpacing_t scs_ssb,
+                                           frequency_range_t frequency_range,
+                                           uint32_t ssb_index,
+                                           uint32_t ssb_offset_point_a) {
 
-  //  deafult for testing
-  subcarrier_spacing_t scs_ssb = scs_30kHz;
-  channel_bandwidth_t min_channel_bw = bw_10MHz;
-  frequency_range_t frequency_range = FR1;
-  const uint32_t num_slot_per_frame = 20;
+  NR_SubcarrierSpacing_t scs_pdcch;
 
-  type0_PDCCH_CSS_config->ssb_length = ssb_length;
-  type0_PDCCH_CSS_config->ssb_index = ssb_index;
-  type0_PDCCH_CSS_config->frame = (mib->systemFrameNumber.buf[0] >> mib->systemFrameNumber.bits_unused);
+  channel_bandwidth_t min_channel_bw = bw_10MHz; // TODO remove hardcoding and implement Table 5.3.5-1 in 38.104
 
-  uint16_t frame_number_4lsb = 0;
-  for (int i=0; i<4; i++) {
-    frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i);
+  if (frequency_range == FR2) {
+    if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60)
+      scs_pdcch = NR_SubcarrierSpacing_kHz60;
+    else
+      scs_pdcch = NR_SubcarrierSpacing_kHz120;
   }
-
-  uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1;    //	extra bits[5]
-  uint8_t ssb_subcarrier_offset = (uint8_t)mib->ssb_SubcarrierOffset;
-
-  type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame << 4;
-  type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame | frame_number_4lsb;
-
-  if(type0_PDCCH_CSS_config->ssb_length == 64){
-    type0_PDCCH_CSS_config->ssb_index = type0_PDCCH_CSS_config->ssb_index & (( extra_bits >> 2 ) & 0x1C );    //	{ extra_bits[5:7], ssb_index[2:0] }
-  }else{
-    if(ssb_subcarrier_offset_msb){
-      ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
-    }
+  else {
+    frequency_range = FR1;
+    if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60)
+      scs_pdcch = NR_SubcarrierSpacing_kHz15;
+    else
+      scs_pdcch = NR_SubcarrierSpacing_kHz30;
   }
 
-  //  assume carrier frequency < 6GHz
-  subcarrier_spacing_t scs_pdcch;
-  if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60){
-    scs_pdcch = scs_15kHz;
-  }else{  //NR_MIB__subCarrierSpacingCommon_scs30or120
-    scs_pdcch = scs_30kHz;
-  }
+  type0_PDCCH_CSS_config->ssb_index = ssb_index;
+  type0_PDCCH_CSS_config->frame = frameP;
+
+  uint8_t ssb_slot = ssb_start_symbol/14;
 
   uint32_t is_condition_A = (ssb_subcarrier_offset == 0);   //  38.213 ch.13
   uint32_t index_4msb = (mib->pdcch_ConfigSIB1.controlResourceSetZero);
@@ -3170,8 +3416,8 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
   type0_PDCCH_CSS_config->rb_offset = -1;
 
   //  type0-pdcch coreset
-  switch( (scs_ssb << 5) | scs_pdcch ){
-    case (scs_15kHz << 5) | scs_15kHz :
+  switch( (scs_ssb << 3) | scs_pdcch ){
+    case (NR_SubcarrierSpacing_kHz15 << 5) | NR_SubcarrierSpacing_kHz15:
       AssertFatal(index_4msb < 15, "38.213 Table 13-1 4 MSB out of range\n");
       type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
       type0_PDCCH_CSS_config->num_rbs     = table_38213_13_1_c2[index_4msb];
@@ -3179,7 +3425,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
       type0_PDCCH_CSS_config->rb_offset   = table_38213_13_1_c4[index_4msb];
       break;
 
-    case (scs_15kHz << 5) | scs_30kHz:
+    case (NR_SubcarrierSpacing_kHz15 << 3) | NR_SubcarrierSpacing_kHz30:
       AssertFatal(index_4msb < 14, "38.213 Table 13-2 4 MSB out of range\n");
       type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
       type0_PDCCH_CSS_config->num_rbs     = table_38213_13_2_c2[index_4msb];
@@ -3187,7 +3433,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
       type0_PDCCH_CSS_config->rb_offset   = table_38213_13_2_c4[index_4msb];
       break;
 
-    case (scs_30kHz << 5) | scs_15kHz:
+    case (NR_SubcarrierSpacing_kHz30 << 3) | NR_SubcarrierSpacing_kHz15:
       if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
         AssertFatal(index_4msb < 9, "38.213 Table 13-3 4 MSB out of range\n");
         type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
@@ -3204,7 +3450,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
 
       break;
 
-    case (scs_30kHz << 5) | scs_30kHz:
+    case (NR_SubcarrierSpacing_kHz30 << 3) | NR_SubcarrierSpacing_kHz30:
       if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
         type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
         type0_PDCCH_CSS_config->num_rbs     = table_38213_13_4_c2[index_4msb];
@@ -3220,7 +3466,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
       }else{ ; }
       break;
 
-    case (scs_120kHz << 5) | scs_60kHz:
+    case (NR_SubcarrierSpacing_kHz120 << 3) | NR_SubcarrierSpacing_kHz60:
       AssertFatal(index_4msb < 12, "38.213 Table 13-7 4 MSB out of range\n");
       if(index_4msb & 0x7){
         type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
@@ -3237,7 +3483,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
       }
       break;
 
-    case (scs_120kHz << 5) | scs_120kHz:
+    case (NR_SubcarrierSpacing_kHz120 << 3) | NR_SubcarrierSpacing_kHz120:
       AssertFatal(index_4msb < 8, "38.213 Table 13-8 4 MSB out of range\n");
       if(index_4msb & 0x3){
         type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
@@ -3254,7 +3500,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
       }
       break;
 
-    case (scs_240kHz << 5) | scs_60kHz:
+    case (NR_SubcarrierSpacing_kHz240 << 3) | NR_SubcarrierSpacing_kHz60:
       AssertFatal(index_4msb < 4, "38.213 Table 13-9 4 MSB out of range\n");
       type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
       type0_PDCCH_CSS_config->num_rbs     = table_38213_13_9_c2[index_4msb];
@@ -3262,7 +3508,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
       type0_PDCCH_CSS_config->rb_offset   = table_38213_13_9_c4[index_4msb];
       break;
 
-    case (scs_240kHz << 5) | scs_120kHz:
+    case (NR_SubcarrierSpacing_kHz240 << 3) | NR_SubcarrierSpacing_kHz120:
       AssertFatal(index_4msb < 8, "38.213 Table 13-10 4 MSB out of range\n");
       if(index_4msb & 0x3){
         type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
@@ -3333,7 +3579,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
     type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb];
     big_m = table_38213_13_11_c3[index_4lsb];
 
-    uint32_t temp = (uint32_t)(big_o*scs_pdcch) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m);
+    uint32_t temp = (uint32_t)(big_o*(1<<scs_pdcch)) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m);
     type0_PDCCH_CSS_config->n_c = temp / num_slot_per_frame;
     if((temp/num_slot_per_frame) & 0x1){
       type0_PDCCH_CSS_config->sfn_c = SFN_C_MOD_2_EQ_1;
@@ -3369,12 +3615,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
   /// MUX PATTERN 2
   if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 2){
 
-    if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_60kHz)){
+    if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz60)){
       //  38.213 Table 13-13
       AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n");
       //  PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
       //                sfn_c = SFN_C_EQ_SFN_SSB;
-      type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index);
+      type0_PDCCH_CSS_config->n_c = ssb_slot;
       switch(type0_PDCCH_CSS_config->ssb_index & 0x3){    //  ssb_index(i) mod 4
         case 0:
           type0_PDCCH_CSS_config->first_symbol_index = 0;
@@ -3391,12 +3637,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
         default: break;
       }
 
-    }else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){
+    }else if((scs_ssb == NR_SubcarrierSpacing_kHz240) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)){
       //  38.213 Table 13-14
       AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n");
       //  PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
       //                sfn_c = SFN_C_EQ_SFN_SSB;
-      type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index);
+      type0_PDCCH_CSS_config->n_c = ssb_slot;
       switch(type0_PDCCH_CSS_config->ssb_index & 0x7){    //  ssb_index(i) mod 8
         case 0:
           type0_PDCCH_CSS_config->first_symbol_index = 0;
@@ -3412,11 +3658,11 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
           break;
         case 4:
           type0_PDCCH_CSS_config->first_symbol_index = 12;
-          type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index) - 1;
+          type0_PDCCH_CSS_config->n_c = ssb_slot - 1;
           break;
         case 5:
           type0_PDCCH_CSS_config->first_symbol_index = 13;
-          type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index) - 1;
+          type0_PDCCH_CSS_config->n_c = ssb_slot - 1;
           break;
         case 6:
           type0_PDCCH_CSS_config->first_symbol_index = 0;
@@ -3433,12 +3679,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
 
   /// MUX PATTERN 3
   if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 3){
-    if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_120kHz)){
+    if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)){
       //  38.213 Table 13-15
       AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n");
       //  PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
       //                sfn_c = SFN_C_EQ_SFN_SSB;
-      type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index);
+      type0_PDCCH_CSS_config->n_c = ssb_slot;
       switch(type0_PDCCH_CSS_config->ssb_index & 0x3){    //  ssb_index(i) mod 4
         case 0:
           type0_PDCCH_CSS_config->first_symbol_index = 4;
@@ -3475,8 +3721,220 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
   AssertFatal(type0_PDCCH_CSS_config->sfn_c!=SFN_C_IMPOSSIBLE,"");
   AssertFatal(type0_PDCCH_CSS_config->n_c!=UINT_MAX,"");
 
-  type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*scs_pdcch) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m))%num_slot_per_frame;
+  type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*(1<<scs_pdcch)) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m))%num_slot_per_frame;
   type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset;
 
-  return 0;
 }
+
+void find_period_offest_SR (NR_SchedulingRequestResourceConfig_t *SchedulingReqRec, int *period, int *offset) {
+  NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR P_O = SchedulingReqRec->periodicityAndOffset->present;
+  switch (P_O){
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl1:
+      *period = 1;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl1;
+      break;
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl2:
+      *period = 2;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl2;
+      break;
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl4:
+      *period = 4;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl4;
+      break;
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl5:
+      *period = 5;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl5;
+      break;
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl8:
+      *period = 8;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl8;
+      break;
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl10:
+      *period = 10;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl10;
+      break;
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl16:
+      *period = 16;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl16;
+      break;
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl20:
+      *period = 20;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl20;
+      break;
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40:
+      *period = 40;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl40;
+      break;
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl80:
+      *period = 80;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl80;
+      break;
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl160:
+      *period = 160;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl160;
+      break;
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl320:
+      *period = 320;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl320;
+      break;
+    case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl640:
+      *period = 640;
+      *offset = SchedulingReqRec->periodicityAndOffset->choice.sl640;
+      break;
+    default:
+      AssertFatal(1==0,"No periodicityAndOffset resources found in schedulingrequestresourceconfig");
+  }
+}
+
+uint16_t compute_pucch_prb_size(uint8_t format,
+                                uint8_t nr_prbs,
+                                uint16_t O_tot,
+                                uint16_t O_csi,
+                                NR_PUCCH_MaxCodeRate_t *maxCodeRate,
+                                uint8_t Qm,
+                                uint8_t n_symb,
+                                uint8_t n_re_ctrl) {
+
+  uint16_t O_crc;
+
+  if (O_tot<12)
+    O_crc = 0;
+  else{
+    if (O_tot<20)
+      O_crc = 6;
+    else {
+      if (O_tot<360)
+        O_crc = 11;
+      else
+        AssertFatal(1==0,"Case for segmented PUCCH not yet implemented");
+    }
+  }
+
+  int rtimes100;
+  switch(*maxCodeRate){
+    case NR_PUCCH_MaxCodeRate_zeroDot08 :
+      rtimes100 = 8;
+      break;
+    case NR_PUCCH_MaxCodeRate_zeroDot15 :
+      rtimes100 = 15;
+      break;
+    case NR_PUCCH_MaxCodeRate_zeroDot25 :
+      rtimes100 = 25;
+      break;
+    case NR_PUCCH_MaxCodeRate_zeroDot35 :
+      rtimes100 = 35;
+      break;
+    case NR_PUCCH_MaxCodeRate_zeroDot45 :
+      rtimes100 = 45;
+      break;
+    case NR_PUCCH_MaxCodeRate_zeroDot60 :
+      rtimes100 = 60;
+      break;
+    case NR_PUCCH_MaxCodeRate_zeroDot80 :
+      rtimes100 = 80;
+      break;
+  default :
+    AssertFatal(1==0,"Invalid MaxCodeRate");
+  }
+
+  float r = (float)rtimes100/100;
+
+  if (O_csi == O_tot) {
+    if ((O_tot+O_csi)>(nr_prbs*n_re_ctrl*n_symb*Qm*r))
+      AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with %d PRBs",
+                  r,O_tot,O_crc,nr_prbs);
+    else
+      return nr_prbs;
+  }
+
+  if (format==2){
+    // TODO fix this for multiple CSI reports
+    for (int i=1; i<=nr_prbs; i++){
+      if((O_tot+O_crc)<=(i*n_symb*Qm*n_re_ctrl*r) &&
+         (O_tot+O_crc)>((i-1)*n_symb*Qm*n_re_ctrl*r))
+        return i;
+    }
+    AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with at most %d PRBs",
+                r,O_tot,O_crc,nr_prbs);
+  }
+  else{
+    AssertFatal(1==0,"Not yet implemented");
+  }
+}
+
+
+/* extract UL PTRS values from RRC and validate it based upon 38.214 6.2.3 */
+bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config,
+                        uint16_t rbSize,uint8_t mcsIndex, uint8_t mcsTable,
+                        uint8_t *K_ptrs, uint8_t *L_ptrs,
+                        uint8_t *reOffset, uint8_t *maxNumPorts, uint8_t *ulPower,
+                        uint8_t NrOfSymbols)
+{
+  bool valid = true;
+
+  /* as defined in T 38.214 6.2.3 */
+  if(rbSize < 3) {
+    valid = false;
+    return valid;
+  }
+  /* Check for Frequency Density values */
+  if(ul_ptrs_config->transformPrecoderDisabled->frequencyDensity->list.count < 2) {
+    /* Default value for K_PTRS = 2 as defined in T 38.214 6.2.3 */
+    *K_ptrs = 2;
+  }
+  else {
+    *K_ptrs = get_K_ptrs(*ul_ptrs_config->transformPrecoderDisabled->frequencyDensity->list.array[0],
+                         *ul_ptrs_config->transformPrecoderDisabled->frequencyDensity->list.array[1],
+                         rbSize);
+  }
+  /* Check for time Density values */
+  if(ul_ptrs_config->transformPrecoderDisabled->timeDensity->list.count < 3) {
+    *L_ptrs = 0;
+  }
+  else {
+    *L_ptrs = get_L_ptrs(*ul_ptrs_config->transformPrecoderDisabled->timeDensity->list.array[0],
+                         *ul_ptrs_config->transformPrecoderDisabled->timeDensity->list.array[1],
+                         *ul_ptrs_config->transformPrecoderDisabled->timeDensity->list.array[2],
+                         mcsIndex,
+                         mcsTable);
+  }
+  
+  *reOffset  = *ul_ptrs_config->transformPrecoderDisabled->resourceElementOffset;
+  *maxNumPorts = ul_ptrs_config->transformPrecoderDisabled->maxNrofPorts;
+  *ulPower = ul_ptrs_config->transformPrecoderDisabled->ptrs_Power;
+  /* If either or both of the parameters PT-RS time density (LPT-RS) and PT-RS frequency density (KPT-RS), shown in Table
+   * 6.2.3.1-1 and Table 6.2.3.1-2, indicates that 'PT-RS not present', the UE shall assume that PT-RS is not present
+   */
+  if(*K_ptrs ==2  || *K_ptrs ==4 ) {
+    valid = true;
+  }
+  else {
+    valid = false;
+    return valid;
+  }
+  if(*L_ptrs ==0 || *L_ptrs ==1 || *L_ptrs ==2  ) {
+    valid = true;
+  }
+  else {
+    valid = false;
+    return valid;
+  }
+  /* PTRS is not present also :
+   * When the UE is receiving a PUSCH with allocation duration of 4 symbols and if LPT-RS is set to 4, the UE shall assume
+   * PT-RS is not transmitted
+   * When the UE is receiving a PUSCH with allocation duration of 2 symbols as defined in Clause 6.4.1.2.2 of [4, TS
+   * 38.211] and if LPT-RS is set to 2 or 4, the UE shall assume PT-RS is not transmitted.
+   */
+  if((NrOfSymbols == 4 && *L_ptrs ==2) || ((NrOfSymbols == 2 && *L_ptrs > 0))) {
+    valid = false;
+    return valid;
+  }
+
+  /* Moved below check from nr_ue_scheduler function to here */
+  if (*L_ptrs >= NrOfSymbols) {
+    valid = false;
+    return valid;
+  }
+  return valid;
+}
+
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index 087d316567eaeddac443631d74c476b6cb193399..9acde415efe32b7ed8f7796d75a3223b2a1c0eef 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -39,26 +39,26 @@
 
 uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
 
-void get_frame_type(uint16_t nr_bandP, uint8_t scs_index, lte_frame_type_t *current_type);
+lte_frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index);
 
-void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex);
+int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index);
 
 uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
 
 uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw);
 
-int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols);
+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);
+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,
@@ -81,7 +81,7 @@ int get_nr_prach_info_from_index(uint8_t index,
                                  uint8_t *N_dur,
                                  uint16_t *RA_sfn_index,
                                  uint8_t *N_RA_slot,
-																 uint8_t *config_period);
+                                 uint8_t *config_period);
 
 int get_nr_prach_occasion_info_from_index(uint8_t index,
                                  uint32_t pointa,
@@ -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);
 
@@ -121,28 +121,56 @@ uint16_t get_NCS(uint8_t index, uint16_t format, uint8_t restricted_set_config);
 
 int get_num_dmrs(uint16_t dmrs_mask );
 uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position);
-int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength);
+int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength, uint8_t start_symbolt, uint8_t dmrs_typeA_position);
 
 uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
 uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
 
-int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
-                                          NR_MIB_t *mib,
-                                          uint8_t extra_bits,
-                                          uint32_t ssb_length,
-                                          uint32_t ssb_index,
-                                          uint32_t ssb_offset_point_a);
+void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
+                                           frame_t frameP,
+                                           NR_MIB_t *mib,
+                                           uint8_t num_slot_per_frame,
+                                           uint8_t ssb_subcarrier_offset,
+                                           uint16_t ssb_start_symbol,
+                                           NR_SubcarrierSpacing_t scs_ssb,
+                                           frequency_range_t frequency_range,
+                                           uint32_t ssb_index,
+                                           uint32_t ssb_offset_point_a);
+
+uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb);
+
+uint16_t compute_pucch_prb_size(uint8_t format,
+                                uint8_t nr_prbs,
+                                uint16_t O_tot,
+                                uint16_t O_csi,
+                                NR_PUCCH_MaxCodeRate_t *maxCodeRate,
+                                uint8_t Qm,
+                                uint8_t n_symb,
+                                uint8_t n_re_ctrl);
 
 int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH);
 
+void find_period_offest_SR (NR_SchedulingRequestResourceConfig_t *SchedulingReqRec, int *period, int *offset);
+
+void csi_period_offset(NR_CSI_ReportConfig_t *csirep,
+                       NR_NZP_CSI_RS_Resource_t *nzpcsi,
+                       int *period, int *offset);
+
+void reverse_n_bits(uint8_t *value, uint16_t bitlen);
+
 bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
                         uint16_t rbSize, uint8_t mcsIndex, uint8_t mcsTable,
                         uint8_t *K_ptrs, uint8_t *L_ptrs,uint8_t *portIndex,
                         uint8_t *nERatio,uint8_t *reOffset,
                         uint8_t NrOfSymbols);
-void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type);
 
-uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols);
+bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config,
+                        uint16_t rbSize,uint8_t mcsIndex, uint8_t mcsTable,
+                        uint8_t *K_ptrs, uint8_t *L_ptrs,
+                        uint8_t *reOffset, uint8_t *maxNumPorts, uint8_t *ulPower,
+                        uint8_t NrOfSymbols);
+
+uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols,int startSymbol,int mappingtype);
 
 /* \brief Set the transform precoding according to 6.1.3 of 3GPP TS 38.214 version 16.3.0 Release 16
 @param    *pusch_config,   pointer to pusch config
@@ -151,11 +179,16 @@ 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,
                                int rnti_type,
                                uint8_t configuredGrant);
 
+void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP,
+                            const int CC_idP,
+                            const frame_t frameP,
+                            const sub_frame_t subframeP,
+                            const rnti_t rntiP) ;
 #endif
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h
index 8f7a726bb8f94dc29b3c17a12f439ba292ee773d..1b3e5e5d602dbb680e61e8a1584f84440eb56543 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h
@@ -56,7 +56,6 @@ extern unsigned char NB_UE_INST;*/
 extern unsigned char NB_INST;
 extern unsigned char NB_eNB_INST;
 extern unsigned char NB_RN_INST;
-extern unsigned short NODE_ID[1];
 
 /* Scheduler */
 extern RAN_CONTEXT_t RC;
@@ -139,4 +138,13 @@ extern const float   table_38213_13_12_c3[16];
 
 extern const int32_t table_38213_10_1_1_c2[5];
 
+extern const uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[16][3];
+extern const uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[16][3];
+extern const uint8_t table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP_dmrs_typeA_pos2[16][3];
+extern const uint8_t table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP_dmrs_typeA_pos3[16][3];
+extern const uint8_t table_5_1_2_1_1_4_time_dom_res_alloc_B_dmrs_typeA_pos2[16][3];
+extern const uint8_t table_5_1_2_1_1_4_time_dom_res_alloc_B_dmrs_typeA_pos3[16][3];
+extern const uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C_dmrs_typeA_pos2[16][3];
+extern const uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C_dmrs_typeA_pos3[16][3];
+
 #endif //DEF_H
diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c
index f6bd5436bc239fd132054f066ba9e762be47058d..3f08b709303a1b5b02274252f5e5a2b270c99567 100755
--- a/openair2/LAYER2/NR_MAC_UE/config_ue.c
+++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c
@@ -31,9 +31,13 @@
  */
 
 //#include "mac_defs.h"
+#include <NR_MAC_gNB/mac_proto.h>
 #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>
+
+extern uint32_t N_RB_DL;
 
 int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
                          int mu,
@@ -147,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;
@@ -155,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;
@@ -174,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;
@@ -200,69 +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;
  
-  lte_frame_type_t frame_type;
-  get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type);
+  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.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)
@@ -274,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;
@@ -300,34 +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;
-
-    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,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){
 
@@ -362,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
@@ -371,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 == 1, "downlinkBWP_ToAddModList->list->count is %d\n", scd->downlinkBWP_ToAddModList->list.count);
 
@@ -443,65 +668,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);
 
 }
 
@@ -510,10 +677,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;
@@ -521,23 +689,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) {
-        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);
+      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 = scell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
+	      mac->physCellId = *mac->scc->physCellId;
+        config_common_ue(mac,module_id,cc_idP);
+        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 dd0aa15c52a0c40b3236db207d70ddcb424faa1e..f5953e7845d1cb8d6395bc1e72c01dcf27b18c5b 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -234,9 +234,12 @@ typedef struct {
 
 typedef enum {
   RA_UE_IDLE = 0,
-  WAIT_RAR = 1,
-  WAIT_CONTENTION_RESOLUTION = 2,
-  RA_SUCCEEDED = 3
+  GENERATE_IDLE = 0,
+  GENERATE_PREAMBLE = 1,
+  WAIT_RAR = 2,
+  WAIT_CONTENTION_RESOLUTION = 3,
+  RA_SUCCEEDED = 4,
+  RA_FAILED = 5
 } RA_state_t;
 
 typedef struct {
@@ -257,8 +260,10 @@ typedef struct {
   uint8_t RA_attempt_number;
   /// Random-access procedure flag
   uint8_t RA_active;
+  /// Random-access preamble index
+  int ra_PreambleIndex;
   /// Flag for the Msg1 generation: enabled at every occurrence of nr prach slot
-  uint8_t generate_nr_prach;
+  RA_state_t generate_nr_prach;
 
   /// Random-access window counter
   int16_t RA_window_cnt;
@@ -289,12 +294,28 @@ typedef struct {
   uint8_t RA_contention_resolution_timer_active;
   /// Random-access Contention Resolution Timer count value
   uint8_t RA_contention_resolution_cnt;
+  /// Transmitted UE Contention Resolution Identifier
+  uint8_t cont_res_id[6];
 
   /// BeamfailurerecoveryConfig
   NR_BeamFailureRecoveryConfig_t RA_BeamFailureRecoveryConfig;
 
 } RA_config_t;
 
+typedef struct {
+  bool active;
+  bool ack_received;
+  uint8_t  pucch_resource_indicator;
+  uint16_t feedback_to_ul;
+  frame_t dl_frame;
+  int dl_slot;
+  uint8_t ack;
+  uint8_t dai;
+  int n_CCE;
+  int N_CCE;
+  int8_t delta_pucch;
+} NR_UE_HARQ_STATUS_t;
+
 typedef struct {
 
   uint8_t freq_hopping;
@@ -304,27 +325,48 @@ typedef struct {
 
 } RAR_grant_t;
 
+typedef struct {
+  int n_HARQ_ACK;
+  uint32_t ack_payload;
+  uint8_t sr_payload;
+  uint32_t csi_part1_payload;
+  uint32_t csi_part2_payload;
+  int resource_indicator;
+  int resource_set_id;
+  int initial_pucch_id;
+  NR_PUCCH_Resource_t *pucch_resource;
+  int n_CCE;
+  int N_CCE;
+  int8_t delta_pucch;
+} PUCCH_sched_t;
+
+
 /*!\brief Top level UE MAC structure */
 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;
   NR_TAG_Config_t                 *tag_Config;
   NR_PHR_Config_t                 *phr_Config;
   NR_RNTI_Value_t                 *cs_RNTI;
-  NR_MIB_t                         *mib;
+  NR_MIB_t                        *mib;
 
   NR_BWP_Downlink_t               *DLbwp[MAX_NUM_BWP];
   NR_BWP_Uplink_t                 *ULbwp[MAX_NUM_BWP];
   NR_ControlResourceSet_t         *coreset[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP];
   NR_SearchSpace_t                *SSpace[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP][FAPI_NR_MAX_SS_PER_CORESET];
 
+  lte_frame_type_t frame_type;
+
   /*BWP*/
   // dedicated active DL BWP
   NR_BWP_Id_t DL_BWP_Id;
@@ -350,9 +392,13 @@ typedef struct {
   RA_config_t ra;
   /// SSB index from MIB decoding
   uint8_t mib_ssb;
+  /// measured SSB RSRP in dBm
+  short ssb_rsrp_dBm;
+
   /// 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;
@@ -371,6 +417,11 @@ 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];
+
+  NR_UE_HARQ_STATUS_t dl_harq_info[16];
 
 } NR_UE_MAC_INST_t;
 
@@ -491,5 +542,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 c4909c138455b835b05cf8b92597a1b8c61b0949..dac62cf9a6f9b02cb2b4d108d4c5a15a78ec68a2 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -37,6 +37,9 @@
 #include "PHY/defs_nr_UE.h"
 #include "RRC/NR_UE/rrc_defs.h"
 
+#define NR_DL_MAX_DAI                            (4)                      /* TS 38.213 table 9.1.3-1 Value of counter DAI for DCI format 1_0 and 1_1 */
+#define NR_DL_MAX_NB_CW                          (2)                      /* number of downlink code word */
+
 /**\brief decode mib pdu in NR_UE, from if_module ul_ind with P7 tx_ind message
    \param module_id      module id
    \param cc_id          component carrier id
@@ -53,22 +56,23 @@ 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 pdu in NR_UE, from if_module dl_ind
+/**\brief decode SIB1 and other SIs pdus in NR_UE, from if_module dl_ind
    \param module_id      module id
    \param cc_id          component carrier id
    \param gNB_index      gNB index
    \param sibs_mask      sibs mask
    \param pduP           pointer to pdu
    \param pdu_length     length of pdu */
-int8_t nr_ue_decode_sib1(module_id_t module_id,
-                         int cc_id,
-                         unsigned int gNB_index,
-                         uint32_t sibs_mask,
-                         uint8_t *pduP,
-                         uint32_t pdu_len);
+int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id,
+                                int cc_id,
+                                unsigned int gNB_index,
+                                uint8_t ack_nack,
+                                uint8_t *pduP,
+                                uint32_t pdu_len);
 
 /**\brief primitive from RRC layer to MAC layer for configuration L1/L2, now supported 4 rrc messages: MIB, cell_group_config for MAC/PHY, spcell_config(serving cell config)
    \param module_id                 module id
@@ -82,8 +86,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);
@@ -119,25 +125,35 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
                              int slot,
                              int thread_id);
 
-/* \brief Get SR payload (0,1) from UE MAC
-@param Mod_id Instance id of UE in machine
-@param CC_id Component Carrier index
-@param eNB_id Index of eNB that UE is attached to
-@param rnti C_RNTI of UE
-@param subframe subframe number
-@returns 0 for no SR, 1 for SR
-*/
-uint32_t ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP,
-       uint8_t eNB_id, rnti_t rnti, sub_frame_t subframe);
-
-int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe);
+int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, int slotP);
 
-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);
+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, fapi_nr_dci_indication_pdu_t *dci_ind);
 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);
 
 uint32_t get_ssb_frame(uint32_t test);
 
-uint32_t mr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe);
+bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac,
+                                         PUCCH_sched_t *pucch,
+                                         frame_t frame,
+                                         int slot);
+
+uint8_t nr_get_csi_measurements(NR_UE_MAC_INST_t *mac,
+                                frame_t frame,
+                                int slot,
+                                PUCCH_sched_t *pucch);
+
+uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
+                             PUCCH_sched_t *pucch,
+                             struct NR_CSI_ReportConfig *csi_reportconfig,
+                             NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
+                             NR_CSI_MeasConfig_t *csi_MeasConfig);
+
+uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
+                           PUCCH_sched_t *pucch,
+                           NR_CSI_MeasConfig_t *csi_MeasConfig);
+
+uint8_t get_rsrp_index(int rsrp);
+uint8_t get_rsrp_diff_index(int best_rsrp,int current_rsrp);
 
 /* \brief Get payload (MAC PDU) from UE PHY
 @param dl_info            pointer to dl indication
@@ -166,6 +182,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,
@@ -178,7 +198,8 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
 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);
+                                                      uint8_t time_domain_ind,
+                                                      bool use_default);
 
 uint8_t
 nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
@@ -189,6 +210,58 @@ int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, int mu,
                          int nrofDownlinkSlots, int nrofDownlinkSymbols,
                          int nrofUplinkSlots,   int nrofUplinkSymbols);
 
+void set_harq_status(NR_UE_MAC_INST_t *mac,
+                     uint8_t pucch_id,
+                     uint8_t harq_id,
+                     int8_t delta_pucch,
+                     uint8_t data_toul_fb,
+                     uint8_t dai,
+                     int n_CCE,
+                     int N_CCE,
+                     frame_t frame,
+                     int slot);
+
+void update_harq_status(nr_downlink_indication_t *dl_info,
+                        int pdu_id);
+
+uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac,
+                         frame_t frame,
+                         int slot,
+                         PUCCH_sched_t *pucch);
+
+int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, int uci_size);
+
+void select_pucch_resource(NR_UE_MAC_INST_t *mac,
+                           PUCCH_sched_t *pucch);
+
+int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
+                              NR_PUCCH_Config_t *pucch_Config,
+                              PUCCH_sched_t *pucch,
+                              uint8_t format_type,
+                              uint16_t nb_of_prbs,
+                              uint8_t  freq_hop_flag,
+                              uint8_t  add_dmrs_flag,
+                              uint8_t N_symb_PUCCH,
+                              int subframe_number,
+                              int O_ACK, int O_SR,
+                              int O_CSI, int O_CRC);
+
+int get_deltatf(uint16_t nb_of_prbs,
+                uint8_t N_symb_PUCCH,
+                uint8_t freq_hop_flag,
+                uint8_t add_dmrs_flag,
+                int N_sc_ctrl_RB,
+                int n_HARQ_ACK,
+                int O_ACK, int O_SR,
+                int O_CSI, int O_CRC);
+
+void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
+                           int slot,
+                           uint16_t rnti,
+                           PUCCH_sched_t *pucch,
+                           fapi_nr_ul_config_pucch_pdu *pucch_pdu,
+                           int O_SR, int O_ACK, int O_CSI);
+
 /** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure.
     @param Mod_id Module id of UE
     @returns Po_NOMINAL_PUSCH (PREAMBLE_RECEIVED_TARGET_POWER+DELTA_PREAMBLE
@@ -218,6 +291,7 @@ and fills the PRACH PDU per each FD occasion.
 @returns void
 */
 void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, int thread_id);
+void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, int thread_id);
 
 /* \brief This function schedules the Msg3 transmission
 @param
@@ -300,7 +374,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/mac_vars.c b/openair2/LAYER2/NR_MAC_UE/mac_vars.c
index ecabdb870c7399667b1c1c57477f4585260e5025..383267090f553b052db2ff2ced66f556edbb4cab 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_vars.c
+++ b/openair2/LAYER2/NR_MAC_UE/mac_vars.c
@@ -32,7 +32,7 @@
 
 #include <stdint.h>
 
-const char *rnti_types[]={"RNTI_new", "RNTI_C", "RNTI_RA", "NR_RNTI_P", "NR_RNTI_CS", "NR_RNTI_TC"};
+const char *rnti_types[]={"RNTI_new", "RNTI_C", "RNTI_RA", "NR_RNTI_P", "NR_RNTI_CS", "NR_RNTI_TC", "NR_RNTI_SP_CSI", "NR_RNTI_SI"};
 const char *dci_formats[]={"1_0", "1_1", "2_0", "2_1", "2_2", "2_3", "0_0", "0_1"};
 
 // table_7_3_1_1_2_2_3_4_5 contains values for number of layers and precoding information for tables 7.3.1.1.2-2/3/4/5 from TS 38.212 subclause 7.3.1.1.2
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 27623fe5bece64e6cfbc07adab1ce7ba5aa3c0f8..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,18 +146,11 @@ 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, delta_preamble;
-  long preambleReceivedTargetPower = 0;
-
-  if (prach_resources->RA_TYPE == RA_4STEP){
-    NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
-    preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower;
-  } else if (prach_resources->RA_TYPE == RA_2STEP){
-    // msgA-PreambleReceivedTargetPower
-    LOG_E(MAC, "In %s:%d: missing implementation for 2-step RA...\n", __FUNCTION__, __LINE__);
-  }
+  int8_t receivedTargerPower;
+  int8_t delta_preamble;
 
+  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);
 
   receivedTargerPower = preambleReceivedTargetPower + delta_preamble + (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP + prach_resources->POWER_OFFSET_2STEP_RA;
@@ -211,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;
@@ -230,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);
 
@@ -262,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 b4b63e0064721a1a89fb714883e6186f5020e0be..5d9126ad6954ac6207551b15e790da7030ffe0f8 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
@@ -35,6 +35,7 @@
 
 /* RRC */
 #include "NR_RACH-ConfigCommon.h"
+#include "RRC/NR_UE/rrc_proto.h"
 
 /* PHY */
 #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
@@ -47,6 +48,8 @@
 #include "NR_MAC_COMMON/nr_mac.h"
 #include "LAYER2/NR_MAC_UE/mac_proto.h"
 
+#include <executables/softmodem-common.h>
+
 void nr_get_RA_window(NR_UE_MAC_INST_t *mac);
 
 // Random Access procedure initialization as per 5.1.1 and initialization of variables specific
@@ -63,6 +66,8 @@ void init_RA(module_id_t mod_id,
 
   RA_config_t *ra          = &mac->ra;
   ra->RA_active            = 1;
+  ra->ra_PreambleIndex     = -1;
+  ra->RA_usedGroupA        = 1;
   ra->RA_RAPID_found       = 0;
   ra->preambleTransMax     = 0;
   ra->first_Msg3           = 1;
@@ -78,8 +83,8 @@ void init_RA(module_id_t mod_id,
 
   if (rach_ConfigDedicated) {
     if (rach_ConfigDedicated->cfra){
-      LOG_I(MAC, "Initialization of 4-step contention-free random access procedure\n");
-      prach_resources->RA_TYPE = RA_4STEP;
+      LOG_I(MAC, "Initialization of 2-step contention-free random access procedure\n");
+      prach_resources->RA_TYPE = RA_2STEP;
       ra->cfra = 1;
     } else if (rach_ConfigDedicated->ext1){
       if (rach_ConfigDedicated->ext1->cfra_TwoStep_r16){
@@ -92,185 +97,176 @@ void init_RA(module_id_t mod_id,
     } else {
       LOG_E(MAC, "In %s: config not handled\n", __FUNCTION__);
     }
+  } else if (nr_rach_ConfigCommon){
+    LOG_I(MAC, "Initialization of 4-step contention-based random access procedure\n");
+    prach_resources->RA_TYPE = RA_4STEP;
+    ra->cfra = 0;
   } else {
     LOG_E(MAC, "In %s: config not handled\n", __FUNCTION__);
   }
 
-  if (prach_resources->RA_TYPE == RA_2STEP){
-    LOG_E(MAC, "Missing implementation of initialization of 2-step RA specific variables...\n");
-  } else if (prach_resources->RA_TYPE == RA_4STEP){
-    LOG_D(MAC, "Initialization of 4-step RA specific variables...\n");
-    switch (rach_ConfigGeneric->powerRampingStep){ // in dB
-      case 0:
+  switch (rach_ConfigGeneric->powerRampingStep){ // in dB
+    case 0:
       prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 0;
       break;
-      case 1:
+    case 1:
       prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 2;
       break;
-      case 2:
+    case 2:
       prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 4;
       break;
-      case 3:
+    case 3:
       prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 6;
       break;
-    }
+  }
 
-    switch (rach_ConfigGeneric->preambleTransMax) {
-      case 0:
+  switch (rach_ConfigGeneric->preambleTransMax) {
+    case 0:
       ra->preambleTransMax = 3;
       break;
-      case 1:
+    case 1:
       ra->preambleTransMax = 4;
       break;
-      case 2:
+    case 2:
       ra->preambleTransMax = 5;
       break;
-      case 3:
+    case 3:
       ra->preambleTransMax = 6;
       break;
-      case 4:
+    case 4:
       ra->preambleTransMax = 7;
       break;
-      case 5:
+    case 5:
       ra->preambleTransMax = 8;
       break;
-      case 6:
+    case 6:
       ra->preambleTransMax = 10;
       break;
-      case 7:
+    case 7:
       ra->preambleTransMax = 20;
       break;
-      case 8:
+    case 8:
       ra->preambleTransMax = 50;
       break;
-      case 9:
+    case 9:
       ra->preambleTransMax = 100;
       break;
-      case 10:
+    case 10:
       ra->preambleTransMax = 200;
       break;
-    }
-    if (nr_rach_ConfigCommon->ext1) {
-      if (nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity){
-        LOG_D(MAC, "In %s:%d: Missing implementation for Access Identity initialization procedures\n", __FUNCTION__, __LINE__);
-      }
-    }
   }
 
-  return;
-
+  if (nr_rach_ConfigCommon->ext1) {
+    if (nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity){
+      LOG_D(MAC, "In %s:%d: Missing implementation for Access Identity initialization procedures\n", __FUNCTION__, __LINE__);
+    }
+  }
 }
 
 void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, fapi_nr_ul_config_prach_pdu *prach_pdu){
 
   // Determine the SSB to RACH mapping ratio
   // =======================================
-  if (prach_resources->RA_TYPE == RA_4STEP){
-    NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->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
-    uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB
-    int total_preambles_per_ssb;
-    uint8_t ssb_nb_in_ro;
-    int numberOfRA_Preambles = 64;
-
-    switch (ssb_perRACH_config){
-      case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth:
-        multiple_ssb_per_ro = false;
-        ssb_rach_ratio = 8;
-        ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1);
-        break;
-      case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth:
-        multiple_ssb_per_ro = false;
-        ssb_rach_ratio = 4;
-        ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1);
-        break;
-      case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf:
-        multiple_ssb_per_ro = false;
-        ssb_rach_ratio = 2;
-        ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1);
-        break;
-      case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one:
-        multiple_ssb_per_ro = true;
-        ssb_rach_ratio = 1;
-        ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1);
-        break;
-      case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two:
-        multiple_ssb_per_ro = true;
-        ssb_rach_ratio = 2;
-        ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1);
-        break;
-      case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four:
-        multiple_ssb_per_ro = true;
-        ssb_rach_ratio = 4;
-        ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four;
-        break;
-      case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight:
-        multiple_ssb_per_ro = true;
-        ssb_rach_ratio = 8;
-        ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight;
-        break;
-      case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen:
-        multiple_ssb_per_ro = true;
-        ssb_rach_ratio = 16;
-        ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen;
-        break;
-      default:
-        AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config);
-        break;
-    }
 
-    if (nr_rach_ConfigCommon->totalNumberOfRA_Preambles)
-      numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles);
+  NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->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
+  uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB
+  int total_preambles_per_ssb;
+  uint8_t ssb_nb_in_ro;
+  int numberOfRA_Preambles = 64;
+
+  switch (ssb_perRACH_config){
+    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth:
+      multiple_ssb_per_ro = false;
+      ssb_rach_ratio = 8;
+      ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1);
+      break;
+    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth:
+      multiple_ssb_per_ro = false;
+      ssb_rach_ratio = 4;
+      ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1);
+      break;
+    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf:
+      multiple_ssb_per_ro = false;
+      ssb_rach_ratio = 2;
+      ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1);
+      break;
+    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one:
+      multiple_ssb_per_ro = true;
+      ssb_rach_ratio = 1;
+      ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1);
+      break;
+    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two:
+      multiple_ssb_per_ro = true;
+      ssb_rach_ratio = 2;
+      ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1);
+      break;
+    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four:
+      multiple_ssb_per_ro = true;
+      ssb_rach_ratio = 4;
+      ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four;
+      break;
+    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight:
+      multiple_ssb_per_ro = true;
+      ssb_rach_ratio = 8;
+      ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight;
+      break;
+    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen:
+      multiple_ssb_per_ro = true;
+      ssb_rach_ratio = 16;
+      ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen;
+      break;
+    default:
+      AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config);
+  }
 
-    // Compute the proper Preamble selection params according to the selected SSB and the ssb_perRACH_OccasionAndCB_PreamblesPerSSB configuration
-    if ((true == multiple_ssb_per_ro) &&
-        (ssb_rach_ratio > 1)) {
-      total_preambles_per_ssb = numberOfRA_Preambles / ssb_rach_ratio;
+  if (nr_rach_ConfigCommon->totalNumberOfRA_Preambles)
+    numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles);
 
-      ssb_nb_in_ro = prach_pdu->ssb_nb_in_ro;
-      ra->starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro;
-    }
-    else {
-      total_preambles_per_ssb = numberOfRA_Preambles;
-      ra->starting_preamble_nb = 0;
-    }
+  // Compute the proper Preamble selection params according to the selected SSB and the ssb_perRACH_OccasionAndCB_PreamblesPerSSB configuration
+  if ((true == multiple_ssb_per_ro) && (ssb_rach_ratio > 1)) {
+    total_preambles_per_ssb = numberOfRA_Preambles / ssb_rach_ratio;
+
+    ssb_nb_in_ro = prach_pdu->ssb_nb_in_ro;
+    ra->starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro;
   } else {
-    LOG_E(MAC, "In %s:%d: missing implementation for 2-step RA...\n", __FUNCTION__, __LINE__);
+    total_preambles_per_ssb = numberOfRA_Preambles;
+    ra->starting_preamble_nb = 0;
   }
 }
 
-// This routine implements RA premable configuration according to
+// This routine implements RA preamble configuration according to
 // section 5.1 (Random Access procedure) of 3GPP TS 38.321 version 16.2.1 Release 16
 void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t *mac, int16_t dl_pathloss){
 
   int messageSizeGroupA = 0;
   int sizeOfRA_PreamblesGroupA = 0;
   int messagePowerOffsetGroupB = 0;
-  int PLThreshold;
+  int PLThreshold = 0;
   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;
-
-  if (prach_resources->RA_TYPE == RA_4STEP){
+  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
-      LOG_D(MAC, "In %s: deltaPreamble_Msg3 set to %ld\n", __FUNCTION__, deltaPreamble_Msg3);
-    }
+  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) {
-      noGroupB = 1;
-      LOG_D(MAC, "In %s:%d: preambles group B is not configured...\n", __FUNCTION__, __LINE__);
-    } else {
-      // RA preambles group B is configured 
-      // - 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){
+  if (!setup->groupBconfigured) {
+    noGroupB = 1;
+    LOG_D(MAC, "In %s:%d: preambles group B is not configured...\n", __FUNCTION__, __LINE__);
+  } else {
+    // RA preambles group B is configured
+    // - 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 = setup->groupBconfigured->numberOfRA_PreamblesGroupA;
+    switch (setup->groupBconfigured->ra_Msg3SizeGroupA){
       /* - Threshold to determine the groups of RA preambles */
       case 0:
       messageSizeGroupA = 56;
@@ -303,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;
@@ -335,45 +331,43 @@ 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;
+    PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
 
-    }
-  } else {
-    // todo:
-    // - groupB-ConfiguredTwoStepRA
-    // - msgA-DeltaPreamble
-    LOG_E(MAC, "In %s:%d: missing implementation for 2-step RA...\n", __FUNCTION__, __LINE__);
   }
+
   /* Msg3 has not been transmitted yet */
   if (ra->first_Msg3) {
-    if (noGroupB) {
-      // use Group A preamble
-      prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb);
-      ra->RA_usedGroupA = 1;
-    } else if ((ra->Msg3_size < messageSizeGroupA) && (dl_pathloss > PLThreshold)) {
-      // Group B is configured and RA preamble Group A is used
-      // - todo add condition on CCCH_sdu_size for initiation by CCCH
-      prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA);
-      ra->RA_usedGroupA = 1;
-    } else {
-      // Group B preamble is configured and used
-      // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
-      // the remaining belong to RA Preambles Group B
-      prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
-      ra->RA_usedGroupA = 0;
+    if(ra->ra_PreambleIndex < 0 || ra->ra_PreambleIndex > 63) {
+      if (noGroupB) {
+        // use Group A preamble
+        ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb);
+        ra->RA_usedGroupA = 1;
+      } else if ((ra->Msg3_size < messageSizeGroupA) && (dl_pathloss > PLThreshold)) {
+        // Group B is configured and RA preamble Group A is used
+        // - todo add condition on CCCH_sdu_size for initiation by CCCH
+        ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA);
+        ra->RA_usedGroupA = 1;
+      } else {
+        // Group B preamble is configured and used
+        // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
+        // the remaining belong to RA Preambles Group B
+        ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
+        ra->RA_usedGroupA = 0;
+      }
     }
   } else { // Msg3 is being retransmitted
     if (ra->RA_usedGroupA && noGroupB) {
-      prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb);
+      ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb);
     } else if (ra->RA_usedGroupA && !noGroupB){
-      prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA);
+      ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA);
     } else {
-      prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
+      ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
     }
   }
+  prach_resources->ra_PreambleIndex = ra->ra_PreambleIndex;
 }
 
 // RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted)
@@ -428,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);
 
@@ -463,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);
@@ -471,6 +470,7 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint
   // start contention resolution timer
   ra->RA_contention_resolution_cnt = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) * 8;
   ra->RA_contention_resolution_timer_active = 1;
+  ra->ra_state = WAIT_CONTENTION_RESOLUTION;
 
 }
 
@@ -502,69 +502,71 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
   NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
   RA_config_t *ra = &mac->ra;
   uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES];
-  uint8_t lcid = UL_SCH_LCID_CCCH_MSG3, *payload;
+  uint8_t lcid = UL_SCH_LCID_CCCH;
+  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;
 
   uint8_t sdu_lcids[NB_RB_MAX] = {0};
   uint16_t sdu_lengths[NB_RB_MAX] = {0};
-  int TBS_bytes = 848, header_length_total=0, num_sdus, offset, mac_ce_len;
+  int num_sdus = 0;
+  int offset = 0;
 
   // 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;
     }
   }
 
-  if (prach_resources->init_msg1) {
+  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;
 
-      payload = (uint8_t*) &mac->CCCH_pdu.payload;
-      mac_ce_len = 0;
       num_sdus = 1;
       post_padding = 1;
+      sdu_lcids[0] = lcid;
 
-      if (0){
-        // initialisation by RRC
-        // CCCH PDU
-        // size_sdu = (uint16_t) mac_rrc_data_req_ue(mod_id,
-        //                                           CC_id,
-        //                                           frame,
-        //                                           CCCH,
-        //                                           1,
-        //                                           mac_sdus,
-        //                                           gNB_id,
-        //                                           0);
-        LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu);
-      } else {
-        // fill ulsch_buffer with random data
-        for (int i = 0; i < TBS_bytes; i++){
-          mac_sdus[i] = (unsigned char) (lrand48()&0xff);
-        }
-        //Sending SDUs with size 1
-        //Initialize elements of sdu_lcids and sdu_lengths
-        sdu_lcids[0] = lcid;
-        sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len;
-        header_length_total += 2 + (sdu_lengths[0] >= 128);
-        size_sdu += sdu_lengths[0];
+      // initialisation by RRC
+
+      // TODO: To be removed after RA procedures fully implemented
+      if(get_softmodem_params()->do_ra) {
+        nr_rrc_ue_generate_RRCSetupRequest(mod_id,gNB_id);
       }
 
+      // CCCH PDU
+      size_sdu = (uint16_t) nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, mac_sdus);
+
+      sdu_lengths[0] = 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) {
 
-        LOG_D(MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx);
+        // UE Contention Resolution Identity
+        // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to determine whether or not the
+        // Random Access Procedure has been successful after reception of Msg4
+        memcpy(ra->cont_res_id, mac_sdus, sizeof(uint8_t) * 6);
+
+        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);
 
@@ -573,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 == 1)
+        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
@@ -589,12 +591,27 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
                                        post_padding,
                                        0);
 
+        AssertFatal(TBS_max > offset, "Frequency resources are not enough for Msg3!\n");
+
         // Padding: fill remainder with 0
         if (post_padding > 0){
-          for (int j = 0; j < (TBS_bytes - offset); j++)
-            payload[offset + j] = 0; // mac_pdu[offset + j] = 0;
+          for (int j = 0; j < (TBS_max - offset); j++)
+            payload[offset + j] = 0;
         }
-      } 
+      }
+
+      LOG_D(MAC,"size_sdu = %i\n", size_sdu);
+      LOG_D(MAC,"offset = %i\n", offset);
+      for(int k = 0; k < TBS_max; k++) {
+        LOG_D(MAC,"(%i): %i\n", k, prach_resources->Msg3[k]);
+      }
+
+      // Msg3 was initialized with TBS_max bytes because the RA_Msg3_size will only be known after
+      // receiving Msg2 (which contains the Msg3 resource reserve).
+      // Msg3 will be transmitted with RA_Msg3_size bytes, removing unnecessary 0s.
+      mac->ulsch_pdu.Pdu_size = TBS_max;
+      memcpy(mac->ulsch_pdu.payload, prach_resources->Msg3, TBS_max);
+
     } else if (ra->RA_window_cnt != -1) { // RACH is active
 
       LOG_D(MAC, "In %s [%d.%d] RA is active: RA window count %d, RA backoff count %d\n", __FUNCTION__, frame, nr_slot_tx, ra->RA_window_cnt, ra->RA_backoff_cnt);
@@ -606,9 +623,13 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
       }
 
       if (ra->RA_window_cnt >= 0 && ra->RA_RAPID_found == 1) {
-        // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
 
-        nr_ra_succeeded(mod_id, frame, nr_slot_tx);
+        if(ra->cfra) {
+          // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
+          nr_ra_succeeded(mod_id, frame, nr_slot_tx);
+        } else {
+          ra->generate_nr_prach = GENERATE_IDLE;
+        }
 
       } else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found) {
 
@@ -622,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 == 1) || 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);
         }
 
@@ -642,7 +664,12 @@ 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);
   }
 
-  return ra->generate_nr_prach;
+  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 {
+    return ra->ra_state;
+  }
 
 }
 
@@ -650,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
 
@@ -736,6 +767,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
     LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mod_id, frame, slot);
 
     ra->RA_window_cnt = -1;
+    mac->crnti = ra->t_crnti;
 
   } else {
 
@@ -743,6 +775,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
 
     ra->RA_contention_resolution_cnt = -1;
     ra->RA_contention_resolution_timer_active = 0;
+    mac->crnti = ra->t_crnti;
     ra->t_crnti = 0;
 
     LOG_D(MAC, "In %s: [UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", __FUNCTION__, mod_id, frame, slot);
@@ -751,50 +784,40 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
 
   LOG_D(MAC, "In %s: [UE %d] clearing RA_active flag...\n", __FUNCTION__, mod_id);
   ra->RA_active = 0;
-  ra->generate_nr_prach = 2;
+  ra->generate_nr_prach = GENERATE_IDLE;
   ra->ra_state = RA_SUCCEEDED;
 
 }
 
-// Handlig failure of RA procedure @ MAC layer
+// Handling failure of RA procedure @ MAC layer
 // according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16
 // todo:
 // - complete handling of received contention-based RA preamble
-// - 2-step RA implementation
 void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot) {
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
   RA_config_t *ra = &mac->ra;
 
-  ra->first_Msg3 = 0;
-  ra->generate_nr_prach = 3;
+  ra->first_Msg3 = 1;
+  ra->ra_PreambleIndex = -1;
+  ra->generate_nr_prach = RA_FAILED;
   ra->ra_state = RA_UE_IDLE;
 
   prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++;
 
-  if(prach_resources->RA_TYPE == RA_4STEP){
-
-    if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER == ra->preambleTransMax + 1){
+  if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER == ra->preambleTransMax + 1){
 
-      LOG_D(MAC, "In %s: [UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n", __FUNCTION__, mod_id, frame, slot, ra->preambleTransMax);
+    LOG_D(MAC, "In %s: [UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n",
+          __FUNCTION__, mod_id, frame, slot, ra->preambleTransMax);
 
-      ra->RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1);
-
-      prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
-      prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment
-      prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
-
-    } else {
-
-      // Resetting RA window
-      nr_get_RA_window(mac);
-
-    }
-
-  } else if (prach_resources->RA_TYPE == RA_2STEP){
-
-    LOG_E(MAC, "Missing implementation of RA failure handling for 2-step RA...\n");
+    ra->RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1);
+    prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
+    prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment
+    prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
 
+  } else {
+    // Resetting RA window
+    nr_get_RA_window(mac);
   }
 
 }
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 11edc6c20d26ef544dbc7e8bef284505dd88dfcb..8891d3354e0eb00be0d0ce33fc0fc5000a274ea6 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
@@ -47,9 +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
-
-dci_pdu_rel15_t *def_dci_pdu_rel15;
+//#define DEBUG_DCI
 
 void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
 
@@ -72,12 +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;
-  def_dci_pdu_rel15 = calloc(1,2*sizeof(dci_pdu_rel15_t));
-  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;
@@ -88,7 +96,11 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
   } else {
     ss = mac->search_space_zero;
     coreset = mac->coreset0;
-    rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
+    if(rnti_type == NR_RNTI_SI) {
+      rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
+    } else {
+      rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG_CSET_0;
+    }
   }
 
   rel15->coreset.duration = coreset->duration;
@@ -100,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;
@@ -115,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;
   }
 
@@ -127,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, def_dci_pdu_rel15+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:
@@ -144,21 +163,34 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
     monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
     rel15->rnti = ra->ra_rnti;
     rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); //NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
+    if (get_softmodem_params()->sa) {
+      rel15->BWPStart = NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    } else { // NSA mode is not using the Initial BWP
+      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, def_dci_pdu_rel15, 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;
     case NR_RNTI_CS:
     break;
     case NR_RNTI_TC:
+      // we use the initial DL BWP
+      sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12;
+      monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
+      rel15->rnti = ra->t_crnti;
+      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(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));
@@ -169,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, def_dci_pdu_rel15, 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:
@@ -211,159 +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 = 1, 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(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space\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_RA, ss_id);
-              fill_dci_search_candidates(ss, rel15);
-              break;
-              case WAIT_CONTENTION_RESOLUTION:
-              LOG_E(MAC, "In %s: CB-RA not implemented yet. Should not have fallen in this case.\n", __FUNCTION__);
-              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) ? 1 : 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;
@@ -377,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 64067e9d60df8b978b2885bf04c2bc7cb3468de5..1d18c8ef3e01e26387d60be6b4cb422f985b8094 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -62,10 +62,79 @@
 #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;
+
+/* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI in a PUCCH */
+/* this is a counter of number of pucch format 4 per subframe */
+static int nb_pucch_format_4_in_subframes[LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] = { 0 } ;
+
+/* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */
+static const int sequence_cyclic_shift_1_harq_ack_bit[2]
+/*        HARQ-ACK Value        0    1 */
+/* Sequence cyclic shift */ = { 0,   6 };
+
+/* TS 36.213 Table 9.2.5-1: Mapping of values for one HARQ-ACK bit and positive SR to sequences */
+static const int sequence_cyclic_shift_1_harq_ack_bit_positive_sr[2]
+/*        HARQ-ACK Value        0    1 */
+/* Sequence cyclic shift */ = { 3,   9 };
+
+/* TS 36.213 Table 9.2.5-2: Mapping of values for two HARQ-ACK bits and positive SR to sequences */
+static const int sequence_cyclic_shift_2_harq_ack_bits_positive_sr[4]
+/*        HARQ-ACK Value      (0,0)  (0,1)   (1,0)  (1,1) */
+/* Sequence cyclic shift */ = {  1,     4,     10,     7 };
+
+/* TS 38.213 Table 9.2.3-4: Mapping of values for two HARQ-ACK bits to sequences */
+static const int sequence_cyclic_shift_2_harq_ack_bits[4]
+/*        HARQ-ACK Value       (0,0)  (0,1)  (1,0)  (1,1) */
+/* Sequence cyclic shift */ = {   0,     3,     9,     6 };
+
+
+/* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */
+static const int nb_symbols_excluding_dmrs[11][2][2]
+= {
+/*                     No additional DMRS            Additional DMRS   */
+/* PUCCH length      No hopping   hopping         No hopping   hopping */
+/* index                  0          1                 0          1    */
+/*    4     */    {{      3    ,     2   }   ,  {      3     ,    2    }},
+/*    5     */    {{      3    ,     3   }   ,  {      3     ,    3    }},
+/*    6     */    {{      4    ,     4   }   ,  {      4     ,    4    }},
+/*    7     */    {{      5    ,     5   }   ,  {      5     ,    5    }},
+/*    8     */    {{      6    ,     6   }   ,  {      6     ,    6    }},
+/*    9     */    {{      7    ,     7   }   ,  {      7     ,    7    }},
+/*   10     */    {{      8    ,     8   }   ,  {      6     ,    6    }},
+/*   11     */    {{      9    ,     9   }   ,  {      7     ,    7    }},
+/*   12     */    {{     10    ,    10   }   ,  {      8     ,    8    }},
+/*   13     */    {{     11    ,    11   }   ,  {      9     ,    9    }},
+/*   14     */    {{     12    ,    12   }   ,  {     10     ,   10    }},
+};
+
+/* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */
+const initial_pucch_resource_t initial_pucch_resource[16] = {
+/*              format           first symbol     Number of symbols        PRB offset    nb index for       set of initial CS */
+/*  0  */ {  0,      12,                  2,                   0,            2,       {    0,   3,    0,    0  }   },
+/*  1  */ {  0,      12,                  2,                   0,            3,       {    0,   4,    8,    0  }   },
+/*  2  */ {  0,      12,                  2,                   3,            3,       {    0,   4,    8,    0  }   },
+/*  3  */ {  1,      10,                  4,                   0,            2,       {    0,   6,    0,    0  }   },
+/*  4  */ {  1,      10,                  4,                   0,            4,       {    0,   3,    6,    9  }   },
+/*  5  */ {  1,      10,                  4,                   2,            4,       {    0,   3,    6,    9  }   },
+/*  6  */ {  1,      10,                  4,                   4,            4,       {    0,   3,    6,    9  }   },
+/*  7  */ {  1,       4,                 10,                   0,            2,       {    0,   6,    0,    0  }   },
+/*  8  */ {  1,       4,                 10,                   0,            4,       {    0,   3,    6,    9  }   },
+/*  9  */ {  1,       4,                 10,                   2,            4,       {    0,   3,    6,    9  }   },
+/* 10  */ {  1,       4,                 10,                   4,            4,       {    0,   3,    6,    9  }   },
+/* 11  */ {  1,       0,                 14,                   0,            2,       {    0,   6,    0,    0  }   },
+/* 12  */ {  1,       0,                 14,                   0,            4,       {    0,   3,    6,    9  }   },
+/* 13  */ {  1,       0,                 14,                   2,            4,       {    0,   3,    6,    9  }   },
+/* 14  */ {  1,       0,                 14,                   4,            4,       {    0,   3,    6,    9  }   },
+/* 15  */ {  1,       0,                 14,                   0,            4,       {    0,   3,    6,    9  }   },
+};
+
+
 int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti){
 
     RA_config_t *ra = &mac->ra;
@@ -73,10 +142,10 @@ int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti){
 
     if (rnti == ra->ra_rnti) {
       rnti_type = NR_RNTI_RA;
+    } else if (rnti == ra->t_crnti && (ra->ra_state == WAIT_RAR || ra->ra_state == WAIT_CONTENTION_RESOLUTION) ) {
+      rnti_type = NR_RNTI_TC;
     } else if (rnti == mac->crnti) {
       rnti_type = NR_RNTI_C;
-    } else if (rnti == ra->t_crnti) {
-      rnti_type = NR_RNTI_TC;
     } else if (rnti == 0xFFFE) {
       rnti_type = NR_RNTI_P;
     } else if (rnti == 0xFFFF) {
@@ -99,69 +168,101 @@ 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_I(MAC,"[L2][MAC] decode mib\n");
+  LOG_D(MAC,"[L2][MAC] decode mib\n");
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
+  mac->physCellId = cell_id;
 
-  nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, NR_BCCH_BCH, (uint8_t *) pduP, 3 );    //  fixed 3 bytes MIB PDU
+  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){
+    mac->frequency_range = FR2;
     for (int i=0; i<3; i++)
       ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i));
   }else{
+    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;
 
-  get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, mac->mib, extra_bits, ssb_length, ssb_index,
-                                        mac->phy_config.config_req.ssb_table.ssb_offset_point_a);
+  if (get_softmodem_params()->sa == 1) {
+
+    // TODO these values shouldn't be taken from SCC in SA
+    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,
+                                          mac->mib,
+                                          nr_slots_per_frame[scs_ssb],
+                                          ssb_subcarrier_offset,
+                                          ssb_start_symbol,
+                                          scs_ssb,
+                                          mac->frequency_range,
+                                          ssb_index,
+                                          ssb_offset_point_a);
+
+
+    mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern;
+    mac->type0_pdcch_ss_sfn_c = mac->type0_PDCCH_CSS_config.sfn_c;
+    mac->type0_pdcch_ss_n_c = mac->type0_PDCCH_CSS_config.n_c;
+  }
 
-  ssb_index = mac->type0_PDCCH_CSS_config.ssb_index; //  TODO: ssb_index should obtain from L1 in case Lssb != 64
-  mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern;
-  mac->type0_pdcch_ss_sfn_c = mac->type0_PDCCH_CSS_config.sfn_c;
-  mac->type0_pdcch_ss_n_c = mac->type0_PDCCH_CSS_config.n_c;
   mac->dl_config_request.sfn = mac->type0_PDCCH_CSS_config.frame;
   mac->dl_config_request.slot = (ssb_index>>1) + ((ssb_index>>4)<<1); // not valid for 240kHz SCS
 
   return 0;
 }
 
-int8_t nr_ue_decode_sib1(module_id_t module_id,
-                         int cc_id,
-                         unsigned int gNB_index,
-                         uint32_t sibs_mask,
-                         uint8_t *pduP,
-                         uint32_t pdu_len) {
-  LOG_D(MAC, "Decode sib1\n");
-  nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len);
+int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id,
+                                int cc_id,
+                                unsigned int gNB_index,
+                                uint8_t ack_nack,
+                                uint8_t *pduP,
+                                uint32_t pdu_len) {
+  if(ack_nack) {
+    LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n");
+    nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len);
+  }
+  else
+    LOG_E(NR_MAC, "Got NACK on NR-BCCH-DL-SCH-Message (SIB1 or SI)\n");
   return 0;
 }
 
@@ -203,10 +304,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){
@@ -229,7 +330,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;
 }
@@ -237,85 +341,16 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
 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
+						      uint8_t time_domain_ind,
+						      bool use_default
 						      ){
-  int dmrs_typeA_pos = mac->scc->dmrs_TypeA_Position;
+  int dmrs_typeA_pos = (mac->scc != NULL) ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position;
+
 //  uint8_t k_offset=0;
   uint8_t sliv_S=0;
   uint8_t sliv_L=0;
-  uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1
-    {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?12:11}, // row index 1
-    {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?10:9},  // row index 2
-    {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?9:8},   // row index 3
-    {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?7:6},   // row index 4
-    {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?5:4},   // row index 5
-    {0,(dmrs_typeA_pos == 0)?9:10,(dmrs_typeA_pos == 0)?4:4},   // row index 6
-    {0,(dmrs_typeA_pos == 0)?4:6, (dmrs_typeA_pos == 0)?4:4},   // row index 7
-    {0,5,7},  // row index 8
-    {0,5,2},  // row index 9
-    {0,9,2},  // row index 10
-    {0,12,2}, // row index 11
-    {0,1,13}, // row index 12
-    {0,1,6},  // row index 13
-    {0,2,4},  // row index 14
-    {0,4,7},  // row index 15
-    {0,8,4}   // row index 16
-  };
-  /*uint8_t table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1
-    {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?6:5},   // row index 1
-    {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?10:9},  // row index 2
-    {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?9:8},   // row index 3
-    {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?7:6},   // row index 4
-    {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?5:4},   // row index 5
-    {0,(dmrs_typeA_pos == 0)?6:8, (dmrs_typeA_pos == 0)?4:2},   // row index 6
-    {0,(dmrs_typeA_pos == 0)?4:6, (dmrs_typeA_pos == 0)?4:4},   // row index 7
-    {0,5,6},  // row index 8
-    {0,5,2},  // row index 9
-    {0,9,2},  // row index 10
-    {0,10,2}, // row index 11
-    {0,1,11}, // row index 12
-    {0,1,6},  // row index 13
-    {0,2,4},  // row index 14
-    {0,4,6},  // row index 15
-    {0,8,4}   // row index 16
-    };*/
-  /*uint8_t table_5_1_2_1_1_4_time_dom_res_alloc_B[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1
-    {0,2,2},  // row index 1
-    {0,4,2},  // row index 2
-    {0,6,2},  // row index 3
-    {0,8,2},  // row index 4
-    {0,10,2}, // row index 5
-    {1,2,2},  // row index 6
-    {1,4,2},  // row index 7
-    {0,2,4},  // row index 8
-    {0,4,4},  // row index 9
-    {0,6,4},  // row index 10
-    {0,8,4},  // row index 11
-    {0,10,4}, // row index 12
-    {0,2,7},  // row index 13
-    {0,(dmrs_typeA_pos == 0)?2:3,(dmrs_typeA_pos == 0)?12:11},  // row index 14
-    {1,2,4},  // row index 15
-    {0,0,0}   // row index 16
-    };*/
-  /*uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1
-    {0,2,2},  // row index 1
-    {0,4,2},  // row index 2
-    {0,6,2},  // row index 3
-    {0,8,2},  // row index 4
-    {0,10,2}, // row index 5
-    {0,0,0},  // row index 6
-    {0,0,0},  // row index 7
-    {0,2,4},  // row index 8
-    {0,4,4},  // row index 9
-    {0,6,4},  // row index 10
-    {0,8,4},  // row index 11
-    {0,10,4}, // row index 12
-    {0,2,7},  // row index 13
-    {0,(dmrs_typeA_pos == 0)?2:3,(dmrs_typeA_pos == 0)?12:11},  // row index 14
-    {0,0,6},  // row index 15
-    {0,2,6}   // row index 16
-    };*/
   uint8_t mu_pusch = 1;
+
   // definition table j Table 6.1.2.1.1-4
   uint8_t j = (mu_pusch==3)?3:(mu_pusch==2)?2:1;
   uint8_t table_6_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PUSCH from TS 38.214 subclause 6.1.2.1.1
@@ -360,11 +395,17 @@ 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[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
+    if (mac->DLbwp[0] &&
+        mac->DLbwp[0]->bwp_Dedicated &&
+        mac->DLbwp[0]->bwp_Dedicated->pdsch_Config &&
+        mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
       pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList->choice.setup;
-    else if (mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
+    else if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
       pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
-    if (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) {
         LOG_E(MAC, "time_domain_ind %d >= pdsch->TimeDomainAllocationList->list.count %d\n",
@@ -387,8 +428,15 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
     }
     else {// Default configuration from tables
 //      k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0];
-      sliv_S   = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][1];
-      sliv_L   = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][2];
+
+      if(dmrs_typeA_pos == 0) {
+        sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[time_domain_ind][1];
+        sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[time_domain_ind][2];
+      } else {
+        sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[time_domain_ind][1];
+        sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[time_domain_ind][2];
+      }
+
       // k_offset = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0];
       // sliv_S   = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1];
       // sliv_L   = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2];
@@ -406,14 +454,23 @@ 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[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
+    if (mac->ULbwp[0] &&
+        mac->ULbwp[0]->bwp_Dedicated &&
+        mac->ULbwp[0]->bwp_Dedicated->pusch_Config &&
+        mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup &&
+        mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
       pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
     }
-    else if (mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+    else if (mac->ULbwp[0] &&
+      mac->ULbwp[0]->bwp_Common &&
+      mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon &&
+      mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup &&
+      mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
       pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
     }
-    	
-    if (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",
               time_domain_ind, pusch_TimeDomainAllocationList->list.count);
@@ -422,6 +479,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);
@@ -429,15 +487,18 @@ 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][1];
-      sliv_L   = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][2];
+      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];
       // k_offset = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0];
       // sliv_S   = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1];
       // sliv_L   = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2];
       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;
 }
@@ -445,16 +506,20 @@ 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);
-
-  uint32_t dci_format = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15);
-  return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci->rnti, 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));
 }
 
-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){
+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, fapi_nr_dci_indication_pdu_t *dci_ind) {
 
+  uint16_t rnti = dci_ind->rnti;
+  uint8_t dci_format = dci_ind->dci_format;
   int ret = 0;
   int pucch_res_set_cnt = 0, valid = 0;
   frame_t frame_tx = 0;
@@ -465,11 +530,10 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
   fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
   uint8_t is_Msg3 = 0;
 
-  //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) ? NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) : NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  uint16_t n_RB_DLBWP;
+  if (mac->DLbwp[0]) n_RB_DLBWP = NRRIV2BW(mac->DLbwp[0]->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);
 
@@ -508,6 +572,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);
@@ -515,10 +580,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
       // Config PUSCH PDU
       ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format);
 
-      if (ret != -1 && ra->RA_active && mac->crnti){
-        nr_ra_succeeded(module_id, frame, slot);
-      }
-
     }
     
     break;
@@ -578,12 +639,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
       // Config PUSCH PDU
       ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format);
 
-      if (ret != -1 && ra->RA_active && mac->crnti){
-        nr_ra_succeeded(module_id, frame, slot);
-      }
-
     }
-
     break;
   }
 
@@ -641,15 +697,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=mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup;
-    uint16_t BWPSize = 0;
+    NR_PDSCH_Config_t *pdsch_config= (mac->DLbwp[0]) ? mac->DLbwp[0]->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;
-      pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; // For PDSCH with mapping type A, the UE shall assume dmrs-AdditionalPosition='pos2'
+      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){
@@ -657,10 +713,31 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
       } else {
         dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
       }
-      dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-      dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-      dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
-      BWPSize = n_RB_DLBWP;
+      if( (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti) || (rnti == ra->t_crnti) ) {
+        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);
+        }
+        if (!get_softmodem_params()->sa) { // NSA mode is not using the Initial BWP
+          dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+          pdsch_config = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup;
+          BWPSize = dlsch_config_pdu_1_0->BWPSize;
+        }
+      } else if (mac->DLbwp[0]) {
+        dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+        dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+        dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
+        pdsch_config = mac->DLbwp[0]->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;
+      }
     }
 
     /* IDENTIFIER_DCI_FORMATS */
@@ -670,15 +747,31 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
       return -1;
     }
     /* TIME_DOM_RESOURCE_ASSIGNMENT */
-    if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val) < 0) {
+    if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val,rnti==SI_RNTI) < 0) {
       LOG_W(MAC, "[%d.%d] Invalid time_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot);
       return -1;
     }
+
+    NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL;
+    if (mac->DLbwp[0] &&
+        mac->DLbwp[0]->bwp_Dedicated &&
+        mac->DLbwp[0]->bwp_Dedicated->pdsch_Config &&
+        mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
+      pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList->choice.setup;
+    else if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
+      pdsch_TimeDomainAllocationList = mac->DLbwp[0]->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 ? 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(pdsch_config,
-							 mac->scc->dmrs_TypeA_Position,
-               dlsch_config_pdu_1_0->start_symbol+dlsch_config_pdu_1_0->number_symbols);
-    dlsch_config_pdu_1_0->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
+                                                         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[0] != NULL) ? (mac->DLbwp[0]->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;
@@ -687,7 +780,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     /* VRB_TO_PRB_MAPPING */
     dlsch_config_pdu_1_0->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved;
     /* MCS TABLE INDEX */
-    dlsch_config_pdu_1_0->mcs_table = (pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0;
+    dlsch_config_pdu_1_0->mcs_table = (pdsch_config) ? ((pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0) : 0;
     /* MCS */
     dlsch_config_pdu_1_0->mcs = dci->mcs;
     // Basic sanity check for MCS value to check for a false or erroneous DCI
@@ -701,8 +794,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     dlsch_config_pdu_1_0->rv = dci->rv;
     /* HARQ_PROCESS_NUMBER (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/
     dlsch_config_pdu_1_0->harq_process_nbr = dci->harq_pid;
-    /* DAI (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/
-    dlsch_config_pdu_1_0->dai = dci->dai[0].val;
     /* TB_SCALING (only if CRC scrambled by P-RNTI or RA-RNTI) */
     // according to TS 38.214 Table 5.1.3.2-3
     if (dci->tb_scaling == 0) dlsch_config_pdu_1_0->scaling_factor_S = 1;
@@ -715,32 +806,50 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     if (dci->tpc == 1) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 0;
     if (dci->tpc == 2) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 1;
     if (dci->tpc == 3) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 3;
-    /* PUCCH_RESOURCE_IND (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI)*/
-    //if (dci->pucch_resource_indicator == 0) dlsch_config_pdu_1_0->pucch_resource_id = 1; //pucch-ResourceId obtained from the 1st value of resourceList FIXME!!!
-    //if (dci->pucch_resource_indicator == 1) dlsch_config_pdu_1_0->pucch_resource_id = 2; //pucch-ResourceId obtained from the 2nd value of resourceList FIXME!!
-    //if (dci->pucch_resource_indicator == 2) dlsch_config_pdu_1_0->pucch_resource_id = 3; //pucch-ResourceId obtained from the 3rd value of resourceList FIXME!!
-    //if (dci->pucch_resource_indicator == 3) dlsch_config_pdu_1_0->pucch_resource_id = 4; //pucch-ResourceId obtained from the 4th value of resourceList FIXME!!
-    //if (dci->pucch_resource_indicator == 4) dlsch_config_pdu_1_0->pucch_resource_id = 5; //pucch-ResourceId obtained from the 5th value of resourceList FIXME!!
-    //if (dci->pucch_resource_indicator == 5) dlsch_config_pdu_1_0->pucch_resource_id = 6; //pucch-ResourceId obtained from the 6th value of resourceList FIXME!!
-    //if (dci->pucch_resource_indicator == 6) dlsch_config_pdu_1_0->pucch_resource_id = 7; //pucch-ResourceId obtained from the 7th value of resourceList FIXME!!
-    //if (dci->pucch_resource_indicator == 7) dlsch_config_pdu_1_0->pucch_resource_id = 8; //pucch-ResourceId obtained from the 8th value of resourceList FIXME!!
-    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[0]->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[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) {
-        valid = 1;
-        break;
+    if (mac->ULbwp[0] &&
+        mac->ULbwp[0]->bwp_Dedicated &&
+        mac->ULbwp[0]->bwp_Dedicated->pucch_Config &&
+        mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup&&
+        mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList) {
+      pucch_res_set_cnt = mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.count;
+      for (int id = 0; id < pucch_res_set_cnt; id++) {
+	if (dci->pucch_resource_indicator < mac->ULbwp[0]->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 (dci->pucch_resource_indicator < 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);
+      LOG_W(MAC, "[%d.%d] pucch_resource_indicator value %d is out of bounds. Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dci->pucch_resource_indicator);
       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 = dci->pdsch_to_harq_feedback_timing_indicator.val;
+   // set the harq status at MAC for feedback
+   set_harq_status(mac,dci->pucch_resource_indicator,
+                   dci->harq_pid,
+                   dlsch_config_pdu_1_0->accumulated_delta_PUCCH,
+                   1+dci->pdsch_to_harq_feedback_timing_indicator.val,
+                   dci->dai[0].val,
+                   dci_ind->n_CCE,dci_ind->N_CCE,
+                   frame,slot);
 
     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,
@@ -759,17 +868,18 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 	  dlsch_config_pdu_1_0->ndi,
 	  dlsch_config_pdu_1_0->rv,
 	  dlsch_config_pdu_1_0->harq_process_nbr,
-	  dlsch_config_pdu_1_0->dai,
+	  dci->dai[0].val,
 	  dlsch_config_pdu_1_0->scaling_factor_S,
 	  dlsch_config_pdu_1_0->accumulated_delta_PUCCH,
-	  dlsch_config_pdu_1_0->pucch_resource_id,
-	  dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind);
+	  dci->pucch_resource_indicator,
+	  1+dci->pdsch_to_harq_feedback_timing_indicator.val);
 
     //	    dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP;
 	    
     LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type);
             
     dl_config->number_pdus = dl_config->number_pdus + 1;
+
     break;
   }
 
@@ -814,7 +924,13 @@ 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;
     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_1 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15;
+
+    dlsch_config_pdu_1_1->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    dlsch_config_pdu_1_1->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+    dlsch_config_pdu_1_1->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
+
     /* IDENTIFIER_DCI_FORMATS */
     /* CARRIER_IND */
     /* BANDWIDTH_PART_IND */
@@ -825,20 +941,36 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
       return -1;
     }
     /* TIME_DOM_RESOURCE_ASSIGNMENT */
-    if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_domain_assignment.val) < 0) {
+    if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_domain_assignment.val,false) < 0) {
       LOG_W(MAC, "[%d.%d] Invalid time_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot);
       return -1;
     }
+
+    NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL;
+    if (mac->DLbwp[0] &&
+        mac->DLbwp[0]->bwp_Dedicated &&
+        mac->DLbwp[0]->bwp_Dedicated->pdsch_Config &&
+        mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
+      pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList->choice.setup;
+    else if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
+      pdsch_TimeDomainAllocationList = mac->DLbwp[0]->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 ? 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,
 							 mac->scc->dmrs_TypeA_Position,
-							 dlsch_config_pdu_1_1->number_symbols);
-    dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
+							 dlsch_config_pdu_1_1->number_symbols,
+               dlsch_config_pdu_1_1->start_symbol,
+               mappingtype);
+    dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? NFAPI_NR_DMRS_TYPE1 : NFAPI_NR_DMRS_TYPE2;
     /* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214,
              using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */
     dlsch_config_pdu_1_1->n_dmrs_cdm_groups = 1;
     /* VRB_TO_PRB_MAPPING */
-    if (mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.resource_allocation != 0)
+    if ((pdsch_config->resourceAllocation == 1) && (pdsch_config->vrb_ToPRB_Interleaver != NULL))
       dlsch_config_pdu_1_1->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved;
     /* PRB_BUNDLING_SIZE_IND */
     dlsch_config_pdu_1_1->prb_bundling_size_ind = dci->prb_bundling_size_indicator.val;
@@ -870,38 +1002,40 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     dlsch_config_pdu_1_1->tb2_rv = dci->rv2.val;
     /* HARQ_PROCESS_NUMBER */
     dlsch_config_pdu_1_1->harq_process_nbr = dci->harq_pid;
-    /* DAI */
-    dlsch_config_pdu_1_1->dai = dci->dai[0].val;
     /* TPC_PUCCH */
     // according to TS 38.213 Table 7.2.1-1
     if (dci->tpc == 0) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = -1;
     if (dci->tpc == 1) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = 0;
     if (dci->tpc == 2) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = 1;
     if (dci->tpc == 3) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = 3;
-    /* PUCCH_RESOURCE_IND */
-    dlsch_config_pdu_1_1->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[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.count;
     for (int id = 0; id < pucch_res_set_cnt; id++) {
-      if (dlsch_config_pdu_1_1->pucch_resource_id < mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) {
+      if (dci->pucch_resource_indicator < mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) {
         valid = 1;
         break;
       }
     }
     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_1->pucch_resource_id);
+      LOG_W(MAC, "[%d.%d] pucch_resource_indicator value %d is out of bounds. Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dci->pucch_resource_indicator);
       return -1;
     }
 
-    /* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */
-    // according to TS 38.213 Table 9.2.3-1
-    NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
-    dlsch_config_pdu_1_1->pdsch_to_harq_feedback_time_ind = mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0];
     /* ANTENNA_PORTS */
     uint8_t n_codewords = 1; // FIXME!!!
-    if ((mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.dmrs_type == 1) &&
-	(mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.max_length == 1)){
+    long *max_length = NULL;
+    long *dmrs_type = NULL;
+    if (pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA) {
+      max_length = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength;
+      dmrs_type = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type;
+    }
+    if (pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeB) {
+      max_length = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength;
+      dmrs_type = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type;
+    }
+    if ((dmrs_type == NULL) && (max_length == NULL)){
       // Table 7.3.1.2.2-1: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=1
       dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_1[dci->antenna_ports.val][0];
       dlsch_config_pdu_1_1->dmrs_ports[0]     = table_7_3_2_3_3_1[dci->antenna_ports.val][1];
@@ -909,8 +1043,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
       dlsch_config_pdu_1_1->dmrs_ports[2]     = table_7_3_2_3_3_1[dci->antenna_ports.val][3];
       dlsch_config_pdu_1_1->dmrs_ports[3]     = table_7_3_2_3_3_1[dci->antenna_ports.val][4];
     }
-    if ((mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.dmrs_type == 1) &&
-	(mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.max_length == 2)){
+    if ((dmrs_type == NULL) && (max_length != NULL)){
       // Table 7.3.1.2.2-2: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=2
       if (n_codewords == 1) {
 	dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][0];
@@ -920,7 +1053,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 	dlsch_config_pdu_1_1->dmrs_ports[3]     = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][4];
 	dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][5];
       }
-      if (n_codewords == 1) {
+      if (n_codewords == 2) {
 	dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][0];
 	dlsch_config_pdu_1_1->dmrs_ports[0]     = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][1];
 	dlsch_config_pdu_1_1->dmrs_ports[1]     = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][2];
@@ -933,8 +1066,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 	dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][9];
       }
     }
-    if ((mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.dmrs_type == 2) &&
-	(mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.max_length == 1)){
+    if ((dmrs_type != NULL) && (max_length == NULL)){
       // Table 7.3.1.2.2-3: Antenna port(s) (1000 + DMRS port), dmrs-Type=2, maxLength=1
       if (n_codewords == 1) {
 	dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][0];
@@ -943,7 +1075,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 	dlsch_config_pdu_1_1->dmrs_ports[2]     = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][3];
 	dlsch_config_pdu_1_1->dmrs_ports[3]     = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][4];
       }
-      if (n_codewords == 1) {
+      if (n_codewords == 2) {
 	dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][0];
 	dlsch_config_pdu_1_1->dmrs_ports[0]     = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][1];
 	dlsch_config_pdu_1_1->dmrs_ports[1]     = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][2];
@@ -953,8 +1085,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 	dlsch_config_pdu_1_1->dmrs_ports[5]     = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][6];
       }
     }
-    if ((mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.dmrs_type == 2) &&
-	(mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.max_length == 2)){
+    if ((dmrs_type != NULL) && (max_length != NULL)){
       // Table 7.3.1.2.2-4: Antenna port(s) (1000 + DMRS port), dmrs-Type=2, maxLength=2
       if (n_codewords == 1) {
 	dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][0];
@@ -964,7 +1095,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 	dlsch_config_pdu_1_1->dmrs_ports[3]     = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][4];
 	dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][5];
       }
-      if (n_codewords == 1) {
+      if (n_codewords == 2) {
 	dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][0];
 	dlsch_config_pdu_1_1->dmrs_ports[0]     = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][1];
 	dlsch_config_pdu_1_1->dmrs_ports[1]     = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][2];
@@ -994,7 +1125,22 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     //FIXME!!!
 
     //	    dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP;
-	    
+
+    /* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */
+    // according to TS 38.213 Table 9.2.3-1
+    NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
+    uint8_t feedback_ti =
+      mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0];
+
+   // set the harq status at MAC for feedback
+   set_harq_status(mac,dci->pucch_resource_indicator,
+                   dci->harq_pid,
+                   dlsch_config_pdu_1_1->accumulated_delta_PUCCH,
+                   feedback_ti,
+                   dci->dai[0].val,
+                   dci_ind->n_CCE,dci_ind->N_CCE,
+                   frame,slot);
+
     dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
     LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type);
             
@@ -1010,6 +1156,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
                                             &dlsch_config_pdu_1_1->PTRSReOffset, dlsch_config_pdu_1_1->number_symbols);
       if(valid_ptrs_setup==true) {
         dlsch_config_pdu_1_1->pduBitmap |= 0x1;
+        LOG_D(MAC, "DL PTRS values: PTRS time den: %d, PTRS freq den: %d\n", dlsch_config_pdu_1_1->PTRSTimeDensity, dlsch_config_pdu_1_1->PTRSFreqDensity);
       }
     }
 
@@ -1053,11 +1200,1173 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 
 }
 
-int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe){
+void set_harq_status(NR_UE_MAC_INST_t *mac,
+                     uint8_t pucch_id,
+                     uint8_t harq_id,
+                     int8_t delta_pucch,
+                     uint8_t data_toul_fb,
+                     uint8_t dai,
+                     int n_CCE,
+                     int N_CCE,
+                     frame_t frame,
+                     int slot) {
+
+  NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_id];
+
+  current_harq->active = true;
+  current_harq->ack_received = false;
+  current_harq->pucch_resource_indicator = pucch_id;
+  current_harq->feedback_to_ul = data_toul_fb;
+  current_harq->dai = dai;
+  current_harq->n_CCE = n_CCE;
+  current_harq->N_CCE = N_CCE;
+  current_harq->delta_pucch = delta_pucch;
+  // FIXME k0 != 0 currently not taken into consideration
+  current_harq->dl_frame = frame;
+  current_harq->dl_slot = slot;
+
+}
+
+
+void update_harq_status(nr_downlink_indication_t *dl_info, int pdu_id) {
+
+  NR_UE_MAC_INST_t *mac = get_mac_inst(dl_info->module_id);
+  uint8_t harq_pid = dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.harq_pid;
+  NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_pid];
+
+  if (current_harq->active) {
+    current_harq->ack = dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.ack_nack;
+    current_harq->ack_received = true;
+  }
+  else {
+    //shouldn't get here
+    LOG_E(MAC, "Trying to process acknack for an inactive harq process (%d)\n", harq_pid);
+  }
+}
+
+
+void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
+                           int slot,
+                           uint16_t rnti,
+                           PUCCH_sched_t *pucch,
+                           fapi_nr_ul_config_pucch_pdu *pucch_pdu,
+                           int O_SR, int O_ACK, int O_CSI) {
+
+  int O_CRC = 0; //FIXME
+  uint16_t O_uci = O_CSI + O_ACK;
+  NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
+  NR_PUCCH_FormatConfig_t *pucchfmt;
+  long *pusch_id = NULL;
+  long *id0 = NULL;
+  int scs;
+  NR_BWP_UplinkCommon_t *initialUplinkBWP;
+  if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP;
+  else          initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP;
+  NR_BWP_Uplink_t *ubwp = mac->ULbwp[0];
+  if (mac->cg && ubwp &&
+      mac->cg->spCellConfig &&
+      mac->cg->spCellConfig->spCellConfigDedicated &&
+      mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+      mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) {
+    scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+  }
+  else
+    scs = initialUplinkBWP->genericParameters.subcarrierSpacing;
+
+  int subframe_number = slot / (nr_slots_per_frame[scs]/10);
+  nb_pucch_format_4_in_subframes[subframe_number] = 0;
+
+  pucch_pdu->rnti = rnti;
+
+  // configure pucch from Table 9.2.1-1
+  if (pucch->initial_pucch_id > -1 &&
+      pucch->pucch_resource == NULL) {
+
+    pucch_pdu->format_type = initial_pucch_resource[pucch->initial_pucch_id].format;
+    pucch_pdu->start_symbol_index = initial_pucch_resource[pucch->initial_pucch_id].startingSymbolIndex;
+    pucch_pdu->nr_of_symbols = initial_pucch_resource[pucch->initial_pucch_id].nrofSymbols;
+
+    pucch_pdu->bwp_size = NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth,
+                                   MAX_BWP_SIZE);
+    pucch_pdu->bwp_start = NRRIV2PRBOFFSET(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth,
+                                           MAX_BWP_SIZE);
+
+    pucch_pdu->prb_size = 1; // format 0 or 1
+    int RB_BWP_offset;
+    if (pucch->initial_pucch_id == 15)
+      RB_BWP_offset = pucch_pdu->bwp_size>>2;
+    else
+      RB_BWP_offset = initial_pucch_resource[pucch->initial_pucch_id].PRB_offset;
+
+    int N_CS = initial_pucch_resource[pucch->initial_pucch_id].nb_CS_indexes;
+    pucch_pdu->prb_start = RB_BWP_offset + (pucch->initial_pucch_id/N_CS);
+    if (pucch->initial_pucch_id>>3 == 0) {
+      pucch_pdu->second_hop_prb = pucch_pdu->bwp_size - 1 - RB_BWP_offset - (pucch->initial_pucch_id/N_CS);
+      pucch_pdu->initial_cyclic_shift = initial_pucch_resource[pucch->initial_pucch_id].initial_CS_indexes[pucch->initial_pucch_id%N_CS];
+    }
+    else {
+      pucch_pdu->second_hop_prb = pucch_pdu->bwp_size - 1 - RB_BWP_offset - ((pucch->initial_pucch_id - 8)/N_CS);
+      pucch_pdu->initial_cyclic_shift =  initial_pucch_resource[pucch->initial_pucch_id].initial_CS_indexes[(pucch->initial_pucch_id - 8)%N_CS];
+    }
+    pucch_pdu->freq_hop_flag = 1;
+    pucch_pdu->time_domain_occ_idx = 0;
+
+    if (O_SR == 0 || pucch->sr_payload == 0) {  /* only ack is transmitted TS 36.213 9.2.3 UE procedure for reporting HARQ-ACK */
+      if (O_ACK == 1)
+        pucch_pdu->mcs = sequence_cyclic_shift_1_harq_ack_bit[pucch->ack_payload & 0x1];   /* only harq of 1 bit */
+      else
+        pucch_pdu->mcs = sequence_cyclic_shift_2_harq_ack_bits[pucch->ack_payload & 0x3];  /* only harq with 2 bits */
+    }
+    else { /* SR + eventually ack are transmitted TS 36.213 9.2.5.1 UE procedure for multiplexing HARQ-ACK or CSI and SR */
+      if (pucch->sr_payload == 1) {                /* positive scheduling request */
+        if (O_ACK == 1)
+          pucch_pdu->mcs = sequence_cyclic_shift_1_harq_ack_bit_positive_sr[pucch->ack_payload & 0x1];   /* positive SR and harq of 1 bit */
+        else if (O_ACK == 2)
+          pucch_pdu->mcs = sequence_cyclic_shift_2_harq_ack_bits_positive_sr[pucch->ack_payload & 0x3];  /* positive SR and harq with 2 bits */
+        else
+          pucch_pdu->mcs = 0;  /* only positive SR */
+      }
+    }
+
+    // TODO verify if SR can be transmitted in this mode
+    pucch_pdu->payload = (pucch->sr_payload << O_ACK) | pucch->ack_payload;
+
+  }
+  else if (pucch->pucch_resource != NULL) {
+
+    NR_PUCCH_Resource_t *pucchres = pucch->pucch_resource;
+
+    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;
+    }
+    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(MAC,"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;
+    }
+    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) {
+      NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup;
+      pusch_id = pusch_Config->dataScramblingIdentityPUSCH;
+      if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL)
+        id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->transformPrecodingDisabled->scramblingID0;
+      else if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB != NULL)
+        id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->transformPrecodingDisabled->scramblingID0;
+      else *id0 = mac->physCellId;
+      pucch_Config =  mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup;
+      pucch_pdu->bwp_size = NRRIV2BW(mac->ULbwp[bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
+      pucch_pdu->bwp_start = NRRIV2PRBOFFSET(mac->ULbwp[bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
+    }
+    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;
+      pucch_pdu->bwp_size = NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
+      pucch_pdu->bwp_start = NRRIV2PRBOFFSET(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
+    }
+    else AssertFatal(1==0,"no pucch_Config\n");
+
+    NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon;
+    if (mac->scc) pucch_ConfigCommon = mac->scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup;
+    else          pucch_ConfigCommon = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon->choice.setup;
+    if (pucch_ConfigCommon->hoppingId != NULL)
+      pucch_pdu->hopping_id = *pucch_ConfigCommon->hoppingId;
+    else
+      pucch_pdu->hopping_id = mac->physCellId;
+
+    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 undefined (0,1,2) \n");
+    }
+
+    pucch_pdu->prb_start = pucchres->startingPRB;
+    pucch_pdu->freq_hop_flag = pucchres->intraSlotFrequencyHopping!= NULL ?  1 : 0;
+    pucch_pdu->second_hop_prb = pucchres->secondHopPRB!= NULL ?  *pucchres->secondHopPRB : 0;
+    pucch_pdu->prb_size = 1; // format 0 or 1
+
+    if ((O_SR+O_CSI+O_SR) > (sizeof(uint64_t)*8)) {
+      LOG_E(MAC,"PUCCH number of UCI bits exceeds payload size : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+      return;
+    }
+    pucch_pdu->payload = (pucch->csi_part1_payload << (O_ACK + O_SR)) |  (pucch->sr_payload << O_ACK) | pucch->ack_payload;
+
+    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;
+        if (O_SR == 0 || pucch->sr_payload == 0) {  /* only ack is transmitted TS 36.213 9.2.3 UE procedure for reporting HARQ-ACK */
+          if (O_ACK == 1)
+            pucch_pdu->mcs = sequence_cyclic_shift_1_harq_ack_bit[pucch->ack_payload & 0x1];   /* only harq of 1 bit */
+          else
+            pucch_pdu->mcs = sequence_cyclic_shift_2_harq_ack_bits[pucch->ack_payload & 0x3];  /* only harq with 2 bits */
+        }
+        else { /* SR + eventually ack are transmitted TS 36.213 9.2.5.1 UE procedure for multiplexing HARQ-ACK or CSI and SR */
+          if (pucch->sr_payload == 1) {                /* positive scheduling request */
+            if (O_ACK == 1)
+              pucch_pdu->mcs = sequence_cyclic_shift_1_harq_ack_bit_positive_sr[pucch->ack_payload & 0x1];   /* positive SR and harq of 1 bit */
+            else if (O_ACK == 2)
+              pucch_pdu->mcs = sequence_cyclic_shift_2_harq_ack_bits_positive_sr[pucch->ack_payload & 0x3];  /* positive SR and harq with 2 bits */
+            else
+              pucch_pdu->mcs = 0;  /* only positive 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;
+        break;
+      case NR_PUCCH_Resource__format_PR_format2 :
+        pucch_pdu->format_type = 2;
+        pucch_pdu->n_bit = O_uci+O_SR;
+        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 : mac->physCellId;
+        pucch_pdu->dmrs_scrambling_id = id0!= NULL ? *id0 : mac->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);
+        break;
+      case NR_PUCCH_Resource__format_PR_format3 :
+        pucch_pdu->format_type = 3;
+        pucch_pdu->n_bit = O_uci+O_SR;
+        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 : mac->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);
+        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 : mac->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;
+        }
+        break;
+      default :
+        AssertFatal(1==0,"Undefined PUCCH format \n");
+    }
+    pucch_pdu->pucch_tx_power = get_pucch_tx_power_ue(mac,
+                                                      pucch_Config,
+                                                      pucch,
+                                                      pucch_pdu->format_type,
+                                                      pucch_pdu->prb_size,
+                                                      pucch_pdu->freq_hop_flag,
+                                                      pucch_pdu->add_dmrs_flag,
+                                                      pucch_pdu->nr_of_symbols,
+                                                      subframe_number,
+                                                      O_ACK, O_SR,
+                                                      O_CSI, O_CRC);
+  }
+}
+
+
+int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
+                              NR_PUCCH_Config_t *pucch_Config,
+                              PUCCH_sched_t *pucch,
+                              uint8_t format_type,
+                              uint16_t nb_of_prbs,
+                              uint8_t  freq_hop_flag,
+                              uint8_t  add_dmrs_flag,
+                              uint8_t N_symb_PUCCH,
+                              int subframe_number,
+                              int O_ACK, int O_SR,
+                              int O_CSI, int O_CRC) {
+
+  int PUCCH_POWER_DEFAULT = 0;
+  int16_t P_O_NOMINAL_PUCCH;
+  if (mac->scc) P_O_NOMINAL_PUCCH = *mac->scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal;
+  else          P_O_NOMINAL_PUCCH = *mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon->choice.setup->p0_nominal;
+
+  struct NR_PUCCH_PowerControl *power_config = pucch_Config->pucch_PowerControl;
+
+  if (!power_config)
+    return (PUCCH_POWER_DEFAULT);
+
+  int16_t P_O_UE_PUCCH;
+  int16_t G_b_f_c = 0;
+
+  if (pucch_Config->spatialRelationInfoToAddModList != NULL) {  /* FFS TODO NR */
+    LOG_D(MAC,"PUCCH Spatial relation infos are not yet implemented : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
+    return (PUCCH_POWER_DEFAULT);
+  }
+
+  if (power_config->p0_Set != NULL) {
+    P_O_UE_PUCCH = power_config->p0_Set->list.array[0]->p0_PUCCH_Value; /* get from index 0 if no spatial relation set */
+    G_b_f_c = 0;
+  }
+  else {
+    G_b_f_c = pucch->delta_pucch;
+    LOG_D(MAC,"PUCCH Transmit power control command not yet implemented for NR : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
+    return (PUCCH_POWER_DEFAULT);
+  }
+
+  int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH;
+
+  int16_t delta_F_PUCCH;
+  int DELTA_TF;
+  uint16_t N_ref_PUCCH;
+  int N_sc_ctrl_RB = 0;
+
+  /* computing of pucch transmission power adjustment */
+  switch (format_type) {
+    case 0:
+      N_ref_PUCCH = 2;
+      DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH);
+      delta_F_PUCCH =  *power_config->deltaF_PUCCH_f0;
+      break;
+    case 1:
+      N_ref_PUCCH = 14;
+      DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH);
+      delta_F_PUCCH =  *power_config->deltaF_PUCCH_f1;
+      break;
+    case 2:
+      N_sc_ctrl_RB = 10;
+      DELTA_TF = get_deltatf(nb_of_prbs,
+                             N_symb_PUCCH,
+                             freq_hop_flag,
+                             add_dmrs_flag,
+                             N_sc_ctrl_RB,
+                             pucch->n_HARQ_ACK,
+                             O_ACK, O_SR,
+                             O_CSI, O_CRC);
+      delta_F_PUCCH =  *power_config->deltaF_PUCCH_f2;
+      break;
+    case 3:
+      N_sc_ctrl_RB = 14;
+      DELTA_TF = get_deltatf(nb_of_prbs,
+                             N_symb_PUCCH,
+                             freq_hop_flag,
+                             add_dmrs_flag,
+                             N_sc_ctrl_RB,
+                             pucch->n_HARQ_ACK,
+                             O_ACK, O_SR,
+                             O_CSI, O_CRC);
+      delta_F_PUCCH =  *power_config->deltaF_PUCCH_f3;
+      break;
+    case 4:
+      N_sc_ctrl_RB = 14/(nb_pucch_format_4_in_subframes[subframe_number]);
+      DELTA_TF = get_deltatf(nb_of_prbs,
+                             N_symb_PUCCH,
+                             freq_hop_flag,
+                             add_dmrs_flag,
+                             N_sc_ctrl_RB,
+                             pucch->n_HARQ_ACK,
+                             O_ACK, O_SR,
+                             O_CSI, O_CRC);
+      delta_F_PUCCH =  *power_config->deltaF_PUCCH_f4;
+      break;
+    default:
+    {
+      LOG_E(MAC,"PUCCH unknown pucch format : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
+      return (0);
+    }
+  }
+
+  if (*power_config->twoPUCCH_PC_AdjustmentStates > 1) {
+    LOG_E(MAC,"PUCCH power control adjustment states with 2 states not yet implemented : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
+    return (PUCCH_POWER_DEFAULT);
+  }
+
+  int16_t pucch_power = P_O_PUCCH + delta_F_PUCCH + DELTA_TF + G_b_f_c;
+
+  NR_TST_PHY_PRINTF("PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n",
+                    pucch_power, contributor, PL, delta_F_PUCCH, DELTA_TF, G_b_f_c);
+
+  return (pucch_power);
+}
+
+int get_deltatf(uint16_t nb_of_prbs,
+                uint8_t N_symb_PUCCH,
+                uint8_t freq_hop_flag,
+                uint8_t add_dmrs_flag,
+                int N_sc_ctrl_RB,
+                int n_HARQ_ACK,
+                int O_ACK, int O_SR,
+                int O_CSI, int O_CRC){
+
+  int DELTA_TF;
+  int O_UCI = O_ACK + O_SR + O_CSI + O_CRC;
+  int N_symb = nb_symbols_excluding_dmrs[N_symb_PUCCH-4][add_dmrs_flag][freq_hop_flag];
+  float N_RE = nb_of_prbs * N_sc_ctrl_RB * N_symb;
+  float K1 = 6;
+  if (O_UCI < 12)
+    DELTA_TF = 10 * log10((double)(((K1 * (n_HARQ_ACK + O_SR + O_CSI))/N_RE)));
+  else {
+    float K2 = 2.4;
+    float BPRE = O_UCI/N_RE;
+    DELTA_TF = 10 * log10((double)(pow(2,(K2*BPRE)) - 1));
+  }
+  return DELTA_TF;
+}
+
+/*******************************************************************
+*
+* NAME :         find_pucch_resource_set
+*
+* PARAMETERS :   ue context
+*                gNB_id identifier
+*
+*
+* RETURN :       harq process identifier
+*
+* DESCRIPTION :  return tx harq process identifier for given transmission slot
+*                YS 38.213 9.2.2  PUCCH Formats for UCI transmission
+*
+*********************************************************************/
+
+int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, int uci_size) {
+  int pucch_resource_set_id = 0;
+  NR_BWP_Id_t bwp_id = mac->DL_BWP_Id;
+
+  //long *pucch_max_pl_bits = NULL;
+
+  /* from TS 38.331 field maxPayloadMinus1
+    -- Maximum number of payload bits minus 1 that the UE may transmit using this PUCCH resource set. In a PUCCH occurrence, the UE
+    -- chooses the first of its PUCCH-ResourceSet which supports the number of bits that the UE wants to transmit.
+    -- The field is not present in the first set (Set0) since the maximum Size of Set0 is specified to be 3 bit.
+    -- The field is not present in the last configured set since the UE derives its maximum payload size as specified in 38.213.
+    -- This field can take integer values that are multiples of 4. Corresponds to L1 parameter 'N_2' or 'N_3' (see 38.213, section 9.2)
+  */
+  /* 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 ((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;
+      }
+      else {
+        pucch_resource_set_id = 1;
+        return (pucch_resource_set_id);
+        break;
+      }
+    }
+    pucch_resource_set_id++;
+  }
+
+  pucch_resource_set_id = MAX_NB_OF_PUCCH_RESOURCE_SETS;
+
+  return (pucch_resource_set_id);
+}
+
+
+/*******************************************************************
+*
+* NAME :         select_pucch_format
+*
+* PARAMETERS :   ue context
+*                processing slots of reception/transmission
+*                gNB_id identifier
+*
+* RETURN :       TRUE a valid resource has been found
+*
+* DESCRIPTION :  return tx harq process identifier for given transmission slot
+*                TS 38.213 9.2.1  PUCCH Resource Sets
+*                TS 38.213 9.2.2  PUCCH Formats for UCI transmission
+*                In the case of pucch for scheduling request only, resource is already get from scheduling request configuration
+*
+*********************************************************************/
+
+void select_pucch_resource(NR_UE_MAC_INST_t *mac,
+                           PUCCH_sched_t *pucch) {
+
+  NR_PUCCH_ResourceId_t *current_resource_id = NULL;
+  NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
+  int n_list;
+
+  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)
+      ){
+
+    /* see TS 38.213 9.2.1  PUCCH Resource Sets */
+    int delta_PRI = pucch->resource_indicator;
+    int n_CCE_0 = pucch->n_CCE;
+    int N_CCE_0 = pucch->N_CCE;
+    if (N_CCE_0 == 0) {
+      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);
+    pucch->initial_pucch_id = r_PUCCH;
+    pucch->pucch_resource = NULL;
+  }
+  else {
+    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;
+    }
+
+    n_list = resourceSetToAddModList->list.count;
+    if (pucch->resource_set_id > n_list) {
+      LOG_E(MAC,"Invalid PUCCH resource set id %d\n",pucch->resource_set_id);
+      pucch->pucch_resource = NULL;
+      return;
+    }
+    n_list = resourceSetToAddModList->list.array[pucch->resource_set_id]->resourceList.list.count;
+    if (pucch->resource_indicator > n_list) {
+      LOG_E(MAC,"Invalid PUCCH resource id %d\n",pucch->resource_indicator);
+      pucch->pucch_resource = NULL;
+      return;
+    }
+    current_resource_id = resourceSetToAddModList->list.array[pucch->resource_set_id]->resourceList.list.array[pucch->resource_indicator];
+    n_list = resourceToAddModList->list.count;
+    int res_found = 0;
+    for (int i=0; i<n_list; i++) {
+      if (resourceToAddModList->list.array[i]->pucch_ResourceId == *current_resource_id) {
+        pucch->pucch_resource = resourceToAddModList->list.array[i];
+        res_found = 1;
+        break;
+      }
+    }
+    if (res_found == 0) {
+      LOG_E(MAC,"Couldn't find PUCCH Resource\n");
+      pucch->pucch_resource = NULL;
+    }
+  }
+}
+
+/*******************************************************************
+*
+* NAME :         get_downlink_ack
+*
+* PARAMETERS :   ue context
+*                processing slots of reception/transmission
+*                gNB_id identifier
+*
+* RETURN :       o_ACK acknowledgment data
+*                o_ACK_number_bits number of bits for acknowledgment
+*
+* DESCRIPTION :  return acknowledgment value
+*                TS 38.213 9.1.3 Type-2 HARQ-ACK codebook determination
+*
+*          --+--------+-------+--------+-------+---  ---+-------+--
+*            | PDCCH1 |       | PDCCH2 |PDCCH3 |        | PUCCH |
+*          --+--------+-------+--------+-------+---  ---+-------+--
+*    DAI_DL      1                 2       3              ACK for
+*                V                 V       V        PDCCH1, PDDCH2 and PCCH3
+*                |                 |       |               ^
+*                +-----------------+-------+---------------+
+*
+*                PDCCH1, PDCCH2 and PDCCH3 are PDCCH monitoring occasions
+*                M is the total of monitoring occasions
+*
+*********************************************************************/
+
+uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac,
+                         frame_t frame,
+                         int slot,
+                         PUCCH_sched_t *pucch) {
+
+
+  uint32_t ack_data[NR_DL_MAX_NB_CW][NR_DL_MAX_DAI] = {{0},{0}};
+  uint32_t dai[NR_DL_MAX_NB_CW][NR_DL_MAX_DAI] = {{0},{0}};       /* for serving cell */
+  uint32_t dai_total[NR_DL_MAX_NB_CW][NR_DL_MAX_DAI] = {{0},{0}}; /* for multiple cells */
+  int number_harq_feedback = 0;
+  uint32_t dai_current = 0;
+  uint32_t dai_max = 0;
+  bool two_transport_blocks = FALSE;
+  int number_of_code_word = 1;
+  int U_DAI_c = 0;
+  int N_m_c_rx = 0;
+  int V_DAI_m_DL = 0;
+  NR_UE_HARQ_STATUS_t *current_harq;
+  int sched_frame,sched_slot;
+  NR_BWP_UplinkCommon_t *initialUplinkBWP;
+  if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP;
+  else          initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP;
+  int slots_per_frame,scs;
+
+  if (mac->DLbwp[0] &&
+      mac->DLbwp[0]->bwp_Dedicated &&
+      mac->DLbwp[0]->bwp_Dedicated->pdsch_Config &&
+      mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup &&
+      mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI[0] == 2) {
+    two_transport_blocks = TRUE;
+    number_of_code_word = 2;
+  }
+  else {
+    number_of_code_word = 1;
+  }
+
+  NR_BWP_Uplink_t *ubwp = mac->ULbwp[0];
+  if (mac->cg && ubwp &&
+      mac->cg->spCellConfig &&
+      mac->cg->spCellConfig->spCellConfigDedicated &&
+      mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+      mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) {
+    scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+  }
+  else
+    scs = initialUplinkBWP->genericParameters.subcarrierSpacing;
+
+  slots_per_frame = nr_slots_per_frame[scs];
+
+  /* look for dl acknowledgment which should be done on current uplink slot */
+  for (int code_word = 0; code_word < number_of_code_word; code_word++) {
+
+    for (int dl_harq_pid = 0; dl_harq_pid < 16; dl_harq_pid++) {
+
+      current_harq = &mac->dl_harq_info[dl_harq_pid];
+
+      if (current_harq->active) {
+
+        sched_slot = current_harq->dl_slot + current_harq->feedback_to_ul;
+        sched_frame = current_harq->dl_frame;
+        if (sched_slot>=slots_per_frame){
+          sched_slot %= slots_per_frame;
+          sched_frame++;
+        }
+
+        /* check if current tx slot should transmit downlink acknowlegment */
+        if (sched_frame == frame && sched_slot == slot) {
+
+          if (current_harq->dai > NR_DL_MAX_DAI) {
+            LOG_E(MAC,"PUCCH Downlink DAI has an invalid value : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+          }
+          else {
+
+            if ((pucch->resource_indicator != -1) && (pucch->resource_indicator != current_harq->pucch_resource_indicator))
+              LOG_E(MAC, "Value of pucch_resource_indicator %d not matching with what set before %d (Possibly due to a false DCI) \n",
+                    current_harq->pucch_resource_indicator,pucch->resource_indicator);
+            else{
+              dai_current = current_harq->dai+1; // DCI DAI to counter DAI conversion
+
+              if (dai_current == 0) {
+                LOG_E(MAC,"PUCCH Downlink dai is invalid : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+                return(0);
+              } else if (dai_current > dai_max) {
+                dai_max = dai_current;
+              }
+
+              number_harq_feedback++;
+              if (current_harq->ack_received)
+                ack_data[code_word][dai_current - 1] = current_harq->ack;
+              else
+                ack_data[code_word][dai_current - 1] = 0;
+              dai[code_word][dai_current - 1] = dai_current;
+
+              pucch->resource_indicator = current_harq->pucch_resource_indicator;
+              pucch->n_CCE = current_harq->n_CCE;
+              pucch->N_CCE = current_harq->N_CCE;
+              pucch->delta_pucch = current_harq->delta_pucch;
+              current_harq->active = false;
+              current_harq->ack_received = false;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /* no any ack to transmit */
+  if (number_harq_feedback == 0) {
+    pucch->n_HARQ_ACK = 0;
+    return(0);
+  }
+  else  if (number_harq_feedback > (sizeof(uint32_t)*8)) {
+    LOG_E(MAC,"PUCCH number of ack bits exceeds payload size : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+    return(0);
+  }
+
+  /* for computing n_HARQ_ACK for power */
+  V_DAI_m_DL = dai_max;
+  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->cg != NULL &&
+      mac->cg->physicalCellGroupConfig != NULL &&
+      mac->cg->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH != NULL) {
+    int N_TB_max_DL = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI[0];
+    pucch->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", pucch->n_HARQ_ACK, V_DAI_m_DL, U_DAI_c, N_TB_max_DL, N_m_c_rx);
+  }
+
+  /*
+  * For a monitoring occasion of a PDCCH with DCI format 1_0 or DCI format 1_1 in at least one serving cell,
+  * when a UE receives a PDSCH with one transport block and the value of higher layer parameter maxNrofCodeWordsScheduledByDCI is 2,
+  * the HARQ-ACK response is associated with the first transport block and the UE generates a NACK for the second transport block
+  * if spatial bundling is not applied (HARQ-ACK-spatial-bundling-PUCCH = FALSE) and generates HARQ-ACK value of ACK for the second
+  * transport block if spatial bundling is applied.
+  */
+
+  for (int code_word = 0; code_word < number_of_code_word; code_word++) {
+    for (uint32_t i = 0; i < dai_max ; i++ ) {
+      if (dai[code_word][i] != i + 1) { /* fill table with consistent value for each dai */
+        dai[code_word][i] = i + 1;      /* it covers case for which PDCCH DCI has not been successfully decoded and so it has been missed */
+        ack_data[code_word][i] = 0;     /* nack data transport block which has been missed */
+        number_harq_feedback++;
+      }
+      if (two_transport_blocks == TRUE) {
+        dai_total[code_word][i] = dai[code_word][i]; /* for a single cell, dai_total is the same as dai of first cell */
+      }
+    }
+  }
+
+  int M = dai_max;
+  int j = 0;
+  uint32_t V_temp = 0;
+  uint32_t V_temp2 = 0;
+  int O_ACK = 0;
+  int o_ACK = 0;
+  int O_bit_number_cw0 = 0;
+  int O_bit_number_cw1 = 0;
+
+  for (int m = 0; m < M ; m++) {
+
+    if (dai[0][m] <= V_temp) {
+      j = j + 1;
+    }
+
+    V_temp = dai[0][m]; /* value of the counter DAI for format 1_0 and format 1_1 on serving cell c */
+
+    if (dai_total[0][m] == 0) {
+      V_temp2 = dai[0][m];
+    } else {
+      V_temp2 = dai[1][m];         /* second code word has been received */
+      O_bit_number_cw1 = (8 * j) + 2*(V_temp - 1) + 1;
+      o_ACK = o_ACK | (ack_data[1][m] << O_bit_number_cw1);
+    }
+
+    if (two_transport_blocks == TRUE) {
+      O_bit_number_cw0 = (8 * j) + 2*(V_temp - 1);
+    }
+    else {
+      O_bit_number_cw0 = (4 * j) + (V_temp - 1);
+    }
+
+    o_ACK = o_ACK | (ack_data[0][m] << O_bit_number_cw0);
+  }
+
+  if (V_temp2 < V_temp) {
+    j = j + 1;
+  }
+
+  if (two_transport_blocks == TRUE) {
+    O_ACK = 2 * ( 4 * j + V_temp2);  /* for two transport blocks */
+  }
+  else {
+    O_ACK = 4 * j + V_temp2;         /* only one transport block */
+  }
+
+  if (number_harq_feedback != O_ACK) {
+    LOG_E(MAC,"PUCCH Error for number of bits for acknowledgment : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+    return (0);
+  }
+
+  pucch->ack_payload = o_ACK;
+
+  return(number_harq_feedback);
+}
+
+
+bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac,
+                                         PUCCH_sched_t *pucch,
+                                         frame_t frame,
+                                         int slot) {
+
+  NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
+  NR_PUCCH_Config_t *pucch_Config = NULL;
+  int scs;
+  NR_BWP_Uplink_t *ubwp = mac->ULbwp[0];
+  NR_BWP_UplinkCommon_t *initialUplinkBWP;
+  if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP;
+  else          initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP;
+
+  if (mac->cg && ubwp &&
+      mac->cg->spCellConfig &&
+      mac->cg->spCellConfig->spCellConfigDedicated &&
+      mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+      mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) {
+    scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+  }
+  else
+    scs = initialUplinkBWP->genericParameters.subcarrierSpacing;
+
+  const int n_slots_frame = nr_slots_per_frame[scs];
+
+  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;
+  }
+  if(!pucch_Config || pucch_Config->schedulingRequestResourceToAddModList->list.count==0)
+    return false; // SR not configured
+
+  for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) {
+    NR_SchedulingRequestResourceConfig_t *SchedulingRequestResourceConfig = pucch_Config->schedulingRequestResourceToAddModList->list.array[SR_resource_id];
+    int SR_period; int SR_offset;
+
+    find_period_offest_SR(SchedulingRequestResourceConfig,&SR_period,&SR_offset);
+    int sfn_sf = frame * n_slots_frame + slot;
+
+    if ((sfn_sf - SR_offset) % SR_period == 0) {
+      LOG_D(MAC, "Scheduling Request active in frame %d slot %d \n", frame, slot);
+      NR_PUCCH_ResourceId_t *PucchResourceId = SchedulingRequestResourceConfig->resource;
+
+      int found = -1;
+      NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[0]; // set with formats 0,1
+      int n_list = pucchresset->resourceList.list.count;
+       for (int i=0; i<n_list; i++) {
+        if (*pucchresset->resourceList.list.array[i] == *PucchResourceId ) {
+          found = i;
+          break;
+        }
+      }
+      if (found == -1) {
+        LOG_E(MAC,"Couldn't find PUCCH resource for SR\n");
+        return false;
+      }
+      pucch->resource_indicator = found;
+      return true;
+    }
+  }
+  return false;
+}
+
 
+int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, int slotP){
   return 0;
 }
 
+
+uint8_t nr_get_csi_measurements(NR_UE_MAC_INST_t *mac,
+                                frame_t frame,
+                                int slot,
+                                PUCCH_sched_t *pucch) {
+
+  NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
+  NR_PUCCH_Config_t *pucch_Config = NULL;
+  int csi_bits = 0;
+
+  if(mac->cg &&
+     mac->cg->spCellConfig &&
+     mac->cg->spCellConfig->spCellConfigDedicated &&
+     mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig) {
+
+    NR_CSI_MeasConfig_t *csi_measconfig = mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
+
+    for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
+      NR_CSI_ReportConfig_t *csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
+
+      if(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_periodic){
+        int period, offset;
+        csi_period_offset(csirep, NULL, &period, &offset);
+
+        int scs;
+        NR_BWP_Uplink_t *ubwp = mac->ULbwp[0];
+        NR_BWP_UplinkCommon_t *initialUplinkBWP;
+        if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP;
+        else          initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP;
+
+        if (ubwp &&
+            mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+            mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP)
+          scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+        else
+          scs = initialUplinkBWP->genericParameters.subcarrierSpacing;
+
+        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->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;
+        }
+
+        const int n_slots_frame = nr_slots_per_frame[scs];
+        if (((n_slots_frame*frame + slot - offset)%period) == 0 && pucch_Config) {
+
+          NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0];
+          NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[1]; // set with formats >1
+          int n = pucchresset->resourceList.list.count;
+
+          int res_index;
+          int found = -1;
+          for (res_index = 0; res_index < n; res_index++) {
+            if (*pucchresset->resourceList.list.array[res_index] == pucchcsires->pucch_Resource) {
+              found = res_index;
+              break;
+            }
+          }
+          AssertFatal(found != -1,
+                      "CSI resource not found among PUCCH resources\n");
+
+          pucch->resource_indicator = found;
+          csi_bits = nr_get_csi_payload(mac, pucch, csi_measconfig);
+        }
+      }
+      else
+        AssertFatal(1==0,"Only periodic CSI reporting is currently implemented\n");
+    }
+  }
+
+  return csi_bits;
+}
+
+
+uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
+                           PUCCH_sched_t *pucch,
+                           NR_CSI_MeasConfig_t *csi_MeasConfig) {
+
+  int n_csi_bits = 0;
+
+  AssertFatal(csi_MeasConfig->csi_ReportConfigToAddModList->list.count>0,"No CSI Report configuration available\n");
+
+  for (int csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
+    struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
+    NR_CSI_ResourceConfigId_t csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
+    switch(csi_reportconfig->reportQuantity.present) {
+      case NR_CSI_ReportConfig__reportQuantity_PR_none:
+        break;
+      case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
+        n_csi_bits += get_ssb_rsrp_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
+        break;
+      case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
+      case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
+      case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1:
+      case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI:
+      case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
+      case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
+        AssertFatal(1==0,"Measurement report based on CSI-RS not availalble\n");
+      default:
+        AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present);
+    }
+  }
+  return (n_csi_bits);
+}
+
+
+uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
+                             PUCCH_sched_t *pucch,
+                             struct NR_CSI_ReportConfig *csi_reportconfig,
+                             NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
+                             NR_CSI_MeasConfig_t *csi_MeasConfig) {
+
+  int nb_ssb = 0;  // nb of ssb in the resource
+  int nb_meas = 0; // nb of ssb to report measurements on
+  int bits = 0;
+  uint32_t temp_payload = 0;
+
+  for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) {
+    struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
+    if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) {
+
+      if (csi_reportconfig->groupBasedBeamReporting.present == NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled) {
+        if (csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS != NULL)
+          nb_meas = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1;
+        else
+          nb_meas = 1;
+      } else
+        nb_meas = 2;
+
+      for (int csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) {
+        if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId ==
+            *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){
+
+          ///only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
+          nb_ssb = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.count;
+          break;
+        }
+      }
+
+      AssertFatal(nb_ssb>0,"No SSB found in the resource set\n");
+      int ssbri_bits = ceil(log2(nb_ssb));
+
+      //TODO measurement of multiple SSBs at PHY and indication to MAC
+      if(nb_ssb>1)
+        LOG_E(MAC, "In current implementation only the SSB of synchronization is measured at PHY. This works only for a single SSB scenario\n");
+
+      int ssb_rsrp[2][nb_meas]; // the array contains index and RSRP of each SSB to be reported (nb_meas highest RSRPs)
+
+      //TODO replace the following 2 lines with a function to order the nb_meas highest SSB RSRPs
+      ssb_rsrp[0][0] = mac->mib_ssb;
+      ssb_rsrp[1][0] = mac->ssb_rsrp_dBm;
+
+      uint8_t ssbi;
+
+      if (ssbri_bits > 0) {
+        ssbi = ssb_rsrp[0][0];
+        reverse_n_bits(&ssbi, ssbri_bits);
+        temp_payload = ssbi;
+        bits += ssbri_bits;
+      }
+
+      uint8_t rsrp_idx = get_rsrp_index(ssb_rsrp[1][0]);
+      reverse_n_bits(&rsrp_idx, 7);
+      temp_payload |= (rsrp_idx<<bits);
+      bits += 7; // 7 bits for highest RSRP
+
+      // from the second SSB, differential report
+      for (int i=1; i<nb_meas; i++){
+        ssbi = ssb_rsrp[0][i];
+        reverse_n_bits(&ssbi, ssbri_bits);
+        temp_payload = ssbi;
+        bits += ssbri_bits;
+
+        rsrp_idx = get_rsrp_diff_index(ssb_rsrp[1][0],ssb_rsrp[1][i]);
+        reverse_n_bits(&rsrp_idx, 4);
+        temp_payload |= (rsrp_idx<<bits);
+        bits += 4; // 7 bits for highest RSRP
+      }
+      break; // resorce found
+    }
+  }
+  pucch->csi_part1_payload = temp_payload;
+  return bits;
+}
+
+
+// returns index from RSRP
+// according to Table 10.1.6.1-1 in 38.133
+
+uint8_t get_rsrp_index(int rsrp) {
+
+  int index = rsrp + 157;
+  if (rsrp>-44)
+    index = 113;
+  if (rsrp<-140)
+    index = 16;
+
+  return index;
+}
+
+
+// returns index from differential RSRP
+// according to Table 10.1.6.1-2 in 38.133
+uint8_t get_rsrp_diff_index(int best_rsrp,int current_rsrp) {
+
+  int diff = best_rsrp-current_rsrp;
+  if (diff>30)
+    return 15;
+  else
+    return (diff>>1);
+
+}
+
 void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN);
@@ -1119,55 +2428,38 @@ int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type){
 }
 
 uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
-			 uint8_t dci_format,
-			 uint8_t dci_size,
-			 uint16_t rnti,
-			 uint64_t *dci_pdu,
-			 dci_pdu_rel15_t *dci_pdu_rel15) {
-
-  int rnti_type = get_rnti_type(mac, rnti);
+                            uint8_t dci_format,
+                            uint8_t dci_size,
+                            uint16_t rnti,
+                            uint64_t *dci_pdu,
+                            dci_pdu_rel15_t *dci_pdu_rel15) {
 
-  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 N_RB_UL = (mac->scg != NULL) ? 
-    NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) :
-    NRRIV2BW(mac->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  int N_RB = 0;
+  int pos = 0;
+  int fsize = 0;
 
-  int pos=0;
-  int fsize=0;
-
-  if (rnti_type == NR_RNTI_C) {
-    // First find out the DCI format from the first bit (UE performed blind decoding)
-    pos++;
-    dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
-#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
+  int rnti_type = get_rnti_type(mac, rnti);
 
-    if (dci_format == NR_UL_DCI_FORMAT_0_0 || dci_format == NR_DL_DCI_FORMAT_1_0) {
-      if (dci_pdu_rel15->format_indicator == 0) 
-        dci_format = NR_UL_DCI_FORMAT_0_0;
-      else
-        dci_format = NR_DL_DCI_FORMAT_1_0;
-    }
-    else if (dci_format == NR_UL_DCI_FORMAT_0_1 || dci_format == NR_DL_DCI_FORMAT_1_1) {
-      // In case the sizes of formats 0_1 and 1_1 happen to be the same
-      if (dci_pdu_rel15->format_indicator == 0) 
-        dci_format = NR_UL_DCI_FORMAT_0_1;
-      else
-        dci_format = NR_DL_DCI_FORMAT_1_1;
-    }
+  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[0]) {
+    N_RB_UL = NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  } else if(mac->scc) {
+    N_RB_UL = NRRIV2BW(mac->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
   }
-#ifdef DEBUG_EXTRACT_DCI
-  LOG_D(MAC, "DCI format is %d\n", dci_format);
-#endif
-  
+
+  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;
@@ -1203,7 +2495,23 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
       break;
 
     case NR_RNTI_C:
-	
+
+      //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 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[0]) N_RB=NRRIV2BW(mac->DLbwp[0]->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;
@@ -1313,7 +2621,7 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
 	  
       } //end else
       break;
-    	
+
     case NR_RNTI_P:
       /*
       // Short Messages Indicator  E2 bits
@@ -1343,110 +2651,184 @@ 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:
-      // indicating a DL DCI format 1bit
+
+      // check BWP id
+      if (mac->DLbwp[0]) N_RB=NRRIV2BW(mac->DLbwp[0]->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;
-      // Freq domain assignment 0-16 bit
+
+      if (dci_pdu_rel15->format_indicator == 0)
+        return 1; // discard dci, format indicator not corresponding to dci_format
+
+        // 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
+
+      // Time domain assignment - 4 bits
       pos+=4;
       dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf;
-      // VRB to PRB mapping 1 bit
+
+      // VRB to PRB mapping - 1 bit
+      pos++;
       dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&1;
+
       // MCS 5bit  //bit over 32, so dci_pdu ++
       pos+=5;
       dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f;
-      // New data indicator 1bit
+
+      // New data indicator - 1 bit
+      pos++;
       dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&1;
-      // Redundancy version  2bit
+
+      // Redundancy version - 2 bits
       pos+=2;
       dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&3;
-      // HARQ process number  4bit
+
+      // HARQ process number - 4 bits
       pos+=4;
       dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
-      // Downlink assignment index  E2 bits
+
+      // Downlink assignment index - 2 bits
       pos+=2;
       dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&3;
-      // TPC command for scheduled PUCCH  E2 bits
+
+      // TPC command for scheduled PUCCH - 2 bits
       pos+=2;
       dci_pdu_rel15->tpc  = (*dci_pdu>>(dci_size-pos))&3;
-      // PDSCH-to-HARQ_feedback timing indicator  E3 bits
+
+      // PUCCH resource indicator - 3 bits
+      pos+=3;
+      dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&7;
+
+      // PDSCH-to-HARQ_feedback timing indicator - 3 bits
       pos+=3;
       dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&7;
-       
+
+      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->format_indicator = %i\n", dci_pdu_rel15->format_indicator);
+      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->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val);
+      LOG_D(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs);
+      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->dai[0].val = %i\n", dci_pdu_rel15->dai[0].val);
+      LOG_D(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc);
+      LOG_D(NR_MAC,"dci_pdu_rel15->pucch_resource_indicator = %i\n", dci_pdu_rel15->pucch_resource_indicator);
+      LOG_D(NR_MAC,"dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = %i\n", dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val);
+
       break;
     }
     break;
   
   case NR_UL_DCI_FORMAT_0_0:
+    if (mac->ULbwp[0]) N_RB_UL=NRRIV2BW(mac->ULbwp[0]->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)
@@ -1498,6 +2880,11 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
   switch(rnti_type)
     {
       case NR_RNTI_C:
+        //Identifier for DCI formats
+        pos++;
+        dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
+        if (dci_pdu_rel15->format_indicator == 0)
+          return 1; // discard dci, format indicator not corresponding to dci_format
         // Carrier indicator
         pos+=dci_pdu_rel15->carrier_indicator.nbits;
         dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1);
@@ -1583,6 +2970,11 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
     switch(rnti_type)
       {
       case NR_RNTI_C:
+        //Identifier for DCI formats
+        pos++;
+        dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
+        if (dci_pdu_rel15->format_indicator == 1)
+          return 1; // discard dci, format indicator not corresponding to dci_format
         // Carrier indicator
         pos+=dci_pdu_rel15->carrier_indicator.nbits;
         dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1);
@@ -1597,10 +2989,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
@@ -1691,7 +3080,7 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
     break;
        }
     
-    return dci_format;
+    return 0;
 }
 
 ///////////////////////////////////
@@ -1736,7 +3125,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;
-  uint16_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;
@@ -1747,32 +3136,54 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
     return;
   }
 
-  LOG_D(MAC, "In %s [%d.%d]: processing PDU %d of %d total number of PDUs...\n", __FUNCTION__, frameP, slot, pdu_id, dl_info->rx_ind->number_pdus);
+  LOG_D(MAC, "In %s [%d.%d]: processing PDU %d (with length %d) of %d total number of PDUs...\n", __FUNCTION__, frameP, slot, pdu_id, pdu_len, dl_info->rx_ind->number_pdus);
 
     while (!done && pdu_len > 0){
         mac_ce_len = 0x0000;
         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){
             //  MAC CE
 
             case DL_SCH_LCID_CCCH:
-                //  MSG4 RRC Connection Setup 38.331
-                //  varialbe length
-                mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
+              //  MSG4 RRC Setup 38.331
+              //  variable length
+              if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
+                mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8)
+                              | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff);
+                mac_subheader_len = 3;
+              } else {
+                mac_sdu_len = ((NR_MAC_SUBHEADER_SHORT *) pduP)->L;
                 mac_subheader_len = 2;
-                if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
-                    mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
-                    mac_subheader_len = 3;
-                }
+              }
 
+              // Check if it is a valid CCCH message, we get all 00's messages very often
+              int i = 0;
+              for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) {
+                if(pduP[i] != 0) {
+                  break;
+                }
+              }
+              if (i == (mac_subheader_len+mac_sdu_len)) {
+                LOG_D(NR_MAC, "%s() Invalid CCCH message!, pdu_len: %d\n", __func__, pdu_len);
+                done = 1;
                 break;
+              }
+
+              if ( mac_sdu_len > 0 ) {
+                LOG_D(NR_MAC,"DL_SCH_LCID_CCCH (e.g. RRCSetup) with payload len %d\n", mac_sdu_len);
+                for (int i = 0; i < mac_subheader_len; i++) {
+                  LOG_D(NR_MAC, "MAC header %d: 0x%x\n", i, pduP[i]);
+                }
+                for (int i = 0; i < mac_sdu_len; i++) {
+                  LOG_D(NR_MAC, "%d: 0x%x\n", i, pduP[mac_subheader_len + i]);
+                }
+                nr_mac_rrc_data_ind_ue(module_idP, CC_id, gNB_index, frameP, 0, mac->crnti, CCCH, pduP+mac_subheader_len, mac_sdu_len);
+              }
+              break;
 
             case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH:
 
@@ -1879,17 +3290,34 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
 
                 break;
             case DL_SCH_LCID_CON_RES_ID:
-                //  Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16
-                // WIP todo: handle CCCH_pdu
-                mac_ce_len = 6;
-                
-                LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", module_idP, frameP, pduP[0], pduP[1], pduP[2], pduP[3], pduP[4], pduP[5]);
+              //  Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16
+              // MAC Header: 1 byte (R/R/LCID)
+              // MAC SDU: 6 bytes (UE Contention Resolution Identity)
+              mac_ce_len = 6;
+
+              if(ra->ra_state == WAIT_CONTENTION_RESOLUTION) {
+                LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution identity: 0x%02x%02x%02x%02x%02x%02x Terminating RA procedure\n",
+                      module_idP, frameP, pduP[1], pduP[2], pduP[3], pduP[4], pduP[5], pduP[6]);
+
+                bool ra_success = true;
+                for(int i = 0; i<mac_ce_len; i++) {
+                  if(ra->cont_res_id[i] != pduP[i+1]) {
+                    ra_success = false;
+                    break;
+                  }
+                }
 
-                if (ra->RA_active == 1) {
+                if ( (ra->RA_active == 1) && ra_success) {
                   nr_ra_succeeded(module_idP, frameP, slot);
+                } else if (!ra_success){
+                  // TODO: Handle failure of RA procedure @ MAC layer
+                  //  nr_ra_failed(module_idP, CC_id, prach_resources, frameP, slot); // prach_resources is a PHY structure
+                  ra->ra_state = RA_UE_IDLE;
+                  ra->RA_active = 0;
                 }
+              }
 
-                break;
+              break;
             case DL_SCH_LCID_PADDING:
                 done = 1;
                 //  end of MAC PDU, can ignore the rest.
@@ -1927,8 +3355,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,
@@ -1944,14 +3372,14 @@ 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;
         }
         pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
         pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
         if (pdu_len < 0)
-          LOG_E(MAC, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", pdu_len);
+          LOG_E(MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", module_idP, frameP, slot, pdu_len);
     }
 }
 
@@ -1973,22 +3401,19 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
                                     uint16_t buflen) {
 
   NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) pdu;
-  unsigned char last_size = 0, i, mac_header_control_elements[16], *ce_ptr, bsr = 0;
-  int mac_ce_size;
-  uint16_t offset = 0;
 
   LOG_D(MAC, "[UE] Generating ULSCH PDU : num_sdus %d\n", num_sdus);
 
   #ifdef DEBUG_HEADER_PARSING
 
-    for (i = 0; i < num_sdus; i++)
+    for (int i = 0; i < num_sdus; i++)
       LOG_D(MAC, "[UE] MAC subPDU %d (lcid %d length %d bytes \n", i, sdu_lcids[i], sdu_lengths[i]);
 
   #endif
 
   // Generating UL MAC subPDUs including MAC SDU and subheader
 
-  for (i = 0; i < num_sdus; i++) {
+  for (int i = 0; i < num_sdus; i++) {
     LOG_D(MAC, "[UE] Generating UL MAC subPDUs for SDU with lenght %d ( num_sdus %d )\n", sdu_lengths[i], num_sdus);
 
     if (sdu_lcids[i] != UL_SCH_LCID_CCCH){
@@ -1997,22 +3422,21 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
         ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
         ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i];
         ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i];
-        last_size = 2;
+        mac_pdu_ptr += sizeof(NR_MAC_SUBHEADER_SHORT);
       } else {
         ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0;
         ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1;
         ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i];
         ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f;
         ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff;
-        last_size = 3;
+        mac_pdu_ptr += sizeof(NR_MAC_SUBHEADER_LONG);
       }
     } else { // UL CCCH SDU
       mac_pdu_ptr->R = 0;
       mac_pdu_ptr->LCID = sdu_lcids[i];
+      mac_pdu_ptr ++;
     }
 
-    mac_pdu_ptr += last_size;
-
     // cycle through SDUs, compute each relevant and place ulsch_buffer in
     memcpy((void *) mac_pdu_ptr, (void *) sdus_payload, sdu_lengths[i]);
     sdus_payload += sdu_lengths[i]; 
@@ -2021,8 +3445,6 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
 
   // Generating UL MAC subPDUs including MAC CEs (MAC CE and subheader)
 
-  ce_ptr = &mac_header_control_elements[0];
-
   if (power_headroom) {
     // MAC CE fixed subheader
     mac_pdu_ptr->R = 0;
@@ -2030,17 +3452,11 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
     mac_pdu_ptr++;
 
     // PHR MAC CE (1 octet)
-    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PH = power_headroom;
-    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R1 = 0;
-    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PCMAX = 0; // todo
-    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R2 = 0;
-
-    mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
-
-    // Copying bytes for PHR MAC CEs to the mac pdu pointer
-    memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
-    ce_ptr += mac_ce_size;
-    mac_pdu_ptr += (unsigned char) mac_ce_size;
+    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->PH = power_headroom;
+    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->R1 = 0;
+    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->PCMAX = 0; // todo
+    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->R2 = 0;
+    mac_pdu_ptr += sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
   }
 
   if (crnti) {
@@ -2050,13 +3466,8 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
     mac_pdu_ptr++;
 
     // C-RNTI MAC CE (2 octets)
-    * (uint16_t *) ce_ptr = crnti;
-    mac_ce_size = sizeof(uint16_t);
-
-    // Copying bytes for CRNTI MAC CE to the mac pdu pointer
-    memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
-    ce_ptr += mac_ce_size;
-    mac_pdu_ptr += (unsigned char) mac_ce_size;
+    * (uint16_t *) mac_pdu_ptr = crnti;
+    mac_pdu_ptr += sizeof(uint16_t);
   }
 
   if (truncated_bsr) {
@@ -2066,11 +3477,9 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
     mac_pdu_ptr++;
 
     // Short truncated BSR MAC CE (1 octet)
-    ((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> Buffer_size = truncated_bsr;
-    ((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> LcgID = 0; // todo
-    mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED);
-
-    bsr = 1 ;
+    ((NR_BSR_SHORT_TRUNCATED *) mac_pdu_ptr)-> Buffer_size = truncated_bsr;
+    ((NR_BSR_SHORT_TRUNCATED *) mac_pdu_ptr)-> LcgID = 0; // todo
+    mac_pdu_ptr+= sizeof(NR_BSR_SHORT_TRUNCATED);
   } else if (short_bsr) {
     // MAC CE fixed subheader
     mac_pdu_ptr->R = 0;
@@ -2078,11 +3487,9 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
     mac_pdu_ptr++;
 
     // Short truncated BSR MAC CE (1 octet)
-    ((NR_BSR_SHORT *) ce_ptr)->Buffer_size = short_bsr;
-    ((NR_BSR_SHORT *) ce_ptr)->LcgID = 0; // todo
-    mac_ce_size = sizeof(NR_BSR_SHORT);
-
-    bsr = 1 ;
+    ((NR_BSR_SHORT *) mac_pdu_ptr)->Buffer_size = short_bsr;
+    ((NR_BSR_SHORT *) mac_pdu_ptr)->LcgID = 0; // todo
+     mac_pdu_ptr+= sizeof(NR_BSR_SHORT);
   } else if (long_bsr) {
     // MAC CE variable subheader
     // todo ch 6.1.3.1. TS 38.321
@@ -2098,36 +3505,21 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
     // ((NR_BSR_LONG *) ce_ptr)->LCGID0 = 0;
     // mac_ce_size = sizeof(NR_BSR_LONG); // size is variable
   }
-
-  if (bsr){
-    // Copying bytes for BSR MAC CE to the mac pdu pointer
-    memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
-    ce_ptr += mac_ce_size;
-    mac_pdu_ptr += (unsigned char) mac_ce_size;
-  }
-
-  // compute offset before adding padding (if necessary)
-  offset = ((unsigned char *) mac_pdu_ptr - pdu);
-  uint16_t padding_bytes = 0; 
+// compute offset before adding padding (if necessary)
+  int padding_bytes = 0; 
 
   if(buflen > 0) // If the buflen is provided
-    padding_bytes = buflen - offset;
+    padding_bytes = buflen + pdu - (unsigned char *) mac_pdu_ptr;
+
+  AssertFatal(padding_bytes>=0,"");
 
   // Compute final offset for padding
-  if (post_padding > 0 || padding_bytes>0) {
+  if (post_padding || padding_bytes>0) {
     ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
     ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING;
     mac_pdu_ptr++;
-  } else {            
-    // no MAC subPDU with padding
-  }
-
-  // compute final offset
-  offset = ((unsigned char *) mac_pdu_ptr - pdu);
-
-  //printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - pdu));
-
-  return offset;
+  } 
+  return (uint8_t *)mac_pdu_ptr-pdu;
 }
 
 /////////////////////////////////////
@@ -2184,27 +3576,32 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
   NR_MAC_RAR *rar          = (NR_MAC_RAR *) (dlsch_buffer + 1);   // RAR subPDU pointer
   uint8_t preamble_index   = get_ra_PreambleIndex(mod_id, cc_id, gNB_id); //prach_resources->ra_PreambleIndex;
 
-  LOG_D(MAC, "In %s:[%d.%d]: [UE %d][RAPROC] invoking MAC for received RAR (current preamble %d)\n", __FUNCTION__, frame, slot, mod_id, preamble_index);
+  LOG_D(NR_MAC, "In %s:[%d.%d]: [UE %d][RAPROC] invoking MAC for received RAR (current preamble %d)\n", __FUNCTION__, frame, slot, mod_id, preamble_index);
 
   while (1) {
     n_subheaders++;
     if (rarh->T == 1) {
       n_subPDUs++;
-      LOG_D(MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mod_id);
+      LOG_I(NR_MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mod_id);
     } else {
-      n_subPDUs++;
       ra->RA_backoff_indicator = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI];
       ra->RA_BI_found = 1;
-      LOG_D(MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d\n", mod_id, ra->RA_backoff_indicator);
+      LOG_I(NR_MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d ms\n", mod_id, ra->RA_backoff_indicator);
+      if ( ((NR_RA_HEADER_BI *)rarh)->E == 1) {
+        rarh += sizeof(NR_RA_HEADER_BI);
+        continue;
+      } else {
+        break;
+      }
     }
     if (rarh->RAPID == preamble_index) {
-      LOG_I(MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID);
+      LOG_I(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID);
       rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR));
       ra->RA_RAPID_found = 1;
       break;
     }
     if (rarh->E == 0) {
-      LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match the intended RAPID...\n", mod_id, preamble_index);
+      LOG_W(NR_MAC,"[UE %d][RAPROC][%d.%d] Received RAR preamble (%d) doesn't match the intended RAPID (%d)\n", mod_id, frame, slot, rarh->RAPID, preamble_index);
       break;
     } else {
       rarh += sizeof(NR_MAC_RAR) + 1;
@@ -2230,7 +3627,7 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
 
   // TA command
   ul_time_alignment->apply_ta = 1;
-  ul_time_alignment->ta_command = rar->TA2 + (rar->TA1 << 5);
+  ul_time_alignment->ta_command = 31 + rar->TA2 + (rar->TA1 << 5);
 
 #ifdef DEBUG_RAR
   // CSI
@@ -2280,21 +3677,37 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
       rnti = mac->crnti;
     }
 
-  #ifdef DEBUG_RAR
-  LOG_D(MAC, "In %s:[%d.%d]: [UE %d] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti %x \n",
-    __FUNCTION__,
-    frame,
-    slot,
-    mod_id,
-    rar_grant.Msg3_t_alloc,
-    rar_grant.Msg3_f_alloc,
-    ul_time_alignment->ta_command,
-    rar_grant.mcs,
-    rar_grant.freq_hopping,
-    tpc_command,
-    csi_req,
-    ra->t_crnti);
-  #endif
+#ifdef DEBUG_RAR
+    LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E);
+    LOG_I(NR_MAC, "rarh->T = 0x%x\n", rarh->T);
+    LOG_I(NR_MAC, "rarh->RAPID = 0x%x (%i)\n", rarh->RAPID, rarh->RAPID);
+
+    LOG_I(NR_MAC, "rar->R = 0x%x\n", rar->R);
+    LOG_I(NR_MAC, "rar->TA1 = 0x%x\n", rar->TA1);
+
+    LOG_I(NR_MAC, "rar->TA2 = 0x%x\n", rar->TA2);
+    LOG_I(NR_MAC, "rar->UL_GRANT_1 = 0x%x\n", rar->UL_GRANT_1);
+
+    LOG_I(NR_MAC, "rar->UL_GRANT_2 = 0x%x\n", rar->UL_GRANT_2);
+    LOG_I(NR_MAC, "rar->UL_GRANT_3 = 0x%x\n", rar->UL_GRANT_3);
+    LOG_I(NR_MAC, "rar->UL_GRANT_4 = 0x%x\n", rar->UL_GRANT_4);
+
+    LOG_I(NR_MAC, "rar->TCRNTI_1 = 0x%x\n", rar->TCRNTI_1);
+    LOG_I(NR_MAC, "rar->TCRNTI_2 = 0x%x\n", rar->TCRNTI_2);
+
+    LOG_I(NR_MAC, "In %s:[%d.%d]: [UE %d] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d t_crnti %x \n",
+      __FUNCTION__,
+      frame,
+      slot,
+      mod_id,
+      rar_grant.Msg3_t_alloc,
+      rar_grant.Msg3_f_alloc,
+      ul_time_alignment->ta_command,
+      rar_grant.mcs,
+      rar_grant.freq_hopping,
+      tpc_command,
+      ra->t_crnti);
+#endif
 
     // Schedule Msg3
     ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, rar_grant.Msg3_t_alloc);
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index d6e1cba6df103f133a755501b0fb9258c0f12d05..5422e8342b3b03c92357126ee70db3fa1dc6a58d 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -51,6 +51,8 @@
 #include "asn1_conversions.h"
 #include "SIMULATION/TOOLS/sim.h" // for taus
 
+#include <executables/softmodem-common.h>
+
 static prach_association_pattern_t prach_assoc_pattern;
 static ssb_list_info_t ssb_list;
 
@@ -61,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);
 
 }
 
@@ -93,24 +95,36 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
 long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) {
   long k2 = -1;
   // Get K2 from RRC configuration
-  NR_PUSCH_Config_t *pusch_config=mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
+  NR_PUSCH_Config_t *pusch_config=mac->ULbwp[0] ? mac->ULbwp[0]->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[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+  else if (mac->ULbwp[0] &&
+	   mac->ULbwp[0]->bwp_Common&&
+	   mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon&&
+	   mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup &&
+	   mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
     pusch_TimeDomainAllocationList = mac->ULbwp[0]->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;
     }
     k2 = *pusch_TimeDomainAllocationList->list.array[time_domain_ind]->k2;
   }
-  
-  LOG_D(MAC, "get_k2(): k2 is %ld\n", k2);
+
+  AssertFatal(k2 >= DURATION_RX_TO_TX,
+              "Slot offset K2 (%ld) cannot be less than DURATION_RX_TO_TX (%d)\n",
+              k2,DURATION_RX_TO_TX);
+
+  LOG_D(NR_MAC, "get_k2(): k2 is %ld\n", k2);
   return k2;
 }
 
@@ -118,23 +132,28 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) {
  * This function returns the UL config corresponding to a given UL slot
  * from MAC instance .
  */
-fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot) {
+fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot)
+{
+  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) == 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[0]->bwp_Common->genericParameters.subcarrierSpacing;
-  NR_TDD_UL_DL_Pattern_t *tdd_pattern = &mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1;
+  int mu = mac->ULbwp[0] ?
+    mac->ULbwp[0]->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);
@@ -144,14 +163,25 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl
 
 void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) {
 
-  fapi_nr_pusch_config_dedicated_t *pusch_config_dedicated = &mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated;
+  NR_ServingCellConfigCommon_t *scc = mac->scc;
   NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
 
+  long	transformPrecoder;
+  if (pusch_Config->transformPrecoder)
+    transformPrecoder = *pusch_Config->transformPrecoder;
+  else {
+    if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder)
+      transformPrecoder = NR_PUSCH_Config__transformPrecoder_enabled;
+    else
+      transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled;
+  }
+
+
   /* PRECOD_NBR_LAYERS */
-  if ((pusch_config_dedicated->tx_config == tx_config_nonCodebook));
+  if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_nonCodebook));
   // 0 bits if the higher layer parameter txConfig = nonCodeBook
 
-  if ((pusch_config_dedicated->tx_config == tx_config_codebook)){
+  if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)){
 
     uint8_t n_antenna_port = 0; //FIXME!!!
 
@@ -160,43 +190,43 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con
     if (n_antenna_port == 4){ // 4 antenna port and the higher layer parameter txConfig = codebook
 
       // Table 7.3.1.1.2-2: transformPrecoder=disabled and maxRank = 2 or 3 or 4
-      if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled)
-        && ((pusch_config_dedicated->max_rank == 2) ||
-        (pusch_config_dedicated->max_rank == 3) ||
-        (pusch_config_dedicated->max_rank == 4))){
+      if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)
+        && ((*pusch_Config->maxRank == 2) ||
+        (*pusch_Config->maxRank == 3) ||
+        (*pusch_Config->maxRank == 4))){
 
-        if (pusch_config_dedicated->codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) {
+        if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) {
           pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][0];
           pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][1];
         }
 
-        if (pusch_config_dedicated->codebook_subset == codebook_subset_partialAndNonCoherent){
+        if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent){
           pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][2];
           pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][3];
         }
 
-        if (pusch_config_dedicated->codebook_subset == codebook_subset_nonCoherent){
+        if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){
           pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][4];
           pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][5];
         }
       }
 
       // Table 7.3.1.1.2-3: transformPrecoder= enabled, or transformPrecoder=disabled and maxRank = 1
-      if (((pusch_config_dedicated->transform_precoder == transform_precoder_enabled)
-        || (pusch_config_dedicated->transform_precoder == transform_precoder_disabled))
-        && (pusch_config_dedicated->max_rank == 1)){
+      if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled)
+        || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled))
+        && (*pusch_Config->maxRank == 1)){
 
-        if (pusch_config_dedicated->codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) {
+        if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) {
           pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][6];
           pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][7];
         }
 
-        if (pusch_config_dedicated->codebook_subset == codebook_subset_partialAndNonCoherent){
+        if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent){
           pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][8];
           pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][9];
         }
 
-        if (pusch_config_dedicated->codebook_subset == codebook_subset_nonCoherent){
+        if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){
           pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][10];
           pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][11];
         }
@@ -205,14 +235,14 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con
 
     if (n_antenna_port == 4){ // 2 antenna port and the higher layer parameter txConfig = codebook
       // Table 7.3.1.1.2-4: transformPrecoder=disabled and maxRank = 2
-      if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) && (pusch_config_dedicated->max_rank == 2)){
+      if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank == 2)){
 
-        if (pusch_config_dedicated->codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) {
+        if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) {
           pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][12];
           pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][13];
         }
 
-        if (pusch_config_dedicated->codebook_subset == codebook_subset_nonCoherent){
+        if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){
           pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][14];
           pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][15];
         }
@@ -220,16 +250,16 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con
       }
 
       // Table 7.3.1.1.2-5: transformPrecoder= enabled, or transformPrecoder= disabled and maxRank = 1
-      if (((pusch_config_dedicated->transform_precoder == transform_precoder_enabled)
-        || (pusch_config_dedicated->transform_precoder == transform_precoder_disabled))
-        && (pusch_config_dedicated->max_rank == 1)){
+      if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled)
+        || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled))
+        && (*pusch_Config->maxRank == 1)){
 
-        if (pusch_config_dedicated->codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) {
+        if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) {
           pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][16];
           pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][17];
         }
 
-        if (pusch_config_dedicated->codebook_subset == codebook_subset_nonCoherent){
+        if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){
           pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][18];
           pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][19];
         }
@@ -240,7 +270,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con
 
   /*-------------------- Changed to enable Transform precoding in RF SIM------------------------------------------------*/
 
-  if (pusch_config_pdu->transform_precoding == transform_precoder_enabled) {
+ /*if (pusch_config_pdu->transform_precoding == transform_precoder_enabled) {
 
     pusch_config_dedicated->transform_precoder = transform_precoder_enabled;
 
@@ -264,15 +294,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con
 
     }
   } else
-    pusch_config_dedicated->transform_precoder = transform_precoder_disabled;
-
-  // mapping type b configured from RRC. TBD: Mapping type b is not handled in this function.
-  if ((pusch_config_dedicated->transform_precoder == transform_precoder_enabled) &&
-      (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_b.dmrs_type == 1) &&
-      (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_b.max_length == 1)) { // tables 7.3.1.1.2-6
-    pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2;
-    pusch_config_pdu->dmrs_ports = dci->antenna_ports.val;
-  }
+    pusch_config_dedicated->transform_precoder = transform_precoder_disabled;*/
 }
 
 // todo: this function shall be reviewed completely because of the many comments left by the author
@@ -280,27 +302,47 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf
 
   /* ANTENNA_PORTS */
   uint8_t rank = 0; // We need to initialize rank FIXME!!!
-  fapi_nr_pusch_config_dedicated_t *pusch_config_dedicated = &mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated;
 
-  if ((pusch_config_dedicated->transform_precoder == transform_precoder_enabled) &&
-    (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
-    (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-6
+  NR_ServingCellConfigCommon_t *scc = mac->scc;
+  NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
+
+  long	transformPrecoder;
+  if (pusch_Config->transformPrecoder)
+    transformPrecoder = *pusch_Config->transformPrecoder;
+  else {
+    if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder)
+      transformPrecoder = NR_PUSCH_Config__transformPrecoder_enabled;
+    else
+      transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled;
+  }
+  long *max_length = NULL;
+  long *dmrs_type = NULL;
+  if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA) {
+    max_length = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->maxLength;
+    dmrs_type = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->dmrs_Type;
+  }
+  else {
+    max_length = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->maxLength;
+    dmrs_type = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->dmrs_Type;
+  }
+
+
+  if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) &&
+    (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-6
       pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC
       pusch_config_pdu->dmrs_ports = dci->antenna_ports.val; //TBC
   }
 
-  if ((pusch_config_dedicated->transform_precoder == transform_precoder_enabled) &&
-    (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
-    (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-7
+  if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) &&
+    (dmrs_type == NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-7
 
     pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC
     pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 3)?(dci->antenna_ports.val-4):(dci->antenna_ports.val); //TBC
     //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports > 3)?2:1; //FIXME
   }
 
-  if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) &&
-    (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
-    (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-8/9/10/11
+  if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) &&
+    (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-8/9/10/11
 
     if (rank == 1) {
       pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC
@@ -332,9 +374,8 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf
     }
   }
 
-  if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) &&
-    (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
-    (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-12/13/14/15
+  if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) &&
+    (dmrs_type == NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-12/13/14/15
 
     if (rank == 1){
       pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC
@@ -370,9 +411,9 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf
     }
   }
 
-  if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) &&
-    (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 2) &&
-    (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-16/17/18/19
+  if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) &&
+    (dmrs_type != NULL) &&
+    (max_length == NULL)) { // tables 7.3.1.1.2-16/17/18/19
 
     if (rank == 1){
       pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?((dci->antenna_ports.val > 5)?3:2):1; //TBC
@@ -404,9 +445,8 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf
     }
   }
 
-  if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) &&
-    (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 2) &&
-    (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-20/21/22/23
+  if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) &&
+    (dmrs_type != NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-20/21/22/23
 
     if (rank == 1){
       pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_20[dci->antenna_ports.val][0]; //TBC
@@ -464,11 +504,10 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
   int NrOfSymbols;
   uint8_t nb_dmrs_re_per_rb;
 
-  uint16_t        l_prime_mask = 1;
+  uint16_t        l_prime_mask = 0;
   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);
 
   // Common configuration
@@ -476,30 +515,56 @@ 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;
 
   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[0];
-    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;
-
-    // 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
-    pusch_config_pdu->bwp_size = ibwp_size;
-    if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size))
+      // 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;
-    else
+      pusch_config_pdu->bwp_size = abwp_size;
+    } else {
       pusch_config_pdu->bwp_start = ibwp_start;
+      pusch_config_pdu->bwp_size = ibwp_size;
+    }
 
     //// Resource assignment from RAR
     // Frequency domain allocation according to 8.3 of TS 38.213
@@ -513,15 +578,18 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
       return -1;
 
     // virtual resource block to physical resource mapping for Msg3 PUSCH (6.3.1.7 in 38.211)
-    pusch_config_pdu->rb_start += ibwp_start - abwp_start;
+    //pusch_config_pdu->rb_start += ibwp_start - abwp_start;
 
     // Time domain allocation
     SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
     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, 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
@@ -538,17 +606,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
@@ -560,29 +628,30 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
   } else if (dci) {
 
     int target_ss;
-    uint8_t  ptrs_time_density;
-    uint8_t  ptrs_freq_density;
-    nfapi_nr_ue_ptrs_ports_t ptrs_ports_list;
-    uint16_t n_RB_ULBWP = NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    fapi_nr_pusch_config_dedicated_t *pusch_config_dedicated = &mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated;
-    NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
-
-    // These should come from RRC config!!!
-    uint8_t  ptrs_mcs1          = 2;
-    uint8_t  ptrs_mcs2          = 4;
-    uint8_t  ptrs_mcs3          = 10;
-    uint16_t n_rb0              = 25;
-    uint16_t n_rb1              = 75;
+    bool valid_ptrs_setup = 0;
+    uint16_t n_RB_ULBWP;
+    if (mac->ULbwp[0] && mac->ULbwp[0]->bwp_Common) {
+      n_RB_ULBWP = NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+      pusch_config_pdu->bwp_start = NRRIV2PRBOFFSET(mac->ULbwp[0]->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[0] ? mac->ULbwp[0]->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*/
@@ -594,7 +663,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
 
       /* BANDWIDTH_PART_IND */
       if (dci->bwp_indicator.val != 1) {
-        LOG_W(MAC, "bwp_indicator != 1! Possibly due to false DCI. Ignoring DCI!\n");
+        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);
@@ -604,23 +673,40 @@ 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_Config->pusch_TimeDomainAllocationList) {
+      pusch_TimeDomainAllocationList = pusch_Config->pusch_TimeDomainAllocationList->choice.setup;
+    }
+    else if (mac->ULbwp[0] &&
+             mac->ULbwp[0]->bwp_Common&&
+             mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon&&
+             mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup &&
+             mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+      pusch_TimeDomainAllocationList = mac->ULbwp[0]->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;
+    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 ------------------------------------------------------------------------------------------*/
 
-    if (pusch_config_pdu->transform_precoding == transform_precoder_enabled) {
+    if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) {
 
       pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2;
 
-      NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = NULL;
-      if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL)
-        NR_DMRS_ulconfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup;
-      else
-        NR_DMRS_ulconfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
-
       uint32_t n_RS_Id = 0;
       if (NR_DMRS_ulconfig->transformPrecodingEnabled->nPUSCH_Identity != NULL)
         n_RS_Id = *NR_DMRS_ulconfig->transformPrecodingEnabled->nPUSCH_Identity;
@@ -637,7 +723,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);
     }
 
@@ -649,12 +735,12 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
       return -1;
     }
     /* TIME_DOM_RESOURCE_ASSIGNMENT */
-    if (nr_ue_process_dci_time_dom_resource_assignment(mac, pusch_config_pdu, NULL, dci->time_domain_assignment.val) < 0) {
+    if (nr_ue_process_dci_time_dom_resource_assignment(mac, pusch_config_pdu, NULL, dci->time_domain_assignment.val,false) < 0) {
       return -1;
     }
 
     /* FREQ_HOPPING_FLAG */
-    if ((pusch_config_dedicated->resource_allocation != 0) && (pusch_config_dedicated->frequency_hopping !=0)){
+    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;
     }
 
@@ -662,10 +748,10 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
     pusch_config_pdu->mcs_index = dci->mcs;
 
     /* 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);
+    if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) {
+      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 */
@@ -689,36 +775,57 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
       pusch_config_pdu->absolute_delta_PUSCH = 4;
     }
 
-    ptrs_time_density  = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
-    ptrs_freq_density  = get_K_ptrs(n_rb0, n_rb1, pusch_config_pdu->rb_size);
-    // PTRS ports configuration
-    // TbD: ptrs_dmrs_port and ptrs_port_index are not initialised!
-    ptrs_ports_list.ptrs_re_offset = 0;
+    if (NR_DMRS_ulconfig != NULL) {
+      add_pos = (NR_DMRS_ulconfig->dmrs_AdditionalPosition == NULL) ? 2 : *NR_DMRS_ulconfig->dmrs_AdditionalPosition;
+      dmrslength = NR_DMRS_ulconfig->maxLength == NULL ? pusch_len1 : pusch_len2;
+    }
 
     /* DMRS */
-    l_prime_mask = get_l_prime(pusch_config_pdu->nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
-    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[0] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled))
       pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1;
+    else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[0] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_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;
 
-    /* PTRS */
-    pusch_config_pdu->pusch_ptrs.ptrs_time_density = ptrs_time_density;
-    pusch_config_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
-    pusch_config_pdu->pusch_ptrs.ptrs_ports_list   = &ptrs_ports_list;
+    else N_PRB_oh = 0;
 
-    if (1 << pusch_config_pdu->pusch_ptrs.ptrs_time_density >= pusch_config_pdu->nr_of_symbols) {
-      pusch_config_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
+    /* PTRS */
+    if (mac->ULbwp[0] &&
+	mac->ULbwp[0]->bwp_Dedicated &&
+	mac->ULbwp[0]->bwp_Dedicated->pusch_Config &&
+	mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup &&
+	mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB &&
+	mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) {
+      if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) {
+        nfapi_nr_ue_ptrs_ports_t ptrs_ports_list;
+        pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list;
+        valid_ptrs_setup = set_ul_ptrs_values(mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup,
+                                              pusch_config_pdu->rb_size, pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table,
+                                              &pusch_config_pdu->pusch_ptrs.ptrs_freq_density,&pusch_config_pdu->pusch_ptrs.ptrs_time_density,
+                                              &pusch_config_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset,&pusch_config_pdu->pusch_ptrs.num_ptrs_ports,
+                                              &pusch_config_pdu->pusch_ptrs.ul_ptrs_power, pusch_config_pdu->nr_of_symbols);
+        if(valid_ptrs_setup==true) {
+          pusch_config_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS;
+        }
+        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,
@@ -726,12 +833,12 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
     pusch_config_pdu->nr_of_symbols,
     rnti_types[rnti_type]);
 
-  pusch_config_pdu->ul_dmrs_symb_pos = l_prime_mask << pusch_config_pdu->start_symbol_index;;
+  pusch_config_pdu->ul_dmrs_symb_pos = l_prime_mask;
   pusch_config_pdu->target_code_rate = nr_get_code_rate_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
   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;
   }
 
@@ -774,8 +881,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){
@@ -816,17 +923,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;
@@ -872,9 +1001,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;
@@ -888,35 +1017,55 @@ 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 ( (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,
+                                            frame_tx,
+                                            slot_tx,
+                                            0,
+                                            ulsch_input_buffer,
+                                            TBS_bytes,
+                                            &access_mode);
+            }
 
-          // Push data from MAC to PHY only when NDI toggles
-          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)){
-            // Getting IP traffic to be transmitted
-            data_existing = nr_ue_get_sdu(mod_id,
-                                          cc_id,
-                                          frame_tx,
-                                          slot_tx,
-                                          0,
-                                          ulsch_input_buffer,
-                                          TBS_bytes,
-                                          &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;
 
-          mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator;
-          //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
-          if (!IS_SOFTMODEM_NOS1 || !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);
-
-            //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] = 0x31;
-
-            for (int i = 1; i < TBS_bytes; i++) {
-              ulsch_input_buffer[i] = (unsigned char) rand();
-              //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
+            //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
+            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);
+
+              //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++) {
+                ulsch_input_buffer[i] = (unsigned char) rand();
+              }
             }
           }
 
@@ -937,7 +1086,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
           tx_req.tx_request_body[0].pdu_index = j;
           tx_req.tx_request_body[0].pdu = ulsch_input_buffer;
 
-          if (ra->ra_state != RA_SUCCEEDED && !ra->cfra){
+          if (ra->ra_state == WAIT_RAR && !ra->cfra){
+            LOG_I(NR_MAC,"[RAPROC] RA-Msg3 transmitted\n");
             nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->gNB_index);
           }
 
@@ -972,12 +1122,18 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac,
 
   int delta = 0;
   NR_BWP_Uplink_t *ubwp = mac->ULbwp[0];
+
   // 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
-  uint8_t k2;
+  int k2;
 
   if (is_Msg3) {
     k2 = *pusch_TimeDomainAllocationList->list.array[tda_id]->k2;
@@ -997,6 +1153,10 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac,
         break;
     }
 
+    AssertFatal((k2+delta) >= DURATION_RX_TO_TX,
+                "Slot offset (%d) for Msg3 cannot be less than DURATION_RX_TO_TX (%d)\n",
+                k2+delta,DURATION_RX_TO_TX);
+
     *slot_tx = (current_slot + k2 + delta) % nr_slots_per_frame[mu];
     if (current_slot + k2 + delta > nr_slots_per_frame[mu]){
       *frame_tx = (current_frame + 1) % 1024;
@@ -1018,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
@@ -1043,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;
@@ -1051,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){
@@ -1080,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];
@@ -1116,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);
@@ -1131,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
   // ----------------------------------------------------------------------------------------------------------------------------------------------
@@ -1143,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 ) {
 
@@ -1177,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];
@@ -1189,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);
@@ -1203,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
   // ===================================
@@ -1211,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++;
       }
@@ -1232,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++;
       }
@@ -1248,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++;
       }
@@ -1263,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
@@ -1319,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;
   }
@@ -1334,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) {
@@ -1359,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);
 
@@ -1371,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;
@@ -1419,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) {
@@ -1467,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) {
 
@@ -1491,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:
@@ -1555,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))) {
 
@@ -1615,26 +1807,116 @@ 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");
 }
 
+
+void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, int thread_id) {
+
+  NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
+  int O_SR = 0;
+  int O_ACK = 0;
+  int O_CSI = 0;
+  int N_UCI = 0;
+
+  PUCCH_sched_t *pucch = calloc(1,sizeof(*pucch));
+  pucch->resource_indicator = -1;
+  pucch->initial_pucch_id = -1;
+  uint16_t rnti = mac->crnti;  //FIXME not sure this is valid for all pucch instances
+
+  // SR
+  if(trigger_periodic_scheduling_request(mac, pucch, frameP, slotP)) {
+    O_SR = 1;
+    /* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */
+    pucch->sr_payload = nr_ue_get_SR(module_idP,
+                                     frameP,
+                                     slotP);
+  }
+
+  // CSI
+  if (mac->ra.ra_state == RA_SUCCEEDED)
+    O_CSI = nr_get_csi_measurements(mac, frameP, slotP, pucch);
+
+  // ACKNACK
+  O_ACK = get_downlink_ack(mac, frameP, slotP, pucch);
+
+  NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
+  NR_PUCCH_Config_t *pucch_Config = NULL;
+
+  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;
+  }
+
+
+  // if multiplexing of HARQ and CSI is not possible, transmit only HARQ bits
+  if ((O_ACK != 0) && (O_CSI != 0) &&
+      pucch_Config &&
+      pucch_Config->format2 &&
+      (pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI == NULL)) {
+    O_CSI = 0;
+    pucch->csi_part1_payload = 0;
+    pucch->csi_part2_payload = 0;
+  }
+
+  N_UCI = O_SR + O_ACK + O_CSI;
+
+  // do no transmit pucch if only SR scheduled and it is negative
+  if ((O_ACK + O_CSI) == 0 && pucch->sr_payload == 0)
+    return;
+
+  if (N_UCI > 0) {
+
+    pucch->resource_set_id = find_pucch_resource_set(mac, N_UCI);
+    select_pucch_resource(mac, pucch);
+    fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
+    fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu;
+    nr_ue_configure_pucch(mac,
+                          slotP,
+                          rnti,
+                          pucch,
+                          pucch_pdu,
+                          O_SR, O_ACK, O_CSI);
+    fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
+    nr_scheduled_response_t scheduled_response;
+    fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
+    if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
+      mac->if_module->scheduled_response(&scheduled_response);
+  }
+
+}
+
+
 // This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x
 // PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3.
 // - todo:
@@ -1656,13 +1938,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 = 0; // Reset flag for PRACH generation
+  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)) {
+  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
@@ -1677,24 +1963,22 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
     if (is_nr_prach_slot && ra->ra_state == RA_UE_IDLE) {
       AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n");
 
-      ra->generate_nr_prach = 1;
+      ra->generate_nr_prach = GENERATE_PREAMBLE;
 
       format = prach_occasion_info_p->format;
       format0 = format & 0xff;        // single PRACH format
       format1 = (format >> 8) & 0xff; // dual PRACH format
 
-      ul_config->sfn = frameP;
-      ul_config->slot = slotP;
-
-      ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PRACH;
       prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu;
       memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu));
-      ul_config->number_pdus += 1;
+
+      fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH);
+
       LOG_D(PHY, "In %s: (%p) %d UL PDUs:\n", __FUNCTION__, ul_config, ul_config->number_pdus);
 
       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;
@@ -1705,7 +1989,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++) {
@@ -1767,115 +2051,81 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
             AssertFatal(1 == 0, "Invalid PRACH format");
         }
       } // if format1
+      fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
+      if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
+        mac->if_module->scheduled_response(&scheduled_response);
     } // is_nr_prach_slot
-
-    fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
-    if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
-      mac->if_module->scheduled_response(&scheduled_response);
   } // 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,
            uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) {
-  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,
+  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,
               "Transmission on secondary CCs is not supported yet\n");
-
+  
   // Check for DCCH first
   // TO DO: Multiplex in the order defined by the logical channel prioritization
+  int buflen_remain = buflen;
+  char * current_ulsch_ptr = (char*)ulsch_sdus;
   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){
-
-        buflen_remain =
-          buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE);
-        LOG_D(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){
-
-        sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
-                                mac->crnti,
-                                eNB_index,
-                                frameP,
-                                ENB_FLAG_NO,
-                                MBMS_FLAG_NO,
-                                lcid,
-                                buflen_remain,
-                                (char *)&ulsch_sdus[sdu_length_total],0,
-                                0);
-
-        AssertFatal(buflen_remain >= sdu_lengths[num_sdus],
-                    "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n",
-                    lcid, sdu_lengths[num_sdus], buflen_remain);
-
-        if (sdu_lengths[num_sdus]) {
-          sdu_length_total += sdu_lengths[num_sdus];
-          sdu_lcids[num_sdus] = lcid;
-
-          total_rlc_pdu_header_len += MAX_RLC_SDU_SUBHEADER_SIZE; //rlc_pdu_header_len_last;
-
-          //Update number of SDU
-          num_sdus++;
-        }
-
-        /* 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);
-        buflen_remain =
-                  buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE);
-        }
+       lcid < MAX_LCID; lcid++) {
+    while ( (sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
+						   mac->crnti,
+						   eNB_index,
+						   frameP,
+						   ENB_FLAG_NO,
+						   MBMS_FLAG_NO,
+						   lcid,
+						   buflen_remain-MAX_RLC_SDU_SUBHEADER_SIZE*2,
+						   //Fixme: Laurent I removed MAX_RLC_SDU_SUBHEADER_SIZE*2 because else we get out the buffer silently
+						   // the interface with nr_generate_ulsch_pdu() looks over complex and not CPU optimized
+						   current_ulsch_ptr , 0,
+						      0)) > 0 ) {
+	  
+      AssertFatal(buflen_remain >= sdu_lengths[num_sdus],
+		  "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n",
+		  lcid, sdu_lengths[num_sdus], buflen_remain);
+      AssertFatal(current_ulsch_ptr < (char*)ulsch_sdus+MAX_ULSCH_PAYLOAD_BYTES, "");
+      
+      current_ulsch_ptr += sdu_lengths[num_sdus];
+      buflen_remain -= sdu_lengths[num_sdus];
+      buflen_remain -=  MAX_RLC_SDU_SUBHEADER_SIZE;
+      sdu_lcids[num_sdus] = lcid;
+      num_sdus++;
+    }
   }
-
-}
-
+  
   // Generate ULSCH PDU
   if (num_sdus>0) {
-  payload_offset = nr_generate_ulsch_pdu(ulsch_sdus,
-                                         ulsch_buffer,  // mac header
-                                         num_sdus,  // num sdus
-                                         sdu_lengths, // sdu length
-                                         sdu_lcids, // sdu lcid
-                                         0, // power_headroom
-                                         mac->crnti, // crnti
-                                         0, // truncated_bsr
-                                         0, // short_bsr
-                                         0, // long_bsr
-                                         0, // post_padding 
-                                         buflen);  // TBS in bytes
+    payload_offset = nr_generate_ulsch_pdu(ulsch_sdus,
+					   ulsch_buffer,  // mac header
+					   num_sdus,  // num sdus
+					   sdu_lengths, // sdu length
+					   sdu_lcids, // sdu lcid
+					   0, // power_headroom
+					   mac->crnti, // crnti
+					   0, // truncated_bsr
+					   0, // short_bsr
+					   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){
@@ -1884,7 +2134,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 bce07195562851925fb7901b74f79f6c9bb9a55a..f649f818c99ac6cf876419898b040956d576ce43 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -54,7 +54,88 @@ extern RAN_CONTEXT_t RC;
 extern void mac_top_init_gNB(void);
 extern uint8_t nfapi_mode;
 
-void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
+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];
   RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc;
@@ -67,7 +148,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
                                                             *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 pdsch_AntennaPorts, NR_ServingCellConfigComm
                                                                 *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)
@@ -127,8 +208,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
   uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
   frequency_range_t frequency_range = band<100?FR1:FR2;
 
-  lte_frame_type_t frame_type;
-  get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type);
+  lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
   RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type;
 
   // Cell configuration
@@ -209,8 +289,12 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
       cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839;
     cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.tl.tag = NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG;
     cfg->num_tlv++;
-    cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
-//k1= msg1_FrequencyStart + 12 (no. of FDM)(RB for PRACH occasion);
+    cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = 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.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
+    if (get_softmodem_params()->sa) {
+      cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = 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.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
+    } else {
+      cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
+    }
     cfg->prach_config.num_prach_fd_occasions_list[i].k1.tl.tag = NFAPI_NR_CONFIG_K1_TAG;
     cfg->num_tlv++;
     cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
@@ -241,6 +325,9 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
   cfg->ssb_table.ssb_period.value = *scc->ssb_periodicityServingCell;
   cfg->ssb_table.ssb_period.tl.tag = NFAPI_NR_CONFIG_SSB_PERIOD_TAG;
   cfg->num_tlv++;
+  cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset;
+  cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
+  cfg->num_tlv++;
 
   switch (scc->ssb_PositionsInBurst->present) {
     case 1 :
@@ -265,20 +352,34 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
 
   cfg->ssb_table.ssb_mask_list[0].ssb_mask.tl.tag = NFAPI_NR_CONFIG_SSB_MASK_TAG;
   cfg->ssb_table.ssb_mask_list[1].ssb_mask.tl.tag = NFAPI_NR_CONFIG_SSB_MASK_TAG;
-  cfg->num_tlv++;
+  cfg->num_tlv+=2;
 
   cfg->carrier_config.num_tx_ant.value = pdsch_AntennaPorts;
   AssertFatal(pdsch_AntennaPorts > 0 && pdsch_AntennaPorts < 13, "pdsch_AntennaPorts in 1...12\n");
   cfg->carrier_config.num_tx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_TX_ANT_TAG;
+
   int num_ssb=0;
   for (int i=0;i<32;i++) {
-    num_ssb += (cfg->ssb_table.ssb_mask_list[0].ssb_mask.value>>i)&1;
-    num_ssb += (cfg->ssb_table.ssb_mask_list[1].ssb_mask.value>>i)&1;
+    cfg->ssb_table.ssb_beam_id_list[i].beam_id.tl.tag = NFAPI_NR_CONFIG_BEAM_ID_TAG;
+    if ((cfg->ssb_table.ssb_mask_list[0].ssb_mask.value>>(31-i))&1) {
+      cfg->ssb_table.ssb_beam_id_list[i].beam_id.value = num_ssb;
+      num_ssb++;
+    }
+    cfg->num_tlv++;
+  }
+  for (int i=0;i<32;i++) {
+    cfg->ssb_table.ssb_beam_id_list[32+i].beam_id.tl.tag = NFAPI_NR_CONFIG_BEAM_ID_TAG;
+    if ((cfg->ssb_table.ssb_mask_list[1].ssb_mask.value>>(31-i))&1) {
+      cfg->ssb_table.ssb_beam_id_list[32+i].beam_id.value = num_ssb;
+      num_ssb++;
+    }
+    cfg->num_tlv++;
   } 
 
-  cfg->carrier_config.num_rx_ant.value = cfg->carrier_config.num_tx_ant.value;
+  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++;
@@ -295,34 +396,33 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
     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);
-    int return_tdd = set_tdd_config_nr(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(MAC,"TDD configuration can not be done\n");
-    else 
-      LOG_I(MAC,"TDD has been properly configurated\n");    
+    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,
+                                              scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols,
+                                              scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
+                                              scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols);
+
+    if (periods_per_frame < 0)
+      LOG_E(NR_MAC,"TDD configuration can not be done\n");
+    else {
+      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));
+    }
   }
 
 }
 
-
-
 extern uint16_t sl_ahead;
-int rrc_mac_config_req_gNB(module_id_t Mod_idP, 
-			   int ssb_SubcarrierOffset,
+int rrc_mac_config_req_gNB(module_id_t Mod_idP,
+                           int ssb_SubcarrierOffset,
                            int pdsch_AntennaPorts,
-                           int pusch_tgt_snrx10,
-                           int pucch_tgt_snrx10,
+                           int pusch_AntennaPorts,
                            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);
@@ -351,20 +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");
 
-    for (int i = 0; i < MAX_NUM_BWP; ++i) {
-      RC.nrmac[Mod_idP]->pucch_index_used[i] =
-        calloc(n, sizeof(*RC.nrmac[Mod_idP]->pucch_index_used));
-      AssertFatal(RC.nrmac[Mod_idP]->pucch_index_used[i],
-                  "could not allocate memory for RC.nrmac[]->pucch_index_used[%d]\n",
-                  i);
-    }
-
-    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,
-                  pdsch_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);
+                  ssb_SubcarrierOffset,
+                  pdsch_AntennaPorts,
+                  pusch_AntennaPorts,
+                  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) ){
@@ -374,32 +468,83 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
         printf("Waiting for PHY_config_req\n");
       }
     }
-  
-    RC.nrmac[Mod_idP]->pusch_target_snrx10 = pusch_tgt_snrx10;
-    RC.nrmac[Mod_idP]->pucch_target_snrx10 = pucch_tgt_snrx10;
+    RC.nrmac[Mod_idP]->ssb_SubcarrierOffset = ssb_SubcarrierOffset;
+
     NR_PHY_Config_t phycfg;
     phycfg.Mod_id = Mod_idP;
     phycfg.CC_id  = 0;
     phycfg.cfg    = &RC.nrmac[Mod_idP]->config[0];
 
-    phycfg.cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset;
-    phycfg.cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
-    phycfg.cfg->num_tlv++;
-
     if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg);
 
     find_SSB_and_RO_available(Mod_idP);
 
+    const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
+    const int nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0;
+    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] |= (uint64_t)((slot % nr_slots_period) < nr_dlmix_slots) << (slot % 64);
+      RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
+      LOG_D(NR_MAC, "slot %d DL %d UL %d\n",
+            slot,
+            (RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0,
+            (RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0);
+    }
+
+    if (get_softmodem_params()->phy_test) {
+      RC.nrmac[Mod_idP]->pre_processor_dl = nr_preprocessor_phytest;
+      RC.nrmac[Mod_idP]->pre_processor_ul = nr_ul_preprocessor_phytest;
+    } else {
+      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) {
+
+    const NR_ServingCellConfig_t *servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated;
 
-    RC.nrmac[Mod_idP]->secondaryCellGroupCommon = secondaryCellGroup;
+    const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
+    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;
+    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];
@@ -409,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));
@@ -433,12 +579,20 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
             }
           }
         }
+      } else {
+        ra->cfra = false;
+        ra->rnti = 0;
+        ra->preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES;
+        ra->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++)
+          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 ede68b11efbdf5f8a5a118449a8037e68edbd4ac..7fc611365fecbaafd5d592a574bc8936fffc30b7 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -53,40 +53,85 @@
 
 #include "executables/softmodem-common.h"
 #include "nfapi/oai_integration/vendor_ext.h"
+#include "executables/nr-softmodem.h"
+
+#include <errno.h>
+#include <string.h>
 
 uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
 
 void clear_mac_stats(gNB_MAC_INST *gNB) {
   memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
 }
-
+#define MACSTATSSTRLEN 16384
 void dump_mac_stats(gNB_MAC_INST *gNB)
 {
   NR_UE_info_t *UE_info = &gNB->UE_info;
   int num = 1;
+  FILE *fd=fopen("nrMAC_stats.log","w");
+  AssertFatal(fd!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno));
+  char output[MACSTATSSTRLEN];
+  memset(output,0,MACSTATSSTRLEN);
+  int stroff=0;
   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)\n", UE_id, UE_info->rnti[UE_id], num++, UE_info->num_UEs);
-    const NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
-    LOG_I(MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d\n",
+    stroff = sprintf(output,"UE ID %d RNTI %04x (%d/%d)\n", UE_id, UE_info->rnti[UE_id], num++, UE_info->num_UEs);
+    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++,
+      UE_info->num_UEs,
+      UE_info->UE_sched_ctrl[UE_id].ph,
+      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;
+    stroff+=sprintf(output+stroff,"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);
-    LOG_I(MAC, "UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes);
-    LOG_I(MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n",
+          stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors,
+          avg_rsrp, stats->num_rsrp_meas);
+    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 ;
+    stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes);
+    stroff+=sprintf(output+stroff,"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_DTX,
+                    stats->ulsch_errors);
+    stroff+=sprintf(output+stroff,
+                    "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);
+    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);
-    LOG_I(MAC,
+          stats->ulsch_rounds[2], stats->ulsch_rounds[3],
+          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]);
-      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]);
+      if (stats->lc_bytes_tx[lc_id] > 0) {
+        stroff+=sprintf(output+stroff, "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) {
+        stroff+=sprintf(output+stroff, "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);
+  if (stroff>0) fprintf(fd,"%s",output);
+  fclose(fd);
 }
 
 void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
@@ -297,6 +342,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
 
 
 bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
+  if (slot>=64) return false; //quickfix for FR2 where there are more than 64 slots (bitmap to be removed)
   return (bitmap >> slot) & 0x01;
 }
 
@@ -304,59 +350,26 @@ 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);
- 
-  int nb_periods_per_frame;
 
   const int bwp_id = 1;
 
   gNB_MAC_INST *gNB = RC.nrmac[module_idP];
   NR_COMMON_channels_t *cc = gNB->common_channels;
   NR_ServingCellConfigCommon_t        *scc     = cc->ServingCellConfigCommon;
-  NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
-
-  switch(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity) {
-    case 0:
-      nb_periods_per_frame = 20; // 10ms/0p5ms
-      break;
-
-    case 1:
-      nb_periods_per_frame = 16; // 10ms/0p625ms
-      break;
-
-    case 2:
-      nb_periods_per_frame = 10; // 10ms/1ms
-      break;
-
-    case 3:
-      nb_periods_per_frame = 8; // 10ms/1p25ms
-      break;
-
-    case 4:
-      nb_periods_per_frame = 5; // 10ms/2ms
-      break;
-
-    case 5:
-      nb_periods_per_frame = 4; // 10ms/2p5ms
-      break;
 
-    case 6:
-      nb_periods_per_frame = 2; // 10ms/5ms
-      break;
-
-    case 7:
-      nb_periods_per_frame = 1; // 10ms/10ms
-      break;
-
-    default:
-      AssertFatal(1==0,"Undefined tdd period %ld\n", scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
+  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;
+    const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
+    const int nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0;
+    const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots;
+    const int nb_periods_per_frame = n / nr_slots_period;
+    // re-initialization of tdd_beam_association at beginning of frame (only for FR2)
+    for (int i=0; i<nb_periods_per_frame; i++)
+      gNB->tdd_beam_association[i] = -1;
   }
 
-  int num_slots_per_tdd = (nr_slots_per_frame[*scc->ssbSubcarrierSpacing])/nb_periods_per_frame;
-
-  const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0);
-
   start_meas(&RC.nrmac[module_idP]->eNB_scheduler);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
 
@@ -364,22 +377,13 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
   /* send tick to RLC and RRC every ms */
   if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) {
     void nr_rlc_tick(int frame, int subframe);
+    void nr_pdcp_tick(int frame, int subframe);
     nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing);
+    nr_pdcp_tick(frame, slot >> *scc->ssbSubcarrierSpacing);
     nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
   }
 
-#define BIT(x) (1 << (x))
-  const uint64_t dlsch_in_slot_bitmap = BIT( 1) | BIT( 2) | BIT( 3) | BIT( 4) | BIT( 5) | BIT( 6)
-                                      | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16);
-
-  uint8_t prach_config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
-  uint64_t ulsch_in_slot_bitmap;
-  if (prach_config_index==4) //this is the PRACH config used in the Benetel RRU. TODO: make this generic for any PRACH config. 
-    ulsch_in_slot_bitmap = BIT( 8) | BIT( 9);
-  else
-    ulsch_in_slot_bitmap = BIT( 8) | BIT(18);
-
-  memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
+  memset(RC.nrmac[module_idP]->cce_list[0][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
   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])
@@ -404,7 +408,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
 
 
   // This schedules MIB
-  schedule_nr_mib(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]);
+  schedule_nr_mib(module_idP, frame, slot);
 
   // This schedules SIB1
   if ( get_softmodem_params()->sa == 1 )
@@ -426,7 +430,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
   }
 
   // This schedule SR
-  // TODO
+  nr_sr_reporting(module_idP, frame, slot);
+
+  // Schedule CSI-RS transmission
+  nr_csirs_scheduling(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]);
 
   // Schedule CSI measurement reporting: check in slot 0 for the whole frame
   if (slot == 0)
@@ -439,14 +446,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
   }
 
   // This schedules the DCI for Uplink and subsequently PUSCH
-  {
-    nr_schedule_ulsch(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, ulsch_in_slot_bitmap);
-  }
+  nr_schedule_ulsch(module_idP, frame, slot);
 
   // This schedules the DCI for Downlink and PDSCH
-  if (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot))
-    nr_schedule_ue_spec(module_idP, frame, slot);
-
+  nr_schedule_ue_spec(module_idP, frame, slot);
 
   nr_schedule_pucch(module_idP, frame, slot);
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index ac3a4e77d236626f371e93313d1c6105008da7bc..220b4a921e34f8529cfe52438450e0ebc15941db 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -41,6 +41,7 @@
 #include "UTIL/OPT/opt.h"
 #include "SIMULATION/TOOLS/sim.h" // for taus
 
+#include <executables/softmodem-common.h>
 extern RAN_CONTEXT_t RC;
 extern const uint8_t nr_slots_per_frame[5];
 extern uint16_t sl_ahead;
@@ -65,7 +66,7 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
   uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
   uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
   
-  uint8_t total_RApreambles = 64;
+  uint8_t total_RApreambles = MAX_NUM_NR_PRACH_PREAMBLES;
   if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
     total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;	
   
@@ -130,7 +131,7 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
     }
   }
 
-  LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %d ssb per RO = %f number of active SSB %u index = %d fdm %u symbol index %u freq_index %u total_RApreambles %u\n", 
+  LOG_D(NR_MAC, "Frame %d, Slot %d: Prach Occasion id = %d ssb per RO = %f number of active SSB %u index = %d fdm %u symbol index %u freq_index %u total_RApreambles %u\n",
         frameP, slotP, prach_occasion_id, num_ssb_per_RO, num_active_ssb, index, fdm, start_symbol_index, freq_index, total_RApreambles);
 
   return index;
@@ -214,7 +215,7 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
   }
 
   cc->total_prach_occasions_per_config_period = total_RA_occasions;
-  for(int i=1; (1 << (i-1)) < max_association_period; i++) {
+  for(int i=1; (1 << (i-1)) <= max_association_period; i++) {
     cc->max_association_period = (1 <<(i-1));
     total_RA_occasions = total_RA_occasions * cc->max_association_period;
     if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) {
@@ -227,7 +228,7 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
   cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion;
   cc->num_active_ssb = num_active_ssb;
 
-  LOG_I(MAC,
+  LOG_I(NR_MAC,
         "Total available RO %d, num of active SSB %d: unused RO = %d association_period %u N_RA_sfn %u total_prach_occasions_per_config_period %u\n",
         cc->total_prach_occasions,
         cc->num_active_ssb,
@@ -245,7 +246,8 @@ 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)) {
+  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;
     uint16_t RA_sfn_index = -1;
@@ -312,7 +314,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
                                         format0,
                                         scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig);
 
-            LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %u  fdm index = %u start symbol = %u slot index = %u subframe index = %u \n",
+            LOG_D(NR_MAC, "Frame %d, Slot %d: Prach Occasion id = %u  fdm index = %u start symbol = %u slot index = %u subframe index = %u \n",
                   frameP, slotP,
                   prach_occasion_id, prach_pdu->num_ra,
                   prach_pdu->prach_start_symbol,
@@ -376,6 +378,16 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
           }
         }
       }
+
+      // block resources in vrb_map_UL
+      const NR_RACH_ConfigGeneric_t *rach_ConfigGeneric =
+          &scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric;
+      const uint8_t mu_pusch =
+          scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+      const int16_t N_RA_RB = get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, mu_pusch);
+      uint16_t *vrb_map_UL = &cc->vrb_map_UL[slotP * MAX_BWP_SIZE];
+      for (int i = 0; i < N_RA_RB * fdm; ++i)
+        vrb_map_UL[rach_ConfigGeneric->msg1_FrequencyStart + i] = 0xff; // all symbols
     }
   }
 }
@@ -384,7 +396,9 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
                       uint16_t *msg2_frame, uint16_t *msg2_slot,
                       NR_ServingCellConfigCommon_t *scc,
                       uint16_t monitoring_slot_period,
-                      uint16_t monitoring_offset,uint8_t index,uint8_t num_active_ssb){
+                      uint16_t monitoring_offset,uint8_t beam_index,
+                      uint8_t num_active_ssb,
+                      int16_t *tdd_beam_association){
 
   // preferentially we schedule the msg2 in the mixed slot or in the last dl slot
   // if they are allowed by search space configuration
@@ -401,18 +415,6 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
   if ((scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) || (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0))
     tdd_period_slot++;
 
-  // computing start of next period
-  uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu];
-  *msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
-  *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
-
-  // we can't schedule msg2 before sl_ahead since prach
-  int eff_slot = *msg2_slot+(*msg2_frame-rach_frame)*nr_slots_per_frame[mu];
-  if ((eff_slot-rach_slot)<=sl_ahead) {
-    *msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu];
-    *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
-  }
-
   switch(response_window){
     case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
       slot_window = 1;
@@ -447,6 +449,31 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
   uint8_t slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu];
   uint8_t frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1);
 
+  // computing start of next period
+
+  int FR = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257 ? nr_FR2 : nr_FR1;
+
+  uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu];
+  *msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
+  *msg2_frame = ((*msg2_slot>(rach_slot))? rach_frame : (rach_frame+1))%1024;
+
+  // we can't schedule msg2 before sl_ahead since prach
+  int eff_slot = *msg2_slot+(*msg2_frame-rach_frame)*nr_slots_per_frame[mu];
+  if ((eff_slot-rach_slot)<=sl_ahead) {
+    *msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu];
+    *msg2_frame = ((*msg2_slot>(rach_slot))? rach_frame : (rach_frame+1))%1024;
+  }
+  if (FR==nr_FR2) {
+    int num_tdd_period = *msg2_slot/tdd_period_slot;
+    while((tdd_beam_association[num_tdd_period]!=-1)&&(tdd_beam_association[num_tdd_period]!=beam_index)) {
+      *msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu];
+      *msg2_frame = ((*msg2_slot>(rach_slot))? rach_frame : (rach_frame+1))%1024;
+      num_tdd_period = *msg2_slot/tdd_period_slot;
+    }
+    if(tdd_beam_association[num_tdd_period] == -1)
+      tdd_beam_association[num_tdd_period] = beam_index;
+  }
+
   // go to previous slot if the current scheduled slot is beyond the response window
   // and if the slot is not among the PDCCH monitored ones (38.213 10.1)
   while (((*msg2_slot>slot_limit)&&(*msg2_frame>frame_limit)) || ((*msg2_frame*nr_slots_per_frame[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0))  {
@@ -475,13 +502,13 @@ void nr_initiate_ra_proc(module_id_t module_idP,
   NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
   NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
 
-  uint8_t total_RApreambles = 64;
-  uint8_t  num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;	
+  uint8_t total_RApreambles = MAX_NUM_NR_PRACH_PREAMBLES;
+  uint8_t  num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
   int pr_found;
 
   if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
-    total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;	
-  
+    total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
+
   if(num_ssb_per_RO > 3) { /*num of ssb per RO >= 1*/
     num_ssb_per_RO -= 3;
     total_RApreambles = total_RApreambles/num_ssb_per_RO ;
@@ -498,7 +525,6 @@ void nr_initiate_ra_proc(module_id_t module_idP,
           break;
         }
       }
-
       if (pr_found == 0) {
          continue;
       }
@@ -514,13 +540,17 @@ void nr_initiate_ra_proc(module_id_t module_idP,
         ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8);
 
       // This should be handled differently when we use the initialBWP for RA
-      ra->bwp_id = 1;
-      NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
-                                   ->list.array[ra->bwp_id - 1];
+      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);
 
-      LOG_I(MAC,
+      LOG_D(NR_MAC,
             "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d  Initiating RA procedure for preamble index %d\n",
             module_idP,
             CC_id,
@@ -535,29 +565,38 @@ void nr_initiate_ra_proc(module_id_t module_idP,
         // if the preamble received correspond to one of the listed
         if (!(preamble_index == ra->preambles.preamble_list[beam_index])) {
           LOG_E(
-              MAC,
+              NR_MAC,
               "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n",
               module_idP,
               preamble_index);
           continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc
         }
       }
-      int loop = 0;
-      LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP);
+      LOG_D(NR_MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP);
       ra->state = Msg2;
       ra->timing_offset = timing_offset;
       ra->preamble_slot = slotP;
 
-      struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList =
-          bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
+      NR_SearchSpaceId_t	ra_SearchSpace = 0;
+      struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = NULL;
+      if(bwp) {
+        commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
+        ra_SearchSpace = *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace;
+      } else {
+        commonSearchSpaceList = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
+        ra_SearchSpace = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace;
+      }
       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 == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)
+        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);
 
@@ -569,13 +608,16 @@ void nr_initiate_ra_proc(module_id_t module_idP,
                        monitoring_slot_period,
                        monitoring_offset,
                        beam_index,
-                       cc->num_active_ssb);
+                       cc->num_active_ssb,
+                       nr_mac->tdd_beam_association);
 
       ra->Msg2_frame = msg2_frame;
       ra->Msg2_slot = msg2_slot;
 
-      LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
-      if (!ra->cfra) {
+      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;
+      if (ra->rnti == 0) { // This condition allows for the usage of a preconfigured rnti for the CFRA
         do {
           ra->rnti = (taus() % 65518) + 1;
           loop++;
@@ -583,15 +625,16 @@ void nr_initiate_ra_proc(module_id_t module_idP,
                  && !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1)
                       && ra->rnti >= 1 && ra->rnti <= 65519));
         if (loop == 100) {
-          LOG_E(MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
+          LOG_E(NR_MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
           abort();
         }
       }
+
       ra->RA_rnti = ra_rnti;
       ra->preamble_index = preamble_index;
       ra->beam_id = beam_index;
 
-      LOG_I(MAC,
+      LOG_D(NR_MAC,
             "[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB "
             "index %u\n",
             module_idP,
@@ -605,38 +648,38 @@ void nr_initiate_ra_proc(module_id_t module_idP,
       return;
     }
   }
-  LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index);
+  LOG_E(NR_MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index);
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);
 }
 
-void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
-{
-  gNB_MAC_INST *mac = RC.nrmac[module_idP];
-
-  start_meas(&mac->schedule_ra);
-  for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-    NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
-    for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
-      NR_RA_t *ra = &cc->ra[i];
-      LOG_D(MAC, "RA[state:%d]\n", ra->state);
-      switch (ra->state) {
-        case Msg2:
-          nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra);
-          break;
-        case Msg4:
-          // generate_Msg4(module_idP, CC_id, frameP, slotP);
-          break;
-        case WAIT_Msg4_ACK:
-          // check_Msg4_retransmission(module_idP, CC_id, frameP, slotP);
-          break;
-        default:
-          break;
+  void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
+  {
+    gNB_MAC_INST *mac = RC.nrmac[module_idP];
+
+    start_meas(&mac->schedule_ra);
+    for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+      NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
+      for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
+        NR_RA_t *ra = &cc->ra[i];
+        LOG_D(NR_MAC, "RA[state:%d]\n", ra->state);
+        switch (ra->state) {
+          case Msg2:
+            nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra);
+            break;
+          case Msg4:
+            nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra);
+            break;
+          case WAIT_Msg4_ACK:
+            nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra);
+            break;
+          default:
+            break;
+        }
       }
     }
+    stop_meas(&mac->schedule_ra);
   }
-  stop_meas(&mac->schedule_ra);
-}
 
 void nr_get_Msg3alloc(module_id_t module_id,
                       int CC_id,
@@ -644,54 +687,84 @@ void nr_get_Msg3alloc(module_id_t module_id,
                       NR_BWP_Uplink_t *ubwp,
                       sub_frame_t current_slot,
                       frame_t current_frame,
-                      NR_RA_t *ra) {
-
-  // msg3 is schedulend in mixed slot in the following TDD period
-  // for now we consider a TBS of 18 bytes
-
-  int mu = ubwp->bwp_Common->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;
-    SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
-    // we want to transmit in the uplink symbols of mixed slot
-    if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) {
-      ra->Msg3_tda_id = i;
-      break;
+                      NR_RA_t *ra,
+                      int16_t *tdd_beam_association) {
+
+    // msg3 is schedulend in mixed slot in the following TDD period
+
+    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 ?
+      ubwp->bwp_Common->genericParameters.subcarrierSpacing :
+      scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
+    int StartSymbolIndex = 0;
+    int NrOfSymbols = 0;
+    int startSymbolAndLength = 0;
+    int temp_slot = 0;
+    ra->Msg3_tda_id = 16; // initialization to a value above limit
+
+    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;
+
+    uint8_t k2 = 0;
+    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) {
+        k2 = *pusch_TimeDomainAllocationList->list.array[i]->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];
+        if (is_xlsch_in_slot(RC.nrmac[module_id]->ulsch_slot_bitmap[ra->Msg3_slot / 64], ra->Msg3_slot)) {
+          ra->Msg3_tda_id = i;
+          break;
+        }
+      }
     }
-  }
-  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;
+    AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
 
-  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];
-  if (nr_slots_per_frame[mu]>temp_slot)
-    ra->Msg3_frame = current_frame;
-  else
-    ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]);
+    if (nr_slots_per_frame[mu]>temp_slot)
+      ra->Msg3_frame = current_frame;
+    else
+      ra->Msg3_frame = (current_frame + (temp_slot/nr_slots_per_frame[mu]))%1024;
+
+  // beam association for FR2
+  if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) {
+    uint8_t tdd_period_slot =  scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
+    if ((scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) || (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0))
+      tdd_period_slot++;
+    int num_tdd_period = ra->Msg3_slot/tdd_period_slot;
+    if((tdd_beam_association[num_tdd_period]!=-1)&&(tdd_beam_association[num_tdd_period]!=ra->beam_id))
+      AssertFatal(1==0,"Cannot schedule MSG3\n");
+    else
+      tdd_beam_association[num_tdd_period] = ra->beam_id;
+  }
 
-  LOG_I(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);
+  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);
-  /* search 18 free RBs */
+  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;
   int rbStart = 0;
-  while (rbSize < 18) {
+  while (rbSize < msg3_nb_rb) {
     rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
     rbSize = 0;
     while (rbStart < bwpSize && vrb_map_UL[rbStart])
       rbStart++;
-    AssertFatal(rbStart < bwpSize - 18, "no space to allocate Msg 3 for RA!\n");
+    AssertFatal(rbStart < bwpSize - msg3_nb_rb, "no space to allocate Msg 3 for RA!\n");
     while (rbStart + rbSize < bwpSize
            && !vrb_map_UL[rbStart + rbSize]
-           && rbSize < 18)
+           && rbSize < msg3_nb_rb)
       rbSize++;
   }
-  ra->msg3_nb_rb = 18;
+  ra->msg3_nb_rb = msg3_nb_rb;
   ra->msg3_first_rb = rbStart;
 }
 
@@ -702,7 +775,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
   NR_ServingCellConfigCommon_t                   *scc = cc->ServingCellConfigCommon;
 
   if (ra->state == RA_IDLE) {
-    LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti);
+    LOG_W(NR_MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti);
     return;
   }
 
@@ -717,7 +790,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
     vrb_map_UL[i + ra->msg3_first_rb] = 1;
   }
 
-  LOG_I(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
+  LOG_D(NR_MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
 
   nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][ra->Msg3_slot];
   AssertFatal(future_ul_tti_req->SFN == ra->Msg3_frame
@@ -732,14 +805,29 @@ 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 == 1,
+		"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);
-  AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
-    "downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
-  NR_BWP_Uplink_t *ubwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
-  LOG_D(MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
+  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,
     ra->Msg3_frame,
@@ -749,23 +837,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);
 
   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;
@@ -777,23 +861,25 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
     pusch_pdu->transform_precoding = 0;
   pusch_pdu->data_scrambling_id = *scc->physCellId;
   pusch_pdu->nrOfLayers = 1;
-  pusch_pdu->ul_dmrs_symb_pos = 1<<start_symbol_index; // ok for now but use fill dmrs mask later
+
+  pusch_pdu->ul_dmrs_symb_pos = get_l_prime(nr_of_symbols,mappingtype,pusch_dmrs_pos2,pusch_len1,start_symbol_index, scc->dmrs_TypeA_Position);
+  LOG_D(MAC, "MSG3 start_sym:%d NR Symb:%d mappingtype:%d , ul_dmrs_symb_pos:%x\n", start_symbol_index, nr_of_symbols, mappingtype, pusch_pdu->ul_dmrs_symb_pos);
+
   pusch_pdu->dmrs_config_type = 0;
   pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id.
   pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0.
   pusch_pdu->dmrs_ports = 1;  // 6.2.2 in 38.214 only port 0 to be used
   pusch_pdu->num_dmrs_cdm_grps_no_data = 2;  // no data in dmrs symbols as in 6.2.2 in 38.214
   pusch_pdu->resource_alloc = 1; //type 1
-  pusch_pdu->rb_start = ra->msg3_first_rb + ibwp_start - abwp_start; // as for 6.3.1.7 in 38.211
+  //pusch_pdu->rb_start = ra->msg3_first_rb + ibwp_start - abwp_start; // as for 6.3.1.7 in 38.211
+  pusch_pdu->rb_start = ra->msg3_first_rb;
   if (ra->msg3_nb_rb > pusch_pdu->bwp_size)
     AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n");
   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
@@ -819,83 +905,92 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
 
 void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra)
 {
-  int mcsIndex;
-  int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0;
-  gNB_MAC_INST                      *nr_mac = RC.nrmac[module_idP];
-  NR_COMMON_channels_t                  *cc = &nr_mac->common_channels[CC_id];
-  NR_SearchSpace_t *ss = ra->ra_ss;
-
-  // This code from this point on will not work on initialBWP or CORESET0
-  AssertFatal(ra->bwp_id > 0, "cannot work on initialBWP for now\n");
 
-  AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->crnti);
-  AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
-              "downlinkBWP_ToAddModList has %d BWP!\n",
-              ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
-
-  uint16_t RA_rnti = ra->RA_rnti;
-  long locationAndBandwidth;
+  gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
+  NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
 
-  // check if UE is doing RA on CORESET0 , InitialBWP or configured BWP from SCD
-  // get the BW of the PDCCH for PDCCH size and RAR PDSCH size
+  if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) {
 
-  NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
-  int dci10_bw = 0;
+    uint8_t time_domain_assignment = 1;
+    uint8_t mcsIndex = 0;
+    int rbStart = 0;
+    int rbSize = 8;
+
+    NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+    NR_SearchSpace_t *ss = ra->ra_ss;
+
+    long BWPSize  = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
+    NR_BWP_Downlink_t *bwp = NULL;
+    NR_ControlResourceSet_t *coreset = NULL;
+    NR_BWP_t *genericParameters = NULL;
+    NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList=NULL;
+    long BWPStart = 0;
+
+    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);
 
-  if (ra->coreset0_configured == 1) {
-    AssertFatal(1==0,"This is a standalone condition\n");
-  }
-  else { // on configured BWP or initial LDBWP, bandwidth parameters in DCI correspond size of initialBWP
-    locationAndBandwidth = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth;
-    dci10_bw = NRRIV2BW(locationAndBandwidth, MAX_BWP_SIZE); 
-  }
+    if (*ss->controlResourceSetId == 0)
+      coreset = nr_mac->sched_ctrlCommon->coreset; // this is coreset 0
+    else
+      coreset = get_coreset(scc, bwp, ss, NR_SearchSpace__searchSpaceType_PR_common);
 
-  if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) {
+    AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg2\n");
 
     uint16_t *vrb_map = cc[CC_id].vrb_map;
-    int rbStart = 0, rbSize = 6;
-    for (int i = 0; (i < rbSize) && (rbStart <= (dci10_bw - rbSize)); i++) {
+    for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) {
       if (vrb_map[rbStart + i]) {
         rbStart += i;
         i = 0;
       }
     }
-    if (rbStart > (dci10_bw - rbSize)) {
-      LOG_E(MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti);
+
+    if (rbStart > (BWPSize - rbSize)) {
+      LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti);
       return;
     }
 
+    // Checking if the DCI allocation is feasible in current subframe
     nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
-    // Checking if the DCI allocation is feasible in current subframe: we might
-    // need to need up to two (PDCCH + PDSCH) messages, so check that we can
-    // always allocate both (this might be an overestimation, since the PDCCH
-    // message might already exist)
     if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
-      LOG_I(MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, RA_rnti);
+      LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti);
       return;
     }
 
-    uint8_t nr_of_candidates, aggregation_level;
+    uint8_t aggregation_level;
+    uint8_t nr_of_candidates;
     find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
-    NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
-    NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 0 /* common */);
-    int CCEIndex = allocate_nr_CCEs(nr_mac,
-                                    bwp,
-                                    coreset,
-                                    aggregation_level,
-                                    0, // Y
-                                    0, // m
-                                    nr_of_candidates);
-
+    int CCEIndex = allocate_nr_CCEs(nr_mac, bwp, coreset, aggregation_level,0,0,nr_of_candidates);
     if (CCEIndex < 0) {
-      LOG_E(MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti);
+      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_Id;
+    // Calculate number of symbols
+    int startSymbolIndex, nrOfSymbols;
+    const int startSymbolAndLength = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
+    SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
+    AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n");
+
+    LOG_D(MAC,"Msg2 startSymbolIndex.nrOfSymbols %d.%d\n",startSymbolIndex,nrOfSymbols);
+
+    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][bwpid][coresetid];
     if (!pdcch_pdu_rel15) {
@@ -916,81 +1011,408 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     dl_req->nPDUs+=1;
     nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
 
-    LOG_I(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
+    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);
 
-    NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
-
-    LOG_I(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw);
+    // 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]++;
 
-    // Qm>2 not allowed for RAR
-    if (get_softmodem_params()->do_ra)
-      mcsIndex = 9;
-    else
-      mcsIndex = 0;
+    uint8_t 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)
+        mcsTableIdx = 1;
+      else
+        mcsTableIdx = 2;
+    }
+    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_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]++;
+    pdsch_pdu_rel15->rnti = ra->RA_rnti;
     pdsch_pdu_rel15->pduIndex = pduindex;
-
-
-    pdsch_pdu_rel15->BWPSize  = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
-    pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
+    pdsch_pdu_rel15->BWPSize  = BWPSize;
+    pdsch_pdu_rel15->BWPStart = BWPStart;
+    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,0);
+    pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,mcsTableIdx);
     pdsch_pdu_rel15->qamModOrder[0] = 2;
     pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
-    if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL)
-      pdsch_pdu_rel15->mcsTable[0] = 0;
-    else{
-      if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0)
-        pdsch_pdu_rel15->mcsTable[0] = 1;
-      else
-        pdsch_pdu_rel15->mcsTable[0] = 2;
-    }
+    pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx;
     pdsch_pdu_rel15->rvIndex[0] = 0;
     pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
     pdsch_pdu_rel15->nrOfLayers = 1;
     pdsch_pdu_rel15->transmissionScheme = 0;
     pdsch_pdu_rel15->refPoint = 0;
-    pdsch_pdu_rel15->dmrsConfigType = 0;
+    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;
     pdsch_pdu_rel15->rbSize = rbSize;
-    pdsch_pdu_rel15->VRBtoPRBMapping = 0; // non interleaved
-
-    for (int i=0; i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) {
-      startSymbolAndLength = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
-      SLIV2SL(startSymbolAndLength, &StartSymbolIndex_tmp, &NrOfSymbols_tmp);
-      if (NrOfSymbols_tmp < NrOfSymbols) {
-        NrOfSymbols = NrOfSymbols_tmp;
-        StartSymbolIndex = StartSymbolIndex_tmp;
-        time_domain_assignment = i; // this is short PDSCH added to the config to fit mixed slot
+    pdsch_pdu_rel15->VRBtoPRBMapping = 0;
+    pdsch_pdu_rel15->StartSymbolIndex = startSymbolIndex;
+    pdsch_pdu_rel15->NrOfSymbols = nrOfSymbols;
+    pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL,
+                                                    nr_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position,
+                                                    nrOfSymbols,
+                                                    startSymbolIndex,
+                                                    mappingtype);
+
+    int x_Overhead = 0;
+    uint8_t tb_scaling = 0;
+    nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling);
+
+    // Fill PDCCH DL DCI PDU
+    nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci];
+    pdcch_pdu_rel15->numDlDci++;
+    dci_pdu->RNTI = ra->RA_rnti;
+    dci_pdu->ScramblingId = *scc->physCellId;
+    dci_pdu->ScramblingRNTI = 0;
+    dci_pdu->AggregationLevel = aggregation_level;
+    dci_pdu->CceIndex = CCEIndex;
+    dci_pdu->beta_PDCCH_1_0 = 0;
+    dci_pdu->powerControlOffsetSS = 1;
+
+    dci_pdu_rel15_t dci_payload;
+    dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize,
+                                                                                    pdsch_pdu_rel15->rbStart,
+                                                                                    pdsch_pdu_rel15->BWPSize);
+
+    dci_payload.time_domain_assignment.val = time_domain_assignment;
+    dci_payload.vrb_to_prb_mapping.val = 0;
+    dci_payload.mcs = pdsch_pdu_rel15->mcsIndex[0];
+    dci_payload.tb_scaling = tb_scaling;
+
+    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",
+          dci_payload.frequency_domain_assignment.val,
+          pdsch_pdu_rel15->rbStart,
+          pdsch_pdu_rel15->rbSize,
+          pdsch_pdu_rel15->BWPSize,
+          dci_payload.time_domain_assignment.val,
+          dci_payload.vrb_to_prb_mapping.val,
+          dci_payload.mcs,
+          dci_payload.tb_scaling);
+
+    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",
+          pdcch_pdu_rel15->dci_pdu[0].RNTI,
+          NR_RNTI_RA,
+          NR_DL_DCI_FORMAT_1_0,
+          (unsigned long long)pdcch_pdu_rel15->FreqDomainResource,
+          pdcch_pdu_rel15->StartSymbolIndex,
+          pdcch_pdu_rel15->DurationSymbols);
+
+    fill_dci_pdu_rel15(scc,
+                       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,
+                       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->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]);
+
+    if(ra->cfra) {
+      LOG_I(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
+    }
+
+    T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->RA_rnti), T_INT(frameP),
+      T_INT(slotP), T_INT(0), T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length));
+
+    tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0];
+    tx_req->PDU_index = pduindex;
+    tx_req->num_TLV = 1;
+    tx_req->TLVs[0].length = tx_req->PDU_length + 2;
+    nr_mac->TX_req[CC_id].SFN = frameP;
+    nr_mac->TX_req[CC_id].Number_of_PDUs++;
+    nr_mac->TX_req[CC_id].Slot = slotP;
+
+    // Mark the corresponding RBs as used
+    for (int rb = 0; rb < rbSize; rb++) {
+      vrb_map[rb + rbStart] = 1;
+    }
+
+    ra->state = WAIT_Msg3;
+    LOG_I(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
+  }
+}
+
+void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) {
+
+  gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
+  NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
+
+  if (ra->Msg4_frame == frameP && ra->Msg4_slot == slotP ) {
+
+    uint8_t time_domain_assignment = 0;
+    uint8_t mcsIndex = 0;
+
+    NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+    NR_SearchSpace_t *ss = ra->ra_ss;
+
+    NR_BWP_Downlink_t *bwp = NULL;
+    NR_ControlResourceSet_t *coreset = NULL;
+    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;
+    }
+
+    if (*ss->controlResourceSetId == 0)
+      coreset = nr_mac->sched_ctrlCommon->coreset; // this is coreset 0
+    else
+      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(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+    long BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+
+    // HARQ management
+    AssertFatal(sched_ctrl->available_dl_harq.head >= 0,
+                "UE context not initialized: no HARQ processes found\n");
+    int current_harq_pid = sched_ctrl->available_dl_harq.head;
+    remove_front_nr_list(&sched_ctrl->available_dl_harq);
+    NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
+    DevAssert(!harq->is_waiting);
+    add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid);
+    harq->is_waiting = true;
+    ra->harq_pid = current_harq_pid;
+
+    // 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;
+    harq->feedback_frame = pucch->frame;
+
+    // Bytes to be transmitted
+    uint8_t *buf = (uint8_t *) harq->tb;
+    uint16_t mac_pdu_length = nr_write_ce_dlsch_pdu(module_idP, nr_mac->sched_ctrlCommon, buf, 255, ra->cont_res_id);
+    LOG_D(NR_MAC,"Encoded contention resolution mac_pdu_length %d\n",mac_pdu_length);
+    uint16_t mac_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, CCCH, ra->rnti, 1, &buf[mac_pdu_length+2]);
+    ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->R = 0;
+    ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->F = 0;
+    ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->LCID = DL_SCH_LCID_CCCH;
+    ((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 + %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 = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
+    SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
+    AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n");
+
+    int mappingtype = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType;
+
+    uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL,
+                                            scc->dmrs_TypeA_Position,
+                                            nrOfSymbols,
+                                            startSymbolIndex,
+                                            mappingtype);
+
+    uint16_t N_DMRS_SLOT = get_num_dmrs(dlDmrsSymbPos);
+
+    long dmrsConfigType = bwp!=NULL ? (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0;
+
+    nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 2;
+    if (nrOfSymbols == 2) {
+      nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 1;
+    }
+
+    AssertFatal(nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData == 1
+                || nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData == 2,
+                "nr_mac->schedCtrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData %d is not possible",
+                nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData);
+
+    uint8_t N_PRB_DMRS = 0;
+    if (dmrsConfigType==NFAPI_NR_DMRS_TYPE1) {
+      N_PRB_DMRS = nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 6;
+    }
+    else {
+      N_PRB_DMRS = nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 4;
+    }
+
+    uint8_t 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)
+        mcsTableIdx = 1;
+      else
+        mcsTableIdx = 2;
+    }
+    else mcsTableIdx = 0;
+
+    int rbStart = 0;
+    int rbSize = 0;
+    uint8_t tb_scaling = 0;
+    uint16_t *vrb_map = cc[CC_id].vrb_map;
+    do {
+      rbSize++;
+      LOG_D(NR_MAC,"Calling nr_compute_tbs with N_PRB_DMRS %d, N_DMRS_SLOT %d\n",N_PRB_DMRS,N_DMRS_SLOT);
+      harq->tb_size = nr_compute_tbs(nr_get_Qm_dl(mcsIndex, mcsTableIdx),
+                           nr_get_code_rate_dl(mcsIndex, mcsTableIdx),
+                           rbSize, nrOfSymbols, N_PRB_DMRS * N_DMRS_SLOT, 0, tb_scaling,1) >> 3;
+    } while (rbStart + rbSize < BWPSize && !vrb_map[rbStart + rbSize] && harq->tb_size < mac_pdu_length);
+
+    for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) {
+      if (vrb_map[rbStart + i]) {
+        rbStart += i;
+        i = 0;
+      }
+    }
+
+    if (rbStart > (BWPSize - rbSize)) {
+      LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RNTI %04x!\n", __func__, ra->rnti);
+      return;
+    }
+
+    // Checking if the DCI allocation is feasible in current subframe
+    nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
+    if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
+      LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, 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][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));
+      dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
+      dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu));
+      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][bwpid][coresetid] = pdcch_pdu_rel15;
     }
 
-    AssertFatal(StartSymbolIndex >= 0, "StartSymbolIndex is negative\n");
+    nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
+    memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
+    dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
+    dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
+    dl_req->nPDUs+=1;
+    nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
+
+    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);
+
+    // 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]++;
+
+    pdsch_pdu_rel15->pduBitmap = 0;
+    pdsch_pdu_rel15->rnti = ra->rnti;
+    pdsch_pdu_rel15->pduIndex = pduindex;
+    pdsch_pdu_rel15->BWPSize  = BWPSize;
+    pdsch_pdu_rel15->BWPStart = BWPStart;
+    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);
+    pdsch_pdu_rel15->qamModOrder[0] = 2;
+    pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
+    pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx;
+    pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[harq->round];
+    pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
+    pdsch_pdu_rel15->nrOfLayers = 1;
+    pdsch_pdu_rel15->transmissionScheme = 0;
+    pdsch_pdu_rel15->refPoint = 0;
+    pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType;
+    pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
+    pdsch_pdu_rel15->SCID = 0;
+    pdsch_pdu_rel15->numDmrsCdmGrpsNoData = nrOfSymbols <= 2 ? 1 : 2;
+    pdsch_pdu_rel15->dmrsPorts = 1;
+    pdsch_pdu_rel15->resourceAlloc = 1;
+    pdsch_pdu_rel15->rbStart = rbStart;
+    pdsch_pdu_rel15->rbSize = rbSize;
+    pdsch_pdu_rel15->VRBtoPRBMapping = 0;
+    pdsch_pdu_rel15->StartSymbolIndex = startSymbolIndex;
+    pdsch_pdu_rel15->NrOfSymbols = nrOfSymbols;
+    pdsch_pdu_rel15->dlDmrsSymbPos = dlDmrsSymbPos;
+
+    int x_Overhead = 0;
+    nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling);
 
-    pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
-    pdsch_pdu_rel15->NrOfSymbols      = NrOfSymbols;
-    pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, scc->dmrs_TypeA_Position, NrOfSymbols);
+    pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=1;
+    pdsch_pdu_rel15->precodingAndBeamforming.prg_size=275;
+    pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces=1;
+    pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0;
+    pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = ra->beam_id;
 
     /* Fill PDCCH DL DCI PDU */
     nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci];
     pdcch_pdu_rel15->numDlDci++;
-    dci_pdu->RNTI = RA_rnti;
-    /* TODO: remove next line */
-    AssertFatal(ss->searchSpaceType->present != NR_SearchSpace__searchSpaceType_PR_ue_Specific,
-                "shouldn't the RA SS be common?\n");
+    dci_pdu->RNTI = ra->rnti;
     dci_pdu->ScramblingId = *scc->physCellId;
     dci_pdu->ScramblingRNTI = 0;
     dci_pdu->AggregationLevel = aggregation_level;
@@ -1000,85 +1422,135 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
 
     dci_pdu_rel15_t dci_payload;
     dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize,
-										     pdsch_pdu_rel15->rbStart,dci10_bw);
+                                                                                    pdsch_pdu_rel15->rbStart,
+                                                                                    pdsch_pdu_rel15->BWPSize);
+
+    dci_payload.format_indicator = 1;
     dci_payload.time_domain_assignment.val = time_domain_assignment;
     dci_payload.vrb_to_prb_mapping.val = 0;
     dci_payload.mcs = pdsch_pdu_rel15->mcsIndex[0];
-    dci_payload.tb_scaling = 0;
-
-    LOG_I(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",
+    dci_payload.tb_scaling = tb_scaling;
+    dci_payload.rv = pdsch_pdu_rel15->rvIndex[0];
+    dci_payload.harq_pid = current_harq_pid;
+    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 = 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 pucchres %d harqtiming %d\n",
           dci_payload.frequency_domain_assignment.val,
           pdsch_pdu_rel15->rbStart,
           pdsch_pdu_rel15->rbSize,
-          dci10_bw,
+          pdsch_pdu_rel15->BWPSize,
           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_I(MAC, "Frame %d: Subframe %d : Adding common DL DCI for RA_RNTI %x\n", frameP, slotP, RA_rnti);
-
-    const int dci_format = NR_DL_DCI_FORMAT_1_0;
-    const int rnti_type = NR_RNTI_RA;
-
-    LOG_I(MAC,
-          "[RAPROC] DCI params: rnti %d, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d  n_symb %d\n",
+    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",
           pdcch_pdu_rel15->dci_pdu[0].RNTI,
-          rnti_type,
-          dci_format,
+          NR_RNTI_TC,
+          NR_DL_DCI_FORMAT_1_0,
           (unsigned long long)pdcch_pdu_rel15->FreqDomainResource,
           pdcch_pdu_rel15->StartSymbolIndex,
           pdcch_pdu_rel15->DurationSymbols);
 
     fill_dci_pdu_rel15(scc,
-                       ra->secondaryCellGroup,
-                       dci_pdu,
+                       ra->CellGroup,
+                       &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1],
                        &dci_payload,
-                       dci_format,
-                       rnti_type,
-                       dci10_bw,
-                       ra->bwp_id);
+                       NR_DL_DCI_FORMAT_1_0,
+                       NR_RNTI_TC,
+                       pdsch_pdu_rel15->BWPSize,
+                       bwpid);
+
+    // Add padding header and zero rest out if there is space left
+    if (mac_pdu_length < harq->tb_size) {
+      NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) &buf[mac_pdu_length];
+      padding->R = 0;
+      padding->LCID = DL_SCH_LCID_PADDING;
+      for(int k = mac_pdu_length+1; k<harq->tb_size; k++) {
+        buf[k] = 0;
+      }
+    }
 
     // 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];
-    tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0];
+    memcpy(tx_req->TLVs[0].value.direct, harq->tb, sizeof(uint8_t) * harq->tb_size);
+    tx_req->PDU_length =  harq->tb_size;
     tx_req->PDU_index = pduindex;
     tx_req->num_TLV = 1;
-    tx_req->TLVs[0].length = 8;
+    tx_req->TLVs[0].length =  harq->tb_size + 2;
     nr_mac->TX_req[CC_id].SFN = frameP;
     nr_mac->TX_req[CC_id].Number_of_PDUs++;
     nr_mac->TX_req[CC_id].Slot = slotP;
 
-    // Program UL processing for Msg3
-    nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra);
-    LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
-    nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]);
-    ra->state = WAIT_Msg3;
-    LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
+    // Mark the corresponding RBs as used
+    for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) {
+      vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1;
+    }
 
-    x_Overhead = 0;
-    nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_payload.tb_scaling);
+    LOG_D(NR_MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize);
+    LOG_D(NR_MAC,"BWPStart: %i\n", pdcch_pdu_rel15->BWPStart);
+    LOG_D(NR_MAC,"SubcarrierSpacing: %i\n", pdcch_pdu_rel15->SubcarrierSpacing);
+    LOG_D(NR_MAC,"CyclicPrefix: %i\n", pdcch_pdu_rel15->CyclicPrefix);
+    LOG_D(NR_MAC,"StartSymbolIndex: %i\n", pdcch_pdu_rel15->StartSymbolIndex);
+    LOG_D(NR_MAC,"DurationSymbols: %i\n", pdcch_pdu_rel15->DurationSymbols);
+    for(int n=0;n<6;n++) LOG_D(NR_MAC,"FreqDomainResource[%i]: %x\n",n, pdcch_pdu_rel15->FreqDomainResource[n]);
+    LOG_D(NR_MAC,"CceRegMappingType: %i\n", pdcch_pdu_rel15->CceRegMappingType);
+    LOG_D(NR_MAC,"RegBundleSize: %i\n", pdcch_pdu_rel15->RegBundleSize);
+    LOG_D(NR_MAC,"InterleaverSize: %i\n", pdcch_pdu_rel15->InterleaverSize);
+    LOG_D(NR_MAC,"CoreSetType: %i\n", pdcch_pdu_rel15->CoreSetType);
+    LOG_D(NR_MAC,"ShiftIndex: %i\n", pdcch_pdu_rel15->ShiftIndex);
+    LOG_D(NR_MAC,"precoderGranularity: %i\n", pdcch_pdu_rel15->precoderGranularity);
+    LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci);
+
+    ra->state = WAIT_Msg4_ACK;
+    LOG_I(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
+  }
+}
 
-    T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id),
-      T_INT(RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0) /* harq pid, meaningful? */,
-      T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length));
+void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) {
 
-    /* mark the corresponding RBs as used */
-    for (int rb = 0; rb < rbSize; rb++)
-      vrb_map[rb + rbStart] = 1;
+  int UE_id = find_nr_UE_id(module_id, ra->rnti);
+  const int current_harq_pid = ra->harq_pid;
+
+  NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
+  NR_UE_harq_t *harq = &UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid];
+
+  LOG_D(NR_MAC, "ue %d, rnti %d, harq is waiting %d, round %d, frame %d %d, harq id %d\n", UE_id, ra->rnti, harq->is_waiting, harq->round, frame, slot, current_harq_pid);
+
+  if (harq->is_waiting == 0)
+  {
+    if (harq->round == 0)
+    {
+      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
+    {
+      ra->state = Msg4;
+    }
   }
+
 }
 
-void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){
-  
-  NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[0];
-  LOG_D(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti);
-  ra->state = IDLE;
+void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra){
+  LOG_D(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti);
+  ra->state = RA_IDLE;
   ra->timing_offset = 0;
   ra->RRC_timer = 20;
-  ra->rnti = 0;
   ra->msg3_round = 0;
+  if(ra->cfra == false) {
+    ra->rnti = 0;
+  }
 }
 
 
@@ -1117,9 +1589,10 @@ void nr_fill_rar(uint8_t Mod_idP,
                  uint8_t * dlsch_buffer,
                  nfapi_nr_pusch_pdu_t  *pusch_pdu){
 
-  LOG_I(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u TA command %d \n", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index, ra->timing_offset);
-  NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer;
-  NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1);
+  LOG_I(NR_MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u TA command %d \n", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index, ra->timing_offset);
+  NR_RA_HEADER_BI *rarbi = (NR_RA_HEADER_BI *) dlsch_buffer;
+  NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) (dlsch_buffer + 1);
+  NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 2);
   unsigned char csi_req = 0, tpc_command;
   //uint8_t N_UL_Hop;
   uint8_t valid_bits;
@@ -1128,6 +1601,16 @@ void nr_fill_rar(uint8_t Mod_idP,
 
   tpc_command = 3; // this is 0 dB
 
+  /// E/T/R/R/BI subheader ///
+  // E = 1, MAC PDU includes another MAC sub-PDU (RAPID)
+  // T = 0, Back-off indicator subheader
+  // R = 2, Reserved
+  // BI = 0, 5ms
+  rarbi->E = 1;
+  rarbi->T = 0;
+  rarbi->R = 0;
+  rarbi->BI = 0;
+
   /// E/T/RAPID subheader ///
   // E = 0, one only RAR, first and last
   // T = 1, RAPID
@@ -1174,4 +1657,50 @@ void nr_fill_rar(uint8_t Mod_idP,
   rar->UL_GRANT_3 = (uint8_t) (ul_grant >> 8) & 0xff;
   rar->UL_GRANT_4 = (uint8_t) ul_grant & 0xff;
 
+#ifdef DEBUG_RAR
+  //LOG_I(NR_MAC, "rarbi->E = 0x%x\n", rarbi->E);
+  //LOG_I(NR_MAC, "rarbi->T = 0x%x\n", rarbi->T);
+  //LOG_I(NR_MAC, "rarbi->R = 0x%x\n", rarbi->R);
+  //LOG_I(NR_MAC, "rarbi->BI = 0x%x\n", rarbi->BI);
+
+  LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E);
+  LOG_I(NR_MAC, "rarh->T = 0x%x\n", rarh->T);
+  LOG_I(NR_MAC, "rarh->RAPID = 0x%x (%i)\n", rarh->RAPID, rarh->RAPID);
+
+  LOG_I(NR_MAC, "rar->R = 0x%x\n", rar->R);
+  LOG_I(NR_MAC, "rar->TA1 = 0x%x\n", rar->TA1);
+
+  LOG_I(NR_MAC, "rar->TA2 = 0x%x\n", rar->TA2);
+  LOG_I(NR_MAC, "rar->UL_GRANT_1 = 0x%x\n", rar->UL_GRANT_1);
+
+  LOG_I(NR_MAC, "rar->UL_GRANT_2 = 0x%x\n", rar->UL_GRANT_2);
+  LOG_I(NR_MAC, "rar->UL_GRANT_3 = 0x%x\n", rar->UL_GRANT_3);
+  LOG_I(NR_MAC, "rar->UL_GRANT_4 = 0x%x\n", rar->UL_GRANT_4);
+
+  LOG_I(NR_MAC, "rar->TCRNTI_1 = 0x%x\n", rar->TCRNTI_1);
+  LOG_I(NR_MAC, "rar->TCRNTI_2 = 0x%x\n", rar->TCRNTI_2);
+#endif
+
+  int mcs = (unsigned char) (rar->UL_GRANT_4 >> 4);
+  // time alloc
+  int Msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x07);
+  // frequency alloc
+  int Msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12));
+  // frequency hopping
+  int freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2);
+  // TA command
+  int  ta_command = rar->TA2 + (rar->TA1 << 5);
+  // TC-RNTI
+  int t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8);
+
+  LOG_I(NR_MAC, "In %s: Transmitted RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti %x \n",
+        __FUNCTION__,
+        Msg3_t_alloc,
+        Msg3_f_alloc,
+        ta_command,
+        mcs,
+        freq_hopping,
+        tpc_command,
+        csi_req,
+        t_crnti);
 }
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index 1de46aaea4504707b4f1305c78c165cb76aadff6..fbd08f18c48297f04f2e54f2ca4e2aa1de161b81 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -53,26 +53,12 @@
 #include "executables/softmodem-common.h"
 
 extern RAN_CONTEXT_t RC;
-extern uint8_t SSB_Table[38];
 
-void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, uint8_t slots_per_frame){
 
-  gNB_MAC_INST *gNB = RC.nrmac[module_idP];
-  NR_COMMON_channels_t *cc;
-  
-  nfapi_nr_dl_tti_request_t      *dl_tti_request;
-  nfapi_nr_dl_tti_request_body_t *dl_req;
-  nfapi_nr_dl_tti_request_pdu_t  *dl_config_pdu;
+uint16_t get_ssboffset_pointa(NR_ServingCellConfigCommon_t *scc,const long band) {
 
-  int mib_sdu_length;
-  int CC_id;
-
-  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-    cc = &gNB->common_channels[CC_id];
-    const long band = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
-    const uint32_t ssb_offset0 = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
-    int ratio;
-    switch (*cc->ServingCellConfigCommon->ssbSubcarrierSpacing) {
+  int ratio;
+  switch (*scc->ssbSubcarrierSpacing) {
     case NR_SubcarrierSpacing_kHz15:
       AssertFatal(band <= 79,
                   "Band %ld is not possible for SSB with 15 kHz SCS\n",
@@ -105,116 +91,206 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP,
       break;
     default:
       AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n",
-                  *cc->ServingCellConfigCommon->ssbSubcarrierSpacing);
-    }
+                  *scc->ssbSubcarrierSpacing);
+  }
 
-    // scheduling MIB every 8 frames, PHY repeats it in between
-    if((slotP == 0) && (frameP & 7) == 0) {
-      dl_tti_request = &gNB->DL_req[CC_id];
-      dl_req = &dl_tti_request->dl_tti_request_body;
-
-      mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]);
-
-      LOG_D(MAC, "Frame %d, slot %d: BCH PDU length %d\n", frameP, slotP, mib_sdu_length);
-
-      if (mib_sdu_length > 0) {
-        LOG_D(MAC,
-              "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n",
-              frameP,
-              slotP,
-              dl_req->nPDUs,
-              mib_sdu_length);
-
-        if ((frameP & 1023) < 80){
-          LOG_D(MAC,
-                "[gNB %d] Frame %d : MIB->BCH  CC_id %d, Received %d bytes\n",
-                module_idP,
-                frameP,
-                CC_id,
-                mib_sdu_length);
-        }
-
-        dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
-        memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
-        dl_config_pdu->PDUType      = NFAPI_NR_DL_TTI_SSB_PDU_TYPE;
-        dl_config_pdu->PDUSize      =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t);
-
-        AssertFatal(cc->ServingCellConfigCommon->physCellId!=NULL,"cc->ServingCellConfigCommon->physCellId is null\n");
-        dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId          = *cc->ServingCellConfigCommon->physCellId;
-        dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss             = 0;
-        dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex       = 0;
-        AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
-        AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
-        AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
-        AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count);
-        AssertFatal(cc->ServingCellConfigCommon->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n");
-        AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n");
-
-        const nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
-        dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; //kSSB
-        dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA     = ssb_offset0/(ratio*12) - 10; // absoluteFrequencySSB is the center of SSB
-        dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag      = 1;
-        dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload          = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1);
-        dl_req->nPDUs++;
-      }
+  const uint32_t ssb_offset0 = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
+
+  return (ssb_offset0/(ratio*12) - 10); // absoluteFrequencySSB is the center of SSB
+
+}
 
-      // Get type0_PDCCH_CSS_config parameters
-      NR_DL_FRAME_PARMS *frame_parms = &RC.gNB[module_idP]->frame_parms;
-      NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib;
-      uint8_t gNB_xtra_byte = 0;
-      for (int i = 0; i < 8; i++) {
-        gNB_xtra_byte |= ((RC.gNB[module_idP]->pbch.pbch_a >> (31 - i)) & 1) << (7 - i);
-      }
-      get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config, mib, gNB_xtra_byte, frame_parms->Lmax,
-                                            frame_parms->ssb_index, frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB);
 
+void schedule_ssb(frame_t frame, sub_frame_t slot,
+                  NR_ServingCellConfigCommon_t *scc,
+                  nfapi_nr_dl_tti_request_body_t *dl_req,
+                  int i_ssb, uint8_t scoffset, uint16_t offset_pointa, uint32_t payload) {
+
+  uint8_t beam_index = 0;
+  nfapi_nr_dl_tti_request_pdu_t  *dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
+  memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
+  dl_config_pdu->PDUType      = NFAPI_NR_DL_TTI_SSB_PDU_TYPE;
+  dl_config_pdu->PDUSize      =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t);
+
+  AssertFatal(scc->physCellId!=NULL,"ServingCellConfigCommon->physCellId is null\n");
+  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId          = *scc->physCellId;
+  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss             = 0;
+  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex       = i_ssb;
+  AssertFatal(scc->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
+  AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
+  AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
+  AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",
+              scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count);
+  AssertFatal(scc->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n");
+  AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n");
+
+  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = scoffset; //kSSB
+  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA     = offset_pointa;
+  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag      = 1;
+  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload          = payload;
+  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.num_prgs=1;
+  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prg_size=275; //1 PRG of max size for analogue beamforming
+  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.dig_bf_interfaces=1;
+  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].pm_idx = 0;
+  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index;
+  dl_req->nPDUs++;
+
+  LOG_D(MAC,"Scheduling ssb %d at frame %d and slot %d\n",i_ssb,frame,slot);
+
+}
+
+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;
+  nfapi_nr_dl_tti_request_body_t *dl_req;
+  NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib;
+  uint8_t num_tdd_period,num_ssb;
+  int mib_sdu_length;
+  int CC_id;
+
+  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+    cc = &gNB->common_channels[CC_id];
+    NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+    const int slots_per_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
+    dl_tti_request = &gNB->DL_req[CC_id];
+    dl_req = &dl_tti_request->dl_tti_request_body;
+
+    // get MIB every 8 frames
+    if(((slotP == 0) && (frameP & 7) == 0) ||
+       gNB->first_MIB) {
+
+      mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 0, 1, &cc->MIB_pdu.payload[0]);
+
+      // flag to avoid sending an empty MIB in the first frames of execution since gNB doesn't get at the beginning in frame 0 slot 0
+      gNB->first_MIB = false;
+
+      LOG_D(MAC,
+            "[gNB %d] Frame %d : MIB->BCH  CC_id %d, Received %d bytes\n",
+            module_idP,
+            frameP,
+            CC_id,
+            mib_sdu_length);
     }
 
-    // checking if there is any SSB in slot
-    const int abs_slot = (slots_per_frame * frameP) + slotP;
-    const int slot_per_period = (slots_per_frame>>1)<<(*cc->ServingCellConfigCommon->ssb_periodicityServingCell);
-    int eff_120_slot;
-    const BIT_STRING_t *shortBitmap = &cc->ServingCellConfigCommon->ssb_PositionsInBurst->choice.shortBitmap;
-    const BIT_STRING_t *mediumBitmap = &cc->ServingCellConfigCommon->ssb_PositionsInBurst->choice.mediumBitmap;
-    const BIT_STRING_t *longBitmap = &cc->ServingCellConfigCommon->ssb_PositionsInBurst->choice.longBitmap;
-    uint8_t buf = 0;
-    switch (cc->ServingCellConfigCommon->ssb_PositionsInBurst->present) {
-      case 1:
-        // presence of ssbs possible in the first 2 slots of ssb period
-        if ((abs_slot % slot_per_period) < 2 &&
-            (((shortBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0)
-          fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id);
-        break;
-      case 2:
-        // presence of ssbs possible in the first 4 slots of ssb period
-        if ((abs_slot % slot_per_period) < 4 &&
-            (((mediumBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0)
-          fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id);
-        break;
-      case 3:
-        AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing ==
-                      NR_SubcarrierSpacing_kHz120,
-                    "240kHZ subcarrier spacing currently not supported for SSBs\n");
-        if ((abs_slot % slot_per_period) < 8) {
-          eff_120_slot = slotP;
-          buf = longBitmap->buf[0];
-        } else if ((abs_slot % slot_per_period) < 17) {
-          eff_120_slot = slotP - 9;
-          buf = longBitmap->buf[1];
-        } else if ((abs_slot % slot_per_period) < 26) {
-          eff_120_slot = slotP - 18;
-          buf = longBitmap->buf[2];
-        } else if ((abs_slot % slot_per_period) < 35) {
-          eff_120_slot = slotP - 27;
-          buf = longBitmap->buf[3];
-        }
-        if (((buf >> (6 - (eff_120_slot << 1))) & 3) != 0)
-          fill_ssb_vrb_map(cc, ssb_offset0 / (ratio * 12) - 10, CC_id);
-        break;
-    default:
-      AssertFatal(0,
-                  "SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
-                  cc->ServingCellConfigCommon->ssb_PositionsInBurst->present);
+    int8_t ssb_period = *scc->ssb_periodicityServingCell;
+    uint8_t ssb_frame_periodicity = 1;  // every how many frames SSB are generated
+
+    if (ssb_period > 1) // 0 is every half frame
+      ssb_frame_periodicity = 1 << (ssb_period -1);
+
+    if (!(frameP%ssb_frame_periodicity) &&
+        ((slotP<(slots_per_frame>>1)) || (ssb_period == 0))) {
+      // schedule SSB only for given frames according to SSB periodicity
+      // and in first half frame unless periodicity of 5ms
+      int rel_slot;
+      if (ssb_period == 0) // scheduling every half frame
+        rel_slot = slotP%(slots_per_frame>>1);
+      else
+        rel_slot = slotP;
+
+      NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing;
+      const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+      uint16_t offset_pointa = get_ssboffset_pointa(scc,band);
+      uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset;
+
+      const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
+      const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
+      const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;
+
+      uint16_t ssb_start_symbol;
+
+      switch (scc->ssb_PositionsInBurst->present) {
+        case 1:
+          // short bitmap (<3GHz) max 4 SSBs
+          for (int i_ssb=0; i_ssb<4; i_ssb++) {
+            if ((shortBitmap->buf[0]>>(7-i_ssb))&0x01) {
+              ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
+              // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
+              if ((ssb_start_symbol/14) == rel_slot){
+                schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
+                fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
+                if (get_softmodem_params()->sa == 1) {
+                  get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
+                                                        frameP,
+                                                        mib,
+                                                        slots_per_frame,
+                                                        ssbSubcarrierOffset,
+                                                        ssb_start_symbol,
+                                                        scs,
+                                                        FR1,
+                                                        i_ssb,
+                                                        offset_pointa);
+                  gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
+                }
+              }
+            }
+          }
+          break;
+        case 2:
+          // medium bitmap (<6GHz) max 8 SSBs
+          for (int i_ssb=0; i_ssb<8; i_ssb++) {
+            if ((mediumBitmap->buf[0]>>(7-i_ssb))&0x01) {
+              ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
+              // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
+              if ((ssb_start_symbol/14) == rel_slot){
+                schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
+                fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
+                if (get_softmodem_params()->sa == 1) {
+                  get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
+                                                        frameP,
+                                                        mib,
+                                                        slots_per_frame,
+                                                        ssbSubcarrierOffset,
+                                                        ssb_start_symbol,
+                                                        scs,
+                                                        FR1,
+                                                        i_ssb,
+                                                        offset_pointa);
+                  gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
+                }
+              }
+            }
+          }
+          break;
+        case 3:
+          // long bitmap FR2 max 64 SSBs
+          num_ssb = 0;
+          for (int i_ssb=0; i_ssb<64; i_ssb++) {
+            if ((longBitmap->buf[i_ssb/8]>>(7-(i_ssb%8)))&0x01) {
+              ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
+              // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
+              if ((ssb_start_symbol/14) == rel_slot){
+                schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
+                fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
+                const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
+                const int nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0;
+                const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots;
+                num_tdd_period = rel_slot/nr_slots_period;
+                gNB->tdd_beam_association[num_tdd_period]=i_ssb;
+                num_ssb++;
+                AssertFatal(num_ssb<2,"beamforming currently not supported for more than one SSB per slot\n");
+                if (get_softmodem_params()->sa == 1) {
+                  get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
+                                                        frameP,
+                                                        mib,
+                                                        slots_per_frame,
+                                                        ssbSubcarrierOffset,
+                                                        ssb_start_symbol,
+                                                        scs,
+                                                        FR2,
+                                                        i_ssb,
+                                                        offset_pointa);
+                  gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
+                }
+              }
+            }
+          }
+          break;
+        default:
+          AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
+                      scc->ssb_PositionsInBurst->present);
+      }
     }
   }
 }
@@ -224,17 +300,26 @@ void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframe
 //----------------------------------------  
 }
 
-void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id) {
+void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart,  uint16_t symStart, int CC_id) {
+
+  AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing !=
+              NR_SubcarrierSpacing_kHz240,
+              "240kHZ subcarrier won't work with current VRB map because a single SSB might be across 2 slots\n");
+
   uint16_t *vrb_map = cc[CC_id].vrb_map;
+
   for (int rb = 0; rb < 20; rb++)
-    vrb_map[rbStart + rb] = 1;
+    vrb_map[rbStart + rb] = 15<<symStart;
+
 }
 
 void schedule_control_sib1(module_id_t module_id,
                            int CC_id,
+                           NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
                            int time_domain_allocation,
                            uint8_t mcsTableIdx,
                            uint8_t mcs,
+                           uint8_t candidate_idx,
                            int num_total_bytes) {
 
   gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
@@ -242,20 +327,19 @@ void schedule_control_sib1(module_id_t module_id,
   uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
 
   if (gNB_mac->sched_ctrlCommon == NULL){
+    LOG_D(NR_MAC,"schedule_control_common: Filling nr_mac->sched_ctrlCommon\n");
     gNB_mac->sched_ctrlCommon = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon));
     gNB_mac->sched_ctrlCommon->search_space = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->search_space));
-    gNB_mac->sched_ctrlCommon->active_bwp = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->active_bwp));
     gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset));
     gNB_mac->sched_ctrlCommon->active_bwp = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->active_bwp));
     fill_default_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space);
     fill_default_coresetZero(gNB_mac->sched_ctrlCommon->coreset,servingcellconfigcommon);
     fill_default_initialDownlinkBWP(gNB_mac->sched_ctrlCommon->active_bwp,servingcellconfigcommon);
   }
-  gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL;
 
-  gNB_mac->sched_ctrlCommon->time_domain_allocation = time_domain_allocation;
-  gNB_mac->sched_ctrlCommon->mcsTableIdx = mcsTableIdx;
-  gNB_mac->sched_ctrlCommon->mcs = mcs;
+  gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation = time_domain_allocation;
+  gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx = mcsTableIdx;
+  gNB_mac->sched_ctrlCommon->sched_pdsch.mcs = mcs;
   gNB_mac->sched_ctrlCommon->num_total_bytes = num_total_bytes;
 
   uint8_t nr_of_candidates;
@@ -266,70 +350,77 @@ void schedule_control_sib1(module_id_t module_id,
                                                           gNB_mac->sched_ctrlCommon->coreset,
                                                           gNB_mac->sched_ctrlCommon->aggregation_level,
                                                           0,
-                                                          0,
+                                                          candidate_idx,
                                                           nr_of_candidates);
 
-  if (gNB_mac->sched_ctrlCommon->cce_index < 0) {
-    LOG_E(MAC, "%s(): could not find CCE for coreset0\n", __func__);
-    return;
-  }
+  AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n");
+
+  const uint16_t bwpSize = type0_PDCCH_CSS_config->num_rbs;
+  int rbStart = type0_PDCCH_CSS_config->cset_start_rb;
 
-  const uint16_t bwpSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
-  int rbStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
+  int startSymbolIndex = 0;
+  int nrOfSymbols = 0;
 
-  // Calculate number of symbols
-  struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
-  const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength;
-  int startSymbolIndex, nrOfSymbols;
-  SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
+  if(gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position == 0) {
+    startSymbolIndex = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][1];
+    nrOfSymbols = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][2];
+  } else {
+    startSymbolIndex = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][1];
+    nrOfSymbols = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][2];
+  }
+
+  // TODO: There are exceptions to this in table 5.1.2.1.1-4,5 (Default time domain allocation tables B, C)
+  int mappingtype = (startSymbolIndex <= 3)? typeA: typeB;
 
   if (nrOfSymbols == 2) {
-    gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData = 1;
+    gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 1;
   } else {
-    gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData = 2;
+    gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 2;
   }
 
   // Calculate number of PRB_DMRS
-  uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6;
-  uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols);
+  uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 6;
+  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->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
-                         nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->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);
 
-    // FIXME: Something is not working in nr_modulation() for TBS = 84, so we need to skip it
-  } while ( (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes) || (TBS==84) );
-
-  gNB_mac->sched_ctrlCommon->rbSize = rbSize;
-  gNB_mac->sched_ctrlCommon->rbStart = 0;
+  gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize = rbSize;
+  gNB_mac->sched_ctrlCommon->sched_pdsch.rbStart = 0;
 
-  LOG_D(MAC,"SLIV = %i\n", startSymbolAndLength);
   LOG_D(MAC,"startSymbolIndex = %i\n", startSymbolIndex);
   LOG_D(MAC,"nrOfSymbols = %i\n", nrOfSymbols);
-  LOG_D(MAC,"rbSize = %i\n", gNB_mac->sched_ctrlCommon->rbSize);
+  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
-  for (int rb = 0; rb < gNB_mac->sched_ctrlCommon->rbSize; rb++) {
+  for (int rb = 0; rb < gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize; rb++) {
     vrb_map[rb + rbStart] = 1;
   }
 }
 
 void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
                                nfapi_nr_dl_tti_request_body_t *dl_req,
+                               NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
                                uint32_t TBS,
                                int StartSymbolIndex,
-                               int NrOfSymbols) {
+                               int NrOfSymbols,
+                               uint16_t dlDmrsSymbPos) {
 
   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];
@@ -344,6 +435,10 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
                      scc,
                      bwp);
 
+  // TODO: This assignment should be done in function nr_configure_pdcch()
+  pdcch_pdu_rel15->BWPSize = type0_PDCCH_CSS_config->num_rbs;
+  pdcch_pdu_rel15->BWPStart = type0_PDCCH_CSS_config->cset_start_rb;
+
   nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
   memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
   dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
@@ -357,8 +452,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
   pdsch_pdu_rel15->rnti = SI_RNTI;
   pdsch_pdu_rel15->pduIndex = gNB_mac->pdu_index[0]++;
 
-  pdsch_pdu_rel15->BWPSize  = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
-  pdsch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
+  pdsch_pdu_rel15->BWPSize  = type0_PDCCH_CSS_config->num_rbs;
+  pdsch_pdu_rel15->BWPStart = type0_PDCCH_CSS_config->cset_start_rb;
 
   pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
   if (bwp->bwp_Common->genericParameters.cyclicPrefix) {
@@ -368,32 +463,31 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
   }
 
   pdsch_pdu_rel15->NrOfCodewords = 1;
-  pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs,0);
+  pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, 0);
   pdsch_pdu_rel15->qamModOrder[0] = 2;
-  pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->mcs;
+  pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs;
   pdsch_pdu_rel15->mcsTable[0] = 0;
   pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[0];
   pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
   pdsch_pdu_rel15->nrOfLayers = 1;
   pdsch_pdu_rel15->transmissionScheme = 0;
   pdsch_pdu_rel15->refPoint = 1;
-  pdsch_pdu_rel15->dmrsConfigType = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
+  pdsch_pdu_rel15->dmrsConfigType = 0;
   pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
   pdsch_pdu_rel15->SCID = 0;
-  pdsch_pdu_rel15->numDmrsCdmGrpsNoData = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData;
+  pdsch_pdu_rel15->numDmrsCdmGrpsNoData = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData;
   pdsch_pdu_rel15->dmrsPorts = 1;
   pdsch_pdu_rel15->resourceAlloc = 1;
-  pdsch_pdu_rel15->rbStart = gNB_mac->sched_ctrlCommon->rbStart;
-  pdsch_pdu_rel15->rbSize = gNB_mac->sched_ctrlCommon->rbSize;
+  pdsch_pdu_rel15->rbStart = gNB_mac->sched_ctrlCommon->sched_pdsch.rbStart;
+  pdsch_pdu_rel15->rbSize = gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize;
   pdsch_pdu_rel15->VRBtoPRBMapping = 0;
-  pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx);
+  pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs,
+                                                 gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx);
   pdsch_pdu_rel15->TBSize[0] = TBS;
-  pdsch_pdu_rel15->mcsTable[0] = gNB_mac->sched_ctrlCommon->mcsTableIdx;
+  pdsch_pdu_rel15->mcsTable[0] = gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx;
   pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
   pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols;
-
-  pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, pdsch_pdu_rel15->StartSymbolIndex+pdsch_pdu_rel15->NrOfSymbols);
-
+  pdsch_pdu_rel15->dlDmrsSymbPos = dlDmrsSymbPos;
   LOG_D(MAC,"dlDmrsSymbPos = 0x%x\n", pdsch_pdu_rel15->dlDmrsSymbPos);
 
   /* Fill PDCCH DL DCI PDU */
@@ -415,10 +509,10 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
 
   // frequency domain assignment
   dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(
-      pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, gNB_mac->type0_PDCCH_CSS_config.num_rbs);
+      pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, type0_PDCCH_CSS_config->num_rbs);
 
-  dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->time_domain_allocation;
-  dci_payload.mcs = gNB_mac->sched_ctrlCommon->mcs;
+  dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation;
+  dci_payload.mcs = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs;
   dci_payload.rv = pdsch_pdu_rel15->rvIndex[0];
   dci_payload.harq_pid = 0;
   dci_payload.ndi = 0;
@@ -433,7 +527,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,
@@ -460,61 +554,95 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
 
 void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
 
-  LOG_D(MAC,"Schedule_nr_sib1: frameP = %i, slotP = %i\n", frameP, slotP);
-
   // TODO: Get these values from RRC
   const int CC_id = 0;
   int time_domain_allocation = 0;
   uint8_t mcsTableIdx = 0;
   uint8_t mcs = 6;
+  uint8_t candidate_idx = 0;
 
   gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
+  NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
 
-  if( (frameP%2 == gNB_mac->type0_PDCCH_CSS_config.sfn_c) && (slotP == gNB_mac->type0_PDCCH_CSS_config.n_0) && (gNB_mac->type0_PDCCH_CSS_config.num_rbs > 0) ) {
+  int L_max;
+  switch (scc->ssb_PositionsInBurst->present) {
+    case 1:
+      L_max = 4;
+      break;
+    case 2:
+      L_max = 8;
+      break;
+    case 3:
+      L_max = 64;
+      break;
+    default:
+      AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
+                  scc->ssb_PositionsInBurst->present);
+  }
 
-    LOG_D(MAC,"> SIB1 transmission\n");
+  for (int i=0; i<L_max; i++) {
 
-    // Get SIB1
-    uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
-    uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, 1, sib1_payload);
-    LOG_D(MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
-    LOG_D(MAC,"SIB1: \n");
-    for (int i=0;i<sib1_sdu_length;i++) LOG_D(MAC,"byte %d : %x\n",i,((uint8_t*)sib1_payload)[i]);
+    NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[i];
 
-    // Configure sched_ctrlCommon for SIB1
-    schedule_control_sib1(module_idP, CC_id, time_domain_allocation, mcsTableIdx, mcs, sib1_sdu_length);
+    if((frameP%2 == type0_PDCCH_CSS_config->sfn_c) &&
+       (slotP == type0_PDCCH_CSS_config->n_0) &&
+       (type0_PDCCH_CSS_config->num_rbs > 0) &&
+       (type0_PDCCH_CSS_config->active == true)) {
 
-    // Calculate number of symbols
-    int startSymbolIndex, nrOfSymbols;
-    struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
-    const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength;
-    SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
+      LOG_D(NR_MAC,"(%d.%d) SIB1 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index);
 
-    // Calculate number of PRB_DMRS
-    uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6;
-    uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols);
-    uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos);
+      // Get SIB1
+      uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
+      uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, SI_RNTI, 1, sib1_payload);
+      LOG_D(NR_MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
+      LOG_D(NR_MAC,"SIB1: \n");
+      for (int k=0;k<sib1_sdu_length;k++)
+        LOG_D(NR_MAC,"byte %d : %x\n",k,((uint8_t*)sib1_payload)[k]);
 
-    const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
-                                        nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
-                                        gNB_mac->sched_ctrlCommon->rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3;
+      // Configure sched_ctrlCommon for SIB1
+      schedule_control_sib1(module_idP, CC_id, type0_PDCCH_CSS_config, time_domain_allocation, mcsTableIdx, mcs, candidate_idx, sib1_sdu_length);
 
-    nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
-    nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, TBS, startSymbolIndex, nrOfSymbols);
+      int startSymbolIndex = 0;
+      int nrOfSymbols = 0;
+      if(gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position == 0) {
+        startSymbolIndex = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][1];
+        nrOfSymbols = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][2];
+      } else {
+        startSymbolIndex = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][1];
+        nrOfSymbols = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation][2];
+      }
+
+      // TODO: There are exceptions to this in table 5.1.2.1.1-4,5 (Default time domain allocation tables B, C)
+      int mappingtype = (startSymbolIndex <= 3) ? typeA : typeB;
+
+      // Calculate number of PRB_DMRS
+      uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 6;
+      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);
+
+      const uint32_t 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),
+                                          gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3;
 
-    const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
-    nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
+      nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
+      nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, type0_PDCCH_CSS_config, TBS, startSymbolIndex, nrOfSymbols, dlDmrsSymbPos);
 
-    // Data to be transmitted
-    bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES);
-    memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
+      const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
+      nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
 
-    tx_req->PDU_length = TBS;
-    tx_req->PDU_index  = gNB_mac->pdu_index[0]++;
-    tx_req->num_TLV = 1;
-    tx_req->TLVs[0].length = TBS + 2;
-    gNB_mac->TX_req[CC_id].Number_of_PDUs++;
-    gNB_mac->TX_req[CC_id].SFN = frameP;
-    gNB_mac->TX_req[CC_id].Slot = slotP;
+      // Data to be transmitted
+      bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES);
+      memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
+
+      tx_req->PDU_length = TBS;
+      tx_req->PDU_index  = gNB_mac->pdu_index[0]++;
+      tx_req->num_TLV = 1;
+      tx_req->TLVs[0].length = TBS + 2;
+      gNB_mac->TX_req[CC_id].Number_of_PDUs++;
+      gNB_mac->TX_req[CC_id].SFN = frameP;
+      gNB_mac->TX_req[CC_id].Slot = slotP;
+
+      type0_PDCCH_CSS_config->active = false;
+    }
   }
 }
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index 4d491b28434edd5c2f649e4ad1d9cef42b56b03f..bfdb1a01e39183d1e3f05d48ed82ce5d361ea2ad 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -55,6 +55,84 @@
 #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->bwp_Id : 0;
+  if (nrmac->preferred_dl_tda[bwp_id])
+    return;
+
+  /* there is a mixed slot only when in TDD */
+  NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
+  const NR_TDD_UL_DL_Pattern_t *tdd =
+      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 = 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;
+
+  /* check that TDA index 0 fits into DL and does not overlap CORESET */
+  const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
+      bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+  AssertFatal(tdaList->list.count >= 1, "need to have at least one TDA for DL slots\n");
+  const NR_PDSCH_TimeDomainResourceAllocation_t *tdaP_DL = tdaList->list.array[0];
+  AssertFatal(!tdaP_DL->k0 || *tdaP_DL->k0 == 0,
+              "TimeDomainAllocation at index 1: non-null k0 (%ld) is not supported by the scheduler\n",
+              *tdaP_DL->k0);
+  int start, len;
+  SLIV2SL(tdaP_DL->startSymbolAndLength, &start, &len);
+  const uint16_t symb_tda = ((1 << len) - 1) << start;
+  // check whether coreset and TDA overlap: then we cannot use it. Note that
+  // here we assume that the coreset is scheduled every slot (which it
+  // currently is) and starting at symbol 0
+  AssertFatal((symb_coreset & symb_tda) == 0, "TDA index 0 for DL overlaps with CORESET\n");
+
+  /* check that TDA index 1 fits into DL part of mixed slot, if it exists */
+  int tdaMi = -1;
+  if (tdaList->list.count > 1) {
+    const NR_PDSCH_TimeDomainResourceAllocation_t *tdaP_Mi = tdaList->list.array[1];
+    AssertFatal(!tdaP_Mi->k0 || *tdaP_Mi->k0 == 0,
+                "TimeDomainAllocation at index 1: non-null k0 (%ld) is not supported by the scheduler\n",
+                *tdaP_Mi->k0);
+    int start, len;
+    SLIV2SL(tdaP_Mi->startSymbolAndLength, &start, &len);
+    const uint16_t symb_tda = ((1 << len) - 1) << start;
+    // check whether coreset and TDA overlap: then, we cannot use it. Also,
+    // check whether TDA is entirely within mixed slot DL. Note that
+    // here we assume that the coreset is scheduled every slot (which it
+    // currently is)
+    if ((symb_coreset & symb_tda) == 0 && (symb_dlMixed & symb_tda) == symb_tda) {
+      tdaMi = 1;
+    } else {
+      LOG_E(MAC,
+            "TDA index 1 DL overlaps with CORESET or is not entirely in mixed slot (symb_coreset %x symb_dlMixed %x symb_tda %x), won't schedule DL mixed slot\n",
+            symb_coreset,
+            symb_dlMixed,
+            symb_tda);
+    }
+  }
+
+  const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
+  const int n = slots_per_frame[*scc->ssbSubcarrierSpacing];
+  nrmac->preferred_dl_tda[bwp_id] = malloc(n * sizeof(*nrmac->preferred_dl_tda[bwp_id]));
+
+  const int nr_mix_slots = tdd ? tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0 : 0;
+  const int nr_slots_period = tdd ? tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots : n;
+  for (int i = 0; i < n; ++i) {
+    nrmac->preferred_dl_tda[bwp_id][i] = -1;
+    if (!tdd || i % nr_slots_period < tdd->nrofDownlinkSlots)
+      nrmac->preferred_dl_tda[bwp_id][i] = 0;
+    else if (tdd && nr_mix_slots && i % nr_slots_period == tdd->nrofDownlinkSlots)
+      nrmac->preferred_dl_tda[bwp_id][i] = tdaMi;
+    LOG_I(MAC, "slot %d preferred_dl_tda %d\n", i, nrmac->preferred_dl_tda[bwp_id][i]);
+  }
+}
 
 // Compute and write all MAC CEs and subheaders, and return number of written
 // bytes
@@ -100,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);
@@ -119,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
@@ -144,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);
@@ -255,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;
@@ -302,35 +380,6 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
   return offset;
 }
 
-int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda) {
-  struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
-    bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
-  AssertFatal(tda < tdaList->list.count,
-              "time_domain_allocation %d>=%d\n",
-              tda,
-              tdaList->list.count);
-
-  const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
-  int startSymbolIndex, nrOfSymbols;
-  SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
-  return nrOfSymbols;
-}
-
-nfapi_nr_dmrs_type_e getDmrsConfigType(NR_BWP_Downlink_t *bwp) {
-  return bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
-}
-
-uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData) {
-  const nfapi_nr_dmrs_type_e dmrsConfigType = getDmrsConfigType(bwp);
-  if (dmrsConfigType == NFAPI_NR_DMRS_TYPE1) {
-    // 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
-    return numDmrsCdmGrpsNoData * 6;
-  } else {
-    return numDmrsCdmGrpsNoData * 4;
-  }
-}
-
 void nr_store_dlsch_buffer(module_id_t module_id,
                            frame_t frame,
                            sub_frame_t slot) {
@@ -341,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,
@@ -354,73 +411,159 @@ 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);
   }
 }
 
-bool allocate_retransmission(module_id_t module_id,
-                             uint8_t *rballoc_mask,
-                             int *n_rb_sched,
-                             int UE_id,
-                             int current_harq_pid){
-  NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id];
-  NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
-  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);
+bool allocate_dl_retransmission(module_id_t module_id,
+                                frame_t frame,
+                                sub_frame_t slot,
+                                uint8_t *rballoc_mask,
+                                int *n_rb_sched,
+                                int UE_id,
+                                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;
+  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);
 
-  sched_ctrl->time_domain_allocation = retInfo->time_domain_allocation;
+  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);
 
-  /* ensure that there is a free place for RB allocation */
   int rbSize = 0;
-  while (rbSize < retInfo->rbSize) {
-    rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
-    rbSize = 0;
-    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,
-            RC.nrmac[module_id]->UE_info.rnti[UE_id]);
-      return false;
+  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) {
+      rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
+      rbSize = 0;
+      while (rbStart < bwpSize && !rballoc_mask[rbStart])
+        rbStart++;
+      if (rbStart >= bwpSize) {
+        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)
+        rbSize++;
     }
-    while (rbStart + rbSize < bwpSize
-           && rballoc_mask[rbStart + rbSize]
-           && rbSize < retInfo->rbSize)
+    /* check whether we need to switch the TDA allocation since the last
+     * (re-)transmission */
+    if (ps->time_domain_allocation != tda || ps->numDmrsCdmGrpsNoData != num_dmrs_cdm_grps_no_data)
+      nr_set_pdsch_semi_static(
+          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 */
+    while (rbStart < bwpSize && !rballoc_mask[rbStart])
+      rbStart++;
+    while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize])
       rbSize++;
+    NR_pdsch_semi_static_t temp_ps;
+    nr_set_pdsch_semi_static(
+        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,
+                                 retInfo->R,
+                                 temp_ps.nrOfSymbols,
+                                 temp_ps.N_PRB_DMRS * temp_ps.N_DMRS_SLOT,
+                                 retInfo->tb_size,
+                                 rbSize,
+                                 &new_tbs,
+                                 &new_rbSize);
+    if (!success || new_tbs != retInfo->tb_size) {
+      LOG_D(MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size);
+      return false; /* the maximum TBsize we might have is smaller than what we need */
+    }
+    /* we can allocate it. Overwrite the time_domain_allocation, the number
+     * of RBs, and the new TB size. The rest is done below */
+    retInfo->tb_size = new_tbs;
+    retInfo->rbSize = new_rbSize;
+    retInfo->time_domain_allocation = tda;
+    sched_ctrl->pdsch_semi_static = temp_ps;
   }
-  sched_ctrl->rbSize = retInfo->rbSize;
-  sched_ctrl->rbStart = rbStart;
 
-  /* MCS etc: just reuse from previous scheduling opportunity */
-  sched_ctrl->mcsTableIdx = retInfo->mcsTableIdx;
-  sched_ctrl->mcs = retInfo->mcs;
-  sched_ctrl->numDmrsCdmGrpsNoData = retInfo->numDmrsCdmGrpsNoData;
+  /* 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 retransmission UE %d/RNTI %04x\n",
+          frame, slot, UE_id, UE_info->rnti[UE_id]);
+    return false;
+  }
+
+  /* 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, -1);
+  if (alloc<0) {
+    LOG_D(MAC,
+          "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
+          __func__,
+          UE_id,
+          UE_info->rnti[UE_id],
+          frame,
+          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];
+    for (int i = 0; i < sched_ctrl->aggregation_level; i++)
+      cce_list[sched_ctrl->cce_index + i] = 0;
+    return false;
+  }
+
+  sched_ctrl->sched_pdsch.pucch_allocation = alloc;
+
+  /* just reuse from previous scheduling opportunity, set new start RB */
+  sched_ctrl->sched_pdsch = *retInfo;
+  sched_ctrl->sched_pdsch.rbStart = rbStart;
 
   /* retransmissions: directly allocate */
-  *n_rb_sched -= sched_ctrl->rbSize;
-  for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
-    rballoc_mask[rb+sched_ctrl->rbStart] = 0;
+  *n_rb_sched -= sched_ctrl->sched_pdsch.rbSize;
+  for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++)
+    rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] = 0;
   return true;
 }
 
 float thr_ue[MAX_MOBILES_PER_GNB];
+uint32_t pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient
 
 void pf_dl(module_id_t module_id,
            frame_t frame,
            sub_frame_t slot,
            NR_list_t *UE_list,
+           int max_num_ue,
            int n_rb_sched,
-           uint8_t *rballoc_mask,
-           int max_num_ue) {
+           uint8_t *rballoc_mask) {
 
-  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];
@@ -428,12 +571,13 @@ 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];
-    sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, NR_SearchSpace__searchSpaceType_PR_ue_Specific);
-    sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
+    if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
+    NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
+    NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
     /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
-    sched_ctrl->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
-    const rnti_t rnti = UE_info->rnti[UE_id];
+    sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
 
     /* Calculate Throughput */
     const float a = 0.0005f; // corresponds to 200ms window
@@ -441,35 +585,12 @@ void pf_dl(module_id_t module_id,
     thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b;
 
     /* retransmission */
-    if (sched_ctrl->dl_harq_pid >= 0) {
-      /* 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 retransmission UE %d/RNTI %04x\n", frame, slot, UE_id, rnti);
-        continue;
-      }
-      /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
-       * allocation after CCE alloc fail would be more complex) */
-      const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot);
-      if (!alloc) {
-        LOG_W(MAC,
-              "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
-              __func__,
-              UE_id,
-              rnti,
-              frame,
-              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];
-        for (int i = 0; i < sched_ctrl->aggregation_level; i++)
-          cce_list[sched_ctrl->cce_index + i] = 0;
-        return;
-      }
+    if (sched_pdsch->dl_harq_pid >= 0) {
       /* Allocate retransmission */
-      bool r = allocate_retransmission(module_id, rballoc_mask, &n_rb_sched, UE_id, sched_ctrl->dl_harq_pid);
+      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 */
@@ -481,25 +602,11 @@ void pf_dl(module_id_t module_id,
         continue;
 
       /* Calculate coeff */
-      sched_ctrl->time_domain_allocation = 2;
-      sched_ctrl->mcsTableIdx = 0;
-      sched_ctrl->mcs = 9;
-      sched_ctrl->numDmrsCdmGrpsNoData = 1;
-      uint8_t N_PRB_DMRS =
-              getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
-      int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp,
-                                       sched_ctrl->time_domain_allocation);
-      uint32_t tbs = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
-                                    nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
-                                    1,  // rbSize
-                                    nrOfSymbols,
-                                    N_PRB_DMRS,  // FIXME // This should be multiplied by the
-                                    // number of dmrs symbols
-                                    0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */,
-                                    1 /* nrOfLayers */)
-                     >> 3;
+      sched_pdsch->mcs = 9;
+      sched_pdsch->nrOfLayers = 1;
+      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);
@@ -527,14 +634,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 */
@@ -543,9 +655,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 bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot);
-    if (!alloc) {
-      LOG_W(MAC,
+    const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1);
+    if (alloc<0) {
+      LOG_D(NR_MAC,
             "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
             __func__,
             UE_id,
@@ -554,64 +666,56 @@ 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;
     }
 
-    /* Allocate transmission */
-    // Time-domain allocation
-    sched_ctrl->time_domain_allocation = 2;
-
-    // modulation scheme
-    sched_ctrl->mcsTableIdx = 0;
-    sched_ctrl->mcs = 9;
-    sched_ctrl->numDmrsCdmGrpsNoData = 1;
-
     // Freq-demain allocation
     while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
-
-    const uint8_t N_PRB_DMRS =
-        getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
-    const int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp,
-        sched_ctrl->time_domain_allocation);
-    const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon;
-    const uint8_t N_DMRS_SLOT = get_num_dmrs_symbols(
-        sched_ctrl->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup,
-        scc->dmrs_TypeA_Position,
-        nrOfSymbols);
-
-    int rbSize = 0;
+    uint16_t max_rbSize = 1;
+    while (rbStart + max_rbSize < bwpSize && rballoc_mask[rbStart + max_rbSize])
+      max_rbSize++;
+
+    /* MCS has been set above */
+    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->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;
     uint32_t TBS = 0;
-    const int oh = 2 + (sched_ctrl->num_total_bytes >= 256)
-                 + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
-    do {
-      rbSize++;
-      TBS = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
-                           nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
-                           rbSize,
-                           nrOfSymbols,
-                           N_PRB_DMRS * N_DMRS_SLOT,
-                           0 /* N_PRB_oh, 0 for initialBWP */,
-                           0 /* tb_scaling */,
-                           1 /* nrOfLayers */)
-            >> 3;
-    } while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize] && TBS < sched_ctrl->num_total_bytes + oh);
-    sched_ctrl->rbSize = rbSize;
-    sched_ctrl->rbStart = rbStart;
+    uint16_t rbSize;
+    const int oh = 3 + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
+    nr_find_nb_rb(sched_pdsch->Qm,
+                  sched_pdsch->R,
+                  ps->nrOfSymbols,
+                  ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
+                  sched_ctrl->num_total_bytes + oh,
+                  max_rbSize,
+                  &TBS,
+                  &rbSize);
+    sched_pdsch->rbSize = rbSize;
+    sched_pdsch->rbStart = rbStart;
+    sched_pdsch->tb_size = TBS;
 
     /* transmissions: directly allocate */
-    n_rb_sched -= sched_ctrl->rbSize;
-    for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
-      rballoc_mask[rb+sched_ctrl->rbStart] = 0;
+    n_rb_sched -= sched_pdsch->rbSize;
+    for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
+      rballoc_mask[rb + sched_pdsch->rbStart] = 0;
   }
 }
 
-void nr_simple_dlsch_preprocessor(module_id_t module_id,
-                                  frame_t frame,
-                                  sub_frame_t slot) {
+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;
@@ -622,7 +726,11 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
   /* Get bwpSize from the first UE */
   int UE_id = UE_info->list.head;
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
-  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];
@@ -642,15 +750,45 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
         frame,
         slot,
         &UE_info->list,
+        2,
         n_rb_sched,
-        rballoc_mask,
-        2);
+        rballoc_mask);
+}
+
+nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id)
+{
+  /* in the PF algorithm, we have to use the TBsize to compute the coefficient.
+   * This would include the number of DMRS symbols, which in turn depends on
+   * the time domain allocation. In case we are in a mixed slot, we do not want
+   * to recalculate all these values just, and therefore we provide a look-up
+   * table which should approximately give us the TBsize */
+  for (int mcsTableIdx = 0; mcsTableIdx < 3; ++mcsTableIdx) {
+    for (int mcs = 0; mcs < 29; ++mcs) {
+      if (mcs > 27 && mcsTableIdx == 1)
+        continue;
+      const uint8_t Qm = nr_get_Qm_dl(mcs, mcsTableIdx);
+      const uint16_t R = nr_get_code_rate_dl(mcs, mcsTableIdx);
+      pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm,
+                                                R,
+                                                1, /* rbSize */
+                                                10, /* hypothetical number of slots */
+                                                0, /* N_PRB_DMRS * N_DMRS_SLOT */
+                                                0 /* N_PRB_oh, 0 for initialBWP */,
+                                                0 /* tb_scaling */,
+                                                1 /* nrOfLayers */)
+                                 >> 3;
+    }
+  }
+
+  return nr_fr1_dlsch_preprocessor;
 }
 
 void nr_schedule_ue_spec(module_id_t module_id,
                          frame_t frame,
                          sub_frame_t slot) {
   gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
+  if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
+    return;
 
   /* PREPROCESSOR */
   gNB_mac->pre_processor_dl(module_id, frame, slot);
@@ -664,6 +802,8 @@ 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;
 
     /* update TA and set ta_apply every 10 frames.
@@ -672,48 +812,26 @@ 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_ctrl->rbSize <= 0)
+    if (sched_pdsch->rbSize <= 0)
       continue;
 
     const rnti_t rnti = UE_info->rnti[UE_id];
 
     /* POST processing */
-    struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
-      sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
-    AssertFatal(sched_ctrl->time_domain_allocation < tdaList->list.count,
-                "time_domain_allocation %d>=%d\n",
-                sched_ctrl->time_domain_allocation,
-                tdaList->list.count);
-
-    const int startSymbolAndLength =
-      tdaList->list.array[sched_ctrl->time_domain_allocation]->startSymbolAndLength;
-    int startSymbolIndex, nrOfSymbols;
-    SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
-
-    uint8_t N_PRB_DMRS =
-        getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
-    uint8_t N_DMRS_SLOT = get_num_dmrs_symbols(sched_ctrl->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup,
-                                               RC.nrmac[module_id]->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position ,
-                                               nrOfSymbols);
-    const nfapi_nr_dmrs_type_e dmrsConfigType = getDmrsConfigType(sched_ctrl->active_bwp);
-    const int nrOfLayers = 1;
-    const uint16_t R = nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx);
-    const uint8_t Qm = nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx);
-    const uint32_t TBS =
-        nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
-                       nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
-                       sched_ctrl->rbSize,
-                       nrOfSymbols,
-                       N_PRB_DMRS * N_DMRS_SLOT,
-                       0 /* N_PRB_oh, 0 for initialBWP */,
-                       0 /* tb_scaling */,
-                       nrOfLayers)
-        >> 3;
-
-    int8_t current_harq_pid = sched_ctrl->dl_harq_pid;
+    const uint8_t nrOfLayers = sched_pdsch->nrOfLayers;
+    const uint16_t R = sched_pdsch->R;
+    const uint8_t Qm = sched_pdsch->Qm;
+    const uint32_t TBS = sched_pdsch->tb_size;
+
+    /* pre-computed PDSCH values that only change if time domain
+     * allocation/DMRS parameters change. Updated in the preprocessor through
+     * nr_set_pdsch_semi_static() */
+    NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
+
+    int8_t current_harq_pid = sched_pdsch->dl_harq_pid;
     if (current_harq_pid < 0) {
       /* PP has not selected a specific HARQ Process, get a new one */
       current_harq_pid = sched_ctrl->available_dl_harq.head;
@@ -721,7 +839,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
                   "no free HARQ process available for UE %d\n",
                   UE_id);
       remove_front_nr_list(&sched_ctrl->available_dl_harq);
-      sched_ctrl->dl_harq_pid = current_harq_pid;
+      sched_pdsch->dl_harq_pid = current_harq_pid;
     } else {
       /* PP selected a specific HARQ process. Check whether it will be a new
        * transmission or a retransmission, and remove from the corresponding
@@ -734,36 +852,33 @@ void nr_schedule_ue_spec(module_id_t module_id,
     NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
     DevAssert(!harq->is_waiting);
     add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid);
-    NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0];
+    NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[sched_pdsch->pucch_allocation];
+    harq->feedback_frame = pucch->frame;
     harq->feedback_slot = pucch->ul_slot;
     harq->is_waiting = true;
     UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++;
 
-    LOG_D(MAC,
-          "%4d.%2d RNTI %04x start %d RBs %d startSymbol %d nb_symbsol %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n",
+    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,
           rnti,
-          sched_ctrl->rbStart,
-          sched_ctrl->rbSize,
-          startSymbolIndex,
-          nrOfSymbols,
-          sched_ctrl->mcs,
+          sched_pdsch->rbStart,
+          sched_pdsch->rbSize,
+          ps->startSymbolIndex,
+          ps->nrOfSymbols,
+          sched_pdsch->mcs,
           TBS,
           current_harq_pid,
           harq->round,
           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];
@@ -772,7 +887,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;
     }
 
@@ -792,20 +910,22 @@ 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;
     pdsch_pdu->targetCodeRate[0] = R;
     pdsch_pdu->qamModOrder[0] = Qm;
-    pdsch_pdu->mcsIndex[0] = sched_ctrl->mcs;
-    pdsch_pdu->mcsTable[0] = sched_ctrl->mcsTableIdx;
+    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;
 
@@ -815,29 +935,33 @@ void nr_schedule_ue_spec(module_id_t module_id,
     pdsch_pdu->refPoint = 0; // Point A
 
     // DMRS
-    pdsch_pdu->dlDmrsSymbPos =
-        fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup,
-                       scc->dmrs_TypeA_Position,
-                       nrOfSymbols);
-    pdsch_pdu->dmrsConfigType = dmrsConfigType;
+    pdsch_pdu->dlDmrsSymbPos = ps->dl_dmrs_symb_pos;
+    pdsch_pdu->dmrsConfigType = ps->dmrsConfigType;
     pdsch_pdu->dlDmrsScramblingId = *scc->physCellId;
     pdsch_pdu->SCID = 0;
-    pdsch_pdu->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData;
+    pdsch_pdu->numDmrsCdmGrpsNoData = ps->numDmrsCdmGrpsNoData;
     pdsch_pdu->dmrsPorts = 1;
 
     // Pdsch Allocation in frequency domain
     pdsch_pdu->resourceAlloc = 1;
-    pdsch_pdu->rbStart = sched_ctrl->rbStart;
-    pdsch_pdu->rbSize = sched_ctrl->rbSize;
+    pdsch_pdu->rbStart = sched_pdsch->rbStart;
+    pdsch_pdu->rbSize = sched_pdsch->rbSize;
     pdsch_pdu->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP
 
     // Resource Allocation in time domain
-    pdsch_pdu->StartSymbolIndex = startSymbolIndex;
-    pdsch_pdu->NrOfSymbols = nrOfSymbols;
+    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,
@@ -857,7 +981,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;
@@ -874,21 +1000,21 @@ 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 == 1,
-          "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 <= 1, "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.time_domain_assignment.val = sched_ctrl->time_domain_allocation;
-    dci_payload.mcs = sched_ctrl->mcs;
+    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];
     dci_payload.harq_pid = current_harq_pid;
     dci_payload.ndi = harq->ndi;
@@ -898,9 +1024,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,
@@ -912,54 +1038,33 @@ 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,
           pdcch_pdu->DurationSymbols);
 
-    NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
     if (harq->round != 0) { /* retransmission */
-      if (sched_ctrl->rbSize != retInfo->rbSize)
-        LOG_W(MAC,
-              "retransmission uses different rbSize (%d vs. orig %d)\n",
-              sched_ctrl->rbSize,
-              retInfo->rbSize);
-      if (sched_ctrl->time_domain_allocation != retInfo->time_domain_allocation)
-        LOG_W(MAC,
-              "retransmission uses different time_domain_allocation (%d vs. orig %d)\n",
-              sched_ctrl->time_domain_allocation,
-              retInfo->time_domain_allocation);
-      if (sched_ctrl->mcs != retInfo->mcs
-          || sched_ctrl->mcsTableIdx != retInfo->mcsTableIdx
-          || sched_ctrl->numDmrsCdmGrpsNoData != retInfo->numDmrsCdmGrpsNoData)
-        LOG_W(MAC,
-              "retransmission uses different table/MCS/numDmrsCdmGrpsNoData (%d/%d/%d vs. orig %d/%d/%d)\n",
-              sched_ctrl->mcsTableIdx,
-              sched_ctrl->mcs,
-              sched_ctrl->numDmrsCdmGrpsNoData,
-              retInfo->mcsTableIdx,
-              retInfo->mcs,
-              retInfo->numDmrsCdmGrpsNoData);
       /* 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,
@@ -968,15 +1073,15 @@ void nr_schedule_ue_spec(module_id_t module_id,
             current_harq_pid,
             harq->round,
             harq->ndi);
-      AssertFatal(harq->tb_size == TBS,
+
+      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);
 
-      harq->tb_size = TBS;
       uint8_t *buf = (uint8_t *) harq->tb;
 
       /* first, write all CEs that might be there */
@@ -991,7 +1096,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;
@@ -1018,12 +1124,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);
@@ -1045,14 +1152,14 @@ void nr_schedule_ue_spec(module_id_t module_id,
           size += 3;
         }
       }
-      else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) {
+      else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
         /* we will need the large header, phy-test typically allocates all
          * resources and fills to the last byte below */
         NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
         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;
@@ -1084,17 +1191,17 @@ void nr_schedule_ue_spec(module_id_t module_id,
       UE_info->mac_stats[UE_id].dlsch_current_bytes = TBS;
       UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += dlsch_total_bytes;
 
-      retInfo->rbSize = sched_ctrl->rbSize;
-      retInfo->time_domain_allocation = sched_ctrl->time_domain_allocation;
-      retInfo->mcsTableIdx = sched_ctrl->mcsTableIdx;
-      retInfo->mcs = sched_ctrl->mcs;
-      retInfo->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData;
+      /* save retransmission information */
+      harq->sched_pdsch = *sched_pdsch;
+      /* save which time allocation has been used, to be used on
+       * retransmissions */
+      harq->sched_pdsch.time_domain_allocation = ps->time_domain_allocation;
 
       // ta command is sent, values are reset
       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,
@@ -1117,6 +1224,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
     gNB_mac->TX_req[CC_id].Slot = slot;
 
     /* mark UE as scheduled */
-    sched_ctrl->rbSize = 0;
+    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 6487f391b9198bfb489dba0471ba670f53e3fa84..47ccc74612a3a58c5e995e986af8fde5d3d5eeb2 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -146,15 +146,18 @@ void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
     int startSymbolAndLength=0;
     int StartSymbolIndex=-1,NrOfSymbols=14;
     int StartSymbolIndex_tmp,NrOfSymbols_tmp;
+    int mappingtype_tmp, mappingtype=0;
 
     for (int i=0;
 	 i<scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;
 	 i++) {
       startSymbolAndLength = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
       SLIV2SL(startSymbolAndLength,&StartSymbolIndex_tmp,&NrOfSymbols_tmp);
+      mappingtype_tmp = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType;
       if (NrOfSymbols_tmp < NrOfSymbols) {
 	NrOfSymbols = NrOfSymbols_tmp;
         StartSymbolIndex = StartSymbolIndex_tmp;
+        mappingtype = mappingtype_tmp;
 	//	k0 = *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0;
 	//	time_domain_assignment = i;
       }
@@ -164,7 +167,9 @@ void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
     pdsch_pdu_rel15->NrOfSymbols      = NrOfSymbols;
     pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL,
 						    scc->dmrs_TypeA_Position,
-						    NrOfSymbols);
+						    NrOfSymbols,
+                StartSymbolIndex,
+                mappingtype);
 
     /*
     AssertFatal(k0==0,"k0 is not zero for Initial DL BWP TimeDomain Alloc\n");
@@ -254,14 +259,21 @@ void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
   }
 }
 
+extern int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda);
+extern uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData);
+uint32_t target_dl_mcs = 9;
+uint32_t target_dl_Nl = 1;
+uint32_t target_dl_bw = 50;
+uint64_t dlsch_slot_bitmap = (1<<1);
 /* schedules whole bandwidth for first user, all the time */
 void nr_preprocessor_phytest(module_id_t module_id,
                              frame_t frame,
                              sub_frame_t slot)
 {
-  if (slot != 1)
+  if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot))
     return;
   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],
@@ -272,24 +284,27 @@ void nr_preprocessor_phytest(module_id_t module_id,
   /* find largest unallocated chunk */
   const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
   int rbStart = 0;
-  int tStart = 0;
   int rbSize = 0;
+  if (target_dl_bw>bwpSize)
+    target_dl_bw = bwpSize;
   uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
-  /* find largest unallocated RB region */
-  do {
+  /* loop ensures that we allocate exactly target_dl_bw, or return */
+  while (true) {
     /* advance to first free RB */
-    while (tStart < bwpSize && vrb_map[tStart])
-      tStart++;
-    /* find maximum rbSize at current rbStart */
-    int tSize = 1;
-    while (tStart + tSize < bwpSize && !vrb_map[tStart + tSize])
-      tSize++;
-    if (tSize > rbSize) {
-      rbStart = tStart;
-      rbSize = tSize;
-    }
-    tStart += tSize;
-  } while (tStart < bwpSize);
+    while (rbStart < bwpSize && vrb_map[rbStart])
+      rbStart++;
+    rbSize = 1;
+    /* iterate until we are at target_dl_bw or no available RBs */
+    while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && rbSize < target_dl_bw)
+      rbSize++;
+    /* found target_dl_bw? */
+    if (rbSize == target_dl_bw)
+      break;
+    /* at end and below target_dl_bw? */
+    if (rbStart + rbSize >= bwpSize)
+      return;
+    rbStart += rbSize;
+  }
 
   sched_ctrl->num_total_bytes = 0;
   const int lcid = DL_SCH_LCID_DTCH;
@@ -308,14 +323,10 @@ void nr_preprocessor_phytest(module_id_t module_id,
                                                     0);
   sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
 
-  const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
-  sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, 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 */);
   const int cid = sched_ctrl->coreset->controlResourceSetId;
   const uint16_t Y = UE_info->Y[UE_id][cid][slot];
   const int m = UE_info->num_pdcch_cand[UE_id][cid];
@@ -331,8 +342,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
               __func__,
               UE_id);
 
-  const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot);
-  if (!alloc) {
+  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",
           __func__,
@@ -347,36 +358,50 @@ void nr_preprocessor_phytest(module_id_t module_id,
     return;
   }
 
-  AssertFatal(alloc,
-              "could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n",
-              rnti, frame, slot);
-
-  sched_ctrl->rbStart = rbStart;
-  sched_ctrl->rbSize = rbSize;
-  sched_ctrl->time_domain_allocation = 2;
-  if (!UE_info->secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table)
-    sched_ctrl->mcsTableIdx = 0;
-  else {
-    if (*UE_info->secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table == 0)
-      sched_ctrl->mcsTableIdx = 1;
-    else
-      sched_ctrl->mcsTableIdx = 2;
-  }
-  sched_ctrl->mcs = 9;
-  sched_ctrl->numDmrsCdmGrpsNoData = 1;
+  //AssertFatal(alloc,
+  //            "could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n",
+  //            rnti, frame, slot);
+
+  NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
+  NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
+  sched_pdsch->pucch_allocation = alloc;
+  sched_pdsch->rbStart = rbStart;
+  sched_pdsch->rbSize = rbSize;
+  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->CellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
+
+  sched_pdsch->nrOfLayers = target_dl_Nl;
+  sched_pdsch->mcs = target_dl_mcs;
+  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->tb_size = nr_compute_tbs(sched_pdsch->Qm,
+                                        sched_pdsch->R,
+                                        sched_pdsch->rbSize,
+                                        ps->nrOfSymbols,
+                                        ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
+                                        0 /* N_PRB_oh, 0 for initialBWP */,
+                                        0 /* tb_scaling */,
+                                        sched_pdsch->nrOfLayers)
+                         >> 3;
+
   /* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */
-  sched_ctrl->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
+  sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
 
   /* mark the corresponding RBs as used */
-  for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
-    vrb_map[rb + sched_ctrl->rbStart] = 1;
+  for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
+    vrb_map[rb + sched_pdsch->rbStart] = 1;
+
+  if ((frame&127) == 0) LOG_D(MAC,"phytest: %d.%d DL mcs %d, DL rbStart %d, DL rbSize %d\n", frame, slot, sched_pdsch->mcs, rbStart,rbSize);
 }
 
-bool nr_ul_preprocessor_phytest(module_id_t module_id,
-                                frame_t frame,
-                                sub_frame_t slot,
-                                int num_slots_per_tdd,
-                                uint64_t ulsch_in_slot_bitmap) {
+uint32_t target_ul_mcs = 9;
+uint32_t target_ul_bw = 50;
+uint64_t ulsch_slot_bitmap = (1 << 8);
+bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot)
+{
   gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
   NR_COMMON_channels_t *cc = nr_mac->common_channels;
   NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -395,32 +420,53 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id,
 
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
 
-  const int tda = 1;
+  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 =
     sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
   AssertFatal(tda < tdaList->list.count,
               "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
    * limitations).  Note that if K2 or the TDD configuration is changed, below
    * conditions might exclude each other and never be true */
-  if (!(is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot) && sched_slot == 8))
+  if (!is_xlsch_in_slot(ulsch_slot_bitmap, sched_slot))
     return false;
 
-  const int bw = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  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 uint8_t num_dmrs_cdm_grps_no_data = 1;
+  /* 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 */
+  NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
+  if (ps->time_domain_allocation != tda
+      || ps->dci_format != dci_format
+      || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
+    nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
+
   uint16_t rbStart = 0;
-  uint16_t rbSize = 50; /* due to OAI UE limitations */
-  if (rbSize>bw)
+  uint16_t rbSize;
+
+  const int bw = NRRIV2BW(sched_ctrl->active_ubwp ?
+			  sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth :
+			  scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
+  if (target_ul_bw>bw)
     rbSize = bw;
+  else
+    rbSize = target_ul_bw;
 
   uint16_t *vrb_map_UL =
       &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
+  const uint16_t symb = ((1 << ps->nrOfSymbols) - 1) << ps->startSymbolIndex;
   for (int i = rbStart; i < rbStart + rbSize; ++i) {
-    if (vrb_map_UL[i]) {
+    if ((vrb_map_UL[i] & symb) != 0) {
       LOG_E(MAC,
             "%s(): %4d.%2d RB %d is already reserved, cannot schedule UE\n",
             __func__,
@@ -434,14 +480,10 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id,
   sched_ctrl->sched_pusch.slot = sched_slot;
   sched_ctrl->sched_pusch.frame = sched_frame;
 
-  const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
-  sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, 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 */);
   const int cid = sched_ctrl->coreset->controlResourceSetId;
   const uint16_t Y = UE_info->Y[UE_id][cid][slot];
   const int m = UE_info->num_pdcch_cand[UE_id][cid];
@@ -458,25 +500,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id,
   }
   UE_info->num_pdcch_cand[UE_id][cid]++;
 
-  sched_ctrl->sched_pusch.time_domain_allocation = tda;
-  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 uint8_t num_dmrs_cdm_grps_no_data = 1;
-  /* 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 */
-  NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
-  if (ps->time_domain_allocation != tda
-      || ps->dci_format != dci_format
-      || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
-    nr_save_pusch_fields(scc,
-                         sched_ctrl->active_ubwp,
-                         dci_format,
-                         tda,
-                         num_dmrs_cdm_grps_no_data,
-                         ps);
-
-  const int mcs = 9;
+  const int mcs = target_ul_mcs;
   NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
   sched_pusch->mcs = mcs;
   sched_pusch->rbStart = rbStart;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 20da8fa30aaa520b3e44a22549de780c03f0043f..1606e5dfef523e674b46a0165eebd62612c1d9be 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -120,18 +120,23 @@ static inline uint8_t get_max_candidates(uint8_t scs) {
 static inline uint8_t get_max_cces(uint8_t scs) {
   AssertFatal(scs<4, "Invalid PDCCH subcarrier spacing %d\n", scs);
   return (nr_max_number_of_cces_per_slot[scs]);
-} 
+}
 
-NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp,
+NR_ControlResourceSet_t *get_coreset(NR_ServingCellConfigCommon_t *scc,
+                                     NR_BWP_Downlink_t *bwp,
                                      NR_SearchSpace_t *ss,
-                                     int ss_type) {
+                                     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;
@@ -146,22 +151,24 @@ NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp,
   }
 }
 
-NR_SearchSpace_t *get_searchspace(
-    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,
@@ -178,8 +185,8 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
   int coreset_id = coreset->controlResourceSetId;
 
   int *cce_list;
-  if(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];
   }
@@ -212,38 +219,126 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
 
 }
 
-void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc,
-                          const NR_BWP_Uplink_t *ubwp,
-                          long dci_format,
-                          int tda,
-                          uint8_t num_dmrs_cdm_grps_no_data,
-                          NR_sched_pusch_save_t *ps)
+bool nr_find_nb_rb(uint16_t Qm,
+                   uint16_t R,
+                   uint16_t nb_symb_sch,
+                   uint16_t nb_dmrs_prb,
+                   uint32_t bytes,
+                   uint16_t nb_rb_max,
+                   uint32_t *tbs,
+                   uint16_t *nb_rb)
+{
+  /* is the maximum (not even) enough? */
+  *nb_rb = nb_rb_max;
+  *tbs = nr_compute_tbs(Qm, R, *nb_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3;
+  /* check whether it does not fit, or whether it exactly fits. Some algorithms
+   * might depend on the return value! */
+  if (bytes > *tbs)
+    return false;
+  if (bytes == *tbs)
+    return true;
+
+  /* is the minimum enough? */
+  *nb_rb = 1;
+  *tbs = nr_compute_tbs(Qm, R, *nb_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3;
+  if (bytes <= *tbs)
+    return true;
+
+  /* perform binary search to allocate all bytes within a TBS up to nb_rb_max
+   * RBs */
+  int hi = nb_rb_max;
+  int lo = 1;
+  for (int p = (hi + lo) / 2; lo + 1 < hi; p = (hi + lo) / 2) {
+    const uint32_t TBS = nr_compute_tbs(Qm, R, p, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3;
+    if (bytes == TBS) {
+      hi = p;
+      break;
+    } else if (bytes < TBS) {
+      hi = p;
+    } else {
+      lo = p;
+    }
+  }
+  *nb_rb = hi;
+  *tbs = nr_compute_tbs(Qm, R, *nb_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3;
+  /* return whether we could allocate all bytes and stay below nb_rb_max */
+  return *tbs >= bytes && *nb_rb <= nb_rb_max;
+}
+
+void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
+                              const NR_CellGroupConfig_t *secondaryCellGroup,
+                              const NR_BWP_Downlink_t *bwp,
+                              int tda,
+                              uint8_t num_dmrs_cdm_grps_no_data,
+                              NR_pdsch_semi_static_t *ps)
+{
+  ps->time_domain_allocation = tda;
+
+  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);
+
+  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!=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->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,
+                              const NR_BWP_Uplink_t *ubwp,
+                              long dci_format,
+                              int tda,
+                              uint8_t num_dmrs_cdm_grps_no_data,
+                              NR_pusch_semi_static_t *ps)
 {
   ps->dci_format = dci_format;
   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,
@@ -256,25 +351,26 @@ void nr_save_pusch_fields(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;
-  const uint16_t l_prime_mask = get_l_prime(ps->nrOfSymbols,
+    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,
-                                            pusch_maxLength);
-  ps->ul_dmrs_symb_pos = l_prime_mask << ps->startSymbolIndex;
+                                            pusch_maxLength,
+                                            ps->startSymbolIndex,
+                                            scc->dmrs_TypeA_Position);
   uint8_t num_dmrs_symb = 0;
   for(int i = ps->startSymbolIndex; i < ps->startSymbolIndex + ps->nrOfSymbols; i++)
     num_dmrs_symb += (ps->ul_dmrs_symb_pos >> i) & 1;
@@ -503,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,
@@ -510,7 +607,10 @@ 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;
@@ -520,8 +620,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;
@@ -531,7 +631,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
@@ -545,7 +649,7 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp,
       AssertFatal(0, "Valid UL formats are 0_0 and 0_1\n");
   }
 
-  LOG_D(MAC,
+  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,
@@ -557,82 +661,94 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp,
         dci_pdu_rel15->rv);
 }
 
+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)
 {
-  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;
-
-    // first symbol
-    //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored");
-    int sps = bwp->bwp_Common->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;
-      }
-    }
+  NR_BWP_t *genericParameters = bwp ? &bwp->bwp_Common->genericParameters : &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
 
-    pdcch_pdu->DurationSymbols  = coreset->duration;
-    
-    for (int i=0;i<6;i++)
-      pdcch_pdu->FreqDomainResource[i] = coreset->frequencyDomainResources.buf[i];
+  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;
 
-    
-    //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;
-    }
+  // 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;
+
+  AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n");
+  AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n");
 
-    if(coreset->controlResourceSetId == 0) {
-      pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
-    } else{
-      pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
+  // 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;
     }
+  }
 
-    //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 { // this is for InitialBWP
-    AssertFatal(1==0,"Fill in InitialBWP PDCCH configuration\n");
+  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;
@@ -646,60 +762,70 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
   int res_found = 0;
 
   pucch_pdu->bit_len_harq = O_ack;
+  pucch_pdu->bit_len_csi_part1 = O_csi;
 
   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);
-    }
-
-    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;
+  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);
+  }
 
-    pucch_Config = bwp->bwp_Dedicated->pucch_Config->choice.setup;
+  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");
+                "PUCCH resourceSetToAddModList is null\n");
 
-    n_set = pucch_Config->resourceSetToAddModList->list.count; 
+    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 
+    // 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++) {
@@ -708,7 +834,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
       if (pucchresset->pucch_ResourceSetId == 0 && O_uci<3) {
         if (pucch_resource < n_list)
           resource_id = pucchresset->resourceList.list.array[pucch_resource];
-        else 
+        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) {
@@ -720,7 +846,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
         if (N2<O_uci && N3>O_uci) {
           if (pucch_resource < n_list)
             resource_id = pucchresset->resourceList.list.array[pucch_resource];
-          else 
+          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;
@@ -730,9 +856,9 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
     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");
+                "PUCCH resourceToAddModList is null\n");
 
-    n_list = pucch_Config->resourceToAddModList->list.count; 
+    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
@@ -825,30 +951,48 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
       }
     }
     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");
   }
-
+  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;
+  }
 }
 
 
-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;
@@ -858,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)
@@ -879,8 +1023,8 @@ void prepare_dci(const NR_CellGroupConfig_t *secondaryCellGroup,
       if (bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[bwp_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:
@@ -900,7 +1044,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 :
@@ -910,7 +1054,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,
@@ -920,12 +1064,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) {
@@ -936,7 +1080,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,
@@ -946,7 +1090,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,
@@ -954,7 +1098,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,
@@ -963,21 +1107,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,
@@ -988,7 +1132,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,
@@ -1018,7 +1162,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,
@@ -1027,7 +1171,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,
@@ -1036,31 +1180,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,
@@ -1069,7 +1213,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,
@@ -1131,6 +1275,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
       break;
 
     case NR_RNTI_TC:
+      pos = 1;
       // indicating a DL DCI format 1bit
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 1) << (dci_size - pos++);
       // Freq domain assignment 0-16 bit
@@ -1159,9 +1304,27 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
       // TPC command for scheduled PUCCH – 2 bits
       for (int i = 0; i < 2; i++)
         *dci_pdu |= (((uint64_t)dci_pdu_rel15->tpc >> (1 - i)) & 1) << (dci_size - pos++);
+      // PUCCH resource indicator – 3 bits
+      for (int i = 0; i < 3; i++)
+        *dci_pdu |= (((uint64_t)dci_pdu_rel15->pucch_resource_indicator >> (2 - i)) & 1) << (dci_size - pos++);
       // PDSCH-to-HARQ_feedback timing indicator – 3 bits
       for (int i = 0; i < 3; i++)
         *dci_pdu |= (((uint64_t)dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val >> (2 - i)) & 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->format_indicator = %i\n", dci_pdu_rel15->format_indicator);
+      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->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val);
+      LOG_D(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs);
+      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->dai[0].val = %i\n", dci_pdu_rel15->dai[0].val);
+      LOG_D(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc);
+      LOG_D(NR_MAC,"dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = %i\n", dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val);
+
       break;
     }
     break;
@@ -1169,31 +1332,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++);
@@ -1203,6 +1369,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:
@@ -1406,7 +1585,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) {
@@ -1445,7 +1624,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]);
 }
 
 /*
@@ -1581,7 +1760,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);
@@ -1613,59 +1792,93 @@ int get_nrofHARQ_ProcessesForPDSCH(e_NR_PDSCH_ServingCellConfig__nrofHARQ_Proces
   }
 }
 
+int get_dl_bwp_id(const NR_ServingCellConfig_t *servingCellConfig)
+{
+  if (servingCellConfig->firstActiveDownlinkBWP_Id)
+    return *servingCellConfig->firstActiveDownlinkBWP_Id;
+  else if (servingCellConfig->defaultDownlinkBWP_Id)
+    return *servingCellConfig->defaultDownlinkBWP_Id;
+  else
+    return 1;
+}
+
+int get_ul_bwp_id(const NR_ServingCellConfig_t *servingCellConfig)
+{
+  if (servingCellConfig->uplinkConfig && servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id)
+    return *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id;
+  else
+    return 1;
+}
+
 //------------------------------------------------------------------------------
-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, UE_info, UE_id);
+    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->pusch_save.time_domain_allocation = -1;
-    const NR_ServingCellConfig_t *servingCellConfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated;
+    sched_ctrl->pdsch_semi_static.time_domain_allocation = -1;
+    sched_ctrl->pusch_semi_static.time_domain_allocation = -1;
+    const NR_ServingCellConfig_t *servingCellConfig = CellGroup ? CellGroup->spCellConfig->spCellConfigDedicated : NULL;
 
     /* Set default BWPs */
-    const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
-    AssertFatal(bwpList->list.count == 1,
-                "downlinkBWP_ToAddModList has %d BWP!\n",
-                bwpList->list.count);
+    const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig ? servingCellConfig->downlinkBWP_ToAddModList : NULL;
+    if (bwpList) AssertFatal(bwpList->list.count == 1,
+			     "downlinkBWP_ToAddModList has %d BWP!\n",
+			     bwpList->list.count);
     const int bwp_id = 1;
-    sched_ctrl->active_bwp = bwpList->list.array[bwp_id - 1];
-    const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
-    AssertFatal(ubwpList->list.count == 1,
-                "uplinkBWP_ToAddModList has %d BWP!\n",
-                ubwpList->list.count);
-    sched_ctrl->active_ubwp = ubwpList->list.array[bwp_id - 1];
+    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);
+    if (*sched_ctrl->search_space->controlResourceSetId == 0)
+      sched_ctrl->coreset = RC.nrmac[mod_idP]->sched_ctrlCommon->coreset; // this is coreset 0
+    else
+      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 == 1,
+			      "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++)
@@ -1679,7 +1892,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);
@@ -1688,7 +1901,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;
 }
@@ -1702,6 +1915,7 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
 {
   int UE_id;
   int i;
+  int cc_id;
   NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
 
   for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
@@ -1725,7 +1939,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);
@@ -1734,19 +1948,43 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
     if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1);
     if (rnti_to_remove_count == 10) exit(1);
     rnti_to_remove[rnti_to_remove_count] = rnti;
-    LOG_W(MAC, "to remove in mac rnti_to_remove[%d]=%d\n", rnti_to_remove_count, rnti);
+    LOG_W(NR_MAC, "to remove in mac rnti_to_remove[%d] = 0x%04x\n", rnti_to_remove_count, rnti);
     rnti_to_remove_count++;
     if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
   }
+
+  /* clear RA process(es?) associated to the UE */
+  for (cc_id = 0; cc_id < NFAPI_CC_MAX; cc_id++) {
+    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(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;
+        cc->ra[i].crnti = 0;
+      }
+    }
+  }
+}
+
+void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti) {
+  // Hack to remove UE in the phy (following the same procedure as in function mac_remove_nr_ue)
+  if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1);
+  if (rnti_to_remove_count == 10) exit(1);
+  rnti_to_remove[rnti_to_remove_count] = rnti;
+  LOG_W(NR_MAC, "to remove in mac rnti_to_remove[%d] = 0x%04x\n", rnti_to_remove_count, rnti);
+  rnti_to_remove_count++;
+  if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
 }
 
 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
 }
 
@@ -1758,11 +1996,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) {
@@ -1802,6 +2045,206 @@ void get_pdsch_to_harq_feedback(int Mod_idP,
 }
 
 
+void nr_csirs_scheduling(int Mod_idP,
+                         frame_t frame,
+                         sub_frame_t slot,
+                         int n_slots_frame){
+
+  int CC_id = 0;
+  NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
+  NR_list_t *UE_list = &UE_info->list;
+  gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP];
+  uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map;
+
+  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_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id];
+
+    if (!CellGroup || !CellGroup->spCellConfig || !CellGroup->spCellConfig->spCellConfigDedicated ||
+	      !CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig) continue;
+
+    NR_CSI_MeasConfig_t *csi_measconfig = CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
+
+    if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList != NULL) {
+
+      NR_NZP_CSI_RS_Resource_t *nzpcsi;
+      int period, offset;
+
+      nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
+      NR_BWP_Downlink_t *bwp=CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[sched_ctrl->active_bwp->bwp_Id-1];
+
+      for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){
+        nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id];
+        NR_CSI_RS_ResourceMapping_t  resourceMapping = nzpcsi->resourceMapping;
+        csi_period_offset(NULL,nzpcsi,&period,&offset);
+
+        if((frame*n_slots_frame+slot-offset)%period == 0) {
+
+          LOG_I(MAC,"Scheduling CSI-RS in frame %d slot %d\n",frame,slot);
+
+          nfapi_nr_dl_tti_request_pdu_t *dl_tti_csirs_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
+          memset((void*)dl_tti_csirs_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
+          dl_tti_csirs_pdu->PDUType = NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE;
+          dl_tti_csirs_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_csi_rs_pdu));
+
+          nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csirs_pdu_rel15 = &dl_tti_csirs_pdu->csi_rs_pdu.csi_rs_pdu_rel15;
+
+          csirs_pdu_rel15->bwp_size  = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
+          csirs_pdu_rel15->bwp_start = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
+          csirs_pdu_rel15->subcarrier_spacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
+          if (bwp->bwp_Common->genericParameters.cyclicPrefix)
+            csirs_pdu_rel15->cyclic_prefix = *bwp->bwp_Common->genericParameters.cyclicPrefix;
+          else
+            csirs_pdu_rel15->cyclic_prefix = 0;
+
+          csirs_pdu_rel15->start_rb = resourceMapping.freqBand.startingRB;
+          csirs_pdu_rel15->nr_of_rbs = resourceMapping.freqBand.nrofRBs;
+          csirs_pdu_rel15->csi_type = 1; // NZP-CSI-RS
+          csirs_pdu_rel15->symb_l0 = resourceMapping.firstOFDMSymbolInTimeDomain;
+          if (resourceMapping.firstOFDMSymbolInTimeDomain2)
+            csirs_pdu_rel15->symb_l1 = *resourceMapping.firstOFDMSymbolInTimeDomain2;
+          csirs_pdu_rel15->cdm_type = resourceMapping.cdm_Type;
+          csirs_pdu_rel15->freq_density = resourceMapping.density.present;
+          if ((resourceMapping.density.present == NR_CSI_RS_ResourceMapping__density_PR_dot5)
+              && (resourceMapping.density.choice.dot5 == NR_CSI_RS_ResourceMapping__density__dot5_evenPRBs))
+            csirs_pdu_rel15->freq_density--;
+          csirs_pdu_rel15->scramb_id = nzpcsi->scramblingID;
+          csirs_pdu_rel15->power_control_offset = nzpcsi->powerControlOffset + 8;
+          if (nzpcsi->powerControlOffsetSS)
+            csirs_pdu_rel15->power_control_offset_ss = *nzpcsi->powerControlOffsetSS;
+          else
+            csirs_pdu_rel15->power_control_offset_ss = 1; // 0 dB
+          switch(resourceMapping.frequencyDomainAllocation.present){
+            case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1:
+              csirs_pdu_rel15->row = 1;
+              csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row1.buf[0])>>4)&0x0f;
+              for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
+              break;
+            case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2:
+              csirs_pdu_rel15->row = 2;
+              csirs_pdu_rel15->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]>>4)&0x0f) |
+                                             ((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]<<8)&0xff0));
+              for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
+              break;
+            case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4:
+              csirs_pdu_rel15->row = 4;
+              csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row4.buf[0])>>5)&0x07;
+              for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
+              break;
+            case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other:
+              csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.other.buf[0])>>2)&0x3f;
+              // determining the row of table 7.4.1.5.3-1 in 38.211
+              switch(resourceMapping.nrofPorts){
+                case NR_CSI_RS_ResourceMapping__nrofPorts_p1:
+                  break;
+                case NR_CSI_RS_ResourceMapping__nrofPorts_p2:
+                  csirs_pdu_rel15->row = 3;
+                  for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                    vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
+                  break;
+                case NR_CSI_RS_ResourceMapping__nrofPorts_p4:
+                  csirs_pdu_rel15->row = 5;
+                  for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                    vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
+                  break;
+                case NR_CSI_RS_ResourceMapping__nrofPorts_p8:
+                  if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
+                    csirs_pdu_rel15->row = 8;
+                    for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                      vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
+                  }
+                  else{
+                    int num_k = 0;
+                    for (int k=0; k<6; k++)
+                      num_k+=(((csirs_pdu_rel15->freq_domain)>>k)&0x01);
+                    if(num_k==4) {
+                      csirs_pdu_rel15->row = 6;
+                      for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                        vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
+                    }
+                    else {
+                      csirs_pdu_rel15->row = 7;
+                      for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                        vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
+                    }
+                  }
+                  break;
+                case NR_CSI_RS_ResourceMapping__nrofPorts_p12:
+                  if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
+                    csirs_pdu_rel15->row = 10;
+                    for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                      vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
+                  }
+                  else {
+                    csirs_pdu_rel15->row = 9;
+                    for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                      vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
+                  }
+                  break;
+                case NR_CSI_RS_ResourceMapping__nrofPorts_p16:
+                  if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2)
+                    csirs_pdu_rel15->row = 12;
+                  else
+                    csirs_pdu_rel15->row = 11;
+                  for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                    vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
+                  break;
+                case NR_CSI_RS_ResourceMapping__nrofPorts_p24:
+                  if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
+                    csirs_pdu_rel15->row = 14;
+                    for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                      vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
+                  }
+                  else{
+                    if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
+                      csirs_pdu_rel15->row = 15;
+                      for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                        vrb_map[rb] |= (7 << csirs_pdu_rel15->symb_l0);
+                    }
+                    else {
+                      csirs_pdu_rel15->row = 13;
+                      for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                        vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
+                    }
+                  }
+                  break;
+                case NR_CSI_RS_ResourceMapping__nrofPorts_p32:
+                  if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
+                    csirs_pdu_rel15->row = 17;
+                    for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                      vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
+                  }
+                  else{
+                    if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
+                      csirs_pdu_rel15->row = 18;
+                      for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                        vrb_map[rb] |= (7 << csirs_pdu_rel15->symb_l0);
+                    }
+                    else {
+                      csirs_pdu_rel15->row = 16;
+                      for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
+                        vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
+                    }
+                  }
+                  break;
+              default:
+                AssertFatal(1==0,"Invalid number of ports in CSI-RS resource\n");
+              }
+              break;
+          default:
+            AssertFatal(1==0,"Invalid freqency domain allocation in CSI-RS resource\n");
+          }
+          dl_req->nPDUs++;
+        }
+      }
+    }
+  }
+}
+
 bool find_free_CCE(module_id_t module_id,
                    sub_frame_t slot,
                    int UE_id){
@@ -1827,6 +2270,7 @@ bool find_free_CCE(module_id_t module_id,
   return true;
 }
 
+
 /*void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg,
 					  nfapi_nr_coreset_t *coreset,
 					  nfapi_nr_search_space_t *search_space) {
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
index 629b4dc7b065972f9923fb2d5d66b98b3b82efac..a284ad96e81925b0982d55ec61ae2187449b61e7 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"
@@ -35,6 +36,7 @@
 
 extern RAN_CONTEXT_t RC;
 
+
 void nr_fill_nfapi_pucch(module_id_t mod_id,
                          frame_t frame,
                          sub_frame_t slot,
@@ -72,22 +74,66 @@ 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
+#define MAX_NUM_SSB 128
+#define MAX_SSB_SCHED 8
+#define L1_RSRP_HYSTERIS 10 //considering 10 dBm as hysterisis for avoiding frequent SSB Beam Switching. !Fixme provide exact value if any
+//#define L1_DIFF_RSRP_STEP_SIZE 2
+
+int ssb_index_sorted[MAX_NUM_SSB] = {0};
+int ssb_rsrp_sorted[MAX_NUM_SSB] = {0};
+
+//Measured RSRP Values Table 10.1.16.1-1 from 36.133
+//Stored all the upper limits[Max RSRP Value of corresponding index]
+//stored -1 for invalid values
+int L1_SSB_CSI_RSRP_measReport_mapping_38133_10_1_6_1_1[128] = {
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0 - 9
+     -1, -1, -1, -1, -1, -1, INT_MIN, -140, -139, -138, //10 - 19
+    -137, -136, -135, -134, -133, -132, -131, -130, -129, -128, //20 - 29
+    -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, //30 - 39
+    -117,-116, -115, -114, -113, -112, -111, -110, -109, -108, //40 - 49
+    -107, -106, -105, -104, -103, -102, -101, -100, -99, -98, //50 - 59
+    -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, //60 - 69
+    -87, -86, -85, -84, -83, -82, -81, -80, -79, -78, //70 - 79
+    -77, -76, -75, -74, -73, -72, -71, -70, -69, -68, //80 - 89
+    -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, //90 - 99
+    -57, -56, -55, -54, -53, -52, -51, -50, -49, -48, //100 - 109
+    -47, -46, -45, -44, INT_MAX, -1, -1, -1, -1, -1, //110 - 119
+    -1, -1, -1, -1, -1, -1, -1, -1//120 - 127
+  };
+
+//Differential RSRP values Table 10.1.6.1-2 from 36.133
+//Stored the upper limits[MAX RSRP Value]
+int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = {
+  0, -2, -4, -6, -8, -10, -12, -14, -16, -18, //0 - 9
+  -20, -22, -24, -26, -28, -30 //10 - 15
+};
+
+
 void nr_schedule_pucch(int Mod_idP,
                        frame_t frameP,
-                       sub_frame_t slotP) {
-  NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
+                       sub_frame_t slotP)
+{
+  gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
+  if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slotP / 64], slotP))
+    return;
+
+  NR_UE_info_t *UE_info = &nrmac->UE_info;
   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;
     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];
@@ -98,7 +144,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));
     }
@@ -106,121 +152,342 @@ void nr_schedule_pucch(int Mod_idP,
 }
 
 
-//!TODO : same function can be written to handle csi_resources
-void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t *UE_info, int UE_id) {
-  uint8_t csi_report_id = 0;
-  uint8_t csi_resourceidx =0;
-  uint8_t csi_ssb_idx =0;
+//! Calculating number of bits set
+uint8_t number_of_bits_set (uint8_t buf,uint8_t * max_ri){
+  uint8_t nb_of_bits_set = 0;
+  uint8_t mask = 0xff;
+  uint8_t index = 0;
 
-  NR_CSI_MeasConfig_t *csi_MeasConfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
-  NR_CSI_ResourceConfigId_t csi_ResourceConfigId;
-  for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
-    csi_ResourceConfigId=csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->resourcesForChannelMeasurement;
-    UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->reportQuantity.present;
+  for (index=7; (buf & mask) && (index>=0)  ; index--){
+    if (buf & (1<<index))
+      nb_of_bits_set++;
+
+    mask>>=1;
+  }
+  *max_ri = 8-index;
+  return nb_of_bits_set;
+}
+
+
+void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
+                         uint8_t nb_resources,
+                         nr_csi_report_t *csi_report){
+
+  if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) {
+    if (NULL != csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)
+      csi_report->CSI_report_bitlen.nb_ssbri_cri = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1;
+    else
+      /*! From Spec 38.331
+       * nrofReportedRS
+       * The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE
+       * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report.
+       * When the field is absent the UE applies the value 1
+       */
+      csi_report->CSI_report_bitlen.nb_ssbri_cri= 1;
+  } else
+    csi_report->CSI_report_bitlen.nb_ssbri_cri= 2;
+
+  if (nb_resources) {
+    csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_resources));
+    csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
+    csi_report->CSI_report_bitlen.diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
+  } else {
+    csi_report->CSI_report_bitlen.cri_ssbri_bitlen =0;
+    csi_report->CSI_report_bitlen.rsrp_bitlen = 0;
+    csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0;
+  }
+}
+
+
+uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
+                          nr_csi_report_t *csi_report){
+
+  struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
+  uint8_t nb_allowed_ri, ri_restriction,ri_bitlen;
+  uint8_t  max_ri = 0;
+
+  if (codebookConfig == NULL) {
+    csi_report->csi_meas_bitlen.ri_bitlen=0;
+    return max_ri;
+  }
 
-    for ( csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) {
-      if ( csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_ResourceConfigId != csi_ResourceConfigId)
-	continue;
+  // codebook type1 single panel
+  if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present){
+    struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel;
+    if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two){
+      // two antenna ports case
+      /*  From Spec 38.212
+       *  If the higher layer parameter nrofCQIsPerReport=1, nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator
+       *  values in the 4 LSBs of the higher layer parameter typeI-SinglePanel-ri-Restriction according to Subclause 5.2.2.2.1 [6,
+       *  TS 38.214]; otherwise nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator values according to Subclause
+       *  5.2.2.2.1 [6, TS 38.214].
+       *
+       *  But from Current RRC ASN structures nrofCQIsPerReport is not present. Present a dummy variable is present so using it to
+       *  calculate RI for antennas equal or more than two.
+       * */
+      AssertFatal (NULL!=csi_reportconfig->dummy, "nrofCQIsPerReport is not present");
+
+      ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
+
+      /* Replace dummy with the nrofCQIsPerReport from the CSIreport
+         config when equalent ASN structure present */
+      if (0==*(csi_reportconfig->dummy)){
+        nb_allowed_ri = number_of_bits_set((ri_restriction & 0xf0), &max_ri);
+        ri_bitlen = ceil(log2(nb_allowed_ri));
+      }
+      else{
+        nb_allowed_ri = number_of_bits_set(ri_restriction, &max_ri);
+        ri_bitlen = ceil(log2(nb_allowed_ri));
+      }
+      ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table  6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
+      csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
+    }
+    if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo){
+      if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present ==
+          NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) {
+        // 4 ports
+        AssertFatal (NULL!=csi_reportconfig->dummy, "nrofCQIsPerReport is not present");
+
+        ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
+
+        /* Replace dummy with the nrofCQIsPerReport from the CSIreport
+           config when equalent ASN structure present*/
+        if (0==*(csi_reportconfig->dummy)){
+          nb_allowed_ri = number_of_bits_set((ri_restriction & 0xf0), &max_ri);
+          ri_bitlen = ceil(log2(nb_allowed_ri));
+        }
+        else{
+          nb_allowed_ri = number_of_bits_set(ri_restriction,&max_ri);
+          ri_bitlen = ceil(log2(nb_allowed_ri));
+        }
+        ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table  6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
+        csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
+      }
       else {
-      //Finding the CSI_RS or SSB Resources
-        UE_info->csi_report_template[UE_id][csi_report_id].CSI_Resource_type= csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_RS_ResourceSetList.present;
-        if (NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB ==UE_info->csi_report_template[UE_id][csi_report_id].CSI_Resource_type){
-          struct NR_CSI_ResourceConfig__csi_RS_ResourceSetList__nzp_CSI_RS_SSB * nzp_CSI_RS_SSB = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB;
+        // more than 4 ports
+        AssertFatal (NULL!=csi_reportconfig->dummy, "nrofCQIsPerReport is not present");
+
+        ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
 
-          UE_info->csi_report_template[UE_id][csi_report_id].nb_of_nzp_csi_report = nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList!=NULL ? nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.count:0;
-          UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report = nzp_CSI_RS_SSB->csi_SSB_ResourceSetList!=NULL ? nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.count:0;
+        /* Replace dummy with the nrofCQIsPerReport from the CSIreport
+           config when equalent ASN structure present */
+        if (0==*(csi_reportconfig->dummy)){
+          nb_allowed_ri = number_of_bits_set((ri_restriction & 0xf0),&max_ri);
+          ri_bitlen = ceil(log2(nb_allowed_ri));
         }
+        else{
+          nb_allowed_ri = number_of_bits_set(ri_restriction, &max_ri);
+          ri_bitlen = ceil(log2(nb_allowed_ri));
+        }
+        csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
+      }
+    }
+    return max_ri;
+  }
+  else
+    AssertFatal(1==0,"Other configurations not yet implemented\n");
+}
+
+void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
+                       uint8_t max_ri,
+                       nr_csi_report_t *csi_report){
+
+  struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
+  if (codebookConfig == NULL) {
+    csi_report->csi_meas_bitlen.li_bitlen=0;
+    return;
+  }
+  // codebook type1 single panel
+  if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present){
+    /* From Spec 38.212
+     *  If the higher layer parameter nrofCQIsPerReport=1, nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator
+     *  values in the 4 LSBs of the higher layer parameter typeI-SinglePanel-ri-Restriction according to Subclause 5.2.2.2.1 [6,
+     *  TS 38.214]; otherwise nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator values according to Subclause
+     *  5.2.2.2.1 [6, TS 38.214].
+     *
+     *  But from Current RRC ASN structures nrofCQIsPerReport is not present. Present a dummy variable is present so using it to
+     *  calculate RI for antennas equal or more than two.
+     */
+     //! TODO: The bit length of LI is as follows LI = log2(RI), Need to confirm wheather we should consider maximum RI can be reported from ri_restricted
+     //        or we should consider reported RI. If we need to consider reported RI for calculating LI bit length then we need to modify the code.
+     csi_report->csi_meas_bitlen.li_bitlen=ceil(log2(max_ri))<2?ceil(log2(max_ri)):2;
+  }
+  else
+    AssertFatal(1==0,"Other configurations not yet implemented\n");
+}
 
-        if (0 != UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report){
-	  uint8_t nb_ssb_resources =0;
-          for ( csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) {
-            if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId ==
-                *(csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])) { 
-              ///We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
-              if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled ==
-                csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->groupBasedBeamReporting.present ) {
-	        if (NULL != csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->groupBasedBeamReporting.choice.disabled->nrofReportedRS)
-                  UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].nb_ssbri_cri = *(csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1;
-                else
-                  /*! From Spec 38.331
-                  * nrofReportedRS
-                  * The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE
-                  * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report.
-                  * When the field is absent the UE applies the value 1
-                  */
-                  UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].nb_ssbri_cri= 1;
-              } else
-                UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].nb_ssbri_cri= 2;
-
-              nb_ssb_resources=  csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.count;
-              if (nb_ssb_resources){
-                UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen =ceil(log2 (nb_ssb_resources));
-                UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP 
-                UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
-              }
-              else{
-                UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen =0;
-                UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen = 0;
-                UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen =0;
-              }
-
-              LOG_I (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d\n",
-                     UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen,
-                     UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen,
-                     UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen);
-              break ;
-            }
+
+void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
+                        uint8_t max_ri,
+                        nr_csi_report_t *csi_report){
+
+  struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig;
+  struct NR_CSI_ReportConfig__reportFreqConfiguration *freq_config = csi_reportconfig->reportFreqConfiguration;
+
+  if (*freq_config->cqi_FormatIndicator == NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI) {
+    csi_report->csi_meas_bitlen.cqi_bitlen = 4;
+    if(codebookConfig != NULL) {
+      if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel == codebookConfig->codebookType.choice.type1->subType.present){
+        struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel;
+        if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo) {
+          if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present >
+              NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) {
+            // more than 4 antenna ports
+            if (max_ri > 4)
+              csi_report->csi_meas_bitlen.cqi_bitlen += 4; // CQI for second TB
           }
         }
-        if (0 != UE_info->csi_report_template[UE_id][csi_report_id].nb_of_nzp_csi_report)
-          AssertFatal(1==0,"Currently configuring only SSB beamreporting.");
-        break;
       }
     }
   }
+  else
+    AssertFatal(1==0,"Sub-band CQI reporting not yet supported");
 }
 
+//!TODO : same function can be written to handle csi_resources
+void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_info, int UE_id, module_id_t Mod_idP){
+  uint8_t csi_report_id = 0;
+  uint8_t nb_resources = 0;
+  uint8_t max_ri = 0;
+  NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
+  NR_CSI_ResourceConfigId_t csi_ResourceConfigId;
+  struct NR_CSI_ResourceConfig *csi_resourceconfig;
 
-uint16_t nr_get_csi_bitlen(const nr_csi_report_t *csi_report)
-{
-  const CRI_SSBRI_RSRP_bitlen_t *bitlen = &csi_report->CSI_report_bitlen[0];
-  return bitlen->cri_ssbri_bitlen * bitlen->nb_ssbri_cri
-         + bitlen->rsrp_bitlen
-         + bitlen->diff_rsrp_bitlen * (bitlen->nb_ssbri_cri - 1) * csi_report->nb_of_csi_ssb_report;
+  // for each CSI measurement report configuration (list of CSI-ReportConfig)
+  for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
+    struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
+    // MAC structure for CSI measurement reports (per UE and per report)
+    nr_csi_report_t *csi_report = &UE_info->csi_report_template[UE_id][csi_report_id];
+    // csi-ResourceConfigId of a CSI-ResourceConfig included in the configuration
+    // (either CSI-RS or SSB)
+    csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
+    // looking for CSI-ResourceConfig
+    int found_resource = 0;
+    int csi_resourceidx = 0;
+    while (found_resource == 0 && csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count) {
+      csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
+      if ( csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId)
+        found_resource = 1;
+      csi_resourceidx++;
+    }
+    AssertFatal(found_resource==1,"Not able to found any CSI-ResourceConfig with csi-ResourceConfigId %ld\n",
+                csi_ResourceConfigId);
+
+    long resourceType = csi_resourceconfig->resourceType;
+
+    reportQuantity_type = csi_reportconfig->reportQuantity.present;
+    csi_report->reportQuantity_type = reportQuantity_type;
+
+    // setting the CSI or SSB index list
+    if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) {
+      AssertFatal(csi_MeasConfig->csi_SSB_ResourceSetToAddModList != NULL,
+                  "Wrong settings! Report quantity is SSB-RSRP but csi_MeasConfig->csi_SSB_ResourceSetToAddModList is NULL\n");
+      for (int csi_idx = 0; csi_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_idx++) {
+        if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceSetId ==
+            *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){
+          //We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
+          nb_resources = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count;
+          csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.array;
+          csi_report->CSI_Index_list = NULL;
+          break;
+        }
+      }
+    }
+    else {
+      if (resourceType == NR_CSI_ResourceConfig__resourceType_periodic) {
+        AssertFatal(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList != NULL,
+                    "Wrong settings! Report quantity requires CSI-RS but csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList is NULL\n");
+        for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) {
+          if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId ==
+              *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) {
+            //For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 for spec 38.212
+            nb_resources = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.count;
+            csi_report->CSI_Index_list = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.array;
+            csi_report->SSB_Index_list = NULL;
+            break;
+          }
+        }
+      }
+      else AssertFatal(1==0,"Only periodic resource configuration currently supported\n");
+    }
+
+    // computation of bit length depending on the report type
+    switch(reportQuantity_type){
+      case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP):
+        compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
+        break;
+      case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP):
+        compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report);
+        break;
+      case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI):
+        csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources));
+        max_ri = compute_ri_bitlen(csi_reportconfig, csi_report);
+        compute_cqi_bitlen(csi_reportconfig, max_ri, csi_report);
+        break;
+    default:
+      AssertFatal(1==0,"Not yet supported CSI report quantity type");
+    }
+  }
+}
+
+
+uint16_t nr_get_csi_bitlen(int Mod_idP,
+                           int UE_id,
+                           uint8_t csi_report_id) {
+
+  uint16_t csi_bitlen =0;
+  NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
+  L1_RSRP_bitlen_t * CSI_report_bitlen = NULL;
+  CSI_Meas_bitlen_t * csi_meas_bitlen = NULL;
+
+  if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP==UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type||
+      NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP==UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type){
+    CSI_report_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
+    csi_bitlen+= ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) +
+                  CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
+                  (CSI_report_bitlen->nb_ssbri_cri -1 )));
+  } else{
+   csi_meas_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
+   csi_bitlen+= (csi_meas_bitlen->cri_bitlen +csi_meas_bitlen->ri_bitlen+csi_meas_bitlen->li_bitlen+csi_meas_bitlen->cqi_bitlen+csi_meas_bitlen->pmi_x1_bitlen+csi_meas_bitlen->pmi_x2_bitlen);
+ }
+
+  return csi_bitlen;
 }
 
 
 void nr_csi_meas_reporting(int Mod_idP,
                            frame_t frame,
-                           sub_frame_t slot)
-{
-  NR_ServingCellConfigCommon_t *scc =
-      RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
+                           sub_frame_t slot) {
+
+  NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
   const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
 
   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 (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
+    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;
 
     for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
-      const NR_CSI_ReportConfig_t *csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
+      NR_CSI_ReportConfig_t *csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
 
       AssertFatal(csirep->reportConfigType.choice.periodic,
                   "Only periodic CSI reporting is implemented currently\n");
       int period, offset;
-      csi_period_offset(csirep, &period, &offset);
+      csi_period_offset(csirep, NULL, &period, &offset);
       const int sched_slot = (period + offset) % n_slots_frame;
       // prepare to schedule csi measurement reception according to 5.2.1.4 in 38.214
       // preparation is done in first slot of tdd period
       if (frame % (period / n_slots_frame) != offset / n_slots_frame)
         continue;
-      LOG_D(MAC, "CSI in frame %d slot %d\n", frame, sched_slot);
+      LOG_I(MAC, "CSI reporting in frame %d slot %d\n", frame, sched_slot);
 
       const NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0];
       const NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[1]; // set with formats >1
@@ -234,17 +501,17 @@ void nr_csi_meas_reporting(int Mod_idP,
 
       // find free PUCCH that is in order with possibly existing PUCCH
       // schedulings (other CSI, SR)
-      NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[2];
+      NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[1];
       AssertFatal(curr_pucch->csi_bits == 0
                   && !curr_pucch->sr_flag
                   && curr_pucch->dai_c == 0,
-                  "PUCCH not free at index 2 for UE %04x\n",
+                  "PUCCH not free at index 1 for UE %04x\n",
                   UE_info->rnti[UE_id]);
       curr_pucch->frame = frame;
       curr_pucch->ul_slot = sched_slot;
       curr_pucch->resource_indicator = res_index;
       curr_pucch->csi_bits +=
-          nr_get_csi_bitlen(&UE_info->csi_report_template[UE_id][csi_report_id]);
+          nr_get_csi_bitlen(Mod_idP,UE_id,csi_report_id);
 
       // going through the list of PUCCH resources to find the one indexed by resource_id
       uint16_t *vrb_map_UL = &RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
@@ -278,9 +545,6 @@ void nr_csi_meas_reporting(int Mod_idP,
         for (int i = start; i < start + len; ++i) {
           vrb_map_UL[i] |= mask;
         }
-        AssertFatal(!curr_pucch->simultaneous_harqcsi,
-                    "UE %04x has simultaneous HARQ/CSI configured, but we don't support that\n",
-                    UE_info->rnti[UE_id]);
       }
     }
   }
@@ -299,7 +563,7 @@ static void handle_dl_harq(module_id_t mod_id,
     add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].available_dl_harq, harq_pid);
     harq->round = 0;
     harq->ndi ^= 1;
-  } else if (harq->round == MAX_HARQ_ROUNDS) {
+  } else if (harq->round >= MAX_HARQ_ROUNDS - 1) {
     add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].available_dl_harq, harq_pid);
     harq->round = 0;
     harq->ndi ^= 1;
@@ -312,6 +576,488 @@ 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 *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 *)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) {
+        if(tci->qcl_Type1.referenceSignal.choice.ssb == ssb_index_t)
+          return tci->tci_StateId;  // returned TCI state ID
+      }
+      // if type2 is configured
+      else if(tci->qcl_Type2 != NULL && tci->qcl_Type2->referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) {
+        if(tci->qcl_Type2->referenceSignal.choice.ssb == ssb_index_t)
+          return tci->tci_StateId; // returned TCI state ID
+      } else LOG_I(MAC,"SSB index is not found in first 64 TCI states of TCI_statestoAddModList[%d]", i);
+    }
+  }
+
+  // tci state not identified in first 64 TCI States of PDSCH Config
+  return -1;
+}
+
+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 *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 = 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 *)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) {
+        flag = 1;
+        tci_stateID = tci->tci_StateId;
+        break;
+      } else if(tci->qcl_Type2 != NULL && tci->qcl_Type2->referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) {
+        flag = 1;
+        tci_stateID = tci->tci_StateId;
+        break;
+      }
+    }
+
+    if(flag != 0 && tci_stateID != -1 && coreset != NULL) {
+      for(i=0; i<64 && i<coreset->tci_StatesPDCCH_ToAddList->list.count; i++) {
+        tci_id = coreset->tci_StatesPDCCH_ToAddList->list.array[i];
+
+        if(tci_id != NULL && *tci_id == tci_stateID)
+          return tci_stateID;
+      }
+    }
+  }
+
+  // Need to implement once configuration is received
+  return -1;
+}
+
+//returns the measured RSRP value (upper limit)
+int get_measured_rsrp(uint8_t index) {
+  //if index is invalid returning minimum rsrp -140
+  if(index <= 15 || index >= 114)
+    return MIN_RSRP_VALUE;
+
+  return L1_SSB_CSI_RSRP_measReport_mapping_38133_10_1_6_1_1[index];
+}
+
+//returns the differential RSRP value (upper limit)
+int get_diff_rsrp(uint8_t index, int strongest_rsrp) {
+  if(strongest_rsrp != -1) {
+    return strongest_rsrp + diff_rsrp_ssb_csi_meas_10_1_6_1_2[index];
+  } else
+    return MIN_RSRP_VALUE;
+}
+
+//identifies the target SSB Beam index
+//keeps the required date for PDCCH and PDSCH TCI state activation/deactivation CE consutruction globally
+//handles triggering of PDCCH and PDSCH MAC CEs
+void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
+
+  int strongest_ssb_rsrp = 0;
+  int cqi_idx = 0;
+  int curr_ssb_beam_index = 0; //ToDo: yet to know how to identify the serving ssb beam index
+  uint8_t target_ssb_beam_index = curr_ssb_beam_index;
+  uint8_t is_triggering_ssb_beam_switch =0;
+  uint8_t ssb_idx = 0;
+  int pdsch_bwp_id =0;
+  int ssb_index[MAX_NUM_SSB] = {0};
+  int ssb_rsrp[MAX_NUM_SSB] = {0};
+  uint8_t idx = 0;
+  int bwp_id  = 1;
+  NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
+  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 = 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
+  uint8_t diff_rsrp_idx = 0;
+  uint8_t i, j;
+  NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+  NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
+
+  if (n_dl_bwp < 4)
+    pdsch_bwp_id = bwp_id;
+  else
+    pdsch_bwp_id = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212
+
+  /*Example:
+  CRI_SSBRI: 1 2 3 4| 5 6 7 8| 9 10 1 2|
+  nb_of_csi_ssb_report = 3 //3 sets as above
+  nr_ssbri_cri = 4 //each set has 4 elements
+  storing ssb indexes in ssb_index array as ssb_index[0] = 1 .. ssb_index[4] = 5
+  ssb_rsrp[0] = strongest rsrp in first set, ssb_rsrp[4] = strongest rsrp in second set, ..
+  idx: resource set index
+  */
+
+  //for all reported SSB
+  for (idx = 0; idx < nb_of_csi_ssb_report; idx++) {
+    nr_ssbri_cri = sched_ctrl->CSI_report[idx].choice.ssb_cri_report.nr_ssbri_cri;
+      //extracting the ssb indexes
+      for (ssb_idx = 0; ssb_idx < nr_ssbri_cri; ssb_idx++) {
+        ssb_index[idx * nb_of_csi_ssb_report + ssb_idx] = sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI[ssb_idx];
+      }
+
+      //if strongest measured RSRP is configured
+      strongest_ssb_rsrp = get_measured_rsrp(sched_ctrl->CSI_report[idx].choice.ssb_cri_report.RSRP);
+      // including ssb rsrp in mac stats
+      stats->cumul_rsrp += strongest_ssb_rsrp;
+      stats->num_rsrp_meas++;
+      ssb_rsrp[idx * nb_of_csi_ssb_report] = strongest_ssb_rsrp;
+      LOG_D(MAC,"ssb_rsrp = %d\n",strongest_ssb_rsrp);
+
+      //if current ssb rsrp is greater than better rsrp
+      if(ssb_rsrp[idx * nb_of_csi_ssb_report] > better_rsrp_reported) {
+        better_rsrp_reported = ssb_rsrp[idx * nb_of_csi_ssb_report];
+        target_ssb_beam_index = idx * nb_of_csi_ssb_report;
+      }
+
+      for(diff_rsrp_idx =1; diff_rsrp_idx < nr_ssbri_cri; diff_rsrp_idx++) {
+        ssb_rsrp[idx * nb_of_csi_ssb_report + diff_rsrp_idx] = get_diff_rsrp(sched_ctrl->CSI_report[idx].choice.ssb_cri_report.diff_RSRP[diff_rsrp_idx-1], strongest_ssb_rsrp);
+
+        //if current reported rsrp is greater than better rsrp
+        if(ssb_rsrp[idx * nb_of_csi_ssb_report + diff_rsrp_idx] > better_rsrp_reported) {
+          better_rsrp_reported = ssb_rsrp[idx * nb_of_csi_ssb_report + diff_rsrp_idx];
+          target_ssb_beam_index = idx * nb_of_csi_ssb_report + diff_rsrp_idx;
+        }
+      }
+  }
+
+
+  if(ssb_index[target_ssb_beam_index] != ssb_index[curr_ssb_beam_index] && ssb_rsrp[target_ssb_beam_index] > ssb_rsrp[curr_ssb_beam_index]) {
+    if( ssb_rsrp[target_ssb_beam_index] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) {
+      is_triggering_ssb_beam_switch = 1;
+      LOG_D(MAC, "Triggering ssb beam switching using tci\n");
+    }
+  }
+
+  if(is_triggering_ssb_beam_switch) {
+    //filling pdcch tci state activativation mac ce structure fields
+    sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.is_scheduled = 1;
+    //OAI currently focusing on Non CA usecase hence 0 is considered as serving
+    //cell id
+    sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.servingCellId = 0; //0 for PCell as 38.331 v15.9.0 page 353 //serving cell id for which this MAC CE applies
+    sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.coresetId = 0; //coreset id for which the TCI State id is being indicated
+
+    /* 38.321 v15.8.0 page 66
+    TCI State ID: This field indicates the TCI state identified by TCI-StateId as specified in TS 38.331 [5] applicable
+    to the Control Resource Set identified by CORESET ID field.
+    If the field of CORESET ID is set to 0,
+      this field indicates a TCI-StateId for a TCI state of the first 64 TCI-states configured by tci-States-ToAddModList and tciStates-ToReleaseList in the PDSCH-Config in the active BWP.
+    If the field of CORESET ID is set to the other value than 0,
+     this field indicates a TCI-StateId configured by tci-StatesPDCCH-ToAddList and tciStatesPDCCH-ToReleaseList in the controlResourceSet identified by the indicated CORESET ID.
+    The length of the field is 7 bits
+     */
+    if(sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.coresetId == 0) {
+      int tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index[target_ssb_beam_index], Mod_idP, UE_id);
+
+      if( tci_state_id != -1)
+        sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
+      else {
+        //identify the best beam within first 64 TCI States of PDSCH
+        //Config TCI-states-to-addModList
+        int flag = 0;
+
+        for(i =0; ssb_index_sorted[i]!=0; i++) {
+          tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index_sorted[i], Mod_idP, UE_id) ;
+
+          if(tci_state_id != -1 && ssb_rsrp_sorted[i] > ssb_rsrp[curr_ssb_beam_index] && ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) {
+            sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
+            flag = 1;
+            break;
+          }
+        }
+
+        if(flag == 0 || ssb_rsrp_sorted[i] < ssb_rsrp[curr_ssb_beam_index] || ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] < L1_RSRP_HYSTERIS) {
+          sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.is_scheduled = 0;
+        }
+      }
+    } else {
+      int tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index[target_ssb_beam_index], Mod_idP, UE_id);
+
+      if (tci_state_id !=-1)
+        sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
+      else {
+        //identify the best beam within CORESET/PDCCH
+        ////Config TCI-states-to-addModList
+        int flag = 0;
+
+        for(i =0; ssb_index_sorted[i]!=0; i++) {
+          tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index_sorted[i], Mod_idP, UE_id);
+
+          if( tci_state_id != -1 && ssb_rsrp_sorted[i] > ssb_rsrp[curr_ssb_beam_index] && ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) {
+            sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
+            flag = 1;
+            break;
+          }
+        }
+
+        if(flag == 0 || ssb_rsrp_sorted[i] < ssb_rsrp[curr_ssb_beam_index] || ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] < L1_RSRP_HYSTERIS) {
+          sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.is_scheduled = 0;
+        }
+      }
+    }
+
+    sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tci_present_inDCI = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[bwp_id-1]->tci_PresentInDCI;
+
+    //filling pdsch tci state activation deactivation mac ce structure fields
+    if(sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tci_present_inDCI) {
+      sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.is_scheduled = 1;
+      /*
+      Serving Cell ID: This field indicates the identity of the Serving Cell for which the MAC CE applies
+      Considering only PCell exists. Serving cell index of PCell is always 0, hence configuring 0
+      */
+      sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.servingCellId = 0;
+      /*
+      BWP ID: This field indicates a DL BWP for which the MAC CE applies as the codepoint of the DCI bandwidth
+      part indicator field as specified in TS 38.212
+      */
+      sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.bwpId = pdsch_bwp_id;
+
+      /*
+       * TODO ssb_rsrp_sort() API yet to code to find 8 best beams, rrc configuration
+       * is required
+       */
+      for(i = 0; i<8; i++) {
+        sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.tciStateActDeact[i] = i;
+      }
+
+      sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.highestTciStateActivated = 8;
+
+      for(i = 0, j =0; i<MAX_TCI_STATES; i++) {
+        if(sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.tciStateActDeact[i]) {
+          sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.codepoint[j] = i;
+          j++;
+        }
+      }
+    }//tci_presentInDCI
+  }//is-triggering_beam_switch
+}//tci handling
+
+
+uint8_t pickandreverse_bits(uint8_t *payload, uint16_t bitlen, uint8_t start_bit) {
+  uint8_t rev_bits = 0;
+  for (int i=0; i<bitlen; i++)
+    rev_bits |= ((payload[(start_bit+i)/8]>>((start_bit+i)%8))&0x01)<<(bitlen-i-1);
+  return rev_bits;
+}
+
+
+void evaluate_rsrp_report(NR_UE_info_t *UE_info,
+                             NR_UE_sched_ctrl_t *sched_ctrl,
+                             int UE_id,
+                             uint8_t csi_report_id,
+                             uint8_t *payload,
+                             int *cumul_bits,
+                             NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type){
+
+  uint8_t cri_ssbri_bitlen = UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen.cri_ssbri_bitlen;
+  uint16_t curr_payload;
+
+  /*! As per the spec 38.212 and table:  6.3.1.1.2-12 in a single UCI sequence we can have multiple CSI_report
+  * the number of CSI_report will depend on number of CSI resource sets that are configured in CSI-ResourceConfig RRC IE
+  * From spec 38.331 from the IE CSI-ResourceConfig for SSB RSRP reporting we can configure only one resource set
+  * From spec 38.214 section 5.2.1.2 For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1
+  */
+
+  /** from 38.214 sec 5.2.1.4.2
+  - if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'disabled', the UE is
+    not required to update measurements for more than 64 CSI-RS and/or SSB resources, and the UE shall report in
+    a single report nrofReportedRS (higher layer configured) different CRI or SSBRI for each report setting
+
+  - if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'enabled', the UE is not
+    required to update measurements for more than 64 CSI-RS and/or SSB resources, and the UE shall report in a
+    single reporting instance two different CRI or SSBRI for each report setting, where CSI-RS and/or SSB
+    resources can be received simultaneously by the UE either with a single spatial domain receive filter, or with
+    multiple simultaneous spatial domain receive filter
+  */
+
+  int idx = 0; //Since for SSB RSRP reporting in RRC can configure only one ssb resource set per one report config
+  sched_ctrl->CSI_report[idx].choice.ssb_cri_report.nr_ssbri_cri = UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen.nb_ssbri_cri;
+
+  for (int csi_ssb_idx = 0; csi_ssb_idx < sched_ctrl->CSI_report[idx].choice.ssb_cri_report.nr_ssbri_cri ; csi_ssb_idx++) {
+    curr_payload = pickandreverse_bits(payload, cri_ssbri_bitlen, *cumul_bits);
+
+    if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type)
+      sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] =
+        *(UE_info->csi_report_template[UE_id][csi_report_id].SSB_Index_list[cri_ssbri_bitlen>0?((curr_payload)&~(~1<<(cri_ssbri_bitlen-1))):cri_ssbri_bitlen]);
+    else
+      sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] =
+        *(UE_info->csi_report_template[UE_id][csi_report_id].CSI_Index_list[cri_ssbri_bitlen>0?((curr_payload)&~(~1<<(cri_ssbri_bitlen-1))):cri_ssbri_bitlen]);
+
+    *cumul_bits += cri_ssbri_bitlen;
+    LOG_D(MAC,"SSB_index = %d\n",sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx]);
+  }
+
+  curr_payload = pickandreverse_bits(payload, 7, *cumul_bits);
+  sched_ctrl->CSI_report[idx].choice.ssb_cri_report.RSRP = curr_payload & 0x7f;
+  *cumul_bits += 7;
+
+  for (int diff_rsrp_idx =0; diff_rsrp_idx < sched_ctrl->CSI_report[idx].choice.ssb_cri_report.nr_ssbri_cri - 1; diff_rsrp_idx++ ) {
+    curr_payload = pickandreverse_bits(payload, 4, *cumul_bits);
+    sched_ctrl->CSI_report[idx].choice.ssb_cri_report.diff_RSRP[diff_rsrp_idx] = curr_payload & 0x0f;
+    *cumul_bits += 4;
+  }
+  UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report++;
+  LOG_D(MAC,"rsrp_id = %d rsrp = %d\n",
+        sched_ctrl->CSI_report[idx].choice.ssb_cri_report.RSRP,
+        get_measured_rsrp(sched_ctrl->CSI_report[idx].choice.ssb_cri_report.RSRP));
+}
+
+
+void evaluate_cri_report(uint8_t *payload,
+                         uint8_t cri_bitlen,
+                         int cumul_bits,
+                         NR_UE_sched_ctrl_t *sched_ctrl){
+
+  int idx = 0; // FIXME not sure about this index. Should it be the same as csi_report_id?
+
+  uint8_t temp_cri = pickandreverse_bits(payload, cri_bitlen, cumul_bits);
+  sched_ctrl->CSI_report[idx].choice.cri_ri_li_pmi_cqi_report.cri = temp_cri;
+}
+
+void evaluate_ri_report(uint8_t *payload,
+                        uint8_t ri_bitlen,
+                        NR_UE_sched_ctrl_t *sched_ctrl){
+
+  AssertFatal(1==0,"Evaluation of RI report not yet implemented\n");
+}
+
+
+void evaluate_cqi_report(uint8_t *payload,
+                         uint8_t cqi_bitlen,
+                         int *cumul_bits,
+                         NR_UE_sched_ctrl_t *sched_ctrl){
+
+  //TODO sub-band CQI report not yet implemented
+  int idx = 0; // FIXME not sure about this index. Should it be the same as csi_report_id?
+  
+  uint8_t temp_cqi = pickandreverse_bits(payload, 4, *cumul_bits);
+  sched_ctrl->CSI_report[idx].choice.cri_ri_li_pmi_cqi_report.wb_cqi_1tb = temp_cqi;
+  *cumul_bits += 4;
+  LOG_I(MAC,"Wide-band CQI for the first TB %d\n", temp_cqi);
+  if (cqi_bitlen > 4) {
+    temp_cqi = pickandreverse_bits(payload, 4, *cumul_bits);
+    sched_ctrl->CSI_report[idx].choice.cri_ri_li_pmi_cqi_report.wb_cqi_2tb = temp_cqi;
+    LOG_D(MAC,"Wide-band CQI for the second TB %d\n", temp_cqi);
+  }
+}
+
+void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
+                              const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu,
+                              frame_t frame,
+                              slot_t slot,
+                              int UE_id,
+                              module_id_t Mod_idP) {
+
+  /** From Table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel */
+  NR_ServingCellConfigCommon_t *scc =
+      RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
+  const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
+  uint8_t *payload = uci_pdu->csi_part1.csi_part1_payload;
+  NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type = NR_CSI_ReportConfig__reportQuantity_PR_NOTHING;
+  NR_UE_info_t *UE_info = &(RC.nrmac[Mod_idP]->UE_info);
+  NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+  int cumul_bits = 0;
+  for (int csi_report_id = 0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++ ) {
+    UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report = 0;
+    uint8_t cri_bitlen = 0;
+    uint8_t ri_bitlen = 0;
+    uint8_t cqi_bitlen = 0;
+    NR_CSI_ReportConfig_t *csirep = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
+    int period, offset;
+    csi_period_offset(csirep, NULL, &period, &offset);
+    // verify if report with current id has been scheduled for this frame and slot
+    if ((n_slots_frame*frame + slot - offset)%period == 0) {
+      reportQuantity_type = UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type;
+      LOG_I(MAC,"SFN/SF:%d/%d reportQuantity type = %d\n",frame,slot,reportQuantity_type);
+      switch(reportQuantity_type){
+        case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
+          evaluate_rsrp_report(UE_info,sched_ctrl,UE_id,csi_report_id,payload,&cumul_bits,reportQuantity_type);
+          break;
+        case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
+          evaluate_rsrp_report(UE_info,sched_ctrl,UE_id,csi_report_id,payload,&cumul_bits,reportQuantity_type);
+          break;
+        case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
+          cri_bitlen = UE_info->csi_report_template[UE_id][csi_report_id].csi_meas_bitlen.cri_bitlen;
+          if(cri_bitlen)
+            evaluate_cri_report(payload,cri_bitlen,cumul_bits,sched_ctrl);
+          cumul_bits += cri_bitlen;
+          ri_bitlen = UE_info->csi_report_template[UE_id][csi_report_id].csi_meas_bitlen.ri_bitlen;
+          if(ri_bitlen)
+            evaluate_ri_report(payload,ri_bitlen,sched_ctrl);
+          cumul_bits += ri_bitlen;
+          //TODO add zero padding bits when needed
+          cqi_bitlen = UE_info->csi_report_template[UE_id][csi_report_id].csi_meas_bitlen.cqi_bitlen;
+          if(cqi_bitlen)
+            evaluate_cqi_report(payload,cqi_bitlen,&cumul_bits,sched_ctrl);
+          break;
+        default:
+          AssertFatal(1==0, "Invalid or not supported CSI measurement report\n");
+      }
+    }
+  }
+}
+
+static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t slot, int UE_id)
+{
+  /* In case of realtime problems: we can only identify a HARQ process by
+   * timing. If the HARQ process's feedback_frame/feedback_slot is not the one we
+   * expected, we assume that processing has been aborted and we need to
+   * skip this HARQ process, which is what happens in the loop below.
+   * Similarly, we might be "in advance", in which case we need to skip
+   * this result. */
+  NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id];
+  int8_t pid = sched_ctrl->feedback_dl_harq.head;
+  if (pid < 0)
+    return NULL;
+  NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid];
+  /* old feedbacks we missed: mark for retransmission */
+  while (harq->feedback_frame != frame
+         || (harq->feedback_frame == frame && harq->feedback_slot < slot)) {
+    LOG_W(MAC,
+          "expected HARQ pid %d feedback at %d.%d, but is at %d.%d instead (HARQ feedback is in the past)\n",
+          pid,
+          harq->feedback_frame,
+          harq->feedback_slot,
+          frame,
+          slot);
+    remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
+    handle_dl_harq(mod_id, UE_id, pid, 0);
+    pid = sched_ctrl->feedback_dl_harq.head;
+    if (pid < 0)
+      return NULL;
+    harq = &sched_ctrl->harq_processes[pid];
+  }
+  /* feedbacks that we wait for in the future: don't do anything */
+  if (harq->feedback_slot > slot) {
+    LOG_W(MAC,
+          "expected HARQ pid %d feedback at %d.%d, but is at %d.%d instead (HARQ feedback is in the future)\n",
+          pid,
+          harq->feedback_frame,
+          harq->feedback_slot,
+          frame,
+          slot);
+    return NULL;
+  }
+  return harq;
+}
+
 void handle_nr_uci_pucch_0_1(module_id_t mod_id,
                              frame_t frame,
                              sub_frame_t slot,
@@ -325,43 +1071,34 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
   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];
 
-  // tpc (power control)
-  sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
-                                uci_01->ul_cqi,
-                                30);
-
-  NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
-  const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
   if (((uci_01->pduBitmap >> 1) & 0x01)) {
     // iterate over received harq bits
     for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) {
       const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value;
       const uint8_t harq_confidence = uci_01->harq->harq_confidence_level;
-      const int feedback_slot = (slot - 1 + num_slots) % num_slots;
-      /* In case of realtime problems: we can only identify a HARQ process by
-       * timing. If the HARQ process's feedback_slot is not the one we
-       * expected, we assume that processing has been aborted and we need to
-       * skip this HARQ process, which is what happens in the loop below. If
-       * you don't experience real-time problems, you might simply revert the
-       * commit that introduced these changes. */
-      int8_t pid = sched_ctrl->feedback_dl_harq.head;
-      DevAssert(pid >= 0);
-      while (sched_ctrl->harq_processes[pid].feedback_slot != feedback_slot) {
-        LOG_W(MAC,
-              "expected feedback slot %d, but found %d instead\n",
-              sched_ctrl->harq_processes[pid].feedback_slot,
-              feedback_slot);
-        remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
-        handle_dl_harq(mod_id, UE_id, pid, 0);
-        pid = sched_ctrl->feedback_dl_harq.head;
-        DevAssert(pid >= 0);
-      }
-      remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
-      NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid];
+      NR_UE_harq_t *harq = find_harq(mod_id, frame, slot, UE_id);
+      if (!harq)
+        break;
       DevAssert(harq->is_waiting);
+      const int8_t pid = sched_ctrl->feedback_dl_harq.head;
+      remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
       handle_dl_harq(mod_id, UE_id, pid, harq_value == 1 && harq_confidence == 0);
     }
   }
+
+  // check scheduling request result, confidence_level == 0 is good
+  if (uci_01->pduBitmap & 0x1 && uci_01->sr->sr_indication && uci_01->sr->sr_confidence_level == 0 && uci_01->ul_cqi >= 148) {
+    // SR detected with SNR >= 10dB
+    sched_ctrl->SR |= true;
+    LOG_D(MAC, "SR UE %04x ul_cqi %d\n", uci_01->rnti, uci_01->ul_cqi);
+  }
+
+  // tpc (power control) only if we received AckNack or positive SR. For a
+  // negative SR, the UE won't have sent anything, and the SNR is not valid
+  if (((uci_01->pduBitmap >> 1) & 0x1) || sched_ctrl->SR) {
+    sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, uci_01->ul_cqi, 30);
+    sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640;
+  }
 }
 
 void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
@@ -374,6 +1111,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;
   }
+  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];
 
@@ -381,46 +1124,42 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
   sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
                                 uci_234->ul_cqi,
                                 30);
+  sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640;
 
-  NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
-  const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
   if ((uci_234->pduBitmap >> 1) & 0x01) {
     // iterate over received harq bits
     for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) {
       const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01;
-      const int feedback_slot = (slot - 1 + num_slots) % num_slots;
-      /* In case of realtime problems: we can only identify a HARQ process by
-       * timing. If the HARQ process's feedback_slot is not the one we
-       * expected, we assume that processing has been aborted and we need to
-       * skip this HARQ process, which is what happens in the loop below. If
-       * you don't experience real-time problems, you might simply revert the
-       * commit that introduced these changes. */
-      int8_t pid = sched_ctrl->feedback_dl_harq.head;
-      DevAssert(pid >= 0);
-      while (sched_ctrl->harq_processes[pid].feedback_slot != feedback_slot) {
-        LOG_W(MAC,
-              "expected feedback slot %d, but found %d instead\n",
-              sched_ctrl->harq_processes[pid].feedback_slot,
-              feedback_slot);
-        remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
-        handle_dl_harq(mod_id, UE_id, pid, 0);
-        pid = sched_ctrl->feedback_dl_harq.head;
-        DevAssert(pid >= 0);
-      }
-      remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
-      NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid];
+      NR_UE_harq_t *harq = find_harq(mod_id, frame, slot, UE_id);
+      if (!harq)
+        break;
       DevAssert(harq->is_waiting);
+      const int8_t pid = sched_ctrl->feedback_dl_harq.head;
+      remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
       handle_dl_harq(mod_id, UE_id, pid, uci_234->harq.harq_crc != 1 && acknack);
     }
   }
+  if ((uci_234->pduBitmap >> 2) & 0x01) {
+    //API to parse the csi report and store it into sched_ctrl
+    extract_pucch_csi_report (csi_MeasConfig, uci_234, frame, slot, UE_id, mod_id);
+    //TCI handling function
+    tci_handling(mod_id, UE_id,frame, slot);
+  }
+  if ((uci_234->pduBitmap >> 3) & 0x01) {
+    //@TODO:Handle CSI Report 2
+  }
 }
 
 
-// function to update pucch scheduling parameters in UE list when a USS DL is scheduled
-bool nr_acknack_scheduling(int mod_id,
-                           int UE_id,
-                           frame_t frame,
-                           sub_frame_t slot)
+// this function returns an index to NR_sched_pucch structure
+// currently this structure contains PUCCH0 at index 0 and PUCCH2 at index 1
+// if the function returns -1 it was not possible to schedule acknack
+// when current pucch is ready to be scheduled nr_fill_nfapi_pucch is called
+int nr_acknack_scheduling(int mod_id,
+                          int UE_id,
+                          frame_t frame,
+                          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];
@@ -430,6 +1169,7 @@ bool nr_acknack_scheduling(int mod_id,
   const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots;
   const int first_ul_slot_tdd = tdd->nrofDownlinkSlots + nr_slots_period * (slot / nr_slots_period);
   const int CC_id = 0;
+  NR_sched_pucch_t *csi_pucch;
 
   AssertFatal(slot < first_ul_slot_tdd + (tdd->nrofUplinkSymbols != 0),
               "cannot handle multiple TDD periods (yet): slot %d first_ul_slot_tdd %d nrofUplinkSlots %ld\n",
@@ -442,23 +1182,16 @@ bool nr_acknack_scheduling(int mod_id,
    * * we do not multiplex with CSI, which is always in pucch_sched[2]
    * * SR uses format 0 and is allocated in the first UL (mixed) slot (and not
    *   later)
-   * * that the PUCCH resource set 0 (for up to 2 bits) points to the first N
-   *   PUCCH resources, where N is the number of resources in the PUCCH
-   *   resource set. This is used in pucch_index_used, which counts the used
-   *   resources by index, and not by their 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__,
               pucch->csi_bits);
-
-  const int max_acknacks = 2;
-  AssertFatal(pucch->dai_c + pucch->sr_flag <= max_acknacks,
-              "illegal number of bits in PUCCH of UE %d\n",
-              UE_id);
   /* if the currently allocated PUCCH of this UE is full, allocate it */
-  if (pucch->sr_flag + pucch->dai_c == max_acknacks) {
+  if (pucch->dai_c == 2) {
     /* advance the UL slot information in PUCCH by one so we won't schedule in
      * the same slot again */
     const int f = pucch->frame;
@@ -468,39 +1201,37 @@ bool nr_acknack_scheduling(int mod_id,
     pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
     pucch->ul_slot = (s + 1) % n_slots_frame;
     // we assume that only two indices over the array sched_pucch exist
-    const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[2];
+    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) {
-      AssertFatal(!csi_pucch->simultaneous_harqcsi,
-                  "%s(): %d.%d cannot handle simultaneous_harqcsi, but found for UE %d\n",
-                  __func__,
-                  pucch->frame,
-                  pucch->ul_slot,
-                  UE_id);
+        && csi_pucch->ul_slot == pucch->ul_slot
+        && !csi_pucch->simultaneous_harqcsi) {
       nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id);
+      memset(csi_pucch, 0, sizeof(*csi_pucch));
       pucch->frame = s >= n_slots_frame - 2 ?  (f + 1) % 1024 : f;
       pucch->ul_slot = (s + 2) % n_slots_frame;
     }
   }
 
+  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 */
   if ((pucch->frame == frame
        && (pucch->ul_slot >= first_ul_slot_tdd + nr_ulmix_slots))
       || (pucch->frame == frame + 1))
-    return false;
+    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);
 
-  /* there is a scheduled SR or HARQ. Check whether we can use it for this
-   * ACKNACK */
-  if (pucch->sr_flag + pucch->dai_c > 0) {
+  /* there is a HARQ. Check whether we can use it for this ACKNACK */
+  if (pucch->dai_c > 0) {
     /* this UE already has a PUCCH occasion */
     DevAssert(pucch->frame == frame);
 
@@ -520,29 +1251,25 @@ bool 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;
     pucch->dai_c++;
     // retain old resource indicator, and we are good
-    return true;
+    return 0;
   }
 
   /* we need to find a new PUCCH occasion */
 
-  NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
-  DevAssert(pucch_Config->resourceToAddModList->list.count > 0);
-  DevAssert(pucch_Config->resourceSetToAddModList->list.count > 0);
-  const int n_res = pucch_Config->resourceSetToAddModList->list.array[0]->resourceList.list.count;
-  int *pucch_index_used = RC.nrmac[mod_id]->pucch_index_used[sched_ctrl->active_ubwp->bwp_Id];
-
   /* if time information is outdated (e.g., last PUCCH occasion in last frame),
    * set to first possible UL occasion in this frame. Note that if such UE is
    * scheduled a lot and used all AckNacks, pucch->frame might have been
    * wrapped around to next frame */
   if (frame != pucch->frame || pucch->ul_slot < first_ul_slot_tdd) {
-    DevAssert(pucch->sr_flag + pucch->dai_c == 0);
+    AssertFatal(pucch->sr_flag + pucch->dai_c == 0,
+                "expected no SR/AckNack for UE %d in %4d.%2d, but has %d/%d for %4d.%2d\n",
+                UE_id, frame, slot, pucch->sr_flag, pucch->dai_c, pucch->frame, pucch->ul_slot);
     AssertFatal(frame + 1 != pucch->frame,
                 "frame wrap around not handled in %s() yet\n",
                 __func__);
@@ -550,28 +1277,14 @@ bool nr_acknack_scheduling(int mod_id,
     pucch->ul_slot = first_ul_slot_tdd;
   }
 
-  // increase to first slot in which PUCCH resources are available
-  while (pucch_index_used[pucch->ul_slot] >= n_res) {
-    pucch->ul_slot++;
-    /* if there is no free resource anymore, abort search */
-    if ((pucch->frame == frame
-         && pucch->ul_slot >= first_ul_slot_tdd + nr_ulmix_slots)
-        || (pucch->frame == frame + 1)) {
-      LOG_E(MAC,
-            "%4d.%2d no free PUCCH resources anymore while searching for UE %d\n",
-            frame,
-            slot,
-            UE_id);
-      return false;
-    }
-  }
-
   // advance ul_slot if it is not reachable by UE
   pucch->ul_slot = max(pucch->ul_slot, slot + pdsch_to_harq_feedback[0]);
 
   // 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;
@@ -584,164 +1297,170 @@ bool nr_acknack_scheduling(int mod_id,
           slot,
           UE_id,
           pucch->ul_slot);
-    return false;
+    return -1;
+  }
+
+  // is there already CSI in this slot?
+  csi_pucch = &sched_ctrl->sched_pucch[1];
+  if (csi_pucch->csi_bits > 0
+      && csi_pucch->frame == pucch->frame
+      && csi_pucch->ul_slot == pucch->ul_slot) {
+    // skip the CSI PUCCH if it is present and if in the next frame/slot
+    // and if we don't multiplex
+    // FIXME currently we support at most 11 bits in pucch2 so skip also in that case
+    if(!csi_pucch->simultaneous_harqcsi
+       || ((csi_pucch->csi_bits + csi_pucch->dai_c) >= 11)) {
+      nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id);
+      memset(csi_pucch, 0, sizeof(*csi_pucch));
+      /* advance the UL slot information in PUCCH by one so we won't schedule in
+       * the same slot again */
+      const int f = pucch->frame;
+      const int s = pucch->ul_slot;
+      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, -1);
+    }
+    // multiplexing harq and csi in a pucch
+    else {
+      csi_pucch->timing_indicator = i;
+      csi_pucch->dai_c++;
+      return 1;
+    }
   }
+
   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++;
-  const int pucch_res = pucch_index_used[pucch->ul_slot];
-  pucch->resource_indicator = pucch_res;
-  pucch_index_used[pucch->ul_slot] += 1;
-  AssertFatal(pucch_index_used[pucch->ul_slot] <= n_res,
-              "UE %d in %4d.%2d: pucch_index_used is %d (%d available)\n",
-              UE_id,
-              pucch->frame,
-              pucch->ul_slot,
-              pucch_index_used[pucch->ul_slot],
-              n_res);
+  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_Resource_t *resource =
-      pucch_Config->resourceToAddModList->list.array[pucch_res];
+  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) {
     uint16_t *vrb_map_UL = &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch->ul_slot * MAX_BWP_SIZE];
     const uint16_t symb = 1 << resource->format.choice.format0->startingSymbolIndex;
-    AssertFatal((vrb_map_UL[resource->startingPRB] & symb) == 0,
-                "symbol %x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d\n",
-                symb, resource->startingPRB, pucch->ul_slot);
+    if ((vrb_map_UL[resource->startingPRB] & symb) != 0)
+      LOG_W(MAC, "symbol 0x%x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d.%d\n", symb, resource->startingPRB, pucch->frame, pucch->ul_slot);
     vrb_map_UL[resource->startingPRB] |= symb;
   }
-  return true;
+  return 0;
 }
 
 
-void csi_period_offset(const NR_CSI_ReportConfig_t *csirep,
-                       int *period, int *offset) {
-
-    NR_CSI_ReportPeriodicityAndOffset_PR p_and_o = csirep->reportConfigType.choice.periodic->reportSlotConfig.present;
+void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
+{
+  gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
+  if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot))
+    return;
+  NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
+  const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
+  NR_UE_info_t *UE_info = &nrmac->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]) {
+    NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
 
-    switch(p_and_o){
-      case NR_CSI_ReportPeriodicityAndOffset_PR_slots4:
-        *period = 4;
-        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots4;
-        break;
-      case NR_CSI_ReportPeriodicityAndOffset_PR_slots5:
-        *period = 5;
-        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots5;
-        break;
-      case NR_CSI_ReportPeriodicityAndOffset_PR_slots8:
-        *period = 8;
-        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots8;
-        break;
-      case NR_CSI_ReportPeriodicityAndOffset_PR_slots10:
-        *period = 10;
-        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots10;
-        break;
-      case NR_CSI_ReportPeriodicityAndOffset_PR_slots16:
-        *period = 16;
-        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots16;
-        break;
-      case NR_CSI_ReportPeriodicityAndOffset_PR_slots20:
-        *period = 20;
-        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots20;
-        break;
-      case NR_CSI_ReportPeriodicityAndOffset_PR_slots40:
-        *period = 40;
-        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots40;
-        break;
-      case NR_CSI_ReportPeriodicityAndOffset_PR_slots80:
-        *period = 80;
-        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots80;
-        break;
-      case NR_CSI_ReportPeriodicityAndOffset_PR_slots160:
-        *period = 160;
-        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots160;
-        break;
-      case NR_CSI_ReportPeriodicityAndOffset_PR_slots320:
-        *period = 320;
-        *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320;
-        break;
-    default:
-      AssertFatal(1==0,"No periodicity and offset resource found in CSI report");
+    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;
     }
-}
 
-uint16_t compute_pucch_prb_size(uint8_t format,
-                                uint8_t nr_prbs,
-                                uint16_t O_tot,
-                                uint16_t O_csi,
-                                NR_PUCCH_MaxCodeRate_t *maxCodeRate,
-                                uint8_t Qm,
-                                uint8_t n_symb,
-                                uint8_t n_re_ctrl) {
-
-  uint16_t O_crc;
-
-  if (O_tot<12)
-    O_crc = 0;
-  else{
-    if (O_tot<20)
-      O_crc = 6;
-    else {
-      if (O_tot<360)
-        O_crc = 11;
-      else
-        AssertFatal(1==0,"Case for segmented PUCCH not yet implemented");
-    }
-  }
+    AssertFatal(pucch_Config->schedulingRequestResourceToAddModList->list.count>0,"NO SR configuration available");
 
-  int rtimes100;
-  switch(*maxCodeRate){
-    case NR_PUCCH_MaxCodeRate_zeroDot08 :
-      rtimes100 = 8;
-      break;
-    case NR_PUCCH_MaxCodeRate_zeroDot15 :
-      rtimes100 = 15;
-      break;
-    case NR_PUCCH_MaxCodeRate_zeroDot25 :
-      rtimes100 = 25;
-      break;
-    case NR_PUCCH_MaxCodeRate_zeroDot35 :
-      rtimes100 = 35;
-      break;
-    case NR_PUCCH_MaxCodeRate_zeroDot45 :
-      rtimes100 = 45;
-      break;
-    case NR_PUCCH_MaxCodeRate_zeroDot60 :
-      rtimes100 = 60;
-      break;
-    case NR_PUCCH_MaxCodeRate_zeroDot80 :
-      rtimes100 = 80;
-      break;
-  default :
-    AssertFatal(1==0,"Invalid MaxCodeRate");
-  }
+    for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) {
+      NR_SchedulingRequestResourceConfig_t *SchedulingRequestResourceConfig = pucch_Config->schedulingRequestResourceToAddModList->list.array[SR_resource_id];
 
-  float r = (float)rtimes100/100;
+      int SR_period; int SR_offset;
 
-  if (O_csi == O_tot) {
-    if ((O_tot+O_csi)>(nr_prbs*n_re_ctrl*n_symb*Qm*r))
-      AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with %d PRBs",
-                  r,O_tot,O_crc,nr_prbs);
-    else
-      return nr_prbs;
-  }
+      find_period_offest_SR(SchedulingRequestResourceConfig,&SR_period,&SR_offset);
+      // convert to int to avoid underflow of uint
+      int sfn_sf = SFN * n_slots_frame + slot;
+      if ((sfn_sf - SR_offset) % SR_period != 0)
+        continue;
+      LOG_D(MAC, "%4d.%2d Scheduling Request identified\n", SFN, slot);
+      NR_PUCCH_ResourceId_t *PucchResourceId = SchedulingRequestResourceConfig->resource;
+
+      int found = -1;
+      NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[0]; // set with formats 0,1
+      int n_list = pucchresset->resourceList.list.count;
+       for (int i=0; i<n_list; i++) {
+        if (*pucchresset->resourceList.list.array[i] == *PucchResourceId )
+          found = i;
+      }
+      AssertFatal(found>-1,"SR resource not found among PUCCH resources");
+
+      /* loop through nFAPI PUCCH messages: if the UEs is in there in this slot
+       * with the resource_indicator, it means we already allocated that PUCCH
+       * resource for AckNack (e.g., the UE has been scheduled often), and we
+       * just need to add the SR_flag. Otherwise, just allocate in the internal
+       * PUCCH resource, and nr_schedule_pucch() will handle the rest */
+      NR_PUCCH_Resource_t *pucch_res = pucch_Config->resourceToAddModList->list.array[found];
+      /* for the moment, can only handle SR on PUCCH Format 0 */
+      DevAssert(pucch_res->format.present == NR_PUCCH_Resource__format_PR_format0);
+      nfapi_nr_ul_tti_request_t *ul_tti_req = &nrmac->UL_tti_req_ahead[0][slot];
+      bool nfapi_allocated = false;
+      for (int i = 0; i < ul_tti_req->n_pdus; ++i) {
+        if (ul_tti_req->pdus_list[i].pdu_type != NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE)
+          continue;
+        nfapi_nr_pucch_pdu_t *pdu = &ul_tti_req->pdus_list[i].pucch_pdu;
+        /* check that it is our PUCCH F0. Assuming there can be only one */
+        if (pdu->rnti == UE_info->rnti[UE_id]
+            && pdu->format_type == 0 // does not use NR_PUCCH_Resource__format_PR_format0
+            && pdu->initial_cyclic_shift == pucch_res->format.choice.format0->initialCyclicShift
+            && pdu->nr_of_symbols == pucch_res->format.choice.format0->nrofSymbols
+            && pdu->start_symbol_index == pucch_res->format.choice.format0->startingSymbolIndex) {
+          LOG_D(MAC,"%4d.%2d adding SR_flag 1 to PUCCH nFAPI SR for RNTI %04x\n", SFN, slot, pdu->rnti);
+          pdu->sr_flag = 1;
+          nfapi_allocated = true;
+          break;
+        }
+      }
 
-  if (format==2){
-    // TODO fix this for multiple CSI reports
-    for (int i=1; i<=nr_prbs; i++){
-      if((O_tot+O_crc)<=(i*n_symb*Qm*n_re_ctrl*r) &&
-         (O_tot+O_crc)>((i-1)*n_symb*Qm*n_re_ctrl*r))
-        return i;
+      if (nfapi_allocated)  // break scheduling resource loop, continue next UE
+        break;
+
+      /* we did not find it: check if current PUCCH is for the current slot, in
+       * which case we add the SR to it; otherwise, allocate SR separately */
+      NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[0];
+      if (curr_pucch->frame == SFN && curr_pucch->ul_slot == slot) {
+        if (curr_pucch->resource_indicator != found) {
+          LOG_W(MAC, "%4d.%2d expected PUCCH in this slot to have resource indicator of SR (%d), skipping SR\n", SFN, slot, found);
+          continue;
+        }
+        curr_pucch->sr_flag = true;
+      } else {
+        NR_sched_pucch_t sched_sr;
+        memset(&sched_sr, 0, sizeof(sched_sr));
+        sched_sr.frame = SFN;
+        sched_sr.ul_slot = slot;
+        sched_sr.resource_indicator = found;
+        sched_sr.sr_flag = true;
+        nr_fill_nfapi_pucch(Mod_idP, SFN, slot, &sched_sr, UE_id);
+      }
     }
-    AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with at most %d PRBs",
-                r,O_tot,O_crc,nr_prbs);
-  }
-  else{
-    AssertFatal(1==0,"Not yet implemented");
   }
-
 }
+
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 08736719211a625246a5d9b760653455fe8cfadc..fbd8a4b5ca0f924041a912dc7fa38292999033c2 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] = {
@@ -61,13 +63,124 @@ const uint32_t NR_LONG_BSR_TABLE[256] ={
 35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295
 };
 
-void nr_process_mac_pdu(
-    module_id_t module_idP,
-    rnti_t rnti,
-    uint8_t CC_id,
-    frame_t frameP,
-    uint8_t *pduP,
-    uint16_t mac_pdu_len)
+void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ubwp)
+{
+  gNB_MAC_INST *nrmac = RC.nrmac[module_id];
+  const int bwp_id = ubwp->bwp_Id;
+  if (nrmac->preferred_ul_tda[bwp_id])
+    return;
+
+  /* there is a mixed slot only when in TDD */
+  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;
+  /* Uplink symbols are at the end of the slot */
+  const int symb_ulMixed = tdd ? ((1 << tdd->nrofUplinkSymbols) - 1) << (14 - tdd->nrofUplinkSymbols) : 0;
+
+  const struct NR_PUCCH_Config__resourceToAddModList *resList = ubwp->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList;
+  // for the moment, just block any symbol that might hold a PUCCH, regardless
+  // of the RB. This is a big simplification, as most RBs will NOT have a PUCCH
+  // in the respective symbols, but it simplifies scheduling
+  uint16_t symb_pucch = 0;
+  for (int i = 0; i < resList->list.count; ++i) {
+    const NR_PUCCH_Resource_t *resource = resList->list.array[i];
+    int nrofSymbols = 0;
+    int startingSymbolIndex = 0;
+    switch (resource->format.present) {
+      case NR_PUCCH_Resource__format_PR_format0:
+        nrofSymbols = resource->format.choice.format0->nrofSymbols;
+        startingSymbolIndex = resource->format.choice.format0->startingSymbolIndex;
+        break;
+      case NR_PUCCH_Resource__format_PR_format1:
+        nrofSymbols = resource->format.choice.format1->nrofSymbols;
+        startingSymbolIndex = resource->format.choice.format1->startingSymbolIndex;
+        break;
+      case NR_PUCCH_Resource__format_PR_format2:
+        nrofSymbols = resource->format.choice.format2->nrofSymbols;
+        startingSymbolIndex = resource->format.choice.format2->startingSymbolIndex;
+        break;
+      case NR_PUCCH_Resource__format_PR_format3:
+        nrofSymbols = resource->format.choice.format3->nrofSymbols;
+        startingSymbolIndex = resource->format.choice.format3->startingSymbolIndex;
+        break;
+      case NR_PUCCH_Resource__format_PR_format4:
+        nrofSymbols = resource->format.choice.format4->nrofSymbols;
+        startingSymbolIndex = resource->format.choice.format4->startingSymbolIndex;
+        break;
+      default:
+        AssertFatal(0, "found NR_PUCCH format index %d\n", resource->format.present);
+        break;
+    }
+    symb_pucch |= ((1 << nrofSymbols) - 1) << startingSymbolIndex;
+  }
+
+  /* check that TDA index 1 fits into UL slot and does not overlap with PUCCH */
+  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(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;
+  // check whether PUCCH and TDA overlap: then, we cannot use it. Note that
+  // here we assume that the PUCCH is scheduled in every slot, and on all RBs
+  // (which is mostly not true, this is a simplification)
+  AssertFatal((symb_pucch & symb_tda) == 0, "TDA index 0 for UL overlaps with PUCCH\n");
+
+  // 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(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(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
+  // whether TDA is entirely within mixed slot, UL. Note that here we assume
+  // that the PUCCH is scheduled in every slot, and on all RBs (which is
+  // mostly not true, this is a simplification)
+  if ((symb_pucch & symb_tda_mi) == 0 && (symb_ulMixed & symb_tda_mi) == symb_tda_mi) {
+    tdaMi = 1;
+  } else {
+    LOG_E(NR_MAC,
+          "TDA index 1 UL overlaps with PUCCH or is not entirely in mixed slot (symb_pucch %x symb_ulMixed %x symb_tda_mi %x), won't schedule UL mixed slot\n",
+          symb_pucch,
+          symb_ulMixed,
+          symb_tda_mi);
+  }
+
+  const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
+  const int n = slots_per_frame[*scc->ssbSubcarrierSpacing];
+  nrmac->preferred_ul_tda[bwp_id] = malloc(n * sizeof(*nrmac->preferred_ul_tda[bwp_id]));
+
+  const int nr_mix_slots = tdd ? tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0 : 0;
+  const int nr_slots_period = tdd ? tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots : n;
+  for (int slot = 0; slot < n; ++slot) {
+    const int sched_slot = (slot + k2) % n;
+    nrmac->preferred_ul_tda[bwp_id][slot] = -1;
+    if (!tdd || sched_slot % nr_slots_period >= tdd->nrofDownlinkSlots + nr_mix_slots)
+      nrmac->preferred_ul_tda[bwp_id][slot] = 0;
+    else if (tdd && nr_mix_slots && sched_slot % nr_slots_period == tdd->nrofDownlinkSlots)
+      nrmac->preferred_ul_tda[bwp_id][slot] = tdaMi;
+    LOG_I(MAC, "DL slot %d UL slot %d preferred_ul_tda %d\n", slot, sched_slot, nrmac->preferred_ul_tda[bwp_id][slot]);
+  }
+
+  if (k2 < tdd->nrofUplinkSlots)
+    LOG_W(NR_MAC,
+          "k2 %d < tdd->nrofUplinkSlots %ld: not all UL slots can be scheduled\n",
+          k2,
+          tdd->nrofUplinkSlots);
+}
+
+void nr_process_mac_pdu(module_id_t module_idP,
+                        int UE_id,
+                        uint8_t CC_id,
+                        frame_t frameP,
+                        sub_frame_t slot,
+                        uint8_t *pduP,
+                        uint16_t mac_pdu_len)
 {
 
     // This function is adapting code from the old
@@ -77,14 +190,12 @@ void nr_process_mac_pdu(
     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;
-    int UE_id = find_nr_UE_id(module_idP, rnti);
-    if (UE_id == -1) {
-      LOG_E(MAC, "%s() UE_id == -1\n",__func__);
-      return;
-    }
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+
+    if ( pduP[0] != UL_SCH_LCID_PADDING )
+      trace_NRpdu(DIRECTION_UPLINK, pduP, mac_pdu_len ,UE_id, WS_C_RNTI, UE_info->rnti[UE_id], frameP, 0, 0, 0);
+
     //  For both DL/UL-SCH
     //  Except:
     //   - UL/DL-SCH: fixed-size MAC CE(known by LCID)
@@ -116,7 +227,7 @@ void nr_process_mac_pdu(
         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;
@@ -125,7 +236,7 @@ void nr_process_mac_pdu(
             //  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
@@ -137,20 +248,23 @@ void nr_process_mac_pdu(
 
         case UL_SCH_LCID_S_BSR:
         case UL_SCH_LCID_S_TRUNCATED_BSR:
-        	//38.321 section 6.1.3.1
-        	//fixed length
-        	mac_ce_len =1;
-        	/* Extract short BSR value */
+               //38.321 section 6.1.3.1
+               //fixed length
+               mac_ce_len =1;
+               /* Extract short BSR value */
                ce_ptr = &pdu_ptr[mac_subheader_len];
                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, "SHORT BSR, LCG ID %d, BS Index %d, BS value < %d, est buf %d\n",
+               LOG_D(NR_MAC,
+                     "SHORT BSR at %4d.%2d, LCG ID %d, BS Index %d, BS value < %d, est buf %d\n",
+                     frameP,
+                     slot,
                      bsr_s->LcgID,
                      bsr_s->Buffer_size,
                      NR_SHORT_BSR_TABLE[bsr_s->Buffer_size],
                      sched_ctrl->estimated_ul_buffer);
-        	break;
+               break;
 
         case UL_SCH_LCID_L_BSR:
         case UL_SCH_LCID_L_TRUNCATED_BSR:
@@ -170,19 +284,28 @@ void nr_process_mac_pdu(
                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(MAC, "LONG BSR, LCG ID(7-0) %d/%d/%d/%d/%d/%d/%d/%d\n",
+               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(MAC, "LONG BSR, %d/%d (n/n_Lcg), BS Index %d, BS value < %d",
+                 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(NR_MAC,
+                       "LONG BSR at %4d.%2d, %d/%d (n/n_Lcg), BS Index %d, BS value < %d, total %d\n",
+                       frameP,
+                       slot,
+                       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);
                }
 
-        	break;
+               break;
 
         case UL_SCH_LCID_C_RNTI:
         	//38.321 section 6.1.3.2
@@ -196,6 +319,20 @@ void nr_process_mac_pdu(
         	//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(NR_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;
 
         case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT:
@@ -227,67 +364,118 @@ void nr_process_mac_pdu(
         	//  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[UE_id]);
+          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;
-        case UL_SCH_LCID_CCCH_MSG3:
-              // todo
-              break;
+
         case UL_SCH_LCID_CCCH:
-              // todo
-              mac_subheader_len = 2;
+        case UL_SCH_LCID_CCCH1:
+          // fixed length
+          mac_subheader_len = 1;
+
+          if ( rx_lcid == UL_SCH_LCID_CCCH1 ) {
+            // RRCResumeRequest1 message includes the full I-RNTI and has a size of 8 bytes
+            mac_sdu_len = 8;
+
+            // Check if it is a valid CCCH1 message, we get all 00's messages very often
+            int i = 0;
+            for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) {
+              if(pdu_ptr[i] != 0) {
+                break;
+              }
+            }
+            if (i == (mac_subheader_len+mac_sdu_len)) {
+              LOG_D(NR_MAC, "%s() Invalid CCCH1 message!, pdu_len: %d\n", __func__, pdu_len);
+              done = 1;
               break;
+            }
+          } else {
+            // fixed length of 6 bytes
+            mac_sdu_len = 6;
+          }
+
+          nr_mac_rrc_data_ind(module_idP,
+                              CC_id,
+                              frameP,
+                              0,
+                              0,
+                              UE_info->rnti[UE_id],
+                              CCCH,
+                              pdu_ptr+mac_subheader_len,
+                              mac_sdu_len,
+                              0);
+          break;
 
         case UL_SCH_LCID_DTCH:
-                //  check if LCID is valid at current time.
-                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(MAC, "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len);
-		int UE_id = find_nr_UE_id(module_idP, rnti);
-		RC.nrmac[module_idP]->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");
-
-                #endif
-
-                mac_rlc_data_ind(module_idP,
-                                 rnti,
-                                 module_idP,
-                                 frameP,
-                                 ENB_FLAG_YES,
-                                 MBMS_FLAG_NO,
-                                 rx_lcid,
-                                 (char *) (pdu_ptr + mac_subheader_len),
-                                 mac_sdu_len,
-                                 1,
-                                 NULL);
-
-                /* Updated estimated buffer when receiving data */
-                if (sched_ctrl->estimated_ul_buffer >= mac_sdu_len)
-                  sched_ctrl->estimated_ul_buffer -= mac_sdu_len;
-                else
-                  sched_ctrl->estimated_ul_buffer = 0;
-
-            break;
+          //  check if LCID is valid at current time.
+          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-%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(NR_MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n");
+#endif
+
+          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);
+
+          /* Updated estimated buffer when receiving data */
+          if (sched_ctrl->estimated_ul_buffer >= mac_sdu_len)
+            sched_ctrl->estimated_ul_buffer -= mac_sdu_len;
+          else
+            sched_ctrl->estimated_ul_buffer = 0;
+          break;
 
         default:
-          LOG_D(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;
         }
@@ -295,8 +483,8 @@ void nr_process_mac_pdu(
         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");
@@ -305,6 +493,24 @@ void nr_process_mac_pdu(
     }
 }
 
+void abort_nr_ul_harq(module_id_t mod_id, int UE_id, int8_t harq_pid)
+{
+  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];
+  NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid];
+
+  harq->ndi ^= 1;
+  harq->round = 0;
+  UE_info->mac_stats[UE_id].ulsch_errors++;
+  add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
+
+  /* the transmission failed: the UE won't send the data we expected initially,
+   * so retrieve to correctly schedule after next BSR */
+  sched_ctrl->sched_ul_bytes -= harq->sched_pusch.tb_size;
+  if (sched_ctrl->sched_ul_bytes < 0)
+    sched_ctrl->sched_ul_bytes = 0;
+}
+
 void handle_nr_ul_harq(module_id_t mod_id,
                        frame_t frame,
                        sub_frame_t slot,
@@ -312,7 +518,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;
@@ -320,7 +526,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,
@@ -329,8 +535,13 @@ void handle_nr_ul_harq(module_id_t mod_id,
       return;
 
     remove_front_nr_list(&sched_ctrl->feedback_ul_harq);
-    sched_ctrl->ul_harq_processes[harq_pid].round++;
-    add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid);
+    sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false;
+    if(sched_ctrl->ul_harq_processes[harq_pid].round >= MAX_HARQ_ROUNDS - 1) {
+      abort_nr_ul_harq(mod_id, UE_id, harq_pid);
+    } else {
+      sched_ctrl->ul_harq_processes[harq_pid].round++;
+      add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid);
+    }
     harq_pid = sched_ctrl->feedback_ul_harq.head;
   }
   remove_front_nr_list(&sched_ctrl->feedback_ul_harq);
@@ -341,23 +552,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) {
-    harq->ndi ^= 1;
-    harq->round = 0;
-    LOG_D(MAC,
+  } else if (harq->round >= MAX_HARQ_ROUNDS - 1) {
+    abort_nr_ul_harq(mod_id, UE_id, harq_pid);
+    LOG_D(NR_MAC,
           "RNTI %04x: Ulharq id %d crc failed in all rounds\n",
           crc_pdu->rnti,
           harq_pid);
-    UE_info->mac_stats[UE_id].ulsch_errors++;
-    add_tail_nr_list(&sched_ctrl->available_ul_harq, 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);
@@ -384,6 +592,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];
@@ -395,7 +604,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(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,
@@ -404,15 +613,17 @@ 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)
-    if (UE_scheduling_control->ul_rssi < (100+rssi)) {
+    if (UE_scheduling_control->raw_rssi < 100 + rssi) {
       UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30);
       if (timing_advance != 0xffff)
         UE_scheduling_control->ta_update = timing_advance;
-      UE_scheduling_control->ul_rssi = rssi;
-      LOG_D(MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
+      UE_scheduling_control->raw_rssi = rssi;
+      UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
+      LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
     }
     else{
       UE_scheduling_control->tpc0 = 1;
@@ -420,7 +631,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]);
@@ -431,14 +642,15 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
 #endif
 
     if (sduP != NULL){
-      LOG_D(MAC, "Received PDU at MAC gNB \n");
+      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)
         UE_scheduling_control->sched_ul_bytes = 0;
 
-      nr_process_mac_pdu(gnb_mod_idP, current_rnti, CC_idP, frameP, sduP, sdu_lenP);
+      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];
@@ -449,10 +661,29 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
         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;
+         nr_mac_gNB_rrc_ul_failure(gnb_mod_idP,CC_idP,frameP,slotP,rntiP);
+      }
+    }
+  } else if(sduP) {
+
+    bool no_sig = true;
+    for (int k = 0; k < sdu_lenP; k++) {
+      if(sduP[k]!=0) {
+        no_sig = false;
+        break;
+      }
+    }
+
+    if(no_sig) {
+      LOG_W(NR_MAC, "No signal\n");
     }
-  } else {
-    if (!sduP) // check that CRC passed
-      return;
 
     T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP),
       T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */,
@@ -466,41 +697,105 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
       if (ra->state != WAIT_Msg3)
         continue;
 
-      // random access pusch with TC-RNTI
-      if (ra->rnti != current_rnti) {
-        LOG_W(MAC,
-              "expected TC-RNTI %04x to match current RNTI %04x\n",
+      if(no_sig) {
+        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 {
+
+        // random access pusch with TC-RNTI
+        if (ra->rnti != current_rnti) {
+          LOG_W(NR_MAC,
+                "expected TC_RNTI %04x to match current RNTI %04x\n",
+                ra->rnti,
+                current_rnti);
+
+          if( (frameP==ra->Msg3_frame) && (slotP==ra->Msg3_slot) ) {
+            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);
+          }
+
+          continue;
+        }
+
+        int UE_id=-1;
+
+        UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->CellGroup);
+        if (UE_id<0) {
+          LOG_W(NR_MAC, "Random Access %i discarded at state %i (TC_RNTI %04x RNTI %04x): max number of users achieved!\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);
+          return;
+        }
+
+        UE_info->UE_beam_index[UE_id] = ra->beam_id;
+
+        // re-initialize ta update variables after RA procedure completion
+        UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP;
+
+        LOG_I(NR_MAC,
+              "reset RA state information for RA-RNTI %04x/index %d\n",
               ra->rnti,
-              current_rnti);
-        continue;
+              i);
+
+        LOG_I(NR_MAC,
+              "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
+              "adding UE MAC Context UE_id %d/RNTI %04x\n",
+              gnb_mod_idP,
+              current_rnti,
+              UE_id,
+              ra->rnti);
+
+        if(ra->cfra) {
+
+          LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) CFRA procedure succeeded!\n", UE_id, ra->rnti);
+          nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
+          nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
+          UE_info->active[UE_id] = true;
+
+        } else {
+
+          LOG_I(NR_MAC,"[RAPROC] RA-Msg3 received (sdu_lenP %d)\n",sdu_lenP);
+          LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n");
+          for (int k = 0; k < sdu_lenP; k++) {
+            LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]);
+          }
+
+          // UE Contention Resolution Identity
+          // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to fill in Msg4
+          // First byte corresponds to R/LCID MAC sub-header
+          memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6);
+
+          nr_process_mac_pdu(gnb_mod_idP, UE_id, CC_idP, frameP, slotP, sduP, sdu_lenP);
+
+          ra->state = Msg4;
+          ra->Msg4_frame = ( frameP +2 ) % 1024;
+          ra->Msg4_slot = 1;
+          LOG_I(NR_MAC, "Scheduling RA-Msg4 for TC_RNTI %04x (state %d, frame %d, slot %d)\n", ra->rnti, ra->state, ra->Msg4_frame, ra->Msg4_slot);
+
+        }
+        return;
       }
-      const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->secondaryCellGroup);
-      UE_info->UE_beam_index[UE_id] = ra->beam_id;
-      LOG_I(MAC,
-            "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
-            "adding UE MAC Context UE_id %d/RNTI %04x\n",
-            gnb_mod_idP,
-            current_rnti,
-            UE_id,
-            ra->rnti);
-      // re-initialize ta update variables afrer RA procedure completion
-      UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP;
-
-      free(ra->preambles.preamble_list);
-      ra->state = RA_IDLE;
-      LOG_I(MAC,
-            "reset RA state information for RA-RNTI %04x/index %d\n",
-            ra->rnti,
-            i);
+    }
+  } else {
+    for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
+      NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i];
+      if (ra->state != WAIT_Msg3)
+        continue;
 
-      return;
+      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(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)
@@ -511,6 +806,34 @@ long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
     return 3;
 }
 
+bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t frame, sub_frame_t slot)
+{
+  const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
+  const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
+  const int n = slots_per_frame[*scc->ssbSubcarrierSpacing];
+  const int now = frame * n + slot;
+
+  const struct gNB_MAC_INST_s *nrmac = RC.nrmac[mod_id];
+  const NR_UE_sched_ctrl_t *sched_ctrl = &nrmac->UE_info.UE_sched_ctrl[UE_id];
+  const int last_ul_sched = sched_ctrl->last_ul_frame * n + sched_ctrl->last_ul_slot;
+
+  const int diff = (now - last_ul_sched + 1024 * n) % (1024 * n);
+  /* UE is to be scheduled if
+   * (1) we think the UE has more bytes awaiting than what we scheduled
+   * (2) there is a scheduling request
+   * (3) or we did not schedule it in more than 10 frames */
+  const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes;
+  const bool high_inactivity = diff >= nrmac->ulsch_max_slots_inactivity;
+  LOG_D(NR_MAC,
+        "%4d.%2d UL inactivity %d slots has_data %d SR %d\n",
+        frame,
+        slot,
+        diff,
+        has_data,
+        sched_ctrl->SR);
+  return has_data || sched_ctrl->SR || high_inactivity;
+}
+
 int next_list_entry_looped(NR_list_t *list, int UE_id)
 {
   if (UE_id < 0)
@@ -518,125 +841,196 @@ int next_list_entry_looped(NR_list_t *list, int UE_id)
   return list->next[UE_id] < 0 ? list->head : list->next[UE_id];
 }
 
+bool allocate_ul_retransmission(module_id_t module_id,
+                                frame_t frame,
+                                sub_frame_t slot,
+                                uint8_t *rballoc_mask,
+                                int *n_rb_sched,
+                                int UE_id,
+                                int harq_pid)
+{
+  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_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;
+
+  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 = 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] : 0;
+  LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda);
+  if (tda == retInfo->time_domain_allocation) {
+    /* Check the resource is enough for retransmission */
+    while (rbStart < bwpSize && !rballoc_mask[rbStart])
+      rbStart++;
+    if (rbStart + retInfo->rbSize > bwpSize) {
+      LOG_W(NR_MAC, "cannot allocate retransmission of UE %d/RNTI %04x: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d\n", UE_id, UE_info->rnti[UE_id], rbStart, retInfo->rbSize, bwpSize);
+      return false;
+    }
+    /* check whether we need to switch the TDA allocation since tha last
+     * (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 = 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)
+      nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
+    LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size);
+  } else {
+    /* the retransmission will use a different time domain allocation, check
+     * that we have enough resources */
+    while (rbStart < bwpSize && !rballoc_mask[rbStart])
+      rbStart++;
+    int rbSize = 0;
+    while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize])
+      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 = 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;
+    bool success = nr_find_nb_rb(retInfo->Qm,
+                                 retInfo->R,
+                                 temp_ps.nrOfSymbols,
+                                 temp_ps.N_PRB_DMRS * temp_ps.num_dmrs_symb,
+                                 retInfo->tb_size,
+                                 rbSize,
+                                 &new_tbs,
+                                 &new_rbSize);
+    if (!success || new_tbs != retInfo->tb_size) {
+      LOG_D(NR_MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size);
+      return false; /* the maximum TBsize we might have is smaller than what we need */
+    }
+    LOG_D(NR_MAC, "%s(): retransmission with TDA %d->%d and TBS %d -> %d\n", __func__, retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs);
+    /* we can allocate it. Overwrite the time_domain_allocation, the number
+     * of RBs, and the new TB size. The rest is done below */
+    retInfo->tb_size = new_tbs;
+    retInfo->rbSize = new_rbSize;
+    retInfo->time_domain_allocation = tda;
+    sched_ctrl->pusch_semi_static = temp_ps;
+  }
+
+  /* Find free CCE */
+  bool freeCCE = find_free_CCE(module_id, slot, UE_id);
+  if (!freeCCE) {
+    LOG_D(NR_MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_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(NR_MAC,
+        "%4d.%2d Allocate UL retransmission UE %d/RNTI %04x sched %4d.%2d (%d RBs)\n",
+        frame,
+        slot,
+        UE_id,
+        UE_info->rnti[UE_id],
+        sched_pusch->frame,
+        sched_pusch->slot,
+        sched_pusch->rbSize);
+
+  sched_pusch->rbStart = rbStart;
+  /* no need to recompute the TBS, it will be the same */
+
+  /* Mark the corresponding RBs as used */
+  n_rb_sched -= sched_pusch->rbSize;
+  for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
+    rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] = 0;
+  return true;
+}
+
+void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static_t *ps)
+{
+  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 && 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;
+  }
+}
+
 float ul_thr_ue[MAX_MOBILES_PER_GNB];
-int bsr0ue = -1;
+uint32_t ul_pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient
 void pf_ul(module_id_t module_id,
            frame_t frame,
            sub_frame_t slot,
-           int num_slots_per_tdd,
            NR_list_t *UE_list,
+           int max_num_ue,
            int n_rb_sched,
-           uint8_t *rballoc_mask,
-           int max_num_ue) {
+           uint8_t *rballoc_mask) {
 
   const int CC_id = 0;
-  const int tda = 1;
-  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;
+  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;
   const int min_rb = 5;
   float coeff_ue[MAX_MOBILES_PER_GNB];
   // UEs that could be scheduled
   int ue_array[MAX_MOBILES_PER_GNB];
   NR_list_t UE_sched = { .head = -1, .next = ue_array, .tail = -1, .len = MAX_MOBILES_PER_GNB };
 
-  /* Hack: currently, we do not have SR, and need to schedule UEs continuously.
-   * To keep the wasted resources low, we switch UEs to be scheduled in a
-   * round-robin fashion below, and only schedule a UE with BSR=0 if it is the
-   * selected one */
-  bsr0ue = next_list_entry_looped(UE_list, bsr0ue);
-
   /* 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_bwp->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;
 
     /* Calculate throughput */
     const float a = 0.0005f; // corresponds to 200ms window
     const uint32_t b = UE_info->mac_stats[UE_id].ulsch_current_bytes;
     ul_thr_ue[UE_id] = (1 - a) * ul_thr_ue[UE_id] + a * b;
 
-    /* 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 */
-    sched_ctrl->sched_pusch.time_domain_allocation = tda;
-    sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, NR_SearchSpace__searchSpaceType_PR_ue_Specific);
-    sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
-    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 uint8_t num_dmrs_cdm_grps_no_data = 1;
-    NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
-    if (ps->time_domain_allocation != tda
-        || ps->dci_format != dci_format
-        || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
-      nr_save_pusch_fields(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
-
     /* Check if retransmission is necessary */
-    sched_ctrl->sched_pusch.ul_harq_pid = sched_ctrl->retrans_ul_harq.head;
-    if (sched_ctrl->sched_pusch.ul_harq_pid >= 0) {
-      /* RETRANSMISSION: Allocate retransmission*/
-      /* Find free CCE */
-      bool freeCCE = find_free_CCE(module_id, slot, UE_id);
-      if (!freeCCE) {
-        LOG_D(MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
+    sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head;
+    if (sched_pusch->ul_harq_pid >= 0) {
+      /* Allocate retransmission*/
+      bool r = allocate_ul_retransmission(
+          module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pusch->ul_harq_pid);
+      if (!r) {
+        LOG_D(NR_MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\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 */
       max_num_ue--;
       if (max_num_ue < 0)
         return;
-
-      /* Save shced_frame and sched_slot before overwrite by previous PUSCH filed */
-      NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[sched_ctrl->sched_pusch.ul_harq_pid];
-      cur_harq->sched_pusch.frame = sched_ctrl->sched_pusch.frame;
-      cur_harq->sched_pusch.slot = sched_ctrl->sched_pusch.slot;
-      /* Get previous PSUCH filed info */
-      sched_ctrl->sched_pusch = cur_harq->sched_pusch;
-      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, slot, UE_id, UE_info->rnti[UE_id],
-            sched_pusch->frame, sched_pusch->slot,
-            sched_pusch->rbSize);
-
-      while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
-      if (rbStart + sched_pusch->rbSize >= bwpSize) {
-        LOG_W(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n",
-              UE_id, UE_info->rnti[UE_id]);
-        return;
-      }
-      sched_pusch->rbStart = rbStart;
-      /* no need to recompute the TBS, it will be the same */
-
-      /* Mark the corresponding RBs as used */
-      n_rb_sched -= sched_pusch->rbSize;
-      for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
-        rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] = 0;
-
       continue;
     }
 
-    /* Calculate TBS from MCS */
-    NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
-    const int mcs = 9;
-    sched_pusch->mcs = 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))) {
-      sched_pusch->R >>= 1;
-      sched_pusch->Qm <<= 1;
-    }
+    const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
+    /* preprocessor computed sched_frame/sched_slot */
+    const bool do_sched = nr_UE_is_to_be_scheduled(module_id, 0, UE_id, sched_pusch->frame, sched_pusch->slot);
 
-    /* Check BSR and schedule UE if it is zero to avoid starvation, since we do
-     * not have SR (yet) */
-    if (sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes <= 0) {
-      if (UE_id != bsr0ue)
-        continue;
+    if (B == 0 && !do_sched)
+      continue;
+
+    /* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled
+     * based on data to transmit) */
+    if (B == 0 && do_sched) {
       /* 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 */
@@ -644,12 +1038,29 @@ 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_W(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n",
-              UE_id, UE_info->rnti[UE_id]);
+        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 = 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] : 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)
+        nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
+      NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
+      sched_pusch->mcs = 9;
+      update_ul_ue_R_Qm(sched_pusch, ps);
       sched_pusch->rbStart = rbStart;
       sched_pusch->rbSize = min_rb;
       sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
@@ -674,17 +1085,10 @@ void pf_ul(module_id_t module_id,
     add_tail_nr_list(&UE_sched, UE_id);
 
     /* Calculate coefficient*/
-    const uint32_t tbs = nr_compute_tbs(sched_pusch->Qm,
-                                        sched_pusch->R,
-                                        1, // rbSize
-                                        ps->nrOfSymbols,
-                                        ps->N_PRB_DMRS * ps->num_dmrs_symb,
-                                        0, // nb_rb_oh
-                                        0,
-                                        1 /* NrOfLayers */)
-                          >> 3;
+    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]);
   }
 
@@ -710,7 +1114,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;
     }
 
@@ -720,37 +1124,53 @@ 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);
-    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;
 
     while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
     sched_pusch->rbStart = rbStart;
+    uint16_t max_rbSize = 1;
+    while (rbStart + max_rbSize < bwpSize && rballoc_mask[rbStart + max_rbSize])
+      max_rbSize++;
+
     if (rbStart + min_rb >= bwpSize) {
-      LOG_W(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n",
-            UE_id, UE_info->rnti[UE_id]);
+      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;
     }
 
-    /* Calculate the current scheduling bytes */
+    /* 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 = 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] : 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)
+      nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
+    update_ul_ue_R_Qm(sched_pusch, ps);
+
+    /* Calculate the current scheduling bytes and the necessary RBs */
     const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0);
-    uint16_t rbSize = min_rb - 1;
-    do {
-      rbSize++;
-      sched_pusch->rbSize = rbSize;
-      sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
-                                            sched_pusch->R,
-                                            sched_pusch->rbSize,
-                                            sched_ctrl->pusch_save.nrOfSymbols,
-                                            sched_ctrl->pusch_save.N_PRB_DMRS * sched_ctrl->pusch_save.num_dmrs_symb,
-                                            0, // nb_rb_oh
-                                            0,
-                                            1 /* NrOfLayers */)
-                             >> 3;
-    } while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart+rbSize] &&
-             sched_pusch->tb_size < B);
-    LOG_D(MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n",
+    uint16_t rbSize = 0;
+    uint32_t TBS = 0;
+    nr_find_nb_rb(sched_pusch->Qm,
+                  sched_pusch->R,
+                  ps->nrOfSymbols,
+                  ps->N_PRB_DMRS * ps->num_dmrs_symb,
+                  B,
+                  max_rbSize,
+                  &TBS,
+                  &rbSize);
+    sched_pusch->rbSize = rbSize;
+    sched_pusch->tb_size = TBS;
+    LOG_D(NR_MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n",
           rbSize, sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B);
 
     /* Mark the corresponding RBs as used */
@@ -760,11 +1180,8 @@ void pf_ul(module_id_t module_id,
   }
 }
 
-bool nr_simple_ulsch_preprocessor(module_id_t module_id,
-                                  frame_t frame,
-                                  sub_frame_t slot,
-                                  int num_slots_per_tdd,
-                                  uint64_t ulsch_in_slot_bitmap) {
+bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
+{
   gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
   NR_COMMON_channels_t *cc = nr_mac->common_channels;
   NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -776,45 +1193,62 @@ bool nr_simple_ulsch_preprocessor(module_id_t module_id,
 
   const int CC_id = 0;
 
-  /* NOT support different K2 in here, Get the K2 for first UE */
+  /* Get the K2 for first UE to compute offset. The other UEs are guaranteed to
+   * have the same K2 (we don't support multiple/different K2s via different
+   * TDAs yet). If the TDA is negative, it means that there is no UL slot to
+   * 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 = 1;
-  const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
-    sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
-  AssertFatal(tda < tdaList->list.count,
-              "time domain assignment %d >= %d\n",
-              tda,
-              tdaList->list.count);
-
-  int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu);
+  const int tda = sched_ctrl->active_ubwp ? nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
+  if (tda < 0)
+    return false;
+  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(ulsch_in_slot_bitmap, sched_slot))
+
+  if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot))
+    return false;
+
+  bool is_mixed_slot = is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[sched_slot / 64], sched_slot) &&
+                        is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot);
+
+  // FIXME: Avoid mixed slots for initialUplinkBWP
+  if (sched_ctrl->active_ubwp==NULL && is_mixed_slot)
     return false;
 
   sched_ctrl->sched_pusch.slot = sched_slot;
   sched_ctrl->sched_pusch.frame = sched_frame;
-
-  /* Confirm all the UE have same K2 as the first UE */
   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(sched_ctrl->active_ubwp, tda, mu),
-                "Different K2, %d(UE%d) != %ld(UE%d)\n", K2, 0, get_K2(sched_ctrl->active_ubwp, tda, mu), 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;
   }
 
-  /* Change vrb_map_UL to rballoc_mask */
+  /* Change vrb_map_UL to rballoc_mask: check which symbols per RB (in
+   * vrb_map_UL) overlap with the "default" tda and exclude those RBs.
+   * 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 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] == 1)
+    while ((vrb_map_UL[i] & symb) != 0 && i < bwpSize)
       i++;
     st = i;
-    while (vrb_map_UL[i] == 0)
+    while ((vrb_map_UL[i] & symb) == 0 && i < bwpSize)
       i++;
     if (i - st > len) {
       len = i - st;
@@ -833,28 +1267,53 @@ bool nr_simple_ulsch_preprocessor(module_id_t module_id,
   pf_ul(module_id,
         frame,
         slot,
-        num_slots_per_tdd,
         &UE_info->list,
+        2,
         len,
-        rballoc_mask,
-        2);
+        rballoc_mask);
   return true;
 }
 
-void nr_schedule_ulsch(module_id_t module_id,
-                       frame_t frame,
-                       sub_frame_t slot,
-                       int num_slots_per_tdd,
-                       int ul_slots,
-                       uint64_t ulsch_in_slot_bitmap) {
+nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(module_id_t module_id, int CC_id)
+{
+  /* in the PF algorithm, we have to use the TBsize to compute the coefficient.
+   * This would include the number of DMRS symbols, which in turn depends on
+   * the time domain allocation. In case we are in a mixed slot, we do not want
+   * to recalculate all these values, and therefore we provide a look-up table
+   * which should approximately(!) give us the TBsize. In particular, the
+   * number of symbols, the number of DMRS symbols, and the exact Qm and R, are
+   * not correct*/
+  for (int mcsTableIdx = 0; mcsTableIdx < 3; ++mcsTableIdx) {
+    for (int mcs = 0; mcs < 29; ++mcs) {
+      if (mcs > 27 && mcsTableIdx == 1)
+        continue;
+      const uint8_t Qm = nr_get_Qm_dl(mcs, mcsTableIdx);
+      const uint16_t R = nr_get_code_rate_dl(mcs, mcsTableIdx);
+      /* note: we do not update R/Qm based on low MCS or pi2BPSK */
+      ul_pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm,
+                                                   R,
+                                                   1, /* rbSize */
+                                                   10, /* hypothetical number of slots */
+                                                   0, /* N_PRB_DMRS * N_DMRS_SLOT */
+                                                   0 /* N_PRB_oh, 0 for initialBWP */,
+                                                   0 /* tb_scaling */,
+                                                   1 /* nrOfLayers */)
+                                    >> 3;
+    }
+  }
+  return nr_fr1_ulsch_preprocessor;
+}
+
+void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
+{
+  gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
   /* 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(ulsch_in_slot_bitmap, slot)) {
-    LOG_D(MAC, "Current slot %d is NOT DL slot, cannot schedule DCI0 for UL data\n", slot);
+  if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slot / 64], 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, num_slots_per_tdd, ulsch_in_slot_bitmap);
+  bool do_sched = RC.nrmac[module_id]->pre_processor_ul(module_id, frame, slot);
   if (!do_sched)
     return;
 
@@ -872,14 +1331,18 @@ void nr_schedule_ulsch(module_id_t module_id,
   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;
 
     uint16_t rnti = UE_info->rnti[UE_id];
+    sched_ctrl->SR = false;
 
     int8_t harq_id = sched_pusch->ul_harq_pid;
     if (harq_id < 0) {
@@ -909,8 +1372,8 @@ void nr_schedule_ulsch(module_id_t module_id,
 
     /* pre-computed PUSCH values that only change if time domain allocation,
      * DCI format, or DMRS parameters change. Updated in the preprocessor
-     * through nr_save_pusch_fields() */
-    NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
+     * through nr_set_pusch_semi_static() */
+    NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
 
     /* Statistics */
     UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
@@ -919,9 +1382,12 @@ void nr_schedule_ulsch(module_id_t module_id,
       /* Save information on MCS, TBS etc for the current initial transmission
        * so we have access to it when retransmitting */
       cur_harq->sched_pusch = *sched_pusch;
+      /* save which time allocation has been used, to be used on
+       * retransmissions */
+      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,
@@ -933,9 +1399,11 @@ void nr_schedule_ulsch(module_id_t module_id,
             cur_harq->ndi);
     }
     UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size;
+    sched_ctrl->last_ul_frame = sched_pusch->frame;
+    sched_ctrl->last_ul_slot = sched_pusch->slot;
 
-    LOG_D(MAC,
-          "%4d.%2d RNTI %04x UL sched %4d.%2d start %d RBS %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n",
+    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,
           rnti,
@@ -943,11 +1411,17 @@ void nr_schedule_ulsch(module_id_t module_id,
           sched_pusch->slot,
           sched_pusch->rbStart,
           sched_pusch->rbSize,
+          ps->startSymbolIndex,
+          ps->nrOfSymbols,
           sched_pusch->mcs,
           sched_pusch->tb_size,
           harq_id,
           cur_harq->round,
-          cur_harq->ndi);
+          cur_harq->ndi,
+          sched_ctrl->estimated_ul_buffer,
+          sched_ctrl->sched_ul_bytes,
+          sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
+
 
     /* PUSCH in a later slot, but corresponding DCI now! */
     nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][sched_pusch->slot];
@@ -965,16 +1439,18 @@ void nr_schedule_ulsch(module_id_t module_id,
     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 */
@@ -983,7 +1459,8 @@ void nr_schedule_ulsch(module_id_t module_id,
     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;
@@ -993,10 +1470,10 @@ void nr_schedule_ulsch(module_id_t module_id,
     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;
@@ -1005,9 +1482,9 @@ void nr_schedule_ulsch(module_id_t module_id,
     }
     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]
@@ -1015,13 +1492,11 @@ void nr_schedule_ulsch(module_id_t module_id,
     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;
@@ -1045,8 +1520,8 @@ void nr_schedule_ulsch(module_id_t module_id,
       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");
@@ -1057,19 +1532,17 @@ void nr_schedule_ulsch(module_id_t module_id,
     /*-----------------------------------------------------------------------------*/
 
     /* PUSCH PTRS */
-    if (ps->NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) {
-      // TODO to be fixed from RRC config
-      uint8_t ptrs_mcs1 = 2;  // higher layer parameter in PTRS-UplinkConfig
-      uint8_t ptrs_mcs2 = 4;  // higher layer parameter in PTRS-UplinkConfig
-      uint8_t ptrs_mcs3 = 10; // higher layer parameter in PTRS-UplinkConfig
-      uint16_t n_rb0 = 25;    // higher layer parameter in PTRS-UplinkConfig
-      uint16_t n_rb1 = 75;    // higher layer parameter in PTRS-UplinkConfig
-      pusch_pdu->pusch_ptrs.ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_pdu->mcs_index, pusch_pdu->mcs_table);
-      pusch_pdu->pusch_ptrs.ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_pdu->rb_size);
+    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));
-      pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
-
-      pusch_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS
+      valid_ptrs_setup = set_ul_ptrs_values(ps->NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup,
+                                            pusch_pdu->rb_size, pusch_pdu->mcs_index, pusch_pdu->mcs_table,
+                                            &pusch_pdu->pusch_ptrs.ptrs_freq_density,&pusch_pdu->pusch_ptrs.ptrs_time_density,
+                                            &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset,&pusch_pdu->pusch_ptrs.num_ptrs_ports,
+                                            &pusch_pdu->pusch_ptrs.ul_ptrs_power, pusch_pdu->nr_of_symbols);
+      if (valid_ptrs_setup==true) {
+        pusch_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS
+      }
     }
     else{
       pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
@@ -1077,8 +1550,10 @@ void nr_schedule_ulsch(module_id_t module_id,
 
     /* 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];
@@ -1087,19 +1562,19 @@ void nr_schedule_ulsch(module_id_t module_id,
       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;
@@ -1112,25 +1587,31 @@ void nr_schedule_ulsch(module_id_t module_id,
 
     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));
   }
-}
\ No newline at end of file
+}
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 3502a11580cf75af67805070267e34d5044f1b0c..7af01850ae0d81707677b386851be65f30e1db48 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -41,19 +41,20 @@ void set_cset_offset(uint16_t);
 void mac_top_init_gNB(void);
 
 void config_common(int Mod_idP,
+                   int ssb_SubcarrierOffset,
                    int pdsch_AntennaPorts,
+                   int pusch_AntennaPorts,
 		   NR_ServingCellConfigCommon_t *scc
 		   );
 
-int rrc_mac_config_req_gNB(module_id_t Mod_idP, 
-			   int ssb_SubcarrierOffset,
+int rrc_mac_config_req_gNB(module_id_t Mod_idP,
+                           int ssb_SubcarrierOffset,
                            int pdsch_AntennaPorts,
-                           int pusch_tgt_snrx10,
-                           int pucch_tgt_snrx10,
+                           int pusch_AntennaPorts,
                            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, 
@@ -64,39 +65,36 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
 void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
 			       frame_t frame_rxP, sub_frame_t slot_rxP);
 
+/* \brief main DL scheduler function. Calls a preprocessor to decide on
+ * resource allocation, then "post-processes" resource allocation (nFAPI
+ * messages, statistics, HARQ handling, CEs, ... */
 void nr_schedule_ue_spec(module_id_t module_id,
                          frame_t frame,
                          sub_frame_t slot);
 
+/* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */
+nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id);
+
 void schedule_control_sib1(module_id_t module_id,
                            int CC_id,
+                           NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
                            int time_domain_allocation,
                            uint8_t mcsTableIdx,
                            uint8_t mcs,
+                           uint8_t candidate_idx,
                            int num_total_bytes);
 
 void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
 
-/* \brief default preprocessor */
-void nr_simple_dlsch_preprocessor(module_id_t module_id,
-                                  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 subframeP, uint8_t slots_per_frame);
+/* \brief main UL scheduler function. Calls a preprocessor to decide on
+ * resource allocation, then "post-processes" resource allocation (nFAPI
+ * messages, statistics, HARQ handling, ... */
+void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot);
 
-/// uplink scheduler
-void nr_schedule_ulsch(module_id_t module_id,
-                       frame_t frame,
-                       sub_frame_t slot,
-                       int num_slots_per_tdd,
-                       int ul_slots,
-                       uint64_t ulsch_in_slot_bitmap);
-
-bool nr_simple_ulsch_preprocessor(module_id_t module_id,
-                                  frame_t frame,
-                                  sub_frame_t slot,
-                                  int num_slots_per_tdd,
-                                  uint64_t ulsch_in_slot_bitmap);
+/* \brief default FR1 UL preprocessor init routine, returns preprocessor to call */
+nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(module_id_t module_id, int CC_id);
 
 /////// Random Access MAC-PHY interface functions and primitives ///////
 
@@ -113,7 +111,7 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
 void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP,
                          uint16_t preamble_index, uint8_t freq_index, uint8_t symbol, int16_t timing_offset);
 
-void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP);
+void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra);
 
 int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only);
 
@@ -123,7 +121,8 @@ void nr_get_Msg3alloc(module_id_t module_id,
                       NR_BWP_Uplink_t *ubwp,
                       sub_frame_t current_subframe,
                       frame_t current_frame,
-                      NR_RA_t *ra);
+                      NR_RA_t *ra,
+                      int16_t *tdd_beam_association);
 
 /* \brief Function in gNB to fill RAR pdu when requested by PHY.
 @param ra Instance of RA resources of gNB
@@ -149,11 +148,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
                              sub_frame_t slot);
 /* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a
  * fixed set of resources */
-bool nr_ul_preprocessor_phytest(module_id_t module_id,
-                                frame_t frame,
-                                sub_frame_t slot,
-                                int num_slots_per_tdd,
-                                uint64_t ulsch_in_slot_bitmap);
+bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot);
 
 void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
                                    frame_t       frameP,
@@ -170,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,
@@ -182,17 +178,20 @@ void nr_schedule_pucch(int Mod_idP,
                        frame_t frameP,
                        sub_frame_t slotP);
 
-void csi_period_offset(const NR_CSI_ReportConfig_t *csirep,
-                       int *period, int *offset);
+void nr_csirs_scheduling(int Mod_idP,
+                         frame_t frame,
+                         sub_frame_t slot,
+                         int n_slots_frame);
 
 void nr_csi_meas_reporting(int Mod_idP,
                            frame_t frameP,
                            sub_frame_t slotP);
 
-bool nr_acknack_scheduling(int Mod_idP,
+int nr_acknack_scheduling(int Mod_idP,
                            int UE_id,
                            frame_t frameP,
-                           sub_frame_t slotP);
+                           sub_frame_t slotP,
+                           int r_pucch);
 
 void get_pdsch_to_harq_feedback(int Mod_idP,
                                 int UE_id,
@@ -219,13 +218,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,
@@ -238,7 +239,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,
@@ -246,30 +247,37 @@ 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(NR_BWP_Downlink_t *bwp,
+NR_ControlResourceSet_t *get_coreset(NR_ServingCellConfigCommon_t *scc,
+                                     NR_BWP_Downlink_t *bwp,
                                      NR_SearchSpace_t *ss,
-                                     int ss_type);
+                                     NR_SearchSpace__searchSpaceType_PR ss_type);
 
 /* find a search space within a BWP */
-NR_SearchSpace_t *get_searchspace(
-    NR_BWP_Downlink_t *bwp,
-    NR_SearchSpace__searchSpaceType_PR target_ss);
-
-
-long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu);
-
-void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc,
-                          const NR_BWP_Uplink_t *ubwp,
-                          long dci_format,
-                          int tda,
-                          uint8_t num_dmrs_cdm_grps_no_data,
-                          NR_sched_pusch_save_t *ps);
+NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc,
+                                  NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
+                                  NR_SearchSpace__searchSpaceType_PR target_ss);
+
+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,
+                              const NR_BWP_Downlink_t *bwp,
+                              int tda,
+                              uint8_t num_dmrs_cdm_grps_no_data,
+                              NR_pdsch_semi_static_t *ps);
+
+void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc,
+                              const NR_BWP_Uplink_t *ubwp,
+                              long dci_format,
+                              int tda,
+                              uint8_t num_dmrs_cdm_grps_no_data,
+                              NR_pusch_semi_static_t *ps);
 
 uint8_t nr_get_tpc(int target, uint8_t cqi, int incr);
 
@@ -307,10 +315,12 @@ 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);
 
+void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti);
+
 int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
                      NR_BWP_Downlink_t *bwp,
                      NR_ControlResourceSet_t *coreset,
@@ -319,16 +329,9 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
                      int m,
                      int nr_of_candidates);
 
-uint16_t compute_pucch_prb_size(uint8_t format,
-                                uint8_t nr_prbs,
-                                uint16_t O_tot,
-                                uint16_t O_csi,
-                                NR_PUCCH_MaxCodeRate_t *maxCodeRate,
-                                uint8_t Qm,
-                                uint8_t n_symb,
-                                uint8_t n_re_ctrl);
+int nr_get_default_pucch_res(int pucch_ResourceCommon);
 
-void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t *UE_info, int UE_id);
+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);
 
@@ -346,21 +349,23 @@ void config_nr_mib(int Mod_idP,
                    int cellBarred,
                    int intraFreqReselection);
 
+int nr_write_ce_dlsch_pdu(module_id_t module_idP,
+                          const NR_UE_sched_ctrl_t *ue_sched_ctl,
+                          unsigned char *mac_pdu,
+                          unsigned char drx_cmd,
+                          unsigned char *ue_cont_res_id);
+
 void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
 
-void nr_process_mac_pdu(
-    module_id_t module_idP,
-    rnti_t rnti,
-    uint8_t CC_id,
-    frame_t frameP,
-    uint8_t *pduP,
-    uint16_t mac_pdu_len);
+void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
+
+void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra);
 
 int binomial(int n, int k);
 
 bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot);
 
-void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id);
+void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id);
 
 
 /* \brief Function to indicate a received SDU on ULSCH.
@@ -397,5 +402,20 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
 
 void find_SSB_and_RO_available(module_id_t module_idP);
 
+void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp);
+void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ubwp);
+
 bool find_free_CCE(module_id_t module_id, sub_frame_t slot, int UE_id);
+
+bool nr_find_nb_rb(uint16_t Qm,
+                   uint16_t R,
+                   uint16_t nb_symb_sch,
+                   uint16_t nb_dmrs_prb,
+                   uint32_t bytes,
+                   uint16_t nb_rb_max,
+                   uint32_t *tbs,
+                   uint16_t *nb_rb);
+
+void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP);
+
 #endif /*__LAYER2_NR_MAC_PROTO_H__*/
diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c
index 8dc1303801a349378d3180dd23b6f3dfc45951f4..117c18ae8da3784749948cc18daed5f6a5ca028f 100644
--- a/openair2/LAYER2/NR_MAC_gNB/main.c
+++ b/openair2/LAYER2/NR_MAC_gNB/main.c
@@ -81,12 +81,14 @@ void mac_top_init_gNB(void)
         
       RC.nrmac[i]->ul_handle = 0;
 
+      RC.nrmac[i]->first_MIB = true;
+
       if (get_softmodem_params()->phy_test) {
         RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest;
         RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest;
       } else {
-        RC.nrmac[i]->pre_processor_dl = nr_simple_dlsch_preprocessor;
-        RC.nrmac[i]->pre_processor_ul = nr_simple_ulsch_preprocessor;
+        RC.nrmac[i]->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(i, 0);
+        RC.nrmac[i]->pre_processor_ul = nr_init_fr1_ulsch_preprocessor(i, 0);
       }
 
     }//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++)
@@ -96,12 +98,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)
+    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 63587d58a4f118935ff4f0e38477e25c8e46e3ec..bd88c39306ab09098c13e288e447c33c331fc856 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
@@ -246,8 +246,17 @@ typedef struct pdcchStateInd {
   uint8_t servingCellId;
   uint8_t coresetId;
   uint8_t tciStateId;
+  bool tci_present_inDCI;
 } pdcchStateInd_t;
 
+typedef struct pucchSpatialRelation {
+  bool is_scheduled;
+  uint8_t servingCellId;
+  uint8_t bwpId;
+  uint8_t pucchResourceId;
+  bool s0tos7_actDeact[8];
+} pucchSpatialRelation_t;
+
 typedef struct SPCSIReportingpucch {
   bool is_scheduled;
   uint8_t servingCellId;
@@ -271,12 +280,14 @@ typedef struct pdschTciStatesActDeact {
   uint8_t bwpId;
   uint8_t highestTciStateActivated;
   bool tciStateActDeact[MAX_TCI_STATES];
+  uint8_t codepoint[8];
 } pdschTciStatesActDeact_t;
 
 typedef struct UE_info {
   sp_zp_csirs_t sp_zp_csi_rs;
   csi_rs_im_t csi_im;
   pdcchStateInd_t pdcch_state_ind;
+  pucchSpatialRelation_t pucch_spatial_relation;
   SPCSIReportingpucch_t SP_CSI_reporting_pucch;
   aperiodicCSI_triggerStateSelection_t aperi_CSI_trigger;
   pdschTciStatesActDeact_t pdsch_TCI_States_ActDeact;
@@ -292,13 +303,14 @@ typedef struct NR_sched_pucch {
   uint8_t dai_c;
   uint8_t timing_indicator;
   uint8_t resource_indicator;
+  int r_pucch;
 } NR_sched_pucch_t;
 
-/* this struct is a helper: as long as the TDA and DCI format remain the same
- * over the same uBWP and search space, there is no need to recalculate all
- * S/L, MCS table, or DMRS-related parameters over and over again. Hence, we
- * store them in this struct for easy reference. */
-typedef struct NR_sched_pusch_save {
+/* PUSCH semi-static configuration: as long as the TDA and DCI format remain
+ * the same over the same uBWP and search space, there is no need to
+ * recalculate all S/L, MCS table, or DMRS-related parameters over and over
+ * again. Hence, we store them in this struct for easy reference. */
+typedef struct NR_pusch_semi_static_t {
   int dci_format;
   int time_domain_allocation;
   uint8_t num_dmrs_cdm_grps_no_data;
@@ -316,7 +328,7 @@ typedef struct NR_sched_pusch_save {
   uint16_t ul_dmrs_symb_pos;
   uint8_t num_dmrs_symb;
   uint8_t N_PRB_DMRS;
-} NR_sched_pusch_save_t;
+} NR_pusch_semi_static_t;
 
 typedef struct NR_sched_pusch {
   int frame;
@@ -326,9 +338,6 @@ typedef struct NR_sched_pusch {
   uint16_t rbSize;
   uint16_t rbStart;
 
-  // time-domain allocation for scheduled RBs
-  int time_domain_allocation;
-
   /// MCS
   uint8_t mcs;
 
@@ -339,26 +348,153 @@ typedef struct NR_sched_pusch {
 
   /// UL HARQ PID to use for this UE, or -1 for "any new"
   int8_t ul_harq_pid;
+
+  /// the Time Domain Allocation used for this transmission. Note that this is
+  /// only important for retransmissions; otherwise, the TDA in
+  /// NR_pusch_semi_static_t has precedence
+  int time_domain_allocation;
 } NR_sched_pusch_t;
 
+/* PDSCH semi-static configuratio: as long as the TDA/DMRS/mcsTable remains the
+ * same, there is no need to recalculate all S/L or DMRS-related parameters
+ * over and over again.  Hence, we store them in this struct for easy
+ * reference. */
+typedef struct NR_pdsch_semi_static {
+  int time_domain_allocation;
+  uint8_t numDmrsCdmGrpsNoData;
+
+  int startSymbolIndex;
+  int nrOfSymbols;
+
+  uint8_t mcsTableIdx;
+
+  uint8_t N_PRB_DMRS;
+  uint8_t N_DMRS_SLOT;
+  uint16_t dl_dmrs_symb_pos;
+  nfapi_nr_dmrs_type_e dmrsConfigType;
+} NR_pdsch_semi_static_t;
+
+typedef struct NR_sched_pdsch {
+  /// RB allocation within active BWP
+  uint16_t rbSize;
+  uint16_t rbStart;
+
+  /// MCS-related infos
+  uint8_t mcs;
+
+  /// TBS-related info
+  uint8_t nrOfLayers;
+  uint16_t R;
+  uint8_t Qm;
+  uint32_t tb_size;
+
+  /// DL HARQ PID to use for this UE, or -1 for "any new"
+  int8_t dl_harq_pid;
+
+  // pucch format allocation
+  uint8_t pucch_allocation;
+
+  /// the Time Domain Allocation used for this transmission. Note that this is
+  /// only important for retransmissions; otherwise, the TDA in
+  /// NR_pdsch_semi_static_t has precedence
+  int time_domain_allocation;
+} NR_sched_pdsch_t;
+
 typedef struct NR_UE_harq {
   bool is_waiting;
   uint8_t ndi;
   uint8_t round;
+  uint16_t feedback_frame;
   uint16_t feedback_slot;
 
-  /* Transport block to be sent using this HARQ process */
+  /* Transport block to be sent using this HARQ process, its size is in
+   * sched_pdsch */
   uint32_t tb[16384];
   uint32_t tb_size;
+
+  /// sched_pdsch keeps information on MCS etc used for the initial transmission
+  NR_sched_pdsch_t sched_pdsch;
 } NR_UE_harq_t;
 
-typedef struct NR_UE_old_sched {
-  uint16_t rbSize;
-  int time_domain_allocation;
-  uint8_t mcsTableIdx;
-  uint8_t mcs;
-  uint8_t numDmrsCdmGrpsNoData;
-} NR_UE_ret_info_t;
+//! fixme : need to enhace for the multiple TB CQI report
+
+
+//
+/*! As per spec 38.214 section 5.2.1.4.2
+ * - if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'disabled', the UE shall report in
+  a single report nrofReportedRS (higher layer configured) different CRI or SSBRI for each report setting.
+ * - if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'enabled', the UE shall report in a
+  single reporting instance two different CRI or SSBRI for each report setting, where CSI-RS and/or SSB
+  resources can be received simultaneously by the UE either with a single spatial domain receive filter, or with
+  multiple simultaneous spatial domain receive filter
+*/
+#define MAX_NR_OF_REPORTED_RS 4
+
+typedef enum NR_CSI_Report_Config {
+  CSI_Report_PR_cri_ri_li_pmi_cqi_report,
+  CSI_Report_PR_ssb_cri_report
+} NR_CSI_Report_Config_PR;
+struct CRI_RI_LI_PMI_CQI {
+  uint8_t cri;
+  uint8_t ri;
+  uint8_t li;
+  uint8_t pmi_x1;
+  uint8_t pmi_x2;
+  uint8_t wb_cqi_1tb;
+  uint8_t wb_cqi_2tb;
+};
+
+typedef struct CRI_SSB_RSRP {
+  uint8_t nr_ssbri_cri;
+  uint8_t CRI_SSBRI[MAX_NR_OF_REPORTED_RS];
+  uint8_t RSRP;
+  uint8_t diff_RSRP[MAX_NR_OF_REPORTED_RS - 1];
+} CRI_SSB_RSRP_t;
+
+struct CSI_Report {
+  NR_CSI_Report_Config_PR present;
+  union Config_CSI_Report {
+    struct CRI_RI_LI_PMI_CQI cri_ri_li_pmi_cqi_report;
+    struct CRI_SSB_RSRP ssb_cri_report;
+  } choice;
+};
+
+#define MAX_SR_BITLEN 8
+
+typedef struct {
+  uint8_t nb_ssbri_cri;
+  uint8_t cri_ssbri_bitlen;
+  uint8_t rsrp_bitlen;
+  uint8_t diff_rsrp_bitlen;
+}L1_RSRP_bitlen_t;
+
+typedef struct{
+  uint8_t cri_bitlen;
+  uint8_t ri_bitlen;
+  uint8_t li_bitlen;
+  uint8_t pmi_x1_bitlen;
+  uint8_t pmi_x2_bitlen;
+  uint8_t cqi_bitlen;
+} CSI_Meas_bitlen_t;
+
+typedef struct nr_csi_report {
+  NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
+  long periodicity;
+  uint16_t offset;
+  long ** SSB_Index_list;
+  long ** CSI_Index_list;
+//  uint8_t nb_of_nzp_csi_report;
+  uint8_t nb_of_csi_ssb_report;
+  L1_RSRP_bitlen_t CSI_report_bitlen;
+  CSI_Meas_bitlen_t csi_meas_bitlen;
+} nr_csi_report_t;
+
+/*! As per the spec 38.212 and table:  6.3.1.1.2-12 in a single UCI sequence we can have multiple CSI_report 
+  the number of CSI_report will depend on number of CSI resource sets that are configured in CSI-ResourceConfig RRC IE
+  From spec 38.331 from the IE CSI-ResourceConfig for SSB RSRP reporting we can configure only one resource set 
+  From spec 38.214 section 5.2.1.2 For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1
+ */
+#define MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG 16
 
 typedef enum {
   INACTIVE = 0,
@@ -376,80 +512,71 @@ typedef struct NR_UE_ul_harq {
   NR_sched_pusch_t sched_pusch;
 } NR_UE_ul_harq_t;
 
-
-typedef struct {
-  uint8_t nb_ssbri_cri;
-  uint8_t cri_ssbri_bitlen;
-  uint8_t rsrp_bitlen;
-  uint8_t diff_rsrp_bitlen;
-}CRI_SSBRI_RSRP_bitlen_t;
-
-
-#define MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG 16
-typedef struct nr_csi_report {
-  NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
-  NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR CSI_Resource_type;
-  uint8_t nb_of_nzp_csi_report;
-  uint8_t nb_of_csi_ssb_report;
-  CRI_SSBRI_RSRP_bitlen_t CSI_report_bitlen[MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG];
-} nr_csi_report_t;
-
-
 /*! \brief scheduling control information set through an API */
+#define MAX_CSI_REPORTS 48
 typedef struct {
-  /// total amount of data awaiting for this UE
-  uint32_t num_total_bytes;
-  /// per-LC status data
-  mac_rlc_status_resp_t rlc_status[MAX_NUM_LCID];
-
   /// the currently active BWP in DL
   NR_BWP_Downlink_t *active_bwp;
   /// the currently active BWP in UL
   NR_BWP_Uplink_t *active_ubwp;
-
-  /// PUCCH scheduling information. Array of three, we assume for the moment:
-  /// HARQ in the first field, SR in second, CSI in third (as fixed by RRC
-  /// conf., i.e. if actually present).  The order is important for
-  /// nr_acknack_scheduling()!
-  NR_sched_pucch_t sched_pucch[3];
-
-  NR_sched_pusch_save_t pusch_save;
-  NR_sched_pusch_t sched_pusch;
-
   /// CCE index and aggregation, should be coherent with cce_list
   NR_SearchSpace_t *search_space;
   NR_ControlResourceSet_t *coreset;
+
+  /// CCE index and Aggr. Level are shared for PUSCH/PDSCH allocation decisions
+  /// corresponding to the sched_pusch/sched_pdsch structures below
   int cce_index;
   uint8_t aggregation_level;
 
-  /// RB allocation within active BWP
-  uint16_t rbSize;
-  uint16_t rbStart;
+  /// PUCCH scheduling information. Array of two: HARQ+SR in the first field,
+  /// CSI in second.  This order is important for nr_acknack_scheduling()!
+  NR_sched_pucch_t sched_pucch[2];
+
+  /// PUSCH semi-static configuration: is not cleared across TTIs
+  NR_pusch_semi_static_t pusch_semi_static;
+  /// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI
+  NR_sched_pusch_t sched_pusch;
 
   /// uplink bytes that are currently scheduled
   int sched_ul_bytes;
   /// estimation of the UL buffer size
   int estimated_ul_buffer;
 
-  // time-domain allocation for scheduled RBs
-  int time_domain_allocation;
+  /// PHR info: power headroom level (dB)
+  int ph;
+  /// PHR info: nominal UE transmit power levels (dBm)
+  int pcmax;
 
-  /// MCS-related infos
-  uint8_t mcsTableIdx;
-  uint8_t mcs;
-  uint8_t numDmrsCdmGrpsNoData;
+  /// PDSCH semi-static configuration: is not cleared across TTIs
+  NR_pdsch_semi_static_t pdsch_semi_static;
+  /// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI
+  NR_sched_pdsch_t sched_pdsch;
+  /// For UL synchronization: store last UL scheduling grant
+  frame_t last_ul_frame;
+  sub_frame_t last_ul_slot;
 
-  /// Retransmission-related information
-  NR_UE_ret_info_t retInfo[NR_MAX_NB_HARQ_PROCESSES];
-  /// DL HARQ PID to use for this UE, or -1 for "any new"
-  int8_t dl_harq_pid;
+  /// total amount of data awaiting for this UE
+  uint32_t num_total_bytes;
+  /// 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;
   uint8_t tpc0;
   uint8_t tpc1;
+  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;
+
   /// information about every HARQ process
   NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
   /// HARQ processes that are free
@@ -466,7 +593,6 @@ typedef struct {
   NR_list_t feedback_ul_harq;
   /// UL HARQ processes that await retransmission
   NR_list_t retrans_ul_harq;
-  int dummy;
   NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information
 } NR_UE_sched_ctrl_t;
 
@@ -484,9 +610,12 @@ 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;
+  int cumul_rsrp;
+  uint8_t num_rsrp_meas;
 } NR_mac_stats_t;
 
 
@@ -502,13 +631,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,
@@ -516,9 +646,7 @@ typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
                               sub_frame_t slot);
 typedef bool (*nr_pp_impl_ul)(module_id_t mod_id,
                               frame_t frame,
-                              sub_frame_t slot,
-                              int num_slots_per_tdd,
-                              uint64_t ulsch_in_slot_bitmap);
+                              sub_frame_t slot);
 
 /*! \brief top level eNB MAC structure */
 typedef struct gNB_MAC_INST_s {
@@ -536,6 +664,12 @@ 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
   NR_COMMON_channels_t common_channels[NFAPI_CC_MAX];
   /// current PDU index (BCH,DLSCH)
@@ -589,10 +723,23 @@ typedef struct gNB_MAC_INST_s {
   time_stats_t schedule_pch;
   /// CCE lists
   int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE];
-  /// PUCCH: keep track of the resources has already been used by saving the
-  /// highest index not yet been used in a given slot. Dynamically allocated
-  /// so we can have it for every slot as a function of the numerology
-  int *pucch_index_used[MAX_NUM_BWP];
+  /// list of allocated beams per period
+  int16_t *tdd_beam_association;
+
+  /// bitmap of DLSCH slots, can hold up to 160 slots
+  uint64_t dlsch_slot_bitmap[3];
+  /// Lookup for preferred time domain allocation for BWP, in DL, slots
+  /// dynamically allocated
+  int *preferred_dl_tda[MAX_NUM_BWP];
+  /// bitmap of ULSCH slots, can hold up to 160 slots
+  uint64_t ulsch_slot_bitmap[3];
+  /// Lookup for preferred time domain allocation for UL BWP, dynamically
+  /// allocated. The index refers to the DL slot, and the indicated TDA's k2
+  /// points to the right UL slot
+  int *preferred_ul_tda[MAX_NUM_BWP];
+
+  /// maximum number of slots before a UE will be scheduled ULSCH automatically
+  uint32_t ulsch_max_slots_inactivity;
 
   /// DL preprocessor for differentiated scheduling
   nr_pp_impl_dl pre_processor_dl;
@@ -600,9 +747,9 @@ 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;
+  NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64];
 
+  bool first_MIB;
 } gNB_MAC_INST;
 
 #endif /*__LAYER2_NR_MAC_GNB_H__ */
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index ee2711c6efe82f3415e817594640e8a7ea87bb15..cddb666bfdbd346cf2dc7ae4cd7837bc50d850bf 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -57,10 +57,11 @@
 #include "openair2/RRC/NAS/nas_config.h"
 #include "intertask_interface.h"
 #include "openair3/S1AP/s1ap_eNB.h"
-
+#include <pthread.h>
 
 #  include "gtpv1u_eNB_task.h"
 #  include "gtpv1u.h"
+#include <openair3/ocp-gtpu/gtp_itf.h>
 
 #include "ENB_APP/enb_config.h"
 
@@ -83,9 +84,94 @@ hash_table_t  *pdcp_coll_p = NULL;
   static int mbms_socket = -1;
 #endif
 
-
+uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+
+uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+int pdcp_pc5_sockfd;
+struct sockaddr_in prose_ctrl_addr;
+struct sockaddr_in prose_pdcp_addr;
+struct sockaddr_in pdcp_sin;
 /* pdcp module parameters and related functions*/
 static pdcp_params_t pdcp_params= {0,NULL};
+rnti_t                 pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB];
+rnti_t                 pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB]; // for noS1 mode
+unsigned int           pdcp_eNB_UE_instance_to_rnti_index;
+
+signed int             pdcp_2_nas_irq;
+pdcp_stats_t              UE_pdcp_stats[MAX_MOBILES_PER_ENB];
+pdcp_stats_t              eNB_pdcp_stats[NUMBER_OF_eNB_MAX];
+
+static pdcp_mbms_t               pdcp_mbms_array_ue[MAX_MOBILES_PER_ENB][LTE_maxServiceCount][LTE_maxSessionPerPMCH];   // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
+static pdcp_mbms_t               pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
+static sdu_size_t             pdcp_input_sdu_remaining_size_to_read;
+static sdu_size_t             pdcp_output_header_bytes_to_write;
+static sdu_size_t             pdcp_output_sdu_bytes_to_write;
+notifiedFIFO_t         pdcp_sdu_list;
+
+pdcp_enb_t pdcp_enb[MAX_NUM_CCs];
+
+
+extern volatile int oai_exit;
+
+pthread_t pdcp_stats_thread_desc;
+
+void *pdcp_stats_thread(void *param) {
+
+   FILE *fd;
+   int old_byte_cnt[MAX_MOBILES_PER_ENB][NB_RB_MAX],old_byte_cnt_rx[MAX_MOBILES_PER_ENB][NB_RB_MAX];
+   for (int i=0;i<MAX_MOBILES_PER_ENB;i++)
+     for (int j=0;j<NB_RB_MAX;j++) {
+	old_byte_cnt[i][j]=0;
+	old_byte_cnt_rx[i][j]=0;
+     }
+   while (!oai_exit) {
+     sleep(1);
+
+     fd=fopen("PDCP_stats.log","w+");
+     AssertFatal(fd!=NULL,"Cannot open MAC_stats.log\n");
+     int drb_id=3;
+     for (int UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
+        if (pdcp_enb[0].rnti[UE_id]>0) {
+           fprintf(fd,"PDCP: CRNTI %x, DRB %d: tx_bytes %d, DL Throughput %e\n",
+                   pdcp_enb[0].rnti[UE_id],drb_id,
+                   Pdcp_stats_tx_bytes[0][UE_id][drb_id],
+                   (double)((Pdcp_stats_tx_bytes[0][UE_id][drb_id]-old_byte_cnt[UE_id][drb_id])<<3));
+           fprintf(fd,"                              rx_bytes %d, UL Throughput %e\n",             
+                   Pdcp_stats_rx_bytes[0][UE_id][drb_id],
+                   (double)((Pdcp_stats_rx_bytes[0][UE_id][drb_id]-old_byte_cnt_rx[UE_id][drb_id])<<3));
+           old_byte_cnt[UE_id][drb_id]=Pdcp_stats_tx_bytes[0][UE_id][drb_id];
+           old_byte_cnt_rx[UE_id][drb_id]=Pdcp_stats_rx_bytes[0][UE_id][drb_id];
+        }
+     }
+     fclose(fd);
+   }
+   return(NULL);
+}
 
 uint64_t get_pdcp_optmask(void) {
   return pdcp_params.optmask;
@@ -467,7 +553,7 @@ boolean_t pdcp_data_req(
       break;
   }
 
-  //LOG_I(PDCP,"ueid %d lcid %d tx seq num %d\n", pdcp_uid, rb_idP+rb_offset, current_sn);
+  LOG_D(PDCP,"ueid %d lcid %d tx seq num %d\n", pdcp_uid, (int)(rb_idP+rb_offset), current_sn);
   Pdcp_stats_tx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++;
   Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++;
   Pdcp_stats_tx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP;
@@ -937,7 +1023,7 @@ pdcp_data_ind(
       GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset       = GTPU_HEADER_OVERHEAD_MAX;
       GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti         = ctxt_pP->rnti;
       GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id       = rb_id + 4;
-      itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
+      itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p);
       packet_forwarded = TRUE;
     }
   } else {
@@ -995,7 +1081,13 @@ pdcp_data_ind(
               pdcpHead->inst  = 1;
             }
           } // nfapi_mode
-        }
+        } else {
+	  if (UE_NAS_USE_TUN) {
+	    pdcpHead->inst  = ctxt_pP->module_id;
+	  } else if (ENB_NAS_USE_TUN) {
+	    pdcpHead->inst  = 0;
+	  }
+	}
       } else {
         pdcpHead->rb_id = rb_id + (ctxt_pP->module_id * LTE_maxDRB);
         pdcpHead->inst  = ctxt_pP->module_id;
@@ -2296,6 +2388,8 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
              LOG_E(PDCP, "ENB pdcp will not use tun interface\n");
    }
 
+  pthread_create(&pdcp_stats_thread_desc,NULL,pdcp_stats_thread,NULL);
+
   return pdcp_params.optmask ;
 }
 
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
index c8ab4499eeddc9f07fb6d0d9e8506346d9a9e3e4..0c3dd2f04fed4798988e4cab59ef53d2cc29b8d4 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
@@ -91,34 +91,34 @@ extern int             pdcp_instance_cnt;
 int init_pdcp_thread(void);
 void cleanup_pdcp_thread(void);
 
-uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
-uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-
-uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
-uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+extern uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+
+extern uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+extern uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
 
 void pdcp_update_perioidical_stats(const protocol_ctxt_t *const  ctxt_pP);
 
@@ -138,7 +138,7 @@ typedef struct pdcp_enb_s {
 
 } pdcp_enb_t;
 
-pdcp_enb_t pdcp_enb[MAX_NUM_CCs];
+extern pdcp_enb_t pdcp_enb[MAX_NUM_CCs];
 
 typedef struct pdcp_stats_s {
   time_stats_t pdcp_run;
@@ -242,17 +242,18 @@ typedef struct pdcp_mbms_s {
 * \note None
 * @ingroup _pdcp
 */
+
 boolean_t pdcp_data_req(
   protocol_ctxt_t  *ctxt_pP,
   const srb_flag_t srb_flagP,
   const rb_id_t rb_id,
   const mui_t muiP,
-  const confirm_t confirmP, \
+  const confirm_t confirmP,
   const sdu_size_t sdu_buffer_size,
   unsigned char *const sdu_buffer,
   const pdcp_transmission_mode_t mode,
-  const uint32_t *const sourceL2Id,
-  const uint32_t *const destinationL2Id
+  const uint32_t * sourceL2Id,
+  const uint32_t * destinationL2Id
 );
 
 /*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t)
@@ -455,10 +456,10 @@ struct pdcp_netlink_element_s {
 //TTN for D2D (PC5S)
 #define PDCP_SOCKET_PORT_NO 9999 //temporary value
 #define PC5_SIGNALLING_PAYLOAD_SIZE   100  //should be updated with a correct value
-int pdcp_pc5_sockfd;
-struct sockaddr_in prose_ctrl_addr;
-struct sockaddr_in prose_pdcp_addr;
-struct sockaddr_in pdcp_sin;
+extern int pdcp_pc5_sockfd;
+extern struct sockaddr_in prose_ctrl_addr;
+extern struct sockaddr_in prose_pdcp_addr;
+extern struct sockaddr_in pdcp_sin;
 void pdcp_pc5_socket_init(void);
 
 typedef struct  {
@@ -500,28 +501,18 @@ typedef struct {
 #define REORDERING_WINDOW_SN_7BIT 64
 #define REORDERING_WINDOW_SN_12BIT 2048
 
-signed int             pdcp_2_nas_irq;
-pdcp_stats_t              UE_pdcp_stats[MAX_MOBILES_PER_ENB];
-pdcp_stats_t              eNB_pdcp_stats[NUMBER_OF_eNB_MAX];
+extern signed int             pdcp_2_nas_irq;
+extern pdcp_stats_t              UE_pdcp_stats[MAX_MOBILES_PER_ENB];
+extern pdcp_stats_t              eNB_pdcp_stats[NUMBER_OF_eNB_MAX];
 
 
 // for UE code conly
-rnti_t                 pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB];
-rnti_t                 pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB]; // for noS1 mode
-unsigned int           pdcp_eNB_UE_instance_to_rnti_index;
-
-pdcp_mbms_t               pdcp_mbms_array_ue[MAX_MOBILES_PER_ENB][LTE_maxServiceCount][LTE_maxSessionPerPMCH];   // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
-pdcp_mbms_t               pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
-
-sdu_size_t             pdcp_output_sdu_bytes_to_write;
-sdu_size_t             pdcp_output_header_bytes_to_write;
-notifiedFIFO_t         pdcp_sdu_list;
-int                    pdcp_sent_a_sdu;
-pdcp_data_req_header_t pdcp_input_header;
-unsigned char          pdcp_input_sdu_buffer[MAX_IP_PACKET_SIZE];
-sdu_size_t             pdcp_input_index_header;
-sdu_size_t             pdcp_input_sdu_size_read;
-sdu_size_t             pdcp_input_sdu_remaining_size_to_read;
+extern rnti_t                 pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB];
+extern rnti_t                 pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB]; // for noS1 mode
+extern unsigned int           pdcp_eNB_UE_instance_to_rnti_index;
+
+
+extern notifiedFIFO_t         pdcp_sdu_list;
 
 #define PDCP_COLL_KEY_VALUE(mODULE_iD, rNTI, iS_eNB, rB_iD, iS_sRB) \
   ((hash_key_t)mODULE_iD          | \
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_control_primitive.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_control_primitive.c
index 0ef6893d084a4c366fba14276dd5655fd46d40c6..c2736ddd840869392fd20bc236648594485cbc0f 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_control_primitive.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_control_primitive.c
@@ -32,7 +32,6 @@
 #include "rtos_header.h"
 #include "platform.h"
 #include "protocol_vars_extern.h"
-#include "print.h"
 //-----------------------------------------------------------------------------
 #include "rlc.h"
 #include "pdcp.h"
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index 687d7b1bfefaf905f75e31dfd8f8c8f4ff4f0ad4..cc44572abddc2b5a5802822b4dbd987f4384ee95 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -43,6 +43,7 @@ extern int otg_enabled;
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <netinet/ip.h>
 #define rtf_put write
 #define rtf_get read
 
@@ -78,9 +79,6 @@ extern int nas_sock_fd[MAX_MOBILES_PER_ENB];
 
 extern int nas_sock_mbms_fd;
 
-extern int mbms_rab_id;
-
-
 extern struct msghdr nas_msg_tx;
 extern struct msghdr nas_msg_rx;
 
@@ -113,8 +111,6 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const  ctxt_pP) {
      * PDCP packet to pick the right socket below */
 
     int rb_id = pdcpHead->rb_id;
-    int sizeToWrite= sizeof (pdcp_data_ind_header_t) +
-      pdcpHead->data_size;
     void * pdcpData=(void*)(pdcpHead+1);
     if (rb_id == 10) { //hardcoded for PC5-Signaling
       if( LOG_DEBUGFLAG(DEBUG_PDCP) ) {
@@ -128,24 +124,25 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const  ctxt_pP) {
     } else if (UE_NAS_USE_TUN) {
       //ret = write(nas_sock_fd[pdcpHead->inst], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
        if(rb_id == mbms_rab_id){
-       ret = write(nas_sock_mbms_fd, pdcpData,sizeToWrite );
+       ret = write(nas_sock_mbms_fd, pdcpData, pdcpHead->data_size );
        LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH MBMS DATA TO rb_id %d handle %d sizeToWrite %d\n",
-	     ret,rb_id,nas_sock_fd[pdcpHead->inst],sizeToWrite);
+	     ret,rb_id,nas_sock_fd[pdcpHead->inst],pdcpHead->data_size);
         }
        else
        {
 	 if( LOG_DEBUGFLAG(DEBUG_PDCP) ) 
-	   log_dump(PDCP, pdcpData, sizeToWrite, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
-	 ret = write(nas_sock_fd[pdcpHead->inst], pdcpData,sizeToWrite );
+	   log_dump(PDCP, pdcpData, pdcpHead->data_size, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
+	 ret = write(nas_sock_fd[pdcpHead->inst], pdcpData,pdcpHead->data_size );
 	 LOG_T(PDCP,"[UE PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",
-	       ret,rb_id,nas_sock_fd[pdcpHead->inst],sizeToWrite);
+	       ret,rb_id,nas_sock_fd[pdcpHead->inst],pdcpHead->data_size);
        }
     } else if (ENB_NAS_USE_TUN) {
       if( LOG_DEBUGFLAG(DEBUG_PDCP) ) 
-	log_dump(PDCP, pdcpData, sizeToWrite, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
-      ret = write(nas_sock_fd[0], pdcpData, sizeToWrite);
-       LOG_T(PDCP,"[NB PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[0],sizeToWrite);
+	log_dump(PDCP, pdcpData, pdcpHead->data_size, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
+      ret = write(nas_sock_fd[0], pdcpData, pdcpHead->data_size);
+       LOG_T(PDCP,"[NB PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[0],pdcpHead->data_size);
     } else if (PDCP_USE_NETLINK) {
+      int sizeToWrite= sizeof (pdcp_data_ind_header_t) + pdcpHead->data_size;
       memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) pdcpHead,  sizeToWrite);
       nas_nlh_tx->nlmsg_len = sizeToWrite;
       ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0);
@@ -154,7 +151,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const  ctxt_pP) {
     AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]);
 
     if( LOG_DEBUGFLAG(DEBUG_PDCP) )
-      log_dump(PDCP, pdcpData, min(sizeToWrite,30) , LOG_DUMP_CHAR,
+      log_dump(PDCP, pdcpData, min(pdcpHead->data_size,30) , LOG_DUMP_CHAR,
 	       "Printing first bytes of PDCP SDU before removing it from the list: \n");
     delNotifiedFIFO_elt (sdu_p);
     pdcp_nb_sdu_sent ++;
@@ -226,7 +223,11 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const  ctxt_pP) {
       key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
       h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
     } else { // => ENB_NAS_USE_TUN
-      ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[0];
+      /* Get the IP from a packet */
+      struct ip *ip_pack = (struct ip *) nl_rx_buf;
+      /* Use last octet of destination IP to get index of UE */
+      int ue_indx = ((ip_pack->ip_dst.s_addr >> 24) -  2) % MAX_MOBILES_PER_ENB;
+      ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[ue_indx];
       ctxt.enb_flag=ENB_FLAG_YES;
       ctxt.module_id=0;
       key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
@@ -377,7 +378,6 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const  ctx
     protocol_ctxt_t                ctxt;
     hash_key_t                     key       = HASHTABLE_NOT_A_KEY_VALUE;
     hashtable_rc_t                 h_rc;
-    module_id_t                    ue_id     = 0;
     pdcp_t                        *pdcp_p    = NULL;
     static unsigned char pdcp_read_state_g =0;
     rb_id_t          rab_id  = 0;
@@ -471,30 +471,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const  ctx
             } else  { // rb_id =0, thus interpreated as broadcast and transported as multiple unicast
               // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs
               //#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES
-              for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) {
-                if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) {
-                  ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id];
-                  LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n",
-                        ctxt.frame,
-                        pdcp_read_header_g.inst,
-                        pdcp_read_header_g.rb_id,
-                        pdcp_read_header_g.data_size,
-                        ctxt.module_id,
-                        ctxt.rnti,
-                        DEFAULT_RAB_ID);
-                  pdcp_data_req (
-                    &ctxt,
-                    SRB_FLAG_NO,
-                    DEFAULT_RAB_ID,
-                    RLC_MUI_UNDEFINED,
-                    RLC_SDU_CONFIRM_NO,
-                    pdcp_read_header_g.data_size,
-                    (unsigned char *)NLMSG_DATA(nas_nlh_rx),
-                    PDCP_TRANSMISSION_MODE_DATA
-                    ,NULL, NULL
-                  );
-                }
-              }
+              // never finished code, dropped
             }
           } else { // ctxt.enb_flag => UE
             if (NFAPI_MODE == NFAPI_UE_STUB_PNF) {
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 bf6579955ba7985ef2b8daf88cec310b5fd47c95..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
@@ -319,13 +318,15 @@ error:
 }
 
 int proto_agent_get_ack_result(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) {
+/* code useless in this status: return 0 anyways
   rlc_op_status_t result = 0;
-  //printf("PROTO_AGENT: handling the data_req_ack message\n");
+  printf("PROTO_AGENT: handling the data_req_ack message\n");
   Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
   Protocol__FspRlcDataReqAck *data_ack = input->data_req_ack;
   result = data_ack->result;
-  //printf("PROTO_AGENT: ACK RESULT IS %u\n", result);
+  printf("PROTO_AGENT: ACK RESULT IS %u\n", result);
   ack_result = result;
+*/
   return 0;
 }
 
@@ -362,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) {
@@ -500,6 +496,13 @@ error:
   return -1;
 }
 
+boolean_t pdcp_data_ind(
+  const protocol_ctxt_t *const  ctxt_pP,
+  const srb_flag_t srb_flagP,
+  const MBMS_flag_t MBMS_flagP,
+  const rb_id_t rb_id,
+  const sdu_size_t sdu_buffer_size,
+  mem_block_t *const sdu_buffer);
 
 int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) {
   boolean_t result = 0;
@@ -522,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/PROTO_AGENT/proto_agent_common.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h
index c805b8154339cb654521969847708f0654424086..8f553e05e1db1401358c4fa0dc9dc5d5624b8d42 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h
@@ -62,7 +62,6 @@ typedef int (*proto_agent_message_destruction_callback)(
 );
 
 
-uint32_t ack_result;
 
 /**********************************
  * progRAN protocol messages helper 
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
index 9a63427ed5887111ba21b9863da5e738763ad239..925c11c8f81907b4869f681f7d3ffe93fdbed9dc 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
@@ -30,7 +30,7 @@
 #include "common/utils/LOG/log.h"
 
 proto_agent_channel_t *proto_channel[NUMBER_OF_eNB_MAX][ENB_AGENT_MAX];
-proto_agent_channel_instance_t channel_instance;
+static proto_agent_channel_instance_t channel_instance;
 int proto_agent_channel_id = 0;
 
 int proto_agent_register_channel(mod_id_t mod_id, proto_agent_channel_t *channel, proto_agent_id_t agent_id) {
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c
index fda84879be06681705e62bbd15b1b7fe3f769284..cf77f9ec37f6992fa829a35ce2f5f5d035c362d1 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c
@@ -80,6 +80,8 @@ static int  g_send_id_read_index[2];
 static struct mac_data_ind g_tx_delayed_indications[MAX_TIME_DELAYED_PDU_DUE_TO_HARQ];
 static struct mac_data_ind g_rx_delayed_indications[MAX_TIME_DELAYED_PDU_DUE_TO_HARQ];
 
+static rlc_um_entity_t       um_tx;
+static rlc_um_entity_t       um_rx;
 
 static int8_t *g_sdus[] = {"En dépit de son volontarisme affiché, le premier ministre est de plus en plus décrié pour son incompétence. La tension politique et dans l'opinion publique est encore montée d'un cran au Japon, sur fond d'inquiétantes nouvelles, avec du plutonium détecté dans le sol autour de la centrale de Fukushima. Le premier ministre Naoto Kan a solennellement déclaré que son gouvernement était «en état d'alerte maximum». Tout en reconnaissant que la situation restait «imprévisible». Ce volontarisme affiché par le premier ministre - que Nicolas Sarkozy rencontrera demain lors d'une visite au Japon - ne l'a pas empêché d'être la cible de violentes critiques de la part de parlementaires sur sa gestion de la crise. Attaqué sur le manque de transparence, il a assuré qu'il rendait publiques toutes les informations en sa possession. Un député de l'opposition, Yosuke Isozaki, a aussi reproché à Naoto Kan de ne pas avoir ordonné l'évacuation des populations dans la zone comprise entre 20 et 30 km autour de la centrale. «Peut-il y avoir quelque chose de plus irresponsable que cela ?», a-t-il lancé. Pour l'heure, la zone d'évacuation est limitée à un rayon de 20 km, seul le confinement étant recommandé pour les 10 km suivants. Sur ce sujet, les autorités japonaises ont été fragilisées mardi par les déclarations de Greenpeace, affirmant que ses experts avaient détecté une radioactivité dangereuse à 40 km de la centrale. L'organisation écologiste a appelé à une extension de la zone d'évacuation, exhortant Tokyo à «cesser de privilégier la politique aux dépens de la science». L'Agence japonaise de sûreté nucléaire a balayé ces critiques.",
 
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h
index 6da464aa28ef0894808a884c628231a5020cfecf..bfde1b31f35f286ae8d928011363468a059ffa0e 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h
@@ -21,8 +21,6 @@
 
 #    ifndef __RLC_UM_TEST_H__
 #        define __RLC_UM_TEST_H__
-rlc_um_entity_t       um_tx;
-rlc_um_entity_t       um_rx;
 
 void rlc_um_v9_3_0_test_windows_5(void);
 void rlc_um_v9_3_0_test_windows_10(void);
diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c
index 98c8c3e252da05ebe81b4f237b2078f07ffe39d7..b9dcf0414b99024195fe1a6bdc26f4ba7e10ef06 100644
--- a/openair2/LAYER2/RLC/rlc.c
+++ b/openair2/LAYER2/RLC/rlc.c
@@ -36,6 +36,7 @@
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "targets/COMMON/openairinterface5g_limits.h"
 #include "assertions.h"
+#include <rlc.h>
 
 #include "common/ran_context.h"
 extern RAN_CONTEXT_t RC;
@@ -51,7 +52,27 @@ extern boolean_t pdcp_data_ind(
 #define DEBUG_RLC_PDCP_INTERFACE 1
 //#define TRACE_RLC_PAYLOAD 1
 #define DEBUG_RLC_DATA_REQ 1
+void (*rlc_rrc_data_conf)(
+  const protocol_ctxt_t *const ctxtP,
+  const rb_id_t         rb_idP,
+  const mui_t           muiP,
+  const rlc_tx_status_t statusP) __attribute__ ((aligned(32)));
+
+void (*rlc_rrc_data_ind)(
+  const protocol_ctxt_t *const ctxtP,
+  const rb_id_t     rb_idP,
+  const sdu_size_t  sdu_sizeP,
+  const uint8_t    *const sduP)  __attribute__ ((aligned(32)));
+
+logical_chan_id_t    rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX];              /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
+logical_chan_id_t    rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX];              /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
+rlc_mbms_id_t        rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC];    // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
+rlc_mbms_id_t        rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC];  // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
+hash_table_t  *rlc_coll_p  __attribute__ ((aligned(32)));
+
 
+logical_chan_id_t    rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX];              /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
+logical_chan_id_t    rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX];              /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
 //-----------------------------------------------------------------------------
 void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP)
 //-----------------------------------------------------------------------------
diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h
index 7e4920a579c1b76a8971f96bca1283f876fecd27..1e5b7947d7a384f209776fce7a9af2136e3eda04 100644
--- a/openair2/LAYER2/RLC/rlc.h
+++ b/openair2/LAYER2/RLC/rlc.h
@@ -133,13 +133,13 @@ typedef struct {
 #define  RLC_MAX_MBMS_LC (LTE_maxSessionPerPMCH * LTE_maxServiceCount)
 #define  RLC_MAX_LC  ((max_val_LTE_DRB_Identity+1)* MAX_MOBILES_PER_ENB)
 
-void (*rlc_rrc_data_ind)(
+extern void (*rlc_rrc_data_ind)(
   const protocol_ctxt_t *const ctxtP,
   const rb_id_t     rb_idP,
   const sdu_size_t  sdu_sizeP,
   const uint8_t    *const sduP)  __attribute__ ((aligned(32)));
 
-void (*rlc_rrc_data_conf)(
+extern void (*rlc_rrc_data_conf)(
   const protocol_ctxt_t *const ctxtP,
   const rb_id_t         rb_idP,
   const mui_t           muiP,
@@ -184,8 +184,8 @@ typedef struct rlc_mbms_id_s {
 
 //rlc_mbms_t           rlc_mbms_array_ue[MAX_MOBILES_PER_ENB][maxServiceCount][maxSessionPerPMCH];   // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
 //rlc_mbms_t           rlc_mbms_array_eNB[NUMBER_OF_eNB_MAX][maxServiceCount][maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
-rlc_mbms_id_t        rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC];    // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
-rlc_mbms_id_t        rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC];  // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
+extern rlc_mbms_id_t        rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC];    // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
+extern rlc_mbms_id_t        rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC];  // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
 
 #define rlc_mbms_enb_get_lcid_by_rb_id(Enb_mOD,rB_iD) rlc_mbms_rbid2lcid_eNB[Enb_mOD][rB_iD]
 ;
@@ -201,8 +201,8 @@ rlc_mbms_id_t        rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_
     rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] = lOG_cH_iD; \
   } while (0);
 
-logical_chan_id_t    rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX];              /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
-logical_chan_id_t    rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX];              /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
+extern logical_chan_id_t    rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX];              /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
+extern logical_chan_id_t    rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX];              /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
 
 
 #define RLC_COLL_KEY_VALUE(eNB_iD, rNTI, iS_eNB, rB_iD, iS_sRB) \
@@ -250,7 +250,7 @@ logical_chan_id_t    rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX];
    (((hash_key_t)(sESSION_ID)) << 37) | \
    (((hash_key_t)(0x0000000000000001))  << 63))
 
-hash_table_t  *rlc_coll_p  __attribute__ ((aligned(32)));
+extern hash_table_t  *rlc_coll_p  __attribute__ ((aligned(32)));
 
 /*! \fn tbs_size_t mac_rlc_serialize_tb (char* bufferP, list_t transport_blocksP)
 * \brief  Serialize a list of transport blocks coming from RLC in order to be processed by MAC.
@@ -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/UTIL/TRACE/fifo_printf.h b/openair2/LAYER2/nr_pdcp/nr_pdcp.h
similarity index 63%
rename from openair2/UTIL/TRACE/fifo_printf.h
rename to openair2/LAYER2/nr_pdcp/nr_pdcp.h
index ce2702b19a9c74fc59d5c031a64b891137781c19..94939a0421751edd723bc3ae12f89e03c0880b99 100644
--- a/openair2/UTIL/TRACE/fifo_printf.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp.h
@@ -19,19 +19,12 @@
  *      contact@openairinterface.org
  */
 
-/***************************************************************************
-                          fifo_printf.h  -  description
-                             -------------------
-  AUTHOR  : Lionel GAUTHIER
-  COMPANY : EURECOM
-  EMAIL   : Lionel.Gauthier@eurecom.fr
+#include <stdint.h>
 
+#ifndef _NR_PDCP_H_
+#define _NR_PDCP_H_
 
- ***************************************************************************/
-#ifndef __FIFO_PRINTF_H__
-#    define __FIFO_PRINTF_H__
-#    define FIFO_PRINTF_MAX_STRING_SIZE   500
-#    define FIFO_PRINTF_L1_NO              63
-#    define FIFO_PRINTF_L2_NO              62
-#    define FIFO_PRINTF_SIZE            65536
-#endif
+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 ffc669a46169740fdaf7cab79921a4864165f9e7..0b5d0ad4866f8a89b190ea0cca5f424aa9fc9fe3 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
@@ -21,25 +21,323 @@
 
 #include "nr_pdcp_entity.h"
 
-#include "nr_pdcp_entity_drb_am.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
 #include "nr_pdcp_security_nea2.h"
+#include "nr_pdcp_integrity_nia2.h"
+#include "nr_pdcp_sdu.h"
 
 #include "LOG/log.h"
 
-nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
-    int is_gnb, int rb_id,
-    void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
-                        char *buf, int size),
-    void *deliver_sdu_data,
-    void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
-                        char *buf, int size, int sdu_id),
-    void *deliver_pdu_data)
+static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
+                                    char *_buffer, int size)
 {
-  abort();
+  unsigned char    *buffer = (unsigned char *)_buffer;
+  nr_pdcp_sdu_t    *sdu;
+  int              rcvd_sn;
+  uint32_t         rcvd_hfn;
+  uint32_t         rcvd_count;
+  int              header_size;
+  int              integrity_size;
+  int              rx_deliv_sn;
+  uint32_t         rx_deliv_hfn;
+
+  if (size < 1) {
+    LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
+    return;
+  }
+
+  if (entity->type != NR_PDCP_SRB && !(buffer[0] & 0x80)) {
+    LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+    exit(1);
+  }
+
+  if (entity->sn_size == 12) {
+    rcvd_sn = ((buffer[0] & 0xf) <<  8) |
+                buffer[1];
+    header_size = 2;
+  } else {
+    rcvd_sn = ((buffer[0] & 0x3) << 16) |
+               (buffer[1]        <<  8) |
+                buffer[2];
+    header_size = 3;
+  }
+
+  /* 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;
+  }
+
+  if (size < header_size + integrity_size + 1) {
+    LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
+    return;
+  }
+
+  rx_deliv_sn  = entity->rx_deliv & entity->sn_max;
+  rx_deliv_hfn = entity->rx_deliv >> entity->sn_size;
+
+  if (rcvd_sn < rx_deliv_sn - entity->window_size) {
+    rcvd_hfn = rx_deliv_hfn + 1;
+  } else if (rcvd_sn >= rx_deliv_sn + entity->window_size) {
+    rcvd_hfn = rx_deliv_hfn - 1;
+  } else {
+    rcvd_hfn = rx_deliv_hfn;
+  }
+
+  rcvd_count = (rcvd_hfn << entity->sn_size) | rcvd_sn;
+
+  if (entity->has_ciphering)
+    entity->cipher(entity->security_context,
+                   buffer+header_size, size-header_size,
+                   entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
+
+  if (entity->has_integrity) {
+    unsigned char integrity[4];
+    entity->integrity(entity->integrity_context, integrity,
+                      buffer, size - integrity_size,
+                      entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
+    if (memcmp(integrity, buffer + size - integrity_size, 4) != 0) {
+      LOG_E(PDCP, "discard NR PDU, integrity failed\n");
+    }
+  }
+
+  if (rcvd_count < entity->rx_deliv
+      || nr_pdcp_sdu_in_list(entity->rx_list, rcvd_count)) {
+    LOG_D(PDCP, "discard NR PDU rcvd_count=%d\n", rcvd_count);
+    return;
+  }
+
+  sdu = nr_pdcp_new_sdu(rcvd_count,
+                        (char *)buffer + header_size,
+                        size - header_size - integrity_size);
+  entity->rx_list = nr_pdcp_sdu_list_add(entity->rx_list, sdu);
+  entity->rx_size += size-header_size;
+
+  if (rcvd_count >= entity->rx_next) {
+    entity->rx_next = rcvd_count + 1;
+  }
+
+  /* TODO(?): out of order delivery */
+
+  if (rcvd_count == entity->rx_deliv) {
+    /* deliver all SDUs starting from rx_deliv up to discontinuity or end of list */
+    uint32_t count = entity->rx_deliv;
+    while (entity->rx_list != NULL && count == entity->rx_list->count) {
+      nr_pdcp_sdu_t *cur = entity->rx_list;
+      entity->deliver_sdu(entity->deliver_sdu_data, entity,
+                          cur->buffer, cur->size);
+      entity->rx_list = cur->next;
+      entity->rx_size -= cur->size;
+      nr_pdcp_free_sdu(cur);
+      count++;
+    }
+    entity->rx_deliv = count;
+  }
+
+  if (entity->t_reordering_start != 0 && entity->rx_deliv >= entity->rx_reord) {
+    /* stop and reset t-Reordering */
+    entity->t_reordering_start = 0;
+  }
+
+  if (entity->t_reordering_start == 0 && entity->rx_deliv < entity->rx_next) {
+    entity->rx_reord = entity->rx_next;
+    entity->t_reordering_start = entity->t_current;
+  }
 }
 
-nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
-    int is_gnb, int rb_id,
+static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
+                                    char *buffer, int size, int sdu_id)
+{
+  uint32_t count;
+  int      sn;
+  int      header_size;
+  int      integrity_size;
+  char     buf[size + 3 + 4];
+  int      dc_bit;
+
+  count = entity->tx_next;
+  sn = entity->tx_next & entity->sn_max;
+
+  /* D/C bit is only to be set for DRBs */
+  if (entity->type == NR_PDCP_DRB_AM || entity->type == NR_PDCP_DRB_UM) {
+    dc_bit = 0x80;
+  } else {
+    dc_bit = 0;
+  }
+
+  if (entity->sn_size == 12) {
+    buf[0] = dc_bit | ((sn >> 8) & 0xf);
+    buf[1] = sn & 0xff;
+    header_size = 2;
+  } else {
+    buf[0] = dc_bit | ((sn >> 16) & 0x3);
+    buf[1] = (sn >> 8) & 0xff;
+    buf[2] = sn & 0xff;
+    header_size = 3;
+  }
+
+  /* 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;
+  }
+
+  memcpy(buf + header_size, buffer, size);
+
+  if (entity->has_integrity)
+    entity->integrity(entity->integrity_context,
+                      (unsigned char *)buf + header_size + size,
+                      (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,
+                   entity->rb_id, count, entity->is_gnb ? 1 : 0);
+
+  entity->tx_next++;
+
+  entity->deliver_pdu(entity->deliver_pdu_data, entity, buf,
+                      header_size + size + integrity_size, sdu_id);
+}
+
+/* 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)
+{
+  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)
+{
+  uint32_t count;
+
+  /* if t_reordering is set to "infinity" (seen as -1) then do nothing */
+  if (entity->t_reordering == -1)
+    return;
+
+  if (entity->t_reordering_start == 0
+      || entity->t_current <= entity->t_reordering_start + entity->t_reordering)
+    return;
+
+  /* stop timer */
+  entity->t_reordering_start = 0;
+
+  /* deliver all SDUs with count < rx_reord */
+  while (entity->rx_list != NULL && entity->rx_list->count < entity->rx_reord) {
+    nr_pdcp_sdu_t *cur = entity->rx_list;
+    entity->deliver_sdu(entity->deliver_sdu_data, entity,
+                        cur->buffer, cur->size);
+    entity->rx_list = cur->next;
+    entity->rx_size -= cur->size;
+    nr_pdcp_free_sdu(cur);
+  }
+
+  /* deliver all SDUs starting from rx_reord up to discontinuity or end of list */
+  count = entity->rx_reord;
+  while (entity->rx_list != NULL && count == entity->rx_list->count) {
+    nr_pdcp_sdu_t *cur = entity->rx_list;
+    entity->deliver_sdu(entity->deliver_sdu_data, entity,
+                        cur->buffer, cur->size);
+    entity->rx_list = cur->next;
+    entity->rx_size -= cur->size;
+    nr_pdcp_free_sdu(cur);
+    count++;
+  }
+
+  entity->rx_deliv = count;
+
+  if (entity->rx_deliv < entity->rx_next) {
+    entity->rx_reord = entity->rx_next;
+    entity->t_reordering_start = entity->t_current;
+  }
+}
+
+void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now)
+{
+  entity->t_current = now;
+
+  check_t_reordering(entity);
+}
+
+void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity)
+{
+  nr_pdcp_sdu_t *cur = entity->rx_list;
+  while (cur != NULL) {
+    nr_pdcp_sdu_t *next = cur->next;
+    nr_pdcp_free_sdu(cur);
+    cur = next;
+  }
+  if (entity->free_security != NULL)
+    entity->free_security(entity->security_context);
+  if (entity->free_integrity != NULL)
+    entity->free_integrity(entity->integrity_context);
+  free(entity);
+}
+
+nr_pdcp_entity_t *new_nr_pdcp_entity(
+    nr_pdcp_entity_type_t type,
+    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,
@@ -54,52 +352,46 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
     unsigned char *ciphering_key,
     unsigned char *integrity_key)
 {
-  nr_pdcp_entity_drb_am_t *ret;
+  nr_pdcp_entity_t *ret;
 
-  ret = calloc(1, sizeof(nr_pdcp_entity_drb_am_t));
+  ret = calloc(1, sizeof(nr_pdcp_entity_t));
   if (ret == NULL) {
     LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
     exit(1);
   }
 
-  ret->common.recv_pdu          = nr_pdcp_entity_drb_am_recv_pdu;
-  ret->common.recv_sdu          = nr_pdcp_entity_drb_am_recv_sdu;
-  ret->common.set_integrity_key = nr_pdcp_entity_drb_am_set_integrity_key;
+  ret->type = type;
 
-  ret->common.delete = nr_pdcp_entity_drb_am_delete;
+  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->common.deliver_sdu = deliver_sdu;
-  ret->common.deliver_sdu_data = deliver_sdu_data;
+  ret->delete = nr_pdcp_entity_delete;
 
-  ret->common.deliver_pdu = deliver_pdu;
-  ret->common.deliver_pdu_data = deliver_pdu_data;
+  ret->deliver_sdu = deliver_sdu;
+  ret->deliver_sdu_data = deliver_sdu_data;
+
+  ret->deliver_pdu = deliver_pdu;
+  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;
 
-  ret->common.maximum_nr_pdcp_sn = (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->common.has_ciphering = 1;
-    ret->common.ciphering_algorithm = ciphering_algorithm;
-    memcpy(ret->common.ciphering_key, ciphering_key, 16);
+  ret->sn_max        = (1 << sn_size) - 1;
+  ret->window_size   = 1 << (sn_size - 1);
 
-    ret->common.security_context = nr_pdcp_security_nea2_init(ciphering_key);
-    ret->common.cipher = nr_pdcp_security_nea2_cipher;
-    ret->common.free_security = nr_pdcp_security_nea2_free_security;
-  }
-  ret->common.is_gnb = is_gnb;
+  ret->is_gnb = is_gnb;
 
-  if (integrity_key != NULL) {
-    printf("%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
-    exit(1);
-  }
+  nr_pdcp_entity_set_security(ret,
+                              integrity_algorithm, (char *)integrity_key,
+                              ciphering_algorithm, (char *)ciphering_key);
 
-  return (nr_pdcp_entity_t *)ret;
+  return ret;
 }
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
index 58d79835ecbc588524526887624ecea47c15632e..fbcc2b96cd37d31cb35a02277721b4da6dee85d0 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
@@ -19,18 +19,40 @@
  *      contact@openairinterface.org
  */
 
-#include <stdint.h>
-
 #ifndef _NR_PDCP_ENTITY_H_
 #define _NR_PDCP_ENTITY_H_
 
+#include <stdint.h>
+
+#include "nr_pdcp_sdu.h"
+
+typedef enum {
+  NR_PDCP_DRB_AM,
+  NR_PDCP_DRB_UM,
+  NR_PDCP_SRB
+} nr_pdcp_entity_type_t;
+
 typedef struct nr_pdcp_entity_t {
+  nr_pdcp_entity_type_t type;
+
   /* functions provided by the PDCP module */
   void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size);
   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 */
   void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
@@ -39,9 +61,31 @@ typedef struct nr_pdcp_entity_t {
   void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
                       char *buf, int size, int sdu_id);
   void *deliver_pdu_data;
-  int tx_hfn;
-  int next_nr_pdcp_tx_sn;
-  int maximum_nr_pdcp_sn;
+
+  /* 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 */
+
+  int sn_max;                   /* (2^SN_size) - 1 */
+  int window_size;              /* 2^(SN_size - 1) */
+
+  /* state variables */
+  uint32_t tx_next;
+  uint32_t rx_next;
+  uint32_t rx_deliv;
+  uint32_t rx_reord;
+
+  /* set to the latest know time by the user of the module. Unit: ms */
+  uint64_t t_current;
+
+  /* timers (stores the ms of activation, 0 means not active) */
+  int t_reordering_start;
 
   /* security */
   int has_ciphering;
@@ -55,24 +99,27 @@ typedef struct nr_pdcp_entity_t {
                  unsigned char *buffer, int length,
                  int bearer, int count, int direction);
   void (*free_security)(void *security_context);
-  /* security algorithms need to know uplink/downlink information
+  void *integrity_context;
+  void (*integrity)(void *integrity_context, unsigned char *out,
+                 unsigned char *buffer, int length,
+                 int bearer, int count, int direction);
+  void (*free_integrity)(void *integrity_context);
+  /* security/integrity algorithms need to know uplink/downlink information
    * which is reverse for gnb and ue, so we need to know if this
    * pdcp entity is for a gnb or an ue
    */
   int is_gnb;
-} nr_pdcp_entity_t;
 
-nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
-    int is_gnb, int rb_id,
-    void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
-                        char *buf, int size),
-    void *deliver_sdu_data,
-    void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
-                        char *buf, int size, int sdu_id),
-    void *deliver_pdu_data);
+  /* rx management */
+  nr_pdcp_sdu_t *rx_list;
+  int           rx_size;
+  int           rx_maxsize;
+} nr_pdcp_entity_t;
 
-nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
-    int is_gnb, int rb_id,
+nr_pdcp_entity_t *new_nr_pdcp_entity(
+    nr_pdcp_entity_type_t type,
+    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_drb_am.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_srb.c
similarity index 52%
rename from openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
rename to openair2/LAYER2/nr_pdcp/nr_pdcp_entity_srb.c
index 62881c184e8cf3f35198b54f2893e2b4c4bb3eeb..73840aeb0aae0da858d99c4bfd9cf2da841229ed 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_srb.c
@@ -19,41 +19,27 @@
  *      contact@openairinterface.org
  */
 
-#include "nr_pdcp_entity_drb_am.h"
+#include "nr_pdcp_entity_srb.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include "common/utils/LOG/log.h"
 
-void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size)
+void nr_pdcp_entity_srb_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size)
 {
-  nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
-  int sn;
-
-  if (size < 3) abort();
-
-  if (!(buffer[0] & 0x80))
-    LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
-
-  sn = (((unsigned char)buffer[0] & 0x3) << 16) |
-        ((unsigned char)buffer[1]        <<  8) |
-         (unsigned char)buffer[2];
-
-  if (entity->common.has_ciphering)
-    entity->common.cipher(entity->common.security_context, (unsigned char *)buffer+3, size-3,
-                          entity->rb_id, sn, entity->common.is_gnb ? 0 : 1);
+  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+3, size-3);
+                             (nr_pdcp_entity_t *)entity, buffer+2, size-6);
 }
 
-void nr_pdcp_entity_drb_am_recv_sdu(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)
 {
-  nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
+  nr_pdcp_entity_srb_t *entity = (nr_pdcp_entity_srb_t *)_entity;
   int sn;
-  char buf[size+3];
+  char buf[size+6];
 
   sn = entity->common.next_nr_pdcp_tx_sn;
 
@@ -63,28 +49,27 @@ void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int
     entity->common.tx_hfn++;
   }
 
-  buf[0] = 0x80 | ((sn >> 16) & 0x3);
-  buf[1] = (sn >> 8) & 0xff;
-  buf[2] = sn & 0xff;
-  memcpy(buf+3, buffer, size);
+  buf[0] = (sn >> 8) & 0x0f;
+  buf[1] = sn & 0xff;
+  memcpy(buf+2, buffer, size);
 
-  if (entity->common.has_ciphering)
-    entity->common.cipher(entity->common.security_context, (unsigned char *)buf+3, size,
-                          entity->rb_id, sn, entity->common.is_gnb ? 1 : 0);
+  /* 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+3, sdu_id);
+                             (nr_pdcp_entity_t *)entity, buf, size+6, sdu_id);
 }
 
-void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *key)
+void nr_pdcp_entity_srb_set_integrity_key(nr_pdcp_entity_t *_entity, char *key)
 {
   /* nothing to do */
 }
 
-void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity)
+void nr_pdcp_entity_srb_delete(nr_pdcp_entity_t *_entity)
 {
-  nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
-  if (entity->common.free_security != NULL)
-    entity->common.free_security(entity->common.security_context);
+  nr_pdcp_entity_srb_t *entity = (nr_pdcp_entity_srb_t *)_entity;
   free(entity);
 }
+
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_srb.h
similarity index 62%
rename from openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h
rename to openair2/LAYER2/nr_pdcp/nr_pdcp_entity_srb.h
index d7c42e6a629281ddc36253894857e120d95f3e93..f0f9d3e28f200c47e781064b3fb6fe22f750b33f 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_srb.h
@@ -1,4 +1,4 @@
-/*
+ /*
  * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -19,23 +19,20 @@
  *      contact@openairinterface.org
  */
 
-#ifndef _NR_PDCP_ENTITY_DRB_AM_H_
-#define _NR_PDCP_ENTITY_DRB_AM_H_
+#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 rb_id;
-  int sn_size;               /* unit: bits */
-  int t_reordering;          /* unit: ms */
-  int discard_timer;         /* unit: ms, -1 means infinity */
-} nr_pdcp_entity_drb_am_t;
+  int srb_id;
+} nr_pdcp_entity_srb_t;
 
-void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size);
-void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *entity, char *buffer, int size,
-                                    int sdu_id);
-void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *entity, char *key);
-void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *entity);
+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_DRB_AM_H_ */
+
+#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
new file mode 100644
index 0000000000000000000000000000000000000000..86f05586114e439201e9aee59ac57db2a9084025
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
@@ -0,0 +1,82 @@
+/*
+ * 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_integrity_nia2.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <openssl/cmac.h>
+
+void *nr_pdcp_integrity_nia2_init(unsigned char *integrity_key)
+{
+  CMAC_CTX *ctx;
+
+  ctx = CMAC_CTX_new();
+  if (ctx == NULL) abort();
+
+  CMAC_Init(ctx, integrity_key, 16, EVP_aes_128_cbc(), NULL);
+
+  return ctx;
+}
+
+static void compute_t(unsigned char *t, uint32_t count, int bearer,
+                      int direction)
+{
+  t[0] = (count >> 24) & 255;
+  t[1] = (count >> 16) & 255;
+  t[2] = (count >>  8) & 255;
+  t[3] = (count      ) & 255;
+  t[4] = ((bearer-1) << 3) | (direction << 2);
+  memset(&t[5], 0, 8-5);
+}
+
+void nr_pdcp_integrity_nia2_integrity(void *integrity_context,
+                            unsigned char *out,
+                            unsigned char *buffer, int length,
+                            int bearer, int count, int direction)
+{
+  CMAC_CTX *ctx = integrity_context;
+  unsigned char t[8];
+  unsigned char mac[16];
+  size_t maclen;
+
+  /* see 33.401 B.2.3 for the input to 128-EIA2
+   * (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);
+
+  /* AES CMAC (RFC 4493) outputs 128 bits but NR PDCP PDUs have a MAC-I of
+   * 32 bits (see 38.323 6.2). RFC 4493 2.1 says to truncate most significant
+   * bit first (so seems to say 33.401 B.2.3)
+   */
+  memcpy(out, mac, 4);
+}
+
+void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context)
+{
+  CMAC_CTX *ctx = integrity_context;
+  CMAC_CTX_free(ctx);
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h
new file mode 100644
index 0000000000000000000000000000000000000000..9593a2825c0022e384f7bcc9d45711f10fb29264
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h
@@ -0,0 +1,34 @@
+/*
+ * 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_INTEGRITY_NIA2_H_
+#define _NR_PDCP_INTEGRITY_NIA2_H_
+
+void *nr_pdcp_integrity_nia2_init(unsigned char *integrity_key);
+
+void nr_pdcp_integrity_nia2_integrity(void *integrity_context,
+                            unsigned char *out,
+                            unsigned char *buffer, int length,
+                            int bearer, int count, int direction);
+
+void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context);
+
+#endif /* _NR_PDCP_INTEGRITY_NIA2_H_ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index f14d25b145a72c4b3534e05ff46cce5752478edc..60788826017a44ba2ff0609d04a87c9bb1ebe256 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -24,15 +24,18 @@
 #endif
 #include "asn1_utils.h"
 #include "nr_pdcp_ue_manager.h"
+#include "nr_pdcp_timer_thread.h"
 #include "NR_RadioBearerConfig.h"
 #include "NR_RLC-BearerConfig.h"
 #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"
 #include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
+#include <openair3/ocp-gtpu/gtp_itf.h>
 
 #define TODO do { \
     printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \
@@ -41,10 +44,18 @@
 
 static nr_pdcp_ue_manager_t *nr_pdcp_ue_manager;
 
+/* TODO: handle time a bit more properly */
+static uint64_t nr_pdcp_current_time;
+static int      nr_pdcp_current_time_last_frame;
+static int      nr_pdcp_current_time_last_subframe;
+
 /* necessary globals for OAI, not used internally */
 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                                               */
 /****************************************************************************/
@@ -179,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                                                 */
 /****************************************************************************/
@@ -338,7 +369,12 @@ 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);
 }
 
 #include "nfapi/oai_integration/vendor_ext.h"
@@ -409,7 +445,8 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
   int rb_id;
   int i;
 
-  if(IS_SOFTMODEM_NOS1){
+  if(IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN){
+    LOG_D(PDCP, "IP packet received, to be sent to TUN interface");
     len = write(nas_sock_fd[0], buf, size);
     if (len != size) {
       LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
@@ -428,22 +465,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");
-      itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
-
+      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);
+   }
   }
 }
 
@@ -488,6 +528,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 < sizeofArray(ue->srb) ; 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 < sizeofArray(ue->srb) ; 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,
@@ -548,14 +687,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,
@@ -586,9 +737,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,
@@ -601,11 +777,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 = decode_t_reordering(*s->pdcp_Config->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) */
+  int t_reordering = -1;
+  if (s->pdcp_Config->t_Reordering != NULL) {
+    t_reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering);
+  }
+
+  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",
@@ -625,11 +831,12 @@ 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_drb_am(is_gnb, drb_id,
-                                         deliver_sdu_drb, ue, deliver_pdu_drb, ue,
-                                         sn_size_dl, t_reordering, discard_timer,
-                                         ciphering_algorithm, integrity_algorithm,
-                                         ciphering_key, integrity_key);
+    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,
+                                  ciphering_key, integrity_key);
     nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
 
     LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
@@ -690,19 +897,20 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
       //ctxt_pP->configured != 2 ||
       //srb2add_list == NULL ||
       //drb2add_list != NULL ||
-      drb2release_list != NULL ||
+      //drb2release_list != NULL ||
       //security_modeP != 255 ||
       //kRRCenc != NULL ||
       //kRRCint != NULL ||
       //kUPenc != NULL ||
       pmch_InfoList_r9 != NULL /*||
       defaultDRB != NULL */) {
+    LOG_I(PDCP,"Releasing DRBs, oops\n");
     TODO;
   }
 
   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]);
     }
   }
 
@@ -720,6 +928,10 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
     /* todo */
   }
 
+  if (drb2release_list != NULL) {
+    // TODO
+  }
+
   free(kRRCenc);
   free(kRRCint);
   free(kUPenc);
@@ -768,7 +980,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
   drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config));
   drb_ToAddMod->pdcp_Config->drb = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb));
   drb_ToAddMod->pdcp_Config->drb->discardTimer = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->discardTimer));
-  *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_ms30;
+  *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_infinity;
   drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL));
   *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len12bits;
   drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL));
@@ -796,10 +1008,12 @@ void nr_DRB_preconfiguration(uint16_t crnti)
   rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse));
   *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
 
-  xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
+  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+    xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
+  }
 
   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);
 
@@ -818,7 +1032,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
     (NR_SRB_ToAddModList_t *) NULL,
     rbconfig->drb_ToAddModList ,
     rbconfig->drb_ToReleaseList,
-    0xff,
+    0,
     NULL,
     NULL,
     NULL,
@@ -865,37 +1079,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,
@@ -931,6 +1195,7 @@ static boolean_t pdcp_data_req_drb(
   if (rb == NULL) {
     LOG_E(PDCP, "%s:%d:%s: no DRB found (rnti %d, rb_id %ld)\n",
           __FILE__, __LINE__, __FUNCTION__, rnti, rb_id);
+    nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
     return 0;
   }
 
@@ -956,9 +1221,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)
@@ -976,3 +1244,14 @@ void
 pdcp_mbms_run ( const protocol_ctxt_t *const  ctxt_pP){
   /* nothing to do */
 }
+
+void nr_pdcp_tick(int frame, int subframe)
+{
+  if (frame != nr_pdcp_current_time_last_frame ||
+      subframe != nr_pdcp_current_time_last_subframe) {
+    nr_pdcp_current_time_last_frame = frame;
+    nr_pdcp_current_time_last_subframe = subframe;
+    nr_pdcp_current_time++;
+    nr_pdcp_wakeup_timer_thread(nr_pdcp_current_time);
+  }
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c
new file mode 100644
index 0000000000000000000000000000000000000000..47d95156e3db1982307c8410b37187673370d94f
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c
@@ -0,0 +1,78 @@
+/*
+ * 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_sdu.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size)
+{
+  nr_pdcp_sdu_t *ret = calloc(1, sizeof(nr_pdcp_sdu_t));
+  if (ret == NULL)
+    exit(1);
+  ret->count = count;
+  ret->buffer = malloc(size);
+  if (ret->buffer == NULL)
+    exit(1);
+  memcpy(ret->buffer, buffer, size);
+  ret->size = size;
+  return ret;
+}
+
+nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu)
+{
+  nr_pdcp_sdu_t head;
+  nr_pdcp_sdu_t *cur;
+  nr_pdcp_sdu_t *prev;
+
+  head.next = l;
+  cur = l;
+  prev = &head;
+
+  /* order is by 'count' */
+  while (cur != NULL) {
+    /* check if 'sdu' is before 'cur' in the list */
+    if (sdu->count < cur->count)
+      break;
+    prev = cur;
+    cur = cur->next;
+  }
+  prev->next = sdu;
+  sdu->next = cur;
+  return head.next;
+}
+
+int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count)
+{
+  while (l != NULL) {
+    if (l->count == count)
+      return 1;
+    l = l->next;
+  }
+  return 0;
+}
+
+void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu)
+{
+  free(sdu->buffer);
+  free(sdu);
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h
new file mode 100644
index 0000000000000000000000000000000000000000..3d4e50a4ce38cc7493c7974bdb7004a5a10297fd
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h
@@ -0,0 +1,39 @@
+/*
+ * 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_SDU_H_
+#define _NR_PDCP_SDU_H_
+
+#include <stdint.h>
+
+typedef struct nr_pdcp_sdu_t {
+  uint32_t             count;
+  char                 *buffer;
+  int                  size;
+  struct nr_pdcp_sdu_t *next;
+} nr_pdcp_sdu_t;
+
+nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size);
+nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu);
+int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count);
+void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu);
+
+#endif /* _NR_PDCP_SDU_H_ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
index fc07f661dd590ee486a2a5d850a2256a66e62ceb..52afe95673853799743e5511ea39c8fb112deb66 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
@@ -27,12 +27,21 @@
 #include <nettle/aes.h>
 #include <nettle/ctr.h>
 
+#ifndef NETTLE_VERSION_MAJOR
+/* hack: include bignum.h, not version.h because version.h does not exist
+ *       in old versions and bignum.h includes version.h (as of today).
+ *       May completely fail to work... maybe we should skip support of old
+ *       versions of nettle.
+ */
+#include <nettle/bignum.h>
+#endif
+
 void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key)
 {
   void *ctx = calloc(1, nettle_aes128.context_size);
   if (ctx == NULL) exit(1);
 
-#if NETTLE_VERSION_MAJOR < 3
+#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3
   nettle_aes128.set_encrypt_key(ctx, 16, ciphering_key);
 #else
   nettle_aes128.set_encrypt_key(ctx, ciphering_key);
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c
new file mode 100644
index 0000000000000000000000000000000000000000..36e9b16024879db067a7784c66eb898e36527dc7
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c
@@ -0,0 +1,87 @@
+/*
+ * 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_timer_thread.h"
+
+#include <stdlib.h>
+#include <pthread.h>
+#include <stdint.h>
+
+#include "LOG/log.h"
+
+static pthread_mutex_t   timer_thread_mutex   = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t    timer_thread_cond    = PTHREAD_COND_INITIALIZER;
+static volatile uint64_t timer_thread_curtime = 0;
+
+static void *nr_pdcp_timer_thread(void *_nr_pdcp_ue_manager)
+{
+  nr_pdcp_ue_manager_t *nr_pdcp_ue_manager = (nr_pdcp_ue_manager_t *)_nr_pdcp_ue_manager;
+  nr_pdcp_ue_t         **ue_list;
+  int                  ue_count;
+  int                  i;
+  int                  j;
+  uint64_t             curtime = 0;
+
+  while (1) {
+    if (pthread_mutex_lock(&timer_thread_mutex) != 0) abort();
+    while (curtime == timer_thread_curtime)
+      if (pthread_cond_wait(&timer_thread_cond, &timer_thread_mutex) != 0) abort();
+    curtime = timer_thread_curtime;
+    if (pthread_mutex_unlock(&timer_thread_mutex) != 0) abort();
+
+    nr_pdcp_manager_lock(nr_pdcp_ue_manager);
+
+    ue_list  = nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager);
+    ue_count = nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager);
+    for (i = 0; i < ue_count; i++) {
+      for (j = 0; j < 2; j++) {
+        if (ue_list[i]->srb[j] != NULL)
+          ue_list[i]->srb[j]->set_time(ue_list[i]->srb[j], curtime);
+      }
+      for (j = 0; j < 5; j++) {
+        if (ue_list[i]->drb[j] != NULL)
+          ue_list[i]->drb[j]->set_time(ue_list[i]->drb[j], curtime);
+      }
+    }
+
+    nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+  }
+
+  return NULL;
+}
+
+void nr_pdcp_init_timer_thread(nr_pdcp_ue_manager_t *nr_pdcp_ue_manager)
+{
+  pthread_t t;
+
+  if (pthread_create(&t, NULL, nr_pdcp_timer_thread, nr_pdcp_ue_manager) != 0) {
+    LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+    exit(1);
+  }
+}
+
+void nr_pdcp_wakeup_timer_thread(uint64_t time)
+{
+  if (pthread_mutex_lock(&timer_thread_mutex)) abort();
+  timer_thread_curtime = time;
+  if (pthread_cond_broadcast(&timer_thread_cond)) abort();
+  if (pthread_mutex_unlock(&timer_thread_mutex)) abort();
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h
new file mode 100644
index 0000000000000000000000000000000000000000..db8282f940057393b099b4f9e50542838fb30991
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h
@@ -0,0 +1,32 @@
+/*
+ * 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_TIMER_THREAD_H_
+#define _NR_PDCP_TIMER_THREAD_H_
+
+#include "nr_pdcp_ue_manager.h"
+
+#include <stdint.h>
+
+void nr_pdcp_init_timer_thread(nr_pdcp_ue_manager_t *nr_pdcp_ue_manager);
+void nr_pdcp_wakeup_timer_thread(uint64_t time);
+
+#endif /* _NR_PDCP_TIMER_THREAD_H_ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
index ca51da3d5f13426993c9395cf3c06550fff9c4f5..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);
@@ -189,6 +189,20 @@ void nr_pdcp_ue_add_drb_pdcp_entity(nr_pdcp_ue_t *ue, int drb_id, nr_pdcp_entity
   ue->drb[drb_id] = entity;
 }
 
+/* must be called with lock acquired */
+nr_pdcp_ue_t **nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager_t *_m)
+{
+  nr_pdcp_ue_manager_internal_t *m = _m;
+  return m->ue_list;
+}
+
+/* must be called with lock acquired */
+int nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager_t *_m)
+{
+  nr_pdcp_ue_manager_internal_t *m = _m;
+  return m->ue_count;
+}
+
 int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *_m)
 {
   nr_pdcp_ue_manager_internal_t *m = _m;
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h
index 0de2f024b3f53746ff12537dfb08da9ec8fef1b1..742e0e84be8c67f0e1a109a95e32879f2884ce9d 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h
@@ -28,7 +28,7 @@ typedef void nr_pdcp_ue_manager_t;
 
 typedef struct nr_pdcp_ue_t {
   int rnti;
-  nr_pdcp_entity_t *srb[2];
+  nr_pdcp_entity_t *srb[3];
   nr_pdcp_entity_t *drb[5];
 } nr_pdcp_ue_t;
 
@@ -46,6 +46,9 @@ void nr_pdcp_manager_unlock(nr_pdcp_ue_manager_t *m);
 nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *m, int rnti);
 void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *m, int rnti);
 
+nr_pdcp_ue_t **nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager_t *_m);
+int nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager_t *_m);
+
 /***********************************************************************/
 /* ue functions                                                        */
 /***********************************************************************/
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
index 1d4efc1e264b19a25b5b5ffc4feb11d6ba933249..08f5b11c23197f47587d5f8801cd8c875dd211df 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
@@ -650,7 +650,7 @@ control:
   control_decoder = decoder;
   control_e1 = e1;
   while (control_e1) {
-    nr_rlc_pdu_decoder_get_bits(&control_decoder, entity->sn_field_length); R(control_decoder); /* NACK_SN */
+    nack_sn = nr_rlc_pdu_decoder_get_bits(&control_decoder, entity->sn_field_length); R(control_decoder);
     control_e1 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
     control_e2 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
     control_e3 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
@@ -660,17 +660,36 @@ control:
     } else {
       nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
     }
+    /* check range and so_start/so_end consistency */
     if (control_e2) {
-      nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); /* SOstart */
-      nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); /* SOend */
+      so_start = nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder);
+      so_end = nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder);
+    } else {
+      so_start = 0;
+      so_end = 0xffff;
     }
     if (control_e3) {
-      nr_rlc_pdu_decoder_get_bits(&control_decoder, 8); R(control_decoder); /* NACK range */
+      range = nr_rlc_pdu_decoder_get_bits(&control_decoder, 8); R(control_decoder);
+    } else {
+      range = 1;
+    }
+    if (range < 1) {
+      LOG_E(RLC, "%s:%d:%s: error, bad 'range' in RLC NACK (sn %d)\n",
+            __FILE__, __LINE__, __FUNCTION__, nack_sn);
+      goto err;
+    }
+    /* so_start can be > so_end if more than one range; they don't refer
+     * to the same PDU then
+     */
+    if (range == 1 && so_end < so_start) {
+      LOG_E(RLC, "%s:%d:%s: error, bad so start/end (sn %d)\n",
+            __FILE__, __LINE__, __FUNCTION__, nack_sn);
+      goto err;
     }
   }
 
   /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is
-   * received for the SN 'poll_sn'
+   * received for the SN 'poll_sn' - check ACK case (NACK done below)
    */
   if (sn_compare_tx(entity, entity->poll_sn, ack_sn) < 0)
     entity->t_poll_retransmit_start = 0;
@@ -697,28 +716,22 @@ control:
     if (e2) {
       so_start = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder);
       so_end = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder);
-      if (so_end < so_start) {
-        LOG_W(RLC, "%s:%d:%s: warning, bad so start/end, NACK the whole PDU (sn %d)\n",
-              __FILE__, __LINE__, __FUNCTION__, nack_sn);
-        so_start = 0;
-        so_end = -1;
-      }
-      /* special value 0xffff indicates 'all bytes to the end' */
-      if (so_end == 0xffff)
-        so_end = -1;
     } else {
       so_start = 0;
-      so_end = -1;
+      so_end = 0xffff;
     }
     if (e3) {
       range = nr_rlc_pdu_decoder_get_bits(&decoder, 8); R(decoder);
     } else {
       range = 1;
     }
+    /* special value 0xffff indicates 'all bytes to the end' */
+    if (so_end == 0xffff)
+      so_end = -1;
     process_received_nack(entity, nack_sn, so_start, so_end, range, sn_set);
 
     /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is
-     * received for the SN 'poll_sn'
+     * received for the SN 'poll_sn' - check NACK case (ACK done above)
      */
     if (sn_compare_tx(entity, nack_sn, entity->poll_sn) <= 0 &&
         sn_compare_tx(entity, entity->poll_sn, (nack_sn + range) % entity->sn_modulus) < 0)
@@ -1516,7 +1529,7 @@ static int tx_list_size(nr_rlc_entity_am_t *entity,
 {
   int ret = 0;
 
-  while (l != NULL) {
+  while (l != NULL && ret < maxsize) {
     ret += compute_pdu_header_size(entity, l) + l->size;
     l = l->next;
   }
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c
index 86a0697624091d9d41dae21a095753ed8bf928d4..26ae4818891f2062113c4eeedd4d7da9a293141c 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c
@@ -78,7 +78,7 @@ static int tx_list_size(nr_rlc_entity_tm_t *entity,
 {
   int ret = 0;
 
-  while (l != NULL) {
+  while (l != NULL && ret < maxsize) {
     ret += l->size;
     l = l->next;
   }
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c
index 4ef952667dc84be0c6de1b219c5cf5f37833558e..f967c3c5432a9832768ea4ceb22a0083eecbc0ff 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c
@@ -497,7 +497,7 @@ static int tx_list_size(nr_rlc_entity_um_t *entity,
 {
   int ret = 0;
 
-  while (l != NULL) {
+  while (l != NULL && ret < maxsize) {
     ret += compute_pdu_header_size(entity, l) + l->size;
     l = l->next;
   }
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index 9c139624ebddeb846e6c4d26546e4f80c24556fd..e196b56f1cf0a0d608f8e2afa3578c6409839426 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -35,9 +35,19 @@
 #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"
+
+#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>
 
+#include <executables/softmodem-common.h>
+
 static nr_rlc_ue_manager_t *nr_rlc_ue_manager;
 
 /* TODO: handle time a bit more properly */
@@ -45,18 +55,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;
+  }
 
 }
 
@@ -73,7 +90,8 @@ void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChann
 
   mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup                = calloc(1,sizeof(*mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup));
   *mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup               = 1;
-  mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID                = NULL;
+  mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID                = calloc(1,sizeof(*mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID));
+  *mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID               = 0;
   mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask              = false;
   mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = false;
   mac_LogicalChannelConfig->ul_SpecificParameters->bitRateQueryProhibitTimer          = NULL;
@@ -159,7 +177,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);
@@ -198,8 +216,10 @@ tbs_size_t mac_rlc_data_req(
     maxsize = tb_sizeP;
     ret = rb->generate_pdu(rb, buffer_pP, maxsize);
   } else {
-    LOG_E(RLC, "%s:%d:%s: fatal: data req for unknown RB, channel_idP: %d\n", __FILE__, __LINE__, __FUNCTION__, channel_idP);
-    exit(1);
+    // Laurent: the query loop was checking all possible RB, but by  mac_rlc_get_buffer_occupancy_ind
+    // so it is more straitforward to try to get data
+    //LOG_E(RLC, "%s:%d:%s: fatal: data req for unknown RB, channel_idP: %d\n", __FILE__, __LINE__, __FUNCTION__, channel_idP);
+    //exit(1);
     ret = 0;
   }
 
@@ -245,12 +265,14 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
      * reports '> 81338368' (table 6.1.3.1-2). Passing 100000000 is thus
      * more than enough.
      */
-    buf_stat = rb->buffer_status(rb, 100000000);
+    // Fix me: temproary reduction meanwhile cpu cost of this computation is optimized
+    buf_stat = rb->buffer_status(rb, 1000*1000);
     ret.bytes_in_buffer = buf_stat.status_size
                         + buf_stat.retx_size
                         + buf_stat.tx_size;
   } else {
-    LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP);
+    if (!(frameP%128)) //to supress this warning message
+      LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP);
     ret.bytes_in_buffer = 0;
   }
 
@@ -306,7 +328,9 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
      * reports '> 81338368' (table 6.1.3.1-2). Passing 100000000 is thus
      * more than enough.
      */
-    buf_stat = rb->buffer_status(rb, 100000000);
+    // Fixme : Laurent reduced size for CPU saving
+    // Fix me: temproary reduction meanwhile cpu cost of this computation is optimized
+    buf_stat = rb->buffer_status(rb, 1000*1000);
     ret = buf_stat.status_size
         + buf_stat.retx_size
         + buf_stat.tx_size;
@@ -319,7 +343,6 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
   return ret;
 }
 
-int oai_emulation;
 
 rlc_op_status_t rlc_data_req     (const protocol_ctxt_t *const ctxt_pP,
                                   const srb_flag_t   srb_flagP,
@@ -409,7 +432,7 @@ static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size)
   int is_enb;
 
   /* is it SRB? */
-  for (i = 0; i < 2; i++) {
+  for (i = 0; i < sizeofArray(ue->srb); i++) {
     if (entity == ue->srb[i]) {
       is_srb = 1;
       rb_id = i+1;
@@ -418,7 +441,7 @@ static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size)
   }
 
   /* maybe DRB? */
-  for (i = 0; i < 5; i++) {
+  for (i = 0; i < sizeofArray(ue->drb) ; i++) {
     if (entity == ue->drb[i]) {
       is_srb = 0;
       rb_id = i+1;
@@ -460,6 +483,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)) {
@@ -560,7 +604,7 @@ static void max_retx_reached(void *_ue, nr_rlc_entity_t *entity)
   exit(1);
 
 rb_found:
-  LOG_D(RLC, "max RETX reached on %s %d\n",
+  LOG_E(RLC, "max RETX reached on %s %d\n",
         is_srb ? "SRB" : "DRB",
         rb_id);
 
@@ -583,14 +627,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;
@@ -601,25 +646,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__);
@@ -627,29 +668,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);
@@ -658,7 +692,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;
@@ -679,8 +713,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);
 }
@@ -721,7 +754,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) {
@@ -762,7 +795,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);
 }
@@ -830,7 +863,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);
 }
@@ -849,7 +882,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 */
@@ -865,7 +898,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,
@@ -873,6 +906,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 ||
@@ -890,18 +924,39 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt
 
   if (drb2release_listP != NULL) {
     LOG_E(RLC, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
-    exit(1);
+    //exit(1);
   }
 
   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/nr_rlc/tests/run_tests.sh b/openair2/LAYER2/nr_rlc/tests/run_tests.sh
index bf1b343d7ec6150aabfe81f7c88b87e7e013a5e3..a98f6b5d0fffe9f530e0ee49d06bedb9413ed11b 100755
--- a/openair2/LAYER2/nr_rlc/tests/run_tests.sh
+++ b/openair2/LAYER2/nr_rlc/tests/run_tests.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-test_count=14
+test_count=15
 
 for i in `seq $test_count`
 do
diff --git a/openair2/LAYER2/nr_rlc/tests/test15.h b/openair2/LAYER2/nr_rlc/tests/test15.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ce9f97896c318e67fe36e72a1603c3b8c46c401
--- /dev/null
+++ b/openair2/LAYER2/nr_rlc/tests/test15.h
@@ -0,0 +1,19 @@
+/*
+ * am test (SN field size 18):
+ * test "range" in NACK, generate a case where so_start > so_end
+ * (so so_start and so_end are not from the same PDU)
+ */
+
+TIME, 1,
+    GNB_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18,
+    UE_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18,
+    GNB_PDU_SIZE, 40,
+    UE_PDU_SIZE, 80,
+    GNB_SDU, 0, 50,
+    GNB_SDU, 1, 50,
+    GNB_SDU, 2, 50,
+TIME, 2,
+    UE_RECV_FAILS, 1,
+TIME, 4,
+    UE_RECV_FAILS, 0,
+TIME, -1
diff --git a/openair2/LAYER2/nr_rlc/tests/test15.txt.gz b/openair2/LAYER2/nr_rlc/tests/test15.txt.gz
new file mode 100644
index 0000000000000000000000000000000000000000..e615a59a5faa88571ac77198d4f53f979163309c
Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test15.txt.gz differ
diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c
index bbdc55e0366098cf0e284bea75e758fda3bc5007..3d2c06f4893c5fa457bb068922a02d5765845bdc 100644
--- a/openair2/LAYER2/openair2_proc.c
+++ b/openair2/LAYER2/openair2_proc.c
@@ -503,8 +503,8 @@ int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length) {
         } else if(Mac_rlc_xface->Is_cluster_head[k] ==1) {
             Mod_id=k;
             len+=sprintf(&buffer[len],
-                         "-------------------------------------------------------------------CH %d: TTI: %d------------------------------------------------------------------\n",
-                         NODE_ID[Mod_id],Mac_rlc_xface->frame);
+                         "------------------------------------------------------------------- TTI: %d------------------------------------------------------------------\n",
+                         Mac_rlc_xface->frame);
 
             for(i=1; i<=NB_CNX_CH; i++) {
                 if (CH_mac_inst[Mod_id].Dcch_lchan[i].Active==1) {
diff --git a/openair2/LAYER2/rlc_v2/rlc_oai_api.c b/openair2/LAYER2/rlc_v2/rlc_oai_api.c
index 919d577a18f3a091e91096c42e78a8583baa6193..0cf4b85fa2cb98145cc1bc24f0a0a41f5eca793f 100644
--- a/openair2/LAYER2/rlc_v2/rlc_oai_api.c
+++ b/openair2/LAYER2/rlc_v2/rlc_oai_api.c
@@ -265,7 +265,6 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
   return ret;
 }
 
-int oai_emulation;
 
 rlc_op_status_t rlc_data_req     (const protocol_ctxt_t *const ctxt_pP,
                                   const srb_flag_t   srb_flagP,
@@ -1032,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/MCE_APP/mce_app.c b/openair2/MCE_APP/mce_app.c
index 3572de215c446a12b3573cda32f635c345b110df..4ac12ab5b49388092bbf54eed08922e944a12aeb 100644
--- a/openair2/MCE_APP/mce_app.c
+++ b/openair2/MCE_APP/mce_app.c
@@ -54,7 +54,6 @@
 #   define X2AP_ENB_REGISTER_RETRY_DELAY   10
 
 #include "openair1/PHY/INIT/phy_init.h"
-extern unsigned char NB_MCE_INST;
 
 extern RAN_CONTEXT_t RC;
 
diff --git a/openair2/NETWORK_DRIVER/MESH/local.h b/openair2/NETWORK_DRIVER/MESH/local.h
index 58ae78e7a5a3e47d22190cf969a43e6ed829940e..4918e196280f9317dc15bed651f5c60fc31a30c9 100644
--- a/openair2/NETWORK_DRIVER/MESH/local.h
+++ b/openair2/NETWORK_DRIVER/MESH/local.h
@@ -64,10 +64,6 @@
 #include "rrc_nas_primitives.h"
 #include "COMMON/platform_types.h"
 
-#ifndef MAKE_VERSION
-  #define MAKE_VERSION(a,b,c) ((a)*256+(b)*16+(c))
-#endif
-
 struct rb_entity {
   nasRadioBearerId_t rab_id;
   nasSapId_t sapi;
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/NETWORK_DRIVER/UE_IP/local.h b/openair2/NETWORK_DRIVER/UE_IP/local.h
index 5532de9573ba7758724af826e1ba9ca30e733cb4..46e44f0040892bb942e6877abd8a9cca492f1a42 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/local.h
+++ b/openair2/NETWORK_DRIVER/UE_IP/local.h
@@ -55,10 +55,6 @@
 #include "platform_types.h"
 #include "sap.h"
 
-#ifndef MAKE_VERSION
-  #define MAKE_VERSION(a,b,c) ((a)*256+(b)*16+(c))
-#endif
-
 typedef struct ue_ip_priv_s {
   int                        irq;
   int                        rx_flags;
diff --git a/openair2/NETWORK_DRIVER/UE_IP/netlink.c b/openair2/NETWORK_DRIVER/UE_IP/netlink.c
index 658ae19aba91cc2718710f59f691ca58ba327a28..b3829c51d1018e9d73266226f41ae387cb30857e 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/netlink.c
+++ b/openair2/NETWORK_DRIVER/UE_IP/netlink.c
@@ -39,6 +39,7 @@
 #include "local.h"
 #include "proto_extern.h"
 
+MODULE_LICENSE("OAI");
 
 #define OAI_IP_DRIVER_NETLINK_ID 31
 #define NL_DEST_PID 1
diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
index b183b32aab4971c6d58d1b1c70566301bbe5676c..fa76fd00bca0e7446f594bf0a0c6818a4a1f9307 100644
--- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
@@ -41,9 +41,8 @@
 #define MAX_IF_MODULES 100
 //#define UL_HARQ_PRINT
 
-NR_IF_Module_t *if_inst[MAX_IF_MODULES];
-NR_Sched_Rsp_t Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs];
-
+static NR_IF_Module_t *nr_if_inst[MAX_IF_MODULES];
+static NR_Sched_Rsp_t NR_Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs];
 extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind);
 extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
 extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind);
@@ -56,7 +55,7 @@ extern uint16_t sl_ahead;
 void handle_nr_rach(NR_UL_IND_t *UL_info) {
 
   if (UL_info->rach_ind.number_of_pdus>0) {
-    LOG_I(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
+    LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
     int npdus = UL_info->rach_ind.number_of_pdus;
     for(int i = 0; i < npdus; i++) {
       UL_info->rach_ind.number_of_pdus--;
@@ -96,6 +95,7 @@ void handle_nr_uci(NR_UL_IND_t *UL_info)
         handle_nr_uci_pucch_0_1(mod_id, frame, slot, uci_pdu);
         break;
       }
+
       case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
         const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4;
         handle_nr_uci_pucch_2_3_4(mod_id, frame, slot, uci_pdu);
@@ -105,13 +105,8 @@ void handle_nr_uci(NR_UL_IND_t *UL_info)
   }
 
   UL_info->uci_ind.num_ucis = 0;
-
-  // mark corresponding PUCCH resources as free
-  // NOTE: we just assume it is BWP ID 1, to be revised for multiple BWPs
-  RC.nrmac[mod_id]->pucch_index_used[1][slot] = 0;
 }
 
-
 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) {
@@ -178,8 +173,8 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
 #endif
   module_id_t      module_id   = UL_info->module_id;
   int              CC_id       = UL_info->CC_id;
-  NR_Sched_Rsp_t   *sched_info = &Sched_INFO[module_id][CC_id];
-  NR_IF_Module_t   *ifi        = if_inst[module_id];
+  NR_Sched_Rsp_t   *sched_info = &NR_Sched_INFO[module_id][CC_id];
+  NR_IF_Module_t   *ifi        = nr_if_inst[module_id];
   gNB_MAC_INST     *mac        = RC.nrmac[module_id];
   LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rach_pdus:%d rx_ind:%d crcs:%d]\n",
         UL_info->frame,UL_info->slot,
@@ -253,17 +248,17 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {
   AssertFatal(Mod_id<MAX_MODULES,"Asking for Module %d > %d\n",Mod_id,MAX_IF_MODULES);
   LOG_I(PHY,"Installing callbacks for IF_Module - UL_indication\n");
 
-  if (if_inst[Mod_id]==NULL) {
-    if_inst[Mod_id] = (NR_IF_Module_t*)malloc(sizeof(NR_IF_Module_t));
-    memset((void*)if_inst[Mod_id],0,sizeof(NR_IF_Module_t));
+  if (nr_if_inst[Mod_id]==NULL) {
+    nr_if_inst[Mod_id] = (NR_IF_Module_t*)malloc(sizeof(NR_IF_Module_t));
+    memset((void*)nr_if_inst[Mod_id],0,sizeof(NR_IF_Module_t));
 
-    LOG_I(MAC,"Allocating shared L1/L2 interface structure for instance %d @ %p\n",Mod_id,if_inst[Mod_id]);
+    LOG_I(MAC,"Allocating shared L1/L2 interface structure for instance %d @ %p\n",Mod_id,nr_if_inst[Mod_id]);
 
-    if_inst[Mod_id]->CC_mask=0;
-    if_inst[Mod_id]->NR_UL_indication = NR_UL_indication;
-    AssertFatal(pthread_mutex_init(&if_inst[Mod_id]->if_mutex,NULL)==0,
-                "allocation of if_inst[%d]->if_mutex fails\n",Mod_id);
+    nr_if_inst[Mod_id]->CC_mask=0;
+    nr_if_inst[Mod_id]->NR_UL_indication = NR_UL_indication;
+    AssertFatal(pthread_mutex_init(&nr_if_inst[Mod_id]->if_mutex,NULL)==0,
+                "allocation of nr_if_inst[%d]->if_mutex fails\n",Mod_id);
   }
 
-  return if_inst[Mod_id];
+  return nr_if_inst[Mod_id];
 }
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index edaef6d1ce4b574f987a8d4392db4457eebc51c4..435d7e8d30afb38169e0627e1f4113382f66d535 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,14 +59,15 @@ 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);
 
 }
 
 //  L2 Abstraction Layer
-int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint32_t sibs_mask, uint8_t *pduP, uint32_t pdu_len){
-  return nr_ue_decode_sib1(module_id, cc_id, gNB_index, sibs_mask, pduP, pdu_len);
+int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint8_t ack_nack, uint8_t *pduP, uint32_t pdu_len){
+  return nr_ue_decode_BCCH_DL_SCH(module_id, cc_id, gNB_index, ack_nack, pduP, pdu_len);
 }
 
 //  L2 Abstraction Layer
@@ -76,6 +81,7 @@ int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t
 // Note: sdu should always be processed because data and timing advance updates are transmitted by the UE
 int8_t handle_dlsch (nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){
 
+  update_harq_status(dl_info, pdu_id);
   nr_ue_send_sdu(dl_info, ul_time_alignment, pdu_id);
 
   return 0;
@@ -88,11 +94,21 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
   module_id_t module_id = ul_info->module_id;
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
 
-  ret = nr_ue_scheduler(NULL, ul_info);
+  if (ul_info->ue_sched_mode == ONLY_PUSCH) {
+    ret = nr_ue_scheduler(NULL, ul_info);
+    return 0;
+  }
+  else if (ul_info->ue_sched_mode == SCHED_ALL)
+    ret = nr_ue_scheduler(NULL, ul_info);
+
+  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(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra)
+  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);
 
+  if (is_nr_UL_slot(tdd_UL_DL_ConfigurationCommon, ul_info->slot_tx, mac->frame_type))
+    nr_ue_pucch_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->thread_id);
+
   switch(ret){
   case UE_CONNECTION_OK:
     break;
@@ -154,42 +170,32 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
           dl_info->rx_ind->number_pdus);
 
         switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
-
-        case FAPI_NR_RX_PDU_TYPE_MIB:
-
-          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;
-
-          break;
-
-        case FAPI_NR_RX_PDU_TYPE_SIB:
-
-          ret_mask |= (handle_bcch_dlsch(dl_info->module_id,
-                       dl_info->cc_id, dl_info->gNB_index,
-                      (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.sibs_mask,
-                      (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu,
-                      (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB;
-
-          break;
-
-        case FAPI_NR_RX_PDU_TYPE_DLSCH:
-
-          ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
-
-          break;
-
-        case FAPI_NR_RX_PDU_TYPE_RAR:
-
-          ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_RAR;
-
-          break;
-
-        default:
-          break;
+          case FAPI_NR_RX_PDU_TYPE_SSB:
+            mac->ssb_rsrp_dBm = (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.rsrp_dBm;
+            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)->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;
+          case FAPI_NR_RX_PDU_TYPE_SIB:
+            ret_mask |= (handle_bcch_dlsch(dl_info->module_id,
+                                           dl_info->cc_id, dl_info->gNB_index,
+                                           (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.ack_nack,
+                                           (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu,
+                                           (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB;
+            break;
+          case FAPI_NR_RX_PDU_TYPE_DLSCH:
+            ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
+            break;
+          case FAPI_NR_RX_PDU_TYPE_RAR:
+            ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_RAR;
+            break;
+          default:
+            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..1ba8238f1ec7d04c262bb1cc2df78e4889ebc246 100755
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
@@ -39,6 +39,12 @@
 
 typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t;
 
+typedef enum {
+  ONLY_PUSCH,
+  NOT_PUSCH,
+  SCHED_ALL,
+} NR_UE_SCHED_MODE_t;
+
 typedef struct {
     /// module id
   module_id_t module_id;
@@ -100,6 +106,9 @@ typedef struct {
 
     /// dci reception indication structure
     fapi_nr_dci_indication_t *dci_ind;
+
+    NR_UE_SCHED_MODE_t ue_sched_mode;
+
 } nr_uplink_indication_t;
 
 // Downlink subframe P7
@@ -221,13 +230,21 @@ 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
    \param pdu_len   length(bytes) of pdu
    \param pduP      pointer to pdu*/
-int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint32_t sibs_mask, uint8_t *pduP, uint32_t pdu_len);
+int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint8_t ack_nack, uint8_t *pduP, uint32_t pdu_len);
 
 int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
 
diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c
index d98c603d78444f2951f2a47bf6413506a959ad83..ed3c9a5b7d2f7e84d59fc797e7730f0c1fa3c714 100644
--- a/openair2/PHY_INTERFACE/IF_Module.c
+++ b/openair2/PHY_INTERFACE/IF_Module.c
@@ -7,8 +7,8 @@
 #include "nfapi/oai_integration/vendor_ext.h"
 #define MAX_IF_MODULES 100
 
-IF_Module_t *if_inst[MAX_IF_MODULES];
-Sched_Rsp_t Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs];
+static IF_Module_t *if_inst[MAX_IF_MODULES];
+static Sched_Rsp_t Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs];
 
 extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind);
 extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
@@ -19,6 +19,8 @@ extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind);
 extern uint16_t sf_ahead;
 extern UL_RCC_IND_t  UL_RCC_INFO;
 
+extern RAN_CONTEXT_t RC;
+
 uint16_t frame_cnt=0;
 void handle_rach(UL_IND_t *UL_info) {
   int i;
@@ -685,7 +687,7 @@ static void dump_dl(Sched_Rsp_t *d) {
 /* debug utility functions end                                              */
 /****************************************************************************/
 
-void UL_indication(UL_IND_t *UL_info, L1_rxtx_proc_t *proc) {
+void UL_indication(UL_IND_t *UL_info, void *proc) {
   AssertFatal(UL_info!=NULL,"UL_INFO is null\n");
 #ifdef DUMP_FAPI
   dump_ul(UL_info);
diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h
index 1470cbc0060117ee9af62273bf964684a4be3bb5..096979c4fd195595ac9e6076d3d06d686cfa5745 100644
--- a/openair2/PHY_INTERFACE/IF_Module.h
+++ b/openair2/PHY_INTERFACE/IF_Module.h
@@ -37,7 +37,6 @@
 #include <sched.h>
 //#include "openair1/PHY/LTE_TRANSPORT/transport_eNB.h"
 #include "nfapi_interface.h"
-#include "platform_constants.h"
 #include "platform_types.h"
 #include <common/utils/threadPool/thread-pool.h>
 
@@ -135,64 +134,13 @@ typedef struct {
     uint8_t Mod_id;
     int CC_id;
     nfapi_config_request_t *cfg;
-}PHY_Config_t;
+} PHY_Config_t;
 #include <targets/ARCH/COMMON/common_lib.h>
-/// Context data structure for RX/TX portion of subframe processing
-typedef struct {
-  /// Component Carrier index
-  uint8_t              CC_id;
-  /// timestamp transmitted to HW
-  openair0_timestamp timestamp_tx;
-  openair0_timestamp timestamp_rx;
-  /// subframe to act upon for transmission
-  int subframe_tx;
-  /// subframe to act upon for reception
-  int subframe_rx;
-  /// frame to act upon for transmission
-  int frame_tx;
-  /// frame to act upon for reception
-  int frame_rx;
-  int frame_prach;
-  int subframe_prach;
-  int frame_prach_br;
-  int subframe_prach_br;
-  /// \brief Instance count for RXn-TXnp4 processing thread.
-  /// \internal This variable is protected by \ref mutex_rxtx.
-  int instance_cnt;
-  /// pthread structure for RXn-TXnp4 processing thread
-  pthread_t pthread;
-  /// pthread attributes for RXn-TXnp4 processing thread
-  pthread_attr_t attr;
-  /// condition variable for tx processing thread
-  pthread_cond_t cond;
-  /// mutex for RXn-TXnp4 processing thread
-  pthread_mutex_t mutex;
-  /// scheduling parameters for RXn-TXnp4 thread
-  struct sched_param sched_param_rxtx;
-
-  /// \internal This variable is protected by \ref mutex_RUs.
-  int instance_cnt_RUs;
-  /// condition variable for tx processing thread
-  pthread_cond_t cond_RUs;
-  /// mutex for RXn-TXnp4 processing thread
-  pthread_mutex_t mutex_RUs;
-  tpool_t *threadPool;
-  int nbEncode;
-  int nbDecode;
-  notifiedFIFO_t *respEncode;
-  notifiedFIFO_t *respDecode;
-    pthread_mutex_t mutex_emulateRF;
-  int instance_cnt_emulateRF;
-  pthread_t pthread_emulateRF;
-  pthread_attr_t attr_emulateRF;
-  pthread_cond_t cond_emulateRF;
-  int first_rx;
-} L1_rxtx_proc_t;
 
 typedef struct IF_Module_s{
 //define the function pointer
-  void (*UL_indication)(UL_IND_t *UL_INFO, L1_rxtx_proc_t *proc);
-  void (*schedule_response)(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
+  void (*UL_indication)(UL_IND_t *UL_INFO, void *proc);
+  void (*schedule_response)(Sched_Rsp_t *Sched_INFO, void *proc);
   void (*PHY_config_req)(PHY_Config_t* config_INFO);
 
   void (*PHY_config_update_sib2_req)(PHY_Config_t* config_INFO);
@@ -209,7 +157,7 @@ void IF_Module_kill(int Mod_id);
 
 /*Interface for uplink, transmitting the Preamble(list), ULSCH SDU, NAK, Tick (trigger scheduler)
  */
-void UL_indication(UL_IND_t *UL_INFO, L1_rxtx_proc_t *proc);
+void UL_indication(UL_IND_t *UL_INFO, void *proc);
 
 /*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/
 void Schedule_Response(Sched_Rsp_t *Sched_INFO);
diff --git a/openair2/PHY_INTERFACE/mac_phy_primitives.c b/openair2/PHY_INTERFACE/mac_phy_primitives.c
deleted file mode 100644
index 06e06d096dc53caf0066bbdd26f6546dd5f7f9ee..0000000000000000000000000000000000000000
--- a/openair2/PHY_INTERFACE/mac_phy_primitives.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-/*________________________mac_phy_primitives.c________________________
-
- Authors : Hicham Anouar, Raymond Knopp
- Company : EURECOM
- Emails  : anouar@eurecom.fr,  knopp@eurecom.fr
-________________________________________________________________*/
-
-
-//#include "openair_extern.h"
-
-#ifdef MAC_CONTEXT
-#include "LAYER2/MAC/defs.h"
-#include "LAYER2/MAC/extern.h"
-//#include "extern.h"
-#include "defs.h"
-#endif //MAC_CONTEXT
-
-
-//#define DEBUG_UE_DECODE_SACH
-//#define DEBUG_NODEB_DECODE_SACH
-
-#ifdef PHY_CONTEXT
-#ifdef PHY_EMUL
-#include "extern.h"
-#include "SIMULATION/simulation_defs.h"
-#else //PHY_EMUL
-#include "MAC_INTERFACE/extern.h"
-#endif //PHY_EMUL
-
-void clear_macphy_data_req(unsigned char Mod_id)
-{
-  //msg("CLEAR DATA_REQ\n");
-  unsigned char i;
-
-  Macphy_req_table[Mod_id].Macphy_req_cnt = 0;
-
-  for (i=0; i<NB_REQ_MAX; i++)
-    Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Active = 0;
-}
-
-/*
-unsigned char phy_resources_compare(PHY_RESOURCES *Phy1,PHY_RESOURCES* Phy2 ){
-
-  if(Phy1->Time_alloc==Phy2->Time_alloc && Phy1->Freq_alloc==Phy2->Freq_alloc)// && Phy1->Coding_fmt==Phy2->Coding_fmt && Phy1->Seq_index==Phy2->Seq_index)
-    return 1;
-  else
-    return 0;
-
-}
-*/
-
-MACPHY_DATA_REQ_TABLE_ENTRY* find_data_req_entry(unsigned char Mod_id,MACPHY_REQ_ENTRY_KEY *Search_key)
-{
-
-  unsigned char i;
-
-  //msg("[MAC_PHY]MAC_PHY_REQUEST_CNT=%d\n",Macphy_req_table.Macphy_req_cnt);
-  if (Macphy_req_table[Mod_id].Macphy_req_cnt > 0) {
-#ifdef DEBUG_PHY
-    //    msg("[MACPHY_FIND_REQ] SEARCH KEY=%d\n",Search_key->Key_type);
-#endif //DEBUG_PHY
-    //msg("[MACPHY_FIND_REQ] SEARCH KEY=%d, NB_REQ_MAX=%d\n",Search_key->Key_type,NB_REQ_MAX);
-
-    switch(Search_key->Key_type) {
-    case PDU_TYPE_KEY:
-      for(i=0; i<NB_REQ_MAX; i++) {
-        if ( (Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Pdu_type==Search_key->Key.Pdu_type) &&
-             (Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Active == 1) ) {
-          //msg("[MACPHY_FIND] MACPHY_req_table_entry=%p,idx=%d,Phy_resources %p",       &Macphy_req_table.Macphy_req_table_entry[i],i,Macphy_req_table.Macphy_req_table_entry[i].Macphy_data_req.Phy_Resources_Entry);
-          return(&Macphy_req_table[Mod_id].Macphy_req_table_entry[i]);
-        }
-      }
-
-      break;
-      /*
-      case LCHAN_KEY:
-      for(i=0;i<NB_REQ_MAX;i++){
-      if ((Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Lchan_id.Index==Search_key->Key.Lchan_id->Index) &&
-      (Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Active == 1) )
-      return(&Macphy_req_table[Mod_id].Macphy_req_table_entry[i]);
-      }
-      break;
-
-      case PHY_RESOURCES_KEY:
-      for(i=0;i<NB_REQ_MAX;i++){
-      if(Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Active == 1)
-      if ( ( Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Phy_resources->Time_alloc ==
-        Search_key->Key.Phy_resources.Time_alloc )
-         &&( Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Phy_resources->Freq_alloc ==
-       Search_key->Key.Phy_resources.Freq_alloc )
-         &&( Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.CH_index ==
-      Search_key->CH_index )
-         && ( Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Direction == RX))
-      return(&Macphy_req_table[Mod_id].Macphy_req_table_entry[i]);
-      }
-      break;
-      */
-    }
-  }
-
-#ifndef PHY_EMUL
-  //  msg("[PHY][PHY_MAC] Frame %d : No data request\n",mac_xface->frame);
-#endif //PHY_EMUL
-
-
-  return (MACPHY_DATA_REQ_TABLE_ENTRY*)0;
-
-}
-
-
-
-
-
-
-void print_active_requests(unsigned char Mod_id)
-{
-
-  int i;
-  msg("_________________________INST %d , FRAME %d ACTIVE_REQUESTS_________________\n",Mod_id,mac_xface->frame);
-
-  for (i=0; i<NB_REQ_MAX; i++) {
-
-    if (Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Active == 1) {
-      msg("[MACPHY][DATA][REQ] Request %d: Direction %d, Pdu_type %d\n",
-          i,
-          Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Direction,
-          Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Pdu_type);
-      //    Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Lchan_id.Index);
-      //    Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Phy_resources,
-      //    Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Phy_resources->Time_alloc,
-      //    Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Phy_resources->Freq_alloc);
-      //if(Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Pdu_type==RACH)
-      //msg("[RACH_REQ] Rach_pdu %p, Payload %p\n",Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Dir.Req_rx.Pdu.Rach_pdu,
-      //    Macphy_req_table[Mod_id].Macphy_req_table_entry[i].Macphy_data_req.Dir.Req_rx.Pdu.Rach_pdu->Rach_payload);
-
-    }
-  }
-}
-
-
-/*___________________________________________________________________________________________________*/
-#define RCNT Macphy_req_table[Mod_id].Macphy_req_cnt
-
-MACPHY_DATA_REQ *new_macphy_data_req(unsigned char Mod_id)
-{
-  /*___________________________________________________________________________________________________*/
-  unsigned char i;
-
-
-
-  for (i=0; i<NB_REQ_MAX; i++) {
-    if (Macphy_req_table[Mod_id].Macphy_req_table_entry[(i)%NB_REQ_MAX].Active == 0) {
-      Macphy_req_table[Mod_id].Macphy_req_table_entry[(i)%NB_REQ_MAX].Active = 1;
-      RCNT = (RCNT + 1)%NB_REQ_MAX;
-      //            msg("[MAC_PHY]NEW MAC_REQUEST_CNT=%d,frame %d, Module %d, entry %d \n",Macphy_req_table[Mod_id].Macphy_req_cnt,mac_xface->frame,Mod_id,i);
-      //        Macphy_req_table[Mod_id].Macphy_req_table_entry[i%NB_REQ_MAX].Macphy_data_req.Phy_resources=(PHY_RESOURCES*)malloc16(sizeof(PHY_RESOURCES));
-      return(&Macphy_req_table[Mod_id].Macphy_req_table_entry[i%NB_REQ_MAX].Macphy_data_req);
-    }
-  }
-
-  msg("[OPENAIR][MAC][ERROR] frame %d: No more DATA_REQ !!!!\n",mac_xface->frame);
-
-  print_active_requests(Mod_id);
-  mac_xface->macphy_exit("new_macphy_data_req: no more DATA_REQ");
-  //rt_sleep(nano2count(2000));
-
-  return((MACPHY_DATA_REQ*)0);
-}
-
-
-#endif //PHY_CONTEXT
-
-#ifdef MAC_CONTEXT
-#include "LAYER2/MAC/extern.h"
-
-// Function called by PHY to indicate available data/measurements for MAC
-
-/*___________________________________________________________________________________________________*/
-void macphy_data_ind(unsigned char Mod_id,unsigned char Pdu_type,void *pdu,unsigned short rnti)
-{
-  /*___________________________________________________________________________________________________*/
-  //msg("[OPENAIR][MACPHY] Calling mac_resp In\n");
-
-  int i;
-
-  //  if (Req_rx->crc_status[0]!= -1) {  //CRC_STATUS
-
-  // msg("[OPENAIR][MACPHY] Calling mac_indicate In\n");
-  //     Req_rx->Meas.UL_meas=&UL_meas[Mod_id];
-  //   Req_rx->Meas.DL_meas=&DL_meas[Mod_id];
-
-  switch (Pdu_type) {
-  case ULSCH:
-
-    //        msg("[OPENAIR][MACPHY] Received RACH, Sending to MAC\n");
-    nodeb_decode_ulsch(Mod_id,(ULSCH_PDU *)pdu,rnti);
-
-    break;
-
-  case DLSCH:
-#ifdef DEBUG_UE_DECODE_SACH
-    msg("[MAC][UE][MAC_PHY] TTI %d Inst %d\n",mac_xface->frame,Mod_id);
-#endif
-
-    //      ue_decode_dlsch(Mod_id-NB_CH_INST,
-    //          (DLSCH_PDU *)pdu,rnti);
-
-    break;
-
-  default:
-    break;
-  }
-
-  //    msg("Freeing Req %p\n",Macphy_data_req_table_entry);
-  //  }
-
-}
-
-
-
-
-
-/*PHY_RESOURCES_TABLE_ENTRY *new_phy_resources() {
-
-
-  unsigned char i;
-
-  //msg("[OPENAIR][PHY][MAC Interface] New Phy Resource, cnt %d\n",Phy_resources_table.Phy_resources_cnt);
-
-  for (i=0;i<NB_PHY_RESOURCES_MAX;i++){
-
-    if (Phy_resources_table.Phy_resources_table_entry[(i+Phy_resources_table.Phy_resources_cnt+1)%NB_PHY_RESOURCES_MAX].Active == 0) {
-      Phy_resources_table.Phy_resources_table_entry[(i+Phy_resources_table.Phy_resources_cnt+1)%NB_PHY_RESOURCES_MAX].Active = 1;
-      Phy_resources_table.Phy_resources_cnt = (Phy_resources_table.Phy_resources_cnt + 1)%NB_PHY_RESOURCES_MAX;
-      //  msg("[OPENAIR][PHY][MAC Interface] NEW PHY_RESOURCES: Taking index %d\n\n",(i+Phy_resources_table.Phy_resources_cnt+1)%NB_PHY_RESOURCES_MAX);
-
-      return(&Phy_resources_table.Phy_resources_table_entry[(i+Phy_resources_table.Phy_resources_cnt)%NB_PHY_RESOURCES_MAX]);
-    }
-  }
-  msg("[OPENAIR][MAC][ERROR] No more PHY_RESOURCES !!!!\n");
-  exit(-1);
-}
-*/
-
-#endif //MAC_CONTEXT
-
-
-// Measurements, etc ..
-
-//short phy_resource_cnt = 0, macphy_data_req_cnt = 0, macphy_data_ind_cnt = 0;
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/openair2/PHY_INTERFACE/mac_phy_primitives.h b/openair2/PHY_INTERFACE/mac_phy_primitives.h
deleted file mode 100644
index 889cb503dca1d91088401f20c8ee963433512e35..0000000000000000000000000000000000000000
--- a/openair2/PHY_INTERFACE/mac_phy_primitives.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-/*________________________mac_phy_primitives.h________________________
-
- Authors : Hicham Anouar, Raymond Knopp
- Company : EURECOM
- Emails  : anouar@eurecom.fr,  knopp@eurecom.fr
-________________________________________________________________*/
-
-
-#ifndef __MAC_PHY_PRIMITIVES_H__
-#    define __MAC_PHY_PRIMITIVES_H__
-
-#include "../LAYER2/MAC/defs.h"
-
-
-/**@defgroup _mac_phy_primitives_ MAC Layer Primitives for Communications with PHY
- *@ingroup w3g4f_mac_layer_
- *@{
-
-This subclause describes the primitives for communications between the MAC and PHY sub-layers.
-
-The primitives for dynamic MAC-PHY PDU exchange (Transport channel interface) are:
-
-- MACPHY_DATA_REQ: transfers or requests a PDU from PHY.  The data is passed along with the dynamic PHY transmission
-format (coding and modulation, time/freq/space resource allocation)
-
-- MACPHY_DATA_IND: Function call (by PHY) to deliver a new PDU and corresponding measurements to MAC.  This implicitly confirms the MACPHY_DATA_REQ by
-filling the fields of the request (TX or RX) with the data and measurements.
-
-One primitive is used for semi-static configuration (during logical channel establishment)
-relaying the puncturing/repetition patterns for HARQ:
-
-- MACPHY_CONFIG_SACH_HARQ_REQ (still to be defined...)
-
-The primitive for static (re)configuration is:
-- MACPHY_CONFIG_REQ : This primitive transports the initial configuration during the setup phase of equipment, both for CH and UE.
-Static configuration is used during the initialization phase of the equipment.  For a CH, it is done prior to any communication.  For a UE, some
-structures may be set after receiving configuration information from the network via the BCCH/CCCH.
-*/
-
-
-
-
-/*! \brief MACPHY-DATA-REQ_RX structure is used to request transfer a new PDU from PHY corresponding to a particular transport channel*/
-typedef struct {
-  int crc_status[MAX_NUMBER_TB_PER_LCHAN];                   /*!< This field indicates the CRC status of the PDU upon reception from PHY*/
-  unsigned char num_tb;                /*!< This field indicates the number of transport blocks to be received*/
-  unsigned short tb_size_bytes;        /*!< This field indicates the number of bytes per transpor block*/
-  unsigned int Active_process_map;   /*!< HARQ indicator for active processes*/
-  union {
-    CHBCH_PDU   *Chbch_pdu;        /*!< This is a pointer to CHBCH data*/
-    DL_SACH_PDU *DL_sach_pdu;      /*!< This is a pointer to DL_SACH data*/
-    UL_SACH_PDU *UL_sach_pdu;      /*!< This is a pointer to UL_SACH data*/
-    RACH_PDU    *Rach_pdu;         /*!< This is a pointer to RACH data*/
-    MRBCH_PDU   *Mrbch_pdu;        /*!< This is a pointer to MRBCH data*/
-  } Pdu;
-  union {
-    DL_MEAS *DL_meas;   /*!< This is an array of pointers to the current measurements of DL quality at UE (indexed by CH_id) */
-    UL_MEAS *UL_meas;   /*!< This is an array of pointers to the current measurements of UL quality at Node-B (indexed by user_id) */
-  } Meas;
-} MACPHY_DATA_REQ_RX;
-
-
-/*! \brief MACPHY-DATA-REQ_TX structure is used to transfer a new PDU to PHY corresponding to a particular transport channel*/
-typedef struct {
-  unsigned char num_tb;             /*!< This field indicates the number of transport blocks to be received*/
-  unsigned short tb_size_bytes;     /*!< This field indicates the number of bytes per transpor block*/
-  unsigned int Active_process_map;   /*!< HARQ indicator for active processes*/
-  unsigned int New_process_map;      /*!< HARQ indicator for new processes*/
-  //  unsigned char round_indices_tx;
-  union {
-    CHBCH_PDU   *Chbch_pdu;      /*!< pointer to CHBCH data */
-    DL_SACH_PDU DL_sach_pdu;    /*!< pointer to DL_SACH data*/
-    UL_SACH_PDU UL_sach_pdu;    /*!< pointer to UL_SACH data*/
-    RACH_PDU Rach_pdu;  //H.A   /*!< pointer to RACH data */
-    MRBCH_PDU   *Mrbch_pdu;     /*!< pointer to MRBCH data */
-  } Pdu;
-} MACPHY_DATA_REQ_TX;
-
-/*! \brief MACPHY-DATA-REQ primitive is used to transfer a new PDU to PHY corresponding to a particular transport channel*/
-typedef struct {
-  unsigned char Direction;
-  unsigned char Pdu_type;                 /*!< This field indicates the type of PDU requested */
-  LCHAN_ID      Lchan_id;                 /*!< This field indicates the flow id of the PDU */
-  PHY_RESOURCES *Phy_resources;           /*!< This field indicates to PHY the physical resources */
-  unsigned int format_flag;               /*!< This field indicates to PHY something about a SACH, e.g. presense of SACCH*/
-  union {
-    MACPHY_DATA_REQ_RX Req_rx;            /*!< This field contains the request corresponding to an RX resource*/
-    MACPHY_DATA_REQ_TX Req_tx;            /*!< This field contains the request corresponding to a TX resource*/
-  } Dir;
-} MACPHY_DATA_REQ;
-
-/*!\fn void macphy_data_ind(unsigned char Mod_id,MACPHY_DATA_REQ_RX *Req_rx,unsigned char Pdu_type,unsigned short Index);
-\brief MACPHY_DATA_IND function call.  Called by PHY to upload PDU and measurements in response to a MACPHY_DATA_REQ_RX.
-@param Mod_id MAC instance ID (only useful if multiple MAC instances run in the same machine)
-@param Req_rx Pointer to MACPHY_DTA_REQ_RX received previously
-@param Pdu_type Type of PDU (redundant!)
-@param Index CH Index for CH, UEid for UE
-*/
-void macphy_data_ind(unsigned char Mod_id,
-                     MACPHY_DATA_REQ_RX *Req_rx,
-                     unsigned char Pdu_type,
-                     unsigned short Index);
-
-/*! \brief MACPHY-CONFIG-REQ primitive is used to configure a new instance of OpenAirInterface (static configuration) during initialization*/
-typedef struct {
-  PHY_FRAMING Phy_framing;   /*!< Framing Configuration*/
-  PHY_CHSCH Phy_chsch[8];    /*!< CHSCH Static Configuration*/
-  PHY_CHBCH Phy_chbch;       /*!< CHBCH Static Configuration*/
-  PHY_SCH   Phy_sch[8];      /*!< SCH Static Configuration*/
-  PHY_SACH  Phy_sach;        /*!< SACH Statuc Configuration*/
-} MACPHY_CONFIG_REQ;
-
-/*! \brief MACPHY-CONFIG-SACH-HARQ-REQ primitive is used to configure a new SACH transport channel (dynamic configuration) during logical channel establishment*/
-//typedef struct {
-//  LCHAN_ID Lchan_id;             /*!< This is the identifier of the SACH, which should simply be the logical channel id*/
-//  HARQ_PARAMS Harq_params;           /*!< This is the set of HARQ parameters corresponding to the QoS description of the logical channel*/
-//} MACPHY_CONFIG_SACH_HARQ_REQ;
-
-/** @} */
-
-#define MAX_NUMBER_OF_MAC_INSTANCES 16
-
-#define NULL_PDU 255
-#define CHBCH 0
-#define DL_SACH 1
-#define UL_SACH 2
-#define UL_SACCH_SACH 3
-#define RACH 4
-#define MRBCH 5
-
-
-#define NUMBER_OF_SUBBANDS 64
-#define LCHAN_KEY 0
-#define PDU_TYPE_KEY 1
-#define PHY_RESOURCES_KEY 2
-
-typedef struct Macphy_req_entry_key {
-  unsigned char Key_type;
-  union {
-    LCHAN_ID *Lchan_id;  //SACH, EMULATION
-    unsigned char Pdu_type;//CHBCH, RACH, EMULATION
-    PHY_RESOURCES Phy_resources;//REAL PHY
-  } Key;
-} MACPHY_REQ_ENTRY_KEY;
-
-/** @ingroup _PHY_TRANSPORT_CHANNEL_PROCEDURES_
- * @{
-\var typedef struct Macphy_data_req_table_entry {
-  MACPHY_DATA_REQ Macphy_data_req;
-  unsigned char Active;
-} MACPHY_DATA_REQ_TABLE_ENTRY;
-\brief An entry in the MACPHY_DATA_REQ Table.
-*/
-
-typedef struct Macphy_data_req_table_entry {
-  /// The MACPHY_DATA_REQ Structure itself
-  MACPHY_DATA_REQ Macphy_data_req;
-  /// Active flag.  Active=1 means that the REQ is pending.
-  unsigned char Active;
-} MACPHY_DATA_REQ_TABLE_ENTRY;
-
-/*!\var typedef struct  {
-  MACPHY_DATA_REQ_TABLE_ENTRY *Macphy_req_table_entry;
-  unsigned int Macphy_req_cnt;
-} MACPHY_DATA_REQ_TABLE
-\brief The MACPHY_DATA_REQ interface between MAC and PHY.  This table stores the pending requests from MAC which are serviced by PHY.  The pointer Macphy_req_table_entry points
-to an array of idle reqests allocated during initialization of the MAC-layer.
-*/
-
-typedef struct  {
-  /// Pointer to a MACPHY_DATA_REQ
-  MACPHY_DATA_REQ_TABLE_ENTRY *Macphy_req_table_entry;
-  /// Number of active requests
-  unsigned int Macphy_req_cnt;
-} MACPHY_DATA_REQ_TABLE;
-
-/** @} */
-
-/*typedef struct Tx_Phy_Pdu{                              //H.A
-  PHY_RESOURCES *Phy_resources;
-  MACPHY_DATA_IND *Macphy_data_ind;
-}T_PHY_PDU;
-
-typedef struct Rx_Phy_Pdu{                              //H.A
-  PHY_RESOURCES *Phy_resources;
-  char *Phy_payload;
-  }RX_PHY_PDU;*/
-
-
-typedef struct GRANTED_LCHAN_TABLE_ENTRY {
-  PHY_RESOURCES *Phy_resources;
-  LCHAN_ID Lchan_id;
-} GRANTED_LCHAN_TABLE_ENTRY;
-
-void clear_macphy_data_req(uint8_t);
-//void clean_macphy_interface(void);
-unsigned char phy_resources_compare(PHY_RESOURCES *,PHY_RESOURCES*);
-MACPHY_DATA_REQ_TABLE_ENTRY* find_data_req_entry(uint8_t,MACPHY_REQ_ENTRY_KEY*);
-void print_active_requests(uint8_t);
-void mac_process_meas_ul(uint8_t Mod_id,UL_MEAS *UL_meas, uint16_t Index);
-void mac_process_meas_dl(uint8_t Mod_id,DL_MEAS *DL_meas, uint16_t Index);
-
-
-
-
-MACPHY_DATA_REQ *new_macphy_data_req(uint8_t);
-//PHY_RESOURCES_TABLE_ENTRY *new_phy_resources(void);
-//MACPHY_DATA_IND *new_macphy_data_ind(void);
-#endif
-
-
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 21740016b11a6ff3e141f8675df5b3f7903a47f7..c212075934871c6b6a1994244eb0c490585f090a 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -54,6 +54,7 @@ extern nfapi_tx_request_pdu_t* tx_request_pdu[1023][10][10];
 
 extern uint16_t sf_ahead;
 
+static eth_params_t         stub_eth_params;
 void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
 void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
 
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h
index 547fc2dfc432ac3fe1758cfa5d51798d1928532b..bdf8872371e5e7f6b752a407f33f24d7ffc37497 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.h
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.h
@@ -26,16 +26,7 @@ extern nfapi_tx_request_pdu_t* tx_request_pdu_list;
 extern nfapi_dl_config_request_t* dl_config_req;
 extern nfapi_ul_config_request_t* ul_config_req;
 extern nfapi_hi_dci0_request_t* hi_dci0_req;
-
-int	tx_req_num_elems;
-
-//below 2 difinitions move to lte-ue.c to add initialization when difinition.
-//int next_ra_frame;
-//module_id_t next_Mod_id;
-eth_params_t         stub_eth_params;
-
-
-
+extern int	tx_req_num_elems;
 
 // This function should return all the sched_response config messages which concern a specific UE. Inside this
 // function we should somehow make the translation of config message's rnti to Mod_ID.
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 d9682b466f2f98148bc920ac221c26d63a93097a..0b767b8ad6efa203c3317cb8c876a35bb7adf803 100644
--- a/openair2/RRC/LTE/L2_interface.c
+++ b/openair2/RRC/LTE/L2_interface.c
@@ -49,8 +49,6 @@
 #include "intertask_interface.h"
 
 #include "flexran_agent_extern.h"
-#undef C_RNTI // C_RNTI is used in F1AP generated code, prevent preprocessor replace
-//#include "f1ap_du_rrc_message_transfer.h"
 #include "openair2/F1AP/f1ap_du_rrc_message_transfer.h"
 
 extern RAN_CONTEXT_t RC;
@@ -316,8 +314,9 @@ mac_rrc_data_ind(
       UE_id,
       rntiP,
       sduP,
-      sdu_lenP
-    );
+      sdu_lenP,
+      NULL,
+      0);
     return(0);
   }
 
@@ -349,12 +348,12 @@ mac_rrc_data_ind(
     ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id],rntiP);
 
     if(ue_context_p) {
-      if (ue_context_p->ue_context.Status != RRC_RECONFIGURED) {
-        LOG_E(RRC,"[eNB %d] Received C-RNTI ,but UE %x status(%d) not RRC_RECONFIGURED\n",module_idP,rntiP,ue_context_p->ue_context.Status);
+      if (ue_context_p->ue_context.StatusRrc != RRC_RECONFIGURED) {
+        LOG_E(RRC,"[eNB %d] Received C-RNTI ,but UE %x status(%d) not RRC_RECONFIGURED\n",module_idP,rntiP,ue_context_p->ue_context.StatusRrc);
         return (-1);
       } 
       rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,ue_context_p,0);
-      ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+      ue_context_p->ue_context.StatusRrc = RRC_RECONFIGURED;
     }
   }
 
@@ -376,7 +375,7 @@ mac_eNB_get_rrc_status(
   ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP], rntiP);
 
   if (ue_context_p != NULL) {
-    return(ue_context_p->ue_context.Status);
+    return(ue_context_p->ue_context.StatusRrc);
   } else {
     return RRC_INACTIVE;
   }
diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c
index 61bce26b2c1cc2d006ad67bcba98b06630f3ef16..ce26aeef871a192f171d994e7449fdad95b63a72 100644
--- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c
@@ -2728,7 +2728,7 @@ do_RRCConnectionSetup(
   //  assign_enum(&physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax,
   //SchedulingRequestConfig__setup__dsr_TransMax_n4);
   //  assign_enum(&physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = SchedulingRequestConfig__setup__dsr_TransMax_n4;
-  physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = LTE_SchedulingRequestConfig__setup__dsr_TransMax_n4;
+  physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = LTE_SchedulingRequestConfig__setup__dsr_TransMax_n64;
   rrcConnectionSetup->rrc_TransactionIdentifier = Transaction_id;
   rrcConnectionSetup->criticalExtensions.present = LTE_RRCConnectionSetup__criticalExtensions_PR_c1;
   rrcConnectionSetup->criticalExtensions.choice.c1.present = LTE_RRCConnectionSetup__criticalExtensions__c1_PR_rrcConnectionSetup_r8 ;
@@ -3220,56 +3220,58 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
   dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count=0;
   ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list,
                    &rat);
-
-  /* request NR configuration */
   LTE_UECapabilityEnquiry_r8_IEs_t *r8 = &dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8;
   LTE_UECapabilityEnquiry_v8a0_IEs_t r8_a0;
   LTE_UECapabilityEnquiry_v1180_IEs_t r11_80;
   LTE_UECapabilityEnquiry_v1310_IEs_t r13_10;
   LTE_UECapabilityEnquiry_v1430_IEs_t r14_30;
   LTE_UECapabilityEnquiry_v1510_IEs_t r15_10;
+  OCTET_STRING_t req_freq;
 
-  memset(&r8_a0, 0, sizeof(r8_a0));
-  memset(&r11_80, 0, sizeof(r11_80));
-  memset(&r13_10, 0, sizeof(r13_10));
-  memset(&r14_30, 0, sizeof(r14_30));
-  memset(&r15_10, 0, sizeof(r15_10));
+  if (nr_band>0) {
 
-  r8->nonCriticalExtension = &r8_a0;
-  r8_a0.nonCriticalExtension = &r11_80;
-  r11_80.nonCriticalExtension = &r13_10;
-  r13_10.nonCriticalExtension = &r14_30;
-  r14_30.nonCriticalExtension = &r15_10;
+    /* request NR configuration */
 
-  /* TODO: no hardcoded values here */
+    memset(&r8_a0, 0, sizeof(r8_a0));
+    memset(&r11_80, 0, sizeof(r11_80));
+    memset(&r13_10, 0, sizeof(r13_10));
+    memset(&r14_30, 0, sizeof(r14_30));
+    memset(&r15_10, 0, sizeof(r15_10));
 
-  nsa_band_list = (NR_FreqBandList_t *)calloc(1, sizeof(NR_FreqBandList_t));
+    r8->nonCriticalExtension = &r8_a0;
+    r8_a0.nonCriticalExtension = &r11_80;
+    r11_80.nonCriticalExtension = &r13_10;
+    r13_10.nonCriticalExtension = &r14_30;
+    r14_30.nonCriticalExtension = &r15_10;
 
-  nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t));
-  nsa_band->present = NR_FreqBandInformation_PR_bandInformationEUTRA;
-  nsa_band->choice.bandInformationEUTRA = (NR_FreqBandInformationEUTRA_t *) calloc(1, sizeof(NR_FreqBandInformationEUTRA_t));
-  nsa_band->choice.bandInformationEUTRA->bandEUTRA = eutra_band;
-  ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band);
+    /* TODO: no hardcoded values here */
 
-  nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t));
-  nsa_band->present = NR_FreqBandInformation_PR_bandInformationNR;
-  nsa_band->choice.bandInformationNR = (NR_FreqBandInformationNR_t *) calloc(1, sizeof(NR_FreqBandInformationNR_t));
-  if(nr_band > 0)
+    nsa_band_list = (NR_FreqBandList_t *)calloc(1, sizeof(NR_FreqBandList_t));
+
+    nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t));
+    nsa_band->present = NR_FreqBandInformation_PR_bandInformationEUTRA;
+    nsa_band->choice.bandInformationEUTRA = (NR_FreqBandInformationEUTRA_t *) calloc(1, sizeof(NR_FreqBandInformationEUTRA_t));
+    nsa_band->choice.bandInformationEUTRA->bandEUTRA = eutra_band;
+    ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band);
+
+    nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t));
+    nsa_band->present = NR_FreqBandInformation_PR_bandInformationNR;
+    nsa_band->choice.bandInformationNR = (NR_FreqBandInformationNR_t *) calloc(1, sizeof(NR_FreqBandInformationNR_t));
+  //if(nr_band > 0)
     nsa_band->choice.bandInformationNR->bandNR = nr_band;
-  else
-    nsa_band->choice.bandInformationNR->bandNR = 78;
-  ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band);
+  //else
+  //  nsa_band->choice.bandInformationNR->bandNR = 78;
+    ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band);
 
-  OCTET_STRING_t req_freq;
   //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 };  // bands 7 & nr78
-  unsigned char req_freq_buf[1024];
-  enc_rval = uper_encode_to_buffer(&asn_DEF_NR_FreqBandList,
-                              NULL,
-                              (void *)nsa_band_list,
-                              req_freq_buf,
-                              1024);
+    unsigned char req_freq_buf[1024];
+    enc_rval = uper_encode_to_buffer(&asn_DEF_NR_FreqBandList,
+                                NULL,
+                                (void *)nsa_band_list,
+                                req_freq_buf,
+                                1024);
 
-  xer_fprint(stdout, &asn_DEF_NR_FreqBandList, (void *)nsa_band_list);
+    xer_fprint(stdout, &asn_DEF_NR_FreqBandList, (void *)nsa_band_list);
 
 
 
@@ -3280,14 +3282,16 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
 //0x01, 0x60, 0x18, 0x05, 0x80, 0xc0, 0x04, 0x04, 0xc1, 0x2c, 0x10, 0x08, 0x20, 0x30, 0x40, 0xe0, 0x82, 0x40, 0x28, 0x80, 0x9a
 //  };
 
-  req_freq.buf = req_freq_buf;
-  req_freq.size = (enc_rval.encoded+7)/8;
+    req_freq.buf = req_freq_buf;
+    req_freq.size = (enc_rval.encoded+7)/8;
 //  req_freq.size = 21;
 
-  r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq;
-  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
-    xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void *)&dl_dcch_msg);
+    r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq;
+    // Add request for eutra-nr 
   }
+//  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+    xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void *)&dl_dcch_msg);
+//  }
 
   enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message,
                                    NULL,
diff --git a/openair2/RRC/LTE/defs_NB_IoT.h b/openair2/RRC/LTE/defs_NB_IoT.h
index 91dc7aafd4396ccec1f11ad2a4dce7e5f03ecdad..3907d2321d89aa6f2ee66ccfdb2c0211c5f9cbe8 100644
--- a/openair2/RRC/LTE/defs_NB_IoT.h
+++ b/openair2/RRC/LTE/defs_NB_IoT.h
@@ -148,7 +148,7 @@ typedef struct UE_RRC_INFO_NB_IoT_s {
 //Measurement Report not supported in NB-IoT
 
 #define PAYLOAD_SIZE_MAX 1024
-#define RRC_BUF_SIZE 255
+#define RRC_BUF_SIZE 8192
 #define UNDEF_SECURITY_MODE 0xff
 #define NO_SECURITY_MODE 0x20
 
@@ -211,13 +211,13 @@ typedef struct RB_INFO_TABLE_ENTRY_NB_IoT_s {
   RB_INFO_NB_IoT Rb_info;
   uint8_t Active;
   uint32_t Next_check_frame;
-  uint8_t Status;
+  uint8_t status;
 } RB_INFO_TABLE_ENTRY_NB_IoT;
 
 typedef struct SRB_INFO_TABLE_ENTRY_NB_IoT_s {
   SRB_INFO_NB_IoT Srb_info;
   uint8_t Active;
-  uint8_t Status;
+  uint8_t status;
   uint32_t Next_check_frame;
 } SRB_INFO_TABLE_ENTRY_NB_IoT;
 
@@ -269,7 +269,7 @@ typedef struct eNB_RRC_UE_NB_IoT_s {
   e_LTE_CipheringAlgorithm_r12     ciphering_algorithm; //Specs. TS 36.331 V14.1.0 pag 432 Change position of chipering enumerative w.r.t previous version
   e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
 
-  uint8_t                            Status;
+  uint8_t                            status;
   rnti_t                             rnti;
   uint64_t                           random_ue_identity;
 
diff --git a/openair2/RRC/LTE/plmn_data.h b/openair2/RRC/LTE/plmn_data.h
index 97dc94343b613365709d2840c614ec03f3f73388..701bcaf764c1bf2b8abae392c2e5d25895472d5c 100644
--- a/openair2/RRC/LTE/plmn_data.h
+++ b/openair2/RRC/LTE/plmn_data.h
@@ -2231,7 +2231,8 @@ static const plmn_data_t plmn_data[] = {
   /*
   310   900     Mid-Rivers Communications   Mid-Rivers Wireless   Operational
   */
-  {310,   910,    "Verizon Wireless",   "Verizon USA"}
+  {310,   910,    "Verizon Wireless",   "Verizon USA"},
+  {0,0,"",""}
   /*
   310   920     Get Mobile    Inactive
   310   930     Copper Valley Wireless    Inactive
diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c
index c57cec6ba5eaba879b2c3874d2d3b4a088834e8e..b2230df623cfe1440044c8339d0f797467ae00ba 100644
--- a/openair2/RRC/LTE/rrc_UE.c
+++ b/openair2/RRC/LTE/rrc_UE.c
@@ -330,7 +330,7 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) {
   preconfigpool->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12    = 0;
   // 40 ms SL Period
   preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.present              = LTE_SubframeBitmapSL_r12_PR_bs40_r12;
-  preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf         = CALLOC(1,5);
+  preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf         = CALLOC(5,1);
   preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size        = 5;
   preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0;
   // last 36 subframes for PSCCH
@@ -338,7 +338,7 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) {
   preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[1]      = 0xFF;
   preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[2]      = 0xFF;
   preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[3]      = 0xFF;
-  preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[5]      = 0xFF;
+  preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[4]      = 0xFF;
   preconfigpool->dataHoppingConfig_r12.hoppingParameter_r12                         = 0;
   preconfigpool->dataHoppingConfig_r12.numSubbands_r12                              = LTE_SL_HoppingConfigComm_r12__numSubbands_r12_ns1;
   preconfigpool->dataHoppingConfig_r12.rb_Offset_r12                                = 0;
@@ -492,7 +492,7 @@ rrc_t310_expiration(
                           UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Srb_info.Srb_id,
                           Rlc_info_um);
       UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Active = 0;
-      UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Status = IDLE;
+      UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].StatusSrb = IDLE;
       UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Next_check_frame = 0;
     }
   } else { // Restablishment procedure
@@ -671,7 +671,7 @@ rrc_ue_establish_srb1(
 {
   // add descriptor from RRC PDU
   UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Active = 1;
-  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG
+  UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].StatusSrb = RADIO_CONFIG_OK;//RADIO CFG
   UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Srb_id = 1;
   // copy default configuration for now
   //  memcpy(&UE_rrc_inst[ue_mod_idP].Srb1[eNB_index].Srb_info.Lchan_desc[0],&DCCH_LCHAN_DESC,LCHAN_DESC_SIZE);
@@ -695,7 +695,7 @@ rrc_ue_establish_srb2(
 {
   // add descriptor from RRC PDU
   UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Active = 1;
-  UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG
+  UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].StatusSrb = RADIO_CONFIG_OK;//RADIO CFG
   UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Srb_info.Srb_id = 2;
   // copy default configuration for now
   //  memcpy(&UE_rrc_inst[ue_mod_idP].Srb2[eNB_index].Srb_info.Lchan_desc[0],&DCCH_LCHAN_DESC,LCHAN_DESC_SIZE);
diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h
index 4f55f94121f1b63c0e64978de42b9cd6aba1652a..1c02c3de46c0a2ed3e559a0e5b99e7aa6ca490f4 100644
--- a/openair2/RRC/LTE/rrc_defs.h
+++ b/openair2/RRC/LTE/rrc_defs.h
@@ -67,6 +67,8 @@
 
 #define MAX_NUM_NEIGH_CELLs 6 /* maximum neighbouring cells number */
 
+#define MAX_NUM_GNB_CELLs 1   /* maximum gNB cells number */
+
 #define UE_STATE_NOTIFICATION_INTERVAL      50
 
 #define IPV4_ADDR    "%u.%u.%u.%u"
@@ -327,7 +329,7 @@ typedef enum SL_TRIGGER_e {
 #define MAX_MEAS_ID 6
 
 #define PAYLOAD_SIZE_MAX 1024
-#define RRC_BUF_SIZE 255
+#define RRC_BUF_SIZE 8192
 #define UNDEF_SECURITY_MODE 0xff
 #define NO_SECURITY_MODE 0x20
 
@@ -517,13 +519,13 @@ typedef struct RB_INFO_TABLE_ENTRY_s {
   RB_INFO Rb_info;
   uint8_t Active;
   uint32_t Next_check_frame;
-  uint8_t Status;
+  uint8_t StatusRb;
 } RB_INFO_TABLE_ENTRY;
 
 typedef struct SRB_INFO_TABLE_ENTRY_s {
   SRB_INFO Srb_info;
   uint8_t Active;
-  uint8_t Status;
+  uint8_t StatusSrb;
   uint32_t Next_check_frame;
 } SRB_INFO_TABLE_ENTRY;
 
@@ -597,7 +599,7 @@ typedef struct eNB_RRC_UE_s {
   LTE_CipheringAlgorithm_r12_t                          ciphering_algorithm;
   e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
 
-  uint8_t                            Status; // RRC status, type enum UE_STATE_t
+  uint8_t                            StatusRrc; // RRC status, type enum UE_STATE_t
   rnti_t                             rnti;
   int                                gnb_rnti;     //RNTI of the UE at the gNB if in ENDC connection
   int                                gnb_x2_assoc_id;
@@ -804,8 +806,13 @@ typedef struct eNB_RRC_INST_s {
   int num_neigh_cells_cc[MAX_NUM_CCs];
   uint32_t neigh_cells_id[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs];
 
+  // gNB cells connected to this eNB
+  int num_gnb_cells;
+  int num_gnb_cells_cc[MAX_NUM_GNB_CELLs];
+  uint32_t gnb_cells_id[MAX_NUM_GNB_CELLs][MAX_NUM_CCs];
+
   // Nr scc freq band and SSB absolute frequency
-  uint32_t nr_neigh_freq_band[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs];
+  uint32_t nr_gnb_freq_band[MAX_NUM_GNB_CELLs][MAX_NUM_CCs];
   int nr_scg_ssb_freq;
 
   // other RAN parameters
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index 526ce129b1e43302ab8e5161e4282c0baba224e9..a03fb51749a74e482bda761a67c727b08011ed2a 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -87,6 +87,7 @@
 
 #include "pdcp.h"
 #include "gtpv1u_eNB_task.h"
+#include <openair3/ocp-gtpu/gtp_itf.h>
 
 #include "intertask_interface.h"
 
@@ -103,13 +104,9 @@ static int is_en_dc_supported(LTE_UE_EUTRA_Capability_t *c);
 
 extern RAN_CONTEXT_t RC;
 
-#ifdef PHY_EMUL
-  extern EMULATION_VARS              *Emul_vars;
-#endif
 extern eNB_MAC_INST                *eNB_mac_inst;
 extern UE_MAC_INST                 *UE_mac_inst;
 
-extern uint16_t                     two_tier_hexagonal_cellIds[7];
 
 mui_t                               rrc_eNB_mui = 0;
 
@@ -996,6 +993,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++;
@@ -1045,17 +1043,17 @@ 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]);
 
         // clean UCI entries for rnti
-        for (i=0; i<NUMBER_OF_UCI_VARS_MAX; i++) {
+        for (i=0; i<NUMBER_OF_UCI_MAX; i++) {
           if(eNB_PHY->uci_vars[i].rnti == rnti) {
             LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti);
             memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI));
@@ -1089,7 +1087,7 @@ void release_UE_in_freeList(module_id_t mod_id) {
                 clean_eNb_ulsch(ulsch);
               }
 
-              for (i=0; i<NUMBER_OF_UCI_VARS_MAX; i++) {
+              for (i=0; i<NUMBER_OF_UCI_MAX; i++) {
                 if(eNB_PHY->uci_vars[i].rnti == rnti) {
                   LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti);
                   memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI));
@@ -1201,7 +1199,7 @@ rrc_eNB_process_RRCConnectionSetupComplete(
   LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing LTE_RRCConnectionSetupComplete from UE (SRB1 Active)\n",
         PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
   ue_context_pP->ue_context.Srb1.Active = 1;
-  ue_context_pP->ue_context.Status = RRC_CONNECTED;
+  ue_context_pP->ue_context.StatusRrc = RRC_CONNECTED;
   ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity timer when UE goes into RRC_CONNECTED
   T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE,
     T_INT(ctxt_pP->module_id),
@@ -1283,7 +1281,7 @@ rrc_eNB_generate_UECapabilityEnquiry(
   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));
   int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0];
-  uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0];
+  uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0];
   size = do_UECapabilityEnquiry(
            ctxt_pP,
            buffer,
@@ -1333,7 +1331,7 @@ rrc_eNB_generate_NR_UECapabilityEnquiry(
   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));
   int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0];
-  uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0];
+  uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0];
   size = do_NR_UECapabilityEnquiry(
            ctxt_pP,
            buffer,
@@ -1577,7 +1575,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
   int                                    measurements_enabled;
   uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);
   int ret = 0;
-  ue_context_pP->ue_context.Status = RRC_CONNECTED;
+  ue_context_pP->ue_context.StatusRrc = 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];
@@ -2207,7 +2205,7 @@ rrc_eNB_generate_RRCConnectionRelease(
 #if 0
 
   if(ue_context_pP != NULL) {
-    if(ue_context_pP->ue_context.Status == RRC_NR_NSA) {
+    if(ue_context_pP->ue_context.StatusRrc == RRC_NR_NSA) {
       //rrc_eNB_generate_SgNBReleaseRequest(ctxt_pP,ue_context_pP);
     }
   }
@@ -3441,6 +3439,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
   ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5);
 
   if (ue_context_pP->ue_context.does_nr) {
+    LOG_I(RRC,"Configuring measurement for NR cell\n");
     ReportConfig_NR->reportConfigId = 7;
     ReportConfig_NR->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigInterRAT;
     ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.present = LTE_ReportConfigInterRAT__triggerType_PR_event;
@@ -4567,7 +4566,6 @@ rrc_eNB_process_MeasurementReport(
 
       case 7:
         LOG_D(RRC, "NR event frame %d subframe %d\n", ctxt_pP->frame, ctxt_pP->subframe);
-        printf("NR event frame %d subframe %d\n", ctxt_pP->frame, ctxt_pP->subframe);
         break;
 
       default:
@@ -4585,13 +4583,16 @@ rrc_eNB_process_MeasurementReport(
 
   /* TODO: improve NR triggering */
   if (measResults2->measId == 7) {
-    if ((ue_context_pP->ue_context.Status != RRC_NR_NSA) && (ue_context_pP->ue_context.Status != RRC_NR_NSA_RECONFIGURED)) {
+    if ((ue_context_pP->ue_context.StatusRrc != RRC_NR_NSA) && (ue_context_pP->ue_context.StatusRrc != RRC_NR_NSA_RECONFIGURED)) {
       MessageDef      *msg;
-      ue_context_pP->ue_context.Status = RRC_NR_NSA;
+      ue_context_pP->ue_context.StatusRrc = RRC_NR_NSA;
       ue_context_pP->ue_context.gnb_rnti = -1;         // set when receiving X2AP_ENDC_SGNB_ADDITION_REQ_ACK
       ue_context_pP->ue_context.gnb_x2_assoc_id = -1;  // set when receiving X2AP_ENDC_SGNB_ADDITION_REQ_ACK
 
       if(is_en_dc_supported(ue_context_pP->ue_context.UE_Capability)) {
+
+        AssertFatal(measResults2->measResultNeighCells!=NULL,"no measResultNeighCells, shouldn't happen!\n");
+        AssertFatal(measResults2->measResultNeighCells->present==LTE_MeasResults__measResultNeighCells_PR_measResultNeighCellListNR_r15,"field is not LTE_MeasResults__measResultNeighCells_PR_measResultNeighCellListNR_r15");
         /** to add gNB as Secondary node CG-ConfigInfo to be added as per 36.423 r15 **/
         if(encode_CG_ConfigInfo(enc_buf,sizeof(enc_buf),ue_context_pP,&enc_size) == RRC_OK)
           LOG_I(RRC,"CG-ConfigInfo encoded successfully\n");
@@ -4610,6 +4611,7 @@ rrc_eNB_process_MeasurementReport(
         X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = enc_size;
 
         X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId
+          //= measResults2->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->pci_r15;
           = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId;
 
         //For the moment we have a single E-RAB which will be the one to be added to the gNB
@@ -4632,6 +4634,32 @@ rrc_eNB_process_MeasurementReport(
         return;
       }
     }
+
+    if (!ue_context_pP->ue_context.measResults->measResultNeighCells) {
+      ue_context_pP->ue_context.measResults->measResultNeighCells = calloc(1,sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells));
+      ue_context_pP->ue_context.measResults->measResultNeighCells->present = LTE_MeasResults__measResultNeighCells_PR_measResultNeighCellListNR_r15;
+      ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array = calloc(1, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array));
+      ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0] = calloc(1, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]));
+      ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.count = 1;
+    }
+    struct LTE_MeasResultCellNR_r15 *ueCtxtMeasResultCellNR_r15 = ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0];
+    const struct LTE_MeasResultCellNR_r15 *measNeighCellNR0 = measResults2->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0];
+    ueCtxtMeasResultCellNR_r15->pci_r15 = measNeighCellNR0->pci_r15;
+    if (!ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrpResult_r15)
+      ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrpResult_r15 = calloc(1, sizeof(*ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrpResult_r15));
+    if (!ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrqResult_r15)
+      ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrqResult_r15 = calloc(1, sizeof(*ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrqResult_r15));
+    *ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrpResult_r15 = *measNeighCellNR0->measResultCell_r15.rsrpResult_r15;
+    *ueCtxtMeasResultCellNR_r15->measResultCell_r15.rsrqResult_r15 = *measNeighCellNR0->measResultCell_r15.rsrqResult_r15;
+    if (measNeighCellNR0->measResultRS_IndexList_r15) {
+       if (!ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15) {
+          ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15 = calloc(1,sizeof(*ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15));
+          ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15->list.array = calloc(1, sizeof(ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15->list.array));
+          ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15->list.array[0] = calloc(1, sizeof(*ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15->list.array));
+          ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15->list.count = 1;
+       }
+      ueCtxtMeasResultCellNR_r15->measResultRS_IndexList_r15->list.array[0]->ssb_Index_r15 = measNeighCellNR0->measResultRS_IndexList_r15->list.array[0]->ssb_Index_r15;
+    }
   }
 
   if (measResults2->measResultNeighCells == NULL)
@@ -4693,12 +4721,12 @@ rrc_eNB_process_MeasurementReport(
   LOG_D(RRC, "A3 event is triggered...\n");
 
   /* if the UE is not in handover mode, start handover procedure */
-  if (ue_context_pP->ue_context.Status != RRC_HO_EXECUTION) {
+  if (ue_context_pP->ue_context.StatusRrc != RRC_HO_EXECUTION) {
     MessageDef      *msg;
     LOG_I(RRC, "Send HO preparation message at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe);
     /* HO info struct may not be needed anymore */
     ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info)));
-    ue_context_pP->ue_context.Status = RRC_HO_EXECUTION;
+    ue_context_pP->ue_context.StatusRrc = RRC_HO_EXECUTION;
     ue_context_pP->ue_context.handover_info->state = HO_REQUEST;
     /* HO Preparation message */
     msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_HANDOVER_REQ);
@@ -4830,7 +4858,7 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re
   RB_INSERT(rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head, ue_context_target_p);
   LOG_D(RRC, "eNB %d: Created new UE context uid %u\n", mod_id, ue_context_target_p->local_uid);
   ue_context_target_p->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info)));
-  //ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION;
+  //ue_context_target_p->ue_context.StatusRrc = RRC_HO_EXECUTION;
   //ue_context_target_p->ue_context.handover_info->state = HO_ACK;
   ue_context_target_p->ue_context.handover_info->x2_id = m->x2_id;
   ue_context_target_p->ue_context.handover_info->assoc_id = m->target_assoc_id;
@@ -4905,7 +4933,7 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re
   }
 
   rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ(mod_id, ue_context_target_p);
-  ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION;
+  ue_context_target_p->ue_context.StatusRrc = RRC_HO_EXECUTION;
   ue_context_target_p->ue_context.handover_info->state = HO_ACK;
 }
 
@@ -4968,7 +4996,7 @@ void rrc_eNB_handover_ue_context_release(
     ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
   }
 
-  itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p);
+  itti_send_msg_to_task(TASK_VARIABLE, ctxt_pP->module_id, msg_delete_tunnels_p);
   struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
   rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id);
 
@@ -5020,7 +5048,7 @@ flexran_rrc_eNB_trigger_handover (int mod_id,
   LOG_D(RRC, "Handover is triggered by FlexRAN controller...\n");
 
   /* if the UE is not in handover mode, start handover procedure */
-  if (ue_context_pP->ue_context.Status != RRC_HO_EXECUTION) {
+  if (ue_context_pP->ue_context.StatusRrc != RRC_HO_EXECUTION) {
     MessageDef      *msg;
     LOG_I(RRC, "Send HO preparation message at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe);
     /* Check memory leakage for handover info */
@@ -5028,7 +5056,7 @@ flexran_rrc_eNB_trigger_handover (int mod_id,
     //free(ue_context_pP->ue_context.handover_info);
     //}
     ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info)));
-    ue_context_pP->ue_context.Status = RRC_HO_EXECUTION;
+    ue_context_pP->ue_context.StatusRrc = RRC_HO_EXECUTION;
     ue_context_pP->ue_context.handover_info->state = HO_REQUEST;
     /* HO Preparation message */
     msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_HANDOVER_REQ);
@@ -5089,7 +5117,7 @@ check_handovers(
   RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
     ctxt_pP->rnti  = ue_context_p->ue_id_rnti;
 
-    if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION && ue_context_p->ue_context.handover_info != NULL) {
+    if (ue_context_p->ue_context.StatusRrc == RRC_HO_EXECUTION && ue_context_p->ue_context.handover_info != NULL) {
       /* in the source, UE in HO_PREPARE mode */
       if (ue_context_p->ue_context.handover_info->state == HO_PREPARE) {
         LOG_D(RRC,
@@ -5140,7 +5168,7 @@ check_handovers(
       }
     }
 
-    if (ue_context_p->ue_context.Status == RRC_RECONFIGURED
+    if (ue_context_p->ue_context.StatusRrc == RRC_RECONFIGURED
         && ue_context_p->ue_context.handover_info != NULL &&
         ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_NO_EMPTY ) {
       MessageDef   *msg_p;
@@ -5206,7 +5234,7 @@ check_handovers(
       ue_context_p->ue_context.handover_info->forwarding_state = FORWARDING_EMPTY;
     }
 
-    if( ue_context_p->ue_context.Status == RRC_RECONFIGURED &&
+    if( ue_context_p->ue_context.StatusRrc == RRC_RECONFIGURED &&
         ue_context_p->ue_context.handover_info != NULL &&
         ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_EMPTY &&
         ue_context_p->ue_context.handover_info->endmark_state == ENDMARK_NO_EMPTY &&
@@ -5709,7 +5737,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
   //SchedulingRequestConfig__setup__dsr_TransMax_n4);
   //  assign_enum(&physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = SchedulingRequestConfig__setup__dsr_TransMax_n4;
   physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax =
-    LTE_SchedulingRequestConfig__setup__dsr_TransMax_n4;
+    LTE_SchedulingRequestConfig__setup__dsr_TransMax_n64;
   LOG_D(RRC,
         "handover_config [FRAME %05d][RRC_eNB][MOD %02d][][--- MAC_CONFIG_REQ  (SRB1 UE %x) --->][MAC_eNB][MOD %02d][]\n",
         ctxt_pP->frame, ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ctxt_pP->module_id);
@@ -6088,7 +6116,6 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
   mobilityInfo = CALLOC(1, sizeof(*mobilityInfo));
   memset((void *)mobilityInfo, 0, sizeof(*mobilityInfo));
   mobilityInfo->targetPhysCellId = RC.rrc[ctxt_pP->module_id]->carrier[0].physCellId;
-  //(PhysCellId_t) two_tier_hexagonal_cellIds[ue_context_pP->ue_context.handover_info->modid_t];
   LOG_D(RRC, "[eNB %d] Frame %d: handover preparation: targetPhysCellId: %ld mod_id: %d ue: %x \n",
         ctxt_pP->module_id,
         ctxt_pP->frame,
@@ -6557,10 +6584,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
               (int)DRB_configList->list.array[i]->drb_Identity,
               (int)*DRB_configList->list.array[i]->logicalChannelIdentity);
         /* For pre-ci tests */
-        LOG_I(RRC, "[eNB %d] Frame  %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE %u, reconfiguring DRB %d/LCID %d\n",
+        LOG_I(RRC, "[eNB %d] Frame  %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete, reconfiguring DRB %d/LCID %d\n",
               ctxt_pP->module_id,
               ctxt_pP->frame,
-              oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid],
               (int)DRB_configList->list.array[i]->drb_Identity,
               (int)*DRB_configList->list.array[i]->logicalChannelIdentity);
 
@@ -6585,7 +6611,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
                     "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n",
                     ctxt_pP->module_id, ctxt_pP->module_id,
                     (long int)((ue_context_pP->local_uid * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity));
-              ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid];
+              ue_module_id = 0; // Was oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid];
               rb_conf_ipv4(0, //add
                            ue_module_id,  //cx
                            ctxt_pP->module_id,    //inst
@@ -7198,7 +7224,7 @@ rrc_eNB_decode_ccch(
           }
 
           //c-plane not end
-          if((ue_context_p->ue_context.Status != RRC_RECONFIGURED) && (ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1)) {
+          if((ue_context_p->ue_context.StatusRrc != RRC_RECONFIGURED) && (ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1)) {
             LOG_E(RRC,
                   PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest (UE %x c-plane is not end), let's reject the UE\n",
                   PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti);
@@ -7210,9 +7236,9 @@ rrc_eNB_decode_ccch(
             LOG_E(RRC,
                   PROTOCOL_RRC_CTXT_UE_FMT" RRRCConnectionReconfigurationComplete(Previous) don't receive, delete the Previous UE,\nprevious Status %d, new Status RRC_RECONFIGURED\n",
                   PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
-                  ue_context_p->ue_context.Status
+                  ue_context_p->ue_context.StatusRrc
                  );
-            ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+            ue_context_p->ue_context.StatusRrc = RRC_RECONFIGURED;
             protocol_ctxt_t  ctxt_old_p;
             PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p,
                                           ctxt_pP->instance,
@@ -7581,42 +7607,239 @@ rrc_eNB_decode_ccch(
   return rval;
 }
 
+#define NCE nonCriticalExtension
+
+static void
+get_ue_Category(
+  LTE_UE_EUTRA_Capability_t *c,
+  long *catDL,
+  long *catUL
+)
+{
+  if (c != NULL) { // v8.6
+     *catDL=c->ue_Category; *catUL=c->ue_Category;
+     struct LTE_UE_EUTRA_Capability_v920_IEs *c92=c->NCE;
+     if (c92 != NULL) { // v9.2
+        struct LTE_UE_EUTRA_Capability_v940_IEs *c94=c92->NCE;
+        if (c94 != NULL) { // v9.4
+           struct LTE_UE_EUTRA_Capability_v1020_IEs *c102=c94->NCE;
+           if (c102 != NULL) { // v10.2
+              if (c102->ue_Category_v1020) {*catDL=*c102->ue_Category_v1020;*catUL=*c102->ue_Category_v1020;}
+              struct LTE_UE_EUTRA_Capability_v1060_IEs *c106=c102->NCE;
+                 if (c106 != NULL) { // v10.6
+                    struct LTE_UE_EUTRA_Capability_v1090_IEs *c109=c106->NCE;
+                    if (c109 != NULL) { // v10.9
+                       struct LTE_UE_EUTRA_Capability_v1130_IEs *c113=c109->NCE;
+                       if (c113 != NULL) { // v11.3
+                          struct LTE_UE_EUTRA_Capability_v1170_IEs *c117=c113->NCE;
+                          if (c117 != NULL) { // v11.7
+                             if (c117->ue_Category_v1170) {*catDL=*c117->ue_Category_v1170;
+                             struct LTE_UE_EUTRA_Capability_v1180_IEs *c118=c117->NCE;
+                             if (c118 != NULL) { // v11.8
+                                struct LTE_UE_EUTRA_Capability_v11a0_IEs *c11a=c118->NCE;
+                                if (c11a != NULL) { // v11.a
+                                   if (c11a->ue_Category_v11a0) {*catDL=*c11a->ue_Category_v11a0;*catUL=*c11a->ue_Category_v11a0;}
+                                   struct LTE_UE_EUTRA_Capability_v1250_IEs *c125=c11a->NCE;
+                                   if (c125 != NULL) { // v12.5
+                                      if (c125->ue_CategoryDL_r12) *catDL=*c125->ue_CategoryDL_r12;
+                                      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;
+                                         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;
+                                            if (c128 != NULL) { // v12.8
+                                               struct LTE_UE_EUTRA_Capability_v1310_IEs *c131=c128->NCE;
+                                               if (c131 != NULL) { // v13.1
+                                                  if (c131->ue_CategoryDL_v1310 && *c131->ue_CategoryDL_v1310 == 0) *catDL=17;
+                                                  if (c131->ue_CategoryDL_v1310 && *c131->ue_CategoryDL_v1310 == 1) *catDL=-1;
+                                                  if (c131->ue_CategoryUL_v1310 && *c131->ue_CategoryUL_v1310 == 0) *catUL=14;
+                                                  if (c131->ue_CategoryUL_v1310 && *c131->ue_CategoryUL_v1310 == 1) *catUL=-1;
+                                                  struct LTE_UE_EUTRA_Capability_v1320_IEs *c132=c131->NCE;
+                                                  if (c132 != NULL) { //v13.2
+                                                     struct LTE_UE_EUTRA_Capability_v1330_IEs *c133=c132->NCE;
+                                                     if (c133 != NULL) { // v13.3
+                                                        if (c133->ue_CategoryDL_v1330) *catDL=*c133->ue_CategoryDL_v1330;
+                                                        struct LTE_UE_EUTRA_Capability_v1340_IEs *c134=c133->NCE;
+                                                        if (c134 != NULL) { // v13.4
+                                                           if (c134->ue_CategoryUL_v1340) *catUL=*c134->ue_CategoryUL_v1340;
+                                                           struct LTE_UE_EUTRA_Capability_v1350_IEs *c135=c134->NCE;
+                                                           if (c135 != NULL) { // v13.5
+                                                              if (c135->ue_CategoryDL_v1350) *catDL=99; // Cat 1Bis
+                                                              if (c135->ue_CategoryUL_v1350) *catUL=99; // Cat 1Bis
+                                                              struct LTE_UE_EUTRA_Capability_v1360_IEs *c136=c135->NCE;
+                                                              if (c136 != NULL) { // v13.6
+                                                                 struct LTE_UE_EUTRA_Capability_v1430_IEs *c143=c136->NCE;
+                                                                 if (c143 != NULL) { // v14.3
+                                                                    if (c143->ue_CategoryDL_v1430 && *c143->ue_CategoryDL_v1430 == LTE_UE_EUTRA_Capability_v1430_IEs__ue_CategoryDL_v1430_m2) *catDL=-2;
+                                                                    if (c143->ue_CategoryUL_v1430 && *c143->ue_CategoryUL_v1430 == LTE_UE_EUTRA_Capability_v1430_IEs__ue_CategoryDL_v1430_m2) *catUL=-2;
+                                                                    if (c143->ue_CategoryUL_v1430) *catUL=16+*c143->ue_CategoryUL_v1430;
+                                                                    if (c143->ue_CategoryUL_v1430b)*catUL=21;
+                                                                    struct LTE_UE_EUTRA_Capability_v1440_IEs *c144=c143->NCE;
+                                                                    if (c144 != NULL) { // v14.4
+                                                                       struct LTE_UE_EUTRA_Capability_v1450_IEs *c145=c144->NCE;
+                                                                       if (c145 != NULL) { // v14.5
+                                                                          if (c145->ue_CategoryDL_v1450) *catDL=*c145->ue_CategoryDL_v1450;
+                                                                          struct LTE_UE_EUTRA_Capability_v1460_IEs *c146=c145->NCE;
+                                                                          if (c146 != NULL) { // v14.6
+                                                                             if (c146->ue_CategoryDL_v1460) *catDL=*c146->ue_CategoryDL_v1460;
+                                                                             struct LTE_UE_EUTRA_Capability_v1510_IEs *c151=c146->NCE;
+                                                                             if (c151 != NULL) { // v15.1
+                                                                                struct LTE_UE_EUTRA_Capability_v1520_IEs *c152=c151->NCE;
+                                                                                if (c152 != NULL) { // v15.20
+                                                                                   struct LTE_UE_EUTRA_Capability_v1530_IEs *c153=c152->NCE;
+                                                                                   if (c153 != NULL) { // v15.30
+                                                                                      if (c153->ue_CategoryDL_v1530) *catDL=*c153->ue_CategoryDL_v1530;
+                                                                                      if (c153->ue_CategoryUL_v1530) *catUL=*c153->ue_CategoryUL_v1530;
+                                                                                   }
+                                                                                }
+                                                                             }
+                                                                          }
+                                                                       }
+                                                                    }
+                                                                 }
+                                                              }
+                                                           }
+                                                        }
+                                                     }
+                                                  }
+                                               }
+                                            }
+                                         }
+                                      }
+                                   }
+                                }
+                             }
+                          }
+                       }
+                    }
+                 }
+              }
+           }
+        }
+     }
+  }
+}
+
+static int
+is_ul_64QAM_supported(
+  LTE_UE_EUTRA_Capability_t *c
+)
+//-----------------------------------------------------------------------------
+{
+  return c != NULL  // R8
+         && c->NCE != NULL // R92
+         && c->NCE->NCE != NULL // R94
+         && c->NCE->NCE->NCE != NULL // R102
+         && 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->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->rf_Parameters_v1250 != NULL
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250 != NULL
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250->list.array != NULL
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250->list.array[0]->ul_64QAM_r12 != NULL
+         && *c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250->list.array[0]->ul_64QAM_r12==LTE_SupportedBandEUTRA_v1250__ul_64QAM_r12_supported;
+}
+
+static int
+is_dl_256QAM_supported(
+  LTE_UE_EUTRA_Capability_t *c
+)
 //-----------------------------------------------------------------------------
+{
+  return c != NULL  // R8
+         && c->NCE != NULL // R92
+         && c->NCE->NCE != NULL // R94
+         && c->NCE->NCE->NCE != NULL // R102
+         && 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->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->rf_Parameters_v1250 != NULL
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250 != NULL
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250->list.array != NULL
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250->list.array[0]->dl_256QAM_r12 != NULL
+         && *c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1250->supportedBandListEUTRA_v1250->list.array[0]->dl_256QAM_r12==LTE_SupportedBandEUTRA_v1250__dl_256QAM_r12_supported;
+
+}
+static int
+is_ul_256QAM_supported(
+  LTE_UE_EUTRA_Capability_t *c
+)
+//-----------------------------------------------------------------------------
+{
+  return c != NULL  // R8
+         && c->NCE != NULL // R92
+         && c->NCE->NCE != NULL // R94
+         && c->NCE->NCE->NCE != NULL // R102
+         && 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->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->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
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //135
+         && 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->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[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
+         && *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==LTE_BandParameters_v1430__ul_256QAM_r14_supported;
+}
+
 static int
 is_en_dc_supported(
   LTE_UE_EUTRA_Capability_t *c
 )
 //-----------------------------------------------------------------------------
 {
-  /* to be refined - check that the eNB is connected to a gNB, check that
-   * the bands supported by the UE include the band of the gNB
+  /* to be refined - check that the bands supported by the UE include
+   * the band of the gNB
    */
-#define NCE nonCriticalExtension
-  return c != NULL
-         && c->NCE != NULL
-         && c->NCE->NCE != NULL
-         && c->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL
-         && 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
-         && 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
+  return c != NULL  // R8
+         && c->NCE != NULL // R92
+         && c->NCE->NCE != NULL // R94
+         && c->NCE->NCE->NCE != NULL // R102
+         && 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->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->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
+         && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //135
+         && 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->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
          && 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->en_DC_r15 != NULL
          && *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->en_DC_r15 ==
@@ -7624,6 +7847,45 @@ is_en_dc_supported(
 #undef NCE
 }
 
+int to_nr_rsrpq(long rsrpq_result,int nr_band) {
+
+    switch(nr_band) {
+      case 1:  // A
+      case 70:
+      case 74:
+      case 34:
+      case 38:
+      case 39:
+      case 40:
+      case 50:
+      case 51:
+       return((rsrpq_result*10)-1180);
+      case 66:  // B
+       return((rsrpq_result*10)-1175);
+      case 77:  // C
+      case 78:
+      case 79:
+       return((rsrpq_result*10)-1170);
+      case 28:  // D
+       return((rsrpq_result*10)-1165);
+      case 2:
+      case 5:
+      case 7:
+      case 41:  // E
+       return((rsrpq_result*10)-1160);
+      case 3:   // G
+      case 8:
+      case 12:
+      case 20:
+      case 71:
+       return((rsrpq_result*10)-1150);
+      case 25:  // H
+       return((rsrpq_result*10)-1145);
+      default:
+       AssertFatal(1==0,"Illegal NR band %d\n",nr_band);
+    }
+}
+
 //-----------------------------------------------------------------------------
 int
 rrc_eNB_decode_dcch(
@@ -7748,7 +8010,7 @@ rrc_eNB_decode_dcch(
           int flexran_agent_handover = 0;
 
           if (EPC_MODE_ENABLED) {
-            if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) {
+            if (ue_context_p->ue_context.StatusRrc == RRC_RECONFIGURED) {
               dedicated_DRB = 1;
               LOG_I(RRC,
                     PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n",
@@ -7773,7 +8035,7 @@ rrc_eNB_decode_dcch(
                 dedicated_DRB = 2;
                 RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
               }
-            } else if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION) {
+            } else if (ue_context_p->ue_context.StatusRrc == RRC_HO_EXECUTION) {
               int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
 
               if(UE_id == -1) {
@@ -7787,7 +8049,7 @@ rrc_eNB_decode_dcch(
               RC.rrc[ctxt_pP->module_id]->Nb_ue++;
               dedicated_DRB = 3;
               RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
-              ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+              ue_context_p->ue_context.StatusRrc = RRC_RECONFIGURED;
 
               if(ue_context_p->ue_context.handover_info) {
                 ue_context_p->ue_context.handover_info->state = HO_CONFIGURED;
@@ -7796,7 +8058,7 @@ rrc_eNB_decode_dcch(
               LOG_I(RRC,
                     PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_HO_EXECUTION (xid %ld)\n",
                     PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
-            } else if(ue_context_p->ue_context.Status == RRC_NR_NSA) {
+            } else if(ue_context_p->ue_context.StatusRrc == RRC_NR_NSA) {
               //Looking for a condition to trigger S1AP E-RAB-Modification-indication, based on the reception of RRCConnectionReconfigurationComplete
               //including NR specific elements.
               if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
@@ -7815,7 +8077,7 @@ rrc_eNB_decode_dcch(
                               nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
                               ->scg_ConfigResponseNR_r15!=NULL) {
                             dedicated_DRB = -1;     /* put a value that does not run anything below */
-                            ue_context_p->ue_context.Status = RRC_NR_NSA_RECONFIGURED;
+                            ue_context_p->ue_context.StatusRrc = RRC_NR_NSA_RECONFIGURED;
                             /*Trigger E-RAB Modification Indication */
                             rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p);
                             /* send reconfiguration complete to gNB */
@@ -7829,7 +8091,7 @@ rrc_eNB_decode_dcch(
               }
             } else {
               dedicated_DRB = 0;
-              ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+              ue_context_p->ue_context.StatusRrc = RRC_RECONFIGURED;
               LOG_I(RRC,
                     PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (default DRB, xid %ld)\n",
                     PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
@@ -7838,7 +8100,7 @@ rrc_eNB_decode_dcch(
             ue_context_p->ue_context.reestablishment_xid = -1;
           } else {
             dedicated_DRB = 1;
-            ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+            ue_context_p->ue_context.StatusRrc = RRC_RECONFIGURED;
             LOG_I(RRC,
                   PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n",
                   PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
@@ -8193,7 +8455,7 @@ rrc_eNB_decode_dcch(
               ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr);
               ue_context_p->ue_context.UE_Capability_nr = 0;
             }
-
+            LOG_I(RRC,"Received NR_UE_Capabilities\n");
             dec_rval = uper_decode(NULL,
                                    &asn_DEF_NR_UE_NR_Capability,
                                    (void **)&ue_context_p->ue_context.UE_Capability_nr,
@@ -8218,6 +8480,8 @@ rrc_eNB_decode_dcch(
 
           if (ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->rat_Type ==
               LTE_RAT_Type_eutra_nr) {
+            LOG_I(RRC,"Received UE_Capabilities_MRDC\n");
+
             if(ue_context_p->ue_context.UE_Capability_MRDC) {
               ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC);
               ue_context_p->ue_context.UE_Capability_MRDC = 0;
@@ -8289,8 +8553,13 @@ rrc_eNB_decode_dcch(
           ue_context_p->ue_context.UE_Capability = 0;
         }
 
-        if (dec_rval.code == RC_OK)
-          ue_context_p->ue_context.does_nr = is_en_dc_supported(ue_context_p->ue_context.UE_Capability);
+        if (dec_rval.code == RC_OK) {
+          /* do NR only if at least one gNB connected */
+          if (RC.rrc[ctxt_pP->module_id]->num_gnb_cells != 0)
+            ue_context_p->ue_context.does_nr = is_en_dc_supported(ue_context_p->ue_context.UE_Capability);
+          else
+            ue_context_p->ue_context.does_nr = 0;
+        }
 
         if (EPC_MODE_ENABLED) {
           rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP,
@@ -8563,24 +8832,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][num_SI]        = rrc->carrier[0].SIB23;
-          F1AP_SETUP_RESP (msg_p).SI_container_length[cu_cell_ind][num_SI] = rrc->carrier[0].sizeof_SIB23;
-          //printf("SI %d size %d: ", 0, F1AP_SETUP_RESP(msg_p).SI_container_length[j][num_SI]);
-          //for (int n = 0; n < F1AP_SETUP_RESP(msg_p).SI_container_length[j][num_SI]; n++)
-          //  printf("%02x ", F1AP_SETUP_RESP(msg_p).SI_container[0][num_SI][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;
@@ -8775,10 +9043,6 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
   struct rrc_eNB_ue_context_s *ue_to_be_removed[NUMBER_OF_UE_MAX];
   int removed_ue_count = 0;
   int cur_ue;
-#ifdef LOCALIZATION
-  double estimated_distance = 0;
-  protocol_ctxt_t                     ctxt;
-#endif
   MessageDef *msg;
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_IN);
 
@@ -8790,22 +9054,53 @@ 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)
+    fd=fopen("RRC_stats.log","w+");
+
   RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
     ctxt_pP->rnti = ue_context_p->ue_id_rnti;
 
-    if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe == 0)) {
-      if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
-        LOG_I(RRC, "UE rnti %x: S-TMSI %x failure timer %d/8\n",
-              ue_context_p->ue_context.rnti,
-              ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
-              ue_context_p->ue_context.ul_failure_timer);
-      } else {
-        LOG_I(RRC, "UE rnti %x failure timer %d/8\n",
-              ue_context_p->ue_context.rnti,
-              ue_context_p->ue_context.ul_failure_timer);
+    if ((ctxt_pP->frame&127) == 0 && ctxt_pP->subframe ==0) {
+      if (fd) {
+        if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
+          fprintf(fd,"RRC UE rnti %x: S-TMSI %x failure timer %d/8\n",
+                ue_context_p->ue_context.rnti,
+                ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
+                ue_context_p->ue_context.ul_failure_timer);
+        } else {
+          fprintf(fd,"RRC UE rnti %x failure timer %d/8\n",
+                ue_context_p->ue_context.rnti,
+                ue_context_p->ue_context.ul_failure_timer);
+        }
+
+        if (ue_context_p->ue_context.UE_Capability) {
+          long catDL,catUL;
+          get_ue_Category(ue_context_p->ue_context.UE_Capability,&catDL,&catUL);
+          fprintf(fd,"RRC UE cap: CatDL %ld, CatUL %ld, 64QAM UL %s, 256 QAM DL %s, 256 QAM UL %s, ENDC %s,\n",
+                catDL,catUL,
+		is_ul_64QAM_supported(ue_context_p->ue_context.UE_Capability) == 1 ? "yes" : "no",
+		is_dl_256QAM_supported(ue_context_p->ue_context.UE_Capability) == 1 ? "yes" : "no",
+                is_ul_256QAM_supported(ue_context_p->ue_context.UE_Capability) == 1 ? "yes" : "no",
+                is_en_dc_supported(ue_context_p->ue_context.UE_Capability) == 1 ? "yes" : "no");
+        }
+        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) {
+
+            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)
+              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)
+              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);
+           }
+        }
       }
     }
-
     if (ue_context_p->ue_context.ul_failure_timer > 0) {
       ue_context_p->ue_context.ul_failure_timer++;
 
@@ -8973,8 +9268,8 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
     }
 
     /* remove UE from gNB if UE is in NSA mode */
-    if (ue_to_be_removed[cur_ue]->ue_context.Status == RRC_NR_NSA ||
-        ue_to_be_removed[cur_ue]->ue_context.Status == RRC_NR_NSA_RECONFIGURED) {
+    if (ue_to_be_removed[cur_ue]->ue_context.StatusRrc == RRC_NR_NSA ||
+        ue_to_be_removed[cur_ue]->ue_context.StatusRrc == RRC_NR_NSA_RECONFIGURED) {
       MessageDef *message_p;
       message_p = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_RELEASE_REQUEST);
       X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).rnti = ue_to_be_removed[cur_ue]->ue_context.gnb_rnti;
@@ -8982,7 +9277,7 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
       X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).cause = X2AP_CAUSE_RADIO_CONNECTION_WITH_UE_LOST;
       itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, message_p);
       /* set state to RRC_NR_NSA_DELETED to avoid sending X2AP_ENDC_SGNB_RELEASE_REQUEST again later */
-      ue_to_be_removed[cur_ue]->ue_context.Status = RRC_NR_NSA_DELETED;
+      ue_to_be_removed[cur_ue]->ue_context.StatusRrc = RRC_NR_NSA_DELETED;
     }
 
     rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed[cur_ue]);
@@ -8997,31 +9292,9 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
     }
   }
 
-#ifdef RRC_LOCALIZATION
-  /* for the localization, only primary CC_id might be relevant*/
-  gettimeofday(&ts, NULL);
-  current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000;
-  ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms;
-  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
-    ctxt = *ctxt_pP;
-    ctxt.rnti = ue_context_p->ue_context.rnti;
-    estimated_distance = rrc_get_estimated_ue_distance(&ctxt, CC_id, RC.rrc[ctxt_pP->module_id]->loc_type);
-
-    if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) &&
-        estimated_distance != -1) {
-      LOG_D(LOCALIZE, "RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n",
-            ctxt.rnti,
-            ctxt_pP->module_id,
-            current_timestamp_ms,
-            ctxt_pP->frame,
-            estimated_distance);
-      LOG_D(LOCALIZE, "RRC status %d\n",
-            ue_context_p->ue_context.Status);
-      push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, estimated_distance);
-      RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms;
-    } // end if
-  } // end RB_FOREACH
-#endif
+  if (fd!=NULL) fclose(fd);
+
+
   (void)ts; /* remove gcc warning "unused variable" */
   (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */
   (void)current_timestamp_ms; /* remove gcc warning "unused variable" */
@@ -9029,22 +9302,22 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
 }
 
 void rrc_eNB_process_ENDC_x2_setup_request(int mod_id, x2ap_ENDC_setup_req_t *m) {
-  if (RC.rrc[mod_id]->num_neigh_cells > MAX_NUM_NEIGH_CELLs) {
-    LOG_E(RRC, "Error: number of neighbouring cells is exceeded \n");
+  if (RC.rrc[mod_id]->num_gnb_cells >= MAX_NUM_GNB_CELLs) {
+    LOG_E(RRC, "Error: number of gNB cells is exceeded\n");
     return;
   }
 
   if (m->num_cc > MAX_NUM_CCs) {
-    LOG_E(RRC, "Error: number of neighbouring cells carriers is exceeded \n");
+    LOG_E(RRC, "Error: number of gNB cells carriers is exceeded \n");
     return;
   }
 
-  RC.rrc[mod_id]->num_neigh_cells++;
-  RC.rrc[mod_id]->num_neigh_cells_cc[RC.rrc[mod_id]->num_neigh_cells-1] = m->num_cc;
+  RC.rrc[mod_id]->num_gnb_cells++;
+  RC.rrc[mod_id]->num_gnb_cells_cc[RC.rrc[mod_id]->num_gnb_cells-1] = m->num_cc;
 
   for (int i=0; i<m->num_cc; i++) {
-    RC.rrc[mod_id]->neigh_cells_id[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->Nid_cell[i];
-    RC.rrc[mod_id]->nr_neigh_freq_band[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->servedNrCell_band[i];
+    RC.rrc[mod_id]->gnb_cells_id[RC.rrc[mod_id]->num_gnb_cells-1][i] = m->Nid_cell[i];
+    RC.rrc[mod_id]->nr_gnb_freq_band[RC.rrc[mod_id]->num_gnb_cells-1][i] = m->servedNrCell_band[i];
   }
 
 }
@@ -9174,13 +9447,13 @@ void rrc_eNB_process_ENDC_DC_prep_timeout(module_id_t module_id, x2ap_ENDC_dc_pr
     return;
   }
 
-  if (ue_context->ue_context.Status != RRC_NR_NSA) {
+  if (ue_context->ue_context.StatusRrc != RRC_NR_NSA) {
     LOG_E(RRC, "receiving DC prep timeout for UE rnti %d not in state RRC_NR_NSA\n", m->rnti);
     return;
   }
 
   LOG_I(RRC, "DC prep timeout for UE rnti %d, put back to RRC_RECONFIGURED mode\n", m->rnti);
-  ue_context->ue_context.Status = RRC_RECONFIGURED;
+  ue_context->ue_context.StatusRrc = RRC_RECONFIGURED;
 }
 
 void rrc_eNB_process_ENDC_sgNB_release_required(module_id_t module_id, x2ap_ENDC_sgnb_release_required_t *m)
@@ -9201,7 +9474,7 @@ void rrc_eNB_process_ENDC_sgNB_release_required(module_id_t module_id, x2ap_ENDC
   ue_context->ue_context.ue_release_timer_thres_rrc = 100;
   ue_context->ue_context.ue_release_timer_rrc = 1;
 
-  ue_context->ue_context.Status = RRC_NR_NSA_DELETED;
+  ue_context->ue_context.StatusRrc = RRC_NR_NSA_DELETED;
 
   PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
                                 module_id,  /* TODO: should be 'instance' */
@@ -9467,7 +9740,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
         if (X2AP_HANDOVER_CANCEL(msg_p).cause == X2AP_T_RELOC_PREP_TIMEOUT) {
           /* for prep timeout, simply return to normal state */
           /* TODO: be sure that it's correct to set Status to RRC_RECONFIGURED */
-          ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+          ue_context_p->ue_context.StatusRrc = RRC_RECONFIGURED;
           /* TODO: be sure free is enough here (check memory leaks) */
           free(ue_context_p->ue_context.handover_info);
           ue_context_p->ue_context.handover_info = NULL;
diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
index e974a28f680b84bcbe9c80c9d19165bc2fd9c151..a6af6a4163a7f941e49ba89079b541799a6d1dc2 100644
--- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
+++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
@@ -40,6 +40,7 @@
 
 
 # include "common/ran_context.h"
+#include <openair3/ocp-gtpu/gtp_itf.h>
 
 extern RAN_CONTEXT_t RC;
 
@@ -92,7 +93,6 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
   }
 }
 
-
 //------------------------------------------------------------------------------
 boolean_t
 gtpv_data_req(
@@ -113,64 +113,151 @@ gtpv_data_req(
     return FALSE;
   }
   LOG_D(GTPU,"gtpv_data_req ue rnti %x sdu_sizeP %d rb id %ld", ctxt_pP->rnti, sdu_sizeP, rb_idP);
-  {
-    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;
-
-    if(task_id == TASK_DATA_FORWARDING){
-
-      LOG_I(GTPU,"gtpv_data_req task_id = TASK_DATA_FORWARDING\n");
-
-      message_buffer = itti_malloc (TASK_GTPV1_U, TASK_DATA_FORWARDING, sdu_sizeP);
-
-      memcpy (message_buffer, buffer_pP, sdu_sizeP);
-
-      message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_DATA_FORWARDING_IND);
-      GTPV1U_ENB_DATA_FORWARDING_IND (message_p).frame 	= ctxt_pP->frame;
-      GTPV1U_ENB_DATA_FORWARDING_IND (message_p).enb_flag	= ctxt_pP->enb_flag;
-      GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rb_id 	= rb_idP;
-      GTPV1U_ENB_DATA_FORWARDING_IND (message_p).muip		= muiP;
-      GTPV1U_ENB_DATA_FORWARDING_IND (message_p).confirmp	= confirmP;
-      GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_size	= sdu_sizeP;
-      GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_p 	= message_buffer;
-      GTPV1U_ENB_DATA_FORWARDING_IND (message_p).mode		= modeP;
-      GTPV1U_ENB_DATA_FORWARDING_IND (message_p).module_id = ctxt_pP->module_id;
-      GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rnti		 = ctxt_pP->rnti;
-      GTPV1U_ENB_DATA_FORWARDING_IND (message_p).eNB_index = ctxt_pP->eNB_index;
-
-      itti_send_msg_to_task (TASK_DATA_FORWARDING, ctxt_pP->instance, message_p);
-      return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
-    }else if(task_id == TASK_END_MARKER){
-      
-      LOG_I(GTPU,"gtpv_data_req task_id = TASK_END_MARKER\n");
-
-      message_buffer = itti_malloc (TASK_GTPV1_U, TASK_END_MARKER, sdu_sizeP);
-
-      memcpy (message_buffer, buffer_pP, sdu_sizeP);
-
-      message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_IND);
-      GTPV1U_ENB_END_MARKER_IND (message_p).frame 	= ctxt_pP->frame;
-      GTPV1U_ENB_END_MARKER_IND (message_p).enb_flag	= ctxt_pP->enb_flag;
-      GTPV1U_ENB_END_MARKER_IND (message_p).rb_id 	= rb_idP;
-      GTPV1U_ENB_END_MARKER_IND (message_p).muip		= muiP;
-      GTPV1U_ENB_END_MARKER_IND (message_p).confirmp	= confirmP;
-      GTPV1U_ENB_END_MARKER_IND (message_p).sdu_size	= sdu_sizeP;
-      GTPV1U_ENB_END_MARKER_IND (message_p).sdu_p 	= message_buffer;
-      GTPV1U_ENB_END_MARKER_IND (message_p).mode		= modeP;
-      GTPV1U_ENB_END_MARKER_IND (message_p).module_id = ctxt_pP->module_id;
-      GTPV1U_ENB_END_MARKER_IND (message_p).rnti		 = ctxt_pP->rnti;
-      GTPV1U_ENB_END_MARKER_IND (message_p).eNB_index = ctxt_pP->eNB_index;
-
-      itti_send_msg_to_task (TASK_END_MARKER, ctxt_pP->instance, message_p);
-      return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
-    }
+  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;
+  
+  if(task_id == TASK_DATA_FORWARDING){
+    
+    LOG_I(GTPU,"gtpv_data_req task_id = TASK_DATA_FORWARDING\n");
+    
+    message_buffer = itti_malloc (TASK_GTPV1_U, TASK_DATA_FORWARDING, sdu_sizeP);
+    
+    memcpy (message_buffer, buffer_pP, sdu_sizeP);
+    
+    message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_DATA_FORWARDING_IND);
+    GTPV1U_ENB_DATA_FORWARDING_IND (message_p).frame 	= ctxt_pP->frame;
+    GTPV1U_ENB_DATA_FORWARDING_IND (message_p).enb_flag	= ctxt_pP->enb_flag;
+    GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rb_id 	= rb_idP;
+    GTPV1U_ENB_DATA_FORWARDING_IND (message_p).muip		= muiP;
+    GTPV1U_ENB_DATA_FORWARDING_IND (message_p).confirmp	= confirmP;
+    GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_size	= sdu_sizeP;
+    GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_p 	= message_buffer;
+    GTPV1U_ENB_DATA_FORWARDING_IND (message_p).mode		= modeP;
+    GTPV1U_ENB_DATA_FORWARDING_IND (message_p).module_id = ctxt_pP->module_id;
+    GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rnti		 = ctxt_pP->rnti;
+    GTPV1U_ENB_DATA_FORWARDING_IND (message_p).eNB_index = ctxt_pP->eNB_index;
+    
+    itti_send_msg_to_task (TASK_DATA_FORWARDING, ctxt_pP->instance, message_p);
+    return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
+  } else if (task_id == TASK_END_MARKER){
+    
+    LOG_I(GTPU,"gtpv_data_req task_id = TASK_END_MARKER\n");
+    
+    message_buffer = itti_malloc (TASK_GTPV1_U, TASK_END_MARKER, sdu_sizeP);
+    
+    memcpy (message_buffer, buffer_pP, sdu_sizeP);
+    
+    message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_IND);
+    GTPV1U_ENB_END_MARKER_IND (message_p).frame 	= ctxt_pP->frame;
+    GTPV1U_ENB_END_MARKER_IND (message_p).enb_flag	= ctxt_pP->enb_flag;
+    GTPV1U_ENB_END_MARKER_IND (message_p).rb_id 	= rb_idP;
+    GTPV1U_ENB_END_MARKER_IND (message_p).muip	= muiP;
+    GTPV1U_ENB_END_MARKER_IND (message_p).confirmp	= confirmP;
+    GTPV1U_ENB_END_MARKER_IND (message_p).sdu_size	= sdu_sizeP;
+    GTPV1U_ENB_END_MARKER_IND (message_p).sdu_p 	= message_buffer;
+    GTPV1U_ENB_END_MARKER_IND (message_p).mode	= modeP;
+    GTPV1U_ENB_END_MARKER_IND (message_p).module_id = ctxt_pP->module_id;
+    GTPV1U_ENB_END_MARKER_IND (message_p).rnti      = ctxt_pP->rnti;
+    GTPV1U_ENB_END_MARKER_IND (message_p).eNB_index = ctxt_pP->eNB_index;
+    
+    itti_send_msg_to_task (TASK_END_MARKER, ctxt_pP->instance, message_p);
+    return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
   }
-  return TRUE;
-
+  LOG_E(RRC, "Impossible state\n");
+  return FALSE;
 }
 
-//#endif
+boolean_t gtpv_data_req_new (
+  protocol_ctxt_t  *ctxt,
+  const srb_flag_t     srb_flagP,
+  const rb_id_t        rb_idP,
+  const mui_t          muiP,
+  const confirm_t      confirmP,
+  const sdu_size_t     sdu_buffer_sizeP,
+  unsigned char *const sdu_buffer_pP,
+  const pdcp_transmission_mode_t modeP,
+  const uint32_t *sourceL2Id,
+  const uint32_t *destinationL2Id) {
+  int task;
+
+  if (sdu_buffer_sizeP==0)
+    task=TASK_END_MARKER;
+  else
+    task=TASK_DATA_FORWARDING;
+  
+  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt->module_id], ctxt->rnti);
+  if(ue_context_p == NULL || ue_context_p->ue_context.handover_info == NULL ||
+     ue_context_p->ue_context.StatusRrc != RRC_HO_EXECUTION) {
+    LOG_E(RRC,"incoming GTP-U for X2 in non HO context\n");
+    return false;
+  }
+
+  /* in the source enb, UE in RRC_HO_EXECUTION mode */
+  // We have 2*2=4 cases (data or end marker) * (from slave, from EPC)
+  if (ue_context_p->ue_context.handover_info->state == HO_COMPLETE) {
+      LOG_I(GTPU, "source receive END MARKER\n");
+      /* set handover state */
+      //ue_context_p->ue_context.handover_info->state = HO_END_MARKER;
+      MessageDef *msg;
+      // Configure end marker
+      msg = itti_alloc_new_message(TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_REQ);
+      GTPV1U_ENB_END_MARKER_REQ(msg).buffer = itti_malloc(TASK_GTPV1_U, TASK_GTPV1_U, GTPU_HEADER_OVERHEAD_MAX + sdu_buffer_sizeP);
+      memcpy(&GTPV1U_ENB_END_MARKER_REQ(msg).buffer[GTPU_HEADER_OVERHEAD_MAX],  sdu_buffer_pP, sdu_buffer_sizeP);
+      GTPV1U_ENB_END_MARKER_REQ(msg).length = sdu_buffer_sizeP;
+      GTPV1U_ENB_END_MARKER_REQ(msg).rnti   = ctxt->rnti;
+      GTPV1U_ENB_END_MARKER_REQ(msg).rab_id = rb_idP;
+      GTPV1U_ENB_END_MARKER_REQ(msg).offset = GTPU_HEADER_OVERHEAD_MAX;
+      LOG_I(GTPU, "Send End Marker to GTPV1-U at frame %d and subframe %d \n", ctxt->frame,ctxt->subframe);
+      itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(ctxt->module_id), msg);
+      return NW_GTPV1U_OK;
+  }
+  
+  /* target enb */
+  //  We have 2*2=4 cases (data or end marker) * (from source, from EPC)
+  if (ue_context_p->ue_context.StatusRrc == RRC_RECONFIGURED) {
+    // It should come from remote eNB
+    // case end marker by EPC is not possible ?
+    if (task==TASK_END_MARKER) { 
+      LOG_I(GTPU, "target end receive END MARKER\n");
+      // We close the HO, nothing to send to remote ?
+      ue_context_p->ue_context.handover_info->state = HO_END_MARKER;
+      gtpv1u_enb_delete_tunnel_req_t delete_tunnel_req;
+      memset(&delete_tunnel_req, 0, sizeof(delete_tunnel_req));
+      delete_tunnel_req.rnti = ctxt->rnti;
+      gtpv1u_delete_x2u_tunnel(ctxt->module_id, &delete_tunnel_req, GTPV1U_TARGET_ENB);
+      return true;
+    } else {
+      /* data packet */
+      LOG_I(GTPU, "Received a message data forwarding length %d\n", sdu_buffer_sizeP);
+      // Is it from remote ENB
+      // We have to push it to the UE ?
+      if(ue_context_p->ue_context.handover_info->state != HO_COMPLETE) {
+	int result = pdcp_data_req(
+			       ctxt,
+			       srb_flagP,
+			       rb_idP,
+			       muiP, // mui
+			       confirmP, // confirm
+			        sdu_buffer_sizeP,
+			       sdu_buffer_pP,
+			       modeP,
+			       sourceL2Id,
+			       destinationL2Id
+			       );
+	ue_context_p->ue_context.handover_info->forwarding_state = FORWARDING_NO_EMPTY;
+	return result;
+      } else {  /* It is from from epc message */
+	/* in the source enb, UE in RRC_HO_EXECUTION mode */
+	// ?????
+	return true;
+      }
+    }
+  }
+  LOG_E(RRC,"This function should return before the end\n");
+  return false;
+}	
+
 
 void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
   module_id_t enb_mod_idP,
@@ -181,21 +268,16 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
     LOG_W(RRC, "[eNB] In %s: invalid UE\n", __func__);
     return;
   }
+  gtpv1u_enb_delete_tunnel_req_t tmp={0};
 
-  MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL, 0,
-                     "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ",
-                     ue_context_pP->ue_context.eNB_ue_s1ap_id);
-
-  MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, 0, GTPV1U_ENB_DELETE_TUNNEL_REQ);
-  memset(&GTPV1U_ENB_DELETE_TUNNEL_REQ(msg), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg)));
-  GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).rnti = ue_context_pP->ue_context.rnti;
-  GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).from_gnb = 0;
-  GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).num_erab = ue_context_pP->ue_context.nb_of_e_rabs;
+  tmp.rnti = ue_context_pP->ue_context.rnti;
+  tmp.from_gnb = 0;
+  tmp.num_erab = ue_context_pP->ue_context.nb_of_e_rabs;
   for (int e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_e_rabs; e_rab++) {
     const rb_id_t gtp_ebi = ue_context_pP->ue_context.enb_gtp_ebi[e_rab];
-    GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).eps_bearer_id[e_rab] = gtp_ebi;
+    tmp.eps_bearer_id[e_rab] = gtp_ebi;
   }
-  itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg);
+  gtpv1u_delete_s1u_tunnel(enb_mod_idP,&tmp); 
 }
 
 
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c
index d34b4164a204dbf299f28b6e02f15c5dd03beda8..1cb575d1ddb323877700097692265f82ee28a0f8 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c
@@ -48,11 +48,12 @@
 #include "pdcp_primitives.h"
 
 #include "UTIL/OSA/osa_defs.h"
-#include "msc.h"
+#include <common/utils/msc/msc.h>
 
 #include "LTE_UERadioAccessCapabilityInformation.h"
 
 #include "gtpv1u_eNB_task.h"
+#include <openair3/ocp-gtpu/gtp_itf.h>
 #include "RRC/LTE/rrc_eNB_GTPV1U.h"
 
 #include "TLVDecoder.h"
@@ -782,21 +783,37 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
         S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei;
 
         if (r_mme->plmn_Identity != NULL) {
-          if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) {
-            /* Use first indicated PLMN MCC if it is defined */
-            S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[selected_plmn_identity];
+          if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count == 3))
+          {
+            S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = (*r_mme->plmn_Identity->mcc->list.array[0] & 0xf) * 100 +
+                                                                    (*r_mme->plmn_Identity->mcc->list.array[1] & 0xf) * 10 +
+                                                                    (*r_mme->plmn_Identity->mcc->list.array[2] & 0xf);
             LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n",
                   ctxt_pP->module_id,
                   S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc,
                   ue_context_pP->ue_context.rnti);
           }
-
-          if (r_mme->plmn_Identity->mnc.list.count > 0) {
-            /* Use first indicated PLMN MNC if it is defined */
-            S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity];
-            LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n",
+          if(r_mme->plmn_Identity->mnc.list.count == 3)
+          {
+            S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = (*r_mme->plmn_Identity->mnc.list.array[0] & 0xf) * 100 +
+                                                                    (*r_mme->plmn_Identity->mnc.list.array[1] & 0xf) * 10 +
+                                                                    (*r_mme->plmn_Identity->mnc.list.array[2] & 0xf);
+            S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = 3;
+            LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x\n",
+                  ctxt_pP->module_id,
+                  S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc,
+                  S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len,
+                  ue_context_pP->ue_context.rnti);
+          }
+          else if(r_mme->plmn_Identity->mnc.list.count == 2)
+          {
+            S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = (*r_mme->plmn_Identity->mnc.list.array[0] & 0xf) * 10 +
+                                                                    (*r_mme->plmn_Identity->mnc.list.array[1] & 0xf);
+            S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = 2;
+            LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x\n",
                   ctxt_pP->module_id,
                   S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc,
+                  S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len,
                   ue_context_pP->ue_context.rnti);
           }
         } else { // end if plmn_Identity != NULL
@@ -1055,7 +1072,7 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
                  ue_context_p->ue_context.nr_security.kgNB);
 
     // 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 == RRC_RECONFIGURED) {
+    if (ue_context_p->ue_context.StatusRrc == RRC_RECONFIGURED) {
       LOG_I(RRC, "Sending rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause);
       //if(ue_context_p->ue_context.reestablishment_cause == ReestablishmentCause_spare1){}
       rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(&ctxt,ue_context_p);
@@ -1771,7 +1788,7 @@ int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *ms
         }
       }
 
-      itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p);
+      itti_send_msg_to_task(TASK_VARIABLE, instance, msg_delete_tunnels_p);
       //S1AP_E_RAB_RELEASE_RESPONSE
       rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(&ctxt, ue_context_p, xid);
     }
diff --git a/openair2/RRC/LTE/rrc_extern.h b/openair2/RRC/LTE/rrc_extern.h
index 6564f38ade9e90bbd0c438c94a7cb04306cd36e5..7f7fd6579e088532a36600e15b149a3de83762f1 100644
--- a/openair2/RRC/LTE/rrc_extern.h
+++ b/openair2/RRC/LTE/rrc_extern.h
@@ -47,7 +47,6 @@ extern LTE_LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue;
 extern unsigned char NB_INST;
 extern unsigned char NB_eNB_INST;
 extern uint16_t NB_UE_INST;
-extern unsigned short NODE_ID[1];
 extern void* bigphys_malloc(int);
 
 
diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c
index 58c595a3d009ff0397cf1a1605858501860df8b9..8a6e16499947323d1928a78f474d9e8e2cdacf21 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"
@@ -42,6 +43,10 @@
 
 #include "NR_MIB.h"
 #include "NR_BCCH-BCH-Message.h"
+#include "rrc_gNB_UE_context.h"
+#include <openair2/RRC/NR/MESSAGES/asn1_msg.h>
+#include <openair2/F1AP/f1ap_du_rrc_message_transfer.h>
+
 
 extern RAN_CONTEXT_t RC;
 
@@ -163,12 +168,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,
@@ -181,11 +186,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;
@@ -193,7 +198,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;
@@ -202,12 +207,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.
@@ -217,29 +222,22 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
                            const int         CC_id,
                            const frame_t     frameP,
                            const rb_id_t     Srb_id,
+                           const rnti_t      rnti,
                            const uint8_t     Nb_tb,
                            uint8_t *const    buffer_pP ){
 
-  asn_enc_rval_t enc_rval;
-  uint8_t Sdu_size = 0;
-  uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f);
-  
 #ifdef DEBUG_RRC
   LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id);
 #endif
 
-    rrc_gNB_carrier_data_t *carrier;
-    NR_BCCH_BCH_Message_t *mib;
-    NR_SRB_INFO *srb_info;
-    char payload_size, *payload_pP;
-
-    carrier = &RC.nrrrc[Mod_idP]->carrier;
-    mib = &carrier->mib;
-    srb_info = &carrier->Srb0;
-
-    /* MIBCH */
+    // MIBCH
     if ((Srb_id & RAB_OFFSET) == MIBCH) {
 
+      asn_enc_rval_t enc_rval;
+      uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f);
+      rrc_gNB_carrier_data_t *carrier = &RC.nrrrc[Mod_idP]->carrier;
+      NR_BCCH_BCH_Message_t *mib = &carrier->mib;
+
         // Currently we are getting the pdcch_ConfigSIB1 from the configuration file.
         // Uncomment this function for a dynamic pdcch_ConfigSIB1.
         //channel_bandwidth_t min_channel_bw = bw_10MHz; // Must be obtained based on TS 38.101-1 Table 5.3.5-1
@@ -269,7 +267,7 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
         return (3);
     }
 
-  /* TODO BCCH SIB1 SIBs */
+  // TODO BCCH SIB1 SIBs
   if ((Srb_id & RAB_OFFSET ) == BCCH) {
     memcpy(&buffer_pP[0],
            RC.nrrrc[Mod_idP]->carrier.SIB1,
@@ -278,29 +276,110 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
     return RC.nrrrc[Mod_idP]->carrier.sizeof_SIB1;
   }
 
-  /* CCCH */
+  // CCCH
   if( (Srb_id & RAB_OFFSET ) == CCCH) {
-    //struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP],rnti);
-    //if (ue_context_p == NULL) return(0);
-    //eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
-    LOG_D(RRC,"[gNB %d] Frame %d CCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id);
 
-    // srb_info=&ue_p->Srb0;
+    char *payload_pP;
+    uint8_t Sdu_size = 0;
+    struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[Mod_idP], rnti);
+
+    LOG_D(NR_RRC,"[gNB %d] Frame %d CCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id);
 
-    payload_size = srb_info->Tx_buffer.payload_size;
+    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
     if (payload_size > 0) {
-      payload_pP = srb_info->Tx_buffer.Payload;
-      LOG_D(RRC,"[gNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n", Mod_idP, srb_info, payload_size, buffer_pP, payload_pP);
+      payload_pP = ue_context_p->ue_context.Srb0.Tx_buffer.Payload;
+      LOG_D(NR_RRC,"[gNB %d] CCCH has %d bytes (dest: %p, src %p)\n", Mod_idP, payload_size, buffer_pP, payload_pP);
       // Fill buffer
       memcpy((void *)buffer_pP, (void*)payload_pP, payload_size);
       Sdu_size = payload_size;
-      srb_info->Tx_buffer.payload_size = 0;
+      ue_context_p->ue_context.Srb0.Tx_buffer.payload_size = 0;
     }
     return Sdu_size;
   }
 
   return(0);
 
-}
\ No newline at end of file
+}
+
+int8_t nr_mac_rrc_data_ind(const module_id_t     module_idP,
+                           const int             CC_id,
+                           const frame_t         frameP,
+                           const sub_frame_t     sub_frameP,
+                           const int             UE_id,
+                           const rnti_t          rntiP,
+                           const rb_id_t         srb_idP,
+                           const uint8_t        *sduP,
+                           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);
+
+  if((srb_idP & RAB_OFFSET) == CCCH) {
+    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, NULL, CC_id);
+    }
+  }
+
+  return 0;
+}
+
+void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP,
+                            const int CC_idP,
+                            const frame_t frameP,
+                            const sub_frame_t subframeP,
+                            const rnti_t rntiP) {
+  struct rrc_gNB_ue_context_s *ue_context_p = NULL;
+  ue_context_p = rrc_gNB_get_ue_context(
+                   RC.nrrrc[Mod_instP],
+                   rntiP);
+
+  if (ue_context_p != NULL) {
+    LOG_D(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP);
+    if(ue_context_p->ue_context.ul_failure_timer == 0)
+      ue_context_p->ue_context.ul_failure_timer=1;
+  } else {
+    LOG_D(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP);
+  }
+}
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 82855365c8aee1f76ca97135b637bb9d67f3f24a..e36644afb0089375208ded1a1b8834af5b76668e
--- 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;
@@ -326,7 +327,7 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
 
   // cellSelectionInfo
   sib1->cellSelectionInfo = CALLOC(1,sizeof(struct NR_SIB1__cellSelectionInfo));
-  sib1->cellSelectionInfo->q_RxLevMin = -50;
+  sib1->cellSelectionInfo->q_RxLevMin = -65;
 
   // cellAccessRelatedInfo
   struct NR_PLMN_IdentityInfo *nr_plmn_info=CALLOC(1,sizeof(struct NR_PLMN_IdentityInfo));
@@ -418,7 +419,8 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
     nrMultiBandInfo->freqBandIndicatorNR = configuration->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[i];
     ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list,nrMultiBandInfo);
   }
-  sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
+  //sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
+  sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = 86;
   for(int i = 0; i< configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.count; i++) {
     ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list,configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[i]);
   }
@@ -443,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));
@@ -561,14 +563,14 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
     case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap:
       sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup = configuration->scc->ssb_PositionsInBurst->choice.mediumBitmap;
       break;
-      /*
-      groupPresence: This field is present when maximum number of SS/PBCH blocks per half frame equals to 64 as defined in TS 38.213 [13], clause 4.1.
-                     The first/leftmost bit corresponds to the SS/PBCH index 0-7, the second bit corresponds to SS/PBCH block 8-15, and so on.
-                     Value 0 in the bitmap indicates that the SSBs according to inOneGroup are absent. Value 1 indicates that the SS/PBCH blocks are transmitted in accordance with inOneGroup.
-      inOneGroup: When maximum number of SS/PBCH blocks per half frame equals to 64 as defined in TS 38.213 [13], clause 4.1, all 8 bit are valid;
-                  The first/ leftmost bit corresponds to the first SS/PBCH block index in the group (i.e., to SSB index 0, 8, and so on); the second bit corresponds to the second SS/PBCH block index in the group
-                  (i.e., to SSB index 1, 9, and so on), and so on. Value 0 in the bitmap indicates that the corresponding SS/PBCH block is not transmitted while value 1 indicates that the corresponding SS/PBCH block is transmitted.
-      */
+    /*
+    groupPresence: This field is present when maximum number of SS/PBCH blocks per half frame equals to 64 as defined in TS 38.213 [13], clause 4.1.
+                   The first/leftmost bit corresponds to the SS/PBCH index 0-7, the second bit corresponds to SS/PBCH block 8-15, and so on.
+                   Value 0 in the bitmap indicates that the SSBs according to inOneGroup are absent. Value 1 indicates that the SS/PBCH blocks are transmitted in accordance with inOneGroup.
+    inOneGroup: When maximum number of SS/PBCH blocks per half frame equals to 64 as defined in TS 38.213 [13], clause 4.1, all 8 bit are valid;
+                The first/ leftmost bit corresponds to the first SS/PBCH block index in the group (i.e., to SSB index 0, 8, and so on); the second bit corresponds to the second SS/PBCH block index in the group
+                (i.e., to SSB index 1, 9, and so on), and so on. Value 0 in the bitmap indicates that the corresponding SS/PBCH block is not transmitted while value 1 indicates that the corresponding SS/PBCH block is transmitted.
+    */
     case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap:
       sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup.size = 1;
       sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup.bits_unused = 0;
@@ -657,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,
@@ -925,29 +977,319 @@ 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);
+  
+  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;
@@ -962,6 +1304,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);
@@ -981,97 +1324,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);
@@ -1145,6 +1450,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;
 
@@ -1161,6 +1471,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);
 
@@ -1234,7 +1573,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,
@@ -1244,14 +1583,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;
@@ -1272,13 +1612,14 @@ uint16_t do_RRCReconfiguration(
     // *security_config->keyToUse = NR_SecurityConfig__keyToUse_master;
 
     ie = calloc(1, sizeof(NR_RRCReconfiguration_IEs_t));
-    ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t));
-    ie->radioBearerConfig->srb_ToAddModList  = SRB_configList;
-    ie->radioBearerConfig->drb_ToAddModList  = DRB_configList;
-    ie->radioBearerConfig->securityConfig    = security_config;
-    ie->radioBearerConfig->srb3_ToRelease    = NULL;
-    ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList;
-
+    if (SRB_configList || DRB_configList) {
+      ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t));
+      ie->radioBearerConfig->srb_ToAddModList  = SRB_configList;
+      ie->radioBearerConfig->drb_ToAddModList  = DRB_configList;
+      ie->radioBearerConfig->securityConfig    = security_config;
+      ie->radioBearerConfig->srb3_ToRelease    = NULL;
+      ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList;
+    }
     /******************** Secondary Cell Group ********************/
     // rrc_gNB_carrier_data_t *carrier = &(gnb_rrc_inst->carrier);
     // fill_default_secondaryCellGroup( carrier->servingcellconfigcommon,
@@ -1286,7 +1627,8 @@ uint16_t do_RRCReconfiguration(
     //                                  1,
     //                                  1,
     //                                  carrier->pdsch_AntennaPorts,
-    //                                  carrier->initial_csi_index[gnb_rrc_inst->Nb_ue]);
+    //                                  carrier->initial_csi_index[ue_context_p->local_uid + 1],
+    //                                  ue_context_pP->local_uid);
 
     /******************** Meas Config ********************/
     // measConfig
@@ -1294,20 +1636,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",
@@ -1507,6 +1871,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 36d9bdee60c44f18ed419aa729ca5881685ffd6c..b92b5defe68c7896220e4e384b8c7cc7fd7ab27c 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"
@@ -127,7 +128,7 @@ typedef enum UE_STATE_NR_e {
 #define MAX_MEAS_ID                                   6
 
 #define PAYLOAD_SIZE_MAX                              1024
-#define RRC_BUF_SIZE                                  255
+#define RRC_BUF_SIZE                                  8192
 #define UNDEF_SECURITY_MODE                           0xff
 #define NO_SECURITY_MODE                              0x20
 
@@ -238,13 +239,13 @@ typedef struct RB_INFO_TABLE_ENTRY_NR_s {
   NR_RB_INFO                                          Rb_info;
   uint8_t                                             Active;
   uint32_t                                            Next_check_frame;
-  uint8_t                                             Status;
+  uint8_t                                             status;
 } NR_RB_INFO_TABLE_ENTRY;
 
 typedef struct SRB_INFO_TABLE_ENTRY_NR_s {
   NR_SRB_INFO                                         Srb_info;
   uint8_t                                             Active;
-  uint8_t                                             Status;
+  uint8_t                                             status;
   uint32_t                                            Next_check_frame;
 } NR_SRB_INFO_TABLE_ENTRY;
 
@@ -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;
 
@@ -354,7 +356,7 @@ typedef struct gNB_RRC_UE_s {
   /* list of e_rab to be setup by RRC layers */
   /* list of pdu session to be setup by RRC layers */
   e_rab_param_t                      e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
-  pdu_session_param_t                pdusession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION];
+  pdu_session_param_t                pduSession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION];
   //release e_rabs
   uint8_t                            nb_release_of_e_rabs;
   e_rab_failed_t                     e_rabs_release_failed[S1AP_MAX_E_RAB];
@@ -379,6 +381,7 @@ typedef struct gNB_RRC_UE_s {
   uint32_t                           ue_reestablishment_timer_thres;
   uint8_t                            e_rab_release_command_flag;
   uint8_t                            pdu_session_release_command_flag;
+  uint8_t                            established_pdu_sessions_flag;
   uint32_t                           ue_rrc_inactivity_timer;
   int8_t                             reestablishment_xid;
   //------------------------------------------------------------------------------//
@@ -425,14 +428,27 @@ 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;
   int pusch_TargetSNRx10;
   int pucch_TargetSNRx10;
+  int do_CSIRS;
   NR_BCCH_DL_SCH_Message_t                  *siblock1;
   NR_ServingCellConfigCommon_t              *servingcellconfigcommon;
   NR_PDCCH_ConfigSIB1_t                     *pdcch_ConfigSIB1;
@@ -440,7 +456,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;
@@ -460,6 +475,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;
@@ -471,6 +489,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;
@@ -487,6 +511,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_extern.h b/openair2/RRC/NR/nr_rrc_extern.h
index 04e0392236bf5ada098861923a84bf3a2da13b4a..3b08a240279d55d0420e882e111c2cf0b3e67771 100644
--- a/openair2/RRC/NR/nr_rrc_extern.h
+++ b/openair2/RRC/NR/nr_rrc_extern.h
@@ -47,7 +47,6 @@ extern NR_LogicalChannelConfig_t NR_SRB3_logicalChannelConfig_defaultValue;
 extern unsigned char NB_INST;
 extern unsigned char NB_eNB_INST;
 extern uint16_t NB_UE_INST;
-extern unsigned short NODE_ID[1];
 extern void* bigphys_malloc(int);
 
 
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index 6d876a0eefacbfa7dcb94474849e2a40fa186025..811c7a152fd7bcf12f9c6f38c54a245ff348d72f 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -51,6 +51,7 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
                            const int         CC_id,
                            const frame_t     frameP,
                            const rb_id_t     Srb_id,
+                           const rnti_t      rnti,
                            const uint8_t     Nb_tb,
                            uint8_t *const    buffer_pP );
 
@@ -79,17 +80,25 @@ void fill_default_coresetZero(NR_ControlResourceSet_t *coreset0, NR_ServingCellC
 void fill_default_searchSpaceZero(NR_SearchSpace_t *ss0);
 
 void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
-				     NR_CellGroupConfig_t *secondaryCellGroup,
-				     int scg_id,
-				     int servCellIndex,
-				     int n_physical_antenna_ports,
-				     int initial_csi_index);
+                                     NR_ServingCellConfig_t *servingcellconfigdedicated,
+                                     NR_CellGroupConfig_t *secondaryCellGroup,
+                                     int scg_id,
+                                     int servCellIndex,
+                                     int dl_antenna_ports,
+                                     int do_csirs,
+                                     int initial_csi_index,
+                                     int uid);
+
+void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_CSI_MeasConfig_t *csi_MeasConfig, int dl_antenna_ports, int do_csirs);
 
 void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
-			   NR_RRCReconfiguration_IEs_t *reconfig,
-			   NR_CellGroupConfig_t *secondaryCellGroup,
-			   int n_physical_antenna_ports,
-			   int initial_csi_index);
+                           NR_ServingCellConfig_t *servingcellconfigdedicated,
+                           NR_RRCReconfiguration_IEs_t *reconfig,
+                           NR_CellGroupConfig_t *secondaryCellGroup,
+                           int dl_antenna_ports,
+                           int do_csirs,
+                           int initial_csi_index,
+                           int uid);
 
 void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
                            int eps_bearer_id, int rb_id,
@@ -101,6 +110,21 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
 		       NR_RRCReconfiguration_t *reconfig,
 		       NR_RadioBearerConfig_t *rbconfig);
 
+void apply_macrlc_config(gNB_RRC_INST *rrc,
+                         rrc_gNB_ue_context_t         *const ue_context_pP,
+                         const protocol_ctxt_t        *const ctxt_pP );
+
+void apply_pdcp_config(rrc_gNB_ue_context_t         *const ue_context_pP,
+                       const protocol_ctxt_t        *const ctxt_pP );
+
+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
@@ -156,6 +180,25 @@ int
 nr_rrc_mac_remove_ue(module_id_t mod_idP,
                   rnti_t rntiP);
 
+int8_t nr_mac_rrc_data_ind(
+    const module_id_t     module_idP,
+    const int             CC_id,
+    const frame_t         frameP,
+    const sub_frame_t     sub_frameP,
+    const int             UE_id,
+    const rnti_t          rntiP,
+    const rb_id_t         srb_idP,
+    const uint8_t        *sduP,
+    const sdu_size_t      sdu_lenP,
+    const boolean_t   brOption
+);
+
+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
 rrc_gNB_generate_dedicatedRRCReconfiguration_release(
     const protocol_ctxt_t   *const ctxt_pP,
@@ -163,3 +206,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/nr_rrc_types.h b/openair2/RRC/NR/nr_rrc_types.h
index 02495591a91daab0602c8c5b631018caa8cf4e4f..61f90e35727dc8b2f638870bcc0b089dcd019881 100644
--- a/openair2/RRC/NR/nr_rrc_types.h
+++ b/openair2/RRC/NR/nr_rrc_types.h
@@ -32,11 +32,11 @@
 #define RRC_TYPES_NR_H_
 
 typedef enum Rrc_State_NR_e {
-  RRC_STATE_INACTIVE_NR=0,
-  RRC_STATE_IDLE_NR,
+  RRC_STATE_IDLE_NR=0,
+  RRC_STATE_INACTIVE_NR,
   RRC_STATE_CONNECTED_NR,
 
-  RRC_STATE_FIRST_NR = RRC_STATE_INACTIVE_NR,
+  RRC_STATE_FIRST_NR = RRC_STATE_IDLE_NR,
   RRC_STATE_LAST_NR = RRC_STATE_CONNECTED_NR,
 } Rrc_State_NR_t;
 
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 6d430d722370c71d0c0351e0a87fade5d2f49d2d..07493f332c9f5f1f07e781921b246e8fbb5d5ada 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,26 +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_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");
@@ -277,13 +296,16 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
       parse_CG_ConfigInfo(rrc,CG_ConfigInfo,NULL);
     } else {
       struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
+      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];
@@ -307,9 +329,11 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
   rrc->carrier.servingcellconfigcommon = configuration->scc;
   rrc->carrier.ssb_SubcarrierOffset = configuration->ssb_SubcarrierOffset;
   rrc->carrier.pdsch_AntennaPorts = configuration->pdsch_AntennaPorts;
-  rrc->carrier.pusch_TargetSNRx10 = configuration->pusch_TargetSNRx10;
-  rrc->carrier.pucch_TargetSNRx10 = configuration->pucch_TargetSNRx10;
-  /// System Information INIT
+  rrc->carrier.pusch_AntennaPorts = configuration->pusch_AntennaPorts;
+  rrc->carrier.do_CSIRS = configuration->do_CSIRS;
+   /// 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();
@@ -355,17 +379,59 @@ rrc_gNB_get_next_transaction_identifier(
   return nr_rrc_transaction_identifier[gnb_mod_idP];
 }
 
+void apply_macrlc_config(gNB_RRC_INST *rrc,
+                         rrc_gNB_ue_context_t         *const ue_context_pP,
+                         const protocol_ctxt_t        *const ctxt_pP ) {
+
+      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);
+
+}
+
+void apply_pdcp_config(rrc_gNB_ue_context_t         *const ue_context_pP,
+                       const protocol_ctxt_t        *const ctxt_pP ) {
+
+      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);
+
+}
+
 //-----------------------------------------------------------------------------
 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),
@@ -373,55 +439,106 @@ 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
+      apply_macrlc_config(rrc,ue_context_pP,ctxt_pP);
+
+      apply_pdcp_config(ue_context_pP,ctxt_pP);
 #endif
+    }
+    break;
+
+    default:
+      LOG_W(NR_RRC, "Unknown node type %d\n", rrc->node_type);
+      break;
+  }
 }
 
 //-----------------------------------------------------------------------------
@@ -433,20 +550,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),
@@ -460,43 +575,42 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
   rrc_mac_config_req_gNB(rrc_instance_p->module_id,
                          rrc_instance_p->carrier.ssb_SubcarrierOffset,
                          rrc_instance_p->carrier.pdsch_AntennaPorts,
-                         rrc_instance_p->carrier.pusch_TargetSNRx10,
-                         rrc_instance_p->carrier.pucch_TargetSNRx10,
+                         rrc_instance_p->carrier.pusch_AntennaPorts,
                          (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
 }
 
@@ -510,6 +624,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,
@@ -529,17 +645,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);
+  }
 }
 
 //-----------------------------------------------------------------------------
@@ -557,7 +703,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);
@@ -576,13 +723,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;
@@ -591,7 +738,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);
   }
@@ -600,10 +747,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);
   }
@@ -631,7 +778,7 @@ rrc_gNB_generate_defaultRRCReconfiguration(
   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_ms30;
+  *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));
@@ -649,10 +796,26 @@ 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));
 
+  /* Add all NAS PDUs to the list */
+  for (int 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) {
+      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);
+    }
+
+    ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
+    LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
+          i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE");
+  }
+
   if (ue_context_pP->ue_context.nas_pdu_flag == 1) {
     dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
     memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
@@ -671,24 +834,65 @@ 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);
 
   LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n");
+
+  /* Free all NAS PDUs */
+  for (int 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(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 NR_RRCReconfiguration (bytes %d, UE id %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",
+  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,
@@ -696,7 +900,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,
@@ -705,27 +909,246 @@ 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 == NULL) {
+    *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_absent;
+    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
 }
 
 //-----------------------------------------------------------------------------
@@ -754,7 +1177,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
 
   *DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2));
   for(i = 0; i < NB_RB_MAX; i++) {
-    if((ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pdusession[i].xid == xid) {
+    if((ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pduSession[i].xid == xid) {
       DRB_release = CALLOC(1, sizeof(NR_DRB_Identity_t));
       *DRB_release = i+1;
       ASN_SEQUENCE_ADD(&(*DRB_Release_configList2)->list, DRB_release);
@@ -784,6 +1207,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
                                NULL,
                                NULL,
                                dedicatedNAS_MessageList,
+                               NULL,
                                NULL);
 
   ue_context_pP->ue_context.pdu_session_release_command_flag = 1;
@@ -854,6 +1278,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
   NR_DRB_ToReleaseList_t             *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid];
   NR_DRB_Identity_t                  *drb_id_p      = NULL;
 //  uint8_t                             nr_DRB2LCHAN[8];
+  gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
 
   ue_context_pP->ue_context.ue_reestablishment_timer = 0;
 
@@ -878,25 +1303,39 @@ 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,
                               DRB_Release_configList2,
-                              0xff, // already configured during the securitymodecommand
+                              0, // already configured during the securitymodecommand
                               kRRCenc,
                               kRRCint,
                               kUPenc,
                               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)) {
+    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,
+                           ue_context_pP->ue_context.masterCellGroup
+                           );
+    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 */
@@ -904,6 +1343,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;
@@ -1106,7 +1546,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];
@@ -1202,13 +1642,14 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
     memset(&create_tunnel_req, 0, sizeof(create_tunnel_req));
 
     for ( j = 0, i = 0; i < NB_RB_MAX; i++) {
-      if (ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_DONE) {
-        create_tunnel_req.pdusession_id[j]   = ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
-        create_tunnel_req.upf_NGu_teid[j]  = ue_context_pP->ue_context.pdusession[i].param.gtp_teid;
+      if (ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_DONE) {
+        create_tunnel_req.pdusession_id[j]   = ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
+        create_tunnel_req.incoming_rb_id[j]  = i+1;
+        create_tunnel_req.upf_NGu_teid[j]  = ue_context_pP->ue_context.pduSession[i].param.gtp_teid;
         memcpy(create_tunnel_req.upf_addr[j].buffer,
-               ue_context_pP->ue_context.pdusession[i].param.upf_addr.buffer,
+               ue_context_pP->ue_context.pduSession[i].param.upf_addr.buffer,
                 sizeof(uint8_t)*20);
-        create_tunnel_req.upf_addr[j].length = ue_context_pP->ue_context.pdusession[i].param.upf_addr.length;
+        create_tunnel_req.upf_addr[j].length = ue_context_pP->ue_context.pduSession[i].param.upf_addr.length;
         j++;
       }
     }
@@ -1268,10 +1709,10 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
 
     /* TODO parameters yet to process ... */
     /* TODO should test if pdu session are Ok before! */
-    ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_DONE;
-    ue_context_pP->ue_context.pdusession[i].xid    = xid;
+    ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
+    ue_context_pP->ue_context.pduSession[i].xid    = xid;
     LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
-          i, ue_context_pP->ue_context.pdusession[i].status, "PDU_SESSION_STATUS_DONE");
+          i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE");
   }
 
   memset(buffer, 0, RRC_BUF_SIZE);
@@ -1285,16 +1726,17 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
                                 NULL,
                                 NULL, // MeasObj_list,
                                 NULL,
+                                NULL,
                                 NULL);
   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) {
+    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;
+      free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer);
+      ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer = NULL;
     }
   }
 
@@ -1319,15 +1761,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,
@@ -1346,6 +1788,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;
@@ -1383,7 +1826,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
         break;
 
       case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest:
-        LOG_I(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %x)\n", ctxt_pP->rnti);
+        LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %x)\n", ctxt_pP->rnti);
         ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti);
         if (ue_context_p != NULL) {
           rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_p);
@@ -1470,9 +1913,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 {
@@ -1490,15 +1933,15 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
                                        CC_id);
             break;
           }
-        }
 
-        if (ue_context_p != NULL) {
           ue_context_p->ue_context.establishment_cause = rrcSetupRequest->establishmentCause;
-        }
 
-        rrc_gNB_generate_RRCSetup(ctxt_pP,
-                                  rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti),
-                                  CC_id);
+          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);
+        }
         break;
 
       case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest:
@@ -1596,7 +2039,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);
@@ -1608,9 +2051,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,
@@ -1623,10 +2066,10 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
                 ue_context_p->ue_context.reestablishment_xid);
 
             for (uint8_t pdusessionid = 0; pdusessionid < ue_context_p->ue_context.nb_of_pdusessions; pdusessionid++) {
-              if (ue_context_p->ue_context.pdusession[pdusessionid].status == PDU_SESSION_STATUS_DONE) {
-                ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED;
+              if (ue_context_p->ue_context.pduSession[pdusessionid].status == PDU_SESSION_STATUS_DONE) {
+                ue_context_p->ue_context.pduSession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED;
               } else {
-                ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_FAILED;
+                ue_context_p->ue_context.pduSession[pdusessionid].status = PDU_SESSION_STATUS_FAILED;
               }
             }
           }
@@ -1785,6 +2228,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,
@@ -1793,7 +2240,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++) {
@@ -1865,7 +2315,7 @@ rrc_gNB_decode_dcch(
             GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
 
             for(i = 0; i < NB_RB_MAX; i++) {
-              if(xid == ue_context_p->ue_context.pdusession[i].xid) {
+              if(xid == ue_context_p->ue_context.pduSession[i].xid) {
                 GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] =
                   ue_context_p->ue_context.gnb_gtp_psi[i];
                 ue_context_p->ue_context.gnb_gtp_teid[i] = 0;
@@ -1877,13 +2327,14 @@ rrc_gNB_decode_dcch(
             itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->instance, msg_delete_tunnels_p);
             //NGAP_PDUSESSION_RELEASE_RESPONSE
             rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid);
-          } else {
-            rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP,
-                                               ue_context_p,
-                                               ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier);
+          } else if (ue_context_p->ue_context.established_pdu_sessions_flag != 1) {
+            if (ue_context_p->ue_context.setup_pdu_sessions > 0) {
+              rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP,
+                ue_context_p,
+                ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier);
+            }
           }
         }
-
         if (first_rrcreconfiguration == 0){
           first_rrcreconfiguration = 1;
           rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
@@ -2164,7 +2615,13 @@ rrc_gNB_decode_dcch(
                                     ue_context_p,
                                     ul_dcch_msg);
       }
-      rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
+
+      if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) {
+        rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p);
+      } else {
+        rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
+      }
+
       break;
 
             case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete:
@@ -2247,6 +2704,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];
@@ -2259,8 +2829,294 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC
   rrc_remove_nsa_user(rrc, m->rnti);
 }
 
+unsigned int mask_flip(unsigned int x) {
+  return((((x>>8) + (x<<8))&0xffff)>>6);
+}
+
+unsigned int get_dl_bw_mask(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+
+
+  int common_band = *rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+  int common_scs  = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+  for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
+     NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
+     if (bandNRinfo->bandNR == common_band) {
+       if (common_band < 257) { // FR1
+          switch (common_scs) {
+            case NR_SubcarrierSpacing_kHz15 :
+               if (bandNRinfo->channelBWs_DL &&
+                   bandNRinfo->channelBWs_DL->choice.fr1 &&
+                   bandNRinfo->channelBWs_DL->choice.fr1->scs_15kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_15kHz->buf));
+ 	      break;
+            case NR_SubcarrierSpacing_kHz30 :
+               if (bandNRinfo->channelBWs_DL &&
+                   bandNRinfo->channelBWs_DL->choice.fr1 &&
+                   bandNRinfo->channelBWs_DL->choice.fr1->scs_30kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_30kHz->buf));
+              break;
+            case NR_SubcarrierSpacing_kHz60 :
+               if (bandNRinfo->channelBWs_DL &&
+                   bandNRinfo->channelBWs_DL->choice.fr1 &&
+                   bandNRinfo->channelBWs_DL->choice.fr1->scs_60kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_60kHz->buf));
+              break;
+          }
+       }
+       else {
+          switch (common_scs) {
+            case NR_SubcarrierSpacing_kHz60 :
+               if (bandNRinfo->channelBWs_DL &&
+                   bandNRinfo->channelBWs_DL->choice.fr2 &&
+                   bandNRinfo->channelBWs_DL->choice.fr2->scs_60kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr2->scs_60kHz->buf));
+              break;
+            case NR_SubcarrierSpacing_kHz120 :
+               if (bandNRinfo->channelBWs_DL &&
+                   bandNRinfo->channelBWs_DL->choice.fr2 &&
+                   bandNRinfo->channelBWs_DL->choice.fr2->scs_120kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr2->scs_120kHz->buf));
+              break;
+       }
+     }
+   }
+  }
+  return(0);
+}
+
+unsigned int get_ul_bw_mask(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+
+
+  int common_band = *rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0];
+  int common_scs  = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+  for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
+     NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
+     if (bandNRinfo->bandNR == common_band) {
+       if (common_band < 257) { // FR1
+          switch (common_scs) {
+            case NR_SubcarrierSpacing_kHz15 :
+               if (bandNRinfo->channelBWs_UL &&
+                   bandNRinfo->channelBWs_UL->choice.fr1 &&
+                   bandNRinfo->channelBWs_UL->choice.fr1->scs_15kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_15kHz->buf));
+ 	      break;
+            case NR_SubcarrierSpacing_kHz30 :
+               if (bandNRinfo->channelBWs_UL &&
+                   bandNRinfo->channelBWs_UL->choice.fr1 &&
+                   bandNRinfo->channelBWs_UL->choice.fr1->scs_30kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_30kHz->buf));
+              break;
+            case NR_SubcarrierSpacing_kHz60 :
+               if (bandNRinfo->channelBWs_UL &&
+                   bandNRinfo->channelBWs_UL->choice.fr1 &&
+                   bandNRinfo->channelBWs_UL->choice.fr1->scs_60kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_60kHz->buf));
+              break;
+          }
+       }
+       else {
+          switch (common_scs) {
+            case NR_SubcarrierSpacing_kHz60 :
+               if (bandNRinfo->channelBWs_UL &&
+                   bandNRinfo->channelBWs_UL->choice.fr2 &&
+                   bandNRinfo->channelBWs_UL->choice.fr2->scs_60kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr2->scs_60kHz->buf));
+              break;
+            case NR_SubcarrierSpacing_kHz120 :
+               if (bandNRinfo->channelBWs_UL &&
+                   bandNRinfo->channelBWs_UL->choice.fr2 &&
+                   bandNRinfo->channelBWs_UL->choice.fr2->scs_120kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr2->scs_120kHz->buf));
+              break;
+       }
+     }
+   }
+  }
+  return(0);
+}
+
+int is_dl_256QAM_supported(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+  int common_band = *rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+  int common_scs  = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+  if (common_band>256) {
+    for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
+       NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
+       if (bandNRinfo->bandNR == common_band && !bandNRinfo->pdsch_256QAM_FR2) return (0);
+    }
+  }
+  else if (cap->phy_Parameters.phy_ParametersFR1 && !cap->phy_Parameters.phy_ParametersFR1->pdsch_256QAM_FR1) return(0);
+
+  // check featureSet
+  NR_FeatureSets_t *fs=cap->featureSets;
+  if (fs) {
+    // go through DL feature sets and look for one with current SCS
+    for (int i=0;i<fs->featureSetsDownlinkPerCC->list.count;i++) {
+       if (fs->featureSetsDownlinkPerCC->list.array[i]->supportedSubcarrierSpacingDL == common_scs &&
+           fs->featureSetsDownlinkPerCC->list.array[i]->supportedModulationOrderDL &&
+           *fs->featureSetsDownlinkPerCC->list.array[i]->supportedModulationOrderDL == NR_ModulationOrder_qam256) return(1);
+    }
+  }
+  return(0);
+}
+
+int is_ul_256QAM_supported(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+  int common_band = *rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0];
+  int common_scs  = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+  for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
+       NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
+       if (bandNRinfo->bandNR == common_band && !bandNRinfo->pusch_256QAM) return (0);
+  }
+
+  // check featureSet
+  NR_FeatureSets_t *fs=cap->featureSets;
+  if (fs) {
+    // go through UL feature sets and look for one with current SCS
+    for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) {
+       if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
+           fs->featureSetsUplinkPerCC->list.array[i]->supportedModulationOrderUL &&
+           *fs->featureSetsUplinkPerCC->list.array[i]->supportedModulationOrderUL == NR_ModulationOrder_qam256) return(1);
+    }
+  }
+  return(0);
+}
+
+int get_ul_mimo_layersCB(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+  int common_scs  = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+
+  // check featureSet
+  NR_FeatureSets_t *fs=cap->featureSets;
+  if (fs) {
+    // go through UL feature sets and look for one with current SCS
+    for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) {
+       if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
+           fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH &&
+           fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH)
+           return(1<<*fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH);
+    }
+  }
+  return(1);
+}
+
+int get_ul_mimo_layers(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+  int common_scs  = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+
+  // check featureSet
+  NR_FeatureSets_t *fs=cap->featureSets;
+  if (fs) {
+    // go through UL feature sets and look for one with current SCS
+    for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) {
+       if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
+           fs->featureSetsUplinkPerCC->list.array[i]->maxNumberMIMO_LayersNonCB_PUSCH)
+           return(1<<*fs->featureSetsUplinkPerCC->list.array[i]->maxNumberMIMO_LayersNonCB_PUSCH);
+    }
+  }
+  return(1);
+}
+
+int get_dl_mimo_layers(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+  int common_scs  = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+
+  // check featureSet
+  NR_FeatureSets_t *fs=cap->featureSets;
+  if (fs) {
+    // go through UL feature sets and look for one with current SCS
+    for (int i=0;i<fs->featureSetsDownlinkPerCC->list.count;i++) {
+       if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
+           fs->featureSetsDownlinkPerCC->list.array[i]->maxNumberMIMO_LayersPDSCH)
+           return(2<<*fs->featureSetsDownlinkPerCC->list.array[i]->maxNumberMIMO_LayersPDSCH);
+    }
+  }
+  return(1);
+}
 void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
+
   MessageDef *msg;
+  rrc_gNB_ue_context_t *ue_context_p = NULL;
+  FILE *fd=NULL;//fopen("nrRRCstats.log","w");
+  RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head)) {
+    ctxt_pP->rnti = ue_context_p->ue_id_rnti;
+
+     if (fd) {
+        if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) {
+          fprintf(fd,"NR RRC UE rnti %x: S-TMSI %x failure timer %d/8\n",
+                ue_context_p->ue_id_rnti,
+                ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi,
+                ue_context_p->ue_context.ul_failure_timer);
+        } else {
+          fprintf(fd,"NR RRC UE rnti %x failure timer %d/8\n",
+                ue_context_p->ue_id_rnti,
+                ue_context_p->ue_context.ul_failure_timer);
+        }
+
+        if (ue_context_p->ue_context.UE_Capability_nr) {
+          fprintf(fd,"NR RRC UE cap: BW DL %x. BW UL %x, 256 QAM DL %s, 256 QAM UL %s, DL MIMO Layers %d UL MIMO Layers (CB) %d UL MIMO Layers (nonCB) %d\n",
+                get_dl_bw_mask(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
+                get_ul_bw_mask(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
+                is_dl_256QAM_supported(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr) == 1 ? "yes" : "no",
+                is_ul_256QAM_supported(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr) == 1 ? "yes" : "no",
+                get_dl_mimo_layers(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
+                get_ul_mimo_layersCB(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
+                get_ul_mimo_layers(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr));
+        }
+    }
+    if (ue_context_p->ue_context.ul_failure_timer > 0) {
+      ue_context_p->ue_context.ul_failure_timer++;
+
+      if (ue_context_p->ue_context.ul_failure_timer >= 20000) {
+        // remove UE after 20 seconds after MAC (or else) has indicated UL failure
+        LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n",
+              ue_context_p->ue_context.rnti);
+        if(ue_context_p->ue_context.StatusRrc >= NR_RRC_CONNECTED){
+          rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(
+                   ctxt_pP->module_id,
+                   ue_context_p,
+                   NGAP_CAUSE_RADIO_NETWORK,
+                   30);
+        }
+
+        // Remove here the MAC and RRC context when RRC is not connected or gNB is not connected to CN5G
+        if(ue_context_p->ue_context.StatusRrc < NR_RRC_CONNECTED || ue_context_p->ue_context.gNB_ue_ngap_id == 0) {
+          mac_remove_nr_ue(ctxt_pP->module_id, ctxt_pP->rnti);
+          rrc_rlc_remove_ue(ctxt_pP);
+          pdcp_remove_UE(ctxt_pP);
+
+          /* remove RRC UE Context */
+          ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti);
+          if (ue_context_p) {
+            rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p);
+            LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti);
+          }
+        }
+
+        break; // break RB_FOREACH
+      }
+    }
+
+    if (ue_context_p->ue_context.ue_release_timer_rrc > 0) {
+      ue_context_p->ue_context.ue_release_timer_rrc++;
+
+      if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) {
+        LOG_I(NR_RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n",
+              ue_context_p->ue_context.rnti);
+        ue_context_p->ue_context.ue_release_timer_rrc = 0;
+
+        mac_remove_nr_ue(ctxt_pP->module_id, ctxt_pP->rnti);
+        rrc_rlc_remove_ue(ctxt_pP);
+        pdcp_remove_UE(ctxt_pP);
+
+        /* remove RRC UE Context */
+        ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti);
+        if (ue_context_p) {
+          rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p);
+          LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti);
+        }
+
+        break; // break RB_FOREACH
+      }
+    }
+  }
+
+  if (fd) fclose(fd);
 
   /* send a tick to x2ap */
   if (is_x2ap_enabled()){
@@ -2278,7 +3134,16 @@ 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");
 
@@ -2308,17 +3173,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",
@@ -2327,9 +3193,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 */
@@ -2340,6 +3213,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,
@@ -2348,6 +3226,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:
@@ -2411,11 +3291,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
@@ -2426,6 +3302,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");
@@ -2477,12 +3361,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;
@@ -2497,24 +3382,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;
@@ -2526,15 +3432,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
@@ -2546,32 +3457,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;
@@ -2583,15 +3514,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);
+  }
 }
 
 //-----------------------------------------------------------------------------
@@ -2614,6 +3549,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),
@@ -2646,12 +3583,14 @@ 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)) {
+    uint8_t *message_buffer = itti_malloc (TASK_RRC_GNB, TASK_CU_F1, size);
+    memcpy (message_buffer, buffer, size);
     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;
     F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release
-    F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = buffer;
+    F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = message_buffer;
     F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = size;
     itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m);
   } else {
@@ -2662,6 +3601,9 @@ rrc_gNB_generate_RRCRelease(
                  size,
                  buffer,
                  PDCP_TRANSMISSION_MODE_CONTROL);
+
+    rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_context_pP->ue_context.gNB_ue_ngap_id);
+    ue_context_pP->ue_context.ue_release_timer_rrc = 1;
   }
 #endif
 }
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index c6778729ec47d1daf78fa467f1e6dc3935068679..30c3f2f9962bf60b797a4e1fbec0392e56a79d0b 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -57,6 +57,9 @@
 #include "RRC/NR/MESSAGES/asn1_msg.h"
 #include "NR_UERadioAccessCapabilityInformation.h"
 #include "NR_UE-CapabilityRAT-ContainerList.h"
+#include "NGAP_Cause.h"
+#include "NGAP_CauseRadioNetwork.h"
+#include "f1ap_messages_types.h"
 
 extern RAN_CONTEXT_t RC;
 
@@ -303,25 +306,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) ;
@@ -332,33 +354,23 @@ nr_rrc_pdcp_config_security(
     if (print_keys == 1 ) {
       print_keys =0;
       LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, ue_context_pP->ue_context.kgnb, 32,"\nKgNB:" );
-      LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 32,"\nKRRCenc:" );
-      LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 32,"\nKRRCint:" );
+      LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 16,"\nKRRCenc:" );
+      LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 16,"\nKRRCint:" );
     }
   }
 
-  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 +436,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);
@@ -494,6 +506,10 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
     rrc_gNB_ue_context_t            *ue_context_p = NULL;
     protocol_ctxt_t                 ctxt;
     uint8_t                         pdu_sessions_done = 0;
+    gtpv1u_gnb_create_tunnel_req_t  create_tunnel_req;
+    gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp;
+    uint8_t                         inde_list[NR_NB_RB_MAX - 3]= {0};
+    int                             ret = 0;
 
     ue_initial_id  = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_initial_id;
     gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).gNB_ue_ngap_id;
@@ -517,28 +533,65 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
       ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id;
       ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nas_pdu_flag;
 
-      if (NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions != 0) {
-        ue_context_p->ue_context.nb_of_pdusessions = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions;
+      uint8_t nb_pdusessions_tosetup = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions;
+      if (nb_pdusessions_tosetup != 0) {
+        memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
         for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
-          if(ue_context_p->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE)
-              continue;
-            ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_NEW;
-            ue_context_p->ue_context.pdusession[i].param  = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done];
-            pdu_sessions_done++;
+          if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
+            continue;
+          ue_context_p->ue_context.pduSession[i].status        = PDU_SESSION_STATUS_NEW;
+          ue_context_p->ue_context.pduSession[i].param         = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done];
+          create_tunnel_req.pdusession_id[pdu_sessions_done]   = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].pdusession_id;
+          create_tunnel_req.incoming_rb_id[pdu_sessions_done]  = i+1;
+          create_tunnel_req.upf_NGu_teid[pdu_sessions_done]    = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].gtp_teid;
+          create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.length;
+          memcpy(create_tunnel_req.upf_addr[pdu_sessions_done].buffer,
+                  NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.buffer,
+                  sizeof(uint8_t)*20);
+          LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n",
+                i,
+                create_tunnel_req.upf_NGu_teid[pdu_sessions_done],
+                create_tunnel_req.pdusession_id[pdu_sessions_done]);
+          inde_list[pdu_sessions_done] = i;
+          pdu_sessions_done++;
+
+          if(pdu_sessions_done >= nb_pdusessions_tosetup) {
+            break;
+          }
+        }
 
-            // TODO establish PDU SESSION
+        ue_context_p->ue_context.nb_of_pdusessions = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions;
+        create_tunnel_req.rnti                     = ue_context_p->ue_context.rnti;
+        create_tunnel_req.num_tunnels              = pdu_sessions_done;
 
-            if(pdu_sessions_done >= NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions) {
-              break;
-            }
+        ret = gtpv1u_create_ngu_tunnel(
+                instance,
+                &create_tunnel_req,
+                &create_tunnel_resp);
+        if (ret != 0) {
+          LOG_E(NR_RRC,"rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti);
+          ue_context_p->ue_context.ue_release_timer_ng = 1;
+          ue_context_p->ue_context.ue_release_timer_thres_ng = 100;
+          ue_context_p->ue_context.ue_release_timer = 0;
+          ue_context_p->ue_context.ue_reestablishment_timer = 0;
+          ue_context_p->ue_context.ul_failure_timer = 20000;
+          ue_context_p->ue_context.ul_failure_timer = 0;
+          return (0);
         }
+
+        nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
+          &ctxt,
+          &create_tunnel_resp,
+          &inde_list[0]);
+        ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup;
+        ue_context_p->ue_context.established_pdu_sessions_flag = 1;
       }
 
       /* NAS PDU */
-      ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag;
-      if (ue_context_p->ue_context.nas_pdu_flag == 1) {
-          ue_context_p->ue_context.nas_pdu.length = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.length;
-          ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer;
+      if (NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag == 1) {
+        ue_context_p->ue_context.nas_pdu_flag   = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag;
+        ue_context_p->ue_context.nas_pdu.length = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.length;
+        ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer;
       }
         
       /* security */
@@ -569,7 +622,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);
     }
@@ -588,25 +641,34 @@ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(
 {
   MessageDef      *msg_p         = NULL;
   int pdusession;
-  int e_rabs_done = 0;
-  int e_rabs_failed = 0;
+  int pdu_sessions_done = 0;
+  int pdu_sessions_failed = 0;
+  int qos_flow_index = 0;
   msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, NGAP_INITIAL_CONTEXT_SETUP_RESP);
   NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id;
 
   for (pdusession = 0; pdusession < ue_context_pP->ue_context.nb_of_pdusessions; pdusession++) {
-    if (ue_context_pP->ue_context.pdusession[pdusession].status == E_RAB_STATUS_DONE) {
-      e_rabs_done++;
-      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
+    if (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_DONE) {
+      pdu_sessions_done++;
+      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
       // TODO add other information from S1-U when it will be integrated
       NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gtp_teid = ue_context_pP->ue_context.gnb_gtp_teid[pdusession];
       memcpy(NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gNB_addr.buffer , ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].buffer, 20);
       NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gNB_addr.length = 4;
-      ue_context_pP->ue_context.pdusession[pdusession].status = E_RAB_STATUS_ESTABLISHED;
+      ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED;
+      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos;
+      for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos; qos_flow_index++) {
+        NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi =
+            ue_context_pP->ue_context.pduSession[pdusession].param.qos[qos_flow_index].qfi;
+        NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL;
+      }
     } else {
-      e_rabs_failed++;
-      ue_context_pP->ue_context.pdusession[pdusession].status = E_RAB_STATUS_FAILED;
-      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
+      pdu_sessions_failed++;
+      ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_FAILED;
+      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
       // TODO add cause when it will be integrated
+      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].cause = NGAP_Cause_PR_radioNetwork;
+      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID;
     }
   }
 
@@ -619,13 +681,17 @@ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(
     MSC_AS_TIME_ARGS(ctxt_pP),
     ue_context_pP->ue_id_rnti,
     NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).gNB_ue_ngap_id,
-    e_rabs_done, e_rabs_failed);
-  NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions = e_rabs_done;
-  NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions_failed = e_rabs_failed;
+    pdu_sessions_done, pdu_sessions_failed);
+  NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions = pdu_sessions_done;
+  NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions_failed = pdu_sessions_failed;
   itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
 }
 
 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 +704,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 +853,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);
     }
 }
@@ -859,10 +954,10 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
 
   for (pdusession = 0; pdusession < ue_context_pP->ue_context.setup_pdu_sessions; pdusession++) {
     // if (xid == ue_context_pP->ue_context.pdusession[pdusession].xid) {
-      if (ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_DONE) {
-        NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
+      if (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_DONE) {
+        NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
         // NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = 1;
-        NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pdusession[pdusession].param.nb_qos;
+        NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos;
         NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gtp_teid = ue_context_pP->ue_context.gnb_gtp_teid[pdusession];
         NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gNB_addr.pdu_session_type = PDUSessionType_ipv4;
         NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gNB_addr.length = ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].length;
@@ -870,13 +965,13 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
                 ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].buffer, sizeof(uint8_t)*20);
         for (qos_flow_index = 0; qos_flow_index < NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow; qos_flow_index++) {
           NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi =
-            ue_context_pP->ue_context.pdusession[pdusession].param.qos[qos_flow_index].qfi;
+            ue_context_pP->ue_context.pduSession[pdusession].param.qos[qos_flow_index].qfi;
           NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL;
         }
 
-        ue_context_pP->ue_context.pdusession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED;
+        ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED;
         LOG_I (NR_RRC,"gnb_gtp_addr (msg index %d, pdu_sessions index %d, status %d, xid %d): nb_of_pdusessions %d,  pdusession_id %d, teid: %u, addr: %d.%d.%d.%d \n ",
-               pdu_sessions_done, pdusession, ue_context_pP->ue_context.pdusession[pdusession].status, xid,
+               pdu_sessions_done, pdusession, ue_context_pP->ue_context.pduSession[pdusession].status, xid,
                ue_context_pP->ue_context.nb_of_pdusessions,
                NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].pdusession_id,
                NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gtp_teid,
@@ -885,12 +980,12 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
                NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[2],
                NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[3]);
         pdu_sessions_done++;
-      } else if ((ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_NEW) ||
-                 (ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_ESTABLISHED)) {
+      } else if ((ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_NEW) ||
+                 (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_ESTABLISHED)) {
         LOG_D (NR_RRC,"PDU-SESSION is NEW or already ESTABLISHED\n");
       } else { /* to be improved */
-        ue_context_pP->ue_context.pdusession[pdusession].status = PDU_SESSION_STATUS_FAILED;
-        NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
+        ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_FAILED;
+        NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
         pdu_sessions_failed++;
         // TODO add cause when it will be integrated
       }
@@ -919,7 +1014,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
   }
 
   for(int i = 0; i < NB_RB_MAX; i++) {
-    ue_context_pP->ue_context.pdusession[i].xid = -1;
+    ue_context_pP->ue_context.pduSession[i].xid = -1;
   }
 
   return;
@@ -965,20 +1060,21 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
 
     PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
     for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
-      if(ue_context_p->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE)
+      if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
         continue;
-      ue_context_p->ue_context.pdusession[i].status      = PDU_SESSION_STATUS_NEW;
-      ue_context_p->ue_context.pdusession[i].param       = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done];
+      ue_context_p->ue_context.pduSession[i].status      = PDU_SESSION_STATUS_NEW;
+      ue_context_p->ue_context.pduSession[i].param       = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done];
       create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id;
+      create_tunnel_req.incoming_rb_id[pdu_sessions_done]= i+1;
       create_tunnel_req.upf_NGu_teid[pdu_sessions_done]  = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid;
       memcpy(create_tunnel_req.upf_addr[pdu_sessions_done].buffer,
-              NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.buffer,
+              NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer,
               sizeof(uint8_t)*20);
-      create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.length;
+      create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.length;
       LOG_I(NR_RRC,"NGAP PDUSESSION SETUP REQ: local index %d teid %u, pdusession id %d \n",
             i,
-            create_tunnel_req.upf_NGu_teid[i],
-            create_tunnel_req.pdusession_id[i]);
+            create_tunnel_req.upf_NGu_teid[pdu_sessions_done],
+            create_tunnel_req.pdusession_id[pdu_sessions_done]);
       inde_list[pdu_sessions_done] = i;
       pdu_sessions_done++;
 
@@ -1015,8 +1111,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);
   }
 }
@@ -1045,7 +1142,7 @@ rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(
     NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause_value       = cause_valueP;
     NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).nb_of_pdusessions = ue_context_pP->ue_context.setup_pdu_sessions;
     for (int pdusession = 0; pdusession < ue_context_pP->ue_context.setup_pdu_sessions; pdusession++) {
-      NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
+      NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
     }
     itti_send_msg_to_task(TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_mod_idP), msg_context_release_req_p);
   }
@@ -1130,11 +1227,25 @@ rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(
     return -1;
   } else {
     ue_context_p->ue_context.ue_release_timer_ng = 0;
+    ue_context_p->ue_context.ue_release_timer_thres_rrc = 1000;
     PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
+    ctxt.eNB_index = 0;
     rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
     return 0;
   }
 }
+
+void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(
+  instance_t instance,
+  uint32_t   gNB_ue_ngap_id) {
+  MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, MSC_NGAP_GNB, NULL, 0,
+                     "0 NGAP_UE_CONTEXT_RELEASE_COMPLETE gNB_ue_ngap_id 0x%06"PRIX32" ",
+                     gNB_ue_ngap_id);
+  MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
+  NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = gNB_ue_ngap_id;
+  itti_send_msg_to_task(TASK_NGAP, instance, msg);
+}
+
 //------------------------------------------------------------------------------
 /*
 * Remove UE ids (ue_initial_id and ng_id) from hashtables.
@@ -1244,12 +1355,12 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
   NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id;
 
   for (int i = 0;  i < NB_RB_MAX; i++) {
-    if (xid == ue_context_pP->ue_context.pdusession[i].xid) {
+    if (xid == ue_context_pP->ue_context.pduSession[i].xid) {
       NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusession_release[pdu_sessions_released].pdusession_id =
-          ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
+          ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
       pdu_sessions_released++;
       //clear
-      memset(&ue_context_pP->ue_context.pdusession[i], 0, sizeof(pdu_session_param_t));
+      memset(&ue_context_pP->ue_context.pduSession[i], 0, sizeof(pdu_session_param_t));
     }
   }
 
@@ -1265,7 +1376,7 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
 
   //clear xid
   for(int i = 0; i < NB_RB_MAX; i++) {
-    ue_context_pP->ue_context.pdusession[i].xid = -1;
+    ue_context_pP->ue_context.pduSession[i].xid = -1;
   }
 
   //clear release pdusessions
@@ -1326,7 +1437,7 @@ rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
       }
 
       for (i = 0;  i < NR_NB_RB_MAX; i++) {
-        if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pdusession[i].param.pdusession_id) {
+        if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pduSession[i].param.pdusession_id) {
           b_existed = 1;
           break;
         }
@@ -1340,13 +1451,13 @@ rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
         ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 30;
         ue_context_p->ue_context.nb_release_of_pdusessions++;
       } else {
-        if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_FAILED) {
-          ue_context_p->ue_context.pdusession[i].xid = xid;
+        if(ue_context_p->ue_context.pduSession[i].status == PDU_SESSION_STATUS_FAILED) {
+          ue_context_p->ue_context.pduSession[i].xid = xid;
           continue;
-        } else if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED) {
-          LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pdusession[i].param.pdusession_id);
-          ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_TORELEASE;
-          ue_context_p->ue_context.pdusession[i].xid = xid;
+        } else if(ue_context_p->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED) {
+          LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pduSession[i].param.pdusession_id);
+          ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_TORELEASE;
+          ue_context_p->ue_context.pduSession[i].xid = xid;
           pdusession_release_drb++;
         } else {
           // pdusession_id status NG
@@ -1370,7 +1481,7 @@ rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
       GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
 
       for(i = 0; i < NB_RB_MAX; i++) {
-        if(xid == ue_context_p->ue_context.pdusession[i].xid) {
+        if(xid == ue_context_p->ue_context.pduSession[i].xid) {
           GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] = ue_context_p->ue_context.gnb_gtp_psi[i];
           ue_context_p->ue_context.gnb_gtp_teid[i] = 0;
           memset(&ue_context_p->ue_context.gnb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.gnb_gtp_addrs[i]));
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h
index f13c468f94f7141b28866725f9b2ae9aa67b4c80..8779d62ff6b37d9ff7a9464ea87eb1245a2a97a3 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.h
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.h
@@ -129,6 +129,10 @@ rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(
   instance_t instance
 );
 
+void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(
+  instance_t instance,
+  uint32_t   gNB_ue_ngap_id);
+
 void
 rrc_gNB_NGAP_remove_ue_ids(
   gNB_RRC_INST *const rrc_instance_pP,
diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c
index 988db09cc1e2573cd14c3b8cec6a436ab837cf7d..eb7559f69d8c63fa27565df050e5f6114fdb022c 100644
--- a/openair2/RRC/NR/rrc_gNB_UE_context.c
+++ b/openair2/RRC/NR/rrc_gNB_UE_context.c
@@ -135,7 +135,7 @@ rrc_gNB_allocate_new_UE_context(
 
   for(int i = 0; i < NB_RB_MAX; i++) {
     new_p->ue_context.e_rab[i].xid = -1;
-    new_p->ue_context.pdusession[i].xid = -1;
+    new_p->ue_context.pduSession[i].xid = -1;
     new_p->ue_context.modify_e_rab[i].xid = -1;
   }
 
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index 5ea02c78322f1b9d377f9d127baf6f1d9a20e2e6..0b7b0745aa0616f8dcaa4e0f095c6ca7335064f1 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -39,6 +39,7 @@
 #include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
 #include "executables/softmodem-common.h"
 #include <openair2/RRC/NR/rrc_gNB_UE_context.h>
+#include <openair3/ocp-gtpu/gtp_itf.h>
 #include "UTIL/OSA/osa_defs.h"
 
 extern boolean_t nr_rrc_pdcp_config_asn1_req(
@@ -151,7 +152,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
   ue_context_p->ue_context.reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
   NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t));
   ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies;
-  carrier->initial_csi_index[rrc->Nb_ue] = 0;
+  carrier->initial_csi_index[ue_context_p->local_uid + 1] = 0;
   ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
   if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){
     fill_default_rbconfig(ue_context_p->ue_context.rb_config,
@@ -238,11 +239,25 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
                           cipher_algo,
                           NR_SecurityConfig__keyToUse_secondary);
   }
-  fill_default_reconfig(carrier->servingcellconfigcommon,
+  if (ue_context_p->ue_context.spCellConfig) {
+    fill_default_reconfig(carrier->servingcellconfigcommon,
+                        ue_context_p->ue_context.spCellConfig->spCellConfigDedicated,
                         reconfig_ies,
                         ue_context_p->ue_context.secondaryCellGroup,
                         carrier->pdsch_AntennaPorts,
-                        carrier->initial_csi_index[rrc->Nb_ue]);
+                        carrier->do_CSIRS,
+                        carrier->initial_csi_index[ue_context_p->local_uid + 1],
+                        ue_context_p->local_uid);
+  } else {
+    fill_default_reconfig(carrier->servingcellconfigcommon,
+                        NULL,
+                        reconfig_ies,
+                        ue_context_p->ue_context.secondaryCellGroup,
+                        carrier->pdsch_AntennaPorts,
+                        carrier->do_CSIRS,
+                        carrier->initial_csi_index[ue_context_p->local_uid + 1],
+                        ue_context_p->local_uid);
+  }
   ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
   NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config));
   memset((void *)CG_Config,0,sizeof(*CG_Config));
@@ -327,21 +342,31 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
                               1024);
     X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = (enc_rval.encoded+7)>>3;
     itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding
-  } else if (get_softmodem_params()->do_ra) {
+  } else if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
     PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0,rrc->module_id);
   }
 
   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_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,
@@ -352,26 +377,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);
 
@@ -380,7 +404,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);
@@ -397,25 +420,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_GTPV1_U, 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 ab3f19227622cbcb9b26f3339bfc448fcdc32997..596aaf8dc15d9c14f8ccb6c89d86691585090dc5 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -31,6 +31,7 @@
 #define RRC_GNB_NSA_C
 
 #include "NR_ServingCellConfigCommon.h"
+#include "NR_ServingCellConfig.h"
 #include "NR_RRCReconfiguration.h"
 #include "NR_RRCReconfiguration-IEs.h"
 #include "NR_CellGroupConfig.h"
@@ -49,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) {
@@ -80,8 +61,15 @@ void fill_default_coresetZero(NR_ControlResourceSet_t *coreset0, NR_ServingCellC
 
   // frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B,
   if(coreset0->frequencyDomainResources.buf == NULL) coreset0->frequencyDomainResources.buf = calloc(1,6);
-  coreset0->frequencyDomainResources.buf[0] = 0xff;
-  coreset0->frequencyDomainResources.buf[1] = 0;
+  int curr_bwp = NRRIV2BW(servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
+  if (curr_bwp < 48)
+    coreset0->frequencyDomainResources.buf[0] = 0xf0;
+  else
+    coreset0->frequencyDomainResources.buf[0] = 0xff;
+  if (curr_bwp < 96)
+    coreset0->frequencyDomainResources.buf[1] = 0;
+  else
+    coreset0->frequencyDomainResources.buf[1] = 0xff;
   coreset0->frequencyDomainResources.buf[2] = 0;
   coreset0->frequencyDomainResources.buf[3] = 0;
   coreset0->frequencyDomainResources.buf[4] = 0;
@@ -135,7 +123,7 @@ void fill_default_searchSpaceZero(NR_SearchSpace_t *ss0) {
   // 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
   ss0->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
   ss0->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
-  ss0->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
+  ss0->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2;
   ss0->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
   ss0->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
 
@@ -143,11 +131,14 @@ void fill_default_searchSpaceZero(NR_SearchSpace_t *ss0) {
 }
 
 void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
+                                     NR_ServingCellConfig_t *servingcellconfigdedicated,
                                      NR_CellGroupConfig_t *secondaryCellGroup,
                                      int scg_id,
                                      int servCellIndex,
-                                     int n_physical_antenna_ports,
-                                     int initial_csi_index) {
+                                     int dl_antenna_ports,
+                                     int do_csirs,
+                                     int initial_csi_index,
+                                     int uid) {
   AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
   AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n");
 
@@ -171,8 +162,8 @@ 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);
-  if (get_softmodem_params()->do_ra)
+  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
     nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_am);
@@ -180,12 +171,22 @@ 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 = 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));
+  SchedulingRequestConf->schedulingRequestId = 0;  //Could be changed
+  SchedulingRequestConf->sr_ProhibitTimer = calloc(1,sizeof(*SchedulingRequestConf->sr_ProhibitTimer));
+  *SchedulingRequestConf->sr_ProhibitTimer = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms16;
+  SchedulingRequestConf->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n32;
+  ASN_SEQUENCE_ADD(&secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list,SchedulingRequestConf);
+  secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToReleaseList = NULL;
+
   secondaryCellGroup->mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->bsr_Config));
-  secondaryCellGroup->mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf80;
-  secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer     = NR_BSR_Config__retxBSR_Timer_sf320;
+  secondaryCellGroup->mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10;
+  secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer     = NR_BSR_Config__retxBSR_Timer_sf160;
   secondaryCellGroup->mac_CellGroupConfig->tag_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config));
   secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL;
   secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList  = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList));
@@ -226,66 +227,52 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
   secondaryCellGroup->spCellConfig->reconfigurationWithSync->t304=NR_ReconfigurationWithSync__t304_ms2000;
   secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = NULL;
   secondaryCellGroup->spCellConfig->reconfigurationWithSync->ext1                 = NULL;
-  /* contention free ra */
-  secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = calloc(1,sizeof(struct NR_ReconfigurationWithSync__rach_ConfigDedicated));
-  secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->present= NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink;
-  secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink= calloc(1,sizeof(struct NR_RACH_ConfigDedicated));
-  secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra= calloc(1,sizeof(struct NR_CFRA));
-  secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->ra_Prioritization= NULL;
-  secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions= calloc(1,sizeof(struct NR_CFRA__occasions));
-  memcpy(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->rach_ConfigGeneric,
-         &servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric, sizeof(NR_RACH_ConfigGeneric_t));
-  secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long));
-  *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one;
-  secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb;
-  secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb));
-  secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0;
-  struct NR_CFRA_SSB_Resource *ssbElem[8];
-  ssbElem[0] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
-  ssbElem[0]->ssb = 0;
-  ssbElem[0]->ra_PreambleIndex = 63;
-  ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[0]);
-#if 0
-  ssbElem[1] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
-  ssbElem[1]->ssb = 1;
-  ssbElem[1]->ra_PreambleIndex = 62;
-  ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[1]);
-  ssbElem[2] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
-  ssbElem[2]->ssb = 2;
-  ssbElem[2]->ra_PreambleIndex = 63;
-  ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[2]);
-  ssbElem[3] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
-  ssbElem[3]->ssb = 3;
-  ssbElem[3]->ra_PreambleIndex = 63;
-  ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[3]);
-  ssbElem[4] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
-  ssbElem[4]->ssb = 4;
-  ssbElem[4]->ra_PreambleIndex = 63;
-  ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[4]);
-  ssbElem[5] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
-  ssbElem[5]->ssb = 5;
-  ssbElem[5]->ra_PreambleIndex = 63;
-  ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[5]);
-  ssbElem[6] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
-  ssbElem[6]->ssb = 6;
-  ssbElem[6]->ra_PreambleIndex = 63;
-  ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[6]);
-  ssbElem[7] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
-  ssbElem[7]->ssb = 7;
-  ssbElem[7]->ra_PreambleIndex = 63;
-  ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[7]);
-#endif
-  secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->ext1 = NULL;
+
+  // For 2-step contention-free random access procedure
+  if(get_softmodem_params()->sa == 0) {
+    secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = calloc(1,sizeof(struct NR_ReconfigurationWithSync__rach_ConfigDedicated));
+    secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->present= NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink;
+    secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink= calloc(1,sizeof(struct NR_RACH_ConfigDedicated));
+    secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra= calloc(1,sizeof(struct NR_CFRA));
+    secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->ra_Prioritization= NULL;
+    secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions= calloc(1,sizeof(struct NR_CFRA__occasions));
+    memcpy(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->rach_ConfigGeneric,
+           &servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric, sizeof(NR_RACH_ConfigGeneric_t));
+    secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long));
+    *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one;
+    secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb;
+    secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb));
+    secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0;
+
+    int n_ssb = 0;
+    struct NR_CFRA_SSB_Resource *ssbElem[64];
+    for (int i=0;i<64;i++) {
+      if ((bitmap>>(63-i))&0x01){
+        ssbElem[n_ssb] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
+        ssbElem[n_ssb]->ssb = i;
+        ssbElem[n_ssb]->ra_PreambleIndex = 63 - (uid % 64);
+        ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[n_ssb]);
+        n_ssb++;
+      }
+    }
+
+    secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->ext1 = NULL;
+  }
+
   secondaryCellGroup->spCellConfig->rlf_TimersAndConstants = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants));
   secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->present = NR_SetupRelease_RLF_TimersAndConstants_PR_setup;
   secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup));
-  secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->t310 = NR_RLF_TimersAndConstants__t310_ms2000;
-  secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n310 = NR_RLF_TimersAndConstants__n310_n10;
+  secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->t310 = NR_RLF_TimersAndConstants__t310_ms4000;
+  secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n310 = NR_RLF_TimersAndConstants__n310_n20;
   secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n311 = NR_RLF_TimersAndConstants__n311_n1;
   secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1 = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1));
   secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1->t311 = NR_RLF_TimersAndConstants__ext1__t311_ms30000;
   secondaryCellGroup->spCellConfig->rlmInSyncOutOfSyncThreshold                   = NULL;
-  secondaryCellGroup->spCellConfig->spCellConfigDedicated = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated));
+  if (servingcellconfigdedicated) {
+    secondaryCellGroup->spCellConfig->spCellConfigDedicated = servingcellconfigdedicated;
+  } else {
+    secondaryCellGroup->spCellConfig->spCellConfigDedicated = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated));
+  }
   secondaryCellGroup->spCellConfig->spCellConfigDedicated->tdd_UL_DL_ConfigurationDedicated = NULL;
   secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP));
   secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdcch_Config=NULL;
@@ -460,9 +447,15 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
 #endif
 
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList= NULL;
- secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList));
+ 
+ NR_BWP_Downlink_t *bwp = NULL;
+ if (servingcellconfigdedicated) {
+   bwp=servingcellconfigdedicated->downlinkBWP_ToAddModList->list.array[0];
+ } else {
+   secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList));
 
- NR_BWP_Downlink_t *bwp=calloc(1,sizeof(*bwp));
+   bwp=calloc(1,sizeof(*bwp));
+ }
  bwp->bwp_Id=1;
  bwp->bwp_Common=calloc(1,sizeof(*bwp->bwp_Common));
  // copy common BWP size from initial BWP except for bandwdith
@@ -548,7 +541,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0));
 
  ASN_SEQUENCE_ADD(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list,ss);
- 
+
 
  bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1));
  *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=0;
@@ -577,8 +570,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
    ASN_SEQUENCE_ADD(&bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list,pdschi);
  }
 
- bwp->bwp_Dedicated=calloc(1,sizeof(*bwp->bwp_Dedicated));
-
+ if (!servingcellconfigdedicated) {
+   bwp->bwp_Dedicated=calloc(1,sizeof(*bwp->bwp_Dedicated));
+ }
  bwp->bwp_Dedicated->pdcch_Config=calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config));
  bwp->bwp_Dedicated->pdcch_Config->present = NR_SetupRelease_PDCCH_Config_PR_setup;
  bwp->bwp_Dedicated->pdcch_Config->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup));
@@ -626,113 +620,33 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
 
  bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToReleaseList = NULL;
 
- bwp->bwp_Dedicated->pdsch_Config = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config));
+ if (!servingcellconfigdedicated) {
+  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 = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup));
+ }
+ bwp->bwp_Dedicated->pdsch_Config->choice.setup->dataScramblingIdentityPDSCH = NULL;
 
- bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL;
+ if (dl_antenna_ports > 1)// for MIMO, we use DMRS Config Type 2
+   bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type));
+ else
+   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;
-
+ if (!servingcellconfigdedicated) {
+   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_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=NULL;
- bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList));
-
-#if 0
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList));
 
- NR_TCI_State_t*tcid0=calloc(1,sizeof(*tcid0));
- tcid0->tci_StateId=0;
- tcid0->qcl_Type1.cell=NULL;
- tcid0->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid0->qcl_Type1.bwp_Id));
- *tcid0->qcl_Type1.bwp_Id=1;
- tcid0->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs;
- tcid0->qcl_Type1.referenceSignal.choice.csi_rs = 2;
- tcid0->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA;
- ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid0);
-
- NR_TCI_State_t*tcid1=calloc(1,sizeof(*tcid1));
- tcid1->tci_StateId=0;
- tcid1->qcl_Type1.cell=NULL;
- tcid1->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid1->qcl_Type1.bwp_Id));
- *tcid1->qcl_Type1.bwp_Id=1;
- tcid1->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs;
- tcid1->qcl_Type1.referenceSignal.choice.csi_rs = 6;
- tcid1->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA;
- ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid1);
-
- NR_TCI_State_t*tcid2=calloc(1,sizeof(*tcid2));
- tcid2->tci_StateId=2;
- tcid2->qcl_Type1.cell=NULL;
- tcid2->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid2->qcl_Type1.bwp_Id));
- *tcid2->qcl_Type1.bwp_Id=1;
- tcid2->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs;
- tcid2->qcl_Type1.referenceSignal.choice.csi_rs = 10;
- tcid2->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA;
- ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid2);
-
- NR_TCI_State_t*tcid3=calloc(1,sizeof(*tcid3));
- tcid3->tci_StateId=3;
- tcid3->qcl_Type1.cell=NULL;
- tcid3->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid3->qcl_Type1.bwp_Id));
- *tcid3->qcl_Type1.bwp_Id=1;
- tcid3->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs;
- tcid3->qcl_Type1.referenceSignal.choice.csi_rs = 14;
- tcid3->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA;
- ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid3);
-
- NR_TCI_State_t*tcid4=calloc(1,sizeof(*tcid4));
- tcid4->tci_StateId=4;
- tcid4->qcl_Type1.cell=NULL;
- tcid4->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid4->qcl_Type1.bwp_Id));
- *tcid4->qcl_Type1.bwp_Id=1;
- tcid4->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs;
- tcid4->qcl_Type1.referenceSignal.choice.csi_rs = 18;
- tcid4->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA;
- ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid4);
-
- NR_TCI_State_t*tcid5=calloc(1,sizeof(*tcid5));
- tcid5->tci_StateId=5;
- tcid5->qcl_Type1.cell=NULL;
- tcid5->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid5->qcl_Type1.bwp_Id));
- *tcid5->qcl_Type1.bwp_Id=1;
- tcid5->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs;
- tcid5->qcl_Type1.referenceSignal.choice.csi_rs = 22;
- tcid5->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA;
- ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid5);
-
- NR_TCI_State_t*tcid6=calloc(1,sizeof(*tcid6));
- tcid6->tci_StateId=6;
- tcid6->qcl_Type1.cell=NULL;
- tcid6->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid6->qcl_Type1.bwp_Id));
- *tcid6->qcl_Type1.bwp_Id=1;
- tcid6->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs;
- tcid6->qcl_Type1.referenceSignal.choice.csi_rs = 26;
- tcid6->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA;
- ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid6);
-
- NR_TCI_State_t*tcid7=calloc(1,sizeof(*tcid7));
- tcid7->tci_StateId=7;
- tcid7->qcl_Type1.cell=NULL;
- tcid7->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid7->qcl_Type1.bwp_Id));
- *tcid7->qcl_Type1.bwp_Id=1;
- tcid7->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs;
- tcid7->qcl_Type1.referenceSignal.choice.csi_rs = 30;
- tcid7->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA;
- ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid7);
-#endif
-
-
  n_ssb = 0;
  NR_TCI_State_t *tcid[64];
  for (int i=0;i<64;i++) {
@@ -828,8 +742,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  *bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup->beamFailureDetectionTimer = NR_RadioLinkMonitoringConfig__beamFailureDetectionTimer_pbfd2;
 #endif
  
- ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list,bwp);
-
+ if (!servingcellconfigdedicated) {
+   ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list,bwp);
+ }
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id));
  
  *secondaryCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id=1;
@@ -837,26 +752,38 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id = NULL;
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id = calloc(1, sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id));
  *secondaryCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id = 1;
- secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig));
+
+ if (!servingcellconfigdedicated) {
+   secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig));
+ }
 
  NR_BWP_UplinkDedicated_t *initialUplinkBWP = calloc(1,sizeof(*initialUplinkBWP));
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP = initialUplinkBWP;
  initialUplinkBWP->pucch_Config = NULL;
  initialUplinkBWP->pusch_Config = calloc(1,sizeof(*initialUplinkBWP->pusch_Config));
  initialUplinkBWP->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup;
- NR_PUSCH_Config_t *pusch_Config = calloc(1,sizeof(*pusch_Config));
+ NR_PUSCH_Config_t *pusch_Config = NULL;
+ if (servingcellconfigdedicated) {
+   pusch_Config = servingcellconfigdedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup;
+ } else {
+   pusch_Config = calloc(1,sizeof(*pusch_Config));
+ }
  initialUplinkBWP->pusch_Config->choice.setup = pusch_Config;
  pusch_Config->txConfig=calloc(1,sizeof(*pusch_Config->txConfig));
  *pusch_Config->txConfig= NR_PUSCH_Config__txConfig_codebook;
  pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA = NULL;
- pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB = calloc(1,sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB));
- pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->present = NR_SetupRelease_DMRS_UplinkConfig_PR_setup;
- pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup = calloc(1,sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup));
+ if (!servingcellconfigdedicated) {
+  pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB = calloc(1,sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB));
+  pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->present = NR_SetupRelease_DMRS_UplinkConfig_PR_setup;
+  pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup = calloc(1,sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup));
+ }
  NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
  NR_DMRS_UplinkConfig->dmrs_Type = NULL;
  NR_DMRS_UplinkConfig->dmrs_AdditionalPosition = calloc(1,sizeof(*NR_DMRS_UplinkConfig->dmrs_AdditionalPosition));
  *NR_DMRS_UplinkConfig->dmrs_AdditionalPosition = NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos0;
- NR_DMRS_UplinkConfig->phaseTrackingRS=NULL;
+ if (!servingcellconfigdedicated) {
+   NR_DMRS_UplinkConfig->phaseTrackingRS=NULL;
+ }
  NR_DMRS_UplinkConfig->maxLength=NULL;
  NR_DMRS_UplinkConfig->transformPrecodingDisabled = calloc(1,sizeof(*NR_DMRS_UplinkConfig->transformPrecodingDisabled));
  NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0 = NULL;
@@ -903,7 +830,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  pusch_Config->tp_pi2BPSK=NULL;
 
  /*------------------------------TRANSFORM PRECODING- -----------------------------------------------------------------------*/
- 
+
  uint8_t transform_precoding = NR_PUSCH_Config__transformPrecoder_disabled;
 
  // TBD: configure this from .conf file, Dedicated params cannot yet be configured in .conf file.
@@ -918,20 +845,20 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
   if (servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder != NULL)
     transform_precoding = NR_PUSCH_Config__transformPrecoder_enabled;
  }
- else 
+ else
     transform_precoding = *pusch_Config->transformPrecoder;
-    
- 
+
+
  if (transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled ) {
     /* Enable DMRS uplink config for transform precoding enabled */
     NR_DMRS_UplinkConfig->transformPrecodingEnabled = calloc(1,sizeof(*NR_DMRS_UplinkConfig->transformPrecodingEnabled));
     NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity = NULL;
-    NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceGroupHopping = NULL; 
+    NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceGroupHopping = NULL;
     NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceHopping = NULL;
-    NR_DMRS_UplinkConfig->transformPrecodingEnabled->ext1 = NULL; 
+    NR_DMRS_UplinkConfig->transformPrecodingEnabled->ext1 = NULL;
 
     LOG_I(RRC,"TRANSFORM PRECODING ENABLED......\n");
- 
+
   }
  /*----------------------------------------------------------------------------------------------------------------------------*/ 
 
@@ -992,8 +919,13 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  ASN_SEQUENCE_ADD(&srs_Config->srs_ResourceToAddModList->list,srs_res0);
 
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToReleaseList = NULL;
- secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList));
- NR_BWP_Uplink_t *ubwp = calloc(1,sizeof(*ubwp));
+ NR_BWP_Uplink_t *ubwp = NULL;
+ if (servingcellconfigdedicated) {
+   ubwp = servingcellconfigdedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0];
+ } else {
+   secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList));
+   ubwp = calloc(1,sizeof(*ubwp));
+ }
  ubwp->bwp_Id=1;
  ubwp->bwp_Common = calloc(1,sizeof(*ubwp->bwp_Common));
  // copy bwp_Common from Initial UL BWP except for bandwidth
@@ -1006,7 +938,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  ubwp->bwp_Common->pusch_ConfigCommon = servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon;
  ubwp->bwp_Common->pucch_ConfigCommon = servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon;
  
- ubwp->bwp_Dedicated = calloc(1,sizeof(*ubwp->bwp_Dedicated));
+ if (!servingcellconfigdedicated) {
+   ubwp->bwp_Dedicated = calloc(1,sizeof(*ubwp->bwp_Dedicated));
+ }
  ubwp->bwp_Dedicated->pucch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pucch_Config));
  ubwp->bwp_Dedicated->pucch_Config->present = NR_SetupRelease_PUCCH_Config_PR_setup;
  NR_PUCCH_Config_t *pucch_Config = calloc(1,sizeof(*pucch_Config));
@@ -1017,22 +951,16 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  NR_PUCCH_ResourceSet_t *pucchresset1=calloc(1,sizeof(*pucchresset1));
  pucchresset0->pucch_ResourceSetId = 0;
  NR_PUCCH_ResourceId_t *pucchresset0id0=calloc(1,sizeof(*pucchresset0id0));
- NR_PUCCH_ResourceId_t *pucchresset0id1=calloc(1,sizeof(*pucchresset0id1));
  *pucchresset0id0=1;
  ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchresset0id0);
- *pucchresset0id1=2;
- ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchresset0id1);
  pucchresset0->maxPayloadSize=NULL;
 
  ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset0);
 
  pucchresset1->pucch_ResourceSetId = 1;
  NR_PUCCH_ResourceId_t *pucchresset1id0=calloc(1,sizeof(*pucchresset1id0));
- NR_PUCCH_ResourceId_t *pucchresset1id1=calloc(1,sizeof(*pucchresset1id1));
- *pucchresset1id0=3;
+ *pucchresset1id0=2;
  ASN_SEQUENCE_ADD(&pucchresset1->resourceList.list,pucchresset1id0);
- *pucchresset1id1=4;
- ASN_SEQUENCE_ADD(&pucchresset1->resourceList.list,pucchresset1id1);
  pucchresset1->maxPayloadSize=NULL;
  ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset1);
 
@@ -1042,8 +970,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  NR_PUCCH_Resource_t *pucchres1=calloc(1,sizeof(*pucchres1));
  NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2));
  NR_PUCCH_Resource_t *pucchres3=calloc(1,sizeof(*pucchres3));
+
  pucchres0->pucch_ResourceId=1;
- pucchres0->startingPRB=8;
+ pucchres0->startingPRB= (8 + uid) % curr_bwp;
  pucchres0->intraSlotFrequencyHopping=NULL;
  pucchres0->secondHopPRB=NULL;
  pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0;
@@ -1053,18 +982,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  pucchres0->format.choice.format0->startingSymbolIndex=13;
  ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0);
 
- pucchres1->pucch_ResourceId=2;
- pucchres1->startingPRB=8;
- pucchres1->intraSlotFrequencyHopping=NULL;
- pucchres1->secondHopPRB=NULL;
- pucchres1->format.present= NR_PUCCH_Resource__format_PR_format0;
- pucchres1->format.choice.format0=calloc(1,sizeof(*pucchres1->format.choice.format0));
- pucchres1->format.choice.format0->initialCyclicShift=0;
- pucchres1->format.choice.format0->nrofSymbols=1;
- pucchres1->format.choice.format0->startingSymbolIndex=12;
- ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres1);
-
- pucchres2->pucch_ResourceId=3;
+ pucchres2->pucch_ResourceId=2;
  pucchres2->startingPRB=0;
  pucchres2->intraSlotFrequencyHopping=NULL;
  pucchres2->secondHopPRB=NULL;
@@ -1075,17 +993,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  pucchres2->format.choice.format2->startingSymbolIndex=13;
  ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2);
 
- pucchres3->pucch_ResourceId=4;
- pucchres3->startingPRB=0;
- pucchres3->intraSlotFrequencyHopping=NULL;
- pucchres3->secondHopPRB=NULL;
- pucchres3->format.present= NR_PUCCH_Resource__format_PR_format2;
- pucchres3->format.choice.format2=calloc(1,sizeof(*pucchres3->format.choice.format2));
- pucchres3->format.choice.format2->nrofPRBs=8;
- pucchres3->format.choice.format2->nrofSymbols=1;
- pucchres3->format.choice.format2->startingSymbolIndex=12;
- ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres3);
-
  pucch_Config->format2=calloc(1,sizeof(*pucch_Config->format2));
  pucch_Config->format2->present=NR_SetupRelease_PUCCH_FormatConfig_PR_setup;
  NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucchfmt2));
@@ -1093,11 +1000,24 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  pucchfmt2->interslotFrequencyHopping=NULL;
  pucchfmt2->additionalDMRS=NULL;
  pucchfmt2->maxCodeRate=calloc(1,sizeof(*pucchfmt2->maxCodeRate));
- *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot25;
+ *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot35;
  pucchfmt2->nrofSlots=NULL;
  pucchfmt2->pi2BPSK=NULL;
- pucchfmt2->simultaneousHARQ_ACK_CSI=NULL;
- pucch_Config->schedulingRequestResourceToAddModList=NULL;
+ pucchfmt2->simultaneousHARQ_ACK_CSI=calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI));
+ *pucchfmt2->simultaneousHARQ_ACK_CSI=NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true;
+
+ // for scheduling requestresource
+ 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_sl10;
+ schedulingRequestResourceConfig->periodicityAndOffset->choice.sl10 = 7;
+ schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource));
+ *schedulingRequestResourceConfig->resource = 1;
+ ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig);
+
  pucch_Config->schedulingRequestResourceToReleaseList=NULL;
  pucch_Config->multi_CSI_PUCCH_ResourceList=NULL;
  pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK));
@@ -1111,8 +1031,14 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  NR_PUCCH_SpatialRelationInfo_t *pucchspatial = calloc(1,sizeof(*pucchspatial));
  pucchspatial->pucch_SpatialRelationInfoId = 1;
  pucchspatial->servingCellId = NULL;
- pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index;
- pucchspatial->referenceSignal.choice.csi_RS_Index = 0;
+ if(do_csirs) {
+   pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index;
+   pucchspatial->referenceSignal.choice.csi_RS_Index = 0;
+ }
+ else {
+   pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_ssb_Index;
+   pucchspatial->referenceSignal.choice.ssb_Index = 0;
+ }
  pucchspatial->pucch_PathlossReferenceRS_Id = 0;
  pucchspatial->p0_PUCCH_Id = 1;
  pucchspatial->closedLoopIndex = NR_PUCCH_SpatialRelationInfo__closedLoopIndex_i0;
@@ -1136,11 +1062,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  ASN_SEQUENCE_ADD(&pucch_Config->pucch_PowerControl->p0_Set->list,p00);
  pucch_Config->pucch_PowerControl->pathlossReferenceRSs = NULL;
 
- // copy pusch_Config from dedicated initialBWP
- ubwp->bwp_Dedicated->pusch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pusch_Config));
- ubwp->bwp_Dedicated->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup;
- ubwp->bwp_Dedicated->pusch_Config->choice.setup = pusch_Config;
-
+ if (!servingcellconfigdedicated) {
+   // copy pusch_Config from dedicated initialBWP
+   ubwp->bwp_Dedicated->pusch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pusch_Config));
+   ubwp->bwp_Dedicated->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup;
+   ubwp->bwp_Dedicated->pusch_Config->choice.setup = pusch_Config;
+ }
  ubwp->bwp_Dedicated->configuredGrantConfig = NULL;
  ubwp->bwp_Dedicated->srs_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->srs_Config));
  ubwp->bwp_Dedicated->srs_Config->present = NR_SetupRelease_SRS_Config_PR_setup;
@@ -1148,7 +1075,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
 
  ubwp->bwp_Dedicated->beamFailureRecoveryConfig = NULL;
 
- ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list,ubwp);
+ if (!servingcellconfigdedicated) {
+   ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list,ubwp);
+ }
 
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id));
  *secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = 1;
@@ -1192,13 +1121,57 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  NR_CSI_MeasConfig_t *csi_MeasConfig = calloc(1,sizeof(*csi_MeasConfig));
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup = csi_MeasConfig;
 
- csi_MeasConfig->csi_IM_ResourceToAddModList = NULL;
+ if (do_csirs && dl_antenna_ports > 1) {
+   csi_MeasConfig->csi_IM_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_IM_ResourceToAddModList));
+   NR_CSI_IM_Resource_t *imres0 = calloc(1,sizeof(*imres0));
+   imres0->csi_IM_ResourceId = 0;
+   imres0->csi_IM_ResourceElementPattern = calloc(1,sizeof(*imres0->csi_IM_ResourceElementPattern));
+   imres0->csi_IM_ResourceElementPattern->present = NR_CSI_IM_Resource__csi_IM_ResourceElementPattern_PR_pattern1;
+   imres0->csi_IM_ResourceElementPattern->choice.pattern1 = calloc(1,sizeof(*imres0->csi_IM_ResourceElementPattern->choice.pattern1));
+   imres0->csi_IM_ResourceElementPattern->choice.pattern1->subcarrierLocation_p1 = NR_CSI_IM_Resource__csi_IM_ResourceElementPattern__pattern1__subcarrierLocation_p1_s4;
+   imres0->csi_IM_ResourceElementPattern->choice.pattern1->symbolLocation_p1 = 6;
+   imres0->freqBand = calloc(1,sizeof(*imres0->freqBand));
+   imres0->freqBand->startingRB = 0;
+   imres0->freqBand->nrofRBs = 108;
+   imres0->periodicityAndOffset = calloc(1,sizeof(*imres0->periodicityAndOffset));
+   imres0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots320;
+   imres0->periodicityAndOffset->choice.slots320 = 0;
+   ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_IM_ResourceToAddModList->list,imres0);
+   csi_MeasConfig->csi_IM_ResourceSetToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_IM_ResourceSetToAddModList));
+   NR_CSI_IM_ResourceSet_t *imset0 = calloc(1,sizeof(*imset0));
+   imset0->csi_IM_ResourceSetId = 0;
+   NR_CSI_IM_ResourceId_t *res0 = calloc(1,sizeof(*res0));
+   *res0 = 0;
+   ASN_SEQUENCE_ADD(&imset0->csi_IM_Resources,res0);
+   ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_IM_ResourceSetToAddModList->list,imset0);
+ }
+ else {
+   csi_MeasConfig->csi_IM_ResourceToAddModList = NULL;
+   csi_MeasConfig->csi_IM_ResourceSetToAddModList = NULL;
+ }
+
  csi_MeasConfig->csi_IM_ResourceToReleaseList = NULL;
  csi_MeasConfig->csi_IM_ResourceSetToAddModList = NULL;
  csi_MeasConfig->csi_IM_ResourceSetToReleaseList = NULL;
- csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList  = NULL;
+
+ if (do_csirs) {
+   csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList  = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList));
+   NR_NZP_CSI_RS_ResourceSet_t *nzpcsirs0 = calloc(1,sizeof(*nzpcsirs0));
+   nzpcsirs0->nzp_CSI_ResourceSetId = 0;
+   NR_NZP_CSI_RS_ResourceId_t *nzpid0 = calloc(1,sizeof(*nzpid0));
+   *nzpid0 = 0;
+   ASN_SEQUENCE_ADD(&nzpcsirs0->nzp_CSI_RS_Resources,nzpid0);
+   nzpcsirs0->repetition = NULL;
+   nzpcsirs0->aperiodicTriggeringOffset = NULL;
+   nzpcsirs0->trs_Info = NULL;
+   ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpcsirs0);
+ }
+ else
+   csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList  = NULL;
+
  csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList = NULL;
- csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = NULL;
+
+ config_csirs(servingcellconfigcommon, csi_MeasConfig,dl_antenna_ports,do_csirs);
 
  csi_MeasConfig->csi_SSB_ResourceSetToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_SSB_ResourceSetToAddModList));
  csi_MeasConfig->csi_SSB_ResourceSetToReleaseList = NULL;
@@ -1217,80 +1190,175 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list,ssbresset0);
 
  csi_MeasConfig->csi_ResourceConfigToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_ResourceConfigToAddModList));
- csi_MeasConfig->csi_ResourceConfigToReleaseList = NULL;
- NR_CSI_ResourceConfig_t *csires0 = calloc(1,sizeof(*csires0));
- csires0->csi_ResourceConfigId=0;
- csires0->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB;
- csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB));
- csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = NULL;
- csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = calloc(1,sizeof(*csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList));
+
+ if (do_csirs) {
+   csi_MeasConfig->csi_ResourceConfigToReleaseList = NULL;
+   NR_CSI_ResourceConfig_t *csires0 = calloc(1,sizeof(*csires0));
+   csires0->csi_ResourceConfigId=0;
+   csires0->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB;
+   csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB));
+   csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1,sizeof(*csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList));
+   NR_NZP_CSI_RS_ResourceSetId_t *nzp0 = calloc(1,sizeof(*nzp0));
+   *nzp0 = 0;
+   ASN_SEQUENCE_ADD(&csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list,nzp0);
+   csires0->bwp_Id = 1;
+   csires0->resourceType = NR_CSI_ResourceConfig__resourceType_periodic;
+   ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires0);
+ }
+
+ NR_CSI_ResourceConfig_t *csires1 = calloc(1,sizeof(*csires1));
+ csires1->csi_ResourceConfigId=1;
+ csires1->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB;
+ csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB));
+ csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = calloc(1,sizeof(*csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList));
  NR_CSI_SSB_ResourceSetId_t *ssbres00 = calloc(1,sizeof(*ssbres00));
  *ssbres00 = 0;
- ASN_SEQUENCE_ADD(&csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list,ssbres00);
- csires0->bwp_Id = 1;
- csires0->resourceType = NR_CSI_ResourceConfig__resourceType_periodic;
- ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires0);
+ ASN_SEQUENCE_ADD(&csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list,ssbres00);
+ csires1->bwp_Id = 1;
+ csires1->resourceType = NR_CSI_ResourceConfig__resourceType_periodic;
+ ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires1);
+
+ if (do_csirs && dl_antenna_ports > 1) {
+   NR_CSI_ResourceConfig_t *csires2 = calloc(1,sizeof(*csires2));
+   csires2->csi_ResourceConfigId=2;
+   csires2->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_csi_IM_ResourceSetList;
+   csires2->csi_RS_ResourceSetList.choice.csi_IM_ResourceSetList = calloc(1,sizeof(*csires2->csi_RS_ResourceSetList.choice.csi_IM_ResourceSetList));
+   NR_CSI_IM_ResourceSetId_t *csiim00 = calloc(1,sizeof(*csiim00));
+   *csiim00 = 0;
+   ASN_SEQUENCE_ADD(&csires2->csi_RS_ResourceSetList.choice.csi_IM_ResourceSetList->list,csiim00);
+   ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires2);
+ }
 
- csi_MeasConfig->csi_ReportConfigToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_ReportConfigToAddModList));
- csi_MeasConfig->csi_ReportConfigToReleaseList = NULL;
- NR_CSI_ReportConfig_t *csirep1 = calloc(1,sizeof(*csirep1));
- csirep1->reportConfigId=0;
- csirep1->carrier=NULL;
- csirep1->resourcesForChannelMeasurement=0;
- csirep1->csi_IM_ResourcesForInterference=NULL;
- csirep1->nzp_CSI_RS_ResourcesForInterference=NULL;
- csirep1->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic;
- csirep1->reportConfigType.choice.periodic = calloc(1,sizeof(*csirep1->reportConfigType.choice.periodic));
- csirep1->reportConfigType.choice.periodic->reportSlotConfig.present=NR_CSI_ReportPeriodicityAndOffset_PR_slots320;
- csirep1->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320 = 49;
  NR_PUCCH_CSI_Resource_t *pucchcsires1 = calloc(1,sizeof(*pucchcsires1));
  pucchcsires1->uplinkBandwidthPartId=1;
- pucchcsires1->pucch_Resource=3;
- ASN_SEQUENCE_ADD(&csirep1->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list,pucchcsires1);
- csirep1->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP;
- csirep1->reportQuantity.choice.ssb_Index_RSRP=(NULL_t)0;
- csirep1->reportFreqConfiguration = calloc(1,sizeof(*csirep1->reportFreqConfiguration));
- csirep1->reportFreqConfiguration->cqi_FormatIndicator=NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI;
- csirep1->reportFreqConfiguration->pmi_FormatIndicator=NR_CSI_ReportConfig__reportFreqConfiguration__pmi_FormatIndicator_widebandPMI;
- csirep1->reportFreqConfiguration->csi_ReportingBand=NULL;
- csirep1->timeRestrictionForChannelMeasurements= NR_CSI_ReportConfig__timeRestrictionForChannelMeasurements_configured;
- csirep1->timeRestrictionForInterferenceMeasurements=NR_CSI_ReportConfig__timeRestrictionForInterferenceMeasurements_configured;
- csirep1->codebookConfig=calloc(1,sizeof(*csirep1->codebookConfig));
- csirep1->codebookConfig->codebookType.present = NR_CodebookConfig__codebookType_PR_type1;
- csirep1->codebookConfig->codebookType.choice.type1 = calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1));
- csirep1->codebookConfig->codebookType.choice.type1->subType.present=NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel;
- csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel=calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel));
- csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present=NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two;
- csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two=
-   calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two));
- csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.size=1;
- csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.bits_unused=2;
- csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf=malloc(1);
- csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf[0]=0xfc;
- //'111111'B
-
-
- csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.size=1; 
- csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.bits_unused=0;
- csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf=malloc(1); 
- csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]=0xc0; //'00000011'B
-
- csirep1->codebookConfig->codebookType.choice.type1->codebookMode=1;
- csirep1->dummy = NULL;
- csirep1->groupBasedBeamReporting.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled;
- csirep1->groupBasedBeamReporting.choice.disabled=calloc(1,sizeof(*csirep1->groupBasedBeamReporting.choice.disabled));
- csirep1->groupBasedBeamReporting.choice.disabled->nrofReportedRS = calloc(1,sizeof(*csirep1->groupBasedBeamReporting.choice.disabled->nrofReportedRS));
- *csirep1->groupBasedBeamReporting.choice.disabled->nrofReportedRS=NR_CSI_ReportConfig__groupBasedBeamReporting__disabled__nrofReportedRS_n1;
- // this corresponds to:
- //if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'disabled', the UE is not required to update measurements for more than 64 CSI-RS and/or SSB resources, and the UE shall report in a single report nrofReportedRS (higher layer configured) different CRI or SSBRI for each report setting. 
-
- csirep1->cqi_Table = calloc(1,sizeof(*csirep1->cqi_Table));
- *csirep1->cqi_Table = NR_CSI_ReportConfig__cqi_Table_table1;
- csirep1->subbandSize = NR_CSI_ReportConfig__subbandSize_value1;
- csirep1->non_PMI_PortIndication = NULL;
- csirep1->ext1 = NULL;
-
- ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ReportConfigToAddModList->list,csirep1);
+ pucchcsires1->pucch_Resource=2;
+
+ csi_MeasConfig->csi_ReportConfigToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_ReportConfigToAddModList));
+ csi_MeasConfig->csi_ReportConfigToReleaseList = NULL;
+ if (do_csirs && dl_antenna_ports > 1) {
+   NR_CSI_ReportConfig_t *csirep1 = calloc(1,sizeof(*csirep1));
+   csirep1->reportConfigId=0;
+   csirep1->carrier=NULL;
+   csirep1->resourcesForChannelMeasurement=0;
+   csirep1->csi_IM_ResourcesForInterference=calloc(1,sizeof(*csirep1->csi_IM_ResourcesForInterference));
+   *csirep1->csi_IM_ResourcesForInterference=2;
+   csirep1->nzp_CSI_RS_ResourcesForInterference=NULL;
+   csirep1->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic;
+   csirep1->reportConfigType.choice.periodic = calloc(1,sizeof(*csirep1->reportConfigType.choice.periodic));
+   csirep1->reportConfigType.choice.periodic->reportSlotConfig.present=NR_CSI_ReportPeriodicityAndOffset_PR_slots320;
+   csirep1->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320 = 9 + (20 * uid) % 320;
+   ASN_SEQUENCE_ADD(&csirep1->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list,pucchcsires1);
+   csirep1->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI;
+   csirep1->reportQuantity.choice.cri_RI_PMI_CQI=(NULL_t)0;
+   csirep1->reportFreqConfiguration = calloc(1,sizeof(*csirep1->reportFreqConfiguration));
+   csirep1->reportFreqConfiguration->cqi_FormatIndicator = calloc(1,sizeof(*csirep1->reportFreqConfiguration->cqi_FormatIndicator));
+   *csirep1->reportFreqConfiguration->cqi_FormatIndicator=NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI;
+   csirep1->reportFreqConfiguration->pmi_FormatIndicator = calloc(1,sizeof(*csirep1->reportFreqConfiguration->pmi_FormatIndicator));
+   *csirep1->reportFreqConfiguration->pmi_FormatIndicator=NR_CSI_ReportConfig__reportFreqConfiguration__pmi_FormatIndicator_widebandPMI;
+   csirep1->reportFreqConfiguration->csi_ReportingBand = calloc(1,sizeof(*csirep1->reportFreqConfiguration->csi_ReportingBand));
+   csirep1->reportFreqConfiguration->csi_ReportingBand->present = NR_CSI_ReportConfig__reportFreqConfiguration__csi_ReportingBand_PR_subbands7;
+   csirep1->reportFreqConfiguration->csi_ReportingBand->choice.subbands7.size=1;
+   csirep1->reportFreqConfiguration->csi_ReportingBand->choice.subbands7.bits_unused=1;
+   csirep1->reportFreqConfiguration->csi_ReportingBand->choice.subbands7.buf=malloc(1);
+   csirep1->reportFreqConfiguration->csi_ReportingBand->choice.subbands7.buf[0]=254;
+   csirep1->timeRestrictionForChannelMeasurements= NR_CSI_ReportConfig__timeRestrictionForChannelMeasurements_configured;
+   csirep1->timeRestrictionForInterferenceMeasurements=NR_CSI_ReportConfig__timeRestrictionForInterferenceMeasurements_configured;
+   csirep1->codebookConfig=calloc(1,sizeof(*csirep1->codebookConfig));
+   csirep1->codebookConfig->codebookType.present = NR_CodebookConfig__codebookType_PR_type1;
+   csirep1->codebookConfig->codebookType.choice.type1 = calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1));
+   csirep1->codebookConfig->codebookType.choice.type1->subType.present=NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel;
+   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel=calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel));
+   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present=
+     NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two;
+   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two=
+     calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two));
+   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.size=1;
+   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.bits_unused=2;
+   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf=malloc(1);
+   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf[0]=0xfc;
+   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.size=1;
+   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.bits_unused=0;
+   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf=malloc(1);
+   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]=0x03;
+   csirep1->codebookConfig->codebookType.choice.type1->codebookMode=1;
+   csirep1->dummy = NULL;
+   csirep1->groupBasedBeamReporting.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled;
+   csirep1->groupBasedBeamReporting.choice.disabled=calloc(1,sizeof(*csirep1->groupBasedBeamReporting.choice.disabled));
+   //csirep1->groupBasedBeamReporting.choice.disabled->nrofReportedRS = calloc(1,sizeof(*csirep1->groupBasedBeamReporting.choice.disabled->nrofReportedRS));
+   //*csirep1->groupBasedBeamReporting.choice.disabled->nrofReportedRS=NR_CSI_ReportConfig__groupBasedBeamReporting__disabled__nrofReportedRS_n1;
+   csirep1->cqi_Table = calloc(1,sizeof(*csirep1->cqi_Table));
+   *csirep1->cqi_Table = NR_CSI_ReportConfig__cqi_Table_table1;
+   csirep1->subbandSize = NR_CSI_ReportConfig__subbandSize_value2;
+   csirep1->non_PMI_PortIndication = NULL;
+   csirep1->ext1 = NULL;
+   ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ReportConfigToAddModList->list,csirep1);
+ }
+
+ if (do_csirs) {
+   NR_CSI_ReportConfig_t *csirep2 = calloc(1,sizeof(*csirep2));
+   csirep2->reportConfigId=1;
+   csirep2->carrier=NULL;
+   csirep2->resourcesForChannelMeasurement=0;
+   csirep2->csi_IM_ResourcesForInterference=NULL;
+   csirep2->nzp_CSI_RS_ResourcesForInterference=NULL;
+   csirep2->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic;
+   csirep2->reportConfigType.choice.periodic = calloc(1,sizeof(*csirep2->reportConfigType.choice.periodic));
+   csirep2->reportConfigType.choice.periodic->reportSlotConfig.present=NR_CSI_ReportPeriodicityAndOffset_PR_slots320;
+   csirep2->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320 = 29 + (20 * uid) % 320;
+   ASN_SEQUENCE_ADD(&csirep2->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list,pucchcsires1);
+   csirep2->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP;
+   csirep2->reportQuantity.choice.cri_RSRP=(NULL_t)0;
+   csirep2->reportFreqConfiguration = calloc(1,sizeof(*csirep2->reportFreqConfiguration));
+   csirep2->reportFreqConfiguration->cqi_FormatIndicator = NULL;
+   csirep2->reportFreqConfiguration->pmi_FormatIndicator=NULL;
+   csirep2->reportFreqConfiguration->csi_ReportingBand=NULL;
+   csirep2->timeRestrictionForChannelMeasurements= NR_CSI_ReportConfig__timeRestrictionForChannelMeasurements_configured;
+   csirep2->timeRestrictionForInterferenceMeasurements=NR_CSI_ReportConfig__timeRestrictionForInterferenceMeasurements_configured;
+   csirep2->codebookConfig=NULL;
+   csirep2->dummy = NULL;
+   csirep2->groupBasedBeamReporting.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled;
+   csirep2->groupBasedBeamReporting.choice.disabled=calloc(1,sizeof(*csirep2->groupBasedBeamReporting.choice.disabled));
+   csirep2->groupBasedBeamReporting.choice.disabled->nrofReportedRS = calloc(1,sizeof(*csirep2->groupBasedBeamReporting.choice.disabled->nrofReportedRS));
+   *csirep2->groupBasedBeamReporting.choice.disabled->nrofReportedRS=NR_CSI_ReportConfig__groupBasedBeamReporting__disabled__nrofReportedRS_n1;
+   csirep2->cqi_Table = NULL;
+   csirep2->subbandSize = NR_CSI_ReportConfig__subbandSize_value1;
+   csirep2->non_PMI_PortIndication = NULL;
+   csirep2->ext1 = NULL;
+   ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ReportConfigToAddModList->list,csirep2);
+ }
+ else{
+   NR_CSI_ReportConfig_t *csirep2 = calloc(1,sizeof(*csirep2));
+   csirep2->reportConfigId=1;
+   csirep2->carrier=NULL;
+   csirep2->resourcesForChannelMeasurement=1;
+   csirep2->csi_IM_ResourcesForInterference=NULL;
+   csirep2->nzp_CSI_RS_ResourcesForInterference=NULL;
+   csirep2->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic;
+   csirep2->reportConfigType.choice.periodic = calloc(1,sizeof(*csirep2->reportConfigType.choice.periodic));
+   csirep2->reportConfigType.choice.periodic->reportSlotConfig.present=NR_CSI_ReportPeriodicityAndOffset_PR_slots320;
+   csirep2->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320 = 29 + (20 * uid) % 320;
+   ASN_SEQUENCE_ADD(&csirep2->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list,pucchcsires1);
+   csirep2->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP;
+   csirep2->reportQuantity.choice.ssb_Index_RSRP=(NULL_t)0;
+   csirep2->reportFreqConfiguration = calloc(1,sizeof(*csirep2->reportFreqConfiguration));
+   csirep2->reportFreqConfiguration->cqi_FormatIndicator=NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI;
+   csirep2->reportFreqConfiguration->pmi_FormatIndicator=NR_CSI_ReportConfig__reportFreqConfiguration__pmi_FormatIndicator_widebandPMI;
+   csirep2->reportFreqConfiguration->csi_ReportingBand=NULL;
+   csirep2->timeRestrictionForChannelMeasurements= NR_CSI_ReportConfig__timeRestrictionForChannelMeasurements_configured;
+   csirep2->timeRestrictionForInterferenceMeasurements=NR_CSI_ReportConfig__timeRestrictionForInterferenceMeasurements_configured;
+   csirep2->codebookConfig= NULL;
+   csirep2->dummy = NULL;
+   csirep2->groupBasedBeamReporting.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled;
+   csirep2->groupBasedBeamReporting.choice.disabled=calloc(1,sizeof(*csirep2->groupBasedBeamReporting.choice.disabled));
+   csirep2->groupBasedBeamReporting.choice.disabled->nrofReportedRS = calloc(1,sizeof(*csirep2->groupBasedBeamReporting.choice.disabled->nrofReportedRS));
+   *csirep2->groupBasedBeamReporting.choice.disabled->nrofReportedRS=NR_CSI_ReportConfig__groupBasedBeamReporting__disabled__nrofReportedRS_n1;
+   csirep2->cqi_Table = calloc(1,sizeof(*csirep2->cqi_Table));
+   *csirep2->cqi_Table = NR_CSI_ReportConfig__cqi_Table_table1;
+   csirep2->subbandSize = NR_CSI_ReportConfig__subbandSize_value1;
+   csirep2->non_PMI_PortIndication = NULL;
+   csirep2->ext1 = NULL;
+   ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ReportConfigToAddModList->list,csirep2);
+ }
 
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->sCellDeactivationTimer=NULL;
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig=NULL;
@@ -1300,18 +1368,84 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->servingCellMO=NULL;
 
 }
+
+
+void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_CSI_MeasConfig_t *csi_MeasConfig, int dl_antenna_ports, int do_csirs) {
+
+ if (do_csirs) {
+   csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList));
+   NR_NZP_CSI_RS_Resource_t *nzpcsi0 = calloc(1,sizeof(*nzpcsi0));
+   nzpcsi0->nzp_CSI_RS_ResourceId = 0;
+   NR_CSI_RS_ResourceMapping_t resourceMapping;
+   switch (dl_antenna_ports) {
+     case 1:
+       resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2;
+       resourceMapping.frequencyDomainAllocation.choice.row2.buf = calloc(2, sizeof(uint8_t));
+       resourceMapping.frequencyDomainAllocation.choice.row2.size = 2;
+       resourceMapping.frequencyDomainAllocation.choice.row2.bits_unused = 4;
+       resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]=0;
+       resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]=16;
+       resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1;
+       resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM;
+       break;
+     case 2:
+       resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other;
+       resourceMapping.frequencyDomainAllocation.choice.row2.buf = calloc(2, sizeof(uint8_t));
+       resourceMapping.frequencyDomainAllocation.choice.row2.size = 1;
+       resourceMapping.frequencyDomainAllocation.choice.row2.bits_unused = 2;
+       resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]=4;
+       resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p2;
+       resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2;
+       break;
+     default:
+       AssertFatal(1==0,"Number of ports not yet supported\n");
+   }
+   resourceMapping.firstOFDMSymbolInTimeDomain = 6;
+   resourceMapping.firstOFDMSymbolInTimeDomain2 = NULL;
+   resourceMapping.density.present = NR_CSI_RS_ResourceMapping__density_PR_one;
+   resourceMapping.density.choice.one = (NULL_t)0;
+   resourceMapping.freqBand.startingRB = 0;
+   resourceMapping.freqBand.nrofRBs = 108;
+   nzpcsi0->resourceMapping = resourceMapping;
+   nzpcsi0->powerControlOffset = 0;
+   nzpcsi0->powerControlOffsetSS=calloc(1,sizeof(*nzpcsi0->powerControlOffsetSS));
+   *nzpcsi0->powerControlOffsetSS = NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0;
+   nzpcsi0->scramblingID = *servingcellconfigcommon->physCellId;
+   nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset));
+   nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots320;
+   nzpcsi0->periodicityAndOffset->choice.slots320 = 0;
+   nzpcsi0->qcl_InfoPeriodicCSI_RS = NULL;
+   ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpcsi0);
+ }
+ else
+   csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = NULL;
+}
+
+
 void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
+                           NR_ServingCellConfig_t *servingcellconfigdedicated,
                            NR_RRCReconfiguration_IEs_t *reconfig,
                            NR_CellGroupConfig_t *secondaryCellGroup,
-                           int n_physical_antenna_ports,
-                           int initial_csi_index) {
+                           int dl_antenna_ports,
+                           int do_csirs,
+                           int initial_csi_index,
+                           int uid) {
   AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
   AssertFatal(reconfig!=NULL,"reconfig is null\n");
   AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n");
   // radioBearerConfig
   reconfig->radioBearerConfig=NULL;
   // secondaryCellGroup
-  fill_default_secondaryCellGroup(servingcellconfigcommon,secondaryCellGroup,1,1,n_physical_antenna_ports,initial_csi_index);
+  fill_default_secondaryCellGroup(servingcellconfigcommon,
+                                  servingcellconfigdedicated,
+                                  secondaryCellGroup,
+                                  1,
+                                  1,
+                                  dl_antenna_ports,
+                                  do_csirs,
+                                  initial_csi_index,
+                                  uid);
+
   xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
 
   char scg_buffer[1024];
@@ -1347,7 +1481,7 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
   drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config));
   drb_ToAddMod->pdcp_Config->drb = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb));
   drb_ToAddMod->pdcp_Config->drb->discardTimer = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->discardTimer));
-  *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_ms30;
+  *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_infinity;
   drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL));
   *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
   drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL));
diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c
index 5ad6746696bb98b8829331336af83e9c5dc2b349..5c9293dcf9c0951a61251bbca17d51d917c7b540 100644
--- a/openair2/RRC/NR_UE/L2_interface_ue.c
+++ b/openair2/RRC/NR_UE/L2_interface_ue.c
@@ -33,6 +33,7 @@
 #include "rrc_defs.h"
 #include "rrc_proto.h"
 #include "assertions.h"
+#include "rrc_vars.h"
 
 typedef uint32_t channel_t;
 
@@ -41,17 +42,71 @@ nr_mac_rrc_data_ind_ue(
     const module_id_t     module_id,
     const int             CC_id,
     const uint8_t         gNB_index,
+    const frame_t         frame,
+    const sub_frame_t     sub_frame,
+    const rnti_t          rnti,
     const channel_t       channel,
     const uint8_t*        pduP,
     const sdu_size_t      pdu_len){
+    sdu_size_t      sdu_size = 0;
 
     switch(channel){
       case NR_BCCH_BCH:
         AssertFatal( nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n");
         break;
+
       case NR_BCCH_DL_SCH:
-        AssertFatal( nr_rrc_ue_decode_NR_SIB1_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-DLSCH error!\n");
+        if (pdu_len>0) {
+          LOG_T(NR_RRC, "[UE %d] Received SDU for NR-BCCH-DL-SCH on SRB %u from gNB %d\n", module_id, channel & RAB_OFFSET,
+                gNB_index);
+
+          MessageDef *message_p;
+          int msg_sdu_size = BCCH_SDU_SIZE;
+
+          if (pdu_len > msg_sdu_size) {
+            LOG_E(NR_RRC, "SDU larger than NR-BCCH-DL-SCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size);
+            sdu_size = msg_sdu_size;
+          } else {
+            sdu_size = pdu_len;
+          }
+
+          message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_BCCH_DATA_IND);
+          memset(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE);
+          memcpy(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, pduP, sdu_size);
+          NR_RRC_MAC_BCCH_DATA_IND (message_p).frame = frame; //frameP
+          NR_RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frame; //sub_frameP
+          NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size;
+          NR_RRC_MAC_BCCH_DATA_IND (message_p).gnb_index = gNB_index;
+          itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p);
+        }
         break;
+
+      case CCCH:
+        if (pdu_len>0) {
+          LOG_T(NR_RRC,"[UE %d] Received SDU for CCCH on SRB %u from gNB %d\n",module_id,channel & RAB_OFFSET,gNB_index);
+
+          MessageDef *message_p;
+          int msg_sdu_size = CCCH_SDU_SIZE;
+
+          if (pdu_len > msg_sdu_size) {
+            LOG_E(NR_RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size);
+            sdu_size = msg_sdu_size;
+          } else {
+            sdu_size =  pdu_len;
+          }
+
+          message_p = itti_alloc_new_message (TASK_MAC_UE, 0, NR_RRC_MAC_CCCH_DATA_IND);
+          memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
+          memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, pduP, sdu_size);
+          NR_RRC_MAC_CCCH_DATA_IND (message_p).frame     = frame; //frameP
+          NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frame; //sub_frameP
+          NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size  = sdu_size;
+          NR_RRC_MAC_CCCH_DATA_IND (message_p).gnb_index = gNB_index;
+          NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti      = rnti;  //rntiP
+          itti_send_msg_to_task (TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE( module_id ), message_p);
+        }
+        break;
+
       default:
         break;
     }
@@ -59,13 +114,36 @@ nr_mac_rrc_data_ind_ue(
     return(0);
 }
 
-int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
+int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
                               const int         CC_id,
+                              const uint8_t     gNB_id,
                               const frame_t     frameP,
                               const rb_id_t     Srb_id,
-                              uint8_t *const    buffer_pP ){
+                              uint8_t           *buffer_pP){
+
+  switch(Srb_id){
+
+    case CCCH:
+
+      // TODO: Enable timer T300
+      //NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_active = 1;
+      //NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_cnt = 0;
+
+      LOG_D(NR_RRC, "nr_mac_rrc_data_req_ue: Payload size = %i\n", NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size);
+      memcpy(buffer_pP, (uint8_t*)NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.Payload, NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size);
+      for(int i = 0; i<NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size; i++) {
+        LOG_D(NR_RRC,"(%i): %i\n", i, buffer_pP[i]);
+      }
+
+      return NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size;
 
-  // todo
+    case DCCH:
+      AssertFatal(1==0, "SRB1 not implemented yet!\n");
+    case DCCH1:
+      AssertFatal(1==0, "SRB2 not implemented yet!\n");
+    default:
+      AssertFatal(1==0, "Invalid SRB id!\n");
+  }
 
   return 0;
 }
@@ -84,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 460dbf1d22b5f06a6ff41b9da7f2d2d370cec00a..c988ec9b80202555d485462b95e2b9c84e58a340 100644
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -67,11 +67,11 @@
 #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
 #include "nr_nas_msg_sim.h"
-#endif
 
+NR_UE_RRC_INST_t *NR_UE_rrc_inst;
 /* NAS Attach request with IMSI */
 static const char  nr_nas_attach_req_imsi[] = {
   0x07, 0x41,
@@ -127,7 +127,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;
@@ -227,8 +226,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);
@@ -414,6 +413,18 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
     for(nr_ue=0;nr_ue<NB_NR_UE_INST;nr_ue++){
       // fill UE-NR-Capability @ UE-CapabilityRAT-Container here.
       NR_UE_rrc_inst[nr_ue].selected_plmn_identity = 1;
+
+      // TODO: Put the appropriate list of SIBs
+      NR_UE_rrc_inst[nr_ue].requested_SI_List.buf = CALLOC(1,4);
+      NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[0] = SIB2 | SIB3 | SIB5;  // SIB2 - SIB9
+      NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[1] = 0;                   // SIB10 - SIB17
+      NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[2] = 0;                   // SIB18 - SIB25
+      NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[3] = 0;                   // SIB26 - SIB32
+      NR_UE_rrc_inst[nr_ue].requested_SI_List.size= 4;
+      NR_UE_rrc_inst[nr_ue].requested_SI_List.bits_unused= 0;
+
+      NR_UE_rrc_inst[nr_ue].ra_trigger = RA_NOT_RUNNING;
+
       //  init RRC lists
       RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].RLC_Bearer_Config_list, NR_maxLC_ID);
       RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SchedulingRequest_list, NR_maxNrofSR_ConfigPerCellGroup);
@@ -469,7 +480,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];
@@ -540,45 +551,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;
 }
 
@@ -835,7 +837,7 @@ int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index
           // After SI is received, prepare RRCConnectionRequest
           if (NR_UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option
             if (AMF_MODE_ENABLED) {
-              rrc_ue_generate_RRCSetupRequest( ctxt_pP, gNB_index );
+              nr_rrc_ue_generate_RRCSetupRequest( ctxt_pP->module_id, gNB_index );
             }
 
           if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_IDLE) {
@@ -1029,205 +1031,120 @@ int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index
   return 0;
 }
 
-int nr_decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, const uint8_t rsrq, const uint8_t rsrp ) {
-  NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index];
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN );
-  LOG_I( RRC, "[UE %d] : Dumping SIB 1\n", ctxt_pP->module_id );
-  const int n = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count;
-  for (int i = 0; i < n; ++i) {
-    NR_PLMN_Identity_t *PLMN_identity = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[i]->plmn_IdentityList.list.array[0];
-    int mccdigits = PLMN_identity->mcc->list.count;
-    int mncdigits = PLMN_identity->mnc.list.count;
-
-    int mcc;
-    if (mccdigits == 2) {
-      mcc = *PLMN_identity->mcc->list.array[0]*10 + *PLMN_identity->mcc->list.array[1];
-    } else {
-      mcc = *PLMN_identity->mcc->list.array[0]*100 + *PLMN_identity->mcc->list.array[1]*10 + *PLMN_identity->mcc->list.array[2];
-    }
-
-    int mnc;
-    if (mncdigits == 2) {
-      mnc = *PLMN_identity->mnc.list.array[0]*10 + *PLMN_identity->mnc.list.array[1];
-    } else {
-      mnc = *PLMN_identity->mnc.list.array[0]*100 + *PLMN_identity->mnc.list.array[1]*10 + *PLMN_identity->mnc.list.array[2];
-    }
+int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_List, NR_SIB1_t sib1) {
 
-    LOG_I( RRC, "PLMN %d MCC %0*d, MNC %0*d\n", i + 1, mccdigits, mcc, mncdigits, mnc);
-    // search internal table for provider name
-    int plmn_ind = 0;
+  if(sib1.si_SchedulingInfo) {
 
-    while (plmn_data[plmn_ind].mcc > 0) {
-      if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) {
-        LOG_I( RRC, "Found %s (name from internal table)\n", plmn_data[plmn_ind].oper_short );
-        break;
-      }
+    bool SIB_to_request[32] = {};
 
-      plmn_ind++;
+    LOG_D(RRC, "SIBs broadcasting: ");
+    for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) {
+      printf("SIB%li  ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2);
     }
-  }
-  LOG_I( RRC, "TAC 0x%04x\n",
-         ((sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->size == 2)?((sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->buf[0]<<8) + sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->buf[1]):0));
-  LOG_I( RRC, "cellReservedForOperatorUse                 : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse,
-         nr_SIBreserved(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse) );
-
-  LOG_I( RRC, "cellAccessRelatedInfo.cellIdentity         : raw:%"PRIu32" decoded:%02x.%02x.%02x.%02x\n",
-         BIT_STRING_to_uint32( &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity ),
-         sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[0],
-         sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[1],
-         sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[2],
-         sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[3] >> sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.bits_unused);
-  //LOG_I( RRC, "cellAccessRelatedInfo.cellBarred           : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.cellBarred, SIBbarred(sib1->cellAccessRelatedInfo.cellBarred) );
-  //LOG_I( RRC, "cellAccessRelatedInfo.intraFreqReselection : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.intraFreqReselection, SIBallowed(sib1->cellAccessRelatedInfo.intraFreqReselection) );
-  //LOG_I( RRC, "cellAccessRelatedInfo.csg_Indication       : %d\n", sib1->cellAccessRelatedInfo.csg_Indication );
-
-  //if (sib1->cellAccessRelatedInfo.csg_Identity)
-  //  LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity         : %"PRIu32"\n", BIT_STRING_to_uint32(sib1->cellAccessRelatedInfo.csg_Identity) );
-  //else
-  //  LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity         : not defined\n" );
-
-  LOG_I( RRC, "cellSelectionInfo.q_RxLevMin               : %ld\n", sib1->cellSelectionInfo->q_RxLevMin );
-
-  if (sib1->cellSelectionInfo->q_RxLevMinOffset)
-    LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset         : %ld\n", *sib1->cellSelectionInfo->q_RxLevMinOffset );
-  else
-    LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset         : not defined\n" );
+    printf("\n");
 
-  //if (sib1->p_Max)
-  //  LOG_I( RRC, "p_Max                                      : %ld\n", *sib1->p_Max );
-  //else
-  //  LOG_I( RRC, "p_Max                                      : not defined\n" );
+    LOG_D(RRC, "SIBs needed by UE: ");
+    for(int j = 0; j < 8*requested_SI_List.size; j++) {
+      if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) {
 
-  //LOG_I( RRC, "freqBandIndicator                          : %ld\n", sib1->freqBandIndicator );
+        printf("SIB%i  ", j + 2);
 
-  if (sib1->si_SchedulingInfo->schedulingInfoList.list.count > 0) {
-    for (int i=0; i<sib1->si_SchedulingInfo->schedulingInfoList.list.count; i++) {
-      LOG_I( RRC, "si_Periodicity[%d]                          : %s\n", i, SIBPeriod[min(sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->si_Periodicity,7)]);
+        SIB_to_request[j] = true;
+        for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) {
+          if(sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type == j) {
+            SIB_to_request[j] = false;
+            break;
+          }
+        }
 
-      if (sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count > 0) {
-        char temp[32 * sizeof(SIBType[0])] = {0}; // maxSIB==32
+      }
+    }
+    printf("\n");
 
-        for (int j=0; j<sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count; j++) {
-          sprintf( temp + j*sizeof(SIBType[0]), "%*s ", (int)sizeof(SIBType[0])-1, SIBType[min(sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.array[0]->type,11)] );
-        }
+    LOG_D(RRC, "SIBs to request by UE: ");
+    bool do_ra = false;
+    for(int j = 0; j < 8*requested_SI_List.size; j++) {
+      if(SIB_to_request[j]) {
+        printf("SIB%i  ", j + 2);
+        do_ra = true;
+      }
+    }
+    printf("\n");
+
+    if(do_ra) {
 
-        LOG_I( RRC, "siSchedulingInfoSIBType[%d]                 : %s\n", i, temp );
+      NR_UE_rrc_inst[module_id].ra_trigger = REQUEST_FOR_OTHER_SI;
+      get_softmodem_params()->do_ra = 1;
+
+      if(sib1.si_SchedulingInfo->si_RequestConfig) {
+        LOG_D(RRC, "Trigger contention-free RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger);
       } else {
-        LOG_I( RRC, "mapping list %d is null\n", i );
+        LOG_D(RRC, "Trigger contention-based RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger);
       }
+
     }
-  } else {
-    LOG_E( RRC, "siSchedulingInfoPeriod[0]                  : PROBLEM!!!\n" );
-    return -1;
-  }
 
-  if (sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon) {
-      //TODO
   }
 
-  LOG_I( RRC, "siWindowLength                             : %s\n", siWindowLength[min(sib1->si_SchedulingInfo->si_WindowLength,8)] );
-  //LOG_I( RRC, "systemInfoValueTag                         : %ld\n", sib1->systemInfoValueTag );
-  NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIperiod     = siPeriod_int[sib1->si_SchedulingInfo->schedulingInfoList.list.array[0]->si_Periodicity];
-  NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIwindowsize = siWindowLength_int[sib1->si_SchedulingInfo->si_WindowLength];
-  LOG_I( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1 params gNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n",
-         ctxt_pP->module_id, gNB_index, ctxt_pP->module_id );
-  //rrc_mac_config_req_ue
-  LOG_I(RRC,"Setting SIStatus bit 0 to 1\n");
-  NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus = 1;
-  //NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIB1systemInfoValueTag = sib1->systemInfoValueTag;
+  return 0;
+}
 
-  if (AMF_MODE_ENABLED) {
-    int cell_valid = 0;
-
-    //if (sib1->cellAccessRelatedInfo.cellBarred == LTE_SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred) {
-      /* Cell is not barred */
-      int plmn;
-      int plmn_number;
-      plmn_number = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count;
-
-      /* Compare requested PLMN and PLMNs from SIB1*/
-      for (plmn = 0; plmn < plmn_number; plmn++) {
-        NR_PLMN_Identity_t *plmn_Identity;
-        plmn_Identity = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[plmn]->plmn_IdentityList.list.array[0];
-
-        if (
-          (
-            (plmn_Identity->mcc == NULL)
-            ||
-            (
-              (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit1 == *(plmn_Identity->mcc->list.array[0])) &&
-              (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit2 == *(plmn_Identity->mcc->list.array[1])) &&
-              (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit3 == *(plmn_Identity->mcc->list.array[2]))
-            )
-          )
-          &&
-          (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit1 == *(plmn_Identity->mnc.list.array[0]))
-          &&
-          (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit2 == *(plmn_Identity->mnc.list.array[1]))
-          &&
-          (
-            ((NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == 0xf) && (plmn_Identity->mnc.list.count == 2))
-            ||
-            (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == *(plmn_Identity->mnc.list.array[2]))
-          )
-        ) {
-          /* PLMN match, send a confirmation to NAS */
-          MessageDef  *msg_p;
-          msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CELL_SELECTION_CNF);
-          NAS_CELL_SELECTION_CNF (msg_p).errCode = AS_SUCCESS;
-          NAS_CELL_SELECTION_CNF (msg_p).cellID = BIT_STRING_to_uint32(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity);
-          NAS_CELL_SELECTION_CNF (msg_p).tac = BIT_STRING_to_uint16(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode);
-          NAS_CELL_SELECTION_CNF (msg_p).rat = 0xFF;
-          NAS_CELL_SELECTION_CNF (msg_p).rsrq = rsrq;
-          NAS_CELL_SELECTION_CNF (msg_p).rsrp = rsrp;
-          itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
-          cell_valid = 1;
-          NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity = plmn + 1;
-          break;
-        }
-      }
-    //}
+int8_t nr_rrc_ue_generate_ra_msg(module_id_t module_id, uint8_t gNB_index) {
 
-    if (cell_valid == 0) {
-      /* Cell can not be used, ask PHY to try the next one */
-      MessageDef  *msg_p;
-      msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, PHY_FIND_NEXT_CELL_REQ);
-      itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p);
-      LOG_E(RRC,
-            "Synched with a cell, but PLMN doesn't match our SIM "
-            "(selected_plmn_identity %ld), the message PHY_FIND_NEXT_CELL_REQ "
-            "is sent but lost in current UE implementation!\n",
-            NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity);
-    }
+  switch(NR_UE_rrc_inst[module_id].ra_trigger){
+    case INITIAL_ACCESS_FROM_RRC_IDLE:
+      // After SIB1 is received, prepare RRCConnectionRequest
+      nr_rrc_ue_generate_RRCSetupRequest(module_id,gNB_index);
+      break;
+    case RRC_CONNECTION_REESTABLISHMENT:
+      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+      break;
+    case DURING_HANDOVER:
+      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+      break;
+    case NON_SYNCHRONISED:
+      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+      break;
+    case TRANSITION_FROM_RRC_INACTIVE:
+      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+      break;
+    case TO_ESTABLISH_TA:
+      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+      break;
+    case REQUEST_FOR_OTHER_SI:
+      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+      break;
+    case BEAM_FAILURE_RECOVERY:
+      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+      break;
+    default:
+      AssertFatal(1==0, "Invalid ra_trigger value!\n");
+      break;
   }
 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT );
   return 0;
 }
 
-int nr_decode_BCCH_DLSCH_Message(
-  const protocol_ctxt_t *const ctxt_pP,
-  const uint8_t                gNB_index,
-  uint8_t               *const Sdu,
-  const uint8_t                Sdu_len,
-  const uint8_t                rsrq,
-  const uint8_t                rsrp ) {
+int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(
+    module_id_t module_id,
+    const uint8_t gNB_index,
+    uint8_t *const Sdu,
+    const uint8_t Sdu_len,
+    const uint8_t rsrq,
+    const uint8_t rsrp) {
+
   NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
-  NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index];
+  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[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 1) &&  // SIB1 received
-      (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)) {
+  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 );
     return 0;
   }
 
-  nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR );
-
-  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
-    xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message );
-  }
+  nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR );
 
   asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
                             &asn_DEF_NR_BCCH_DL_SCH_Message,
@@ -1235,11 +1152,15 @@ int nr_decode_BCCH_DLSCH_Message(
                             (const void *)Sdu,
                             Sdu_len );
 
+  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+    xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message );
+  }
+
   if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
-    LOG_E( RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
-           ctxt_pP->module_id,
+    LOG_E( NR_RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
+           module_id,
            dec_rval.consumed );
-    log_dump(RRC, Sdu, Sdu_len, LOG_DUMP_CHAR,"   Received bytes:\n" );
+    log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR,"   Received bytes:\n" );
     // free the memory
     SEQUENCE_free( &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message, 1 );
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
@@ -1249,35 +1170,59 @@ int nr_decode_BCCH_DLSCH_Message(
   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:
-        if ((ctxt_pP->frame % 2) == 0) {
-          // even frame
-          if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 0) {
-            NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index];
-            memcpy( (void *)sib1,
-                    (void *)bcch_message->message.choice.c1->choice.systemInformationBlockType1,
-                    sizeof(NR_SIB1_t) );
-            LOG_D( RRC, "[UE %"PRIu8"] Decoding First SIB1\n", ctxt_pP->module_id );
-            nr_decode_SIB1( ctxt_pP, gNB_index, rsrq, rsrp );
+        if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 0) {
+          NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index];
+          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;
+            if( g_log->log_component[NR_RRC].level >= OAILOG_DEBUG ) {
+              xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) NR_UE_rrc_inst[module_id].sib1[gNB_index]);
+            }
+            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 ) {
+              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;
+              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");
           }
         }
-
         break;
 
       case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
-        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 1) {
+        if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) {
+          LOG_W(NR_RRC, "Decoding SI not implemented yet\n");
+          // TODO: Decode SI
+          /*
           // SIB1 with schedulingInfoList is available
-          NR_SystemInformation_t *si = NR_UE_rrc_inst[ctxt_pP->module_id].si[gNB_index];
+          NR_SystemInformation_t *si = NR_UE_rrc_inst[module_id].si[gNB_index];
+
           memcpy( si,
                   bcch_message->message.choice.c1->choice.systemInformation,
                   sizeof(NR_SystemInformation_t) );
-          LOG_I( RRC, "[UE %"PRIu8"] Decoding SI for frameP %"PRIu32"\n",
-                 ctxt_pP->module_id,
-                 ctxt_pP->frame );
+          LOG_I(NR_RRC, "[UE %"PRIu8"] Decoding SI\n", module_id);
           nr_decode_SI( ctxt_pP, gNB_index );
-          //if (nfapi_mode == 3)
-          //UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1;
-        }
 
+          if (nfapi_mode == 3)
+            UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1;
+           */
+        }
         break;
 
       case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
@@ -1286,10 +1231,10 @@ int nr_decode_BCCH_DLSCH_Message(
     }
   }
 
-  if (nr_rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) {
+  if (nr_rrc_get_sub_state(module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) {
     //if ( (NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) || (!AMF_MODE_ENABLED)) {
-      rrc_ue_generate_RRCSetupRequest(ctxt_pP, 0);
-      nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_CONNECTING );
+      nr_rrc_ue_generate_RRCSetupRequest(module_id, 0);
+      nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_CONNECTING );
     //}
   }
 
@@ -1306,10 +1251,22 @@ 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(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config == NULL){
+    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t));
   }
 
   if( cellGroupConfig->rlc_BearerToReleaseList != NULL){
@@ -1318,10 +1275,24 @@ nr_rrc_ue_process_masterCellGroup(
 
   if( cellGroupConfig->rlc_BearerToAddModList != NULL){
     //TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4)
+    if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList != NULL){
+      free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList);
+    }
+    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList = calloc(1, sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
+    memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList,cellGroupConfig->rlc_BearerToAddModList,
+                 sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
   }
 
   if( cellGroupConfig->mac_CellGroupConfig != NULL){
     //TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5)
+    LOG_I(RRC, "Received mac_CellGroupConfig from gNB\n");
+    if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig != NULL){
+      LOG_E(RRC, "UE RRC instance already contains mac CellGroupConfig which will be overwritten\n");
+      free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig);
+    }
+    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig = malloc(sizeof(struct NR_MAC_CellGroupConfig));
+    memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig,cellGroupConfig->mac_CellGroupConfig,
+                     sizeof(struct NR_MAC_CellGroupConfig));
   }
 
   if( cellGroupConfig->sCellToReleaseList != NULL){
@@ -1329,12 +1300,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)
   }
 
@@ -1362,15 +1339,30 @@ 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)
     as_nas_info_t initialNasMsg;
-    generateRegistrationRequest(&initialNasMsg);
+    generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id);
     nas_msg = (char*)initialNasMsg.data;
     nas_msg_length = initialNasMsg.length;
 #else
-    nas_msg         = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data;
-    nas_msg_length  = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length;
+    if (get_softmodem_params()->sa) {
+      as_nas_info_t initialNasMsg;
+      generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id);
+      nas_msg = (char*)initialNasMsg.data;
+      nas_msg_length = initialNasMsg.length;
+    } else {
+      nas_msg         = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data;
+      nas_msg_length  = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length;
+    }
 #endif
   } else {
     nas_msg         = nr_nas_attach_req_imsi;
@@ -1379,18 +1371,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;
@@ -1405,429 +1401,404 @@ 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;
-}
-
-/*brief decode SIB1 message*/
-int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
-
-  NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
-
-  asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
-                                                  &asn_DEF_NR_BCCH_DL_SCH_Message,
-                                                  (void **)&bcch_message,
-                                                  (const void *)bufferP,
-                                                  buffer_len);
-
-  if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
-    LOG_D(RRC,"NR_BCCH_DL_SCH decode error\n");
-    SEQUENCE_free( &asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1 );
-    return -1;
-  }
-  else {
-    NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index];
-    if(sib1 != NULL){
-      SEQUENCE_free(&asn_DEF_NR_BCCH_BCH_Message, (void *)sib1, 1 );
-    }
-    sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
-    if (*(int64_t*)sib1 != 1) {
-      LOG_I(RRC, "SIB1 decoded\n");
-      if( g_log->log_component[RRC].level >= OAILOG_DEBUG  )
-        xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1);
-    }
-    else
-       LOG_E(PHY, "sib1 is starting by 8 times 0\n");
-  }
-
-  return 0;
-}
-
-
-// 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_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);
+   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;
+   }
 
-    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);
-}
+   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);
+   }
 
-//-----------------------------------------------------------------------------
-void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) {
-  uint8_t i=0,rv[6];
-
-  if(NR_UE_rrc_inst[ctxt_pP->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 (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);
     }
+     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[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size =
-      do_RRCSetupRequest(
-        ctxt_pP->module_id,
-        (uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload,
-        rv);
-    LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, eNB %d)\n",
-          ctxt_pP->module_id, ctxt_pP->frame, NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index);
-
-    for (i=0; i<NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) {
-      LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[ctxt_pP->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;
     uint8_t *message_buffer;
     message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
-          NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size);
-    memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload,
-          NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size);
+          NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size);
+    memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload,
+          NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size);
     message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_CCCH_DATA_IND);
     GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
-    GNB_RRC_CCCH_DATA_IND (message_p).size  = NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size;
-    itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
+    GNB_RRC_CCCH_DATA_IND (message_p).size  = NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size;
+    itti_send_msg_to_task (TASK_RRC_GNB_SIM, gNB_index, message_p);
 #endif
   }
 }
@@ -1844,7 +1815,7 @@ nr_rrc_ue_establish_srb1(
 {
   // add descriptor from RRC PDU
   NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Active = 1;
-  NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG
+  NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].status = RADIO_CONFIG_OK;//RADIO CFG
   NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Srb_info.Srb_id = 1;
   LOG_I(NR_RRC, "[UE %d], CONFIG_SRB1 %d corresponding to gNB_index %d\n", ue_mod_idP, DCCH, gNB_index);
   return(0);
@@ -1862,728 +1833,630 @@ nr_rrc_ue_establish_srb2(
 {
   // add descriptor from RRC PDU
   NR_UE_rrc_inst[ue_mod_idP].Srb2[gNB_index].Active = 1;
-  NR_UE_rrc_inst[ue_mod_idP].Srb2[gNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG
+  NR_UE_rrc_inst[ue_mod_idP].Srb2[gNB_index].status = RADIO_CONFIG_OK;//RADIO CFG
   NR_UE_rrc_inst[ue_mod_idP].Srb2[gNB_index].Srb_info.Srb_id = 2;
   LOG_I(NR_RRC, "[UE %d], CONFIG_SRB2 %d corresponding to gNB_index %d\n", ue_mod_idP, DCCH1, gNB_index);
   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.)
-    }
-  }
-
-  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]);
+ //-----------------------------------------------------------------------------
+ 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);
     }
   }
 
-  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);
+   return(0);
+ }
 
-  NR_RRCReconfiguration_IEs_t *ie = NULL;
+ //-----------------------------------------------------------------------------
+ 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 (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 (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 (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->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]);
+     }
+   }
 
-    /* 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->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];
+         }
+       }
+     }
+   }
 
-      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->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]);
+     }
+   }
 
-      free (ie->nonCriticalExtension->dedicatedNAS_MessageList);
-    }
-  }
-}
+   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];
+       }
+     }
+   }
 
-//-----------------------------------------------------------------------------
-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->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;
+     }
+   }
 
-  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->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;
+     }
+   }
 
-#else
-  rrc_data_req_ue (
-    ctxt_pP,
-    DCCH,
-    nr_rrc_mui++,
-    SDU_CONFIRM_NO,
-    size,
-    buffer,
-    PDCP_TRANSMISSION_MODE_CONTROL);
-#endif
+   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.)
+     }
+   }
 
-// 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 (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,
+                                    0,
+                                    NULL,
+                                    NULL,
+                                    kUPenc,
+                                    NULL,
+                                    NULL,
+                                    NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB,
+                                    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList);
+       // Refresh DRBs
+        nr_rrc_rlc_config_asn1_req(ctxt_pP,
+                                    NULL,
+                                    radioBearerConfig->drb_ToAddModList,
+                                    NULL,
+                                    NULL,
+                                    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList
+                                    );
+   } // 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]);
+     }
+   }
 
-  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);
-  }
+   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);
+ }
 
-  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);
+ //-----------------------------------------------------------------------------
+ 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->nonCriticalExtension->masterCellGroup!=NULL) {
+       nr_rrc_ue_process_masterCellGroup(
+           ctxt_pP,
+           gNB_index,
+           ie->nonCriticalExtension->masterCellGroup);
+     }
+
+     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 ((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 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
 
-  // 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
-              }
-            }
+ }
 
-              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;
-}
+ // 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);
+   } else {
+     LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id);
+   }
 
-//-----------------------------------------------------------------------------
-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;
+   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 MESSAGE_TEST:
-        LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
-        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_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_INSTANCE(&ctxt, instance, ENB_FLAG_NO, NOT_A_RNTI, RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0);
-        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_decode_BCCH_DLSCH_Message (&ctxt,
-                                   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);
-
-      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:
@@ -2654,7 +2527,7 @@ void *rrc_nrue_task( void *args_p ) {
         LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
         break;
     }
-    LOG_I(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, nr_rrc_get_state(ue_mod_id));
+    LOG_D(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, nr_rrc_get_state(ue_mod_id));
     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;
diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h
index 52bd6c564a6013ac74e842bed79cd2fccc0047f9..e417b9f0b478130a8cfc78a57dcd680b7572b75f 100644
--- a/openair2/RRC/NR_UE/rrc_defs.h
+++ b/openair2/RRC/NR_UE/rrc_defs.h
@@ -77,10 +77,37 @@ typedef struct OAI_NR_UECapability_s {
   NR_UE_NR_Capability_t *UE_NR_Capability;
 } OAI_NR_UECapability_t;
 
+typedef enum requested_SI_List_e {
+  SIB2  = 1,
+  SIB3  = 2,
+  SIB4  = 4,
+  SIB5  = 8,
+  SIB6  = 16,
+  SIB7  = 32,
+  SIB8  = 64,
+  SIB9  = 128
+} requested_SI_List_t;
+
+// 3GPP TS 38.300 Section 9.2.6
+typedef enum RA_trigger_e {
+  RA_NOT_RUNNING,
+  INITIAL_ACCESS_FROM_RRC_IDLE,
+  RRC_CONNECTION_REESTABLISHMENT,
+  DURING_HANDOVER,
+  NON_SYNCHRONISED,
+  TRANSITION_FROM_RRC_INACTIVE,
+  TO_ESTABLISH_TA,
+  REQUEST_FOR_OTHER_SI,
+  BEAM_FAILURE_RECOVERY,
+} RA_trigger_t;
+
 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];
@@ -99,10 +126,13 @@ 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;
-    uint8_t 					   *UECapability;
+    OAI_NR_UECapability_t          *UECap;
+    uint8_t 					             *UECapability;
     uint8_t                        UECapability_size;
 
+    RA_trigger_t                   ra_trigger;
+    BIT_STRING_t                   requested_SI_List;
+
     NR_SystemInformation_t         *si[NB_CNX_UE];
     NR_SIB1_t                      *sib1[NB_CNX_UE];
     NR_SIB2_t                      *sib2[NB_CNX_UE];
@@ -182,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/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h
index 401924844172addc98a54e43da71463080b8ce21..534da0112bf3feedd45cf7682ebde12bb9a714b9 100644
--- a/openair2/RRC/NR_UE/rrc_proto.h
+++ b/openair2/RRC/NR_UE/rrc_proto.h
@@ -86,12 +86,14 @@ int8_t nr_rrc_ue_process_radio_bearer_config(NR_RadioBearerConfig_t *radio_beare
    \param sdu_len       length of buffer*/
 int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len);
 
-/**\brief decode NR SIB1 message
+/**\brief decode NR BCCH-DLSCH (SI) messages
    \param module_idP    module id
    \param gNB_index     gNB index
-   \param sduP          pointer to buffer of ASN message
-   \param sdu_len       length of buffer*/
-int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len);
+   \param sduP          pointer to buffer of ASN message BCCH-DLSCH
+   \param sdu_len       length of buffer
+   \param rsrq          RSRQ
+   \param rsrp          RSRP*/
+int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len, const uint8_t rsrq, const uint8_t rsrp);
 
 /**\brief Decode NR DCCH from gNB, sent from lower layer through SRB3
    \param module_id  module id
@@ -107,29 +109,38 @@ int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(const module_id_t module_id, const ui
    \param channel    indicator for channel of the pdu
    \param pduP       pointer to pdu
    \param pdu_len    data length of pdu*/
-int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len);
+int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
+                              const int CC_id,
+                              const uint8_t gNB_index,
+                              const frame_t frame,
+                              const sub_frame_t sub_frame,
+                              const rnti_t rnti,
+                              const channel_t channel,
+                              const uint8_t* pduP,
+                              const sdu_size_t pdu_len);
 
 /**\brief
    \param module_id  module id
    \param CC_id      component carrier id
+   \param gNB_index  gNB index
    \param frame_t    frameP
    \param rb_id_t    SRB id
    \param buffer_pP  pointer to buffer*/
-int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
+int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
                               const int         CC_id,
+                              const uint8_t     gNB_id,
                               const frame_t     frameP,
                               const rb_id_t     Srb_id,
-                              uint8_t *const    buffer_pP);
-
+                              uint8_t           *buffer_pP);
 
 /**\brief RRC UE task.
    \param void *args_p Pointer on arguments to start the task. */
 void *rrc_nrue_task(void *args_p);
 
 /**\brief RRC UE generate RRCSetupRequest message.
-   \param ctxt_pP    protocol context 
+   \param module_id  module id
    \param gNB_index  gNB index  */
-void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index );
+void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index);
 
 /** @}*/
 #endif
diff --git a/openair2/RRC/NR_UE/rrc_vars.h b/openair2/RRC/NR_UE/rrc_vars.h
index 5c74e5b5a8555db98ad76ac7a82f532978fcfa52..30c74debdd2db39cc5f203782078627d24988800 100644
--- a/openair2/RRC/NR_UE/rrc_vars.h
+++ b/openair2/RRC/NR_UE/rrc_vars.h
@@ -36,6 +36,6 @@
 
 #include "rrc_defs.h"
 
-NR_UE_RRC_INST_t *NR_UE_rrc_inst;
+extern NR_UE_RRC_INST_t *NR_UE_rrc_inst;
 
 #endif
diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c
index e11a92d6912164f28ec6666aea4345782a4f5e5b..0cd022217db1a75d94ef2a67cfd333c58491c509 100644
--- a/openair2/SIMULATION/NR_RRC/itti_sim.c
+++ b/openair2/SIMULATION/NR_RRC/itti_sim.c
@@ -81,14 +81,16 @@ unsigned short config_frames[4] = {2,9,11,13};
 #include "RRC/NR_UE/rrc_proto.h"
 #include "RRC/NR_UE/rrc_vars.h"
 #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;
 int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
 
-uint8_t nfapi_mode = 0; // Default to monolithic mode
-uint32_t target_dl_mcs = 28;
-uint32_t target_ul_mcs = 20;
 uint32_t timing_advance = 0;
 uint64_t num_missed_slots=0;
 
@@ -96,7 +98,18 @@ 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");
 }
+void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) {
+  AssertFatal(false, "Must not be called in this context\n");
+}
+
+nrUE_params_t nrUE_params;
+nrUE_params_t *get_nrUE_params(void) {
+  return &nrUE_params;
+}
 
+void processSlotTX(void *arg) {}
+
+THREAD_STRUCT thread_struct;
 pthread_cond_t sync_cond;
 pthread_mutex_t sync_mutex;
 int sync_var=-1; //!< protected by mutex \ref sync_mutex.
@@ -120,7 +133,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
 //Temp fix for inexistent NR upper layer
 unsigned char NB_gNB_INST = 1;
 
-static char                    *itti_dump_file = NULL;
 
 int UE_scan = 1;
 int UE_scan_carrier = 0;
@@ -148,7 +160,6 @@ extern void *udp_eNB_task(void *args_p);
 int transmission_mode=1;
 int emulate_rf = 0;
 int numerology = 0;
-int usrp_tx_thread = 0;
 
 
 double cpuf;
@@ -404,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;
+    }
   }
 
 
@@ -571,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;
@@ -624,7 +647,7 @@ int main( int argc, char **argv )
                                 0);
   NR_UE_rrc_inst[ctxt.module_id].Info[0].State = RRC_SI_RECEIVED;
 
-  rrc_ue_generate_RRCSetupRequest(&ctxt, 0);
+  nr_rrc_ue_generate_RRCSetupRequest(ctxt.module_id, 0);
 
   printf("Entering ITTI signals handler\n");
   itti_wait_tasks_end();
diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h
index 34190f7d15839e2a0c3a83e9bcc9d501fbf7fb25..58cc7184e7d05ef0f449f15aafa44a2b1ca9c7c4 100644
--- a/openair2/UTIL/OCG/OCG.h
+++ b/openair2/UTIL/OCG/OCG.h
@@ -667,7 +667,6 @@ typedef struct {
   unsigned char omv_enabled; // openair mobility visulizer
   unsigned char opp_enabled; // openair performance profiler
   unsigned char oeh_enabled; // openair event handler, with CLI this could provide a remote event management
-  char *itti_dump_file;
   unsigned char vcd_enabled;
   char *vcd_file;
   unsigned char eMBMS_active_state;
@@ -717,12 +716,6 @@ typedef struct {
    */
   unsigned char slot_isr;
   int           slot_sfd;
-  rnti_t        eNB_ue_module_id_to_rnti[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];/*!< \brief  used by eNB, this array can be filled:
-       by local virtualization: set directly by UE, or by remote UEs: TODO add signalisation on ethernet emulation link from UE to eNB*/
-
-  module_id_t   eNB_ue_local_uid_to_ue_module_id[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];/*!< \brief  used by eNB, this array can be filled:
-       by local virtualization: set directly by UE, or by remote UEs: TODO add signalisation on ethernet emulation link from UE to eNB*/
-
 } Info;
 /* @}*/
 
diff --git a/openair2/UTIL/OPT/README.txt b/openair2/UTIL/OPT/README.txt
index 2ac68f83fdbf1057f414e88a7559e6eb0c7345db..13ec727fd5a5b41c3cc4f0d58e6e543db92e0422 100644
--- a/openair2/UTIL/OPT/README.txt
+++ b/openair2/UTIL/OPT/README.txt
@@ -1,13 +1,14 @@
 
-How to configure wireshark for dissecting LTE protocols:
+How to configure wireshark for dissecting LTE/NR protocols:
 - start the wireshark as a sudoers
   - goto analyze->enabled prototols
-  => enable mac_lte_udp and rlc_lte_udp
+  => enable mac_xxx_udp and rlc_xxx_udp (xxx is lte or nr)
   - goto edit/preferences and expand Protocols
   - select UDP and check "try heuristic sub-dissectors first"
-  - select MAC-LTE, and check all the options (checkboxes), and set the "which layer info to show in info column" to "MAC info"
-    - select RLC-LTE, and check all the options except the "May see RLC headers only", and
+  - select MAC-LTE (or MAC-NR), and check all the options (checkboxes), and set the "which layer info to show in info column" to "MAC info"
+  - select RLC-LTE (or NR), and check all the options except the "May see RLC headers only", and
     set the "call PDCP dissector for DRB PDUs" to "12-bit SN". Optionally you may select the sequence analysis for RLC AM/UM.
+  - select PDCP-LTE (or NR)
 
     How to use
     - start eNB or UE with option --opt.type wireshark
diff --git a/openair2/UTIL/OPT/opt.h b/openair2/UTIL/OPT/opt.h
index ab591d3a6572c7c114149baa78e8509ee97b9ab7..ae6a3eb2a65fb4e8dac6eabaa69942381afbc445 100644
--- a/openair2/UTIL/OPT/opt.h
+++ b/openair2/UTIL/OPT/opt.h
@@ -59,7 +59,8 @@ typedef uint16_t guint16;
 typedef uint32_t guint32;
 typedef guint8   gboolean;
 
-#include "packet-mac-lte.h"
+#include <openair2/UTIL/OPT/wireshark_headers.h>
+
 #include "mac_pcap.h"
 
 /* OPT parameters definitions */
@@ -107,9 +108,10 @@ typedef enum radio_type_e {
 */
 
 extern int opt_enabled;
-#define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(x)
+#define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(0, x)
+#define trace_NRpdu(x...) if (opt_enabled) trace_pdu_implementation(1, x)
 
-void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
+void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
                               int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe,
                               int oob_event, int oob_event_value);
 
diff --git a/openair2/UTIL/OPT/packet-mac-lte.h b/openair2/UTIL/OPT/packet-mac-lte.h
deleted file mode 100644
index 2d36e02df4d580af33f9fa5423dc984480f2d47f..0000000000000000000000000000000000000000
--- a/openair2/UTIL/OPT/packet-mac-lte.h
+++ /dev/null
@@ -1,382 +0,0 @@
-/* packet-mac-lte.h
- *
- * Martin Mathieson
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- *
- * This header file may also be distributed under
- * the terms of the BSD Licence as follows:
- *
- * Copyright (C) 2009 Martin Mathieson. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- 
- /* 
- this is wireshark, commit: commit eda834b6e29c36e05a63a6056afa98390ff79357 
- Date:   Wed Aug 22 14:36:20 2018 +0200
- modified to be used in OpenAir to create the LTE MAC/RLC encapsulated in UDP as per Wireshark feature 
- */
-
-#ifndef __UTIL_OPT_PACKET_MAC_LTE__H__
-#define __UTIL_OPT_PACKET_MAC_LTE__H__
-
-#include "ws_symbol_export.h"
-
-/** data structure to hold time values with nanosecond resolution*/
-typedef struct {
-	time_t	secs;
-	int	nsecs;
-} nstime_t;
-
-
-/* radioType */
-#define FDD_RADIO 1
-#define TDD_RADIO 2
-
-/* Direction */
-#define DIRECTION_UPLINK   0
-#define DIRECTION_DOWNLINK 1
-
-/* rntiType */
-#define WS_NO_RNTI     0
-#define WS_P_RNTI      1
-#define WS_RA_RNTI     2
-#define WS_C_RNTI      3
-#define WS_SI_RNTI     4
-#define WS_SPS_RNTI    5
-#define WS_M_RNTI      6
-#define WS_SL_BCH_RNTI 7
-#define WS_SL_RNTI     8
-#define WS_SC_RNTI     9
-#define WS_G_RNTI      10
-
-typedef enum mac_lte_oob_event {
-    ltemac_send_preamble,
-    ltemac_send_sr,
-    ltemac_sr_failure
-} mac_lte_oob_event;
-
-typedef enum mac_lte_dl_retx {
-    dl_retx_no,
-    dl_retx_yes,
-    dl_retx_unknown
-} mac_lte_dl_retx;
-
-typedef enum mac_lte_crc_status {
-    crc_fail = 0,
-    crc_success = 1,
-    crc_high_code_rate = 2,
-    crc_pdsch_lost = 3,
-    crc_duplicate_nonzero_rv = 4,
-    crc_false_dci = 5
-} mac_lte_crc_status;
-
-/* N.B. for SCellIndex-r13 extends to 31 */
-typedef enum mac_lte_carrier_id {
-    carrier_id_primary,
-    carrier_id_secondary_1,
-    carrier_id_secondary_2,
-    carrier_id_secondary_3,
-    carrier_id_secondary_4,
-    carrier_id_secondary_5,
-    carrier_id_secondary_6,
-    carrier_id_secondary_7
-} mac_lte_carrier_id;
-
-typedef enum mac_lte_ce_mode {
-    no_ce_mode = 0,
-    ce_mode_a = 1,
-    ce_mode_b = 2
-} mac_lte_ce_mode;
-
-typedef enum mac_lte_nb_mode {
-    no_nb_mode = 0,
-    nb_mode = 1
-} mac_lte_nb_mode;
-
-/* Context info attached to each LTE MAC frame */
-typedef struct mac_lte_info
-{
-    /* Needed for decode */
-    guint8          radioType;
-    guint8          direction;
-    guint8          rntiType;
-
-    /* Extra info to display */
-    guint16         rnti;
-    guint16         ueid;
-
-    /* Timing info */
-    guint16         sysframeNumber;
-    guint16         subframeNumber;
-
-    /* Optional field. More interesting for TDD (FDD is always -4 subframeNumber) */
-    gboolean        subframeNumberOfGrantPresent;
-    guint16         subframeNumberOfGrant;
-
-    /* Flag set only if doing PHY-level data test - i.e. there may not be a
-       well-formed MAC PDU so just show as raw data */
-    gboolean        isPredefinedData;
-
-    /* Length of DL PDU or UL grant size in bytes */
-    guint16         length;
-
-    /* 0=newTx, 1=first-retx, etc */
-    guint8          reTxCount;
-    guint8          isPHICHNACK; /* FALSE=PDCCH retx grant, TRUE=PHICH NACK */
-
-    /* UL only.  Indicates if the R10 extendedBSR-Sizes parameter is set */
-    gboolean        isExtendedBSRSizes;
-
-    /* UL only.  Indicates if the R10 simultaneousPUCCH-PUSCH parameter is set for PCell */
-    gboolean        isSimultPUCCHPUSCHPCell;
-
-    /* UL only.  Indicates if the R10 extendedBSR-Sizes parameter is set for PSCell */
-    gboolean        isSimultPUCCHPUSCHPSCell;
-
-    /* Status of CRC check. For UE it is DL only. For eNodeB it is UL
-       only. For an analyzer, it is present for both DL and UL. */
-    gboolean        crcStatusValid;
-    mac_lte_crc_status crcStatus;
-
-    /* Carrier ID */
-    mac_lte_carrier_id   carrierId;
-
-    /* DL only.  Is this known to be a retransmission? */
-    mac_lte_dl_retx dl_retx;
-
-    /* DL only. CE mode to be used for RAR decoding */
-    mac_lte_ce_mode ceMode;
-
-    /* DL and UL. NB-IoT mode of the UE */
-    mac_lte_nb_mode nbMode;
-
-    /* UL only, for now used for CE mode A RAR decoding */
-    guint8          nUlRb;
-
-    /* More Physical layer info (see direction above for which side of union to use) */
-    union {
-        struct mac_lte_ul_phy_info
-        {
-            guint8 present;  /* Remaining UL fields are present and should be displayed */
-            guint8 modulation_type;
-            guint8 tbs_index;
-            guint8 resource_block_length;
-            guint8 resource_block_start;
-            guint8 harq_id;
-            gboolean ndi;
-        } ul_info;
-        struct mac_lte_dl_phy_info
-        {
-            guint8 present; /* Remaining DL fields are present and should be displayed */
-            guint8 dci_format;
-            guint8 resource_allocation_type;
-            guint8 aggregation_level;
-            guint8 mcs_index;
-            guint8 redundancy_version_index;
-            guint8 resource_block_length;
-            guint8 harq_id;
-            gboolean ndi;
-            guint8   transport_block;  /* 0..1 */
-        } dl_info;
-    } detailed_phy_info;
-
-    /* Relating to out-of-band events */
-    /* N.B. dissector will only look to these fields if length is 0... */
-    mac_lte_oob_event  oob_event;
-    guint8             rapid;
-    guint8             rach_attempt_number;
-    #define MAX_SRs 20
-    guint16            number_of_srs;
-    guint16            oob_ueid[MAX_SRs];
-    guint16            oob_rnti[MAX_SRs];
-} mac_lte_info;
-
-
-typedef struct mac_lte_tap_info {
-    /* Info from context */
-    guint16  rnti;
-    guint16  ueid;
-    guint8   rntiType;
-    guint8   isPredefinedData;
-    gboolean crcStatusValid;
-    mac_lte_crc_status   crcStatus;
-    guint8   direction;
-
-    guint8   isPHYRetx;
-    guint16  ueInTTI;
-
-    nstime_t mac_lte_time;
-
-    /* Number of bytes (which part is used depends upon context settings) */
-    guint32  single_number_of_bytes;
-    guint32  bytes_for_lcid[11];
-    guint32  sdus_for_lcid[11];
-    guint8   number_of_rars;
-    guint8   number_of_paging_ids;
-
-    /* Number of padding bytes includes padding subheaders and trailing padding */
-    guint16  padding_bytes;
-    guint16  raw_length;
-} mac_lte_tap_info;
-
-
-
-/*****************************************************************/
-/* UDP framing format                                            */
-/* -----------------------                                       */
-/* Several people have asked about dissecting MAC by framing     */
-/* PDUs over IP.  A suggested format over UDP has been created   */
-/* and implemented by this dissector, using the definitions      */
-/* below. A link to an example program showing you how to encode */
-/* these headers and send LTE MAC PDUs on a UDP socket is        */
-/* provided at https://wiki.wireshark.org/MAC-LTE                */
-/*                                                               */
-/* A heuristic dissector (enabled by a preference) will          */
-/* recognise a signature at the beginning of these frames.       */
-/*****************************************************************/
-
-
-/* Signature.  Rather than try to define a port for this, or make the
-   port number a preference, frames will start with this string (with no
-   terminating NULL */
-#define MAC_LTE_START_STRING "mac-lte"
-
-/* Fixed fields.  This is followed by the following 3 mandatory fields:
-   - radioType (1 byte)
-   - direction (1 byte)
-   - rntiType (1 byte)
-   (where the allowed values are defined above */
-
-/* Optional fields. Attaching this info to frames will allow you
-   to show you display/filter/plot/add-custom-columns on these fields, so should
-   be added if available.
-   The format is to have the tag, followed by the value (there is no length field,
-   it's implicit from the tag) */
-
-#define MAC_LTE_RNTI_TAG            0x02
-/* 2 bytes, network order */
-
-#define MAC_LTE_UEID_TAG            0x03
-/* 2 bytes, network order */
-
-#define MAC_LTE_FRAME_SUBFRAME_TAG  0x04
-/* 2 bytes, network order, SFN is stored in 12 MSB and SF in 4 LSB */
-
-#define MAC_LTE_PREDEFINED_DATA_TAG 0x05
-/* 1 byte */
-
-#define MAC_LTE_RETX_TAG            0x06
-/* 1 byte */
-
-#define MAC_LTE_CRC_STATUS_TAG      0x07
-/* 1 byte */
-
-#define MAC_LTE_EXT_BSR_SIZES_TAG   0x08
-/* 0 byte */
-
-#define MAC_LTE_SEND_PREAMBLE_TAG   0x09
-/* 2 bytes, RAPID value (1 byte) followed by RACH attempt number (1 byte) */
-
-#define MAC_LTE_CARRIER_ID_TAG      0x0A
-/* 1 byte */
-
-#define MAC_LTE_PHY_TAG             0x0B
-/* variable length, length (1 byte) then depending on direction
-   in UL: modulation type (1 byte), TBS index (1 byte), RB length (1 byte),
-          RB start (1 byte), HARQ id (1 byte), NDI (1 byte)
-   in DL: DCI format (1 byte), resource allocation type (1 byte), aggregation level (1 byte),
-          MCS index (1 byte), redundancy version (1 byte), resource block length (1 byte),
-          HARQ id (1 byte), NDI (1 byte), TB (1 byte), DL reTx (1 byte) */
-
-#define MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG  0x0C
-/* 0 byte */
-
-#define MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG 0x0D
-/* 0 byte */
-
-#define MAC_LTE_CE_MODE_TAG         0x0E
-/* 1 byte containing mac_lte_ce_mode enum value */
-
-#define MAC_LTE_NB_MODE_TAG         0x0F
-/* 1 byte containing mac_lte_nb_mode enum value */
-
-#define MAC_LTE_N_UL_RB_TAG         0x10
-/* 1 byte containing the number of UL resource blocks: 6, 15, 25, 50, 75 or 100 */
-
-#define MAC_LTE_SR_TAG              0x11
-/* 2 bytes for the number of items, followed by that number of ueid, rnti (2 bytes each) */
-
-
-/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
-   continues until the end of the frame) */
-#define MAC_LTE_PAYLOAD_TAG 0x01
-
-
-/* Type to store parameters for configuring LCID->RLC channel settings for DRB */
-/* Some are optional, and may not be seen (e.g. on reestablishment) */
-typedef struct drb_mapping_t
-{
-    guint16    ueid;                /* Mandatory */
-    guint8     drbid;               /* Mandatory */
-    gboolean   lcid_present;
-    guint8     lcid;                /* Part of LogicalChannelConfig - optional */
-    gboolean   rlcMode_present;
-    guint8     rlcMode;             /* Part of RLC config - optional */
-    gboolean   rlc_ul_ext_li_field; /* Part of RLC config - optional */
-    gboolean   rlc_dl_ext_li_field; /* Part of RLC config - optional */
-    gboolean   rlc_ul_ext_am_sn;    /* Part of RLC config - optional */
-    gboolean   rlc_dl_ext_am_sn;    /* Part of RLC config - optional */
-    gboolean   um_sn_length_present;
-    guint8     um_sn_length;        /* Part of RLC config - optional */
-    gboolean   ul_priority_present;
-    guint8     ul_priority;         /* Part of LogicalChannelConfig - optional */
-    gboolean   pdcp_sn_size_present;
-    guint8     pdcp_sn_size;        /* Part of pdcp-Config - optional */
-} drb_mapping_t;
-
-
-
-/* Dedicated DRX config. Used to verify that a sensible config is given.
-   Also, beginning to configure MAC with this config and (optionally) show
-   DRX config and state (cycles/timers) attached to each UL/DL PDU! */
-typedef struct drx_config_t {
-    gboolean    configured;
-    guint32     frameNum;
-    guint32     previousFrameNum;
-
-    guint32     onDurationTimer;
-    guint32     inactivityTimer;
-    guint32     retransmissionTimer;
-    guint32     longCycle;
-    guint32     cycleOffset;
-    /* Optional Short cycle */
-    gboolean    shortCycleConfigured;
-    guint32     shortCycle;
-    guint32     shortCycleTimer;
-} drx_config_t;
-
-/* RRC can indicate whether simultaneous PUCCH/PUSCH is used */
-typedef enum {
-    SIMULT_PUCCH_PUSCH_PCELL = 0,
-    SIMULT_PUCCH_PUSCH_PSCELL
-} simult_pucch_pusch_cell_type;
-/*
- * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
- *
- * Local variables:
- * c-basic-offset: 4
- * tab-width: 8
- * indent-tabs-mode: nil
- * End:
- *
- * vi: set shiftwidth=4 tabstop=8 expandtab:
- * :indentSize=4:tabSize=8:noTabs=true:
- */
-
-#endif
diff --git a/openair2/UTIL/OPT/packet-rohc.h b/openair2/UTIL/OPT/packet-rohc.h
new file mode 100644
index 0000000000000000000000000000000000000000..c6c807f6872d139768f916bd3f166e45933705ce
--- /dev/null
+++ b/openair2/UTIL/OPT/packet-rohc.h
@@ -0,0 +1,72 @@
+/* packet-rohc.h
+ * Routines for RObust Header Compression (ROHC) dissection.
+ *
+ * Copyright 2011, Anders Broman <anders.broman[at]ericsson.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Ref:
+ * http://www.ietf.org/rfc/rfc3095.txt         RObust Header Compression (ROHC): Framework and four profiles: RTP, UDP, ESP, and uncompressed
+ * http://datatracker.ietf.org/doc/rfc4815/    RObust Header Compression (ROHC): Corrections and Clarifications to RFC 3095
+ * http://datatracker.ietf.org/doc/rfc5225/    RObust Header Compression Version 2 (ROHCv2): Profiles for RTP, UDP, IP, ESP and UDP-Lite
+ */
+
+#ifndef PACKET_ROHC_H
+#define PACKET_ROHC_H
+
+#define MAX_CID      15
+
+ /* ROHC Profiles */
+#define ROHC_PROFILE_UNCOMPRESSED   0
+#define ROHC_PROFILE_RTP            1
+#define ROHC_PROFILE_UDP            2
+#define ROHC_PROFILE_IP             4
+#define ROHC_PROFILE_UNKNOWN        0xFFFF
+
+enum rohc_mode
+{
+  MODE_NOT_SET = 0,
+  UNIDIRECTIONAL = 1,
+  OPTIMISTIC_BIDIRECTIONAL = 2,
+  RELIABLE_BIDIRECTIONAL = 3
+};
+
+enum rohc_d_mode
+{
+  NO_CONTEXT = 1,
+  STATIC_CONTEXT = 2,
+  FULL_CONTEXT = 3
+};
+typedef struct rohc_info
+{
+    gboolean           rohc_compression;
+    guint8             rohc_ip_version;
+    gboolean           cid_inclusion_info;
+    gboolean           large_cid_present;
+    enum rohc_mode     mode;
+    gboolean           rnd;
+    gboolean           udp_checksum_present;
+    guint16            profile;
+    proto_item         *last_created_item;
+} rohc_info;
+
+
+typedef struct rohc_context
+{
+    guint8             rohc_ip_version[MAX_CID+1];
+    gboolean           large_cid_present[MAX_CID+1];
+    enum rohc_mode     mode[MAX_CID+1];
+    enum rohc_d_mode   d_mode[MAX_CID+1];
+    gboolean           rnd[MAX_CID+1];
+    gboolean           udp_checkum_present[MAX_CID+1];
+    guint16            profile[MAX_CID+1];
+	gboolean           rohc_context_init[MAX_CID+1];
+	gint               ir_frame_number[MAX_CID+1];        /* The frame number of the last IR packet seen */
+
+} rohc_context;
+
+#endif /* PACKET_ROHC_H */
diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c
index 3f416c92553d97bfa1cc3a6a09d12255ed804e76..e64f7724c6399833723a6f84dd5176cd31b6b6f0 100644
--- a/openair2/UTIL/OPT/probe.c
+++ b/openair2/UTIL/OPT/probe.c
@@ -128,12 +128,6 @@ typedef struct {
 
 opt_listener_t opt_listener;
 
-static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
-                      guint16 rnti, guint16 ueid, guint16 sysframeNumber,
-                      guint8 isPredefinedData, guint8 retx, guint8 crcStatus,
-                      guint8 oob_event, guint8 oob_event_value,
-                      uint8_t *pdu_buffer, unsigned int pdu_buffer_size);
-
 unsigned short checksum(unsigned short *ptr, int length) {
   int sum = 0;
   u_short answer = 0;
@@ -152,7 +146,7 @@ unsigned short checksum(unsigned short *ptr, int length) {
 }
 
 /* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
-static int MAC_LTE_PCAP_WritePDU(const uint8_t *PDU,
+static int PCAP_WritePDU(const uint8_t *PDU,
                                  unsigned int length) {
   pcaprec_hdr_t packet_header;
   // IPv4 header
@@ -288,7 +282,7 @@ int opt_create_listener_socket(char *ip_address, uint16_t port) {
  */
 /* Add framing header to MAC PDU and send. */
 static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
-                      guint16 rnti, guint16 ueid, guint16 sfnSf,
+                      guint16 rnti, guint16 ueid, guint16 frame, guint16 subframe,
                       guint8 isPredefinedData, guint8 retx, guint8 crcStatus,
                       guint8 oob_event, guint8 oob_event_value,
                       uint8_t *pdu_buffer, unsigned int pdu_buffer_size) {
@@ -317,9 +311,9 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
   tmp16 = htons(ueid);
   memcpy(frameBuffer+frameOffset, &tmp16, 2);
   frameOffset += 2;
-  /* Subframe number */
+  /* Subframe number */ 
   frameBuffer[frameOffset++] = MAC_LTE_FRAME_SUBFRAME_TAG;
-  tmp16 = htons(sfnSf); // frame counter : this will give an expert info as wireshark expects SF and not F
+  tmp16 = htons((frame<<4)+subframe); // frame counter : this will give an expert info as wireshark expects SF and not F
   memcpy(frameBuffer+frameOffset, &tmp16, 2);
   frameOffset += 2;
   frameBuffer[frameOffset++] = MAC_LTE_CRC_STATUS_TAG;
@@ -400,7 +394,76 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
     bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0,
                        (const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr));
   else
-    bytesSent = MAC_LTE_PCAP_WritePDU(frameBuffer, frameOffset);
+    bytesSent = PCAP_WritePDU(frameBuffer, frameOffset);
+
+  if (bytesSent != frameOffset) {
+    LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n",
+          frameOffset, bytesSent, errno);
+    //exit(1);
+  }
+}
+
+static void SendFrameNR(guint8 radioType, guint8 direction, guint8 rntiType,
+			guint16 rnti, guint16 ueid,  guint16 frame, guint16 subframe,
+			guint8 isPredefinedData, guint8 retx, guint8 crcStatus,
+			guint8 oob_event, guint8 oob_event_value,
+			uint8_t *pdu_buffer, unsigned int pdu_buffer_size) {
+  unsigned char frameBuffer[9000];
+  unsigned int frameOffset;
+  ssize_t bytesSent;
+  frameOffset = 0;
+  uint16_t tmp16;
+  memcpy(frameBuffer+frameOffset, MAC_NR_START_STRING,
+         strlen(MAC_NR_START_STRING));
+  frameOffset += strlen(MAC_NR_START_STRING);
+  /******************************************************************************/
+  /* Now write out fixed fields (the mandatory elements of struct mac_lte_info) */
+  frameBuffer[frameOffset++] = radioType;
+  frameBuffer[frameOffset++] = direction;
+  frameBuffer[frameOffset++] = rntiType;
+  /*************************************/
+  /* Now optional fields               */
+  /* RNTI */
+  frameBuffer[frameOffset++] = MAC_NR_RNTI_TAG;
+  tmp16 = htons(rnti);
+  memcpy(frameBuffer+frameOffset, &tmp16, 2);
+  frameOffset += 2;
+  /* UEId */
+  frameBuffer[frameOffset++] = MAC_NR_UEID_TAG;
+  tmp16 = htons(ueid);
+  memcpy(frameBuffer+frameOffset, &tmp16, 2);
+  frameOffset += 2;
+  /* Subframe number */
+  frameBuffer[frameOffset++] = MAC_NR_FRAME_SLOT_TAG;
+  tmp16 = htons(frame); // frame counter : this will give an expert info as wireshark expects SF and not F
+  memcpy(frameBuffer+frameOffset, &tmp16, 2);
+  frameOffset += 2;
+  tmp16 = htons(subframe); // frame counter : this will give an expert info as wireshark expects SF and not F
+  memcpy(frameBuffer+frameOffset, &tmp16, 2);
+  frameOffset += 2;
+  if (direction == 0 ) { //ulink
+    frameBuffer[frameOffset++] = MAC_NR_PHR_TYPE2_OTHERCELL_TAG;
+    frameBuffer[frameOffset++] = 0;
+  }
+  
+  /***************************************/
+  /* Now write the MAC PDU               */
+  frameBuffer[frameOffset++] = MAC_NR_PAYLOAD_TAG;
+
+  /* Append actual PDU  */
+  //memcpy(frameBuffer+frameOffset, g_PDUBuffer, g_PDUOffset);
+  //frameOffset += g_PDUOffset;
+  if (pdu_buffer != NULL) {
+    memcpy(frameBuffer+frameOffset, (void *)pdu_buffer, pdu_buffer_size);
+    frameOffset += pdu_buffer_size;
+  }
+
+  if ( opt_type ==  OPT_WIRESHARK )
+    /* Send out the data over the UDP socket */
+    bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0,
+                       (const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr));
+  else
+    bytesSent = PCAP_WritePDU(frameBuffer, frameOffset);
 
   if (bytesSent != frameOffset) {
     LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n",
@@ -413,20 +476,23 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
 extern RAN_CONTEXT_t RC;
 #include <openair1/PHY/phy_extern_ue.h>
 /* Remote serveraddress (where Wireshark is running) */
-void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
+void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
                               int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event,
                               int oob_event_value) {
   int radioType=FDD_RADIO;
   LOG_D(OPT,"sending packet to wireshark: direction=%s, size: %d, ueid: %d, rnti: %x, frame/sf: %d.%d\n",
         direction?"DL":"UL", pdu_buffer_size, ueid, rnti, sysFrameNumber,subFrameNumber);
 
-  if (RC.eNB && RC.eNB[0][0]!=NULL)
-    radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
-  else if (PHY_vars_UE_g && PHY_vars_UE_g[0][0] != NULL)
-    radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
-  else {
-    LOG_E(OPT,"not a eNB neither a UE!!! \n");
-    return;
+  if (nr) {
+    radioType=TDD_RADIO;
+  } else {
+    if (RC.eNB && RC.eNB[0][0]!=NULL) 
+      radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
+    else if (PHY_vars_UE_g && PHY_vars_UE_g[0][0] != NULL)
+      radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
+    else {
+      LOG_E(OPT,"not a 4G eNB neither a 4G UE!!! \n");
+    }
   }
 
   switch (opt_type) {
@@ -448,9 +514,17 @@ void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int p
       break;
   }
 
+  if (nr)
+  SendFrameNR( radioType,
+             (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
+	       rntiType, rnti, ueid, sysFrameNumber, subFrameNumber,
+             1, 0, 1,  //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
+             oob_event,oob_event_value,
+             pdu_buffer, pdu_buffer_size);
+  else 
   SendFrame( radioType,
              (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
-             rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber,
+             rntiType, rnti, ueid, sysFrameNumber, subFrameNumber,
              1, 0, 1,  //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
              oob_event,oob_event_value,
              pdu_buffer, pdu_buffer_size);
diff --git a/openair2/UTIL/OPT/wireshark_headers.h b/openair2/UTIL/OPT/wireshark_headers.h
new file mode 100644
index 0000000000000000000000000000000000000000..27d8753ffe8c9e676a211399babb80f3d554a5ef
--- /dev/null
+++ b/openair2/UTIL/OPT/wireshark_headers.h
@@ -0,0 +1,895 @@
+/* packet-mac-lte.h
+ *
+ * Martin Mathieson
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * Copyright (C) 2009 Martin Mathieson. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+ /* 
+ this is wireshark, commit: commit eda834b6e29c36e05a63a6056afa98390ff79357 
+ Date:   Wed Aug 22 14:36:20 2018 +0200
+ modified to be used in OpenAir to create the LTE MAC/RLC encapsulated in UDP as per Wireshark feature 
+ */
+
+#ifndef __UTIL_OPT_PACKET_MAC_LTE__H__
+#define __UTIL_OPT_PACKET_MAC_LTE__H__
+
+/** data structure to hold time values with nanosecond resolution*/
+typedef struct {
+	time_t	secs;
+	int	nsecs;
+} nstime_t;
+
+
+/* radioType */
+#define FDD_RADIO 1
+#define TDD_RADIO 2
+
+/* Direction */
+#define DIRECTION_UPLINK   0
+#define DIRECTION_DOWNLINK 1
+
+/* rntiType */
+#define WS_NO_RNTI     0
+#define WS_P_RNTI      1
+#define WS_RA_RNTI     2
+#define WS_C_RNTI      3
+#define WS_SI_RNTI     4
+#define WS_SPS_RNTI    5
+#define WS_M_RNTI      6
+#define WS_SL_BCH_RNTI 7
+#define WS_SL_RNTI     8
+#define WS_SC_RNTI     9
+#define WS_G_RNTI      10
+
+#define WS_CS_RNTI     5
+
+typedef enum mac_lte_oob_event {
+    ltemac_send_preamble,
+    ltemac_send_sr,
+    ltemac_sr_failure
+} mac_lte_oob_event;
+
+typedef enum mac_lte_dl_retx {
+    dl_retx_no,
+    dl_retx_yes,
+    dl_retx_unknown
+} mac_lte_dl_retx;
+
+typedef enum mac_lte_crc_status {
+    crc_fail = 0,
+    crc_success = 1,
+    crc_high_code_rate = 2,
+    crc_pdsch_lost = 3,
+    crc_duplicate_nonzero_rv = 4,
+    crc_false_dci = 5
+} mac_lte_crc_status;
+
+/* N.B. for SCellIndex-r13 extends to 31 */
+typedef enum mac_lte_carrier_id {
+    carrier_id_primary,
+    carrier_id_secondary_1,
+    carrier_id_secondary_2,
+    carrier_id_secondary_3,
+    carrier_id_secondary_4,
+    carrier_id_secondary_5,
+    carrier_id_secondary_6,
+    carrier_id_secondary_7
+} mac_lte_carrier_id;
+
+typedef enum mac_lte_ce_mode {
+    no_ce_mode = 0,
+    ce_mode_a = 1,
+    ce_mode_b = 2
+} mac_lte_ce_mode;
+
+typedef enum mac_lte_nb_mode {
+    no_nb_mode = 0,
+    nb_mode = 1
+} mac_lte_nb_mode;
+
+/* Context info attached to each LTE MAC frame */
+typedef struct mac_lte_info
+{
+    /* Needed for decode */
+    guint8          radioType;
+    guint8          direction;
+    guint8          rntiType;
+
+    /* Extra info to display */
+    guint16         rnti;
+    guint16         ueid;
+
+    /* Timing info */
+    guint16         sysframeNumber;
+    guint16         subframeNumber;
+    gboolean        sfnSfInfoPresent;
+
+    /* Optional field. More interesting for TDD (FDD is always -4 subframeNumber) */
+    gboolean        subframeNumberOfGrantPresent;
+    guint16         subframeNumberOfGrant;
+
+    /* Flag set only if doing PHY-level data test - i.e. there may not be a
+       well-formed MAC PDU so just show as raw data */
+    gboolean        isPredefinedData;
+
+    /* Length of DL PDU or UL grant size in bytes */
+    guint16         length;
+
+    /* 0=newTx, 1=first-retx, etc */
+    guint8          reTxCount;
+    guint8          isPHICHNACK; /* FALSE=PDCCH retx grant, TRUE=PHICH NACK */
+
+    /* UL only.  Indicates if the R10 extendedBSR-Sizes parameter is set */
+    gboolean        isExtendedBSRSizes;
+
+    /* UL only.  Indicates if the R10 simultaneousPUCCH-PUSCH parameter is set for PCell */
+    gboolean        isSimultPUCCHPUSCHPCell;
+
+    /* UL only.  Indicates if the R10 extendedBSR-Sizes parameter is set for PSCell */
+    gboolean        isSimultPUCCHPUSCHPSCell;
+
+    /* Status of CRC check. For UE it is DL only. For eNodeB it is UL
+       only. For an analyzer, it is present for both DL and UL. */
+    gboolean        crcStatusValid;
+    mac_lte_crc_status crcStatus;
+
+    /* Carrier ID */
+    mac_lte_carrier_id   carrierId;
+
+    /* DL only.  Is this known to be a retransmission? */
+    mac_lte_dl_retx dl_retx;
+
+    /* DL only. CE mode to be used for RAR decoding */
+    mac_lte_ce_mode ceMode;
+
+    /* DL and UL. NB-IoT mode of the UE */
+    mac_lte_nb_mode nbMode;
+
+    /* UL only, for now used for CE mode A RAR decoding */
+    guint8          nUlRb;
+
+    /* More Physical layer info (see direction above for which side of union to use) */
+    union {
+        struct mac_lte_ul_phy_info
+        {
+            guint8 present;  /* Remaining UL fields are present and should be displayed */
+            guint8 modulation_type;
+            guint8 tbs_index;
+            guint8 resource_block_length;
+            guint8 resource_block_start;
+            guint8 harq_id;
+            gboolean ndi;
+        } ul_info;
+        struct mac_lte_dl_phy_info
+        {
+            guint8 present; /* Remaining DL fields are present and should be displayed */
+            guint8 dci_format;
+            guint8 resource_allocation_type;
+            guint8 aggregation_level;
+            guint8 mcs_index;
+            guint8 redundancy_version_index;
+            guint8 resource_block_length;
+            guint8 harq_id;
+            gboolean ndi;
+            guint8   transport_block;  /* 0..1 */
+        } dl_info;
+    } detailed_phy_info;
+
+    /* Relating to out-of-band events */
+    /* N.B. dissector will only look to these fields if length is 0... */
+    mac_lte_oob_event  oob_event;
+    guint8             rapid;
+    guint8             rach_attempt_number;
+    #define MAX_SRs 20
+    guint16            number_of_srs;
+    guint16            oob_ueid[MAX_SRs];
+    guint16            oob_rnti[MAX_SRs];
+} mac_lte_info;
+
+ /* 0 to 10 and 32 to 38 */
+#define MAC_LTE_DATA_LCID_COUNT_MAX 18
+#define MAC_LTE_START_STRING "mac-lte"
+
+/* Fixed fields.  This is followed by the following 3 mandatory fields:
+   - radioType (1 byte)
+   - direction (1 byte)
+   - rntiType (1 byte)
+   (where the allowed values are defined above */
+
+/* Optional fields. Attaching this info to frames will allow you
+   to show you display/filter/plot/add-custom-columns on these fields, so should
+   be added if available.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag) */
+
+#define MAC_LTE_RNTI_TAG            0x02
+/* 2 bytes, network order */
+
+#define MAC_LTE_UEID_TAG            0x03
+/* 2 bytes, network order */
+
+#define MAC_LTE_FRAME_SUBFRAME_TAG  0x04
+/* 2 bytes, network order, SFN is stored in 12 MSB and SF in 4 LSB */
+
+#define MAC_LTE_PREDEFINED_DATA_TAG 0x05
+/* 1 byte */
+
+#define MAC_LTE_RETX_TAG            0x06
+/* 1 byte */
+
+#define MAC_LTE_CRC_STATUS_TAG      0x07
+/* 1 byte */
+
+#define MAC_LTE_EXT_BSR_SIZES_TAG   0x08
+/* 0 byte */
+
+#define MAC_LTE_SEND_PREAMBLE_TAG   0x09
+/* 2 bytes, RAPID value (1 byte) followed by RACH attempt number (1 byte) */
+
+#define MAC_LTE_CARRIER_ID_TAG      0x0A
+/* 1 byte */
+
+#define MAC_LTE_PHY_TAG             0x0B
+/* variable length, length (1 byte) then depending on direction
+   in UL: modulation type (1 byte), TBS index (1 byte), RB length (1 byte),
+          RB start (1 byte), HARQ id (1 byte), NDI (1 byte)
+   in DL: DCI format (1 byte), resource allocation type (1 byte), aggregation level (1 byte),
+          MCS index (1 byte), redundancy version (1 byte), resource block length (1 byte),
+          HARQ id (1 byte), NDI (1 byte), TB (1 byte), DL reTx (1 byte) */
+
+#define MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG  0x0C
+/* 0 byte */
+
+#define MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG 0x0D
+/* 0 byte */
+
+#define MAC_LTE_CE_MODE_TAG         0x0E
+/* 1 byte containing mac_lte_ce_mode enum value */
+
+#define MAC_LTE_NB_MODE_TAG         0x0F
+/* 1 byte containing mac_lte_nb_mode enum value */
+
+#define MAC_LTE_N_UL_RB_TAG         0x10
+/* 1 byte containing the number of UL resource blocks: 6, 15, 25, 50, 75 or 100 */
+
+#define MAC_LTE_SR_TAG              0x11
+/* 2 bytes for the number of items, followed by that number of ueid, rnti (2 bytes each) */
+
+
+/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
+   continues until the end of the frame) */
+#define MAC_LTE_PAYLOAD_TAG 0x01
+
+/* rlcMode */
+#define RLC_TM_MODE 1
+#define RLC_UM_MODE 2
+#define RLC_AM_MODE 4
+#define RLC_PREDEF  8
+
+/* priority ? */
+
+/* channelType */
+#define CHANNEL_TYPE_CCCH 1
+#define CHANNEL_TYPE_BCCH_BCH 2
+#define CHANNEL_TYPE_PCCH 3
+#define CHANNEL_TYPE_SRB 4
+#define CHANNEL_TYPE_DRB 5
+#define CHANNEL_TYPE_BCCH_DL_SCH 6
+#define CHANNEL_TYPE_MCCH 7
+#define CHANNEL_TYPE_MTCH 8
+
+/* sequenceNumberLength */
+#define UM_SN_LENGTH_5_BITS 5
+#define UM_SN_LENGTH_10_BITS 10
+#define AM_SN_LENGTH_10_BITS 10
+#define AM_SN_LENGTH_16_BITS 16
+
+
+typedef enum rlc_lte_nb_mode {
+    rlc_no_nb_mode = 0,
+    rlc_nb_mode = 1
+} rlc_lte_nb_mode;
+
+
+/* Info attached to each LTE RLC frame */
+typedef struct rlc_lte_info
+{
+    guint8          rlcMode;
+    guint8          direction;
+    guint8          priority;
+    guint8          sequenceNumberLength;
+    guint16         ueid;
+    guint16         channelType;
+    guint16         channelId; /* for SRB: 1=SRB1, 2=SRB2, 3=SRB1bis; for DRB: DRB ID */
+    guint16         pduLength;
+    gboolean        extendedLiField;
+    rlc_lte_nb_mode nbMode;
+} rlc_lte_info;
+
+
+typedef struct rlc_lte_tap_info {
+    /* Info from context */
+    guint8          rlcMode;
+    guint8          direction;
+    guint8          priority;
+    guint16         ueid;
+    guint16         channelType;
+    guint16         channelId;
+    guint16         pduLength;
+    guint8          sequenceNumberLength;
+
+    nstime_t        rlc_lte_time;
+    guint8          loggedInMACFrame;
+    guint16         sequenceNumber;
+    guint8          isResegmented;
+    guint8          isControlPDU;
+    guint16         ACKNo;
+    #define MAX_NACKs 128
+    guint16         noOfNACKs;
+    guint16         NACKs[MAX_NACKs];
+
+    guint16         missingSNs;
+} rlc_lte_tap_info;
+
+
+/* Signature.  Rather than try to define a port for this, or make the
+   port number a preference, frames will start with this string (with no
+   terminating NULL */
+#define RLC_LTE_START_STRING "rlc-lte"
+
+/* Fixed field.  This is followed by the following 1 mandatory field:
+   - rlcMode (1 byte)
+   (where the allowed values are defined above */
+
+/* Conditional field. This field is mandatory in case of RLC Unacknowledged mode.
+   In case of RLC Acknowledged mode, the field is optional (assume 10 bits by default).
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag). The allowed values are defined above. */
+
+#define RLC_LTE_SN_LENGTH_TAG    0x02
+/* 1 byte */
+
+/* Optional fields. Attaching this info to frames will allow you
+   to show you display/filter/plot/add-custom-columns on these fields, so should
+   be added if available.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag) */
+
+#define RLC_LTE_DIRECTION_TAG       0x03
+/* 1 byte */
+
+#define RLC_LTE_PRIORITY_TAG        0x04
+/* 1 byte */
+
+#define RLC_LTE_UEID_TAG            0x05
+/* 2 bytes, network order */
+
+#define RLC_LTE_CHANNEL_TYPE_TAG    0x06
+/* 2 bytes, network order */
+
+#define RLC_LTE_CHANNEL_ID_TAG      0x07
+/* 2 bytes, network order */
+
+#define RLC_LTE_EXT_LI_FIELD_TAG    0x08
+/* 0 byte, tag presence indicates that AM DRB PDU is using an extended LI field of 15 bits */
+
+#define RLC_LTE_NB_MODE_TAG         0x09
+/* 1 byte containing rlc_lte_nb_mode enum value */
+
+/* RLC PDU. Following this tag comes the actual RLC PDU (there is no length, the PDU
+   continues until the end of the frame) */
+#define RLC_LTE_PAYLOAD_TAG         0x01
+
+enum pdcp_plane
+{
+    SIGNALING_PLANE = 1,
+    USER_PLANE = 2
+};
+
+typedef enum LogicalChannelType
+{
+    Channel_DCCH=1,
+    Channel_BCCH=2,
+    Channel_CCCH=3,
+    Channel_PCCH=4,
+    Channel_DCCH_NB=5,
+    Channel_BCCH_NB=6,
+    Channel_CCCH_NB=7,
+    Channel_PCCH_NB=8
+} LogicalChannelType;
+
+typedef enum
+{
+    BCH_TRANSPORT=1,
+    DLSCH_TRANSPORT=2
+} BCCHTransportType;
+
+#define PDCP_SN_LENGTH_5_BITS  5
+#define PDCP_SN_LENGTH_7_BITS  7
+#define PDCP_SN_LENGTH_12_BITS 12
+#define PDCP_SN_LENGTH_15_BITS 15
+#define PDCP_SN_LENGTH_18_BITS 18
+
+enum lte_security_integrity_algorithm_e { eia0, eia1, eia2, eia3 };
+enum lte_security_ciphering_algorithm_e { eea0, eea1, eea2, eea3 };
+
+typedef struct pdcp_lte_security_info_t
+{
+    guint32                                 configuration_frame;
+    gboolean                                seen_next_ul_pdu;  /* i.e. have we seen SecurityModeResponse */
+    enum lte_security_integrity_algorithm_e integrity;
+    enum lte_security_ciphering_algorithm_e ciphering;
+
+    /* Store previous settings so can revert if get SecurityModeFailure */
+    guint32                                 previous_configuration_frame;
+    enum lte_security_integrity_algorithm_e previous_integrity;
+    enum lte_security_ciphering_algorithm_e previous_ciphering;
+} pdcp_lte_security_info_t;
+
+
+/***********************************************************************/
+/* UDP framing format                                                  */
+/* -----------------------                                             */
+/* Several people have asked about dissecting PDCP by framing          */
+/* PDUs over IP.  A suggested format over UDP has been defined         */
+/* and implemented by this dissector, using the definitions            */
+/* below. A link to an example program showing you how to encode       */
+/* these headers and send LTE PDCP PDUs on a UDP socket is             */
+/* provided at https://gitlab.com/wireshark/wireshark/-/wikis/PDCP-LTE */
+/*                                                                     */
+/* A heuristic dissecter (enabled by a preference) will                */
+/* recognise a signature at the beginning of these frames.             */
+/* Until someone is using this format, suggestions for changes         */
+/* are welcome.                                                        */
+/***********************************************************************/
+
+
+/* Signature.  Rather than try to define a port for this, or make the
+   port number a preference, frames will start with this string (with no
+   terminating NULL */
+#define PDCP_LTE_START_STRING "pdcp-lte"
+
+/* Fixed fields.  This is followed by the following 3 mandatory fields:
+   - no_header_pdu (1 byte)
+   - plane (1 byte)
+   - rohc_compression ( byte)
+   (where the allowed values are defined above) */
+
+/* Conditional field. This field is mandatory in case of User Plane PDCP PDU.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag). The allowed values are defined above. */
+
+#define PDCP_LTE_SEQNUM_LENGTH_TAG          0x02
+/* 1 byte */
+
+/* Optional fields. Attaching this info to frames will allow you
+   to show you display/filter/plot/add-custom-columns on these fields, so should
+   be added if available.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag) */
+
+#define PDCP_LTE_DIRECTION_TAG              0x03
+/* 1 byte */
+
+#define PDCP_LTE_LOG_CHAN_TYPE_TAG          0x04
+/* 1 byte */
+
+#define PDCP_LTE_BCCH_TRANSPORT_TYPE_TAG    0x05
+/* 1 byte */
+
+#define PDCP_LTE_ROHC_IP_VERSION_TAG        0x06
+/* 2 bytes, network order */
+
+#define PDCP_LTE_ROHC_CID_INC_INFO_TAG      0x07
+/* 1 byte */
+
+#define PDCP_LTE_ROHC_LARGE_CID_PRES_TAG    0x08
+/* 1 byte */
+
+#define PDCP_LTE_ROHC_MODE_TAG              0x09
+/* 1 byte */
+
+#define PDCP_LTE_ROHC_RND_TAG               0x0A
+/* 1 byte */
+
+#define PDCP_LTE_ROHC_UDP_CHECKSUM_PRES_TAG 0x0B
+/* 1 byte */
+
+#define PDCP_LTE_ROHC_PROFILE_TAG           0x0C
+/* 2 bytes, network order */
+
+#define PDCP_LTE_CHANNEL_ID_TAG             0x0D
+/* 2 bytes, network order */
+
+#define PDCP_LTE_UEID_TAG                   0x0E
+/* 2 bytes, network order */
+
+/* PDCP PDU. Following this tag comes the actual PDCP PDU (there is no length, the PDU
+   continues until the end of the frame) */
+#define PDCP_LTE_PAYLOAD_TAG                0x01
+
+
+
+/* Called by RRC, or other configuration protocols */
+
+/* Function to configure ciphering & integrity algorithms */
+void set_pdcp_lte_security_algorithms(guint16 ueid, pdcp_lte_security_info_t *security_info);
+
+/* Function to indicate securityModeCommand did not complete */
+void set_pdcp_lte_security_algorithms_failed(guint16 ueid);
+
+
+/* Called by external dissectors */
+void set_pdcp_lte_rrc_ciphering_key(guint16 ueid, const char *key);
+void set_pdcp_lte_rrc_integrity_key(guint16 ueid, const char *key);
+void set_pdcp_lte_up_ciphering_key(guint16 ueid, const char *key);
+
+
+
+/* Context info attached to each NR MAC frame */
+typedef struct mac_nr_info
+{
+    /* Needed for decode */
+    guint8          radioType;
+    guint8          direction;
+    guint8          rntiType;
+
+    /* Extra info to display */
+    guint16         rnti;
+    guint16         ueid;
+    guint8          harqid;
+
+    /* Will these be included in the ME PHR report? */
+    guint8          phr_type2_othercell;
+
+    /* Timing info */
+    gboolean        sfnSlotInfoPresent;
+    guint16         sysframeNumber;
+    guint16         slotNumber;
+
+    /* Length of DL PDU or UL grant size in bytes */
+    guint16         length;
+
+} mac_nr_info;
+
+
+/*****************************************************************/
+/* UDP framing format                                            */
+/* -----------------------                                       */
+/* Several people have asked about dissecting MAC by framing     */
+/* PDUs over IP.  A suggested format over UDP has been created   */
+/* and implemented by this dissector, using the definitions      */
+/* below.                                                        */
+/*                                                               */
+/* A heuristic dissector (enabled by a preference) will          */
+/* recognise a signature at the beginning of these frames.       */
+/*****************************************************************/
+
+
+/* Signature.  Rather than try to define a port for this, or make the
+   port number a preference, frames will start with this string (with no
+   terminating NULL */
+#define MAC_NR_START_STRING "mac-nr"
+
+/* Fixed fields.  This is followed by the following 3 mandatory fields:
+   - radioType (1 byte)
+   - direction (1 byte)
+   - rntiType (1 byte)
+   (where the allowed values are defined above */
+
+/* Optional fields. Attaching this info to frames will allow you
+   to show you display/filter/plot/add-custom-columns on these fields, so should
+   be added if available.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag) */
+
+#define MAC_NR_RNTI_TAG                0x02
+/* 2 bytes, network order */
+
+#define MAC_NR_UEID_TAG                0x03
+/* 2 bytes, network order */
+
+#define MAC_NR_FRAME_SUBFRAME_TAG      0x04
+/* 2 bytes, deprecated, do not use it */
+
+#define MAC_NR_PHR_TYPE2_OTHERCELL_TAG 0x05
+/* 1 byte, TRUE/FALSE */
+
+#define MAC_NR_HARQID                  0x06
+/* 1 byte */
+
+#define MAC_NR_FRAME_SLOT_TAG          0x07
+/* 4 bytes, network order, SFN is stored in the 2 first bytes and slot number in the 2 last bytes */
+
+/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
+   continues until the end of the frame) */
+#define MAC_NR_PAYLOAD_TAG             0x01
+
+
+/* Type to store parameters for configuring LCID->RLC channel settings for DRB */
+/* Some are optional, and may not be seen (e.g. on reestablishment) */
+typedef struct nr_drb_mac_rlc_mapping_t
+{
+    gboolean   active;
+    guint16    ueid;                /* Mandatory */
+    guint8     drbid;               /* Mandatory */
+
+    gboolean   lcid_present;
+    guint8     lcid;                /* Part of LogicalChannelConfig - optional */
+    gboolean   rlcMode_present;
+    guint8     rlcMode;             /* Part of RLC config - optional */
+
+    guint8     tempDirection;       /* So know direction of next SN length... */
+
+    gboolean   rlcUlSnLength_present;
+    guint8     rlcUlSnLength;        /* Part of RLC config - optional */
+    gboolean   rlcDlSnLength_present;
+    guint8     rlcDlSnLength;        /* Part of RLC config - optional */
+} nr_drb_mac_rlc_mapping_t;
+
+/* rlcMode */
+#define RLC_TM_MODE 1
+#define RLC_UM_MODE 2
+#define RLC_AM_MODE 4
+
+/* bearerType */
+#define BEARER_TYPE_CCCH 1
+#define BEARER_TYPE_BCCH_BCH 2
+#define BEARER_TYPE_PCCH 3
+#define BEARER_TYPE_SRB 4
+#define BEARER_TYPE_DRB 5
+#define BEARER_TYPE_BCCH_DL_SCH 6
+
+/* sequenceNumberLength */
+#define TM_SN_LENGTH_0_BITS  0
+#define UM_SN_LENGTH_6_BITS  6
+#define UM_SN_LENGTH_12_BITS 12
+#define AM_SN_LENGTH_12_BITS 12
+#define AM_SN_LENGTH_18_BITS 18
+
+/* Info attached to each NR RLC frame */
+typedef struct rlc_nr_info
+{
+    guint8          rlcMode;
+    guint8          direction;
+    guint8          sequenceNumberLength;
+    guint8          bearerType;
+    guint8          bearerId;
+    guint16         ueid;
+    guint16         pduLength;
+} rlc_nr_info;
+
+typedef struct nr_drb_rlc_pdcp_mapping_t
+{
+    gboolean   active;
+    guint16    ueid;                /* Mandatory */
+    guint8     drbid;               /* Mandatory */
+
+    gboolean   pdcpUlSnLength_present;
+    guint8     pdcpUlSnLength;        /* Part of PDCP config - optional */
+    gboolean   pdcpDlSnLength_present;
+    guint8     pdcpDlSnLength;        /* Part of PDCP config - optional */
+    gboolean   pdcpUlSdap;
+    gboolean   pdcpDlSdap;
+    gboolean   pdcpIntegrityProtection;
+    gboolean   pdcpCipheringDisabled;
+
+} nr_drb_rlc_pdcp_mapping_t;
+
+/* TODO: could probably merge this struct with above */
+typedef struct pdcp_ue_parameters {
+    guint32   id;
+    guint8    pdcp_sn_bits_ul;
+    guint8    pdcp_sn_bits_dl;
+    gboolean  pdcp_sdap_ul;
+    gboolean  pdcp_sdap_dl;
+    gboolean  pdcp_integrity;
+    gboolean  pdcp_ciphering_disabled;
+} pdcp_bearer_parameters;
+
+/*****************************************************************/
+/* UDP framing format                                            */
+/* -----------------------                                       */
+/* Several people have asked about dissecting RLC by framing     */
+/* PDUs over IP. A suggested format over UDP has been defined    */
+/* and implemented by this dissector, using the definitions      */
+/* below.                                                        */
+/*                                                               */
+/* A heuristic dissector (enabled by a preference) will          */
+/* recognise a signature at the beginning of these frames.       */
+/*****************************************************************/
+
+
+/* Signature.  Rather than try to define a port for this, or make the
+   port number a preference, frames will start with this string (with no
+   terminating NULL */
+#define RLC_NR_START_STRING "rlc-nr"
+
+/* Fixed field. This is followed by the following 2 mandatory field:
+   - rlcMode (1 byte)
+   - sequenceNumberLength (1 byte)
+   (where the allowed values are defined above) */
+
+/* Optional fields. Attaching this info to frames will allow you
+   to show you display/filter/plot/add-custom-columns on these fields, so should
+   be added if available.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag) */
+
+#define RLC_NR_DIRECTION_TAG       0x02
+/* 1 byte */
+
+#define RLC_NR_UEID_TAG            0x03
+/* 2 bytes, network order */
+
+#define RLC_NR_BEARER_TYPE_TAG     0x04
+/* 1 byte */
+
+#define RLC_NR_BEARER_ID_TAG       0x05
+/* 1 byte */
+
+/* RLC PDU. Following this tag comes the actual RLC PDU (there is no length, the PDU
+   continues until the end of the frame) */
+#define RLC_NR_PAYLOAD_TAG         0x01
+
+enum pdcp_nr_plane
+{
+    NR_SIGNALING_PLANE = 1,
+    NR_USER_PLANE = 2
+};
+
+typedef enum NRBearerType
+{
+    Bearer_DCCH=1,
+    Bearer_BCCH_BCH=2,
+    Bearer_BCCH_DL_SCH=3,
+    Bearer_CCCH=4,
+    Bearer_PCCH=5,
+} NRBearerType;
+
+
+#define PDCP_NR_SN_LENGTH_12_BITS 12
+#define PDCP_NR_SN_LENGTH_18_BITS 18
+
+#define PDCP_NR_UL_SDAP_HEADER_PRESENT 0x01
+#define PDCP_NR_DL_SDAP_HEADER_PRESENT 0x02
+
+enum nr_security_integrity_algorithm_e { nia0, nia1, nia2, nia3 };
+enum nr_security_ciphering_algorithm_e { nea0, nea1, nea2, nea3, nea_disabled=999};
+
+typedef struct pdcp_nr_security_info_t
+{
+    guint32                                configuration_frame;
+    gboolean                               seen_next_ul_pdu;  /* i.e. have we seen SecurityModeResponse */
+    enum nr_security_integrity_algorithm_e integrity;
+    enum nr_security_ciphering_algorithm_e ciphering;
+
+    /* Store previous settings so can revert if get SecurityModeFailure */
+    guint32                                previous_configuration_frame;
+    enum nr_security_integrity_algorithm_e previous_integrity;
+    enum nr_security_ciphering_algorithm_e previous_ciphering;
+} pdcp_nr_security_info_t;
+
+
+/*****************************************************************/
+/* UDP framing format                                            */
+/* -----------------------                                       */
+/* Several people have asked about dissecting PDCP by framing    */
+/* PDUs over IP.  A suggested format over UDP has been defined   */
+/* and implemented by this dissector, using the definitions      */
+/* below.                                                        */
+/*                                                               */
+/* A heuristic dissector (enabled by a preference) will          */
+/* recognise a signature at the beginning of these frames.       */
+/* Until someone is using this format, suggestions for changes   */
+/* are welcome.                                                  */
+/*****************************************************************/
+
+
+/* Signature.  Rather than try to define a port for this, or make the
+   port number a preference, frames will start with this string (with no
+   terminating NULL */
+#define PDCP_NR_START_STRING "pdcp-nr"
+
+/* Fixed fields:
+   - plane (1 byte) */
+
+/* Conditional field. This field is mandatory in case of User Plane PDCP PDU.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag). The allowed values are defined above. */
+
+#define PDCP_NR_SEQNUM_LENGTH_TAG          0x02
+/* 1 byte */
+
+/* Optional fields. Attaching this info should be added if available.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag) */
+
+#define PDCP_NR_DIRECTION_TAG              0x03
+/* 1 byte */
+
+#define PDCP_NR_BEARER_TYPE_TAG            0x04
+/* 1 byte */
+
+#define PDCP_NR_BEARER_ID_TAG              0x05
+/* 1 byte */
+
+#define PDCP_NR_UEID_TAG                   0x06
+/* 2 bytes, network order */
+
+#define PDCP_NR_ROHC_COMPRESSION_TAG       0x07
+/* 0 byte */
+
+/* N.B. The following ROHC values only have significance if rohc_compression
+   is in use for the current channel */
+
+#define PDCP_NR_ROHC_IP_VERSION_TAG        0x08
+/* 1 byte */
+
+#define PDCP_NR_ROHC_CID_INC_INFO_TAG      0x09
+/* 0 byte */
+
+#define PDCP_NR_ROHC_LARGE_CID_PRES_TAG    0x0A
+/* 0 byte */
+
+#define PDCP_NR_ROHC_MODE_TAG              0x0B
+/* 1 byte */
+
+#define PDCP_NR_ROHC_RND_TAG               0x0C
+/* 0 byte */
+
+#define PDCP_NR_ROHC_UDP_CHECKSUM_PRES_TAG 0x0D
+/* 0 byte */
+
+#define PDCP_NR_ROHC_PROFILE_TAG           0x0E
+/* 2 bytes, network order */
+
+#define PDCP_NR_MACI_PRES_TAG              0x0F
+/* 0 byte */
+
+#define PDCP_NR_SDAP_HEADER_TAG            0x10
+/* 1 byte, bitmask with PDCP_NR_UL_SDAP_HEADER_PRESENT and/or PDCP_NR_DL_SDAP_HEADER_PRESENT */
+
+#define PDCP_NR_CIPHER_DISABLED_TAG        0x11
+/* 0 byte */
+
+/* PDCP PDU. Following this tag comes the actual PDCP PDU (there is no length, the PDU
+   continues until the end of the frame) */
+#define PDCP_NR_PAYLOAD_TAG                0x01
+
+
+/* Called by RRC, or other configuration protocols */
+
+/* Function to configure ciphering & integrity algorithms */
+void set_pdcp_nr_security_algorithms(guint16 ueid, pdcp_nr_security_info_t *security_info);
+
+/* Function to indicate securityModeCommand did not complete */
+void set_pdcp_nr_security_algorithms_failed(guint16 ueid);
+
+
+/* Called by external dissectors */
+void set_pdcp_nr_rrc_ciphering_key(guint16 ueid, const char *key);
+void set_pdcp_nr_rrc_integrity_key(guint16 ueid, const char *key);
+void set_pdcp_nr_up_ciphering_key(guint16 ueid, const char *key);
+void set_pdcp_nr_up_integrity_key(guint16 ueid, const char *key);
+
+/*
+ * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
+#endif
diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h
index 633465868380bba098f25dfbe385873baa050765..e845315922ceaafe585c1a04adfb2bdb8bd84a60 100644
--- a/openair2/UTIL/OSA/osa_defs.h
+++ b/openair2/UTIL/OSA/osa_defs.h
@@ -48,7 +48,8 @@ typedef enum {
   NAS_INT_ALG = 0x02,
   RRC_ENC_ALG = 0x03,
   RRC_INT_ALG = 0x04,
-  UP_ENC_ALG  = 0x05
+  UP_ENC_ALG  = 0x05,
+  UP_INT_ALG  = 0x06
 } algorithm_type_dist_t;
 
 //int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB);
diff --git a/openair2/UTIL/OTG/otg_defs.h b/openair2/UTIL/OTG/otg_defs.h
index 6c9944014fd99f08e01e53f2ef4e4330446bf8e3..af0260587fef51d04cf4ba4fb63cc5af6e23ee67 100644
--- a/openair2/UTIL/OTG/otg_defs.h
+++ b/openair2/UTIL/OTG/otg_defs.h
@@ -34,13 +34,8 @@
 # define __OTG_DEFS_H__
 
 /* \brief To define the NUMBER_OF_eNB_MAX and MAX_MOBILES_PER_ENB */
-#if STANDALONE==1
-	#include "openairinterface5g_limits.h"
-#else
-	// impl_defs_top.h includes openairinterface5g_limits.h
-	#include "PHY/impl_defs_top.h"
-#endif
-
+#include "openairinterface5g_limits.h"
+#include <openair2/COMMON/platform_constants.h>
 #include "otg_config.h"
 
 /**
diff --git a/openair2/UTIL/TRACE/fifo_printf.c b/openair2/UTIL/TRACE/fifo_printf.c
deleted file mode 100644
index 2dc4da06371f923efca0d445e36a79558af4f9ee..0000000000000000000000000000000000000000
--- a/openair2/UTIL/TRACE/fifo_printf.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-/*
- *                               fifo_printf.c
- *                             -------------------
- *  AUTHOR  : Lionel GAUTHIER
- *  COMPANY : EURECOM
- *  EMAIL   : Lionel.Gauthier@eurecom.fr
- *
- */
-#include "rtos_header.h"
-#include "platform.h"
-#include "protocol_vars_extern.h"
-
-#include <asm/page.h>
-#include <asm/system.h>
-#include <stdarg.h>
-
-
-#include "fifo_printf.h"
-
-#ifndef FIFO_PRINTF
-//-----------------------------------------------------------------------------
-int fifo_printf_null (const char *fmt, ...)
-{
-  return 0;
-}
-#else
-static uint8_t       fifo_printed_l1[FIFO_PRINTF_MAX_STRING_SIZE];
-static uint8_t       fifo_printed_l2[FIFO_PRINTF_MAX_STRING_SIZE];
-//-----------------------------------------------------------------------------
-void
-fifo_printf_init (void)
-{
-  //-----------------------------------------------------------------------------
-  printk ("[TRACE] INIT\n");
-  rtf_create (FIFO_PRINTF_L1_NO, FIFO_PRINTF_SIZE);
-  rtf_create (FIFO_PRINTF_L2_NO, FIFO_PRINTF_SIZE);
-}
-
-//-----------------------------------------------------------------------------
-void
-fifo_printf_clean_up (void)
-{
-  //-----------------------------------------------------------------------------
-  rtf_destroy (FIFO_PRINTF_L1_NO);
-  rtf_destroy (FIFO_PRINTF_L2_NO);
-}
-
-//-----------------------------------------------------------------------------
-int
-fifo_printf (const char *fmt, ...)
-{
-  //-----------------------------------------------------------------------------
-  int             i;
-  va_list         args;
-
-  va_start (args, fmt);
-
-  if (pthread_self () == &task_l1l) {
-    i = vsprintf (fifo_printed_l1, fmt, args);
-    va_end (args);
-
-    /* perhaps we should discard old data instead */
-    if (i > FIFO_PRINTF_MAX_STRING_SIZE) {
-      rt_printk ("[WCDMA] FIFO_PRINTF WROTE OUTSIDE ITS MEMORY BOUNDARY : ERRORS WILL OCCUR\n");
-    }
-
-    if (i <= 0) {
-      return 0;
-    }
-
-    rtf_put (FIFO_PRINTF_L1_NO, fifo_printed_l1, i);
-
-    return i;
-  }
-
-  if (pthread_self () == &task_l2) {
-    i = vsprintf (fifo_printed_l2, fmt, args);
-    va_end (args);
-
-    /* perhaps we should discard old data instead */
-    if (i > FIFO_PRINTF_MAX_STRING_SIZE) {
-      rt_printk ("[WCDMA] FIFO_PRINTF WROTE OUTSIDE ITS MEMORY BOUNDARY : ERRORS WILL OCCUR\n");
-    }
-
-    if (i <= 0) {
-      return 0;
-    }
-
-    rtf_put (FIFO_PRINTF_L2_NO, fifo_printed_l2, i);
-
-    return i;
-  }
-
-  return 0;
-}
-#endif
diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c
index 58535646fd023c1d17f4402b55a9b43681d76544..38e6149ccd2ef103f8425720c53816ca3a546cd4 100644
--- a/openair2/X2AP/x2ap_eNB.c
+++ b/openair2/X2AP/x2ap_eNB.c
@@ -115,10 +115,13 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
     if (x2ap_enb_data_p != NULL) {
       /* some sanity check - to be refined at some point */
       if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
-        X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n");
-        // Allow for a gracious exit when we kill first the gNB, then the eNB
-        //abort();
-        return;
+        X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED?\n");
+        if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN){
+          RB_REMOVE(x2ap_enb_map, &instance_p->x2ap_enb_head, x2ap_enb_data_p);
+          return;
+        }
+
+        exit(1);
       }
 
       x2ap_enb_data_p->in_streams  = sctp_new_association_resp->in_streams;
@@ -132,6 +135,18 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
   DevAssert(x2ap_enb_data_p != NULL);
   dump_trees();
 
+  /* gNB: exit if connection to eNB failed - to be modified if needed.
+   * We may want to try to connect over and over again until we succeed
+   * but the modifications to the code to get this behavior are complex.
+   * Exit on error is a simple solution that can be caught by a script
+   * for example.
+   */
+  if (instance_p->cell_type == CELL_MACRO_GNB
+      && sctp_new_association_resp->sctp_state == SCTP_STATE_UNREACHABLE) {
+    X2AP_ERROR("association with eNB failed, is it running? If no, run it first. If yes, check IP addresses in your configuration file.\n");
+    exit(1);
+  }
+
   if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
     X2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
               sctp_new_association_resp->sctp_state,
diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c
index fdce8678b0eacbee802ccdf6d72240d1f7653e87..7c3a89e7f4bff4b0a652f8224d1b94161b375cf0 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.c
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.c
@@ -1318,6 +1318,9 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length
 
             ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band);
             switch (instance_p->N_RB_DL[i]) {
+            case 24:
+              servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb24;
+              break;
             case 32:
               servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb32;
               break;
diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c
index f0e0fa9c231b41c592560dee73a9f9756b25c790..d60f7654ad40348af381e6778d611857667aaa2c 100644
--- a/openair2/X2AP/x2ap_eNB_handler.c
+++ b/openair2/X2AP/x2ap_eNB_handler.c
@@ -536,6 +536,14 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
     return -1;
   }
 
+  if((x2ap_eNB_data->state == X2AP_ENB_STATE_CONNECTED) ||
+     (x2ap_eNB_data->state == X2AP_ENB_STATE_READY))
+  
+  {
+    X2AP_ERROR("Received Unexpexted X2 Setup Response Message\n");
+    return -1;
+  }
+
   X2AP_DEBUG("Received a new X2 setup response\n");
 
   X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupResponse_IEs_t, ie, x2SetupResponse,
@@ -662,6 +670,14 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance,
     return -1;
   }
 
+  if((x2ap_eNB_data->state == X2AP_ENB_STATE_CONNECTED) ||
+     (x2ap_eNB_data->state == X2AP_ENB_STATE_READY))
+  
+  {
+    X2AP_ERROR("Received Unexpexted X2 Setup Failure Message\n");
+    return -1;
+  }
+
   X2AP_DEBUG("Received a new X2 setup failure\n");
 
   X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupFailure_IEs_t, ie, x2SetupFailure,
@@ -674,9 +690,11 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance,
   // need a FSM to handle all cases
   if ((ie->value.choice.Cause.present == X2AP_Cause_PR_misc) &&
       (ie->value.choice.Cause.choice.misc == X2AP_CauseMisc_unspecified)) {
-    X2AP_WARN("Received X2 setup failure for eNB ... eNB is not ready\n");
+    X2AP_ERROR("Received X2 setup failure for eNB ... eNB is not ready\n");
+    exit(1);
   } else {
     X2AP_ERROR("Received x2 setup failure for eNB... please check your parameters\n");
+    exit(1);
   }
 
   x2ap_eNB_data->state = X2AP_ENB_STATE_WAITING;
@@ -730,6 +748,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
                              X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true);
   if (ie == NULL ) {
     X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+    itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
     return -1;
   }
 
@@ -750,7 +769,11 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
                                                //measResultListEUTRA.list.array[ncell_index]->physCellId;
   X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest,
                              X2AP_ProtocolIE_ID_id_GUMMEI_ID, true);
-
+  if (ie == NULL ) {
+    X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+    itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
+    return -1;
+  }
   TBCD_TO_MCC_MNC(&ie->value.choice.ECGI.pLMN_Identity, X2AP_HANDOVER_REQ(msg).ue_gummei.mcc,
                   X2AP_HANDOVER_REQ(msg).ue_gummei.mnc, X2AP_HANDOVER_REQ(msg).ue_gummei.mnc_len);
   OCTET_STRING_TO_INT8(&ie->value.choice.GUMMEI.mME_Code, X2AP_HANDOVER_REQ(msg).ue_gummei.mme_code);
@@ -761,6 +784,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
 
   if (ie == NULL ) {
     X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+    itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
     return -1;
   }
 
@@ -872,6 +896,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
 
   if (ie == NULL ) {
     X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+    itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
     return -1;
   }
 
@@ -882,6 +907,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
 
   if (ie == NULL ) {
     X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+    itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
     return -1;
   }
 
@@ -912,6 +938,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
 
   if (ie == NULL ) {
     X2AP_ERROR("%s %d: ie is a NULL pointer \n", __FILE__, __LINE__);
+    itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
     return -1;
   }else{
     if (ie->value.choice.E_RABs_Admitted_List.list.count > 0) {
@@ -959,6 +986,12 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
   X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck,
                              X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true);
 
+  if (ie == NULL ) {
+    X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+    itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
+    return -1;
+  }
+
   X2AP_TargeteNBtoSource_eNBTransparentContainer_t *c = &ie->value.choice.TargeteNBtoSource_eNBTransparentContainer;
 
   if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s */)
@@ -1012,6 +1045,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance,
 
   if (ie == NULL ) {
     X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+    itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
     return -1;
   }
 
@@ -1022,6 +1056,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance,
 
   if (ie == NULL ) {
     X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+    itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
     return -1;
   }
 
diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c
index 4769380d187351786db5a36778efbe90b7a47912..0fe2741d7bd1f3bd9d3b3357b64e8d01a32ce807 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB.c
+++ b/openair3/GTPV1-U/gtpv1u_eNB.c
@@ -51,6 +51,7 @@
 #include "gtpv1u_eNB_defs.h"
 #include "gtpv1u_eNB_task.h"
 #include "rrc_eNB_GTPV1U.h"
+#include <common/utils/msc/msc.h>
 
 #undef GTP_DUMP_SOCKET
 
@@ -280,7 +281,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
             (ue_context_p->ue_context.handover_info->state < HO_FORWARDING_COMPLETE)) {
           if(msgType == NW_GTP_END_MARKER) {
             /* in the source enb, UE in RRC_HO_EXECUTION mode */
-            if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION && ue_context_p->ue_context.handover_info->state == HO_COMPLETE) {
+            if (ue_context_p->ue_context.StatusRrc == RRC_HO_EXECUTION && ue_context_p->ue_context.handover_info->state == HO_COMPLETE) {
               /* set handover state */
               //ue_context_p->ue_context.handover_info->state = HO_END_MARKER;
               MessageDef *msg;
@@ -298,17 +299,17 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
             }
           }
 
-          if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION || ue_context_p->ue_context.Status == RRC_RECONFIGURED) {
+          if (ue_context_p->ue_context.StatusRrc == RRC_HO_EXECUTION || ue_context_p->ue_context.StatusRrc == RRC_RECONFIGURED) {
             int msgsrc = gtpv1u_eNB_get_msgsource(ue_context_p, teid);
             LOG_D(GTPU,"UE INFO.ueStatus %d, handover state %d, forwarding state %d, from %s. message type %s\n",
-                  ue_context_p->ue_context.Status,
+                  ue_context_p->ue_context.StatusRrc,
                   ue_context_p->ue_context.handover_info->state,
                   ue_context_p->ue_context.handover_info->forwarding_state,
                   msgsrc == GTPV1U_MSG_FROM_SOURCE_ENB?"Source eNB":"EPC",
                   msgsrc != GTPV1U_MSG_FROM_SOURCE_ENB? "UDP DATA" :
                   msgType == NW_GTP_END_MARKER?"END MARKER":"DATA FORWARDING");
 
-            /* target enb */
+	    /* target enb */
             if(msgType == NW_GTP_END_MARKER) {
               LOG_I(GTPU, "target end receive END MARKER\n");
               ue_context_p->ue_context.handover_info->state = HO_END_MARKER;
@@ -1211,7 +1212,7 @@ int gtpv1u_eNB_init(void) {
   //gtpv1u_data_g.udp_data;
   RC.gtpv1u_data_g->seq_num         = 0;
   RC.gtpv1u_data_g->restart_counter = 0;
-
+  RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up = 0;
   /* Initializing GTPv1-U stack */
   if ((rc = nwGtpv1uInitialize(&RC.gtpv1u_data_g->gtpv1u_stack, GTPU_STACK_ENB)) != NW_GTPV1U_OK) {
     LOG_E(GTPU, "Failed to setup nwGtpv1u stack %x\n", rc);
@@ -1497,15 +1498,15 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) {
           stack_req.apiInfo.sendtoInfo.teid   = tenb_x2u_teid;
           stack_req.apiInfo.sendtoInfo.ipAddr = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr;// target enb ip
           rc = nwGtpv1uGpduMsgNew(
-                 RC.gtpv1u_data_g->gtpv1u_stack,
-                 tenb_x2u_teid,
-                 NW_FALSE,
-                 RC.gtpv1u_data_g->seq_num++,
-                 data_req_p->buffer,
-                 data_req_p->length,
-                 data_req_p->offset,
-                 &(stack_req.apiInfo.sendtoInfo.hMsg));
-
+				  RC.gtpv1u_data_g->gtpv1u_stack,
+				  tenb_x2u_teid,
+				  NW_FALSE,
+				  RC.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_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u",
@@ -1515,7 +1516,7 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) {
             pMsg = (NwGtpv1uMsgT *) stack_req.apiInfo.sendtoInfo.hMsg;
             pMsg->msgType = NW_GTP_END_MARKER;
             rc = nwGtpv1uProcessUlpReq(RC.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_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u",
@@ -1535,11 +1536,11 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) {
 
             rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack,
                                    stack_req.apiInfo.sendtoInfo.hMsg);
-
+	    
             if (rc != NW_GTPV1U_OK) {
               LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc);
             }
-
+	    
             gtpv1u_enb_delete_tunnel_req_t delete_tunnel_req;
             memset(&delete_tunnel_req, 0, sizeof(delete_tunnel_req));
             delete_tunnel_req.rnti = data_req_p->rnti;
@@ -1547,7 +1548,7 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) {
           }
         }
       }
-
+      
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_OUT);
     }
     break;
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/MME_APP/mme_app.c b/openair3/MME_APP/mme_app.c
index 5a32ddc98cc26ce390d5905dd20c5c698faffd85..57f1b4c9d239a8049effddd0dea6c671c8ed0735 100644
--- a/openair3/MME_APP/mme_app.c
+++ b/openair3/MME_APP/mme_app.c
@@ -54,7 +54,6 @@
 #   define X2AP_ENB_REGISTER_RETRY_DELAY   10
 
 #include "openair1/PHY/INIT/phy_init.h"
-extern unsigned char NB_MCE_INST;
 
 extern RAN_CONTEXT_t RC;
 
diff --git a/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c b/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c
index 8ac43cf7b13fd1c3e4c09a9c39db6e4649699c3d..637d930226dd5e61a79e5a914846d46940f58061 100644
--- a/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c
+++ b/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c
@@ -190,7 +190,6 @@ int decode_attach_accept(attach_accept_msg *attach_accept, uint8_t *buffer, uint
     default:
       errorCodeDecoder = TLV_DECODE_UNEXPECTED_IEI;
       LOG_TRACE(WARNING, "DECODE_UNEXPECTED_IEI %x (4 bits)", ieiDecoded);
-      AssertFatal(0, " ");
       return TLV_DECODE_UNEXPECTED_IEI;
     }
   }
diff --git a/openair3/NAS/COMMON/EMM/MSG/CsServiceNotification.h b/openair3/NAS/COMMON/EMM/MSG/CsServiceNotification.h
index c173d3b729319e275ac0e9779b7899ebd5a072c0..4bed349327326a15393fbf25ebbb57ccc398d689 100644
--- a/openair3/NAS/COMMON/EMM/MSG/CsServiceNotification.h
+++ b/openair3/NAS/COMMON/EMM/MSG/CsServiceNotification.h
@@ -26,7 +26,7 @@
 #include "ProtocolDiscriminator.h"
 #include "SecurityHeaderType.h"
 #include "MessageType.h"
-#include "PagingIdentity.h"
+#include "NasPagingIdentity.h"
 #include "Cli.h"
 #include "SsCode.h"
 #include "LcsIndicator.h"
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/COMMON/IES/FGSMobileIdentity.c b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c
index e3204b4c0c7816fee36eb029067162612b783b1f..5f920105f9b1307ff28d3761853dfbc13893b7c0 100644
--- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c
+++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c
@@ -194,23 +194,23 @@ static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_
 static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer)
 {
   uint32_t encoded = 0;
-  *(buffer + encoded) = 0x00 | (suci->supiformat << 4) | (suci->typeofidentity);
+  *(buffer + encoded) = (suci->supiformat << 4) | (suci->typeofidentity);
   encoded++;
-  *(buffer + encoded) = 0x00 | ((suci->mccdigit2 & 0xf) << 4) |
+  *(buffer + encoded) = ((suci->mccdigit2 & 0xf) << 4) |
                         (suci->mccdigit1 & 0xf);
   encoded++;
-  *(buffer + encoded) = 0x00 | ((suci->mncdigit3 & 0xf) << 4) |
+  *(buffer + encoded) = ((suci->mncdigit3 & 0xf) << 4) |
                         (suci->mccdigit3 & 0xf);
   encoded++;
-  *(buffer + encoded) = 0x00 | ((suci->mncdigit2 & 0xf) << 4) |
+  *(buffer + encoded) = ((suci->mncdigit2 & 0xf) << 4) |
                         (suci->mncdigit1 & 0xf);
   encoded++;
 
-  *(buffer + encoded) = 0x00 | ((suci->routingindicatordigit2 & 0xf) << 4) |
+  *(buffer + encoded) = ((suci->routingindicatordigit2 & 0xf) << 4) |
                         (suci->routingindicatordigit1 & 0xf);
   encoded++;
 
-  *(buffer + encoded) = 0x00 | ((suci->routingindicatordigit4 & 0xf) << 4) |
+  *(buffer + encoded) = ((suci->routingindicatordigit4 & 0xf) << 4) |
                         (suci->routingindicatordigit3 & 0xf);
   encoded++;
 
@@ -220,8 +220,15 @@ static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_
   *(buffer + encoded) = suci->homenetworkpki;
   encoded++;
 
-  IES_ENCODE_U32(buffer, encoded, suci->schemeoutput);
+  char *ptr=suci->schemeoutput;
+  while ( ptr < suci->schemeoutput+strlen(suci->schemeoutput) ) {
+    buffer[encoded]=((*(ptr+1)-'0')<<4) | (*(ptr) -'0');
+    encoded++;
+    ptr+=2;
+  }
 
+  if (strlen(suci->schemeoutput)%2 == 1)
+    buffer[encoded++]=((*(ptr-1)-'0')) | 0xF0;
   return encoded;
 }
 
diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.h b/openair3/NAS/COMMON/IES/FGSMobileIdentity.h
index a673a86dd1be7eea096edd0eaa603989d7e50951..7968bc33006c255f10fec598edacb78976050e58 100644
--- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.h
+++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.h
@@ -64,7 +64,7 @@ typedef struct {
   uint8_t  spare6:1;
   uint8_t  protectionschemeId:4;
   uint8_t  homenetworkpki;
-  uint32_t schemeoutput;
+  char schemeoutput[32];
 } Suci5GSMobileIdentity_t;
 
 typedef struct {
diff --git a/openair3/NAS/COMMON/IES/NasPagingIdentity.h b/openair3/NAS/COMMON/IES/NasPagingIdentity.h
new file mode 100644
index 0000000000000000000000000000000000000000..3e03128006781eef714dd5835963d0ac9f312278
--- /dev/null
+++ b/openair3/NAS/COMMON/IES/NasPagingIdentity.h
@@ -0,0 +1,43 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "OctetString.h"
+
+#ifndef NASPAGING_IDENTITY_H_
+#define NASPAGING_IDENTITY_H_
+
+#define PAGING_IDENTITY_MINIMUM_LENGTH 2
+#define PAGING_IDENTITY_MAXIMUM_LENGTH 2
+
+typedef uint8_t PagingIdentity;
+
+int encode_paging_identity(PagingIdentity *pagingidentity, uint8_t iei, uint8_t *buffer, uint32_t len);
+
+void dump_paging_identity_xml(PagingIdentity *pagingidentity, uint8_t iei);
+
+int decode_paging_identity(PagingIdentity *pagingidentity, uint8_t iei, uint8_t *buffer, uint32_t len);
+
+#endif /* PAGING IDENTITY_H_ */
+
diff --git a/openair3/NAS/COMMON/IES/SupportedCodecList.c b/openair3/NAS/COMMON/IES/SupportedCodecList.c
index 3a69eee366a82822fa5edb2da8c3e48db92ea54c..15a2fecaa02358cbc5fb7624e261727caa0ded30 100644
--- a/openair3/NAS/COMMON/IES/SupportedCodecList.c
+++ b/openair3/NAS/COMMON/IES/SupportedCodecList.c
@@ -43,13 +43,17 @@ int decode_supported_codec_list(SupportedCodecList *supportedcodeclist, uint8_t
   CHECK_LENGTH_DECODER(len - decoded, ielen);
   supportedcodeclist->systemidentification = *(buffer + decoded);
   decoded++;
+  ielen--;
   supportedcodeclist->lengthofbitmap = *(buffer + decoded);
   decoded++;
+  ielen--;
   //IES_DECODE_U16(supportedcodeclist->codecbitmap, *(buffer + decoded));
   IES_DECODE_U16(buffer, decoded, supportedcodeclist->codecbitmap);
+  ielen=ielen -2;
 #if defined (NAS_DEBUG)
   dump_supported_codec_list_xml(supportedcodeclist, iei);
 #endif
+  decoded = decoded + ielen;
   return decoded;
 }
 int encode_supported_codec_list(SupportedCodecList *supportedcodeclist, uint8_t iei, uint8_t *buffer, uint32_t len)
diff --git a/openair3/NAS/COMMON/NR_NAS_defs.h b/openair3/NAS/COMMON/NR_NAS_defs.h
index 906c0cf504a9d61059c509fc3c758e6605b81907..54ac8c037e9f3b672870ee6489dfb1e3e980ea5e 100644
--- a/openair3/NAS/COMMON/NR_NAS_defs.h
+++ b/openair3/NAS/COMMON/NR_NAS_defs.h
@@ -387,5 +387,6 @@ void processNAS(void *msg, NRUEcontext_t *UE);
 int identityRequest(void **msg, NRUEcontext_t *UE);
 int authenticationRequest(void **msg, NRUEcontext_t *UE);
 int securityModeCommand(void **msg, NRUEcontext_t *UE);
+void servingNetworkName(uint8_t *msg, char * imsiStr, int nmc_size);
 
 #endif
diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c
index 2c07de8dd5abfea1d460c0f0b09d5d672a724f80..c6992642e9ee67e5fe4ea5d2bd09b2a3aec427d4 100644
--- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c
+++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c
@@ -38,15 +38,15 @@
 #include "aka_functions.h"
 #include "secu_defs.h"
 #include "PduSessionEstablishRequest.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};
+#include "intertask_interface.h"
+#include "openair2/RRC/NAS/nas_config.h"
+#include <openair3/UICC/usim_interface.h>
+#include <openair3/NAS/COMMON/NR_NAS_defs.h>
+#include <openair1/PHY/phy_extern_nr_ue.h>
 
 uint8_t  *registration_request_buf;
 uint32_t  registration_request_len;
+extern char *baseNetAddress;
 
 static int nas_protected_security_header_encode(
   char                                       *buffer,
@@ -151,11 +151,11 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) {
   LOG_FUNC_RETURN (header_result + encode_result);
 }
 
-void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output) {
-  uint8_t S[100];
+void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output, uicc_t* uicc) {
+  uint8_t S[100]={0};
   S[0] = 0x6B;
-  int netNamesize = strlen(netName);
-  memcpy(&S[1], netName, netNamesize);
+  servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size);
+  int netNamesize = strlen((char*)S+1);
   S[1 + netNamesize] = (netNamesize & 0xff00) >> 8;
   S[2 + netNamesize] = (netNamesize & 0x00ff);
   for (int i = 0; i < 16; i++)
@@ -192,14 +192,15 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16
     output[i] = out[16 + i];
 }
 
-void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32]) {
-  uint8_t S[100];
+void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32], uicc_t *uicc) {
+  uint8_t S[100]={0};
   uint8_t key[32];
-  int netNamesize = strlen(netName);
+
   memcpy(&key[0], ck, 16);
   memcpy(&key[16], ik, 16);  //KEY
   S[0] = 0x6A;
-  memcpy(&S[1], netName, netNamesize);
+  servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size);
+  int netNamesize = strlen((char*)S+1);
   S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
   S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
   for (int i = 0; i < 6; i++) {
@@ -210,21 +211,21 @@ void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[
   kdf(key, 32, S, 11 + netNamesize, kausf, 32);
 }
 
-void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32]) {
-  uint8_t S[100];
-  int netNamesize = strlen(netName);
+void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], uicc_t *uicc) {
+  uint8_t S[100]={0};
   S[0] = 0x6C;  //FC
-  memcpy(&S[1], netName, netNamesize);
+  servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size);
+  int netNamesize = strlen((char*)S+1);
   S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
   S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
   kdf(kausf, 32, S, 3 + netNamesize, kseaf, 32);
 }
 
-void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba) {
-  int imsiLen = strlen(imsi);
+void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba, uicc_t* uicc) {
+  int imsiLen = strlen(uicc->imsiStr);
   uint8_t S[100];
   S[0] = 0x6D;  //FC = 0x6D
-  memcpy(&S[1], imsi, imsiLen);
+  memcpy(&S[1], uicc->imsiStr, imsiLen );
   S[1 + imsiLen] = (uint8_t)((imsiLen & 0xff00) >> 8);
   S[2 + imsiLen] = (uint8_t)(imsiLen & 0x00ff);
   S[3 + imsiLen] = abba & 0x00ff;
@@ -250,11 +251,11 @@ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t
     knas_int[i] = out[16 + i];
 }
 
-void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
+void generateRegistrationRequest(as_nas_info_t *initialNasMsg, int Mod_id) {
   int size = sizeof(mm_msg_header_t);
-  fgs_nas_message_t nas_msg;
-  memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
+  fgs_nas_message_t nas_msg={0};
   MM_msg *mm_msg;
+  uicc_t * uicc=checkUicc(Mod_id);
 
   mm_msg = &nas_msg.plain.mm_msg;
   // set header
@@ -273,32 +274,37 @@ 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.mncdigit3 = 0xf;
-    mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = 2;
-    mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = 0;
-    mm_msg->registration_request.fgsmobileidentity.guti.mccdigit3 = 8;
+    mm_msg->registration_request.fgsmobileidentity.guti.mncdigit1 =
+      uicc->nmc_size==2 ? uicc->imsiStr[3]-'0' :  uicc->imsiStr[4]-'0';
+    mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 =
+      uicc->nmc_size==2 ? uicc->imsiStr[4]-'0' :  uicc->imsiStr[5]-'0';
+    mm_msg->registration_request.fgsmobileidentity.guti.mncdigit3 =
+      uicc->nmc_size==2 ? 0xf : uicc->imsiStr[3]-'0';
+    mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = uicc->imsiStr[0]-'0';
+    mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = uicc->imsiStr[1]-'0';
+    mm_msg->registration_request.fgsmobileidentity.guti.mccdigit3 = uicc->imsiStr[2]-'0';
 
     size += 13;
 
   } 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.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;
-
-    size += 14;
+    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit1 =
+     uicc->nmc_size==2 ? uicc->imsiStr[3]-'0' :  uicc->imsiStr[4]-'0';
+    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit2 =
+      uicc->nmc_size==2 ? uicc->imsiStr[4]-'0' :  uicc->imsiStr[5]-'0';
+    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit3 =
+      uicc->nmc_size==2 ? 0xf : uicc->imsiStr[3]-'0';
+    mm_msg->registration_request.fgsmobileidentity.suci.mccdigit1 = uicc->imsiStr[0]-'0';
+    mm_msg->registration_request.fgsmobileidentity.suci.mccdigit2 = uicc->imsiStr[1]-'0';
+    mm_msg->registration_request.fgsmobileidentity.suci.mccdigit3 = uicc->imsiStr[2]-'0';
+    memcpy(mm_msg->registration_request.fgsmobileidentity.suci.schemeoutput, uicc->imsiStr+3+uicc->nmc_size, strlen(uicc->imsiStr) - (3+uicc->nmc_size));
+    size += sizeof(Suci5GSMobileIdentity_t);
   }
 
   mm_msg->registration_request.presencemask |= REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT;
@@ -325,7 +331,7 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
 
 }
 
-void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype) {
+void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype, uicc_t* uicc) {
   int size = sizeof(mm_msg_header_t);
   fgs_nas_message_t nas_msg;
   memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
@@ -347,15 +353,17 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
   size += 1;
   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.mncdigit3 = 0xf;
-    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit1 = 2;
-    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit2 = 0;
-    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit3 = 8;
-    mm_msg->fgs_identity_response.fgsmobileidentity.suci.schemeoutput = 0x4778;
-
-    size += 14;
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit1 =
+      uicc->nmc_size==2 ? uicc->imsiStr[3]-'0' :  uicc->imsiStr[4]-'0';
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit2 =
+      uicc->nmc_size==2 ? uicc->imsiStr[4]-'0' :  uicc->imsiStr[5]-'0';
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit3 =
+      uicc->nmc_size==2? 0xF : uicc->imsiStr[3]-'0';
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit1 = uicc->imsiStr[0]-'0';
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit2 = uicc->imsiStr[1]-'0';
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit3 = uicc->imsiStr[2]-'0';
+    memcpy(mm_msg->registration_request.fgsmobileidentity.suci.schemeoutput, uicc->imsiStr+3+uicc->nmc_size, strlen(uicc->imsiStr) - (3+uicc->nmc_size));
+    size += sizeof(Suci5GSMobileIdentity_t);
   }
 
   // encode the message
@@ -366,7 +374,7 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
 }
 
 OctetString knas_int;
-void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){
+static void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf, uicc_t *uicc){
 
   uint8_t ak[6];
 
@@ -384,9 +392,9 @@ void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){
 
   uint8_t resTemp[16];
   uint8_t ck[16], ik[16], output[16];
-  f2345(k, rand, resTemp, ck, ik, ak, opc);
+  f2345(uicc->key, rand, resTemp, ck, ik, ak, uicc->opc);
 
-  transferRES(ck, ik, resTemp, rand, output);
+  transferRES(ck, ik, resTemp, rand, output, uicc);
 
   // get knas_int
   knas_int.length = 16;
@@ -395,9 +403,9 @@ void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){
     sqn[index] = buf[26+index];
   }
 
-  derive_kausf(ck, ik, sqn, kausf);
-  derive_kseaf(kausf, kseaf);
-  derive_kamf(kseaf, kamf, 0x0000);
+  derive_kausf(ck, ik, sqn, kausf, uicc);
+  derive_kseaf(kausf, kseaf, uicc);
+  derive_kamf(kseaf, kamf, 0x0000, uicc);
   derive_knas(0x02, 2, kamf, knas_int.value);
 
   printf("kausf:");
@@ -457,7 +465,7 @@ void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){
   initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
 }
 
-void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
+static void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
 {
   int size = sizeof(mm_msg_header_t);
   fgs_nas_message_t nas_msg;
@@ -524,7 +532,7 @@ void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
   }
 }
 
-void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer               *sortransparentcontainer) {
+static void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer               *sortransparentcontainer) {
   //wait send RRCReconfigurationComplete and InitialContextSetupResponse
   sleep(1);
   int length = 0;
@@ -604,22 +612,35 @@ void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentCo
   }
 }
 
-void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){
+void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t * pdu_buffer){
+  uint8_t msg_type = *(pdu_buffer + 16);
+  if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){
+    sprintf(baseNetAddress, "%d.%d", *(pdu_buffer + 39),*(pdu_buffer + 40));
+    int third_octet = *(pdu_buffer + 41);
+    int fourth_octet = *(pdu_buffer + 42);
+    LOG_I(NAS, "Received PDU Session Establishment Accept\n");
+    nas_config(1,third_octet,fourth_octet,"ue");
+  } else {
+    LOG_E(NAS, "Received unexpected message in DLinformationTransfer %d\n", msg_type);
+  }
+}
+
+static void generatePduSessionEstablishRequest(uicc_t * uicc, as_nas_info_t *initialNasMsg){
   //wait send RegistrationComplete
   usleep(100*150);
   int size = 0;
-  fgs_nas_message_t nas_msg;
-  memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
+  fgs_nas_message_t nas_msg={0};
 
   // 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 +648,6 @@ 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
   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;
@@ -659,11 +677,21 @@ void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){
   mm_msg->uplink_nas_transport.requesttype = 1;
   size += 3;
   mm_msg->uplink_nas_transport.snssai.length = 4;
-  mm_msg->uplink_nas_transport.snssai.value = nssai;
+  //Fixme: it seems there are a lot of memory errors in this: this value was on the stack, 
+  // but pushed  in a itti message to another thread
+  // this kind of error seems in many places in 5G NAS
+  mm_msg->uplink_nas_transport.snssai.value=calloc(1,4);
+  mm_msg->uplink_nas_transport.snssai.value[0] = uicc->nssai_sst;
+  mm_msg->uplink_nas_transport.snssai.value[1] = (uicc->nssai_sd>>16)&0xFF;
+  mm_msg->uplink_nas_transport.snssai.value[2] = (uicc->nssai_sd>>8)&0xFF; 
+  mm_msg->uplink_nas_transport.snssai.value[3] = (uicc->nssai_sd)&0xFF;
   size += (1+1+4);
-  mm_msg->uplink_nas_transport.dnn.length = 9;
-  mm_msg->uplink_nas_transport.dnn.value = dnn;
-  size += (1+1+9);
+  int dnnSize=strlen(uicc->dnnStr);
+  mm_msg->uplink_nas_transport.dnn.value=calloc(1,dnnSize+1);
+  mm_msg->uplink_nas_transport.dnn.length = dnnSize + 1;
+  mm_msg->uplink_nas_transport.dnn.value[0] = dnnSize + 1;
+  memcpy(mm_msg->uplink_nas_transport.dnn.value+1,uicc->dnnStr, dnnSize);
+  size += (1+1+dnnSize+1);
 
   // encode the message
   initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
@@ -690,3 +718,215 @@ 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 ;
+      uicc_t *uicc=checkUicc(Mod_id);
+
+      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(uicc, &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");
+          }
+        }
+        else if((pdu_buffer + 16) != NULL){
+          msg_type = *(pdu_buffer + 16);
+          if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){
+            sprintf(baseNetAddress, "%d.%d", *(pdu_buffer + 39),*(pdu_buffer + 40));
+            int third_octet = *(pdu_buffer + 41);
+            int fourth_octet = *(pdu_buffer + 42);
+            LOG_I(NAS, "Received PDU Session Establishment Accept\n");
+            nas_config(1,third_octet,fourth_octet,"ue");
+          }
+        }
+
+        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={0};
+
+        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), uicc);
+              break;
+          case FGS_AUTHENTICATION_REQUEST:
+	            generateAuthenticationResp(&initialNasMsg, pdu_buffer, uicc);
+              break;
+          case FGS_SECURITY_MODE_COMMAND:
+            generateSecurityModeComplete(&initialNasMsg);
+            break;
+          case FGS_DOWNLINK_NAS_TRANSPORT:
+            decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer);
+            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..753ebf1762d4351064627ed882c70c3ce5d98962 100644
--- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h
+++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h
@@ -56,9 +56,11 @@
 #define FGS_SECURITY_MODE_COMMAND                          0b01011101 /* 93 = 0x5d */
 #define FGS_SECURITY_MODE_COMPLETE                         0b01011110 /* 94 = 0x5e */
 #define FGS_UPLINK_NAS_TRANSPORT                           0b01100111 /* 103= 0x67 */
+#define FGS_DOWNLINK_NAS_TRANSPORT                         0b01101000 /* 104= 0x68 */
 
 // message type for 5GS session management
 #define FGS_PDU_SESSION_ESTABLISHMENT_REQ                  0b11000001 /* 193= 0xc1 */
+#define FGS_PDU_SESSION_ESTABLISHMENT_ACC                  0b11000010 /* 194= 0xc2 */
 
 #define INITIAL_REGISTRATION                               0b001
 
@@ -114,12 +116,8 @@ typedef union {
   fgs_nas_message_plain_t plain;
 } fgs_nas_message_t;
 
-void generateRegistrationRequest(as_nas_info_t *initialNasMsg);
-void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype);
-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 generateRegistrationRequest(as_nas_info_t *initialNasMsg, int Mod_id);
+void *nas_nrue_task(void *args_p);
 
 #endif /* __NR_NAS_MSG_SIM_H__*/
 
diff --git a/openair3/NAS/TOOLS/ue_sim_ci.conf b/openair3/NAS/TOOLS/ue_sim_ci.conf
new file mode 100644
index 0000000000000000000000000000000000000000..5d95c9ba3f182497836948f5c872071f678b4228
--- /dev/null
+++ b/openair3/NAS/TOOLS/ue_sim_ci.conf
@@ -0,0 +1,45 @@
+# List of known PLMNS
+PLMN: {
+    PLMN0: {
+           FULLNAME="OpenAirInterface";
+           SHORTNAME="OAICN";
+           MNC="96";
+           MCC="208";
+    };
+};
+
+UE0:
+{
+    USER: {
+        IMEI="356113022094149";
+        MANUFACTURER="OAI";
+        MODEL="LTE SoftModem";
+        PIN="0000";
+    };
+
+    SIM: {
+        MSIN="0100001111";
+        USIM_API_K="8baf473f2f8fd09487cccbd7097c6862";
+        OPC="e734f8734007d6c5ce7a0508809e7e9c";
+        MSISDN="33611123456";
+    };
+
+    # Home PLMN Selector with Access Technology
+    HPLMN= "20896";
+
+    # User controlled PLMN Selector with Access Technology
+    UCPLMN_LIST = ();
+
+    # Operator PLMN List
+    OPLMN_LIST = ("20896");
+
+    # Operator controlled PLMN Selector with Access Technology
+    OCPLMN_LIST = ();
+
+    # Forbidden plmns
+    FPLMN_LIST = ();
+
+    # Equivalent home plmns
+    EHPLMN_LIST = ();
+
+};
diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c
index 99a3763dea30efa3df76113fc35dcf447457845f..10b118eac0315e338e282ef192ed7397dcb6e538 100644
--- a/openair3/NAS/UE/EMM/SAP/emm_as.c
+++ b/openair3/NAS/UE/EMM/SAP/emm_as.c
@@ -443,14 +443,14 @@ static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm
                    EPS_MOBILITY_MANAGEMENT_MESSAGE) {
           /* Process EMM data */
           rc = _emm_as_recv(user, plain_msg, bytes, emm_cause);
+          free(plain_msg);
         } else if (header.protocol_discriminator ==
                    EPS_SESSION_MANAGEMENT_MESSAGE) {
           const OctetString data = {bytes, (uint8_t *)plain_msg};
           /* Foward ESM data to EPS session management */
           rc = lowerlayer_data_ind(user, &data);
+          free(plain_msg);
         }
-
-        free(plain_msg);
       }
     } else {
       /* Process successfull lower layer transfer indication */
diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c
index 67bfaf784e63bad0b37e960d662d7ef7693f310a..b27270fadc43fd89ed7d59d1742b792a30ca953a 100644
--- a/openair3/NAS/UE/EMM/SecurityModeControl.c
+++ b/openair3/NAS/UE/EMM/SecurityModeControl.c
@@ -296,16 +296,16 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
     else {
       /* Setup EMM cause code */
       emm_cause = EMM_CAUSE_SECURITY_MODE_REJECTED;
-
-      /* Release security mode control internal data */
-      if (security_data->kenb.value) {
-        free(security_data->kenb.value);
-        security_data->kenb.value = NULL;
-        security_data->kenb.length = 0;
-      }
     }
   }
 
+  /* Release security mode control internal data */
+  if (security_data->kenb.value) {
+    free(security_data->kenb.value);
+    security_data->kenb.value = NULL;
+    security_data->kenb.length = 0;
+  }
+
   /* Setup EMM procedure handler to be executed upon receiving
    * lower layer notification */
   rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL);
diff --git a/openair3/NAS/UE/nas_parser.c b/openair3/NAS/UE/nas_parser.c
index beba47f64a89096557e4fa941c15e308c337dd4e..94c61b654cab2423fbceefc0476060bb37f27f9f 100644
--- a/openair3/NAS/UE/nas_parser.c
+++ b/openair3/NAS/UE/nas_parser.c
@@ -86,10 +86,7 @@ static parser_command_line_t nasParserCommandLine = {
       "-trace", "<mask>", "Logging trace level\t\t",
       NAS_PARSER_DEFAULT_TRACE_LEVEL
     },
-    {
-      "-uhost", "<uhost>", "User app layer's hostname\t",
-      NAS_PARSER_DEFAULT_USER_HOSTNAME
-    },
+    {"-uhost", "<uhost>", "User app layer's hostname\t", "NULL"},
     {
       "-nhost", "<nhost>", "Network layer's hostname\t",
       NAS_PARSER_DEFAULT_NETWORK_HOSTNAME
diff --git a/openair3/NAS/UE/nas_parser.h b/openair3/NAS/UE/nas_parser.h
index 0924654e3fb84f9d7d82f9ef192f364e2d6333fc..1c97dbdaf1dacb3ab6712c243010240a6edd0610 100644
--- a/openair3/NAS/UE/nas_parser.h
+++ b/openair3/NAS/UE/nas_parser.h
@@ -55,7 +55,7 @@ Description NAS command line parser
 #define NAS_PARSER_DEFAULT_UE_ID        "1"
 
 /* User application layer default hostname */
-#define NAS_PARSER_DEFAULT_USER_HOSTNAME    "localhost"
+#define NAS_PARSER_DEFAULT_USER_HOSTNAME    NULL
 
 /* User application layer default port number */
 #define NAS_PARSER_DEFAULT_USER_PORT_NUMBER "10000"
diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c
index 178f21a44a12fd54d47822d5df6d3978a7f554c1..be887623bb56e49abaa0b17114c6032e67a1f260 100644
--- a/openair3/NAS/UE/nas_ue_task.c
+++ b/openair3/NAS/UE/nas_ue_task.c
@@ -33,6 +33,7 @@
 # include "memory.h"
 
 #include "nas_user.h"
+#include <common/utils/msc/msc.h>
 
 // FIXME make command line option for NAS_UE_AUTOSTART
 # define NAS_UE_AUTOSTART 1
diff --git a/openair3/NGAP/ngap_common.h b/openair3/NGAP/ngap_common.h
index f0302a88c77a135fc94257940a9a9a1a749bbd65..283dd2bffa58ae41aca733b9a955053f04bb0bf1 100644
--- a/openair3/NGAP/ngap_common.h
+++ b/openair3/NGAP/ngap_common.h
@@ -142,9 +142,12 @@ 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) {\
+      NGAP_ERROR("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL (searching for ie: %ld)\n",__FILE__,__LINE__, IE_ID);\
+      abort();\
+      }\
+      else NGAP_INFO("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL (searching for ie: %ld)\n",__FILE__,__LINE__, IE_ID);\
     } \
-    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..401695473cfc044c16baa9912e977b16711f2a56 100644
--- a/openair3/NGAP/ngap_gNB_handlers.c
+++ b/openair3/NGAP/ngap_gNB_handlers.c
@@ -657,6 +657,7 @@ int ngap_gNB_handle_error_indication(uint32_t         assoc_id,
           case NGAP_CauseRadioNetwork_up_integrity_protection_not_possible:
             NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_up_integrity_protection_not_possible\n");
             break;
+
           case NGAP_CauseRadioNetwork_up_confidentiality_protection_not_possible:
             NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_up_confidentiality_protection_not_possible\n");
             break;
@@ -1030,6 +1031,12 @@ int ngap_gNB_handle_initial_context_request(uint32_t   assoc_id,
                 
                 /* Set the QOS informations */
                 NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
+                if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){
+                  if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){
+                    NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].fiveQI =
+                        (uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI;
+                  }
+                }
               
                 NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.priority_level =
                   qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP;
@@ -1061,13 +1068,33 @@ 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_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_WARN("AllowedNSSAI not present, forging 2 NSSAI\n");
+
+    	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_INFO("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count);
     NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_allowed_nssais = ie->value.choice.AllowedNSSAI.list.count;
     
     for(i = 0; i < ie->value.choice.AllowedNSSAI.list.count; i++) {
@@ -1082,9 +1109,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..6686f8c19e0ae5d0584b8dc7698318e3be8015b3 100644
--- a/openair3/NGAP/ngap_gNB_nas_procedures.c
+++ b/openair3/NGAP/ngap_gNB_nas_procedures.c
@@ -656,6 +656,7 @@ int ngap_gNB_initial_ctxt_resp(
   NGAP_InitialContextSetupResponse_t    *out;
   NGAP_InitialContextSetupResponseIEs_t *ie;
   uint8_t  *buffer = NULL;
+  uint8_t pdusessionTransfer_buffer[1000];
   uint32_t length;
   int      i;
   asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
@@ -729,7 +730,8 @@ int ngap_gNB_initial_ctxt_resp(
       pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t));
 
       pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel;
-     
+    
+      pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel = (NGAP_GTPTunnel_t *)calloc(1, sizeof(NGAP_GTPTunnel_t)); 
       GTP_TEID_TO_ASN1(initial_ctxt_resp_p->pdusessions[i].gtp_teid, &pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->gTP_TEID);
 
       pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf = malloc(initial_ctxt_resp_p->pdusessions[i].gNB_addr.length);
@@ -757,17 +759,29 @@ int ngap_gNB_initial_ctxt_resp(
         ass_qos_item_p->qosFlowIdentifier = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qfi;
 
         /* qosFlowMappingIndication */
-        if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) {
-          ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication));
-          *ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind;
-        }
+        //if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) {
+        //  ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication));
+        //  *ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind;
+        // }
         ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p);
       }
                
-      memset(&res, 0, sizeof(res));
-      res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
-      item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer;
-      item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded;
+      //res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
+      //item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer;
+      //item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded;
+
+      if (asn1_xer_print) {
+        xer_fprint(stdout, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
+      }
+
+      memset(pdusessionTransfer_buffer, 0, 1000);
+      asn_enc_rval_t  enc_rval = aper_encode_to_buffer(&asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, 
+          NULL, 
+          pdusessionTransfer_p, 
+          pdusessionTransfer_buffer,1000);
+      AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
+      item->pDUSessionResourceSetupResponseTransfer.buf = pdusessionTransfer_buffer; 
+      item->pDUSessionResourceSetupResponseTransfer.size = enc_rval.encoded;
 
       ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
     
@@ -784,16 +798,14 @@ int ngap_gNB_initial_ctxt_resp(
     ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_PDUSessionResourceFailedToSetupListCxtRes;
 
     for (i = 0; i < initial_ctxt_resp_p->nb_of_pdusessions_failed; i++) {
-        NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t *item;
-        NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *pdusessionUnTransfer_p = NULL;
+        NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t *item= calloc(1, sizeof *item);
+        NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *pdusessionUnTransfer_p = calloc(1, sizeof *pdusessionUnTransfer_p);
     
-        /* mandatory */
-        item = (NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t));
         /* pDUSessionID */
         item->pDUSessionID = initial_ctxt_resp_p->pdusessions_failed[i].pdusession_id;
 
         /* cause */
-        pdusessionUnTransfer_p = (NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t));
+
         pdusessionUnTransfer_p->cause.present = initial_ctxt_resp_p->pdusessions_failed[i].cause;
         switch(pdusessionUnTransfer_p->cause.present) {
           case NGAP_Cause_PR_radioNetwork:
@@ -846,6 +858,10 @@ int ngap_gNB_initial_ctxt_resp(
     ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
   }
 
+  if (asn1_xer_print) {
+    xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, &pdu);
+  }
+
   if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) {
     NGAP_ERROR("Failed to encode InitialContextSetupResponse\n");
     /* Encode procedure has failed... */
@@ -932,7 +948,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;
@@ -973,8 +989,6 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance,
   NGAP_PDUSessionResourceSetupResponseIEs_t *ie;
   uint8_t  *buffer  = NULL;
   uint32_t length;
-  int      i;
-  asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
 
   /* Retrieve the NGAP gNB instance associated with Mod_id */
   ngap_gNB_instance_p = ngap_gNB_get_instance(instance);
@@ -1003,20 +1017,20 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance,
   /* Prepare the NGAP message to encode */
   memset(&pdu, 0, sizeof(pdu));
   pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome;
-  pdu.choice.successfulOutcome = (NGAP_SuccessfulOutcome_t *)calloc(1,sizeof(struct NGAP_SuccessfulOutcome));
+  pdu.choice.successfulOutcome = calloc(1,sizeof *pdu.choice.successfulOutcome);
   pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceSetup;
   pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject;
   pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceSetupResponse;
   out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceSetupResponse;
   /* mandatory */
-  ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t));
+  ie = calloc(1, sizeof *ie);
   ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
   ie->criticality = NGAP_Criticality_ignore;
   ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_AMF_UE_NGAP_ID;
   asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id);
   ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
   /* mandatory */
-  ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t));
+  ie = calloc(1, sizeof *ie );
   ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
   ie->criticality = NGAP_Criticality_ignore;
   ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_RAN_UE_NGAP_ID;
@@ -1025,23 +1039,19 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance,
 
   /* optional */
   if (pdusession_setup_resp_p->nb_of_pdusessions > 0) {
-    ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t));
+    ie = calloc(1, sizeof *ie );
     ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSURes;
     ie->criticality = NGAP_Criticality_ignore;
     ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_PDUSessionResourceSetupListSURes;
 
-    for (i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions; i++) {
-      NGAP_PDUSessionResourceSetupItemSURes_t *item;
-      NGAP_PDUSessionResourceSetupResponseTransfer_t     *pdusessionTransfer_p = NULL;
-
-      /* mandatory */
-      item = (NGAP_PDUSessionResourceSetupItemSURes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupItemSURes_t));
+    for (int i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions; i++) {
+      NGAP_PDUSessionResourceSetupItemSURes_t *item=calloc(1, sizeof *item );
+      NGAP_PDUSessionResourceSetupResponseTransfer_t *pdusessionTransfer_p = calloc(1, sizeof *pdusessionTransfer_p );
 
       /* pDUSessionID */
       item->pDUSessionID = pdusession_setup_resp_p->pdusessions[i].pdusession_id;
 
       /* dLQosFlowPerTNLInformation */
-      pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t));
 
       pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel;
       pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel =
@@ -1067,8 +1077,7 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance,
 
       /* associatedQosFlowList. number of 1? */
       for(int j=0; j < pdusession_setup_resp_p->pdusessions[i].nb_of_qos_flow; j++) {
-        NGAP_AssociatedQosFlowItem_t *ass_qos_item_p;
-        ass_qos_item_p = (NGAP_AssociatedQosFlowItem_t *)calloc(1, sizeof(NGAP_AssociatedQosFlowItem_t));
+        NGAP_AssociatedQosFlowItem_t *ass_qos_item_p = calloc(1, sizeof *ass_qos_item_p);
 
         /* qosFlowIdentifier */
         ass_qos_item_p->qosFlowIdentifier = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qfi;
@@ -1081,18 +1090,11 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance,
         ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p);
       }
 
-      memset(&res, 0, sizeof(res));
-//      res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
-//      item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer;
-//      item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded;
-      uint8_t buffer[100];
-      asn_enc_rval_t  enc_rval = aper_encode_to_buffer(&asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, 
-                                  NULL, 
-                                  pdusessionTransfer_p, 
-                                  buffer,100);
-      AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
-      item->pDUSessionResourceSetupResponseTransfer.buf = buffer;
-      item->pDUSessionResourceSetupResponseTransfer.size = enc_rval.encoded;
+      asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER,
+								       &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
+      AssertFatal (res.buffer, "ASN1 message encoding failed (%s, %lu)!\n", res.result.failed_type->name, res.result.encoded);
+      item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer;
+      item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded;
 
       ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
 
@@ -1103,22 +1105,20 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance,
 
   /* optional */
   if (pdusession_setup_resp_p->nb_of_pdusessions_failed > 0) {
-    ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t));
+    ie = calloc(1, sizeof *ie);
     ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToSetupListSURes;
     ie->criticality = NGAP_Criticality_ignore;
     ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_PDUSessionResourceFailedToSetupListSURes;
 
-    for (i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions_failed; i++) {
-      NGAP_PDUSessionResourceFailedToSetupItemSURes_t *item;
-      NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *pdusessionUnTransfer_p = NULL;
+    for (int i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions_failed; i++) {
+      LOG_W(NGAP,"add a failed session\n");
+      NGAP_PDUSessionResourceFailedToSetupItemSURes_t *item=calloc(1, sizeof *item);
+      NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *pdusessionUnTransfer_p = calloc(1, sizeof *pdusessionUnTransfer_p);
 
-      /* mandatory */
-      item = (NGAP_PDUSessionResourceFailedToSetupItemSURes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceFailedToSetupItemSURes_t));
       /* pDUSessionID */
       item->pDUSessionID = pdusession_setup_resp_p->pdusessions_failed[i].pdusession_id;
 
       /* cause */
-      pdusessionUnTransfer_p = (NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t));
       pdusessionUnTransfer_p->cause.present = pdusession_setup_resp_p->pdusessions_failed[i].cause;
       switch(pdusessionUnTransfer_p->cause.present) {
         case NGAP_Cause_PR_radioNetwork:
@@ -1148,8 +1148,9 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance,
 
       NGAP_DEBUG("pdusession setup response: failed pdusession ID %ld\n", item->pDUSessionID);
 
-      memset(&res, 0, sizeof(res));
-      res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p);
+     asn_encode_to_new_buffer_result_t res =
+	       asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER,
+				  &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p);     
       item->pDUSessionResourceSetupUnsuccessfulTransfer.buf = res.buffer;
       item->pDUSessionResourceSetupUnsuccessfulTransfer.size = res.result.encoded;
 
@@ -1163,7 +1164,7 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance,
 
   /* optional */
   if (0) {
-      ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t));
+    ie = calloc(1, sizeof *ie);
       ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics;
       ie->criticality = NGAP_Criticality_ignore;
       ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_CriticalityDiagnostics;
diff --git a/openair3/S1AP/s1ap_common.h b/openair3/S1AP/s1ap_common.h
index 77d03f4ae4b099471155dc774a208e432303d888..efac0201a31feaa1aa5dd5380e6ab5dcb7f2dd56 100644
--- a/openair3/S1AP/s1ap_common.h
+++ b/openair3/S1AP/s1ap_common.h
@@ -106,7 +106,12 @@ extern int asn1_xer_print;
     if (ie == NULL ) { \
       S1AP_ERROR("S1AP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\
     } \
-    if (mandatory)  DevAssert(ie != NULL); \
+    if (mandatory) { \
+      if (ie == NULL) { \
+        S1AP_ERROR("S1AP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\
+        return -1; \
+      } \
+    } \
   } while(0)
 /** \brief Function callback prototype.
  **/
diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c
index 31ea3359da1829217bb01c48103f34d18df6d058..e528c9e53eb4e87ca439deb2217a87d2a51710b4 100644
--- a/openair3/S1AP/s1ap_eNB.c
+++ b/openair3/S1AP/s1ap_eNB.c
@@ -73,6 +73,42 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
 
 void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
 
+static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p,
+                         s1ap_eNB_mme_data_t *s1ap_mme_data_p);
+void s1ap_eNB_timer_expired(instance_t                 instance,
+                            timer_has_expired_t   *msg_p);
+
+int s1ap_timer_setup(
+  uint32_t      interval_sec,
+  uint32_t      interval_us,
+  task_id_t     task_id,
+  int32_t       instance,
+  uint32_t      timer_kind,
+  timer_type_t  type,
+  void         *timer_arg,
+  long         *timer_id)
+{
+  uint32_t *timeoutArg=NULL;
+  int ret=0;
+  timeoutArg=malloc(sizeof(uint32_t));
+  *timeoutArg=timer_kind;
+  ret=timer_setup(interval_sec,
+                interval_us,
+                task_id,
+                instance,
+                type,
+                (void*)timeoutArg,
+                timer_id);
+  return ret;
+}
+
+int s1ap_timer_remove(long timer_id)
+{
+  int ret;
+  ret=timer_remove(timer_id);
+  return ret;
+}
+
 uint32_t s1ap_generate_eNB_id(void) {
   char    *out;
   char     hostname[50];
@@ -98,7 +134,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
   MessageDef                 *message_p                   = NULL;
   sctp_new_association_req_t *sctp_new_association_req_p  = NULL;
   s1ap_eNB_mme_data_t        *s1ap_mme_data_p             = NULL;
-  struct s1ap_eNB_mme_data_s *mme                         = NULL;
+//  struct s1ap_eNB_mme_data_s *mme                         = NULL;
   DevAssert(instance_p != NULL);
   DevAssert(mme_ip_address != NULL);
   message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_NEW_ASSOCIATION_REQ);
@@ -114,51 +150,32 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
          local_ip_addr,
          sizeof(*local_ip_addr));
   S1AP_INFO("[eNB %ld] check the mme registration state\n",instance_p->instance);
-  mme = NULL;
-
-  if ( mme == NULL ) {
-    /* Create new MME descriptor */
-    s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p));
-    DevAssert(s1ap_mme_data_p != NULL);
-    s1ap_mme_data_p->cnx_id                = s1ap_eNB_fetch_add_global_cnx_id();
-    sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
-    s1ap_mme_data_p->assoc_id          = -1;
-    s1ap_mme_data_p->broadcast_plmn_num = broadcast_plmn_num;
-    memcpy(&s1ap_mme_data_p->mme_s1_ip,
-    	   mme_ip_address,
-    	   sizeof(*mme_ip_address));
-    s1ap_mme_data_p->mme_port = mme_port;
-    for (int i = 0; i < broadcast_plmn_num; ++i)
-      s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i];
-
-    s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
-    STAILQ_INIT(&s1ap_mme_data_p->served_gummei);
-    /* Insert the new descriptor in list of known MME
-     * but not yet associated.
-     */
-    RB_INSERT(s1ap_mme_map, &instance_p->s1ap_mme_head, s1ap_mme_data_p);
-    s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING;
-    instance_p->s1ap_mme_nb ++;
-    instance_p->s1ap_mme_pending_nb ++;
-  } else if (mme->state == S1AP_ENB_STATE_WAITING) {
-    instance_p->s1ap_mme_pending_nb ++;
-    sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id;
-    S1AP_INFO("[eNB %ld] MME already registered, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
-              instance_p->instance,
-              mme->state, mme->cnx_id,
-              instance_p->s1ap_mme_nb, instance_p->s1ap_mme_pending_nb);
-    /*s1ap_mme_data_p->cnx_id                = mme->cnx_id;
-    sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id;
-
-    s1ap_mme_data_p->assoc_id          = -1;
-    s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
-    */
-  } else {
-    S1AP_WARN("[eNB %ld] MME already registered but not in the waiting state, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
-              instance_p->instance,
-              mme->state, mme->cnx_id,
-              instance_p->s1ap_mme_nb, instance_p->s1ap_mme_pending_nb);
-  }
+  /* Create new MME descriptor */
+  s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p));
+  DevAssert(s1ap_mme_data_p != NULL);
+  s1ap_mme_data_p->cnx_id                = s1ap_eNB_fetch_add_global_cnx_id();
+  sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
+  s1ap_mme_data_p->assoc_id          = -1;
+  s1ap_mme_data_p->broadcast_plmn_num = broadcast_plmn_num;
+  memcpy(&s1ap_mme_data_p->mme_s1_ip,
+         mme_ip_address,
+         sizeof(*mme_ip_address));
+  s1ap_mme_data_p->mme_port = mme_port;
+  for (int i = 0; i < broadcast_plmn_num; ++i)
+    s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i];
+
+  s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
+  STAILQ_INIT(&s1ap_mme_data_p->served_gummei);
+  /* Insert the new descriptor in list of known MME
+   * but not yet associated.
+   */
+  RB_INSERT(s1ap_mme_map, &instance_p->s1ap_mme_head, s1ap_mme_data_p);
+  s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED;
+  memcpy( &(s1ap_mme_data_p->mme_ip_address), mme_ip_address, sizeof(net_ip_address_t) );
+  s1ap_mme_data_p->overload_state = S1AP_NO_OVERLOAD;
+  s1ap_mme_data_p->sctp_req_cnt++;
+  s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT;
+  instance_p->s1ap_mme_pending_nb ++;
 
   itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
 }
@@ -196,10 +213,10 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
     new_instance->eNB_id           = s1ap_register_eNB->eNB_id;
     new_instance->cell_type        = s1ap_register_eNB->cell_type;
     new_instance->tac              = s1ap_register_eNB->tac;
-    
+
     memcpy(&new_instance->eNB_s1_ip,
-	   &s1ap_register_eNB->enb_ip_address,
-	   sizeof(s1ap_register_eNB->enb_ip_address));
+       &s1ap_register_eNB->enb_ip_address,
+       sizeof(s1ap_register_eNB->enb_ip_address));
 
     for (int i = 0; i < s1ap_register_eNB->num_plmn; i++) {
       new_instance->mcc[i]              = s1ap_register_eNB->mcc[i];
@@ -207,6 +224,15 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
       new_instance->mnc_digit_length[i] = s1ap_register_eNB->mnc_digit_length[i];
     }
 
+    memcpy( &(new_instance->enb_ip_address), &(s1ap_register_eNB->enb_ip_address), sizeof(net_ip_address_t) );
+    new_instance->s1_setuprsp_wait_timer = s1ap_register_eNB->s1_setuprsp_wait_timer;
+    new_instance->s1_setupreq_wait_timer = s1ap_register_eNB->s1_setupreq_wait_timer;
+    new_instance->s1_setupreq_count = s1ap_register_eNB->s1_setupreq_count;
+    new_instance->sctp_req_timer = s1ap_register_eNB->sctp_req_timer;
+    new_instance->sctp_req_count = s1ap_register_eNB->sctp_req_count;
+    new_instance->sctp_in_streams = s1ap_register_eNB->sctp_in_streams;
+    new_instance->sctp_out_streams = s1ap_register_eNB->sctp_out_streams;
+
     new_instance->num_plmn         = s1ap_register_eNB->num_plmn;
     new_instance->default_drx      = s1ap_register_eNB->default_drx;
     /* Add the new instance to the list of eNB (meaningfull in virtual mode) */
@@ -217,8 +243,12 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
               s1ap_register_eNB->eNB_id);
   }
 
-  DevCheck(s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS,
-           S1AP_MAX_NB_MME_IP_ADDRESS, s1ap_register_eNB->nb_mme, 0);
+  if( s1ap_register_eNB->nb_mme > S1AP_MAX_NB_MME_IP_ADDRESS )
+  {
+    S1AP_ERROR("Invalid MME number = %d\n ", s1ap_register_eNB->nb_mme);
+    s1ap_register_eNB->nb_mme = S1AP_MAX_NB_MME_IP_ADDRESS;
+  }
+  new_instance->s1ap_mme_nb = s1ap_register_eNB->nb_mme;
 
   /* Trying to connect to provided list of MME ip address */
   for (index = 0; index < s1ap_register_eNB->nb_mme; index++) {
@@ -250,28 +280,131 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
 void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
   s1ap_eNB_instance_t *instance_p;
   s1ap_eNB_mme_data_t *s1ap_mme_data_p;
+  s1ap_eNB_ue_context_t        *ue_p = NULL;
+  MessageDef                   *message_p = NULL;
+  uint32_t                     timer_kind = 0;
+  struct plmn_identity_s*      plmnInfo;
+  struct served_group_id_s*    groupInfo;
+  struct served_gummei_s*      gummeiInfo;
+  struct mme_code_s*           mmeCode;
+  int8_t                       cnt = 0;
+  unsigned                     enb_s1ap_id[NUMBER_OF_UE_MAX];
   DevAssert(sctp_new_association_resp != NULL);
   instance_p = s1ap_eNB_get_instance(instance);
   DevAssert(instance_p != NULL);
   s1ap_mme_data_p = s1ap_eNB_get_MME(instance_p, -1,
                                      sctp_new_association_resp->ulp_cnx_id);
   DevAssert(s1ap_mme_data_p != NULL);
-
-  if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
-    S1AP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
-              sctp_new_association_resp->sctp_state,
-              instance,
-              sctp_new_association_resp->ulp_cnx_id);
-    s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
-    return;
+  memset(enb_s1ap_id, 0, sizeof(enb_s1ap_id) );
+  if( s1ap_mme_data_p->timer_id != S1AP_TIMERID_INIT ) {
+    s1ap_timer_remove( s1ap_mme_data_p->timer_id );
+    s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT;
+  }
+  
+  if( sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED ) {
+    RB_FOREACH(ue_p, s1ap_ue_map, &instance_p->s1ap_ue_head) {
+      if( ue_p->mme_ref == s1ap_mme_data_p ) {
+        if(cnt < NUMBER_OF_UE_MAX) {
+          enb_s1ap_id[cnt] = ue_p->eNB_ue_s1ap_id;
+          cnt++;
+          
+          message_p = NULL;
+          message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_UE_CONTEXT_RELEASE_COMMAND);
+          
+          if( message_p != NULL ) {
+            S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = ue_p->eNB_ue_s1ap_id;
+            
+            if( itti_send_msg_to_task(TASK_RRC_ENB, ue_p->eNB_instance->instance, message_p) < 0 ) {
+              S1AP_ERROR("UE Context Release Command Transmission Failure: eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id);
+            }
+          } else {
+            S1AP_ERROR("Invalid message_p : eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id);
+          }
+        }else{
+          S1AP_ERROR("s1ap_eNB_handle_sctp_association_resp: cnt %d > max\n", cnt);
+        }
+      }
+    }
+    for( ; cnt > 0 ; ) {
+      cnt--;
+      struct s1ap_eNB_ue_context_s *ue_context_p = NULL;
+      struct s1ap_eNB_ue_context_s *s1ap_ue_context_p = NULL;
+      ue_context_p = s1ap_eNB_get_ue_context(instance_p, (uint32_t)enb_s1ap_id[cnt]);
+      if (ue_context_p != NULL) {
+        s1ap_ue_context_p = RB_REMOVE(s1ap_ue_map, &instance_p->s1ap_ue_head, ue_context_p);
+        s1ap_eNB_free_ue_context(s1ap_ue_context_p);
+      }
+    }
+    s1ap_mme_data_p->mme_name = 0;
+    s1ap_mme_data_p->overload_state = S1AP_NO_OVERLOAD;
+    s1ap_mme_data_p->nextstream = 0;
+    s1ap_mme_data_p->in_streams = 0;
+    s1ap_mme_data_p->out_streams = 0;
+    s1ap_mme_data_p->assoc_id = -1;
+    
+    while (!STAILQ_EMPTY(&s1ap_mme_data_p->served_gummei)) {
+      gummeiInfo = STAILQ_FIRST(&s1ap_mme_data_p->served_gummei);
+      STAILQ_REMOVE_HEAD(&s1ap_mme_data_p->served_gummei, next);
+
+      while (!STAILQ_EMPTY(&gummeiInfo->served_plmns)) {
+        plmnInfo = STAILQ_FIRST(&gummeiInfo->served_plmns);
+        STAILQ_REMOVE_HEAD(&gummeiInfo->served_plmns, next);
+        free(plmnInfo);
+      }
+      while (!STAILQ_EMPTY(&gummeiInfo->served_group_ids)) {
+        groupInfo = STAILQ_FIRST(&gummeiInfo->served_group_ids);
+        STAILQ_REMOVE_HEAD(&gummeiInfo->served_group_ids, next);
+        free(groupInfo);
+      }
+      while (!STAILQ_EMPTY(&gummeiInfo->mme_codes)) {
+        mmeCode = STAILQ_FIRST(&gummeiInfo->mme_codes);
+        STAILQ_REMOVE_HEAD(&gummeiInfo->mme_codes, next);
+        free(mmeCode);
+      }
+      free(gummeiInfo);
+    }
+    
+    STAILQ_INIT(&s1ap_mme_data_p->served_gummei);
+    
+    if( s1ap_mme_data_p->state == S1AP_ENB_STATE_DISCONNECTED ) {
+      if( (s1ap_mme_data_p->sctp_req_cnt <= instance_p->sctp_req_count) ||
+        (instance_p->sctp_req_count == 0xffff) ) {
+        timer_kind = s1ap_mme_data_p->cnx_id;
+        timer_kind = timer_kind | S1AP_MMEIND;
+        timer_kind = timer_kind | SCTP_REQ_WAIT;
+        
+        if( s1ap_timer_setup( instance_p->sctp_req_timer, 0, TASK_S1AP, instance_p->instance,
+          timer_kind, S1AP_TIMER_ONE_SHOT, NULL, &s1ap_mme_data_p->timer_id) < 0 ) {
+          S1AP_ERROR("Timer Start NG(SCTP retransmission wait timer) : MME=%d\n",s1ap_mme_data_p->cnx_id);
+          s1ap_sctp_req( instance_p, s1ap_mme_data_p );
+        }
+      } else {
+        S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id);
+      }
+    } else {
+      S1AP_ERROR("SCTP disconnection reception : MME = %d\n",s1ap_mme_data_p->cnx_id);
+
+      if( (s1ap_mme_data_p->sctp_req_cnt <= instance_p->sctp_req_count) ||
+          (instance_p->sctp_req_count == 0xffff) ) {
+        s1ap_sctp_req( instance_p, s1ap_mme_data_p );
+      } else {
+        S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id);
+      }
+      s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED;
+    }
+  } else {
+    /* Update parameters */
+    s1ap_mme_data_p->assoc_id    = sctp_new_association_resp->assoc_id;
+    s1ap_mme_data_p->in_streams  = sctp_new_association_resp->in_streams;
+    s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams;
+    /* Prepare new S1 Setup Request */
+    s1ap_mme_data_p->s1_setupreq_cnt = 0;
+    s1ap_mme_data_p->sctp_req_cnt = 0;
+    if (s1ap_eNB_generate_s1_setup_request(instance_p, s1ap_mme_data_p) == -1) {
+      S1AP_ERROR("s1ap eNB generate s1 setup request failed\n");
+      return;
+    }
   }
-
-  /* Update parameters */
-  s1ap_mme_data_p->assoc_id    = sctp_new_association_resp->assoc_id;
-  s1ap_mme_data_p->in_streams  = sctp_new_association_resp->in_streams;
-  s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams;
-  /* Prepare new S1 Setup Request */
-  s1ap_eNB_generate_s1_setup_request(instance_p, s1ap_mme_data_p);
 }
 
 static
@@ -282,13 +415,94 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) {
   mme_test_s1_notify_sctp_data_ind(sctp_data_ind->assoc_id, sctp_data_ind->stream,
                                    sctp_data_ind->buffer, sctp_data_ind->buffer_length);
 #else
-  s1ap_eNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream,
-                          sctp_data_ind->buffer, sctp_data_ind->buffer_length);
+  if (s1ap_eNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream,
+                          sctp_data_ind->buffer, sctp_data_ind->buffer_length) == -1) {
+    S1AP_ERROR("Failed to handle s1ap eNB message\n");
+  }
 #endif
   result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
   AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
 }
 
+void s1ap_eNB_timer_expired(
+  instance_t                instance,
+  timer_has_expired_t   *msg_p)
+{
+  uint32_t                  timer_kind = 0;
+  int16_t                   line_ind = 0;
+  s1ap_eNB_mme_data_t       *mme_desc_p = NULL;
+  uint32_t                  timer_ind = 0;
+  s1ap_eNB_instance_t       *instance_p = NULL;
+  long                      timer_id = S1AP_TIMERID_INIT;
+  
+  instance_p = s1ap_eNB_get_instance(instance);
+  if(msg_p->arg!=NULL){
+    timer_kind = *((uint32_t*)msg_p->arg);
+    free(msg_p->arg);
+  }else{
+    S1AP_ERROR("s1 timer timer_kind is NULL\n");
+    return;
+  }
+  line_ind = (int16_t)(timer_kind & S1AP_LINEIND);
+  timer_id = msg_p->timer_id;
+  
+  if( (timer_kind & S1AP_MMEIND) == S1AP_MMEIND ) {
+    mme_desc_p = s1ap_eNB_get_MME(instance_p, -1, line_ind);
+    if(mme_desc_p != NULL) {
+      if( timer_id == mme_desc_p->timer_id ) {
+        mme_desc_p->timer_id = S1AP_TIMERID_INIT;
+        timer_ind = timer_kind & S1AP_TIMERIND;
+        
+        switch(timer_ind)
+        {
+          case S1_SETRSP_WAIT:
+          {
+            if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) ||
+                (instance_p->s1_setupreq_count == 0xffff) ) {
+              s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p );
+            } else {
+              S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind);
+            }
+            break;
+          }
+          case S1_SETREQ_WAIT:
+          {
+            if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) ||
+                (instance_p->s1_setupreq_count == 0xffff) ) {
+              s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p );
+            } else {
+              S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind);
+            }
+            break;
+          }
+          case SCTP_REQ_WAIT:
+          {
+            if( (instance_p->sctp_req_count >= mme_desc_p->sctp_req_cnt) ||
+                (instance_p->sctp_req_count == 0xffff) ) {
+              s1ap_sctp_req( instance_p, mme_desc_p );
+            } else {
+              S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",line_ind);
+            }
+            break;
+          }
+          default:
+          {
+            S1AP_WARN("Invalid Timer indication\n");
+            break;
+          }
+        }
+      } else {
+        S1AP_DEBUG("Unmatch timer id\n");
+        return;
+      }
+    } else {
+      S1AP_WARN("Not applicable MME detected : connection id = %d\n", line_ind);
+      return;
+    }
+  }
+  return;
+}
+
 void s1ap_eNB_init(void) {
   S1AP_DEBUG("Starting S1AP layer\n");
   s1ap_eNB_prepare_internal_data();
@@ -412,6 +626,13 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) {
     }
     break;
 
+    case TIMER_HAS_EXPIRED:
+    {
+      s1ap_eNB_timer_expired(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
+                             &received_msg->ittiMsg.timer_has_expired);
+    }
+    break;
+
     default:
       S1AP_ERROR("Received unhandled message: %d:%s\n",
                  ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
@@ -452,6 +673,7 @@ static int s1ap_eNB_generate_s1_setup_request(
   uint8_t  *buffer = NULL;
   uint32_t  len = 0;
   int       ret = 0;
+  uint32_t  timer_kind = 0;
   DevAssert(instance_p != NULL);
   DevAssert(s1ap_mme_data_p != NULL);
   s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING;
@@ -526,6 +748,17 @@ static int s1ap_eNB_generate_s1_setup_request(
     return -1;
   }
 
+  timer_kind = s1ap_mme_data_p->cnx_id;
+  timer_kind = timer_kind | S1AP_MMEIND;
+  timer_kind = timer_kind | S1_SETRSP_WAIT;
+  
+  if( s1ap_timer_setup(instance_p->s1_setuprsp_wait_timer, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT,
+    NULL, &s1ap_mme_data_p->timer_id) < 0 )
+  {
+    S1AP_ERROR("Timer Start NG(S1 Setup Response) : MME=%d\n",s1ap_mme_data_p->cnx_id);
+  }
+  s1ap_mme_data_p->s1_setupreq_cnt++;
+
   /* Non UE-Associated signalling -> stream = 0 */
   s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0);
   return ret;
@@ -534,3 +767,55 @@ static int s1ap_eNB_generate_s1_setup_request(
 
 
 
+static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p,
+                         s1ap_eNB_mme_data_t *s1ap_mme_data_p)
+{
+  MessageDef                 *message_p                   = NULL;
+  sctp_new_association_req_t *sctp_new_association_req_p  = NULL;
+  
+  if( instance_p == NULL )
+  {
+      S1AP_ERROR("Invalid instance_p\n");
+      return -1;
+  }
+  
+  message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_NEW_ASSOCIATION_REQ);
+  sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req;
+  sctp_new_association_req_p->port = S1AP_PORT_NUMBER;
+  sctp_new_association_req_p->ppid = S1AP_SCTP_PPID;
+  sctp_new_association_req_p->in_streams  = instance_p->sctp_in_streams;
+  sctp_new_association_req_p->out_streams = instance_p->sctp_out_streams;
+  sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
+  
+  if( s1ap_mme_data_p->mme_ip_address.ipv4 != 0 ) {
+    memcpy(&sctp_new_association_req_p->remote_address,
+        &s1ap_mme_data_p->mme_ip_address,
+        sizeof(net_ip_address_t));
+    if( instance_p->enb_ip_address.ipv4 != 0 ) {
+      memcpy(&sctp_new_association_req_p->local_address,
+          &instance_p->enb_ip_address,
+          sizeof(net_ip_address_t));
+    } else {
+      S1AP_ERROR("Invalid IP Address Format V4(MME):V6\n");
+      return -1;
+    }
+  } else {
+    memcpy(&sctp_new_association_req_p->remote_address,
+        &s1ap_mme_data_p->mme_ip_address,
+        sizeof(net_ip_address_t));
+    if( instance_p->enb_ip_address.ipv6 != 0 ) {
+      memcpy(&sctp_new_association_req_p->local_address,
+          &instance_p->enb_ip_address,
+          sizeof(net_ip_address_t));
+    } else {
+      S1AP_ERROR("Invalid IP Address Format V6(MME):V4\n");
+      return -1;
+    }
+  }
+  
+  itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
+  
+  s1ap_mme_data_p->sctp_req_cnt++;
+  
+  return 0;
+}
diff --git a/openair3/S1AP/s1ap_eNB.h b/openair3/S1AP/s1ap_eNB.h
index 2abbc53ec992f288c14761eb31170e6134a046e0..21835872147d6cc25f982847307d9c52cf3296bc 100644
--- a/openair3/S1AP/s1ap_eNB.h
+++ b/openair3/S1AP/s1ap_eNB.h
@@ -30,6 +30,22 @@
 #ifndef S1AP_ENB_H_
 #define S1AP_ENB_H_
 
+#define S1AP_MMEIND     0x80000000
+#define S1AP_UEIND      0x00000000
+#define S1_SETRSP_WAIT  0x00010000
+#define S1_SETREQ_WAIT  0x00020000
+#define SCTP_REQ_WAIT   0x00030000
+#define S1AP_LINEIND    0x0000ffff
+#define S1AP_TIMERIND   0x00ff0000
+
+#define S1AP_TIMERID_INIT   0xffffffffffffffff
+
+typedef enum s1ap_timer_type_s {
+  S1AP_TIMER_PERIODIC,
+  S1AP_TIMER_ONE_SHOT,
+  S1AP_TIMER_TYPE_MAX,
+} s1ap_timer_type_t;
+
 typedef struct s1ap_eNB_config_s {
   // MME related params
   unsigned char mme_enabled;          ///< MME enabled ?
@@ -43,6 +59,7 @@ void *s1ap_eNB_process_itti_msg(void*);
 void  s1ap_eNB_init(void);
 void *s1ap_eNB_task(void *arg);
 
+int s1ap_timer_remove(long timer_id);
 uint32_t s1ap_generate_eNB_id(void);
 
 #endif /* S1AP_ENB_H_ */
diff --git a/openair3/S1AP/s1ap_eNB_decoder.c b/openair3/S1AP/s1ap_eNB_decoder.c
index 4635946a059446a3a9af91bab78e00e07de32773..14e4b49238555611bac2adcb2e8222d9837384de 100644
--- a/openair3/S1AP/s1ap_eNB_decoder.c
+++ b/openair3/S1AP/s1ap_eNB_decoder.c
@@ -89,8 +89,6 @@ static int s1ap_eNB_decode_initiating_message(S1AP_S1AP_PDU_t *pdu) {
     default:
       S1AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
                  (int)pdu->choice.initiatingMessage.procedureCode);
-      AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n",
-                   (int)pdu->choice.initiatingMessage.procedureCode);
       return -1;
   }
 
diff --git a/openair3/S1AP/s1ap_eNB_defs.h b/openair3/S1AP/s1ap_eNB_defs.h
index d8a8da8001a32dbff65913336829afec781a3ff5..ed0909d66e4be26147548d4a3eb0dc0338e7d865 100644
--- a/openair3/S1AP/s1ap_eNB_defs.h
+++ b/openair3/S1AP/s1ap_eNB_defs.h
@@ -165,6 +165,12 @@ typedef struct s1ap_eNB_mme_data_s {
 
   /* Only meaningfull in virtual mode */
   struct s1ap_eNB_instance_s *s1ap_eNB_instance;
+  
+  uint32_t nb_calls;
+  net_ip_address_t mme_ip_address;
+  long             timer_id;
+  uint16_t         s1_setupreq_cnt;
+  uint16_t         sctp_req_cnt;
 } s1ap_eNB_mme_data_t;
 
 typedef struct s1ap_eNB_instance_s {
@@ -217,6 +223,14 @@ typedef struct s1ap_eNB_instance_s {
 
   /* Default Paging DRX of the eNB as defined in TS 36.304 */
   paging_drx_t default_drx;
+  net_ip_address_t   enb_ip_address;
+  uint16_t           s1_setuprsp_wait_timer;
+  uint16_t           s1_setupreq_wait_timer;
+  uint16_t           s1_setupreq_count;
+  uint16_t           sctp_req_timer;
+  uint16_t           sctp_req_count;
+  uint16_t           sctp_in_streams;
+  uint16_t           sctp_out_streams;
 } s1ap_eNB_instance_t;
 
 typedef struct {
diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c
index 370d34868b577e7428a68d5e70ac49dad397124a..9ee3287b94f3b43a236b0d41ae85a79270682c00 100644
--- a/openair3/S1AP/s1ap_eNB_handlers.c
+++ b/openair3/S1AP/s1ap_eNB_handlers.c
@@ -38,6 +38,9 @@
 #include "s1ap_eNB_defs.h"
 #include "s1ap_eNB_handlers.h"
 #include "s1ap_eNB_decoder.h"
+#include "s1ap_eNB_encoder.h"
+
+#include "s1ap_eNB_itti_messaging.h"
 
 #include "s1ap_eNB_ue_context.h"
 #include "s1ap_eNB_trace.h"
@@ -109,6 +112,20 @@ int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t               as
     uint32_t               stream,
     S1AP_S1AP_PDU_t       *pdu);
 
+static int s1ap_eNB_snd_s1_setup_request(
+  s1ap_eNB_instance_t *instance_p,
+  s1ap_eNB_mme_data_t *s1ap_mme_data_p);
+
+int s1ap_timer_setup(
+  uint32_t      interval_sec,
+  uint32_t      interval_us,
+  task_id_t     task_id,
+  int32_t       instance,
+  uint32_t      timer_kind,
+  timer_type_t  type,
+  void         *timer_arg,
+  long         *timer_id);
+
 /* Handlers matrix. Only eNB related procedure present here */
 s1ap_message_decoded_callback messages_callback[][3] = {
   { 0, 0, 0 }, /* HandoverPreparation */
@@ -260,6 +277,10 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t               assoc_id,
   S1AP_S1SetupFailure_t      *container;
   S1AP_S1SetupFailureIEs_t   *ie;
   s1ap_eNB_mme_data_t        *mme_desc_p;
+  uint32_t                   interval_sec = 0;
+  uint32_t                   timer_kind = 0;
+  s1ap_eNB_instance_t        *instance_p;
+
   DevAssert(pdu != NULL);
   container = &pdu->choice.unsuccessfulOutcome.value.choice.S1SetupFailure;
 
@@ -270,7 +291,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t               assoc_id,
   }
 
   if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
-    S1AP_ERROR("[SCTP %d] Received S1 setup response for non existing "
+    S1AP_ERROR("[SCTP %d] Received S1 setup failure for non existing "
                "MME context\n", assoc_id);
     return -1;
   }
@@ -278,6 +299,10 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t               assoc_id,
   S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container,
                              S1AP_ProtocolIE_ID_id_Cause,true);
 
+  if(ie == NULL) {
+    return -1;
+  }
+
   if ((ie->value.choice.Cause.present == S1AP_Cause_PR_misc) &&
       (ie->value.choice.Cause.choice.misc == S1AP_CauseMisc_unspecified)) {
     S1AP_WARN("Received s1 setup failure for MME... MME is not ready\n");
@@ -285,8 +310,56 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t               assoc_id,
     S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n");
   }
 
-  mme_desc_p->state = S1AP_ENB_STATE_WAITING;
-  s1ap_handle_s1_setup_message(mme_desc_p, 0);
+  if( mme_desc_p->timer_id != S1AP_TIMERID_INIT ) {
+    s1ap_timer_remove( mme_desc_p->timer_id );
+    mme_desc_p->timer_id = S1AP_TIMERID_INIT;
+  }
+  instance_p = mme_desc_p->s1ap_eNB_instance;
+  if( ( instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) ||
+      ( instance_p->s1_setupreq_count == 0xffff) ) {
+    S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container,
+                               S1AP_ProtocolIE_ID_id_TimeToWait, false);
+    if( ie != NULL ) {
+      switch(ie->value.choice.TimeToWait)
+      {
+        case S1AP_TimeToWait_v1s:
+          interval_sec = 1;
+          break;
+        case S1AP_TimeToWait_v2s:
+          interval_sec = 2;
+          break;
+        case S1AP_TimeToWait_v5s:
+          interval_sec = 5;
+          break;
+        case S1AP_TimeToWait_v10s:
+          interval_sec = 10;
+          break;
+        case S1AP_TimeToWait_v20s:
+          interval_sec = 20;
+          break;
+        case S1AP_TimeToWait_v60s:
+          interval_sec = 60;
+          break;
+        default:
+          interval_sec = instance_p->s1_setupreq_wait_timer;
+          break;
+      }
+    } else {
+      interval_sec = instance_p->s1_setupreq_wait_timer;
+    }
+    
+    timer_kind = mme_desc_p->cnx_id;
+    timer_kind = timer_kind | S1AP_MMEIND;
+    timer_kind = timer_kind | S1_SETREQ_WAIT;
+    
+    if( s1ap_timer_setup(interval_sec, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT,
+      NULL, &mme_desc_p->timer_id) < 0 ) {
+      S1AP_ERROR("Timer Start NG(S1 Setup Request) : MME=%d\n",mme_desc_p->cnx_id);
+      s1ap_eNB_snd_s1_setup_request( instance_p, mme_desc_p );
+    }
+  } else {
+    S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",mme_desc_p->cnx_id);
+  }
   return 0;
 }
 
@@ -314,9 +387,27 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t               assoc_id,
     return -1;
   }
 
+  /* Set the capacity of this MME */
+  S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
+                             S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true);
+  if(ie == NULL) {
+    return -1;
+  }
+  mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity;
+
   S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
                              S1AP_ProtocolIE_ID_id_ServedGUMMEIs, true);
+  if(ie == NULL) {
+    return -1;
+  }
 
+  if( mme_desc_p->timer_id != S1AP_TIMERID_INIT )
+  {
+    s1ap_timer_remove( mme_desc_p->timer_id );
+    mme_desc_p->timer_id = S1AP_TIMERID_INIT;
+  }
+  mme_desc_p->s1_setupreq_cnt = 0;
+  mme_desc_p->sctp_req_cnt = 0;
   /* The list of served gummei can contain at most 8 elements.
    * LTE related gummei is the first element in the list, i.e with an id of 0.
    */
@@ -368,13 +459,7 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t               assoc_id,
 
     STAILQ_INSERT_TAIL(&mme_desc_p->served_gummei, new_gummei_p, next);
   }
-
-  /* Set the capacity of this MME */
-  S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
-                             S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true);
-
-  mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity;
-
+  
   /* Optionaly set the mme name */
   S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
                              S1AP_ProtocolIE_ID_id_MMEname, false);
@@ -392,7 +477,6 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t               assoc_id,
    */
   mme_desc_p->state = S1AP_ENB_STATE_CONNECTED;
   mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb ++;
-  s1ap_handle_s1_setup_message(mme_desc_p, 0);
   return 0;
 }
 
@@ -725,6 +809,9 @@ int s1ap_eNB_handle_error_indication(uint32_t         assoc_id,
                              S1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false);
 
   if (ie) {
+    if( ie->value.choice.CriticalityDiagnostics.procedureCode ) {
+      S1AP_WARN("Received S1 Error indication CriticalityDiagnostics procedureCode = %ld\n", *ie->value.choice.CriticalityDiagnostics.procedureCode);
+    }
     // TODO continue
   }
 
@@ -807,9 +894,11 @@ int s1ap_eNB_handle_initial_context_request(uint32_t   assoc_id,
                       &(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_dl));
     /* id-E-RABToBeSetupListCtxtSUReq */
   } else {
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
+
   S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
                              S1AP_ProtocolIE_ID_id_E_RABToBeSetupListCtxtSUReq, true);
 
@@ -852,6 +941,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t   assoc_id,
         item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability;
     } /* for i... */
   } else {/* ie != NULL */
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
@@ -865,6 +955,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t   assoc_id,
     S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms =
       BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms);
   } else {/* ie != NULL */
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
@@ -876,9 +967,10 @@ int s1ap_eNB_handle_initial_context_request(uint32_t   assoc_id,
     memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key,
            ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size);
   } else {/* ie != NULL */
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
-
+  
   /* id-NRUESecurityCapabilities */
   S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
                              S1AP_ProtocolIE_ID_id_NRUESecurityCapabilities, false);
@@ -891,7 +983,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t   assoc_id,
     S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms = 0;
     S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms = 0;
   }
-
+  
   itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
 
   return 0;
@@ -918,6 +1010,13 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t   assoc_id,
     return -1;
   }
 
+  S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container,
+                             S1AP_ProtocolIE_ID_id_Cause, true);
+  if( ie == NULL ) {
+    S1AP_ERROR( "Mandatory Element Nothing : UEContextReleaseCommand(Cause)\n" );
+    return -1;
+  }
+
   S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container,
                              S1AP_ProtocolIE_ID_id_UE_S1AP_IDs, true);
 
@@ -965,9 +1064,26 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t   assoc_id,
       //#warning "TODO mapping mme_ue_s1ap_id  enb_ue_s1ap_id?"
 
       case S1AP_UE_S1AP_IDs_PR_mME_UE_S1AP_ID:
-        mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID;
-        S1AP_ERROR("TO DO mapping mme_ue_s1ap_id  enb_ue_s1ap_id");
-        (void)mme_ue_s1ap_id; /* TODO: remove - it's to remove gcc warning about unused var */
+        mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.mME_UE_S1AP_ID;
+        
+        RB_FOREACH(ue_desc_p, s1ap_ue_map, &mme_desc_p->s1ap_eNB_instance->s1ap_ue_head)
+        {
+          if( ue_desc_p->mme_ue_s1ap_id == mme_ue_s1ap_id )
+          {
+            enb_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id;
+            
+            message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_UE_CONTEXT_RELEASE_COMMAND);
+            S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
+            itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
+            
+            return 0;
+          }
+        }
+        S1AP_ERROR("[SCTP %d] Received UE context release command(mME_UE_S1AP_ID) for non "
+                   "existing UE context 0x%06lx\n",
+                   assoc_id,
+                   mme_ue_s1ap_id);
+        return -1;
 
       case S1AP_UE_S1AP_IDs_PR_NOTHING:
       default:
@@ -975,12 +1091,10 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t   assoc_id,
         return -1;
     }
   } else {
+    S1AP_ERROR( "Mandatory Element Nothing : UEContextReleaseCommand(UE_S1AP_IDs)\n" );
     return -1;
   }
 
-  S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container,
-                             S1AP_ProtocolIE_ID_id_Cause, true);
-  /* TBD */
 }
 
 static
@@ -999,7 +1113,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t         assoc_id,
   container = &pdu->choice.initiatingMessage.value.choice.E_RABSetupRequest;
 
   if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
-    S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
+    S1AP_ERROR("[SCTP %d] Received E-RAB setup request for non "
                "existing MME context\n", assoc_id);
     return -1;
   }
@@ -1026,7 +1140,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t         assoc_id,
 
   if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
                    enb_ue_s1ap_id)) == NULL) {
-    S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
+   S1AP_ERROR("[SCTP %d] Received E-RAB setup request for non "
                "existing UE context 0x%06lx\n", assoc_id,
                enb_ue_s1ap_id);
     return -1;
@@ -1099,6 +1213,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t         assoc_id,
 
     itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
   } else {
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
@@ -1119,13 +1234,6 @@ int s1ap_eNB_handle_paging(uint32_t               assoc_id,
   // received Paging Message from MME
   S1AP_DEBUG("[SCTP %d] Received Paging Message From MME\n",assoc_id);
 
-  /* Paging procedure -> stream != 0 */
-  if (stream == 0) {
-    LOG_W(S1AP,"[SCTP %d] Received Paging procedure on stream (%d)\n",
-          assoc_id, stream);
-    return -1;
-  }
-
   if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
     S1AP_ERROR("[SCTP %d] Received Paging for non "
                "existing MME context\n", assoc_id);
@@ -1153,6 +1261,7 @@ int s1ap_eNB_handle_paging(uint32_t               assoc_id,
     S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code = 0;
     S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi = 0;
   } else {
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
@@ -1180,6 +1289,7 @@ int s1ap_eNB_handle_paging(uint32_t               assoc_id,
           if(i != ie->value.choice.UEPagingID.choice.iMSI.size - 1) {
             /* invalid paging_p->uePagingID.choise.iMSI.buffer */
             S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI error(i %d 0x0F)\n", assoc_id,i);
+            itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
             return -1;
           }
         } else {
@@ -1190,14 +1300,17 @@ int s1ap_eNB_handle_paging(uint32_t               assoc_id,
       if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length >= S1AP_IMSI_LENGTH) {
         /* invalid paging_p->uePagingID.choise.iMSI.size */
         S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI.size(%d) is over IMSI length(%d)\n", assoc_id, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length, S1AP_IMSI_LENGTH);
+        itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
         return -1;
       }
     } else { /* of if (ie->value.choice.UEPagingID.present == S1AP_UEPagingID_PR_iMSI) */
       /* invalid paging_p->uePagingID.present */
       S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.present(%d) is unknown\n", assoc_id, ie->value.choice.UEPagingID.present);
+      itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
       return -1;
     }
   } else { /* of ie != NULL */
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
@@ -1230,6 +1343,7 @@ int s1ap_eNB_handle_paging(uint32_t               assoc_id,
       return -1;
     }
   } else {
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
@@ -1257,6 +1371,7 @@ int s1ap_eNB_handle_paging(uint32_t               assoc_id,
                  S1AP_PAGING_IND(message_p).tac[i]);
     }
   } else {
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
@@ -1351,6 +1466,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t               assoc_id,
         S1AP_E_RAB_MODIFY_RESP(message_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id;
       }
     } else {
+      itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
       return -1;
     }
 
@@ -1403,6 +1519,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t               assoc_id,
 
     itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
   } else { /* of if (ie != NULL)*/
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
@@ -1476,22 +1593,6 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t               assoc_id,
   message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_E_RAB_RELEASE_COMMAND);
   S1AP_E_RAB_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
   S1AP_E_RAB_RELEASE_COMMAND(message_p).mme_ue_s1ap_id = mme_ue_s1ap_id;
-  /* id-NAS-PDU */
-  S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container,
-                             S1AP_ProtocolIE_ID_id_NAS_PDU, false);
-
-  if(ie && ie->value.choice.NAS_PDU.size > 0) {
-    S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = ie->value.choice.NAS_PDU.size;
-    S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer =
-      malloc(sizeof(uint8_t) * ie->value.choice.NAS_PDU.size);
-    memcpy(S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer,
-           ie->value.choice.NAS_PDU.buf,
-           ie->value.choice.NAS_PDU.size);
-  } else {
-    S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = 0;
-    S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer = NULL;
-  }
-
   /* id-E-RABToBeReleasedList */
   S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container,
                              S1AP_ProtocolIE_ID_id_E_RABToBeReleasedList, true);
@@ -1506,9 +1607,25 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t               assoc_id,
       S1AP_DEBUG("[SCTP] Received E-RAB release command for e-rab id %ld\n", item_p->e_RAB_ID);
     }
   } else {
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
+  /* id-NAS-PDU */
+  S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container,
+                             S1AP_ProtocolIE_ID_id_NAS_PDU, false);
+
+  if(ie && ie->value.choice.NAS_PDU.size > 0) {
+    S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = ie->value.choice.NAS_PDU.size;
+    S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer =
+      malloc(sizeof(uint8_t) * ie->value.choice.NAS_PDU.size);
+    memcpy(S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer,
+           ie->value.choice.NAS_PDU.buf,
+           ie->value.choice.NAS_PDU.size);
+  } else {
+    S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = 0;
+    S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer = NULL;
+  }
   itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
   return 0;
 }
@@ -1533,7 +1650,6 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t               assoc_id,
   if (stream == 0) {
     S1AP_ERROR("[SCTP %d] Received s1 path switch request ack on stream (%d)\n",
                assoc_id, stream);
-    //return -1;
   }
 
   if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
@@ -1550,6 +1666,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t               assoc_id,
   if (ie == NULL) {
     S1AP_ERROR("[SCTP %d] Received path switch request ack for non "
                "ie context is NULL\n", assoc_id);
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
@@ -1572,6 +1689,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t               assoc_id,
   if (ie == NULL) {
     S1AP_ERROR("[SCTP %d] Received path switch request ack for non "
                "ie context is NULL\n", assoc_id);
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
@@ -1589,6 +1707,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t               assoc_id,
   if (ie == NULL) {
     S1AP_ERROR("[SCTP %d] Received path switch request ack for non "
                "ie context is NULL\n", assoc_id);
+    itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
     return -1;
   }
 
@@ -1602,14 +1721,10 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t               assoc_id,
                              S1AP_ProtocolIE_ID_id_uEaggregateMaximumBitrate, false);
 
   if (ie) {
-    OCTET_STRING_TO_INT32 (
-      &ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL,
-      S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul
-    );
-    OCTET_STRING_TO_INT32 (
-      &ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL,
-      S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_dl
-    );
+    asn_INTEGER2ulong(&ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL,
+                      &S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul);
+    asn_INTEGER2ulong(&ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL,
+                      &S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_dl);
   } else {
     S1AP_WARN("UEAggregateMaximumBitrate not supported\n");
     S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul = 0;
@@ -1688,9 +1803,8 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t               assoc_
   pathSwitchRequestFailure = &pdu->choice.unsuccessfulOutcome.value.choice.PathSwitchRequestFailure;
 
   if (stream != 0) {
-    S1AP_ERROR("[SCTP %d] Received s1 path switch request failure on stream != 0 (%d)\n",
+    S1AP_WARN("[SCTP %d] Received s1 path switch request failure on stream != 0 (%d)\n",
                assoc_id, stream);
-    return -1;
   }
 
   if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
@@ -1754,3 +1868,144 @@ int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t               as
 	return 0;
 }
 
+//-----------------------------------------------------------------------------
+/*
+* eNB generate a S1 setup request towards MME
+*/
+static int s1ap_eNB_snd_s1_setup_request(
+  s1ap_eNB_instance_t *instance_p,
+  s1ap_eNB_mme_data_t *s1ap_mme_data_p)
+//-----------------------------------------------------------------------------
+{
+  S1AP_S1AP_PDU_t            pdu;
+  S1AP_S1SetupRequest_t     *out = NULL;
+  S1AP_S1SetupRequestIEs_t   *ie = NULL;
+  S1AP_SupportedTAs_Item_t   *ta = NULL;
+  S1AP_PLMNidentity_t      *plmn = NULL;
+  uint8_t  *buffer = NULL;
+  uint32_t  len = 0;
+  int       ret = 0;
+  uint32_t                 timer_kind = 0;
+
+  DevAssert(instance_p != NULL);
+  DevAssert(s1ap_mme_data_p != NULL);
+  s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING;
+  /* Prepare the S1AP message to encode */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_S1Setup;
+  pdu.choice.initiatingMessage.criticality = S1AP_Criticality_reject;
+  pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_S1SetupRequest;
+  out = &pdu.choice.initiatingMessage.value.choice.S1SetupRequest;
+  /* mandatory */
+  ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+  ie->id = S1AP_ProtocolIE_ID_id_Global_ENB_ID;
+  ie->criticality = S1AP_Criticality_reject;
+  ie->value.present = S1AP_S1SetupRequestIEs__value_PR_Global_ENB_ID;
+  MCC_MNC_TO_PLMNID(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[0]],
+                    instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[0]],
+                    instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[0]],
+                    &ie->value.choice.Global_ENB_ID.pLMNidentity);
+  ie->value.choice.Global_ENB_ID.eNB_ID.present = S1AP_ENB_ID_PR_macroENB_ID;
+  MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
+                             &ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID);
+  S1AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
+            ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[0],
+            ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[1],
+            ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[2]);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  if (instance_p->eNB_name) {
+    ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+    ie->id = S1AP_ProtocolIE_ID_id_eNBname;
+    ie->criticality = S1AP_Criticality_ignore;
+    ie->value.present = S1AP_S1SetupRequestIEs__value_PR_ENBname;
+    OCTET_STRING_fromBuf(&ie->value.choice.ENBname, instance_p->eNB_name,
+                         strlen(instance_p->eNB_name));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+  ie->id = S1AP_ProtocolIE_ID_id_SupportedTAs;
+  ie->criticality = S1AP_Criticality_reject;
+  ie->value.present = S1AP_S1SetupRequestIEs__value_PR_SupportedTAs;
+  {
+    ta = (S1AP_SupportedTAs_Item_t *)calloc(1, sizeof(S1AP_SupportedTAs_Item_t));
+    INT16_TO_OCTET_STRING(instance_p->tac, &ta->tAC);
+    {
+      for (int i = 0; i < s1ap_mme_data_p->broadcast_plmn_num; ++i) {
+        plmn = (S1AP_PLMNidentity_t *)calloc(1, sizeof(S1AP_PLMNidentity_t));
+        MCC_MNC_TO_TBCD(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[i]],
+                        instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[i]],
+                        instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[i]],
+                        plmn);
+        ASN_SEQUENCE_ADD(&ta->broadcastPLMNs.list, plmn);
+      }
+    }
+    ASN_SEQUENCE_ADD(&ie->value.choice.SupportedTAs.list, ta);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  /* mandatory */
+  ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+  ie->id = S1AP_ProtocolIE_ID_id_DefaultPagingDRX;
+  ie->criticality = S1AP_Criticality_ignore;
+  ie->value.present = S1AP_S1SetupRequestIEs__value_PR_PagingDRX;
+  ie->value.choice.PagingDRX = instance_p->default_drx;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  if (0) {
+    ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+    ie->id = S1AP_ProtocolIE_ID_id_CSG_IdList;
+    ie->criticality = S1AP_Criticality_reject;
+    ie->value.present = S1AP_S1SetupRequestIEs__value_PR_CSG_IdList;
+    // ie->value.choice.CSG_IdList = ;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+#if (S1AP_VERSION >= MAKE_VERSION(13, 0, 0))
+
+  if (0) {
+    ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+    ie->id = S1AP_ProtocolIE_ID_id_UE_RetentionInformation;
+    ie->criticality = S1AP_Criticality_ignore;
+    ie->value.present = S1AP_S1SetupRequestIEs__value_PR_UE_RetentionInformation;
+    // ie->value.choice.UE_RetentionInformation = ;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  if (0) {
+    ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+    ie->id = S1AP_ProtocolIE_ID_id_NB_IoT_DefaultPagingDRX;
+    ie->criticality = S1AP_Criticality_ignore;
+    ie->value.present = S1AP_S1SetupRequestIEs__value_PR_NB_IoT_DefaultPagingDRX;
+    // ie->value.choice.NB_IoT_DefaultPagingDRX = ;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+#endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */
+
+  if (s1ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
+    S1AP_ERROR("Failed to encode S1 setup request\n");
+    return -1;
+  }
+
+  timer_kind = s1ap_mme_data_p->cnx_id;
+  timer_kind = timer_kind | S1AP_MMEIND;
+  timer_kind = timer_kind | S1_SETRSP_WAIT;
+  
+  if( s1ap_timer_setup(instance_p->s1_setuprsp_wait_timer, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT,
+    NULL, &s1ap_mme_data_p->timer_id) < 0 )
+  {
+    S1AP_ERROR("Timer Start NG(S1 Setup Response) : MME=%d\n",s1ap_mme_data_p->cnx_id);
+  }
+  s1ap_mme_data_p->s1_setupreq_cnt++;
+
+  /* Non UE-Associated signalling -> stream = 0 */
+  s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0);
+  return ret;
+}
diff --git a/openair3/S1AP/s1ap_eNB_management_procedures.c b/openair3/S1AP/s1ap_eNB_management_procedures.c
index fc7ae70e4902073e3a5ceb70ccd9b4b93b4be2a8..a870e975a2d0f5fb6f6ca91e9f56f5b273fedbf1 100644
--- a/openair3/S1AP/s1ap_eNB_management_procedures.c
+++ b/openair3/S1AP/s1ap_eNB_management_procedures.c
@@ -95,23 +95,43 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME(
 {
   struct s1ap_eNB_mme_data_s  temp;
   struct s1ap_eNB_mme_data_s *found;
+  struct s1ap_eNB_mme_data_s *mme_p;
 
   memset(&temp, 0, sizeof(struct s1ap_eNB_mme_data_s));
 
   temp.assoc_id = assoc_id;
   temp.cnx_id   = cnx_id;
 
-  if (instance_p == NULL) {
-    STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head,
-                   s1ap_eNB_entries) {
-      found = RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp);
+  if( cnx_id != 0 ) {
+    if (instance_p == NULL) {
+      STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head,
+                     s1ap_eNB_entries) {
+        found = RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp);
 
-      if (found != NULL) {
-        return found;
+        if (found != NULL) {
+          return found;
+        }
       }
+    } else {
+      return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp);
     }
   } else {
-    return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp);
+    if (instance_p == NULL) {
+      STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head,
+                     s1ap_eNB_entries) {
+        RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
+          if( mme_p->assoc_id == assoc_id ) {
+            return mme_p;
+          }
+        }
+      }
+    } else {
+      RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
+        if( mme_p->assoc_id == assoc_id ) {
+          return mme_p;
+        }
+      }
+    }
   }
 
   return NULL;
diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c
index 919989897afc52cf85b9b042835aaae5ec7c1a78..b55bc06e11a4842a4d607023cb85f05f75ac8e95 100644
--- a/openair3/S1AP/s1ap_eNB_nas_procedures.c
+++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c
@@ -138,8 +138,8 @@ int s1ap_eNB_handle_nas_first_req(
          * identity, selects the MME with the highest capacity.
          */
         mme_desc_p = s1ap_eNB_nnsf_select_mme(
-                         instance_p,
-                         s1ap_nas_first_req_p->establishment_cause);
+                       instance_p,
+                       s1ap_nas_first_req_p->establishment_cause);
 
         if (mme_desc_p) {
             S1AP_INFO("[eNB %ld] Chose MME '%s' (assoc_id %d) through highest relative capacity\n",
@@ -358,10 +358,18 @@ int s1ap_eNB_handle_nas_downlink(uint32_t         assoc_id,
     container = &pdu->choice.initiatingMessage.value.choice.DownlinkNASTransport;
     S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container,
                                S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true);
+    if(ie == NULL)
+    {
+      return -1;
+    }
     mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID;
 
     S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container,
                                S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true);
+    if(ie == NULL)
+    {
+      return -1;
+    }
     enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID;
 
     if ((ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance,
@@ -416,6 +424,10 @@ int s1ap_eNB_handle_nas_downlink(uint32_t         assoc_id,
 
     S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container,
                                S1AP_ProtocolIE_ID_id_NAS_PDU, true);
+    if(ie == NULL)
+    {
+      return -1;
+    }
     /* Forward the NAS PDU to RRC */
     s1ap_eNB_itti_send_nas_downlink_ind(s1ap_eNB_instance->instance,
                                         ue_desc_p->ue_initial_id,
@@ -494,9 +506,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_
     ie->criticality = S1AP_Criticality_ignore;
     ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI;
     MCC_MNC_TO_PLMNID(
-        s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity],
-        s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity],
-        s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity],
+        s1ap_eNB_instance_p->mcc[ue_context_p->mme_ref->broadcast_plmn_index[0]],
+        s1ap_eNB_instance_p->mnc[ue_context_p->mme_ref->broadcast_plmn_index[0]],
+        s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->mme_ref->broadcast_plmn_index[0]],
         &ie->value.choice.EUTRAN_CGI.pLMNidentity);
     //#warning "TODO get cell id from RRC"
     MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id,
diff --git a/openair3/S1AP/s1ap_eNB_nnsf.c b/openair3/S1AP/s1ap_eNB_nnsf.c
index 6319f6e054d878fb19087e0c3f3fa8e946a6d602..a5a4e747344a08d8ebf81dddcaca44c1cbdd73e6 100644
--- a/openair3/S1AP/s1ap_eNB_nnsf.c
+++ b/openair3/S1AP/s1ap_eNB_nnsf.c
@@ -36,15 +36,29 @@
 #include "s1ap_eNB_defs.h"
 #include "s1ap_eNB_nnsf.h"
 
+
+typedef struct MME_nnsf_inf {
+  struct s1ap_eNB_mme_data_s *mme_p;
+  uint64_t weight;
+} MME_nnsf_inf_t;
+
 struct s1ap_eNB_mme_data_s *
 s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t       *instance_p,
                          rrc_establishment_cause_t  cause)
 {
   struct s1ap_eNB_mme_data_s *mme_data_p = NULL;
   struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL;
-  uint8_t current_capacity = 0;
-
+  
+  uint16_t capacity_sum = 0;
+  MME_nnsf_inf_t mme_inf[10];
+  int       cnt;
+  int       nb_mme = 0;
+  uint64_t  weight = 0;
+  
+  memset(mme_inf, 0, sizeof(mme_inf));
+  
   RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
+    capacity_sum = capacity_sum + mme_data_p->relative_mme_capacity;
     if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) {
       /* The association between MME and eNB is not ready for the moment,
        * go to the next known MME.
@@ -69,7 +83,8 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t       *instance_p,
                 || (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) {
           continue;
         }
-
+        mme_inf[nb_mme].mme_p = mme_data_p;
+        nb_mme++;
         /* At this point, the RRC establishment can be handled by the MME
          * even if it is in overload state.
          */
@@ -78,14 +93,27 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t       *instance_p,
         continue;
       }
     }
-
-    if (current_capacity < mme_data_p->relative_mme_capacity) {
-      /* We find a better MME, keep a reference to it */
-      current_capacity = mme_data_p->relative_mme_capacity;
-      mme_highest_capacity_p = mme_data_p;
+  }
+  
+  if( nb_mme != 0 ) {
+    for( cnt = 0 ; cnt < nb_mme ; cnt++ ) {
+      mme_inf[cnt].weight = (capacity_sum*10)/mme_inf[cnt].mme_p->relative_mme_capacity;
+      mme_inf[cnt].weight = (mme_inf[cnt].weight)*(mme_inf[cnt].mme_p->nb_calls + 1);
+    }
+    mme_highest_capacity_p = mme_inf[0].mme_p;
+    weight = mme_inf[0].weight;
+    for( cnt = 1 ; cnt < nb_mme ; cnt++ ) {
+      if( weight > mme_inf[cnt].weight ) {
+        mme_highest_capacity_p = mme_inf[cnt].mme_p;
+        weight = mme_inf[cnt].weight;
+      }
     }
+  } else {
+    mme_highest_capacity_p = NULL;
+  }
+  if( mme_highest_capacity_p != NULL ) {
+    mme_highest_capacity_p->nb_calls++;
   }
-
   return mme_highest_capacity_p;
 }
 
@@ -96,8 +124,15 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t       *instance_p,
 {
   struct s1ap_eNB_mme_data_s *mme_data_p = NULL;
   struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL;
-  uint8_t current_capacity = 0;
-
+  
+  uint16_t capacity_sum = 0;
+  MME_nnsf_inf_t mme_inf[10];
+  int       cnt;
+  int       nb_mme = 0;
+  uint64_t  weight = 0;
+  
+  memset(mme_inf, 0, sizeof(mme_inf));
+  
   RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
     struct served_gummei_s *gummei_p = NULL;
     struct plmn_identity_s *served_plmn_p = NULL;
@@ -140,6 +175,8 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t       *instance_p,
       STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) {
         if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) &&
             (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) {
+          mme_inf[nb_mme].mme_p = mme_data_p;
+          nb_mme++;
           break;
         }
       }
@@ -148,14 +185,27 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t       *instance_p,
     }
     /* if we didn't find such a served PLMN, go on with the next MME */
     if (!served_plmn_p) continue;
+  }
 
-    if (current_capacity < mme_data_p->relative_mme_capacity) {
-      /* We find a better MME, keep a reference to it */
-      current_capacity = mme_data_p->relative_mme_capacity;
-      mme_highest_capacity_p = mme_data_p;
+  if( nb_mme != 0 ) {
+    for( cnt = 0 ; cnt < nb_mme ; cnt++ ) {
+      mme_inf[cnt].weight = (capacity_sum*10)/mme_inf[cnt].mme_p->relative_mme_capacity;
+      mme_inf[cnt].weight = (mme_inf[cnt].weight)*(mme_inf[cnt].mme_p->nb_calls + 1);
+    }
+    mme_highest_capacity_p = mme_inf[0].mme_p;
+    weight = mme_inf[0].weight;
+    for( cnt = 1 ; cnt < nb_mme ; cnt++ ) {
+      if( weight > mme_inf[cnt].weight ) {
+        mme_highest_capacity_p = mme_inf[cnt].mme_p;
+        weight = mme_inf[cnt].weight;
+      }
     }
+  } else {
+    mme_highest_capacity_p = NULL;
+  }
+  if( mme_highest_capacity_p != NULL ) {
+    mme_highest_capacity_p->nb_calls++;
   }
-
   return mme_highest_capacity_p;
 }
 
diff --git a/openair3/S1AP/s1ap_eNB_overload.c b/openair3/S1AP/s1ap_eNB_overload.c
index 9358ae62bdb6286873240f3194af9e609921172f..64d3fcdf65943c3b8f8d939f2072b943df3ef272 100644
--- a/openair3/S1AP/s1ap_eNB_overload.c
+++ b/openair3/S1AP/s1ap_eNB_overload.c
@@ -62,8 +62,16 @@ int s1ap_eNB_handle_overload_start(uint32_t         assoc_id,
                  S1AP_OverloadResponse_PR_overloadAction,
                  S1AP_OverloadResponse_PR_overloadAction, 0, 0);
     }
+    else
+    {
+        return -1;
+    }
     /* Non UE-associated signalling -> stream 0 */
-    DevCheck(stream == 0, stream, 0, 0);
+    if (stream != 0) {
+      S1AP_ERROR("[SCTP %d] Received s1 overload start on stream != 0 (%d)\n",
+                 assoc_id, stream);
+      return -1;
+    }
 
     if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
         /* No MME context associated */
@@ -93,7 +101,11 @@ int s1ap_eNB_handle_overload_stop(uint32_t         assoc_id,
     s1ap_eNB_mme_data_t *mme_desc_p;
 
     /* Non UE-associated signalling -> stream 0 */
-    DevCheck(stream == 0, stream, 0, 0);
+    if (stream != 0) {
+      S1AP_ERROR("[SCTP %d] Received s1 overload stop on stream != 0 (%d)\n",
+                 assoc_id, stream);
+      return -1;
+    }
 
     if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
         /* No MME context associated */
diff --git a/openair3/S1AP/s1ap_eNB_trace.c b/openair3/S1AP/s1ap_eNB_trace.c
index 19f50592386843fb774cf8bc3adbbd35b728cfb1..695eeb4ef836a340f4639153ba06699172596f0b 100644
--- a/openair3/S1AP/s1ap_eNB_trace.c
+++ b/openair3/S1AP/s1ap_eNB_trace.c
@@ -121,6 +121,10 @@ int s1ap_eNB_handle_trace_start(uint32_t         assoc_id,
   if (ie != NULL) {
     ue_desc_p = s1ap_eNB_get_ue_context(mme_ref_p->s1ap_eNB_instance,
                                         ie->value.choice.ENB_UE_S1AP_ID);
+  }
+  else
+  {
+    return -1;
   }
     if (ue_desc_p == NULL) {
         /* Could not find context associated with this eNB_ue_s1ap_id -> generate
diff --git a/openair3/SCTP/sctp_default_values.h b/openair3/SCTP/sctp_default_values.h
index 528ffb5a05114aea3c37ea584e8a55f871210ddc..0f8f94dca9b9e36be5b36379e67840b5bc53c900 100644
--- a/openair3/SCTP/sctp_default_values.h
+++ b/openair3/SCTP/sctp_default_values.h
@@ -24,8 +24,8 @@
 
 #define SCTP_OUT_STREAMS        (16)
 #define SCTP_IN_STREAMS         (16)
-#define SCTP_MAX_ATTEMPTS       (2)
-#define SCTP_TIMEOUT            (5)
+#define SCTP_MAX_ATTEMPTS       (8)
+#define SCTP_TIMEOUT            (60000)
 #define SCTP_RECV_BUFFER_SIZE   (8192)
 
 #endif /* SCTP_DEFAULT_VALUES_H_ */
diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c
index 2f732443bea0e9086fa79e2e8c61177dad9586ef..a14d4b9780c487b8f1cf01d3b510de2bc486041a 100644
--- a/openair3/SCTP/sctp_eNB_task.c
+++ b/openair3/SCTP/sctp_eNB_task.c
@@ -270,7 +270,7 @@ sctp_handle_new_association_req_multi(
                            sctp_new_association_req_p->remote_address.ipv6_address);
                 //close(sd);
                 //return;
-                exit(1);
+                exit_fun("sctp_handle_new_association_req_multi fatal: inet_pton error");
             }
 
             SCTP_DEBUG("Converted ipv6 address %*s to network type\n",
@@ -290,7 +290,7 @@ sctp_handle_new_association_req_multi(
                            sctp_new_association_req_p->remote_address.ipv4_address);
                 //close(sd);
                 //return;
-                exit(1);
+                exit_fun("sctp_handle_new_association_req_multi fatal: inet_pton error");
             }
 
             SCTP_DEBUG("Converted ipv4 address %*s to network type\n",
@@ -329,7 +329,7 @@ sctp_handle_new_association_req_multi(
     if (ns == -1) {
       perror("sctp_peeloff");
       printf("sctp_peeloff: sd=%d assoc_id=%d\n", sd, assoc_id);
-      exit(1);
+      exit_fun("sctp_handle_new_association_req_multi fatal: sctp_peeloff error");
     }
 
     sctp_cnx = calloc(1, sizeof(*sctp_cnx));
@@ -943,10 +943,12 @@ sctp_eNB_read_from_socket(
                      &sinfo, &flags);
 
     if (n < 0) {
-        if (errno == ENOTCONN) {
+        if( (errno == ENOTCONN) || (errno == ECONNRESET) || (errno == ETIMEDOUT) || (errno == ECONNREFUSED) )
+        {
             itti_unsubscribe_event_fd(TASK_SCTP, sctp_cnx->sd);
 
             SCTP_DEBUG("Received not connected for sd %d\n", sctp_cnx->sd);
+            SCTP_ERROR("sctp_recvmsg (fd %d, len %d ): %s:%d\n", sctp_cnx->sd, n, strerror(errno), errno);
 
             sctp_itti_send_association_resp(
                 sctp_cnx->task_id, sctp_cnx->instance, -1,
@@ -969,7 +971,7 @@ sctp_eNB_read_from_socket(
 
     if (!(flags & MSG_EOR)) {
       SCTP_ERROR("fatal: partial SCTP messages are not handled\n");
-      exit(1);
+      exit_fun("fatal: partial SCTP messages are not handled" );
     }
 
     if (flags & MSG_NOTIFICATION) {
@@ -983,6 +985,7 @@ sctp_eNB_read_from_socket(
         if (SCTP_SHUTDOWN_EVENT == snp->sn_header.sn_type) {
             itti_unsubscribe_event_fd(TASK_SCTP, sctp_cnx->sd);
 
+            SCTP_WARN("Received SCTP SHUTDOWN EVENT\n");
             close(sctp_cnx->sd);
 
             sctp_itti_send_association_resp(
@@ -1024,7 +1027,14 @@ sctp_eNB_read_from_socket(
             break;
 
             default:
-                SCTP_WARN("unhandled: SCTP_ASSOC_CHANGE to %d\n", sctp_assoc_changed->sac_state);
+                if ( sctp_assoc_changed->sac_state == SCTP_SHUTDOWN_COMP) 
+                    SCTP_WARN("SCTP_ASSOC_CHANGE to SSCTP_SHUTDOWN_COMP\n");
+                if ( sctp_assoc_changed->sac_state == SCTP_RESTART) 
+                    SCTP_WARN("SCTP_ASSOC_CHANGE to SCTP_RESTART\n");
+                if ( sctp_assoc_changed->sac_state == SCTP_CANT_STR_ASSOC) 
+                    SCTP_ERROR("SCTP_ASSOC_CHANGE to SCTP_CANT_STR_ASSOC\n");
+                if ( sctp_assoc_changed->sac_state == SCTP_COMM_LOST) 
+                    SCTP_ERROR("SCTP_ASSOC_CHANGE to SCTP_COMM_LOST\n");
                 break;
             }
         }
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/UICC/usim_interface.c b/openair3/UICC/usim_interface.c
index 15a4e2e540e3b894b998d2c5628200d4ac05f74d..5d04f882859fe263dabc3c391957c5c4533813c3 100644
--- a/openair3/UICC/usim_interface.c
+++ b/openair3/UICC/usim_interface.c
@@ -20,9 +20,11 @@
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
+#include <ctype.h>
 
 #include <openair3/UICC/usim_interface.h>
 #include <openair3/NAS/COMMON/milenage.h>
+extern uint16_t NB_UE_INST;
 
 #define UICC_SECTION    "uicc"
 #define UICC_CONFIG_HELP_OPTIONS     " list of comma separated options to interface a simulated (real UICC to be developped). Available options: \n"\
@@ -34,18 +36,23 @@
 /*   optname                     helpstr                     paramflags           XXXptr                               defXXXval                          type         numelt  */
 /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define UICC_PARAMS_DESC {\
-    {"imsi",             "USIM IMSI\n",          0,         strptr:&(uicc->imsiStr),              defstrval:"",           TYPE_STRING,    0 },\
-    {"nmc_size"          "number of digits in NMC", 0,      iptr:&(uicc->nmc_size),               defintval:2,            TYPE_INT,       0 },\
-    {"key",              "USIM Ki\n",            0,         strptr:&(uicc->keyStr),               defstrval:"",           TYPE_STRING,    0 },\
-    {"opc",              "USIM OPc\n",           0,         strptr:&(uicc->opcStr),               defstrval:"",           TYPE_STRING,    0 },\
-    {"amf",              "USIM amf\n",           0,         strptr:&(uicc->amfStr),               defstrval:"8000",       TYPE_STRING,    0 },\
-    {"sqn",              "USIM sqn\n",           0,         strptr:&(uicc->sqnStr),               defstrval:"000000",     TYPE_STRING,    0 },\
+    {"imsi",             "USIM IMSI\n",          0,         strptr:&(uicc->imsiStr),              defstrval:"2089900007487",           TYPE_STRING,    0 },\
+    {"nmc_size"          "number of digits in NMC", 0,      iptr:&(uicc->nmc_size),               defintval:2,         TYPE_INT,       0 },\
+    {"key",              "USIM Ki\n",            0,         strptr:&(uicc->keyStr),               defstrval:"fec86ba6eb707ed08905757b1bb44b8f", TYPE_STRING,    0 },\
+    {"opc",              "USIM OPc\n",           0,         strptr:&(uicc->opcStr),               defstrval:"c42449363bbad02b66d16bc975d77cc1", TYPE_STRING,    0 },\
+    {"amf",              "USIM amf\n",           0,         strptr:&(uicc->amfStr),               defstrval:"8000",    TYPE_STRING,    0 },\
+    {"sqn",              "USIM sqn\n",           0,         strptr:&(uicc->sqnStr),               defstrval:"000000",  TYPE_STRING,    0 },\
+    {"dnn",              "UE dnn (apn)\n",       0,         strptr:&(uicc->dnnStr),               defstrval:"oai",     TYPE_STRING,    0 },\
+      {"nssai_sst",            "UE nssai\n",           0,         iptr:&(uicc->nssai_sst),             defintval:1,    TYPE_INT,    0 }, \
+      {"nssai_sd",            "UE nssai\n",           0,         iptr:&(uicc->nssai_sd),             defintval:1,    TYPE_INT,    0 }, \
   };
 
+static uicc_t** uiccArray=NULL;
+
 const char *hexTable="0123456789abcdef";
 static inline uint8_t mkDigit(unsigned char in) {
   for (int i=0; i<16; i++)
-    if (in==hexTable[i])
+    if (tolower(in)==hexTable[i])
       return i;
   LOG_E(SIM,"Impossible hexa input: %c\n",in);
   return 0;
@@ -65,7 +72,7 @@ uicc_t *init_uicc(char *sectionName) {
   // we can read the IMSI from the USIM
   // key, OPc, sqn, amf don't need to be read from the true USIM 
   int ret = config_get( uicc_params,sizeof(uicc_params)/sizeof(paramdef_t),sectionName);
-  AssertFatal(ret >= 0, "configuration couldn't be performed");
+  AssertFatal(ret >= 0, "configuration couldn't be performed for uicc name: %s", sectionName);
   LOG_I(SIM, "UICC simulation: IMSI=%s, Ki=%s, OPc=%s\n", uicc->imsiStr, uicc->keyStr, uicc->opcStr);
   to_hex(uicc->keyStr,uicc->key, sizeof(uicc->key) );
   to_hex(uicc->opcStr,uicc->opc, sizeof(uicc->opc) );
@@ -90,3 +97,15 @@ void uicc_milenage_generate(uint8_t *autn, uicc_t *uicc) {
   log_dump(SIM,autn,sizeof(autn), LOG_DUMP_CHAR,"milenage output autn:");
 }
 
+uicc_t * checkUicc(int Mod_id) {
+  AssertFatal(Mod_id < NB_UE_INST, "Mod_id must be less than NB_UE_INST. Mod_id:%d NB_UE_INST:%d", Mod_id,NB_UE_INST);
+  if(uiccArray==NULL){
+    uiccArray=(uicc_t **)calloc(1,sizeof(uicc_t*)*NB_UE_INST);
+  }
+  if (!uiccArray[Mod_id]) {
+    char uiccName[64];
+    sprintf(uiccName,"uicc%d",  Mod_id);
+    uiccArray[Mod_id]=(void*)init_uicc(uiccName);
+  }
+  return (uicc_t*) uiccArray[Mod_id];  
+}
diff --git a/openair3/UICC/usim_interface.h b/openair3/UICC/usim_interface.h
index e8f241c1e815403905a8a551237f6382ccb1a65e..eb32a6bfc1eb5d9e4a0ae0b4206d35ee0a6e2911 100644
--- a/openair3/UICC/usim_interface.h
+++ b/openair3/UICC/usim_interface.h
@@ -49,6 +49,9 @@ typedef struct {
   char *opcStr;
   char *amfStr;
   char *sqnStr;
+  char *dnnStr;
+  int  nssai_sst;
+  int  nssai_sd;
   uint8_t key[16];
   uint8_t opc[16];
   uint8_t amf[2];
@@ -66,6 +69,8 @@ typedef struct {
 /*
  * Read the configuration file, section name variable to be able to manage several UICC
  */
+uicc_t *checkUicc(int Mod_id);
 uicc_t *init_uicc(char *sectionName);
 void uicc_milenage_generate(uint8_t * autn, uicc_t *uicc);
+uicc_t * checkUicc(int Mod_id);
 #endif
diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c367374436fd9b3c78c518f7c198046b3510eb49
--- /dev/null
+++ b/openair3/ocp-gtpu/gtp_itf.cpp
@@ -0,0 +1,905 @@
+#include <map>
+using namespace std;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <netdb.h>
+
+#include <openair2/COMMON/platform_types.h>
+#include <openair3/UTILS/conversions.h>
+#include "common/utils/LOG/log.h"
+#include <common/utils/ocp_itti/intertask_interface.h>
+#include <openair2/COMMON/gtpv1_u_messages_types.h>
+#include <openair3/ocp-gtpu/gtp_itf.h>
+#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
+//#include <openair1/PHY/phy_extern.h>
+
+#pragma pack(1)
+
+typedef struct Gtpv1uMsgHeader {
+  uint8_t PN:1;
+  uint8_t S:1;
+  uint8_t E:1;
+  uint8_t spare:1;
+  uint8_t PT:1;
+  uint8_t version:3;
+  uint8_t msgType;
+  uint16_t msgLength;
+  teid_t teid;
+} __attribute__((packed)) Gtpv1uMsgHeaderT;
+
+#pragma pack()
+
+// TS 29.060, table 7.1 defines the possible message types
+// here are all the possible messages (3GPP R16)
+#define GTP_ECHO_REQ                                         (1)
+#define GTP_ECHO_RSP                                         (2)
+#define GTP_ERROR_INDICATION                                 (26)
+#define GTP_SUPPORTED_EXTENSION_HEADER_INDICATION            (31)
+#define GTP_END_MARKER                                       (254)
+#define GTP_GPDU                                             (255)
+
+
+typedef struct ocp_gtpv1u_bearer_s {
+  /* TEID used in dl and ul */
+  teid_t          teid_incoming;                ///< eNB TEID
+  teid_t          teid_outgoing;                ///< Remote TEID
+  in_addr_t       outgoing_ip_addr;
+  struct in6_addr outgoing_ip6_addr;
+  tcp_udp_port_t  outgoing_port;
+  uint16_t        seqNum;
+  uint8_t         npduNum;
+} ocp_gtpv1u_bearer_t;
+
+typedef struct {
+  map<int, ocp_gtpv1u_bearer_t> bearers;
+} teidData_t;
+
+typedef struct {
+  rnti_t rnti;
+  ebi_t incoming_rb_id;
+  gtpCallback callBack;
+} rntiData_t;
+
+class gtpEndPoint {
+ public:
+  openAddr_t addr;
+  uint8_t foundAddr[20];
+  int foundAddrLen;
+  int ipVersion;
+  map<int,teidData_t> ue2te_mapping;
+  map<int,rntiData_t> te2ue_mapping;
+};
+
+class gtpEndPoints {
+ public:
+  pthread_mutex_t gtp_lock=PTHREAD_MUTEX_INITIALIZER;
+  // the instance id will be the Linux socket handler, as this is uniq
+  map<int, gtpEndPoint> instances;
+};
+
+gtpEndPoints globGtp;
+
+// 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;
+  return g_gtpv1u_teid;
+#else
+  return random() + random() % (RAND_MAX - 1) + 1;
+#endif
+}
+
+int legacyInstanceMapping=0;
+#define compatInst(a) ((a)==0 || (a)==INSTANCE_DEFAULT?legacyInstanceMapping:a)
+
+#define GTPV1U_HEADER_SIZE                                  (8)
+static  int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, teid_t teid, uint8_t *Msg,int msgLen,
+                                   bool seqNumFlag, bool  npduNumFlag, bool extHdrFlag, int seqNum, int npduNum, int extHdrType) {
+  AssertFatal(extHdrFlag==false,"Not developped");
+  int headerAdditional=0;
+
+  if ( seqNumFlag || npduNumFlag || extHdrFlag)
+    headerAdditional=4;
+
+  uint8_t *buffer;
+  int fullSize=GTPV1U_HEADER_SIZE+headerAdditional+msgLen;
+  AssertFatal((buffer=(uint8_t *) malloc(fullSize)) != NULL, "");
+  Gtpv1uMsgHeaderT      *msgHdr = (Gtpv1uMsgHeaderT *)buffer ;
+  // N should be 0 for us (it was used only in 2G and 3G)
+  msgHdr->PN=npduNumFlag;
+  msgHdr->S=seqNumFlag;
+  msgHdr->E=extHdrFlag;
+  msgHdr->spare=0;
+  //PT=0 is for GTP' TS 32.295 (charging)
+  msgHdr->PT=1;
+  msgHdr->version=1;
+  msgHdr->msgType=GTP_GPDU;
+  msgHdr->msgLength=htons(msgLen);
+  if ( seqNumFlag || extHdrFlag || npduNumFlag)
+    msgHdr->msgLength+=4;
+  msgHdr->teid=htonl(teid);
+
+  if(seqNumFlag || extHdrFlag || npduNumFlag) {
+    *((uint16_t *) (buffer+8)) = seqNumFlag ? htons(seqNum) : 0x0000;
+    *((uint8_t *) (buffer+10)) = npduNumFlag ? htons(npduNum) : 0x00;
+    *((uint8_t *) (buffer+11)) = extHdrFlag ? htons(extHdrType) : 0x00;
+  }
+
+  memcpy(buffer+GTPV1U_HEADER_SIZE+headerAdditional, Msg, msgLen);
+  // Fix me: add IPv6 support, using flag ipVersion
+  static struct sockaddr_in to= {0};
+  to.sin_family      = AF_INET;
+  to.sin_port        = htons(peerPort);
+  to.sin_addr.s_addr = peerIp ;
+  LOG_D(GTPU,"sending packet size: %d to %s\n",fullSize, inet_ntoa(to.sin_addr) );
+
+  if (sendto(h, (void *)buffer, (size_t)fullSize, 0,(struct sockaddr *)&to, sizeof(to) ) != fullSize ) {
+    LOG_E(GTPU,
+          "[SD %d] Failed to send data to " IPV4_ADDR " on port %d, buffer size %u\n",
+          h, IPV4_ADDR_FORMAT(peerIp), peerPort, fullSize);
+    free(buffer);
+    return GTPNOK;
+  }
+
+  free(buffer);
+  return  !GTPNOK;
+}
+
+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;
+  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 %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 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) {
+  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 %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 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;
+  msgHdr.S=0;
+  msgHdr.E=0;
+  msgHdr.spare=0;
+  //PT=0 is for GTP' TS 32.295 (charging)
+  msgHdr.PT=1;
+  msgHdr.version=1;
+  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;
+  to.sin_port        = htons(tmp.outgoing_port);
+  to.sin_addr.s_addr = tmp.outgoing_ip_addr;
+
+  char ip4[INET_ADDRSTRLEN];
+  //char ip6[INET6_ADDRSTRLEN];
+  LOG_D(GTPU,"sending end packet to %s\n", inet_ntoa(to.sin_addr) );
+
+  if (sendto(compatInst(instance), (void *)&msgHdr, sizeof(msgHdr), 0,(struct sockaddr *)&to, sizeof(to) ) !=  sizeof(msgHdr)) {
+    LOG_E(GTPU,
+          "[SD %ld] Failed to send data to %s on port %d, buffer size %lu\n",
+          compatInst(instance), inet_ntop(AF_INET, &tmp.outgoing_ip_addr, ip4, INET_ADDRSTRLEN), 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;
+  struct addrinfo hints= {0}, *servinfo, *p;
+  hints.ai_family = AF_UNSPEC;
+  hints.ai_socktype = SOCK_DGRAM;
+  hints.ai_flags = AI_PASSIVE;
+
+  if ((status = getaddrinfo(addr.originHost, addr.originService, &hints, &servinfo)) != 0) {
+    LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status));
+    return -1;
+  }
+
+  int sockfd=-1;
+
+  // loop through all the results and bind to the first we can
+  for(p = servinfo; p != NULL; p = p->ai_next) {
+    if ((sockfd = socket(p->ai_family, p->ai_socktype,
+                         p->ai_protocol)) == -1) {
+      LOG_W(GTPU,"socket: %s\n", strerror(errno));
+      continue;
+    }
+
+    if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
+      close(sockfd);
+      LOG_W(GTPU,"bind: %s\n", strerror(errno));
+      continue;
+    } else {
+      // We create the gtp instance on the socket
+      globGtp.instances[sockfd].addr=addr;
+
+      if (p->ai_family == AF_INET) {
+        struct sockaddr_in *ipv4=(struct sockaddr_in *)p->ai_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;
+        break;
+      } else if (p->ai_family == AF_INET6) {
+        LOG_W(GTPU,"Local address is IP v6\n");
+        struct sockaddr_in6 *ipv6=(struct sockaddr_in6 *)p->ai_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;
+      } else
+        AssertFatal(false,"Local address is not IPv4 or IPv6");
+    }
+
+    break; // if we get here, we must have connected successfully
+  }
+
+  if (p == NULL) {
+    // looped off the end of the list with no successful bind
+    LOG_E(GTPU,"failed to bind socket: %s %s \n", addr.originHost, addr.originService);
+    return -1;
+  }
+
+  freeaddrinfo(servinfo); // all done with this structure
+
+  if (strlen(addr.destinationHost)>1) {
+    struct addrinfo hints;
+    memset(&hints,0,sizeof(hints));
+    hints.ai_family=AF_UNSPEC;
+    hints.ai_socktype=SOCK_DGRAM;
+    hints.ai_protocol=0;
+    hints.ai_flags=AI_PASSIVE|AI_ADDRCONFIG;
+    struct addrinfo *res=0;
+    int err=getaddrinfo(addr.destinationHost,addr.destinationService,&hints,&res);
+
+    if (err==0) {
+      for(p = res; p != NULL; p = p->ai_next) {
+        if ((err=connect(sockfd,  p->ai_addr, p->ai_addrlen))==0)
+          break;
+      }
+    }
+
+    if (err)
+      LOG_E(GTPU,"Can't filter remote host: %s, %s\n", addr.destinationHost,addr.destinationService);
+  }
+
+  int sendbuff = 1000*1000*10;
+  AssertFatal(0==setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)),"");
+  LOG_D(GTPU,"Created listener for paquets to: %s:%s, send buffer size: %d\n", addr.originHost, addr.originService,sendbuff);
+  return sockfd;
+}
+
+instance_t ocp_gtpv1Init(openAddr_t context) {
+  pthread_mutex_lock(&globGtp.gtp_lock);
+  int id=udpServerSocket(context);
+
+  if (id>=0) {
+    itti_subscribe_event_fd(OCP_GTPV1_U, id);
+  } else
+    LOG_E(GTPU,"can't create GTP-U instance\n");
+
+  pthread_mutex_unlock(&globGtp.gtp_lock);
+  return id;
+}
+
+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);
+
+  if ( it != inst->ue2te_mapping.end() ) {
+    LOG_W(GTPU,"Create a config for a already existing GTP tunnel (rnti %x)\n", rnti);
+    inst->ue2te_mapping.erase(it);
+  }
+
+  uint32_t incoming_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[incoming_teid].rnti=rnti;
+
+  inst->te2ue_mapping[incoming_teid].incoming_rb_id= incoming_bearer_id;
+
+  inst->te2ue_mapping[incoming_teid].callBack=callBack;
+
+  auto tmp=&inst->ue2te_mapping[rnti].bearers[outgoing_bearer_id];
+
+  int addrs_length_in_bytes = remoteAddr.length / 8;
+
+  switch (addrs_length_in_bytes) {
+    case 4:
+      memcpy(&tmp->outgoing_ip_addr,remoteAddr.buffer,4);
+      break;
+
+    case 16:
+      memcpy(tmp->outgoing_ip6_addr.s6_addr,remoteAddr.buffer,
+             16);
+      break;
+
+    case 20:
+      memcpy(&tmp->outgoing_ip_addr,remoteAddr.buffer,4);
+      memcpy(&tmp->outgoing_ip6_addr.s6_addr,
+             remoteAddr.buffer+4,
+             16);
+
+    default:
+      AssertFatal(false, "SGW Address size impossible");
+  }
+
+  tmp->teid_incoming = incoming_teid;
+  tmp->outgoing_port=port;
+  tmp->teid_outgoing= outgoing_teid;
+  pthread_mutex_unlock(&globGtp.gtp_lock);
+  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 %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,
+                                    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->enb_S1u_teid[i]=teid;
+    create_tunnel_resp->eps_bearer_id[i] = create_tunnel_req->eps_bearer_id[i];
+    memcpy(create_tunnel_resp->enb_addr.buffer,globGtp.instances[compatInst(instance)].foundAddr,
+           globGtp.instances[compatInst(instance)].foundAddrLen);
+    create_tunnel_resp->enb_addr.length= globGtp.instances[compatInst(instance)].foundAddrLen;
+  }
+
+  return !GTPNOK;
+}
+
+int ocp_gtpv1u_update_s1u_tunnel(
+  const instance_t                              instance,
+  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 %x, eps_bearer_id %x\n",
+        prior_rnti,
+        create_tunnel_req->rnti,
+        create_tunnel_req->num_tunnels,
+        create_tunnel_req->sgw_S1u_teid[0],
+        create_tunnel_req->eps_bearer_id[0]);
+  pthread_mutex_lock(&globGtp.gtp_lock);
+  auto inst=&globGtp.instances[compatInst(instance)];
+
+  if ( inst->ue2te_mapping.find(create_tunnel_req->rnti) == inst->ue2te_mapping.end() ) {
+    LOG_E(GTPU,"Update not already existing tunnel (new rnti %x, old rnti %x)\n", create_tunnel_req->rnti, prior_rnti);
+  }
+
+  auto it=inst->ue2te_mapping.find(prior_rnti);
+
+  if ( it != inst->ue2te_mapping.end() ) {
+    LOG_W(GTPU,"Update a not existing tunnel, start create the new one (new rnti %x, old rnti %x)\n", create_tunnel_req->rnti, prior_rnti);
+    pthread_mutex_unlock(&globGtp.gtp_lock);
+    gtpv1u_enb_create_tunnel_resp_t tmp;
+    (void)ocp_gtpv1u_create_s1u_tunnel(instance, create_tunnel_req, &tmp);
+    return 0;
+  }
+
+  inst->ue2te_mapping[create_tunnel_req->rnti]=it->second;
+  inst->ue2te_mapping.erase(it);
+  pthread_mutex_unlock(&globGtp.gtp_lock);
+  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->incoming_rb_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
+) {
+  AssertFatal( false, "to be developped\n");
+  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,
+  gtpv1u_enb_create_x2u_tunnel_resp_t *const create_tunnel_resp_pP) {
+  AssertFatal( false, "to be developped\n");
+}
+
+int newGtpuDeleteTunnel(instance_t instance, rnti_t rnti) {
+  LOG_D(GTPU, "Start delete tunnels for RNTI %x\n",
+        rnti);
+  pthread_mutex_lock(&globGtp.gtp_lock);
+  auto inst=&globGtp.instances[compatInst(instance)];
+  auto it=inst->ue2te_mapping.find(rnti);
+
+  if ( it == inst->ue2te_mapping.end() ) {
+    LOG_W(GTPU,"Delete a non existing GTP tunnel\n");
+    pthread_mutex_unlock(&globGtp.gtp_lock);
+    return -1;
+  }
+
+  int nb=0;
+
+  for (auto j=it->second.bearers.begin();
+       j!=it->second.bearers.end();
+       ++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;
+}
+
+// Legacy delete tunnel finish by deleting all the rnti
+// so the list of bearer provided is only a design bug
+int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance,
+                                  const gtpv1u_enb_delete_tunnel_req_t *const req_pP) {
+  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,
+                               uint16_t peerPort,
+                               uint32_t peerIp) {
+  LOG_E(GTPU,"to be dev\n");
+  int rc = GTPNOK;
+  return rc;
+}
+
+static int Gtpv1uHandleError(int h,
+                             uint8_t *msgBuf,
+                             uint32_t msgBufLen,
+                             uint16_t peerPort,
+                             uint32_t peerIp) {
+  LOG_E(GTPU,"to be dev\n");
+  int rc = GTPNOK;
+  return rc;
+}
+
+static int Gtpv1uHandleSupportedExt(int h,
+                                    uint8_t *msgBuf,
+                                    uint32_t msgBufLen,
+                                    uint16_t peerPort,
+                                    uint32_t peerIp) {
+  LOG_E(GTPU,"to be dev\n");
+  int rc = GTPNOK;
+  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
+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;
+  }
+
+  pthread_mutex_lock(&globGtp.gtp_lock);
+  // the socket Linux file handler is the instance id
+  auto inst=&globGtp.instances[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 (%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
+  protocol_ctxt_t ctxt;
+  ctxt.module_id = 0;
+  ctxt.enb_flag = 1;
+  ctxt.instance = inst->addr.originInstance;
+  ctxt.rnti = tunnel->second.rnti;
+  ctxt.frame = 0;
+  ctxt.subframe = 0;
+  ctxt.eNB_index = 0;
+  ctxt.configured = 0;
+  ctxt.brOption = 0;
+  const srb_flag_t     srb_flag=SRB_FLAG_NO;
+  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;
+  const uint32_t sourceL2Id=0;
+  const uint32_t destinationL2Id=0;
+  pthread_mutex_unlock(&globGtp.gtp_lock);
+
+  if ( !tunnel->second.callBack(&ctxt,
+                                srb_flag,
+                                rb_id,
+                                mui,
+                                confirm,
+                                0,
+                                NULL,
+                                mode,
+                                &sourceL2Id,
+                                &destinationL2Id) )
+    LOG_E(GTPU,"down layer refused incoming packet\n");
+
+  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,
+                            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;
+  }
+
+  pthread_mutex_lock(&globGtp.gtp_lock);
+  // the socket Linux file handler is the instance id
+  auto inst=&globGtp.instances[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 (%x) Dropping!\n", msgHdr->teid);
+    pthread_mutex_unlock(&globGtp.gtp_lock);
+    return GTPNOK;
+  }
+
+  int offset=8;
+
+  if( msgHdr->E ||  msgHdr->S ||msgHdr->PN)
+    offset+=8;
+
+  // This context is not good for gtp
+  // frame, ... has no meaning
+  // manyother attributes may come from create tunnel
+  protocol_ctxt_t ctxt;
+  ctxt.module_id = 0;
+  ctxt.enb_flag = 1;
+  ctxt.instance = inst->addr.originInstance;
+  ctxt.rnti = tunnel->second.rnti;
+  ctxt.frame = 0;
+  ctxt.subframe = 0;
+  ctxt.eNB_index = 0;
+  ctxt.configured = 0;
+  ctxt.brOption = 0;
+  const srb_flag_t     srb_flag=SRB_FLAG_NO;
+  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;
+  unsigned char *const sdu_buffer=msgBuf+offset;
+  const pdcp_transmission_mode_t mode=PDCP_TRANSMISSION_MODE_DATA;
+  const uint32_t sourceL2Id=0;
+  const uint32_t destinationL2Id=0;
+  pthread_mutex_unlock(&globGtp.gtp_lock);
+
+  if ( !tunnel->second.callBack(&ctxt,
+                                srb_flag,
+                                rb_id,
+                                mui,
+                                confirm,
+                                sdu_buffer_size,
+                                sdu_buffer,
+                                mode,
+                                &sourceL2Id,
+                                &destinationL2Id) )
+    LOG_E(GTPU,"down layer refused incoming packet\n");
+
+  LOG_D(GTPU,"Received a %d bytes packet for: teid:%x\n",
+        msgBufLen-offset,
+        ntohl(msgHdr->teid));
+  return !GTPNOK;
+}
+
+void gtpv1uReceiver(int h) {
+  uint8_t                   udpData[65536];
+  int               udpDataLen;
+  socklen_t          from_len;
+  struct sockaddr_in addr;
+  from_len = (socklen_t)sizeof(struct sockaddr_in);
+
+  if ((udpDataLen = recvfrom(h, udpData, sizeof(udpData), 0,
+                             (struct sockaddr *)&addr, &from_len)) < 0) {
+    LOG_E(GTPU, "Recvfrom failed on %d (%s)\n", h, strerror(errno));
+    return;
+  } else if (udpDataLen == 0) {
+    LOG_W(GTPU, "Recvfrom returned 0\n");
+    return;
+  } else {
+    uint8_t msgType = *((uint8_t *)(udpData + 1));
+    LOG_D(GTPU, "Received GTP data, msg type: %x\n", msgType);
+
+    switch(msgType) {
+      case GTP_ECHO_RSP:
+        break;
+
+      case GTP_ECHO_REQ:
+        Gtpv1uHandleEchoReq( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr);
+        break;
+
+      case GTP_ERROR_INDICATION:
+        Gtpv1uHandleError( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr);
+        break;
+
+      case GTP_SUPPORTED_EXTENSION_HEADER_INDICATION:
+        Gtpv1uHandleSupportedExt( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr);
+        break;
+
+      case GTP_END_MARKER:
+        Gtpv1uHandleEndMarker( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr);
+        break;
+
+      case GTP_GPDU:
+        Gtpv1uHandleGpdu( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr);
+        break;
+
+      default:
+        LOG_E(GTPU, "Received a GTP packet of unknown type: %d\n",msgType);
+        break;
+    }
+  }
+}
+
+#include <openair2/ENB_APP/enb_paramdef.h>
+
+void *ocp_gtpv1uTask(void *args)  {
+  while(1) {
+    /* Trying to fetch a message from the message queue.
+       If the queue is empty, this function will block till a
+       message is sent to the task.
+    */
+    MessageDef *message_p = NULL;
+    itti_receive_msg(OCP_GTPV1_U, &message_p);
+
+    if (message_p != NULL ) {
+      openAddr_t addr= {0};
+
+      switch (ITTI_MSG_ID(message_p)) {
+        // DATA TO BE SENT TO UDP
+        case GTPV1U_ENB_TUNNEL_DATA_REQ: {
+          gtpv1uSend(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)),
+                     &GTPV1U_ENB_TUNNEL_DATA_REQ(message_p), false, false);
+          itti_free(OCP_GTPV1_U, GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer);
+        }
+        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_DATA_FORWARDING_IND:
+        case GTPV1U_ENB_END_MARKER_IND:
+          LOG_E(GTPU, "to be developped %s\n", ITTI_MSG_NAME(message_p));
+          abort();
+          break;
+
+        case GTPV1U_ENB_S1_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;
+
+        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();
+          break;
+      }
+
+      AssertFatal(EXIT_SUCCESS==itti_free(OCP_GTPV1_U, message_p), "Failed to free memory!\n");
+    }
+
+    struct epoll_event *events;
+
+    int nb_events = itti_get_events(OCP_GTPV1_U, &events);
+
+    for (int i = 0; i < nb_events; i++)
+      if ((events[i].events&EPOLLIN))
+        gtpv1uReceiver(events[i].data.fd);
+  }
+
+  return NULL;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd406e27cddc579eca574453c96b7ce2a2abd40b
--- /dev/null
+++ b/openair3/ocp-gtpu/gtp_itf.h
@@ -0,0 +1,71 @@
+#ifndef __GTPUNEW_ITF_H__
+#define __GTPUNEW_ITF_H__
+#define GTPNOK -1
+
+# define GTPU_HEADER_OVERHEAD_MAX 64
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <openair3/GTPV1-U/gtpv1u_eNB_defs.h>
+#if defined(NEW_GTPU)
+#define gtpv1u_create_s1u_tunnel ocp_gtpv1u_create_s1u_tunnel
+#define gtpv1u_update_s1u_tunnel ocp_gtpv1u_update_s1u_tunnel
+#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 nr_gtpv1u_gNB_task       ocp_gtpv1uTask
+#define TASK_VARIABLE            OCP_GTPV1_U
+#else
+#define TASK_VARIABLE            TASK_GTPV1_U
+#endif
+
+typedef boolean_t (*gtpCallback)(
+  protocol_ctxt_t  *ctxt_pP,
+  const srb_flag_t     srb_flagP,
+  const rb_id_t        rb_idP,
+  const mui_t          muiP,
+  const confirm_t      confirmP,
+  const sdu_size_t     sdu_buffer_sizeP,
+  unsigned char *const sdu_buffer_pP,
+  const pdcp_transmission_mode_t modeP,
+  const uint32_t *sourceL2Id,
+  const uint32_t *destinationL2Id);
+
+typedef struct openAddr_s {
+  char originHost[HOST_NAME_MAX];
+  char originService[HOST_NAME_MAX];
+  char destinationHost[HOST_NAME_MAX];
+  char destinationService[HOST_NAME_MAX];
+  instance_t originInstance;
+} openAddr_t;
+
+// the init function create a gtp instance and return the gtp instance id
+// the parameter originInstance will be sent back in each message from gtp to the creator
+void ocp_gtpv1uReceiver(int h);
+void ocp_gtpv1uProcessTimeout(int handle,void *arg);
+int ocp_gtpv1u_create_s1u_tunnel(const instance_t instance, const gtpv1u_enb_create_tunnel_req_t  *create_tunnel_req,
+                                 gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp);
+int ocp_gtpv1u_update_s1u_tunnel(const instance_t instanceP,
+                                 const gtpv1u_enb_create_tunnel_req_t   *create_tunnel_req_pP,
+                                 const rnti_t prior_rnti
+                                );
+int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP);
+int gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP);
+
+int ocp_gtpv1u_create_x2u_tunnel(
+  const instance_t instanceP,
+  const gtpv1u_enb_create_x2u_tunnel_req_t   *const create_tunnel_req_pP,
+  gtpv1u_enb_create_x2u_tunnel_resp_t *const create_tunnel_resp_pP);
+
+
+// New API
+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);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openshift/oai-physim-image-stream.yml b/openshift/oai-physim-image-stream.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9ef338f139a347f434badb8fc137e55bb497b4d5
--- /dev/null
+++ b/openshift/oai-physim-image-stream.yml
@@ -0,0 +1,29 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+apiVersion: image.openshift.io/v1
+kind: ImageStream
+metadata:
+  name: oai-physim
+spec:
+  lookupPolicy:
+    local: true
diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c
index 3a69d4c991f1de68e057875691d718f1433e5d9f..2758d01de3f11ae06217a1a7d705194d42e96520 100644
--- a/targets/ARCH/COMMON/common_lib.c
+++ b/targets/ARCH/COMMON/common_lib.c
@@ -40,7 +40,8 @@
 #include "assertions.h"
 #include "common/utils/load_module_shlib.h"
 #include "common/utils/LOG/log.h"
-#include "targets/RT/USER/lte-softmodem.h"
+//#include "targets/RT/USER/lte-softmodem.h"
+#include "executables/softmodem-common.h"
 
 char *get_devname(int devtype) {
 char *devnames[MAX_RF_DEV_TYPE]=DEVTYPE_NAMES;
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index 93e9ffb52f8d908c5f6da1dbcf56bdd68db50aad..7b934822ea24b389445251c45bb96476c967af99 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -33,6 +33,7 @@
 #ifndef COMMON_LIB_H
 #define COMMON_LIB_H
 #include <stdint.h>
+#include <stdio.h>
 #include <sys/types.h>
 #include <openair1/PHY/TOOLS/tools_defs.h>
 #include "record_player.h"
@@ -560,7 +561,10 @@ extern int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **r
 extern void iqrecorder_end(openair0_device *device);
 
 
+#include <unistd.h>
+#ifndef gettid
 #define gettid() syscall(__NR_gettid)
+#endif
 /*@}*/
 
 
diff --git a/targets/ARCH/COMMON/record_player.c b/targets/ARCH/COMMON/record_player.c
index 2dcd61e47949be1b2311c905e89d62221ffaaf40..522f6b6d166e7aa7a60f28f2e92cd0f28c1772ef 100644
--- a/targets/ARCH/COMMON/record_player.c
+++ b/targets/ARCH/COMMON/record_player.c
@@ -68,8 +68,10 @@ int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_
     *recplay_conf=NULL;
   }
 
-  if (u_sf_replay == 1) return RECPLAY_REPLAYMODE;
-  else if (u_sf_record == 1) return RECPLAY_RECORDMODE;
+  if (u_sf_replay == 1)
+    return RECPLAY_REPLAYMODE;
+  else if (u_sf_record == 1)
+    return RECPLAY_RECORDMODE;
 
   return 0;
 }
@@ -80,7 +82,7 @@ int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_
  */
 void iqrecorder_end(openair0_device *device) {
   if (device->recplay_state != NULL) { // subframes store
-    iqfile_header_t    fh = {device->type,device->openair0_cfg->tx_sample_advance, device->openair0_cfg->rx_bw,OAIIQFILE_ID};
+    iqfile_header_t    fh = {device->type,device->openair0_cfg->tx_sample_advance, device->openair0_cfg->rx_bw,0,OAIIQFILE_ID};
     recplay_state_t *rs = device->recplay_state;
     recplay_conf_t  *rc = device->openair0_cfg[0].recplay_conf;
     rs->pFile = fopen (rc->u_sf_filename,"wb+");
@@ -91,16 +93,20 @@ void iqrecorder_end(openair0_device *device) {
       unsigned int i = 0;
       unsigned int modu = 0;
 
-      if ((modu = rs->nb_samples % 10) != 0) {
-        rs->nb_samples -= modu; // store entire number of frames
+      if ((modu = rs->nbSamplesBlocks % 10) != 0) {
+        rs->nbSamplesBlocks -= modu; // store entire number of frames
       }
 
+      fh.nbSamplesBlocks=rs->nbSamplesBlocks;
       LOG_I(HW,"Writing file header to %s \n", rc->u_sf_filename );
       fwrite(&fh, sizeof(fh), 1, rs->pFile);
-      LOG_UI(HW,"Writing %u subframes to %s \n",rs->nb_samples, rc->u_sf_filename );
+      LOG_UI(HW,"Writing %u subframes to %s \n",rs->nbSamplesBlocks, rc->u_sf_filename );
+      uint8_t *ptr=(uint8_t *)rs->ms_sample;
 
-      for (i = 0; i < rs->nb_samples; i++) {
-        fwrite(rs->ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), rs->pFile);
+      for (i = 0; i < rs->nbSamplesBlocks; i++) {
+        int blockBytes=sizeof(iqrec_t)+((iqrec_t *)ptr)->nbBytes;
+        fwrite(ptr, sizeof(unsigned char), blockBytes, rs->pFile);
+        ptr+=blockBytes;
       }
 
       fclose (rs->pFile);
@@ -112,4 +118,4 @@ void iqrecorder_end(openair0_device *device) {
       rs->ms_sample = NULL;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/targets/ARCH/COMMON/record_player.h b/targets/ARCH/COMMON/record_player.h
index 500acdd709950c167f4513e87b30f65a7f5bb6f7..d91da6832308eb8db2dfa949feb39f44a0eaf030 100644
--- a/targets/ARCH/COMMON/record_player.h
+++ b/targets/ARCH/COMMON/record_player.h
@@ -46,21 +46,22 @@ extern "C"
 #define BELL_LABS_IQ_HEADER       0xabababababababab
 #define BELL_LABS_IQ_PER_SF       7680 // Up to 5MHz bw for now
 #define BELL_LABS_IQ_BYTES_PER_SF (BELL_LABS_IQ_PER_SF * 4)
+#define MAX_BELL_LABS_IQ_BYTES_PER_SF  BELL_LABS_IQ_BYTES_PER_SF*10
 
-#define    OAIIQFILE_ID "OIQF"
+#define OAIIQFILE_ID {'O', 'I','Q','F'}
 typedef struct {
   uint64_t      devtype;
   uint64_t      tx_sample_advance;
   double        bw;
+  unsigned int  nbSamplesBlocks;
   char          oaiid[4];
 } iqfile_header_t;
 
 typedef struct {
   int64_t       header;
   int64_t       ts;
-  int64_t       rfu1;
+  int64_t       nbBytes;
   int64_t       rfu2; // pad for 256 bits alignement required by AVX2
-  unsigned char samples[BELL_LABS_IQ_BYTES_PER_SF]; // iq's for one subframe
 } iqrec_t;
 #define DEF_NB_SF           120000               // default nb of sf or ms to capture (2 minutes at 5MHz)
 #define DEF_SF_FILE         "/tmp/iqfile"        // default subframes file name
@@ -114,14 +115,16 @@ typedef struct {
   int             use_mmap; // default is to use mmap
   size_t          mapsize;
   FILE            *pFile;
-  int             mmapfd;
-  int             iqfd;
+  int             fd;
   iqrec_t        *ms_sample;                      // memory for all subframes
-  unsigned int    nb_samples;
+  unsigned int    nbSamplesBlocks;
+  uint8_t        *currentPtr;
+  uint64_t        currentTs;
+  unsigned int    curSamplesBlock;
+  int64_t         wrap_count;
+  size_t          maxSizeBytes;
 } recplay_state_t;
 
-
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
index 2dfb4a7bf1321c253105a0e0971bd9cdfa60b6d3..ee0dce48f0976346210f659230e017f99059cb05 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
@@ -45,7 +45,6 @@
 
 #include "common_lib.h"
 #include "ethernet_lib.h"
-#include "common/ran_context.h"
 
 //#define DEBUG 1
 
@@ -414,7 +413,7 @@ int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, voi
   char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES;  
 #endif
 #elif defined(__arm__) || defined(__aarch64__)
-  int nsamps2 = (payload_size>>4)+1
+  int nsamps2 = (payload_size>>4)+1;
   int16x8_t temp_rx[nsamps2];
   char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES;  
 #else
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
index dce410de47e0fb1dcd49dc8258c7d5606e8b26d3..c15bdc37cb459866c096e1180385a3a2c8fc5414 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
@@ -42,7 +42,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <linux/sysctl.h>
-#include <sys/sysctl.h>
 
 #include "common_lib.h"
 #include "ethernet_lib.h"
@@ -219,11 +218,6 @@ int ethernet_tune(openair0_device *device,
     struct timeval timeout;
     struct ifreq ifr;
     char system_cmd[256];
-    int rname[] = { CTL_NET, NET_CORE, NET_CORE_RMEM_MAX };
-    int wname[] = { CTL_NET, NET_CORE, NET_CORE_WMEM_MAX };
-    int namelen=3;
-    int newval[1];
-    int newlen=sizeof(newval);
     int ret=0;
     //  int i=0;
 
@@ -363,28 +357,36 @@ int ethernet_tune(openair0_device *device,
         }
         break;
     case KERNEL_RCV_BUF_MAX_SIZE:
-        newval[0] = value;
-        ret=sysctl(rname, namelen, NULL, 0, newval, newlen);
-        if (ret) {
-            fprintf(stderr,"[ETHERNET] Error using sysctl():%s\n",strerror(errno));
-        } else {
-            printf("[ETHERNET] Kernel network receive buffer max size is set to %u\n",(unsigned int)newval[0]);
-        }
-        break;
+      ret=snprintf(system_cmd,sizeof(system_cmd),"sysctl -w net.core.rmem_max=%d",value);
+      if (ret > 0) {
+	ret=system(system_cmd);
+	if (ret == -1) {
+	  fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
+	} else {
+	  printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret));
+	}
+	printf("[ETHERNET] net core rmem %s\n",system_cmd);
+      } else {
+	perror("[ETHERNET] Can't set net core rmem\n");
+      }
+      break;
     case KERNEL_SND_BUF_MAX_SIZE:
-        newval[0] = value;
-        ret=sysctl(wname, namelen, NULL, 0, newval, newlen);
-        if (ret) {
-            fprintf(stderr,"[ETHERNET] Error using sysctl():%s\n",strerror(errno));
-        } else {
-            printf("[ETHERNET] Kernel network send buffer max size is set to %u\n",(unsigned int)newval[0]);
-        }
-        break;
-
+      ret=snprintf(system_cmd,sizeof(system_cmd),"sysctl -w net.core.wmem_max=%d",value);
+      if (ret > 0) {
+	ret=system(system_cmd);
+	if (ret == -1) {
+	  fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
+	} else {
+	  printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret));
+	}
+	printf("[ETHERNET] net core wmem %s\n",system_cmd);
+      } else {
+	perror("[ETHERNET] Can't set net core wmem\n");
+      }
+      break;
     default:
         break;
     }
-
     return 0;
 }
 
diff --git a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c
index 88f4ecb4cdebde52d1f8ce2997ad34762c1b5364..9b398e9bd951eb0c70b4c27e902adc2f5703748f 100644
--- a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c
+++ b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c
@@ -312,14 +312,13 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs)
                 oai_slot = tx_subframe * 2 + tx_slot;
                 lock_dl_buffer(bs->buffers, oai_slot);
                 if (!(bs->buffers->dl_busy[a][oai_slot] & (1 << tx_symbol))) {
-                  printf("%s: warning, DL underflow (antenna %d sl.symbol %d.%d)\n", __FUNCTION__,
-                         a, oai_slot, tx_symbol);
+                  //printf("%s: warning, DL underflow (antenna %d sl.symbol %d.%d)\n", __FUNCTION__,a, oai_slot, tx_symbol);
                   memset(IQ_ptr, 0, 1272 * 4);
                 } else {
                   memcpy(IQ_ptr, bs->buffers->dl[a][oai_slot] + tx_symbol * 1272*4,
                          1272*4);
                 }
-//printf("DL buffer f sf slot symbol %d %d %d %d (sf %d)\n", tx_frame, tx_subframe, tx_slot, tx_symbol, (int)sf);
+	        //printf("DL buffer f sf slot symbol %d %d %d %d (sf %d)\n", tx_frame, tx_subframe, tx_slot, tx_symbol, (int)sf);
                 bs->buffers->dl_busy[a][oai_slot] &= ~(1 << tx_symbol);
                 unlock_dl_buffer(bs->buffers, oai_slot);
 	}
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index dd29d01fae751ebc527ea59dc1423ed29475150f..877f60799049d0d7a3f963fe24c9cec81d5a3809 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -153,7 +153,7 @@ int check_ref_locked(usrp_state_t *s,size_t mboard) {
 }
 
 static int sync_to_gps(openair0_device *device) {
-  uhd::set_thread_priority_safe();
+  //uhd::set_thread_priority_safe();
   //std::string args;
   //Set up program options
   //po::options_description desc("Allowed options");
@@ -276,7 +276,7 @@ static int trx_usrp_start(openair0_device *device) {
   // setup GPIO for TDD, GPIO(4) = ATR_RX
   //set data direction register (DDR) to output
   s->usrp->set_gpio_attr("FP0", "DDR", 0xfff, 0xfff);
-  //set lower 7 bits to be controlled automatically by ATR (the rest 5 bits are controlled manually) 
+  //set lower 7 bits to be controlled automatically by ATR (the rest 5 bits are controlled manually)
   s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0xfff);
   //set pins 4 (RX_TX_Switch) and 6 (Shutdown PA) to 1 when the radio is only receiving (ATR_RX)
   s->usrp->set_gpio_attr("FP0", "ATR_RX", (1<<4)|(1<<6), 0x7f);
@@ -301,7 +301,7 @@ static int trx_usrp_start(openair0_device *device) {
   }
 
   uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
-  cmd.time_spec = uhd::time_spec_t(1.0);    
+  cmd.time_spec = uhd::time_spec_t(1.0);
   cmd.stream_now = false; // start at constant delay
   s->rx_stream->issue_stream_cmd(cmd);
 
@@ -315,7 +315,7 @@ static void trx_usrp_end(openair0_device *device) {
     return;
 
   usrp_state_t *s = (usrp_state_t *)device->priv;
-  
+
   if (s == NULL)
     return;
   iqrecorder_end(device);
@@ -385,14 +385,14 @@ static int trx_usrp_write(openair0_device *device,
 #if defined(__x86_64) || defined(__i386__)
   #ifdef __AVX2__
       nsamps2 = (nsamps+7)>>3;
-      __m256i buff_tx[8][nsamps2];
+      __m256i buff_tx[cc<2?2:cc][nsamps2];
   #else
     nsamps2 = (nsamps+3)>>2;
-    __m128i buff_tx[8][nsamps2];
+    __m128i buff_tx[cc<2?2:cc][nsamps2];
   #endif
 #elif defined(__arm__)
     nsamps2 = (nsamps+3)>>2;
-    int16x8_t buff_tx[8][nsamps2];
+    int16x8_t buff_tx[cc<2?2:cc][nsamps2];
 #else
 #error Unsupported CPU architecture, USRP device cannot be built
 #endif
@@ -436,7 +436,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHI
         buff_ptrs.push_back(&(((int16_t *)buff_tx[i])[0]));
 
       ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md);
-    } 
+    }
     else {
       ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md);
     }
@@ -464,6 +464,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHI
       write_package[end].buff[i]    = buff[i];
     write_thread->count_write++;
     write_thread->end = (write_thread->end + 1)% MAX_WRITE_THREAD_PACKAGE;
+    LOG_D(HW,"Signaling TX TS %llu\n",(unsigned long long)timestamp);
     pthread_cond_signal(&write_thread->cond_write);
     pthread_mutex_unlock(&write_thread->mutex_write);
     return 0;
@@ -480,7 +481,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHI
       @param antenna_id index of the antenna if the device has multiple antennas
       @param flags flags must be set to TRUE if timestamp parameter needs to be applied
 */
-void *trx_usrp_write_thread(void * arg){ 
+void *trx_usrp_write_thread(void * arg){
   int ret=0;
   openair0_device *device=(openair0_device *)arg;
   openair0_thread_t *write_thread = &device->write_thread;
@@ -522,14 +523,14 @@ void *trx_usrp_write_thread(void * arg){
     #if defined(__x86_64) || defined(__i386__)
       #ifdef __AVX2__
         nsamps2 = (nsamps+7)>>3;
-        __m256i buff_tx[8][nsamps2];
+        __m256i buff_tx[cc<2?2:cc][nsamps2];
       #else
         nsamps2 = (nsamps+3)>>2;
-        __m128i buff_tx[8][nsamps2];
+        __m128i buff_tx[cc<2?2:cc][nsamps2];
       #endif
     #elif defined(__arm__)
       nsamps2 = (nsamps+3)>>2;
-      int16x8_t buff_tx[8][nsamps2];
+      int16x8_t buff_tx[cc<2?2:cc][nsamps2];
     #else
     #error Unsupported CPU architecture, USRP device cannot be built
     #endif
@@ -549,7 +550,7 @@ void *trx_usrp_write_thread(void * arg){
       }
     }
 
-    
+
     s->tx_md.has_time_spec  = true;
     s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet;
     s->tx_md.end_of_burst   = last_packet;
@@ -572,7 +573,7 @@ void *trx_usrp_write_thread(void * arg){
         buff_ptrs.push_back(&(((int16_t *)buff_tx[i])[0]));
 
       ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md);
-    } 
+    }
     else {
       ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md);
     }
@@ -581,7 +582,6 @@ void *trx_usrp_write_thread(void * arg){
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_USRP_SEND_RETURN, ret );
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_THREAD, 0 );
 
-    if(0) break;
   }
 
   return NULL;
@@ -589,7 +589,7 @@ void *trx_usrp_write_thread(void * arg){
 
 int trx_usrp_write_init(openair0_device *device){
 
-  uhd::set_thread_priority_safe(1.0);
+  //uhd::set_thread_priority_safe(1.0);
   openair0_thread_t *write_thread = &device->write_thread;
   printf("initializing tx write thread\n");
 
@@ -597,7 +597,8 @@ int trx_usrp_write_init(openair0_device *device){
   write_thread->end                = 0;
   write_thread->count_write        = 0;
   printf("end of tx write thread\n");
-
+  pthread_mutex_init(&write_thread->mutex_write, NULL);
+  pthread_cond_init(&write_thread->cond_write, NULL);
   pthread_create(&write_thread->pthread_write,NULL,trx_usrp_write_thread,(void *)device);
 
   return(0);
@@ -623,40 +624,53 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
 #if defined(__x86_64) || defined(__i386__)
 #ifdef __AVX2__
   nsamps2 = (nsamps+7)>>3;
-  __m256i buff_tmp[2][nsamps2];
+  __m256i buff_tmp[cc<2 ? 2 : cc][nsamps2];
 #else
   nsamps2 = (nsamps+3)>>2;
-  __m128i buff_tmp[2][nsamps2];
+  __m128i buff_tmp[cc<2 ? 2 : cc][nsamps2];
 #endif
 #elif defined(__arm__)
   nsamps2 = (nsamps+3)>>2;
-  int16x8_t buff_tmp[2][nsamps2];
+  int16x8_t buff_tmp[cc<2 ? 2 : cc][nsamps2];
 #endif
 
-    if (cc>1) {
+  int rxshift;
+  switch (device->type) {
+     case USRP_B200_DEV:
+        rxshift=4;
+        break;
+     case USRP_X300_DEV:
+     case USRP_N300_DEV:
+        rxshift=2;
+        break;
+     default:
+       AssertFatal(1==0,"Shouldn't be here\n");
+  }
+
+    samples_received=0;
+    while (samples_received != nsamps) {
+
+      if (cc>1) {
       // receive multiple channels (e.g. RF A and RF B)
-      std::vector<void *> buff_ptrs;
+        std::vector<void *> buff_ptrs;
 
-      for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]);
+        for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]+samples_received);
 
-      samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md);
-    } else {
+        samples_received += s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md);
+      } else {
       // receive a single channel (e.g. from connector RF A)
-      samples_received=0;
 
-      while (samples_received != nsamps) {
         samples_received += s->rx_stream->recv((void*)((int32_t*)buff_tmp[0]+samples_received),
                                                nsamps-samples_received, s->rx_md);
+      }
+      if  ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE))
+        break;
 
-        if  ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE))
-          break;
-
-        if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) {
-          printf("sleep...\n"); //usleep(100);
-        }
+      if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) {
+        printf("sleep...\n"); //usleep(100);
       }
-      if (samples_received == nsamps) s->wait_for_first_pps=0;
     }
+    if (samples_received == nsamps) s->wait_for_first_pps=0;
 
     // bring RX data into 12 LSBs for softmodem RX
     for (int i=0; i<cc; i++) {
@@ -666,17 +680,17 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
         // FK: in some cases the buffer might not be 32 byte aligned, so we cannot use avx2
 
         if ((((uintptr_t) buff[i])&0x1F)==0) {
-          ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4);
+          ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],rxshift);
         } else {
-          ((__m128i *)buff[i])[2*j] = _mm_srai_epi16(((__m128i *)buff_tmp[i])[2*j],4);
-          ((__m128i *)buff[i])[2*j+1] = _mm_srai_epi16(((__m128i *)buff_tmp[i])[2*j+1],4);
+          ((__m128i *)buff[i])[2*j] = _mm_srai_epi16(((__m128i *)buff_tmp[i])[2*j],rxshift);
+          ((__m128i *)buff[i])[2*j+1] = _mm_srai_epi16(((__m128i *)buff_tmp[i])[2*j+1],rxshift);
         }
 
 #else
-        ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4);
+        ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],rxshift);
 #endif
 #elif defined(__arm__)
-        ((int16x8_t *)buff[i])[j] = vshrq_n_s16(buff_tmp[i][j],4);
+        ((int16x8_t *)buff[i])[j] = vshrq_n_s16(buff_tmp[i][j],rxshift);
 #endif
       }
     }
@@ -697,15 +711,23 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
    s->usrp->set_gpio_attr("FP0", "OUT", gpio789<<7, 0x380);
    s->usrp->clear_command_time();
    gpio789 = (gpio789+1)&7;*/
+  recplay_state_t *recPlay=device->recplay_state;
 
-  if (device->recplay_state != NULL) { // record mode
+  if ( recPlay != NULL) { // record mode
     // Copy subframes to memory (later dump on a file)
-    if (device->recplay_state->nb_samples < device->openair0_cfg->recplay_conf->u_sf_max) {
-      (device->recplay_state->ms_sample+device->recplay_state->nb_samples)->header = BELL_LABS_IQ_HEADER;
-      (device->recplay_state->ms_sample+device->recplay_state->nb_samples)->ts = *ptimestamp;
-      memcpy((device->recplay_state->ms_sample+device->recplay_state->nb_samples)->samples, buff[0], nsamps*4);
-      device->recplay_state->nb_samples++;
-    } else     exit_function(__FILE__, __FUNCTION__, __LINE__,"Recording reaches max iq limit\n");
+    if (recPlay->nbSamplesBlocks < device->openair0_cfg->recplay_conf->u_sf_max &&
+        recPlay->maxSizeBytes > (recPlay->currentPtr-(uint8_t *)recPlay->ms_sample) +
+        sizeof(iqrec_t) + nsamps*4 ) {
+      iqrec_t *hdr=(iqrec_t *)recPlay->currentPtr;
+      hdr->header = BELL_LABS_IQ_HEADER;
+      hdr->ts = *ptimestamp;
+      hdr->nbBytes=nsamps*4;
+      memcpy(hdr+1, buff[0], nsamps*4);
+      recPlay->currentPtr+=sizeof(iqrec_t)+nsamps*4;
+      recPlay->nbSamplesBlocks++;
+      LOG_D(HW,"recorded %d samples, for TS %lu, shift in buffer %ld\n", nsamps, hdr->ts, recPlay->currentPtr-(uint8_t *)recPlay->ms_sample);
+    } else
+      exit_function(__FILE__, __FUNCTION__, __LINE__,"Recording reaches max iq limit\n");
   }
 
   return samples_received;
@@ -915,8 +937,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) {
@@ -940,29 +962,29 @@ extern "C" {
 
 
     // hotfix! to be checked later
-    uhd::set_thread_priority_safe(1.0);
+    //uhd::set_thread_priority_safe(1.0);
     // Initialize USRP device
     int vers=0,subvers=0,subsubvers=0;
     int bw_gain_adjust=0;
-  
+
     if (device->openair0_cfg->recplay_mode == RECPLAY_RECORDMODE) {
       std::cerr << "USRP device initialized in subframes record mode" << std::endl;
     }
-  
+
     sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers);
     LOG_I(HW,"UHD version %s (%d.%d.%d)\n",
           uhd::get_version_string().c_str(),vers,subvers,subsubvers);
     std::string args;
-  
+
     if (openair0_cfg[0].sdr_addrs == NULL) {
       args = "type=b200";
     } else {
       args = openair0_cfg[0].sdr_addrs;
       LOG_I(HW,"Checking for USRP with args %s\n",openair0_cfg[0].sdr_addrs);
     }
-  
+
     uhd::device_addrs_t device_adds = uhd::device::find(args);
-  
+
     if (device_adds.size() == 0) {
       LOG_E(HW,"No USRP Device Found.\n ");
       free(s);
@@ -972,52 +994,52 @@ extern "C" {
       free(s);
       return -1;
     }
-  
+
     LOG_I(HW,"Found USRP %s\n", device_adds[0].get("type").c_str());
     double usrp_master_clock;
-  
+
     if (device_adds[0].get("type") == "b200") {
       device->type = USRP_B200_DEV;
       usrp_master_clock = 30.72e6;
       args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock);
       args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=7680, recv_frame_size=7680" ;
     }
-  
+
     if (device_adds[0].get("type") == "n3xx") {
       printf("Found USRP n300\n");
-      device->type=USRP_N300_DEV; 
+      device->type=USRP_N300_DEV;
       usrp_master_clock = 122.88e6;
       args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock);
       //args += ", send_buff_size=33554432";
     }
-  
+
     if (device_adds[0].get("type") == "x300") {
       printf("Found USRP x300\n");
       device->type=USRP_X300_DEV;
       usrp_master_clock = 184.32e6;
       args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock);
-  
+
       // USRP recommended: https://files.ettus.com/manual/page_usrp_x3x0_config.html
       if ( 0 != system("sysctl -w net.core.rmem_max=33554432 net.core.wmem_max=33554432") )
         LOG_W(HW,"Can't set kernel parameters for X3xx\n");
     }
-  
+
     s->usrp = uhd::usrp::multi_usrp::make(args);
-  
+
     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 { 
+	else {
 	  LOG_W(HW,"Clock source set neither in usrp_args nor on command line, using default!\n");
 	}
     }
@@ -1030,17 +1052,17 @@ 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 { 
+	else {
 	  LOG_W(HW,"Time source set neither in usrp_args nor on command line, using default!\n");
 	}
     }
@@ -1050,10 +1072,10 @@ extern "C" {
 	}
   }
 
-    
+
   if (s->usrp->get_clock_source(0) == "gpsdo") {
     s->use_gps = 1;
-  
+
     if (sync_to_gps(device)==EXIT_SUCCESS) {
       LOG_I(HW,"USRP synced with GPS!\n");
     } else {
@@ -1068,15 +1090,15 @@ extern "C" {
       exit(EXIT_FAILURE);
     }
   }
-  
+
   if (device->type==USRP_X300_DEV) {
     openair0_cfg[0].rx_gain_calib_table = calib_table_x310;
-    std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; 
+    std::cerr << "-- Using calibration table: calib_table_x310" << std::endl;
   }
 
   if (device->type==USRP_N300_DEV) {
     openair0_cfg[0].rx_gain_calib_table = calib_table_n310;
-    std::cerr << "-- Using calibration table: calib_table_n310" << std::endl; 
+    std::cerr << "-- Using calibration table: calib_table_n310" << std::endl;
   }
 
 
@@ -1091,7 +1113,7 @@ extern "C" {
         openair0_cfg[0].tx_bw                 = 80e6;
         openair0_cfg[0].rx_bw                 = 80e6;
         break;
-  
+
       case 92160000:
         // from usrp_time_offset
         //openair0_cfg[0].samples_per_packet    = 2048;
@@ -1099,7 +1121,7 @@ extern "C" {
         openair0_cfg[0].tx_bw                 = 80e6;
         openair0_cfg[0].rx_bw                 = 80e6;
         break;
-  
+
       case 61440000:
         // from usrp_time_offset
         //openair0_cfg[0].samples_per_packet    = 2048;
@@ -1107,14 +1129,14 @@ extern "C" {
         openair0_cfg[0].tx_bw                 = 40e6;
         openair0_cfg[0].rx_bw                 = 40e6;
         break;
-  
+
       case 46080000:
         //openair0_cfg[0].samples_per_packet    = 2048;
         openair0_cfg[0].tx_sample_advance     = 15;
         openair0_cfg[0].tx_bw                 = 40e6;
         openair0_cfg[0].rx_bw                 = 40e6;
         break;
-  
+
       case 30720000:
         // from usrp_time_offset
         //openair0_cfg[0].samples_per_packet    = 2048;
@@ -1122,35 +1144,35 @@ extern "C" {
         openair0_cfg[0].tx_bw                 = 20e6;
         openair0_cfg[0].rx_bw                 = 20e6;
         break;
-  
+
       case 15360000:
         //openair0_cfg[0].samples_per_packet    = 2048;
         openair0_cfg[0].tx_sample_advance     = 45;
         openair0_cfg[0].tx_bw                 = 10e6;
         openair0_cfg[0].rx_bw                 = 10e6;
         break;
-  
+
       case 7680000:
         //openair0_cfg[0].samples_per_packet    = 2048;
         openair0_cfg[0].tx_sample_advance     = 50;
         openair0_cfg[0].tx_bw                 = 5e6;
         openair0_cfg[0].rx_bw                 = 5e6;
         break;
-  
+
       case 1920000:
         //openair0_cfg[0].samples_per_packet    = 2048;
         openair0_cfg[0].tx_sample_advance     = 50;
         openair0_cfg[0].tx_bw                 = 1.25e6;
         openair0_cfg[0].rx_bw                 = 1.25e6;
         break;
-  
+
       default:
         LOG_E(HW,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate);
         exit(-1);
         break;
     }
   }
-  
+
   if (device->type == USRP_B200_DEV) {
     if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) {
       openair0_cfg[0].rx_gain_calib_table = calib_table_b210;
@@ -1161,7 +1183,7 @@ extern "C" {
       bw_gain_adjust=1;
       std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info
     }
-  
+
     switch ((int)openair0_cfg[0].sample_rate) {
       case 46080000:
         s->usrp->set_master_clock_rate(46.08e6);
@@ -1170,7 +1192,7 @@ extern "C" {
         openair0_cfg[0].tx_bw                 = 40e6;
         openair0_cfg[0].rx_bw                 = 40e6;
         break;
-  
+
       case 30720000:
         s->usrp->set_master_clock_rate(30.72e6);
         //openair0_cfg[0].samples_per_packet    = 1024;
@@ -1178,7 +1200,7 @@ extern "C" {
         openair0_cfg[0].tx_bw                 = 20e6;
         openair0_cfg[0].rx_bw                 = 20e6;
         break;
-  
+
       case 23040000:
         s->usrp->set_master_clock_rate(23.04e6); //to be checked
         //openair0_cfg[0].samples_per_packet    = 1024;
@@ -1186,7 +1208,7 @@ extern "C" {
         openair0_cfg[0].tx_bw                 = 20e6;
         openair0_cfg[0].rx_bw                 = 20e6;
         break;
-  
+
       case 15360000:
         s->usrp->set_master_clock_rate(30.72e06);
         //openair0_cfg[0].samples_per_packet    = 1024;
@@ -1194,7 +1216,7 @@ extern "C" {
         openair0_cfg[0].tx_bw                 = 20e6;
         openair0_cfg[0].rx_bw                 = 20e6;
         break;
-  
+
       case 7680000:
         s->usrp->set_master_clock_rate(30.72e6);
         //openair0_cfg[0].samples_per_packet    = 1024;
@@ -1202,7 +1224,7 @@ extern "C" {
         openair0_cfg[0].tx_bw                 = 20e6;
         openair0_cfg[0].rx_bw                 = 20e6;
         break;
-  
+
       case 1920000:
         s->usrp->set_master_clock_rate(30.72e6);
         //openair0_cfg[0].samples_per_packet    = 1024;
@@ -1210,20 +1232,20 @@ extern "C" {
         openair0_cfg[0].tx_bw                 = 20e6;
         openair0_cfg[0].rx_bw                 = 20e6;
         break;
-  
+
       default:
         LOG_E(HW,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate);
         exit(-1);
         break;
     }
   }
-  
+
   /* device specific */
   //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered
   //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered
   openair0_cfg[0].iq_txshift = 4;//shift
   openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
-  
+
   for(int i=0; i<((int) s->usrp->get_rx_num_channels()); i++) {
     if (i<openair0_cfg[0].rx_num_channels) {
       s->usrp->set_rx_rate(openair0_cfg[0].sample_rate,i);
@@ -1231,22 +1253,26 @@ 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());
     }
   }
-  
+
   LOG_D(HW, "usrp->get_tx_num_channels() == %zd\n", s->usrp->get_tx_num_channels());
   LOG_D(HW, "openair0_cfg[0].tx_num_channels == %d\n", openair0_cfg[0].tx_num_channels);
-  
+
   for(int i=0; i<((int) s->usrp->get_tx_num_channels()); i++) {
     ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(i);
-  
+
     if (i<openair0_cfg[0].tx_num_channels) {
       s->usrp->set_tx_rate(openair0_cfg[0].sample_rate,i);
       s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i);
@@ -1254,7 +1280,7 @@ extern "C" {
       LOG_I(HW,"USRP TX_GAIN:%3.2lf gain_range:%3.2lf tx_gain:%3.2lf\n", gain_range_tx.stop()-openair0_cfg[0].tx_gain[i], gain_range_tx.stop(), openair0_cfg[0].tx_gain[i]);
     }
   }
-  
+
   //s->usrp->set_clock_source("external");
   //s->usrp->set_time_source("external");
   // display USRP settings
@@ -1268,32 +1294,34 @@ extern "C" {
   int max=s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps();
   samples/=10000;
   LOG_I(HW,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples);
-  
+
   if ( samples < max ) {
     stream_args_rx.args["spp"] = str(boost::format("%d") % samples );
   }
-  
+
   LOG_I(HW,"rx_max_num_samps %zu\n",
         s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps());
-  
-  for (int i = 0; i<openair0_cfg[0].rx_num_channels; i++)
+
+  for (int i = 0; i<openair0_cfg[0].rx_num_channels; i++) {
+    LOG_I(HW,"setting rx channel %d\n",i);
     stream_args_rx.channels.push_back(i);
-  
+  }
+
   s->rx_stream = s->usrp->get_rx_stream(stream_args_rx);
   uhd::stream_args_t stream_args_tx("sc16", "sc16");
-  
+
   for (int i = 0; i<openair0_cfg[0].tx_num_channels; i++)
     stream_args_tx.channels.push_back(i);
-  
+
   s->tx_stream = s->usrp->get_tx_stream(stream_args_tx);
-  
+
   /* Setting TX/RX BW after streamers are created due to USRP calibration issue */
   for(int i=0; i<((int) s->usrp->get_tx_num_channels()) && i<openair0_cfg[0].tx_num_channels; i++)
     s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i);
-  
+
   for(int i=0; i<((int) s->usrp->get_rx_num_channels()) && i<openair0_cfg[0].rx_num_channels; i++)
     s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i);
-  
+
   for (int i=0; i<openair0_cfg[0].rx_num_channels; i++) {
     LOG_I(HW,"RX Channel %d\n",i);
     LOG_I(HW,"  Actual RX sample rate: %fMSps...\n",s->usrp->get_rx_rate(i)/1e6);
@@ -1302,7 +1330,7 @@ extern "C" {
     LOG_I(HW,"  Actual RX bandwidth: %fM...\n", s->usrp->get_rx_bandwidth(i)/1e6);
     LOG_I(HW,"  Actual RX antenna: %s...\n", s->usrp->get_rx_antenna(i).c_str());
   }
-  
+
   for (int i=0; i<openair0_cfg[0].tx_num_channels; i++) {
     LOG_I(HW,"TX Channel %d\n",i);
     LOG_I(HW,"  Actual TX sample rate: %fMSps...\n", s->usrp->get_tx_rate(i)/1e6);
@@ -1312,33 +1340,35 @@ extern "C" {
     LOG_I(HW,"  Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str());
     LOG_I(HW,"  Actual TX packet size: %lu\n",s->tx_stream->get_max_num_samps());
   }
-  
+
   LOG_I(HW,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs());
   device->trx_write_func = trx_usrp_write;
   device->trx_read_func  = trx_usrp_read;
   s->sample_rate = openair0_cfg[0].sample_rate;
-  
+
   // TODO:
   // init tx_forward_nsamps based usrp_time_offset ex
   if(is_equal(s->sample_rate, (double)30.72e6))
     s->tx_forward_nsamps  = 176;
-  
+
   if(is_equal(s->sample_rate, (double)15.36e6))
     s->tx_forward_nsamps = 90;
-  
+
   if(is_equal(s->sample_rate, (double)7.68e6))
     s->tx_forward_nsamps = 50;
-  
-  
-  if (device->recplay_state != NULL) { // record mode
-    device->recplay_state->ms_sample = (iqrec_t *) malloc(openair0_cfg[0].recplay_conf->u_sf_max * sizeof(iqrec_t));
-  
-    if (device->recplay_state->ms_sample == NULL) {
+
+  recplay_state_t *recPlay=device->recplay_state;
+
+  if (recPlay != NULL) { // record mode
+    recPlay->maxSizeBytes=openair0_cfg[0].recplay_conf->u_sf_max *
+                            (sizeof(iqrec_t)+BELL_LABS_IQ_BYTES_PER_SF);
+    recPlay->ms_sample = (iqrec_t *) malloc(recPlay->maxSizeBytes);
+    recPlay->currentPtr= (uint8_t *)recPlay->ms_sample;
+
+    if (recPlay->ms_sample == NULL) {
       std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl;
       exit(-1);
     }
-  
-    memset(device->recplay_state->ms_sample, 0, openair0_cfg[0].recplay_conf->u_sf_max * BELL_LABS_IQ_BYTES_PER_SF);
   }
   return 0;
 }
diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/targets/ARCH/iqplayer/iqplayer_lib.c
index c4133d1b11652615f320065b405f65016ba48970..8b6844f9d3f5bfaa2df87ae236cf997ae874ac48 100644
--- a/targets/ARCH/iqplayer/iqplayer_lib.c
+++ b/targets/ARCH/iqplayer/iqplayer_lib.c
@@ -25,7 +25,6 @@
  */
 #define _LARGEFILE_SOURCE
 #define _FILE_OFFSET_BITS 64
-#define NB_ANTENNAS_RX  2
 #include <string.h>
 #include <pthread.h>
 #include <unistd.h>
@@ -40,18 +39,15 @@
 #include "assertions.h"
 #include "common/utils/LOG/log.h"
 
-
-
-
-
-
 static void parse_iqfile_header(openair0_device *device, iqfile_header_t *iq_fh) {
-  AssertFatal((memcmp(iq_fh->oaiid,OAIIQFILE_ID,sizeof(OAIIQFILE_ID)) == 0),
-  	           "iqfile doesn't seem to be compatible with oai (invalid id %.4s in header)\n",
-  	           iq_fh->oaiid);
+  char tmp[4]=OAIIQFILE_ID;
+  AssertFatal((memcmp(iq_fh->oaiid,tmp,sizeof(iq_fh->oaiid)) == 0),
+              "iqfile doesn't seem to be compatible with oai (invalid id %.4s in header)\n",
+              iq_fh->oaiid);
   device->type = iq_fh->devtype;
   device->openair0_cfg[0].tx_sample_advance=iq_fh->tx_sample_advance;
   device->openair0_cfg[0].tx_bw =  device->openair0_cfg[0].rx_bw = iq_fh->bw;
+  device->recplay_state->nbSamplesBlocks=iq_fh->nbSamplesBlocks;
   LOG_UI(HW,"Replay iqs from %s device, bandwidth %e\n",get_devname(iq_fh->devtype),iq_fh->bw);
 }
 
@@ -63,89 +59,73 @@ static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair
   recplay_state_t *s = device->recplay_state;
   recplay_conf_t  *c = openair0_cfg->recplay_conf;
 
+  struct stat sb;
+  s->fd = open(c->u_sf_filename, O_RDONLY );
+  if (s->fd >= 0 ) {
+    fstat(s->fd, &sb);
+  } else {
+    LOG_E( HW,"Cannot open %s exiting.\n", c->u_sf_filename );
+    exit(-1);
+  }
+  
   if (s->use_mmap) {
     // use mmap
-    s->mmapfd = open(c->u_sf_filename, O_RDONLY );
-
-    if (s->mmapfd != 0) {
-      struct stat sb;
-      fstat(s->mmapfd, &sb);
       s->mapsize=sb.st_size;
       LOG_I(HW,"Loading subframes using mmap() from %s size=%lu bytes ...\n",c->u_sf_filename, (uint64_t)sb.st_size );
-      void *mptr = mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->mmapfd, 0) ;
-      s->ms_sample = (iqrec_t *) ( mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->mmapfd, 0) + sizeof(iqfile_header_t));
+      void *mptr = mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->fd, 0) ;
+      s->ms_sample = (iqrec_t *) ( mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->fd, 0) + sizeof(iqfile_header_t));
 
       if (mptr != MAP_FAILED) {
         parse_iqfile_header(device, (iqfile_header_t *)mptr);
         s->ms_sample = (iqrec_t *)((char *)mptr + sizeof(iqfile_header_t));
-        s->nb_samples = ((sb.st_size-sizeof(iqfile_header_t)) / sizeof(iqrec_t));
-        int aligned = (((unsigned long)s->ms_sample & 31) == 0)? 1:0;
-        LOG_I(HW,"Loaded %u subframes.\n",s->nb_samples );
-
-        if (aligned == 0) {
-          LOG_E(HW, "mmap address is not 32 bytes aligned, exiting.\n" );
-          close(s->mmapfd);
-          exit(-1);
-        }
+        LOG_I(HW,"Loaded %u subframes.\n",s->nbSamplesBlocks );
       } else {
         LOG_E(HW,"Cannot mmap file, exiting.\n");
-        close(s->mmapfd);
+        close(s->fd);
         exit(-1);
       }
-    } else {
-      LOG_E( HW,"Cannot open %s exiting.\n", c->u_sf_filename );
-      exit(-1);
-    }
   } else {
-    s->iqfd = open(c->u_sf_filename, O_RDONLY);
+    iqfile_header_t fh;
+    size_t hs = read(s->fd,&fh,sizeof(fh));
 
-    if (s->iqfd != 0) {
-      struct stat sb;
-      iqfile_header_t fh;
-      size_t hs = read(s->iqfd,&fh,sizeof(fh));
-
-      if (hs == sizeof(fh)) {
-        parse_iqfile_header(device, &fh);
-        fstat(s->iqfd, &sb);
+    if (hs == sizeof(fh)) {
+      parse_iqfile_header(device, &fh);
+        fstat(s->fd, &sb);
         s->mapsize=sb.st_size;
-        s->nb_samples = ((sb.st_size-sizeof(iqfile_header_t))/ sizeof(iqrec_t));
-        LOG_I(HW, "Loading %u subframes from %s,size=%lu bytes ...\n",s->nb_samples, c->u_sf_filename,(uint64_t)sb.st_size);
+        LOG_I(HW, "Loading %u subframes from %s,size=%lu bytes ...\n",s->nbSamplesBlocks, c->u_sf_filename,(uint64_t)sb.st_size);
         // allocate buffer for 1 sample at a time
-        s->ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t));
+        s->ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)+MAX_BELL_LABS_IQ_BYTES_PER_SF*4);
 
         if (s->ms_sample == NULL) {
           LOG_E(HW,"Memory allocation failed for individual subframe replay mode.\n" );
-          close(s->iqfd);
+          close(s->fd);
           exit(-1);
         }
 
         memset(s->ms_sample, 0, sizeof(iqrec_t));
 
         // point at beginning of iqs in file
-        if (lseek(s->iqfd,sizeof(iqfile_header_t), SEEK_SET) == 0) {
+        if (lseek(s->fd,sizeof(iqfile_header_t), SEEK_SET) == 0) {
           LOG_I(HW,"Initial seek at beginning of the file\n" );
         } else {
           LOG_I(HW,"Problem initial seek at beginning of the file\n");
         }
       } else {
         LOG_E(HW,"Cannot read header in %s exiting.\n",c->u_sf_filename );
-        close(s->iqfd);
+        close(s->fd);
         exit(-1);
       }
-    } else {
-      LOG_E(HW,"Cannot open %s exiting.\n",c->u_sf_filename );
-      exit(-1);
-    }
   }
 
+  s->currentPtr=(uint8_t *)s->ms_sample;
   return 0;
 }
 
 /*! \brief start the oai iq player
  * \param device, the hardware used
  */
-static int trx_iqplayer_start(openair0_device *device){
-	return 0;
+static int trx_iqplayer_start(openair0_device *device) {
+  return 0;
 }
 
 /*! \brief Terminate operation of the oai iq player
@@ -157,28 +137,22 @@ static void trx_iqplayer_end(openair0_device *device) {
 
   if (device->recplay_state == NULL)
     return;
-
+  
   if (device->recplay_state->use_mmap) {
     if (device->recplay_state->ms_sample != MAP_FAILED) {
       munmap(device->recplay_state->ms_sample, device->recplay_state->mapsize);
-      device->recplay_state->ms_sample = NULL;
-    }
-
-    if (device->recplay_state->mmapfd != 0) {
-      close(device->recplay_state->mmapfd);
-      device->recplay_state->mmapfd = 0;
-    }
+      }
   } else {
     if (device->recplay_state->ms_sample != NULL) {
       free(device->recplay_state->ms_sample);
-      device->recplay_state->ms_sample = NULL;
-    }
-
-    if (device->recplay_state->iqfd != 0) {
-      close(device->recplay_state->iqfd);
-      device->recplay_state->iqfd = 0;
-    }
+    } 
+  }
+  device->recplay_state->ms_sample = NULL;
+  if (device->recplay_state->fd >= 0) {
+    close(device->recplay_state->fd);
+    device->recplay_state->fd = -1;
   }
+
 }
 /*! \brief Write iqs function when in replay mode, just introduce a delay, as configured at init time,
       @param device pointer to the device structure specific to the RF hardware target
@@ -208,93 +182,68 @@ static int trx_iqplayer_write(openair0_device *device, openair0_timestamp timest
  * \returns the number of sample read
 */
 static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
-  int samples_received=0;
-  static unsigned int    cur_samples;
-  static int64_t         wrap_count;
-  static int64_t  wrap_ts;
   recplay_state_t *s = device->recplay_state;
 
-  if (cur_samples == s->nb_samples) {
-    cur_samples = 0;
-    wrap_count++;
-
-    if (wrap_count == device->openair0_cfg->recplay_conf->u_sf_loops) {
-      LOG_W(HW, "iqplayer device terminating subframes replay  after %u iteration\n",device->openair0_cfg->recplay_conf->u_sf_loops);
+  if (s->curSamplesBlock==0 && s->wrap_count==0 ) 
+    s->currentTs=s->ms_sample->ts;
+  
+  if (s->curSamplesBlock == s->nbSamplesBlocks) {
+    LOG_I(HW, "wrapping on iq file (%ld)\n", s->wrap_count);
+    s->curSamplesBlock = 0;
+    s->wrap_count++;
+
+    if (s->wrap_count == device->openair0_cfg->recplay_conf->u_sf_loops) {
+      LOG_W(HW, "iqplayer device terminating subframes replay  after %u iteration\n",
+            device->openair0_cfg->recplay_conf->u_sf_loops);
       exit_function(__FILE__, __FUNCTION__, __LINE__,"replay ended, triggering process termination\n");
     }
 
-    wrap_ts = wrap_count * (s->nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000));
+    LOG_I(HW,"go back at the beginning of IQ file");
+    device->recplay_state->currentPtr=(uint8_t *)device->recplay_state->ms_sample;
 
-    if (!device->recplay_state->use_mmap) {
-      if (lseek(device->recplay_state->iqfd, 0, SEEK_SET) == 0) {
-        LOG_I(HW,"Seeking at the beginning of IQ file");
-      } else {
-        LOG_I(HW, "Problem seeking at the beginning of IQ file");
+    if (!s->use_mmap) {
+      if (lseek(device->recplay_state->fd, 0, SEEK_SET) != 0) {
+        LOG_E(HW, "Problem seeking at the beginning of IQ file");
       }
     }
   }
 
-  if (s->use_mmap) {
-    if (cur_samples < s->nb_samples) {
-      *ptimestamp = (s->ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts;
-
-      if (cur_samples == 0) {
-        LOG_I(HW,"starting subframes file with wrap_count=%lu wrap_ts=%lu ts=%lu\n", wrap_count,wrap_ts,*ptimestamp);
-      }
-
-      memcpy(buff[0], &s->ms_sample[cur_samples].samples[0], nsamps*4);
-      cur_samples++;
-    }
-  } else {
+  if (!s->use_mmap) {
     // read sample from file
-    if (read(s->iqfd, s->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) {
-      LOG_E(HW,"pb reading iqfile at index %lu\n",sizeof(iqrec_t)*cur_samples );
-      close(s->iqfd);
-      free(s->ms_sample);
-      s->ms_sample = NULL;
-      s->iqfd = 0;
+    if (read(s->fd, s->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) {
+      LOG_E(HW,"pb reading iqfile at index %lu\n",sizeof(iqrec_t)*s->curSamplesBlock );
       exit(-1);
-    }
-
-    if (cur_samples < s->nb_samples) {
-      static int64_t ts0 = 0;
-
-      if ((cur_samples == 0) && (wrap_count == 0)) {
-        ts0 = s->ms_sample->ts;
-      }
-
-      *ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts;
-
-      if (cur_samples == 0) {
-        LOG_I(HW, "starting subframes file with wrap_count=%lu wrap_ts=%lu ts=%lu ",wrap_count,wrap_ts, *ptimestamp);
-      }
-
-      memcpy(buff[0], &s->ms_sample->samples[0], nsamps*4);
-      cur_samples++;
-      // Prepare for next read
-      off_t where = lseek(s->iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET);
-
-      if (where < 0) {
-        LOG_E(HW,"Cannot lseek in iqfile: %s\n",strerror(errno));
+    } else {
+      if (read(s->fd, s->ms_sample+1, s->ms_sample->nbBytes) !=  s->ms_sample->nbBytes) {
+        LOG_E(HW,"pb reading iqfile at index %lu\n",sizeof(iqrec_t)*s->curSamplesBlock );
         exit(-1);
       }
     }
   }
 
-  struct timespec req;
+  iqrec_t *curHeader=(iqrec_t *)s->currentPtr;
+  AssertFatal(curHeader->header==BELL_LABS_IQ_HEADER,"" );
+  // the current timestamp is the stored timestamp until we wrap on input
+  // USRP shifts 1 sample time to time
+  AssertFatal(s->wrap_count !=0 || abs(curHeader->ts-s->currentTs) < 5 ,"");
+  AssertFatal(nsamps*4==curHeader->nbBytes,"");
+  *ptimestamp = s->currentTs;
+  memcpy(buff[0], curHeader+1, nsamps*4);
+  s->curSamplesBlock++;
+  // Prepare for next read
+  s->currentTs+=nsamps;
+
+  if (s->use_mmap)
+    s->currentPtr+=sizeof(iqrec_t)+s->ms_sample->nbBytes;
 
+  struct timespec req;
   req.tv_sec = 0;
-
   req.tv_nsec = (device->openair0_cfg[0].recplay_conf->u_sf_read_delay) * 1000;
-
   nanosleep(&req, NULL);
-
+  LOG_D(HW, "returning %d samples at ts %lu\n", nsamps, *ptimestamp);
   return nsamps;
-
-  return samples_received;
 }
 
-
 int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
   device->openair0_cfg = openair0_cfg;
   device->trx_start_func = trx_iqplayer_start;
@@ -313,5 +262,4 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
   LOG_UI(HW,"iqplayer device initialized, replay %s  for %i iterations",openair0_cfg->recplay_conf->u_sf_filename,openair0_cfg->recplay_conf->u_sf_loops);
   return 0;
 }
-
 /*@}*/
diff --git a/targets/ARCH/rfsimulator/apply_channelmod.c b/targets/ARCH/rfsimulator/apply_channelmod.c
index 3f4c0e1517e162274b2f015bc4f09d7393179aef..ab8ae77edde7320d887b670663ce45eaa5c66a0c 100644
--- a/targets/ARCH/rfsimulator/apply_channelmod.c
+++ b/targets/ARCH/rfsimulator/apply_channelmod.c
@@ -65,17 +65,8 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
   // Fixme: not sure when it is "volts" so dB is 20*log10(...) or "power", so dB is 10*log10(...)
   const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0);
   // Energy in one sample to calibrate input noise
-  //Fixme: modified the N0W computation, not understand the origin value
-  const double KT=1.38e-23*290; //Boltzman*temperature
-  // sampling rate is linked to acquisition band (the input pass band filter)
-  const double noise_figure_watt = KT*channelDesc->sampling_rate;
-  // Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ?
-  // the parameter "-s" is declared as SNR, but the input power is not well defined
-  // −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise)
-  const double rxGain= 132.24 - channelmod_get_snr_dB();
-  // sqrt(4*noise_figure_watt) is the thermal noise factor (volts)
-  // fixme: the last constant is pure trial results to make decent noise
-  const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10;
+  // the normalized OAI value seems to be 256 as average amplitude (numerical amplification = 1)
+  const double noise_per_sample = pow(10,channelDesc->noise_power_dB/10.0) * 256;
   // Fixme: we don't fill the offset length samples at begining ?
   // anyway, in today code, channel_offset=0
   const int dd = abs(channelDesc->channel_offset);
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index cd35c46a15a40c882e7c393adbe55ea527599792..13945998d754faa5f0f490099a992baaa8ee5667 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -54,22 +54,21 @@
 #include <targets/ARCH/rfsimulator/rfsimulator.h>
 
 #define PORT 4043 //default TCP port for this simulator
-#define CirSize 307200 // 100ms is enough
+#define CirSize 6144000 // 100ms is enough
 #define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
 #define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
 
 #define MAX_SIMULATION_CONNECTED_NODES 5
 #define GENERATE_CHANNEL 10 //each frame in DL
 
-// Fixme: datamodel, external variables in .h files, ...
-#include <common/ran_context.h>
 
-extern RAN_CONTEXT_t RC;
 //
 
 #define RFSIMU_SECTION    "rfsimulator"
 #define RFSIMU_OPTIONS_PARAMNAME "options"
-# define RFSIM_CONFIG_HELP_OPTIONS     " list of comma separated options to enable rf simulator functionalities. Available options: \n"\
+
+
+#define RFSIM_CONFIG_HELP_OPTIONS     " list of comma separated options to enable rf simulator functionalities. Available options: \n"\
   "        chanmod:   enable channel modelisation\n"\
   "        saviq:     enable saving written iqs to a file\n"
 /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
@@ -78,21 +77,21 @@ extern RAN_CONTEXT_t RC;
 /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define simOpt PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED
 #define RFSIMULATOR_PARAMS_DESC {					\
-    {"serveraddr",             "<ip address to connect to>\n",    simOpt   ,  strptr:&(rfsimulator->ip),              defstrval:"127.0.0.1",           TYPE_STRING,    0 },\
-    {"serverport",             "<port to connect to>\n",             simOpt,  u16ptr:&(rfsimulator->port),            defuintval:PORT,                 TYPE_UINT16,    0 },\
-    {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS,            0,       strlistptr:NULL,                        defstrlistval:NULL,              TYPE_STRINGLIST,0 },\
-    {"IQfile",                 "<file path to use when saving IQs>\n",simOpt, strptr:&(saveF),                        defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING,    0 },\
-    {"modelname",              "<channel model name>\n",              simOpt, strptr:&(modelname),                    defstrval:"AWGN",                TYPE_STRING,    0 },\
-    {"ploss",                  "<channel path loss in dB>\n",         simOpt, dblptr:&(rfsimulator->chan_pathloss),   defdblval:0,                     TYPE_DOUBLE,    0 },\
-    {"forgetfact",             "<channel forget factor ((0 to 1)>\n", simOpt, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0,                     TYPE_DOUBLE,    0 },\
-    {"offset",                 "<channel offset in samps>\n",         simOpt, iptr:&(rfsimulator->chan_offset),       defintval:0,                     TYPE_INT,       0 }\
+    {"serveraddr",             "<ip address to connect to>\n",        simOpt,  strptr:&(rfsimulator->ip),              defstrval:"127.0.0.1",           TYPE_STRING,    0 },\
+    {"serverport",             "<port to connect to>\n",              simOpt,  u16ptr:&(rfsimulator->port),            defuintval:PORT,                 TYPE_UINT16,    0 },\
+    {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS,             0,       strlistptr:NULL,                        defstrlistval:NULL,              TYPE_STRINGLIST,0 },\
+    {"IQfile",                 "<file path to use when saving IQs>\n",simOpt,  strptr:&(saveF),                        defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING,    0 },\
+    {"modelname",              "<channel model name>\n",              simOpt,  strptr:&(modelname),                    defstrval:"AWGN",                TYPE_STRING,    0 },\
+    {"ploss",                  "<channel path loss in dB>\n",         simOpt,  dblptr:&(rfsimulator->chan_pathloss),   defdblval:0,                     TYPE_DOUBLE,    0 },\
+    {"forgetfact",             "<channel forget factor ((0 to 1)>\n", simOpt,  dblptr:&(rfsimulator->chan_forgetfact), defdblval:0,                     TYPE_DOUBLE,    0 },\
+    {"offset",                 "<channel offset in samps>\n",         simOpt,  iptr:&(rfsimulator->chan_offset),       defintval:0,                     TYPE_INT,       0 }\
   };
 
 
 
 static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg);
 static telnetshell_cmddef_t rfsimu_cmdarray[] = {
-  {"setmodel","<model name>",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
+  {"setmodel","<model name> <model type>",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
   {"","",NULL},
 };
 
@@ -133,6 +132,7 @@ typedef struct {
   double chan_pathloss;
   double chan_forgetfact;
   int    chan_offset;
+  float  noise_power_dB;
   void *telnetcmd_qid;
   poll_telnetcmdq_func_t poll_telnetcmdq;
 } rfsimulator_state_t;
@@ -182,15 +182,9 @@ static void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
       tableNor(rand);
       init_done=true;
     }
-
-    ptr->channel_model=new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels,
-                                            bridge->channelmod,
-                                            bridge->sample_rate,
-                                            bridge->tx_bw,
-                                            30e-9,  // TDL delay-spread parameter
-                                            bridge->chan_forgetfact, // forgetting_factor
-                                            bridge->chan_offset, // maybe used for TA
-                                            bridge->chan_pathloss); // path_loss in dB
+    char *modelname = (bridge->typeStamp == ENB_MAGICDL) ? "rfsimu_channel_ue0":"rfsimu_channel_enB0";
+    ptr->channel_model=find_channel_desc_fromname(modelname); // path_loss in dB
+    AssertFatal((ptr->channel_model!= NULL),"Channel model %s not found, check config file\n",modelname);
     set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID);
     random_channel(ptr->channel_model,false);
   }
@@ -299,7 +293,8 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
       break;
     } else if (strcmp(rfsimu_params[p].strlistptr[i],"chanmod") == 0) {
       init_channelmod();
-      rfsimulator->channelmod=modelid_fromname(modelname);
+      load_channellist(rfsimulator->tx_num_channels, rfsimulator->rx_num_channels, rfsimulator->sample_rate, rfsimulator->tx_bw);
+      rfsimulator->channelmod=true;
     } else {
       fprintf(stderr,"Unknown rfsimulator option: %s\n",rfsimu_params[p].strlistptr[i]);
       exit(-1);
@@ -320,20 +315,27 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
 
 static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) {
   char *modelname=NULL;
-  int s = sscanf(buff,"%ms\n",&modelname);
+  char *modeltype=NULL;
+  if (debug)
+  	  prnt("rfsimu_setchanmod_cmd buffer \"%s\"\n",buff);
+  int s = sscanf(buff,"%m[^ ] %ms\n",&modelname, &modeltype);
 
-  if (s == 1) {
-    int channelmod=modelid_fromname(modelname);
+  if (s == 2) {
+    int channelmod=modelid_fromstrtype(modeltype);
 
     if (channelmod<0)
-      prnt("ERROR: model %s unknown\n",modelname);
+      prnt("ERROR: model type %s unknown\n",modeltype);
     else {
       rfsimulator_state_t *t = (rfsimulator_state_t *)arg;
-
+      int found=0;
       for (int i=0; i<FD_SETSIZE; i++) {
         buffer_t *b=&t->buf[i];
+        if ( b->channel_model==NULL)
+          continue;
+        if (b->channel_model->model_name==NULL)
+          continue;
+        if (b->conn_sock >= 0 && (strcmp(b->channel_model->model_name,modelname)==0)) {
 
-        if (b->conn_sock >= 0 ) {
           channel_desc_t *newmodel=new_channel_desc_scm(t->tx_num_channels,t->rx_num_channels,
                                    channelmod,
                                    t->sample_rate,
@@ -341,21 +343,29 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
                                    30e-9,  // TDL delay-spread parameter
                                    t->chan_forgetfact, // forgetting_factor
                                    t->chan_offset, // maybe used for TA
-                                   t->chan_pathloss); // path_loss in dB
+							       t->chan_pathloss,
+							       t->noise_power_dB
+							       ); // path_loss in dB
           set_channeldesc_owner(newmodel, RFSIMU_MODULEID);
+          set_channeldesc_name(newmodel,modelname);
           random_channel(newmodel,false);
           channel_desc_t *oldmodel=b->channel_model;
           b->channel_model=newmodel;
           free_channel_desc_scm(oldmodel);
-          prnt("New model %s applied to channel connected to sock %d\n",modelname,i);
+          prnt("New model type %s applied to channel %s connected to sock %d\n",modeltype,modelname,i);
+          found=1;
+          break;
         }
-      }
+      } /* for */
+      if (found==0)
+      	prnt("Channel %s not found or not currently used\n",modelname); 
     }
   } else {
-    prnt("ERROR: no model specified\n");
+    prnt("ERROR: 2 parameters required: model name and model type (%i found)\n",s);
   }
 
   free(modelname);
+  free(modeltype);
   return CMDSTATUS_FOUND;
 }
 
@@ -608,8 +618,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
 }
 
 static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
-  if (nbAnt != 1) {
-    LOG_W(HW, "rfsimulator: only 1 antenna tested\n");
+  if (nbAnt > 4) {
+    LOG_W(HW, "rfsimulator: only 4 antenna tested\n");
   }
 
   rfsimulator_state_t *t = device->priv;
@@ -726,14 +736,19 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
                       CirSize
                     );
         else { // no channel modeling
+          double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0
+                                     {0.5, 1.0, 0.5, 0.25},  //rx 1
+                                     {0.25, 0.5, 1.0, 0.5},  //rx 2
+                                     {0.125, 0.25, 0.5, 1.0}};//rx 3
+
           sample_t *out=(sample_t *)samplesVoid[a];
           int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas
 
           //LOG_I(HW, "nbAnt_tx %d\n",nbAnt_tx);
           for (int i=0; i < nsamps; i++) {//loop over nsamps
             for (int a_tx=0; a_tx<nbAnt_tx; a_tx++) { //sum up signals from nbAnt_tx antennas
-              out[i].r+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r;
-              out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i;
+              out[i].r += (short)(ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r*H_awgn_mimo[a][a_tx]);
+              out[i].i += (short)(ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i*H_awgn_mimo[a][a_tx]);
             } // end for a_tx
           } // end for i (number of samps)
         } // end of no channel modeling
@@ -774,6 +789,11 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
   // to change the log level, use this on command line
   // --log_config.hw_log_level debug
   rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1);
+  // initialize channel simulation
+  rfsimulator->tx_num_channels=openair0_cfg->tx_num_channels;
+  rfsimulator->rx_num_channels=openair0_cfg->rx_num_channels;
+  rfsimulator->sample_rate=openair0_cfg->sample_rate;
+  rfsimulator->tx_bw=openair0_cfg->tx_bw;  
   rfsimulator_readconfig(rfsimulator);
   pthread_mutex_init(&Sockmutex, NULL);
   LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL ? "server waiting opposite rfsimulators to connect" : "client: will connect to a rfsimulator server side");
@@ -790,6 +810,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
   device->trx_read_func      = rfsimulator_read;
   /* let's pretend to be a b2x0 */
   device->type = RFSIMULATOR;
+  openair0_cfg[0].rx_gain[0] = 0;
   device->openair0_cfg=&openair0_cfg[0];
   device->priv = rfsimulator;
   device->trx_write_init = rfsimulator_write_init;
@@ -798,11 +819,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
     rfsimulator->buf[i].conn_sock=-1;
 
   AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1,"");
-  // initialize channel simulation
-  rfsimulator->tx_num_channels=openair0_cfg->tx_num_channels;
-  rfsimulator->rx_num_channels=openair0_cfg->rx_num_channels;
-  rfsimulator->sample_rate=openair0_cfg->sample_rate;
-  rfsimulator->tx_bw=openair0_cfg->tx_bw;
+
   //randominit(0);
   set_taus_seed(0);
   /* look for telnet server, if it is loaded, add the channel modeling commands to it */
diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c
index daf0133af20b1540c8c0786e499230f2333f7776..cf025680cd76d3665135a2002a9c5e5ad35158f4 100644
--- a/targets/ARCH/rfsimulator/stored_node.c
+++ b/targets/ARCH/rfsimulator/stored_node.c
@@ -186,21 +186,23 @@ int main(int argc, char *argv[]) {
     serviceSock=client_start(argv[2],atoi(argv[3]));
   }
 
-  uint64_t typeStamp=ENB_MAGICDL_FDD;
+  uint64_t typeStamp=ENB_MAGICDL;
   boolean_t raw=false;
 
   if ( argc == 5 ) {
     raw=true;
 
     if (strcmp(argv[4],"UL") == 0 )
-      typeStamp=UE_MAGICDL_FDD;
+      typeStamp=UE_MAGICDL;
   }
 
   samplesBlockHeader_t header;
   int bufSize=100000;
   void *buff=malloc(bufSize);
   uint64_t timestamp=0;
-  const int blockSize=1000;
+  const int blockSize=1920;
+  // If fileSize is not multiple of blockSize*4 then discard remaining samples
+  fileSize = (fileSize/(blockSize<<2))*(blockSize<<2);
 
   while (1) {
     //Rewind the file to loop on the samples
diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c
index 4d57ab4e16625eac82290aa7ffae94665cc01892..3e0d97f60a09aa82be414e510f0f396dd595303a 100644
--- a/targets/COMMON/create_tasks.c
+++ b/targets/COMMON/create_tasks.c
@@ -42,6 +42,7 @@
 # include "enb_app.h"
 # include "openair2/LAYER2/MAC/mac_proto.h"
 #include <executables/split_headers.h> 
+#include <openair3/ocp-gtpu/gtp_itf.h>
 
 extern RAN_CONTEXT_t RC;
 
diff --git a/targets/COMMON/create_tasks_mbms.c b/targets/COMMON/create_tasks_mbms.c
index 5f81592b96640211e55f9590c8a611c81990c1a8..579e851ea70e699a113a65baff99abb0bc5905df 100644
--- a/targets/COMMON/create_tasks_mbms.c
+++ b/targets/COMMON/create_tasks_mbms.c
@@ -47,6 +47,7 @@
 # include "mce_app.h"
 # include "mme_app.h"
 
+#include <openair3/ocp-gtpu/gtp_itf.h>
 //extern RAN_CONTEXT_t RC;
 
 int create_tasks_mbms(uint32_t enb_nb) {
diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h
index ad98a6091bfa53037203408691957148c1df41ec..9260fe2701ff85b02e9c16faeb36c039845afd80 100644
--- a/targets/COMMON/openairinterface5g_limits.h
+++ b/targets/COMMON/openairinterface5g_limits.h
@@ -6,23 +6,40 @@
 #        define NUMBER_OF_gNB_MAX 1
 #        define NUMBER_OF_RU_MAX 2
 #        define NUMBER_OF_NR_RU_MAX 2
+#        define NUMBER_OF_UCI_MAX 16
+#        define NUMBER_OF_ULSCH_MAX 8
+#        define NUMBER_OF_DLSCH_MAX 8 
+#        define NUMBER_OF_SRS_MAX 16
+#        define NUMBER_OF_NR_ULSCH_MAX 8
+#        define NUMBER_OF_NR_DLSCH_MAX 8
+#        define NUMBER_OF_NR_UCI_MAX 16
+#        define NUMBER_OF_NR_SRS_MAX 16
+#        define NUMBER_OF_NR_CSIRS_MAX 16
+#        define NUMBER_OF_SCH_STATS_MAX 16
+
+#        define NUMBER_OF_NR_SCH_STATS_MAX 16
+
+#        define NUMBER_OF_NR_PUCCH_MAX 16
+#        define NUMBER_OF_NR_SR_MAX 16
+#        define NUMBER_OF_NR_PDCCH_MAX 16
+
+#define MAX_MANAGED_ENB_PER_MOBILE  2
+#define MAX_MANAGED_GNB_PER_MOBILE  2
+
 #        ifndef PHYSIM
 #            ifndef UE_EXPANSION
 #                    define NUMBER_OF_UE_MAX 4
 #                    define NUMBER_OF_NR_UE_MAX 4
-#                    define NUMBER_OF_UCI_VARS_MAX 14
 #                    define NUMBER_OF_CONNECTED_eNB_MAX 1
 #                    define NUMBER_OF_CONNECTED_gNB_MAX 1
 #            else
 #                    define NUMBER_OF_UE_MAX 256
-#                    define NUMBER_OF_UCI_VARS_MAX 256
 #                    define NUMBER_OF_CONNECTED_eNB_MAX 1
 #                    define NUMBER_OF_CONNECTED_gNB_MAX 1
 #            endif
 #        else
 #                    define NUMBER_OF_UE_MAX 4
 #                    define NUMBER_OF_NR_UE_MAX 4
-#                    define NUMBER_OF_UCI_VARS_MAX 56
 #                    define NUMBER_OF_CONNECTED_eNB_MAX 1
 #                    define NUMBER_OF_CONNECTED_gNB_MAX 1
 #        endif
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
index 504d5e7b349d48fb9c047cbcd196d4da020158ee..b260eaa58dca95b725de3e7eed914bf11602d6e1 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
@@ -15,7 +15,8 @@ gNBs =
     // Tracking area code, 0x0000 and 0xfffe are reserved values
     tracking_area_code  =  1;
 
-    plmn_list = ({mcc = 222; mnc = 01; mnc_length = 2;});	 
+    #plmn_list = ({mcc = 222; mnc = 01; mnc_length = 2;});	 
+    plmn_list = ({mcc = 208; mnc = 99; mnc_length = 2;});	 
 
     tr_s_preference     = "local_mac"
 
@@ -23,10 +24,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 31; //0;
     pdsch_AntennaPorts                                        = 1;
-    #pusch_TargetSNRx10                                        = 200;
-    #pucch_TargetSNRx10                                        = 200;
-    pusch_TargetSNRx10                                        = 200;
-    pucch_TargetSNRx10                                        = 200;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
@@ -50,7 +48,7 @@ gNBs =
      #initialDownlinkBWP
       #genericParameters
         # this is RBstart=84,L=13 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 6366; //28875; //6366; #6407; #3384;
+        initialDLBWPlocationAndBandwidth                                        = 6368; 
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
@@ -59,27 +57,14 @@ gNBs =
         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=4 //5 (4 is for 43, 5 is for 57)
-             initialDLBWPstartSymbolAndLength_3  = 57; //43; //57;
+        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;
@@ -92,7 +77,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 6366; //28875; //6366; #6407; #3384;
+        initialULBWPlocationAndBandwidth                                        = 6368; 
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -104,9 +89,9 @@ gNBs =
           prach_msg1_FDM                                            = 0;
           prach_msg1_FrequencyStart                                 = 74;
           zeroCorrelationZoneConfig                                 = 13;
-          preambleReceivedTargetPower                               = -118;
+          #preambleReceivedTargetPower                               = -118;
           #preambleReceivedTargetPower                               = -104;
-          #preambleReceivedTargetPower                               = -108;
+          preambleReceivedTargetPower                               = -108;
 #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
           preambleTransMax                                          = 6;
 #powerRampingStep
@@ -136,20 +121,18 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 2;
+        initialULBWPk2_0                      = 2;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
- 	
-	initialULBWPk2_1                      = 2;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 2;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
-        initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
+
 
         msg3_DeltaPreamble                                          = 1;
         #p0_NominalWithGrant                                         =-90;
@@ -210,7 +193,7 @@ gNBs =
 
 
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "192.168.18.99";
+    mme_ip_address      = ( { ipv4       = "192.168.18.150"; #"192.168.18.99";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
@@ -246,10 +229,12 @@ gNBs =
 
 MACRLCs = (
 	{
-	num_cc = 1;
-	tr_s_preference = "local_L1";
-	tr_n_preference = "local_RRC";
-        }  
+	    num_cc              = 1;
+	    tr_s_preference     = "local_L1";
+	    tr_n_preference     = "local_RRC";
+	    pusch_TargetSNRx10  = 200;
+        pucch_TargetSNRx10  = 200;
+    }
 );
 
 L1s = (
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band22.tm1.106PRB.adrv9371zc706.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band22.tm1.106PRB.adrv9371zc706.conf
deleted file mode 100644
index 5fd4b465b328f8f392d9f140858784675095e446..0000000000000000000000000000000000000000
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band22.tm1.106PRB.adrv9371zc706.conf
+++ /dev/null
@@ -1,289 +0,0 @@
-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  =  1;
-
-    plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});	 
-
-    tr_s_preference     = "local_mac"
-
-    ////////// Physical parameters:
-
-    component_carriers = (
-      {
-      node_function                                                 = "3GPP_gNODEB";
-      node_timing                                                   = "synch_to_ext_device";
-      node_synch_ref                                                = 0;
-      frame_type                                                    = "TDD";
-      DL_prefix_type                                                = "NORMAL";
-      UL_prefix_type                                                = "NORMAL";
-      eutra_band                                                    = 78;
-      downlink_frequency                                            = 3510000000L;
-      uplink_frequency_offset                                       = -120000000;
-      Nid_cell                                                      = 0;
-      N_RB_DL                                                       = 106;
-      nb_antenna_ports                                              = 1;
-      nb_antennas_tx                                                = 1;
-      nb_antennas_rx                                                = 1;
-      tx_gain                                                       = 90;
-      rx_gain                                                       = 125;
-      MIB_subCarrierSpacingCommon                                   = 30;
-      MIB_ssb_SubcarrierOffset                                      = 0;
-      MIB_dmrs_TypeA_Position                                       = 2;
-      pdcch_ConfigSIB1                                              = 0;
-      SIB1_frequencyOffsetSSB                                       = "khz5";
-      SIB1_ssb_PeriodicityServingCell                               = 5;
-      SIB1_ss_PBCH_BlockPower                                       = -60;
-      absoluteFrequencySSB                                          = 0;
-      DL_FreqBandIndicatorNR                                        = 15;
-      DL_absoluteFrequencyPointA                                    = 15;
-      DL_offsetToCarrier                                            = 15;
-      DL_SCS_SubcarrierSpacing                                      = "kHz30";
-      DL_SCS_SpecificCarrier_k0                                     = 0;
-      DL_carrierBandwidth                                           = 15;
-      DL_locationAndBandwidth                                       = 15;
-      DL_BWP_SubcarrierSpacing                                      = "kHz30";
-      DL_BWP_prefix_type                                            = "NORMAL";
-      UL_FreqBandIndicatorNR                                        = 15;
-      UL_absoluteFrequencyPointA                                    = 13;
-      UL_additionalSpectrumEmission                                 = 3;
-      UL_p_Max                                                      = -1;
-      UL_frequencyShift7p5khz                                       = "TRUE";
-      UL_offsetToCarrier                                            = 10;
-      UL_SCS_SubcarrierSpacing                                      = "kHz30";
-      UL_SCS_SpecificCarrier_k0                                     = 0;
-      UL_carrierBandwidth                                           = 15;
-      UL_locationAndBandwidth                                       = 15;
-      UL_BWP_SubcarrierSpacing                                      = "kHz30";
-      UL_BWP_prefix_type                                            = "NORMAL";
-      UL_timeAlignmentTimerCommon                                   = "infinity";
-      ServingCellConfigCommon_n_TimingAdvanceOffset                 = "n0"
-      ServingCellConfigCommon_ssb_PositionsInBurst_PR               = 0x01;
-      ServingCellConfigCommon_ssb_periodicityServingCell            = 10;
-      ServingCellConfigCommon_dmrs_TypeA_Position                   = 2;
-      NIA_SubcarrierSpacing                                         = "kHz15"; 
-      ServingCellConfigCommon_ss_PBCH_BlockPower                    = -60;
-      referenceSubcarrierSpacing                                    = "kHz15";
-      dl_UL_TransmissionPeriodicity                                 = "ms0p5";
-      nrofDownlinkSlots                                             = 10;
-      nrofDownlinkSymbols                                           = 10;
-      nrofUplinkSlots                                               = 10;
-      nrofUplinkSymbols                                             = 10;
-      rach_totalNumberOfRA_Preambles                                = 63;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_choice         = "oneEighth";
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneEighth      = 4;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneFourth      = 8;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneHalf        = 16;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_one            = 24;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_two            = 32;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_four           = 8;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_eight          = 4;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_sixteen        = 2;
-      rach_groupBconfigured                                         = "ENABLE";
-      rach_ra_Msg3SizeGroupA                                        = 56;
-      rach_messagePowerOffsetGroupB                                 = "dB0";
-      rach_numberOfRA_PreamblesGroupA                               = 32;
-      rach_ra_ContentionResolutionTimer                             = 8;
-      rsrp_ThresholdSSB                                             = 64;
-      rsrp_ThresholdSSB_SUL                                         = 64;
-      prach_RootSequenceIndex_choice                                = "l839";
-      prach_RootSequenceIndex_l839                                  = 0;
-      prach_RootSequenceIndex_l139                                  = 0;
-      prach_msg1_SubcarrierSpacing                                  = "kHz30";
-      restrictedSetConfig                                           = "unrestrictedSet";
-      msg3_transformPrecoding                                       = "ENABLE";
-      prach_ConfigurationIndex                                      = 10;
-      prach_msg1_FDM                                                = "one";
-      prach_msg1_FrequencyStart                                     = 10;
-      zeroCorrelationZoneConfig                                     = 10;
-      preambleReceivedTargetPower                                   = -150;
-      preambleTransMax                                              = 6;
-      powerRampingStep                                              = "dB0";
-      ra_ResponseWindow                                             = 8;
-      groupHoppingEnabledTransformPrecoding                         = "ENABLE";
-      msg3_DeltaPreamble                                            = 0;
-      p0_NominalWithGrant                                           = 0;
-      PUSCH_TimeDomainResourceAllocation_k2                         = 0;
-      PUSCH_TimeDomainResourceAllocation_mappingType                = "typeA";
-      PUSCH_TimeDomainResourceAllocation_startSymbolAndLength       = 0;
-      pucch_ResourceCommon                                          = 0;
-      pucch_GroupHopping                                            = "neither";
-      hoppingId                                                     = 0;
-      p0_nominal                                                    = -30;
-      PDSCH_TimeDomainResourceAllocation_k0                         = 2;
-      PDSCH_TimeDomainResourceAllocation_mappingType                = "typeA";
-      PDSCH_TimeDomainResourceAllocation_startSymbolAndLength       = 0;
-      rateMatchPatternId                                            = 0;
-      RateMatchPattern_patternType                                  = "bitmaps";
-      symbolsInResourceBlock                                        = "oneSlot";
-      periodicityAndPattern                                         = 2;
-      RateMatchPattern_controlResourceSet                           = 5;
-      RateMatchPattern_subcarrierSpacing                            = "kHz30";
-      RateMatchPattern_mode                                         = "dynamic";
-      controlResourceSetZero                                        = 0;
-      searchSpaceZero                                               = 0;
-      searchSpaceSIB1                                               = 10;
-      searchSpaceOtherSystemInformation                             = 10;
-      pagingSearchSpace                                             = 10;
-      ra_SearchSpace                                                = 10;
-      PDCCH_common_controlResourceSetId                             = 5;
-      PDCCH_common_ControlResourceSet_duration                      = 2;
-      PDCCH_cce_REG_MappingType                                     = "nonInterleaved";
-      PDCCH_reg_BundleSize                                          = 3;
-      PDCCH_interleaverSize                                         = 3;
-      PDCCH_shiftIndex                                              = 10;  
-      PDCCH_precoderGranularity                                     = "sameAsREG-bundle";
-      PDCCH_TCI_StateId                                             = 32;
-      tci_PresentInDCI                                              = "ENABLE";
-      PDCCH_DMRS_ScramblingID                                       = 0;
-      SearchSpaceId                                                 = 10;
-      commonSearchSpaces_controlResourceSetId                       = 5;
-      SearchSpace_monitoringSlotPeriodicityAndOffset_choice         = "sl1";
-      SearchSpace_monitoringSlotPeriodicityAndOffset_value          = 0;
-      SearchSpace_duration                                          = 2;
-      SearchSpace_nrofCandidates_aggregationLevel1                  = 0;
-      SearchSpace_nrofCandidates_aggregationLevel2                  = 0;
-      SearchSpace_nrofCandidates_aggregationLevel4                  = 0;
-      SearchSpace_nrofCandidates_aggregationLevel8                  = 0;
-      SearchSpace_nrofCandidates_aggregationLevel16                 = 0;
-      SearchSpace_searchSpaceType                                   = "common";
-      Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1     = 1;
-      Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2     = 1;
-      Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4     = 1;
-      Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8     = 1;
-      Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16    = 1; 
-      Common_dci_Format2_3_monitoringPeriodicity                    = 1;
-      Common_dci_Format2_3_nrofPDCCH_Candidates                     = 1;
-      ue_Specific__dci_Formats                                      = "formats0-0-And-1-0";
-      RateMatchPatternLTE_CRS_carrierFreqDL                         = 6;
-      RateMatchPatternLTE_CRS_carrierBandwidthDL                    = 6;
-      RateMatchPatternLTE_CRS_nrofCRS_Ports                         = 1;
-      RateMatchPatternLTE_CRS_v_Shift                               = 0;
-      RateMatchPatternLTE_CRS_radioframeAllocationPeriod            = 1;
-      RateMatchPatternLTE_CRS_radioframeAllocationOffset            = 0;
-      RateMatchPatternLTE_CRS_subframeAllocation_choice             = "oneFrame";
-      }
-    );
-
-
-    srb1_parameters :
-    {
-        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
-        timer_poll_retransmit    = 80;
-
-        # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
-        timer_reordering         = 35;
-
-        # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
-        timer_status_prohibit    = 0;
-
-        # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
-        poll_pdu                 =  4;
-
-        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
-        poll_byte                =  99999;
-
-        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
-        max_retx_threshold       =  4;
-    }
-
-    # ------- SCTP definitions
-    SCTP :
-    {
-        # Number of streams to use in input/output
-        SCTP_INSTREAMS  = 2;
-        SCTP_OUTSTREAMS = 2;
-    };
-
-
-    ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "192.168.12.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 = "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                    = 114;
-         eNB_instances  = [0];
-	 sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=192.168.100.8";
-
-    }
-);  
-
-NETWORK_CONTROLLER :
-{
-    FLEXRAN_ENABLED        = "no";
-    FLEXRAN_INTERFACE_NAME = "lo";
-    FLEXRAN_IPV4_ADDRESS   = "127.0.0.1";
-    FLEXRAN_PORT           = 2210;
-    FLEXRAN_CACHE          = "/mnt/oai_agent_cache";
-    FLEXRAN_AWAIT_RECONF   = "no";
-};
-
-     log_config :
-     {
-       global_log_level                      ="info";
-       global_log_verbosity                  ="medium";
-       hw_log_level                          ="info";
-       hw_log_verbosity                      ="medium";
-       phy_log_level                         ="info";
-       phy_log_verbosity                     ="medium";
-       mac_log_level                         ="info";
-       mac_log_verbosity                     ="high";
-       rlc_log_level                         ="info";
-       rlc_log_verbosity                     ="medium";
-       pdcp_log_level                        ="info";
-       pdcp_log_verbosity                    ="medium";
-       rrc_log_level                         ="info";
-       rrc_log_verbosity                     ="medium";
-    };
-
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
new file mode 100644
index 0000000000000000000000000000000000000000..ef171bf0a9748041308c13fc3c32007a81d4d32f
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
@@ -0,0 +1,286 @@
+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  =  1;
+
+    plmn_list = ({mcc = 208; mnc = 92; mnc_length = 2;});	 
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
+	
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is pointA + 23 PRBs@120kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 2071241;
+      dl_frequencyBand                                                 = 257;
+      # this is 27.900 GHz
+      dl_absoluteFrequencyPointA                                       = 2070833;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        dl_subcarrierSpacing                                           = 3;
+        dl_carrierBandwidth                                            = 32;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=0,L=32 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 8525;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 3;
+      #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_3                    = 0;  #for mixed slot
+        initialDLBWPmappingType_3           = 0;
+        initialDLBWPstartSymbolAndLength_3  = 57; #this is SS=1,L=5
+
+  #uplinkConfigCommon 
+     #frequencyInfoUL
+      ul_frequencyBand                                                 = 261;
+      #scs-SpecificCarrierList
+      ul_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      ul_subcarrierSpacing                                           = 3;
+      ul_carrierBandwidth                                            = 32;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 8525;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialULBWPsubcarrierSpacing                                           = 3;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 52;
+#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                                           = 7;
+#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                = 3;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 7;
+#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                                      = 3,
+
+# 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
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 6;
+        initialULBWPmappingType_1             = 1;
+        # this is SS=0 L=12
+        initialULBWPstartSymbolAndLength_1    = 69;
+
+        initialULBWPk2_2                      = 4;
+        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                                       = 3;
+      ssb_PositionsInBurst_Bitmap                                   = 0x0001000100010001L;
+
+# 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                                             = 3;
+
+
+  #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      referenceSubcarrierSpacing                                    = 3;
+      # pattern1 
+      # dl_UL_TransmissionPeriodicity
+      # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+      dl_UL_TransmissionPeriodicity                                 = 3;
+      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.18.99";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    ///X2
+    enable_x2 = "yes";
+    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       = "192.168.18.199";
+                                       ipv6       = "192:168:30::17";
+                                       preference = "ipv4";
+                                     }
+                                    );
+
+    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_PORT_FOR_S1U                         = 2152; # Spec 2152
+        GNB_IPV4_ADDRESS_FOR_X2C                 = "192.168.18.198/24";
+        GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
+    };
+  }
+);
+
+MACRLCs = (
+	{
+	    num_cc              = 1;
+	    tr_s_preference     = "local_L1";
+	    tr_n_preference     = "local_RRC";
+	    pusch_TargetSNRx10  = 200;
+        pucch_TargetSNRx10  = 200;
+    }
+);
+
+L1s = (
+    	{
+	num_cc = 1;
+	tr_n_preference = "local_mac";
+        }  
+);
+
+RUs = (
+    {		  
+       local_rf       = "yes"
+         nb_tx          = 1;
+         nb_rx          = 1;
+         att_tx         = 0;
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 75;
+         eNB_instances  = [0];
+	 sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2";
+         if_freq = 5124520000L;
+	 clock_src = "external";
+	 time_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";
+    };
+
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
index f2e468c71b5415a0f6951f72d16e60b7a9196401..360b75c67df50642b9f8487fca656523f533e12e 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
@@ -33,10 +34,10 @@ gNBs =
 #  downlinkConfigCommon
     #frequencyInfoDL
       # this is pointA + 23 PRBs@120kHz SCS (same as initial BWP)
-      absoluteFrequencySSB                                          = 2077907;
+      absoluteFrequencySSB                                          = 2071241;
       dl_frequencyBand                                                 = 257;
       # this is 27.900 GHz
-      dl_absoluteFrequencyPointA                                       = 2077499;
+      dl_absoluteFrequencyPointA                                       = 2070833;
       #scs-SpecificCarrierList
         dl_offstToCarrier                                              = 0;
 # subcarrierSpacing
@@ -55,27 +56,14 @@ gNBs =
         initialDLBWPsearchSpaceZero                                             = 0;
       #pdsch-ConfigCommon
         #pdschTimeDomainAllocationList (up to 16 entries)
-             initialDLBWPk0_0                    = 0;
-             #initialULBWPmappingType
-	     #0=typeA,1=typeB
-             initialDLBWPmappingType_0           = 0;
-             #this is SS=2,L=3
-             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=4 //5 (4 is for 43, 5 is for 57)
-             initialDLBWPstartSymbolAndLength_3  = 57; //43; //57;
+        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                                                 = 257;
@@ -110,8 +98,8 @@ gNBs =
 #1,2,4,8,10,20,40,80
         ra_ResponseWindow                                           = 7;
 #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
-#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
-        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 3;
 #oneHalf (0..15) 4,8,12,16,...60,64
         ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 7;
 #ra_ContentionResolutionTimer
@@ -130,20 +118,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;
+        initialULBWPk2_0                      = 6;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
 
-        initialULBWPk2_1                      = 6;
+        initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
-        initialULBWPk2_2                      = 14;
+        initialULBWPk2_2                      = 4;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
@@ -157,7 +142,7 @@ gNBs =
 # ssb_PositionsInBurs_BitmapPR
 # 1=short, 2=medium, 3=long
       ssb_PositionsInBurst_PR                                       = 3;
-      ssb_PositionsInBurst_Bitmap                                   = 0x100000001L;
+      ssb_PositionsInBurst_Bitmap                                   = 0x0001000100010001L;
 
 # ssb_periodicityServingCell
 # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 
@@ -185,7 +170,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
@@ -216,16 +201,19 @@ gNBs =
         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 = "local_RRC";
-        }  
+	    num_cc              = 1;
+	    tr_s_preference     = "local_L1";
+	    tr_n_preference     = "local_RRC";
+	    pusch_TargetSNRx10  = 200;
+        pucch_TargetSNRx10  = 200;
+    }
 );
 
 L1s = (
@@ -247,9 +235,9 @@ RUs = (
          max_rxgain                    = 75;
          eNB_instances  = [0];
 	 sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2";
-         if_freq = 5300000000L;
-         #time_source = "external";
-         clock_source = "external";
+         if_freq = 5124520000L;
+	 clock_src = "external";
+	 time_src = "external";
     }
 );  
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
index 273735785109c26521ce447a1b77d6860c124719..e018aef006ec0f5c9165dc56f19885f517f7c6d3 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
@@ -55,22 +56,14 @@ gNBs =
         initialDLBWPsearchSpaceZero                                             = 0;
       #pdsch-ConfigCommon
         #pdschTimeDomainAllocationList (up to 16 entries)
-             initialDLBWPk0_0                    = 0;
-             #initialULBWPmappingType
-	     #0=typeA,1=typeB
-             initialDLBWPmappingType_0           = 0;
-             #this is SS=2,L=3
-             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_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 (but is not used here)
+        initialDLBWPmappingType_1           = 0;
+        initialDLBWPstartSymbolAndLength_1  = 57; #this is SS=1,L=5
+
   #uplinkConfigCommon 
      #frequencyInfoUL
       ul_frequencyBand                                                 = 257;
@@ -125,15 +118,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 2;
+        initialULBWPk2_0                      = 2;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
- 	
-	initialULBWPk2_1                      = 2;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 2;  # used for mixed slot (not used here)
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
+
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
+        initialULBWPmappingType_2             = 1;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
 
         msg3_DeltaPreamble                                          = 1;
@@ -176,7 +171,7 @@ gNBs =
       nrofUplinkSlots                                               = 10;
       nrofUplinkSymbols                                             = 0;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf
index f810dd546cab7fa7352dd27682e273aef61d333a..834060b071731f9df400830291adffe6f81dab5b 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf
@@ -23,8 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
-    pusch_TargetSNRx10                                        = 200;
-    pucch_TargetSNRx10                                        = 200;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
@@ -57,27 +56,14 @@ gNBs =
         initialDLBWPsearchSpaceZero                                             = 0;
       #pdsch-ConfigCommon
         #pdschTimeDomainAllocationList (up to 16 entries)
-             initialDLBWPk0_0                    = 0;
-             #initialULBWPmappingType
-	     #0=typeA,1=typeB
-             initialDLBWPmappingType_0           = 0;
-             #this is SS=2,L=3
-             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=4 //5 (4 is for 43, 5 is for 57)
-             initialDLBWPstartSymbolAndLength_3  = 57; //43; //57;
+        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                                                 = 261;
@@ -112,8 +98,8 @@ gNBs =
 #1,2,4,8,10,20,40,80
         ra_ResponseWindow                                           = 7;
 #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
-#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
-        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 3;
 #oneHalf (0..15) 4,8,12,16,...60,64
         ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 7;
 #ra_ContentionResolutionTimer
@@ -132,20 +118,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;
+        initialULBWPk2_0                      = 6;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
 
-        initialULBWPk2_1                      = 6;
+        initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
-        initialULBWPk2_2                      = 14;
+        initialULBWPk2_2                      = 4;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
@@ -187,7 +170,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
@@ -239,16 +222,19 @@ gNBs =
 
 MACRLCs = (
 	{
-	num_cc = 1;
-	tr_s_preference = "local_L1";
-	tr_n_preference = "local_RRC";
-        }  
+	    num_cc              = 1;
+	    tr_s_preference     = "local_L1";
+	    tr_n_preference     = "local_RRC";
+	    pusch_TargetSNRx10  = 200;
+        pucch_TargetSNRx10  = 200;
+    }
 );
 
 L1s = (
     	{
 	num_cc = 1;
 	tr_n_preference = "local_mac";
+	pusch_proc_threads = 8;
         }  
 );
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
index 9e13d493a8acc095e27d134e2b6d6e0dbaf0ca8b..2028f405527468ba66ad4cbc5949b0099d422e6d 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
@@ -55,27 +56,14 @@ gNBs =
         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=4
-             initialDLBWPstartSymbolAndLength_3  = 57;
+        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                                                 = 66;
@@ -131,20 +119,18 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;
+        initialULBWPk2_0                      = 6;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
 
-  initialULBWPk2_1                      = 6;
+        initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
-        initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
+
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
 
@@ -185,7 +171,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
@@ -225,19 +211,20 @@ 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"
+         local_rf       = "yes"
          nb_tx          = 1;
          nb_rx          = 1;
          att_tx         = 0;
@@ -246,8 +233,14 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 75;
          eNB_instances  = [0];
-         #beamforming 1x4 matrix:
-         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+         ## 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";
          # if_freq = 3700000000L;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
index 831f9c7978f738041d2e7242e04b63efd1cf4ac0..35c4924ba1c1f491a8254bc83fb29c3f494f524b 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
@@ -55,27 +56,14 @@ gNBs =
         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=4
-             initialDLBWPstartSymbolAndLength_3  = 57;
+        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                                                 = 66;
@@ -131,20 +119,18 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;
+        initialULBWPk2_0                      = 6;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
 
-  initialULBWPk2_1                      = 6;
+        initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
-        initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
+
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
 
@@ -185,7 +171,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
@@ -225,19 +211,20 @@ 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"
+         local_rf       = "yes"
          nb_tx          = 1;
          nb_rx          = 1;
          att_tx         = 0;
@@ -246,8 +233,14 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 114;
          eNB_instances  = [0];
-         #beamforming 1x4 matrix:
-         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+         ## 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 = "type=x300";
          clock_src = "external";
          # if_freq = 3700000000L;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf
index 1cd16d08319379277e9401aa0e40e9ccc196eecc..f90adae46ba3d1f8027a237cd761ebef0b850ebc 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 31;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
@@ -46,7 +47,7 @@ gNBs =
      #initialDownlinkBWP
       #genericParameters
         # this is RBstart=84,L=13 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 6366;
+        initialDLBWPlocationAndBandwidth                                        = 6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
@@ -55,22 +56,14 @@ gNBs =
         initialDLBWPsearchSpaceZero                                             = 0;
       #pdsch-ConfigCommon
         #pdschTimeDomainAllocationList (up to 16 entries)
-             initialDLBWPk0_0                    = 0;
-             #initialULBWPmappingType
-	     #0=typeA,1=typeB
-             initialDLBWPmappingType_0           = 0;
-             #this is SS=2,L=3
-             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_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;
@@ -83,7 +76,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 6366;
+        initialULBWPlocationAndBandwidth                                        = 6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -125,16 +118,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 2;
+        initialULBWPk2_0                      = 2;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
- 	
-	initialULBWPk2_1                      = 2;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 2;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
+        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;
@@ -176,7 +170,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
index dfae41f0a6b47a1251b7b28b667ff6f294df3fb1..aa61153c93c3e5a87a4735ba4e3aa21c782440f0 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
@@ -46,7 +47,7 @@ gNBs =
      #initialDownlinkBWP
       #genericParameters
         # this is RBstart=0,L=50 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 6366;
+        initialDLBWPlocationAndBandwidth                                        = 6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
@@ -55,27 +56,13 @@ gNBs =
         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=4
-             initialDLBWPstartSymbolAndLength_3  = 57;
+        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
@@ -89,7 +76,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 6366;
+        initialULBWPlocationAndBandwidth                                        = 6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -131,21 +118,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 2;
+        initialULBWPk2_0                      = 2;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
- 	
-	initialULBWPk2_1                      = 2;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 2;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
-	initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
-
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf
index dcdfa003a26495723a2c733f62678c63ee105d95..a0ee7f8a6d65c2550eaf436598ff6bc108cad308 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
@@ -55,22 +56,14 @@ gNBs =
         initialDLBWPsearchSpaceZero                                             = 0;
       #pdsch-ConfigCommon
         #pdschTimeDomainAllocationList (up to 16 entries)
-             initialDLBWPk0_0                    = 0;
-             #initialULBWPmappingType
-	     #0=typeA,1=typeB
-             initialDLBWPmappingType_0           = 0;
-             #this is SS=2,L=3
-             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_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 (but not used here)
+        initialDLBWPmappingType_1           = 0;
+        initialDLBWPstartSymbolAndLength_1  = 57; #this is SS=1,L=5
+
   #uplinkConfigCommon 
      #frequencyInfoUL
       ul_frequencyBand                                                 = 78;
@@ -125,16 +118,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 2;
+        initialULBWPk2_0                      = 2;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
- 	
-	initialULBWPk2_1                      = 2;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 2;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 63; # this is SS=7 L=5
 
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
+        initialULBWPmappingType_2             = 1;
+        initialULBWPstartSymbolAndLength_2    = 91; # this is SS=7 L=7
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf
new file mode 100644
index 0000000000000000000000000000000000000000..d08234ab1678ba1e0a8e6c7d71f7aaff1f88e953
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf
@@ -0,0 +1,324 @@
+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  =  1;
+
+   plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
+
+   tr_s_preference     = "local_mac"
+
+   ////////// Physical parameters:
+
+   ssb_SubcarrierOffset                                           = 0;
+   pdsch_AntennaPorts                                             = 1;
+   pusch_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=0,L=50 (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;  #for DL slot
+     initialDLBWPmappingType_0           = 0;  #0=typeA,1=typeB
+     initialDLBWPstartSymbolAndLength_0  = 40; #this is SS=1,L=13
+
+     initialDLBWPk0_3                    = 0;  #for mixed slot
+     initialDLBWPmappingType_3           = 0;
+     initialDLBWPstartSymbolAndLength_3  = 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                              = 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
+     initialULBWPstartSymbolAndLength_0                            = 41;
+
+     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                                             = -25;
+  }
+
+  );
+
+ # Dedicated Serving Cell Configuration
+  servingCellConfigDedicated = (
+  {
+    # DL PTRS related parameters.
+    # 3GPP TS 38.331 PTRS-DownlinkConfig
+
+    # frequencyDensity value range: 1-276
+    dl_ptrsFreqDensity0_0                                           = 25;
+    dl_ptrsFreqDensity1_0                                           = 75;
+
+    # timeDensity value range: 0-29
+    dl_ptrsTimeDensity0_0                                           =  2;
+    dl_ptrsTimeDensity1_0                                           =  4;
+    dl_ptrsTimeDensity2_0                                           = 10;
+
+    # epre_Ratio
+    # 0 = "00", 1 = "01" in TS 38.214, table 4.1-2
+    dl_ptrsEpreRatio_0                                              =  0;
+
+    # resourceElementOffset
+    # 0 = offset01 1 = offset02, 2 = offset02
+    # 3GPP TS 38.331 PTRS-DownlinkConfig; TS 38.211 sec. 7.4.1.2.2
+    dl_ptrsReOffset_0                                               =  0;
+
+    # UL PTRS related parameters.
+    # 3GPP TS 38.331 PTRS-UplinkConfig
+
+    # frequencyDensity value range: 1-276
+    ul_ptrsFreqDensity0_0                                           = 25;
+    ul_ptrsFreqDensity1_0                                           = 75;
+
+    # timeDensity value range: 0-29
+    ul_ptrsTimeDensity0_0                                           =  2;
+    ul_ptrsTimeDensity1_0                                           =  4;
+    ul_ptrsTimeDensity2_0                                           = 10;
+
+    # resourceElementOffset
+    # 0 = offset01 1 = offset02, 2 = offset02
+    # TS 38.331 PTRS-UplinkConfig; TS 38.211 sec. 6.4.1.2.2.1
+    ul_ptrsReOffset_0                                               =  0;
+
+    # maxNrofPorts
+    # 0 = n1, 1 = n2
+    ul_ptrsMaxPorts_0                                               =  0;
+
+    # ptrs-Power
+    # 0 = p00, 1 = p01, 2 = p10, 3 = p11
+    #ul_ptrsPower_0                                                 =  0;
+    }
+  );
+
+  # ------- 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 = "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 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 = "type=x300";
+   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";
+};
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.adrv9371zc706.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.adrv9371zc706.conf
deleted file mode 100644
index 5610694d7d94e2afc07e00843bc4a1baf3837a7a..0000000000000000000000000000000000000000
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.adrv9371zc706.conf
+++ /dev/null
@@ -1,288 +0,0 @@
-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  =  1;
-
-    plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});	 
-
-    tr_s_preference     = "local_mac"
-
-    ////////// Physical parameters:
-
-    component_carriers = (
-      {
-      node_function                                                 = "3GPP_gNODEB";
-      node_timing                                                   = "synch_to_ext_device";
-      node_synch_ref                                                = 0;
-      frame_type                                                    = "TDD";
-      DL_prefix_type                                                = "NORMAL";
-      UL_prefix_type                                                = "NORMAL";
-      eutra_band                                                    = 78;
-      downlink_frequency                                            = 3510000000L;
-      uplink_frequency_offset                                       = 0;
-      Nid_cell                                                      = 0;
-      N_RB_DL                                                       = 106;
-      nb_antenna_ports                                              = 1;
-      nb_antennas_tx                                                = 1;
-      nb_antennas_rx                                                = 1;
-      tx_gain                                                       = 90;
-      rx_gain                                                       = 125;
-      MIB_subCarrierSpacingCommon                                   = 30;
-      MIB_ssb_SubcarrierOffset                                      = 0;
-      MIB_dmrs_TypeA_Position                                       = 2;
-      pdcch_ConfigSIB1                                              = 0;
-      SIB1_frequencyOffsetSSB                                       = "khz5";
-      SIB1_ssb_PeriodicityServingCell                               = 5;
-      SIB1_ss_PBCH_BlockPower                                       = -60;
-      absoluteFrequencySSB                                          = 0;
-      DL_FreqBandIndicatorNR                                        = 15;
-      DL_absoluteFrequencyPointA                                    = 15;
-      DL_offsetToCarrier                                            = 15;
-      DL_SCS_SubcarrierSpacing                                      = "kHz30";
-      DL_SCS_SpecificCarrier_k0                                     = 0;
-      DL_carrierBandwidth                                           = 15;
-      DL_locationAndBandwidth                                       = 15;
-      DL_BWP_SubcarrierSpacing                                      = "kHz30";
-      DL_BWP_prefix_type                                            = "NORMAL";
-      UL_FreqBandIndicatorNR                                        = 15;
-      UL_absoluteFrequencyPointA                                    = 13;
-      UL_additionalSpectrumEmission                                 = 3;
-      UL_p_Max                                                      = -1;
-      UL_frequencyShift7p5khz                                       = "TRUE";
-      UL_offsetToCarrier                                            = 10;
-      UL_SCS_SubcarrierSpacing                                      = "kHz30";
-      UL_SCS_SpecificCarrier_k0                                     = 0;
-      UL_carrierBandwidth                                           = 15;
-      UL_locationAndBandwidth                                       = 15;
-      UL_BWP_SubcarrierSpacing                                      = "kHz30";
-      UL_BWP_prefix_type                                            = "NORMAL";
-      UL_timeAlignmentTimerCommon                                   = "infinity";
-      ServingCellConfigCommon_n_TimingAdvanceOffset                 = "n0"
-      ServingCellConfigCommon_ssb_PositionsInBurst_PR               = 0x01;
-      ServingCellConfigCommon_ssb_periodicityServingCell            = 10;
-      ServingCellConfigCommon_dmrs_TypeA_Position                   = 2;
-      NIA_SubcarrierSpacing                                         = "kHz15"; 
-      ServingCellConfigCommon_ss_PBCH_BlockPower                    = -60;
-      referenceSubcarrierSpacing                                    = "kHz15";
-      dl_UL_TransmissionPeriodicity                                 = "ms0p5";
-      nrofDownlinkSlots                                             = 10;
-      nrofDownlinkSymbols                                           = 10;
-      nrofUplinkSlots                                               = 10;
-      nrofUplinkSymbols                                             = 10;
-      rach_totalNumberOfRA_Preambles                                = 63;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_choice         = "oneEighth";
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneEighth      = 4;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneFourth      = 8;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneHalf        = 16;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_one            = 24;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_two            = 32;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_four           = 8;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_eight          = 4;
-      rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_sixteen        = 2;
-      rach_groupBconfigured                                         = "ENABLE";
-      rach_ra_Msg3SizeGroupA                                        = 56;
-      rach_messagePowerOffsetGroupB                                 = "dB0";
-      rach_numberOfRA_PreamblesGroupA                               = 32;
-      rach_ra_ContentionResolutionTimer                             = 8;
-      rsrp_ThresholdSSB                                             = 64;
-      rsrp_ThresholdSSB_SUL                                         = 64;
-      prach_RootSequenceIndex_choice                                = "l839";
-      prach_RootSequenceIndex_l839                                  = 0;
-      prach_RootSequenceIndex_l139                                  = 0;
-      prach_msg1_SubcarrierSpacing                                  = "kHz30";
-      restrictedSetConfig                                           = "unrestrictedSet";
-      msg3_transformPrecoding                                       = "ENABLE";
-      prach_ConfigurationIndex                                      = 10;
-      prach_msg1_FDM                                                = "one";
-      prach_msg1_FrequencyStart                                     = 10;
-      zeroCorrelationZoneConfig                                     = 10;
-      preambleReceivedTargetPower                                   = -150;
-      preambleTransMax                                              = 6;
-      powerRampingStep                                              = "dB0";
-      ra_ResponseWindow                                             = 8;
-      groupHoppingEnabledTransformPrecoding                         = "ENABLE";
-      msg3_DeltaPreamble                                            = 0;
-      p0_NominalWithGrant                                           = 0;
-      PUSCH_TimeDomainResourceAllocation_k2                         = 0;
-      PUSCH_TimeDomainResourceAllocation_mappingType                = "typeA";
-      PUSCH_TimeDomainResourceAllocation_startSymbolAndLength       = 0;
-      pucch_ResourceCommon                                          = 0;
-      pucch_GroupHopping                                            = "neither";
-      hoppingId                                                     = 0;
-      p0_nominal                                                    = -30;
-      PDSCH_TimeDomainResourceAllocation_k0                         = 2;
-      PDSCH_TimeDomainResourceAllocation_mappingType                = "typeA";
-      PDSCH_TimeDomainResourceAllocation_startSymbolAndLength       = 0;
-      rateMatchPatternId                                            = 0;
-      RateMatchPattern_patternType                                  = "bitmaps";
-      symbolsInResourceBlock                                        = "oneSlot";
-      periodicityAndPattern                                         = 2;
-      RateMatchPattern_controlResourceSet                           = 5;
-      RateMatchPattern_subcarrierSpacing                            = "kHz30";
-      RateMatchPattern_mode                                         = "dynamic";
-      controlResourceSetZero                                        = 0;
-      searchSpaceZero                                               = 0;
-      searchSpaceSIB1                                               = 10;
-      searchSpaceOtherSystemInformation                             = 10;
-      pagingSearchSpace                                             = 10;
-      ra_SearchSpace                                                = 10;
-      PDCCH_common_controlResourceSetId                             = 5;
-      PDCCH_common_ControlResourceSet_duration                      = 2;
-      PDCCH_cce_REG_MappingType                                     = "nonInterleaved";
-      PDCCH_reg_BundleSize                                          = 3;
-      PDCCH_interleaverSize                                         = 3;
-      PDCCH_shiftIndex                                              = 10;  
-      PDCCH_precoderGranularity                                     = "sameAsREG-bundle";
-      PDCCH_TCI_StateId                                             = 32;
-      tci_PresentInDCI                                              = "ENABLE";
-      PDCCH_DMRS_ScramblingID                                       = 0;
-      SearchSpaceId                                                 = 10;
-      commonSearchSpaces_controlResourceSetId                       = 5;
-      SearchSpace_monitoringSlotPeriodicityAndOffset_choice         = "sl1";
-      SearchSpace_monitoringSlotPeriodicityAndOffset_value          = 0;
-      SearchSpace_duration                                          = 2;
-      SearchSpace_nrofCandidates_aggregationLevel1                  = 0;
-      SearchSpace_nrofCandidates_aggregationLevel2                  = 0;
-      SearchSpace_nrofCandidates_aggregationLevel4                  = 0;
-      SearchSpace_nrofCandidates_aggregationLevel8                  = 0;
-      SearchSpace_nrofCandidates_aggregationLevel16                 = 0;
-      SearchSpace_searchSpaceType                                   = "common";
-      Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1     = 1;
-      Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2     = 1;
-      Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4     = 1;
-      Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8     = 1;
-      Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16    = 1; 
-      Common_dci_Format2_3_monitoringPeriodicity                    = 1;
-      Common_dci_Format2_3_nrofPDCCH_Candidates                     = 1;
-      ue_Specific__dci_Formats                                      = "formats0-0-And-1-0";
-      RateMatchPatternLTE_CRS_carrierFreqDL                         = 6;
-      RateMatchPatternLTE_CRS_carrierBandwidthDL                    = 6;
-      RateMatchPatternLTE_CRS_nrofCRS_Ports                         = 1;
-      RateMatchPatternLTE_CRS_v_Shift                               = 0;
-      RateMatchPatternLTE_CRS_radioframeAllocationPeriod            = 1;
-      RateMatchPatternLTE_CRS_radioframeAllocationOffset            = 0;
-      RateMatchPatternLTE_CRS_subframeAllocation_choice             = "oneFrame";
-      }
-    );
-
-
-    srb1_parameters :
-    {
-        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
-        timer_poll_retransmit    = 80;
-
-        # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
-        timer_reordering         = 35;
-
-        # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
-        timer_status_prohibit    = 0;
-
-        # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
-        poll_pdu                 =  4;
-
-        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
-        poll_byte                =  99999;
-
-        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
-        max_retx_threshold       =  4;
-    }
-
-    # ------- SCTP definitions
-    SCTP :
-    {
-        # Number of streams to use in input/output
-        SCTP_INSTREAMS  = 2;
-        SCTP_OUTSTREAMS = 2;
-    };
-
-
-    ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "192.168.12.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 = "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                    = 114;
-         eNB_instances  = [0];
-	 sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=192.168.100.8";
-
-    }
-);  
-
-NETWORK_CONTROLLER :
-{
-    FLEXRAN_ENABLED        = "no";
-    FLEXRAN_INTERFACE_NAME = "lo";
-    FLEXRAN_IPV4_ADDRESS   = "127.0.0.1";
-    FLEXRAN_PORT           = 2210;
-    FLEXRAN_CACHE          = "/mnt/oai_agent_cache";
-    FLEXRAN_AWAIT_RECONF   = "no";
-};
-
-     log_config :
-     {
-       global_log_level                      ="info";
-       global_log_verbosity                  ="medium";
-       hw_log_level                          ="info";
-       hw_log_verbosity                      ="medium";
-       phy_log_level                         ="info";
-       phy_log_verbosity                     ="medium";
-       mac_log_level                         ="info";
-       mac_log_verbosity                     ="high";
-       rlc_log_level                         ="info";
-       rlc_log_verbosity                     ="medium";
-       pdcp_log_level                        ="info";
-       pdcp_log_verbosity                    ="medium";
-       rrc_log_level                         ="info";
-       rrc_log_verbosity                     ="medium";
-    };
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf
index 862f0e6303f29bca115302c991c844f18af76649..f22d5f781f22d398e8fb80789f92f07c65740196 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
@@ -55,22 +56,14 @@ gNBs =
         initialDLBWPsearchSpaceZero                                             = 0;
       #pdsch-ConfigCommon
         #pdschTimeDomainAllocationList (up to 16 entries)
-             initialDLBWPk0_0                    = 0;
-             #initialULBWPmappingType
-	     #0=typeA,1=typeB
-             initialDLBWPmappingType_0           = 0;
-             #this is SS=2,L=3
-             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_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;
@@ -125,16 +118,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 2;
+        initialULBWPk2_0                      = 2;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
- 	
-	initialULBWPk2_1                      = 2;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 2;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
+        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;
@@ -176,7 +170,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
@@ -228,7 +222,7 @@ L1s = (
 
 RUs = (
     {		  
-       local_rf       = "yes"
+         local_rf       = "yes"
          nb_tx          = 1
          nb_rx          = 1
          att_tx         = 0
@@ -237,7 +231,15 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 114;
          eNB_instances  = [0];
-	 sdr_addrs = "type=b200";
+         ## beamforming 1x2 matrix: 1 layer x 2 antennas
+         #bf_weights = [0x00007fff, 0x00007fff];
+         ## 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 = "type=b200";
          #clock_src = "external";
     }
 );  
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
index 760689f653f19bb50f79afd99850d53a46784437..b57cb00779d41a7e2224fbb88b2d25dba8fc9c42 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
@@ -32,7 +33,7 @@ gNBs =
 
 #  downlinkConfigCommon
     #frequencyInfoDL
-      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP), points to Subcarrier 0 of RB#10 of SSB block
       absoluteFrequencySSB                                          = 641032;
       dl_frequencyBand                                                 = 78;
       # this is 3600 MHz
@@ -45,37 +46,23 @@ gNBs =
         dl_carrierBandwidth                                            = 106;
      #initialDownlinkBWP
       #genericParameters
-        # this is RBstart=41,L=24 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 6366;
+        # this is RBstart=33 (Start RB of SSB block),L=24 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6358; #6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
       #pdcch-ConfigCommon
-        initialDLBWPcontrolResourceSetZero                                      = 12;
+        initialDLBWPcontrolResourceSetZero                                      = 0; #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;
+        initialDLBWPk0_0                    = 0;  # used for (full) DL slot
+        initialDLBWPmappingType_0           = 0;  # 0=typeA,1=typeB
+        initialDLBWPstartSymbolAndLength_0  = 40; # this is SS=1,L=13
+
+        initialDLBWPk0_1                    = 0;  # used for DL part mixed slot
+        initialDLBWPmappingType_1           = 0;
+        initialDLBWPstartSymbolAndLength_1  = 57; # this is SS=1,L=5
 
   #uplinkConfigCommon 
      #frequencyInfoUL
@@ -89,7 +76,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 6366;
+        initialULBWPlocationAndBandwidth                                        = 6358;#6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -131,20 +118,17 @@ gNBs =
         restrictedSetConfig                                         = 0,
 
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;
+        initialULBWPk2_0                      = 6;  # used for (full) UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
 
-        initialULBWPk2_1                      = 6;
+        initialULBWPk2_1                      = 6;  # used for UL part mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
-        initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
@@ -158,7 +142,7 @@ gNBs =
 # ssb_PositionsInBurs_BitmapPR
 # 1=short, 2=medium, 3=long
       ssb_PositionsInBurst_PR                                       = 2;
-      ssb_PositionsInBurst_Bitmap                                   = 1;
+      ssb_PositionsInBurst_Bitmap                                   = 0x1;
 
 # ssb_periodicityServingCell
 # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 
@@ -186,7 +170,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
@@ -226,20 +210,20 @@ 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;
-        }  
+	pusch_proc_threads = 8;
+	}
 );
 
 RUs = (
     {		  
-       local_rf       = "yes"
+         local_rf       = "yes"
          nb_tx          = 1
          nb_rx          = 1
          att_tx         = 0
@@ -248,15 +232,14 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 50;
          eNB_instances  = [0];
-         ##beamforming 1x2 matrix: 1 layer x 2 antennas
-         bf_weights = [0x00007fff, 0x0000];
-         ##beamforming 1x4 matrix: 1 layer x 4 antennas
+         ## beamforming 1x2 matrix: 1 layer x 2 antennas
+         #bf_weights = [0x00007fff, 0x00007fff];
+         ## beamforming 1x4 matrix: 1 layer x 4 antennas
          #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
          ## beamforming 2x2 matrix:
-         # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
+         #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";
     }
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
index d38fff42419efb95e1f4ecdee4ce4bc0d66ab98a..862185835e3dc7abd7cd306d95d345bed3144b35 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
@@ -23,7 +23,8 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
-	
+    pusch_AntennaPorts                                        = 1;
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
@@ -32,7 +33,7 @@ gNBs =
 
 #  downlinkConfigCommon
     #frequencyInfoDL
-      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP). points to Subcarrier 0 of RB#10 of SSB block
       absoluteFrequencySSB                                          = 641032;
       dl_frequencyBand                                                 = 78;
       # this is 3600 MHz
@@ -45,37 +46,24 @@ gNBs =
         dl_carrierBandwidth                                            = 106;
      #initialDownlinkBWP
       #genericParameters
-        # this is RBstart=0,L=50 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 6366;
+        # this is RBstart=33 (Start RB of SSB block),L=24 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6358; #6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
       #pdcch-ConfigCommon
-        initialDLBWPcontrolResourceSetZero                                      = 12;
+        initialDLBWPcontrolResourceSetZero                                      = 0;
         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=4
-             initialDLBWPstartSymbolAndLength_3  = 57;
+        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
@@ -89,7 +77,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 6366;
+        initialULBWPlocationAndBandwidth                                        = 6358; #6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -131,21 +119,17 @@ gNBs =
         restrictedSetConfig                                         = 0,
 
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;
+        initialULBWPk2_0                      = 6;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
- 	
-	initialULBWPk2_1                      = 6;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
-	initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
-
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
@@ -187,7 +171,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;  // -25 dBm/RE is the maximum measured power from USRP corresponding to att_tx = 0 dB
   }
 
   );
@@ -227,14 +211,15 @@ 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 = (
@@ -248,8 +233,14 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 114;
          eNB_instances  = [0];
-         #beamforming 1x4 matrix:
-         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+         ##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 = "type=x300";
          clock_src = "external";
     }
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
index 40361aaf4e8ffa042fec8f82965afe156c668bbc..335c3d9f0b5aae258d9d9494d133070c5caef658 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
@@ -32,7 +33,7 @@ gNBs =
 
 #  downlinkConfigCommon
     #frequencyInfoDL
-      # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP)
+      # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP). Points to Subcarrier 0 of RB#10 of SSB block
       absoluteFrequencySSB                                          = 642016;#642364;
       dl_frequencyBand                                                 = 78;
       # this is 3600 MHz
@@ -45,37 +46,24 @@ gNBs =
         dl_carrierBandwidth                                            = 217;
      #initialDownlinkBWP
       #genericParameters
-        # this is RBstart=84,L=50 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 13559;
+        # this is RBstart=74 (Start RB of SSB block),L=50 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 13549;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
       #pdcch-ConfigCommon
-        initialDLBWPcontrolResourceSetZero                                      = 12;
+        initialDLBWPcontrolResourceSetZero                                      = 0;
         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;
+        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;
@@ -88,7 +76,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 13559;
+        initialULBWPlocationAndBandwidth                                        = 13549;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -130,21 +118,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6; #2;
+        initialULBWPk2_0                      = 6;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
- 	
-	initialULBWPk2_1                      = 6; #2;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
-        initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
-
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
@@ -186,7 +170,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
@@ -249,6 +233,7 @@ L1s = (
     	{
 	num_cc = 1;
 	tr_n_preference = "local_mac";
+        pusch_proc_threads = 8;
         }  
 );
 
@@ -291,7 +276,7 @@ log_config :
        global_log_verbosity                  ="medium";
        hw_log_level                          ="info";
        hw_log_verbosity                      ="medium";
-       phy_log_level                         ="debug";
+       phy_log_level                         ="info";
        phy_log_verbosity                     ="medium";
        mac_log_level                         ="info";
        mac_log_verbosity                     ="high";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
index c907dcfe8d84c38ea5f7ae353408d45de201cb09..bf75edc360e56a0130fc99177694617ef4def640 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
@@ -45,37 +46,24 @@ gNBs =
         dl_carrierBandwidth                                            = 217;
      #initialDownlinkBWP
       #genericParameters
-        # this is RBstart=84,L=50 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 13559;
+        # this is RBstart=74,L=50 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 13549;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
       #pdcch-ConfigCommon
-        initialDLBWPcontrolResourceSetZero                                      = 12;
+        initialDLBWPcontrolResourceSetZero                                      = 0;
         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;
+        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;
@@ -88,7 +76,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 13559;
+        initialULBWPlocationAndBandwidth                                        = 13549;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -130,16 +118,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 2;
+        initialULBWPk2_0                      = 2;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
- 	
-	initialULBWPk2_1                      = 2;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 2;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
+        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;
@@ -181,7 +170,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
@@ -228,6 +217,7 @@ L1s = (
     	{
 	num_cc = 1;
 	tr_n_preference = "local_mac";
+        pusch_proc_threads = 8;
         }  
 );
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf
new file mode 100644
index 0000000000000000000000000000000000000000..b4f40d2205d0c7b29b75572647962b5d30d1c59c
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf
@@ -0,0 +1,277 @@
+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  =  1;
+
+    plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});	 
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
+	
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 640288;
+      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                                            = 24;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=41,L=24 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6325;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 0;
+        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_3                    = 0;  #for mixed slot
+        initialDLBWPmappingType_3           = 0;
+        initialDLBWPstartSymbolAndLength_3  = 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                                            = 24;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 6325;
+# 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
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 6;
+        initialULBWPmappingType_1             = 1;
+        initialULBWPstartSymbolAndLength_1    = 69;
+
+        initialULBWPk2_2                      = 7;
+        initialULBWPmappingType_2             = 1;
+        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                                             = -25;
+  }
+
+  );
+
+
+    # ------- 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 = "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                    = 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 = "type=b200";
+         #"addr=192.168.18.207";
+         #"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";
+    };
+
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf
new file mode 100644
index 0000000000000000000000000000000000000000..639b11828ba98cb07b9257507310aa228e8e6925
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf
@@ -0,0 +1,275 @@
+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  =  1;
+
+    plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});	 
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
+	
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 640288;
+      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                                            = 24;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=41,L=24 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6325;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 0;
+        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_3                    = 0;  #for mixed slot
+        initialDLBWPmappingType_3           = 0;
+        initialDLBWPstartSymbolAndLength_3  = 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                                            = 24;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 6325;
+# 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
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 6;
+        initialULBWPmappingType_1             = 1;
+        initialULBWPstartSymbolAndLength_1    = 69;
+
+        initialULBWPk2_2                      = 7;
+        initialULBWPmappingType_2             = 1;
+        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                                             = -25;
+  }
+
+  );
+
+
+    # ------- 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 = "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                    = 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                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+    };
+
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf
new file mode 100644
index 0000000000000000000000000000000000000000..b93b530bed6f9deaf1d6be4e9b433de33613d93b
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf
@@ -0,0 +1,275 @@
+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  =  1;
+
+    plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 640288;
+      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                                            = 24;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=41,L=24 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6325;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 0;
+        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_3                    = 0;  #for mixed slot
+        initialDLBWPmappingType_3           = 0;
+        initialDLBWPstartSymbolAndLength_3  = 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                                            = 24;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 6325;
+# 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
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 6;
+        initialULBWPmappingType_1             = 1;
+        initialULBWPstartSymbolAndLength_1    = 69;
+
+        initialULBWPk2_2                      = 7;
+        initialULBWPmappingType_2             = 1;
+        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                                             = -25;
+  }
+
+  );
+
+
+    # ------- 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 = "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 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 = "type=x300";
+         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";
+    };
+
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
index a899845cb8913e82a529bed2b0809215be7c3f6e..50276c32897ab2fd805981f17922303ce43b5868 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
@@ -45,37 +46,24 @@ gNBs =
         dl_carrierBandwidth                                            = 273;
      #initialDownlinkBWP
       #genericParameters
-        # this is RBstart=84,L=50 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 13559;
+        # this is RBstart=74,L=50 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 13549;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
       #pdcch-ConfigCommon
-        initialDLBWPcontrolResourceSetZero                                      = 12;
+        initialDLBWPcontrolResourceSetZero                                      = 0;
         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;
+        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;
@@ -88,7 +76,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 13559;
+        initialULBWPlocationAndBandwidth                                        = 13549;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -130,21 +118,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;#2;
+        initialULBWPk2_0                      = 6;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
- 	
-	initialULBWPk2_1                      = 6;#2;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
 
-        initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
-
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
@@ -186,7 +170,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-  ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
@@ -233,6 +217,7 @@ L1s = (
     	{
 	num_cc = 1;
 	tr_n_preference = "local_mac";
+        pusch_proc_threads = 8;
         }  
 );
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf
index 5f65a2c80136d16eb07ad6d15685ddf5d71d2359..e541607559c555b15cd1b05452ab8d1a1e30d3a0 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
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..6df25273c83e506c8d286c3bacb8b8f7ad703896 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";
   }
 );
 
@@ -263,7 +263,7 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 118;
          eNB_instances  = [0];
-         clock_src = "external";
+         clock_src = "internal";
     }
 );  
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
index c46ea98ec24cb204ca326f25d25b9fb1815a39d8..7d21dce681162e31336431a27f33b8d1aaea3f71 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
@@ -23,8 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 31; //0;
     pdsch_AntennaPorts                                        = 1;
-    pusch_TargetSNRx10                                        = 200;
-    pucch_TargetSNRx10                                        = 200;
+    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
@@ -48,7 +47,7 @@ gNBs =
      #initialDownlinkBWP
       #genericParameters
         # this is RBstart=84,L=13 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 6366; //28875; //6366; #6407; #3384;
+        initialDLBWPlocationAndBandwidth                                        = 6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
@@ -57,27 +56,14 @@ gNBs =
         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=4 //5 (4 is for 43, 5 is for 57)
-             initialDLBWPstartSymbolAndLength_3  = 57; //43; //57;
+        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;
@@ -90,7 +76,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 6366; //28875; //6366; #6407; #3384;
+        initialULBWPlocationAndBandwidth                                        = 6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -132,20 +118,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 2;
+        initialULBWPk2_0                      = 2;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_0    = 55;
- 	
-	initialULBWPk2_1                      = 2;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 2;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 24; # this is SS=10 L=2
 
-        initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
@@ -203,7 +186,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";
@@ -226,10 +209,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
@@ -239,17 +222,19 @@ gNBs =
 
 MACRLCs = (
 	{
-	num_cc = 1;
-	tr_s_preference = "local_L1";
-	tr_n_preference = "local_RRC";
-        }  
+	    num_cc              = 1;
+	    tr_s_preference     = "local_L1";
+	    tr_n_preference     = "local_RRC";
+	    pusch_TargetSNRx10  = 200;
+        pucch_TargetSNRx10  = 200;
+    }
 );
 
 L1s = (
     	{
 	num_cc = 1;
 	tr_n_preference = "local_mac";
-  pusch_proc_threads = 8;
+	pusch_proc_threads = 8;
         }  
 );
 
@@ -264,7 +249,7 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 114;
          eNB_instances  = [0];
-         clock_src = "external";
+         clock_src = "internal";
     }
 );  
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf
new file mode 100644
index 0000000000000000000000000000000000000000..463b7d6d069ab77be97605b08acc4ea7eedd446e
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf
@@ -0,0 +1,307 @@
+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  =  1;
+
+    plmn_list = ({mcc = 222; mnc = 01; mnc_length = 2;});	 
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 31; //0;
+    pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 12 PRBs@30kHz SCS 
+      absoluteFrequencySSB                                          = 640288;
+      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                                            = 24;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=0,L=24 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 6325; 
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 0;
+        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=4 //5 (4 is for 43, 5 is for 57)
+             initialDLBWPstartSymbolAndLength_3  = 57; //43; //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                                            = 24;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 6325; 
+# 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                               = -100;
+#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                                           = 5;
+#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; //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                      = 2;
+        initialULBWPmappingType_0             = 1
+        # this is SS=0 L=13
+        initialULBWPstartSymbolAndLength_0    = 41; 
+ 	
+	initialULBWPk2_1                      = 2;
+        initialULBWPmappingType_1             = 1;
+        # this is SS=0 L=11
+        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; #0x80;
+
+# 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; //8; //7;
+      nrofDownlinkSymbols                                           = 6; //0; //6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4; //0; //4;
+
+  ssPBCH_BlockPower                                             = -25;
+  }
+
+  );
+
+
+    # ------- 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.18.99";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    ///X2
+    enable_x2 = "yes";
+    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       = "192.168.18.199";
+                                       ipv6       = "192:168:30::17";
+                                       preference = "ipv4";
+                                     }
+                                    );
+
+    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_PORT_FOR_S1U                         = 2152; # Spec 2152
+        GNB_IPV4_ADDRESS_FOR_X2C                 = "192.168.18.198/24";
+        GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
+    };
+  }
+);
+
+MACRLCs = (
+	{
+	    num_cc              = 1;
+	    tr_s_preference     = "local_L1";
+	    tr_n_preference     = "local_RRC";
+	    pusch_TargetSNRx10  = 200;
+        pucch_TargetSNRx10  = 200;
+    }
+);
+
+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 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];
+         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";
+    //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                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+    };
+
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf
index 6a3f008ec1a02a538f4b73f278381fda9c33a8bd..767459aecbfc3727c5ad726bbcdb87e6ca954720 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf
@@ -23,6 +23,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 31; //0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
@@ -46,7 +47,7 @@ gNBs =
      #initialDownlinkBWP
       #genericParameters
         # this is RBstart=84,L=13 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 6366; //28875; //6366; #6407; #3384;
+        initialDLBWPlocationAndBandwidth                                        = 6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
@@ -55,27 +56,14 @@ gNBs =
         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=4 //5 (4 is for 43, 5 is for 57)
-             initialDLBWPstartSymbolAndLength_3  = 57; //43; //57;
+        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;
@@ -88,7 +76,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 6366; //28875; //6366; #6407; #3384;
+        initialULBWPlocationAndBandwidth                                        = 6368;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -130,20 +118,17 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 2;
+        initialULBWPk2_0                      = 2;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
- 	
-	initialULBWPk2_1                      = 2;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
+
+        initialULBWPk2_1                      = 2;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 24; # this is SS=10 L=2
 
-        initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
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 108cf06033b77f5f33afe98117b50dc19c63cc38..1a28ebb9508b7eebbd3ebba0da22e437a2decdd6 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
@@ -7,20 +7,34 @@ 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  =  1;
-    plmn_list = ({mcc = 222; mnc = 93; 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:
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 
      pdcch_ConfigSIB1 = (
       {
@@ -50,8 +64,8 @@ gNBs =
         dl_carrierBandwidth                                            = 106;
      #initialDownlinkBWP
       #genericParameters
-        # this is RBstart=41,L=24 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                               = 6366; # 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;
@@ -60,32 +74,13 @@ gNBs =
         initialDLBWPsearchSpaceZero                                     = 0;
       #pdsch-ConfigCommon
         #pdschTimeDomainAllocationList (up to 16 entries)
-             initialDLBWPk0_0                    = 0;
-             #initialULBWPmappingType
-	         #0=typeA,1=typeB
-             initialDLBWPmappingType_0           = 0;
-             #this is SS=2,L=12
-             initialDLBWPstartSymbolAndLength_0  = 53;
-
-             initialDLBWPk0_1                    = 0;
-             initialDLBWPmappingType_1           = 0;
-             #this is SS=2,L=10
-             initialDLBWPstartSymbolAndLength_1  = 81;
-
-             initialDLBWPk0_2                    = 0;
-             initialDLBWPmappingType_2           = 0;
-             #this is SS=1,L=12
-             initialDLBWPstartSymbolAndLength_2  = 95;
-
-             initialDLBWPk0_3                    = 0;
-             initialDLBWPmappingType_3           = 0;
-             #this is SS=2,L=7
-             initialDLBWPstartSymbolAndLength_3  = 86;
-
-             initialDLBWPk0_4                    = 0;
-             initialDLBWPmappingType_4           = 0;
-             #this is SS=2,L=5
-             initialDLBWPstartSymbolAndLength_4  = 58;
+        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
@@ -99,7 +94,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                            = 6366;
+        initialULBWPlocationAndBandwidth                            = 12952;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
         initialULBWPsubcarrierSpacing                               = 1;
@@ -111,7 +106,7 @@ gNBs =
           prach_msg1_FDM                                            = 0;
           prach_msg1_FrequencyStart                                 = 0;
           zeroCorrelationZoneConfig                                 = 13;
-          preambleReceivedTargetPower                               = -100;
+          preambleReceivedTargetPower                               = -96;
 #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
           preambleTransMax                                          = 6;
 #powerRampingStep
@@ -141,20 +136,17 @@ gNBs =
         restrictedSetConfig                                         = 0,
 
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;
+        initialULBWPk2_0                      = 6;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
 
-        initialULBWPk2_1                      = 6;
+        initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 52; # this is SS=10 L=4
 
-        initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
@@ -196,7 +188,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-      ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
@@ -212,53 +204,43 @@ 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
     };
 
   }
 );
 
 MACRLCs = (
-	{
-	num_cc = 1;
-	tr_s_preference = "local_L1";
-	tr_n_preference = "local_RRC";
-        }
+    {
+        num_cc                      = 1;
+        tr_s_preference             = "local_L1";
+        tr_n_preference             = "local_RRC";
+        ulsch_max_slots_inactivity  = 100;
+        pusch_TargetSNRx10          = 200;
+        pucch_TargetSNRx10          = 200;
+    }
 );
 
 L1s = (
-    	{
+    {
 	num_cc = 1;
 	tr_n_preference = "local_mac";
-        }
+	pusch_proc_threads = 8;
+    }
 );
 
 RUs = (
@@ -312,5 +294,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 4373f38e7bdc833d47d472f4513465904e2a0c28..718038657b30ae4052f750988beb71f9759e0d4c 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
@@ -7,20 +7,34 @@ 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  =  1;
-    plmn_list = ({mcc = 222; mnc = 93; 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:
 
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
 
      pdcch_ConfigSIB1 = (
       {
@@ -50,8 +64,8 @@ gNBs =
         dl_carrierBandwidth                                            = 106;
      #initialDownlinkBWP
       #genericParameters
-        # this is RBstart=41,L=24 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                               = 6366; # 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;
@@ -60,32 +74,13 @@ gNBs =
         initialDLBWPsearchSpaceZero                                     = 0;
       #pdsch-ConfigCommon
         #pdschTimeDomainAllocationList (up to 16 entries)
-             initialDLBWPk0_0                    = 0;
-             #initialULBWPmappingType
-	         #0=typeA,1=typeB
-             initialDLBWPmappingType_0           = 0;
-             #this is SS=2,L=12
-             initialDLBWPstartSymbolAndLength_0  = 53;
-
-             initialDLBWPk0_1                    = 0;
-             initialDLBWPmappingType_1           = 0;
-             #this is SS=2,L=10
-             initialDLBWPstartSymbolAndLength_1  = 81;
-
-             initialDLBWPk0_2                    = 0;
-             initialDLBWPmappingType_2           = 0;
-             #this is SS=1,L=12
-             initialDLBWPstartSymbolAndLength_2  = 95;
-
-             initialDLBWPk0_3                    = 0;
-             initialDLBWPmappingType_3           = 0;
-             #this is SS=2,L=7
-             initialDLBWPstartSymbolAndLength_3  = 86;
-
-             initialDLBWPk0_4                    = 0;
-             initialDLBWPmappingType_4           = 0;
-             #this is SS=2,L=5
-             initialDLBWPstartSymbolAndLength_4  = 58;
+        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
@@ -99,7 +94,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                            = 6366;
+        initialULBWPlocationAndBandwidth                            = 12952;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
         initialULBWPsubcarrierSpacing                               = 1;
@@ -111,7 +106,7 @@ gNBs =
           prach_msg1_FDM                                            = 0;
           prach_msg1_FrequencyStart                                 = 0;
           zeroCorrelationZoneConfig                                 = 13;
-          preambleReceivedTargetPower                               = -100;
+          preambleReceivedTargetPower                               = -96;
 #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
           preambleTransMax                                          = 6;
 #powerRampingStep
@@ -141,20 +136,17 @@ gNBs =
         restrictedSetConfig                                         = 0,
 
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;
+        initialULBWPk2_0                      = 6;  # used for UL slot
         initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
+        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
 
-        initialULBWPk2_1                      = 6;
+        initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
+        initialULBWPstartSymbolAndLength_1    = 52; # this is SS=10 L=4
 
-        initialULBWPk2_2                      = 7;
+        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
+        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
@@ -196,7 +188,7 @@ gNBs =
       nrofUplinkSlots                                               = 2;
       nrofUplinkSymbols                                             = 4;
 
-      ssPBCH_BlockPower                                             = 10;
+      ssPBCH_BlockPower                                             = -25;
   }
 
   );
@@ -212,53 +204,43 @@ 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
     };
 
   }
 );
 
 MACRLCs = (
-	{
-	num_cc = 1;
-	tr_s_preference = "local_L1";
-	tr_n_preference = "local_RRC";
-        }
+    {
+        num_cc                      = 1;
+        tr_s_preference             = "local_L1";
+        tr_n_preference             = "local_RRC";
+        ulsch_max_slots_inactivity  = 100;
+        pusch_TargetSNRx10          = 200;
+        pucch_TargetSNRx10          = 200;
+    }
 );
 
 L1s = (
-    	{
+    {
 	num_cc = 1;
 	tr_n_preference = "local_mac";
-        }
+	pusch_proc_threads = 8;
+    }
 );
 
 RUs = (
@@ -312,5 +294,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.sabox.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf
new file mode 100644
index 0000000000000000000000000000000000000000..9892f974677e607b1dbf2966ad599eab5a236173
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf
@@ -0,0 +1,328 @@
+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  =  1;
+    plmn_list = ({
+                  mcc = 450;
+                  mnc = 05;
+                  mnc_length = 2;
+                  snssaiList = (	
+                    {	     
+                      sst = 1;
+                      sd  = 0xd143a5; // 0 false, else true
+                    }
+                  );
+
+                  });
+ 
+    tr_s_preference     = "local_mac"
+
+    ////////// 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;
+             #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                            = 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;
+        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                                             = -25;
+  }
+
+  );
+
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    amf_ip_address      = ( { ipv4       = "192.168.5.233";
+                              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_NG_AMF            = "eth0";
+        GNB_IPV4_ADDRESS_FOR_NG_AMF              = "192.168.5.200/24";
+        GNB_INTERFACE_NAME_FOR_NGU               = "eth0";
+        GNB_IPV4_ADDRESS_FOR_NGU                 = "192.168.5.200/24";
+        GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
+        GNB_IPV4_ADDRESS_FOR_X2C                 = "192.168.5.200/24";
+        GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
+    };
+
+  }
+);
+
+MACRLCs = (
+	{
+	    num_cc              = 1;
+	    tr_s_preference     = "local_L1";
+	    tr_n_preference     = "local_RRC";
+	    pusch_TargetSNRx10  = 200;
+        pucch_TargetSNRx10  = 200;
+    }
+);
+
+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/targets/RT/USER/eNB_usrp.gtkw b/targets/RT/USER/eNB_usrp.gtkw
index 074e3b1324a7082b57390d368aa123b341ecfc7d..8f3aeaac6261bb652ce2788be01e3e1457b4fb21 100644
--- a/targets/RT/USER/eNB_usrp.gtkw
+++ b/targets/RT/USER/eNB_usrp.gtkw
@@ -1,13 +1,13 @@
 [*]
 [*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI
-[*] Sun May 19 21:39:57 2019
+[*] Tue Jan 26 21:45:57 2021
 [*]
-[dumpfile] "/tmp/openair_dump_eNB.vcd"
-[dumpfile_mtime] "Sun May 19 21:30:25 2019"
-[dumpfile_size] 11590554
-[savefile] "/home/sphex/raymond/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw"
-[timestart] 7629910000
-[size] 1840 795
+[dumpfile] "/home/eurecom/raymond/gtkw/openair_dump_eNB.vcd"
+[dumpfile_mtime] "Tue Jan 26 21:26:33 2021"
+[dumpfile_size] 180869253
+[savefile] "/home/eurecom/raymond/openairinterface5g_2/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw"
+[timestart] 11468800000
+[size] 1693 785
 [pos] -1 -1
 *-21.832302 7639830000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
 [sst_width] 386
@@ -16,17 +16,22 @@
 [sst_vpaned_height] 303
 @28
 functions.trx_read
+@29
+functions.trx_write_thread
+@28
 functions.trx_write
 @24
 variables.trx_ts[63:0]
 variables.trx_tst[63:0]
+variables.trx_write_flags[63:0]
 @28
 functions.eNB_thread_rxtx0
+@420
+variables.l1_proc_tx_ic[63:0]
+variables.l1_proc_ic[63:0]
 @24
 variables.frame_number_RX0_RU[63:0]
-@25
 variables.tti_number_RX0_RU[63:0]
-@24
 variables.frame_number_TX0_RU[63:0]
 variables.tti_number_TX0_RU[63:0]
 @28
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 531670580912cdbc2f7699245c5dda7c4d4e3c52..31c142c8daecd25ac9eeb5d6e28913f35d8fdc2b 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -70,6 +70,7 @@
 
 #include "PHY/LTE_TRANSPORT/if4_tools.h"
 #include "PHY/LTE_TRANSPORT/if5_tools.h"
+#include "PHY/LTE_ESTIMATION/lte_estimation.h"
 
 #include "PHY/phy_extern.h"
 
@@ -96,6 +97,9 @@
 
 #include "T.h"
 
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
+
 //#define DEBUG_THREADS 1
 
 //#define USRP_DEBUG 1
@@ -261,7 +265,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,
   eNB->UL_INFO.subframe  = proc->subframe_rx;
   eNB->UL_INFO.module_id = eNB->Mod_id;
   eNB->UL_INFO.CC_id     = eNB->CC_id;
-  eNB->if_inst->UL_indication(&eNB->UL_INFO, proc);
+  eNB->if_inst->UL_indication(&eNB->UL_INFO, (void*)proc);
   AssertFatal((ret= pthread_mutex_unlock(&eNB->UL_INFO_mutex))==0,"error unlocking UL_INFO_mutex, return %d\n",ret);
   /* this conflict resolution may be totally wrong, to be tested */
   /* CONFLICT RESOLUTION: BEGIN */
@@ -323,7 +327,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,
 static void *L1_thread_tx(void *param) {
   L1_proc_t *eNB_proc  = (L1_proc_t *)param;
   L1_rxtx_proc_t *proc = &eNB_proc->L1_proc_tx;
-  PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
+  PHY_VARS_eNB *eNB = eNB_proc->eNB;
   char thread_name[100];
   sprintf(thread_name,"TXnp4_%d\n",&eNB->proc.L1_proc == proc ? 0 : 1);
   thread_top_init(thread_name,1,470000,500000,500000);
@@ -331,6 +335,7 @@ static void *L1_thread_tx(void *param) {
 
   //wait_sync("tx_thread");
 
+  proc->respEncode = eNB->proc.L1_proc.respEncode;
   while (!oai_exit) {
     LOG_D(PHY,"Waiting for TX (IC %d)\n",proc->instance_cnt);
 
@@ -351,21 +356,19 @@ static void *L1_thread_tx(void *param) {
     LOG_D(PHY,"L1 TX processing %d.%d\n",proc->frame_tx,proc->subframe_tx);
     phy_procedures_eNB_TX(eNB, proc, 1);
     AssertFatal((ret= pthread_mutex_lock( &proc->mutex ))==0,"error locking L1_proc_tx mutex, return %d\n",ret);
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_L1_PROC_TX_IC,proc->instance_cnt);
     int subframe_tx = proc->subframe_tx;
     int frame_tx    = proc->frame_tx;
     uint64_t timestamp_tx = proc->timestamp_tx;
     proc->instance_cnt = -1;
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_L1_PROC_TX_IC,proc->instance_cnt);
     LOG_D(PHY,"L1 TX signaling done for %d.%d\n",proc->frame_tx,proc->subframe_tx);
     // the thread can now be woken up
     LOG_D(PHY,"L1_thread_tx: signaling completion in %d.%d\n",proc->frame_tx,proc->subframe_tx);
 
-    if (pthread_cond_signal(&proc->cond) != 0) {
-      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
-      exit_fun( "ERROR pthread_cond_signal" );
-    }
-
+    AssertFatal((ret=pthread_cond_signal(&proc->cond))== 0, "ERROR pthread_cond_signal for eNB TXnp4 thread ret %d\n",ret);
     AssertFatal((ret= pthread_mutex_unlock( &proc->mutex ))==0,"error unlocking L1_proc_tx mutex, return %d\n",ret);
+
+
     wakeup_txfh(eNB,proc,frame_tx,subframe_tx,timestamp_tx);
   }
 
@@ -391,6 +394,8 @@ static void *L1_thread( void *param ) {
   }
 
   PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
+
+
   char thread_name[100];
   cpu_set_t cpuset;
   CPU_ZERO(&cpuset);
@@ -402,7 +407,7 @@ static void *L1_thread( void *param ) {
   LOG_I(PHY,"thread rxtx created id=%ld\n", syscall(__NR_gettid));
 
   while (!oai_exit) {
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0, 0 );
     T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
     LOG_D(PHY,"L1RX waiting for RU RX\n");
 
@@ -410,7 +415,7 @@ static void *L1_thread( void *param ) {
 
     LOG_D(PHY,"L1RX starting in %d.%d\n",proc->frame_rx,proc->subframe_rx);
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX,sched_getcpu());
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0, 1 );
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB,proc->subframe_tx);
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_ENB,proc->subframe_rx);
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB,proc->frame_tx);
@@ -424,6 +429,8 @@ static void *L1_thread( void *param ) {
 
     LOG_D(PHY,"L1 RX %d.%d done\n",proc->frame_rx,proc->subframe_rx);
 
+    if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break;
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_L1_PROC_IC, proc->instance_cnt);
     if (NFAPI_MODE!=NFAPI_MODE_VNF) {
       if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)     wakeup_tx(eNB,proc->frame_rx,proc->subframe_rx,proc->frame_tx,proc->subframe_tx,proc->timestamp_tx);
       else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) {
@@ -432,9 +439,7 @@ static void *L1_thread( void *param ) {
       }
     }
 
-    if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break;
   } // while !oai_exit
-
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
   LOG_D(PHY, " *** Exiting eNB thread RXn_TXnp4\n");
   eNB_thread_rxtx_status = 0;
@@ -530,6 +535,7 @@ int wakeup_txfh(PHY_VARS_eNB *eNB,
     AssertFatal(pthread_cond_signal(&ru_proc->cond_eNBs) == 0,
                 "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
     AssertFatal((ret=pthread_mutex_unlock(&ru_proc->mutex_eNBs))==0,"mutex_unlock returned %d\n",ret);
+
   }
 
   return(0);
@@ -542,19 +548,19 @@ int wakeup_tx(PHY_VARS_eNB *eNB,
               int frame_tx,
               int subframe_tx,
               uint64_t timestamp_tx) {
-  L1_rxtx_proc_t *L1_proc = &eNB->proc.L1_proc;
   L1_rxtx_proc_t *L1_proc_tx = &eNB->proc.L1_proc_tx;
   int ret;
   LOG_D(PHY,"ENTERED wakeup_tx (IC %d)\n",L1_proc_tx->instance_cnt);
+  // check if subframe is a has TX else return
+  if (subframe_select(&eNB->frame_parms,subframe_tx) == SF_UL) return 0;  
   AssertFatal((ret = pthread_mutex_lock(&L1_proc_tx->mutex))==0,"mutex_lock returns %d\n",ret);
-  LOG_D(PHY,"L1 RX %d.%d Waiting to wake up L1 TX %d.%d (IC L1TX %d)\n",L1_proc->frame_rx,L1_proc->subframe_rx,L1_proc->frame_tx,L1_proc->subframe_tx,L1_proc_tx->instance_cnt);
+  LOG_D(PHY,"L1 RX %d.%d Waiting to wake up L1 TX %d.%d (IC L1TX %d)\n",frame_rx,subframe_rx,frame_tx,subframe_tx,L1_proc_tx->instance_cnt);
 
   while(L1_proc_tx->instance_cnt == 0) {
     pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex);
   }
 
   LOG_D(PHY,"L1 RX Got signal that TX %d.%d is done\n",L1_proc_tx->frame_tx,L1_proc_tx->subframe_tx);
-  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_L1_PROC_TX_IC,L1_proc_tx->instance_cnt);
   L1_proc_tx->instance_cnt = 0;
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_L1_PROC_TX_IC,L1_proc_tx->instance_cnt);
   L1_proc_tx->subframe_rx   = subframe_rx;
@@ -563,9 +569,11 @@ int wakeup_tx(PHY_VARS_eNB *eNB,
   L1_proc_tx->frame_tx      = frame_tx;
   L1_proc_tx->timestamp_tx  = timestamp_tx;
   // the thread can now be woken up
-  LOG_D(PHY,"L1 RX Waking up L1 TX %d.%d\n",L1_proc->frame_tx,L1_proc->subframe_tx);
+  LOG_D(PHY,"L1 RX Waking up L1 TX %d.%d\n",frame_tx,subframe_tx);
+
   AssertFatal(pthread_cond_signal(&L1_proc_tx->cond) == 0, "ERROR pthread_cond_signal for eNB L1 thread tx\n");
   AssertFatal((ret=pthread_mutex_unlock(&L1_proc_tx->mutex))==0,"mutex_unlock returns %d\n",ret);
+
   return(0);
 }
 
@@ -585,10 +593,16 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,
   if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe
     AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"mutex_unlock return %d\n",ret);
     LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
+/*    AssertFatal(1==0,"L1_thread isn't ready in %d.%d (L1RX %d.%d), aborting RX, exiting\n",
+      ru_proc->frame_rx,ru_proc->tti_rx,L1_proc->frame_rx,L1_proc->subframe_rx);
+*/
     return(0);
+   
   }
 
   ++L1_proc->instance_cnt;
+  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_L1_PROC_IC, L1_proc->instance_cnt);
+
   // We have just received and processed the common part of a subframe, say n.
   // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
   // transmitted timestamp of the next TX slot (first).
@@ -606,14 +620,12 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_RXTX_TX_RU+ru->idx, L1_proc->frame_tx);
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_RXTX_TX_RU+ru->idx, L1_proc->subframe_tx);
 
-  // the thread can now be woken up
-  if (pthread_cond_signal(&L1_proc->cond) != 0) {
-    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
-    exit_fun( "ERROR pthread_cond_signal" );
-    return(-1);
-  }
 
+  // the thread can now be woken up
+  AssertFatal((ret=pthread_cond_signal(&L1_proc->cond))== 0, "ERROR pthread_cond_signal for eNB RXn-TXnp4 thread, ret %d\n",ret);
   AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"mutex_unlock return %d\n",ret);
+
+
   return(0);
 }
 
@@ -837,6 +849,21 @@ static void *process_stats_thread(void *param) {
   return(NULL);
 }
 
+void *L1_stats_thread(void *param) {
+  PHY_VARS_eNB     *eNB      = (PHY_VARS_eNB *)param;
+  wait_sync("L1_stats_thread");
+  FILE *fd;
+  while (!oai_exit) {
+    sleep(1);
+    fd=fopen("L1_stats.log","w");
+    AssertFatal(fd!=NULL,"Cannot open L1_stats.log\n");
+    dump_I0_stats(fd,eNB);
+    dump_ulsch_stats(fd,eNB,eNB->proc.L1_proc_tx.frame_tx);
+    dump_uci_stats(fd,eNB,eNB->proc.L1_proc_tx.frame_tx);
+    fclose(fd);
+  }
+  return(NULL);
+}
 
 void init_eNB_proc(int inst) {
   /*int i=0;*/
@@ -858,6 +885,7 @@ void init_eNB_proc(int inst) {
     L1_proc_tx->instance_cnt       = -1;
     L1_proc->instance_cnt_RUs      = 0;
     L1_proc_tx->instance_cnt_RUs   = 0;
+    proc->eNB                      = eNB;
     proc->instance_cnt_prach       = -1;
     proc->instance_cnt_asynch_rxtx = -1;
     proc->instance_cnt_synch       = -1;
@@ -930,6 +958,7 @@ void init_eNB_proc(int inst) {
     AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);
 
     if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void *)eNB);
+    pthread_create(&proc->L1_stats_thread,NULL,L1_stats_thread,(void*)eNB);
   }
 
   //for multiple CCs: setup master and slaves
@@ -1060,60 +1089,47 @@ void print_opp_meas(void) {
 
 
 void free_transport(PHY_VARS_eNB *eNB) {
-  for (int i=0; i<NUMBER_OF_UE_MAX; i++) {
-    LOG_D(PHY, "Freeing Transport Channel Buffers for DLSCH, UE %d\n",i);
+  for (int i=0; i<NUMBER_OF_DLSCH_MAX; i++) {
+    LOG_D(PHY, "Freeing Transport Channel Buffers for DLSCH %d\n",i);
 
     for (int j=0; j<2; j++) free_eNB_dlsch(eNB->dlsch[i][j]);
-
-    LOG_D(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i);
-    free_eNB_ulsch(eNB->ulsch[1+i]);
   }
-
-  free_eNB_ulsch(eNB->ulsch[0]);
+  for (int i=0;i<NUMBER_OF_ULSCH_MAX;i++) {
+    LOG_D(PHY, "Freeing Transport Channel Buffer for ULSCH %d\n",i);
+    free_eNB_ulsch(eNB->ulsch[i]);
+  }
 }
 
 
 void init_transport(PHY_VARS_eNB *eNB) {
-  int i;
-  int j;
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
   LOG_I(PHY, "Initialise transport\n");
 
   if (NFAPI_MODE!=NFAPI_MODE_VNF) {
-    for (i=0; i<NUMBER_OF_UE_MAX; i++) {
-      LOG_D(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
+    for (int i=0;i<NUMBER_OF_DLSCH_MAX; i++) {
+      LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH %d/%d/%d\n",i,NUMBER_OF_DLSCH_MAX,(i-NUMBER_OF_DLSCH_MAX)<0);
 
-      for (j=0; j<2; j++) {
+      for (int j=0; j<2; j++) {
         eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL,0,fp);
-
+        LOG_I(PHY,"eNB->dlsch[%d][%d] %p\n",i,j,eNB->dlsch[i][j]);
         if (!eNB->dlsch[i][j]) {
-          LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i);
+          LOG_E(PHY,"Can't get eNB dlsch structures for DLSCH %d \n", i);
           exit(-1);
         } else {
           eNB->dlsch[i][j]->rnti=0;
           LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti);
         }
       }
+    }
+    for (int i=0;i<NUMBER_OF_ULSCH_MAX; i++) {
 
-      LOG_D(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
-      eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0);
+      LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH %d/%d\n",i,NUMBER_OF_ULSCH_MAX);
+      eNB->ulsch[i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0);
 
-      if (!eNB->ulsch[1+i]) {
+      if (!eNB->ulsch[i]) {
         LOG_E(PHY,"Can't get eNB ulsch structures\n");
         exit(-1);
       }
-
-      // this is the transmission mode for the signalling channels
-      // this will be overwritten with the real transmission mode by the RRC once the UE is connected
-      eNB->transmission_mode[i] = fp->nb_antenna_ports_eNB==1 ? 1 : 2;
-    }
-
-    // ULSCH for RA
-    eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0);
-
-    if (!eNB->ulsch[0]) {
-      LOG_E(PHY,"Can't get eNB ulsch structures\n");
-      exit(-1);
     }
 
     eNB->dlsch_SI  = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp);
@@ -1126,7 +1142,7 @@ void init_transport(PHY_VARS_eNB *eNB) {
 
   eNB->rx_total_gain_dB=130;
 
-  for(i=0; i<NUMBER_OF_UE_MAX; i++)
+  for(int i=0; i<NUMBER_OF_UE_MAX; i++)
     eNB->mu_mimo_mode[i].dl_pow_off = 2;
 
   eNB->check_for_total_transmissions = 0;
@@ -1134,11 +1150,13 @@ void init_transport(PHY_VARS_eNB *eNB) {
   eNB->FULL_MUMIMO_transmissions = 0;
   eNB->check_for_SUMIMO_transmissions = 0;
   fp->pucch_config_common.deltaPUCCH_Shift = 1;
+  if (eNB->use_DTX == 0) fill_subframe_mask(eNB);
+  
 }
 
 
 void init_eNB_afterRU(void) {
-  int inst,CC_id,ru_id,i,aa;
+  int inst,CC_id,i;
   PHY_VARS_eNB *eNB;
   LOG_I(PHY,"%s() RC.nb_inst:%d\n", __FUNCTION__, RC.nb_inst);
 
@@ -1148,13 +1166,14 @@ void init_eNB_afterRU(void) {
     for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
       LOG_I(PHY,"RC.nb_CC[inst:%d][CC_id:%d]:%p\n", inst, CC_id, RC.eNB[inst][CC_id]);
       eNB                                  =  RC.eNB[inst][CC_id];
-      phy_init_lte_eNB(eNB,0,0);
-
-      // map antennas and PRACH signals to eNB RX
-      if (0) AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id);
-
+     // map antennas and PRACH signals to eNB RX
       LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id);
       eNB->frame_parms.nb_antennas_rx       = 0;
+      LOG_I(PHY,"eNB->num_RU:%d\n", eNB->num_RU);     
+      if (NFAPI_MODE==NFAPI_MODE_PNF) AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is      zero\n",eNB->Mod_id);
+      for (int ru_id=0; ru_id<eNB->num_RU; ru_id++) 
+         eNB->frame_parms.nb_antennas_rx    += eNB->RU_list[ru_id]->nb_rx;
+      phy_init_lte_eNB(eNB,0,0);
       LOG_I(PHY,"Overwriting eNB->prach_vars.rxsigF[0]:%p\n", eNB->prach_vars.rxsigF[0]);
       eNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *));
 
@@ -1163,10 +1182,8 @@ void init_eNB_afterRU(void) {
         eNB->prach_vars_br.rxsigF[ce_level] = (int16_t **)malloc16(64*sizeof(int16_t *));
       }
 
-      LOG_I(PHY,"eNB->num_RU:%d\n", eNB->num_RU);
 
-      for (ru_id=0,aa=0; ru_id<eNB->num_RU; ru_id++) {
-        eNB->frame_parms.nb_antennas_rx    += eNB->RU_list[ru_id]->nb_rx;
+      for (int ru_id=0,aa=0; ru_id<eNB->num_RU; ru_id++) {
 
         AssertFatal(eNB->RU_list[ru_id]->common.rxdataF!=NULL,
                     "RU %d : common.rxdataF is NULL\n",
@@ -1214,7 +1231,7 @@ void init_eNB_afterRU(void) {
     init_eNB_proc(inst);
   }
 
-  for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
+  for (int ru_id=0; ru_id<RC.nb_RU; ru_id++) {
     AssertFatal(RC.ru[ru_id]!=NULL,"ru_id %d is null\n",ru_id);
     RC.ru[ru_id]->wakeup_rxtx         = wakeup_rxtx;
     RC.ru[ru_id]->wakeup_prach_eNB    = wakeup_prach_eNB;
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 368fd78f9e8c01230ef5f957efb2398e64c03b32..86d3a88781d7086aca5f7164a697c5693e343ae4 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -51,7 +51,6 @@
 #include "assertions.h"
 #include "msc.h"
 #include "PHY/defs_common.h"
-#include "PHY/phy_extern.h"
 #include "PHY/types.h"
 #include "PHY/INIT/phy_init.h"
 #include "PHY/LTE_ESTIMATION/lte_estimation.h"
@@ -59,23 +58,11 @@
 #include "PHY/LTE_TRANSPORT/if4_tools.h"
 #include "PHY/LTE_TRANSPORT/if5_tools.h"
 #include "PHY/LTE_TRANSPORT/transport_proto.h"
-#include "PHY_INTERFACE/phy_interface.h"
-#include "LAYER2/MAC/mac.h"
-#include "LAYER2/MAC/mac_extern.h"
-#include "LAYER2/MAC/mac_proto.h"
-#include "RRC/LTE/rrc_extern.h"
-#include "SCHED/sched_eNB.h"
-#include "UTIL/OPT/opt.h"
-#include "UTIL/OTG/otg_tx.h"
-#include "UTIL/OTG/otg_externs.h"
-#include "UTIL/MATH/oml.h"
+#include "SCHED/sched_common.h"
 #include "common/utils/LOG/log.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
-#include "nfapi/oai_integration/vendor_ext.h"
-#include "enb_config.h"
 #include "targets/ARCH/COMMON/common_lib.h"
 #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
-#include "targets/RT/USER/lte-softmodem.h"
 //#include "PHY/TOOLS/time_meas.h"
 
 /* these variables have to be defined before including ENB_APP/enb_paramdef.h */
@@ -86,29 +73,25 @@ static int DEFBFW[] = {0x00007fff};
 #include "ENB_APP/enb_paramdef.h"
 #include "common/config/config_userapi.h"
 
-#ifndef OPENAIR2
-  #include "UTIL/OTG/otg_extern.h"
-#endif
-
-#include "s1ap_eNB.h"
 #include "SIMULATION/ETH_TRANSPORT/proto.h"
 
 #include "T.h"
 
-#include "pdcp.h"
+#include "executables/softmodem-common.h"
 
 #define MBMS_EXPERIMENTAL
 
 extern volatile int oai_exit;
-extern int emulate_rf;
-extern int numerology;
 extern clock_source_t clock_source;
 #include "executables/thread-common.h"
 //extern PARALLEL_CONF_t get_thread_parallel_conf(void);
 //extern WORKER_CONF_t   get_thread_worker_conf(void);
 extern void phy_init_RU(RU_t *);
 
-void stop_RU(int nb_ru);
+void prach_procedures(PHY_VARS_eNB *eNB,int br_flag);
+
+void stop_RU(RU_t **rup,int nb_ru);
+
 void do_ru_synch(RU_t *ru);
 
 void configure_ru(int idx,
@@ -124,13 +107,24 @@ void wait_eNBs(void);
 
 const char ru_states[6][9] = {"RU_IDLE","RU_CONFIG","RU_READY","RU_RUN","RU_ERROR","RU_SYNC"};
 
+extern const char NB_functions[7][20];
+extern const char NB_timing[2][20];
+
 extern uint16_t sf_ahead;
 
+extern const char ru_if_types[MAX_RU_IF_TYPES][20];
+
+
 #if defined(PRE_SCD_THREAD)
+#include "common/ran_context.h"
+#include "nfapi/oai_integration/vendor_ext.h"
+#include "openair2/LAYER2/MAC/mac_extern.h"
   extern uint8_t dlsch_ue_select_tbl_in_use;
   void init_ru_vnf(void);
+  extern RAN_CONTEXT_t RC;
 #endif
 
+RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond);
 
 /*************************************************************/
 /* Functions to attach and configure RRU                     */
@@ -141,7 +135,7 @@ extern uint16_t sf_ahead;
 
 // southbound IF5 fronthaul for 16-bit OAI format
 static inline void fh_if5_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) {
-  if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
+  if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
 
   ru->south_out_cnt++;
 
@@ -149,14 +143,12 @@ static inline void fh_if5_south_out(RU_t *ru,int frame, int subframe, uint64_t t
 }
 
 
-
-
 // southbound IF4p5 fronthaul
 static inline void fh_if4p5_south_out(RU_t *ru,
                                       int frame,
                                       int subframe,
                                       uint64_t timestamp) {
-  if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
+  if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
 
   LOG_D(PHY,"ENTERED fh_if4p5_south_out   Sending IF4p5 for frame %d subframe %d ru %d\n",ru->proc.frame_tx,ru->proc.tti_tx,ru->idx);
 
@@ -166,7 +158,7 @@ static inline void fh_if4p5_south_out(RU_t *ru,
     LOG_D(PHY,"south_out_cnt %d\n",ru->south_out_cnt);
   }
 
-  /*if (ru == RC.ru[0] || ru == RC.ru[1]) {
+  /*if (ru->idx == 0 || ru->idx == ru) {
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU+ru->idx, ru->proc.frame_tx );
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU+ru->idx, ru->proc.subframe_tx );
     }*/
@@ -227,31 +219,30 @@ void fh_if4p5_south_in(RU_t *ru,
     symbol_mask_full = (1<<fp->symbols_per_tti)-1;
 
   LOG_D(PHY,"fh_if4p5_south_in: RU %d, frame %d, subframe %d, ru %d, mask %x\n",ru->idx,*frame,*subframe,ru->idx,proc->symbol_mask[*subframe]);
-  AssertFatal(proc->symbol_mask[*subframe]==0 || proc->symbol_mask[*subframe]==symbol_mask_full,"rx_fh_if4p5: proc->symbol_mask[%d] = %x\n",*subframe,proc->symbol_mask[*subframe]);
+  //AssertFatal(proc->symbol_mask[*subframe]==0 || proc->symbol_mask[*subframe]>=symbol_mask_full,"rx_fh_if4p5: proc->symbol_mask[%d] = %x\n",*subframe,proc->symbol_mask[*subframe]); // >= because PULTICK for S-subframe could have been received during normal subframe
 
-  if (proc->symbol_mask[*subframe]==0) { // this is normal case, if not true then we received a PULTICK before the previous subframe was finished
+  if (proc->symbol_mask[*subframe]<symbol_mask_full) { // this is normal case, if not true then we received a PULTICK before the previous subframe was finished
     do {
       recv_IF4p5(ru, &f, &sf, &packet_type, &symbol_number);
-      LOG_D(PHY,"fh_if4p5_south_in: RU %d, frame %d, subframe %d, f %d, sf %d\n",ru->idx,*frame,*subframe,f,sf);
+      LOG_D(PHY,"fh_if4p5_south_in (%s/%d): RU %d, frame %d, subframe %d, f %d, sf %d, symbol %d\n",packet_type == IF4p5_PULFFT ? "PULFFT" : "PULTICK",packet_type,ru->idx,*frame,*subframe,f,sf,symbol_number);
 
       if (oai_exit == 1 || ru->cmd== STOP_RU) break;
 
       if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sf] = proc->symbol_mask[sf] | (1<<symbol_number);
       else if (packet_type == IF4p5_PULTICK) {
-        proc->symbol_mask[sf] = symbol_mask_full;
+        proc->symbol_mask[sf] = 0xffff;
         pultick_received++;
-
         /*
                  if ((proc->first_rx==0) && (f!=*frame)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received frame %d != expected %d (RU %d) \n",f,*frame, ru->idx);
                  else if ((proc->first_rx==0) && (sf!=*subframe)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n",sf,*subframe,proc->first_rx);
                  else break; */
-        if (f==*frame || sf==*subframe) break;
+        //if (f==*frame || sf==*subframe) break;
       } else if (packet_type == IF4p5_PRACH) {
         // nothing in RU for RAU
       }
 
-      LOG_D(PHY,"rx_fh_if4p5 for RU %d: subframe %d, sf %d, symbol mask %x\n",ru->idx,*subframe,sf,proc->symbol_mask[sf]);
-    } while(proc->symbol_mask[sf] != symbol_mask_full);
+      LOG_D(PHY,"rx_fh_if4p5 for RU %d: subframe %d, sf %d, symbol %d, symbol mask %x\n",ru->idx,*subframe,sf,symbol_number,proc->symbol_mask[sf]);
+    } while(proc->symbol_mask[*subframe] < symbol_mask_full);
   } else {
     f = *frame;
     sf = *subframe;
@@ -263,7 +254,7 @@ void fh_if4p5_south_in(RU_t *ru,
   proc->timestamp_rx = ((proc->frame_rx * 10)  + proc->tti_rx ) * fp->samples_per_tti ;
 
   //  proc->timestamp_tx = proc->timestamp_rx +  (4*fp->samples_per_tti);
-  if (get_nprocs()<=4) {
+  if (get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) {
     proc->tti_tx   = (sf+sf_ahead)%10;
     proc->frame_tx = (sf>(9-sf_ahead)) ? (f+1)&1023 : f;
   }
@@ -291,7 +282,7 @@ void fh_if4p5_south_in(RU_t *ru,
     *subframe = proc->tti_rx;
   }
 
-  /*if (ru == RC.ru[0] || ru == RC.ru[1]) {
+  /*if (ru->idx == 0 || ru->idx == 1) {
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU+ru->idx, f );
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_RU+ru->idx, sf );
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, f );
@@ -399,7 +390,7 @@ void fh_if4p5_north_in(RU_t *ru,
   ru->north_in_cnt++;
 
   // dump VCD output for first RU in list
-  if (ru == RC.ru[0]) {
+  if (ru->idx == 0) {
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, *frame );
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, *subframe );
   }
@@ -491,7 +482,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,
   LOG_D(PHY,"RU %d/%d TST %llu, frame %d, subframe %d\n",ru->idx,0,(long long unsigned int)proc->timestamp_tx,frame_tx,tti_tx);
 
   // dump VCD output for first RU in list
-  if (ru == RC.ru[0]) {
+  if (ru->idx == 0) {
     /*VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx );
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx );*/
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_NORTH_ASYNCH_IN, frame_tx);
@@ -557,8 +548,8 @@ volatile late_control_e late_control=STATE_BURST_NORMAL;
 static void *emulatedRF_thread(void *param) {
   RU_proc_t *proc = (RU_proc_t *) param;
   int microsec = 500; // length of time to sleep, in miliseconds
+  int numerology = 0 ;
   struct timespec req = {0};
-  int numerology = get_softmodem_params()->numerology;
   req.tv_sec = 0;
   req.tv_nsec = (numerology>0)? ((microsec * 1000L)/numerology):(microsec * 1000L)*2;
   cpu_set_t cpuset;
@@ -609,7 +600,7 @@ void rx_rf(RU_t *ru,
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
   old_ts = proc->timestamp_rx;
 
-  if(get_softmodem_params()->emulate_rf) {
+  if(ru->emulate_rf) {
     wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
     release_thread(&proc->mutex_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
     rxs = fp->samples_per_tti;
@@ -662,7 +653,7 @@ void rx_rf(RU_t *ru,
   proc->tti_rx  = (proc->timestamp_rx / fp->samples_per_tti)%10;
   // synchronize first reception to frame 0 subframe 0
 
-  if (ru->fh_north_asynch_in == NULL) {
+  if (get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD && ru->fh_north_asynch_in == NULL) {
 #ifdef PHY_TX_THREAD
     proc->timestamp_phy_tx = proc->timestamp_rx+((sf_ahead-1)*fp->samples_per_tti);
     proc->subframe_phy_tx  = (proc->tti_rx+(sf_ahead-1))%10;
@@ -690,16 +681,12 @@ void rx_rf(RU_t *ru,
           proc->frame_rx,
           proc->tti_rx);
 
-    // dump VCD output for first RU in list
-    if (ru == RC.ru[0]) {
-      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, proc->frame_rx );
-      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_RX0_RU, proc->tti_rx );
+  }
 
-      if (ru->fh_north_asynch_in == NULL) {
-        VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx );
-        VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, proc->tti_tx );
-      }
-    }
+  // dump VCD output for first RU in list
+  if (ru->idx == 0) {
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, proc->frame_rx );
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_RX0_RU, proc->tti_rx );
   }
 
   if (proc->first_rx == 0) {
@@ -790,6 +777,7 @@ void tx_rf(RU_t *ru,
 
     /* add fail safe for late command */
     if(late_control!=STATE_BURST_NORMAL) { //stop burst
+      LOG_E(PHY,"%d.%d late_control : %d\n",frame,subframe,late_control);
       switch (late_control) {
         case STATE_BURST_TERMINATE:
           flags=10; // end of burst and no time spec
@@ -818,12 +806,13 @@ void tx_rf(RU_t *ru,
           break;
       }
     }
-
-    /* add fail safe for late command end */
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame);
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, subframe);
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS,flags);
+ 
+    /* add fail safe for late command end */
+   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
     // prepare tx buffer pointers
     txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
                                       timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
@@ -841,7 +830,7 @@ void tx_rf(RU_t *ru,
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
 
     //    AssertFatal(txs ==  siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen);
-    if( (txs !=  siglen+sf_extension) && (late_control==STATE_BURST_NORMAL) ) { /* add fail safe for late command */
+    if( usrp_tx_thread == 0 && (txs !=  siglen+sf_extension) && (late_control==STATE_BURST_NORMAL) ) { /* add fail safe for late command */
       late_control=STATE_BURST_TERMINATE;
       LOG_E(PHY,"TX : Timeout (sent %d/%d) state =%d\n",txs, siglen,late_control);
     }
@@ -869,7 +858,6 @@ static void *ru_thread_asynch_rxtx( void *param ) {
   LOG_I(PHY, "devices ok (ru_thread_asynch_rxtx)\n");
 
   while (!oai_exit) {
-    if (oai_exit) break;
 
     if (ru->state != RU_RUN) {
       subframe=0;
@@ -955,7 +943,7 @@ void *ru_thread_prach( void *param ) {
   thread_top_init("ru_thread_prach",1,500000,1000000,20000000);
   //wait_sync("ru_thread_prach");
 
-  while (RC.ru_mask>0 && ru->function!=eNodeB_3GPP) {
+  while (*ru->ru_mask>0 && ru->function!=eNodeB_3GPP) {
     usleep(1e6);
     LOG_D(PHY,"%s() RACH waiting for RU to be configured\n", __FUNCTION__);
   }
@@ -1168,7 +1156,7 @@ void wakeup_L1s(RU_t *ru) {
     if (ru == eNB->RU_list[i] && eNB->RU_list[i]->wait_cnt == 0) {
       //AssertFatal((proc->RU_mask&(1<<i)) == 0, "eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", eNB->Mod_id,ru->proc.frame_rx,ru->proc.tti_rx,ru->idx,eNB->num_RU,proc->RU_mask);
       proc->RU_mask[ru->proc.tti_rx] |= (1<<i);
-    } else if (/*eNB->RU_list[i]->state == RU_SYNC ||*/(eNB->RU_list[i]->is_slave==1 && eNB->RU_list[i]->wait_cnt>0 && ru!=eNB->RU_list[i] && ru->is_slave==0) ) {
+    } else if (eNB->RU_list[i]->state == RU_SYNC ||(eNB->RU_list[i]->is_slave==1 && eNB->RU_list[i]->wait_cnt>0 && ru!=eNB->RU_list[i] /*&& ru->is_slave==0*/) ) {
       proc->RU_mask[ru->proc.tti_rx] |= (1<<i);
     }
 
@@ -1308,7 +1296,7 @@ void fill_rf_config(RU_t *ru,
   int numerology = get_softmodem_params()->numerology;
 
   if(fp->N_RB_DL == 100) {
-    if(numerology == 0) {
+    if(ru->numerology == 0) {
       if (fp->threequarter_fs) {
         cfg->sample_rate=23.04e6;
         cfg->samples_per_frame = 230400;
@@ -1320,12 +1308,12 @@ void fill_rf_config(RU_t *ru,
         cfg->tx_bw = 10e6;
         cfg->rx_bw = 10e6;
       }
-    } else if(numerology == 1) {
+    } else if(ru->numerology == 1) {
       cfg->sample_rate=61.44e6;
       cfg->samples_per_frame = 307200;
       cfg->tx_bw = 20e6;
       cfg->rx_bw = 20e6;
-    } else if(numerology == 2) {
+    } else if(ru->numerology == 2) {
       cfg->sample_rate=122.88e6;
       cfg->samples_per_frame = 307200;
       cfg->tx_bw = 40e6;
@@ -1524,36 +1512,43 @@ static void *ru_thread_tx( void *param ) {
     LOG_D(PHY,"ru_thread_tx (ru %d): Waiting for TX processing\n",ru->idx);
     // wait until eNBs are finished subframe RX n and TX n+4
     wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
-    LOG_D(PHY,"ru_thread_tx: TX in %d.%d\n",ru->proc.frame_tx,ru->proc.tti_tx);
+    ret = pthread_mutex_lock(&proc->mutex_eNBs);
+    AssertFatal(ret == 0,"mutex_lock return %d\n",ret);
+    int frame_tx=proc->frame_tx;
+    int tti_tx  =proc->tti_tx;
+    uint64_t timestamp_tx = proc->timestamp_tx;
+    ret = pthread_mutex_unlock(&proc->mutex_eNBs);
+    AssertFatal(ret == 0,"mutex_lock returns %d\n",ret);
+
 
     if (oai_exit) break;
 
     // do TX front-end processing if needed (precoding and/or IDFTs)
-    if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx);
+    if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx);
 
     // do OFDM if needed
-    if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx);
+    if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx);
 
-    if(!(get_softmodem_params()->emulate_rf)) { //if(!emulate_rf){
+    if(!(ru->emulate_rf)) { //if(!emulate_rf){
       // do outgoing fronthaul (south) if needed
-      if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx);
+      if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,tti_tx,timestamp_tx);
 
       if (ru->fh_north_out) ru->fh_north_out(ru);
     } else {
       for (int i=0; i<ru->nb_tx; i++) {
-        if(proc->frame_tx == 2) {
-          sprintf(filename,"txdataF%d_frame%d_sf%d.m",i,proc->frame_tx,proc->tti_tx);
+        if(frame_tx == 2) {
+          sprintf(filename,"txdataF%d_frame%d_sf%d.m",i,frame_tx,tti_tx);
           LOG_M(filename,"txdataF_frame",ru->common.txdataF_BF[i],fp->symbols_per_tti*fp->ofdm_symbol_size, 1, 1);
         }
 
-        if(proc->frame_tx == 2 && proc->tti_tx==0) {
-          sprintf(filename,"txdata%d_frame%d.m",i,proc->frame_tx);
+        if(frame_tx == 2 && tti_tx==0) {
+          sprintf(filename,"txdata%d_frame%d.m",i,frame_tx);
           LOG_M(filename,"txdata_frame",ru->common.txdata[i],fp->samples_per_tti*10, 1, 1);
         }
       }
     }
 
-    LOG_D(PHY,"ru_thread_tx: releasing RU TX in %d.%d\n", proc->frame_tx, proc->tti_tx);
+    LOG_D(PHY,"ru_thread_tx: releasing RU TX in %d.%d\n", frame_tx, tti_tx);
     release_thread(&proc->mutex_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
 
     for(int i = 0; i<ru->num_eNB; i++) {
@@ -1569,7 +1564,7 @@ static void *ru_thread_tx( void *param ) {
                   eNB->Mod_id,eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,eNB->num_RU,eNB_proc->RU_mask_tx);
 
           eNB_proc->RU_mask_tx |= (1<<j);
-        } else if (/*eNB->RU_list[j]->state==RU_SYNC ||*/ (eNB->RU_list[j]->is_slave==1 && eNB->RU_list[j]->wait_cnt>0 && ru!=eNB->RU_list[j] && ru->is_slave==0)) {
+        } else if (eNB->RU_list[j]->state==RU_SYNC ||(eNB->RU_list[j]->is_slave==1 && eNB->RU_list[j]->wait_cnt>0 && ru!=eNB->RU_list[j])) {
           eNB_proc->RU_mask_tx |= (1<<j);
         }
 
@@ -1585,7 +1580,7 @@ static void *ru_thread_tx( void *param ) {
         AssertFatal((ret=pthread_mutex_unlock(&eNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
         AssertFatal((ret=pthread_mutex_lock( &L1_proc->mutex_RUs))==0,"mutex_lock returns %d\n",ret);
         L1_proc->instance_cnt_RUs = 0;
-        LOG_D(PHY,"ru_thread_tx: Signaling RU TX done in %d.%d\n", proc->frame_tx, proc->tti_tx);
+        LOG_D(PHY,"ru_thread_tx: Signaling RU TX done in %d.%d\n", frame_tx, tti_tx);
         // the thread can now be woken up
         LOG_D(PHY,"ru_thread_tx: clearing mask and Waking up L1 thread\n");
 
@@ -1638,10 +1633,10 @@ static void *ru_thread( void *param ) {
     }
 
     LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx);
-    AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret);
-    RC.ru_mask &= ~(1<<ru->idx);
-    pthread_cond_signal(&RC.ru_cond);
-    AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret);
+    AssertFatal((ret=pthread_mutex_lock(ru->ru_mutex))==0,"mutex_lock returns %d\n",ret);
+    *ru->ru_mask &= ~(1<<ru->idx);
+    pthread_cond_signal(ru->ru_cond);
+    AssertFatal((ret=pthread_mutex_unlock(ru->ru_mutex))==0,"mutex_unlock returns %d\n",ret);
     ru->state = RU_RUN;
   } else if (ru->has_ctrl_prt == 0) {
     // There is no control port: start everything here
@@ -1661,10 +1656,10 @@ static void *ru_thread( void *param ) {
 	      exit(-1);
     }
 
-    AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret);
-    RC.ru_mask &= ~(1<<ru->idx);
-    pthread_cond_signal(&RC.ru_cond);
-    AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret);
+    AssertFatal((ret=pthread_mutex_lock(ru->ru_mutex))==0,"mutex_lock returns %d\n",ret);
+    *ru->ru_mask &= ~(1<<ru->idx);
+    pthread_cond_signal(ru->ru_cond);
+    AssertFatal((ret=pthread_mutex_unlock(ru->ru_mutex))==0,"mutex_unlock returns %d\n",ret);
     ru->state = RU_RUN;
   }
 
@@ -1673,6 +1668,17 @@ static void *ru_thread( void *param ) {
   pthread_cond_signal(&proc->cond_FH1);
   AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_FH1))==0,"mutex_unlock returns %d\n",ret);
 
+  if(usrp_tx_thread == 1){
+     if (ru->start_write_thread){
+        if(ru->start_write_thread(ru) != 0){
+            LOG_E(HW,"Could not start tx write thread\n");
+        }
+        else{
+            LOG_I(PHY,"tx write thread ready\n");
+        }
+     }
+  }
+
   while (!oai_exit) {
     if (ru->if_south != LOCAL_RF && ru->is_slave==1) {
       ru->wait_cnt = 100;
@@ -1683,10 +1689,12 @@ static void *ru_thread( void *param ) {
 
     // wait to be woken up
     if (ru->function!=eNodeB_3GPP && ru->has_ctrl_prt == 1) {
+      LOG_D(PHY,"RU %d: Waiting for control thread to say go\n",ru->idx);
       if (wait_on_condition(&ru->proc.mutex_ru,&ru->proc.cond_ru_thread,&ru->proc.instance_cnt_ru,"ru_thread")<0) break;
-    } else wait_sync("ru_thread");
+    } else wait_sync("ru_thread"); 
+    LOG_D(PHY,"RU %d: Got start from control thread\n",ru->idx);
 
-    if(!(get_softmodem_params()->emulate_rf)) {
+    if(!(ru->emulate_rf)) {
       if (ru->is_slave == 0) AssertFatal(ru->state == RU_RUN,"ru-%d state = %s != RU_RUN\n",ru->idx,ru_states[ru->state]);
       else if (ru->is_slave == 1) AssertFatal(ru->state == RU_SYNC || ru->state == RU_RUN ||
                                                 ru->state == RU_CHECK_SYNC,"ru %d state = %s != RU_SYNC or RU_RUN or RU_CHECK_SYNC\n",ru->idx,ru_states[ru->state]);
@@ -1712,7 +1720,7 @@ static void *ru_thread( void *param ) {
     // if this is a slave RRU, try to synchronize on the DL frequency
     if ((ru->is_slave == 1) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
 
-    LOG_D(PHY,"Starting steady-state operation\n");
+    if (ru->state == RU_RUN || ru->state == RU_CHECK_SYNC) LOG_I(PHY,"RU %d Starting steady-state operation\n",ru->idx);
 
     // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
     while (ru->state == RU_RUN || ru->state == RU_CHECK_SYNC) {
@@ -1773,14 +1781,14 @@ static void *ru_thread( void *param ) {
         ru->wait_cnt--;
         LOG_D(PHY,"RU thread %d, frame %d, subframe %d, wait_cnt %d \n",ru->idx, frame, subframe, ru->wait_cnt);
 
-        if (ru->if_south!=LOCAL_RF && ru->wait_cnt <=20 && subframe == 5 && frame != RC.ru[0]->proc.frame_rx && resynch_done == 0) {
+        if (ru->if_south!=LOCAL_RF && ru->wait_cnt <=20 && subframe == 5 && frame != ru->ru0->proc.frame_rx && resynch_done == 0) {
           // Send RRU_frame adjust
           RRU_CONFIG_msg_t rru_config_msg;
           rru_config_msg.type = RRU_frame_resynch;
           rru_config_msg.len  = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg len
-          ((uint16_t *)&rru_config_msg.msg[0])[0] = RC.ru[0]->proc.frame_rx;
+          ((uint16_t *)&rru_config_msg.msg[0])[0] = ru->ru0->proc.frame_rx;
           ru->cmd=WAIT_RESYNCH;
-          LOG_I(PHY,"Sending Frame Resynch %d to RRU %d\n", RC.ru[0]->proc.frame_rx,ru->idx);
+          LOG_I(PHY,"Sending Frame Resynch %d to RRU %d\n", ru->ru0->proc.frame_rx,ru->idx);
           AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RAU\n");
           resynch_done=1;
         }
@@ -1838,9 +1846,9 @@ static void *ru_thread( void *param ) {
 
 #ifdef MBMS_EXPERIMENTAL
 	//Workaround ... this must be properly handled
-	if(ru->if_south==LOCAL_RF && ru->function==eNodeB_3GPP && RC.eNB[0][0]!=NULL){
-		if(ru->frame_parms->num_MBSFN_config!=RC.eNB[0][0]->frame_parms.num_MBSFN_config){
-			ru->frame_parms = &RC.eNB[0][0]->frame_parms;//->frame_parms;
+	if(ru->if_south==LOCAL_RF && ru->function==eNodeB_3GPP && ru->eNB_list[0]!=NULL){
+		if(ru->frame_parms->num_MBSFN_config!=ru->eNB_list[0]->frame_parms.num_MBSFN_config){
+			ru->frame_parms = &ru->eNB_list[0]->frame_parms;//->frame_parms;
 			LOG_W(PHY,"RU MBSFN SF PARAMS Updated\n");
 		}
 	}
@@ -1855,7 +1863,7 @@ static void *ru_thread( void *param ) {
           // do OFDM if needed
           if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru, proc->frame_tx, proc->tti_tx);
 
-          if(!(get_softmodem_params()->emulate_rf)) { //if(!emulate_rf){
+          if(!(ru->emulate_rf)) { //if(!emulate_rf){
             // do outgoing fronthaul (south) if needed
             if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru, proc->frame_tx, proc->tti_tx, proc->timestamp_tx);
 
@@ -1889,12 +1897,12 @@ static void *ru_thread( void *param ) {
 
 #endif
       } // else wait_cnt == 0
-    } // ru->state = RU_RUN
+    } // ru->state = RU_RUN || RU_CHECK_SYNC
   } // while !oai_exit
 
   LOG_I(PHY, "Exiting ru_thread \n");
 
-  if (!(get_softmodem_params()->emulate_rf)) {
+  if (!(ru->emulate_rf)) {
     if (ru->stop_rf != NULL) {
       if (ru->stop_rf(ru) != 0)
         LOG_E(HW,"Could not stop the RF device\n");
@@ -1909,7 +1917,7 @@ static void *ru_thread( void *param ) {
 // This thread run the initial synchronization like a UE
 void *ru_thread_synch(void *arg) {
   RU_t *ru = (RU_t *)arg;
-  LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
+  LTE_DL_FRAME_PARMS *fp;
   int64_t peak_val, avg;
   static int ru_thread_synch_status = 0;
   int cnt=0;
@@ -1918,6 +1926,8 @@ void *ru_thread_synch(void *arg) {
   // initialize variables for PSS detection
   ru_sync_time_init(ru); //lte_sync_time_init(ru->frame_parms);
 
+  fp = ru->frame_parms;
+  int last_rxoff=0;
   while (!oai_exit) {
     // wait to be woken up
     if (wait_on_condition(&ru->proc.mutex_synch,&ru->proc.cond_synch,&ru->proc.instance_cnt_synch,"ru_thread_synch")<0) break;
@@ -1931,17 +1941,18 @@ void *ru_thread_synch(void *arg) {
                                    &avg);
       LOG_I(PHY,"RU synch cnt %d: %d, val %llu (%d dB,%d dB)\n",cnt,ru->rx_offset,(unsigned long long)peak_val,dB_fixed64(peak_val),dB_fixed64(avg));
       cnt++;
-
-      //if (/*ru->rx_offset >= 0*/dB_fixed(peak_val)>=85 && cnt>10) {
-      if (ru->rx_offset >= 0 && avg>0 && dB_fixed(peak_val/avg)>=15 && cnt>10) {
+      int abs_diff= ru->rx_offset - last_rxoff;
+      if (abs_diff<0) abs_diff=-abs_diff;
+      if (ru->rx_offset >= 0 && abs_diff<6 && avg>0 && dB_fixed(peak_val/avg)>=15 && cnt>10) {
         LOG_I(PHY,"Estimated peak_val %d dB, avg %d => timing offset %llu\n",dB_fixed(peak_val),dB_fixed(avg),(unsigned long long int)ru->rx_offset);
         ru->in_synch = 1;
-        /*
+       /* 
                 LOG_M("ru_sync_rx.m","rurx",&ru->common.rxdata[0][0],LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,1);
                 LOG_M("ru_sync_corr.m","sync_corr",ru->dmrs_corr,LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,6);
                 LOG_M("ru_dmrs.m","rudmrs",&ru->dmrssync[0],fp->ofdm_symbol_size,1,1);
-          */
-        //exit(-1);
+          
+        exit(-1);
+       */
       } // sync_pos > 0
       else { //AssertFatal(cnt<1000,"Cannot find synch reference\n");
         if (cnt>200) {
@@ -1951,6 +1962,7 @@ void *ru_thread_synch(void *arg) {
           exit(-1);
         }
       }
+      last_rxoff=ru->rx_offset;
     } // ru->in_synch==0
 
     if (release_thread(&ru->proc.mutex_synch,&ru->proc.instance_cnt_synch,"ru_synch_thread") < 0) break;
@@ -2114,7 +2126,7 @@ static void *rf_tx( void *param ) {
       // do OFDM if needed
       if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx);
 
-      if(!emulate_rf) {
+      if(!ru->emulate_rf) {
         // do outgoing fronthaul (south) if needed
         if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx);
 
@@ -2186,6 +2198,9 @@ void reset_proc(RU_t *ru) {
   for (i=0; i<10; i++) proc->symbol_mask[i]=0;
 }
 
+int start_write_thread(RU_t *ru) {
+    return(ru->rfdevice.trx_write_init(&ru->rfdevice));
+}
 
 void init_RU_proc(RU_t *ru) {
   int i=0;
@@ -2283,7 +2298,7 @@ void init_RU_proc(RU_t *ru) {
   pthread_create( &proc->pthread_rf_tx, NULL, rf_tx, (void *)ru );
 #endif
 
-  if (get_softmodem_params()->emulate_rf)
+  if (ru->emulate_rf)
     pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void *)proc );
 
   if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)
@@ -2318,10 +2333,10 @@ void init_RU_proc(RU_t *ru) {
   if (ru->function == eNodeB_3GPP) {
     usleep(10000);
     LOG_I(PHY, "Signaling main thread that RU %d (is_slave %d,send_dmrs %d) is ready in state %s\n",ru->idx,ru->is_slave,ru->generate_dmrs_sync,ru_states[ru->state]);
-    AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret);
-    RC.ru_mask &= ~(1<<ru->idx);
-    pthread_cond_signal(&RC.ru_cond);
-    AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret);
+    AssertFatal((ret=pthread_mutex_lock(ru->ru_mutex))==0,"mutex_lock returns %d\n",ret);
+    *ru->ru_mask &= ~(1<<ru->idx);
+    pthread_cond_signal(ru->ru_cond);
+    AssertFatal((ret=pthread_mutex_unlock(ru->ru_mutex))==0,"mutex_unlock returns %d\n",ret);
   }
   */
 }
@@ -2449,22 +2464,22 @@ void kill_RU_proc(RU_t *ru) {
 }
 
 
-void init_precoding_weights(PHY_VARS_eNB *eNB) {
-  int layer,ru_id,aa,re,ue,tb;
+void init_precoding_weights(RU_t **rup,int nb_RU,PHY_VARS_eNB *eNB) {
+  int layer,ru_id,aa,re,tb;
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
   RU_t *ru;
   LTE_eNB_DLSCH_t *dlsch;
 
   // init precoding weigths
-  for (ue=0; ue<NUMBER_OF_UE_MAX; ue++) {
+  for (int dlsch_id=0; dlsch_id<NUMBER_OF_DLSCH_MAX; dlsch_id++) {
     for (tb=0; tb<2; tb++) {
-      dlsch = eNB->dlsch[ue][tb];
+      dlsch = eNB->dlsch[dlsch_id][tb];
 
       for (layer=0; layer<4; layer++) {
         int nb_tx=0;
 
-        for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
-          ru = RC.ru[ru_id];
+        for (ru_id=0; ru_id<nb_RU; ru_id++) {
+          ru = rup[ru_id];
           nb_tx+=ru->nb_tx;
         }
 
@@ -2548,6 +2563,7 @@ void set_function_spec_param(RU_t *ru) {
         ru->fh_north_out         = NULL;                    // no outgoing fronthaul to north
         ru->start_if             = NULL;                    // no if interface
         ru->rfdevice.host_type   = RAU_HOST;
+        ru->start_write_thread     = start_write_thread;
       }
 
       ru->fh_south_in            = rx_rf;                               // local synchronous RF RX
@@ -2642,60 +2658,61 @@ void set_function_spec_param(RU_t *ru) {
 
 }
 
-//extern void RCconfig_RU(void);
+void init_RU0(RU_t *ru,int ru_id,char *rf_config_file, int send_dmrssync) {
 
+  ru->rf_config_file = rf_config_file;
+  ru->idx            = ru_id;
+  ru->ts_offset      = 0;
+  
+  if (ru->is_slave == 1) {
+    ru->in_synch = 0;
+    ru->generate_dmrs_sync = 0;
+  } else {
+    ru->in_synch = 1;
+    ru->generate_dmrs_sync = send_dmrssync;
+  }
+  
+  ru->cmd = EMPTY;
+  ru->south_out_cnt = 0;
+  // use eNB_list[0] as a reference for RU frame parameters
+  // NOTE: multiple CC_id are not handled here yet!
+  
+  //ru->generate_dmrs_sync = (ru->is_slave == 0) ? 1 : 0;
+  if ((ru->is_slave == 0) && (ru->ota_sync_enable == 1))
+    ru->generate_dmrs_sync = 1;
+  else
+    ru->generate_dmrs_sync = 0;
+  
+  ru->wakeup_L1_sleeptime = 2000;
+  ru->wakeup_L1_sleep_cnt_max  = 3;
+  
+
+}
 
-void init_RU(char *rf_config_file, int send_dmrssync) {
+// This part if on eNB side 
+void init_RU(RU_t **rup,int nb_RU,PHY_VARS_eNB ***eNBp,int nb_L1,int *nb_CC,char *rf_config_file, int send_dmrssync) {
   int ru_id, i, CC_id;
   RU_t *ru;
   PHY_VARS_eNB *eNB0     = (PHY_VARS_eNB *)NULL;
   LTE_DL_FRAME_PARMS *fp = (LTE_DL_FRAME_PARMS *)NULL;
   // create status mask
-  RC.ru_mask= (1 << RC.nb_RU) - 1;
-  pthread_mutex_init(&RC.ru_mutex,NULL);
-  pthread_cond_init(&RC.ru_cond,NULL);
-
-  if (RC.nb_CC != 0)
-    for (i=0; i<RC.nb_L1_inst; i++)
-      for (CC_id=0; CC_id<RC.nb_CC[i]; CC_id++) RC.eNB[i][CC_id]->num_RU=0;
-
-  LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU);
-
-  for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
-    LOG_D(PHY,"Process RC.ru[%d]\n",ru_id);
-    ru                 = RC.ru[ru_id];
-    ru->rf_config_file = rf_config_file;
-    ru->idx            = ru_id;
-    ru->ts_offset      = 0;
-
-    if (ru->is_slave == 1) {
-      ru->in_synch = 0;
-      ru->generate_dmrs_sync = 0;
-    } else {
-      ru->in_synch = 1;
-      ru->generate_dmrs_sync = send_dmrssync;
-    }
-
-    ru->cmd = EMPTY;
-    ru->south_out_cnt = 0;
-    // use eNB_list[0] as a reference for RU frame parameters
-    // NOTE: multiple CC_id are not handled here yet!
-
-    //ru->generate_dmrs_sync = (ru->is_slave == 0) ? 1 : 0;
-    if ((ru->is_slave == 0) && (ru->ota_sync_enable == 1))
-      ru->generate_dmrs_sync = 1;
-    else
-      ru->generate_dmrs_sync = 0;
+  if (nb_CC != NULL)
+    for (i=0; i<nb_L1; i++)
+      for (CC_id=0; CC_id<nb_CC[i]; CC_id++) eNBp[i][CC_id]->num_RU=0;
 
-    ru->wakeup_L1_sleeptime = 2000;
-    ru->wakeup_L1_sleep_cnt_max  = 3;
+  LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",nb_RU);
 
+  for (ru_id=0; ru_id<nb_RU; ru_id++) {
+    LOG_D(PHY,"Process ru[%d]\n",ru_id);
+    ru                 = rup[ru_id];
+    init_RU0(ru,ru_id,rf_config_file,send_dmrssync);
+    ru->ru0 = rup[0];
     if (ru->num_eNB > 0) {
-      LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file);
-
+      LOG_D(PHY, "%s() ru[%d].num_eNB:%d ru->eNB_list[0]:%p eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], eNBp[0][0], ru->rf_config_file);
+      
       if (ru->eNB_list[0] == 0) {
-        LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__);
-        ru->eNB_list[0] = RC.eNB[0][0];
+	LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__);
+	ru->eNB_list[0] = eNBp[0][0];
         ru->num_eNB=1;
         //
         // DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU
@@ -2704,7 +2721,7 @@ void init_RU(char *rf_config_file, int send_dmrssync) {
         LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__);
       }
     }
-
+    
     eNB0 = ru->eNB_list[0];
     fp   = ru->frame_parms;
     LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south);
@@ -2778,10 +2795,10 @@ void stop_ru(RU_t *ru) {
 }
 
 
-void stop_RU(int nb_ru) {
+void stop_RU(RU_t **rup,int nb_ru) {
   for (int inst = 0; inst < nb_ru; inst++) {
     LOG_I(PHY, "Stopping RU %d processing threads\n", inst);
-    kill_RU_proc(RC.ru[inst]);
+    kill_RU_proc(rup[inst]);
   }
 }
 
@@ -2802,7 +2819,7 @@ void init_ru_vnf(void) {
   pthread_cond_init(&RC.ru_cond,NULL);
   // read in configuration file)
   LOG_I(PHY,"configuring RU from file\n");
-  RCconfig_RU();
+  RC.ru = RCconfig_RU(RC.nb_RU,RC.nb_L1_inst,RC.eNB,&RC.ru_mask,&RC.ru_mutex,&RC.ru_cond);
   LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_L1_inst,RC.nb_RU,get_nprocs());
 
   if (RC.nb_CC != 0)
@@ -2878,183 +2895,185 @@ void init_ru_vnf(void) {
 
 /* --------------------------------------------------------*/
 /* from here function to use configuration module          */
-void RCconfig_RU(void) {
+RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond) {
   int i = 0;
   paramdef_t RUParams[] = RUPARAMS_DESC;
   paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0};
   config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL);
-
+  RU_t **ru=NULL;
   if ( RUParamList.numelt > 0) {
-    RC.ru = (RU_t **)malloc(RC.nb_RU*sizeof(RU_t *));
-
-    for (int j = 0; j < RC.nb_RU; j++) {
-      RC.ru[j]                                    = (RU_t *)malloc(sizeof(RU_t));
-      memset((void *)RC.ru[j],0,sizeof(RU_t));
-      RC.ru[j]->idx                                 = j;
-      LOG_I(PHY,"Creating RC.ru[%d]:%p\n", j, RC.ru[j]);
-      RC.ru[j]->if_timing                           = synch_to_ext_device;
-
-      if (RC.nb_L1_inst >0)
-        RC.ru[j]->num_eNB                           = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt;
+    ru = (RU_t **)malloc(nb_RU*sizeof(RU_t *));
+
+    for (int j = 0; j < nb_RU; j++) {
+      ru[j]                                    = (RU_t *)malloc(sizeof(RU_t));
+      memset((void *)ru[j],0,sizeof(RU_t));
+      ru[j]->idx                                 = j;
+      LOG_I(PHY,"Creating ru[%d]:%p\n", j, ru[j]);
+      ru[j]->if_timing                           = synch_to_ext_device;
+
+      ru[j]->ru_mask = ru_mask;
+      ru[j]->ru_mutex = ru_mutex;
+      ru[j]->ru_cond = ru_cond;
+      if (nb_L1_inst >0)
+        ru[j]->num_eNB                           = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt;
       else
-        RC.ru[j]->num_eNB                           = 0;
+        ru[j]->num_eNB                           = 0;
 
-      for (i=0; i<RC.ru[j]->num_eNB; i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0];
+      for (i=0; i<ru[j]->num_eNB; i++) ru[j]->eNB_list[i] = eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0];
 
-      RC.ru[j]->has_ctrl_prt                        = 0;
+      ru[j]->has_ctrl_prt                        = 0;
 
       if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) {
-        RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr));
+        ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr));
       }
 
       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;
+          ru[j]->openair0_cfg.clock_source = internal;
           LOG_D(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;
+          ru[j]->openair0_cfg.clock_source = external;
           LOG_D(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;
+          ru[j]->openair0_cfg.clock_source = gpsdo;
           LOG_D(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;
+	ru[j]->openair0_cfg.clock_source = unset;
       }
 
       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;
+          ru[j]->openair0_cfg.time_source = internal;
           LOG_D(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;
+          ru[j]->openair0_cfg.time_source = external;
           LOG_D(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;
+          ru[j]->openair0_cfg.time_source = gpsdo;
           LOG_D(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;
+	ru[j]->openair0_cfg.time_source = unset;
       }      
 
+      LOG_I(PHY,"RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr));
+
+      if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) ru[j]->is_slave=1;
+      else ru[j]->is_slave=0;
+
+      LOG_I(PHY,"RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr));
+
+      if (strcmp(*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr), "yes") == 0) ru[j]->ota_sync_enable=1;
+      else ru[j]->ota_sync_enable=0;
+
       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;
-          RC.ru[j]->function                        = eNodeB_3GPP;
-          RC.ru[j]->state                           = RU_RUN;
-          LOG_I(PHY,"Setting function for RU %d to eNodeB_3GPP\n",j);
+          ru[j]->if_south                        = LOCAL_RF;
+          ru[j]->function                        = eNodeB_3GPP;
+          ru[j]->state                           = RU_RUN;
+          printf("Setting function for RU %d to eNodeB_3GPP\n",j);
         } else {
-          RC.ru[j]->eth_params.local_if_name            = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
-          RC.ru[j]->eth_params.my_addr                  = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
-          RC.ru[j]->eth_params.remote_addr              = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
-          RC.ru[j]->eth_params.my_portd                 = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
-          RC.ru[j]->eth_params.remote_portd             = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
+          ru[j]->eth_params.local_if_name            = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
+          ru[j]->eth_params.my_addr                  = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
+          ru[j]->eth_params.remote_addr              = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
+          ru[j]->eth_params.my_portd                 = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
+          ru[j]->eth_params.remote_portd             = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
 
           // Check if control port set
           if  (!(config_isparamset(RUParamList.paramarray[j],RU_REMOTE_PORTC_IDX)) ) {
             LOG_I(PHY,"Removing control port for RU %d\n",j);
-            RC.ru[j]->has_ctrl_prt            = 0;
+            ru[j]->has_ctrl_prt            = 0;
           } else {
-            RC.ru[j]->eth_params.my_portc                 = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
-            RC.ru[j]->eth_params.remote_portc             = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
-            LOG_I(PHY," Control port %u \n",RC.ru[j]->eth_params.my_portc);
+            ru[j]->eth_params.my_portc                 = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
+            ru[j]->eth_params.remote_portc             = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
+            LOG_I(PHY," Control port %u \n",ru[j]->eth_params.my_portc);
           }
 
           if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
-            RC.ru[j]->if_south                        = LOCAL_RF;
-            RC.ru[j]->function                        = NGFI_RRU_IF5;
-            RC.ru[j]->eth_params.transp_preference    = ETH_UDP_MODE;
+            ru[j]->if_south                        = LOCAL_RF;
+            ru[j]->function                        = NGFI_RRU_IF5;
+            ru[j]->eth_params.transp_preference    = ETH_UDP_MODE;
             LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j);
           } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
-            RC.ru[j]->if_south                        = LOCAL_RF;
-            RC.ru[j]->function                        = NGFI_RRU_IF5;
-            RC.ru[j]->eth_params.transp_preference    = ETH_RAW_MODE;
+            ru[j]->if_south                        = LOCAL_RF;
+            ru[j]->function                        = NGFI_RRU_IF5;
+            ru[j]->eth_params.transp_preference    = ETH_RAW_MODE;
             LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j);
           } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
-            RC.ru[j]->if_south                        = LOCAL_RF;
-            RC.ru[j]->function                        = NGFI_RRU_IF4p5;
-            RC.ru[j]->eth_params.transp_preference    = ETH_UDP_IF4p5_MODE;
-            RC.ru[j]->has_ctrl_prt                   =1;
+            ru[j]->if_south                        = LOCAL_RF;
+            ru[j]->function                        = NGFI_RRU_IF4p5;
+            ru[j]->eth_params.transp_preference    = ETH_UDP_IF4p5_MODE;
+            ru[j]->has_ctrl_prt                   =1;
             LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j);
           } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
-            RC.ru[j]->if_south                        = LOCAL_RF;
-            RC.ru[j]->function                        = NGFI_RRU_IF4p5;
-            RC.ru[j]->eth_params.transp_preference    = ETH_RAW_IF4p5_MODE;
-            RC.ru[j]->has_ctrl_prt                   =1;
+            ru[j]->if_south                        = LOCAL_RF;
+            ru[j]->function                        = NGFI_RRU_IF4p5;
+            ru[j]->eth_params.transp_preference    = ETH_RAW_IF4p5_MODE;
+            ru[j]->has_ctrl_prt                   =1;
             LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j);
           }
-
-          LOG_I(PHY,"RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr));
-
-          if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1;
-          else RC.ru[j]->is_slave=0;
-
-          LOG_I(PHY,"RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr));
-
-          if (strcmp(*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr), "yes") == 0) RC.ru[j]->ota_sync_enable=1;
-          else RC.ru[j]->ota_sync_enable=0;
         }
 
-        RC.ru[j]->max_pdschReferenceSignalPower     = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);;
-        RC.ru[j]->max_rxgain                        = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr);
-        RC.ru[j]->num_bands                         = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt;
+        ru[j]->max_pdschReferenceSignalPower     = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);;
+        ru[j]->max_rxgain                        = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr);
+        ru[j]->num_bands                         = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt;
         /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */
-        RC.ru[j]->sf_extension                      = *(RUParamList.paramarray[j][RU_SF_EXTENSION_IDX].uptr);
+        ru[j]->sf_extension                      = *(RUParamList.paramarray[j][RU_SF_EXTENSION_IDX].uptr);
 
-        for (i=0; i<RC.ru[j]->num_bands; i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
+        for (i=0; i<ru[j]->num_bands; i++) ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
       } //strcmp(local_rf, "yes") == 0
-else {
+      else {
         LOG_I(PHY,"RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr));
-        RC.ru[j]->eth_params.local_if_name      = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
-        RC.ru[j]->eth_params.my_addr            = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
-        RC.ru[j]->eth_params.remote_addr        = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
-        RC.ru[j]->eth_params.my_portc           = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
-        RC.ru[j]->eth_params.remote_portc       = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
-        RC.ru[j]->eth_params.my_portd           = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
-        RC.ru[j]->eth_params.remote_portd       = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
+        ru[j]->eth_params.local_if_name      = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
+        ru[j]->eth_params.my_addr            = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
+        ru[j]->eth_params.remote_addr        = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
+        ru[j]->eth_params.my_portc           = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
+        ru[j]->eth_params.remote_portc       = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
+        ru[j]->eth_params.my_portd           = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
+        ru[j]->eth_params.remote_portd       = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
       
         if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
-	  RC.ru[j]->if_south                     = REMOTE_IF5;
-	  RC.ru[j]->function                     = NGFI_RAU_IF5;
-	  RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
+	  ru[j]->if_south                     = REMOTE_IF5;
+	  ru[j]->function                     = NGFI_RAU_IF5;
+	  ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
         } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_ecpri_if5") == 0) {
-	  RC.ru[j]->if_south                     = REMOTE_IF5;
-	  RC.ru[j]->function                     = NGFI_RAU_IF5;
-	  RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF5_ECPRI_MODE;
+	  ru[j]->if_south                     = REMOTE_IF5;
+	  ru[j]->function                     = NGFI_RAU_IF5;
+	  ru[j]->eth_params.transp_preference = ETH_UDP_IF5_ECPRI_MODE;
         } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
-	  RC.ru[j]->if_south                     = REMOTE_IF5;
-	  RC.ru[j]->function                     = NGFI_RAU_IF5;
-	  RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
+	  ru[j]->if_south                     = REMOTE_IF5;
+	  ru[j]->function                     = NGFI_RAU_IF5;
+	  ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
         } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
-	  RC.ru[j]->if_south                     = REMOTE_IF4p5;
-	  RC.ru[j]->function                     = NGFI_RAU_IF4p5;
-  	  RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
-	  RC.ru[j]->has_ctrl_prt                 = 1;
+	  ru[j]->if_south                     = REMOTE_IF4p5;
+	  ru[j]->function                     = NGFI_RAU_IF4p5;
+  	  ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
+	  ru[j]->has_ctrl_prt                 = 1;
         } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
-	  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;
-	  RC.ru[j]->has_ctrl_prt                 = 1;
+	  ru[j]->if_south                     = REMOTE_IF4p5;
+	  ru[j]->function                     = NGFI_RAU_IF4p5;
+	  ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
+	  ru[j]->has_ctrl_prt                 = 1;
 	
-          if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1;
-          else RC.ru[j]->is_slave=0;
+          if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) ru[j]->is_slave=1;
+          else ru[j]->is_slave=0;
         }
       }  /* strcmp(local_rf, "yes") != 0 */
       
-      RC.ru[j]->nb_tx                             = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr);
-      RC.ru[j]->nb_rx                             = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr);
-      RC.ru[j]->att_tx                            = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr);
-      RC.ru[j]->att_rx                            = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr);
+      ru[j]->nb_tx                             = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr);
+      ru[j]->nb_rx                             = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr);
+      ru[j]->att_tx                            = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr);
+      ru[j]->att_rx                            = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr);
+      *ru_mask= (*ru_mask)|(1<<j);
     }// j=0..num_rus
-  } else {
-    RC.nb_RU = 0;
-  } // setting != NULL
-
-  return;
+  } 
+    
+  return ru;
 }
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 2e6f148e00710905e7f3afa4e6a0af6a07b5ebc0..f9ff03e422d82e349342c094e9a8e33d4df3945f 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -35,6 +35,7 @@
 #include <sched.h>
 
 #include "rt_wrapper.h"
+#include <common/utils/msc/msc.h>
 
 
 #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
@@ -56,6 +57,8 @@
 
 //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
 
+#include <openair1/PHY/phy_extern_ue.h>
+
 #include "PHY/phy_vars.h"
 #include "SCHED/sched_common_vars.h"
 #include "LAYER2/MAC/mac_vars.h"
@@ -100,7 +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
 
-
 uint16_t sf_ahead=4;
 
 pthread_cond_t sync_cond;
@@ -161,16 +163,17 @@ void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *
   AssertFatal(false, "Must not be called in this context\n");
 }
 
+RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond);
+
 extern void reset_opp_meas(void);
 extern void print_opp_meas(void);
 
 
-extern void init_eNB_afterRU(void);
+RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond);
 
 int transmission_mode=1;
 int emulate_rf = 0;
 int numerology = 0;
-int usrp_tx_thread = 0;
 
 THREAD_STRUCT thread_struct;
 /* struct for ethernet specific parameters given in eNB conf file */
@@ -179,6 +182,7 @@ eth_params_t *eth_params;
 double cpuf;
 
 int oaisim_flag=0;
+uint8_t proto_agent_flag = 0;
 
 
 /* forward declarations */
@@ -424,7 +428,6 @@ int stop_L1L2(module_id_t enb_id) {
  * Restart the lte-softmodem after it has been soft-stopped with stop_L1L2()
  */
 int restart_L1L2(module_id_t enb_id) {
-  RU_t *ru = RC.ru[enb_id];
   int cc_id;
   MessageDef *msg_p = NULL;
   LOG_W(ENB_APP, "restarting lte-softmodem\n");
@@ -435,10 +438,12 @@ int restart_L1L2(module_id_t enb_id) {
 
   for (cc_id = 0; cc_id < RC.nb_L1_CC[enb_id]; cc_id++) {
     RC.eNB[enb_id][cc_id]->configured = 0;
+    for (int ru_id=0;ru_id<RC.eNB[enb_id][cc_id]->num_RU;ru_id++) {
+      int ru_idx = RC.eNB[enb_id][cc_id]->RU_list[ru_id]->idx;
+      RC.ru_mask |= (1 << ru_idx);
+      set_function_spec_param(RC.ru[ru_idx]);
+    }
   }
-
-  RC.ru_mask |= (1 << ru->idx);
-  set_function_spec_param(RC.ru[enb_id]);
   /* reset the list of connected UEs in the MAC, since in this process with
    * loose all UEs (have to reconnect) */
   init_UE_info(&RC.mac[enb_id]->UE_info);
@@ -459,9 +464,15 @@ int restart_L1L2(module_id_t enb_id) {
   /* TODO XForms might need to be restarted, but it is currently (09/02/18)
    * broken, so we cannot test it */
   wait_eNBs();
-  init_RU_proc(ru);
-  ru->rf_map.card = 0;
-  ru->rf_map.chain = 0; /* CC_id + chain_offset;*/
+  for (int cc_id=0;cc_id<RC.nb_L1_CC[enb_id]; cc_id++) {
+    for (int ru_id=0;ru_id<RC.eNB[enb_id][cc_id]->num_RU;ru_id++) {
+      int ru_idx = RC.eNB[enb_id][cc_id]->RU_list[ru_id]->idx;
+
+      init_RU_proc(RC.ru[ru_idx]);
+      RC.ru[ru_idx]->rf_map.card = 0;
+      RC.ru[ru_idx]->rf_map.chain = 0; /* CC_id + chain_offset;*/
+    }
+  }
   wait_RUs();
   init_eNB_afterRU();
   printf("Sending sync to all threads\n");
@@ -574,7 +585,7 @@ int main ( int argc, char **argv )
   /* We need to read RU configuration before FlexRAN starts so it knows what
    * splits to report. Actual RU start comes later. */
   if (RC.nb_RU > 0 && NFAPI_MODE != NFAPI_MODE_VNF) {
-    RCconfig_RU();
+    RC.ru = RCconfig_RU(RC.nb_RU,RC.nb_L1_inst,RC.eNB,&RC.ru_mask,&RC.ru_mutex,&RC.ru_cond);
     LOG_I(PHY,
           "number of L1 instances %d, number of RU %d, number of CPU cores %d\n",
           RC.nb_L1_inst, RC.nb_RU, get_nprocs());
@@ -651,6 +662,7 @@ int main ( int argc, char **argv )
     for (int x=0; x < RC.nb_L1_inst; x++) 
       for (int CC_id=0; CC_id<RC.nb_L1_CC[x]; CC_id++) {
         L1_rxtx_proc_t *L1proc= &RC.eNB[x][CC_id]->proc.L1_proc;
+        L1_rxtx_proc_t *L1proctx= &RC.eNB[x][CC_id]->proc.L1_proc_tx;
 	L1proc->threadPool=(tpool_t*)malloc(sizeof(tpool_t));
         L1proc->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
         L1proc->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
@@ -658,9 +670,11 @@ int main ( int argc, char **argv )
          initTpool(get_softmodem_params()->threadPoolConfig, L1proc->threadPool, true);
         else
          initTpool("n", L1proc->threadPool, true);
-      initNotifiedFIFO(L1proc->respEncode);
-      initNotifiedFIFO(L1proc->respDecode);
-      RC.eNB[x][CC_id]->proc.L1_proc_tx.threadPool = L1proc->threadPool;
+        initNotifiedFIFO(L1proc->respEncode);
+        initNotifiedFIFO(L1proc->respDecode);
+        L1proctx->threadPool=L1proc->threadPool;
+        L1proctx->respEncode=L1proc->respEncode;
+        L1proctx->nbEncode=L1proc->nbEncode;
     }
 
 
@@ -675,7 +689,7 @@ int main ( int argc, char **argv )
   // some initialization is necessary and init_ru_vnf do this.
   if (RC.nb_RU >0 && NFAPI_MODE!=NFAPI_MODE_VNF) {
     printf("Initializing RU threads\n");
-    init_RU(get_softmodem_params()->rf_config_file,get_softmodem_params()->send_dmrs_sync);
+    init_RU(RC.ru,RC.nb_RU,RC.eNB,RC.nb_L1_inst,RC.nb_L1_CC,get_softmodem_params()->rf_config_file,get_softmodem_params()->send_dmrs_sync);
     
     for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
       RC.ru[ru_id]->rf_map.card=0;
@@ -727,7 +741,7 @@ int main ( int argc, char **argv )
   fflush(stderr);
   // end of CI modifications
   //getchar();
-  if(IS_SOFTMODEM_DOFORMS)
+  if(IS_SOFTMODEM_DOSCOPE)
      load_softscope("enb",NULL);
   itti_wait_tasks_end();
   oai_exit=1;
@@ -735,7 +749,7 @@ int main ( int argc, char **argv )
   // stop threads
 
   if (RC.nb_inst == 0 || !NODE_IS_CU(node_type)) {
-    if(IS_SOFTMODEM_DOFORMS)
+    if(IS_SOFTMODEM_DOSCOPE)
       end_forms();
 
     LOG_I(ENB_APP,"stopping MODEM threads\n");
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index 1c537dabe39d5cdb4f79f5469f2bd550321563f3..a1b261f26361722dbbd96fc44fd93102d1a2b3ab 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -97,7 +97,6 @@
 /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
 
 #define CMDLINE_UEPARAMS_DESC {  \
-    {"siml1",             CONFIG_HLP_SIML1,       PARAMFLAG_BOOL,  iptr:&simL1flag,                    defintval:0,          TYPE_INT,      0},   \
     {"U",                 CONFIG_HLP_NUMUE,       0,               u16ptr:&NB_UE_INST,                 defuintval:1,         TYPE_UINT16,   0},   \
     {"ue-rxgain",         CONFIG_HLP_UERXG,       0,               dblptr:&(rx_gain[0][0]),            defdblval:130,        TYPE_DOUBLE,   0},   \
     {"ue-rxgain-off",     CONFIG_HLP_UERXGOFF,    0,               dblptr:&rx_gain_off,                defdblval:0,          TYPE_DOUBLE,   0},   \
@@ -171,7 +170,7 @@ extern void init_RU_proc(RU_t *ru);
 extern void stop_RU(int nb_ru);
 extern void kill_RU_proc(RU_t *ru);
 extern void set_function_spec_param(RU_t *ru);
-extern void init_RU(char *, int send_dmrssync);
+extern void init_RU(RU_t **rup,int nb_RU,PHY_VARS_eNB ***eNBp,int nb_L1,int *nb_CC,char *rf_config_file, int send_dmrssync);
 
 // In lte-ue.c
 extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
@@ -199,7 +198,6 @@ extern void init_te_thread(PHY_VARS_eNB *);
 extern void kill_td_thread(PHY_VARS_eNB *);
 extern void kill_te_thread(PHY_VARS_eNB *);
 
-extern void RCConfig_sim(void);
 extern void init_ocm(void);
 extern void init_ue_devices(PHY_VARS_UE *);
 
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 407756e20f44736a94f9f8e96fe4c63a67ee882c..6e6c2533b4dd5b56b1b8e6f99e22423ffec3a9b0 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -32,6 +32,7 @@
 #include "lte-softmodem.h"
 
 #include "rt_wrapper.h"
+#include "system.h"
 
 #include "LAYER2/MAC/mac.h"
 #include "RRC/LTE/rrc_extern.h"
@@ -95,6 +96,7 @@ extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind);
 extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP);
 
 
+int	tx_req_num_elems;
 extern uint16_t sf_ahead;
 //extern int tx_req_UE_MAC1();
 
@@ -181,9 +183,8 @@ PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
                           uint8_t abstraction_flag)
 
 {
-  PHY_VARS_UE *ue = (PHY_VARS_UE *)malloc(sizeof(PHY_VARS_UE));
-  memset(ue,0,sizeof(PHY_VARS_UE));
-
+  PHY_VARS_UE *ue = (PHY_VARS_UE *)calloc(1,sizeof(PHY_VARS_UE));
+  AssertFatal(ue,"");
   if (frame_parms!=(LTE_DL_FRAME_PARMS *)NULL) { // if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in
     memcpy(&(ue->frame_parms), frame_parms, sizeof(LTE_DL_FRAME_PARMS));
   }
@@ -230,14 +231,23 @@ void init_thread(int sched_runtime,
   }
 
 #else
+  int settingPriority = 1;
+
+  if (checkIfFedoraDistribution())
+    if (checkIfGenericKernelOnFedora())
+      if (checkIfInsideContainer())
+        settingPriority = 0;
 
-  if (CPU_COUNT(cpuset) > 0)
-    AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), "");
+  if (settingPriority) {
+    if (CPU_COUNT(cpuset) > 0)
+      AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), "");
+
+    struct sched_param sp;
+    sp.sched_priority = sched_fifo;
+    AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0,
+                "Can't set thread priority, Are you root?\n");
+  }
 
-  struct sched_param sp;
-  sp.sched_priority = sched_fifo;
-  AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0,
-              "Can't set thread priority, Are you root?\n");
   /* Check the actual affinity mask assigned to the thread */
   cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE);
 
@@ -283,13 +293,7 @@ void init_UE(int nb_inst,
 
     LOG_I(PHY,"Allocating UE context %d\n",inst);
 
-    if ( !IS_SOFTMODEM_SIML1 ) PHY_vars_UE_g[inst][0] = init_ue_vars(fp0,inst,0);
-    else {
-      // needed for memcopy below. these are not used in the RU, but needed for UE
-      RC.ru[0]->frame_parms->nb_antennas_rx = fp0->nb_antennas_rx;
-      RC.ru[0]->frame_parms->nb_antennas_tx = fp0->nb_antennas_tx;
-      PHY_vars_UE_g[inst][0]  = init_ue_vars(RC.ru[0]->frame_parms,inst,0);
-    }
+    PHY_vars_UE_g[inst][0] = init_ue_vars(fp0,inst,0);
 
     // turn off timing control loop in UE
     PHY_vars_UE_g[inst][0]->no_timing_correction = timing_correction;
@@ -371,17 +375,13 @@ void init_UE(int nb_inst,
        */
       UE->N_TA_offset = 0;
 
-    if (IS_SOFTMODEM_SIML1 ) init_ue_devices(UE);
-
     LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
     init_UE_threads(inst);
 
-    if (!IS_SOFTMODEM_SIML1 ) {
-      ret = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]);
+    ret = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]);
 
-      if (ret !=0) {
-        exit_fun("Error loading device library");
-      }
+    if (ret !=0) {
+      exit_fun("Error loading device library");
     }
 
     UE->rfdevice.host_type = RAU_HOST;
diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c
index 9bf179efb928293a82235771b9faeca929d98b53..026e6d4a6061afc262b2a9f31d9c45c0ce371902 100644
--- a/targets/RT/USER/lte-uesoftmodem.c
+++ b/targets/RT/USER/lte-uesoftmodem.c
@@ -168,7 +168,6 @@ extern void get_uethreads_params(void);
 
 int transmission_mode=1;
 
-int usrp_tx_thread = 0;
 
 
 char *usrp_args=NULL;
@@ -193,6 +192,9 @@ int oaisim_flag=0;
  */
 uint8_t abstraction_flag=0;
 
+// needed for pdcp.c
+RAN_CONTEXT_t RC;
+
 /* forward declarations */
 void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
 
@@ -286,7 +288,6 @@ static void get_options(void) {
   int dumpframe=0;
   int timingadv=0;
   uint8_t nfapi_mode = NFAPI_MONOLITHIC;
-  int simL1flag =0;
 
   set_default_frame_parms(frame_parms);
   CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
@@ -300,8 +301,6 @@ static void get_options(void) {
   config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL);
   nfapi_setmode(nfapi_mode);
 
-  if (simL1flag)
-    set_softmodem_optmask(SOFTMODEM_SIML1_BIT);
 
   if (loopfile != NULL) {
     printf("Input file for hardware emulation: %s",loopfile);
@@ -574,11 +573,6 @@ int main( int argc, char **argv ) {
   EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1;
   printf("Running with %d UE instances\n",NB_UE_INST);
 
-  if (NB_UE_INST > 1 && (!IS_SOFTMODEM_SIML1)  && NFAPI_MODE!=NFAPI_UE_STUB_PNF) {
-    printf("Running with more than 1 UE instance and simL1 is not active, this will result in undefined behaviour for now, exiting.\n");
-    abort();
-  }
-
   // Checking option of nums_ue_thread.
   if(NB_THREAD_INST < 1) {
     printf("Running with 0 UE rxtx thread, exiting.\n");
@@ -649,9 +643,6 @@ int main( int argc, char **argv ) {
     }
   } else init_openair0(frame_parms[0],(int)rx_gain[0][0]);
 
-  if (IS_SOFTMODEM_SIML1 ) {
-    RCConfig_sim();
-  }
 
   cpuf=get_cpu_freq_GHz();
   
@@ -753,12 +744,8 @@ int main( int argc, char **argv ) {
 
   //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
 
-  if (IS_SOFTMODEM_SIML1 )  {
-    init_ocm();
-    PHY_vars_UE_g[0][0]->no_timing_correction = 1;
-  }
 
-  if(IS_SOFTMODEM_DOFORMS)
+  if(IS_SOFTMODEM_DOSCOPE)
     load_softscope("ue",NULL);
 
   config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
@@ -783,7 +770,7 @@ int main( int argc, char **argv ) {
   printf("oai_exit=%d\n",oai_exit);
 
   // stop threads
-  if(IS_SOFTMODEM_DOFORMS)
+  if(IS_SOFTMODEM_DOSCOPE)
     end_forms();
 
   printf("stopping MODEM threads\n");
diff --git a/targets/RT/USER/rfsim.c b/targets/RT/USER/rfsim.c
index eb380b95186ae78ed8ec7143bb91615e7d964c31..2bd95507c325a59f757b69e6db9532dd4317c627 100644
--- a/targets/RT/USER/rfsim.c
+++ b/targets/RT/USER/rfsim.c
@@ -361,6 +361,7 @@ void init_ocm(void) {
                                DS_TDL,
                                0.0,
                                0,
+                               0,
                                0);
         random_channel(sim.RU2UE[ru_id][UE_id][CC_id],0);
         LOG_D(OCM,"[SIM] Initializing channel (%s) from UE %d to ru %d\n", "AWGN", UE_id, ru_id);
@@ -374,6 +375,7 @@ void init_ocm(void) {
                                DS_TDL,
                                0.0,
                                0,
+                               0,
                                0);
         random_channel(sim.UE2RU[UE_id][ru_id][CC_id],0);
         // to make channel reciprocal uncomment following line instead of previous. However this only works for SISO at the moment. For MIMO the channel would need to be transposed.
diff --git a/targets/RT/USER/rt_wrapper.c b/targets/RT/USER/rt_wrapper.c
index 5bdbbb36e3f8b5d07b0cd3e8556bb6ce16acc2a6..da3a2d3cfe2ea9456b409ee992db3fda92ee2c8f 100644
--- a/targets/RT/USER/rt_wrapper.c
+++ b/targets/RT/USER/rt_wrapper.c
@@ -43,7 +43,9 @@
 #include <getopt.h>
 #include <sys/sysinfo.h>
 #include "rt_wrapper.h"
+#include "system.h"
 #include <errno.h>
+#include <common/utils/msc/msc.h>
 
 #include "openair1/PHY/defs_common.h"
 
@@ -293,6 +295,7 @@ void thread_top_init(char *thread_name,
   struct sched_param sparam;
   char cpu_affinity[1024];
   cpu_set_t cpuset;
+  int settingPriority = 1;
 
   /* Set affinity mask to include CPUs 2 to MAX_CPUS */
   /* CPU 0 is reserved for UHD threads */
@@ -339,30 +342,37 @@ void thread_top_init(char *thread_name,
     }
   }
 
-  memset(&sparam, 0, sizeof(sparam));
-  sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
-  policy = SCHED_FIFO ; 
+  if (checkIfFedoraDistribution())
+    if (checkIfGenericKernelOnFedora())
+      if (checkIfInsideContainer())
+        settingPriority = 0;
+
+  if (settingPriority) {
+    memset(&sparam, 0, sizeof(sparam));
+    sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
+    policy = SCHED_FIFO;
   
-  s = pthread_setschedparam(pthread_self(), policy, &sparam);
-  if (s != 0) {
-    perror("pthread_setschedparam : ");
-    exit_fun("Error setting thread priority");
-  }
+    s = pthread_setschedparam(pthread_self(), policy, &sparam);
+    if (s != 0) {
+      perror("pthread_setschedparam : ");
+      exit_fun("Error setting thread priority");
+    }
   
-  s = pthread_getschedparam(pthread_self(), &policy, &sparam);
-  if (s != 0) {
-    perror("pthread_getschedparam : ");
-    exit_fun("Error getting thread priority");
-  }
+    s = pthread_getschedparam(pthread_self(), &policy, &sparam);
+    if (s != 0) {
+      perror("pthread_getschedparam : ");
+      exit_fun("Error getting thread priority");
+    }
 
-  pthread_setname_np(pthread_self(), thread_name);
+    pthread_setname_np(pthread_self(), thread_name);
 
-  LOG_I(HW, "[SCHED][eNB] %s started on CPU %d, sched_policy = %s , priority = %d, CPU Affinity=%s \n",thread_name,sched_getcpu(),
-                   (policy == SCHED_FIFO)  ? "SCHED_FIFO" :
-                   (policy == SCHED_RR)    ? "SCHED_RR" :
-                   (policy == SCHED_OTHER) ? "SCHED_OTHER" :
-                   "???",
-                   sparam.sched_priority, cpu_affinity );
+    LOG_I(HW, "[SCHED][eNB] %s started on CPU %d, sched_policy = %s , priority = %d, CPU Affinity=%s \n",thread_name,sched_getcpu(),
+                     (policy == SCHED_FIFO)  ? "SCHED_FIFO" :
+                     (policy == SCHED_RR)    ? "SCHED_RR" :
+                     (policy == SCHED_OTHER) ? "SCHED_OTHER" :
+                     "???",
+                     sparam.sched_priority, cpu_affinity );
+  }
 
 #endif //LOW_LATENCY
 
diff --git a/targets/RT/USER/ru_control.c b/targets/RT/USER/ru_control.c
index 7ac6a8913ef3be0d7eea86a16993aa0126a55617..95b5ce6155bec826e009b221ad2881359349e496 100644
--- a/targets/RT/USER/ru_control.c
+++ b/targets/RT/USER/ru_control.c
@@ -61,30 +61,17 @@
 #include "PHY/LTE_TRANSPORT/if4_tools.h"
 #include "PHY/LTE_TRANSPORT/if5_tools.h"
 
-#include "PHY/phy_extern.h"
-#include "LAYER2/MAC/mac_extern.h"
 #include "PHY/LTE_TRANSPORT/transport_proto.h"
 #include "SCHED/sched_eNB.h"
 #include "PHY/LTE_ESTIMATION/lte_estimation.h"
 #include "PHY/INIT/phy_init.h"
 
-#include "LAYER2/MAC/mac.h"
-#include "LAYER2/MAC/mac_extern.h"
-#include "LAYER2/MAC/mac_proto.h"
-#include "RRC/LTE/rrc_extern.h"
-#include "PHY_INTERFACE/phy_interface.h"
-
 #include "common/utils/LOG/log.h"
-#include "UTIL/OTG/otg_tx.h"
-#include "UTIL/OTG/otg_externs.h"
-#include "UTIL/MATH/oml.h"
-#include "UTIL/OPT/opt.h"
-#include "enb_config.h"
 
 
 int attach_rru(RU_t *ru);
-void configure_ru(int idx, void *arg);
-void configure_rru(int idx, void *arg);
+void configure_ru(RU_t *ru, void *arg);
+void configure_rru(RU_t *ru, void *arg);
 void fill_rf_config(RU_t *ru, char *rf_config_file);
 void* ru_thread_control( void* param );
 
@@ -164,7 +151,7 @@ int send_capab(RU_t *ru)
     cap->FH_fmt                                   = MBP_IF5;
     break;
   default:
-    AssertFatal(1==0,"RU_function is unknown %d\n",RC.ru[0]->function);
+    AssertFatal(1==0,"RU_function is unknown %d\n",ru->function);
     break;
   }
   cap->num_bands                                  = ru->num_bands;
@@ -224,7 +211,7 @@ int attach_rru(RU_t *ru)
       LOG_E(PHY,"Received incorrect message %d from RRU %d\n",rru_config_msg.type,ru->idx); 
     }
   }
-  configure_ru(ru->idx,
+  configure_ru(ru,
 	       (RRU_capabilities_t *)&rru_config_msg.msg[0]);
 		    
   rru_config_msg.type = RRU_config;
@@ -296,7 +283,7 @@ int connect_rau(RU_t *ru)
     cap->FH_fmt                                   = MBP_IF5;
     break;
   default:
-    AssertFatal(1==0,"RU_function is unknown %d\n",RC.ru[0]->function);
+    AssertFatal(1==0,"RU_function is unknown %d\n",ru->function);
     break;
   }
   cap->num_bands                                  = ru->num_bands;
@@ -335,7 +322,7 @@ int connect_rau(RU_t *ru)
 	    ((RRU_config_t *)&rru_config_msg.msg[0])->prach_FreqOffset[0],
 	    ((RRU_config_t *)&rru_config_msg.msg[0])->prach_ConfigIndex[0]);
       
-      configure_rru(ru->idx,
+      configure_rru(ru,
 		    (void*)&rru_config_msg.msg[0]);
       configuration_received = 1;
     }
@@ -388,21 +375,20 @@ int check_capabilities(RU_t *ru,
   return(-1);
 }
 
-void configure_ru(int idx,
+void configure_ru(RU_t *ru,
                   void *arg)
 {
-  RU_t               *ru           = RC.ru[idx];
   RRU_config_t       *config       = (RRU_config_t *)arg;
   RRU_capabilities_t *capabilities = (RRU_capabilities_t*)arg;
   int ret;
 
-  LOG_I(PHY, "Received capabilities from RRU %d\n",idx);
+  LOG_I(PHY, "Received capabilities from RRU %d\n",ru->idx);
 
 
   if (capabilities->FH_fmt < MAX_FH_FMTs) LOG_I(PHY, "RU FH options %s\n",rru_format_options[capabilities->FH_fmt]);
 
   AssertFatal((ret=check_capabilities(ru,capabilities)) == 0,
-	      "Cannot configure RRU %d, check_capabilities returned %d\n", idx,ret);
+	      "Cannot configure RRU %d, check_capabilities returned %d\n", ru->idx,ret);
   // take antenna capabilities of RRU
   ru->nb_tx                      = capabilities->nb_tx[0];
   ru->nb_rx                      = capabilities->nb_rx[0];
@@ -440,11 +426,10 @@ void configure_ru(int idx,
   phy_init_RU(ru);
 }
 
-void configure_rru(int idx,
+void configure_rru(RU_t *ru,
                    void *arg)
 {
   RRU_config_t *config = (RRU_config_t *)arg;
-  RU_t         *ru     = RC.ru[idx];
 
   ru->frame_parms->eutra_band                                               = config->band_list[0];
   ru->frame_parms->dl_CarrierFreq                                           = config->tx_freq[0];
@@ -486,7 +471,6 @@ void configure_rru(int idx,
 static int send_update_rru(RU_t * ru, LTE_DL_FRAME_PARMS * fp){
   //ssize_t      msg_len/*,len*/;
   int i;
-  //LTE_DL_FRAME_PARMS *fp = &RC.eNB[0][0]->frame_parms;
   RRU_CONFIG_msg_t rru_config_msg;
   memset((void *)&rru_config_msg,0,sizeof(rru_config_msg));
   rru_config_msg.type = RRU_config_update;
@@ -535,7 +519,7 @@ void* ru_thread_control( void* param )
 	send_tick(ru);
 
       if (ru->state == RU_RUN && ru->if_south != LOCAL_RF){
-	LTE_DL_FRAME_PARMS *fp = &RC.eNB[0][0]->frame_parms;	
+	LTE_DL_FRAME_PARMS *fp = &ru->eNB_list[0]->frame_parms;	
 	LOG_D(PHY,"Check MBSFN SF changes\n");
 	if(fp->num_MBSFN_config != ru_sf_update){
 		ru_sf_update = fp->num_MBSFN_config;
@@ -579,7 +563,7 @@ void* ru_thread_control( void* param )
 		      ((RRU_capabilities_t*)&rru_config_msg.msg[0])->nb_tx[0],
 		      ((RRU_capabilities_t*)&rru_config_msg.msg[0])->nb_rx[0]);
 
-		configure_ru(ru->idx,(RRU_capabilities_t *)&rru_config_msg.msg[0]);
+		configure_ru(ru,(RRU_capabilities_t *)&rru_config_msg.msg[0]);
 
 		// send config
 		if (send_config(ru,rru_config_msg) == 0) ru->state = RU_CONFIG;
@@ -603,7 +587,7 @@ void* ru_thread_control( void* param )
 		      ((RRU_config_t *)&rru_config_msg.msg[0])->prach_ConfigIndex[0]);
 	      
 		ru->frame_parms = calloc(1, sizeof(*ru->frame_parms));
-		configure_rru(ru->idx, (void*)&rru_config_msg.msg[0]);
+		configure_rru(ru, (void*)&rru_config_msg.msg[0]);
 
  					  
 		fill_rf_config(ru,ru->rf_config_file);
@@ -652,10 +636,10 @@ void* ru_thread_control( void* param )
 					
 
 		LOG_I(PHY, "Signaling main thread that RU %d (is_slave %d) is ready in state %s\n",ru->idx,ru->is_slave,ru_states[ru->state]);
-		pthread_mutex_lock(&RC.ru_mutex);
-		RC.ru_mask &= ~(1<<ru->idx);
-		pthread_cond_signal(&RC.ru_cond);
-		pthread_mutex_unlock(&RC.ru_mutex);
+		pthread_mutex_lock(ru->ru_mutex);
+		*ru->ru_mask &= ~(1<<ru->idx);
+		pthread_cond_signal(ru->ru_cond);
+		pthread_mutex_unlock(ru->ru_mutex);
 					  
 		wait_sync("ru_thread_control");
 
@@ -710,10 +694,10 @@ void* ru_thread_control( void* param )
 		if (ru->state == RU_READY){
 
 		  LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx);
-		  pthread_mutex_lock(&RC.ru_mutex);
-		  RC.ru_mask &= ~(1<<ru->idx);
-		  pthread_cond_signal(&RC.ru_cond);
-		  pthread_mutex_unlock(&RC.ru_mutex);
+		  pthread_mutex_lock(ru->ru_mutex);
+		  *ru->ru_mask &= ~(1<<ru->idx);
+		  pthread_cond_signal(ru->ru_cond);
+		  pthread_mutex_unlock(ru->ru_mutex);
 						  
 		  wait_sync("ru_thread_control");
 						
@@ -736,7 +720,7 @@ void* ru_thread_control( void* param )
 	      break;
 
 	    case RRU_sync_ok: //RAU
-	      if (ru->if_south == LOCAL_RF) LOG_E(PHY,"Received RRU_config_ok msg...Ignoring\n");
+	      if (ru->if_south == LOCAL_RF) LOG_E(PHY,"Received RRU_sync_ok msg...Ignoring\n");
 	      else{
 		if (ru->is_slave == 1){
                   printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Received RRU_sync_ok from RRU %d\n",ru->idx);