Commit 72cc6b16 authored by masayuki.harada's avatar masayuki.harada

Merge branch 'develop_SA_L3' into 'master'

develop_SA_L3_20201021

See merge request !2
parents af35e37c 0312db24
......@@ -37,36 +37,14 @@ def nodeExecutor = params.nodeExecutor
pipeline {
agent {
label nodeExecutor
label 'paris2024'
}
options {
disableConcurrentBuilds()
timestamps()
gitLabConnection('OAI GitLab')
gitlabBuilds(builds: [
"Build gNB-USRP",
"Build nr-UE-USRP",
"Build eNB-USRP",
"Build basic-sim",
"Build phy-sim",
"Build eNB-ethernet",
"Build UE-ethernet",
"Analysis with cppcheck",
"Test phy-sim",
"Test basic-sim",
"Test L1-sim",
"Test RF-sim",
"Test L2-sim",
"Test-Mono-FDD-Band7",
"Test-Mono-TDD-Band40",
"Test-IF4p5-FDD-Band7",
"Test-IF4p5-TDD-Band40",
"Test-Mono-FDD-Band13-LTE-M",
"Test-IF4p5-TDD-Band38-Multi-RRU",
"Test-eNB-OAI-UE-FDD-Band7",
"Test-Mono-FDD-Band13-X2-HO",
"Test-TDD-Band78-gNB-NR-UE",
"Test-OCP-FDD-Band7"
"Analysis with cppcheck"
])
ansiColor('xterm')
}
......@@ -157,62 +135,6 @@ pipeline {
}
}
stage ("Start VM -- basic-sim") {
steps {
timeout (time: 5, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
}
}
}
stage ("Start VM -- gnb-usrp") {
steps {
timeout (time: 5, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
}
}
}
stage ("Start VM -- nr-ue-usrp") {
steps {
timeout (time: 5, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
}
}
}
stage ("Start VM -- enb-usrp") {
steps {
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 {
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 {
timeout (time: 5, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
}
}
}
stage ("Start VM -- ue-ethernet") {
steps {
timeout (time: 5, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
}
}
}
stage ("Start VM -- cppcheck") {
steps {
timeout (time: 5, unit: 'MINUTES') {
......@@ -232,69 +154,6 @@ pipeline {
}
}
}
stage ("Build basic simulator") {
steps {
gitlabCommitStatus(name: "Build basic-sim") {
timeout (time: 20, 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"
}
}
}
}
stage ("Build 5G gNB-USRP") {
steps {
gitlabCommitStatus(name: "Build gNB-USRP") {
timeout (time: 20, 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"
}
}
}
}
stage ("Build 5G NR-UE-USRP") {
steps {
gitlabCommitStatus(name: "Build nr-UE-USRP") {
timeout (time: 20, 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') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
}
}
stage ("Build UE-ethernet") {
steps {
gitlabCommitStatus(name: "Build UE-ethernet") {
timeout (time: 20, 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"
}
}
}
}
}
post {
failure {
......@@ -347,348 +206,12 @@ pipeline {
}
}
}
stage ("Variant Tests") {
parallel {
stage ("VM-based tests") {
stages {
stage ("Test physical simulators") {
steps {
script {
timeout (time: 90, 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}"
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
}
}
}
}
}
stage ("Build Flexran Controller") {
when {
expression {doFlexranCtrlTest}
}
steps {
script {
timeout (time: 20, 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"
} catch (Exception e) {
currentBuild.result = 'FAILURE'
}
}
}
}
}
stage ("Test basic simulator") {
steps {
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}"
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
}
}
}
}
}
stage ("Test L1 simulator") {
steps {
script {
timeout (time: 30, 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"
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
}
}
}
}
}
stage ("Test RF simulator") {
steps {
script {
timeout (time: 30, 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"
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
}
}
}
}
}
stage ("Test L2 simulator") {
steps {
script {
timeout (time: 30, unit: 'MINUTES') {
try {
gitlabCommitStatus(name: "Test L2-sim") {
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
}
}
}
}
}
stage ("Destroy all Virtual Machines") {
steps {
sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
}
}
}
}
stage ("Test MONOLITHIC - FDD - Band 7 - B210") {
steps {
script {
triggerSlaveJob ('eNB-CI-FDD-Band7-B210', 'Test-Mono-FDD-Band7')
}
}
post {
always {
script {
finalizeSlaveJob('eNB-CI-FDD-Band7-B210')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test MONOLITHIC - TDD - Band 40 - B210") {
steps {
script {
triggerSlaveJob ('eNB-CI-TDD-Band40-B210', 'Test-Mono-TDD-Band40')
}
}
post {
always {
script {
finalizeSlaveJob('eNB-CI-TDD-Band40-B210')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test IF4p5 - FDD - Band 7 - B210") {
steps {
script {
sh "sleep 60"
triggerSlaveJob ('eNB-CI-IF4p5-FDD-Band7-B210', 'Test-IF4p5-FDD-Band7')
}
}
post {
always {
script {
finalizeSlaveJob('eNB-CI-IF4p5-FDD-Band7-B210')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test IF4p5 - TDD - Band 40 - B210") {
steps {
script {
sh "sleep 60"
triggerSlaveJob ('eNB-CI-IF4p5-TDD-Band40-B210', 'Test-IF4p5-TDD-Band40')
}
}
post {
always {
script {
finalizeSlaveJob('eNB-CI-IF4p5-TDD-Band40-B210')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test MONOLITHIC - FDD - Band 13 - B210") {
steps {
script {
sh "sleep 60"
triggerSlaveJob ('eNB-CI-MONO-FDD-Band13-B210', 'Test-Mono-FDD-Band13-LTE-M')
}
}
post {
always {
script {
finalizeSlaveJob('eNB-CI-MONO-FDD-Band13-B210')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test X2 Handover - FDD - Band 13 - B210") {
steps {
script {
sh "sleep 60"
triggerSlaveJob ('eNB-CI-MONO-FDD-Band13-X2HO-B210', 'Test-Mono-FDD-Band13-X2-HO')
}
}
post {
always {
script {
finalizeSlaveJob('eNB-CI-MONO-FDD-Band13-X2HO-B210')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test IF4p5 - TDD - Band 38 - B210 - MultiRRU") {
steps {
script {
triggerSlaveJob ('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210', 'Test-IF4p5-TDD-Band38-Multi-RRU')
}
}
post {
always {
script {
finalizeSlaveJob('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test OAI UE - FDD - Band 20 - B200") {
steps {
script {
triggerSlaveJobNoGitLab ('UE-CI-FDD-Band20-B200')
}
}
post {
always {
script {
finalizeSlaveJob('UE-CI-FDD-Band20-B200')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test OAI UE - OAI eNB - FDD - Band 7 - B200") {
steps {
script {
// Delayed trigger on slave job, so it is always the last one to run
sh "sleep 240"
triggerSlaveJob ('eNB-UE-CI-MONO-FDD-Band7-B200', 'Test-eNB-OAI-UE-FDD-Band7')
}
}
post {
always {
script {
finalizeSlaveJob('eNB-UE-CI-MONO-FDD-Band7-B200')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test OAI NR UE - OAI gNB - TDD - Band 78 - N300") {
steps {
script {
triggerSlaveJob ('gNB-nrUE-MONO-TDD-Band78-N300', 'Test-TDD-Band78-gNB-NR-UE')
}
}
post {
always {
script {
finalizeSlaveJob('gNB-nrUE-MONO-TDD-Band78-N300')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test OAI OCP-eNB - FDD - Band 7 - B210") {
steps {
script {
triggerSlaveJob ('OCPeNB-FDD-Band7-B210', 'Test-OCP-FDD-Band7')
}
}
post {
always {
script {
finalizeSlaveJob('OCPeNB-FDD-Band7-B210')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
}
post {
always {
script {
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"
}
if(fileExists('archives/vm_tests_logs.zip')) {
archiveArtifacts artifacts: 'archives/vm_tests_logs.zip'
if ("MERGE".equals(env.gitlabActionType)) {
sh "./ci-scripts/oai-ci-vm-tool report-test --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
} else {
sh "./ci-scripts/oai-ci-vm-tool report-test --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger push --branch ${GIT_BRANCH} --commit ${GIT_COMMIT}"
}
if(fileExists('test_simulator_results.html')) {
sh "sed -i -e 's#Build-ID: ${BUILD_ID}#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_simulator_results.html"
archiveArtifacts artifacts: 'test_simulator_results.html'
}
}
}
}
}
}
}
post {
always {
script {
......@@ -703,12 +226,14 @@ Regards,
OAI CI Team''',
replyTo: 'no-reply@openairinterface.org',
subject: '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!',
to: gitCommitAuthorEmailAddr
to: 'donganyuan@cn.fujitsu.com'
if (fileExists('.git/CI_COMMIT_MSG')) {
sh "rm -f .git/CI_COMMIT_MSG"
}
}
echo '\u2705 \u001B[32mClean Up WorkSpace\u001B[0m'
deleteDir()
}
success {
script {
......
......@@ -879,6 +879,7 @@ add_boolean_option(UE_EXPANSION False "enable UE_EXPANSION w
add_boolean_option(PHY_TX_THREAD False "enable UE_EXPANSION with max 256 UE")
add_boolean_option(PRE_SCD_THREAD False "enable UE_EXPANSION with max 256 UE")
add_boolean_option(UESIM_EXPANSION False "enable UESIM_EXPANSION with max 256 UE")
add_boolean_option(ITTI_SIM False "enable itti simulator")
########################
# Include order
......@@ -2912,7 +2913,7 @@ add_executable(nr-uesoftmodem
target_link_libraries (nr-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
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 S1AP_LIB S1AP_ENB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
......@@ -3223,7 +3224,7 @@ if (${T_TRACER})
foreach(i
#all "add_executable" definitions (except tests, rb_tool, updatefw)
lte-softmodem lte-uesoftmodem nr-softmodem
nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7
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
......@@ -3310,6 +3311,60 @@ add_executable(rb_tool
)
target_include_directories(rb_tool PRIVATE ${OPENAIR2_DIR}/NETWORK_DRIVER/MESH/)
# nr-ittisim
###################################################
add_executable(nr-ittisim
${rrc_h}
${nr_rrc_h}
${OPENAIR2_DIR}/GNB_APP/gnb_app.c
${OPENAIR2_DIR}/GNB_APP/gnb_config.c
${OPENAIR_DIR}/executables/nr-gnb.c
${OPENAIR_DIR}/executables/nr-ru.c
${OPENAIR2_DIR}/SIMULATION/NR_RRC/itti_sim.c
${OPENAIR_DIR}/executables/softmodem-common.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${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
${GTPU_need_ITTI}
${XFORMSINTERFACE_SOURCE}
${T_SOURCE}
${CONFIG_SOURCES}
${SHLIB_LOADER_SOURCES}
)
#target_link_libraries (nr-ittisim
# -Wl,--start-group
# UTIL HASHTABLE SCTP_CLIENT UDP 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
# NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB
# 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)
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_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}
NR_L2_UE
-Wl,--end-group z dl)
target_link_libraries (nr-ittisim ${LIBXML2_LIBRARIES})
target_link_libraries (nr-ittisim pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
target_link_libraries (nr-ittisim ${LIB_LMS_LIBRARIES})
target_link_libraries (nr-ittisim ${T_LIB})
add_dependencies( nr-ittisim ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
# ???
####################
list(APPEND oai_nw_drv_src device.c common.c ioctl.c classifier.c tool.c)
......
......@@ -67,6 +67,7 @@ UE_TIMING_TRACE="False"
USRP_REC_PLAY="False"
BUILD_ECLIPSE=0
NR="False"
ITTI_SIM="False"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc"
trap handle_ctrl_c INT
......@@ -160,6 +161,8 @@ Options
Build for I/Q record-playback modes
-k | --skip-shared-libraries
Skip build for shared libraries to reduce compilation time when building frequently for debugging purposes
--ittiSIM
Makes the itti simulator
-h | --help
Print this help
......@@ -418,6 +421,11 @@ function main() {
CMAKE_CMD="$CMAKE_CMD -GNinja"
MAKE_CMD=ninja
shift;;
--ittiSIM)
ittiSIM=1
ITTI_SIM="True"
echo_info "Will compile itti simulator"
shift;;
-h | --help)
print_help
exit 1;;
......@@ -580,7 +588,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" ] ; then
if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HW" = "EXMIMO" -o "$ittiSIM" = "1" ] ; then
# softmodem compilation
......@@ -605,6 +613,7 @@ 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 ( ITTI_SIM $ITTI_SIM )" >> $cmake_file
echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
cd $DIR/$build_dir/build
eval $CMAKE_CMD
......@@ -626,6 +635,10 @@ function main() {
execlist="$execlist nr-uesoftmodem"
fi
if [ "$ittiSIM" = "1" ] ; then
execlist="$execlist nr-ittisim"
fi
for f in $execlist ; do
echo_info "Compiling $f..."
compilations \
......
......@@ -17,3 +17,7 @@
#include "openair2/COMMON/flexran_messages_def.h"
#include "openair2/COMMON/f1ap_messages_def.h"
#include "openair2/COMMON/ngap_messages_def.h"
#if ITTI_SIM
#include "openair2/COMMON/itti_sim_messages_def.h"
#endif
......@@ -260,7 +260,11 @@ typedef struct IttiMsgText_s {
#include <openair3/GTPV1-U/gtpv1u_gNB_task.h>
void *rrc_enb_process_itti_msg(void *);
#include <openair3/SCTP/sctp_eNB_task.h>
#include <openair3/S1AP/s1ap_eNB.h>
#include <openair3/NGAP/ngap_gNB.h>
#ifdef ITTI_SIM
#include <openair2/COMMON/itti_sim_messages_types.h>
#endif
/*
static const char *const messages_definition_xml = {
......@@ -331,6 +335,7 @@ void * rrc_enb_process_msg(void*);
TASK_DEF(TASK_RLC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_PDCP_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RRC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RRC_NRUE, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_NAS_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RAL_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_MSC, TASK_PRIORITY_MED, 200, NULL, NULL)\
......@@ -338,6 +343,8 @@ void * rrc_enb_process_msg(void*);
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_MAX, TASK_PRIORITY_MED, 200, NULL, NULL)
#define TASK_DEF(TaskID, pRIO, qUEUEsIZE, FuNc, ThreadFunc) { pRIO, qUEUEsIZE, #TaskID, FuNc, ThreadFunc },
......
......@@ -1796,7 +1796,7 @@ void init_RU_proc(RU_t *ru) {
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 );
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 );
......
......@@ -401,7 +401,7 @@ int create_gNB_tasks(uint32_t gnb_nb) {
}
}
if (EPC_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0)) {
if (AMF_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0)) {
if (gnb_nb > 0) {
/*
if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
......@@ -824,7 +824,7 @@ int main( int argc, char **argv )
}
openair0_cfg[0].threequarter_fs = threequarter_fs;
EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test;
AMF_MODE_ENABLED = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test;
if (get_softmodem_params()->do_ra)
AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
......
......@@ -235,8 +235,8 @@ 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);
s1ap_eNB_config_t s1ap_config;
uint32_t s1ap_generate_eNB_id(void) {return 0;}
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;}
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { return;}
......
/*!
\file itti_sim_messages_def.h
\brief itti message for itti simulator
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
MESSAGE_DEF(GNB_RRC_BCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, GNBBCCHind)
MESSAGE_DEF(GNB_RRC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, GNBCCCHind)
MESSAGE_DEF(GNB_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, GNBDCCHind)
MESSAGE_DEF(UE_RRC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, UECCCHind)
MESSAGE_DEF(UE_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, UEDCCHind)
/*!
\file itti_sim_messages_types.h
\brief itti message for itti simulator
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#ifndef ITTI_SIM_MESSAGES_TYPES_H_
#define ITTI_SIM_MESSAGES_TYPES_H_
#include "LTE_asn_constant.h"
#define GNB_RRC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.GNBBCCHind
#define GNB_RRC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.GNBCCCHind
#define GNB_RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.GNBDCCHind
#define UE_RRC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.UECCCHind
#define UE_RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.UEDCCHind
typedef struct itti_sim_rrc_ch_s {
const rb_id_t rbid;
uint8_t *sdu;
int size;
} itti_sim_rrc_ch_t;
#endif /* ITTI_SIM_MESSAGES_TYPES_H_ */
......@@ -41,8 +41,6 @@ MESSAGE_DEF(RRC_MAC_CCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDat
MESSAGE_DEF(RRC_MAC_CCCH_DATA_CNF, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataCnf, rrc_mac_ccch_data_cnf)
MESSAGE_DEF(RRC_MAC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataInd, rrc_mac_ccch_data_ind)
// gNB
MESSAGE_DEF(NR_RRC_MAC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcMacCcchDataInd, nr_rrc_mac_ccch_data_ind)
MESSAGE_DEF(RRC_MAC_MCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataReq, rrc_mac_mcch_data_req)
MESSAGE_DEF(RRC_MAC_MCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataInd, rrc_mac_mcch_data_ind)
......@@ -51,3 +49,8 @@ MESSAGE_DEF(RRC_MAC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacPcchDat
/* RRC configures DRX context (MAC timers) of a UE */
MESSAGE_DEF(RRC_MAC_DRX_CONFIG_REQ, MESSAGE_PRIORITY_MED, rrc_mac_drx_config_req_t, rrc_mac_drx_config_req)
// gNB
MESSAGE_DEF(NR_RRC_MAC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcMacCcchDataInd, nr_rrc_mac_ccch_data_ind)
MESSAGE_DEF(NR_RRC_MAC_BCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcMacBcchDataInd, nr_rrc_mac_bcch_data_ind)
......@@ -38,6 +38,7 @@
#define RRC_MAC_BCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_data_req
#define RRC_MAC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_data_ind
#define NR_RRC_MAC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_mac_bcch_data_ind
#define RRC_MAC_BCCH_MBMS_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_mbms_data_req
#define RRC_MAC_BCCH_MBMS_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_mbms_data_ind
......@@ -87,6 +88,15 @@ typedef struct RrcMacBcchDataInd_s {
uint8_t rsrp;
} RrcMacBcchDataInd;
typedef struct NRRrcMacBcchDataInd_s {
uint32_t frame;
uint8_t sub_frame;
uint32_t sdu_size;
uint8_t sdu[BCCH_SDU_SIZE];
uint8_t gnb_index;
uint8_t rsrq;
uint8_t rsrp;
} NRRrcMacBcchDataInd;
typedef struct RrcMacBcchMbmsDataReq_s {
uint32_t frame;
......
......@@ -74,6 +74,7 @@ TASK_DEF(TASK_PROTO_AGENT, TASK_PRIORITY_MED, 200)
/// 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)
......@@ -81,3 +82,8 @@ 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
......@@ -173,7 +173,7 @@ void *gNB_app_task(void *args_p)
__attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
}
if (EPC_MODE_ENABLED) {
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);
......
......@@ -342,7 +342,7 @@ void RCconfig_nr_flexran()
/* gNB ID from configuration, as read in by RCconfig_RRC() */
if (!GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr) {
// Calculate a default gNB ID
if (EPC_MODE_ENABLED)
if (AMF_MODE_ENABLED)
gnb_id = i + (ngap_generate_gNB_id () & 0xFFFFFF8);
else
gnb_id = i;
......@@ -536,7 +536,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
AssertFatal (i<num_gnbs,"Failed to parse config file no %ith element in %s \n",i, GNB_CONFIG_STRING_ACTIVE_GNBS);
/*
if (EPC_MODE_ENABLED) {
if (AMF_MODE_ENABLED) {
if (strcasecmp( *(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr), GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) {
asn_debug = 0;
asn1_xer_print = 0;
......@@ -562,7 +562,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
if (GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr == NULL) {
// Calculate a default gNB ID
if (EPC_MODE_ENABLED) {
if (AMF_MODE_ENABLED) {
uint32_t hash;
hash = ngap_generate_gNB_id ();
gnb_id = i + (hash & 0xFFFFFF8);
......@@ -742,7 +742,7 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) {
config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL);
/*
if (EPC_MODE_ENABLED) {
if (AMF_MODE_ENABLED) {
if (strcasecmp( *(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr), GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) {
asn_debug = 0;
asn1_xer_print = 0;
......@@ -771,7 +771,7 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) {
for (k = 0; k < GNBParamList.numelt; k++) {
if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) {
// Calculate a default gNB ID
if (EPC_MODE_ENABLED) {
if (AMF_MODE_ENABLED) {
uint32_t hash;
hash = ngap_generate_gNB_id ();
......@@ -925,7 +925,7 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) {
// SCTP SETTING
NGAP_REGISTER_GNB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
NGAP_REGISTER_GNB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS;
if (EPC_MODE_ENABLED) {
if (AMF_MODE_ENABLED) {
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);
NGAP_REGISTER_GNB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
......@@ -1044,7 +1044,7 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
for (k = 0; k < GNBParamList.numelt; k++) {
if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) {
// Calculate a default eNB ID
if (EPC_MODE_ENABLED) {
if (AMF_MODE_ENABLED) {
uint32_t hash;
hash = ngap_generate_gNB_id ();
gnb_id = k + (hash & 0xFFFFFF8);
......@@ -1173,7 +1173,7 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS;
if (EPC_MODE_ENABLED) {
if (AMF_MODE_ENABLED) {
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);
X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
......
......@@ -863,10 +863,45 @@ boolean_t pdcp_remove_UE(
return 1;
}
void pdcp_config_set_security(const protocol_ctxt_t* const ctxt_pP, pdcp_t *pdcp_pP, rb_id_t rb_id,
uint16_t lc_idP, uint8_t security_modeP, uint8_t *kRRCenc_pP, uint8_t *kRRCint_pP, uint8_t *kUPenc_pP)
void pdcp_config_set_security(
const protocol_ctxt_t* const ctxt_pP,
pdcp_t *const pdcp_pP,
const rb_id_t rb_id,
const uint16_t lc_idP,
const uint8_t security_modeP,
uint8_t *const kRRCenc_pP,
uint8_t *const kRRCint_pP,
uint8_t *const kUPenc_pP)
{
TODO;
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);
} 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);
}
}
static boolean_t pdcp_data_req_drb(
......
......@@ -37,6 +37,9 @@
#include "COMMON/s1ap_messages_types.h"
#include "COMMON/rrc_messages_types.h"
#if ITTI_SIM
#include "COMMON/itti_sim_messages_types.h"
#endif
#include "collection/tree.h"
#include "rrc_types_NB_IoT.h"
......
......@@ -41,8 +41,10 @@
#include <per_encoder.h>
#include "asn1_msg.h"
#include "../nr_rrc_proto.h"
#include "RRC/NR/nr_rrc_extern.h"
#include "NR_DL-CCCH-Message.h"
#include "NR_UL-CCCH-Message.h"
#include "NR_DL-DCCH-Message.h"
#include "NR_RRCReject.h"
#include "NR_RejectWaitTime.h"
......@@ -61,6 +63,8 @@
#include "NR_DRB-ToAddMod.h"
#include "NR_DRB-ToAddModList.h"
#include "NR_SecurityConfig.h"
#include "NR_RRCReconfiguration-v1530-IEs.h"
#include "NR_UL-DCCH-Message.h"
#if defined(NR_Rel16)
#include "NR_SCS-SpecificCarrier.h"
#include "NR_TDD-UL-DL-ConfigCommon.h"
......@@ -659,17 +663,18 @@ uint8_t do_RRCSetup(const protocol_ctxt_t *const ctxt_pP,
NR_MAC_CellGroupConfig_t *mac_CellGroupConfig = NULL;
char masterCellGroup_buf[1000];
int size = 0;
long *logicalChannelGroup = NULL;
memset((void *)&dl_ccch_msg, 0, sizeof(NR_DL_CCCH_Message_t));
dl_ccch_msg.message.present = NR_DL_CCCH_MessageType_PR_c1;
dl_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_CCCH_MessageType__c1));
dl_ccch_msg.message.choice.c1->present = NR_DL_CCCH_MessageType__c1_PR_rrcSetup;
dl_ccch_msg.message.choice.c1->choice.rrcSetup = calloc(1, sizeof(NR_RRCSetup_t));
rrcSetup = dl_ccch_msg.message.choice.c1->choice.rrcSetup;
rrcSetup->criticalExtensions.present = NR_RRCSetup__criticalExtensions_PR_rrcSetup;
rrcSetup->rrc_TransactionIdentifier = transaction_id;
rrcSetup->criticalExtensions.choice.rrcSetup = calloc(1, sizeof(NR_RRCSetup_IEs_t));
ie = rrcSetup->criticalExtensions.choice.rrcSetup;
/****************************** radioBearerConfig ******************************/
......@@ -703,14 +708,18 @@ uint8_t do_RRCSetup(const protocol_ctxt_t *const ctxt_pP,
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;
......@@ -718,6 +727,7 @@ uint8_t do_RRCSetup(const protocol_ctxt_t *const ctxt_pP,
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));
......@@ -726,6 +736,10 @@ uint8_t do_RRCSetup(const protocol_ctxt_t *const ctxt_pP,
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));
......@@ -932,12 +946,13 @@ uint16_t do_RRCReconfiguration(
NR_DL_DCCH_Message_t dl_dcch_msg;
asn_enc_rval_t enc_rval;
NR_RRCReconfiguration_IEs_t *ie;
NR_SRB_ToAddModList_t *SRB2_configList = NULL;
NR_SRB_ToAddModList_t *SRB_configList = NULL;
NR_SRB_ToAddModList_t *SRB_configList2 = NULL;
NR_SRB_ToAddMod_t *SRB2_config = NULL;
NR_DRB_ToAddModList_t *DRB_configList = NULL;
NR_DRB_ToAddModList_t *DRB_configList2 = NULL;
NR_DRB_ToAddMod_t *DRB_config = NULL;
NR_SecurityConfig_t *security_config = NULL;
NR_CellGroupConfig_t *secondaryCellGroup = NULL;
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL;
memset(&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t));
......@@ -949,26 +964,40 @@ uint16_t do_RRCReconfiguration(
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier = Transaction_id;
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
/******************** Radio Bearer Config ********************/
ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t));
/* Configure SRB2 */
SRB2_configList = ue_context_pP->ue_context.SRB_configList2[xid];
SRB_configList2 = ue_context_pP->ue_context.SRB_configList2[Transaction_id];
SRB_configList = ue_context_pP->ue_context.SRB_configList;
SRB_configList = CALLOC(1, sizeof(*SRB_configList));
memset(SRB_configList, 0, sizeof(*SRB_configList));
if (SRB2_configList) {
free(SRB2_configList);
if (SRB_configList2) {
free(SRB_configList2);
}
SRB2_configList = CALLOC(1, sizeof(*SRB2_configList));
memset(SRB2_configList, 0, sizeof(*SRB2_configList));
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(&SRB2_configList->list, SRB2_config);
ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
ASN_SEQUENCE_ADD(&SRB_configList2->list, SRB2_config);
/* Configure DRB */
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[Transaction_id];
if (DRB_configList2) {
free(DRB_configList2);
}
DRB_configList2 = CALLOC(1, sizeof(*DRB_configList2));
memset(DRB_configList2, 0, sizeof(*DRB_configList2));
DRB_config = CALLOC(1, sizeof(*DRB_config));
DRB_config->drb_Identity = 1;
DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation));
......@@ -998,31 +1027,32 @@ uint16_t do_RRCReconfiguration(
DRB_config->pdcp_Config->ext1 = NULL;
ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config);
ASN_SEQUENCE_ADD(&DRB_configList2->list, DRB_config);
/* Configure Security */
security_config = CALLOC(1, sizeof(NR_SecurityConfig_t));
security_config->securityAlgorithmConfig = CALLOC(1, sizeof(*ie->radioBearerConfig->securityConfig->securityAlgorithmConfig));
security_config->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
security_config->securityAlgorithmConfig->integrityProtAlgorithm = NULL;
security_config->keyToUse = CALLOC(1, sizeof(*ie->radioBearerConfig->securityConfig->keyToUse));
*security_config->keyToUse = NR_SecurityConfig__keyToUse_master;
// security_config = CALLOC(1, sizeof(NR_SecurityConfig_t));
// security_config->securityAlgorithmConfig = CALLOC(1, sizeof(*ie->radioBearerConfig->securityConfig->securityAlgorithmConfig));
// security_config->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
// security_config->securityAlgorithmConfig->integrityProtAlgorithm = NULL;
// security_config->keyToUse = CALLOC(1, sizeof(*ie->radioBearerConfig->securityConfig->keyToUse));
// *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 = SRB2_configList;
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 = NULL;
/******************** Secondary Cell Group ********************/
rrc_gNB_carrier_data_t *carrier = &(gnb_rrc_inst->carrier);
fill_default_secondaryCellGroup( carrier->ServingCellConfigCommon,
ue_context_pP->ue_context.secondaryCellGroup,
1,
1,
carrier->pdsch_AntennaPorts,
carrier->initial_csi_index[gnb_rrc_inst->Nb_ue]);
// rrc_gNB_carrier_data_t *carrier = &(gnb_rrc_inst->carrier);
// fill_default_secondaryCellGroup( carrier->servingcellconfigcommon,
// ue_context_pP->ue_context.secondaryCellGroup,
// 1,
// 1,
// carrier->pdsch_AntennaPorts,
// carrier->initial_csi_index[gnb_rrc_inst->Nb_ue]);
/******************** Meas Config ********************/
// measConfig
......@@ -1030,9 +1060,10 @@ uint16_t do_RRCReconfiguration(
// lateNonCriticalExtension
ie->lateNonCriticalExtension = NULL;
// nonCriticalExtension
ie->nonCriticalExtension = calloc(1, sizeof(NR_RRCReconfiguration_v1530_IEs_t));
dedicatedNAS_Message = calloc(1, sizeof(NR_DedicatedNAS_Message_t));
dedicatedNAS_Message->buf = ue_context_pP->ue_context.nas_pdu.buffer;
dedicatedNAS_Message->size = ue_context_pP->ue_context.nas_pdu.length;
ie->nonCriticalExtension->dedicatedNAS_MessageList = CALLOC(1, sizeof(*ie->nonCriticalExtension->dedicatedNAS_MessageList));
ASN_SEQUENCE_ADD(&ie->nonCriticalExtension->dedicatedNAS_MessageList->list, dedicatedNAS_Message);
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration = ie;
......@@ -1064,3 +1095,125 @@ uint16_t do_RRCReconfiguration(
return((enc_rval.encoded+7)/8);
}
uint8_t do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) {
asn_enc_rval_t enc_rval;
uint8_t buf[5],buf2=0;
NR_UL_CCCH_Message_t ul_ccch_msg;
NR_RRCSetupRequest_t *rrcSetupRequest;
memset((void *)&ul_ccch_msg,0,sizeof(NR_UL_CCCH_Message_t));
ul_ccch_msg.message.present = NR_UL_CCCH_MessageType_PR_c1;
ul_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_CCCH_MessageType__c1));
ul_ccch_msg.message.choice.c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest;
rrcSetupRequest = ul_ccch_msg.message.choice.c1->choice.rrcSetupRequest;
if (1) {
rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_randomValue;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.size = 5;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.bits_unused = 0;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf = buf;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[0] = rv[0];
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[1] = rv[1];
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[2] = rv[2];
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[3] = rv[3];
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[4] = rv[4];
} else {
rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.size = 1;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.bits_unused = 0;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.buf = buf;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.buf[0] = 0x12;
}
rrcSetupRequest->rrcSetupRequest.establishmentCause = NR_EstablishmentCause_mo_Signalling; //EstablishmentCause_mo_Data;
rrcSetupRequest->rrcSetupRequest.spare.buf = &buf2;
rrcSetupRequest->rrcSetupRequest.spare.size=1;
rrcSetupRequest->rrcSetupRequest.spare.bits_unused = 7;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_ccch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_CCCH_Message,
NULL,
(void *)&ul_ccch_msg,
buffer,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(RRC,"[UE] RRCSetupRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
//------------------------------------------------------------------------------
uint8_t
do_NR_RRCReconfigurationComplete(
const protocol_ctxt_t *const ctxt_pP,
uint8_t *buffer,
const uint8_t Transaction_id
)
//------------------------------------------------------------------------------
{
asn_enc_rval_t enc_rval;
NR_UL_DCCH_Message_t ul_dcch_msg;
NR_RRCReconfigurationComplete_t *rrcReconfigurationComplete;
memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1));
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete;
rrcReconfigurationComplete = ul_dcch_msg.message.choice.c1->choice.rrcReconfigurationComplete;
rrcReconfigurationComplete->rrc_TransactionIdentifier = Transaction_id;
rrcReconfigurationComplete->criticalExtensions.present =
NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete;
rrcReconfigurationComplete->criticalExtensions.choice.rrcReconfigurationComplete->nonCriticalExtension = NULL;
rrcReconfigurationComplete->criticalExtensions.choice.rrcReconfigurationComplete->lateNonCriticalExtension = NULL;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
}
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, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(RRC,"rrcReconfigurationComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, uint8_t sel_plmn_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS){
asn_enc_rval_t enc_rval;
NR_UL_DCCH_Message_t ul_dcch_msg;
NR_RRCSetupComplete_t *RrcSetupComplete;
memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
ul_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_DL_DCCH_MessageType__c1));
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete;
RrcSetupComplete = ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete;
RrcSetupComplete->rrc_TransactionIdentifier = Transaction_id;
RrcSetupComplete->criticalExtensions.present = NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->nonCriticalExtension = CALLOC(1,
sizeof(*RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->nonCriticalExtension));
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->selectedPLMN_Identity = sel_plmn_id;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->registeredAMF = NULL;
memset(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t));
OCTET_STRING_fromBuf(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,dedicatedInfoNAS,dedicatedInfoNASLength);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&ul_dcch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
NULL,
(void *)&ul_dcch_msg,
buffer,
100);
AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name,enc_rval.encoded);
LOG_D(RRC,"RRCConnectionSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
......@@ -99,6 +99,10 @@ uint8_t do_NR_SecurityModeCommand(
const uint8_t cipheringAlgorithm,
NR_IntegrityProtAlgorithm_t *integrityProtAlgorithm);
uint8_t do_NR_UECapabilityEnquiry_nr( const protocol_ctxt_t *const ctxt_pP,
uint8_t *const buffer,
const uint8_t Transaction_id);
uint8_t do_NR_RRCConnectionRelease(uint8_t *buffer,
uint8_t Transaction_id);
uint16_t do_RRCReconfiguration(
......@@ -107,3 +111,10 @@ uint16_t do_RRCReconfiguration(
uint8_t *buffer,
uint8_t Transaction_id,
gNB_RRC_INST *gnb_rrc_inst);
uint8_t do_RRCSetupComplete(uint8_t Mod_id,
uint8_t *buffer,
const uint8_t Transaction_id,
uint8_t sel_plmn_id,
const int dedicatedInfoNASLength,
const char *dedicatedInfoNAS);
\ No newline at end of file
......@@ -134,8 +134,6 @@ typedef enum UE_STATE_NR_e {
/* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */
#define NR_RRC_TRANSACTION_IDENTIFIER_NUMBER 3
#define ENABLE_SECURITY 1
typedef struct {
unsigned short transport_block_size; /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */
unsigned short max_transport_blocks; /*!< \brief Maximum PDU size in bytes provided by RLC to MAC layer interface */
......@@ -289,13 +287,12 @@ typedef struct gNB_RRC_UE_s {
ImsiMobileIdentity_t imsi;
#if defined(ENABLE_SECURITY)
/* KeNB as derived from KASME received from EPC */
uint8_t kenb[32];
int8_t kenb_ncc;
/* KgNB as derived from KASME received from EPC */
uint8_t kgnb[32];
int8_t kgnb_ncc;
uint8_t nh[32];
int8_t nh_ncc;
#endif
/* Used integrity/ciphering algorithms */
NR_CipheringAlgorithm_t ciphering_algorithm;
e_NR_IntegrityProtAlgorithm integrity_algorithm;
......@@ -322,7 +319,7 @@ typedef struct gNB_RRC_UE_s {
uint64_t amf_ue_ngap_id:40;
nr_rrc_guami_t ue_guami;
security_capabilities_t security_capabilities;
ngap_security_capabilities_t security_capabilities;
/* Total number of e_rab already setup in the list */
uint8_t setup_e_rabs;
......
......@@ -68,9 +68,7 @@
#include "OCG.h"
#include "OCG_extern.h"
#if defined(ENABLE_SECURITY)
#include "UTIL/OSA/osa_defs.h"
#endif
#include "UTIL/OSA/osa_defs.h"
#include "rrc_eNB_S1AP.h"
#include "rrc_gNB_NGAP.h"
......@@ -92,6 +90,28 @@
extern RAN_CONTEXT_t RC;
extern boolean_t nr_rrc_pdcp_config_asn1_req(
const protocol_ctxt_t *const ctxt_pP,
NR_SRB_ToAddModList_t *const srb2add_list,
NR_DRB_ToAddModList_t *const drb2add_list,
NR_DRB_ToReleaseList_t *const drb2release_list,
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
uint8_t *const kUPenc
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
,rb_id_t *const defaultDRB,
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);
mui_t rrc_gNB_mui = 0;
///---------------------------------------------------------------------------------------------------------------///
......@@ -347,7 +367,7 @@ rrc_gNB_generate_RRCSetup(
)
//-----------------------------------------------------------------------------
{
LOG_I(RRC, "rrc_gNB_generate_RRCSetup \n");
LOG_I(NR_RRC, "rrc_gNB_generate_RRCSetup \n");
NR_SRB_ToAddModList_t *SRB_configList = NULL;
// T(T_GNB_RRC_SETUP,
......@@ -357,7 +377,7 @@ rrc_gNB_generate_RRCSetup(
// T_INT(ctxt_pP->rnti));
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
SRB_configList = ue_p->SRB_configList;
do_RRCSetup(ctxt_pP,
ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ctxt_pP,
ue_context_pP,
CC_id,
(uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
......@@ -420,6 +440,13 @@ rrc_gNB_generate_RRCSetup(
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;
message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, GNB_RRC_CCCH_DATA_IND);
GNB_RRC_CCCH_DATA_IND (message_p).sdu = (uint8_t*)ue_p->Srb0.Tx_buffer.Payload;
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
}
void
......@@ -562,18 +589,18 @@ rrc_gNB_process_RRCReconfigurationComplete(
return;
}
/* Derive the keys from kenb */
/* Derive the keys from kgnb */
if (DRB_configList != NULL) {
derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kenb,
ue_context_pP->ue_context.kgnb,
&kUPenc);
}
derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kenb,
ue_context_pP->ue_context.kgnb,
&kRRCenc);
derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
ue_context_pP->ue_context.kenb,
ue_context_pP->ue_context.kgnb,
&kRRCint);
/* Refresh SRBs/DRBs */
......@@ -590,6 +617,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
kRRCint,
kUPenc,
NULL,
NULL,
NULL);
/* Refresh SRBs/DRBs */
nr_rrc_rlc_config_asn1_req(ctxt_pP,
......@@ -597,9 +625,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
DRB_configList,
DRB_Release_configList2,
NULL,
0,
0
);
NULL);
/* Loop through DRBs and establish if necessary */
if (DRB_configList != NULL) {
......
......@@ -47,6 +47,7 @@
#include "S1AP_NAS-PDU.h"
#include "executables/softmodem-common.h"
#include "UTIL/OSA/osa_defs.h"
extern RAN_CONTEXT_t RC;
......@@ -115,6 +116,75 @@ rrc_gNB_get_ue_context_from_ngap_ids(
return NULL;
}
//------------------------------------------------------------------------------
void
nr_rrc_pdcp_config_security(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
const uint8_t send_security_mode_command
)
//------------------------------------------------------------------------------
{
NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList;
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;
/* Derive the keys from kgnb */
if (SRB_configList != NULL) {
derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb,
&kUPenc);
}
derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb,
&kRRCenc);
derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
ue_context_pP->ue_context.kgnb,
&kRRCint);
if (!IS_SOFTMODEM_IQPLAYER) {
SET_LOG_DUMP(DEBUG_SECURITY) ;
}
if ( LOG_DUMPFLAG( DEBUG_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:" );
}
}
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);
}
}
//------------------------------------------------------------------------------
/*
* Initial UE NAS message on S1AP.
......@@ -280,7 +350,7 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
uint8_t send_security_mode_command = TRUE;
rrc_pdcp_config_security(
nr_rrc_pdcp_config_security(
&ctxt,
ue_context_p,
send_security_mode_command);
......@@ -289,7 +359,7 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
rrc_gNB_generate_SecurityModeCommand (&ctxt, ue_context_p);
send_security_mode_command = FALSE;
rrc_pdcp_config_security(
nr_rrc_pdcp_config_security(
&ctxt,
ue_context_p,
send_security_mode_command);
......@@ -370,7 +440,7 @@ int
rrc_gNB_process_security(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
security_capabilities_t *security_capabilities_pP
ngap_security_capabilities_t *security_capabilities_pP
) {
boolean_t changed = FALSE;
NR_CipheringAlgorithm_t cipheringAlgorithm;
......@@ -381,19 +451,19 @@ rrc_gNB_process_security(
LOG_D(NR_RRC,
"[eNB %d] NAS security_capabilities.encryption_algorithms %u AS ciphering_algorithm %lu NAS security_capabilities.integrity_algorithms %u AS integrity_algorithm %u\n",
ctxt_pP->module_id,
ue_context_pP->ue_context.security_capabilities.encryption_algorithms,
ue_context_pP->ue_context.security_capabilities.nRencryption_algorithms,
(unsigned long)ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.security_capabilities.integrity_algorithms,
ue_context_pP->ue_context.security_capabilities.nRintegrity_algorithms,
ue_context_pP->ue_context.integrity_algorithm);
/* Select relevant algorithms */
cipheringAlgorithm = rrc_gNB_select_ciphering (ue_context_pP->ue_context.security_capabilities.encryption_algorithms);
cipheringAlgorithm = rrc_gNB_select_ciphering (ue_context_pP->ue_context.security_capabilities.nRencryption_algorithms);
if (ue_context_pP->ue_context.ciphering_algorithm != cipheringAlgorithm) {
ue_context_pP->ue_context.ciphering_algorithm = cipheringAlgorithm;
changed = TRUE;
}
integrityProtAlgorithm = rrc_gNB_select_integrity (ue_context_pP->ue_context.security_capabilities.integrity_algorithms);
integrityProtAlgorithm = rrc_gNB_select_integrity (ue_context_pP->ue_context.security_capabilities.nRintegrity_algorithms);
if (ue_context_pP->ue_context.integrity_algorithm != integrityProtAlgorithm) {
ue_context_pP->ue_context.integrity_algorithm = integrityProtAlgorithm;
......
......@@ -74,7 +74,7 @@ int
rrc_gNB_process_security(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
security_capabilities_t *security_capabilities_pP
ngap_security_capabilities_t *security_capabilities_pP
);
#endif
......@@ -68,3 +68,42 @@ int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
return 0;
}
uint8_t
rrc_data_req_ue(
const protocol_ctxt_t *const ctxt_pP,
const rb_id_t rb_idP,
const mui_t muiP,
const confirm_t confirmP,
const sdu_size_t sdu_sizeP,
uint8_t *const buffer_pP,
const pdcp_transmission_mode_t modeP
)
{
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);
memcpy (message_buffer, buffer_pP, sdu_sizeP);
message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, 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;
RRC_DCCH_DATA_REQ (message_p).muip = muiP;
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;
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;
RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index;
itti_send_msg_to_task (
TASK_PDCP_UE,
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.
}
......@@ -33,10 +33,17 @@
#define RRC_UE
#define RRC_UE_C
#include "asn1_conversions.h"
#include "NR_DL-DCCH-Message.h" //asn_DEF_NR_DL_DCCH_Message
#include "NR_DL-CCCH-Message.h" //asn_DEF_NR_DL_CCCH_Message
#include "NR_BCCH-BCH-Message.h" //asn_DEF_NR_BCCH_BCH_Message
#include "NR_BCCH-DL-SCH-Message.h" //asn_DEF_NR_BCCH_DL_SCH_Message
#include "NR_CellGroupConfig.h" //asn_DEF_NR_CellGroupConfig
#include "NR_BWP-Downlink.h" //asn_DEF_NR_BWP_Downlink
#include "NR_RRCReconfiguration.h"
#include "NR_MeasConfig.h"
#include "NR_UL-DCCH-Message.h"
#include "rrc_list.h"
#include "rrc_defs.h"
......@@ -44,8 +51,87 @@
#include "rrc_vars.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "intertask_interface.h"
#include "executables/softmodem-common.h"
#include "plmn_data.h"
#include "pdcp.h"
#include "UTIL/OSA/osa_defs.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
mui_t nr_rrc_mui=0;
static Rrc_State_t nr_rrc_get_state (module_id_t ue_mod_idP) {
return NR_UE_rrc_inst[ue_mod_idP].nrRrcState;
}
static Rrc_Sub_State_t nr_rrc_get_sub_state (module_id_t ue_mod_idP) {
return NR_UE_rrc_inst[ue_mod_idP].nrRrcSubState;
}
static int nr_rrc_set_state (module_id_t ue_mod_idP, Rrc_State_t state) {
AssertFatal ((RRC_STATE_FIRST <= state) && (state <= RRC_STATE_LAST),
"Invalid state %d!\n", state);
if (NR_UE_rrc_inst[ue_mod_idP].nrRrcState != state) {
NR_UE_rrc_inst[ue_mod_idP].nrRrcState = state;
return (1);
}
return (0);
}
static int nr_rrc_set_sub_state( module_id_t ue_mod_idP, Rrc_Sub_State_NR_t subState ) {
if (AMF_MODE_ENABLED) {
switch (NR_UE_rrc_inst[ue_mod_idP].nrRrcState) {
case RRC_STATE_INACTIVE_NR:
AssertFatal ((RRC_SUB_STATE_INACTIVE_FIRST_NR <= subState) && (subState <= RRC_SUB_STATE_INACTIVE_LAST_NR),
"Invalid nr sub state %d for state %d!\n", subState, NR_UE_rrc_inst[ue_mod_idP].nrRrcState);
break;
case RRC_STATE_IDLE_NR:
AssertFatal ((RRC_SUB_STATE_IDLE_FIRST_NR <= subState) && (subState <= RRC_SUB_STATE_IDLE_LAST_NR),
"Invalid nr sub state %d for state %d!\n", subState, NR_UE_rrc_inst[ue_mod_idP].nrRrcState);
break;
case RRC_STATE_CONNECTED_NR:
AssertFatal ((RRC_SUB_STATE_CONNECTED_FIRST_NR <= subState) && (subState <= RRC_SUB_STATE_CONNECTED_LAST_NR),
"Invalid nr sub state %d for state %d!\n", subState, NR_UE_rrc_inst[ue_mod_idP].nrRrcState);
break;
}
}
if (NR_UE_rrc_inst[ue_mod_idP].nrRrcSubState != subState) {
NR_UE_rrc_inst[ue_mod_idP].nrRrcSubState = subState;
return (1);
}
return (0);
}
extern boolean_t nr_rrc_pdcp_config_asn1_req(
const protocol_ctxt_t *const ctxt_pP,
NR_SRB_ToAddModList_t *const srb2add_list,
NR_DRB_ToAddModList_t *const drb2add_list,
NR_DRB_ToReleaseList_t *const drb2release_list,
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
uint8_t *const kUPenc
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
,rb_id_t *const defaultDRB,
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);
// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded)
int8_t nr_rrc_ue_decode_secondary_cellgroup_config(
......@@ -384,6 +470,42 @@ int8_t nr_ue_process_spcell_config(NR_SpCellConfig_t *spcell_config){
return 0;
}
//-----------------------------------------------------------------------------
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(RRC,"%x.",rv[i]);
}
LOG_T(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(RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %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(RRC,"%x.",NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
}
LOG_T(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; */
}
}
/*brief decode BCCH-BCH (MIB) message*/
int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(
const module_id_t module_id,
......@@ -432,6 +554,896 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(
return 0;
}
static const char siWindowLength[10][5] = {"5s", "10s", "20s", "40s", "80s", "160s", "320s", "640s", "1280s","ERR"};// {"1ms","2ms","5ms","10ms","15ms","20ms","40ms","80ms","ERR"};
static const char siWindowLength_int[9] = {5,10,20,40,80,160,320,640,1280};//{1,2,5,10,15,20,40,80};
static const char SIBType[12][6] = {"SIB3","SIB4","SIB5","SIB6","SIB7","SIB8","SIB9","SIB10","SIB11","SIB12","SIB13","Spare"};
static const char SIBPeriod[8][6]= {"rf8","rf16","rf32","rf64","rf128","rf256","rf512","ERR"};
static int siPeriod_int[7] = {80,160,320,640,1280,2560,5120};
const char *nr_SIBreserved( long value ) {
if (value < 0 || value > 1)
return "ERR";
if (value)
return "notReserved";
return "reserved";
}
void nr_dump_sib2( NR_SIB2_t *sib2 ){
//cellReselectionInfoCommon
//nrofSS_BlocksToAverage
if( sib2->cellReselectionInfoCommon.nrofSS_BlocksToAverage)
LOG_I( RRC, "cellReselectionInfoCommon.nrofSS_BlocksToAverage : %ld\n",
*sib2->cellReselectionInfoCommon.nrofSS_BlocksToAverage );
else
LOG_I( RRC, "cellReselectionInfoCommon->nrofSS_BlocksToAverage : not defined\n" );
//absThreshSS_BlocksConsolidation
if( sib2->cellReselectionInfoCommon.absThreshSS_BlocksConsolidation){
LOG_I( RRC, "absThreshSS_BlocksConsolidation.thresholdRSRP : %ld\n",
*sib2->cellReselectionInfoCommon.absThreshSS_BlocksConsolidation->thresholdRSRP );
LOG_I( RRC, "absThreshSS_BlocksConsolidation.thresholdRSRQ : %ld\n",
*sib2->cellReselectionInfoCommon.absThreshSS_BlocksConsolidation->thresholdRSRQ );
LOG_I( RRC, "absThreshSS_BlocksConsolidation.thresholdSINR : %ld\n",
*sib2->cellReselectionInfoCommon.absThreshSS_BlocksConsolidation->thresholdSINR );
} else
LOG_I( RRC, "cellReselectionInfoCommon->absThreshSS_BlocksConsolidation : not defined\n" );
//q_Hyst
LOG_I( RRC, "cellReselectionInfoCommon.q_Hyst : %ld\n",
sib2->cellReselectionInfoCommon.q_Hyst );
//speedStateReselectionPars
if( sib2->cellReselectionInfoCommon.speedStateReselectionPars){
LOG_I( RRC, "speedStateReselectionPars->mobilityStateParameters.t_Evaluation : %ld\n",
sib2->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.t_Evaluation);
LOG_I( RRC, "speedStateReselectionPars->mobilityStateParameters.t_HystNormal : %ld\n",
sib2->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.t_HystNormal);
LOG_I( RRC, "speedStateReselectionPars->mobilityStateParameters.n_CellChangeMedium : %ld\n",
sib2->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.n_CellChangeMedium);
LOG_I( RRC, "speedStateReselectionPars->mobilityStateParameters.n_CellChangeHigh : %ld\n",
sib2->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.n_CellChangeHigh);
LOG_I( RRC, "speedStateReselectionPars->q_HystSF.sf_Medium : %ld\n",
sib2->cellReselectionInfoCommon.speedStateReselectionPars->q_HystSF.sf_Medium);
LOG_I( RRC, "speedStateReselectionPars->q_HystSF.sf_High : %ld\n",
sib2->cellReselectionInfoCommon.speedStateReselectionPars->q_HystSF.sf_High);
} else
LOG_I( RRC, "cellReselectionInfoCommon->speedStateReselectionPars : not defined\n" );
//cellReselectionServingFreqInfo
if( sib2->cellReselectionServingFreqInfo.s_NonIntraSearchP)
LOG_I( RRC, "cellReselectionServingFreqInfo.s_NonIntraSearchP : %ld\n",
*sib2->cellReselectionServingFreqInfo.s_NonIntraSearchP );
else
LOG_I( RRC, "cellReselectionServingFreqInfo->s_NonIntraSearchP : not defined\n" );
if( sib2->cellReselectionServingFreqInfo.s_NonIntraSearchQ)
LOG_I( RRC, "cellReselectionServingFreqInfo.s_NonIntraSearchQ : %ld\n",
*sib2->cellReselectionServingFreqInfo.s_NonIntraSearchQ );
else
LOG_I( RRC, "cellReselectionServingFreqInfo->s_NonIntraSearchQ : not defined\n" );
LOG_I( RRC, "cellReselectionServingFreqInfo.threshServingLowP : %ld\n",
sib2->cellReselectionServingFreqInfo.threshServingLowP );
if( sib2->cellReselectionServingFreqInfo.threshServingLowQ)
LOG_I( RRC, "cellReselectionServingFreqInfo.threshServingLowQ : %ld\n",
*sib2->cellReselectionServingFreqInfo.threshServingLowQ );
else
LOG_I( RRC, "cellReselectionServingFreqInfo->threshServingLowQ : not defined\n" );
LOG_I( RRC, "cellReselectionServingFreqInfo.cellReselectionPriority : %ld\n",
sib2->cellReselectionServingFreqInfo.cellReselectionPriority );
if( sib2->cellReselectionServingFreqInfo.cellReselectionSubPriority)
LOG_I( RRC, "cellReselectionServingFreqInfo.cellReselectionSubPriority : %ld\n",
*sib2->cellReselectionServingFreqInfo.cellReselectionSubPriority );
else
LOG_I( RRC, "cellReselectionServingFreqInfo->cellReselectionSubPriority : not defined\n" );
//intraFreqCellReselectionInfo
LOG_I( RRC, "intraFreqCellReselectionInfo.q_RxLevMin : %ld\n",
sib2->intraFreqCellReselectionInfo.q_RxLevMin );
if( sib2->intraFreqCellReselectionInfo.q_RxLevMinSUL)
LOG_I( RRC, "intraFreqCellReselectionInfo.q_RxLevMinSUL : %ld\n",
*sib2->intraFreqCellReselectionInfo.q_RxLevMinSUL );
else
LOG_I( RRC, "intraFreqCellReselectionInfo->q_RxLevMinSUL : not defined\n" );
if( sib2->intraFreqCellReselectionInfo.q_QualMin)
LOG_I( RRC, "intraFreqCellReselectionInfo.q_QualMin : %ld\n",
*sib2->intraFreqCellReselectionInfo.q_QualMin );
else
LOG_I( RRC, "intraFreqCellReselectionInfo->q_QualMin : not defined\n" );
LOG_I( RRC, "intraFreqCellReselectionInfo.s_IntraSearchP : %ld\n",
sib2->intraFreqCellReselectionInfo.s_IntraSearchP );
if( sib2->intraFreqCellReselectionInfo.s_IntraSearchQ)
LOG_I( RRC, "intraFreqCellReselectionInfo.s_IntraSearchQ : %ld\n",
*sib2->intraFreqCellReselectionInfo.s_IntraSearchQ );
else
LOG_I( RRC, "intraFreqCellReselectionInfo->s_IntraSearchQ : not defined\n" );
LOG_I( RRC, "intraFreqCellReselectionInfo.t_ReselectionNR : %ld\n",
sib2->intraFreqCellReselectionInfo.t_ReselectionNR );
if( sib2->intraFreqCellReselectionInfo.frequencyBandList)
LOG_I( RRC, "intraFreqCellReselectionInfo.frequencyBandList : %p\n",
sib2->intraFreqCellReselectionInfo.frequencyBandList );
else
LOG_I( RRC, "intraFreqCellReselectionInfo->frequencyBandList : not defined\n" );
if( sib2->intraFreqCellReselectionInfo.frequencyBandListSUL)
LOG_I( RRC, "intraFreqCellReselectionInfo.frequencyBandListSUL : %p\n",
sib2->intraFreqCellReselectionInfo.frequencyBandListSUL );
else
LOG_I( RRC, "intraFreqCellReselectionInfo->frequencyBandListSUL : not defined\n" );
if( sib2->intraFreqCellReselectionInfo.p_Max)
LOG_I( RRC, "intraFreqCellReselectionInfo.p_Max : %ld\n",
*sib2->intraFreqCellReselectionInfo.p_Max );
else
LOG_I( RRC, "intraFreqCellReselectionInfo->p_Max : not defined\n" );
if( sib2->intraFreqCellReselectionInfo.smtc)
LOG_I( RRC, "intraFreqCellReselectionInfo.smtc : %p\n",
sib2->intraFreqCellReselectionInfo.smtc );
else
LOG_I( RRC, "intraFreqCellReselectionInfo->smtc : not defined\n" );
if( sib2->intraFreqCellReselectionInfo.ss_RSSI_Measurement)
LOG_I( RRC, "intraFreqCellReselectionInfo.ss_RSSI_Measurement : %p\n",
sib2->intraFreqCellReselectionInfo.ss_RSSI_Measurement );
else
LOG_I( RRC, "intraFreqCellReselectionInfo->ss_RSSI_Measurement : not defined\n" );
if( sib2->intraFreqCellReselectionInfo.ssb_ToMeasure)
LOG_I( RRC, "intraFreqCellReselectionInfo.ssb_ToMeasure : %p\n",
sib2->intraFreqCellReselectionInfo.ssb_ToMeasure );
else
LOG_I( RRC, "intraFreqCellReselectionInfo->ssb_ToMeasure : not defined\n" );
LOG_I( RRC, "intraFreqCellReselectionInfo.deriveSSB_IndexFromCell : %d\n",
sib2->intraFreqCellReselectionInfo.deriveSSB_IndexFromCell );
}
void nr_dump_sib3( NR_SIB3_t *sib3 ) {
//intraFreqNeighCellList
if( sib3->intraFreqNeighCellList){
LOG_I( RRC, "intraFreqNeighCellList : %p\n",
sib3->intraFreqNeighCellList );
const int n = sib3->intraFreqNeighCellList->list.count;
for (int i = 0; i < n; ++i){
LOG_I( RRC, "intraFreqNeighCellList->physCellId : %ld\n",
sib3->intraFreqNeighCellList->list.array[i]->physCellId );
LOG_I( RRC, "intraFreqNeighCellList->q_OffsetCell : %ld\n",
sib3->intraFreqNeighCellList->list.array[i]->q_OffsetCell );
if( sib3->intraFreqNeighCellList->list.array[i]->q_RxLevMinOffsetCell)
LOG_I( RRC, "intraFreqNeighCellList->q_RxLevMinOffsetCell : %ld\n",
*sib3->intraFreqNeighCellList->list.array[i]->q_RxLevMinOffsetCell );
else
LOG_I( RRC, "intraFreqNeighCellList->q_RxLevMinOffsetCell : not defined\n" );
if( sib3->intraFreqNeighCellList->list.array[i]->q_RxLevMinOffsetCellSUL)
LOG_I( RRC, "intraFreqNeighCellList->q_RxLevMinOffsetCellSUL : %ld\n",
*sib3->intraFreqNeighCellList->list.array[i]->q_RxLevMinOffsetCellSUL );
else
LOG_I( RRC, "intraFreqNeighCellList->q_RxLevMinOffsetCellSUL : not defined\n" );
if( sib3->intraFreqNeighCellList->list.array[i]->q_QualMinOffsetCell)
LOG_I( RRC, "intraFreqNeighCellList->q_QualMinOffsetCell : %ld\n",
*sib3->intraFreqNeighCellList->list.array[i]->q_QualMinOffsetCell );
else
LOG_I( RRC, "intraFreqNeighCellList->q_QualMinOffsetCell : not defined\n" );
}
} else{
LOG_I( RRC, "intraFreqCellReselectionInfo : not defined\n" );
}
//intraFreqBlackCellList
if( sib3->intraFreqBlackCellList){
LOG_I( RRC, "intraFreqBlackCellList : %p\n",
sib3->intraFreqBlackCellList );
const int n = sib3->intraFreqBlackCellList->list.count;
for (int i = 0; i < n; ++i){
LOG_I( RRC, "intraFreqBlackCellList->start : %ld\n",
sib3->intraFreqBlackCellList->list.array[i]->start );
if( sib3->intraFreqBlackCellList->list.array[i]->range)
LOG_I( RRC, "intraFreqBlackCellList->range : %ld\n",
*sib3->intraFreqBlackCellList->list.array[i]->range );
else
LOG_I( RRC, "intraFreqBlackCellList->range : not defined\n" );
}
} else{
LOG_I( RRC, "intraFreqBlackCellList : not defined\n" );
}
//lateNonCriticalExtension
if( sib3->lateNonCriticalExtension)
LOG_I( RRC, "lateNonCriticalExtension : %p\n",
sib3->lateNonCriticalExtension );
else
LOG_I( RRC, "lateNonCriticalExtension : not defined\n" );
}
int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) {
NR_SystemInformation_t **si = &NR_UE_rrc_inst[ctxt_pP->module_id].si[gNB_index];
int new_sib = 0;
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_SI, VCD_FUNCTION_IN );
// Dump contents
if ((*si)->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_systemInformation ||
(*si)->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture_r16) {
LOG_D( RRC, "[UE] (*si)->criticalExtensions.choice.NR_SystemInformation_t->sib_TypeAndInfo.list.count %d\n",
(*si)->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count );
} else {
LOG_D( RRC, "[UE] Unknown criticalExtension version (not Rel16)\n" );
return -1;
}
for (int i=0; i<(*si)->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count; i++) {
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_sib2:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&2) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=2;
//new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib2[gNB_index], &typeandinfo->choice.sib2, sizeof(NR_SIB2_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB2 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
nr_dump_sib2( NR_UE_rrc_inst[ctxt_pP->module_id].sib2[gNB_index] );
LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB2 params gNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n",
ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id );
//TODO rrc_mac_config_req_ue
// 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 );
}
if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_IDLE) {
LOG_I( RRC, "[UE %d] Received SIB1/SIB2/SIB3 Switching to RRC_SI_RECEIVED\n", ctxt_pP->module_id );
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_SI_RECEIVED;
#if ENABLE_RAL
/* TODO {
MessageDef *message_ral_p = NULL;
rrc_ral_system_information_ind_t ral_si_ind;
message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_SYSTEM_INFORMATION_IND);
memset(&ral_si_ind, 0, sizeof(rrc_ral_system_information_ind_t));
ral_si_ind.plmn_id.MCCdigit2 = '0';
ral_si_ind.plmn_id.MCCdigit1 = '2';
ral_si_ind.plmn_id.MNCdigit3 = '0';
ral_si_ind.plmn_id.MCCdigit3 = '8';
ral_si_ind.plmn_id.MNCdigit2 = '9';
ral_si_ind.plmn_id.MNCdigit1 = '9';
ral_si_ind.cell_id = 1;
ral_si_ind.dbm = 0;
//ral_si_ind.dbm = fifo_dump_emos_UE.PHY_measurements->rx_rssi_dBm[gNB_index];
// TO DO
ral_si_ind.sinr = 0;
//ral_si_ind.sinr = fifo_dump_emos_UE.PHY_measurements->subband_cqi_dB[gNB_index][phy_vars_ue->lte_frame_parms.nb_antennas_rx][0];
// TO DO
ral_si_ind.link_data_rate = 0;
memcpy (&message_ral_p->ittiMsg, (void *) &ral_si_ind, sizeof(rrc_ral_system_information_ind_t));
#warning "ue_mod_idP ? for instance ?"
itti_send_msg_to_task (TASK_RAL_UE, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), message_ral_p);
}*/
#endif
}
}
break; // case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&4) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=4;
new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib3[gNB_index], &typeandinfo->choice.sib3, sizeof(LTE_SystemInformationBlockType3_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB3 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
nr_dump_sib3( NR_UE_rrc_inst[ctxt_pP->module_id].sib3[gNB_index] );
}
break;
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib4:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&8) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=8;
new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib4[gNB_index], typeandinfo->choice.sib4, sizeof(NR_SIB4_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB4 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
}
break;
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib5:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&16) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=16;
new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib5[gNB_index], typeandinfo->choice.sib5, sizeof(NR_SIB5_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB5 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
//dump_sib5(NR_UE_rrc_inst[ctxt_pP->module_id].sib5[gNB_index]);
}
break;
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib6:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&32) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=32;
new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib6[gNB_index], typeandinfo->choice.sib6, sizeof(NR_SIB6_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB6 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
}
break;
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib7:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&64) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=64;
new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib7[gNB_index], typeandinfo->choice.sib7, sizeof(NR_SIB7_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB7 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
}
break;
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib8:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&128) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=128;
new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib8[gNB_index], typeandinfo->choice.sib8, sizeof(NR_SIB8_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB8 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
}
break;
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib9:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&256) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=256;
new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib9[gNB_index], typeandinfo->choice.sib9, sizeof(NR_SIB9_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB9 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
}
break;
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib10_v1610:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&512) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=512;
new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib10[gNB_index], typeandinfo->choice.sib10_v1610, sizeof(NR_SIB10_r16_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB10 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
}
break;
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib11_v1610:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1024) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=1024;
new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib11[gNB_index], typeandinfo->choice.sib11_v1610, sizeof(NR_SIB11_r16_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB11 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
}
break;
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib12_v1610:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&2048) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=2048;
new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib12[gNB_index], typeandinfo->choice.sib12_v1610, sizeof(NR_SIB12_r16_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB12 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
}
break;
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib13_v1610:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&4096) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=4096;
new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib13[gNB_index], typeandinfo->choice.sib13_v1610, sizeof(NR_SIB13_r16_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB13 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
//dump_sib13( NR_UE_rrc_inst[ctxt_pP->module_id].sib13[gNB_index] );
// adding here function to store necessary parameters for using in decode_MCCH_Message + maybe transfer to PHY layer
LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB13 params gNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n",
ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
// TODO rrc_mac_config_req_ue
}
break;
case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib14_v1610:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&8192) == 0) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=8192;
new_sib=1;
memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib12[gNB_index], typeandinfo->choice.sib14_v1610, sizeof(NR_SIB14_r16_t) );
LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB14 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
}
break;
default:
break;
}
if (new_sib == 1) {
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt++;
if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)
nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE );
LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n",
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus,
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt,
sib1->si_SchedulingInfo->schedulingInfoList.list.count);
}
}
//if (new_sib == 1) {
// NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt++;
// if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->schedulingInfoList.list.count)
// rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE );
// LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n",
// NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus,
// NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt,
// sib1->schedulingInfoList.list.count);
//}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT);
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];
}
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;
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;
}
plmn_ind++;
}
}
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" );
//if (sib1->p_Max)
// LOG_I( RRC, "p_Max : %ld\n", *sib1->p_Max );
//else
// LOG_I( RRC, "p_Max : not defined\n" );
//LOG_I( RRC, "freqBandIndicator : %ld\n", sib1->freqBandIndicator );
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)]);
if (sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count > 0) {
char temp[32 * sizeof(SIBType[0])] = {0}; // maxSIB==32
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_I( RRC, "siSchedulingInfoSIBType[%d] : %s\n", i, temp );
} else {
LOG_I( RRC, "mapping list %d is null\n", i );
}
}
} 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;
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_UE, 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;
}
}
//}
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_UE, PHY_FIND_NEXT_CELL_REQ);
itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p);
LOG_E(RRC,
"Synched with a cell, but PLMN doesn't match our SIM "
"(selected_plmn_identity %d), 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);
}
}
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 ) {
NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
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_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)) {
// 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 );
}
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
&asn_DEF_NR_BCCH_DL_SCH_Message,
(void **)&bcch_message,
(const void *)Sdu,
Sdu_len );
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,
dec_rval.consumed );
log_dump(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 );
return -1;
}
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 );
}
}
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) {
// SIB1 with schedulingInfoList is available
NR_SystemInformation_t *si = NR_UE_rrc_inst[ctxt_pP->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 );
nr_decode_SI( ctxt_pP, gNB_index );
//if (nfapi_mode == 3)
//UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1;
}
break;
case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
default:
break;
}
}
if (nr_rrc_get_sub_state(ctxt_pP->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 );
//}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
return 0;
}
//-----------------------------------------------------------------------------
void
nr_rrc_ue_process_masterCellGroup(
const protocol_ctxt_t *const ctxt_pP,
uint8_t gNB_index,
OCTET_STRING_t *masterCellGroup
)
//-----------------------------------------------------------------------------
{
NR_CellGroupConfig_t *cellGroupConfig = (NR_CellGroupConfig_t *)masterCellGroup;
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)
}
if( cellGroupConfig->rlc_BearerToReleaseList != NULL){
//TODO (perform RLC bearer release as specified in 5.3.5.5.3)
}
if( cellGroupConfig->rlc_BearerToAddModList != NULL){
//TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4)
}
if( cellGroupConfig->mac_CellGroupConfig != NULL){
//TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5)
}
if( cellGroupConfig->sCellToReleaseList != NULL){
//TODO (perform SCell release as specified in 5.3.5.5.8)
}
if( cellGroupConfig->spCellConfig != NULL){
if (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;
}
//TODO (configure the SpCell as specified in 5.3.5.5.7)
}
if( cellGroupConfig->sCellToAddModList != NULL){
//TODO (perform SCell addition/modification as specified in 5.3.5.5.9)
}
if( cellGroupConfig->ext2->bh_RLC_ChannelToReleaseList_r16 != NULL){
//TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11)
}
if( cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 != NULL){
//TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11)
}
}
/*--------------------------------------------------*/
static void rrc_ue_generate_RRCSetupComplete(
const protocol_ctxt_t *const ctxt_pP,
const uint8_t gNB_index,
const uint8_t Transaction_id,
uint8_t sel_plmn_id){
uint8_t buffer[100];
uint8_t size;
const char *nas_msg;
int nas_msg_length;
/*
if (EPC_MODE_ENABLED) {
nas_msg = (char *) UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data;
nas_msg_length = UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length;
} else {
nas_msg = nas_attach_req_imsi;
nas_msg_length = sizeof(nas_attach_req_imsi);
}
*/
size = do_RRCSetupComplete(ctxt_pP->module_id,buffer,Transaction_id,sel_plmn_id,nas_msg_length,nas_msg);
LOG_I(RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCConnectionSetupComplete (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",
ctxt_pP->frame, ctxt_pP->module_id+NB_RN_INST, size, gNB_index, nr_rrc_mui, ctxt_pP->module_id+NB_eNB_INST, DCCH);
// 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);
}
int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const 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 == RRC_SI_RECEIVED) {
switch (dl_ccch_msg->message.choice.c1->present) {
case NR_DL_CCCH_MessageType__c1_PR_NOTHING:
LOG_I(RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",
ctxt_pP->module_id,
ctxt_pP->frame);
rval = 0;
break;
case NR_DL_CCCH_MessageType__c1_PR_rrcReject:
LOG_I(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(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(RRC, "[UE%d] Frame %d : Unknown message\n",
ctxt_pP->module_id,
ctxt_pP->frame);
rval = -1;
break;
}
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
return rval;
}
// from NR SRB3
int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(
......@@ -507,3 +1519,807 @@ int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(
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(RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (gNB %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(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(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(RRC,"[UE %d] Security algorithm is set to nea2\n",
ctxt_pP->module_id);
securityMode = NR_CipheringAlgorithm_nea2;
break;
default:
LOG_I(RRC,"[UE %d] Security algorithm is set to none\n",ctxt_pP->module_id);
securityMode = NR_CipheringAlgorithm_spare1;
break;
}
switch (*securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm) {
case NR_IntegrityProtAlgorithm_nia1:
LOG_I(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(RRC,"[UE %d] Integrity protection algorithm is set to nia2\n",ctxt_pP->module_id);
securityMode |= 1 << 6;
break;
default:
LOG_I(RRC,"[UE %d] Integrity protection algorithm is set to none\n",ctxt_pP->module_id);
securityMode |= 0x70 ;
break;
}
LOG_D(RRC,"[UE %d] security mode is %x \n",ctxt_pP->module_id, securityMode);
NR_UE_rrc_inst->cipheringAlgorithm =
securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm;
NR_UE_rrc_inst->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 (securityMode >= NO_SECURITY_MODE) {
LOG_I(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(RRC, "rrc_ue_process_securityModeCommand, security mode failure case \n");
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeFailure;
}
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(RRC, "PDCP_COLL_KEY_VALUE() returns valid key = %ld\n", key);
LOG_D(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->kgnb[0], NR_UE_rrc_inst->kgnb[1], NR_UE_rrc_inst->kgnb[2], NR_UE_rrc_inst->kgnb[3],
NR_UE_rrc_inst->kgnb[4], NR_UE_rrc_inst->kgnb[5], NR_UE_rrc_inst->kgnb[6], NR_UE_rrc_inst->kgnb[7],
NR_UE_rrc_inst->kgnb[8], NR_UE_rrc_inst->kgnb[9], NR_UE_rrc_inst->kgnb[10], NR_UE_rrc_inst->kgnb[11],
NR_UE_rrc_inst->kgnb[12], NR_UE_rrc_inst->kgnb[13], NR_UE_rrc_inst->kgnb[14], NR_UE_rrc_inst->kgnb[15],
NR_UE_rrc_inst->kgnb[16], NR_UE_rrc_inst->kgnb[17], NR_UE_rrc_inst->kgnb[18], NR_UE_rrc_inst->kgnb[19],
NR_UE_rrc_inst->kgnb[20], NR_UE_rrc_inst->kgnb[21], NR_UE_rrc_inst->kgnb[22], NR_UE_rrc_inst->kgnb[23],
NR_UE_rrc_inst->kgnb[24], NR_UE_rrc_inst->kgnb[25], NR_UE_rrc_inst->kgnb[26], NR_UE_rrc_inst->kgnb[27],
NR_UE_rrc_inst->kgnb[28], NR_UE_rrc_inst->kgnb[29], NR_UE_rrc_inst->kgnb[30], NR_UE_rrc_inst->kgnb[31]);
derive_key_rrc_enc(NR_UE_rrc_inst->cipheringAlgorithm,NR_UE_rrc_inst->kgnb, &kRRCenc);
derive_key_rrc_int(NR_UE_rrc_inst->integrityProtAlgorithm,NR_UE_rrc_inst->kgnb, &kRRCint);
derive_key_up_enc(NR_UE_rrc_inst->cipheringAlgorithm,NR_UE_rrc_inst->kgnb, &kUPenc);
if (securityMode != 0xff) {
pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0,
NR_UE_rrc_inst->cipheringAlgorithm
| (NR_UE_rrc_inst->integrityProtAlgorithm << 4),
kRRCenc, kRRCint, kUPenc);
} else {
LOG_I(RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x",
securityMode);
}
} else {
LOG_I(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->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->nonCriticalExtension =NULL;
LOG_I(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_D(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(RRC, "%02x.", buffer[i]);
}
LOG_T(RRC, "\n");
rrc_data_req (
ctxt_pP,
DCCH,
nr_rrc_mui++,
SDU_CONFIRM_NO,
(enc_rval.encoded + 7) / 8,
buffer,
PDCP_TRANSMISSION_MODE_CONTROL);
} else LOG_W(RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n",
securityModeCommand->criticalExtensions.present);
}
//-----------------------------------------------------------------------------
int32_t
nr_rrc_ue_establish_srb1(
module_id_t ue_mod_idP,
frame_t frameP,
uint8_t gNB_index,
NR_SRB_ToAddMod_t *SRB_config
)
//-----------------------------------------------------------------------------
{
// 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].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);
}
//-----------------------------------------------------------------------------
int32_t
nr_rrc_ue_establish_srb2(
module_id_t ue_mod_idP,
frame_t frameP,
uint8_t gNB_index,
NR_SRB_ToAddMod_t *SRB_config
)
//-----------------------------------------------------------------------------
{
// 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].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(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(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);
// 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,
NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB,
NULL);
// Refresh DRBs
nr_rrc_rlc_config_asn1_req(ctxt_pP,
NULL,
radioBearerConfig->drb_ToAddModList,
NULL,
NULL,
NULL
);
} // drb_ToAddModList
if (radioBearerConfig->drb_ToReleaseList != NULL) {
for (i = 0; i < radioBearerConfig->drb_ToReleaseList->list.count; i++) {
DRB_id = *radioBearerConfig->drb_ToReleaseList->list.array[i];
free(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]);
}
}
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_CONNECTED;
LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index);
}
//-----------------------------------------------------------------------------
void
rrc_ue_process_rrcReconfiguration(
const protocol_ctxt_t *const ctxt_pP,
NR_RRCReconfiguration_t *rrcReconfiguration,
uint8_t gNB_index
)
//-----------------------------------------------------------------------------
{
LOG_I(NR_RRC, "[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCReconfiguration (gNB %d)\n",
ctxt_pP->module_id, ctxt_pP->frame, gNB_index);
NR_RRCReconfiguration_IEs_t *ie = NULL;
if (rrcReconfiguration->criticalExtensions.present
== NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration) {
ie = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration;
if (ie->measConfig != NULL) {
LOG_I(NR_RRC, "Measurement Configuration is present\n");
nr_rrc_ue_process_measConfig(ctxt_pP, gNB_index, ie->measConfig);
}
if (ie->radioBearerConfig != NULL) {
LOG_I(NR_RRC, "radio Bearer Configuration is present\n");
nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig);
}
/* Check if there is dedicated NAS information to forward to NAS */
if (ie->nonCriticalExtension->dedicatedNAS_MessageList != NULL) {
int list_count;
uint32_t pdu_length;
uint8_t *pdu_buffer;
MessageDef *msg_p;
for (list_count = 0; list_count < ie->nonCriticalExtension->dedicatedNAS_MessageList->list.count; list_count++) {
pdu_length = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->size;
pdu_buffer = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->buf;
msg_p = itti_alloc_new_message(TASK_RRC_UE, 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);
}
free (ie->nonCriticalExtension->dedicatedNAS_MessageList);
}
}
}
//-----------------------------------------------------------------------------
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(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);
rrc_data_req_ue (
ctxt_pP,
DCCH,
nr_rrc_mui++,
SDU_CONFIRM_NO,
size,
buffer,
PDCP_TRANSMISSION_MODE_CONTROL);
}
// from NR SRB1
//-----------------------------------------------------------------------------
int
nr_rrc_ue_decode_dcch(
const protocol_ctxt_t *const ctxt_pP,
const srb_id_t Srb_id,
const uint8_t *const Buffer,
const uint8_t gNB_indexP
)
//-----------------------------------------------------------------------------
{
asn_dec_rval_t dec_rval;
NR_DL_DCCH_Message_t *dl_dcch_msg = NULL;
MessageDef *msg_p;
if (Srb_id != 1) {
LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n",
ctxt_pP->module_id, ctxt_pP->frame, Srb_id);
return -1;
} else {
LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id);
}
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;
}
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:
msg_p = itti_alloc_new_message(TASK_RRC_UE, 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_rrcReestablishment:
case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
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;
case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
break;
}
}
return 0;
}
//-----------------------------------------------------------------------------
void *rrc_nrue_task( void *args_p ) {
MessageDef *msg_p;
instance_t instance;
unsigned int ue_mod_id;
int result;
NR_SRB_INFO *srb_info_p;
protocol_ctxt_t ctxt;
itti_mark_task_ready (TASK_RRC_NRUE);
while(1) {
// Wait for a message
itti_receive_msg (TASK_RRC_NRUE, &msg_p);
instance = ITTI_MSG_INSTANCE (msg_p);
ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance);
switch (ITTI_MSG_ID(msg_p)) {
case TERMINATE_MESSAGE:
LOG_W(RRC, " *** Exiting RRC thread\n");
itti_exit_task ();
break;
case MESSAGE_TEST:
LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
break;
case NR_RRC_MAC_BCCH_DATA_IND:
LOG_D(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(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, ENB_FLAG_NO, RRC_MAC_CCCH_DATA_IND (msg_p).rnti, 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:
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, NR_RRC_DCCH_DATA_IND (msg_p).module_id, GNB_FLAG_NO, NR_RRC_DCCH_DATA_IND (msg_p).rnti, NR_RRC_DCCH_DATA_IND (msg_p).frame, 0,NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, DCCH %d, gNB %d\n",
NR_RRC_DCCH_DATA_IND (msg_p).module_id,
ITTI_MSG_NAME (msg_p),
NR_RRC_DCCH_DATA_IND (msg_p).frame,
NR_RRC_DCCH_DATA_IND (msg_p).dcch_index,
NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
LOG_D(NR_RRC, PROTOCOL_RRC_CTXT_UE_FMT"Received %s DCCH %d, gNB %d\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt),
ITTI_MSG_NAME (msg_p),
NR_RRC_DCCH_DATA_IND (msg_p).dcch_index,
NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
nr_rrc_ue_decode_dcch (
&ctxt,
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).gNB_index);
// Message buffer has been processed, free it now.
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), NR_RRC_DCCH_DATA_IND (msg_p).sdu_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
break;
default:
LOG_E(RRC, "[UE %d] Received unexpected message %s\n", ue_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;
}
}
void *nr_rrc_ue_process_sidelink_radioResourceConfig(
module_id_t Mod_idP,
uint8_t gNB_index,
NR_SetupRelease_SL_ConfigDedicatedNR_r16_t *sl_ConfigDedicatedNR
)
{
//process sl_CommConfig, configure MAC/PHY for transmitting SL communication (RRC_CONNECTED)
if (sl_ConfigDedicatedNR != NULL) {
switch (sl_ConfigDedicatedNR->present){
case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_setup:
//TODO
break;
case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_release:
break;
case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_NOTHING:
break;
default:
break;
}
}
}
......@@ -53,8 +53,15 @@
#include "NR_MIB.h"
#include "NR_BCCH-BCH-Message.h"
#include "NR_DL-DCCH-Message.h"
#include "../NR/nr_rrc_defs.h"
#define NB_NR_UE_INST 1
#define NB_CNX_UE 2//MAX_MANAGED_RG_PER_MOBILE
#define NB_SIG_CNX_UE 2 //MAX_MANAGED_RG_PER_MOBILE
#define MAX_MEAS_OBJ 6
#define MAX_MEAS_CONFIG 6
#define MAX_MEAS_ID 6
typedef uint32_t channel_t;
......@@ -69,8 +76,52 @@ typedef struct NR_UE_RRC_INST_s {
NR_CellGroupConfig_t *cell_group_config;
NR_RadioBearerConfig_t *radio_bearer_config;
NR_MeasObjectToAddMod_t *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ];
NR_ReportConfigToAddMod_t *ReportConfig[NB_CNX_UE][MAX_MEAS_CONFIG];
NR_QuantityConfig_t *QuantityConfig[NB_CNX_UE];
NR_MeasIdToAddMod_t *MeasId[NB_CNX_UE][MAX_MEAS_ID];
NR_MeasGapConfig_t *measGapConfig[NB_CNX_UE];
NR_RSRP_Range_t s_measure;
NR_SRB_ToAddMod_t *SRB1_config[NB_CNX_UE];
NR_SRB_ToAddMod_t *SRB2_config[NB_CNX_UE];
NR_DRB_ToAddMod_t *DRB_config[NB_CNX_UE][8];
rb_id_t *defaultDRB; // remember the ID of the default DRB
NR_SRB_INFO Srb0[NB_SIG_CNX_UE];
NR_SRB_INFO_TABLE_ENTRY Srb1[NB_CNX_UE];
NR_SRB_INFO_TABLE_ENTRY Srb2[NB_CNX_UE];
uint8_t MBMS_flag;
NR_SystemInformation_t *si[NB_CNX_UE];
NR_SIB1_t *sib1[NB_CNX_UE];
NR_SIB2_t *sib2[NB_CNX_UE];
NR_SIB3_t *sib3[NB_CNX_UE];
NR_SIB4_t *sib4[NB_CNX_UE];
NR_SIB5_t *sib5[NB_CNX_UE];
NR_SIB6_t *sib6[NB_CNX_UE];
NR_SIB7_t *sib7[NB_CNX_UE];
NR_SIB8_t *sib8[NB_CNX_UE];
NR_SIB9_t *sib9[NB_CNX_UE];
NR_SIB10_r16_t *sib10[NB_CNX_UE];
NR_SIB11_r16_t *sib11[NB_CNX_UE];
NR_SIB12_r16_t *sib12[NB_CNX_UE];
NR_SIB13_r16_t *sib13[NB_CNX_UE];
NR_SIB14_r16_t *sib14[NB_CNX_UE];
plmn_t plmnID;
NR_UE_RRC_INFO Info[NB_SIG_CNX_UE];
NR_MIB_t *mib;
/* KeNB as computed from parameters within USIM card */
uint8_t kgnb[32];
/* Used integrity/ciphering algorithms */
//RRC_LIST_TYPE(NR_SecurityAlgorithmConfig_t, NR_SecurityAlgorithmConfig) SecurityAlgorithmConfig_list;
NR_CipheringAlgorithm_t cipheringAlgorithm;
e_NR_IntegrityProtAlgorithm integrityProtAlgorithm;
// lists
// CellGroupConfig.rlc-BearerToAddModList
RRC_LIST_TYPE(NR_RLC_BearerConfig_t, NR_maxLC_ID) RLC_Bearer_Config_list;
......@@ -119,6 +170,9 @@ typedef struct NR_UE_RRC_INST_s {
// CellGroupConfig.spCellConfig.spCellConfigDedicated
RRC_LIST_TYPE(NR_CSI_ReportConfig_t, NR_maxNrofCSI_ReportConfigurations) CSI_ReportConfig_list;
long selected_plmn_identity;
Rrc_State_NR_t nrRrcState;
Rrc_Sub_State_NR_t nrRrcSubState;
} NR_UE_RRC_INST_t;
#endif
......
......@@ -114,6 +114,10 @@ int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
const rb_id_t Srb_id,
uint8_t *const buffer_pP);
/**\brief RRC UE task.
\param void *args_p Pointer on arguments to start the task. */
void *rrc_nrue_task(void *args_p);
/** @}*/
#endif
/*!
\file itti_sim.c
\brief simulator for itti message from node to UE
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <sched.h>
#include "T.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
#include <common/utils/assertions.h>
#include "msc.h"
#include "common/ran_context.h"
#include "common/config/config_userapi.h"
#include "common/utils/load_module_shlib.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
#include "PHY/phy_vars.h"
#include "SCHED/sched_common_vars.h"
#include "LAYER2/MAC/mac_vars.h"
#include "RRC/LTE/rrc_vars.h"
#include "gnb_config.h"
#include "SIMULATION/TOOLS/sim.h"
#ifdef SMBV
#include "PHY/TOOLS/smbv.h"
unsigned short config_frames[4] = {2,9,11,13};
#endif
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#ifndef OPENAIR2
#include "UTIL/OTG/otg_vars.h"
#endif
#include "intertask_interface.h"
#include "system.h"
#include <openair2/GNB_APP/gnb_app.h>
#include "PHY/TOOLS/phy_scope_interface.h"
#include "PHY/TOOLS/nr_phy_scope.h"
#include "stats.h"
#include "nr-softmodem.h"
#include "executables/softmodem-common.h"
#include "executables/thread-common.h"
#include "NB_IoT_interface.h"
#include "x2ap_eNB.h"
#include "ngap_gNB.h"
#include "RRC/NR_UE/rrc_proto.h"
#include "openair3/NAS/UE/nas_ue_task.h"
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;
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");
}
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;
openair0_config_t openair0_cfg[MAX_CARDS];
volatile int start_gNB = 0;
volatile int oai_exit = 0;
//static int wait_for_sync = 0;
unsigned int mmapped_dma=0;
int single_thread_flag=1;
int8_t threequarter_fs=0;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
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;
runmode_t mode = normal_txrx;
static double snr_dB=20;
FILE *input_fd=NULL;
int chain_offset=0;
uint8_t dci_Format = 0;
uint8_t agregation_Level =0xFF;
uint8_t nb_antenna_tx = 1;
uint8_t nb_antenna_rx = 1;
char ref[128] = "internal";
char channels[128] = "0";
int otg_enabled;
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;
extern char uecap_xer[1024];
char uecap_xer_in=0;
/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
* this is very hackish - find a proper solution
*/
uint8_t abstraction_flag=0;
/* forward declarations */
void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
/*---------------------BMC: timespec helpers -----------------------------*/
struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
struct timespec clock_difftime(struct timespec start, struct timespec end) {
struct timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return temp;
}
#define KNRM "\x1B[0m"
#define KRED "\x1B[31m"
#define KGRN "\x1B[32m"
#define KBLU "\x1B[34m"
#define RESET "\033[0m"
void exit_function(const char *file, const char *function, const int line, const char *s) {
int ru_id;
if (s != NULL) {
printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s);
}
oai_exit = 1;
if (RC.ru == NULL)
exit(-1); // likely init not completed, prevent crash or hang, exit now...
for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
if (RC.ru[ru_id] && RC.ru[ru_id]->rfdevice.trx_end_func) {
RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);
RC.ru[ru_id]->rfdevice.trx_end_func = NULL;
}
if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) {
RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);
RC.ru[ru_id]->ifdevice.trx_end_func = NULL;
}
}
sleep(1); //allow lte-softmodem threads to exit first
exit(1);
}
void wait_gNBs(void) {
int i;
int waiting=1;
while (waiting==1) {
printf("Waiting for gNB L1 instances to all get configured ... sleeping 50ms (nb_nr_sL1_inst %d)\n",RC.nb_nr_L1_inst);
usleep(50*1000);
waiting=0;
for (i=0; i<RC.nb_nr_L1_inst; i++) {
if (RC.gNB[i]->configured==0) {
waiting=1;
break;
}
}
}
printf("gNB L1 are configured\n");
}
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
pthread_mutex_lock(&RC.ru_mutex);
while (RC.ru_mask>0) {
pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex);
printf("RC.ru_mask:%02lx\n", RC.ru_mask);
}
pthread_mutex_unlock(&RC.ru_mutex);
LOG_I(PHY,"RUs configured\n");
}
int stop_L1L2(module_id_t gnb_id) {
return 0;
}
int restart_L1L2(module_id_t gnb_id) {
return 0;
}
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) {
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 {
LOG_I(X2AP, "X2AP is disabled.\n");
}
}
if (AMF_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0)) {
if (gnb_nb > 0) {
if (itti_create_task (TASK_NGAP, ngap_gNB_task, NULL) < 0) {
LOG_E(S1AP, "Create task for NGAP failed\n");
return -1;
}
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) {
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;
}
}
return 0;
}
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 */
NRRCConfig();
NB_gNB_INST = RC.nb_nr_inst;
NB_RU = RC.nb_RU;
printf("Configuration: nb_rrc_inst %d, nb_nr_L1_inst %d, nb_ru %hhu\n",NB_gNB_INST,RC.nb_nr_L1_inst,NB_RU);
}
}
void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[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));
config[CC_id]->ssb_config.scs_common.value = 1;
config[CC_id]->cell_config.frame_duplex_type.value = 1; //FDD
config[CC_id]->carrier_config.dl_grid_size[1].value = 106;
config[CC_id]->carrier_config.ul_grid_size[1].value = 106;
config[CC_id]->cell_config.phy_cell_id.value = 0;
}
}
/*
* helper function to terminate a certain ITTI task
*/
void terminate_task(task_id_t task_id, module_id_t mod_id) {
LOG_I(GNB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id);
MessageDef *msg;
msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE);
itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg);
}
//extern void free_transport(PHY_VARS_gNB *);
extern void nr_phy_free_RU(RU_t *);
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 ;
}
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);
}
int create_tasks_nrue(uint32_t ue_nb) {
LOG_D(ENB_APP, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb);
itti_wait_ready(1);
if (ue_nb > 0) {
printf("create TASK_RRC_NRUE\n");
if (itti_create_task (TASK_RRC_NRUE, rrc_nrue_task, NULL) < 0) {
LOG_E(RRC, "Create task for RRC UE failed\n");
return -1;
}
}
itti_wait_ready(0);
return 0;
}
void *itti_sim_ue_rrc_task( void *args_p) {
MessageDef *msg_p, *message_p;
instance_t instance;
unsigned int ue_mod_id;
int result;
itti_mark_task_ready (TASK_RRC_UE_SIM);
while(1) {
// Wait for a message
itti_receive_msg (TASK_RRC_UE_SIM, &msg_p);
instance = ITTI_MSG_INSTANCE (msg_p);
ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance);
switch (ITTI_MSG_ID(msg_p)) {
case TERMINATE_MESSAGE:
LOG_W(RRC, " *** Exiting RRC thread\n");
itti_exit_task ();
break;
case MESSAGE_TEST:
LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
break;
case GNB_RRC_BCCH_DATA_IND:
message_p = itti_alloc_new_message (TASK_RRC_NRUE, NR_RRC_MAC_BCCH_DATA_IND);
memset (NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE);
NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = GNB_RRC_BCCH_DATA_IND(msg_p).size;
memcpy (NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, GNB_RRC_BCCH_DATA_IND(msg_p).sdu, GNB_RRC_BCCH_DATA_IND(msg_p).size);
itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p);
break;
case GNB_RRC_CCCH_DATA_IND:
message_p = itti_alloc_new_message (TASK_RRC_NRUE, NR_RRC_MAC_CCCH_DATA_IND);
printf("receive GNB_RRC_CCCH_DATA_IND\n");
memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, GNB_RRC_CCCH_DATA_IND(msg_p).sdu, GNB_RRC_CCCH_DATA_IND(msg_p).size);
NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = GNB_RRC_CCCH_DATA_IND(msg_p).size;
itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p);
break;
case GNB_RRC_DCCH_DATA_IND:
printf("receive GNB_RRC_DCCH_DATA_IND\n");
message_p = itti_alloc_new_message (TASK_RRC_NRUE, NR_RRC_DCCH_DATA_IND);
NR_RRC_DCCH_DATA_IND (message_p).dcch_index = GNB_RRC_DCCH_DATA_IND(msg_p).rbid;
NR_RRC_DCCH_DATA_IND (message_p).sdu_size = GNB_RRC_DCCH_DATA_IND(msg_p).size;
memset(NR_RRC_DCCH_DATA_IND (message_p).sdu_p, 0, GNB_RRC_DCCH_DATA_IND(msg_p).size);
memcpy(NR_RRC_DCCH_DATA_IND (message_p).sdu_p, GNB_RRC_DCCH_DATA_IND(msg_p).sdu, GNB_RRC_DCCH_DATA_IND(msg_p).size);
itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p);
break;
default:
LOG_E(RRC, "[UE %d] Received unexpected message %s\n", ue_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;
}
}
void *itti_sim_gnb_rrc_task( void *args_p) {
MessageDef *msg_p, *message_p;
instance_t instance;
unsigned int ue_mod_id;
int result;
itti_mark_task_ready (TASK_RRC_GNB_SIM);
while(1) {
// Wait for a message
itti_receive_msg (TASK_RRC_GNB_SIM, &msg_p);
instance = ITTI_MSG_INSTANCE (msg_p);
ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance);
switch (ITTI_MSG_ID(msg_p)) {
case TERMINATE_MESSAGE:
LOG_W(RRC, " *** Exiting RRC thread\n");
itti_exit_task ();
break;
case MESSAGE_TEST:
LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
break;
case UE_RRC_CCCH_DATA_IND:
message_p = itti_alloc_new_message (TASK_RRC_GNB, NR_RRC_MAC_CCCH_DATA_IND);
RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = UE_RRC_CCCH_DATA_IND(msg_p).size;
memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, UE_RRC_CCCH_DATA_IND(msg_p).sdu, UE_RRC_CCCH_DATA_IND(msg_p).size);
itti_send_msg_to_task (TASK_RRC_GNB, instance, message_p);
break;
case UE_RRC_DCCH_DATA_IND:
message_p = itti_alloc_new_message (TASK_RRC_GNB, NR_RRC_DCCH_DATA_IND);
RRC_DCCH_DATA_IND (message_p).sdu_size = UE_RRC_DCCH_DATA_IND(msg_p).size;
memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, UE_RRC_DCCH_DATA_IND(msg_p).size);
memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, UE_RRC_DCCH_DATA_IND(msg_p).sdu, UE_RRC_DCCH_DATA_IND(msg_p).size);
itti_send_msg_to_task (TASK_RRC_GNB, instance, message_p);
break;
default:
LOG_E(RRC, "[UE %d] Received unexpected message %s\n", ue_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;
}
}
int main( int argc, char **argv )
{
start_background_system();
///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();
#ifdef DEBUG_CONSOLE
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
#endif
logInit();
//configure_linux();
printf("Reading in command-line options\n");
get_options ();
if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) {
fprintf(stderr,"Getting configuration failed\n");
exit(-1);
}
AMF_MODE_ENABLED = !IS_SOFTMODEM_NOS1;
#if T_TRACER
T_Config_Init();
#endif
//randominit (0);
set_taus_seed (0);
printf("configuring for RAU/RRU\n");
if (opp_enabled ==1) {
reset_opp_meas();
}
cpuf=get_cpu_freq_GHz();
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
// initialize mscgen log after ITTI
MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
init_opt();
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");
return 0;
}
if(itti_create_task (TASK_RRC_GNB_SIM, itti_sim_gnb_rrc_task, NULL) < 0){
printf("cannot create ITTI tasks\n");
exit(-1); // need a softer mode
}
openair_rrc_top_init_ue_nr("./");
if (create_tasks_nrue(1) < 0) {
printf("cannot create ITTI tasks\n");
exit(-1); // need a softer mode
}
if(itti_create_task (TASK_RRC_UE_SIM, itti_sim_ue_rrc_task, NULL) < 0){
printf("cannot create ITTI tasks\n");
exit(-1); // need a softer mode
}
pthread_cond_init(&sync_cond,NULL);
pthread_mutex_init(&sync_mutex, NULL);
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);
// wait for end of program
printf("TYPE <CTRL-C> TO TERMINATE\n");
#if 0
// test itti sim
usleep(10000);
protocol_ctxt_t ctxt;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[0]);
if(ue_context_p == NULL){
printf("ue_context_p == NULL");
}
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
0,
ENB_FLAG_YES,
0,
0,
0);
rrc_gNB_generate_RRCSetup(&ctxt,
ue_context_p,
0);
// end test itti sim
#endif
printf("Entering ITTI signals handler\n");
itti_wait_tasks_end();
printf("Returned from ITTI signal handler\n");
oai_exit=1;
printf("oai_exit=%d\n",oai_exit);
printf("stopping MODEM threads\n");
/* release memory used by the RU/gNB threads (incomplete), after all
* threads have been stopped (they partially use the same memory) */
pthread_cond_destroy(&sync_cond);
pthread_mutex_destroy(&sync_mutex);
logClean();
printf("Bye.\n");
return 0;
}
......@@ -65,6 +65,7 @@
#include "oaisim_amf_test_s1c.h"
#endif
ngap_gNB_config_t ngap_config;
static int ngap_gNB_generate_ng_setup_request(
ngap_gNB_instance_t *instance_p, ngap_gNB_amf_data_t *ngap_amf_data_p);
......
......@@ -39,6 +39,16 @@
#ifndef NGAP_GNB_H_
#define NGAP_GNB_H_
typedef struct ngap_gNB_config_s {
// MME related params
unsigned char amf_enabled; ///< AMF enabled ?
} ngap_gNB_config_t;
extern ngap_gNB_config_t ngap_config;
#define AMF_MODE_ENABLED ngap_config.amf_enabled
void *ngap_gNB_process_itti_msg(void*);
void ngap_gNB_init(void);
void *ngap_gNB_task(void *arg);
......
......@@ -1859,165 +1859,7 @@ static
int ngap_gNB_handle_ng_path_switch_request_ack(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
#if 0
ngap_gNB_amf_data_t *amf_desc_p = NULL;
ngap_gNB_ue_context_t *ue_desc_p = NULL;
MessageDef *message_p = NULL;
NGAP_PathSwitchRequestAcknowledge_t *pathSwitchRequestAcknowledge;
NGAP_PathSwitchRequestAcknowledgeIEs_t *ie;
NGAP_PDUSESSIONToBeSwitchedULItemIEs_t *ngap_PDUSESSIONToBeSwitchedULItemIEs;
NGAP_PDUSESSIONToBeSwitchedULItem_t *ngap_PDUSESSIONToBeSwitchedULItem;
NGAP_PDUSESSIONItemIEs_t *e_RABItemIEs;
NGAP_PDUSESSIONItem_t *e_RABItem;
DevAssert(pdu != NULL);
pathSwitchRequestAcknowledge = &pdu->choice.successfulOutcome->value.choice.PathSwitchRequestAcknowledge;
/* Path Switch request == UE-related procedure -> stream !=0 */
if (stream == 0) {
NGAP_ERROR("[SCTP %d] Received s1 path switch request ack on stream (%d)\n",
assoc_id, stream);
//return -1;
}
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received S1 path switch request ack for non existing "
"AMF context\n", assoc_id);
return -1;
}
// send a message to RRC
message_p = itti_alloc_new_message(TASK_NGAP, NGAP_PATH_SWITCH_REQ_ACK);
/* mandatory */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge,
NGAP_ProtocolIE_ID_id_gNB_UE_NGAP_ID, true);
if (ie == NULL) {
NGAP_ERROR("[SCTP %d] Received path switch request ack for non "
"ie context is NULL\n", assoc_id);
return -1;
}
NGAP_PATH_SWITCH_REQ_ACK(message_p).gNB_ue_ngap_id = ie->value.choice.GNB_UE_NGAP_ID;
if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance,
ie->value.choice.GNB_UE_NGAP_ID)) == NULL) {
NGAP_ERROR("[SCTP %d] Received path switch request ack for non "
"existing UE context 0x%06lx\n", assoc_id,
ie->value.choice.GNB_UE_NGAP_ID);
itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
NGAP_PATH_SWITCH_REQ_ACK(message_p).ue_initial_id = ue_desc_p->ue_initial_id;
/* mandatory */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge,
NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true);
if (ie == NULL) {
NGAP_ERROR("[SCTP %d] Received path switch request ack for non "
"ie context is NULL\n", assoc_id);
return -1;
}
NGAP_PATH_SWITCH_REQ_ACK(message_p).amf_ue_ngap_id = ie->value.choice.AMF_UE_NGAP_ID;
if ( ue_desc_p->amf_ue_ngap_id != ie->value.choice.AMF_UE_NGAP_ID) {
NGAP_WARN("UE context amf_ue_ngap_id is different form that of the message (%d != %ld)",
ue_desc_p->amf_ue_ngap_id, ie->value.choice.AMF_UE_NGAP_ID);
}
/* mandatory */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge,
NGAP_ProtocolIE_ID_id_SecurityContext, true);
if (ie == NULL) {
NGAP_ERROR("[SCTP %d] Received path switch request ack for non "
"ie context is NULL\n", assoc_id);
return -1;
}
NGAP_PATH_SWITCH_REQ_ACK(message_p).next_hop_chain_count =
ie->value.choice.SecurityContext.nextHopChainingCount;
memcpy(&NGAP_PATH_SWITCH_REQ_ACK(message_p).next_security_key,
ie->value.choice.SecurityContext.nextHopParameter.buf,
ie->value.choice.SecurityContext.nextHopParameter.size);
/* optional */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge,
NGAP_ProtocolIE_ID_id_uEaggregateMaximumBitrate, false);
if (ie) {
OCTET_STRING_TO_INT32 (
&ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL,
NGAP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul
);
OCTET_STRING_TO_INT32 (
&ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL,
NGAP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_dl
);
} else {
NGAP_WARN("UEAggregateMaximumBitrate not supported\n");
NGAP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul = 0;
NGAP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_dl = 0;
}
/* optional */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge,
NGAP_ProtocolIE_ID_id_PDUSESSIONToBeSwitchedULList, false);
if (ie) {
NGAP_PATH_SWITCH_REQ_ACK(message_p).nb_pdusessions_tobeswitched = ie->value.choice.PDUSESSIONToBeSwitchedULList.list.count;
for (int i = 0; i < ie->value.choice.PDUSESSIONToBeSwitchedULList.list.count; i++) {
ngap_PDUSESSIONToBeSwitchedULItemIEs = (NGAP_PDUSESSIONToBeSwitchedULItemIEs_t *)ie->value.choice.PDUSESSIONToBeSwitchedULList.list.array[i];
ngap_PDUSESSIONToBeSwitchedULItem = &ngap_PDUSESSIONToBeSwitchedULItemIEs->value.choice.PDUSESSIONToBeSwitchedULItem;
NGAP_PATH_SWITCH_REQ_ACK (message_p).pdusessions_tobeswitched[i].pdusession_id = ngap_PDUSESSIONToBeSwitchedULItem->e_RAB_ID;
memcpy(NGAP_PATH_SWITCH_REQ_ACK (message_p).pdusessions_tobeswitched[i].sgw_addr.buffer,
ngap_PDUSESSIONToBeSwitchedULItem->transportLayerAddress.buf, ngap_PDUSESSIONToBeSwitchedULItem->transportLayerAddress.size);
NGAP_PATH_SWITCH_REQ_ACK (message_p).pdusessions_tobeswitched[i].sgw_addr.length =
ngap_PDUSESSIONToBeSwitchedULItem->transportLayerAddress.size * 8 - ngap_PDUSESSIONToBeSwitchedULItem->transportLayerAddress.bits_unused;
OCTET_STRING_TO_INT32(&ngap_PDUSESSIONToBeSwitchedULItem->gTP_TEID,
NGAP_PATH_SWITCH_REQ_ACK (message_p).pdusessions_tobeswitched[i].gtp_teid);
}
} else {
NGAP_WARN("PDUSESSIONToBeSwitchedULList not supported\n");
NGAP_PATH_SWITCH_REQ_ACK(message_p).nb_pdusessions_tobeswitched = 0;
}
/* optional */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge,
NGAP_ProtocolIE_ID_id_PDUSESSIONToBeReleasedList, false);
if (ie) {
NGAP_PATH_SWITCH_REQ_ACK(message_p).nb_pdusessions_tobereleased = ie->value.choice.PDUSESSIONList.list.count;
for (int i = 0; i < ie->value.choice.PDUSESSIONList.list.count; i++) {
e_RABItemIEs = (NGAP_PDUSESSIONItemIEs_t *)ie->value.choice.PDUSESSIONList.list.array[i];
e_RABItem = &e_RABItemIEs->value.choice.PDUSESSIONItem;
NGAP_PATH_SWITCH_REQ_ACK (message_p).pdusessions_tobereleased[i].pdusession_id = e_RABItem->e_RAB_ID;
}
} else {
NGAP_WARN("PDUSESSIONToBeReleasedList not supported\n");
NGAP_PATH_SWITCH_REQ_ACK(message_p).nb_pdusessions_tobereleased = 0;
}
/* optional */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge,
NGAP_ProtocolIE_ID_id_CriticalityDiagnostics, false);
if(!ie) {
NGAP_WARN("Critical Diagnostic not supported\n");
}
/* optional */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge,
NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID_2, false);
if(!ie) {
NGAP_WARN("AMF_UE_NGAP_ID_2 flag not supported\n");
}
// TODO continue
itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p);
#endif
// TODO
return 0;
}
......@@ -2025,68 +1867,8 @@ static
int ngap_gNB_handle_ng_path_switch_request_failure(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
#if 0
ngap_gNB_amf_data_t *amf_desc_p = NULL;
NGAP_PathSwitchRequestFailure_t *pathSwitchRequestFailure;
NGAP_PathSwitchRequestFailureIEs_t *ie;
DevAssert(pdu != NULL);
pathSwitchRequestFailure = &pdu->choice.unsuccessfulOutcome->value.choice.PathSwitchRequestFailure;
if (stream != 0) {
NGAP_ERROR("[SCTP %d] Received s1 path switch request failure on stream != 0 (%d)\n",
assoc_id, stream);
return -1;
}
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received S1 path switch request failure for non existing "
"AMF context\n", assoc_id);
return -1;
}
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PathSwitchRequestFailureIEs_t, ie, pathSwitchRequestFailure,
NGAP_ProtocolIE_ID_id_Cause, true);
if (ie == NULL) {
NGAP_ERROR("[SCTP %d] Received S1 path switch request failure for non existing "
"ie context is NULL\n", assoc_id);
return -1;
}
switch(ie->value.choice.Cause.present) {
case NGAP_Cause_PR_NOTHING:
NGAP_WARN("Received S1 Error indication cause NOTHING\n");
break;
case NGAP_Cause_PR_radioNetwork:
NGAP_WARN("Radio Network Layer Cause Failure\n");
break;
case NGAP_Cause_PR_transport:
NGAP_WARN("Transport Layer Cause Failure\n");
break;
case NGAP_Cause_PR_nas:
NGAP_WARN("NAS Cause Failure\n");
break;
case NGAP_Cause_PR_misc:
NGAP_WARN("Miscelaneous Cause Failure\n");
break;
default:
NGAP_WARN("Received an unknown S1 Error indication cause\n");
break;
}
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PathSwitchRequestFailureIEs_t, ie, pathSwitchRequestFailure,
NGAP_ProtocolIE_ID_id_CriticalityDiagnostics, false);
if(!ie) {
NGAP_WARN("Critical Diagnostic not supported\n");
}
#endif
// TODO continue
// TODO
return 0;
}
......@@ -2095,7 +1877,7 @@ int ngap_gNB_handle_ng_ENDC_pdusession_modification_confirm(uint32_t
uint32_t stream,
NGAP_NGAP_PDU_t *pdu){
LOG_W(NGAP, "Implementation of NGAP E-RAB Modification confirm handler is pending...\n");
LOG_W(NGAP, "Implementation of NGAP Pdusession Modification confirm handler is pending...\n");
return 0;
}
......@@ -76,6 +76,7 @@ int ngap_gNB_handle_nas_first_req(
out = &pdu.choice.initiatingMessage->value.choice.InitialUEMessage;
/* Select the AMF corresponding to the provided GUAMI. */
//TODO have not be test. it's should be test
if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_guami) {
amf_desc_p = ngap_gNB_nnsf_select_amf_by_guami(
instance_p,
......@@ -97,6 +98,7 @@ int ngap_gNB_handle_nas_first_req(
if (amf_desc_p == NULL) {
/* Select the AMF corresponding to the provided s-TMSI. */
//TODO have not be test. it's should be test
if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_FiveG_s_tmsi) {
amf_desc_p = ngap_gNB_nnsf_select_amf_by_amf_setid(
instance_p,
......@@ -120,6 +122,7 @@ int ngap_gNB_handle_nas_first_req(
if (amf_desc_p == NULL) {
/* Select AMF based on the selected PLMN identity, received through RRC
* Connection Setup Complete */
//TODO have not be test. it's should be test
amf_desc_p = ngap_gNB_nnsf_select_amf_by_plmn_id(
instance_p,
ngap_nas_first_req_p->establishment_cause,
......@@ -141,6 +144,7 @@ int ngap_gNB_handle_nas_first_req(
* If no AMF corresponds to the GUAMI, the s-TMSI, or the selected PLMN
* identity, selects the AMF with the highest capacity.
*/
//TODO have not be test. it's should be test
amf_desc_p = ngap_gNB_nnsf_select_amf(
instance_p,
ngap_nas_first_req_p->establishment_cause);
......@@ -1439,237 +1443,7 @@ int ngap_gNB_path_switch_req(instance_t instance,
ngap_path_switch_req_t *path_switch_req_p)
//------------------------------------------------------------------------------
{
#if 0
ngap_gNB_instance_t *ngap_gNB_instance_p = NULL;
struct ngap_gNB_ue_context_s *ue_context_p = NULL;
struct ngap_gNB_amf_data_s *amf_desc_p = NULL;
NGAP_NGAP_PDU_t pdu;
NGAP_PathSwitchRequest_t *out;
NGAP_PathSwitchRequestIEs_t *ie;
NGAP_PDUSESSIONToBeSwitchedDLItemIEs_t *e_RABToBeSwitchedDLItemIEs;
NGAP_PDUSESSIONToBeSwitchedDLItem_t *e_RABToBeSwitchedDLItem;
uint8_t *buffer = NULL;
uint32_t length;
int ret = 0;//-1;
/* Retrieve the NGAP gNB instance associated with Mod_id */
ngap_gNB_instance_p = ngap_gNB_get_instance(instance);
DevAssert(path_switch_req_p != NULL);
DevAssert(ngap_gNB_instance_p != NULL);
//if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p,
// path_switch_req_p->gNB_ue_ngap_id)) == NULL) {
/* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */
//NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%06x\n",
// path_switch_req_p->gNB_ue_ngap_id);
//return -1;
//}
/* Uplink NAS transport can occur either during an ngap connected state
* or during initial attach (for example: NAS authentication).
*/
//if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED ||
// ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) {
//NGAP_WARN("You are attempting to send NAS data over non-connected "
// "gNB ue ngap id: %06x, current state: %d\n",
// path_switch_req_p->gNB_ue_ngap_id, ue_context_p->ue_state);
//return -1;
//}
/* Select the AMF corresponding to the provided GUAMI. */
amf_desc_p = ngap_gNB_nnsf_select_amf_by_guami_no_cause(ngap_gNB_instance_p, path_switch_req_p->ue_guami);
if (amf_desc_p == NULL) {
/*
* In case gNB has no AMF associated, the gNB should inform RRC and discard
* this request.
*/
NGAP_WARN("No AMF is associated to the gNB\n");
// TODO: Inform RRC
return -1;
}
/* The gNB should allocate a unique gNB UE NGAP ID for this UE. The value
* will be used for the duration of the connectivity.
*/
ue_context_p = ngap_gNB_allocate_new_UE_context();
DevAssert(ue_context_p != NULL);
/* Keep a reference to the selected AMF */
ue_context_p->amf_ref = amf_desc_p;
ue_context_p->ue_initial_id = path_switch_req_p->ue_initial_id;
ue_context_p->gNB_instance = ngap_gNB_instance_p;
do {
struct ngap_gNB_ue_context_s *collision_p;
/* Peek a random value for the gNB_ue_ngap_id */
ue_context_p->gNB_ue_ngap_id = (random() + random()) & 0x00ffffff;
if ((collision_p = RB_INSERT(ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head, ue_context_p))
== NULL) {
NGAP_DEBUG("Found usable gNB_ue_ngap_id: 0x%06x %u(10)\n",
ue_context_p->gNB_ue_ngap_id,
ue_context_p->gNB_ue_ngap_id);
/* Break the loop as the id is not already used by another UE */
break;
}
} while(1);
ue_context_p->amf_ue_ngap_id = path_switch_req_p->amf_ue_ngap_id;
/* Prepare the NGAP message to encode */
memset(&pdu, 0, sizeof(pdu));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_PathSwitchRequest;
pdu.choice.initiatingMessage->criticality = NGAP_Criticality_reject;
pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_PathSwitchRequest;
out = &pdu.choice.initiatingMessage->value.choice.PathSwitchRequest;
/* mandatory */
ie = (NGAP_PathSwitchRequestIEs_t *)calloc(1, sizeof(NGAP_PathSwitchRequestIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_gNB_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_PathSwitchRequestIEs__value_PR_GNB_UE_NGAP_ID;
ie->value.choice.GNB_UE_NGAP_ID = ue_context_p->gNB_ue_ngap_id;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
if (path_switch_req_p->nb_of_pdusessions > 0) {
ie = (NGAP_PathSwitchRequestIEs_t *)calloc(1, sizeof(NGAP_PathSwitchRequestIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_PDUSESSIONToBeSwitchedDLList;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_PathSwitchRequestIEs__value_PR_PDUSESSIONToBeSwitchedDLList;
for (int i = 0; i < path_switch_req_p->nb_of_pdusessions; i++) {
e_RABToBeSwitchedDLItemIEs = (NGAP_PDUSESSIONToBeSwitchedDLItemIEs_t *)calloc(1, sizeof(NGAP_PDUSESSIONToBeSwitchedDLItemIEs_t));
e_RABToBeSwitchedDLItemIEs->id = NGAP_ProtocolIE_ID_id_PDUSESSIONToBeSwitchedDLItem;
e_RABToBeSwitchedDLItemIEs->criticality = NGAP_Criticality_reject;
e_RABToBeSwitchedDLItemIEs->value.present = NGAP_PDUSESSIONToBeSwitchedDLItemIEs__value_PR_PDUSESSIONToBeSwitchedDLItem;
e_RABToBeSwitchedDLItem = &e_RABToBeSwitchedDLItemIEs->value.choice.PDUSESSIONToBeSwitchedDLItem;
e_RABToBeSwitchedDLItem->e_RAB_ID = path_switch_req_p->pdusessions_tobeswitched[i].pdusession_id;
INT32_TO_OCTET_STRING(path_switch_req_p->pdusessions_tobeswitched[i].gtp_teid, &e_RABToBeSwitchedDLItem->gTP_TEID);
e_RABToBeSwitchedDLItem->transportLayerAddress.size = path_switch_req_p->pdusessions_tobeswitched[i].gNB_addr.length;
e_RABToBeSwitchedDLItem->transportLayerAddress.bits_unused = 0;
e_RABToBeSwitchedDLItem->transportLayerAddress.buf = calloc(1,e_RABToBeSwitchedDLItem->transportLayerAddress.size);
memcpy (e_RABToBeSwitchedDLItem->transportLayerAddress.buf,
path_switch_req_p->pdusessions_tobeswitched[i].gNB_addr.buffer,
path_switch_req_p->pdusessions_tobeswitched[i].gNB_addr.length);
NGAP_DEBUG("path_switch_req: pdusession ID %ld, teid %u, enb_addr %d.%d.%d.%d, SIZE %zu\n",
e_RABToBeSwitchedDLItem->e_RAB_ID,
path_switch_req_p->pdusessions_tobeswitched[i].gtp_teid,
e_RABToBeSwitchedDLItem->transportLayerAddress.buf[0],
e_RABToBeSwitchedDLItem->transportLayerAddress.buf[1],
e_RABToBeSwitchedDLItem->transportLayerAddress.buf[2],
e_RABToBeSwitchedDLItem->transportLayerAddress.buf[3],
e_RABToBeSwitchedDLItem->transportLayerAddress.size);
ASN_SEQUENCE_ADD(&ie->value.choice.PDUSESSIONToBeSwitchedDLList.list, e_RABToBeSwitchedDLItemIEs);
}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
}
/* mandatory */
ie = (NGAP_PathSwitchRequestIEs_t *)calloc(1, sizeof(NGAP_PathSwitchRequestIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_SourceAMF_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_PathSwitchRequestIEs__value_PR_AMF_UE_NGAP_ID;
ie->value.choice.AMF_UE_NGAP_ID = path_switch_req_p->amf_ue_ngap_id;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (NGAP_PathSwitchRequestIEs_t *)calloc(1, sizeof(NGAP_PathSwitchRequestIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_EUTRAN_CGI;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_PathSwitchRequestIEs__value_PR_EUTRAN_CGI;
MACRO_GNB_ID_TO_CELL_IDENTITY(ngap_gNB_instance_p->gNB_id,
0,
&ie->value.choice.EUTRAN_CGI.cell_ID);
MCC_MNC_TO_TBCD(ngap_gNB_instance_p->mcc[0],
ngap_gNB_instance_p->mnc[0],
ngap_gNB_instance_p->mnc_digit_length[0],
&ie->value.choice.EUTRAN_CGI.pLMNidentity);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (NGAP_PathSwitchRequestIEs_t *)calloc(1, sizeof(NGAP_PathSwitchRequestIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_TAI;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_PathSwitchRequestIEs__value_PR_TAI;
/* Assuming TAI is the TAI from the cell */
INT16_TO_OCTET_STRING(ngap_gNB_instance_p->tac, &ie->value.choice.TAI.tAC);
MCC_MNC_TO_PLMNID(ngap_gNB_instance_p->mcc[0],
ngap_gNB_instance_p->mnc[0],
ngap_gNB_instance_p->mnc_digit_length[0],
&ie->value.choice.TAI.pLMNidentity);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (NGAP_PathSwitchRequestIEs_t *)calloc(1, sizeof(NGAP_PathSwitchRequestIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_UESecurityCapabilities;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_PathSwitchRequestIEs__value_PR_UESecurityCapabilities;
ENCRALG_TO_BIT_STRING(path_switch_req_p->security_capabilities.encryption_algorithms,
&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms);
INTPROTALG_TO_BIT_STRING(path_switch_req_p->security_capabilities.integrity_algorithms,
&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) {
NGAP_ERROR("Failed to encode Path Switch Req \n");
/* Encode procedure has failed... */
return -1;
}
/* Update the current NGAP UE state */
ue_context_p->ue_state = NGAP_UE_WAITING_CSR;
/* Assign a stream for this UE :
* From 3GPP 36.412 7)Transport layers:
* Within the SCTP association established between one AMF and gNB pair:
* - a single pair of stream identifiers shall be reserved for the sole use
* of NGAP elementary procedures that utilize non UE-associated signalling.
* - At least one pair of stream identifiers shall be reserved for the sole use
* of NGAP elementary procedures that utilize UE-associated signallings.
* However a few pairs (i.e. more than one) should be reserved.
* - A single UE-associated signalling shall use one SCTP stream and
* the stream should not be changed during the communication of the
* UE-associated signalling.
*/
amf_desc_p->nextstream = (amf_desc_p->nextstream + 1) % amf_desc_p->out_streams;
if ((amf_desc_p->nextstream == 0) && (amf_desc_p->out_streams > 1)) {
amf_desc_p->nextstream += 1;
}
ue_context_p->tx_stream = amf_desc_p->nextstream;
MSC_LOG_TX_MESSAGE(
MSC_NGAP_GNB,
MSC_NGAP_AMF,
(const char *)buffer,
length,
MSC_AS_TIME_FMT" E_RAN Setup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u",
0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
ue_context_p->gNB_ue_ngap_id,
path_switch_req_p->amf_ue_ngap_id);
/* UE associated signalling -> use the allocated stream */
ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance,
amf_desc_p->assoc_id, buffer,
length, ue_context_p->tx_stream);
#endif
//TODO
return 0;
}
......@@ -1679,156 +1453,7 @@ int ngap_gNB_generate_PDUSESSION_Modification_Indication(
ngap_pdusession_modification_ind_t *pdusession_modification_ind)
//-----------------------------------------------------------------------------
{
#if 0
struct ngap_gNB_ue_context_s *ue_context_p = NULL;
NGAP_NGAP_PDU_t pdu;
NGAP_PDUSESSIONModificationIndication_t *out = NULL;
NGAP_PDUSESSIONModificationIndicationIEs_t *ie = NULL;
NGAP_PDUSESSIONToBeModifiedItemBearerModInd_t *PDUSESSION_ToBeModifiedItem_BearerModInd = NULL;
NGAP_PDUSESSIONToBeModifiedItemBearerModIndIEs_t *PDUSESSION_ToBeModifiedItem_BearerModInd_IEs = NULL;
//NGAP_PDUSESSIONNotToBeModifiedItemBearerModInd_t *PDUSESSION_NotToBeModifiedItem_BearerModInd = NULL;
//NGAP_PDUSESSIONNotToBeModifiedItemBearerModIndIEs_t *PDUSESSION_NotToBeModifiedItem_BearerModInd_IEs = NULL;
ngap_gNB_instance_t *ngap_gNB_instance_p = NULL;
ngap_gNB_instance_p = ngap_gNB_get_instance(instance);
uint8_t *buffer = NULL;
uint32_t len = 0;
int ret = 0;
DevAssert(ngap_gNB_instance_p != NULL);
DevAssert(pdusession_modification_ind != NULL);
int num_pdusessions_tobemodified = pdusession_modification_ind->nb_of_pdusessions_tobemodified;
//int num_pdusessions_nottobemodified = pdusession_modification_ind->nb_of_pdusessions_nottobemodified;
//uint32_t CSG_id = 0;
//uint32_t pseudo_gtp_teid = 10;
if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p,
pdusession_modification_ind->gNB_ue_ngap_id)) == NULL) {
// The context for this gNB ue ngap id doesn't exist in the map of gNB UEs
NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%06x\n",
pdusession_modification_ind->gNB_ue_ngap_id);
return -1;
}
// Prepare the NGAP message to encode
memset(&pdu, 0, sizeof(pdu));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_PDUSESSIONModificationIndication;
pdu.choice.initiatingMessage->criticality = NGAP_Criticality_reject;
pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_PDUSESSIONModificationIndication;
out = &pdu.choice.initiatingMessage->value.choice.PDUSESSIONModificationIndication;
/* mandatory */
ie = (NGAP_PDUSESSIONModificationIndicationIEs_t *)calloc(1, sizeof(NGAP_PDUSESSIONModificationIndicationIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_PDUSESSIONModificationIndicationIEs__value_PR_AMF_UE_NGAP_ID;
ie->value.choice.AMF_UE_NGAP_ID = pdusession_modification_ind->amf_ue_ngap_id;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (NGAP_PDUSESSIONModificationIndicationIEs_t *)calloc(1, sizeof(NGAP_PDUSESSIONModificationIndicationIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_gNB_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_PDUSESSIONModificationIndicationIEs__value_PR_GNB_UE_NGAP_ID;
ie->value.choice.GNB_UE_NGAP_ID = pdusession_modification_ind->gNB_ue_ngap_id;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//E-RABs to be modified list
ie = (NGAP_PDUSESSIONModificationIndicationIEs_t *)calloc(1, sizeof(NGAP_PDUSESSIONModificationIndicationIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_PDUSESSIONToBeModifiedListBearerModInd;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_PDUSESSIONModificationIndicationIEs__value_PR_PDUSESSIONToBeModifiedListBearerModInd;
//The following two for-loops here will probably need to change. We should do a different type of search
for(int i=0; i<num_pdusessions_tobemodified; i++){
PDUSESSION_ToBeModifiedItem_BearerModInd_IEs = (NGAP_PDUSESSIONToBeModifiedItemBearerModIndIEs_t *)calloc(1,sizeof(NGAP_PDUSESSIONToBeModifiedItemBearerModIndIEs_t));
PDUSESSION_ToBeModifiedItem_BearerModInd_IEs->id = NGAP_ProtocolIE_ID_id_PDUSESSIONToBeModifiedItemBearerModInd;
PDUSESSION_ToBeModifiedItem_BearerModInd_IEs->criticality = NGAP_Criticality_reject;
PDUSESSION_ToBeModifiedItem_BearerModInd_IEs->value.present = NGAP_PDUSESSIONToBeModifiedItemBearerModIndIEs__value_PR_PDUSESSIONToBeModifiedItemBearerModInd;
PDUSESSION_ToBeModifiedItem_BearerModInd = &PDUSESSION_ToBeModifiedItem_BearerModInd_IEs->value.choice.PDUSESSIONToBeModifiedItemBearerModInd;
{
PDUSESSION_ToBeModifiedItem_BearerModInd->e_RAB_ID = pdusession_modification_ind->pdusessions_tobemodified[i].pdusession_id;
PDUSESSION_ToBeModifiedItem_BearerModInd->transportLayerAddress.size = pdusession_modification_ind->pdusessions_tobemodified[i].gNB_addr.length/8;
PDUSESSION_ToBeModifiedItem_BearerModInd->transportLayerAddress.bits_unused = pdusession_modification_ind->pdusessions_tobemodified[i].gNB_addr.length%8;
PDUSESSION_ToBeModifiedItem_BearerModInd->transportLayerAddress.buf = calloc(1, PDUSESSION_ToBeModifiedItem_BearerModInd->transportLayerAddress.size);
memcpy (PDUSESSION_ToBeModifiedItem_BearerModInd->transportLayerAddress.buf, pdusession_modification_ind->pdusessions_tobemodified[i].gNB_addr.buffer,
PDUSESSION_ToBeModifiedItem_BearerModInd->transportLayerAddress.size);
INT32_TO_OCTET_STRING(pdusession_modification_ind->pdusessions_tobemodified[i].gtp_teid, &PDUSESSION_ToBeModifiedItem_BearerModInd->dL_GTP_TEID);
}
ASN_SEQUENCE_ADD(&ie->value.choice.PDUSESSIONToBeModifiedListBearerModInd.list, PDUSESSION_ToBeModifiedItem_BearerModInd_IEs);
}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//E-RABs NOT to be modified list
/*ie = (NGAP_PDUSESSIONModificationIndicationIEs_t *)calloc(1, sizeof(NGAP_PDUSESSIONModificationIndicationIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_PDUSESSIONNotToBeModifiedListBearerModInd;
ie->criticality = NGAP_Criticality_reject;
//if(num_pdusessions_nottobemodified > 0) {
ie->value.present = NGAP_PDUSESSIONModificationIndicationIEs__value_PR_PDUSESSIONNotToBeModifiedListBearerModInd;
for(int i=0; i<num_pdusessions_tobemodified; i++){
PDUSESSION_NotToBeModifiedItem_BearerModInd_IEs = (NGAP_PDUSESSIONNotToBeModifiedItemBearerModIndIEs_t *)calloc(1,sizeof(NGAP_PDUSESSIONNotToBeModifiedItemBearerModIndIEs_t));
PDUSESSION_NotToBeModifiedItem_BearerModInd_IEs->id = NGAP_ProtocolIE_ID_id_PDUSESSIONNotToBeModifiedItemBearerModInd;
PDUSESSION_NotToBeModifiedItem_BearerModInd_IEs->criticality = NGAP_Criticality_reject;
PDUSESSION_NotToBeModifiedItem_BearerModInd_IEs->value.present = NGAP_PDUSESSIONNotToBeModifiedItemBearerModIndIEs__value_PR_PDUSESSIONNotToBeModifiedItemBearerModInd;
PDUSESSION_NotToBeModifiedItem_BearerModInd = &PDUSESSION_NotToBeModifiedItem_BearerModInd_IEs->value.choice.PDUSESSIONNotToBeModifiedItemBearerModInd;
{
PDUSESSION_NotToBeModifiedItem_BearerModInd->e_RAB_ID = 10; //pdusession_modification_ind->pdusessions_tobemodified[i].pdusession_id;
PDUSESSION_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size = pdusession_modification_ind->pdusessions_tobemodified[i].gNB_addr.length/8;
PDUSESSION_NotToBeModifiedItem_BearerModInd->transportLayerAddress.bits_unused = pdusession_modification_ind->pdusessions_tobemodified[i].gNB_addr.length%8;
PDUSESSION_NotToBeModifiedItem_BearerModInd->transportLayerAddress.buf =
calloc(1, PDUSESSION_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size);
memcpy (PDUSESSION_NotToBeModifiedItem_BearerModInd->transportLayerAddress.buf, pdusession_modification_ind->pdusessions_tobemodified[i].gNB_addr.buffer,
PDUSESSION_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size);
//INT32_TO_OCTET_STRING(pdusession_modification_ind->pdusessions_tobemodified[i].gtp_teid, &PDUSESSION_NotToBeModifiedItem_BearerModInd->dL_GTP_TEID);
INT32_TO_OCTET_STRING(pseudo_gtp_teid, &PDUSESSION_NotToBeModifiedItem_BearerModInd->dL_GTP_TEID);
}
ASN_SEQUENCE_ADD(&ie->value.choice.PDUSESSIONNotToBeModifiedListBearerModInd.list, PDUSESSION_NotToBeModifiedItem_BearerModInd_IEs);
}
// }
//else{
// ie->value.present = NGAP_PDUSESSIONModificationIndicationIEs__value_PR_PDUSESSIONNotToBeModifiedListBearerModInd;
// ie->value.choice.PDUSESSIONNotToBeModifiedListBearerModInd.list.size = 0;
// } /
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);*/
/*ie = (NGAP_PDUSESSIONModificationIndicationIEs_t *)calloc(1, sizeof(NGAP_PDUSESSIONModificationIndicationIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_CSGMembershipInfo;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_PDUSESSIONModificationIndicationIEs__value_PR_CSGMembershipInfo;
ie->value.choice.CSGMembershipInfo.cSGMembershipStatus = NGAP_CSGMembershipStatus_member;
INT32_TO_BIT_STRING(CSG_id, &ie->value.choice.CSGMembershipInfo.cSG_Id);
ie->value.choice.CSGMembershipInfo.cSG_Id.bits_unused=5;
ie->value.choice.CSGMembershipInfo.cellAccessMode = NGAP_CellAccessMode_hybrid;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);*/
if (ngap_gNB_encode_pdu(&pdu, &buffer, &len) < 0) {
NGAP_ERROR("Failed to encode S1 E-RAB modification indication \n");
return -1;
}
// Non UE-Associated signalling -> stream = 0
NGAP_INFO("Size of encoded message: %d \n", len);
ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance,
ue_context_p->amf_ref->assoc_id, buffer,
len, ue_context_p->tx_stream);
//ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, ue_context_p->amf_ref->assoc_id, buffer, len, 0);
#endif
//TODO
return 0;
}
......
......@@ -49,38 +49,7 @@ int ngap_gNB_handle_overload_start(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu)
{
#if 0
ngap_gNB_amf_data_t *amf_desc_p;
NGAP_OverloadStart_t *container;
NGAP_OverloadStartIEs_t *ie;
DevAssert(pdu != NULL);
container = &pdu->choice.initiatingMessage.value.choice.OverloadStart;
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_OverloadStartIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_OverloadResponse, true);
if (ie != NULL) {
DevCheck(ie->value.choice.OverloadResponse.present ==
NGAP_OverloadResponse_PR_overloadAction,
NGAP_OverloadResponse_PR_overloadAction, 0, 0);
}
/* Non UE-associated signalling -> stream 0 */
DevCheck(stream == 0, stream, 0, 0);
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
/* No AMF context associated */
return -1;
}
/* Mark the AMF as overloaded and set the overload state according to
* the value received.
*/
amf_desc_p->state = NGAP_GNB_OVERLOAD;
amf_desc_p->overload_state =
ie->value.choice.OverloadResponse.choice.overloadAction;
#endif
//TODO
return 0;
}
......
......@@ -50,38 +50,7 @@ int ngap_gNB_handle_trace_start(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu)
{
#if 0
NGAP_TraceStart_t *container;
NGAP_TraceStartIEs_t *ie;
struct ngap_gNB_ue_context_s *ue_desc_p = NULL;
struct ngap_gNB_amf_data_s *amf_ref_p;
DevAssert(pdu != NULL);
container = &pdu->choice.initiatingMessage.value.choice.TraceStart;
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_TraceStartIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_gNB_UE_NGAP_ID, TRUE);
amf_ref_p = ngap_gNB_get_AMF(NULL, assoc_id, 0);
DevAssert(amf_ref_p != NULL);
if (ie != NULL) {
ue_desc_p = ngap_gNB_get_ue_context(amf_ref_p->ngap_gNB_instance,
ie->value.choice.GNB_UE_NGAP_ID);
}
if (ue_desc_p == NULL) {
/* Could not find context associated with this gNB_ue_ngap_id -> generate
* trace failure indication.
*/
NGAP_E_UTRAN_Trace_ID_t trace_id;
NGAP_Cause_t cause;
memset(&trace_id, 0, sizeof(NGAP_E_UTRAN_Trace_ID_t));
memset(&cause, 0, sizeof(NGAP_Cause_t));
cause.present = NGAP_Cause_PR_radioNetwork;
cause.choice.radioNetwork = NGAP_CauseRadioNetwork_unknown_pair_ue_ngap_id;
ngap_gNB_generate_trace_failure(NULL, &trace_id, &cause);
}
#endif
//TODO
return 0;
}
......
......@@ -26,7 +26,7 @@
# ifdef OPENAIR2
#include "sctp_eNB_task.h"
#include "s1ap_eNB.h"
#include "ngap_gNB.h"
#include "nas_ue_task.h"
#include "udp_eNB_task.h"
#include "gtpv1u_eNB_task.h"
......@@ -59,7 +59,7 @@ int create_gNB_tasks(uint32_t gnb_nb)
}
if (EPC_MODE_ENABLED) {
if (AMF_MODE_ENABLED) {
if (gnb_nb > 0) {
/*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
LOG_E(SCTP, "Create task for SCTP failed\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment