diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a781499ce..116b8a55d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,27 +83,6 @@ else() include_directories(${OPENPGM_INCLUDE_DIRS}) endif() -pkg_search_module(NETTLE nettle) -if(NOT ${NETTLE_FOUND}) - message( FATAL_ERROR "PACKAGE nettle not found: some targets will fail. Run build_oai -I again!") -else() - include_directories(${NETTLE_INCLUDE_DIRS}) -endif() - -message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") - -string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) -string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) -message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") -message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") - -if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") - message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) -endif() - -add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") -add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") - pkg_search_module(XPM xpm) if(NOT ${XPM_FOUND}) message("PACKAGE xpm not found: some targets will fail") @@ -280,7 +259,7 @@ if (SANITIZE_UNDEFINED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all") endif () -add_definitions("-DASN_DISABLE_OER_SUPPORT") +add_definitions("-DASN_DISABLE_OER_SUPPORT -DHAVE_CONFIG_H -DHAVE_CONFIG_H_") ######################### set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ggdb2 -Wl,-rpath -Wl,${CMAKE_CURRENT_BINARY_DIR}") @@ -336,23 +315,19 @@ add_definitions("-DPACKAGE_BUGREPORT=\"openair4g-devel@lists.eurecom.fr\"") # Debug related options ######################################### -add_boolean_option(DEBUG_ASN1C False "ASN1 coder/decoder Debug traces, see common/utils/config.h, the logs are regular OAI logs, in the log group 'ASN'") -add_boolean_option(DISABLE_XER_PRINT False "print XER Format") -add_boolean_option(XER_PRINT False "print XER Format") -add_boolean_option(DEBUG_PDCP_PAYLOAD False "print PDCP PDU to stdout") # if true, make sure that global and PDCP log levels are trace +add_boolean_option(DEBUG_ASN1 False "ASN1 coder/decoder Debug") add_boolean_option(DEBUG_MAC_INTERFACE False "print MAC-RLC PDU exchange to stdout") # if true, make sure that global and PDCP log levels are trace -add_boolean_option(PRINT_STATS False "This adds the possibility to see the status") add_boolean_option(T_TRACER True "Activate the T tracer, a debugging/monitoring framework" ) add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs") add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace") add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace") -add_boolean_option(DEBUG_CONSOLE False "disables stdout/stderr buffering") set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti) add_library(ITTI ${OCP_ITTI}/intertask_interface.cpp ${OPENAIR_DIR}/common/utils/backtrace.c ) + target_link_libraries(ITTI PRIVATE asn1_nr_rrc asn1_lte_rrc) # asn1c skeletons have hardcoded this flag to make customized debug logs @@ -819,7 +794,6 @@ include_directories("${OPENAIR2_DIR}/UTIL/OTG") include_directories("${OPENAIR2_DIR}/UTIL/CLI") include_directories("${OPENAIR2_DIR}/UTIL/OPT") include_directories("${OPENAIR2_DIR}/UTIL/OMV") -include_directories("${OPENAIR2_DIR}/RRC/LTE/MESSAGES") include_directories("${OPENAIR_DIR}") ########### @@ -852,12 +826,17 @@ set(SECU_OSA_SRC ${OPENAIR2_DIR}/UTIL/OSA/osa_snow3g.c ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eea.c ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c - ) -add_library(SECU_OSA ${SECU_OSA_SRC}) -target_link_libraries(SECU_OSA ${NETTLE_LIBRARIES}) + ) +add_library(SECU_OSA ${SECU_OSA_SRC} $ ) + +target_include_directories(SECU_OSA PRIVATE ${OPENAIR_DIR}/common/utils/ds/) set(SECU_CN_SRC + ${OPENAIR3_DIR}/SECU/secu_defs.c ${OPENAIR3_DIR}/SECU/kdf.c + ${OPENAIR3_DIR}/SECU/aes_128_ctr.c + ${OPENAIR3_DIR}/SECU/aes_128_cbc_cmac.c + ${OPENAIR3_DIR}/SECU/sha_256_hmac.c ${OPENAIR3_DIR}/SECU/rijndael.c ${OPENAIR3_DIR}/SECU/snow3g.c ${OPENAIR3_DIR}/SECU/key_nas_deriver.c @@ -866,9 +845,9 @@ set(SECU_CN_SRC ${OPENAIR3_DIR}/SECU/nas_stream_eea2.c ${OPENAIR3_DIR}/SECU/nas_stream_eia2.c ) -add_library(SECU_CN ${SECU_CN_SRC}) -target_link_libraries(SECU_CN ${NETTLE_LIBRARIES}) +add_library(SECU_CN ${SECU_CN_SRC} $) +target_include_directories(SECU_CN PRIVATE ${OPENAIR_DIR}/common/utils/ds/) # Physical Channel Procedures Scheduling ################################" @@ -1594,6 +1573,7 @@ set (ENB_APP_SRC set (GNB_APP_SRC ${OPENAIR2_DIR}/GNB_APP/gnb_app.c + ${OPENAIR2_DIR}/E1AP/e1ap_setup.c ${OPENAIR2_DIR}/GNB_APP/gnb_config.c ) @@ -1639,7 +1619,20 @@ add_library(L2_NR ${GNB_APP_SRC} ) -target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc) +add_library(e1_if + ${NR_RRC_DIR}/cucp_cuup_direct.c + ${NR_RRC_DIR}/cucp_cuup_e1ap.c + ) + +target_link_libraries(e1_if PRIVATE asn1_nr_rrc asn1_lte_rrc asn1_f1ap e1ap GTPV1U) + +add_library(e1_pdcp_if + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_e1_api.c + ) + +target_link_libraries(e1_pdcp_if PRIVATE asn1_nr_rrc asn1_lte_rrc) + +target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap) add_library(L2_LTE_NR ${L2_RRC_SRC} @@ -1986,8 +1979,13 @@ add_library(LIB_NAS_SIMUE ${libnas_ue_esm_sap_OBJS} ${libnrnas_emm_msg_OBJS} ${libnrnas_ies_OBJS} + $ ) +target_include_directories(LIB_NAS_SIMUE PRIVATE ${OPENAIR_DIR}/common/utils/ds/) target_link_libraries(LIB_NAS_SIMUE PRIVATE lte_rrc) + + + set(NAS_SIM_LIB LIB_NAS_SIMUE) target_link_libraries(LIB_NAS_SIMUE PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2007,7 +2005,9 @@ add_library(LIB_NAS_UE ${libnas_ue_emm_sap_OBJS} ${libnas_ue_esm_OBJS} ${libnas_ue_esm_sap_OBJS} + $ ) +target_include_directories(LIB_NAS_UE PRIVATE ${OPENAIR_DIR}/common/utils/ds/) target_link_libraries(LIB_NAS_UE PRIVATE lte_rrc) set(NAS_UE_LIB LIB_NAS_UE) target_link_libraries(LIB_NAS_UE PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2039,6 +2039,8 @@ add_library(LIB_5GNAS_GNB ${NAS_SRC}/NR_UE/ue_process_nas.c ${OPENAIR3_DIR}//UICC/usim_interface.c ) + +target_include_directories(LIB_5GNAS_GNB PRIVATE ${OPENAIR_DIR}/common/utils/ds/) target_link_libraries(LIB_5GNAS_GNB PRIVATE SECU_CN ${CRYPTO_LIBRARIES}) target_link_libraries(LIB_5GNAS_GNB PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2373,11 +2375,11 @@ target_link_libraries(nr-softmodem PRIVATE UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECU_CN SECU_OSA ITTI ${RAL_LIB} ${NAS_UE_LIB} lte_rrc nr_rrc ngap s1ap L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU - x2ap f1ap m2ap m3ap + x2ap f1ap m2ap m3ap e1ap -Wl,--end-group z dl) target_link_libraries(nr-softmodem PRIVATE ${LIBXML2_LIBRARIES}) -target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${CMAKE_DL_LIBS} ${ATLAS_LIBRARIES}) +target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${CMAKE_DL_LIBS} ${ATLAS_LIBRARIES}) target_link_libraries(nr-softmodem PRIVATE ${LIB_LMS_LIBRARIES}) target_link_libraries(nr-softmodem PRIVATE ${T_LIB}) target_link_libraries(nr-softmodem PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2390,8 +2392,27 @@ endif () # force the generation of ASN.1 so that we don't need to wait during the build target_link_libraries(nr-softmodem PRIVATE - asn1_lte_rrc asn1_nr_rrc asn1_s1ap asn1_ngap asn1_m2ap asn1_m3ap asn1_x2ap asn1_f1ap asn1_lpp) + asn1_lte_rrc asn1_nr_rrc asn1_s1ap asn1_ngap asn1_m2ap asn1_m3ap asn1_x2ap asn1_f1ap asn1_lpp) +add_executable(nr-cuup + executables/nr-cuup.c + executables/softmodem-common.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${NR_RRC_DIR}/rrc_gNB_UE_context.c + ${OPENAIR2_DIR}/E1AP/e1ap_setup.c + ${NR_PDCP_SRC} + ${NR_SDAP_SRC} + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) + +target_link_libraries(nr-cuup PRIVATE + CONFIG_LIB ITTI SCTP_CLIENT + GTPV1U e1ap e1_pdcp_if f1ap + SECU_OSA SECU_CN ${OPENSSL_LIBRARIES} crypt z sctp dl pthread) +target_link_libraries(nr-cuup PRIVATE asn1_lte_rrc asn1_nr_rrc) + # nr-uesoftmodem is UE implementation ####################################### @@ -2424,7 +2445,7 @@ target_link_libraries(nr-uesoftmodem PRIVATE -Wl,--end-group z dl) target_link_libraries(nr-uesoftmodem PRIVATE ${LIBXML2_LIBRARIES}) -target_link_libraries(nr-uesoftmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${XFORMS_LIBRARIES} ${CMAKE_DL_LIBS} ${ATLAS_LIBRARIES}) +target_link_libraries(nr-uesoftmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CMAKE_DL_LIBS} ${ATLAS_LIBRARIES}) target_link_libraries(nr-uesoftmodem PRIVATE ${LIB_LMS_LIBRARIES}) target_link_libraries(nr-uesoftmodem PRIVATE ${T_LIB}) target_link_libraries(nr-uesoftmodem PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2465,7 +2486,7 @@ add_executable(rftest ${OPENAIR_DIR}/executables/softmodem-common.c ${SHLIB_LOADER_SOURCES} ) -target_link_libraries(rftest PRIVATE minimal_lib CONFIG_LIB PHY_NR_COMMON UTIL pthread dl m forms ${T_LIB} ) +target_link_libraries(rftest PRIVATE minimal_lib CONFIG_LIB PHY_NR_COMMON UTIL pthread dl m ${T_LIB} ) target_link_libraries(rftest PRIVATE asn1_lte_rrc asn1_nr_rrc) add_executable(polartest @@ -2631,14 +2652,13 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr ${OPENAIR_DIR}/common/utils/lte/ue_power.c ${OPENAIR_DIR}/common/utils/lte/prach_utils.c ${OPENAIR1_DIR}/PHY/INIT/lte_param_init.c - ${XFORMS_SOURCE} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} ${NFAPI_USER_DIR}/nfapi.c ) target_link_libraries (${myExe} PRIVATE -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_NR_COMMON PHY PHY_UE PHY_RU ITTI -Wl,--end-group - pthread m rt CONFIG_LIB ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl + pthread m rt CONFIG_LIB ${ATLAS_LIBRARIES} ${T_LIB} dl ) target_link_libraries(${myExe} PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2649,8 +2669,7 @@ endforeach(myExe) foreach(myExe s1ap secu_knas_encrypt_eia1 secu_kenb - aes128_ctr_encrypt - aes128_ctr_decrypt + aes128_ctr secu_knas_encrypt_eea2 secu_knas secu_knas_encrypt_eea1 kdf @@ -2780,6 +2799,7 @@ include (common/utils/telnetsrv/telnetsrv_CMakeLists.txt) include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt) include (${OPENAIR_DIR}/common/utils/websrv/websrv_CMakeLists.txt) +add_subdirectory(common) add_subdirectory(doc) add_subdirectory(openair2) add_subdirectory(openair3) diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa b/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa index 1d977f00d3..43d6372a33 100644 --- a/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa +++ b/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa @@ -376,19 +376,6 @@ pipeline { } } } - stage ("Result Update"){ - when { - expression { params.DataBaseHost != "none" } - } - agent {label DataBaseHost} - steps { - script { - dir ('ci-scripts/ran_dashboard') { - sh "python3 Hdashboard.py testevent ${params.eNB_MR} " - } - } - } - } } } } diff --git a/ci-scripts/cls_cluster.py b/ci-scripts/cls_cluster.py index 2096404204..487e203d36 100644 --- a/ci-scripts/cls_cluster.py +++ b/ci-scripts/cls_cluster.py @@ -230,6 +230,14 @@ class Cluster: HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_PROJECT_FAIL) return False + # delete old images by Sagar Arora : + # 1. retrieve all images and their timestamp + # 2. awk retrieves those whose timestamp is older than 4 weeks + # 3. issue delete command on corresponding istags (the images are dangling and will be cleaned by the registry) + delete_cmd = "oc get istag -o go-template --template '{{range .items}}{{.metadata.name}} {{.metadata.creationTimestamp}}{{\"\\n\"}}{{end}}' | awk '$2 <= \"'$(date -d '-4weeks' -Ins --utc | sed 's/+0000/Z/')'\" { print $1 }' | xargs --no-run-if-empty oc delete istag" + response = self.cmd.run(delete_cmd) + logging.debug(f"deleted images:\n{response.stdout}") + self._recreate_entitlements() status = True # flag to abandon compiling if any image fails diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index e02d208945..324e718ba1 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -360,6 +360,7 @@ class Containerize(): if result is not None: imageNames.append(('oai-enb', 'eNB')) imageNames.append(('oai-gnb', 'gNB')) + imageNames.append(('oai-nr-cuup', 'nr-cuup')) imageNames.append(('oai-lte-ue', 'lteUE')) imageNames.append(('oai-nr-ue', 'nrUE')) if self.host == 'Red Hat': @@ -680,7 +681,7 @@ class Containerize(): orgTag = 'develop' if self.ranAllowMerge: orgTag = 'ci-temp' - imageNames = ['oai-enb', 'oai-gnb', 'oai-lte-ue', 'oai-nr-ue', 'oai-lte-ru'] + imageNames = ['oai-enb', 'oai-gnb', 'oai-lte-ue', 'oai-nr-ue', 'oai-lte-ru', 'oai-nr-cuup'] for image in imageNames: tagToUse = self.ImageTagToUse(image) mySSH.command(f'docker image tag {image}:{orgTag} {tagToUse}', '\$', 5) @@ -814,7 +815,7 @@ class Containerize(): else: logging.debug('Removing test images locally') - imageNames = ['oai-enb', 'oai-gnb', 'oai-lte-ue', 'oai-nr-ue', 'oai-lte-ru'] + imageNames = ['oai-enb', 'oai-gnb', 'oai-lte-ue', 'oai-nr-ue', 'oai-lte-ru', 'oai-nr-cuup'] for image in imageNames: cmd = f'docker rmi {self.ImageTagToUse(image)} || true' if lIpAddr != 'none': @@ -856,7 +857,7 @@ class Containerize(): mySSH.command('cd ' + lSourcePath + '/' + self.yamlPath[self.eNB_instance], '\$', 5) mySSH.command('cp docker-compose.yml ci-docker-compose.yml', '\$', 5) - imagesList = ['oai-enb', 'oai-gnb'] + imagesList = ['oai-enb', 'oai-gnb', 'oai-nr-cuup'] for image in imagesList: imageToUse = self.ImageTagToUse(image) mySSH.command(f'sed -i -e "s#image: {image}:latest#image: {imageToUse}#" ci-docker-compose.yml', '\$', 2) @@ -1066,7 +1067,7 @@ class Containerize(): cmd = 'cd ' + self.yamlPath[0] + ' && cp docker-compose.y*ml docker-compose-ci.yml' subprocess.run(cmd, shell=True) - imageNames = ['oai-enb', 'oai-gnb', 'oai-lte-ue', 'oai-nr-ue', 'oai-lte-ru'] + imageNames = ['oai-enb', 'oai-gnb', 'oai-lte-ue', 'oai-nr-ue', 'oai-lte-ru', 'oai-nr-cuup'] for image in imageNames: tagToUse = self.ImageTagToUse(image) cmd = f'cd {self.yamlPath[0]} && sed -i -e "s@{image}:develop@{tagToUse}@" docker-compose-ci.yml' @@ -1160,18 +1161,9 @@ class Containerize(): def CaptureOnDockerNetworks(self): cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml config | grep com.docker.network.bridge.name | sed -e "s@^.*name: @@"' networkNames = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) - if re.search('4g.*rfsimulator', self.yamlPath[0]) is not None: - # Excluding any traffic from LTE-UE container (192.168.61.30) - # From the trf-gen, keeping only PING traffic - cmd = 'sudo nohup tshark -f "(host 192.168.61.11 and icmp) or (not host 192.168.61.11 and not host 192.168.61.30 and not arp and not port 53 and not port 2152)"' - elif re.search('5g.*rfsimulator', self.yamlPath[0]) is not None: - # Excluding any traffic from NR-UE containers (192.168.71.150 and 192.168.71.151) - # From the ext-dn, keeping only PING traffic - cmd = 'sudo nohup tshark -f "(host 192.168.72.135 and icmp) or (not host 192.168.72.135 and not host 192.168.71.150 and not host 192.168.71.151 and not arp and not port 53 and not port 2152 and not port 2153)"' - elif re.search('5g_l2sim', self.yamlPath[0]) is not None: - cmd = 'sudo nohup tshark -f "(host 192.168.72.135 and icmp) or (not host 192.168.72.135 and not arp and not port 53 and not port 2152 and not port 2153)"' - else: - return + + # Allow only: control plane RAN (SCTP), HTTP of control in CN (port 80), PFCP traffic (port 8805), MySQL (port 3306) + cmd = 'sudo nohup tshark -f "sctp or port 80 or port 8805 or icmp or port 3306"' for name in networkNames.split('\n'): if re.search('rfsim', name) is not None or re.search('l2sim', name) is not None: cmd += ' -i ' + name @@ -1190,7 +1182,7 @@ class Containerize(): cmd = 'cd ' + self.yamlPath[0] + ' && cp docker-compose.y*ml docker-compose-ci.yml' logging.info(cmd) subprocess.run(cmd, shell=True) - imageNames = ['oai-enb', 'oai-gnb', 'oai-lte-ue', 'oai-nr-ue', 'oai-lte-ru'] + imageNames = ['oai-enb', 'oai-gnb', 'oai-lte-ue', 'oai-nr-ue', 'oai-lte-ru', 'oai-nr-cuup'] for image in imageNames: tagToUse = self.ImageTagToUse(image) cmd = f'cd {self.yamlPath[0]} && sed -i -e "s@{image}:develop@{tagToUse}@" docker-compose-ci.yml' diff --git a/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf b/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf index 354a1eb076..491201426b 100644 --- a/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf +++ b/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf @@ -23,12 +23,6 @@ gNBs = min_rxtxtime = 6; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 12; - searchSpaceZero = 0; - } - ); servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/episci/gnb_band78.sa.fr1.106PRB.2x2.l2sim.conf b/ci-scripts/conf_files/episci/gnb_band78.sa.fr1.106PRB.2x2.l2sim.conf index 71bb34cb31..38b1cbfa40 100644 --- a/ci-scripts/conf_files/episci/gnb_band78.sa.fr1.106PRB.2x2.l2sim.conf +++ b/ci-scripts/conf_files/episci/gnb_band78.sa.fr1.106PRB.2x2.l2sim.conf @@ -21,12 +21,6 @@ gNBs = pusch_AntennaPorts = 2; do_CSIRS = 1; min_rxtxtime = 6; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 12; - searchSpaceZero = 0; - } - ); servingCellConfigCommon = ( { diff --git a/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf index 20b0d3caf7..669558f69c 100644 --- a/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf @@ -19,13 +19,6 @@ gNBs = min_rxtxtime = 6; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 12; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/gNB_SA_CU.conf b/ci-scripts/conf_files/gNB_SA_CU.conf index a5036e354d..9910e761b2 100644 --- a/ci-scripts/conf_files/gNB_SA_CU.conf +++ b/ci-scripts/conf_files/gNB_SA_CU.conf @@ -32,13 +32,6 @@ gNBs = remote_s_portd = 2152; min_rxtxtime = 6; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 12; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/gNB_SA_DU.conf b/ci-scripts/conf_files/gNB_SA_DU.conf index ca5aba10c0..b554326c91 100644 --- a/ci-scripts/conf_files/gNB_SA_DU.conf +++ b/ci-scripts/conf_files/gNB_SA_DU.conf @@ -24,13 +24,6 @@ gNBs = min_rxtxtime = 6; force_256qam_off = 1; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 12; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf index e28eab1fb6..4c68ea1f94 100644 --- a/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf +++ b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf @@ -26,13 +26,6 @@ gNBs = pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 11; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf index 0902eebaeb..7a474f3bb4 100644 --- a/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf +++ b/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf @@ -27,13 +27,6 @@ gNBs = pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 10; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/gnb-cucp.sa.f1.conf b/ci-scripts/conf_files/gnb-cucp.sa.f1.conf new file mode 100644 index 0000000000..62063030bd --- /dev/null +++ b/ci-scripts/conf_files/gnb-cucp.sa.f1.conf @@ -0,0 +1,228 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; +Num_Threads_PUSCH = 8; +sa = 1; + +gNBs = +( + { + ////////// Identification parameters: + gNB_CU_ID = 0xe00; + +# cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) }); + + + nr_cellid = 12345678L; + force_256qam_off = 1; + + tr_s_preference = "f1"; + + local_s_if_name = "lo"; + local_s_address = "192.168.72.140"; + remote_s_address = "192.168.72.143"; + local_s_portc = 501; + local_s_portd = 2152; + remote_s_portc = 500; + remote_s_portd = 2152; + ssb_SubcarrierOffset = 0; + min_rxtxtime = 6; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641280; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640008; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952 +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 11; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 28875; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -96; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + } + + ); + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ( { ipv4 = "192.168.71.132"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + E1_INTERFACE = + ( + { + type = "cp"; + ipv4_cucp = "192.168.72.140"; + port_cucp = 38462; + ipv4_cuup = "192.168.72.141"; + port_cuup = 38462; + } + ) + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/24"; + }; + } +); + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + log_config : + { + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="debug"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + f1ap_log_level ="debug"; + ngap_log_level ="debug"; + }; + diff --git a/ci-scripts/conf_files/gnb-cuup.sa.f1.conf b/ci-scripts/conf_files/gnb-cuup.sa.f1.conf new file mode 100644 index 0000000000..2a57a37273 --- /dev/null +++ b/ci-scripts/conf_files/gnb-cuup.sa.f1.conf @@ -0,0 +1,87 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; +sa = 1; + +gNBs = +( + { + ////////// Identification parameters: + gNB_CU_ID = 0xe00; + +# cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) }); + + + tr_s_preference = "f1"; + + local_s_if_name = "lo"; + local_s_address = "192.168.72.141"; + remote_s_address = "192.168.72.142"; + local_s_portc = 501; + local_s_portd = 2152; + remote_s_portc = 500; + remote_s_portd = 2152; + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + E1_INTERFACE = + ( + { + type = "up"; + ipv4_cucp = "192.168.72.140"; + ipv4_cuup = "192.168.72.141"; + } + ) + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.141/24"; + GNB_INTERFACE_NAME_FOR_NGU = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.141/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + log_config : + { + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="debug"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + f1ap_log_level ="debug"; + ngap_log_level ="debug"; + }; + diff --git a/ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf b/ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf new file mode 100644 index 0000000000..7f6f6c949d --- /dev/null +++ b/ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf @@ -0,0 +1,238 @@ +Active_gNBs = ( "du-rfsim"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + +# cell_type = "CELL_MACRO_GNB"; + + gNB_name = "du-rfsim"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) }); + + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + min_rxtxtime = 6; + force_256qam_off = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641280; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640008; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952 +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 28875; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -96; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "f1"; + local_n_if_name = "eth0"; + local_n_address = "192.168.72.142"; + remote_n_address = "192.168.72.140"; + local_n_portc = 500; + local_n_portd = 2152; + remote_n_portc = 501; + remote_n_portd = 2152; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; + } +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 200; + pucch0_dtx_threshold = 150; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 +} +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + clock_src = "internal"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +rfsimulator: { + serveraddr = "server"; + serverport = "4043"; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs" +} + +log_config : +{ + global_log_level = "info"; + hw_log_level = "info"; + nr_phy_log_level = "info"; + nr_mac_log_level = "info"; + rlc_log_level = "info"; + pdcp_log_level = "info"; + rrc_log_level = "info"; + f1ap_log_level = "debug"; + ngap_log_level = "debug"; +}; diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf index 16ae7a7afc..6f8c53e681 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf @@ -29,13 +29,6 @@ gNBs = do_SRS = 0; do_CSIRS = 1; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 11; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf index 0d4289ab80..a78fa953c1 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf @@ -27,13 +27,6 @@ gNBs = pusch_AntennaPorts = 2; do_SRS = 0; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 11; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.ddsuu.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.ddsuu.2x2.usrpn310.conf index 87445e2b68..92e1ca573f 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.ddsuu.2x2.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.ddsuu.2x2.usrpn310.conf @@ -27,13 +27,6 @@ gNBs = ul_prbblacklist = "51,52,53,54" do_SRS = 0; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 11; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf index 53adb4eae1..cc363e215f 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf @@ -29,13 +29,6 @@ gNBs = min_rxtxtime = 6; do_SRS = 1; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 11; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf index 99add7d367..d83770c852 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf @@ -30,13 +30,6 @@ gNBs = ul_prbblacklist = "79,80,81,82" do_SRS = 0; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 11; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf index 92362ebdc9..b8d2b8c34a 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -46,9 +46,6 @@ gNBs = # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; - #pdcch-ConfigCommon - initialDLBWPcontrolResourceSetZero = 0; - initialDLBWPsearchSpaceZero = 0; #uplinkConfigCommon #frequencyInfoUL diff --git a/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf index d45f9bfd62..73c265c955 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf @@ -20,13 +20,6 @@ gNBs = min_rxtxtime = 6; enable_sdap = 1; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 12; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/gnb.sa.band78.fr1.24PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.sa.band78.fr1.24PRB.usrpb210.conf index 6419dedf43..7cae9a9500 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.fr1.24PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.fr1.24PRB.usrpb210.conf @@ -20,13 +20,6 @@ gNBs = sib1_tda = 15; min_rxtxtime = 6; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 2; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/gnb.sa.band78.fr1.51PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.sa.band78.fr1.51PRB.usrpb210.conf index 6080ac58aa..6e012b5098 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.fr1.51PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.fr1.51PRB.usrpb210.conf @@ -20,13 +20,6 @@ gNBs = do_CSIRS = 0; do_SRS = 0; - pdcch_ConfigSIB1 = ( - { - controlResourceSetZero = 12; - searchSpaceZero = 0; - } - ); - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/ran_dashboard/Hdashboard.py b/ci-scripts/ran_dashboard/Hdashboard.py index bfa07557bd..625baa8f46 100644 --- a/ci-scripts/ran_dashboard/Hdashboard.py +++ b/ci-scripts/ran_dashboard/Hdashboard.py @@ -32,488 +32,34 @@ #Author Remi -import boto3 import shlex import subprocess import json #json structures -import datetime #now() and date formating -from datetime import datetime -import re import gitlab -import yaml -import os -import time import sys -from sqlconnect import SQLConnect - #----------------------------------------------------------- # Class Declaration #----------------------------------------------------------- class Dashboard: def __init__(self): - - - #init with data sources : git, yaml config file, test results databases + #init with data sources : git, test results databases print("Collecting Data") cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """ self.git = self.__getGitData(cmd) #git data from Gitlab - self.tests = self.__loadCfg('ran_dashboard_cfg.yaml') #tests table setup from yaml - self.db = self.__loadFromDB() #test results from database self.mr_list=[] #mr list in string format for x in range(len(self.git)): self.mr_list.append(str(self.git[x]['iid'])) - def __loadCfg(self,yaml_file): - with open(yaml_file,'r') as f: - tests = yaml.load(f) - return tests - def __getGitData(self,cmd): - #cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """ process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE) output = process.stdout.readline() tmp=output.decode("utf-8") d = json.loads(tmp) return d - def __loadFromDB(self): - mr_list=[] - for x in range(len(self.git)): - mr_list.append(str(self.git[x]['iid'])) - mydb=SQLConnect() - for MR in mr_list: - mydb.get(MR) - mydb.close_connection() - return mydb.data - - def singleMR_initHTML(self, date): - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('Test Dashboard\n') - self.f_html.write('\n') - self.f_html.write('
\n') - self.f_html.write('
\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('
OAI RAN TEST Status Dashboard
Update : '+date+'
\n') - self.f_html.write('
\n') - self.f_html.write('
\n') - - - def Test_initHTML(self, date): - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('Test Dashboard\n') - self.f_html.write('\n') - self.f_html.write('
\n') - self.f_html.write('
\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('
OAI RAN TEST Status Dashboard
Update : '+date+'
\n') - self.f_html.write('
\n') - self.f_html.write('
\n') - - def Test_terminateHTML(self): - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.close() - - - def MR_initHTML(self,date): - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('MR Dashboard\n') - self.f_html.write('\n') - self.f_html.write('
\n') - self.f_html.write('
\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('
OAI RAN MR Status Dashboard
Update : '+date+'
\n') - self.f_html.write('
\n') - self.f_html.write('
\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - - def MR_terminateHTML(self): - self.f_html.write('
MRCreated_AtAuthorTitleAssigneeReviewerCAN STARTIN PROGRESSCOMPLETEDReview FormOK MergeMerge Conflicts
\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.close() - - - def MR_rowHTML(self,row): - self.f_html.write('\n') - self.f_html.write(''+row[1]+'\n') - self.f_html.write(''+row[2]+'\n') - self.f_html.write(''+row[3]+'\n') - self.f_html.write(''+row[4]+'\n') - self.f_html.write(''+row[5]+'\n') - self.f_html.write(''+row[6]+'\n') - if row[7]=='X': - self.f_html.write(''+row[7]+'\n') - else: - self.f_html.write('\n') - if row[8]=='X': - self.f_html.write(''+row[8]+'\n') - else: - self.f_html.write('\n') - if row[9]=='X': - self.f_html.write(''+row[9]+'\n') - else: - self.f_html.write('\n') - if row[10]=='X': - self.f_html.write(''+row[10]+'\n') - else: - self.f_html.write('\n') - if row[11]=='X': - self.f_html.write(''+row[11]+'\n') - else: - self.f_html.write('\n') - if row[12]=='YES': - self.f_html.write(''+row[12]+'\n') - else: - self.f_html.write('\n') - self.f_html.write('\n') - - - def Build(self, type, mr, htmlfilename): - if type=='MR': - self.Build_MR_Table(htmlfilename) - elif type=='Tests': - self.Build_Test_Table(htmlfilename) - elif type=='singleMR': - self.Build_singleMR_Table(mr,htmlfilename) - else : - print("Undefined Dashboard Type, options : MR or Tests") - - - def Build_Test_Table(self,htmlfilename): - print("Building Tests Dashboard...") - - self.f_html=open(htmlfilename,'w') - - ###update date/time, format dd/mm/YY H:M:S - now = datetime.now() - dt_string = now.strftime("%d/%m/%Y %H:%M") - #HTML table header - self.Test_initHTML(dt_string) - - - #1 table per MR if test results exist - for x in range(len(self.git)): - mr=str(self.git[x]['iid']) - if 'PASS' not in self.db[mr]: - self.f_html.write('

'+mr+''+' '+self.git[x]['title'] + '

\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write(' \n') - self.f_html.write(' \n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - - #parsing the tests - for t in self.tests: - - row=[] - short_name= t - hyperlink= self.tests[t]['link'] - job=self.tests[t]['job'] - - - if job in self.db[mr]: - if 'PASS' in self.db[mr][job]: - row.append(self.db[mr][job]['PASS']) - else: - row.append('') - if 'FAIL' in self.db[mr][job]: - row.append(self.db[mr][job]['FAIL']) - else: - row.append('') - #2 columns for last_pass and last_fail links - if 'last_pass' in self.db[mr][job]: - lastpasshyperlink= self.db[mr][job]['last_pass'][1] - lastpasstext= self.db[mr][job]['last_pass'][0] - else: - lastpasshyperlink='' - lastpasstext='' - - if 'last_fail' in self.db[mr][job]: - lastfailhyperlink= self.db[mr][job]['last_fail'][1] - lastfailtext= self.db[mr][job]['last_fail'][0] - else: - lastfailhyperlink='' - lastfailtext='' - - - - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - if row[0]!='': - self.f_html.write('\n') - else: - self.f_html.write('\n') - if row[1]!='': - self.f_html.write('\n') - else: - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - - self.f_html.write('
Test NameBenchTest# Pass# FailLast PassLast Fail
'+short_name+''+self.tests[t]['bench']+''+self.tests[t]['test']+''+str(row[0])+''+str(row[1])+''+lastpasstext+''+lastfailtext+'
\n') - - #terminate HTML table and close file - self.Test_terminateHTML() - - - def Build_singleMR_Table(self,singlemr,htmlfilename): - print("Building single MR Tests Results...") - - self.f_html=open(htmlfilename,'w') - - ###update date/time, format dd/mm/YY H:M:S - now = datetime.now() - dt_string = now.strftime("%d/%m/%Y %H:%M") - #HTML table header - self.singleMR_initHTML(dt_string) - - - #1 table per MR if test results exist => 1 table for matching mr - for x in range(len(self.git)): - mr=str(self.git[x]['iid']) - if mr==singlemr: - #if 'PASS' not in self.db[mr]: - self.f_html.write('

'+mr+''+' '+self.git[x]['title'] + '

\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write(' \n') - self.f_html.write(' \n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - - #parsing the tests - for t in self.tests: - - row=[] - short_name= t - hyperlink= self.tests[t]['link'] - job=self.tests[t]['job'] - - - if job in self.db[mr]: - if 'PASS' in self.db[mr][job]: - row.append(self.db[mr][job]['PASS']) - else: - row.append('') - if 'FAIL' in self.db[mr][job]: - row.append(self.db[mr][job]['FAIL']) - else: - row.append('') - #2 columns for last_pass and last_fail links - if 'last_pass' in self.db[mr][job]: - lastpasshyperlink= self.db[mr][job]['last_pass'][1] - lastpasstext= self.db[mr][job]['last_pass'][0] - else: - lastpasshyperlink='' - lastpasstext='' - - if 'last_fail' in self.db[mr][job]: - lastfailhyperlink= self.db[mr][job]['last_fail'][1] - lastfailtext= self.db[mr][job]['last_fail'][0] - else: - lastfailhyperlink='' - lastfailtext='' - - - - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - if row[0]!='': - self.f_html.write('\n') - else: - self.f_html.write('\n') - if row[1]!='': - self.f_html.write('\n') - else: - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - self.f_html.write('\n') - - self.f_html.write('
Test NameBenchTest# Pass# FailLast PassLast Fail
'+short_name+''+self.tests[t]['bench']+''+self.tests[t]['test']+''+str(row[0])+''+str(row[1])+''+lastpasstext+''+lastfailtext+'
\n') - - #terminate HTML table and close file - self.Test_terminateHTML() - - - - def Build_MR_Table(self,htmlfilename): - - print("Building Merge Requests Dashboard...") - - self.f_html=open(htmlfilename,'w') - - ###update date/time, format dd/mm/YY H:M:S - now = datetime.now() - dt_string = now.strftime("%d/%m/%Y %H:%M") - - #HTML table header - self.MR_initHTML(dt_string) - - - ###MR data lines - for x in range(len(self.git)): - - - hyperlink= 'https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/'+ str(self.git[x]['iid']) - text= str(self.git[x]['iid']) - - - date_time_str = self.git[x]['created_at'] - date_time_obj = datetime.strptime(date_time_str, '%Y-%m-%dT%H:%M:%S.%fZ') - - milestone1=milestone2=milestone3=milestone4="" - if self.git[x]['milestone']!=None: - if self.git[x]['milestone']['title']=="REVIEW_CAN_START": - milestone1="X" - elif self.git[x]['milestone']['title']=="REVIEW_IN_PROGRESS": - milestone2="X" - elif self.git[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED": - milestone3="X" - elif self.git[x]['milestone']['title']=="OK_TO_BE_MERGED": - milestone4="X" - else: - pass - else: - pass - - #check if empty or not - if self.git[x]['assignee']!=None: - assignee = str(self.git[x]['assignee']['name']) - else: - assignee = "" - - #check if empty or not - if len(self.git[x]['reviewers'])!=0: - reviewer = str(self.git[x]['reviewers'][0]['name']) - else: - reviewer = "" - - if self.git[x]['has_conflicts']==True: - conflicts = "YES" - else: - conflicts = "" - - - #add a column flagging that the review form is present - #we use gitlab API to parse the MR notes - gl = gitlab.Gitlab.from_config('OAI') - project_id = 223 - project = gl.projects.get(project_id) - #get the opened MR in the project - mrs = project.mergerequests.list(state='opened',per_page=100) - review_form='' - for m in range (0,len(mrs)): - if mrs[m].iid==self.git[x]['iid']:#check the iid is the one we are on - mr_notes = mrs[m].notes.list(all=True) - n=0 - found=False - while found==False and n1: + if len(sys.argv) > 1: #individual MR test results + test dashboard, event based (end of slave jenkins pipeline) - if sys.argv[1]=="testevent" : - mr=sys.argv[2] - htmlDash=Dashboard() - if mr in htmlDash.mr_list: - #single MR test results - htmlDash.Build('singleMR',mr,'/tmp/MR'+mr+'_index.html') - htmlDash.CopyToS3('/tmp/MR'+mr+'_index.html','oaitestdashboard','MR'+mr+'/index.html') - #all MR test results - htmlDash.Build('Tests','0000','/tmp/Tests_index.html') - htmlDash.CopyToS3('/tmp/Tests_index.html','oaitestdashboard','index.html') + if sys.argv[1] != "gitpost": + print("error: only gitpost subcommand is supported") + exit(1) - #git post with MR test results, event based (end of master jenkins pipeline) elif sys.argv[1]=="gitpost": mr=sys.argv[2] commit=sys.argv[3] @@ -603,25 +111,15 @@ def main(): htmlDash.PostGitNote(mr,commit, args) else: print("Not a Merge Request => this build is for testing/debug purpose, no report to git") - elif sys.argv[1]=="awsclean": - mode=sys.argv[2]#report or delete - htmlDash=Dashboard() - htmlDash.AWSCleanup(mode) else: print("Wrong argument at position 1") + exit(1) #test and MR status dashboards, cron based else: - htmlDash=Dashboard() - #all MR status dashboard - htmlDash.Build('MR','0000','/tmp/MR_index.html') - htmlDash.CopyToS3('/tmp/MR_index.html','oairandashboard','index.html') - #all MR test results - htmlDash.Build('Tests','0000','/tmp/Tests_index.html') - htmlDash.CopyToS3('/tmp/Tests_index.html','oaitestdashboard','index.html') - - + print("error: only gitpost subcommand is supported") + exit(1) if __name__ == "__main__": # execute only if run as a script diff --git a/ci-scripts/ran_dashboard/mr_styles.css b/ci-scripts/ran_dashboard/mr_styles.css deleted file mode 100755 index 5d938669cb..0000000000 --- a/ci-scripts/ran_dashboard/mr_styles.css +++ /dev/null @@ -1,136 +0,0 @@ -body { - font-family: 'lato', sans-serif; - } - - -.Main { - text-align:left; - font-size: 30px; - font-weight: bold; -} - -.DashLink { - text-align:left; - font-size: 16px; -} - -.DashLink:hover { - font-weight: bold; -} - -.Date { - text-align:left; - font-size: 16px; - font-weight: bold; -} - - -a { text-decoration: none; } -a:visited { text-decoration: none; color:blue} -a:hover { text-decoration: none; font-weight: bold; color:blue} - - -.MR_Table { - border-collapse: collapse; -} - -.MR_Table tr { - font-size: 12px; - text-align:center; -} - - -.MR_Table tr:hover { - background-color:lightgray; -} - -.MR_Table td { - border: 1px solid black; - padding : 5px; -} -.MR_Table td:hover { -font-weight : bold; -} - -.MR_Table th { - font-size: 14px; - text-align:center; - padding : 5px; -} - - -.title_cell { - text-align:left; -} - - -.MR { - table-layout: fixed; - width: 50px; - background-color: rgb(143, 154, 216); -} - -.CREATED_AT { - table-layout: fixed; - width: 100px; - background-color: rgb(143, 154, 216); -} - -.AUTHOR { - table-layout: fixed; - width: 150px; - background-color: rgb(143, 154, 216); -} - -.TITLE { - table-layout: fixed; - width: 500px; - background-color: rgb(143, 154, 216); -} - -.ASSIGNEE { - table-layout: fixed; - width: 150px; - background-color: rgb(143, 154, 216); -} - -.REVIEWER { - table-layout: fixed; - width: 150px; - background-color: rgb(143, 154, 216); -} - -.CAN_START { - background-color: orange; - table-layout: fixed; - width: 150px; -} -.IN_PROGRESS { - background-color: yellow; - table-layout: fixed; - width: 150px; -} -.COMPLETED { - background-color: rgb(144, 221, 231); - table-layout: fixed; - width: 150px; -} - -.REVIEW_FORM { - table-layout: fixed; - width: 100px; - background-color: rgb(143, 154, 216); -} - -.OK_MERGE { - background-color: rgb(58, 236, 58); - table-layout: fixed; - width: 150px; -} - -.MERGE_CONFLICTS { - table-layout: fixed; - width: 100px; - background-color: rgb(143, 154, 216); -} - diff --git a/ci-scripts/ran_dashboard/ran_dashboard.py b/ci-scripts/ran_dashboard/ran_dashboard.py deleted file mode 100644 index 54a98ec878..0000000000 --- a/ci-scripts/ran_dashboard/ran_dashboard.py +++ /dev/null @@ -1,405 +0,0 @@ -#/* -# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -# * contributor license agreements. See the NOTICE file distributed with -# * this work for additional information regarding copyright ownership. -# * The OpenAirInterface Software Alliance licenses this file to You under -# * the OAI Public License, Version 1.1 (the "License"); you may not use this file -# * except in compliance with the License. -# * You may obtain a copy of the License at -# * -# * http://www.openairinterface.org/?page_id=698 -# * -# * Unless required by applicable law or agreed to in writing, software -# * distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. -# *------------------------------------------------------------------------------- -# * For more information about the OpenAirInterface (OAI) Software Alliance: -# * contact@openairinterface.org -# */ -#--------------------------------------------------------------------- -# Merge Requests Dashboard for RAN on googleSheet -# -# Required Python Version -# Python 3.x -# -#--------------------------------------------------------------------- - -#----------------------------------------------------------- -# Import -#----------------------------------------------------------- - -#author Remi - -#import google spreadsheet API -import gspread -from oauth2client.service_account import ServiceAccountCredentials - - -import subprocess -import shlex #lexical analysis -import json #json structures -import datetime #now() and date formating -from datetime import datetime -import re -import gitlab -import yaml -import os -import pickle -import time - - -from sqlconnect import SQLConnect - -#----------------------------------------------------------- -# Class Declaration -#----------------------------------------------------------- - -class gDashboard: - def __init__(self, creds_file, spreadsheet, worksheet): #"creds.json", 'OAI RAN Dashboard', 'MR Status' - self.scope = ["https://spreadsheets.google.com/feeds",'https://www.googleapis.com/auth/spreadsheets',"https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/drive"] - self.creds = ServiceAccountCredentials.from_json_keyfile_name(creds_file, self.scope) - self.client = gspread.authorize(self.creds) - #spreadsheet - self.ss = self.client.open(spreadsheet) - #worksheet - self.sheet = self.ss.worksheet(worksheet) - self.ss.del_worksheet(self.sheet) #start by deleting the old sheet - self.sheet = self.ss.add_worksheet(title=worksheet, rows="100", cols="30") #create a new one - - #init with data sources : git, yaml config file, test results databases - cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """ - self.git = self.__getGitData(cmd) #git data from Gitlab - self.tests = self.__loadCfg('ran_dashboard_cfg.yaml') #tests table setup from yaml - self.db = self.__loadFromDB() #test results from database - - - def __loadCfg(self,yaml_file): - with open(yaml_file,'r') as f: - tests = yaml.load(f) - return tests - - def __getGitData(self,cmd): - #cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """ - process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE) - output = process.stdout.readline() - tmp=output.decode("utf-8") - d = json.loads(tmp) - return d - - def __loadFromDB(self): - mr_list=[] - for x in range(len(self.git)): - mr_list.append(str(self.git[x]['iid'])) - mydb=SQLConnect() - for MR in mr_list: - mydb.get(MR) - mydb.close_connection() - return mydb.data - - - - def gBuild(self, destinationSheetName): - - ###line 1 : update date/time, format dd/mm/YY H:M:S - now = datetime.now() - dt_string = "Update : " + now.strftime("%d/%m/%Y %H:%M") - row =[dt_string] - self.sheet.insert_row(row, index=1, value_input_option='RAW') - - ###line 2 is for the test short names (links to jenkins pipeline), updated at the end - - ###line 3 is for the column names - i=3 - row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","Review Form","OK MERGE","Merge conflicts",""] - - #tests - for t in range(0,len(self.tests)): - row.append("# PASS") - row.append("# FAIL") - row.append("Last Pass") - row.append("Last Fail") - - self.sheet.insert_row(row, index=i, value_input_option='RAW') - - ###line 4 onward, MR data lines - for x in range(len(self.git)): - i=i+1 - date_time_str = self.git[x]['created_at'] - date_time_obj = datetime.strptime(date_time_str, '%Y-%m-%dT%H:%M:%S.%fZ') - - milestone1=milestone2=milestone3=milestone4="" - if self.git[x]['milestone']!=None: - if self.git[x]['milestone']['title']=="REVIEW_CAN_START": - milestone1="X" - elif self.git[x]['milestone']['title']=="REVIEW_IN_PROGRESS": - milestone2="X" - elif self.git[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED": - milestone3="X" - elif self.git[x]['milestone']['title']=="OK_TO_BE_MERGED": - milestone4="X" - else: - pass - else: - pass - - #check if empty or not - if self.git[x]['assignee']!=None: - assignee = str(self.git[x]['assignee']['name']) - else: - assignee = "" - - #check if empty or not - if len(self.git[x]['reviewers'])!=0: - reviewer = str(self.git[x]['reviewers'][0]['name']) - else: - reviewer = "" - - if self.git[x]['has_conflicts']==True: - conflicts = "YES" - else: - conflicts = "" - - - #add a column flagging that the review form is present - #we use gitlab API to parse the MR notes - gl = gitlab.Gitlab.from_config('OAI') - project_id = 223 - project = gl.projects.get(project_id) - #get the opened MR in the project - mrs = project.mergerequests.list(state='opened',per_page=100) - review_form='' - for m in range (0,len(mrs)): - if mrs[m].iid==self.git[x]['iid']:#check the iid is the one we are on - mr_notes = mrs[m].notes.list(all=True) - n=0 - found=False - while found==False and n - - - - - - -

TEMPLATE Results Summary

- - - - - - - - - - - - - - - - - -
HostnameNb TestsFailuresTimestamp
- - - - - - - -
-

Details

- - - - - - - - - - - - - - - - - -
Test NameResultTimeDescription
- - - - - - - -
- - -
-
diff --git a/ci-scripts/xml_files/container_5g_e1_rfsim.xml b/ci-scripts/xml_files/container_5g_e1_rfsim.xml new file mode 100644 index 0000000000..7130976dad --- /dev/null +++ b/ci-scripts/xml_files/container_5g_e1_rfsim.xml @@ -0,0 +1,131 @@ + + + rfsim-5gnr-e1 + CUCP-CUUP-DU E1+F1 split + wrench + + 111111 + 100021 + 000020 + 000021 + 000022 + 000023 + 000024 + 020021 + 020022 + 030021 + 100021 + + + + + Pull_Local_Registry + Pull Images from Local Registry + 0 + oai-gnb oai-nr-cuup oai-nr-ue + + + + DeployGenObject + Deploy MySql Database + yaml_files/5g_rfsimulator_e1 + mysql + 1 + + + + DeployGenObject + Deploy OAI 5G CoreNetwork + yaml_files/5g_rfsimulator_e1 + oai-nrf oai-amf oai-smf oai-spgwu oai-ext-dn + 6 + + + + DeployGenObject + Deploy OAI 5G CU-CP RF sim SA + yaml_files/5g_rfsimulator_e1 + oai-cucp + 7 + + + + DeployGenObject + Deploy OAI 5G CU-UP and DU RF sim SA + yaml_files/5g_rfsimulator_e1 + oai-cuup oai-du + 9 + + + + DeployGenObject + Deploy OAI 5G NR-UE RF sim SA + yaml_files/5g_rfsimulator_e1 + oai-nr-ue + 10 + + + + PingFromContainer + Ping ext-dn from NR-UE + rfsim5g-oai-nr-ue + -I oaitun_ue1 -c 20 192.168.73.135 + 5 + + + + PingFromContainer + Ping NR-UE from ext-dn + rfsim5g-oai-ext-dn + -c 20 12.1.1.2 + 5 + + + + IperfFromContainer + Iperf UDP Downlink + rfsim5g-oai-nr-ue + rfsim5g-oai-ext-dn + -B 12.1.1.2 -u -i 1 -s + -c 12.1.1.2 -u -i 1 -t 30 -b 3M + + + + IperfFromContainer + Iperf UDP Uplink + rfsim5g-oai-ext-dn + rfsim5g-oai-nr-ue + -u -i 1 -s + -B 12.1.1.2 -c 192.168.73.135 -u -i 1 -t 30 -b 1M + + + + UndeployGenObject + Undeploy all OAI 5G stack + yaml_files/5g_rfsimulator_e1 + 1,0,0,0 + 1,0,0,0 + + + diff --git a/ci-scripts/xml_files/container_5g_e1_rfsim_down.xml b/ci-scripts/xml_files/container_5g_e1_rfsim_down.xml new file mode 100644 index 0000000000..a1213c9b9b --- /dev/null +++ b/ci-scripts/xml_files/container_5g_e1_rfsim_down.xml @@ -0,0 +1,45 @@ + + + rfsim-5gnr-down-e1 + CleanUp CUCP-CUUP-DU E1+F1 split + trash + + 100022 + 222222 + + + + + UndeployGenObject + Undeploy all OAI 5G stack + yaml_files/5g_rfsimulator_e1 + + + + Clean_Test_Server_Images + Clean Test Images on Test Server + 0 + + + diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml index ed80a8b1e1..f9c5115f8a 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml @@ -37,7 +37,7 @@ datalog_rt_stats.1x1.60.yaml NR 192.168.20.2 - numactl --cpunodebind=netdev:enp94s0f0 --membind=netdev:enp94s0f0 + numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml index 831ed5b096..641f5ee0eb 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml @@ -37,7 +37,7 @@ datalog_rt_stats.60.2x2.yaml NR 192.168.20.2 - numactl --cpunodebind=netdev:enp94s0f0 --membind=netdev:enp94s0f0 + numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 diff --git a/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml new file mode 100644 index 0000000000..3d4689e912 --- /dev/null +++ b/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml @@ -0,0 +1,350 @@ +version: '3.8' +services: + oai-nrf: + container_name: "rfsim5g-oai-nrf" + image: oai-nrf:august-dev + environment: + - NRF_INTERFACE_NAME_FOR_SBI=eth0 + - NRF_INTERFACE_PORT_FOR_SBI=80 + - NRF_INTERFACE_HTTP2_PORT_FOR_SBI=9090 + - NRF_API_VERSION=v1 + - INSTANCE=0 + - PID_DIRECTORY=/var/run + networks: + core_net: + ipv4_address: 192.168.71.130 + volumes: + - ../5g_rfsimulator/nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh + healthcheck: + test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh" + interval: 10s + timeout: 5s + retries: 5 + + mysql: + container_name: "rfsim5g-mysql" + image: mysql:5.7 + volumes: + - ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql + - ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh + environment: + - TZ=Europe/Paris + - MYSQL_DATABASE=oai_db + - MYSQL_USER=test + - MYSQL_PASSWORD=test + - MYSQL_ROOT_PASSWORD=linux + healthcheck: + test: /bin/bash -c "/tmp/mysql-healthcheck.sh" + interval: 10s + timeout: 5s + retries: 5 + networks: + core_net: + ipv4_address: 192.168.71.131 + + oai-amf: + container_name: "rfsim5g-oai-amf" + image: oai-amf:august-dev + environment: + - TZ=Europe/paris + - INSTANCE=0 + - PID_DIRECTORY=/var/run + - MCC=208 + - MNC=99 + - REGION_ID=128 + - AMF_SET_ID=1 + - SERVED_GUAMI_MCC_0=208 + - SERVED_GUAMI_MNC_0=99 + - SERVED_GUAMI_REGION_ID_0=128 + - SERVED_GUAMI_AMF_SET_ID_0=1 + - SERVED_GUAMI_MCC_1=460 + - SERVED_GUAMI_MNC_1=11 + - SERVED_GUAMI_REGION_ID_1=10 + - SERVED_GUAMI_AMF_SET_ID_1=1 + - PLMN_SUPPORT_MCC=208 + - PLMN_SUPPORT_MNC=99 + - PLMN_SUPPORT_TAC=0x0001 + - SST_0=1 + - SD_0=0xffffff + - SST_1=1 + - SD_1=1 + - AMF_INTERFACE_NAME_FOR_NGAP=eth0 + - AMF_INTERFACE_NAME_FOR_N11=eth0 + - SMF_INSTANCE_ID_0=1 + - SMF_FQDN_0=oai-smf + - SMF_IPV4_ADDR_0=0.0.0.0 + - SMF_HTTP_VERSION_0=v1 + - SELECTED_0=true + - SMF_INSTANCE_ID_1=2 + - SMF_FQDN_1=oai-smf + - SMF_IPV4_ADDR_1=0.0.0.0 + - SMF_HTTP_VERSION_1=v1 + - SELECTED_1=false + - MYSQL_SERVER=192.168.71.131 + - MYSQL_USER=root + - MYSQL_PASS=linux + - MYSQL_DB=oai_db + - OPERATOR_KEY=c42449363bbad02b66d16bc975d77cc1 + - NRF_IPV4_ADDRESS=192.168.71.130 + - NRF_PORT=80 + - NF_REGISTRATION=yes + - SMF_SELECTION=yes + - USE_FQDN_DNS=yes + - NRF_API_VERSION=v1 + - NRF_FQDN=oai-nrf + - EXTERNAL_AUSF=no + - AUSF_IPV4_ADDRESS=0.0.0.0 + - AUSF_PORT=80 + - AUSF_API_VERSION=v1 + - AUSF_FQDN=localhost + depends_on: + - oai-nrf + - mysql + volumes: + - ../5g_rfsimulator/amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh + healthcheck: + test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh" + interval: 10s + timeout: 15s + retries: 5 + networks: + core_net: + ipv4_address: 192.168.71.132 + + oai-smf: + container_name: "rfsim5g-oai-smf" + image: oai-smf:august-dev + environment: + - TZ=Europe/Paris + - INSTANCE=0 + - PID_DIRECTORY=/var/run + - SMF_INTERFACE_NAME_FOR_N4=eth0 + - SMF_INTERFACE_NAME_FOR_SBI=eth0 + - SMF_INTERFACE_PORT_FOR_SBI=80 + - SMF_INTERFACE_HTTP2_PORT_FOR_SBI=9090 + - SMF_API_VERSION=v1 + - DEFAULT_DNS_IPV4_ADDRESS=172.21.3.100 + - DEFAULT_DNS_SEC_IPV4_ADDRESS=4.4.4.4 + - AMF_IPV4_ADDRESS=0.0.0.0 + - AMF_PORT=80 + - AMF_API_VERSION=v1 + - AMF_FQDN=oai-amf + - UDM_IPV4_ADDRESS=127.0.0.1 + - UDM_PORT=80 + - UDM_API_VERSION=v1 + - UDM_FQDN=localhost + - UPF_IPV4_ADDRESS=192.168.71.134 + - UPF_FQDN_0=oai-spgwu + - NRF_IPV4_ADDRESS=192.168.71.130 + - NRF_PORT=80 + - NRF_API_VERSION=v1 + - NRF_FQDN=oai-nrf + - REGISTER_NRF=yes + - DISCOVER_UPF=yes + - USE_FQDN_DNS=yes + - DNN_NI0=oai + - TYPE0=IPv4 + - DNN_RANGE0=12.1.1.2 - 12.1.1.127 + - NSSAI_SST0=1 + - NSSAI_SD0=0xFFFFFF + - SESSION_AMBR_UL0=200Mbps + - SESSION_AMBR_DL0=400Mbps + - DNN_NI2=oai.ipv4 + depends_on: + - oai-nrf + - oai-amf + volumes: + - ../5g_rfsimulator/smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh + healthcheck: + test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh" + interval: 10s + timeout: 5s + retries: 5 + networks: + core_net: + ipv4_address: 192.168.71.133 + + oai-spgwu: + container_name: "rfsim5g-oai-spgwu" + image: oai-spgwu-tiny:august-dev + environment: + - TZ=Europe/Paris + - PID_DIRECTORY=/var/run + - SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP=eth0 + - SGW_INTERFACE_NAME_FOR_SX=eth0 + - PGW_INTERFACE_NAME_FOR_SGI=eth0 + - NETWORK_UE_NAT_OPTION=yes + - NETWORK_UE_IP=12.1.1.0/24 + - SPGWC0_IP_ADDRESS=192.168.71.133 + - BYPASS_UL_PFCP_RULES=no + - MCC=208 + - MNC=99 + - MNC03=099 + - TAC=1 + - GTP_EXTENSION_HEADER_PRESENT=yes + - GW_ID=1 + - REALM=openairinterface.org + - ENABLE_5G_FEATURES=yes + - REGISTER_NRF=yes + - USE_FQDN_NRF=yes + - UPF_FQDN_5G=oai-spgwu + - NRF_IPV4_ADDRESS=192.168.71.130 + - NRF_PORT=80 + - NRF_API_VERSION=v1 + - NRF_FQDN=oai-nrf + - NSSAI_SST_0=1 + - NSSAI_SD_0=0xffffff + - DNN_0=oai + depends_on: + - oai-nrf + - oai-smf + cap_add: + - NET_ADMIN + - SYS_ADMIN + cap_drop: + - ALL + privileged: true + volumes: + - ../5g_rfsimulator/spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh + healthcheck: + test: /bin/bash -c "/openair-spgwu-tiny/bin/spgwu-healthcheck.sh" + interval: 10s + timeout: 5s + retries: 5 + networks: + core_net: + ipv4_address: 192.168.71.134 + traffic_net: + ipv4_address: 192.168.73.134 + + oai-ext-dn: + image: ubuntu:bionic + privileged: true + container_name: rfsim5g-oai-ext-dn + entrypoint: /bin/bash -c \ + "apt update; apt install -y procps iptables iproute2 iperf iputils-ping;"\ + "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\ + "ip route add 12.1.1.0/24 via 192.168.73.134 dev eth0; sleep infinity" + depends_on: + - oai-spgwu + networks: + traffic_net: + ipv4_address: 192.168.73.135 + healthcheck: + test: /bin/bash -c "ping -c 2 192.168.73.134" + interval: 10s + timeout: 5s + retries: 5 + + oai-cucp: + image: oai-gnb:develop + privileged: true + container_name: rfsim5g-oai-cucp + environment: + USE_VOLUMED_CONF: 'yes' + USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time + depends_on: + - oai-ext-dn + networks: + core_net: + ipv4_address: 192.168.71.140 + ran_net: + ipv4_address: 192.168.72.140 + volumes: + - ../../conf_files/gnb-cucp.sa.f1.conf:/opt/oai-gnb/etc/mounted.conf + healthcheck: + test: /bin/bash -c "pgrep nr-softmodem" + interval: 10s + timeout: 5s + retries: 5 + + oai-cuup: + image: oai-nr-cuup:develop + privileged: true + container_name: rfsim5g-oai-cuup + environment: + USE_VOLUMED_CONF: 'yes' + USE_ADDITIONAL_OPTIONS: --sa --rfsim + #--log_config.global_log_options level,nocolor,time + depends_on: + - oai-cucp + networks: + core_net: + ipv4_address: 192.168.71.141 + ran_net: + ipv4_address: 192.168.72.141 + volumes: + - ../../conf_files/gnb-cuup.sa.f1.conf:/opt/oai-gnb/etc/mounted.conf + healthcheck: + test: /bin/bash -c "pgrep nr-cuup" + interval: 10s + timeout: 5s + retries: 5 + + oai-du: + image: oai-gnb:develop + privileged: true + container_name: rfsim5g-oai-du + environment: + RFSIMULATOR: server + USE_VOLUMED_CONF: 'yes' + USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time + networks: + ran_net: + ipv4_address: 192.168.72.142 + volumes: + - ../../conf_files/gnb-du.band78.106prb.rfsim.conf:/opt/oai-gnb/etc/mounted.conf + healthcheck: + test: /bin/bash -c "pgrep nr-softmodem" + interval: 10s + timeout: 5s + retries: 5 + + oai-nr-ue: + image: oai-nr-ue:develop + privileged: true + container_name: rfsim5g-oai-nr-ue + environment: + RFSIMULATOR: 192.168.72.142 + FULL_IMSI: '208990100001100' + FULL_KEY: 'fec86ba6eb707ed08905757b1bb44b8f' + OPC: 'C42449363BBAD02B66D16BC975D77CC1' + DNN: oai + NSSAI_SST: 1 + USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 106 --numerology 1 -C 3619200000 --nokrnmod --log_config.global_log_options level,nocolor,time + depends_on: + - oai-du + networks: + ran_net: + ipv4_address: 192.168.72.150 + healthcheck: + test: /bin/bash -c "pgrep nr-uesoftmodem" + interval: 10s + timeout: 5s + retries: 5 + +networks: + core_net: + driver: bridge + name: rfsim5g-oai-core-net + ipam: + config: + - subnet: 192.168.71.128/26 + driver_opts: + com.docker.network.bridge.name: "rfsim5g-core" + ran_net: + driver: bridge + name: rfsim5g-oai-ran-net + ipam: + config: + - subnet: 192.168.72.128/26 + driver_opts: + com.docker.network.bridge.name: "rfsim5g-ran" + traffic_net: + driver: bridge + name: rfsim5g-oai-traffic_net-net + ipam: + config: + - subnet: 192.168.73.128/26 + driver_opts: + com.docker.network.bridge.name: "rfsim5g-traffic" diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt index a8f5932045..d2d5db704e 100755 --- a/cmake_targets/at_commands/CMakeLists.txt +++ b/cmake_targets/at_commands/CMakeLists.txt @@ -86,49 +86,8 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.2 -std=gnu99 -Wall -Wstrict-prototype set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -DMALLOC_CHECK_=3") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ggdb -DMALLOC_CHECK_=3 -O2") -##This is to detect nettle version changes between Ubuntu 14.04/16.04 -#set ( nettle_cmd "nettle-hash" ) -#set ( nettle_arg "-V" ) -#execute_process(COMMAND ${nettle_cmd} ${nettle_arg} RESULT_VARIABLE rv OUTPUT_VARIABLE ov ERROR_VARIABLE ev) -# -#string(REGEX MATCH "[+-]?[0-9]+([.][0-9]+)?" nv ${ov}) -# -#message("NETTLE_VERSION = ${nv}") -# -## we need to remove decimal as floating point arithematic does not work properly with C preprocessor -#STRING(REGEX REPLACE "[.]" "" nv ${nv}) -# -#if ("${nv}" STREQUAL "") -# message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) -#endif() -# -#set (NETTLE_VERSION "${nv}") -#add_definitions("-DNETTLE_VERSION=${NETTLE_VERSION}") - include(FindPkgConfig) -pkg_search_module(NETTLE nettle) -if(NOT ${NETTLE_FOUND}) - message( FATAL_ERROR "PACKAGE nettle not found: some targets will fail. Run build_oai -I again!") -else() - include_directories(${NETTLE_INCLUDE_DIRS}) -endif() - -message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") - -string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) -string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) -message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") -message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") - -if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") - message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) -endif() - -add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") -add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") - - pkg_search_module(OPENSSL openssl REQUIRED) include_directories(${OPENSSL_INCLUDE_DIRS}) @@ -159,6 +118,9 @@ add_boolean_option(NAS_MME False "NAS_UE and NAS_MME are incompa # SECU LIB ################################################################################ set(secu_cn_SRC + ${OPENAIR3_DIR}/SECU/aes_128_ctr.c + ${OPENAIR3_DIR}/SECU/aes_128_cbc_cmac.c + ${OPENAIR3_DIR}/SECU/sha_256_hmac.c ${OPENAIR3_DIR}/SECU/kdf.c ${OPENAIR3_DIR}/SECU/rijndael.c ${OPENAIR3_DIR}/SECU/snow3g.c @@ -719,7 +681,6 @@ target_link_libraries (at_nas_ue -Wl,-whole-archive api_network api_user api_usim emm esm ies util secu_cn -Wl,-no-whole-archive - ${NETTLE_LIBRARIES} ${OPENSSL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} m ) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index fd9e2054a2..8e40561111 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -285,6 +285,10 @@ function main() { --UE-gen-nvram) gen_nvram_path=$(readlink -f "$2") shift 2;; + --UE-ip) + UE_ip=1 + echo_info "Will compile UE" + shift;; -w | --hardware) # Use OAI_USRP as the key word USRP is used inside UHD driver case "$2" in @@ -531,7 +535,7 @@ function main() { execlist="$execlist ocp-enb" fi if [ "$gNB" = "1" ] ; then - execlist="$execlist nr-softmodem" + execlist="$execlist nr-softmodem nr-cuup" fi if [ "$RU" = "1" ] ; then execlist="$execlist oairu" @@ -588,7 +592,7 @@ function main() { echo_info "Compiling UE specific part" - if [ $IS_CONTAINER -eq 0 ] + if [ $UE_ip -eq 1 ] then echo_info "Building ue_ip module" compilations $BUILD_DIR ue_ip diff --git a/cmake_targets/tools/MODULES/FindNettle.cmake b/cmake_targets/tools/MODULES/FindNettle.cmake deleted file mode 100755 index 4602e74997..0000000000 --- a/cmake_targets/tools/MODULES/FindNettle.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# Find the native Nettle includes, library, and flags -# -# NETTLE_INCLUDE_DIR - where to find nettle.h, etc. -# NETTLE_LIBRARIES - List of libraries when using Nettle. -# NETTLE_FOUND - True if Nettle found. -IF (NETTLE_INCLUDE_DIR) -# Already in cache, be silent - SET(NETTLE_FIND_QUIETLY TRUE) -ENDIF (NETTLE_INCLUDE_DIR) -FIND_PATH(NETTLE_INCLUDE_DIR nettle/nettle-meta.h) -SET(NETTLE_NAMES nettle) -FIND_LIBRARY(NETTLE_LIBRARY NAMES ${NETTLE_NAMES} ) -# handle the QUIETLY and REQUIRED arguments and set NETTLE_FOUND to TRUE if -# all listed variables are TRUE -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(NETTLE DEFAULT_MSG NETTLE_LIBRARY NETTLE_INCLUDE_DIR) -IF(NETTLE_FOUND) - SET(NETTLE_LIBRARIES ${NETTLE_LIBRARY}) -ELSE(NETTLE_FOUND) - SET(NETTLE_LIBRARIES ) -ENDIF(NETTLE_FOUND) -MARK_AS_ADVANCED(NETTLE_LIBRARY NETTLE_INCLUDE_DIR) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 029d25b236..5af626b182 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -32,8 +32,8 @@ OS_DISTRO=$(grep "^ID=" /etc/os-release | sed "s/ID=//" | sed "s/\"//g") OS_RELEASE=$(grep "^VERSION_ID=" /etc/os-release | sed "s/VERSION_ID=//" | sed "s/\"//g") case "$OS_DISTRO" in fedora) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;; - rhel) OS_BASEDISTRO="fedora"; INSTALLER="yum --skip-broken"; CMAKE="cmake3" ;; - centos) OS_BASEDISTRO="centos"; INSTALLER="yum --skip-broken"; CMAKE="cmake3" ;; + rhel) OS_BASEDISTRO="fedora"; INSTALLER="yum"; CMAKE="cmake3" ;; + centos) OS_BASEDISTRO="centos"; INSTALLER="yum"; CMAKE="cmake3" ;; debian) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;; ubuntu) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;; esac @@ -90,7 +90,6 @@ echo_info() { cecho "$*" $blue ;} # If we can't check the distribution, it returns "Unknown" # This function return always true as exit code by design # Examples: -# ubuntu16.04 # debian8.5 get_distribution_release() { if [[ ! -z "$OS_DISTRO$OS_RELEASE" ]]; then @@ -107,9 +106,9 @@ check_supported_distribution() { "ubuntu21.04") return 0 ;; "ubuntu20.04") return 0 ;; "ubuntu18.04") return 0 ;; - "ubuntu16.04") return 0 ;; - "fedora35") return 0 ;; + "debian11") return 0 ;; "fedora36") return 0 ;; + "fedora37") return 0 ;; "rhel7") return 0 ;; "rhel7.6") return 0 ;; "rhel7.7") return 0 ;; @@ -306,7 +305,8 @@ install_usrp_uhd_driver_from_source(){ } check_install_usrp_uhd_driver(){ - if [[ "$OS_DISTRO" == "ubuntu" ]]; then + if [[ "$OS_BASEDISTRO" == "debian" ]]; then + boost_libs_ubuntu="libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev libboost-test-dev libboost-regex-dev" #first we remove old installation $SUDO apt-get remove uhd -y || true $SUDO apt-get remove uhd-host -y || true @@ -323,8 +323,8 @@ check_install_usrp_uhd_driver(){ fi v=$(lsb_release -cs) $SUDO apt-add-repository --remove "deb http://files.ettus.com/binaries/uhd/repo/uhd/ubuntu/$v $v main" - if [[ -v BUILD_UHD_FROM_SOURCE ]]; then - $SUDO apt-get install -y libboost-all-dev libusb-1.0-0-dev doxygen python3-docutils python3-mako python3-numpy python3-requests python3-setuptools ninja-build + if [[ -v BUILD_UHD_FROM_SOURCE ]] || [[ "$OS_DISTRO" == "debian" ]]; then + $SUDO apt-get install -y $boost_libs_ubuntu libusb-1.0-0-dev doxygen python3-docutils python3-mako python3-numpy python3-requests python3-setuptools ninja-build install_usrp_uhd_driver_from_source return fi @@ -346,22 +346,20 @@ check_install_usrp_uhd_driver(){ x=$((x + 1)) done $SUDO apt-get update - $SUDO apt-get -y install python-tk libboost-all-dev libusb-1.0-0-dev + $SUDO apt-get -y install python-tk $boost_libs_ubuntu libusb-1.0-0-dev case "$(get_distribution_release)" in - "ubuntu16.04") - $SUDO apt-get -y install libuhd-dev libuhd3.15.0 uhd-host - ;; "ubuntu18.04" | "ubuntu20.04" | "ubuntu22.04") $SUDO apt-get -y install libuhd-dev libuhd4.2.0 uhd-host ;; esac elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then + boost_libs_fedora="boost-chrono boost-date-time boost-filesystem boost-program-options boost-thread boost-test boost-regex boost-devel" if [ $IS_CONTAINER -eq 0 ] then - $SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils $CMAKE - $SUDO -H pip install requests + $SUDO $INSTALLER -y install python3 $boost_libs_fedora libusb-devel libusbx-devel python3-mako python3-docutils python3-pip $CMAKE + $SUDO pip3 install requests else - $SUDO $INSTALLER -y install boost boost-devel $CMAKE + $SUDO $INSTALLER -y install $boost_libs_fedora $CMAKE $SUDO pip3 install mako requests fi if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then @@ -419,6 +417,8 @@ install_bladerf_driver_from_source(){ $SUDO ldconfig echo "Downloading FPGA and firmware images" cd /tmp/bladeRF + #wget has been removed from default dependencies, so we must be sure that's installed + $SUDO $INSTALLER -y install wget wget --tries=3 --retry-connrefused https://www.nuand.com/fx3/bladeRF_fw_latest.img wget --tries=3 --retry-connrefused https://www.nuand.com/fpga/hostedx40-latest.rbf sudo mkdir -p /usr/share/Nuand/bladeRF @@ -529,110 +529,42 @@ check_install_soapy () { check_install_additional_tools (){ $SUDO $INSTALLER update -y local optional_packages="" - if [[ "$OS_DISTRO" == "ubuntu" ]]; then + if [[ "$OS_BASEDISTRO" == "debian" ]]; then case "$(get_distribution_release)" in - "ubuntu16.04"| "ubuntu18.04") - optional_packages="python-dev python-pexpect python-numpy python-scipy python-matplotlib ctags" + "ubuntu18.04") + optional_packages="python-dev python-pip python-pyroute2 python python-numpy python-scipy python-matplotlib ctags" ;; - "ubuntu20.04" | "ubuntu21.04" | "ubuntu22.04" ) - optional_packages="python3 python3-pip python3-dev python3-scipy python3-matplotlib universal-ctags" + "ubuntu20.04" | "ubuntu21.04" | "ubuntu22.04" | "debian11" ) + optional_packages="python3 python3-pip python3-dev python3-scipy python3-matplotlib python3-pyroute2 universal-ctags" ;; esac PACKAGE_LIST="\ - check \ - dialog \ - dkms \ - gawk \ - libboost-all-dev \ + doxygen \ libpthread-stubs0-dev \ - openvpn \ - pkg-config \ - sshfs \ - swig \ tshark \ uml-utilities \ - unzip \ - valgrind \ - vlan \ - ntpdate \ iperf3 \ - android-tools-adb \ - wvdial \ - sshpass \ - bc \ - ntp" + libforms-bin \ + libforms-dev \ + xmlstarlet" elif [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then PACKAGE_LIST="\ - check \ - dialog \ - dkms \ - gawk \ - boost-devel \ - openvpn \ - pkgconfig \ - pexpect \ - sshfs \ - swig \ - wireshark \ - unzip \ - valgrind \ - vconfig \ + doxygen \ ctags \ - ntpdate \ iperf3 \ - wvdial \ - numpy \ - sshpass \ - python2-paramiko \ - python-pyroute2 \ - python-netifaces \ - scipy \ - python-matplotlib" + xforms \ + xforms-devel \ + xmlstarlet" elif [[ "$OS_DISTRO" == "fedora" ]]; then PACKAGE_LIST=" \ - check \ - dialog \ - dkms \ - gawk \ - boost-devel \ - openvpn \ - pkgconfig \ - python-pexpect \ - sshfs \ - swig \ - wireshark \ - unzip \ - valgrind \ - vconfig \ + doxygen \ ctags \ - ntpsec \ iperf3 \ - wvdial \ - python-numpy \ - sshpass \ - python-paramiko \ - python-pyroute2 \ - python-netifaces \ - python-scipy \ - python-matplotlib" + xforms \ + xforms-devel \ + xmlstarlet" fi $SUDO $INSTALLER install -y $PACKAGE_LIST $optional_packages - - #The packages below are already installed for Redhat distros (RHEL, CentOS, Fedora) - if [[ "$OS_DISTRO" == "ubuntu" ]]; then - $SUDO -H pip install paramiko - $SUDO -H pip install pyroute2 colorama - log_netiface=$OPENAIR_DIR/cmake_targets/log/netiface_install_log.txt - echo_info "Installing Netinterfaces package. The logfile for installation is in $log_netiface" - ( - $SUDO rm -fr /tmp/netifaces-0.10.4.tar.gz /tmp/netifaces - wget --tries=3 --retry-connrefused -P /tmp https://pypi.python.org/packages/18/fa/dd13d4910aea339c0bb87d2b3838d8fd923c11869b1f6e741dbd0ff3bc00/netifaces-0.10.4.tar.gz - tar -xzvf /tmp/netifaces-0.10.4.tar.gz -C /tmp - cd /tmp/netifaces-0.10.4 - $SUDO python setup.py install - cd - - ) >& $log_netiface - fi } check_install_oai_software() { @@ -642,167 +574,88 @@ check_install_oai_software() { exit 1 fi $SUDO $INSTALLER update -y - if [[ "$OS_DISTRO" == "ubuntu" ]]; then - local LAPACK_LIBNAME="liblapack.so" - local LAPACK_TARGET="/usr/lib/atlas-base/atlas/liblapack.so" + if [[ "$OS_BASEDISTRO" == "debian" ]]; then $SUDO apt install -y software-properties-common case "$(get_distribution_release)" in - "ubuntu16.04") - specific_packages="libtasn1-6-dev libgnutls-dev libatlas-dev iproute libconfig8-dev iptables-dev libgcrypt11-dev python-pip pydb python guile-2.0-dev" - ;; "ubuntu18.04") - specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev iptables-dev libgcrypt11-dev python-pip pydb python guile-2.0-dev" - LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" - LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so" + specific_packages="libgcrypt11-dev guile-2.0-dev" ;; "ubuntu20.04") - specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev python guile-2.0-dev" - LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" - LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so" + specific_packages="guile-2.0-dev" ;; "ubuntu21.04") - specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev python guile-2.0-dev" - LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" - LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so" + specific_packages="guile-2.0-dev" ;; "ubuntu22.04") - specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev python2 guile-2.2-dev" - LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" - LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so" + specific_packages="guile-2.2-dev" + ;; + "debian11") + specific_packages="guile-2.2-dev libz-dev" ;; esac $SUDO apt-get install -y \ $specific_packages \ - autoconf \ automake \ - bison \ build-essential \ $CMAKE \ - cmake-curses-gui \ - curl \ ninja-build \ - doxygen \ - doxygen-gui \ - texlive-latex-base \ - ethtool \ - flex \ - g++ \ - gcc \ - gdb \ + pkg-config \ git \ - graphviz \ - gtkwave \ - iperf \ - iptables \ libatlas-base-dev \ libblas-dev \ liblapack-dev \ liblapacke-dev \ - libffi-dev \ - libforms-bin \ - libforms-dev \ - libgmp-dev \ - libgtk-3-dev \ - libidn2-0-dev \ - libidn11-dev \ - libmysqlclient-dev \ - libpython2.7-dev \ - libreadline-dev \ - libsctp1 \ + libreadline-dev \ + libgnutls28-dev \ + libconfig-dev \ libsctp-dev \ libssl-dev \ libtool \ - libusb-1.0-0-dev \ - libxml2 \ - libxml2-dev \ libxslt1-dev \ - octave-signal \ - openssh-client \ - openssh-server \ + libtasn1-6-dev \ + patch \ openssl \ - subversion \ - xmlstarlet \ - wget \ - libxpm-dev \ - libboost-all-dev + xxd - $SUDO update-alternatives --set "$LAPACK_LIBNAME" "$LAPACK_TARGET" - - $SUDO apt-get install -y nettle-dev nettle-bin elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then if rpm -q epel-release > /dev/null; then echo "EPEL repos already present. Good." else echo "EPEL repos not present. Installing them." - $SUDO $INSTALLER install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm + $SUDO $INSTALLER install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm fi - $SUDO $INSTALLER install -y python-epdb vim-common fi $SUDO $INSTALLER install -y \ - autoconf \ automake \ - bc \ - bison \ $CMAKE \ - doxygen \ - ethtool \ - flex \ - g++ \ gcc \ - gdb \ + gcc-c++ \ git \ - graphviz \ - gtkwave \ guile-devel \ - iperf \ - iproute \ - iptables \ - iptables-devel \ atlas-devel \ - blas-devel \ + pkgconfig \ libconfig-devel \ libffi-devel \ - xforms \ - xforms-devel \ libgcrypt-devel \ - gmp-devel \ - gtk3-devel \ - libidn2-devel \ - libidn-devel \ - mariadb-devel \ lksctp-tools \ lksctp-tools-devel \ - openssl-devel \ libtasn1 \ libtool \ - libusb-devel \ - libxml2 \ - libxml2-devel \ libxslt-devel \ ninja-build \ make \ - openssh-clients \ - openssh-server \ openssl \ + openssl-devel \ patch \ - psmisc \ - python \ readline-devel \ - subversion \ - xmlstarlet \ - python-pip \ - wget \ - kernel-headers \ - kernel-devel \ - nettle-devel \ gnutls-devel \ - libXpm-devel \ lapack \ lapack-devel \ blas \ - blas-devel + blas-devel \ + vim-common fi install_asn1c_from_source $1 diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt new file mode 100644 index 0000000000..512d2b1553 --- /dev/null +++ b/common/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(utils) diff --git a/common/ngran_types.h b/common/ngran_types.h index 3dfa7aa01a..ddd1ec2cca 100644 --- a/common/ngran_types.h +++ b/common/ngran_types.h @@ -42,12 +42,16 @@ typedef enum { ngran_gNB_CU = 5, ngran_eNB_DU = 6, ngran_gNB_DU = 7, - ngran_eNB_MBMS_STA = 8 + ngran_eNB_MBMS_STA = 8, + ngran_gNB_CUCP = 9, + ngran_gNB_CUUP = 10 } ngran_node_t; +typedef enum { CPtype = 0, UPtype } E1_t; + #define NODE_IS_MONOLITHIC(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB || (nOdE_TyPe) == ngran_ng_eNB || (nOdE_TyPe) == ngran_gNB) -#define NODE_IS_CU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_CU || (nOdE_TyPe) == ngran_ng_eNB_CU || (nOdE_TyPe) == ngran_gNB_CU) +#define NODE_IS_CU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_CU || (nOdE_TyPe) == ngran_ng_eNB_CU || (nOdE_TyPe) == ngran_gNB_CU || (nOdE_TyPe) == ngran_gNB_CUCP || (nOdE_TyPe) == ngran_gNB_CUUP) #define NODE_IS_DU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_DU || (nOdE_TyPe) == ngran_gNB_DU) #define NODE_IS_MBMS(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_MBMS_STA) - +#define GTPV1_U_PORT_NUMBER (2152) #endif diff --git a/common/openairinterface5g_limits.h b/common/openairinterface5g_limits.h index 2349941cf2..b86f01df6a 100644 --- a/common/openairinterface5g_limits.h +++ b/common/openairinterface5g_limits.h @@ -1,6 +1,7 @@ #ifndef OPENAIRINTERFACE5G_LIMITS_H_ #define OPENAIRINTERFACE5G_LIMITS_H_ +# define MAX_MOBILES_PER_GNB 16 # define NUMBER_OF_eNB_MAX 1 # define NUMBER_OF_gNB_MAX 1 # define NUMBER_OF_RU_MAX 2 @@ -9,17 +10,10 @@ # define NUMBER_OF_ULSCH_MAX 8 # define NUMBER_OF_DLSCH_MAX 8 # define NUMBER_OF_SRS_MAX 16 -# define NUMBER_OF_NR_ULSCH_MAX 8 -# define NUMBER_OF_NR_DLSCH_MAX 8 -# define NUMBER_OF_NR_UCI_MAX 16 -# define NUMBER_OF_NR_SRS_MAX 16 -# define NUMBER_OF_NR_CSIRS_MAX 16 +# define NUMBER_OF_NR_ULSCH_MAX MAX_MOBILES_PER_GNB +# define NUMBER_OF_NR_DLSCH_MAX MAX_MOBILES_PER_GNB # define NUMBER_OF_SCH_STATS_MAX 16 - -# define NUMBER_OF_NR_SCH_STATS_MAX 16 - -# define NUMBER_OF_NR_PUCCH_MAX 16 -# define NUMBER_OF_NR_PDCCH_MAX 16 +# define NUMBER_OF_NR_SCH_STATS_MAX MAX_MOBILES_PER_GNB #define MAX_MANAGED_ENB_PER_MOBILE 2 #define MAX_MANAGED_GNB_PER_MOBILE 2 diff --git a/common/platform_constants.h b/common/platform_constants.h index 9d67b76cd7..38ec11d49e 100644 --- a/common/platform_constants.h +++ b/common/platform_constants.h @@ -69,20 +69,17 @@ #ifdef LARGE_SCALE #define MAX_MOBILES_PER_ENB 128 #define MAX_MOBILES_PER_ENB_NB_IoT 128 -#define MAX_MOBILES_PER_GNB 128 #define MAX_eNB 2 #define MAX_gNB 2 #else #define MAX_MOBILES_PER_ENB 40 #define MAX_MOBILES_PER_ENB_NB_IoT 40 -#define MAX_MOBILES_PER_GNB 16 #define MAX_eNB 2 #define MAX_gNB 2 #endif #else #define MAX_MOBILES_PER_ENB 256 #define MAX_MOBILES_PER_ENB_NB_IoT 256 -#define MAX_MOBILES_PER_GNB 256 #define MAX_eNB 2 #define MAX_gNB 2 #endif diff --git a/common/utils/CMakeLists.txt b/common/utils/CMakeLists.txt new file mode 100644 index 0000000000..eb6a119968 --- /dev/null +++ b/common/utils/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(ds) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 2215e4bd40..84c70c3767 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -483,6 +483,7 @@ int logInit (void) register_log_component("SDAP","",SDAP); register_log_component("S1AP","",S1AP); register_log_component("F1AP","",F1AP); + register_log_component("E1AP","",E1AP); register_log_component("M2AP","",M2AP); register_log_component("M3AP","",M3AP); register_log_component("SCTP","",SCTP); diff --git a/common/utils/ds/CMakeLists.txt b/common/utils/ds/CMakeLists.txt new file mode 100644 index 0000000000..400d34ad06 --- /dev/null +++ b/common/utils/ds/CMakeLists.txt @@ -0,0 +1,5 @@ +add_library(ds OBJECT + byte_array.c +) + +target_include_directories(ds PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/ci-scripts/Jenkinsfile-git-dashboard b/common/utils/ds/byte_array.c similarity index 53% rename from ci-scripts/Jenkinsfile-git-dashboard rename to common/utils/ds/byte_array.c index 87e781fe8a..04a2af0c5d 100644 --- a/ci-scripts/Jenkinsfile-git-dashboard +++ b/common/utils/ds/byte_array.c @@ -1,4 +1,3 @@ -#!/bin/groovy /* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with @@ -20,29 +19,40 @@ * contact@openairinterface.org */ -// Template Jenkins Declarative Pipeline script to run Test w/ RF HW +#include "byte_array.h" -// Location of the python executor node shall be in the same subnet as the others servers -def pythonExecutor = params.pythonExecutor +#include "common/utils/assertions.h" +#include - -pipeline { - agent { - label pythonExecutor - } - stages { - stage ("gDashboard") { - steps { - script { - dir ("ci-scripts/ran_dashboard") { - //retrieve MR data from gitlab / mySQL db, build HTML pages and load them to AWS S3 bucket (configured as static web page hosting) - //deprecated method : sh returnStdout: true, script: 'python3 ran_dashboard.py' - sh returnStdout: true, script: 'python3 Hdashboard.py' - } - } - } - } - } +byte_array_t copy_byte_array(byte_array_t src) +{ + byte_array_t dst = {0}; + dst.buf = malloc(src.len); + DevAssert(dst.buf != NULL && "Memory exhausted"); + memcpy(dst.buf, src.buf, src.len); + dst.len = src.len; + return dst; } +void free_byte_array(byte_array_t ba) +{ + free(ba.buf); +} +bool eq_byte_array(const byte_array_t* m0, const byte_array_t* m1) +{ + if (m0 == m1) + return true; + + if (m0 == NULL || m1 == NULL) + return false; + + if (m0->len != m1->len) + return false; + + const int rc = memcmp(m0->buf, m1->buf, m0->len); + if (rc != 0) + return false; + + return true; +} diff --git a/common/utils/ds/byte_array.h b/common/utils/ds/byte_array.h new file mode 100644 index 0000000000..f16fd7c01d --- /dev/null +++ b/common/utils/ds/byte_array.h @@ -0,0 +1,42 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef BYTE_ARRAY_H_OAI +#define BYTE_ARRAY_H_OAI + +#include +#include +#include + +typedef struct { + size_t len; + uint8_t* buf; +} byte_array_t; + +typedef struct { + uint8_t buf[32]; +} byte_array_32_t; + +byte_array_t copy_byte_array(byte_array_t src); +void free_byte_array(byte_array_t ba); +bool eq_byte_array(const byte_array_t* m0, const byte_array_t* m1); + +#endif diff --git a/common/utils/ocp_itti/all_msg.h b/common/utils/ocp_itti/all_msg.h index ab75eaffdd..eb484ce8f1 100644 --- a/common/utils/ocp_itti/all_msg.h +++ b/common/utils/ocp_itti/all_msg.h @@ -15,5 +15,6 @@ #include "openair2/COMMON/udp_messages_def.h" #include "openair2/COMMON/gtpv1_u_messages_def.h" #include "openair2/COMMON/f1ap_messages_def.h" +#include "openair2/COMMON/e1ap_messages_def.h" #include "openair2/COMMON/ngap_messages_def.h" diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 0a7bbc3b78..2b17c7e3ef 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -79,6 +79,7 @@ typedef struct IttiMsgText_s { #include #include #include +#include #include #include @@ -409,7 +410,7 @@ typedef struct MessageHeader_s { } MessageHeader; typedef struct message_info_s { - int id; + MessagesIds id; message_priorities_t priority; /* Message payload size */ MessageHeaderSize size; diff --git a/common/utils/websrv/DOC/websrvuse.md b/common/utils/websrv/DOC/websrvuse.md index aac9a40ed4..9ba2c8ade1 100644 --- a/common/utils/websrv/DOC/websrvuse.md +++ b/common/utils/websrv/DOC/websrvuse.md @@ -15,9 +15,6 @@ OPENAIR_DIR = /usr/local/oai/oai-develop/openairinterface5g FreeDiameter prefix not found, install freeDiameter if EPC, HSS 3. building the compilation directives ... running cmake ../../.. -NETTLE VERSION_INSTALLED = 3.5.1 -NETTLE_VERSION_MAJOR = 3 -NETTLE_VERSION_MINOR = 5 cuda include /usr/include cuda library -- CMAKE_BUILD_TYPE is RelWithDebInfo @@ -61,9 +58,6 @@ Call Stack (most recent call first): FreeDiameter prefix not found, install freeDiameter if EPC, HSS 3. building the compilation directives ... running cmake ../../.. - NETTLE VERSION_INSTALLED = 3.5.1 - NETTLE_VERSION_MAJOR = 3 - NETTLE_VERSION_MINOR = 5 cuda include /usr/include cuda library -- CMAKE_BUILD_TYPE is RelWithDebInfo @@ -209,4 +203,4 @@ The interface should be intuitive enough, keeping in mind the following restrict Some front-end objects, which usage are less intuitive provide a tooltip to help interface usage. -[oai web serverinterface home](websrv.md) \ No newline at end of file +[oai web serverinterface home](websrv.md) diff --git a/doc/E1-design.md b/doc/E1-design.md new file mode 100644 index 0000000000..db4bc85f74 --- /dev/null +++ b/doc/E1-design.md @@ -0,0 +1,108 @@ +[[_TOC_]] + +# 1. Introduction + +E1 is named for the interface that lies between the nodes CU Control Plane (CUCP) and CU User Plane (CUUP). Once the nodes are configured, all user plane traffic flows through CUUP. + +The E1 design in OAI follows the 3GPP specification in TS 38.460. The code design on E1 in OAI is very similar to +F1. The ITTI message passing mechanism is used to exchange messages between E1AP thread, SCTP thread and RRC thread. + +The following sequence chart shows the current E1AP message flow. + +```mermaid +sequenceDiagram + participant c as CUCP + participant u as CUUP + u->>c: SCTP new association + c->>u: SCTP new association response + Note over u: Create UDP sockets for F1-U and N3 + u->>c: E1AP Setup Request + c->>u: E1AP Setup Response + Note over c: Receives PDU session setup request from AMF + c->>u: Bearer Context Setup Request + Note over u: Configure DRBs and create GTP Tunnels for F1-U and N3 + u->>c: Bearer Context Setup Response + Note over c: Sends F1-U UL TNL info to DU and receives DL TNL info + c->>u: Bearer Context Modification Request + Note over u: Updates GTP Tunnels with received info +``` + +_Note that the E1 bearer release procedures are currently not implemented._ + +# 2. Running the E1 Split + +## 2.1 Configuration File + +The gNB is started based on the node type that is specified in the configuration file. To start a gNB instance in CUCP or CUUP, the `tr_s_preference` should be set to "f1" and the config member `E1_INTERFACE` should be present in the config file. The `type` parameter within the `E1_INTERFACE` should be set to `cp`, and `nr-softmodem` should be used to run a CU-CP. The type should be `up` and `nr-cuup` should be used to run the CU-UP. Further, there are the parameters `ipv4_cucp` and `ipv4_cuup` to specify the IP addresses of the respective network functions. + +For CUCP, a typical `E1_INTERFACE` config looks like +``` +E1_INTERFACE = +( + { + type = "cp"; + ipv4_cucp = "127.0.0.4"; + ipv4_cuup = "127.0.0.5"; + } +) +``` + +For CUUP, it is +``` +E1_INTERFACE = +( + { + type = "up"; + ipv4_cucp = "127.0.0.4"; + ipv4_cuup = "127.0.0.5"; + } +) +``` +One could take an existing CU configuration file and add the above parameters to run the gNB as CUCP or CUUP. + +The CUUP uses the IP address specified in `local_s_address` for F1-U and `GNB_IPV4_ADDRESS_FOR_NGU` for N3 links. Note that `local_s_address` is under `gNBs` and `GNB_IPV4_ADDRESS_FOR_NGU` is part of the `NETWORK_INTERFACES` config member. + +Alternatively, you can use the config files `ci-scripts/conf_files/gnb-cucp.sa.conf` and `ci-scripts/conf_files/gnb-cuup.sa.conf` which are already in the repository. + +## 2.2 Steps to Run the Split in rfsimulator with OAI UE + +Note: A 5G core must be running at this point. Steps to start the OAI 5G core can be found [in the oai-cn5g-fed repository](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/blob/master/docs/DEPLOY_HOME.md) or [here](NR_SA_CN5G_gNB_USRP_COTS_UE_Tutorial.md). + +0. Open wireshark to capture the E1AP messages. You might set the capture filter + to `sctp` to limit the number of captured packages. + +1. Start the CUCP first by running the following command +``` +sudo ./nr-softmodem -O ../../../ci-scripts/conf_files/gnb-cucp.sa.conf --gNBs.[0].min_rxtxtime 6 --sa +``` + +Note that `min_rxtxtime` should be set to `6` only when you are connecting an OAI UE to the gNB. + +2. Start the CUUP and DU (in any order) + +CUUP (has its own executable): +``` +sudo ./nr-cuup -O ../../../ci-scripts/conf_files/gnb-cuup.sa.conf --sa +``` + +DU: +``` +sudo ./nr-softmodem -O ../../../ci-scripts/conf_files/gNB_SA_DU.conf --rfsim --sa +``` + +You need to use `--rfsim` if you are running the test with rfsimulator. + +3. Start OAI UE or COTS UE. + +OAI UE: +``` +sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --nokrnmod --rfsim --sa +``` + +# 3. Configuration file IP addresses of network functions + +You can also run the nodes on different machines. If you do so please change the interface parameters accordingly and make sure the interfaces are reachable. Please refer to the following figure for an overview of all parameters. + +![E1/F1/NG parameters](images/e1-archi.png){width=1200} + +[PDF version](images/e1-archi.pdf) | [LaTeX/TikZ version](img/e1-archi.tex) if you want to modify to reflect your setup diff --git a/doc/TESTING_5GSA_setup.md b/doc/TESTING_5GSA_setup.md index 1828f967b1..18b61d30a5 100644 --- a/doc/TESTING_5GSA_setup.md +++ b/doc/TESTING_5GSA_setup.md @@ -91,7 +91,8 @@ In the first part (*amf_ip_address*) we specify the IP of the AMF and in the sec Please read [CN5G tutorial for more details](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/blob/master/README.md). -### **gNB configuration in CU/DU split mode** +### gNB configuration in F1 (CU/DU split mode) + For the configuration of the gNB in CU and DU blocks, the following sample configuration files are provided for the [CU](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf) and the [DU](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf) entities respectively. These configuration files have to be updated with the IP addresses of the CU and the DU over the F1 interface. For example, in the following section from the DU configuration file, *local_n_address* corresponds to the DU address and *remote_n_address* corresponds to the CU address: ```bash @@ -112,9 +113,11 @@ MACRLCs = ( ); ``` - At the point of writing this document the control-plane exchanges between the CU and the DU over *F1-C* interface, as well as some IP traffic tests over *F1-U* have been validated using the OAI gNB/nrUE in RFSIMULATOR mode. - + +### gNB configuration with F1 and E1 + +Please refer to [E1-design](E1-design) for more information. ## 1.2 OAI 5G Core Network installation and configuration The instructions for the installation of OAI CN components (AMF, SMF, NRF, UPF) using `docker-compose` can be found [here](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/blob/master/README.md). diff --git a/doc/images/e1-archi.pdf b/doc/images/e1-archi.pdf new file mode 100644 index 0000000000..ddbed79e51 Binary files /dev/null and b/doc/images/e1-archi.pdf differ diff --git a/doc/images/e1-archi.png b/doc/images/e1-archi.png new file mode 100644 index 0000000000..77b398d81a Binary files /dev/null and b/doc/images/e1-archi.png differ diff --git a/doc/images/e1-archi.tex b/doc/images/e1-archi.tex new file mode 100644 index 0000000000..7a18d63c53 --- /dev/null +++ b/doc/images/e1-archi.tex @@ -0,0 +1,73 @@ +\documentclass{standalone} +%\usepackage[tt=false]{libertine} +\renewcommand{\familydefault}{\sfdefault} +% improve for some encodings +\usepackage{textcomp} +\usepackage{tikz} +\usetikzlibrary{positioning} +\usetikzlibrary{shapes.symbols} +\usetikzlibrary{decorations.markings} +\usetikzlibrary{fit} + +\tikzset{splitpos/.store in=\splitpos,splitpos=0.5} +\newcommand{\ip}[1]{\texttt{#1}} + +\begin{document} +\begin{tikzpicture} + [ + font=\scriptsize, + node distance=1.5cm and 3.2cm, + entity/.style={ + rectangle, + draw, + inner sep=0pt, + minimum height=6mm,minimum width=11mm, + align=center + }, + split/.style={postaction={% + decorate, + decoration={ + markings,mark={ + at position \splitpos + with { + \draw (0pt,2.5pt) -- (0pt,-2.5pt); + } + } + } + } + }, + ip/.style={font=\tiny,outer sep=1pt,inner sep=1pt}, + ] + \node[entity] (cu-cp) {CU-CP}; + \node[entity,below=of cu-cp] (cu-up) {CU-UP}; + \node[entity,below left=0.45cm and 3.2cm of cu-cp] (du) {DU}; + \node[entity,right=of cu-cp] (amf) {AMF}; + \node[entity,right=of cu-up] (upf) {UPF}; + + \draw[split,splitpos=0.5] (cu-cp) -- + node[ip,at start, below right, align=left] {\ip{GNB\_IPV4\_ADDRESS\_FOR\_NG\_AMF:38412}} + node[above] {NG-C/N2} + %node[ip,at end, below left] {127.0.1.10/24} + (amf); + \draw[split,splitpos=0.5] (cu-up) -- + node[ip, at start, below right,align=left] {\ip{GNB\_IPV4\_ADDRESS\_FOR\_NGU:2152}} + node[above] {NG-U/N3} + %node[ip, at end, below left] {127.0.1.10/24} + (upf); + \draw[split,splitpos=0.5] (cu-cp) -- + node[ip, at start, below right] {\ip{ipv4\_cucp:38462}} + node[right] {E1AP} + node[ip, at end, above right] {\ip{ipv4\_cuup:38462}} + (cu-up); + \draw[split] (du.north east) -- + node[ip, at start, below right] {to \ip{remote\_n\_address:38472}} + node[above] {F1-C} + node[ip, at end, above left, align=right] {\ip{local\_s\_address:38472}} + (cu-cp); + \draw[split] (du.south east) -- + node[ip, at start, above right] {to \ip{remote\_n\_address:remote\_n\_portd}} + node[above] {F1-U} + node[ip, at end, below left, align=right] {\ip{local\_s\_address:local\_s\_portd}} + (cu-up); +\end{tikzpicture} +\end{document} diff --git a/docker/Dockerfile.base.rhel8.2 b/docker/Dockerfile.base.rhel8.2 index ae41956379..17a559379d 100644 --- a/docker/Dockerfile.base.rhel8.2 +++ b/docker/Dockerfile.base.rhel8.2 @@ -68,5 +68,5 @@ COPY . . RUN /bin/sh oaienv && \ cd cmake_targets && \ mkdir -p log && \ - ./build_oai -I -w USRP && \ + ./build_oai -I --install-optional-packages -w USRP && \ rm /etc/pki/entitlement/*pem diff --git a/docker/Dockerfile.base.ubuntu18 b/docker/Dockerfile.base.ubuntu18 index 1a19304c10..7cf2ecceaa 100644 --- a/docker/Dockerfile.base.ubuntu18 +++ b/docker/Dockerfile.base.ubuntu18 @@ -57,4 +57,4 @@ COPY . . RUN /bin/sh oaienv && \ cd cmake_targets && \ mkdir -p log && \ - ./build_oai -I -w USRP + ./build_oai -I -w USRP --install-optional-packages diff --git a/docker/Dockerfile.eNB.rhel8.2 b/docker/Dockerfile.eNB.rhel8.2 index 38c5d8ae49..8d9f3098d5 100644 --- a/docker/Dockerfile.eNB.rhel8.2 +++ b/docker/Dockerfile.eNB.rhel8.2 @@ -39,7 +39,6 @@ ENV TZ=Europe/Paris RUN yum update -y && \ yum install -y --enablerepo="ubi-8-codeready-builder" \ lksctp-tools \ - nettle \ tzdata \ procps-ng \ atlas \ diff --git a/docker/Dockerfile.eNB.ubuntu18 b/docker/Dockerfile.eNB.ubuntu18 index f2a6ee16ee..1c85eb1232 100644 --- a/docker/Dockerfile.eNB.ubuntu18 +++ b/docker/Dockerfile.eNB.ubuntu18 @@ -44,7 +44,6 @@ RUN apt-get update && \ tzdata \ procps \ libsctp1 \ - libnettle6 \ libblas3 \ libatlas3-base \ libconfig9 \ diff --git a/docker/Dockerfile.gNB.aw2s.rhel8.2 b/docker/Dockerfile.gNB.aw2s.rhel8.2 index 0f0c7f9c5c..bc86223130 100644 --- a/docker/Dockerfile.gNB.aw2s.rhel8.2 +++ b/docker/Dockerfile.gNB.aw2s.rhel8.2 @@ -52,7 +52,6 @@ RUN yum repolist --disablerepo=* && \ libX11 \ atlas \ lksctp-tools \ - nettle \ tzdata \ net-tools \ iputils \ diff --git a/docker/Dockerfile.gNB.rhel8.2 b/docker/Dockerfile.gNB.rhel8.2 index 33dc30bd8a..bb034dc099 100644 --- a/docker/Dockerfile.gNB.rhel8.2 +++ b/docker/Dockerfile.gNB.rhel8.2 @@ -44,7 +44,6 @@ RUN yum repolist --disablerepo=* && \ libX11 \ atlas \ lksctp-tools \ - nettle \ tzdata \ gdb \ python3 \ diff --git a/docker/Dockerfile.gNB.ubuntu18 b/docker/Dockerfile.gNB.ubuntu18 index 4ed4929891..681dd9d3d7 100644 --- a/docker/Dockerfile.gNB.ubuntu18 +++ b/docker/Dockerfile.gNB.ubuntu18 @@ -44,7 +44,6 @@ RUN apt-get update && \ procps \ libsctp1 \ tzdata \ - libnettle6 \ libblas3 \ libatlas3-base \ libconfig9 \ diff --git a/docker/Dockerfile.lteUE.rhel8.2 b/docker/Dockerfile.lteUE.rhel8.2 index de4a315ce4..e86d3d97b8 100644 --- a/docker/Dockerfile.lteUE.rhel8.2 +++ b/docker/Dockerfile.lteUE.rhel8.2 @@ -41,7 +41,6 @@ RUN yum update -y && \ yum install -y --enablerepo="ubi-8-codeready-builder" \ lksctp-tools \ procps-ng \ - nettle \ tzdata \ atlas \ gdb \ diff --git a/docker/Dockerfile.lteUE.ubuntu18 b/docker/Dockerfile.lteUE.ubuntu18 index 7f1b30c2c7..4175bab297 100644 --- a/docker/Dockerfile.lteUE.ubuntu18 +++ b/docker/Dockerfile.lteUE.ubuntu18 @@ -45,7 +45,6 @@ RUN apt-get update && \ tzdata \ procps \ libsctp1 \ - libnettle6 \ liblapacke \ libatlas3-base \ libconfig9 \ diff --git a/docker/Dockerfile.nr-cuup.ubuntu18 b/docker/Dockerfile.nr-cuup.ubuntu18 new file mode 100644 index 0000000000..94d1ff5ef7 --- /dev/null +++ b/docker/Dockerfile.nr-cuup.ubuntu18 @@ -0,0 +1,63 @@ +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Ubuntu18.04 +# +#--------------------------------------------------------------------- + +FROM ran-base:latest as gnb-base + +FROM ran-build:latest AS gnb-build + +RUN cp /oai-ran/docker/scripts/gnb_entrypoint.sh /oai-ran/docker/scripts/entrypoint.sh + +FROM ubuntu:bionic as oai-nr-cuup +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe + +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + libsctp1 \ + libconfig9 \ + openssl && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /opt/oai-gnb/bin +COPY --from=gnb-build \ + /oai-ran/cmake_targets/ran_build/build/nr-cuup \ + /oai-ran/docker/scripts/entrypoint.sh \ + ./ + +COPY --from=gnb-build \ + /oai-ran/cmake_targets/ran_build/build/librfsimulator.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ + /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /usr/local/lib/ + +# Create directory for configuration files +WORKDIR /opt/oai-gnb/etc + +WORKDIR /opt/oai-gnb +ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"] +CMD ["/opt/oai-gnb/bin/nr-cuup", "-O", "/opt/oai-gnb/etc/gnb.conf"] diff --git a/docker/Dockerfile.nrUE.rhel8.2 b/docker/Dockerfile.nrUE.rhel8.2 index 46281b687f..9fc3826a6d 100644 --- a/docker/Dockerfile.nrUE.rhel8.2 +++ b/docker/Dockerfile.nrUE.rhel8.2 @@ -41,7 +41,6 @@ RUN yum update -y && \ lksctp-tools \ procps-ng \ tzdata \ - nettle \ net-tools \ iputils \ iproute \ diff --git a/docker/Dockerfile.nrUE.ubuntu18 b/docker/Dockerfile.nrUE.ubuntu18 index 25379803c0..5fdf41ef2d 100644 --- a/docker/Dockerfile.nrUE.ubuntu18 +++ b/docker/Dockerfile.nrUE.ubuntu18 @@ -44,7 +44,6 @@ RUN apt-get update && \ libsctp1 \ procps \ tzdata \ - libnettle6 \ liblapacke \ libatlas3-base \ libconfig9 \ diff --git a/docker/Dockerfile.phySim.rhel8.2 b/docker/Dockerfile.phySim.rhel8.2 index c3f6d258b3..6abbd52832 100644 --- a/docker/Dockerfile.phySim.rhel8.2 +++ b/docker/Dockerfile.phySim.rhel8.2 @@ -46,7 +46,6 @@ FROM registry.access.redhat.com/ubi8/ubi:latest as oai-physim RUN yum update -y && \ yum install -y --enablerepo="ubi-8-codeready-builder" \ lksctp-tools \ - nettle \ tzdata \ atlas \ hostname \ @@ -101,7 +100,6 @@ WORKDIR /usr/bin/ COPY --from=phy-sim-build \ /usr/bin/killall \ /usr/bin/xmlstarlet \ - /usr/bin/svn \ ./ # Copy the relevant configuration files for phySim diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c new file mode 100644 index 0000000000..e2b2bdb50b --- /dev/null +++ b/executables/nr-cuup.c @@ -0,0 +1,160 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "common/utils/simple_executable.h" +#include "executables/softmodem-common.h" +#include "common/utils/ocp_itti/intertask_interface.h" +#include "openair3/ocp-gtpu/gtp_itf.h" +#include "openair2/E1AP/e1ap.h" +#include "common/ran_context.h" +#include "nfapi/oai_integration/vendor_ext.h" +#include "openair2/F1AP/f1ap_common.h" +#include "openair2/GNB_APP/gnb_config.h" + +RAN_CONTEXT_t RC; +THREAD_STRUCT thread_struct; +uint64_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +int asn1_xer_print; +int oai_exit = 0; +instance_t CUuniqInstance = 0; +RRC_release_list_t rrc_release_info; + +void exit_function(const char *file, const char *function, const int line, const char *s) +{ +} + +nfapi_mode_t nfapi_mod = -1; +void nfapi_setmode(nfapi_mode_t nfapi_mode) +{ + nfapi_mod = nfapi_mode; +} +nfapi_mode_t nfapi_getmode(void) +{ + return nfapi_mod; +} + +ngran_node_t get_node_type() +{ + return ngran_gNB_CUUP; +} + +rlc_op_status_t rlc_data_req(const protocol_ctxt_t *const pc, + const srb_flag_t sf, + const MBMS_flag_t mf, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t c, + const sdu_size_t size, + mem_block_t *const buf, + const uint32_t *const a, + const uint32_t *const b) +{ + abort(); + return 0; +} + +int nr_rlc_get_available_tx_space(const rnti_t rntiP, const logical_chan_id_t channel_idP) +{ + abort(); + return 0; +} + +void nr_rlc_bearer_init(NR_RLC_BearerConfig_t *RLC_BearerConfig, NR_RLC_BearerConfig__servedRadioBearer_PR rb_type) +{ + abort(); +} + +void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, NR_CellGroupConfig_t *cell_groupConfig_from_DU) +{ + abort(); +} + +void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChannelConfig) +{ + abort(); +} + +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, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list) +{ + abort(); + return 0; +} + +int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_pP, const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP) +{ + abort(); + return 0; +} + +void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config_pr) +{ + abort(); +} + +void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp) +{ + abort(); +} + +f1ap_cudu_inst_t *getCxt(F1_t isCU, instance_t instanceP) +{ + abort(); + return NULL; +} + +void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP) +{ + abort(); +} + +int main(int argc, char **argv) +{ + /// static configuration for NR at the moment + if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == NULL) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + logInit(); + set_softmodem_sighandler(); + itti_init(TASK_MAX, tasks_info); + int rc; + rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL); + AssertFatal(rc >= 0, "Create task for SCTP failed\n"); + rc = itti_create_task(TASK_GTPV1_U, gtpv1uTask, NULL); + AssertFatal(rc >= 0, "Create task for GTPV1U failed\n"); + rc = itti_create_task(TASK_CUUP_E1, E1AP_CUUP_task, NULL); + AssertFatal(rc >= 0, "Create task for CUUP E1 failed\n"); + pdcp_layer_init(); + MessageDef *msg = RCconfig_NR_CU_E1(true); + AssertFatal(msg != NULL, "Send init to task for E1AP UP failed\n"); + itti_send_msg_to_task(TASK_CUUP_E1, 0, msg); + + printf("TYPE TO TERMINATE\n"); + itti_wait_tasks_end(); + + logClean(); + printf("Bye.\n"); + return 0; +} diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 395f1bece3..d958e772a9 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -198,21 +198,14 @@ void rx_func(void *param) { } up_removed++; } - for (j = 0; j < NUMBER_OF_NR_PUCCH_MAX; j++) + + for (j = 0; j < gNB->max_nb_pucch; j++) if (gNB->pucch[j]->active > 0 && gNB->pucch[j]->pucch_pdu.rnti == rnti_to_remove[i]) { gNB->pucch[j]->active = 0; gNB->pucch[j]->pucch_pdu.rnti = 0; pucch_removed++; } -#if 0 - for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++) - gNB->pdcch_pdu[j].frame = -1; - for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++) - gNB->ul_pdcch_pdu[j].frame = -1; - for (j = 0; j < NUMBER_OF_NR_PRACH_MAX; j++) - gNB->prach_vars.list[j].frame = -1; -#endif } if (rnti_to_remove_count) LOG_W(NR_PHY, "to remove rnti_to_remove_count=%d, up_removed=%d down_removed=%d pucch_removed=%d\n", rnti_to_remove_count, up_removed, down_removed, pucch_removed); rnti_to_remove_count = 0; diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index d883777972..1c1813d3a1 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -68,7 +68,6 @@ unsigned short config_frames[4] = {2,9,11,13}; #include #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" @@ -78,6 +77,9 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "gnb_paramdef.h" #include #include "nfapi/oai_integration/vendor_ext.h" +#include "gnb_config.h" +#include "openair2/E1AP/e1ap_common.h" +#include "openair2/E1AP/e1ap_api.h" pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; @@ -293,16 +295,60 @@ void exit_function(const char *file, const char *function, const int line, const -int create_gNB_tasks(uint32_t gnb_nb) { +static int create_gNB_tasks(void) { + uint32_t gnb_nb = RC.nb_nr_inst; + uint32_t gnb_id_start = 0; + uint32_t gnb_id_end = gnb_id_start + gnb_nb; LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb); itti_wait_ready(1); + LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__); + + RCconfig_NR_L1(); + RCconfig_nr_prs(); + + if (RC.nb_nr_macrlc_inst>0) RCconfig_nr_macrlc(); + + LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst); + + if (RC.nb_nr_L1_inst>0) AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n"); + + AssertFatal (gnb_nb <= RC.nb_nr_inst, + "Number of gNB is greater than gNB defined in configuration file (%d/%d)!", + gnb_nb, RC.nb_nr_inst); + + LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst); + + RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *)); + LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc); + ngran_node_t node_type = get_node_type(); + for (int gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) { + RC.nrrrc[gnb_id] = (gNB_RRC_INST*)calloc(1,sizeof(gNB_RRC_INST)); + LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, gnb_id_end); + configure_nr_rrc(gnb_id); + } + + if (RC.nb_nr_inst > 0 && + !get_softmodem_params()->nsa && + !(node_type == ngran_gNB_DU)) { + // we start pdcp in both cuup (for drb) and cucp (for srb) + init_pdcp(); + } + + if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(node_type) + LOG_I(X2AP, "X2AP enabled \n"); + __attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end); + } + + /* For the CU case the gNB registration with the AMF might have to take place after the F1 setup, as the PLMN info + * can originate from the DU. Add check on whether x2ap is enabled to account for ENDC NSA scenario.*/ + if ((get_softmodem_params()->sa || is_x2ap_enabled()) && + !NODE_IS_DU(node_type)) { + /* Try to register each gNB */ + //registered_gnb = 0; + __attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end); + } if (gnb_nb > 0) { - /* Last task to create, others task must be ready before its start */ - /*if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { - LOG_E(GNB_APP, "Create task for gNB APP failed\n"); - return -1; - }*/ if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0) { LOG_E(SCTP, "Create task for SCTP failed\n"); return -1; @@ -317,7 +363,8 @@ int create_gNB_tasks(uint32_t gnb_nb) { } } - if (get_softmodem_params()->sa) { + if (get_softmodem_params()->sa && + !NODE_IS_DU(node_type)) { char* gnb_ipv4_address_for_NGU = NULL; uint32_t gnb_port_for_NGU = 0; @@ -330,9 +377,10 @@ int create_gNB_tasks(uint32_t gnb_nb) { for(int i = GNB_INTERFACE_NAME_FOR_NG_AMF_IDX; i <= GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX; i++) { if( NETParams[i].strptr == NULL) { - LOG_E(NGAP, "No AMF configuration in the file.\n"); + LOG_E(NGAP, "No AMF configuration in the file.\n"); + exit(1); } else { - LOG_D(NGAP, "Configuration in the file: %s.\n",*NETParams[i].strptr); + LOG_D(NGAP, "Configuration in the file: %s.\n",*NETParams[i].strptr); } } @@ -350,15 +398,26 @@ int create_gNB_tasks(uint32_t gnb_nb) { return -1; } - LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); - + LOG_I(NR_RRC, "Creating NR RRC gNB Task, that will also create TASKS\n"); if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); return -1; } - //Use check on x2ap to consider the NSA scenario and check for SA scenario - if(is_x2ap_enabled() || get_softmodem_params()->sa) { + // If CU + if (node_type == ngran_gNB_CU || node_type == ngran_gNB) { + MessageDef *msg = RCconfig_NR_CU_E1(false); + instance_t inst = 0; + createE1inst(UPtype, inst, &E1AP_SETUP_REQ(msg)); + cuup_init_n3(inst); + itti_free(TASK_UNKNOWN, msg); + getCxtE1(inst)->same_process = true; + ; + RC.nrrrc[gnb_id_start]->e1_inst = inst; // stupid instance !!!*/ + } + + //Use check on x2ap to consider the NSA scenario + if((is_x2ap_enabled() || get_softmodem_params()->sa) && (node_type != ngran_gNB_CUCP)) { if (itti_create_task (TASK_GTPV1_U, >pv1uTask, NULL) < 0) { LOG_E(GTPU, "Create task for GTPV1U failed\n"); return -1; @@ -508,7 +567,7 @@ void init_pdcp(void) { LINK_ENB_PDCP_TO_GTPV1U_BIT; if (!get_softmodem_params()->nsa) { - if (!NODE_IS_DU(RC.nrrrc[0]->node_type)) { + if (!NODE_IS_DU(get_node_type())) { pdcp_layer_init(); nr_pdcp_module_init(pdcp_initmask, 0); } @@ -586,7 +645,7 @@ int main( int argc, char **argv ) { // don't create if node doesn't connect to RRC/S1/GTP if (NFAPI_MODE != NFAPI_MODE_PNF) { - int ret = create_gNB_tasks(1); + int ret = create_gNB_tasks(); AssertFatal(ret == 0, "cannot create ITTI tasks\n"); } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 815ca30611..5aeb8c76ea 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -102,6 +102,8 @@ int config_sync_var=-1; instance_t CUuniqInstance=0; instance_t DUuniqInstance=0; +int get_node_type() {return -1;} + RAN_CONTEXT_t RC; int oai_exit = 0; diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index cfed33b77d..559c90f3dc 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -1219,8 +1219,8 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, if (tx_data != NULL) { uint8_t *dlsch_sdu = (uint8_t *)tx_data->TLVs[0].value.direct; //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols); - AssertFatal(msgTx->num_pdsch_slot < gNB->number_of_nr_dlsch_max,"Number of PDSCH PDUs %d exceeded the limit %d\n", - msgTx->num_pdsch_slot,gNB->number_of_nr_dlsch_max); + AssertFatal(msgTx->num_pdsch_slot < NUMBER_OF_NR_DLSCH_MAX,"Number of PDSCH PDUs %d exceeded the limit %d\n", + msgTx->num_pdsch_slot, NUMBER_OF_NR_DLSCH_MAX); handle_nr_nfapi_pdsch_pdu(msgTx, pdsch_pdu, dlsch_sdu); } else { diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 6f983f613c..b65068716b 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -134,7 +134,7 @@ int init_codebook_gNB(PHY_VARS_gNB *gNB) { int max_mimo_layers = (CSI_RS_antenna_portsnr_mimo_precoding_matrix = (int32_t ***)malloc16(max_mimo_layers* sizeof(int32_t **)); + gNB->nr_mimo_precoding_matrix = (int32_t ***)malloc16(max_mimo_layers * sizeof(int32_t **)); int32_t ***mat = gNB->nr_mimo_precoding_matrix; double complex res_code; @@ -489,9 +489,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) while(gNB->configured == 0) usleep(10000); - gNB->number_of_nr_dlsch_max = NUMBER_OF_NR_DLSCH_MAX; - gNB->number_of_nr_ulsch_max = NUMBER_OF_NR_ULSCH_MAX; - load_dftslib(); crcTableInit(); @@ -607,14 +604,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) //PRS init nr_init_prs(gNB); - for (int id=0; idnr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); - gNB->nr_srs_info[id]->srs_generated_signal = (int32_t**)malloc16_clear(MAX_NUM_NR_SRS_AP*sizeof(int32_t*)); - for(int ap=0; apnr_srs_info[id]->srs_generated_signal[ap] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - } - } - generate_ul_reference_signal_sequences(SHRT_MAX); /* Generate low PAPR type 1 sequences for PUSCH DMRS, these are used if transform precoding is enabled. */ @@ -623,6 +612,15 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) /// Transport init necessary for NR synchro init_nr_transport(gNB); + gNB->nr_srs_info = (nr_srs_info_t **)malloc16_clear(gNB->max_nb_srs * sizeof(nr_srs_info_t*)); + for (int id = 0; id < gNB->max_nb_srs; id++) { + gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); + gNB->nr_srs_info[id]->srs_generated_signal = (int32_t**)malloc16_clear(MAX_NUM_NR_SRS_AP*sizeof(int32_t*)); + for(int ap=0; apnr_srs_info[id]->srs_generated_signal[ap] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); + } + } + common_vars->txdataF = (int32_t **)malloc16(Ptx*sizeof(int32_t*)); common_vars->rxdataF = (int32_t **)malloc16(Prx*sizeof(int32_t*)); /* Do NOT allocate per-antenna txdataF/rxdataF: the gNB gets a pointer to the @@ -653,7 +651,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) int nb_re_pusch = N_RB_UL * NR_NB_SC_PER_RB; int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); - for (int ULSCH_id=0; ULSCH_idnumber_of_nr_ulsch_max; ULSCH_id++) { + for (int ULSCH_id = 0; ULSCH_id < NUMBER_OF_NR_ULSCH_MAX; ULSCH_id++) { pusch_vars[ULSCH_id] = (NR_gNB_PUSCH *)malloc16_clear( sizeof(NR_gNB_PUSCH) ); pusch_vars[ULSCH_id]->rxdataF_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); pusch_vars[ULSCH_id]->ul_ch_estimates = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); @@ -760,13 +758,14 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(nr_gold_csi_rs); free_and_zero(gNB->nr_csi_info); - for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) { + for (int id = 0; id < gNB->max_nb_srs; id++) { for(int i=0; inr_srs_info[id]->srs_generated_signal[i]); } free_and_zero(gNB->nr_srs_info[id]->srs_generated_signal); free_and_zero(gNB->nr_srs_info[id]); } + free_and_zero(gNB->nr_srs_info); free_ul_reference_signal_sequences(); free_gnb_lowpapr_sequences(); @@ -804,7 +803,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(prach_vars->prach_ifft); NR_gNB_PUSCH** pusch_vars = gNB->pusch_vars; - for (int ULSCH_id=0; ULSCH_idnumber_of_nr_ulsch_max; ULSCH_id++) { + for (int ULSCH_id = 0; ULSCH_id < NUMBER_OF_NR_ULSCH_MAX; ULSCH_id++) { for (int i=0; i< max_ul_mimo_layers; i++) free_and_zero(pusch_vars[ULSCH_id]->llr_layers[i]); for (int i = 0; i < Prx; i++) { @@ -982,8 +981,8 @@ void init_DLSCH_struct(PHY_VARS_gNB *gNB, processingData_L1tx_t *msg) { msg->num_pdsch_slot = 0; int num_cw = NR_MAX_NB_LAYERS > 4? 2:1; - for (int i=0; inumber_of_nr_dlsch_max; i++) { - LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH %d/%d\n",i,gNB->number_of_nr_dlsch_max); + for (int i = 0; i < NUMBER_OF_NR_DLSCH_MAX; i++) { + LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH %d/%d\n", i, NUMBER_OF_NR_DLSCH_MAX); for (int j=0; jdlsch[i][j] = new_gNB_dlsch(fp, grid_size); AssertFatal(msg->dlsch[i][j]!=NULL,"Can't initialize dlsch %d \n", i); @@ -997,30 +996,62 @@ void reset_DLSCH_struct(const PHY_VARS_gNB *gNB, processingData_L1tx_t *msg) const nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; const uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value; int num_cw = NR_MAX_NB_LAYERS > 4? 2:1; - for (int i=0; inumber_of_nr_dlsch_max; i++) + for (int i = 0; i < NUMBER_OF_NR_DLSCH_MAX; i++) for (int j=0; jdlsch[i][j], grid_size, fp); } -void init_nr_transport(PHY_VARS_gNB *gNB) { +void init_nr_transport(PHY_VARS_gNB *gNB) +{ + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + const nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; LOG_I(PHY, "Initialise nr transport\n"); - for (int i=0; icell_config.frame_duplex_type.value ? + fp->slots_per_frame / get_nb_periods_per_frame(cfg->tdd_table.tdd_period.value) : + fp->slots_per_frame; + int nb_ul_slots_period = 0; + if (cfg->cell_config.frame_duplex_type.value) { + for(int i=0; itdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[j].slot_config.value == 1) { // UL symbol + nb_ul_slots_period++; + break; + } + } + } + } + else + nb_ul_slots_period = fp->slots_per_frame; + + int buffer_ul_slots; // the UL channels are scheduled sl_ahead before they are transmitted + int slot_ahead = gNB->if_inst ? gNB->if_inst->sl_ahead : 6; + if (slot_ahead > nb_slots_per_period) + buffer_ul_slots = nb_ul_slots_period + (slot_ahead - nb_slots_per_period); + else + buffer_ul_slots = (nb_ul_slots_period < slot_ahead) ? nb_ul_slots_period : slot_ahead; + + gNB->max_nb_pucch = MAX_MOBILES_PER_GNB * buffer_ul_slots; + gNB->max_nb_srs = buffer_ul_slots << 1; // assuming at most 2 SRS per slot + + gNB->pucch = (NR_gNB_PUCCH_t **) malloc16(gNB->max_nb_pucch * sizeof(NR_gNB_PUCCH_t*)); + for (int i = 0; i < gNB->max_nb_pucch; i++) { + LOG_I(PHY,"Allocating Transport Channel Buffers for PUCCH %d/%d\n", i, gNB->max_nb_pucch); gNB->pucch[i] = new_gNB_pucch(); - AssertFatal(gNB->pucch[i]!=NULL,"Can't initialize pucch %d \n", i); + AssertFatal(gNB->pucch[i] != NULL,"Can't initialize pucch %d \n", i); } - for (int i=0; isrs = (NR_gNB_SRS_t **) malloc16(gNB->max_nb_srs * sizeof(NR_gNB_SRS_t*)); + for (int i = 0; i < gNB->max_nb_srs; i++) { + LOG_I(PHY,"Allocating Transport Channel Buffers for SRS %d/%d\n", i, gNB->max_nb_srs); gNB->srs[i] = new_gNB_srs(); AssertFatal(gNB->srs[i]!=NULL,"Can't initialize srs %d \n", i); } - for (int i=0; inumber_of_nr_ulsch_max; i++) { + for (int i = 0; i < NUMBER_OF_NR_ULSCH_MAX; i++) { - LOG_I(PHY,"Allocating Transport Channel Buffers for ULSCH %d/%d\n",i,gNB->number_of_nr_ulsch_max); + LOG_I(PHY,"Allocating Transport Channel Buffers for ULSCH %d/%d\n", i, NUMBER_OF_NR_ULSCH_MAX); gNB->ulsch[i] = new_gNB_ulsch(gNB->max_ldpc_iterations, fp->N_RB_UL); @@ -1039,12 +1070,14 @@ void reset_nr_transport(PHY_VARS_gNB *gNB) { const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - for (int i = 0; i < NUMBER_OF_NR_PUCCH_MAX; i++) + for (int i = 0; i < gNB->max_nb_pucch; i++) free_gNB_pucch(gNB->pucch[i]); + free(gNB->pucch); - for (int i = 0; i < NUMBER_OF_NR_SRS_MAX; i++) + for (int i = 0; i < gNB->max_nb_srs; i++) free_gNB_srs(gNB->srs[i]); + free(gNB->srs); - for (int i=0; inumber_of_nr_ulsch_max; i++) + for (int i = 0; i < NUMBER_OF_NR_ULSCH_MAX; i++) free_gNB_ulsch(&gNB->ulsch[i], fp->N_RB_UL); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index fa3c961a29..9b6adb8702 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -582,6 +582,6 @@ void dump_pdsch_stats(FILE *fd,PHY_VARS_gNB *gNB) { void clear_pdsch_stats(PHY_VARS_gNB *gNB) { - for (int i=0;inumber_of_nr_dlsch_max;i++) + for (int i = 0;i < NUMBER_OF_NR_SCH_STATS_MAX; i++) memset((void*)&gNB->dlsch_stats[i],0,sizeof(gNB->dlsch_stats[i])); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index b3d492d025..461f012687 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -39,20 +39,19 @@ extern uint16_t prach_root_sequence_map_abc[138]; extern uint16_t nr_du[838]; extern const char *prachfmt[]; -void init_prach_list(PHY_VARS_gNB *gNB) { - +void init_prach_list(PHY_VARS_gNB *gNB) +{ AssertFatal(gNB!=NULL,"gNB is null\n"); for (int i=0; iprach_vars.list[i].frame = -1; - gNB->prach_vars.list[i].slot = -1; - } + gNB->prach_vars.list[i].frame = -1; + gNB->prach_vars.list[i].slot = -1; + } } -void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id) { - +void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id) +{ gNB->prach_vars.list[prach_id].frame = -1; - gNB->prach_vars.list[prach_id].slot = -1; - + gNB->prach_vars.list[prach_id].slot = -1; } int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index e9fcd35f6b..9fb95ac273 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -40,7 +40,7 @@ int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { int16_t first_free_index=-1; AssertFatal(gNB!=NULL,"gNB is null\n"); - for (i=0; inumber_of_nr_ulsch_max; i++) { + for (i = 0; i < NUMBER_OF_NR_ULSCH_MAX; i++) { AssertFatal(gNB->ulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i); LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i]->harq_mask,gNB->ulsch[i]->rnti,first_free_index); if ((gNB->ulsch[i]->harq_mask >0) && @@ -60,7 +60,7 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE); - AssertFatal( (ulsch_id>=0) && (ulsch_idnumber_of_nr_ulsch_max), + AssertFatal((ulsch_id >= 0) && (ulsch_id < NUMBER_OF_NR_ULSCH_MAX), "illegal or no ulsch_id found!!! rnti %04x ulsch_id %d\n",ulsch_pdu->rnti,ulsch_id); NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ulsch_id]; @@ -121,7 +121,7 @@ void nr_ulsch_layer_demapping(int16_t *llr_cw, void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB) { - for (int i=0;inumber_of_nr_ulsch_max;i++) { + for (int i = 0;i < NUMBER_OF_NR_SCH_STATS_MAX;i++) { if (gNB->ulsch_stats[i].rnti>0 && gNB->ulsch_stats[i].frame != gNB->ulsch_stats[i].dump_frame) { gNB->ulsch_stats[i].dump_frame = gNB->ulsch_stats[i].frame; @@ -155,14 +155,14 @@ void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB) { void clear_pusch_stats(PHY_VARS_gNB *gNB) { - for (int i=0;inumber_of_nr_ulsch_max;i++) + for (int i = 0; i < NUMBER_OF_NR_ULSCH_MAX; i++) memset((void*)&gNB->ulsch_stats[i],0,sizeof(gNB->ulsch_stats[i])); } NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch) { NR_gNB_SCH_STATS_t *stats=NULL; int first_free=-1; - for (int i=0;inumber_of_nr_ulsch_max;i++) { + for (int i = 0; i < NUMBER_OF_NR_ULSCH_MAX; i++) { if (gNB->ulsch_stats[i].rnti == 0 && first_free == -1) { first_free = i; stats=&gNB->ulsch_stats[i]; diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 905e03801c..03ed927c37 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -70,20 +70,21 @@ void free_gNB_pucch(NR_gNB_PUCCH_t *pucch) int nr_find_pucch(uint16_t rnti, int frame, int slot, - PHY_VARS_gNB *gNB) { + PHY_VARS_gNB *gNB) +{ AssertFatal(gNB!=NULL,"gNB is null\n"); int index = -1; - for (int i = 0; i < NUMBER_OF_NR_PUCCH_MAX; i++) { + for (int i = 0; i < gNB->max_nb_pucch; i++) { AssertFatal(gNB->pucch[i] != NULL,"gNB->pucch[%d] is null\n",i); if ((gNB->pucch[i]->active > 0) && (gNB->pucch[i]->pucch_pdu.rnti == rnti) && (gNB->pucch[i]->frame == frame) && (gNB->pucch[i]->slot == slot)) - return(i); + return i; else if ((gNB->pucch[i]->active == 0) && (index == -1)) - index=i; + index = i; } if (index==-1) @@ -95,11 +96,13 @@ int nr_find_pucch(uint16_t rnti, void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, - nfapi_nr_pucch_pdu_t *pucch_pdu) { + nfapi_nr_pucch_pdu_t *pucch_pdu) +{ + if (NFAPI_MODE == NFAPI_MODE_PNF) gNB->pucch[0]->active = 0; //check if ture in monolithic mode int id = nr_find_pucch(pucch_pdu->rnti,frame,slot,gNB); - AssertFatal((id >= 0) && (id < NUMBER_OF_NR_PUCCH_MAX), + AssertFatal((id >= 0) && (id < gNB->max_nb_pucch), "invalid id found for pucch !!! rnti %04x id %d\n",pucch_pdu->rnti,id); NR_gNB_PUCCH_t *pucch = gNB->pucch[id]; diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index 5d855ae6b5..7c0e241af8 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -64,7 +64,7 @@ int nr_find_srs(rnti_t rnti, AssertFatal(gNB!=NULL,"gNB is null\n"); int index = -1; - for (int i=0; imax_nb_srs; i++) { AssertFatal(gNB->srs[i]!=NULL,"gNB->srs[%d] is null\n",i); if ((gNB->srs[i]->active>0) && (gNB->srs[i]->srs_pdu.rnti==rnti) && @@ -85,8 +85,8 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, nfapi_nr_srs_pdu_t *srs_pdu) { int id = nr_find_srs(srs_pdu->rnti,frame,slot,gNB); - AssertFatal( (id>=0) && (idrnti,id); + AssertFatal((id >= 0) && (id < gNB->max_nb_srs), + "invalid id found for srs !!! rnti %04x id %d\n",srs_pdu->rnti,id); NR_gNB_SRS_t *srs = gNB->srs[id]; srs->frame = frame; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 0f2f41c470..469218addc 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -617,16 +617,15 @@ typedef struct PHY_VARS_gNB_s { nfapi_nr_ul_tti_request_t UL_tti_req; nfapi_nr_uci_indication_t uci_indication; + int max_nb_pucch; + int max_nb_srs; NR_gNB_PBCH pbch; NR_gNB_COMMON common_vars; NR_gNB_PRACH prach_vars; NR_gNB_PRS prs_vars; NR_gNB_PUSCH *pusch_vars[NUMBER_OF_NR_ULSCH_MAX]; - NR_gNB_PUCCH_t *pucch[NUMBER_OF_NR_PUCCH_MAX]; - NR_gNB_SRS_t *srs[NUMBER_OF_NR_SRS_MAX]; - NR_gNB_PDCCH_t pdcch_pdu[NUMBER_OF_NR_PDCCH_MAX]; - NR_gNB_UL_PDCCH_t ul_pdcch_pdu[NUMBER_OF_NR_PDCCH_MAX]; - NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2]; // Nusers times two spatial streams + NR_gNB_PUCCH_t **pucch; + NR_gNB_SRS_t **srs; NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX]; // [Nusers times] /// statistics for DLSCH measurement collection NR_gNB_SCH_STATS_t dlsch_stats[NUMBER_OF_NR_SCH_STATS_MAX]; @@ -636,7 +635,7 @@ typedef struct PHY_VARS_gNB_s { t_nrPolar_params **polarParams; /// SRS variables - nr_srs_info_t *nr_srs_info[NUMBER_OF_NR_SRS_MAX]; + nr_srs_info_t **nr_srs_info; /// CSI variables nr_csi_info_t *nr_csi_info; @@ -763,8 +762,6 @@ typedef struct PHY_VARS_gNB_s { notifiedFIFO_t resp_RU_tx; tpool_t threadPool; int nbDecode; - int number_of_nr_dlsch_max; - int number_of_nr_ulsch_max; void *scopeData; /// structure for analyzing high-level RT measurements rt_L1_profiling_t rt_L1_profiling; @@ -827,7 +824,7 @@ typedef struct processingData_L1tx { PHY_VARS_gNB *gNB; nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu[NFAPI_NR_MAX_NB_CORESETS]; nfapi_nr_ul_dci_request_pdus_t ul_pdcch_pdu[NFAPI_NR_MAX_NB_CORESETS]; - NR_gNB_CSIRS_t csirs_pdu[NUMBER_OF_NR_CSIRS_MAX]; + NR_gNB_CSIRS_t csirs_pdu[NR_SYMBOLS_PER_SLOT]; NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2]; NR_gNB_SSB_t ssb[64]; uint16_t num_pdsch_slot; diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 49e6edd54e..b9f0d8e681 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -102,12 +102,12 @@ void handle_nr_nfapi_ssb_pdu(processingData_L1tx_t *msgTx,int frame,int slot, void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx, - int frame,int slot, - nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu) { + int frame,int slot, + nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu) { int found = 0; - for (int id=0; idcsirs_pdu[id]; if (csirs->active == 0) { LOG_D(PHY,"Frame %d Slot %d CSI_RS with ID %d is now active\n",frame,slot,id); @@ -203,8 +203,8 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ AssertFatal(TX_req->pdu_list[pduIndex].num_TLV == 1, "TX_req->pdu_list[%d].num_TLV %d != 1\n", pduIndex,TX_req->pdu_list[pduIndex].num_TLV); uint8_t *sdu = (uint8_t *)TX_req->pdu_list[pduIndex].TLVs[0].value.direct; - AssertFatal(msgTx->num_pdsch_slot < gNB->number_of_nr_dlsch_max,"Number of PDSCH PDUs %d exceeded the limit %d\n", - msgTx->num_pdsch_slot,gNB->number_of_nr_dlsch_max); + AssertFatal(msgTx->num_pdsch_slot < NUMBER_OF_NR_DLSCH_MAX,"Number of PDSCH PDUs %d exceeded the limit %d\n", + msgTx->num_pdsch_slot, NUMBER_OF_NR_DLSCH_MAX); handle_nr_nfapi_pdsch_pdu(msgTx,&dl_tti_pdu->pdsch_pdu, sdu); } } diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c index 25c39846fe..9ed7255a84 100644 --- a/openair1/SCHED_NR/phy_frame_config_nr.c +++ b/openair1/SCHED_NR/phy_frame_config_nr.c @@ -33,6 +33,7 @@ #include "PHY/defs_gNB.h" #include "PHY/defs_nr_UE.h" #include "SCHED_NR/phy_frame_config_nr.h" +#include "common/utils/nr/nr_common.h" /******************************************************************* * @@ -53,48 +54,13 @@ int set_tdd_config_nr( nfapi_nr_config_request_scf_t *cfg, int mu, int nrofDownlinkSlots, int nrofDownlinkSymbols, - int nrofUplinkSlots, int nrofUplinkSymbols) { + int nrofUplinkSlots, int nrofUplinkSymbols) +{ + int slot_number = 0; - int nb_periods_per_frame; + int nb_periods_per_frame = get_nb_periods_per_frame(cfg->tdd_table.tdd_period.value); int nb_slots_to_set = TDD_CONFIG_NB_FRAMES*(1<tdd_table.tdd_period.value) { - case 0: - nb_periods_per_frame = 20; // 10ms/0p5ms - break; - - case 1: - nb_periods_per_frame = 16; // 10ms/0p625ms - break; - - case 2: - nb_periods_per_frame = 10; // 10ms/1ms - break; - - case 3: - nb_periods_per_frame = 8; // 10ms/1p25ms - break; - - case 4: - nb_periods_per_frame = 5; // 10ms/2ms - break; - - case 5: - nb_periods_per_frame = 4; // 10ms/2p5ms - break; - - case 6: - nb_periods_per_frame = 2; // 10ms/5ms - break; - - case 7: - nb_periods_per_frame = 1; // 10ms/10ms - break; - - default: - AssertFatal(1==0,"Undefined tdd period %d\n", cfg->tdd_table.tdd_period.value); - } - int nb_slots_per_period = ((1<csirs_pdu[i]; if (csirs->active == 1) { LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot); @@ -529,7 +529,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { } } - for (int i=0;imax_nb_pucch; i++){ NR_gNB_PUCCH_t *pucch = gNB->pucch[i]; if (pucch) { if ((pucch->active == 1) && @@ -552,7 +552,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { } } - for (int ULSCH_id=0;ULSCH_idnumber_of_nr_ulsch_max;ULSCH_id++) { + for (int ULSCH_id = 0; ULSCH_id < NUMBER_OF_NR_ULSCH_MAX; ULSCH_id++) { NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id]; int harq_pid; NR_UL_gNB_HARQ_t *ulsch_harq; @@ -582,7 +582,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { } } - for (int i=0;imax_nb_srs; i++) { NR_gNB_SRS_t *srs = gNB->srs[i]; if (srs) { if ((srs->active == 1) && (srs->frame == frame_rx) && (srs->slot == slot_rx)) { @@ -713,7 +713,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { start_meas(&gNB->phy_proc_rx); - for (int i=0;imax_nb_pucch; i++){ NR_gNB_PUCCH_t *pucch = gNB->pucch[i]; if (pucch) { if (NFAPI_MODE == NFAPI_MODE_PNF) @@ -775,7 +775,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { } } - for (int ULSCH_id=0;ULSCH_idnumber_of_nr_ulsch_max;ULSCH_id++) { + for (int ULSCH_id = 0; ULSCH_id < NUMBER_OF_NR_ULSCH_MAX; ULSCH_id++) { NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id]; NR_UL_gNB_HARQ_t *ulsch_harq; @@ -870,7 +870,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { } } - for (int i = 0; i < NUMBER_OF_NR_SRS_MAX; i++) { + for (int i = 0; i < gNB->max_nb_srs; i++) { NR_gNB_SRS_t *srs = gNB->srs[i]; if (srs) { if ((srs->active == 1) && (srs->frame == frame_rx) && (srs->slot == slot_rx)) { diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index c4ff82c22b..3823fae4d7 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -49,7 +49,6 @@ #include "PHY/MODULATION/modulation_common.h" #include "PHY/MODULATION/modulation_eNB.h" #include "PHY/MODULATION/modulation_UE.h" -#include "PHY/TOOLS/lte_phy_scope.h" #include "SCHED/sched_eNB.h" #include "SCHED_UE/sched_UE.h" #include "SIMULATION/TOOLS/sim.h" @@ -493,7 +492,6 @@ int test_perf=0; int n_frames; int n_ch_rlz = 1; int rx_sample_offset = 0; -int xforms=0; int dump_table=0; int loglvl=OAILOG_INFO; int mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0; @@ -565,8 +563,6 @@ int main(int argc, char **argv) { short *uncoded_ber_bit=NULL; int osf=1; frame_t frame_type = FDD; - FD_lte_phy_scope_ue *form_ue = NULL; - char title[255]; int numCCE=0; //int dci_length_bytes=0,dci_length=0; //double channel_bandwidth = 5.0, sampling_rate=7.68; @@ -679,7 +675,6 @@ int main(int argc, char **argv) { { "uEdual", "Enables the Interference Aware Receiver for TM5 (default is normal receiver)",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, { "xTransmission","Transmission mode (1,2,6,7 for the moment)",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, { "yn_tx_phy","Number of TX antennas used in eNB",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, - { "XForms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms, defintval:0, TYPE_INT, 0 }, { "Yperfect_ce","Perfect CE", PARAMFLAG_BOOL, iptr:&perfect_ce, defintval:0, TYPE_INT, 0 }, { "Zdump", "dump table",PARAMFLAG_BOOL, iptr:&dump_table, defintval:0, TYPE_INT, 0 }, { "Loglvl", "log level",0, iptr:&loglvl, defintval:OAILOG_INFO, TYPE_INT, 0 }, @@ -952,24 +947,6 @@ int main(int argc, char **argv) { AssertFatal(NB_RB <= N_RB_DL,"illegal NB_RB %d\n",NB_RB); } - if (xforms==1) { - fl_initialize (&argc, argv, NULL, 0, 0); - form_ue = create_lte_phy_scope_ue(); - sprintf (title, "LTE PHY SCOPE eNB"); - fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - - if (!dual_stream_UE==0) { - if (UE) { - UE->use_ia_receiver = 1; - fl_set_button(form_ue->button_0,1); - fl_set_object_label(form_ue->button_0, "IA Receiver ON"); - fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN); - } else { - printf("UE is NULL\n"); - exit(-1); - } - } - } if (transmission_mode==5) { n_users = 2; @@ -1792,13 +1769,6 @@ int main(int argc, char **argv) { // UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round++; } - if (xforms==1) { - phy_scope_UE(form_ue, - UE, - eNB_id, - 0,// UE_id - subframe); - } UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++; } //round diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index c03d081387..7c75c27378 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -42,7 +42,6 @@ #include "PHY/INIT/phy_init.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" -#include "PHY/TOOLS/lte_phy_scope.h" #include "SCHED/sched_eNB.h" #include "SCHED_UE/sched_UE.h" #include "SIMULATION/TOOLS/sim.h" @@ -69,18 +68,15 @@ double cpuf; #include channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX]; channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX]; -//Added for PHY abstractionopenair1/PHY/TOOLS/lte_phy_scope.h node_desc_t *enb_data[NUMBER_OF_eNB_MAX]; node_desc_t *ue_data[NUMBER_OF_UE_MAX]; //double sinr_bler_map[MCS_COUNT][2][16]; extern uint16_t beta_ack[16],beta_ri[16],beta_cqi[16]; //extern char* namepointer_chMag ; -int xforms=0; THREAD_STRUCT thread_struct; nfapi_ue_release_request_body_t release_rntis; -FD_lte_phy_scope_enb *form_enb; char title[255]; /*the following parameters are used to control the processing times*/ @@ -435,7 +431,6 @@ int main(int argc, char **argv) { { "delay_chan", "Channel delay",0, iptr:&delay, defintval:0, TYPE_INT, 0 }, { "Doppler", "Maximum doppler shift",0, dblptr:&maxDoppler, defdblval:0.0, TYPE_DOUBLE, 0 }, { "Zdump", "dump table",PARAMFLAG_BOOL, iptr:&dump_table, defintval:0, TYPE_INT, 0 }, - { "Forms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms, defintval:0, TYPE_INT, 0 }, { "Lparallel", "Enable parallel execution",0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0 }, { "Iterations", "Number of iterations of turbo decoder", 0, iptr:&max_turbo_iterations, defintval:4, TYPE_INT, 0 }, { "Performance", "Display CPU perfomance of each L1 piece", PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0 }, @@ -695,13 +690,6 @@ int main(int argc, char **argv) { fprintf(csv_fdUL,"data_all%d=[",mcs); } - if (xforms==1) { - fl_initialize (&argc, argv, NULL, 0, 0); - form_enb = create_lte_phy_scope_enb(); - sprintf (title, "LTE PHY SCOPE eNB"); - fl_show_form (form_enb->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - } - UE->pdcch_vars[0][0]->crnti = 14; UE->frame_parms.soundingrs_ul_config_common.enabled_flag = srs_flag; UE->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2; @@ -1265,9 +1253,6 @@ int main(int argc, char **argv) { if ((errs[0]>=100) && (trials>(n_frames/2))) break; - if (xforms==1) - phy_scope_eNB(form_enb,eNB,0); - double t_tx = inMicroS(UE->phy_proc_tx.p_time); double t_tx_ifft = inMicroS(UE->ofdm_mod_stats.p_time); double t_tx_mod = inMicroS(UE->ulsch_modulation_stats.p_time); diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index bacd100114..f5de60a297 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -366,6 +366,8 @@ int main(int argc, char **argv) frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; crcTableInit(); nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell,SSB_positions); + gNB->gNB_config.tdd_table.tdd_period.value = 6; + set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4); phy_init_nr_gNB(gNB); //init_eNB_afterRU(); frame_length_complex_samples = frame_parms->samples_per_subframe; @@ -612,6 +614,11 @@ int main(int argc, char **argv) reset_DLSCH_struct(gNB, &msgDataTx); + int nb_slots_to_set = TDD_CONFIG_NB_FRAMES * (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + for (int i = 0; i < nb_slots_to_set; ++i) + free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list); + free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list); + phy_free_nr_gNB(gNB); free(RC.gNB[0]); free(RC.gNB); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index da5bbbffdf..9b6db46aa8 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -81,8 +81,6 @@ const char *__asan_default_options() return "detect_leaks=0"; } -LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; - PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; @@ -100,22 +98,6 @@ nfapi_ue_release_request_body_t release_rntis; //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; -teid_t newGtpuCreateTunnel(instance_t instance, - ue_id_t ue_id, - int incoming_bearer_id, - int outgoing_bearer_id, - teid_t outgoing_teid, - int qfi, - transport_layer_addr_t remoteAddr, - int port, - gtpCallback callBack, - gtpCallbackSDAP callBackSDAP) { - return 0; -} - -int newGtpuDeleteAllTunnels(instance_t instance, ue_id_t ue_id) { - return 0; -} // dummy functions int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } @@ -158,59 +140,6 @@ rrc_data_ind( { } -int -gtpv1u_create_s1u_tunnel( - const instance_t instanceP, - const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP, - gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP -) { - return 0; -} - -int -rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( - const protocol_ctxt_t *const ctxt_pP, - const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, - uint8_t *inde_list -) { - return 0; -} - -int -gtpv1u_create_ngu_tunnel( - const instance_t instanceP, - const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP, - gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP){ - return 0; -} - -int -gtpv1u_update_ngu_tunnel( - const instance_t instanceP, - const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, - const ue_id_t prior_ue_id -){ - return 0; -} - -int gtpv1u_delete_s1u_tunnel(const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP) { - return 0; -} - -int gtpv1u_delete_ngu_tunnel( const instance_t instance, - gtpv1u_gnb_delete_tunnel_req_t *req) { - return 0; -} - -int -nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( - const protocol_ctxt_t *const ctxt_pP, - const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, - uint8_t *inde_list -){ - return 0; -} - int nr_derive_key(int alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t **out) { diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 2cbe2ae97f..42fa279018 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -471,6 +471,8 @@ int main(int argc, char **argv) frame_parms->freq_range = mu<2 ? nr_FR1 : nr_FR2; nr_phy_config_request_sim_pbchsim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); + gNB->gNB_config.tdd_table.tdd_period.value = 6; + set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4); phy_init_nr_gNB(gNB); frame_parms->ssb_start_subcarrier = 12 * gNB->gNB_config.ssb_table.ssb_offset_point_a.value + ssb_subcarrier_offset; @@ -817,6 +819,11 @@ int main(int argc, char **argv) free_channel_desc_scm(gNB2UE); + int nb_slots_to_set = TDD_CONFIG_NB_FRAMES * (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + for (int i = 0; i < nb_slots_to_set; ++i) + free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list); + free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list); + phy_free_nr_gNB(gNB); free(RC.gNB[0]); free(RC.gNB); diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index f0ac036926..1e211b7eb7 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -58,7 +58,9 @@ #define NR_PRACH_DEBUG 1 #define PRACH_WRITE_OUTPUT_DEBUG 1 -LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; +THREAD_STRUCT thread_struct; +char *parallel_config = NULL; +char *worker_config = NULL; char *uecap_file; PHY_VARS_gNB *gNB; @@ -91,22 +93,6 @@ int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { return(0); //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; -teid_t newGtpuCreateTunnel(instance_t instance, - ue_id_t ue_id, - int incoming_bearer_id, - int outgoing_bearer_id, - teid_t outgoing_teid, - int qfi, - transport_layer_addr_t remoteAddr, - int port, - gtpCallback callBack, - gtpCallbackSDAP callBackSDAP) { - return 0; -} - -int newGtpuDeleteAllTunnels(instance_t instance, ue_id_t ue_id) { - return 0; -} void rrc_data_ind( @@ -118,59 +104,6 @@ rrc_data_ind( { } -int -gtpv1u_create_s1u_tunnel( - const instance_t instanceP, - const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP, - gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP -) { - return 0; -} - -int -rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( - const protocol_ctxt_t *const ctxt_pP, - const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, - uint8_t *inde_list -) { - return 0; -} - -int -gtpv1u_create_ngu_tunnel( - const instance_t instanceP, - const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP, - gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP){ - return 0; -} - -int -gtpv1u_update_ngu_tunnel( - const instance_t instanceP, - const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, - const ue_id_t prior_ue_id -){ - return 0; -} - -int gtpv1u_delete_s1u_tunnel(const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP) { - return 0; -} - -int gtpv1u_delete_ngu_tunnel( const instance_t instance, - gtpv1u_gnb_delete_tunnel_req_t *req) { - return 0; -} - -int -nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( - const protocol_ctxt_t *const ctxt_pP, - const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, - uint8_t *inde_list -){ - return 0; -} - int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, @@ -671,9 +604,9 @@ int main(int argc, char **argv){ memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config)); RC.nb_nr_L1_inst=1; + set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4); phy_init_nr_gNB(gNB); nr_phy_init_RU(ru); - set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4); // Configure UE UE = malloc(sizeof(PHY_VARS_NR_UE)); diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index ca29219e31..498b31ec8f 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -404,6 +404,8 @@ int main(int argc, char **argv) cfg->carrier_config.num_tx_ant.value = n_tx; cfg->carrier_config.num_rx_ant.value = n_rx; nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); + gNB->gNB_config.tdd_table.tdd_period.value = 6; + set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4); phy_init_nr_gNB(gNB); /* RU handles rxdataF, and gNB just has a pointer. Here, we don't have an RU, * so we need to allocate that memory as well. */ @@ -721,6 +723,11 @@ int main(int argc, char **argv) free_channel_desc_scm(UE2gNB); term_freq_channel(); + int nb_slots_to_set = TDD_CONFIG_NB_FRAMES * (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + for (int i = 0; i < nb_slots_to_set; ++i) + free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list); + free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list); + for (i = 0; i < n_rx; i++) free(gNB->common_vars.rxdataF[i]); phy_free_nr_gNB(gNB); diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 39ab2273e7..0227788877 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -418,7 +418,8 @@ int main(int argc, char **argv) gNB->frame_parms.nb_antennas_rx = n_rx; nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions); - + gNB->gNB_config.tdd_table.tdd_period.value = 6; + set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4); phy_init_nr_gNB(gNB); //configure UE @@ -639,6 +640,11 @@ int main(int argc, char **argv) free_nr_ue_ul_harq(UE->ul_harq_processes, NR_MAX_ULSCH_HARQ_PROCESSES, UE->frame_parms.N_RB_UL, UE->frame_parms.nb_antennas_tx); + int nb_slots_to_set = TDD_CONFIG_NB_FRAMES * (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + for (int i = 0; i < nb_slots_to_set; ++i) + free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list); + free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list); + term_nr_ue_signal(UE, 1); free(UE); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 11c131a5c2..fefae6581d 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -76,8 +76,6 @@ const char *__asan_default_options() return "detect_leaks=0"; } -LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; - PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; @@ -96,22 +94,6 @@ nfapi_ue_release_request_body_t release_rntis; //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; -teid_t newGtpuCreateTunnel(instance_t instance, - ue_id_t ue_id, - int incoming_bearer_id, - int outgoing_bearer_id, - teid_t outgoing_teid, - int qfi, - transport_layer_addr_t remoteAddr, - int port, - gtpCallback callBack, - gtpCallbackSDAP callBackSDAP) { - return 0; -} - -int newGtpuDeleteAllTunnels(instance_t instance, ue_id_t ue_id) { - return 0; -} extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration @@ -149,59 +131,6 @@ rrc_data_ind( } -int -gtpv1u_create_s1u_tunnel( - const instance_t instanceP, - const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP, - gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP -) { - return 0; -} - -int gtpv1u_delete_s1u_tunnel(const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP) { - return 0; -} - -int gtpv1u_delete_ngu_tunnel( const instance_t instance, - gtpv1u_gnb_delete_tunnel_req_t *req) { - return 0; -} - -int -rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( - const protocol_ctxt_t *const ctxt_pP, - const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, - uint8_t *inde_list -) { - return 0; -} - -int -gtpv1u_create_ngu_tunnel( - const instance_t instanceP, - const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP, - gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP){ - return 0; -} - -int -gtpv1u_update_ngu_tunnel( - const instance_t instanceP, - const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, - const ue_id_t prior_ue_id -){ - return 0; -} - -int -nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( - const protocol_ctxt_t *const ctxt_pP, - const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, - uint8_t *inde_list -){ - return 0; -} - // Dummy function to avoid linking error at compilation of nr-ulsim int is_x2ap_enabled(void) { @@ -318,7 +247,6 @@ int main(int argc, char **argv) int ldpc_offload_flag = 0; uint8_t max_rounds = 4; int chest_type[2] = {0}; - int enable_ptrs = 0; int modify_dmrs = 0; /* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */ diff --git a/openair2/COMMON/e1ap_messages_def.h b/openair2/COMMON/e1ap_messages_def.h new file mode 100644 index 0000000000..70533f8add --- /dev/null +++ b/openair2/COMMON/e1ap_messages_def.h @@ -0,0 +1,33 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* gNB_CUUP application layer -> E1AP messages */ +MESSAGE_DEF(E1AP_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_setup_req_t , e1ap_setup_req) + +/* E1AP -> eNB_DU or eNB_CU_RRC -> E1AP application layer messages */ +MESSAGE_DEF(E1AP_SETUP_RESP , MESSAGE_PRIORITY_MED, e1ap_setup_resp_t , e1ap_setup_resp) + +MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_setup_req) + +MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_RESP , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_resp_t , e1ap_bearer_setup_resp) + +MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_mod_req) + diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h new file mode 100644 index 0000000000..941d95b044 --- /dev/null +++ b/openair2/COMMON/e1ap_messages_types.h @@ -0,0 +1,226 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef E1AP_MESSAGES_TYPES_H +#define E1AP_MESSAGES_TYPES_H + +#include "f1ap_messages_types.h" +#include "ngap_messages_types.h" + +#define E1AP_MAX_NUM_TRANSAC_IDS 4 +#define E1AP_MAX_NUM_PLMNS 4 +#define E1AP_MAX_NUM_CELL_GROUPS 4 +#define E1AP_MAX_NUM_QOS_FLOWS 4 +#define E1AP_MAX_NUM_NGRAN_DRB 4 +#define E1AP_MAX_NUM_PDU_SESSIONS 4 +#define E1AP_MAX_NUM_DRBS 4 +#define E1AP_MAX_NUM_DRBS 4 +#define E1AP_MAX_NUM_UP_PARAM 4 + +#define E1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_req +#define E1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_resp +#define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req +#define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp +#define E1AP_BEARER_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req + +typedef f1ap_net_ip_address_t e1ap_net_ip_address_t; + +typedef struct PLMN_ID_s { + int mcc; + int mnc; + int mnc_digit_length; +} PLMN_ID_t; + +typedef struct e1ap_setup_req_s { + uint64_t gNB_cu_up_id; + char * gNB_cu_up_name; + int assoc_id; + uint64_t transac_id; + int supported_plmns; + PLMN_ID_t plmns[E1AP_MAX_NUM_PLMNS]; + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + uint16_t default_sctp_stream_id; + net_ip_address_t CUUP_e1_ip_address; + net_ip_address_t CUCP_e1_ip_address; + long cn_support; + uint16_t remotePortF1U; + char* localAddressF1U; + uint16_t localPortF1U; + char* localAddressN3; + uint16_t localPortN3; + uint16_t remotePortN3; +} e1ap_setup_req_t; + +typedef struct e1ap_setup_resp_s { + long transac_id; +} e1ap_setup_resp_t; + +typedef struct cell_group_s { + long id; +} cell_group_t; + +typedef struct up_params_s { + in_addr_t tlAddress; + long teId; + int cell_group_id; +} up_params_t; + +typedef struct drb_to_setup_s { + long drbId; + long pDCP_SN_Size_UL; + long pDCP_SN_Size_DL; + long rLC_Mode; + long qci; + long qosPriorityLevel; + long pre_emptionCapability; + long pre_emptionVulnerability; + in_addr_t tlAddress; + long teId; + int numCellGroups; + cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS]; +} drb_to_setup_t; + +typedef struct qos_flow_to_setup_s { + long id; + fiveQI_type_t fiveQI_type; + long fiveQI; + long qoSPriorityLevel; + long packetDelayBudget; + long packetError_scalar; + long packetError_exponent; + long priorityLevel; + long pre_emptionCapability; + long pre_emptionVulnerability; +} qos_flow_to_setup_t; + +typedef struct DRB_nGRAN_to_setup_s { + long id; + long defaultDRB; + long sDAP_Header_UL; + long sDAP_Header_DL; + long pDCP_SN_Size_UL; + long pDCP_SN_Size_DL; + long discardTimer; + long reorderingTimer; + long rLC_Mode; + in_addr_t tlAddress; + int teId; + int numDlUpParam; + up_params_t DlUpParamList[E1AP_MAX_NUM_UP_PARAM]; + int numCellGroups; + cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS]; + int numQosFlow2Setup; + qos_flow_to_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS]; +} DRB_nGRAN_to_setup_t; + +typedef struct pdu_session_to_setup_s { + long sessionId; + long sessionType; + int8_t sst; + long integrityProtectionIndication; + long confidentialityProtectionIndication; + in_addr_t tlAddress; + in_addr_t tlAddress_dl; + int32_t teId; + int32_t teId_dl; + int tl_port; + int tl_port_dl; + long numDRB2Setup; + DRB_nGRAN_to_setup_t DRBnGRanList[E1AP_MAX_NUM_NGRAN_DRB]; + long numDRB2Modify; + DRB_nGRAN_to_setup_t DRBnGRanModList[E1AP_MAX_NUM_NGRAN_DRB]; +} pdu_session_to_setup_t; + +typedef struct e1ap_bearer_setup_req_s { + uint32_t gNB_cu_cp_ue_id; + uint32_t gNB_cu_up_ue_id; + rnti_t rnti; + uint64_t cipheringAlgorithm; + uint64_t integrityProtectionAlgorithm; + char encryptionKey[128]; + char integrityProtectionKey[128]; + long ueDlAggMaxBitRate; + PLMN_ID_t servingPLMNid; + long activityNotificationLevel; + int numDRBs; + drb_to_setup_t DRBList[E1AP_MAX_NUM_DRBS]; + int numPDUSessions; + pdu_session_to_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS]; + int numPDUSessionsMod; + pdu_session_to_setup_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS]; +} e1ap_bearer_setup_req_t; + +typedef struct e1ap_bearer_release_cmd_s { + uint32_t gNB_cu_cp_ue_id; + uint32_t gNB_cu_up_ue_id; + long cause_type; + long cause; +} e1ap_bearer_release_cmd_t; + +typedef struct drb_setup_s { + int drbId; + in_addr_t tlAddress; + int teId; + int numUpParam; + up_params_t UpParamList[E1AP_MAX_NUM_UP_PARAM]; +} drb_setup_t; + +typedef struct qos_flow_setup_s { + long id; +} qos_flow_setup_t; + +typedef struct DRB_nGRAN_setup_s { + long id; + int numUpParam; + up_params_t UpParamList[E1AP_MAX_NUM_UP_PARAM]; + int numQosFlowSetup; + qos_flow_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS]; +} DRB_nGRAN_setup_t; + +typedef struct DRB_nGRAN_failed_s { + long id; + long cause_type; + long cause; +} DRB_nGRAN_failed_t; + +typedef struct pdu_session_setup_s { + long id; + in_addr_t tlAddress; + long teId; + int numDRBSetup; + DRB_nGRAN_setup_t DRBnGRanList[E1AP_MAX_NUM_NGRAN_DRB]; + int numDRBFailed; + DRB_nGRAN_failed_t DRBnGRanFailedList[E1AP_MAX_NUM_NGRAN_DRB]; +} pdu_session_setup_t; + +typedef struct e1ap_bearer_setup_resp_s { + uint64_t gNB_cu_cp_ue_id; + uint64_t gNB_cu_up_ue_id; + int numDRBs; + drb_setup_t DRBList[E1AP_MAX_NUM_DRBS]; + int numPDUSessions; + pdu_session_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS]; +} e1ap_bearer_setup_resp_t; + +#endif /* E1AP_MESSAGES_TYPES_H */ diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index 7c784a0c35..77e92f39bb 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -185,7 +185,7 @@ typedef struct gtpv1u_gnb_create_tunnel_resp_s { ue_id_t ue_id; int num_tunnels; teid_t gnb_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier - pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; + pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; transport_layer_addr_t gnb_addr; } gtpv1u_gnb_create_tunnel_resp_t; typedef struct gtpv1u_gnb_delete_tunnel_req_s { diff --git a/openair2/COMMON/messages_def.h b/openair2/COMMON/messages_def.h index 394b40eeed..8334700dd0 100644 --- a/openair2/COMMON/messages_def.h +++ b/openair2/COMMON/messages_def.h @@ -41,3 +41,4 @@ #include "sctp_messages_def.h" #include "udp_messages_def.h" #include "gtpv1_u_messages_def.h" +#include "e1ap_messages_def.h" diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 961599a9ed..70412e8368 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -274,9 +274,15 @@ typedef struct ngap_transport_layer_addr_s { dEST.length = sOURCE.length; \ } while (0) +typedef enum { + non_dynamic, + dynamic +} fiveQI_type_t; + typedef struct pdusession_level_qos_parameter_s { uint8_t qfi; uint64_t fiveQI; + fiveQI_type_t fiveQI_type; ngap_allocation_retention_priority_t allocation_retention_priority; } pdusession_level_qos_parameter_t; @@ -706,12 +712,21 @@ typedef struct ngap_pdusession_setup_req_s { /* gNB ue ngap id as initialized by NGAP layer */ uint32_t gNB_ue_ngap_id; + /* S-NSSAI */ + ngap_allowed_NSSAI_t allowed_nssai[8]; + /* Number of pdusession to be setup in the list */ uint8_t nb_pdusessions_tosetup; /* E RAB setup request */ pdusession_t pdusession_setup_params[NGAP_MAX_PDUSESSION]; + /* UE Uplink Aggregated Max Bitrates */ + uint64_t ueAggMaxBitRateUplink; + + /* UE Downlink Aggregated Max Bitrates */ + uint64_t ueAggMaxBitRateDownlink; + } ngap_pdusession_setup_req_t; typedef struct ngap_pdusession_setup_resp_s { diff --git a/openair2/E1AP/CMakeLists.txt b/openair2/E1AP/CMakeLists.txt index 89d87fe555..a8bacdd3fa 100644 --- a/openair2/E1AP/CMakeLists.txt +++ b/openair2/E1AP/CMakeLists.txt @@ -1,7 +1,7 @@ add_subdirectory(MESSAGES) -add_library(E1AP e1ap.c) -target_link_libraries(E1AP - PUBLIC asn1_e1ap - PRIVATE UTIL asn1_nr_rrc asn1_lte_rrc) -target_include_directories(E1AP PUBLIC ${CMAKE_CURRENT_DIR}) +add_library(e1ap e1ap.c e1ap_common.c e1ap_api.c) +target_link_libraries(e1ap + PUBLIC asn1_e1ap f1ap + PRIVATE asn1_nr_rrc asn1_lte_rrc asn1_f1ap UTIL e1_pdcp_if e1_if) +target_include_directories(e1ap PUBLIC ${CMAKE_CURRENT_DIR}) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index b49f4d4ca1..52043602e2 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -22,48 +22,87 @@ */ #include "e1ap.h" +#include "e1ap_common.h" +#include "e1ap_api.h" +#include "gnb_config.h" +#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h" +#include "openair3/UTILS/conversions.h" +#include "openair2/RRC/NR/MESSAGES/asn1_msg.h" +#include "common/openairinterface5g_limits.h" +#include "common/utils/LOG/log.h" +#include "openair2/F1AP/f1ap_common.h" +#include "e1ap_default_values.h" -int asn1_encoder_xer_print = 1; +#define E1AP_NUM_MSG_HANDLERS 14 +typedef int (*e1ap_message_processing_t)(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *message_p); +e1ap_message_processing_t e1ap_message_processing[E1AP_NUM_MSG_HANDLERS][3] = { -int e1ap_assoc_id(bool isCu, instance_t instance) { - return 0; + { 0, 0, 0 }, /* Reset */ + { 0, 0, 0 }, /* ErrorIndication */ + { 0, 0, 0 }, /* privateMessage */ + { e1apCUCP_handle_SETUP_REQUEST, e1apCUUP_handle_SETUP_RESPONSE, e1apCUUP_handle_SETUP_FAILURE }, /* gNBCUUPE1Setup */ + { 0, 0, 0 }, /* gNBCUCPE1Setup */ + { 0, 0, 0 }, /* gNBCUUPConfigurationUpdate */ + { 0, 0, 0 }, /* gNBCUCPConfigurationUpdate */ + { 0, 0, 0 }, /* E1Release */ + { e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST, e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE, e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE }, /* bearerContextSetup */ + { e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST, 0, 0 }, /* bearerContextModification */ + { 0, 0, 0 }, /* bearerContextModificationRequired */ + { e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND, e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE, 0 }, /* bearerContextRelease */ + { 0, 0, 0 }, /* bearerContextReleaseRequired */ + { 0, 0, 0 } /* bearerContextInactivityNotification */ +}; + +const char *e1ap_direction2String(int e1ap_dir) { + static const char *e1ap_direction_String[] = { + "", /* Nothing */ + "Initiating message", /* initiating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ + }; + return(e1ap_direction_String[e1ap_dir]); } -int e1ap_encode_send(bool isCu, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func) { - DevAssert(pdu != NULL); +int e1ap_handle_message(instance_t instance, uint32_t assoc_id, + const uint8_t *const data, const uint32_t data_length) { + E1AP_E1AP_PDU_t pdu= {0}; + int ret; + DevAssert(data != NULL); - if (asn1_encoder_xer_print) { - LOG_E(E1AP, "----------------- ASN1 ENCODER PRINT START ----------------- \n"); - xer_fprint(stdout, &asn_DEF_E1AP_E1AP_PDU, pdu); - LOG_E(E1AP, "----------------- ASN1 ENCODER PRINT END----------------- \n"); + if (e1ap_decode_pdu(&pdu, data, data_length) < 0) { + LOG_E(E1AP, "Failed to decode PDU\n"); + return -1; } - - char errbuf[2048]; /* Buffer for error message */ - size_t errlen = sizeof(errbuf); /* Size of the buffer */ - int ret = asn_check_constraints(&asn_DEF_E1AP_E1AP_PDU, pdu, errbuf, &errlen); - - if(ret) { - fprintf(stderr, "%s: Constraint validation failed: %s\n", func, errbuf); - } - - void *buffer = NULL; - ssize_t encoded = aper_encode_to_new_buffer(&asn_DEF_E1AP_E1AP_PDU, 0, pdu, buffer); - - if (encoded < 0) { - LOG_E(E1AP, "%s: Failed to encode E1AP message\n", func); + const E1AP_ProcedureCode_t procedureCode = pdu.choice.initiatingMessage->procedureCode; + /* Checking procedure Code and direction of message */ + if ((procedureCode >= E1AP_NUM_MSG_HANDLERS) || (pdu.present > E1AP_E1AP_PDU_PR_unsuccessfulOutcome) || (pdu.present <= E1AP_E1AP_PDU_PR_NOTHING)) { + LOG_E(E1AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", assoc_id, procedureCode, pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_E1AP_E1AP_PDU, &pdu); return -1; - } else { - MessageDef *message = itti_alloc_new_message(isCu?TASK_CUCP_E1:TASK_CUUP_E1, 0, SCTP_DATA_REQ); - sctp_data_req_t *s = &message->ittiMsg.sctp_data_req; - s->assoc_id = e1ap_assoc_id(isCu,instance); - s->buffer = buffer; - s->buffer_length = encoded; - s->stream = stream; - LOG_I(E1AP, "%s: Sending ITTI message to SCTP Task\n", func); - itti_send_msg_to_task(TASK_SCTP, instance, message); } - return encoded; + if (e1ap_message_processing[procedureCode][pdu.present - 1] == NULL) { + // No handler present. This can mean not implemented or no procedure for eNB (wrong direction). + LOG_E(E1AP, "[SCTP %d] No handler for procedureCode %ld in %s\n", assoc_id, procedureCode, e1ap_direction2String(pdu.present - 1)); + ret=-1; + } else { + /* Calling the right handler */ + LOG_I(E1AP, "Calling handler with instance %ld\n",instance); + ret = (*e1ap_message_processing[procedureCode][pdu.present - 1])(getCxtE1(instance), &pdu); + } + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_E1AP_E1AP_PDU, &pdu); + return ret; +} + +void e1_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) +{ + int result; + DevAssert(sctp_data_ind != NULL); + e1ap_handle_message(instance, sctp_data_ind->assoc_id, + sctp_data_ind->buffer, sctp_data_ind->buffer_length); + result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } void e1ap_itti_send_sctp_close_association(bool isCu, instance_t instance) { @@ -73,14 +112,16 @@ void e1ap_itti_send_sctp_close_association(bool isCu, instance_t instance) { itti_send_msg_to_task(TASK_SCTP, instance, message); } -int e1ap_send_RESET(bool isCu, instance_t instance, E1AP_Reset_t *Reset) { +int e1ap_send_RESET(bool isCu, e1ap_setup_req_t *setupReq, E1AP_Reset_t *Reset) +{ AssertFatal(false,"Not implemented yet\n"); E1AP_E1AP_PDU_t pdu= {0}; - return e1ap_encode_send(isCu, instance, &pdu,0, __func__); + return e1ap_encode_send(isCu, setupReq, &pdu, 0, __func__); } int e1ap_send_RESET_ACKNOWLEDGE(instance_t instance, E1AP_Reset_t *Reset) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1ap_handle_RESET(instance_t instance, @@ -88,6 +129,7 @@ int e1ap_handle_RESET(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1ap_handle_RESET_ACKNOWLEDGE(instance_t instance, @@ -95,6 +137,7 @@ int e1ap_handle_RESET_ACKNOWLEDGE(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } /* @@ -105,10 +148,12 @@ int e1ap_handle_ERROR_INDICATION(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1ap_send_ERROR_INDICATION(instance_t instance, E1AP_ErrorIndication_t *ErrorIndication) { AssertFatal(false,"Not implemented yet\n"); + return -1; } @@ -116,74 +161,316 @@ int e1ap_send_ERROR_INDICATION(instance_t instance, E1AP_ErrorIndication_t *Erro E1 Setup: can be sent on both ways, to be refined */ -int e1apCUUP_send_SETUP_REQUEST(instance_t instance, E1AP_Reset_t *Reset) { - AssertFatal(false,"Not implemented yet\n"); +static void fill_SETUP_REQUEST(e1ap_setup_req_t *setup, E1AP_E1AP_PDU_t *pdu) +{ + /* Create */ + /* 0. pdu Type */ + pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu->choice.initiatingMessage, initMsg); + initMsg->procedureCode = E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup; + initMsg->criticality = E1AP_Criticality_reject; + initMsg->value.present = E1AP_InitiatingMessage__value_PR_GNB_CU_UP_E1SetupRequest; + E1AP_GNB_CU_UP_E1SetupRequest_t *e1SetupUP = &initMsg->value.choice.GNB_CU_UP_E1SetupRequest; + /* mandatory */ + /* c1. Transaction ID (integer value) */ + asn1cSequenceAdd(e1SetupUP->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_TransactionID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_TransactionID; + setup->transac_id = E1AP_get_next_transaction_identifier(); + ieC1->value.choice.TransactionID = setup->transac_id; + LOG_I(E1AP, "Transaction ID of setup request %ld\n", setup->transac_id); + /* mandatory */ + /* c2. GNB_CU_ID (integer value) */ + asn1cSequenceAdd(e1SetupUP->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ieC2); + ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_ID; + ieC2->criticality = E1AP_Criticality_reject; + ieC2->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_GNB_CU_UP_ID; + asn_int642INTEGER(&ieC2->value.choice.GNB_CU_UP_ID, setup->gNB_cu_up_id); + /* mandatory */ + /* c4. CN Support */ + asn1cSequenceAdd(e1SetupUP->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ieC4); + ieC4->id = E1AP_ProtocolIE_ID_id_CNSupport; + ieC4->criticality = E1AP_Criticality_reject; + ieC4->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_CNSupport; + ieC4->value.choice.CNSupport = setup->cn_support; + + /* mandatory */ + /* c5. Supported PLMNs */ + asn1cSequenceAdd(e1SetupUP->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ieC5); + ieC5->id = E1AP_ProtocolIE_ID_id_SupportedPLMNs; + ieC5->criticality = E1AP_Criticality_reject; + ieC5->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_SupportedPLMNs_List; + + int numSupportedPLMNs = setup->supported_plmns; + + for (int i=0; i < numSupportedPLMNs; i++) { + asn1cSequenceAdd(ieC5->value.choice.SupportedPLMNs_List.list, E1AP_SupportedPLMNs_Item_t, supportedPLMN); + /* 5.1 PLMN Identity */ + MCC_MNC_TO_PLMNID(setup->plmns[i].mcc, setup->plmns[i].mnc, setup->plmns[i].mnc_digit_length, &supportedPLMN->pLMN_Identity); + } } -int e1apCUCP_send_SETUP_RESPONSE(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +static void fill_SETUP_RESPONSE(const e1ap_setup_resp_t *e1ap_setup_resp, E1AP_E1AP_PDU_t *pdu) +{ + /* Create */ + /* 0. pdu Type */ + pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome; + asn1cCalloc(pdu->choice.successfulOutcome, initMsg); + initMsg->procedureCode = E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup; + initMsg->criticality = E1AP_Criticality_reject; + initMsg->value.present = E1AP_SuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupResponse; + E1AP_GNB_CU_UP_E1SetupResponse_t *out = &pdu->choice.successfulOutcome->value.choice.GNB_CU_UP_E1SetupResponse; + /* mandatory */ + /* c1. Transaction ID (integer value) */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupResponseIEs_t, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_TransactionID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_GNB_CU_UP_E1SetupResponseIEs__value_PR_TransactionID; + ieC1->value.choice.TransactionID = e1ap_setup_resp->transac_id; } -int e1apCUCP_send_SETUP_FAILURE() { - AssertFatal(false,"Not implemented yet\n"); +void e1ap_send_SETUP_RESPONSE(instance_t inst, const e1ap_setup_resp_t *e1ap_setup_resp) +{ + AssertFatal(getCxtE1(inst), ""); + e1ap_setup_req_t *setupReq = &getCxtE1(inst)->setupReq; + E1AP_E1AP_PDU_t pdu = {0}; + fill_SETUP_RESPONSE(e1ap_setup_resp, &pdu); + e1ap_encode_send(getCxtE1(inst)->type, setupReq, &pdu, 0, __func__); } -int e1apCUCP_handle_SETUP_REQUEST(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); +static void fill_SETUP_FAILURE(long transac_id, E1AP_E1AP_PDU_t *pdu) +{ + /* Create */ + /* 0. pdu Type */ + pdu->present = E1AP_E1AP_PDU_PR_unsuccessfulOutcome; + asn1cCalloc(pdu->choice.unsuccessfulOutcome, initMsg); + initMsg->procedureCode = E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup; + initMsg->criticality = E1AP_Criticality_reject; + initMsg->value.present = E1AP_UnsuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupFailure; + E1AP_GNB_CU_UP_E1SetupFailure_t *out = &pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure; + /* mandatory */ + /* c1. Transaction ID (integer value) */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_TransactionID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_GNB_CU_UP_E1SetupResponseIEs__value_PR_TransactionID; + ieC1->value.choice.TransactionID = transac_id; + /* mandatory */ + /* c2. cause (integer value) */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ieC2); + ieC2->id = E1AP_ProtocolIE_ID_id_Cause; + ieC2->criticality = E1AP_Criticality_ignore; + ieC2->value.present = E1AP_GNB_CU_UP_E1SetupFailureIEs__value_PR_Cause; + ieC2->value.choice.Cause.present = E1AP_Cause_PR_radioNetwork; //choose this accordingly + ieC2->value.choice.Cause.choice.radioNetwork = E1AP_CauseRadioNetwork_unspecified; } -int e1apCUUP_handle_SETUP_RESPONSE(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); +void e1apCUCP_send_SETUP_FAILURE(e1ap_setup_req_t *setupReq, long transac_id) +{ + E1AP_E1AP_PDU_t pdu = {0}; + fill_SETUP_FAILURE(transac_id, &pdu); + e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__); } -int e1apCUUP_handle_SETUP_FAILURE(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); +void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, + e1ap_setup_req_t *req) { + E1AP_GNB_CU_UP_E1SetupRequestIEs_t *ie; + E1AP_GNB_CU_UP_E1SetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.GNB_CU_UP_E1SetupRequest; + /* assoc_id */ + /* req->assoc_id = assoc_id; */ + + /* transac_id */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_TransactionID, true); + req->transac_id = ie->value.choice.TransactionID; + LOG_D(E1AP, "gNB CU UP E1 setup request transaction ID: %ld\n", req->transac_id); + + /* gNB CU UP ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_gNB_CU_UP_ID, true); + asn_INTEGER2ulong(&ie->value.choice.GNB_CU_UP_ID, &req->gNB_cu_up_id); + LOG_D(E1AP, "gNB CU UP ID: %ld\n", req->gNB_cu_up_id); + + /* CN Support */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_CNSupport, true); + req->cn_support = ie->value.choice.CNSupport; + LOG_D(E1AP, "E1ap CN support: %ld\n", req->cn_support); + + /* Supported PLMNs */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_SupportedPLMNs, true); + req->supported_plmns = ie->value.choice.SupportedPLMNs_List.list.count; + LOG_D(E1AP, "Number of supported PLMNs: %d\n", req->supported_plmns); + + for (int i=0; i < req->supported_plmns; i++) { + E1AP_SupportedPLMNs_Item_t *supported_plmn_item = (E1AP_SupportedPLMNs_Item_t *)(ie->value.choice.SupportedPLMNs_List.list.array[i]); + + /* PLMN Identity */ + PLMNID_TO_MCC_MNC(&supported_plmn_item->pLMN_Identity, + req->plmns[i].mcc, + req->plmns[i].mnc, + req->plmns[i].mnc_digit_length); + LOG_D(E1AP, "MCC: %d\nMNC: %d\n", req->plmns[i].mcc, req->plmns[i].mnc); + } +} + +int e1apCUCP_handle_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + extract_SETUP_REQUEST(pdu, &inst->setupReq); + /* Create ITTI message and send to queue */ + MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, 0 /*unused by callee*/, E1AP_SETUP_REQ); + memcpy(&E1AP_SETUP_REQ(msg_p), &inst->setupReq, sizeof(e1ap_setup_req_t)); + + if (inst->setupReq.supported_plmns > 0) { + itti_send_msg_to_task(TASK_RRC_GNB, 0 /*unused by callee*/, msg_p); + } else { + e1apCUCP_send_SETUP_FAILURE(&inst->setupReq, inst->setupReq.transac_id); + itti_free(TASK_CUCP_E1, msg_p); + return -1; + } + + return 0; +} + +int e1apCUUP_handle_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) +{ + LOG_D(E1AP, "%s\n", __func__); + DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome); + DevAssert(pdu->choice.successfulOutcome->procedureCode == E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup); + DevAssert(pdu->choice.successfulOutcome->criticality == E1AP_Criticality_reject); + DevAssert(pdu->choice.successfulOutcome->value.present == E1AP_SuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupResponse); + const E1AP_GNB_CU_UP_E1SetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.GNB_CU_UP_E1SetupResponse; + E1AP_GNB_CU_UP_E1SetupResponseIEs_t *ie; + + /* transac_id */ + long transaction_id; + long old_transaction_id = inst->setupReq.transac_id; + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupResponseIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_TransactionID, true); + transaction_id = ie->value.choice.TransactionID; + LOG_D(E1AP, "gNB CU UP E1 setup response transaction ID: %ld\n", transaction_id); + + if (old_transaction_id != transaction_id) + LOG_E(E1AP, "Transaction IDs do not match %ld != %ld\n", old_transaction_id, transaction_id); + + E1AP_free_transaction_identifier(transaction_id); + + /* do the required processing */ + + return 0; +} + +int e1apCUUP_handle_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) +{ + E1AP_GNB_CU_UP_E1SetupFailureIEs_t *ie; + DevAssert(pdu != NULL); + E1AP_GNB_CU_UP_E1SetupFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure; + /* Transaction ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_TransactionID, true); + /* Cause */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_Cause, true); + + return 0; +} + +static void fill_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu) +{ + /* Create */ + /* 0. pdu Type */ + pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu->choice.initiatingMessage, msg); + msg->procedureCode = E1AP_ProcedureCode_id_gNB_CU_UP_ConfigurationUpdate; + msg->criticality = E1AP_Criticality_reject; + msg->value.present = E1AP_InitiatingMessage__value_PR_GNB_CU_UP_ConfigurationUpdate; + E1AP_GNB_CU_UP_ConfigurationUpdate_t *out = &pdu->choice.initiatingMessage->value.choice.GNB_CU_UP_ConfigurationUpdate; + /* mandatory */ + /* c1. Transaction ID (integer value) */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_ConfigurationUpdateIEs_t, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_TransactionID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_GNB_CU_UP_ConfigurationUpdateIEs__value_PR_TransactionID; + ieC1->value.choice.TransactionID = 0;//get this from stored transaction IDs in CU + /* mandatory */ + /* c2. Supported PLMNs */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_ConfigurationUpdateIEs_t, ieC2); + ieC2->id = E1AP_ProtocolIE_ID_id_SupportedPLMNs; + ieC2->criticality = E1AP_Criticality_reject; + ieC2->value.present = E1AP_GNB_CU_UP_ConfigurationUpdateIEs__value_PR_SupportedPLMNs_List; + + int numSupportedPLMNs = 1; + + for (int i=0; i < numSupportedPLMNs; i++) { + asn1cSequenceAdd(ieC2->value.choice.SupportedPLMNs_List.list, E1AP_SupportedPLMNs_Item_t, supportedPLMN); + /* 5.1 PLMN Identity */ + OCTET_STRING_fromBuf(&supportedPLMN->pLMN_Identity, "OAI", strlen("OAI")); + } + + /* mandatory */ + /* c3. TNLA to remove list */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_ConfigurationUpdateIEs_t, ieC3); + ieC3->id = E1AP_ProtocolIE_ID_id_GNB_CU_UP_TNLA_To_Remove_List; + ieC3->criticality = E1AP_Criticality_reject; + ieC3->value.present = E1AP_GNB_CU_UP_ConfigurationUpdateIEs__value_PR_GNB_CU_UP_TNLA_To_Remove_List; + + int numTNLAtoRemoveList = 1; + + for (int i=0; i < numTNLAtoRemoveList; i++) { + asn1cSequenceAdd(ieC2->value.choice.GNB_CU_UP_TNLA_To_Remove_List.list, E1AP_GNB_CU_UP_TNLA_To_Remove_Item_t, TNLAtoRemove); + TNLAtoRemove->tNLAssociationTransportLayerAddress.present = E1AP_CP_TNL_Information_PR_endpoint_IP_Address; + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &TNLAtoRemove->tNLAssociationTransportLayerAddress.choice.endpoint_IP_Address); // TODO: correct me + } } /* E1 configuration update: can be sent in both ways, to be refined */ -int e1apCUUP_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +void e1apCUUP_send_CONFIGURATION_UPDATE(e1ap_setup_req_t *setupReq) +{ + E1AP_E1AP_PDU_t pdu = {0}; + fill_CONFIGURATION_UPDATE(&pdu); + e1ap_encode_send(UPtype, setupReq, &pdu, 0, __func__); } -int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance) { +int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(e1ap_setup_req_t *setupReq) +{ AssertFatal(false,"Not implemented yet\n"); + return -1; } -int e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance) { +int e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(e1ap_setup_req_t *setupReq) +{ AssertFatal(false,"Not implemented yet\n"); + return -1; } -int e1apCUCP_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) { +int e1apCUCP_handle_CONFIGURATION_UPDATE(e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu) +{ + /* + E1AP_GNB_CU_UP_E1SetupRequestIEs_t *ie; + DevAssert(pdu != NULL); + E1AP_GNB_CU_UP_E1SetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.GNB_CU_UP_E1SetupRequest; + */ + AssertFatal(false,"Not implemented yet\n"); + return -1; } -int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) { +int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(e1ap_setup_req_t *setupReq, uint32_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) +{ AssertFatal(false,"Not implemented yet\n"); + return -1; } -int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) { +int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(e1ap_setup_req_t *setupReq, uint32_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) +{ AssertFatal(false,"Not implemented yet\n"); + return -1; } /* @@ -192,10 +479,12 @@ int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, int e1ap_send_RELEASE_REQUEST(instance_t instance) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1ap_send_RELEASE_ACKNOWLEDGE(instance_t instance) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1ap_handle_RELEASE_REQUEST(instance_t instance, @@ -203,6 +492,7 @@ int e1ap_handle_RELEASE_REQUEST(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1ap_handle_RELEASE_ACKNOWLEDGE(instance_t instance, @@ -210,66 +500,750 @@ int e1ap_handle_RELEASE_ACKNOWLEDGE(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } /* BEARER CONTEXT SETUP REQUEST */ -int e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_setup_req_t *setup, e1ap_bearer_setup_req_t *const bearerCxt, E1AP_E1AP_PDU_t *pdu) +{ + pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu->choice.initiatingMessage, msg); + msg->procedureCode = E1AP_ProcedureCode_id_bearerContextSetup; + msg->criticality = E1AP_Criticality_reject; + msg->value.present = E1AP_InitiatingMessage__value_PR_BearerContextSetupRequest; + E1AP_BearerContextSetupRequest_t *out = &pdu->choice.initiatingMessage->value.choice.BearerContextSetupRequest; + /* mandatory */ + /* c1. gNB-CU-UP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID; + ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = bearerCxt->gNB_cu_cp_ue_id; + /* mandatory */ + /* c2. Security Information */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC2); + ieC2->id = E1AP_ProtocolIE_ID_id_SecurityInformation; + ieC2->criticality = E1AP_Criticality_reject; + ieC2->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_SecurityInformation; + ieC2->value.choice.SecurityInformation.securityAlgorithm.cipheringAlgorithm = bearerCxt->cipheringAlgorithm; + OCTET_STRING_fromBuf(&ieC2->value.choice.SecurityInformation.uPSecuritykey.encryptionKey, + bearerCxt->encryptionKey, strlen(bearerCxt->encryptionKey)); + + asn1cCallocOne(ieC2->value.choice.SecurityInformation.securityAlgorithm.integrityProtectionAlgorithm, bearerCxt->integrityProtectionAlgorithm); + asn1cCalloc(ieC2->value.choice.SecurityInformation.uPSecuritykey.integrityProtectionKey, protKey); + OCTET_STRING_fromBuf(protKey, bearerCxt->integrityProtectionKey, strlen(bearerCxt->integrityProtectionKey)); + /* mandatory */ + /* c3. UE DL Aggregate Maximum Bit Rate */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC3); + ieC3->id = E1AP_ProtocolIE_ID_id_UEDLAggregateMaximumBitRate; + ieC3->criticality = E1AP_Criticality_reject; + ieC3->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_BitRate; + asn_long2INTEGER(&ieC3->value.choice.BitRate, bearerCxt->ueDlAggMaxBitRate); + /* mandatory */ + /* c4. Serving PLMN */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC4); + ieC4->id = E1AP_ProtocolIE_ID_id_Serving_PLMN; + ieC4->criticality = E1AP_Criticality_ignore; + ieC4->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_PLMN_Identity; + PLMN_ID_t *servingPLMN = setup->plmns; // First PLMN is serving PLMN. TODO: Remove hard coding here + MCC_MNC_TO_PLMNID(servingPLMN->mcc, servingPLMN->mnc, servingPLMN->mnc_digit_length, &ieC4->value.choice.PLMN_Identity); + /* mandatory */ + /* Activity Notification Level */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC5); + ieC5->id = E1AP_ProtocolIE_ID_id_ActivityNotificationLevel; + ieC5->criticality = E1AP_Criticality_reject; + ieC5->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_ActivityNotificationLevel; + ieC5->value.choice.ActivityNotificationLevel = E1AP_ActivityNotificationLevel_pdu_session;// TODO: Remove hard coding + /* mandatory */ + /* */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC6); + ieC6->id = E1AP_ProtocolIE_ID_id_System_BearerContextSetupRequest; + ieC6->criticality = E1AP_Criticality_reject; + ieC6->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_System_BearerContextSetupRequest; + ieC6->value.choice.System_BearerContextSetupRequest.present = E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest; + E1AP_ProtocolIE_Container_4932P19_t *msgNGRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P19_t)); + ieC6->value.choice.System_BearerContextSetupRequest.choice.nG_RAN_BearerContextSetupRequest = (struct E1AP_ProtocolIE_Container *) msgNGRAN_list; + asn1cSequenceAdd(msgNGRAN_list->list, E1AP_NG_RAN_BearerContextSetupRequest_t, msgNGRAN); + msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_List; + msgNGRAN->criticality = E1AP_Criticality_reject; + msgNGRAN->value.present = E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List; + E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2Setup = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List; + for(pdu_session_to_setup_t *i=bearerCxt->pduSession; i < bearerCxt->pduSession+bearerCxt->numPDUSessions; i++) { + asn1cSequenceAdd(pdu2Setup->list, E1AP_PDU_Session_Resource_To_Setup_Item_t, ieC6_1); + ieC6_1->pDU_Session_ID = i->sessionId; + ieC6_1->pDU_Session_Type = i->sessionType; + + INT8_TO_OCTET_STRING(i->sst, &ieC6_1->sNSSAI.sST); + + ieC6_1->securityIndication.integrityProtectionIndication = i->integrityProtectionIndication; + ieC6_1->securityIndication.confidentialityProtectionIndication = i->confidentialityProtectionIndication; + + ieC6_1->nG_UL_UP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel; + asn1cCalloc(ieC6_1->nG_UL_UP_TNL_Information.choice.gTPTunnel, gTPTunnel); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, &gTPTunnel->transportLayerAddress); + INT32_TO_OCTET_STRING(i->teId, &gTPTunnel->gTP_TEID); + + for (DRB_nGRAN_to_setup_t *j=i->DRBnGRanList; j < i->DRBnGRanList+i->numDRB2Setup; j++) { + asn1cSequenceAdd(ieC6_1->dRB_To_Setup_List_NG_RAN.list, E1AP_DRB_To_Setup_Item_NG_RAN_t, ieC6_1_1); + ieC6_1_1->dRB_ID = j->id; + + ieC6_1_1->sDAP_Configuration.defaultDRB = j->defaultDRB; + ieC6_1_1->sDAP_Configuration.sDAP_Header_UL = j->sDAP_Header_UL; + ieC6_1_1->sDAP_Configuration.sDAP_Header_DL = j->sDAP_Header_DL; + + ieC6_1_1->pDCP_Configuration.pDCP_SN_Size_UL = j->pDCP_SN_Size_UL; + ieC6_1_1->pDCP_Configuration.pDCP_SN_Size_DL = j->pDCP_SN_Size_DL; + asn1cCallocOne(ieC6_1_1->pDCP_Configuration.discardTimer, j->discardTimer); + E1AP_T_ReorderingTimer_t *roTimer = calloc(1, sizeof(E1AP_T_ReorderingTimer_t)); + ieC6_1_1->pDCP_Configuration.t_ReorderingTimer = roTimer; + roTimer->t_Reordering = j->reorderingTimer; + ieC6_1_1->pDCP_Configuration.rLC_Mode = j->rLC_Mode; + + for (cell_group_t *k=j->cellGroupList; k < j->cellGroupList+j->numCellGroups; k++) { + asn1cSequenceAdd(ieC6_1_1->cell_Group_Information.list, E1AP_Cell_Group_Information_Item_t, ieC6_1_1_1); + ieC6_1_1_1->cell_Group_ID = k->id; + } + + for (qos_flow_to_setup_t *k=j->qosFlows; k < j->qosFlows+j->numQosFlow2Setup; k++) { + asn1cSequenceAdd(ieC6_1_1->qos_flow_Information_To_Be_Setup, E1AP_QoS_Flow_QoS_Parameter_Item_t, ieC6_1_1_1); + ieC6_1_1_1->qoS_Flow_Identifier = k->id; + + if (k->fiveQI_type == non_dynamic) { // non Dynamic 5QI + ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.present = E1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + asn1cCalloc(ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI, non_Dynamic_5QI); + non_Dynamic_5QI->fiveQI = k->fiveQI; + } else { // dynamic 5QI + ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.present = E1AP_QoS_Characteristics_PR_dynamic_5QI; + asn1cCalloc(ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI, dynamic_5QI); + dynamic_5QI->qoSPriorityLevel = k->qoSPriorityLevel; + dynamic_5QI->packetDelayBudget = k->packetDelayBudget; + dynamic_5QI->packetErrorRate.pER_Scalar = k->packetError_scalar; + dynamic_5QI->packetErrorRate.pER_Exponent = k->packetError_exponent; + } + + ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = k->priorityLevel; + ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = k->pre_emptionCapability; + ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = k->pre_emptionVulnerability; + } + } + } + return 0; } -int e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +void e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance, e1ap_bearer_setup_req_t *const bearerCxt) +{ + if (!getCxtE1(instance)) { + LOG_E(E1AP, "Received a UE bearer to establish while no CU-UP is connected, response on NGAP to send failure is not developped\n"); + // Fixme: add response on NGAP to send failure + return; + } + + E1AP_E1AP_PDU_t pdu = {0}; + e1ap_setup_req_t *setupReq = &getCxtE1(instance)->setupReq; + fill_BEARER_CONTEXT_SETUP_REQUEST(setupReq, bearerCxt, &pdu); + e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__); +} + +static void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const resp, E1AP_E1AP_PDU_t *pdu) +{ + /* Create */ + /* 0. pdu Type */ + pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome; + asn1cCalloc(pdu->choice.successfulOutcome, msg); + msg->procedureCode = E1AP_ProcedureCode_id_bearerContextSetup; + msg->criticality = E1AP_Criticality_reject; + msg->value.present = E1AP_SuccessfulOutcome__value_PR_BearerContextSetupResponse; + E1AP_BearerContextSetupResponse_t *out = &pdu->choice.successfulOutcome->value.choice.BearerContextSetupResponse; + /* mandatory */ + /* c1. gNB-CU-CP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID; + ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = resp->gNB_cu_cp_ue_id; + /* mandatory */ + /* c2. gNB-CU-UP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC2); + ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID; + ieC2->criticality = E1AP_Criticality_reject; + ieC2->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; + ieC2->value.choice.GNB_CU_CP_UE_E1AP_ID = resp->gNB_cu_up_ue_id; + + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC3); + ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextSetupResponse; + ieC3->criticality = E1AP_Criticality_reject; + ieC3->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_System_BearerContextSetupResponse; + if (0) { // EUTRAN + ieC3->value.choice.System_BearerContextSetupResponse.present = E1AP_System_BearerContextSetupResponse_PR_e_UTRAN_BearerContextSetupResponse; + E1AP_ProtocolIE_Container_4932P21_t *msgEUTRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P21_t)); + ieC3->value.choice.System_BearerContextSetupResponse.choice.e_UTRAN_BearerContextSetupResponse = (struct E1AP_ProtocolIE_Container *) msgEUTRAN_list; + asn1cSequenceAdd(msgEUTRAN_list->list, E1AP_EUTRAN_BearerContextSetupResponse_t, msgEUTRAN); + msgEUTRAN->id = E1AP_ProtocolIE_ID_id_DRB_Setup_List_EUTRAN; + msgEUTRAN->criticality = E1AP_Criticality_reject; + msgEUTRAN->value.present = E1AP_EUTRAN_BearerContextSetupResponse__value_PR_DRB_Setup_List_EUTRAN; + E1AP_DRB_Setup_List_EUTRAN_t *drbSetup = &msgEUTRAN->value.choice.DRB_Setup_List_EUTRAN; + + for (drb_setup_t *i=resp->DRBList; i < resp->DRBList+resp->numDRBs; i++) { + asn1cSequenceAdd(drbSetup->list, E1AP_DRB_Setup_Item_EUTRAN_t, ieC3_1); + ieC3_1->dRB_ID = i->drbId; + + ieC3_1->s1_DL_UP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel; + asn1cCalloc(ieC3_1->s1_DL_UP_TNL_Information.choice.gTPTunnel, gTPTunnel); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, &gTPTunnel->transportLayerAddress); + INT32_TO_OCTET_STRING(i->teId, &gTPTunnel->gTP_TEID); + + for (up_params_t *j=i->UpParamList; j < i->UpParamList+i->numUpParam; j++) { + asn1cSequenceAdd(ieC3_1->uL_UP_Transport_Parameters.list, E1AP_UP_Parameters_Item_t, ieC3_1_1); + ieC3_1_1->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel; + asn1cCalloc(ieC3_1_1->uP_TNL_Information.choice.gTPTunnel, gTPTunnel); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(j->tlAddress, &gTPTunnel->transportLayerAddress); + INT32_TO_OCTET_STRING(j->teId, &gTPTunnel->gTP_TEID); + } + } + } else { + ieC3->value.choice.System_BearerContextSetupResponse.present = E1AP_System_BearerContextSetupResponse_PR_nG_RAN_BearerContextSetupResponse; + E1AP_ProtocolIE_Container_4932P22_t *msgNGRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P22_t)); + ieC3->value.choice.System_BearerContextSetupResponse.choice.nG_RAN_BearerContextSetupResponse = (struct E1AP_ProtocolIE_Container *) msgNGRAN_list; + asn1cSequenceAdd(msgNGRAN_list->list, E1AP_NG_RAN_BearerContextSetupResponse_t, msgNGRAN); + msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Setup_List; + msgNGRAN->criticality = E1AP_Criticality_reject; + msgNGRAN->value.present = E1AP_NG_RAN_BearerContextSetupResponse__value_PR_PDU_Session_Resource_Setup_List; + E1AP_PDU_Session_Resource_Setup_List_t *pduSetup = &msgNGRAN->value.choice.PDU_Session_Resource_Setup_List; + + for (pdu_session_setup_t *i=resp->pduSession; i < resp->pduSession+resp->numPDUSessions; i++) { + asn1cSequenceAdd(pduSetup->list, E1AP_PDU_Session_Resource_Setup_Item_t, ieC3_1); + ieC3_1->pDU_Session_ID = i->id; + + ieC3_1->nG_DL_UP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel; + asn1cCalloc(ieC3_1->nG_DL_UP_TNL_Information.choice.gTPTunnel, gTPTunnel); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, &gTPTunnel->transportLayerAddress); + INT32_TO_OCTET_STRING(i->teId, &gTPTunnel->gTP_TEID); + + for (DRB_nGRAN_setup_t *j=i->DRBnGRanList; j < i->DRBnGRanList+i->numDRBSetup; j++) { + asn1cSequenceAdd(ieC3_1->dRB_Setup_List_NG_RAN.list, E1AP_DRB_Setup_Item_NG_RAN_t, ieC3_1_1); + ieC3_1_1->dRB_ID = j->id; + + for (up_params_t *k=j->UpParamList; k < j->UpParamList+j->numUpParam; k++) { + asn1cSequenceAdd(ieC3_1_1->uL_UP_Transport_Parameters.list, E1AP_UP_Parameters_Item_t, ieC3_1_1_1); + ieC3_1_1_1->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel; + asn1cCalloc(ieC3_1_1_1->uP_TNL_Information.choice.gTPTunnel, gTPTunnel); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(k->tlAddress, &gTPTunnel->transportLayerAddress); + INT32_TO_OCTET_STRING(k->teId, &gTPTunnel->gTP_TEID); + } + + for (qos_flow_setup_t *k=j->qosFlows; k < j->qosFlows+j->numQosFlowSetup; k++) { + asn1cSequenceAdd(ieC3_1_1->flow_Setup_List.list, E1AP_QoS_Flow_Item_t, ieC3_1_1_1); + ieC3_1_1_1->qoS_Flow_Identifier = k->id; + } + } + + if (i->numDRBFailed > 0) + ieC3_1->dRB_Failed_List_NG_RAN = calloc(1, sizeof(E1AP_DRB_Failed_List_NG_RAN_t)); + + for (DRB_nGRAN_failed_t *j=i->DRBnGRanFailedList; j < i->DRBnGRanFailedList+i->numDRBFailed; j++) { + asn1cSequenceAdd(ieC3_1->dRB_Failed_List_NG_RAN->list, E1AP_DRB_Failed_Item_NG_RAN_t, ieC3_1_1); + ieC3_1_1->dRB_ID = j->id; + + ieC3_1_1->cause.present = j->cause_type; + switch (ieC3_1_1->cause.present) { + case E1AP_Cause_PR_radioNetwork: + ieC3_1_1->cause.choice.radioNetwork = j->cause; + break; + + case E1AP_Cause_PR_transport: + ieC3_1_1->cause.choice.transport = j->cause; + break; + + case E1AP_Cause_PR_protocol: + ieC3_1_1->cause.choice.protocol = j->cause; + break; + + case E1AP_Cause_PR_misc: + ieC3_1_1->cause.choice.misc = j->cause; + break; + + default: + LOG_E(E1AP, "DRB setup failure cause out of expected range\n"); + break; + } + } + } + } +} + +void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, e1ap_bearer_setup_resp_t *const resp) +{ + E1AP_E1AP_PDU_t pdu = {0}; + fill_BEARER_CONTEXT_SETUP_RESPONSE(resp, &pdu); + e1ap_encode_send(UPtype, &inst->setupReq, &pdu, 0, __func__); } int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance) { AssertFatal(false,"Not implemented yet\n"); + return -1; } -int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); +void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, + e1ap_bearer_setup_req_t *bearerCxt) { + const E1AP_BearerContextSetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextSetupRequest; + E1AP_BearerContextSetupRequestIEs_t *ie; + + LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); + + for (int i=0; i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + + switch(ie->id) { + case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID); + bearerCxt->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID; + break; + + case E1AP_ProtocolIE_ID_id_SecurityInformation: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_SecurityInformation); + bearerCxt->cipheringAlgorithm = ie->value.choice.SecurityInformation.securityAlgorithm.cipheringAlgorithm; + memcpy(bearerCxt->encryptionKey, + ie->value.choice.SecurityInformation.uPSecuritykey.encryptionKey.buf, + ie->value.choice.SecurityInformation.uPSecuritykey.encryptionKey.size); + if (ie->value.choice.SecurityInformation.securityAlgorithm.integrityProtectionAlgorithm) { + bearerCxt->integrityProtectionAlgorithm = *ie->value.choice.SecurityInformation.securityAlgorithm.integrityProtectionAlgorithm; + } + if (ie->value.choice.SecurityInformation.uPSecuritykey.integrityProtectionKey) { + memcpy(bearerCxt->integrityProtectionKey, + ie->value.choice.SecurityInformation.uPSecuritykey.integrityProtectionKey->buf, + ie->value.choice.SecurityInformation.uPSecuritykey.integrityProtectionKey->size); + } + break; + + case E1AP_ProtocolIE_ID_id_UEDLAggregateMaximumBitRate: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_BitRate); + asn_INTEGER2long(&ie->value.choice.BitRate, &bearerCxt->ueDlAggMaxBitRate); + break; + + case E1AP_ProtocolIE_ID_id_Serving_PLMN: + DevAssert(ie->criticality == E1AP_Criticality_ignore); + DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_PLMN_Identity); + PLMNID_TO_MCC_MNC(&ie->value.choice.PLMN_Identity, + bearerCxt->servingPLMNid.mcc, + bearerCxt->servingPLMNid.mnc, + bearerCxt->servingPLMNid.mnc_digit_length); + break; + + case E1AP_ProtocolIE_ID_id_ActivityNotificationLevel: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_ActivityNotificationLevel); + bearerCxt->activityNotificationLevel = ie->value.choice.ActivityNotificationLevel; + break; + + case E1AP_ProtocolIE_ID_id_System_BearerContextSetupRequest: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_System_BearerContextSetupRequest); + DevAssert(ie->value.choice.System_BearerContextSetupRequest.present == + E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest); + DevAssert(ie->value.choice.System_BearerContextSetupRequest.choice.nG_RAN_BearerContextSetupRequest); + E1AP_ProtocolIE_Container_4932P19_t *msgNGRAN_list = (E1AP_ProtocolIE_Container_4932P19_t *) ie->value.choice.System_BearerContextSetupRequest.choice.nG_RAN_BearerContextSetupRequest; + E1AP_NG_RAN_BearerContextSetupRequest_t *msgNGRAN = msgNGRAN_list->list.array[0]; + DevAssert(msgNGRAN_list->list.count == 1); + DevAssert(msgNGRAN->id == E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_List); + DevAssert(msgNGRAN->value.present == E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List); + + E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2SetupList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List; + bearerCxt->numPDUSessions = pdu2SetupList->list.count; + for (int i=0; i < pdu2SetupList->list.count; i++) { + pdu_session_to_setup_t *pdu_session = bearerCxt->pduSession + i; + E1AP_PDU_Session_Resource_To_Setup_Item_t *pdu2Setup = pdu2SetupList->list.array[i]; + + pdu_session->sessionId = pdu2Setup->pDU_Session_ID; + pdu_session->sessionType = pdu2Setup->pDU_Session_Type; + + OCTET_STRING_TO_INT8(&pdu2Setup->sNSSAI.sST, pdu_session->sst); + + pdu_session->integrityProtectionIndication = pdu2Setup->securityIndication.integrityProtectionIndication; + pdu_session->confidentialityProtectionIndication = pdu2Setup->securityIndication.confidentialityProtectionIndication; + + if (pdu2Setup->nG_UL_UP_TNL_Information.choice.gTPTunnel) { // Optional IE + DevAssert(pdu2Setup->nG_UL_UP_TNL_Information.present == + E1AP_UP_TNL_Information_PR_gTPTunnel); + BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&pdu2Setup->nG_UL_UP_TNL_Information.choice.gTPTunnel->transportLayerAddress, + pdu_session->tlAddress); + OCTET_STRING_TO_INT32(&pdu2Setup->nG_UL_UP_TNL_Information.choice.gTPTunnel->gTP_TEID, pdu_session->teId); + } + + E1AP_DRB_To_Setup_List_NG_RAN_t *drb2SetupList = &pdu2Setup->dRB_To_Setup_List_NG_RAN; + pdu_session->numDRB2Setup = drb2SetupList->list.count; + for (int j=0; j < drb2SetupList->list.count; j++) { + DRB_nGRAN_to_setup_t *drb = pdu_session->DRBnGRanList + j; + E1AP_DRB_To_Setup_Item_NG_RAN_t *drb2Setup = drb2SetupList->list.array[j]; + + drb->id = drb2Setup->dRB_ID; + + drb->defaultDRB = drb2Setup->sDAP_Configuration.defaultDRB; + drb->sDAP_Header_UL = drb2Setup->sDAP_Configuration.sDAP_Header_UL; + drb->sDAP_Header_DL = drb2Setup->sDAP_Configuration.sDAP_Header_DL; + + drb->pDCP_SN_Size_UL = drb2Setup->pDCP_Configuration.pDCP_SN_Size_UL; + drb->pDCP_SN_Size_DL = drb2Setup->pDCP_Configuration.pDCP_SN_Size_DL; + + if (drb2Setup->pDCP_Configuration.discardTimer) { + drb->discardTimer = *drb2Setup->pDCP_Configuration.discardTimer; + } + + if (drb2Setup->pDCP_Configuration.t_ReorderingTimer) { + drb->reorderingTimer = drb2Setup->pDCP_Configuration.t_ReorderingTimer->t_Reordering; + } + + drb->rLC_Mode = drb2Setup->pDCP_Configuration.rLC_Mode; + + E1AP_Cell_Group_Information_t *cellGroupList = &drb2Setup->cell_Group_Information; + drb->numCellGroups = cellGroupList->list.count; + for (int k=0; k < cellGroupList->list.count; k++) { + E1AP_Cell_Group_Information_Item_t *cg2Setup = cellGroupList->list.array[k]; + + drb->cellGroupList[k].id = cg2Setup->cell_Group_ID; + } + + E1AP_QoS_Flow_QoS_Parameter_List_t *qos2SetupList = &drb2Setup->qos_flow_Information_To_Be_Setup; + drb->numQosFlow2Setup = qos2SetupList->list.count; + for (int k=0; k < qos2SetupList->list.count; k++) { + qos_flow_to_setup_t *qos = drb->qosFlows + k; + E1AP_QoS_Flow_QoS_Parameter_Item_t *qos2Setup = qos2SetupList->list.array[k]; + + qos->id = qos2Setup->qoS_Flow_Identifier; + + if (qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.present == + E1AP_QoS_Characteristics_PR_non_Dynamic_5QI) { + qos->fiveQI_type = non_dynamic; + qos->fiveQI = qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI; + } else { + E1AP_Dynamic5QIDescriptor_t *dynamic5QI = qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI; + qos->fiveQI_type = dynamic; + qos->qoSPriorityLevel = dynamic5QI->qoSPriorityLevel; + qos->packetDelayBudget = dynamic5QI->packetDelayBudget; + qos->packetError_scalar = dynamic5QI->packetErrorRate.pER_Scalar; + qos->packetError_exponent = dynamic5QI->packetErrorRate.pER_Exponent; + } + + qos->priorityLevel = qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel; + qos->pre_emptionCapability = qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability; + qos->pre_emptionVulnerability = qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability; + } + } + } + break; + + default: + LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n"); + break; + } + } + + } -int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); +int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + DevAssert(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage); + DevAssert(pdu->choice.initiatingMessage->procedureCode == E1AP_ProcedureCode_id_bearerContextSetup); + DevAssert(pdu->choice.initiatingMessage->criticality == E1AP_Criticality_reject); + DevAssert(pdu->choice.initiatingMessage->value.present == E1AP_InitiatingMessage__value_PR_BearerContextSetupRequest); + + e1ap_bearer_setup_req_t bearerCxt = {0}; + extract_BEARER_CONTEXT_SETUP_REQUEST(pdu, &bearerCxt); + process_e1_bearer_context_setup_req(e1_inst->instance, &bearerCxt); + return 0; } -int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) { +void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu, + e1ap_bearer_setup_resp_t *bearerCxt) { + const E1AP_BearerContextSetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextSetupResponse; + E1AP_BearerContextSetupResponseIEs_t *ie; + + LOG_I(E1AP, "Bearer context setup response number of IEs %d\n", in->protocolIEs.list.count); + + for (int i=0; i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + + switch(ie->id) { + case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID); + bearerCxt->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID; + break; + + case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID); + bearerCxt->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID; + break; + + case E1AP_ProtocolIE_ID_id_System_BearerContextSetupResponse: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextSetupResponseIEs__value_PR_System_BearerContextSetupResponse); + DevAssert(ie->value.choice.System_BearerContextSetupResponse.present == + E1AP_System_BearerContextSetupResponse_PR_nG_RAN_BearerContextSetupResponse); + E1AP_ProtocolIE_Container_4932P22_t *msgNGRAN_list = (E1AP_ProtocolIE_Container_4932P22_t *) ie->value.choice.System_BearerContextSetupResponse.choice.nG_RAN_BearerContextSetupResponse; + DevAssert(msgNGRAN_list->list.count == 1); + E1AP_NG_RAN_BearerContextSetupResponse_t *msgNGRAN = msgNGRAN_list->list.array[0]; + DevAssert(msgNGRAN->id == E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Setup_List); + DevAssert(msgNGRAN->criticality == E1AP_Criticality_reject); + DevAssert(msgNGRAN->value.present == E1AP_NG_RAN_BearerContextSetupResponse__value_PR_PDU_Session_Resource_Setup_List); + E1AP_PDU_Session_Resource_Setup_List_t *pduSetupList = &msgNGRAN->value.choice.PDU_Session_Resource_Setup_List; + bearerCxt->numPDUSessions = pduSetupList->list.count; + + for (int i=0; i < pduSetupList->list.count; i++) { + pdu_session_setup_t *pduSetup = bearerCxt->pduSession + i; + E1AP_PDU_Session_Resource_Setup_Item_t *pdu_session = pduSetupList->list.array[i]; + pduSetup->id = pdu_session->pDU_Session_ID; + + if (pdu_session->nG_DL_UP_TNL_Information.choice.gTPTunnel) { + DevAssert(pdu_session->nG_DL_UP_TNL_Information.present == E1AP_UP_TNL_Information_PR_gTPTunnel); + BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&pdu_session->nG_DL_UP_TNL_Information.choice.gTPTunnel->transportLayerAddress, + pduSetup->tlAddress); + OCTET_STRING_TO_INT32(&pdu_session->nG_DL_UP_TNL_Information.choice.gTPTunnel->gTP_TEID, + pduSetup->teId); + } + + pduSetup->numDRBSetup = pdu_session->dRB_Setup_List_NG_RAN.list.count; + for (int j=0; j < pdu_session->dRB_Setup_List_NG_RAN.list.count; j++) { + DRB_nGRAN_setup_t *drbSetup = pduSetup->DRBnGRanList + j; + E1AP_DRB_Setup_Item_NG_RAN_t *drb = pdu_session->dRB_Setup_List_NG_RAN.list.array[j]; + + drbSetup->id = drb->dRB_ID; + + drbSetup->numUpParam = drb->uL_UP_Transport_Parameters.list.count; + for (int k=0; k < drb->uL_UP_Transport_Parameters.list.count; k++) { + up_params_t *UL_UP_param = drbSetup->UpParamList + k; + E1AP_UP_Parameters_Item_t *in_UL_UP_param = drb->uL_UP_Transport_Parameters.list.array[k]; + + DevAssert(in_UL_UP_param->uP_TNL_Information.present == E1AP_UP_TNL_Information_PR_gTPTunnel); + E1AP_GTPTunnel_t *gTPTunnel = in_UL_UP_param->uP_TNL_Information.choice.gTPTunnel; + if (gTPTunnel) { + BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&gTPTunnel->transportLayerAddress, + UL_UP_param->tlAddress); + OCTET_STRING_TO_INT32(&gTPTunnel->gTP_TEID, + UL_UP_param->teId); + } else { + AssertFatal(false, "gTPTunnel information in required\n"); + } + } + } + } + break; + + // TODO: remaining IE handlers + + default: + LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n"); + break; + } + } +} + +int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) +{ + DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome); + DevAssert(pdu->choice.successfulOutcome->procedureCode == E1AP_ProcedureCode_id_bearerContextSetup); + DevAssert(pdu->choice.successfulOutcome->criticality == E1AP_Criticality_reject); + DevAssert(pdu->choice.successfulOutcome->value.present == E1AP_SuccessfulOutcome__value_PR_BearerContextSetupResponse); + + MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_RESP); + e1ap_bearer_setup_resp_t *bearerCxt = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg); + extract_BEARER_CONTEXT_SETUP_RESPONSE(pdu, bearerCxt); + // Fixme: instance is the NGAP instance, no good way to set it here + instance_t instance = 0; + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg); + + return 0; +} + +int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) +{ AssertFatal(false,"Not implemented yet\n"); + return -1; } /* BEARER CONTEXT MODIFICATION REQUEST */ -int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_setup_req_t *setupReq, e1ap_bearer_setup_req_t *const bearerCxt, E1AP_E1AP_PDU_t *pdu) +{ + pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu->choice.initiatingMessage, msg); + msg->procedureCode = E1AP_ProcedureCode_id_bearerContextModification; + msg->criticality = E1AP_Criticality_reject; + msg->value.present = E1AP_InitiatingMessage__value_PR_BearerContextModificationRequest; + E1AP_BearerContextModificationRequest_t *out = &pdu->choice.initiatingMessage->value.choice.BearerContextModificationRequest; + /* mandatory */ + /* c1. gNB-CU-CP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID; + ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = bearerCxt->gNB_cu_cp_ue_id; + /* mandatory */ + /* c2. gNB-CU-UP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC2); + ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID; + ieC2->criticality = E1AP_Criticality_reject; + ieC2->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; + ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_cp_ue_id; + /* optional */ + /* */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC3); + ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest; + ieC3->criticality = E1AP_Criticality_reject; + ieC3->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_System_BearerContextModificationRequest; + ieC3->value.choice.System_BearerContextModificationRequest.present = E1AP_System_BearerContextModificationRequest_PR_nG_RAN_BearerContextModificationRequest; + E1AP_ProtocolIE_Container_4932P26_t *msgNGRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P26_t)); + ieC3->value.choice.System_BearerContextModificationRequest.choice.nG_RAN_BearerContextModificationRequest = (struct E1AP_ProtocolIE_Container *) msgNGRAN_list; + asn1cSequenceAdd(msgNGRAN_list->list, E1AP_NG_RAN_BearerContextModificationRequest_t, msgNGRAN); + msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Modify_List; + msgNGRAN->criticality = E1AP_Criticality_reject; + msgNGRAN->value.present = E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Modify_List; + E1AP_PDU_Session_Resource_To_Modify_List_t *pdu2Setup = &msgNGRAN->value.choice.PDU_Session_Resource_To_Modify_List; + for(pdu_session_to_setup_t *i=bearerCxt->pduSessionMod; i < bearerCxt->pduSessionMod+bearerCxt->numPDUSessionsMod; i++) { + asn1cSequenceAdd(pdu2Setup->list, E1AP_PDU_Session_Resource_To_Modify_Item_t, ieC3_1); + ieC3_1->pDU_Session_ID = i->sessionId; + + for (DRB_nGRAN_to_setup_t *j=i->DRBnGRanModList; j < i->DRBnGRanModList+i->numDRB2Modify; j++) { + asn1cCalloc(ieC3_1->dRB_To_Modify_List_NG_RAN, drb2Mod_List); + asn1cSequenceAdd(drb2Mod_List->list, E1AP_DRB_To_Modify_Item_NG_RAN_t, drb2Mod); + drb2Mod->dRB_ID = j->id; + + if (j->numDlUpParam > 0) { + asn1cCalloc(drb2Mod->dL_UP_Parameters, DL_UP_Param_List); + for (up_params_t *k=j->DlUpParamList; k < j->DlUpParamList+j->numDlUpParam; k++) { + asn1cSequenceAdd(DL_UP_Param_List->list, E1AP_UP_Parameters_Item_t, DL_UP_Param); + DL_UP_Param->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel; + asn1cCalloc(DL_UP_Param->uP_TNL_Information.choice.gTPTunnel, gTPTunnel); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(k->tlAddress, &gTPTunnel->transportLayerAddress); + INT32_TO_OCTET_STRING(k->teId, &gTPTunnel->gTP_TEID); + + DL_UP_Param->cell_Group_ID = k->cell_group_id; + } + } + } + } + return 0; +} + +static void e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t inst, e1ap_bearer_setup_req_t *const bearerCxt) +{ + AssertFatal(getCxtE1(inst), ""); + e1ap_setup_req_t *setupReq = &getCxtE1(inst)->setupReq; + E1AP_E1AP_PDU_t pdu = {0}; + fill_BEARER_CONTEXT_MODIFICATION_REQUEST(setupReq, bearerCxt, &pdu); + e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__); } int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance) { AssertFatal(false,"Not implemented yet\n"); + return -1; } -int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); +void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu, + e1ap_bearer_setup_req_t *bearerCxt) { + const E1AP_BearerContextModificationRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextModificationRequest; + E1AP_BearerContextModificationRequestIEs_t *ie; + + LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); + + for (int i=0; i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + + switch(ie->id) { + case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID); + bearerCxt->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID; + break; + + case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID); + bearerCxt->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID; + break; + + case E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_System_BearerContextModificationRequest); + DevAssert(ie->value.choice.System_BearerContextModificationRequest.present == + E1AP_System_BearerContextModificationRequest_PR_nG_RAN_BearerContextModificationRequest); + DevAssert(ie->value.choice.System_BearerContextModificationRequest.choice.nG_RAN_BearerContextModificationRequest != NULL); + E1AP_ProtocolIE_Container_4932P26_t *msgNGRAN_list = (E1AP_ProtocolIE_Container_4932P26_t *) ie->value.choice.System_BearerContextModificationRequest.choice.nG_RAN_BearerContextModificationRequest; + E1AP_NG_RAN_BearerContextModificationRequest_t *msgNGRAN = msgNGRAN_list->list.array[0]; + DevAssert(msgNGRAN_list->list.count == 1); + DevAssert(msgNGRAN->id == E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Modify_List); + DevAssert(msgNGRAN->value.present = + E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Modify_List); + + E1AP_PDU_Session_Resource_To_Modify_List_t *pdu2ModList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Modify_List; + bearerCxt->numPDUSessionsMod = pdu2ModList->list.count; + for (int i=0; i < pdu2ModList->list.count; i++) { + pdu_session_to_setup_t *pdu_session = bearerCxt->pduSessionMod + i; + E1AP_PDU_Session_Resource_To_Modify_Item_t *pdu2Mod = pdu2ModList->list.array[i]; + + pdu_session->sessionId = pdu2Mod->pDU_Session_ID; + + E1AP_DRB_To_Modify_List_NG_RAN_t *drb2ModList = pdu2Mod->dRB_To_Modify_List_NG_RAN; + pdu_session->numDRB2Modify = drb2ModList->list.count; + for (int j=0; j < drb2ModList->list.count; j++) { + DRB_nGRAN_to_setup_t *drb = pdu_session->DRBnGRanModList + j; + E1AP_DRB_To_Modify_Item_NG_RAN_t *drb2Mod = drb2ModList->list.array[j]; + + drb->id = drb2Mod->dRB_ID; + + E1AP_UP_Parameters_t *dl_up_paramList = drb2Mod->dL_UP_Parameters; + drb->numDlUpParam = dl_up_paramList->list.count; + for (int k=0; k < dl_up_paramList->list.count; k++) { + up_params_t *dl_up_param = drb->DlUpParamList + k; + E1AP_UP_Parameters_Item_t *dl_up_param_in = dl_up_paramList->list.array[k]; + if (dl_up_param_in->uP_TNL_Information.choice.gTPTunnel) { // Optional IE + DevAssert(dl_up_param_in->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel); + BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_param_in->uP_TNL_Information.choice.gTPTunnel->transportLayerAddress, + dl_up_param->tlAddress); + OCTET_STRING_TO_INT32(&dl_up_param_in->uP_TNL_Information.choice.gTPTunnel->gTP_TEID, dl_up_param->teId); + } else { + AssertFatal(false, "gTPTunnel IE is missing. It is mandatory at this point\n"); + } + dl_up_param->cell_group_id = dl_up_param_in->cell_Group_ID; + } + } + } + break; + + default: + LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n"); + break; + } + } +} + +int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + DevAssert(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage); + DevAssert(pdu->choice.initiatingMessage->procedureCode == E1AP_ProcedureCode_id_bearerContextModification); + DevAssert(pdu->choice.initiatingMessage->criticality == E1AP_Criticality_reject); + DevAssert(pdu->choice.initiatingMessage->value.present == E1AP_InitiatingMessage__value_PR_BearerContextModificationRequest); + + e1ap_bearer_setup_req_t bearerCxt = {0}; + extract_BEARER_CONTEXT_MODIFICATION_REQUEST(pdu, &bearerCxt); + CUUP_process_bearer_context_mod_req(e1_inst->instance, &bearerCxt); + return 0; } int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, @@ -277,6 +1251,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance, @@ -284,14 +1259,17 @@ int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, @@ -299,6 +1277,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, @@ -306,35 +1285,178 @@ int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } /* BEARER CONTEXT RELEASE */ -int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +static int fill_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_setup_req_t *setupReq, e1ap_bearer_release_cmd_t *const cmd, E1AP_E1AP_PDU_t *pdu) +{ + pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu->choice.initiatingMessage, msg); + msg->procedureCode = E1AP_ProcedureCode_id_bearerContextRelease; + msg->criticality = E1AP_Criticality_reject; + msg->value.present = E1AP_InitiatingMessage__value_PR_BearerContextReleaseCommand; + E1AP_BearerContextReleaseCommand_t *out = &pdu->choice.initiatingMessage->value.choice.BearerContextReleaseCommand; + /* mandatory */ + /* c1. gNB-CU-CP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextReleaseCommandIEs_t, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_BearerContextReleaseCommandIEs__value_PR_GNB_CU_CP_UE_E1AP_ID; + ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = cmd->gNB_cu_cp_ue_id; + /* mandatory */ + /* c2. gNB-CU-UP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextReleaseCommandIEs_t, ieC2); + ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID; + ieC2->criticality = E1AP_Criticality_reject; + ieC2->value.present = E1AP_BearerContextReleaseCommandIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; + ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = cmd->gNB_cu_cp_ue_id; + + return 0; } -int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_setup_req_t *setupReq, e1ap_bearer_release_cmd_t *const cmd) +{ + E1AP_E1AP_PDU_t pdu = {0}; + fill_BEARER_CONTEXT_RELEASE_COMMAND(setupReq, cmd, &pdu); + return e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__); +} + +int fill_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_setup_req_t *setupReq, e1ap_bearer_release_cmd_t *const cmd, E1AP_E1AP_PDU_t *pdu) +{ + pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome; + asn1cCalloc(pdu->choice.successfulOutcome, msg); + msg->procedureCode = E1AP_ProcedureCode_id_bearerContextRelease; + msg->criticality = E1AP_Criticality_reject; + msg->value.present = E1AP_SuccessfulOutcome__value_PR_BearerContextReleaseComplete; + E1AP_BearerContextReleaseComplete_t *out = &pdu->choice.successfulOutcome->value.choice.BearerContextReleaseComplete; + /* mandatory */ + /* c1. gNB-CU-CP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextReleaseCompleteIEs_t, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_BearerContextReleaseCompleteIEs__value_PR_GNB_CU_CP_UE_E1AP_ID; + ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = cmd->gNB_cu_cp_ue_id; + /* mandatory */ + /* c2. gNB-CU-UP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextReleaseCompleteIEs_t, ieC2); + ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID; + ieC2->criticality = E1AP_Criticality_reject; + ieC2->value.present = E1AP_BearerContextReleaseCompleteIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; + ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = cmd->gNB_cu_cp_ue_id; + + return 0; +} + +int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *inst, e1ap_bearer_release_cmd_t *const cmd) +{ + E1AP_E1AP_PDU_t pdu = {0}; + fill_BEARER_CONTEXT_RELEASE_COMPLETE(&inst->setupReq, cmd, &pdu); + return e1ap_encode_send(CPtype, &inst->setupReq, &pdu, 0, __func__); } int e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance) { AssertFatal(false,"Not implemented yet\n"); + return -1; } -int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); +void extract_BEARER_CONTEXT_RELEASE_COMMAND(const E1AP_E1AP_PDU_t *pdu, + e1ap_bearer_release_cmd_t *bearerCxt) { + const E1AP_BearerContextReleaseCommand_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextReleaseCommand; + E1AP_BearerContextReleaseCommandIEs_t *ie; + + LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); + + for (int i=0; i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + + switch(ie->id) { + case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextReleaseCommandIEs__value_PR_GNB_CU_CP_UE_E1AP_ID); + bearerCxt->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID; + break; + + case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextReleaseCommandIEs__value_PR_GNB_CU_UP_UE_E1AP_ID); + bearerCxt->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID; + break; + + case E1AP_ProtocolIE_ID_id_Cause: + DevAssert(ie->criticality == E1AP_Criticality_ignore); + DevAssert(ie->value.present == E1AP_BearerContextReleaseCommandIEs__value_PR_Cause); + bearerCxt->cause_type = ie->value.choice.Cause.present; + if ((ie->value.choice.Cause.present != E1AP_Cause_PR_NOTHING) && + (ie->value.choice.Cause.present != E1AP_Cause_PR_choice_extension)) + bearerCxt->cause = ie->value.choice.Cause.choice.radioNetwork; + + + default: + LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n"); + break; + } + } } -int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); +int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + DevAssert(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage); + DevAssert(pdu->choice.initiatingMessage->procedureCode == E1AP_ProcedureCode_id_bearerContextRelease); + DevAssert(pdu->choice.initiatingMessage->criticality == E1AP_Criticality_reject); + DevAssert(pdu->choice.initiatingMessage->value.present == E1AP_InitiatingMessage__value_PR_BearerContextReleaseCommand); + + e1ap_bearer_release_cmd_t bearerCxt = {0}; + extract_BEARER_CONTEXT_RELEASE_COMMAND(pdu, &bearerCxt); + CUUP_process_bearer_release_command(e1_inst->instance, &bearerCxt); + return 0; +} + +void extract_BEARER_CONTEXT_RELEASE_COMPLETE(const E1AP_E1AP_PDU_t *pdu, + e1ap_bearer_release_cmd_t *bearerCxt) { + const E1AP_BearerContextReleaseComplete_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextReleaseComplete; + E1AP_BearerContextReleaseCompleteIEs_t *ie; + + LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); + + for (int i=0; i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + + switch(ie->id) { + case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextReleaseCompleteIEs__value_PR_GNB_CU_CP_UE_E1AP_ID); + bearerCxt->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID; + break; + + case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextReleaseCompleteIEs__value_PR_GNB_CU_UP_UE_E1AP_ID); + bearerCxt->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID; + break; + + default: + LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n"); + break; + } + } +} + +int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome); + DevAssert(pdu->choice.successfulOutcome->procedureCode == E1AP_ProcedureCode_id_bearerContextRelease); + DevAssert(pdu->choice.successfulOutcome->criticality == E1AP_Criticality_reject); + DevAssert(pdu->choice.successfulOutcome->value.present == E1AP_SuccessfulOutcome__value_PR_BearerContextReleaseComplete); + + e1ap_bearer_release_cmd_t bearerCxt = {0}; + extract_BEARER_CONTEXT_RELEASE_COMPLETE(pdu, &bearerCxt); + //TODO: CUCP_process_bearer_release_complete(&beareCxt, instance); + return 0; } int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance, @@ -342,6 +1464,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } /* @@ -350,6 +1473,7 @@ BEARER CONTEXT INACTIVITY NOTIFICATION int e1apCUUP_send_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1apCUCP_handle_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance, @@ -357,6 +1481,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } /* DL DATA @@ -364,10 +1489,12 @@ int e1apCUCP_handle_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance, int e1apCUUP_send_DL_DATA_NOTIFICATION(instance_t instance) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1apCUUP_send_DATA_USAGE_REPORT(instance_t instance) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1apCUCP_handle_DL_DATA_NOTIFICATION(instance_t instance, @@ -375,6 +1502,7 @@ int e1apCUCP_handle_DL_DATA_NOTIFICATION(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } int e1apCUCP_handle_send_DATA_USAGE_REPORT(instance_t instance, @@ -382,4 +1510,236 @@ int e1apCUCP_handle_send_DATA_USAGE_REPORT(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); + return -1; } + +static instance_t cuup_task_create_gtpu_instance_to_du(eth_params_t *IPaddrs) { + openAddr_t tmp= {0}; + strncpy(tmp.originHost, IPaddrs->my_addr, sizeof(tmp.originHost)-1); + sprintf(tmp.originService, "%d", IPaddrs->my_portd); + return gtpv1Init(tmp); +} + +static void e1_task_send_sctp_association_req(long task_id, instance_t instance, e1ap_setup_req_t *e1ap_setup_req) +{ + DevAssert(e1ap_setup_req != NULL); + getCxtE1(instance)->sockState = SCTP_STATE_CLOSED; + MessageDef *message_p = itti_alloc_new_message(task_id, 0, SCTP_NEW_ASSOCIATION_REQ); + sctp_new_association_req_t *sctp_new_req = &message_p->ittiMsg.sctp_new_association_req; + sctp_new_req->ulp_cnx_id = instance; + sctp_new_req->port = E1AP_PORT_NUMBER; + sctp_new_req->ppid = E1AP_SCTP_PPID; + sctp_new_req->in_streams = e1ap_setup_req->sctp_in_streams; + sctp_new_req->out_streams = e1ap_setup_req->sctp_out_streams; + // remote + sctp_new_req->remote_address = e1ap_setup_req->CUCP_e1_ip_address; + // local + sctp_new_req->local_address = e1ap_setup_req->CUUP_e1_ip_address; + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + +static void e1apCUUP_send_SETUP_REQUEST(e1ap_setup_req_t *setup) +{ + E1AP_E1AP_PDU_t pdu = {0}; + fill_SETUP_REQUEST(setup, &pdu); + e1ap_encode_send(UPtype, setup, &pdu, 0, __func__); +} + +static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) +{ + DevAssert(sctp_new_association_resp != NULL); + getCxtE1(instance)->sockState = sctp_new_association_resp->sctp_state; + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + LOG_W(E1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", + sctp_new_association_resp->sctp_state, + instance, + sctp_new_association_resp->ulp_cnx_id); + long timer_id; // if we want to cancel timer + timer_setup(1, 0, TASK_CUUP_E1, 0, TIMER_ONE_SHOT, NULL, &timer_id); + return; + } + + if (type == UPtype) { + e1ap_setup_req_t *e1ap_cuup_setup_req = &getCxtE1(instance)->setupReq; + e1ap_cuup_setup_req->assoc_id = sctp_new_association_resp->assoc_id; + e1ap_cuup_setup_req->sctp_in_streams = sctp_new_association_resp->in_streams; + e1ap_cuup_setup_req->sctp_out_streams = sctp_new_association_resp->out_streams; + e1ap_cuup_setup_req->default_sctp_stream_id = 0; + + eth_params_t IPaddr; + IPaddr.my_addr = e1ap_cuup_setup_req->localAddressF1U; + IPaddr.my_portd = e1ap_cuup_setup_req->localPortF1U; + if (getCxtE1(instance)->gtpInstF1U < 0) + getCxtE1(instance)->gtpInstF1U = cuup_task_create_gtpu_instance_to_du(&IPaddr); + if (getCxtE1(instance)->gtpInstF1U < 0) + LOG_E(E1AP, "Failed to create CUUP F1-U UDP listener"); + extern instance_t CUuniqInstance; + CUuniqInstance = getCxtE1(instance)->gtpInstF1U; + cuup_init_n3(instance); + e1apCUUP_send_SETUP_REQUEST(&getCxtE1(instance)->setupReq); + } +} + +void cuup_init_n3(instance_t instance) +{ + if (getCxtE1(instance)->gtpInstN3 < 0) { + e1ap_setup_req_t *setup = &getCxtE1(instance)->setupReq; + openAddr_t tmp = {0}; + strcpy(tmp.originHost, setup->localAddressN3); + sprintf(tmp.originService, "%d", setup->localPortN3); + sprintf(tmp.destinationService, "%d", setup->remotePortN3); + LOG_I(GTPU, "Configuring GTPu address : %s, port : %s\n", tmp.originHost, tmp.originService); + // Fixme: fully inconsistent instances management + // dirty global var is a bad fix + extern instance_t legacyInstanceMapping; + legacyInstanceMapping = getCxtE1(instance)->gtpInstN3 = gtpv1Init(tmp); + } + if (getCxtE1(instance)->gtpInstN3 < 0) + LOG_E(E1AP, "Failed to create CUUP N3 UDP listener"); + extern instance_t *N3GTPUInst; + N3GTPUInst = &getCxtE1(instance)->gtpInstN3; +} + +void cucp_task_send_sctp_init_req(instance_t instance, char *my_addr) { + LOG_I(E1AP, "E1AP_CUCP_SCTP_REQ(create socket)\n"); + MessageDef *message_p = NULL; + message_p = itti_alloc_new_message (TASK_CUCP_E1, 0, SCTP_INIT_MSG); + message_p->ittiMsg.sctp_init.port = E1AP_PORT_NUMBER; + message_p->ittiMsg.sctp_init.ppid = E1AP_SCTP_PPID; + message_p->ittiMsg.sctp_init.ipv4 = 1; + message_p->ittiMsg.sctp_init.ipv6 = 0; + message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; + message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(my_addr); + /* + * SR WARNING: ipv6 multi-homing fails sometimes for localhost. + * * * * Disable it for now. + */ + message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0; + message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1"; + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + +void e1_task_handle_sctp_association_ind(E1_t type, instance_t instance, sctp_new_association_ind_t *sctp_new_ind) +{ + if (getCxtE1(instance)) + LOG_W(E1AP, "CUCP incoming call, re-use older socket context, finish implementation required\n"); + else + createE1inst(type, instance, NULL); + getCxtE1(instance)->sockState = SCTP_STATE_ESTABLISHED; + getCxtE1(instance)->incoming_sock = true; + e1ap_setup_req_t *setup_req = &getCxtE1(instance)->setupReq; + setup_req->assoc_id = sctp_new_ind->assoc_id; + setup_req->sctp_in_streams = sctp_new_ind->in_streams; + setup_req->sctp_out_streams = sctp_new_ind->out_streams; + setup_req->default_sctp_stream_id = 0; +} + +void e1apHandleTimer(instance_t myInstance) +{ + LOG_W(E1AP, "Try to reconnect to CP\n"); + if (getCxtE1(myInstance)->sockState != SCTP_STATE_ESTABLISHED) + e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, &getCxtE1(myInstance)->setupReq); +} + +void *E1AP_CUCP_task(void *arg) { + LOG_I(E1AP, "Starting E1AP at CU CP\n"); + MessageDef *msg = NULL; + e1ap_common_init(); + int result; + + while (1) { + itti_receive_msg(TASK_CUCP_E1, &msg); + instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg); + const int msgType = ITTI_MSG_ID(msg); + LOG_I(E1AP, "CUCP received %s for instance %ld\n", messages_info[msgType].name, myInstance); + + switch (ITTI_MSG_ID(msg)) { + case SCTP_NEW_ASSOCIATION_IND: + e1_task_handle_sctp_association_ind(CPtype, ITTI_MSG_ORIGIN_INSTANCE(msg), &msg->ittiMsg.sctp_new_association_ind); + break; + + case SCTP_NEW_ASSOCIATION_RESP: + e1_task_handle_sctp_association_resp(CPtype, ITTI_MSG_ORIGIN_INSTANCE(msg), &msg->ittiMsg.sctp_new_association_resp); + break; + + case E1AP_SETUP_REQ: { + e1ap_setup_req_t *req = &E1AP_SETUP_REQ(msg); + if (req->CUCP_e1_ip_address.ipv4 == 0) { + LOG_E(E1AP, "No IPv4 address configured\n"); + return NULL; + } + cucp_task_send_sctp_init_req(0, req->CUCP_e1_ip_address.ipv4_address); + } break; + + case SCTP_DATA_IND: + e1_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind); + break; + + case E1AP_SETUP_RESP: + e1ap_send_SETUP_RESPONSE(myInstance, &E1AP_SETUP_RESP(msg)); + break; + + case E1AP_BEARER_CONTEXT_SETUP_REQ: + e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(myInstance, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); + break; + + case E1AP_BEARER_CONTEXT_MODIFICATION_REQ: + e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(myInstance, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); + break; + + default: + LOG_E(E1AP, "Unknown message received in TASK_CUCP_E1\n"); + break; + } + + result = itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d) in E1AP_CUCP_task!\n", result); + msg = NULL; + + } +} + +void *E1AP_CUUP_task(void *arg) { + LOG_I(E1AP, "Starting E1AP at CU UP\n"); + e1ap_common_init(); + int result; + + // SCTP + while (1) { + MessageDef *msg = NULL; + itti_receive_msg(TASK_CUUP_E1, &msg); + const instance_t myInstance = ITTI_MSG_DESTINATION_INSTANCE(msg); + const int msgType = ITTI_MSG_ID(msg); + LOG_I(E1AP, "CUUP received %s for instance %ld\n", messages_info[msgType].name, myInstance); + switch (msgType) { + case E1AP_SETUP_REQ: { + e1ap_setup_req_t *msgSetup = &E1AP_SETUP_REQ(msg); + createE1inst(UPtype, myInstance, msgSetup); + + e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, msgSetup); + } break; + + case SCTP_NEW_ASSOCIATION_RESP: + e1_task_handle_sctp_association_resp(UPtype, myInstance, &msg->ittiMsg.sctp_new_association_resp); + break; + + case SCTP_DATA_IND: + e1_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind); + break; + + case TIMER_HAS_EXPIRED: + e1apHandleTimer(myInstance); + break; + + default: + LOG_E(E1AP, "Unknown message received in TASK_CUUP_E1\n"); + break; + } + + result = itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d) in E1AP_CUUP_task!\n", result); + msg = NULL; + + } +} + diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h index ef22152648..af1dcae363 100644 --- a/openair2/E1AP/e1ap.h +++ b/openair2/E1AP/e1ap.h @@ -24,11 +24,33 @@ #ifndef __E1AP_H_ #define __E1AP_H_ -#include -#include "common/openairinterface5g_limits.h" -#include +#include "openair2/COMMON/e1ap_messages_types.h" +#include "e1ap_asnc.h" +#include "openair2/E1AP/e1ap_common.h" -#include -#include -#include +int e1apCUCP_handle_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); + +int e1apCUUP_handle_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); + +int e1apCUUP_handle_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); + +int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); + +int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); + +int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); + +int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); + +void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, e1ap_bearer_setup_resp_t *const resp); + +int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); + +int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); + +int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *inst, e1ap_bearer_release_cmd_t *const cmd); + +void *E1AP_CUUP_task(void *arg); + +void *E1AP_CUCP_task(void *arg); #endif diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c new file mode 100644 index 0000000000..23a9fcd1ea --- /dev/null +++ b/openair2/E1AP/e1ap_api.c @@ -0,0 +1,195 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include "e1ap_api.h" +#include "UTIL/OSA/osa_defs.h" +#include "nr_pdcp/nr_pdcp_entity.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" +#include "openair2/RRC/NR/cucp_cuup_if.h" +#include "openair2/RRC/LTE/MESSAGES/asn1_msg.h" +#include "openair3/ocp-gtpu/gtp_itf.h" +#include "e1ap_asnc.h" +#include "e1ap_common.h" +#include "e1ap.h" + +struct NR_DRB_ToAddMod; +static void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, pdu_session_to_setup_t *pdu) { + + for (int i=0; i < pdu->numDRB2Setup; i++) { + DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + i; + asn1cSequenceAdd(DRB_configList->list, struct NR_DRB_ToAddMod, ie); + ie->drb_Identity = drb->id; + ie->cnAssociation = CALLOC(1, sizeof(*ie->cnAssociation)); + ie->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; + + // sdap_Config + asn1cCalloc(ie->cnAssociation->choice.sdap_Config, sdap_config); + sdap_config->pdu_Session = pdu->sessionId; + sdap_config->sdap_HeaderDL = drb->sDAP_Header_DL; + sdap_config->sdap_HeaderUL = drb->sDAP_Header_UL; + sdap_config->defaultDRB = drb->defaultDRB; + + asn1cCalloc(sdap_config->mappedQoS_FlowsToAdd, FlowsToAdd); + for (int j=0; j < drb->numQosFlow2Setup; j++) { + asn1cSequenceAdd(FlowsToAdd->list, NR_QFI_t, qfi); + *qfi = drb->qosFlows[j].fiveQI; + } + sdap_config->mappedQoS_FlowsToRelease = NULL; + + // pdcp_Config + ie->reestablishPDCP = NULL; + ie->recoverPDCP = NULL; + asn1cCalloc(ie->pdcp_Config, pdcp_config); + asn1cCalloc(pdcp_config->drb, drbCfg); + asn1cCallocOne(drbCfg->discardTimer, drb->discardTimer); + asn1cCallocOne(drbCfg->pdcp_SN_SizeUL, drb->pDCP_SN_Size_UL); + asn1cCallocOne(drbCfg->pdcp_SN_SizeDL, drb->pDCP_SN_Size_DL); + drbCfg->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; + drbCfg->headerCompression.choice.notUsed = 0; + + drbCfg->integrityProtection = NULL; + drbCfg->statusReportRequired = NULL; + drbCfg->outOfOrderDelivery = NULL; + pdcp_config->moreThanOneRLC = NULL; + + pdcp_config->t_Reordering = calloc(1, sizeof(*pdcp_config->t_Reordering)); + *pdcp_config->t_Reordering = drb->reorderingTimer; + pdcp_config->ext1 = NULL; + + if (pdu->integrityProtectionIndication == 0 || // Required + pdu->integrityProtectionIndication == 1) { // Preferred + asn1cCallocOne(drbCfg->integrityProtection, NR_PDCP_Config__drb__integrityProtection_enabled); + } + + if (pdu->confidentialityProtectionIndication == 0 || // Required + pdu->confidentialityProtectionIndication == 1) { // Preferred + asn1cCalloc(pdcp_config->ext1, ext1); + asn1cCallocOne(ext1->cipheringDisabled, NR_PDCP_Config__ext1__cipheringDisabled_true); + } + } +} + +static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t * const req, + gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp, + instance_t instance) { + + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; + + NR_DRB_ToAddModList_t DRB_configList = {0}; + for (int i=0; i < req->numPDUSessions; i++) { + pdu_session_to_setup_t *const pdu = &req->pduSession[i]; + create_tunnel_req.pdusession_id[i] = pdu->sessionId; + create_tunnel_req.incoming_rb_id[i] = pdu->DRBnGRanList[0].id; // taking only the first DRB. TODO:change this + memcpy(&create_tunnel_req.dst_addr[i].buffer, + &pdu->tlAddress, + sizeof(uint8_t)*4); + create_tunnel_req.dst_addr[i].length = 32; // 8bits * 4bytes + create_tunnel_req.outgoing_teid[i] = pdu->teId; + fill_DRB_configList_e1(&DRB_configList, pdu); + } + create_tunnel_req.num_tunnels = req->numPDUSessions; + create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF); + + // Create N3 tunnel + int ret = gtpv1u_create_ngu_tunnel(instance, + &create_tunnel_req, + create_tunnel_resp); + if (ret != 0) { + LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE id %ld\n", + create_tunnel_req.ue_id); + return ret; + } + + // Configure DRBs + uint8_t *kUPenc = NULL; + uint8_t *kUPint = NULL; + + nr_derive_key(UP_ENC_ALG, req->cipheringAlgorithm, (uint8_t *)req->encryptionKey, &kUPenc); + + nr_derive_key(UP_INT_ALG, req->integrityProtectionAlgorithm, (uint8_t *)req->integrityProtectionKey, &kUPint); + + nr_pdcp_e1_add_drbs(true, // set this to notify PDCP that his not UE + create_tunnel_req.ue_id, + &DRB_configList, + (req->integrityProtectionAlgorithm << 4) | req->cipheringAlgorithm, + kUPenc, + kUPint); + return ret; +} + +void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_req_t *const req) +{ + e1ap_upcp_inst_t *inst = getCxtE1(instance); + AssertFatal(inst, ""); + gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0}; + + // GTP tunnel for UL + drb_config_N3gtpu_create(req, &create_tunnel_resp_N3, inst->gtpInstN3); + + MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_RESP); + e1ap_bearer_setup_resp_t *resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg); + + in_addr_t my_addr; + if (inet_pton(AF_INET, inst->setupReq.localAddressF1U, &my_addr) != 1) + LOG_E(E1AP, "can't use the F1-U local interface: %s\n", inst->setupReq.localAddressF1U); + fill_e1ap_bearer_setup_resp(resp, req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id, inst->setupReq.remotePortF1U, my_addr); + + resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id; + resp->numPDUSessions = req->numPDUSessions; + for (int i=0; i < req->numPDUSessions; i++) { + pdu_session_setup_t *pduSetup = resp->pduSession + i; + pdu_session_to_setup_t *pdu2Setup = req->pduSession + i; + + pduSetup->id = pdu2Setup->sessionId; + if (inet_pton(AF_INET, inst->setupReq.localAddressN3, &pduSetup->tlAddress) != 1) + LOG_E(E1AP, "can't use the N3 local interface: %s\n", inst->setupReq.localAddressN3); + pduSetup->teId = create_tunnel_resp_N3.gnb_NGu_teid[i]; + pduSetup->numDRBSetup = pdu2Setup->numDRB2Setup; + + // At this point we don't have a way to know the DRBs that failed to setup + // We assume all DRBs to setup have are setup successfully so we always send successful outcome in response + // TODO: Modify nr_pdcp_add_drbs() to return DRB list that failed to setup to support E1AP + pduSetup->numDRBFailed = 0; + } + + e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(inst, resp); +} + +void CUUP_process_bearer_context_mod_req(instance_t instance, e1ap_bearer_setup_req_t *const req) +{ + e1ap_upcp_inst_t *inst = getCxtE1(instance); + AssertFatal(inst, ""); + // assume we receive modification of F1-U but it is wrong, we can also get modification of N3 when HO will occur + CU_update_UP_DL_tunnel(req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id); + // TODO: send bearer cxt mod response +} + +void CUUP_process_bearer_release_command(instance_t instance, e1ap_bearer_release_cmd_t *const cmd) +{ + e1ap_upcp_inst_t *inst = getCxtE1(instance); + AssertFatal(inst, ""); + newGtpuDeleteAllTunnels(inst->gtpInstN3, cmd->gNB_cu_up_ue_id); + newGtpuDeleteAllTunnels(inst->gtpInstF1U, cmd->gNB_cu_up_ue_id); + e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(inst, cmd); +} diff --git a/openair2/E1AP/e1ap_api.h b/openair2/E1AP/e1ap_api.h new file mode 100644 index 0000000000..1b9f219fcc --- /dev/null +++ b/openair2/E1AP/e1ap_api.h @@ -0,0 +1,35 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef E1AP_API_H +#define E1AP_API_H + +#include "platform_types.h" +#include "openair2/COMMON/e1ap_messages_types.h" +#include "openair2/E1AP/e1ap_common.h" +void cuup_init_n3(instance_t instance); +void process_e1_bearer_context_setup_req(instance_t, e1ap_bearer_setup_req_t *const req); +void CUUP_process_bearer_context_mod_req(instance_t, e1ap_bearer_setup_req_t *const req); + +void CUUP_process_bearer_release_command(instance_t, e1ap_bearer_release_cmd_t *const cmd); +#endif diff --git a/openair2/E1AP/e1ap_asnc.h b/openair2/E1AP/e1ap_asnc.h new file mode 100644 index 0000000000..00dbcc13f3 --- /dev/null +++ b/openair2/E1AP/e1ap_asnc.h @@ -0,0 +1,65 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef E1AP_ASNC_H +#define E1AP_ASNC_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c new file mode 100644 index 0000000000..2db1ecef65 --- /dev/null +++ b/openair2/E1AP/e1ap_common.c @@ -0,0 +1,235 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include "e1ap_common.h" +#include "e1ap_default_values.h" +#include "e1ap_asnc.h" +#include "common/openairinterface5g_limits.h" +#include "common/utils/ocp_itti/intertask_interface.h" + +static e1ap_upcp_inst_t *e1ap_inst[NUMBER_OF_gNB_MAX] = {0}; + +e1ap_upcp_inst_t *getCxtE1(instance_t instance) +{ + AssertFatal(instance < sizeofArray(e1ap_inst), "instance exceeds limit\n"); + return e1ap_inst[instance]; +} + +int e1ap_assoc_id(E1_t type, instance_t instance) { + AssertFatal(e1ap_inst[instance] != NULL, "Trying to access uninitiated instance of CUCP\n"); + return e1ap_inst[instance]->setupReq.assoc_id; +} + +void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req) { + AssertFatal(e1ap_inst[instance] == NULL, "Double call to E1 instance %d\n", (int)instance); + e1ap_inst[instance] = calloc(1, sizeof(e1ap_upcp_inst_t)); + e1ap_inst[instance]->type = type; + e1ap_inst[instance]->instance = instance; + if (req) + memcpy(&e1ap_inst[instance]->setupReq, req, sizeof(*req)); + e1ap_inst[instance]->gtpInstN3 = -1; + e1ap_inst[instance]->gtpInstF1U = -1; +} + +E1AP_TransactionID_t transacID[E1AP_MAX_NUM_TRANSAC_IDS] = {0}; + +void e1ap_common_init() { + srand(time(NULL)); +} + +bool check_transac_id(E1AP_TransactionID_t id, int *freeIdx) { + + bool isFreeIdxSet = false; + for (int i=0; i < E1AP_MAX_NUM_TRANSAC_IDS; i++) { + if (id == transacID[i]) + return false; + else if (!isFreeIdxSet && (transacID[i] == 0)) { + *freeIdx = i; + isFreeIdxSet = true; + } + } + + return true; +} + +E1AP_TransactionID_t E1AP_get_next_transaction_identifier() { + E1AP_TransactionID_t genTransacId; + bool isTransacIdValid = false; + int freeIdx; + + while (!isTransacIdValid) { + genTransacId = rand() & 255; + isTransacIdValid = check_transac_id(genTransacId, &freeIdx); + } + + AssertFatal(freeIdx < E1AP_MAX_NUM_TRANSAC_IDS, "Free Index exceeds array length\n"); + transacID[freeIdx] = genTransacId; + return genTransacId; +} + +void E1AP_free_transaction_identifier(E1AP_TransactionID_t id) { + + for (int i=0; i < E1AP_MAX_NUM_TRANSAC_IDS; i++) { + if (id == transacID[i]) { + transacID[i] = 0; + return; + } + } + LOG_E(E1AP, "Couldn't find transaction ID %ld in list\n", id); +} + +int e1ap_decode_initiating_message(E1AP_E1AP_PDU_t *pdu) { + DevAssert(pdu != NULL); + + switch(pdu->choice.initiatingMessage->procedureCode) { + case E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup: + break; + + case E1AP_ProcedureCode_id_gNB_CU_UP_ConfigurationUpdate: + break; + + case E1AP_ProcedureCode_id_bearerContextSetup: + break; + + case E1AP_ProcedureCode_id_bearerContextModification: + break; + + default: + LOG_E(E1AP, "Unsupported procedure code (%d) for initiating message\n", + (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + return 0; +} + +int e1ap_decode_successful_outcome(E1AP_E1AP_PDU_t *pdu) { + DevAssert(pdu != NULL); + switch(pdu->choice.successfulOutcome->procedureCode) { + case E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup: + break; + + case E1AP_ProcedureCode_id_bearerContextSetup: + break; + + default: + LOG_E(E1AP, "Unsupported procedure code (%d) for successful message\n", + (int)pdu->choice.successfulOutcome->procedureCode); + return -1; + } + return 0; +} + +int e1ap_decode_unsuccessful_outcome(E1AP_E1AP_PDU_t *pdu) { + DevAssert(pdu != NULL); + switch(pdu->choice.unsuccessfulOutcome->procedureCode) { + case E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup: + break; + + default: + LOG_E(E1AP, "Unsupported procedure code (%d) for unsuccessful message\n", + (int)pdu->choice.unsuccessfulOutcome->procedureCode); + return -1; + } + return 0; +} + +int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) { + asn_dec_rval_t dec_ret; + DevAssert(buffer != NULL); + dec_ret = aper_decode(NULL, + &asn_DEF_E1AP_E1AP_PDU, + (void **)&pdu, + buffer, + length, + 0, + 0); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + LOG_E(E1AP, "----------------- ASN1 DECODER PRINT START----------------- \n"); + xer_fprint(stdout, &asn_DEF_E1AP_E1AP_PDU, pdu); + LOG_E(E1AP, "----------------- ASN1 DECODER PRINT END ----------------- \n"); + } + + if (dec_ret.code != RC_OK) { + AssertFatal(1==0,"Failed to decode pdu\n"); + return -1; + } + + switch(pdu->present) { + case E1AP_E1AP_PDU_PR_initiatingMessage: + return e1ap_decode_initiating_message(pdu); + + case E1AP_E1AP_PDU_PR_successfulOutcome: + return e1ap_decode_successful_outcome(pdu); + + case E1AP_E1AP_PDU_PR_unsuccessfulOutcome: + return e1ap_decode_unsuccessful_outcome(pdu); + + default: + LOG_E(E1AP, "Unknown presence (%d) or not implemented\n", (int)pdu->present); + break; + } + + return -1; +} + +int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func) +{ + DevAssert(pdu != NULL); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + LOG_E(E1AP, "----------------- ASN1 ENCODER PRINT START ----------------- \n"); + xer_fprint(stdout, &asn_DEF_E1AP_E1AP_PDU, pdu); + LOG_E(E1AP, "----------------- ASN1 ENCODER PRINT END----------------- \n"); + } + + char errbuf[2048]; /* Buffer for error message */ + size_t errlen = sizeof(errbuf); /* Size of the buffer */ + int ret = asn_check_constraints(&asn_DEF_E1AP_E1AP_PDU, pdu, errbuf, &errlen); + + if(ret) { + LOG_E(E1AP, "%s: Constraint validation failed: %s\n", func, errbuf); + } + + void *buffer = NULL; + ssize_t encoded = aper_encode_to_new_buffer(&asn_DEF_E1AP_E1AP_PDU, 0, pdu, &buffer); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_E1AP_E1AP_PDU, pdu); + + if (encoded < 0) { + LOG_E(E1AP, "%s: Failed to encode E1AP message\n", func); + return -1; + } else { + MessageDef *message = itti_alloc_new_message((type==CPtype)?TASK_CUCP_E1:TASK_CUUP_E1, 0, SCTP_DATA_REQ); + sctp_data_req_t *s = &message->ittiMsg.sctp_data_req; + s->assoc_id = setupReq->assoc_id; + s->buffer = buffer; + s->buffer_length = encoded; + s->stream = stream; + LOG_I(E1AP, "%s: Sending ITTI message to SCTP Task\n", func); + itti_send_msg_to_task(TASK_SCTP, 0 /*unused by callee*/, message); + } + + return encoded; +} diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h new file mode 100644 index 0000000000..80a2b925e1 --- /dev/null +++ b/openair2/E1AP/e1ap_common.h @@ -0,0 +1,64 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef E1AP_COMMON_H_ +#define E1AP_COMMON_H_ +#include "openair2/COMMON/e1ap_messages_types.h" +#include "e1ap_asnc.h" +#include "openair2/COMMON/sctp_messages_types.h" +#include "common/ngran_types.h" + +typedef struct e1ap_upcp_inst_s { + bool incoming_sock; + instance_t instance; + bool same_process; + E1_t type; + enum sctp_state_e sockState; + uint32_t assoc_id; + instance_t gtpInstN3; + instance_t gtpInstF1U; + e1ap_setup_req_t setupReq; + e1ap_bearer_setup_req_t bearerSetupReq; + e1ap_bearer_setup_resp_t bearerSetupResp; +} e1ap_upcp_inst_t; + +extern int asn1_xer_print; + +int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length); + +e1ap_upcp_inst_t *getCxtE1(instance_t instance); + +E1AP_TransactionID_t E1AP_get_next_transaction_identifier(); + +void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req); + +bool check_transac_id(E1AP_TransactionID_t id, int *freeIdx); + +int e1ap_assoc_id(E1_t type, instance_t instance); + +int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func); + +void e1ap_common_init(); + +void E1AP_free_transaction_identifier(E1AP_TransactionID_t id); +#endif /* E1AP_COMMON_H_ */ diff --git a/executables/create_nr_tasks.h b/openair2/E1AP/e1ap_default_values.h similarity index 88% rename from executables/create_nr_tasks.h rename to openair2/E1AP/e1ap_default_values.h index 23dd23e7db..f5980031df 100644 --- a/executables/create_nr_tasks.h +++ b/openair2/E1AP/e1ap_default_values.h @@ -19,11 +19,10 @@ * contact@openairinterface.org */ -#ifndef CREATE_NR_TASKS_H_ -#define CREATE_NR_TASKS_H_ +#ifndef E1AP_DEFAULT_VALUES_H +#define E1AP_DEFAULT_VALUES_H +#define E1AP_PORT_NUMBER (38462) +#define E1AP_SCTP_PPID (64) -int create_gNB_tasks(uint32_t gnb_nb); - - -#endif /* CREATE_TASKS_H_ */ +#endif diff --git a/openair2/E1AP/e1ap_setup.c b/openair2/E1AP/e1ap_setup.c new file mode 100644 index 0000000000..349e3dcab5 --- /dev/null +++ b/openair2/E1AP/e1ap_setup.c @@ -0,0 +1,129 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include +#include "common/utils/LOG/log.h" +#include "common/utils/nr/nr_common.h" +#include "common/utils/LOG/log_extern.h" +#include "assertions.h" +#include "common/utils/ocp_itti/intertask_interface.h" +#include "openair2/GNB_APP/gnb_paramdef.h" +#include "openair3/ocp-gtpu/gtp_itf.h" + +static void get_NGU_S1U_addr(char **addr, uint16_t *port) +{ + int num_gnbs = 0; + char *gnb_ipv4_address_for_NGU = NULL; + uint32_t gnb_port_for_NGU = 0; + char *gnb_ipv4_address_for_S1U = NULL; + uint32_t gnb_port_for_S1U = 0; + char gtpupath[MAX_OPTNAME_SIZE * 2 + 8]; + + paramdef_t GNBSParams[] = GNBSPARAMS_DESC; + paramdef_t NETParams[] = GNBNETPARAMS_DESC; + LOG_I(GTPU, "Configuring GTPu\n"); + + /* get number of active eNodeBs */ + config_get(GNBSParams, sizeof(GNBSParams) / sizeof(paramdef_t), NULL); + num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; + AssertFatal(num_gnbs > 0, "Failed to parse config file no active gNodeBs in %s \n", GNB_CONFIG_STRING_ACTIVE_GNBS); + + sprintf(gtpupath, "%s.[%i].%s", GNB_CONFIG_STRING_GNB_LIST, 0, GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + config_get(NETParams, sizeof(NETParams) / sizeof(paramdef_t), gtpupath); + char *address; + if (NETParams[1].strptr != NULL) { + LOG_I(GTPU, "SA mode \n"); + address = strdup(gnb_ipv4_address_for_NGU); + *port = gnb_port_for_NGU; + } else { + LOG_I(GTPU, "NSA mode \n"); + address = strdup(gnb_ipv4_address_for_S1U); + *port = gnb_port_for_S1U; + } + if (strchr(address, '/')) + *strchr(address, '/') = 0; + *addr = address; + return; +} + +MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process) +{ + MessageDef *msgConfig = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_SETUP_REQ); + if (!msgConfig) + return NULL; + + paramdef_t GNBSParams[] = GNBSPARAMS_DESC; + paramdef_t GNBParams[] = GNBPARAMS_DESC; + paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST, NULL, 0}; + config_get(GNBSParams, sizeofArray(GNBSParams), NULL); + char aprefix[MAX_OPTNAME_SIZE * 2 + 8]; + sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); + int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; + AssertFatal(num_gnbs == 1, "Support only one gNB per process\n"); + + if (num_gnbs > 0) { + config_getlist(&GNBParamList, GNBParams, sizeofArray(GNBParams), NULL); + paramdef_t *gnbParms = GNBParamList.paramarray[0]; + AssertFatal(gnbParms[GNB_GNB_ID_IDX].uptr != NULL, "gNB id %u is not defined in configuration file\n", 0); + e1ap_setup_req_t *e1Setup = &E1AP_SETUP_REQ(msgConfig); + msgConfig->ittiMsgHeader.destinationInstance = 0; + e1Setup->gNB_cu_up_id = *(gnbParms[GNB_GNB_ID_IDX].uptr); + + paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC; + paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0}; + /* map parameter checking array instances to parameter definition array instances */ + checkedparam_t config_check_PLMNParams[] = PLMNPARAMS_CHECK; + + for (int I = 0; I < sizeofArray(PLMNParams); ++I) + PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); + + config_getlist(&PLMNParamList, PLMNParams, sizeofArray(PLMNParams), aprefix); + int numPLMNs = PLMNParamList.numelt; + e1Setup->supported_plmns = numPLMNs; + + for (int I = 0; I < numPLMNs; I++) { + e1Setup->plmns[I].mcc = *PLMNParamList.paramarray[I][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; + e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MOBILE_NETWORK_CODE_IDX].uptr; + e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MNC_DIGIT_LENGTH].u8ptr; + } + + e1Setup->remotePortF1U = *(GNBParamList.paramarray[0][GNB_REMOTE_S_PORTD_IDX].uptr); + e1Setup->localAddressF1U = strdup(*(GNBParamList.paramarray[0][GNB_LOCAL_S_ADDRESS_IDX].strptr)); + e1Setup->localPortF1U = *(GNBParamList.paramarray[0][GNB_LOCAL_S_PORTD_IDX].uptr); + get_NGU_S1U_addr(&e1Setup->localAddressN3, &e1Setup->localPortN3); + e1Setup->remotePortN3 = GTPV1_U_PORT_NUMBER; + + if (separate_CUUP_process) { + paramlist_def_t GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0}; + paramdef_t GNBE1Params[] = GNBE1PARAMS_DESC; + config_getlist(&GNBE1ParamList, GNBE1Params, sizeofArray(GNBE1Params), aprefix); + paramdef_t *e1Parms = GNBE1ParamList.paramarray[0]; + strcpy(e1Setup->CUCP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUCP].strptr)); + e1Setup->CUCP_e1_ip_address.ipv4 = 1; + strcpy(e1Setup->CUUP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUUP].strptr)); + e1Setup->CUUP_e1_ip_address.ipv4 = 1; + e1Setup->cn_support = *e1Parms[GNB_CONFIG_E1_CN_SUPPORT].uptr; + } + } + return msgConfig; +} diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 98ddaebfdc..9a0ed3f04a 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -40,7 +40,8 @@ # include "intertask_interface.h" # include "s1ap_eNB.h" -#include "sctp_eNB_task.h" +# include "sctp_eNB_task.h" +# include "openair3/ocp-gtpu/gtp_itf.h" # include "x2ap_eNB.h" # include "x2ap_messages_types.h" diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index fbb5fd0225..776c89c02b 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -2015,7 +2015,7 @@ int RCconfig_gtpu(void ) { int num_enbs = 0; char *enb_interface_name_for_S1U = NULL; char *enb_ipv4_address_for_S1U = NULL; - uint32_t enb_port_for_S1U = 0; + uint16_t enb_port_for_S1U = 0; char *address = NULL; char *cidr = NULL; char gtpupath[MAX_OPTNAME_SIZE*2 + 8]; diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 1f2ca6392f..647ac96c18 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -1123,12 +1123,13 @@ typedef struct srb1_params_s { /* S1/X2 interface configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*--------------------------------------------------------------------------------------------------------------------------------------------------*/ +// clang-format off #define NETPARAMS_DESC { \ {ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_ENB_PORT_FOR_S1U, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_ENB_PORT_FOR_S1U, NULL, 0, u16ptr:NULL, defuintval:GTPV1_U_PORT_NUMBER, TYPE_UINT16, 0}, \ {ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_ENB_PORT_FOR_X2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_M2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ @@ -1144,8 +1145,10 @@ typedef struct srb1_params_s { #define GTPUPARAMS_DESC { \ {ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:&enb_interface_name_for_S1U, defstrval:"lo", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U, NULL, 0, strptr:&enb_ipv4_address_for_S1U, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_ENB_PORT_FOR_S1U, NULL, 0, uptr:&enb_port_for_S1U, defintval:2152, TYPE_UINT, 0} \ + {ENB_CONFIG_STRING_ENB_PORT_FOR_S1U, NULL, 0, u16ptr:&enb_port_for_S1U, defuintval:GTPV1_U_PORT_NUMBER, TYPE_UINT16, 0} \ } +// clang-format on + /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/F1AP/dummy_enb.c b/openair2/F1AP/dummy_enb.c index afb4a1048a..942e652213 100644 --- a/openair2/F1AP/dummy_enb.c +++ b/openair2/F1AP/dummy_enb.c @@ -26,12 +26,6 @@ #include "NR_ServingCellConfigCommon.h" #include "NR_MIB.h" -void apply_macrlc_config(gNB_RRC_INST *rrc, - rrc_gNB_ue_context_t *const ue_context_pP, - const protocol_ctxt_t *const ctxt_pP ) { - abort(); -} - bool sdap_data_req(protocol_ctxt_t *ctxt_p, const ue_id_t ue_id, const srb_flag_t srb_flag, diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 39274cdf38..0dfcefaef3 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -144,7 +144,9 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, // LTS: FIXME data model failure: we don't KNOW if we receive a 4G or a 5G cell // Furthermore, cell_type is not a attribute of a cell in the data structure !!!!!!!!!! - if (RC.nrrrc && RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU) + if (RC.nrrrc && + ( RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CU || + RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type == ngran_gNB_CUCP) ) f1ap_req(true, instance)->cell_type=CELL_MACRO_GNB; else f1ap_req(true, instance)->cell_type=CELL_MACRO_ENB; diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index b4e0c1ad2a..09b3651035 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -57,8 +57,11 @@ static void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_as f1ap_cu_data->sctp_in_streams = sctp_new_association_ind->in_streams; f1ap_cu_data->sctp_out_streams = sctp_new_association_ind->out_streams; f1ap_cu_data->default_sctp_stream_id = 0; - getCxt(CUtype, instance)->gtpInst=cu_task_create_gtpu_instance(IPaddrs); - AssertFatal(getCxt(CUtype, instance)->gtpInst>0,"Failed to create CU F1-U UDP listener"); + if (RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type != ngran_gNB_CUCP) { + getCxt(CUtype, instance)->gtpInst = cu_task_create_gtpu_instance(IPaddrs); + AssertFatal(getCxt(CUtype, instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener"); + } else + LOG_I(F1AP, "In F1AP connection, don't start GTP-U, as we have also E1AP\n"); // Fixme: fully inconsistent instances management // dirty global var is a bad fix CUuniqInstance=getCxt(CUtype, instance)->gtpInst; @@ -120,7 +123,9 @@ void *F1AP_CU_task(void *arg) { eth_params_t *IPaddrs; // Hardcoded instance id! - if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_CU) + if (RC.nrrrc && + (RC.nrrrc[0]->node_type == ngran_gNB_CU || + RC.nrrrc[0]->node_type == ngran_gNB_CUCP ) ) IPaddrs=&RC.nrrrc[0]->eth_params_s; else IPaddrs=&RC.rrc[0]->eth_params_s; @@ -129,71 +134,57 @@ void *F1AP_CU_task(void *arg) { while (1) { itti_receive_msg(TASK_CU_F1, &received_msg); - + LOG_I(F1AP, "CU Task Received %s for instance %ld\n", + ITTI_MSG_NAME(received_msg), ITTI_MSG_DESTINATION_INSTANCE(received_msg)); switch (ITTI_MSG_ID(received_msg)) { case SCTP_NEW_ASSOCIATION_IND: - LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_IND for instance %ld\n", - ITTI_MSG_DESTINATION_INSTANCE(received_msg)); cu_task_handle_sctp_association_ind(ITTI_MSG_ORIGIN_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_ind, IPaddrs); break; case SCTP_NEW_ASSOCIATION_RESP: - LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_RESP for instance %ld\n", - ITTI_MSG_DESTINATION_INSTANCE(received_msg)); cu_task_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_resp); break; case SCTP_DATA_IND: - LOG_I(F1AP, "CU Task Received SCTP_DATA_IND for Instance %ld\n", - ITTI_MSG_DESTINATION_INSTANCE(received_msg)); cu_task_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_data_ind); break; case F1AP_SETUP_RESP: // from rrc - LOG_I(F1AP, "CU Task Received F1AP_SETUP_RESP\n"); CU_send_F1_SETUP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_SETUP_RESP(received_msg)); break; case F1AP_GNB_CU_CONFIGURATION_UPDATE: // from rrc - LOG_I(F1AP, "CU Task Received F1AP_GNB_CU_CONFIGURAITON_UPDATE\n"); - // CU_send_f1setup_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - // &F1AP_SETUP_RESP(received_msg)); CU_send_gNB_CU_CONFIGURATION_UPDATE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_GNB_CU_CONFIGURATION_UPDATE(received_msg)); break; case F1AP_DL_RRC_MESSAGE: // from rrc - LOG_I(F1AP, "CU Task Received F1AP_DL_RRC_MESSAGE\n"); CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_DL_RRC_MESSAGE(received_msg)); free(F1AP_DL_RRC_MESSAGE(received_msg).rrc_container); break; case F1AP_UE_CONTEXT_SETUP_REQ: // from rrc - LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_SETUP_REQ\n"); CU_send_UE_CONTEXT_SETUP_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_UE_CONTEXT_SETUP_REQ(received_msg)); break; case F1AP_UE_CONTEXT_MODIFICATION_REQ: - LOG_I(F1AP, "CU Task received F1AP_UE_CONTEXT_MODIFICATION_REQ\n"); CU_send_UE_CONTEXT_MODIFICATION_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg)); + &F1AP_UE_CONTEXT_SETUP_REQ(received_msg)); break; case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc - LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_RELEASE_CMD\n"); CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_UE_CONTEXT_RELEASE_CMD(received_msg)); break; case F1AP_PAGING_IND: - LOG_I(F1AP, "CU Task Received F1AP_PAGING_IND\n"); CU_send_Paging(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_PAGING_IND(received_msg)); break; diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 597887b841..d609cb98cb 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -510,6 +510,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { + /*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/ /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */ transport_layer_addr_t addr = { length: 32, buffer: { 0 } }; f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst, @@ -1009,7 +1010,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_remove_ue(CUtype, instance, rnti); return 0; } -//void CU_send_UE_CONTEXT_MODIFICATION_REQUEST(F1AP_UEContextModificationRequest_t *UEContextModificationRequest) { + int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_setup_t *f1ap_ue_context_modification_req) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationRequest_t *out; @@ -1477,19 +1478,6 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ for (int j = 0; j < f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context modification response from the DU */ - transport_layer_addr_t addr = { length: 32, buffer: { 0 } }; - - f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst, - f1ap_ue_context_modification_req->rnti, - f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id, - f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id, - 0xFFFF, // We will set the right value from DU answer - -1, // no qfi - addr, // We will set the right value from DU answer - f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].port, - cu_f1u_data_req, - NULL); - /* 12.3.1 ULTunnels_ToBeSetup_Item */ asn1cSequenceAdd(drbs_toBeSetupMod_item->uLUPTNLInformation_ToBeSetup_List.list, F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; diff --git a/openair2/F1AP/f1ap_decoder.c b/openair2/F1AP/f1ap_decoder.c index 6d1c60c67d..0085add838 100644 --- a/openair2/F1AP/f1ap_decoder.c +++ b/openair2/F1AP/f1ap_decoder.c @@ -166,7 +166,8 @@ static int f1ap_decode_unsuccessful_outcome(F1AP_F1AP_PDU_t *pdu) { int f1ap_decode_pdu(F1AP_F1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) { asn_dec_rval_t dec_ret; DevAssert(buffer != NULL); - dec_ret = aper_decode(NULL, + asn_codec_ctx_t st={.max_stack_size = 100 * 1000}; + dec_ret = aper_decode(&st, &asn_DEF_F1AP_F1AP_PDU, (void **)&pdu, buffer, diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index ac952e0498..c11316e19b 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -107,18 +107,18 @@ void *F1AP_DU_task(void *arg) { MessageDef *msg = NULL; itti_receive_msg(TASK_DU_F1, &msg); instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg); - + LOG_I(F1AP, "DU Task Received %s for instance %ld\n", + ITTI_MSG_NAME(msg),myInstance); switch (ITTI_MSG_ID(msg)) { - case F1AP_SETUP_REQ: + case F1AP_SETUP_REQ: { // this is not a true F1 message, but rather an ITTI message sent by enb_app // 1. save the itti msg so that you can use it to sen f1ap_setup_req, fill the f1ap_setup_req message, // 2. store the message in f1ap context, that is also stored in RC // 2. send a sctp_association req - LOG_I(F1AP, "DU Task Received F1AP_SETUP_REQ\n"); - f1ap_setup_req_t *msgSetup=&F1AP_SETUP_REQ(msg); + f1ap_setup_req_t *msgSetup = &F1AP_SETUP_REQ(msg); createF1inst(false, myInstance, msgSetup); - du_task_send_sctp_association_req(myInstance,msgSetup); - break; + du_task_send_sctp_association_req(myInstance, msgSetup); + } break; case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE: DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MSG_ORIGIN_INSTANCE(msg), @@ -133,32 +133,23 @@ void *F1AP_DU_task(void *arg) { case SCTP_NEW_ASSOCIATION_RESP: // 1. store the respon // 2. send the f1setup_req - LOG_I(F1AP, "DU Task Received SCTP_NEW_ASSOCIATION_RESP\n"); du_task_handle_sctp_association_resp(myInstance, &msg->ittiMsg.sctp_new_association_resp); break; case SCTP_DATA_IND: // ex: any F1 incoming message for DU ends here - LOG_I(F1AP, "DU Task Received SCTP_DATA_IND\n"); du_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind); break; case F1AP_INITIAL_UL_RRC_MESSAGE: // from rrc - LOG_I(F1AP, "DU Task Received F1AP_INITIAL_UL_RRC_MESSAGE\n"); + { f1ap_initial_ul_rrc_message_t *msgRrc = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); - DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(0,0,0,msgRrc->crnti, - msgRrc->rrc_container, - msgRrc->rrc_container_length, - msgRrc->du2cu_rrc_container, - msgRrc->du2cu_rrc_container_length - ); - break; + DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(0, 0, 0, msgRrc->crnti, msgRrc->rrc_container, msgRrc->rrc_container_length, msgRrc->du2cu_rrc_container, msgRrc->du2cu_rrc_container_length); + } break; case F1AP_UL_RRC_MESSAGE: // to rrc - LOG_D(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n"); - if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) { DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance, &F1AP_UL_RRC_MESSAGE(msg)); @@ -174,12 +165,10 @@ void *F1AP_DU_task(void *arg) { break; case F1AP_UE_CONTEXT_MODIFICATION_RESP: - LOG_I(F1AP, "DU task received itti message from RRC for F1AP_UE_CONTEXT_MODIFICATION_RESP message generation \n"); DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg)); break; case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC - LOG_I(F1AP, "DU Task Received F1AP_UE_CONTEXT_RELEASE_REQ\n"); DU_send_UE_CONTEXT_RELEASE_REQUEST(myInstance, &F1AP_UE_CONTEXT_RELEASE_REQ(msg)); break; diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 4be90a9c15..23ab58c6ed 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -1078,7 +1078,7 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, char *DUaddr, uint16_t DUport) { - openAddr_t tmp={0}; + openAddr_t tmp = {0}; strncpy(tmp.originHost, DUaddr, sizeof(tmp.originHost)-1); strncpy(tmp.destinationHost, CUaddr, sizeof(tmp.destinationHost)-1); sprintf(tmp.originService, "%d", DUport); diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h index 089569f84e..e5bcd0e228 100644 --- a/openair2/GNB_APP/RRC_nr_paramsvalues.h +++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h @@ -39,7 +39,6 @@ /* cell configuration section name */ #define GNB_CONFIG_STRING_GNB_LIST "gNBs" -#define GNB_CONFIG_STRING_PDCCH_CONFIGSIB1 "pdcch_ConfigSIB1" #define GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON "servingCellConfigCommon" #define GNB_CONFIG_STRING_PHYSCELLID "physCellId" #define GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET "n_TimingAdvanceOffset" @@ -160,19 +159,6 @@ #define GNB_CONFIG_STRING_SCS_ULBWP4 "ul_bwp4_subcarrierSpacing" #define GNB_CONFIG_STRING_FIRSTACTIVEULBWP_ID "firstActiveUplinkBWP-Id" -/*--------------------------------------------------------------------------------------------------------------------*/ -/* pdcch_ConfigSIB1 parameters */ -/*--------------------------------------------------------------------------------------------------------------------*/ -#define CONTROL_RESOURCE_SET_ZERO "controlResourceSetZero" -#define SEARCH_SPACE_ZERO "searchSpaceZero" - -#define PDCCH_CONFIGSIB1PARAMS_DESC(pdcch_ConfigSIB1) { \ -{CONTROL_RESOURCE_SET_ZERO, NULL, 0, i64ptr:&pdcch_ConfigSIB1->controlResourceSetZero, defintval:0, TYPE_INT64, 0}, \ -{SEARCH_SPACE_ZERO, NULL, 0, i64ptr:&pdcch_ConfigSIB1->searchSpaceZero, defintval:0, TYPE_INT64, 0} \ -} - -#define CONTROL_RESOURCE_SET_ZERO_IDX 0 -#define SEARCH_SPACE_ZERO_IDX 1 /*--------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ @@ -201,8 +187,8 @@ {GNB_CONFIG_STRING_DLCARRIERBANDWIDTH,NULL,0,i64ptr:&scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,defint64val:217,TYPE_INT64,0 /*10*/}, \ {GNB_CONFIG_STRING_INITIALDLBWPLOCATIONANDBANDWIDTH,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,defint64val:13036,TYPE_INT64,0/*11*/},\ {GNB_CONFIG_STRING_INITIALDLBWPSUBCARRIERSPACING,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing,defint64val:NR_SubcarrierSpacing_kHz30,TYPE_INT64,0/*12*/},\ -{GNB_CONFIG_STRING_INITIALDLBWPCONTROLRESOURCESETZERO,NULL,0,i64ptr:scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero,defint64val:12,TYPE_INT64,0/*13*/},\ -{GNB_CONFIG_STRING_INITIALDLBWPSEARCHSPACEZERO,NULL,0,i64ptr:scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero,defint64val:0,TYPE_INT64,0/*14*/},\ +{GNB_CONFIG_STRING_INITIALDLBWPCONTROLRESOURCESETZERO,NULL,0,i64ptr:scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero,defint64val:-1,TYPE_INT64,0/*13*/},\ +{GNB_CONFIG_STRING_INITIALDLBWPSEARCHSPACEZERO,NULL,0,i64ptr:scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero,defint64val:-1,TYPE_INT64,0/*14*/},\ {GNB_CONFIG_STRING_ULFREQUENCYBAND,NULL,0,i64ptr:scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0],defint64val:-1,TYPE_INT64,0/*63*/},\ {GNB_CONFIG_STRING_ULABSOLUEFREQUENCYPOINTA,NULL,0,i64ptr:scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA,defint64val:-1,TYPE_INT64,0/*64*/},\ {GNB_CONFIG_STRING_ULOFFSETTOCARRIER,NULL,0,i64ptr:&scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier,defint64val:0,TYPE_INT64,0/*65*/},\ diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index 862cf9dddc..680b566eec 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -35,7 +35,6 @@ #include #include "gnb_app.h" -#include "gnb_config.h" #include "assertions.h" #include "common/ran_context.h" @@ -52,6 +51,8 @@ #include "nfapi/oai_integration/vendor_ext.h" #include #include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h" +#include "openair2/E1AP/e1ap.h" +#include "gnb_config.h" extern unsigned char NB_gNB_INST; extern RAN_CONTEXT_t RC; @@ -59,7 +60,7 @@ extern RAN_CONTEXT_t RC; #define GNB_REGISTER_RETRY_DELAY 10 /*------------------------------------------------------------------------------*/ -static void configure_nr_rrc(uint32_t gnb_id) +void configure_nr_rrc(uint32_t gnb_id) { MessageDef *msg_p = NULL; // int CC_id; @@ -80,7 +81,7 @@ static void configure_nr_rrc(uint32_t gnb_id) /*------------------------------------------------------------------------------*/ -static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties) +uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties) { uint32_t gnb_id; MessageDef *msg_p; @@ -102,7 +103,6 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, itti_send_msg_to_task (TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); } - if (gnb_id == 0) RCconfig_nr_gtpu(); } LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id)); @@ -115,7 +115,7 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, /*------------------------------------------------------------------------------*/ -static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) { +uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) { uint32_t gnb_id; MessageDef *msg_p; uint32_t register_gnb_x2_pending = 0; @@ -138,10 +138,6 @@ static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) void *gNB_app_task(void *args_p) { - uint32_t gnb_nb = RC.nb_nr_inst; - uint32_t gnb_id_start = 0; - uint32_t gnb_id_end = gnb_id_start + gnb_nb; - uint32_t gnb_id; MessageDef *msg_p = NULL; const char *msg_name = NULL; instance_t instance; @@ -151,60 +147,35 @@ void *gNB_app_task(void *args_p) int cell_to_activate = 0; itti_mark_task_ready (TASK_GNB_APP); + ngran_node_t node_type = get_node_type(); - LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__); - - RCconfig_NR_L1(); - RCconfig_nr_prs(); - - if (RC.nb_nr_macrlc_inst>0) RCconfig_nr_macrlc(); - - LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst); - - if (RC.nb_nr_L1_inst>0) AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n"); - - AssertFatal (gnb_nb <= RC.nb_nr_inst, - "Number of gNB is greater than gNB defined in configuration file (%d/%d)!", - gnb_nb, RC.nb_nr_inst); - - LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst); - - RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *)); - LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc); - for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) { - RC.nrrrc[gnb_id] = (gNB_RRC_INST*)calloc(1,sizeof(gNB_RRC_INST)); - LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, gnb_id_end); - configure_nr_rrc(gnb_id); - } - - if (RC.nb_nr_inst > 0 && !get_softmodem_params()->nsa) { - init_pdcp(); - } - - if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type) - LOG_I(X2AP, "X2AP enabled \n"); - __attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end); - } - - /* For the CU case the gNB registration with the AMF might have to take place after the F1 setup, as the PLMN info - * can originate from the DU. Add check on whether x2ap is enabled to account for ENDC NSA scenario.*/ - if ((get_softmodem_params()->sa || is_x2ap_enabled()) && !NODE_IS_DU(RC.nrrrc[0]->node_type) ) { //&& !NODE_IS_CU(RC.nrrrc[0]->node_type)) { - /* Try to register each gNB */ - //registered_gnb = 0; - __attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end); - } - if (RC.nb_nr_inst > 0) { - if (NODE_IS_CU(RC.nrrrc[0]->node_type)) { + if (node_type == ngran_gNB_CUCP || + node_type == ngran_gNB_CU || + node_type == ngran_eNB_CU || + node_type == ngran_ng_eNB_CU) { if (itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL) < 0) { - LOG_E(F1AP, "Create task for F1AP CU failed\n"); - AssertFatal(1==0,"exiting"); + LOG_E(F1AP, "Create task for F1AP CU failed\n"); + AssertFatal(1==0,"exiting"); } } - if (NODE_IS_DU(RC.nrrrc[0]->node_type)) { + if (node_type == ngran_gNB_CUCP) { + if (itti_create_task(TASK_CUCP_E1, E1AP_CUCP_task, NULL) < 0) + AssertFatal(false, "Create task for E1AP CP failed\n"); + MessageDef *msg = RCconfig_NR_CU_E1(true); + if (msg) + itti_send_msg_to_task(TASK_CUCP_E1, 0, msg); + else + AssertFatal(false, "Send inti to task for E1AP CP failed\n"); + } + if (node_type == ngran_gNB_CUUP) { + AssertFatal(false, "To run CU-UP use executable nr-cuup\n"); + } + + if (NODE_IS_DU(node_type)) { if (itti_create_task(TASK_DU_F1, F1AP_DU_task, NULL) < 0) { LOG_E(F1AP, "Create task for F1AP DU failed\n"); AssertFatal(1==0,"exiting"); @@ -213,7 +184,7 @@ void *gNB_app_task(void *args_p) LOG_I(GNB_APP,"ngran_gNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n"); msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, F1AP_SETUP_REQ); RCconfig_NR_DU_F1(msg_p, 0); - + itti_send_msg_to_task (TASK_DU_F1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p); } } @@ -279,7 +250,7 @@ void *gNB_app_task(void *args_p) break; case F1AP_SETUP_RESP: - AssertFatal(NODE_IS_DU(RC.nrrrc[0]->node_type), "Should not have received F1AP_SETUP_RESP in CU/gNB\n"); + AssertFatal(NODE_IS_DU(node_type), "Should not have received F1AP_SETUP_RESP in CU/gNB\n"); LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p), F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate); @@ -289,7 +260,7 @@ void *gNB_app_task(void *args_p) break; case F1AP_GNB_CU_CONFIGURATION_UPDATE: - AssertFatal(NODE_IS_DU(RC.nrrrc[0]->node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n"); + AssertFatal(NODE_IS_DU(node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n"); LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p), F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).gNB_CU_name,F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate); diff --git a/openair2/GNB_APP/gnb_app.h b/openair2/GNB_APP/gnb_app.h index b0b422aae1..44c4374fc3 100644 --- a/openair2/GNB_APP/gnb_app.h +++ b/openair2/GNB_APP/gnb_app.h @@ -33,6 +33,7 @@ #include void *gNB_app_task(void *args_p); - - +void configure_nr_rrc(uint32_t gnb_id); +uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end); +uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end); #endif /* GNB_APP_H_ */ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index e4a855acda..c1fa1d49b9 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -91,8 +91,6 @@ extern uint16_t sf_ahead; int macrlc_has_f1 = 0; -static ngran_node_t get_node_type(void); - extern int config_check_band_frequencies(int ind, int16_t band, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint32_t frame_type); @@ -349,6 +347,17 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) { } } + // fix SS0 and Coreset0 + NR_PDCCH_ConfigCommon_t *pdcch_cc = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup; + if((int)*pdcch_cc->searchSpaceZero == -1) { + free(pdcch_cc->searchSpaceZero); + pdcch_cc->searchSpaceZero = NULL; + } + if((int)*pdcch_cc->controlResourceSetZero == -1) { + free(pdcch_cc->controlResourceSetZero); + pdcch_cc->controlResourceSetZero = NULL; + } + // fix UL absolute frequency if ((int)*scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA==-1) { free(scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA); @@ -1105,17 +1114,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { gnb_id = *(GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr); } - // pdcch_ConfigSIB1 - rrc->carrier.pdcch_ConfigSIB1 = calloc(1,sizeof(NR_PDCCH_ConfigSIB1_t)); - paramdef_t pdcch_ConfigSIB1[] = PDCCH_CONFIGSIB1PARAMS_DESC(rrc->carrier.pdcch_ConfigSIB1); - paramlist_def_t pdcch_ConfigSIB1ParamList = {GNB_CONFIG_STRING_PDCCH_CONFIGSIB1, NULL, 0}; - sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); - config_getlist(&pdcch_ConfigSIB1ParamList, NULL, 0, aprefix); - if (pdcch_ConfigSIB1ParamList.numelt > 0) { - sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_PDCCH_CONFIGSIB1, 0); - config_get(pdcch_ConfigSIB1,sizeof(pdcch_ConfigSIB1)/sizeof(paramdef_t),aprefix); - } - sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); config_getlist(&SCCsParamList, NULL, 0, aprefix); @@ -1154,7 +1152,8 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { printf("NRRRC %d: Southbound Transport %s\n",i,*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr)); - if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) { + rrc->node_type = get_node_type(); + if (NODE_IS_CU(rrc->node_type)) { paramdef_t SCTPParams[] = GNBSCTPPARAMS_DESC; char aprefix[MAX_OPTNAME_SIZE*2 + 8]; sprintf(aprefix,"%s.[%u].%s",GNB_CONFIG_STRING_GNB_LIST,i,GNB_CONFIG_STRING_SCTP_CONFIG); @@ -1171,21 +1170,12 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { rrc->eth_params_s.my_portd = *(GNBParamList.paramarray[i][GNB_LOCAL_S_PORTD_IDX].uptr); rrc->eth_params_s.remote_portd = *(GNBParamList.paramarray[i][GNB_REMOTE_S_PORTD_IDX].uptr); rrc->eth_params_s.transp_preference = ETH_UDP_MODE; - rrc->node_type = ngran_gNB_CU; rrc->sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr); rrc->sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr); - } else { - // set to ngran_gNB for now, it will get set to ngran_gNB_DU if macrlc entity which uses F1 is present - // Note: we will have to handle the case of ngran_ng_gNB_DU - if (macrlc_has_f1 == 0) { - rrc->node_type = ngran_gNB; - LOG_I(NR_RRC,"Setting node_type to ngran_gNB\n"); - } else { - rrc->node_type = ngran_gNB_DU; - LOG_I(NR_RRC,"Setting node_type to ngran_gNB_DU\n"); - } } + + rrc->nr_cellid = (uint64_t)*(GNBParamList.paramarray[i][GNB_NRCELLID_IDX].u64ptr); rrc->um_on_default_drb = *(GNBParamList.paramarray[i][GNB_UMONDEFAULTDRB_IDX].uptr); @@ -1282,55 +1272,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { config_security(rrc); }//End RCconfig_NRRRC function -int RCconfig_nr_gtpu(void ) { - - int num_gnbs = 0; - char* gnb_ipv4_address_for_NGU = NULL; - uint32_t gnb_port_for_NGU = 0; - char* gnb_ipv4_address_for_S1U = NULL; - uint32_t gnb_port_for_S1U = 0; - char gtpupath[MAX_OPTNAME_SIZE*2 + 8]; - - paramdef_t GNBSParams[] = GNBSPARAMS_DESC; - paramdef_t NETParams[] = GNBNETPARAMS_DESC; - LOG_I(GTPU,"Configuring GTPu\n"); - -/* get number of active eNodeBs */ - config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); - num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; - AssertFatal (num_gnbs >0, - "Failed to parse config file no active gNodeBs in %s \n", GNB_CONFIG_STRING_ACTIVE_GNBS); - - sprintf(gtpupath,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); - config_get(NETParams,sizeof(NETParams)/sizeof(paramdef_t),gtpupath); - char *cidr=NULL, *address = NULL; - int port; - if (NETParams[1].strptr != NULL) { - LOG_I(GTPU, "SA mode \n"); - address = strtok_r(gnb_ipv4_address_for_NGU, "/", &cidr); - port=gnb_port_for_NGU; - } else { - LOG_I(GTPU, "NSA mode \n"); - address = strtok_r(gnb_ipv4_address_for_S1U, "/", &cidr); - port=gnb_port_for_S1U; - } - - if (address) { - MessageDef *message; - message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_REQ); - AssertFatal(message!=NULL,""); - IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_REQ(message).localAddr, "BAD IP ADDRESS FORMAT FOR gNB NG_U !\n" ); - LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_REQ(message).localAddr); - GTPV1U_REQ(message).localPort = port; - strcpy(GTPV1U_REQ(message).localAddrStr,address); - sprintf(GTPV1U_REQ(message).localPortStr,"%d", port); - itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) - } else - LOG_E(GTPU,"invalid address for NGU or S1U\n"); - -return 0; -} - int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) { int j,k = 0; @@ -1957,8 +1898,8 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) { f1Setup->mib_length[k] = rrc->carrier.sizeof_MIB; NR_BCCH_DL_SCH_Message_t *bcch_message = NULL; - - asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + asn_codec_ctx_t st={100*1000}; + asn_dec_rval_t dec_rval = uper_decode_complete( &st, &asn_DEF_NR_BCCH_DL_SCH_Message, (void **)&bcch_message, (const void *)rrc->carrier.SIB1, @@ -2252,16 +2193,24 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up return(ret); } -static ngran_node_t get_node_type(void) +ngran_node_t get_node_type(void) { paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC; paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0}; paramdef_t GNBParams[] = GNBPARAMS_DESC; paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0}; + paramdef_t GNBE1Params[] = GNBE1PARAMS_DESC; + paramlist_def_t GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0}; + config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL); + + if (GNBParamList.numelt == 0) // We have no valid configuration, let's return a default + return ngran_gNB; + config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL); - config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL); - + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); + config_getlist( &GNBE1ParamList, GNBE1Params, sizeof(GNBE1Params)/sizeof(paramdef_t), aprefix); if ( MacRLC_ParamList.numelt > 0) { RC.nb_nr_macrlc_inst = MacRLC_ParamList.numelt; for (int j = 0; j < RC.nb_nr_macrlc_inst; j++) { @@ -2271,9 +2220,16 @@ static ngran_node_t get_node_type(void) } } - if (strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) - return ngran_gNB_CU; - else if (macrlc_has_f1 == 0) + if (strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) { + if ( GNBE1ParamList.paramarray == NULL || GNBE1ParamList.numelt == 0 ) + return ngran_gNB_CU; + else if (strcmp(*(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CU_TYPE_IDX].strptr), "cp") == 0) + return ngran_gNB_CUCP; + else if (strcmp(*(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CU_TYPE_IDX].strptr), "up") == 0) + return ngran_gNB_CUUP; + else + return ngran_gNB_CU; + } else if (macrlc_has_f1 == 0) return ngran_gNB; else return ngran_gNB_DU; @@ -2309,9 +2265,7 @@ void nr_read_config_and_init(void) { RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]); } - if (NODE_IS_CU(RC.nrrrc[0]->node_type)) { + if (NODE_IS_CU(RC.nrrrc[0]->node_type) && RC.nrrrc[0]->node_type != ngran_gNB_CUCP) { pdcp_layer_init(); -// nr_DRB_preconfiguration(0x1234); - rrc_init_nr_global_param(); } } diff --git a/openair2/GNB_APP/gnb_config.h b/openair2/GNB_APP/gnb_config.h index b2a9ece078..3089753cff 100644 --- a/openair2/GNB_APP/gnb_config.h +++ b/openair2/GNB_APP/gnb_config.h @@ -41,6 +41,7 @@ #include "s1ap_messages_types.h" #include "ngap_messages_types.h" #include "f1ap_messages_types.h" +#include "e1ap_messages_types.h" #include "rrc_messages_types.h" #include "intertask_interface.h" @@ -94,7 +95,6 @@ extern void NRRCconfig_RU(void); extern void RCconfig_nr_prs(void); extern void RCconfig_NR_L1(void); extern void RCconfig_nr_macrlc(void); -extern int RCconfig_nr_gtpu(void ); extern void NRRCConfig(void); //void enb_config_display(void); @@ -107,6 +107,8 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i); int gNB_app_handle_f1ap_setup_resp(f1ap_setup_resp_t *resp); int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_update_t *gnb_cu_cfg_update); void nr_read_config_and_init(void); +MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process); +ngran_node_t get_node_type(void); #endif /* GNB_CONFIG_H_ */ /** @} */ diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index bf5e9f9660..8b62b7720b 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -34,6 +34,7 @@ #define __GNB_APP_GNB_PARAMDEF__H__ #include "common/config/config_paramdesc.h" +#include "common/ngran_types.h" #include "RRC_nr_paramsvalues.h" @@ -369,6 +370,27 @@ typedef enum { /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* E1 configuration section */ +#define GNB_CONFIG_STRING_E1_PARAMETERS "E1_INTERFACE" + +#define GNB_CONFIG_E1_CU_TYPE_IDX 0 +#define GNB_CONFIG_E1_IPV4_ADDRESS_CUCP 1 +#define GNB_CONFIG_E1_IPV4_ADDRESS_CUUP 2 +#define GNB_CONFIG_E1_CN_SUPPORT 3 + +#define GNB_CONFIG_STRING_E1_CU_TYPE "type" +#define GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUCP "ipv4_cucp" +#define GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUUP "ipv4_cuup" +#define GNB_CONFIG_STRING_E1_CN_SUPPORT "cn_support" + +// clang-format off +#define GNBE1PARAMS_DESC { \ + {GNB_CONFIG_STRING_E1_CU_TYPE, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ + {GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUCP, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ + {GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUUP, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ + {GNB_CONFIG_STRING_E1_CN_SUPPORT, NULL, 0, uptr :NULL, defintval:1L, TYPE_UINT, 0} \ + } +// clang-format on /* L1 configuration section names */ #define CONFIG_STRING_L1_LIST "L1s" #define CONFIG_STRING_L1_CONFIG "l1_config" diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index af94ef3ae0..abb6ba0ec3 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -664,8 +664,6 @@ int remove_ue_list(UE_list_t *listP, int UE_id); void dump_ue_list(UE_list_t *listP); void init_ue_list(UE_list_t *listP); int UE_num_active_CC(UE_info_t *listP, int ue_idP); -int UE_PCCID(module_id_t mod_idP, int ue_idP); -rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP); uint8_t find_rb_table_index(uint8_t average_rbs); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 6d592b797f..e9d41986c5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -249,14 +249,11 @@ void mac_top_init_gNB(ngran_node_t node_type) AssertFatal(rlc_module_init(1) == 0,"Could not initialize RLC layer\n"); // These should be out of here later - pdcp_layer_init(); + if (get_softmodem_params()->usim_test == 0 ) pdcp_layer_init(); if(IS_SOFTMODEM_NOS1 && get_softmodem_params()->phy_test) nr_DRB_preconfiguration(0x1234); - rrc_init_nr_global_param(); - - } else { RC.nrmac = NULL; } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c new file mode 100644 index 0000000000..9a584a3b27 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c @@ -0,0 +1,59 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include "nr_pdcp_e1_api.h" + +void e1_add_drb(int is_gnb, + uint64_t ue_id, + struct NR_DRB_ToAddMod *s, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key) +{ + add_drb_am(is_gnb, ue_id, s, ciphering_algorithm, integrity_algorithm, + ciphering_key, integrity_key); + LOG_I(PDCP, "%s:%s:%d: added DRB for UE ID %ld\n", __FILE__, __FUNCTION__, __LINE__, ue_id); +} + +void nr_pdcp_e1_add_drbs(eNB_flag_t enb_flag, + uint64_t ue_id, + NR_DRB_ToAddModList_t *const drb2add_list, + const uint8_t security_modeP, + uint8_t *const kUPenc, + uint8_t *const kUPint) { + + if (drb2add_list != NULL) { + for (int i = 0; i < drb2add_list->list.count; i++) { + e1_add_drb(enb_flag, ue_id, drb2add_list->list.array[i], + security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, + kUPenc, kUPint); + } + } else + LOG_W(PDCP, "%s with void list\n", __FUNCTION__); + if (kUPenc) + free(kUPenc); + if (kUPint) + free(kUPint); +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h new file mode 100644 index 0000000000..a4b44fb74a --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h @@ -0,0 +1,53 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include "common/utils/oai_asn1.h" +#include "NR_RadioBearerConfig.h" + +#include "pdcp.h" +#include "LAYER2/nr_rlc/nr_rlc_oai_api.h" +#include +#include "openair2/SDAP/nr_sdap/nr_sdap.h" + +void e1_add_drb(int is_gnb, + uint64_t ue_id, + struct NR_DRB_ToAddMod *s, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key); + +void nr_pdcp_e1_add_drbs(eNB_flag_t enb_flag, + uint64_t ue_id, + NR_DRB_ToAddModList_t *const drb2add_list, + const uint8_t security_modeP, + uint8_t *const kUPenc, + uint8_t *const kUPint); + +void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key); + diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c index 86f0558611..eb8c7ee98e 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c @@ -21,62 +21,61 @@ #include "nr_pdcp_integrity_nia2.h" +#include #include #include #include -#include -void *nr_pdcp_integrity_nia2_init(unsigned char *integrity_key) +#include "common/utils/assertions.h" +#include "openair3/SECU/aes_128.h" +#include "openair3/SECU/aes_128_cbc_cmac.h" + +void *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16]) { - CMAC_CTX *ctx; - - ctx = CMAC_CTX_new(); - if (ctx == NULL) abort(); - - CMAC_Init(ctx, integrity_key, 16, EVP_aes_128_cbc(), NULL); + // This is a hack. Reduce the 3 functions to just cipher? + // No. The overhead is x8 times more. Don't change before measuring + // return integrity_key; + cbc_cmac_ctx_t* ctx = calloc(1, sizeof(cbc_cmac_ctx_t)); + DevAssert(ctx != NULL && "Memory exhausted"); + *ctx = init_aes_128_cbc_cmac(integrity_key); return ctx; } -static void compute_t(unsigned char *t, uint32_t count, int bearer, - int direction) +void nr_pdcp_integrity_nia2_integrity(void *integrity_context, unsigned char *out, unsigned char *buffer, int length, int bearer, int count, int direction) { - t[0] = (count >> 24) & 255; - t[1] = (count >> 16) & 255; - t[2] = (count >> 8) & 255; - t[3] = (count ) & 255; - t[4] = ((bearer-1) << 3) | (direction << 2); - memset(&t[5], 0, 8-5); -} + DevAssert(integrity_context != NULL); + DevAssert(out != NULL); + DevAssert(buffer != NULL); + DevAssert(length > -1); + // Strange range: [1-32] instead of [0-31] + DevAssert(bearer > 0 && bearer < 33); + DevAssert(count > -1); -void nr_pdcp_integrity_nia2_integrity(void *integrity_context, - unsigned char *out, - unsigned char *buffer, int length, - int bearer, int count, int direction) -{ - CMAC_CTX *ctx = integrity_context; - unsigned char t[8]; - unsigned char mac[16]; - size_t maclen; + cbc_cmac_ctx_t* ctx = (cbc_cmac_ctx_t*)integrity_context; - /* see 33.401 B.2.3 for the input to 128-EIA2 - * (which is identical to 128-NIA2, see 33.501 D.3.1.3) */ - compute_t(t, count, bearer, direction); + aes_128_t k_iv = {0}; + memcpy(&k_iv.key, ctx->key, sizeof(k_iv.key)); + k_iv.type = AES_INITIALIZATION_VECTOR_8; + k_iv.iv8.d.bearer = bearer -1; + k_iv.iv8.d.direction = direction; + k_iv.iv8.d.count = htonl(count); - CMAC_Init(ctx, NULL, 0, NULL, NULL); - CMAC_Update(ctx, t, 8); - CMAC_Update(ctx, buffer, length); - CMAC_Final(ctx, mac, &maclen); + uint8_t result[16] = {0}; + byte_array_t msg = {.buf = buffer, .len = length}; + + cipher_aes_128_cbc_cmac((cbc_cmac_ctx_t*)integrity_context, &k_iv, msg, sizeof(result), result); + //aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result); - /* AES CMAC (RFC 4493) outputs 128 bits but NR PDCP PDUs have a MAC-I of - * 32 bits (see 38.323 6.2). RFC 4493 2.1 says to truncate most significant - * bit first (so seems to say 33.401 B.2.3) - */ - memcpy(out, mac, 4); + // AES CMAC (RFC 4493) outputs 128 bits but NR PDCP PDUs have a MAC-I of + // 32 bits (see 38.323 6.2). RFC 4493 2.1 says to truncate most significant + // bit first (so seems to say 33.401 B.2.3) + // Precondition: out should have enough space... + memcpy(out, result, 4); } void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context) { - CMAC_CTX *ctx = integrity_context; - CMAC_CTX_free(ctx); + free( ( cbc_cmac_ctx_t*) integrity_context); } + diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h index 9593a2825c..53f117aafb 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h @@ -22,7 +22,9 @@ #ifndef _NR_PDCP_INTEGRITY_NIA2_H_ #define _NR_PDCP_INTEGRITY_NIA2_H_ -void *nr_pdcp_integrity_nia2_init(unsigned char *integrity_key); +#include + +void *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16]); void nr_pdcp_integrity_nia2_integrity(void *integrity_context, unsigned char *out, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index fd1430420c..190757d74c 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -38,6 +38,8 @@ #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include #include "openair2/SDAP/nr_sdap/nr_sdap.h" +#include "nr_pdcp_e1_api.h" +#include "gnb_config.h" #include "executables/softmodem-common.h" #define TODO do { \ @@ -56,10 +58,11 @@ static int nr_pdcp_current_time_last_subframe; hash_table_t *pdcp_coll_p; static uint64_t pdcp_optmask; -ngran_node_t node_type = ngran_gNB; uint8_t first_dcch = 0; uint8_t proto_agent_flag = 0; +static ngran_node_t node_type; + /****************************************************************************/ /* rlc_data_req queue - begin */ /****************************************************************************/ @@ -524,6 +527,10 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) return 0; } +static void set_node_type() { + node_type = get_node_type(); +} + void pdcp_layer_init(void) { /* hack: be sure to initialize only once */ @@ -539,7 +546,9 @@ void pdcp_layer_init(void) nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1); - if ((RC.nrrrc == NULL) || (!NODE_IS_CU(RC.nrrrc[0]->node_type))) { + set_node_type(); + + if ((RC.nrrrc == NULL) || (!NODE_IS_CU(node_type))) { init_nr_rlc_data_req_queue(); } @@ -667,7 +676,7 @@ rb_found: ctxt.brOption = 0; ctxt.rntiMaybeUEid = ue->rntiMaybeUEid; - if (RC.nrrrc != NULL && NODE_IS_CU(RC.nrrrc[0]->node_type)) { + if (NODE_IS_CU(node_type)) { MessageDef *message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0, GTPV1U_TUNNEL_DATA_REQ, sizeof(gtpv1u_tunnel_data_req_t) @@ -688,7 +697,6 @@ rb_found: extern instance_t CUuniqInstance; itti_send_msg_to_task(TASK_GTPV1_U, CUuniqInstance, message_p); } else { - memblock = get_free_mem_block(size, __FUNCTION__); memcpy(memblock->data, buf, size); LOG_D(PDCP, "%s(): (drb %d) calling rlc_data_req size %d\n", __func__, rb_id, size); @@ -764,7 +772,7 @@ srb_found: LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, srb_id, size); //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]); //printf("\n"); - if ((RC.nrrrc == NULL) || (!NODE_IS_CU(RC.nrrrc[0]->node_type))) { + if ((RC.nrrrc == NULL) || (!NODE_IS_CU(node_type))) { if (entity->is_gnb) { f1ap_dl_rrc_message_t dl_rrc = {.old_gNB_DU_ue_id = 0xFFFFFF, .rrc_container = (uint8_t *)buf, .rrc_container_length = size, .rnti = ue->rntiMaybeUEid, .srb_id = DCCH}; gNB_RRC_INST *rrc = RC.nrrrc[0]; @@ -1056,35 +1064,30 @@ void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid) drb_ToAddMod->reestablishPDCP = NULL; drb_ToAddMod->recoverPDCP = NULL; drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config)); - drb_ToAddMod->pdcp_Config->drb = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb)); - drb_ToAddMod->pdcp_Config->drb->discardTimer = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->discardTimer)); - *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_infinity; - drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL)); - *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; - drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL)); - *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; - drb_ToAddMod->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; - drb_ToAddMod->pdcp_Config->drb->headerCompression.choice.notUsed = 0; + asn1cCalloc(drb_ToAddMod->pdcp_Config->drb, drb); + asn1cCallocOne(drb->discardTimer, NR_PDCP_Config__drb__discardTimer_infinity); + asn1cCallocOne(drb->pdcp_SN_SizeUL, NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits); + asn1cCallocOne(drb->pdcp_SN_SizeDL, NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits); + drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; + drb->headerCompression.choice.notUsed = 0; - drb_ToAddMod->pdcp_Config->drb->integrityProtection=NULL; - drb_ToAddMod->pdcp_Config->drb->statusReportRequired=NULL; - drb_ToAddMod->pdcp_Config->drb->outOfOrderDelivery=NULL; + drb->integrityProtection = NULL; + drb->statusReportRequired = NULL; + drb->outOfOrderDelivery = NULL; drb_ToAddMod->pdcp_Config->moreThanOneRLC = NULL; - drb_ToAddMod->pdcp_Config->t_Reordering = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->t_Reordering)); - *drb_ToAddMod->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0; + asn1cCallocOne(drb_ToAddMod->pdcp_Config->t_Reordering, NR_PDCP_Config__t_Reordering_ms0); drb_ToAddMod->pdcp_Config->ext1 = NULL; asn1cSeqAdd(&rbconfig->drb_ToAddModList->list,drb_ToAddMod); rbconfig->drb_ToReleaseList = NULL; - rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig)); - rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig)); - rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; - rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL; - rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse)); - *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; + asn1cCalloc(rbconfig->securityConfig, secConf); + asn1cCalloc(secConf->securityAlgorithmConfig, secConfAlgo); + secConfAlgo->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; + secConfAlgo->integrityProtAlgorithm = NULL; + asn1cCallocOne(secConf->keyToUse, NR_SecurityConfig__keyToUse_master); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); @@ -1108,11 +1111,7 @@ void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid) nr_pdcp_add_drbs(ctxt.enb_flag, ctxt.rntiMaybeUEid, rbconfig->drb_ToAddModList, 0, NULL, NULL, Rlc_Bearer_ToAdd_list); - nr_rrc_rlc_config_asn1_req (&ctxt, - (NR_SRB_ToAddModList_t *) NULL, - rbconfig->drb_ToAddModList, - rbconfig->drb_ToReleaseList, - Rlc_Bearer_ToAdd_list); + nr_rrc_rlc_config_asn1_req(&ctxt, (NR_SRB_ToAddModList_t *)NULL, rbconfig->drb_ToAddModList, rbconfig->drb_ToReleaseList, Rlc_Bearer_ToAdd_list); LOG_D(PDCP, "%s:%d: done RRC PDCP/RLC ASN1 request for UE ID/RNTI %ld\n", __FUNCTION__, __LINE__, ctxt.rntiMaybeUEid); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c index a7479a5032..c46a9d59fe 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c @@ -19,55 +19,50 @@ * contact@openairinterface.org */ +#include "openair3/SECU/aes_128_ctr.h" +#include "common/utils/assertions.h" + #include "nr_pdcp_security_nea2.h" +#include +#include #include #include -#include -#include -#include - -#ifndef NETTLE_VERSION_MAJOR -/* hack: include bignum.h, not version.h because version.h does not exist - * in old versions and bignum.h includes version.h (as of today). - * May completely fail to work... maybe we should skip support of old - * versions of nettle. - */ -#include -#endif void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key) { - void *ctx = calloc(1, nettle_aes128.context_size); - if (ctx == NULL) exit(1); - -#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 - nettle_aes128.set_encrypt_key(ctx, 16, ciphering_key); -#else - nettle_aes128.set_encrypt_key(ctx, ciphering_key); -#endif - - return ctx; + // This is a hack, IMO init, cipher and free functions should be reduced to cipher. + // Test show a ~10% more processing time + return ciphering_key; } -void nr_pdcp_security_nea2_cipher(void *security_context, - unsigned char *buffer, int length, - int bearer, int count, int direction) +void nr_pdcp_security_nea2_cipher(void *security_context, unsigned char *buffer, int length, int bearer, int count, int direction) { - unsigned char t[16] = {0}; + DevAssert(security_context != NULL); + DevAssert(buffer != NULL); + DevAssert(length > 0); + DevAssert(bearer > -1 && bearer < 32); + DevAssert(direction > -1 && direction < 2); + DevAssert(count > -1); - t[0] = (count >> 24) & 255; - t[1] = (count >> 16) & 255; - t[2] = (count >> 8) & 255; - t[3] = (count ) & 255; - t[4] = ((bearer-1) << 3) | (direction << 2); + aes_128_t p = {0}; + const uint8_t *ciphering_key = (uint8_t const *)security_context; + memcpy(p.key, ciphering_key, 16); + p.type = AES_INITIALIZATION_VECTOR_16; + p.iv16.d.count = ntohl(count); + p.iv16.d.bearer = bearer; + p.iv16.d.direction = direction; - nettle_ctr_crypt(security_context, nettle_aes128.encrypt, - nettle_aes128.block_size, t, - length, buffer, buffer); + uint8_t out[length]; + memset(out, 0, length); + + byte_array_t msg = {.buf = buffer, .len = length};; + aes_128_ctr(&p, msg, length, out); + + memcpy(buffer, out, length); } void nr_pdcp_security_nea2_free_security(void *security_context) { - free(security_context); + (void)security_context; } diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 29aab4ab5a..60c002537a 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -985,6 +985,7 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity){ if(srb2add_listP->list.array[i]->srb_Identity == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.srb_Identity){ add_rlc_srb(rnti, srb2add_listP->list.array[i], rlc_bearer2add_list->list.array[j]); + LOG_D(RLC, "Add srb %ld\n", srb2add_listP->list.array[i]->srb_Identity); } } } diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h index 92d20d1aca..c7e42a0a0d 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h @@ -28,6 +28,7 @@ typedef void nr_rlc_ue_manager_t; typedef struct nr_rlc_ue_t { int rnti; + ue_id_t ue_id; nr_rlc_entity_t *srb0; nr_rlc_entity_t *srb[3]; nr_rlc_entity_t *drb[MAX_DRBS_PER_UE]; diff --git a/openair2/MCE_APP/mce_app.c b/openair2/MCE_APP/mce_app.c index 37b461e819..e626a09a98 100644 --- a/openair2/MCE_APP/mce_app.c +++ b/openair2/MCE_APP/mce_app.c @@ -40,7 +40,8 @@ # include "intertask_interface.h" # include "s1ap_eNB.h" -#include "sctp_eNB_task.h" +# include "sctp_eNB_task.h" +# include "openair3/ocp-gtpu/gtp_itf.h" # include "x2ap_eNB.h" # include "x2ap_messages_types.h" diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index b4f7eece01..171e69ea59 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -5629,6 +5629,7 @@ rrc_eNB_generate_RRCConnectionSetup( case ngran_eNB_CU : case ngran_ng_eNB_CU : case ngran_gNB_CU : + case ngran_gNB_CUCP : // create an ITTI message /* TODO: F1 IDs ar missing in RRC */ message_p = itti_alloc_new_message (TASK_RRC_ENB, 0, F1AP_DL_RRC_MESSAGE); diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 6ff90c20fa..9452a1f1a9 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -116,9 +116,7 @@ uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP, uint8_t *const buffer_pP) { -#ifdef DEBUG_RRC LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id); -#endif // MIBCH if ((Srb_id & RAB_OFFSET) == MIBCH) { @@ -128,9 +126,6 @@ uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP, rrc_gNB_carrier_data_t *carrier = &RC.nrrrc[Mod_idP]->carrier; NR_BCCH_BCH_Message_t *mib = &carrier->mib; - mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = carrier->pdcch_ConfigSIB1->controlResourceSetZero; - mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = carrier->pdcch_ConfigSIB1->searchSpaceZero; - mib->message.choice.mib->systemFrameNumber.buf[0] = sfn_msb << 2; enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_BCH_Message, NULL, diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 299e0acaa9..6e57409228 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -237,13 +237,11 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) { * The SIB1 will be sent in this allocation (Type0-PDCCH) : 38.213, 13-4 Table and 38.213 13-11 to 13-14 tables * the reverse allocation is in nr_ue_decode_mib() */ - if(rrc->carrier.pdcch_ConfigSIB1) { - mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = rrc->carrier.pdcch_ConfigSIB1->controlResourceSetZero; - mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = rrc->carrier.pdcch_ConfigSIB1->searchSpaceZero; - } else { - mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero; - mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero; - } + const NR_PDCCH_ConfigCommon_t *pdcch_cc = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup; + long cset0 = pdcch_cc->controlResourceSetZero ? *pdcch_cc->controlResourceSetZero : 0; + mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = cset0; + long ss0 = pdcch_cc->searchSpaceZero ? *pdcch_cc->searchSpaceZero : 0; + mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = ss0; switch (*scc->ssbSubcarrierSpacing) { case NR_SubcarrierSpacing_kHz15: @@ -295,11 +293,6 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) { 24); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - - if (enc_rval.encoded==-1) { - return(-1); - } - return((enc_rval.encoded+7)/8); } @@ -638,11 +631,6 @@ uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier, 100); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - - if (enc_rval.encoded==-1) { - return(-1); - } - return((enc_rval.encoded+7)/8); } @@ -690,11 +678,8 @@ int do_RRCReject(uint8_t Mod_id, buffer, 100); - if(enc_rval.encoded == -1) { - LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; - } + AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); LOG_D(NR_RRC,"RRCReject Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -1297,13 +1282,11 @@ int do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, (void *)&dl_ccch_msg, buffer, 1000); + - if(enc_rval.encoded == -1) { - LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - return -1; - } - + LOG_D(NR_RRC,"RRCSetup Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); @@ -1346,19 +1329,11 @@ uint8_t do_NR_SecurityModeCommand( buffer, 100); - if(enc_rval.encoded == -1) { - LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; - } + AssertFatal(enc_rval.encoded >0 , "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); LOG_D(NR_RRC, "[gNB %d] securityModeCommand for UE %lx Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, enc_rval.encoded, (enc_rval.encoded + 7) / 8); - if (enc_rval.encoded==-1) { - LOG_E(NR_RRC, "[gNB %d] ASN1 : securityModeCommand encoding failed for UE %lx\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid); - return(-1); - } - // rrc_ue_process_ueCapabilityEnquiry(0,1000,&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry,0); // exit(-1); return((enc_rval.encoded+7)/8); @@ -1411,6 +1386,9 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, (void *)sa_band_filter, req_freq_buf, 1024); + AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_NR_UE_CapabilityRequestFilterNR, (void *)sa_band_filter); @@ -1435,19 +1413,11 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, buffer, 100); - if(enc_rval.encoded == -1) { - LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; - } - + AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + LOG_D(NR_RRC, "[gNB %d] NR UECapabilityRequest for UE %lx Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, enc_rval.encoded, (enc_rval.encoded + 7) / 8); - if (enc_rval.encoded==-1) { - LOG_E(NR_RRC, "[gNB %d] ASN1 : NR UECapabilityRequest encoding failed for UE %lx\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid); - return(-1); - } - return((enc_rval.encoded+7)/8); } @@ -1480,11 +1450,8 @@ uint8_t do_NR_RRCRelease(uint8_t *buffer, (void *)&dl_dcch_msg, buffer, buffer_size); - if(enc_rval.encoded == -1) { - LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; - } + AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); return((enc_rval.encoded+7)/8); } @@ -1508,19 +1475,18 @@ int16_t do_RRCReconfiguration( NR_CellGroupConfig_t *cellGroupConfig) //------------------------------------------------------------------------------ { - NR_DL_DCCH_Message_t dl_dcch_msg; + NR_DL_DCCH_Message_t dl_dcch_msg={0}; asn_enc_rval_t enc_rval; NR_RRCReconfiguration_IEs_t *ie; unsigned char masterCellGroup_buf[1000]; - memset(&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t)); dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1; - dl_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_DCCH_MessageType__c1)); - dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration; + asn1cCalloc(dl_dcch_msg.message.choice.c1, c1);// = CALLOC(1, sizeof(struct NR_DL_DCCH_MessageType__c1)); + c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration; - dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration = calloc(1, sizeof(NR_RRCReconfiguration_t)); - 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; + asn1cCalloc(c1->choice.rrcReconfiguration, rrcReconf); // = calloc(1, sizeof(NR_RRCReconfiguration_t)); + rrcReconf->rrc_TransactionIdentifier = Transaction_id; + rrcReconf->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration; /******************** Radio Bearer Config ********************/ /* Configure Security */ @@ -1532,7 +1498,8 @@ int16_t do_RRCReconfiguration( // *security_config->keyToUse = NR_SecurityConfig__keyToUse_master; ie = calloc(1, sizeof(NR_RRCReconfiguration_IEs_t)); - if (SRB_configList || DRB_configList) { + if ((SRB_configList && SRB_configList->list.size) || + (DRB_configList && DRB_configList->list.size)) { ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t)); ie->radioBearerConfig->srb_ToAddModList = SRB_configList; ie->radioBearerConfig->drb_ToAddModList = DRB_configList; @@ -1561,42 +1528,42 @@ int16_t do_RRCReconfiguration( configuration); enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, - NULL, - (void *)cellGroupConfig, - masterCellGroup_buf, - 1000); - if(enc_rval.encoded == -1) { - LOG_E(NR_RRC, "ASN1 message CellGroupConfig encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; - } + NULL, + (void *)cellGroupConfig, + masterCellGroup_buf, + 1000); + AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); } ie->nonCriticalExtension->masterCellGroup = calloc(1,sizeof(OCTET_STRING_t)); - + ie->nonCriticalExtension->masterCellGroup->buf = masterCellGroup_buf; ie->nonCriticalExtension->masterCellGroup->size = (enc_rval.encoded+7)/8; } - + dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration = ie; - + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg); } - + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message, - NULL, - (void *)&dl_dcch_msg, - buffer, - buffer_size); - - if(enc_rval.encoded == -1) { - LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; - } - + NULL, + (void *)&dl_dcch_msg, + buffer, + buffer_size); + + AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + LOG_D(NR_RRC,"[gNB %d] RRCReconfiguration for UE %lx Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rntiMaybeUEid, + enc_rval.encoded, + (enc_rval.encoded+7)/8); + return((enc_rval.encoded+7)/8); } @@ -1731,9 +1698,9 @@ uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, NR_UL_DCCH_Message_t ul_dcch_msg; NR_RRCSetupComplete_t *RrcSetupComplete; memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); - + uint8_t buf[6]; - + 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_rrcSetupComplete; @@ -1746,7 +1713,7 @@ uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, // sizeof(*RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->nonCriticalExtension)); RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->selectedPLMN_Identity = sel_plmn_id; RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->registeredAMF = NULL; - + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value = CALLOC(1, sizeof(struct NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value)); RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI; RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size = 6; @@ -1757,23 +1724,23 @@ uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[3] = 0x78; RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[4] = 0x9A; RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[5] = 0xBC; - - 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_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, - buffer_size); -AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name,enc_rval.encoded); -LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); - -return((enc_rval.encoded+7)/8); + + 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_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, + buffer_size); + AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name,enc_rval.encoded); + LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + return((enc_rval.encoded+7)/8); } //------------------------------------------------------------------------------ @@ -1993,11 +1960,8 @@ NR_SRB_ToAddModList_t **SRB_configList buffer, 100); - if(enc_rval.encoded == -1) { - LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; - } + AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); LOG_D(NR_RRC,"RRCReestablishment Encoded %u bits (%u bytes)\n", (uint32_t)enc_rval.encoded, (uint32_t)(enc_rval.encoded+7)/8); diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c new file mode 100644 index 0000000000..12530c7b82 --- /dev/null +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -0,0 +1,229 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * conmnc_digit_lengtht@openairinterface.org + */ + +#include + +#include "cucp_cuup_if.h" +#include "platform_types.h" +#include "nr_rrc_defs.h" + +#include "softmodem-common.h" +#include "nr_rrc_proto.h" +#include "nr_rrc_extern.h" +#include "openair2/COMMON/e1ap_messages_types.h" +#include "UTIL/OSA/osa_defs.h" +#include "nr_pdcp/nr_pdcp_entity.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" +#include +#include "openair3/ocp-gtpu/gtp_itf.h" +#include "rrc_gNB_GTPV1U.h" +#include "common/ran_context.h" +#include "openair2/F1AP/f1ap_common.h" +#include "openair2/E1AP/e1ap_common.h" +extern RAN_CONTEXT_t RC; + +void fill_e1ap_bearer_setup_resp(e1ap_bearer_setup_resp_t *resp, + e1ap_bearer_setup_req_t *const req, + instance_t gtpInst, + ue_id_t ue_id, + int remote_port, + in_addr_t my_addr) { + + resp->numPDUSessions = req->numPDUSessions; + transport_layer_addr_t dummy_address = {0}; + dummy_address.length = 32; // IPv4 + for (int i=0; i < req->numPDUSessions; i++) { + resp->pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup; + for (int j=0; j < req->pduSession[i].numDRB2Setup; j++) { + DRB_nGRAN_to_setup_t *drb2Setup = req->pduSession[i].DRBnGRanList + j; + DRB_nGRAN_setup_t *drbSetup = resp->pduSession[i].DRBnGRanList + j; + + drbSetup->numUpParam = 1; + drbSetup->UpParamList[0].tlAddress = my_addr; + drbSetup->UpParamList[0].teId = newGtpuCreateTunnel(gtpInst, + (ue_id & 0xFFFF), + drb2Setup->id, + drb2Setup->id, + 0xFFFF, // We will set the right value from DU answer + -1, // no qfi + dummy_address, // We will set the right value from DU answer + remote_port, + cu_f1u_data_req, + NULL); + drbSetup->id = drb2Setup->id; + + drbSetup->numQosFlowSetup = drb2Setup->numQosFlow2Setup; + for (int k=0; k < drbSetup->numQosFlowSetup; k++) { + drbSetup->qosFlows[k].id = drb2Setup->qosFlows[k].id; + } + } + } +} + +void CU_update_UP_DL_tunnel(e1ap_bearer_setup_req_t *const req, instance_t instance, ue_id_t ue_id) { + for (int i=0; i < req->numPDUSessionsMod; i++) { + for (int j=0; j < req->pduSessionMod[i].numDRB2Modify; j++) { + DRB_nGRAN_to_setup_t *drb_p = req->pduSessionMod[i].DRBnGRanModList + j; + + transport_layer_addr_t newRemoteAddr; + newRemoteAddr.length = 32; // IPv4 + memcpy(newRemoteAddr.buffer, + &drb_p->DlUpParamList[0].tlAddress, + sizeof(in_addr_t)); + + GtpuUpdateTunnelOutgoingAddressAndTeid(instance, + (ue_id & 0xFFFF), + (ebi_t)drb_p->id, + *(in_addr_t*)&newRemoteAddr.buffer, + drb_p->DlUpParamList[0].teId); + } + } +} + +static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, + rrc_gNB_ue_context_t *ue_context_p, + e1ap_bearer_setup_req_t *const req, + NR_DRB_ToAddModList_t *DRB_configList, + NR_SRB_ToAddModList_t *SRB_configList, + instance_t instance) { + + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; + gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0}; + + for (int i=0; i < ue_context_p->ue_context.nb_of_pdusessions; i++) { + pdu_session_param_t *pdu = ue_context_p->ue_context.pduSession + i; + create_tunnel_req.pdusession_id[i] = pdu->param.pdusession_id; + create_tunnel_req.incoming_rb_id[i] = i + 1; + create_tunnel_req.outgoing_qfi[i] = req->pduSession[i].DRBnGRanList[0].qosFlows[0].id; + memcpy(&create_tunnel_req.dst_addr[i].buffer, + &pdu->param.upf_addr.buffer, + sizeof(uint8_t)*20); + create_tunnel_req.dst_addr[i].length = pdu->param.upf_addr.length; + create_tunnel_req.outgoing_teid[i] = pdu->param.gtp_teid; + } + create_tunnel_req.num_tunnels = ue_context_p->ue_context.nb_of_pdusessions; + create_tunnel_req.ue_id = ue_context_p->ue_context.rnti; + + int ret = gtpv1u_create_ngu_tunnel(getCxtE1(instance)->gtpInstN3, &create_tunnel_req, &create_tunnel_resp); + + if (ret != 0) { + LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE rnti %ld\n", + create_tunnel_req.ue_id); + return ret; + } + + nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(ctxt_p, + &create_tunnel_resp); + + uint8_t *kRRCenc = NULL; + uint8_t *kRRCint = NULL; + uint8_t *kUPenc = NULL; + uint8_t *kUPint = NULL; + /* Derive the keys from kgnb */ + if (DRB_configList != NULL) { + nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm, + ue_context_p->ue_context.kgnb, + &kUPenc); + nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm, + ue_context_p->ue_context.kgnb, + &kUPint); + } + + nr_derive_key_rrc_enc(ue_context_p->ue_context.ciphering_algorithm, + ue_context_p->ue_context.kgnb, + &kRRCenc); + nr_derive_key_rrc_int(ue_context_p->ue_context.integrity_algorithm, + ue_context_p->ue_context.kgnb, + &kRRCint); + /* Refresh SRBs/DRBs */ + + LOG_D(NR_RRC,"Configuring PDCP DRBs/SRBs for UE %x\n",ue_context_p->ue_context.rnti); + + nr_pdcp_add_srbs(ctxt_p->enb_flag, ctxt_p->rntiMaybeUEid, + SRB_configList, + (ue_context_p->ue_context.integrity_algorithm << 4) + | ue_context_p->ue_context.ciphering_algorithm, + kRRCenc, + kRRCint); + + nr_pdcp_add_drbs(ctxt_p->enb_flag, ctxt_p->rntiMaybeUEid, + DRB_configList, + (ue_context_p->ue_context.integrity_algorithm << 4) + | ue_context_p->ue_context.ciphering_algorithm, + kUPenc, + kUPint, + get_softmodem_params()->sa ? ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); + + return ret; +} + +static NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, NR_SRB_ToAddModList_t *SRB_configList, uint8_t xid) +{ + NR_SRB_ToAddModList_t **SRB_configList2 = NULL; + + SRB_configList2 = &ue->SRB_configList2[xid]; + if (*SRB_configList2 == NULL) { + *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); + NR_SRB_ToAddMod_t *SRB2_config = CALLOC(1, sizeof(*SRB2_config)); + SRB2_config->srb_Identity = 2; + asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config); + asn1cSeqAdd(&SRB_configList->list, SRB2_config); + } + + return SRB_configList2; +} +static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) { + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti); + protocol_ctxt_t ctxt = {0}; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); + + fill_DRB_configList(&ctxt, ue_context_p); + + gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; + // Fixme: xid not random, but almost! + NR_SRB_ToAddModList_t **SRB_configList2 = generateSRB2_confList(&ue_context_p->ue_context, ue_context_p->ue_context.SRB_configList, ue_context_p->ue_context.pduSession[0].xid); + // GTP tunnel for UL + int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, ue_context_p->ue_context.DRB_configList, *SRB_configList2, rrc->e1_inst); + if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n"); + + if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) { + rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL); + } else { + e1ap_bearer_setup_resp_t resp; // Used to store teids + int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd; + in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); + instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; + // GTP tunnel for DL + fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, ue_context_p->ue_context.rnti, remote_port, my_addr); + + prepare_and_send_ue_context_modification_f1(ue_context_p, &resp); + } +} + +static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) { + instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; + CU_update_UP_DL_tunnel(req, gtpInst, req->rnti); +} + +void cucp_cuup_message_transfer_direct_init(gNB_RRC_INST *rrc) { + rrc->cucp_cuup.bearer_context_setup = cucp_cuup_bearer_context_setup_direct; + rrc->cucp_cuup.bearer_context_mod = cucp_cuup_bearer_context_mod_direct; +} diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c new file mode 100644 index 0000000000..069629db0b --- /dev/null +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -0,0 +1,61 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * conmnc_digit_lengtht@openairinterface.org + */ + +#include "cucp_cuup_if.h" +#include + +#include "platform_types.h" +#include "nr_rrc_defs.h" + +#include "nr_rrc_proto.h" +#include "nr_rrc_extern.h" +#include "cucp_cuup_if.h" +#include "openair2/COMMON/e1ap_messages_types.h" +#include "UTIL/OSA/osa_defs.h" +#include +#include "common/ran_context.h" + +extern RAN_CONTEXT_t RC; + +static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) { + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti); + protocol_ctxt_t ctxt = {0}; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); + + fill_DRB_configList(&ctxt, ue_context_p); + MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_SETUP_REQ); + e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p); + memcpy(bearer_req, req, sizeof(e1ap_bearer_setup_req_t)); + + itti_send_msg_to_task (TASK_CUCP_E1, instance, msg_p); +} + +static void cucp_cuup_bearer_context_mod_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) { + MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_MODIFICATION_REQ); + e1ap_bearer_setup_req_t *req_msg = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg); + memcpy(req_msg, req, sizeof(*req)); + itti_send_msg_to_task(TASK_CUCP_E1, instance, msg); +} + +void cucp_cuup_message_transfer_e1ap_init(gNB_RRC_INST *rrc) { + rrc->cucp_cuup.bearer_context_setup = cucp_cuup_bearer_context_setup_e1ap; + rrc->cucp_cuup.bearer_context_mod = cucp_cuup_bearer_context_mod_e1ap; +} diff --git a/openair2/RRC/NR/cucp_cuup_if.h b/openair2/RRC/NR/cucp_cuup_if.h new file mode 100644 index 0000000000..079a32e850 --- /dev/null +++ b/openair2/RRC/NR/cucp_cuup_if.h @@ -0,0 +1,42 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * conmnc_digit_lengtht@openairinterface.org + */ + +#ifndef CUCP_CUUP_IF_H +#define CUCP_CUUP_IF_H + +#include +#include "platform_types.h" + +struct e1ap_bearer_setup_req_s; +struct e1ap_bearer_setup_resp_s; +typedef void (*cucp_cuup_bearer_context_setup_func_t)(struct e1ap_bearer_setup_req_s *const req, instance_t instance); + +struct gNB_RRC_INST_s; +void cucp_cuup_message_transfer_direct_init(struct gNB_RRC_INST_s *rrc); +void cucp_cuup_message_transfer_e1ap_init(struct gNB_RRC_INST_s *rrc); +void fill_e1ap_bearer_setup_resp(struct e1ap_bearer_setup_resp_s *resp, + struct e1ap_bearer_setup_req_s *const req, + instance_t gtpInst, + ue_id_t ue_id, + int remote_port, + in_addr_t my_addr); +void CU_update_UP_DL_tunnel(struct e1ap_bearer_setup_req_s *const req, instance_t instance, ue_id_t ue_id); +#endif diff --git a/openair2/RRC/NR/nr_rrc_common.c b/openair2/RRC/NR/nr_rrc_common.c index 828e392460..85e9c71eaa 100644 --- a/openair2/RRC/NR/nr_rrc_common.c +++ b/openair2/RRC/NR/nr_rrc_common.c @@ -49,21 +49,14 @@ extern UE_MAC_INST *UE_mac_inst; extern mui_t rrc_gNB_mui; //----------------------------------------------------------------------------- -int rrc_init_nr_global_param(void){ - +void rrc_init_nr_srb_param(NR_LCHAN_DESC *chan) +{ rrc_rlc_register_rrc (rrc_data_ind, NULL); //register with rlc - DCCH_LCHAN_DESC.transport_block_size = 4; - DCCH_LCHAN_DESC.max_transport_blocks = 16; - DCCH_LCHAN_DESC.Delay_class = 1; - DTCH_DL_LCHAN_DESC.transport_block_size = 52; - DTCH_DL_LCHAN_DESC.max_transport_blocks = 20; - DTCH_DL_LCHAN_DESC.Delay_class = 1; - DTCH_UL_LCHAN_DESC.transport_block_size = 52; - DTCH_UL_LCHAN_DESC.max_transport_blocks = 20; - DTCH_UL_LCHAN_DESC.Delay_class = 1; - - return 0; + chan->transport_block_size = 4; + chan->max_transport_blocks = 16; + chan->Delay_class = 1; + return; } //----------------------------------------------------------------------------- diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 6b60d64842..0ca8796fb4 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -43,6 +43,7 @@ #include "common/platform_constants.h" #include "COMMON/platform_types.h" #include "mac_rrc_dl.h" +#include "cucp_cuup_if.h" //#include "COMMON/mac_rrc_primitives.h" @@ -416,7 +417,7 @@ typedef struct rrc_gNB_ue_context_s { // another key for protocol layers but should not be used as a key for RB tree uid_t local_uid; - /* UE id for initial connection to S1AP */ + /* UE id for initial connection to NGAP */ struct gNB_RRC_UE_s ue_context; } rrc_gNB_ue_context_t; @@ -448,7 +449,6 @@ typedef struct { NR_BCCH_DL_SCH_Message_t *siblock1; NR_ServingCellConfigCommon_t *servingcellconfigcommon; NR_ServingCellConfig_t *servingcellconfig; - NR_PDCCH_ConfigSIB1_t *pdcch_ConfigSIB1; NR_CellGroupConfig_t *secondaryCellGroup[MAX_NR_RRC_UE_CONTEXTS]; NR_SRB_INFO SI; int p_gNB; @@ -476,6 +476,11 @@ typedef struct nr_mac_rrc_dl_if_s { dl_rrc_message_transfer_func_t dl_rrc_message_transfer; } nr_mac_rrc_dl_if_t; +typedef struct cucp_cuup_if_s { + cucp_cuup_bearer_context_setup_func_t bearer_context_setup; + cucp_cuup_bearer_context_setup_func_t bearer_context_mod; +} cucp_cuup_if_t; + //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { @@ -499,6 +504,9 @@ typedef struct gNB_RRC_INST_s { // RRC configuration gNB_RrcConfigurationReq configuration; + // gNB N3 GTPU instance + instance_t e1_inst; + // other PLMN parameters /// Mobile country code int mcc; @@ -527,6 +535,8 @@ typedef struct gNB_RRC_INST_s { nr_security_configuration_t security; nr_mac_rrc_dl_if_t mac_rrc; + cucp_cuup_if_t cucp_cuup; + } gNB_RRC_INST; #include "nr_rrc_proto.h" //should be put here otherwise compilation error diff --git a/openair2/RRC/NR/nr_rrc_extern.h b/openair2/RRC/NR/nr_rrc_extern.h index 7283b25be0..70493f1010 100644 --- a/openair2/RRC/NR/nr_rrc_extern.h +++ b/openair2/RRC/NR/nr_rrc_extern.h @@ -53,8 +53,7 @@ extern void* bigphys_malloc(int); //uint8_t RACH_TIME_ALLOC; extern uint16_t RACH_FREQ_ALLOC; -//uint8_t NB_RACH; -extern LCHAN_DESC BCCH_LCHAN_DESC,CCCH_LCHAN_DESC,DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; +// uint8_t NB_RACH; extern MAC_MEAS_T BCCH_MEAS_TRIGGER,CCCH_MEAS_TRIGGER,DCCH_MEAS_TRIGGER,DTCH_MEAS_TRIGGER; extern MAC_AVG_T BCCH_MEAS_AVG,CCCH_MEAS_AVG,DCCH_MEAS_AVG, DTCH_MEAS_AVG; @@ -63,7 +62,6 @@ extern UE_PF_PO_t UE_PF_PO[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; extern pthread_mutex_t ue_pf_po_mutex; extern uint16_t reestablish_rnti_map[MAX_MOBILES_PER_ENB][2]; -char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration); #endif diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 0d7e0e7f97..dc32e71aea 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -44,12 +44,7 @@ #include "NR_SecurityConfig.h" #define NR_MAX_SUPPORTED_DL_LAYERS 2 - -int rrc_init_nr_global_param(void); - -void rrc_config_nr_buffer(NR_SRB_INFO* Srb_info, - uint8_t Lchan_type, - uint8_t Role); +void rrc_init_nr_srb_param(NR_LCHAN_DESC *chan); uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP, const int CC_id, @@ -104,18 +99,6 @@ int generate_CG_Config(gNB_RRC_INST *rrc, NR_RRCReconfiguration_t *reconfig, NR_RadioBearerConfig_t *rbconfig); -void apply_macrlc_config(gNB_RRC_INST *rrc, - rrc_gNB_ue_context_t *const ue_context_pP, - const protocol_ctxt_t *const ctxt_pP ); - -void -rrc_gNB_generate_RRCSetup( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, - const uint8_t *masterCellGroup, - int masterCellGroup_len, - NR_ServingCellConfigCommon_t *scc); - int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m); void @@ -124,10 +107,7 @@ rrc_gNB_generate_SecurityModeCommand( rrc_gNB_ue_context_t *const ue_context_pP ); - uint8_t -rrc_gNB_get_next_transaction_identifier( - module_id_t gnb_mod_idP -); +unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP); void rrc_gNB_generate_UECapabilityEnquiry( @@ -209,6 +189,23 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt const NR_DRB_ToReleaseList_t * const drb2release_listP, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); +void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, + instance_t instance); + +void bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *req, + instance_t instance); + +void ue_cxt_mod_send_e1ap(MessageDef *msg, + instance_t instance); + +void ue_cxt_mod_direct(MessageDef *msg, + instance_t instance); + +void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP); + +void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, + e1ap_bearer_setup_resp_t *e1ap_resp); void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddModList_t *const srb2add_list, const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kUPint); void nr_pdcp_add_drbs(eNB_flag_t enb_flag, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index b5a63cdf0d..93e2cea421 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -99,6 +99,10 @@ #include #include #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" +#include "openair2/F1AP/f1ap_common.h" +#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h" +#include "cucp_cuup_if.h" #include "BIT_STRING.h" #include "assertions.h" @@ -132,23 +136,27 @@ bool DURecvCb(protocol_ctxt_t *ctxt_pP, return true; } -void openair_nr_rrc_on(const protocol_ctxt_t *const ctxt_pP) { - LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" gNB:OPENAIR NR RRC IN....\n",PROTOCOL_NR_RRC_CTXT_ARGS(ctxt_pP)); - rrc_config_nr_buffer (&RC.nrrrc[ctxt_pP->module_id]->carrier.SI, BCCH, 1); - RC.nrrrc[ctxt_pP->module_id]->carrier.SI.Active = 1; +static void openair_nr_rrc_on(gNB_RRC_INST *rrc) +{ + NR_SRB_INFO *si = &rrc->carrier.SI; + si->Rx_buffer.payload_size = 0; + si->Tx_buffer.payload_size = 0; + si->Active = 1; } ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// -static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration) { +static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration) +{ + LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { rrc->carrier.MIB = (uint8_t *) malloc16(4); rrc->carrier.sizeof_MIB = do_MIB_NR(rrc,0); } - if((get_softmodem_params()->sa) && ( (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)))) { + if((get_softmodem_params()->sa) && ( (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)))) { rrc->carrier.sizeof_SIB1 = do_SIB1_NR(&rrc->carrier,configuration); } @@ -193,27 +201,34 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration } } -static void rrc_gNB_mac_rrc_init(gNB_RRC_INST *rrc) +static void rrc_gNB_CU_DU_init(gNB_RRC_INST *rrc) { switch (rrc->node_type) { + case ngran_gNB_CUCP: + mac_rrc_dl_f1ap_init(&rrc->mac_rrc); + cucp_cuup_message_transfer_e1ap_init(rrc); + break; case ngran_gNB_CU: mac_rrc_dl_f1ap_init(&rrc->mac_rrc); + cucp_cuup_message_transfer_direct_init(rrc); break; + case ngran_gNB: + mac_rrc_dl_direct_init(&rrc->mac_rrc); + cucp_cuup_message_transfer_direct_init(rrc); + break; case ngran_gNB_DU: /* silently drop this, as we currently still need the RRC at the DU. As * soon as this is not the case anymore, we can add the AssertFatal() */ //AssertFatal(1==0,"nothing to do for DU\n"); break; - case ngran_gNB: - mac_rrc_dl_direct_init(&rrc->mac_rrc); - break; default: AssertFatal(0 == 1, "Unknown node type %d\n", rrc->node_type); break; } } -char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration) { +static void openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration) +{ protocol_ctxt_t ctxt = { 0 }; gNB_RRC_INST *rrc=RC.nrrrc[gnb_mod_idP]; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, gnb_mod_idP, GNB_FLAG_YES, NOT_A_RNTI, 0, 0,gnb_mod_idP); @@ -225,7 +240,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu AssertFatal(configuration!=NULL,"configuration input is null\n"); rrc->module_id = gnb_mod_idP; rrc->Nb_ue = 0; - rrc_gNB_mac_rrc_init(rrc); + rrc_gNB_CU_DU_init(rrc); uid_linear_allocator_init(&rrc->uid_allocator); RB_INIT(&rrc->rrc_ue_head); rrc->initial_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); @@ -241,13 +256,12 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu rrc->cell_info_configured = 0; LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" Checking release \n",PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt)); init_NR_SI(rrc, configuration); - rrc_init_nr_global_param(); - openair_nr_rrc_on(&ctxt); - return 0; -}//END openair_rrc_gNB_configuration + openair_nr_rrc_on(rrc); + return; +} // END openair_rrc_gNB_configuration - -void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_addition_req_t *m) { +static void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_addition_req_t *m) +{ struct NR_CG_ConfigInfo *cg_configinfo = NULL; asn_dec_rval_t dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_CG_ConfigInfo, @@ -272,24 +286,20 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x dec_rval.consumed, (dec_rval.consumed +7/8)); } - //----------------------------------------------------------------------------- -uint8_t -rrc_gNB_get_next_transaction_identifier( - module_id_t gnb_mod_idP -) +unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP) //----------------------------------------------------------------------------- { - static uint8_t nr_rrc_transaction_identifier[NUMBER_OF_gNB_MAX]; - nr_rrc_transaction_identifier[gnb_mod_idP] = (nr_rrc_transaction_identifier[gnb_mod_idP] + 1) % NR_RRC_TRANSACTION_IDENTIFIER_NUMBER; - LOG_T(NR_RRC, "generated xid is %d\n", nr_rrc_transaction_identifier[gnb_mod_idP]); - return nr_rrc_transaction_identifier[gnb_mod_idP]; + static unsigned int transaction_id[NUMBER_OF_gNB_MAX] = {0}; + // used also in NGAP thread, so need thread safe operation + unsigned int tmp = __atomic_add_fetch(&transaction_id[gnb_mod_idP], 1, __ATOMIC_SEQ_CST); + tmp %= NR_RRC_TRANSACTION_IDENTIFIER_NUMBER; + LOG_T(NR_RRC, "generated xid is %d\n", tmp); + return tmp; } -void apply_macrlc_config(gNB_RRC_INST *rrc, - rrc_gNB_ue_context_t *const ue_context_pP, - const protocol_ctxt_t *const ctxt_pP ) { - +static void apply_macrlc_config(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, const protocol_ctxt_t *const ctxt_pP) +{ NR_CellGroupConfig_t *cgc = get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : NULL; rrc_mac_config_req_gNB(rrc->module_id, rrc->configuration.pdsch_AntennaPorts, @@ -308,27 +318,18 @@ void apply_macrlc_config(gNB_RRC_INST *rrc, ue_context_pP->ue_context.DRB_configList, NULL, get_softmodem_params()->sa ? cgc->rlc_BearerToAddModList : NULL); - } //----------------------------------------------------------------------------- -void -rrc_gNB_generate_RRCSetup( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, - const uint8_t *masterCellGroup, - int masterCellGroup_len, - NR_ServingCellConfigCommon_t *scc) +static void rrc_gNB_generate_RRCSetup(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + const uint8_t *masterCellGroup, + int masterCellGroup_len, + NR_ServingCellConfigCommon_t *scc) //----------------------------------------------------------------------------- { LOG_I(NR_RRC, "rrc_gNB_generate_RRCSetup for RNTI %04lx\n", ctxt_pP->rntiMaybeUEid); - // T(T_GNB_RRC_SETUP, - // T_INT(ctxt_pP->module_id), - // T_INT(ctxt_pP->frame), - // T_INT(ctxt_pP->subframe), - // T_INT(ctxt_pP->rnti)); - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; unsigned char buf[1024]; @@ -368,11 +369,7 @@ rrc_gNB_generate_RRCSetup( } //----------------------------------------------------------------------------- -void -rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest( - const protocol_ctxt_t *const ctxt_pP, - const int CC_id -) +static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(const protocol_ctxt_t *const ctxt_pP, const int CC_id) //----------------------------------------------------------------------------- { LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n"); @@ -440,10 +437,7 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest( rrc_instance_p->mac_rrc.dl_rrc_message_transfer(ctxt_pP->module_id, &dl_rrc); } -void -rrc_gNB_generate_RRCReject( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP) +static void rrc_gNB_generate_RRCReject(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP) //----------------------------------------------------------------------------- { LOG_I(NR_RRC, "rrc_gNB_generate_RRCReject \n"); @@ -482,12 +476,7 @@ rrc_gNB_generate_RRCReject( /* * Process the rrc setup complete message from UE (SRB1 Active) */ -void -rrc_gNB_process_RRCSetupComplete( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - NR_RRCSetupComplete_IEs_t *rrcSetupComplete -) +static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, NR_RRCSetupComplete_IEs_t *rrcSetupComplete) //----------------------------------------------------------------------------- { LOG_A(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing NR_RRCSetupComplete from UE (SRB1 Active)\n", @@ -504,22 +493,9 @@ rrc_gNB_process_RRCSetupComplete( } //----------------------------------------------------------------------------- -void -rrc_gNB_generate_defaultRRCReconfiguration( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP -) +static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP) //----------------------------------------------------------------------------- { - uint8_t buffer[RRC_BUF_SIZE]; - int16_t size; - /*NR_SRB_ToAddModList_t **SRB_configList2 = NULL; - NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; - NR_DRB_ToAddModList_t **DRB_configList = NULL; - NR_DRB_ToAddModList_t **DRB_configList2 = NULL; - NR_SRB_ToAddMod_t *SRB2_config = NULL; - NR_DRB_ToAddMod_t *DRB_config = NULL; - NR_SDAP_Config_t *sdap_config = NULL;*/ struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = NULL; NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL; @@ -527,66 +503,6 @@ rrc_gNB_generate_defaultRRCReconfiguration( uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); /******************** Radio Bearer Config ********************/ - /* Configure SRB2 */ - /*SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid]; - if (*SRB_configList2) { - free(*SRB_configList2); - } - *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); - memset(*SRB_configList2, 0, sizeof(**SRB_configList2)); - SRB2_config = CALLOC(1, sizeof(*SRB2_config)); - SRB2_config->srb_Identity = 2; - asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config); - asn1cSeqAdd(&SRB_configList->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[xid]; - 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)); - DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; - // TODO sdap_Config - sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t)); - memset(sdap_config, 0, sizeof(NR_SDAP_Config_t)); - DRB_config->cnAssociation->choice.sdap_Config = sdap_config; - // TODO pdcp_Config - DRB_config->reestablishPDCP = NULL; - DRB_config->recoverPDCP = NULL; - DRB_config->pdcp_Config = calloc(1, sizeof(*DRB_config->pdcp_Config)); - DRB_config->pdcp_Config->drb = calloc(1,sizeof(*DRB_config->pdcp_Config->drb)); - DRB_config->pdcp_Config->drb->discardTimer = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->discardTimer)); - *DRB_config->pdcp_Config->drb->discardTimer = NR_PDCP_Config__drb__discardTimer_infinity; - DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL)); - *DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; - DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL)); - *DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; - DRB_config->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; - DRB_config->pdcp_Config->drb->headerCompression.choice.notUsed = 0; - - DRB_config->pdcp_Config->drb->integrityProtection = NULL; - DRB_config->pdcp_Config->drb->statusReportRequired = NULL; - DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL; - DRB_config->pdcp_Config->moreThanOneRLC = NULL; - - DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering)); - *DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms100; - DRB_config->pdcp_Config->ext1 = NULL; - - asn1cSeqAdd(&(*DRB_configList)->list, DRB_config); - asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);*/ dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList)); @@ -594,7 +510,6 @@ rrc_gNB_generate_defaultRRCReconfiguration( for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) { dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); - memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer, ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length); @@ -608,7 +523,6 @@ rrc_gNB_generate_defaultRRCReconfiguration( if (ue_context_pP->ue_context.nas_pdu_flag == 1) { dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); - memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)ue_context_pP->ue_context.nas_pdu.buffer, ue_context_pP->ue_context.nas_pdu.length); @@ -625,21 +539,23 @@ rrc_gNB_generate_defaultRRCReconfiguration( NR_MeasConfig_t *measconfig = get_defaultMeasConfig(&rrc->configuration); gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - memset(buffer, 0, sizeof(buffer)); - size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), - xid, - NULL, //*SRB_configList2, - NULL, //*DRB_configList, - NULL, - NULL, - NULL, - measconfig, - dedicatedNAS_MessageList, - ue_context_pP, - &rrc->carrier, - &rrc->configuration, - NULL, - ue_p->masterCellGroup); + uint8_t buffer[RRC_BUF_SIZE] = {0}; + int size = do_RRCReconfiguration(ctxt_pP, + buffer, + sizeof(buffer), + xid, + NULL, //*SRB_configList2, + NULL, //*DRB_configList, + NULL, + NULL, + NULL, + measconfig, + dedicatedNAS_MessageList, + ue_context_pP, + &rrc->carrier, + &rrc->configuration, + NULL, + ue_p->masterCellGroup); AssertFatal(size > 0, "cannot encode RRCReconfiguration in %s()\n", __func__); LOG_W(RRC, "do_RRCReconfiguration(): size %d\n", size); @@ -647,6 +563,7 @@ rrc_gNB_generate_defaultRRCReconfiguration( xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, ue_p->masterCellGroup); } + // suspicious if it is always malloced before ? free(ue_context_pP->ue_context.nas_pdu.buffer); LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n"); @@ -666,6 +583,8 @@ rrc_gNB_generate_defaultRRCReconfiguration( ue_context_pP->ue_context.rnti); switch (RC.nrrrc[ctxt_pP->module_id]->node_type) { case ngran_gNB_CU: + case ngran_gNB_CUCP: + case ngran_gNB: nr_rrc_data_req(ctxt_pP, DCCH, rrc_gNB_mui++, @@ -682,28 +601,6 @@ rrc_gNB_generate_defaultRRCReconfiguration( AssertFatal(1==0,"nothing to do for DU\n"); break; - case ngran_gNB: - { - LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", - ctxt_pP->frame, - ctxt_pP->module_id, - size, - ue_context_pP->ue_context.rnti, - rrc_gNB_mui, - ctxt_pP->module_id, - DCCH); - nr_rrc_data_req(ctxt_pP, - DCCH, - rrc_gNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); - // rrc_pdcp_config_asn1_req - // rrc_rlc_config_asn1_req - } - break; - default : LOG_W(NR_RRC, "Unknown node type %d\n", RC.nrrrc[ctxt_pP->module_id]->node_type); } @@ -735,37 +632,22 @@ rrc_gNB_generate_defaultRRCReconfiguration( } } -//----------------------------------------------------------------------------- -void -rrc_gNB_generate_dedicatedRRCReconfiguration( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - NR_CellGroupConfig_t *cell_groupConfig_from_DU -) -//----------------------------------------------------------------------------- -{ +void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP) { + gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; NR_DRB_ToAddModList_t **DRB_configList = NULL; NR_DRB_ToAddModList_t **DRB_configList2 = NULL; - NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; - struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList - *dedicatedNAS_MessageList = NULL; - NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL; - uint8_t buffer[RRC_BUF_SIZE]; - uint16_t size; int qos_flow_index = 0; int pdu_sessions_done = 0; int i; uint8_t drb_id_to_setup_start = 0; uint8_t nb_drb_to_setup = rrc->configuration.drbs; long drb_priority[NGAP_MAX_DRBS_PER_UE]; - NR_CellGroupConfig_t *cellGroupConfig = NULL; uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); - NR_SRB_ToAddModList_t **SRB_configList2 = generateSRB2_confList(ue_p, SRB_configList, xid); - DRB_configList = &ue_context_pP->ue_context.DRB_configList; if (*DRB_configList) { free(*DRB_configList); @@ -780,8 +662,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); memset(*DRB_configList2, 0, sizeof(**DRB_configList2)); - dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList)); - for (i = 0; i < ue_context_pP->ue_context.setup_pdu_sessions; i++) { if (pdu_sessions_done >= ue_context_pP->ue_context.nb_of_pdusessions) { break; @@ -880,11 +760,42 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( asn1cSeqAdd(&(*DRB_configList)->list, DRB_config); asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config); } + LOG_D(RRC, "DRB Priority %ld\n", drb_priority[drb_id]); // To supress warning for now } } ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE; ue_context_pP->ue_context.pduSession[i].xid = xid; + } +} + +//----------------------------------------------------------------------------- +void +rrc_gNB_generate_dedicatedRRCReconfiguration( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP, + NR_CellGroupConfig_t *cell_groupConfig_from_DU +) +//----------------------------------------------------------------------------- +{ + gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; + long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future) + NR_CellGroupConfig_t *cellGroupConfig = NULL; + uint8_t buffer[RRC_BUF_SIZE]; + uint16_t size; + int xid = -1; + + int drb_id_to_setup_start = 1; + NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList; + int nb_drb_to_setup = DRB_configList->list.count; + + struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = NULL; + NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL; + dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList)); + + for (int i=0; i < nb_drb_to_setup; i++) { + NR_DRB_ToAddMod_t *DRB_config = DRB_configList->list.array[i]; + if (drb_id_to_setup_start == 1) drb_id_to_setup_start = DRB_config->drb_Identity; if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) { dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); @@ -899,6 +810,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( // TODO LOG_E(NR_RRC,"no NAS info (pdusession id %d)\n", i); } + + xid = ue_context_pP->ue_context.pduSession[i].xid; } /* If list is empty free the list and reset the address */ @@ -919,10 +832,14 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( cellGroupConfig = cell_groupConfig_from_DU; } + AssertFatal(xid > -1, "Invalid xid %d. No PDU sessions setup to configure.\n", xid); + NR_SRB_ToAddModList_t *SRB_configList2 = NULL; + SRB_configList2 = ue_context_pP->ue_context.SRB_configList2[xid]; + size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), xid, - *SRB_configList2, - *DRB_configList, + SRB_configList2, + DRB_configList, NULL, NULL, NULL, @@ -936,7 +853,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Reconfiguration\n"); /* Free all NAS PDUs */ - for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { + for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) { /* Free the NAS PDU buffer and invalidate it */ free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer); @@ -1208,19 +1125,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( } memset(buffer, 0, sizeof(buffer)); - size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), xid, - NULL, - NULL, - *DRB_Release_configList2, - NULL, - NULL, - NULL, - dedicatedNAS_MessageList, - NULL, - NULL, - NULL, - NULL, - NULL); + size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), xid, NULL, NULL, *DRB_Release_configList2, NULL, NULL, NULL, dedicatedNAS_MessageList, NULL, NULL, NULL, NULL, NULL); ue_context_pP->ue_context.pdu_session_release_command_flag = 1; @@ -1273,10 +1178,6 @@ rrc_gNB_process_RRCReconfigurationComplete( ) { int drb_id; - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; - uint8_t *kUPint = NULL; NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; @@ -1285,36 +1186,6 @@ rrc_gNB_process_RRCReconfigurationComplete( ue_context_pP->ue_context.ue_reestablishment_timer = 0; - /* Derive the keys from kgnb */ - if (DRB_configList != NULL) { - nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kgnb, - &kUPenc); - nr_derive_key_up_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kgnb, - &kUPint); - } - - nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kgnb, - &kRRCenc); - nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kgnb, - &kRRCint); - /* Refresh SRBs/DRBs */ - - LOG_D(NR_RRC,"Configuring PDCP DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti); - - nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, SRB_configList, (ue_context_pP->ue_context.integrity_algorithm << 4) | ue_context_pP->ue_context.ciphering_algorithm, kRRCenc, kRRCint); - - nr_pdcp_add_drbs(ctxt_pP->enb_flag, - ctxt_pP->rntiMaybeUEid, - DRB_configList, - (ue_context_pP->ue_context.integrity_algorithm << 4) | ue_context_pP->ue_context.ciphering_algorithm, - kUPenc, - kUPint, - get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); - /* Refresh SRBs/DRBs */ if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti); @@ -1500,13 +1371,7 @@ rrc_gNB_generate_RRCReestablishment( } //----------------------------------------------------------------------------- -void -rrc_gNB_process_RRCConnectionReestablishmentComplete( - const protocol_ctxt_t *const ctxt_pP, - const rnti_t reestablish_rnti, - rrc_gNB_ue_context_t *ue_context_pP, - const uint8_t xid -) +void rrc_gNB_process_RRCConnectionReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, const rnti_t reestablish_rnti, rrc_gNB_ue_context_t *ue_context_pP, const uint8_t old_xid) //----------------------------------------------------------------------------- { LOG_I(NR_RRC, @@ -1524,12 +1389,12 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; - uint8_t next_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); + uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); int ret = 0; ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - ue_context_pP->ue_context.reestablishment_xid = next_xid; - SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid]; + ue_context_pP->ue_context.reestablishment_xid = new_xid; + SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[old_xid]; // get old configuration of SRB2 if (*SRB_configList2 != NULL) { @@ -1540,7 +1405,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) { if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) { - LOG_D(NR_RRC, "get SRB2_config from (ue_context_pP->ue_context.SRB_configList2[%d])\n", xid); + LOG_D(NR_RRC, "get SRB2_config from (ue_context_pP->ue_context.SRB_configList2[%d])\n", old_xid); SRB2_config = (*SRB_configList2)->list.array[i]; break; } @@ -1550,12 +1415,12 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( // SRB2_config = CALLOC(1, sizeof(*SRB2_config)); // SRB2_config->srb_Identity = 2; - SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[next_xid]); - DRB_configList2 = &(ue_context_pP->ue_context.DRB_configList2[next_xid]); + SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[new_xid]); + DRB_configList2 = &(ue_context_pP->ue_context.DRB_configList2[new_xid]); if (*SRB_configList2) { free(*SRB_configList2); - LOG_D(NR_RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", next_xid); + LOG_D(NR_RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", new_xid); } *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); @@ -1566,8 +1431,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config); LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList\n", SRB2_config->srb_Identity); - LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList2[%d]\n", - SRB2_config->srb_Identity, next_xid); + LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList2[%d]\n", SRB2_config->srb_Identity, new_xid); } else { // SRB configuration list only contains SRB1. LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n"); @@ -1575,7 +1439,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( if (*DRB_configList2) { free(*DRB_configList2); - LOG_D(NR_RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", next_xid); + LOG_D(NR_RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", new_xid); } *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); @@ -1691,27 +1555,29 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( /* TODO parameters yet to process ... */ /* TODO should test if pdu session are Ok before! */ ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE; - ue_context_pP->ue_context.pduSession[i].xid = xid; + ue_context_pP->ue_context.pduSession[i].xid = old_xid; LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE"); } memset(buffer, 0, sizeof(buffer)); - size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), - xid, + size = do_RRCReconfiguration(ctxt_pP, + buffer, + sizeof(buffer), + old_xid, *SRB_configList2, - DRB_configList, - NULL, - NULL, - NULL, - NULL, // MeasObj_list, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); + DRB_configList, + NULL, + NULL, + NULL, + NULL, // MeasObj_list, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n"); @@ -2135,21 +2001,13 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, // SRB1 ue_context_p->ue_context.Srb1.Active = 1; ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx; - memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0], - &DCCH_LCHAN_DESC, - LCHAN_DESC_SIZE); - memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1], - &DCCH_LCHAN_DESC, - LCHAN_DESC_SIZE); + rrc_init_nr_srb_param(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0]); + rrc_init_nr_srb_param(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1]); // SRB2: set it to go through SRB1 with id 1 (DCCH) ue_context_p->ue_context.Srb2.Active = 1; ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx; - memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0], - &DCCH_LCHAN_DESC, - LCHAN_DESC_SIZE); - memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1], - &DCCH_LCHAN_DESC, - LCHAN_DESC_SIZE); + rrc_init_nr_srb_param(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0]); + rrc_init_nr_srb_param(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1]); rrc_gNB_generate_RRCReestablishment(ctxt_pP, ue_context_p, 0); @@ -2483,7 +2341,6 @@ rrc_gNB_decode_dcch( nr_rrc_pdcp_config_security(ctxt_pP, ue_context_p, 1); rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); - //rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); break; case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure: LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, @@ -3499,6 +3356,7 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch } if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { + fill_DRB_configList(&ctxt, ue_context_p); rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig); } else { rrc_gNB_generate_defaultRRCReconfiguration(&ctxt, ue_context_p); @@ -3511,10 +3369,31 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, const char *msg_name, instance_t instance){ - f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); + f1ap_ue_context_setup_t *resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid); + + e1ap_bearer_setup_req_t req = {0}; + req.numPDUSessionsMod = ue_context_p->ue_context.nb_of_pdusessions; + req.gNB_cu_cp_ue_id = ue_context_p->ue_context.gNB_ue_ngap_id; + req.rnti = ue_context_p->ue_context.rnti; + for (int i=0; i < req.numPDUSessionsMod; i++) { + req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length; + for (int j=0; j < resp->drbs_to_be_setup_length; j++) { + f1ap_drb_to_be_setup_t *drb_f1 = resp->drbs_to_be_setup + j; + DRB_nGRAN_to_setup_t *drb_e1 = req.pduSessionMod[i].DRBnGRanModList + j; + + drb_e1->id = drb_f1->drb_id; + drb_e1->numDlUpParam = drb_f1->up_dl_tnl_length; + drb_e1->DlUpParamList[0].tlAddress = drb_f1->up_dl_tnl[0].tl_address; + drb_e1->DlUpParamList[0].teId = drb_f1->up_dl_tnl[0].teid; + } + } + + // send the F1 response message up to update F1-U tunnel info + rrc->cucp_cuup.bearer_context_mod(&req, instance); + NR_CellGroupConfig_t *cellGroupConfig = NULL; if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){ @@ -3803,6 +3682,98 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { } } +int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) { + + AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n"); + gNB_RRC_INST *rrc = RC.nrrrc[0]; //TODO: remove hardcoding of RC index here + MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, instance, E1AP_SETUP_RESP); + + e1ap_setup_resp_t *resp = &E1AP_SETUP_RESP(msg_p); + resp->transac_id = req->transac_id; + + for (int i=0; i < req->supported_plmns; i++) { + if (rrc->configuration.mcc[i] == req->plmns[i].mcc && + rrc->configuration.mnc[i] == req->plmns[i].mnc) { + LOG_E(NR_RRC, "PLMNs received from CUUP (mcc:%d, mnc:%d) did not match with PLMNs in RRC (mcc:%d, mnc:%d)\n", + req->plmns[i].mcc, req->plmns[i].mnc, rrc->configuration.mcc[i], rrc->configuration.mnc[i]); + return -1; + } + } + + itti_send_msg_to_task(TASK_CUCP_E1, instance, msg_p); + + return 0; +} + +void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, + e1ap_bearer_setup_resp_t *e1ap_resp) { + + /*Generate a UE context modification request message towards the DU to instruct the DU + *for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/ + + protocol_ctxt_t ctxt = {0}; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); + // TODO: So many hard codings + MessageDef *message_p; + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); + f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(message_p); + req->rnti = ue_context_p->ue_context.rnti; + req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0]; + req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0]; + req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0]; + req->nr_cellid = RC.nrrrc[ctxt.module_id]->nr_cellid; + + /*Instruction towards the DU for SRB2 configuration*/ + req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t)); + req->srbs_to_be_setup_length = 1; + f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup; + SRBs[0].srb_id = 2; + SRBs[0].lcid = 2; + + /*Instruction towards the DU for DRB configuration and tunnel creation*/ + req->drbs_to_be_setup_length = e1ap_resp->pduSession[0].numDRBSetup; + req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)*req->drbs_to_be_setup_length); + for (int i=0; i < e1ap_resp->pduSession[0].numDRBSetup; i++) { + f1ap_drb_to_be_setup_t *DRBs = req->drbs_to_be_setup + i; + DRBs[i].drb_id = e1ap_resp->pduSession[0].DRBnGRanList[i].id; + DRBs[i].rlc_mode = RLC_MODE_AM; + DRBs[i].up_ul_tnl[0].tl_address = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress; + DRBs[i].up_ul_tnl[0].port = RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd; + DRBs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId; + DRBs[i].up_ul_tnl_length = 1; + } + + itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p); +} + +void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) { + // Find the UE context from UE ID and send ITTI message to F1AP to send UE context modification message to DU + + uint16_t ue_initial_id = 0; // Making an invalid UE initial ID + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, resp->gNB_cu_cp_ue_id); + protocol_ctxt_t ctxt = {0}; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); + + gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0}; + create_tunnel_resp.num_tunnels = resp->numPDUSessions; + for (int i=0; i < resp->numPDUSessions; i++) { + create_tunnel_resp.pdusession_id[i] = resp->pduSession[i].id; + create_tunnel_resp.gnb_NGu_teid[i] = resp->pduSession[i].teId; + memcpy(create_tunnel_resp.gnb_addr.buffer, + &resp->pduSession[i].tlAddress, + sizeof(in_addr_t)); + create_tunnel_resp.gnb_addr.length = sizeof(in_addr_t); // IPv4 byte length + } + + nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt, + &create_tunnel_resp); + + ue_context_p->ue_context.setup_pdu_sessions += resp->numPDUSessions; + + // TODO: SV: combine e1ap_bearer_setup_req_t and e1ap_bearer_setup_resp_t and minimize assignments + prepare_and_send_ue_context_modification_f1(ue_context_p, resp); +} + static void print_rrc_meas(FILE *f, const NR_MeasResults_t *measresults) { DevAssert(measresults->measResultServingMOList.list.count >= 1); @@ -4021,6 +3992,15 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p, msg_name_p, instance); break; + case E1AP_SETUP_REQ: + LOG_I(NR_RRC, "Received E1AP_SETUP_REQ for instance %d\n", (int)instance); + rrc_gNB_process_e1_setup_req(&E1AP_SETUP_REQ(msg_p), instance); + break; + + case E1AP_BEARER_CONTEXT_SETUP_RESP: + LOG_I(NR_RRC, "Received E1AP_BEARER_CONTEXT_SETUP_RESP for instance %d\n", (int)instance); + rrc_gNB_process_e1_bearer_context_setup_resp(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p), instance); + case NGAP_PAGING_IND: rrc_gNB_process_PAGING_IND(msg_p, msg_name_p, instance); break; @@ -4063,6 +4043,7 @@ rrc_gNB_generate_SecurityModeCommand( switch (RC.nrrrc[ctxt_pP->module_id]->node_type) { case ngran_gNB_CU: + case ngran_gNB_CUCP: // create an ITTI message memcpy(ue_context_pP->ue_context.Srb1.Srb_info.Tx_buffer.Payload, buffer, size); ue_context_pP->ue_context.Srb1.Srb_info.Tx_buffer.payload_size = size; @@ -4125,6 +4106,7 @@ rrc_gNB_generate_UECapabilityEnquiry( size); switch (RC.nrrrc[ctxt_pP->module_id]->node_type) { case ngran_gNB_CU: + case ngran_gNB_CUCP: nr_rrc_data_req( ctxt_pP, DCCH, @@ -4352,3 +4334,4 @@ void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) LOG_D(NR_RRC, "Time in RRC: %u/ %u \n", frame, subframe); itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p); } + diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.c b/openair2/RRC/NR/rrc_gNB_GTPV1U.c index ec220172d0..3fef7bc0ef 100644 --- a/openair2/RRC/NR/rrc_gNB_GTPV1U.c +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.c @@ -49,7 +49,6 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, uint8_t *inde_list ) { - rnti_t rnti; int i; struct rrc_gNB_ue_context_s *ue_context_p = NULL; @@ -57,7 +56,6 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels); - rnti = create_tunnel_resp_pP->rnti; ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) { @@ -74,7 +72,6 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( create_tunnel_resp_pP->enb_addr.length); } - (void)rnti; /* avoid gcc warning "set but not used" */ return 0; } else { return -1; @@ -84,10 +81,8 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( const protocol_ctxt_t *const ctxt_pP, - const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, - uint8_t *inde_list + const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP ) { - rnti_t rnti; int i; struct rrc_gNB_ue_context_s *ue_context_p = NULL; @@ -95,24 +90,21 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels); - rnti = create_tunnel_resp_pP->ue_id; ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) { - ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->gnb_NGu_teid[i]; - ue_context_p->ue_context.gnb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->gnb_addr; - ue_context_p->ue_context.gnb_gtp_psi[inde_list[i]] = create_tunnel_resp_pP->pdusession_id[i]; - LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n", + ue_context_p->ue_context.gnb_gtp_teid[i] = create_tunnel_resp_pP->gnb_NGu_teid[i]; + ue_context_p->ue_context.gnb_gtp_addrs[i] = create_tunnel_resp_pP->gnb_addr; + ue_context_p->ue_context.gnb_gtp_psi[i] = create_tunnel_resp_pP->pdusession_id[i]; + LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, id %u, gtp addr len %d \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->gnb_NGu_teid[i], - ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]], - inde_list[i], + ue_context_p->ue_context.gnb_gtp_teid[i], i, create_tunnel_resp_pP->pdusession_id[i], create_tunnel_resp_pP->gnb_addr.length); } - (void)rnti; /* avoid gcc warning "set but not used" */ return 0; } else { return -1; diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.h b/openair2/RRC/NR/rrc_gNB_GTPV1U.h index 748bd98789..03ef050bcf 100644 --- a/openair2/RRC/NR/rrc_gNB_GTPV1U.h +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.h @@ -41,8 +41,7 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( const protocol_ctxt_t *const ctxt_pP, - const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, - uint8_t *inde_list + const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP ); #endif diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 3eccf0ef37..6f3ebcd06d 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -57,6 +57,7 @@ #include "NGAP_Cause.h" #include "NGAP_CauseRadioNetwork.h" #include "f1ap_messages_types.h" +#include "openair2/E1AP/e1ap_asnc.h" extern RAN_CONTEXT_t RC; @@ -242,7 +243,7 @@ rrc_gNB_NGAP_get_ue_ids( } //------------------------------------------------------------------------------ -static struct rrc_gNB_ue_context_s * +struct rrc_gNB_ue_context_s * rrc_gNB_get_ue_context_from_ngap_ids( const instance_t instanceP, const uint16_t ue_initial_idP, @@ -474,7 +475,6 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( protocol_ctxt_t ctxt={0}; uint8_t pdu_sessions_done = 0; gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp; - uint8_t inde_list[NR_NB_RB_MAX - 3]= {0}; int ret = 0; ue_initial_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_initial_id; @@ -495,12 +495,14 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( return (-1); } else { PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).gNB_ue_ngap_id; ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id; ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nas_pdu_flag; uint8_t nb_pdusessions_tosetup = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions; if (nb_pdusessions_tosetup != 0) { + AssertFatal(rrc->node_type != ngran_gNB_CUCP, "PDU sessions in Initial context setup request not handled by E1 yet\n"); gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; for (int i = 0; i < NR_NB_RB_MAX - 3; i++) { if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) @@ -520,7 +522,6 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( i, create_tunnel_req.outgoing_teid[pdu_sessions_done], create_tunnel_req.pdusession_id[pdu_sessions_done]); - inde_list[pdu_sessions_done] = i; pdu_sessions_done++; if(pdu_sessions_done >= nb_pdusessions_tosetup) { @@ -549,9 +550,8 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( &ctxt, - &create_tunnel_resp, - &inde_list[0]); - ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup; + &create_tunnel_resp); + ue_context_p->ue_context.setup_pdu_sessions += NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions; ue_context_p->ue_context.established_pdu_sessions_flag = 1; } @@ -804,6 +804,7 @@ rrc_gNB_process_NGAP_DOWNLINK_NAS( */ switch (RC.nrrrc[ctxt.module_id]->node_type) { case ngran_gNB_CU: + case ngran_gNB_CUCP: /* Transfer data to PDCP */ nr_rrc_data_req ( &ctxt, @@ -945,7 +946,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( } //------------------------------------------------------------------------------ -int +void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( MessageDef *msg_p, const char *msg_name, @@ -953,21 +954,20 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( ) //------------------------------------------------------------------------------ { + gNB_RRC_INST *rrc; uint16_t ue_initial_id; uint32_t gNB_ue_ngap_id; rrc_gNB_ue_context_t *ue_context_p = NULL; protocol_ctxt_t ctxt={0}; - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; - gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0}; - uint8_t pdu_sessions_done; - uint8_t inde_list[NR_NB_RB_MAX - 3]= {0}; - int ret = 0; - ue_initial_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).ue_initial_id; - gNB_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).gNB_ue_ngap_id; + ngap_pdusession_setup_req_t* msg=&NGAP_PDUSESSION_SETUP_REQ(msg_p); + ue_initial_id = msg->ue_initial_id; + gNB_ue_ngap_id = msg->gNB_ue_ngap_id; ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); + rrc = RC.nrrrc[ctxt.module_id]; LOG_I(NR_RRC, "[gNB %ld] Received %s: ue_initial_id %d, gNB_ue_ngap_id %u \n", - instance, msg_name, ue_initial_id, gNB_ue_ngap_id); + instance, msg_name, ue_initial_id, gNB_ue_ngap_id); if (ue_context_p == NULL) { MessageDef *msg_fail_p = NULL; @@ -976,110 +976,102 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( NGAP_PDUSESSION_SETUP_REQ(msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; // TODO add failure cause when defined! itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p); - return (-1); - } else { - memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); - uint8_t nb_pdusessions_tosetup = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup; - pdu_sessions_done = 0; + return ; + } + + ue_context_p->ue_context.nb_of_pdusessions = msg->nb_pdusessions_tosetup; + ue_context_p->ue_context.gNB_ue_ngap_id = msg->gNB_ue_ngap_id; + ue_context_p->ue_context.amf_ue_ngap_id = msg->amf_ue_ngap_id; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); - for (int i = 0; i < NR_NB_RB_MAX - 3; i++) { - if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) - continue; - ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_NEW; - ue_context_p->ue_context.pduSession[i].param = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done]; - create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id; - create_tunnel_req.incoming_rb_id[pdu_sessions_done]= i+1; - create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid; - create_tunnel_req.outgoing_qfi[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].qos[0].qfi; - memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer, - NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer, - sizeof(uint8_t)*20); - create_tunnel_req.dst_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.length; - LOG_I(NR_RRC,"NGAP PDUSESSION SETUP REQ: local index %d teid %u, pdusession id %d \n", - i, - create_tunnel_req.outgoing_teid[pdu_sessions_done], - create_tunnel_req.pdusession_id[pdu_sessions_done]); - inde_list[pdu_sessions_done] = i; - pdu_sessions_done++; + /* Configurations are referred from rrc_gNB_generate_dedicatedRRCReconfiguration() and + rrc_gNB_process_RRCReconfigurationComplete() - if(pdu_sessions_done >= nb_pdusessions_tosetup) { - break; + At CU-CP we configure the E1 bearer context setup parameters (PDU sessions, DRBs and + QoS flows) same as in these functions. At CU-UP we create PDU Sessions and allocate DRBs. + */ + e1ap_bearer_setup_req_t bearer_req; + + bearer_req.gNB_cu_cp_ue_id = gNB_ue_ngap_id; + bearer_req.rnti = ue_context_p->ue_context.rnti; + bearer_req.cipheringAlgorithm = ue_context_p->ue_context.ciphering_algorithm; + memcpy(bearer_req.encryptionKey, ue_context_p->ue_context.kgnb, sizeof(ue_context_p->ue_context.kgnb)); + bearer_req.integrityProtectionAlgorithm = ue_context_p->ue_context.integrity_algorithm; + memcpy(bearer_req.integrityProtectionKey, ue_context_p->ue_context.kgnb, sizeof(ue_context_p->ue_context.kgnb)); + bearer_req.ueDlAggMaxBitRate = msg->ueAggMaxBitRateDownlink; + + bearer_req.numPDUSessions = msg->nb_pdusessions_tosetup; + + for (int i=0; i < bearer_req.numPDUSessions; i++) { + ue_context_p->ue_context.pduSession[i].param = msg->pdusession_setup_params[i]; + + pdu_session_to_setup_t *pdu = bearer_req.pduSession + i; + pdu->sessionId = msg->pdusession_setup_params[i].pdusession_id; + pdu->sessionType = msg->pdusession_setup_params[i].upf_addr.pdu_session_type; + pdu->sst = msg->allowed_nssai[i].sST; + if (rrc->security.do_drb_integrity) { + pdu->integrityProtectionIndication = E1AP_IntegrityProtectionIndication_required; + } else { + pdu->integrityProtectionIndication = E1AP_IntegrityProtectionIndication_not_needed; + } + + if (rrc->security.do_drb_ciphering) { + pdu->confidentialityProtectionIndication = E1AP_ConfidentialityProtectionIndication_required; + } else { + pdu->confidentialityProtectionIndication = E1AP_ConfidentialityProtectionIndication_not_needed; + } + pdu->teId = msg->pdusession_setup_params[i].gtp_teid; + memcpy(&pdu->tlAddress, + msg->pdusession_setup_params[i].upf_addr.buffer, + sizeof(uint8_t)*4); + + ue_context_p->ue_context.pduSession[i].param = msg->pdusession_setup_params[i]; + ue_context_p->ue_context.nb_of_pdusessions = msg->nb_pdusessions_tosetup; + ue_context_p->ue_context.gNB_ue_ngap_id = msg->gNB_ue_ngap_id; + ue_context_p->ue_context.amf_ue_ngap_id = msg->amf_ue_ngap_id; + pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding + ue_context_p->ue_context.setup_pdu_sessions += pdu->numDRB2Setup; + for (int j=0; j < pdu->numDRB2Setup; j++) { + DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j; + + drb->id = i + j + 1; + + drb->defaultDRB = E1AP_DefaultDRB_true; + + drb->sDAP_Header_UL = !(rrc->configuration.enable_sdap); + drb->sDAP_Header_DL = !(rrc->configuration.enable_sdap); + + drb->pDCP_SN_Size_UL = E1AP_PDCP_SN_Size_s_18; + drb->pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_18; + + drb->discardTimer = E1AP_DiscardTimer_infinity; + drb->reorderingTimer = E1AP_T_Reordering_ms0; + + drb->rLC_Mode = E1AP_RLC_Mode_rlc_am; + + drb->numCellGroups = 1; // assume one cell group associated with a DRB + + for (int k=0; k < drb->numCellGroups; k++) { + cell_group_t *cellGroup = drb->cellGroupList + k; + cellGroup->id = 0; // MCG + } + + drb->numQosFlow2Setup = msg->pdusession_setup_params[i].nb_qos; + for (int k=0; k < drb->numQosFlow2Setup; k++) { + qos_flow_to_setup_t *qos = drb->qosFlows + k; + + qos->id = msg->pdusession_setup_params[i].qos[k].qfi; + qos->fiveQI = msg->pdusession_setup_params[i].qos[k].fiveQI; + qos->fiveQI_type = msg->pdusession_setup_params[i].qos[k].fiveQI_type; + + qos->qoSPriorityLevel = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.priority_level; + qos->pre_emptionCapability = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_capability; + qos->pre_emptionVulnerability = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_vulnerability; } } - - ue_context_p->ue_context.nb_of_pdusessions = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup; - ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).gNB_ue_ngap_id; - ue_context_p->ue_context.amf_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).amf_ue_ngap_id; - create_tunnel_req.ue_id = ue_context_p->ue_context.rnti; - create_tunnel_req.num_tunnels = pdu_sessions_done; - - ret = gtpv1u_create_ngu_tunnel( - instance, - &create_tunnel_req, - &create_tunnel_resp); - if (ret != 0) { - LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ue_release_timer_ng = 1; - ue_context_p->ue_context.ue_release_timer_thres_ng = 100; - ue_context_p->ue_context.ue_release_timer = 0; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - ue_context_p->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ - // rrc_gNB_free_UE(ctxt.module_id,ue_context_p); - ue_context_p->ue_context.ul_failure_timer = 0; - return (0); - } - nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( - &ctxt, - &create_tunnel_resp, - &inde_list[0]); - ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup; - - // TEST - // ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE; - // rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0); - if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)){ - rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL); - } - else{ - /*Generate a UE context modification request message towards the DU to instruct the DU - *for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/ - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); - f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ (message_p); - req->rnti = ue_context_p->ue_context.rnti; - req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0]; - req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0]; - req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0]; - req->nr_cellid = RC.nrrrc[ctxt.module_id]->nr_cellid; - - /*Instruction towards the DU for SRB2 configuration*/ - req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t)); - req->srbs_to_be_setup_length = 1; - f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup; - SRBs[0].srb_id = 2; - SRBs[0].lcid = 2; - - /*Instruction towards the DU for DRB configuration and tunnel creation*/ - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; - memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); - req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)); - req->drbs_to_be_setup_length = 1; - f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup; - LOG_D(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length); - DRBs[0].drb_id = 1; - DRBs[0].rlc_mode = RLC_MODE_AM; - DRBs[0].up_ul_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); - DRBs[0].up_ul_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd; - DRBs[0].up_ul_tnl_length = 1; - DRBs[0].up_dl_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.remote_addr); - DRBs[0].up_dl_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd; - DRBs[0].up_dl_tnl_length = 1; - - itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p); - } - return(0); } + + rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance); + return; } //------------------------------------------------------------------------------ diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h index a03e4df41f..6c8a861f03 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.h +++ b/openair2/RRC/NR/rrc_gNB_NGAP.h @@ -101,7 +101,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( uint8_t xid ); -int +void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( MessageDef *msg_p, const char *msg_name, @@ -189,6 +189,13 @@ nr_rrc_pdcp_config_security( const uint8_t send_security_mode_command ); +struct rrc_gNB_ue_context_s * +rrc_gNB_get_ue_context_from_ngap_ids( + const instance_t instanceP, + const uint16_t ue_initial_idP, + const uint32_t gNB_ue_ngap_idP +); + int rrc_gNB_process_PAGING_IND( MessageDef *msg_p, diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index 9c3b6aada0..ff8149b83f 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -22,32 +22,6 @@ #include "rrc_gNB_radio_bearers.h" #include "oai_asn1.h" -NR_SRB_ToAddMod_t *generateSRB2() { - NR_SRB_ToAddMod_t *SRB2_config = NULL; - - SRB2_config = CALLOC(1, sizeof(*SRB2_config)); - SRB2_config->srb_Identity = 2; - - return SRB2_config; -} - -NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, - NR_SRB_ToAddModList_t *SRB_configList, - uint8_t xid) { - NR_SRB_ToAddModList_t **SRB_configList2 = NULL; - - SRB_configList2 = &ue->SRB_configList2[xid]; - if (*SRB_configList2 == NULL) { - *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); - memset(*SRB_configList2, 0, sizeof(**SRB_configList2)); - NR_SRB_ToAddMod_t *SRB2_config = generateSRB2(); - asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config); - asn1cSeqAdd(&SRB_configList->list, SRB2_config); - } - - return SRB_configList2; -} - NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, const pdu_session_param_t *pduSession, diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.h b/openair2/RRC/NR/rrc_gNB_radio_bearers.h index a686fed767..86ab093ced 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.h +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.h @@ -35,10 +35,6 @@ #define GBR_FLOW (1) #define NONGBR_FLOW (0) -NR_SRB_ToAddMod_t *generateSRB2(void); -NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, - NR_SRB_ToAddModList_t *SRB_configList, - uint8_t xid); NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_ue, uint8_t drb_id, const pdu_session_param_t *pduSession, diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.c b/openair2/SDAP/nr_sdap/nr_sdap_entity.c index 09e80feccf..e9a22eb578 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.c +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c @@ -35,6 +35,8 @@ typedef struct { static nr_sdap_entity_info sdap_info; +instance_t *N3GTPUInst = NULL; + nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager(void); void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu) @@ -216,7 +218,8 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, req->ue_id = ue_id; req->bearer_id = pdusession_id; LOG_D(SDAP, "%s() sending message to gtp size %d\n", __func__, size-offset); - itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); + // very very dirty hack gloabl var N3GTPUInst + itti_send_msg_to_task(TASK_GTPV1_U, *N3GTPUInst, message_p); } else { //nrUE /* * TS 37.324 5.2 Data transfer diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.h b/openair2/SDAP/nr_sdap/nr_sdap_entity.h index e8ed236fd1..4b5303a5b6 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.h +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.h @@ -51,6 +51,9 @@ * the GTP-U Extension Header. Inside the DL PDU SESSION INFORMATION frame. * TS 38.415 Fig. 5.5.2.1-1 */ + +extern instance_t *N3GTPUInst; + typedef struct nr_sdap_dl_hdr_s { uint8_t QFI:6; uint8_t RQI:1; diff --git a/openair2/UTIL/ALG_DS/CMakeLists.txt b/openair2/UTIL/ALG_DS/CMakeLists.txt new file mode 100644 index 0000000000..2b16a1b9c9 --- /dev/null +++ b/openair2/UTIL/ALG_DS/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(DS) + diff --git a/openair2/UTIL/ALG_DS/README.md b/openair2/UTIL/ALG_DS/README.md new file mode 100644 index 0000000000..dd9403dad3 --- /dev/null +++ b/openair2/UTIL/ALG_DS/README.md @@ -0,0 +1,2 @@ +Algorithms and Data Structures in C for common usage + diff --git a/openair2/UTIL/CMakeLists.txt b/openair2/UTIL/CMakeLists.txt new file mode 100644 index 0000000000..7ba707d9da --- /dev/null +++ b/openair2/UTIL/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(ALG_DS) + diff --git a/openair2/UTIL/OSA/README b/openair2/UTIL/OSA/README index 1e54944308..c605ebf379 100644 --- a/openair2/UTIL/OSA/README +++ b/openair2/UTIL/OSA/README @@ -1,7 +1,6 @@ OAISIM Security Algorithms v0.1 Dependencies: -- nettle >= 2.5 - openssl >= 1.0.1 Compilation: diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h index 84cdf4aac3..c175f10c84 100644 --- a/openair2/UTIL/OSA/osa_defs.h +++ b/openair2/UTIL/OSA/osa_defs.h @@ -22,7 +22,7 @@ /*! * \file secu_defs.h * \brief Openair security algorithms functions implementing 3GPP TS 33.401 - * \note HMAC computations are done by nettle/openssl library + * \note HMAC computations are done by openssl library * \author Sebastien ROUX * \date 2013 * \version 0.1 diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c index a685eec729..06c0a3f9b2 100644 --- a/openair2/UTIL/OSA/osa_key_deriver.c +++ b/openair2/UTIL/OSA/osa_key_deriver.c @@ -19,31 +19,15 @@ * contact@openairinterface.org */ -#include +#include "../../../openair3/SECU/kdf.h" -#include +#include +#include #include "osa_defs.h" #include "osa_internal.h" #include "common/utils/LOG/log.h" -static inline -void kdf(const uint8_t *s, const uint32_t s_length, const uint8_t *key, - const uint32_t key_length, uint8_t **out, uint32_t out_length) -{ - struct hmac_sha256_ctx ctx; - - uint8_t *buffer; - - buffer = malloc(sizeof(uint8_t) * out_length); - - hmac_sha256_set_key(&ctx, key_length, key); - hmac_sha256_update(&ctx, s_length, s); - hmac_sha256_digest(&ctx, out_length, buffer); - - *out = buffer; -} - /*! * @brief Derive the keys from key and perform truncate on the generated key to * reduce his size to 128 bits. Definition of the derivation function can @@ -58,10 +42,9 @@ void kdf(const uint8_t *s, const uint32_t s_length, const uint8_t *key, * @param[out] out Pointer to reference where output of KDF will be stored. * NOTE: knas is dynamically allocated by the KDF function */ -int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, - const uint8_t key[32], uint8_t **out) +int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t **out) { - uint8_t string[7]; + uint8_t string[7] = {0}; /* FC */ string[0] = FC_ALG_KEY_DER; @@ -84,7 +67,7 @@ int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, { int i; char payload[6 * sizeof(string) + 1]; - int index = 0; + int index = 0; for (i = 0; i < sizeof(string); i++) index += sprintf(&payload[index], "0x%02x ", string[i]); @@ -93,13 +76,17 @@ int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, } #endif - kdf(string, 7, key, 32, out, 32); + byte_array_t data = {.buf = string, .len = 7}; + if (*out == NULL) { + *out = malloc(sizeof(uint8_t) * 32); + DevAssert(*out != NULL && "Memory exhausted"); + } + kdf(key, data, 32, *out); return 0; } -int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, - const uint8_t key[32], uint8_t **out) +int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t **out) { uint8_t string[7]; @@ -120,17 +107,23 @@ int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, string[5] = 0x00; string[6] = 0x01; - kdf(string, 7, key, 32, out, 32); + byte_array_t data = {.buf = string, .len = 7}; + + if (*out == NULL) { + *out = malloc(sizeof(uint8_t) * 32); + DevAssert(*out != NULL && "Memory exhausted"); + } + kdf(key, data, 32, *out); + // in NR, we use the last 16 bytes, ignoring the first 16 ones - memcpy(*out, *out+16, 16); + memcpy(*out, *out + 16, 16); return 0; } int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) { - uint8_t *out; - uint8_t s[10]; + uint8_t s[10] = {0}; /* FC */ s[0] = NR_FC_ALG_KEY_NG_RAN_STAR_DER; @@ -152,18 +145,17 @@ int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t s[8] = 0x00; s[9] = 0x03; - kdf(s, 10, key, 32, &out, 32); - memcpy(key_ng_ran_star, out, 32); - free(out); + byte_array_t data = {.buf = s, .len = 10}; + const uint32_t len_key = 32; + kdf(key, data, len_key, key_ng_ran_star); return 0; } int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB) { - uint8_t *out; - uint8_t s[5]; + uint8_t s[5] = {0}; /* FC is 0x1c (see 3gpp 33.401 annex A.15) */ s[0] = 0x1c; @@ -176,10 +168,8 @@ int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB) s[3] = 0x00; s[4] = 0x02; - kdf(s, 5, keNB, 32, &out, 32); - - memcpy(skgNB, out, 32); - free(out); + byte_array_t data = {.buf = s, .len = 5}; + kdf(keNB, data, 32, skgNB); return 0; } diff --git a/openair2/UTIL/OSA/osa_stream_eea.c b/openair2/UTIL/OSA/osa_stream_eea.c index 03e95008ca..61f003bc32 100644 --- a/openair2/UTIL/OSA/osa_stream_eea.c +++ b/openair2/UTIL/OSA/osa_stream_eea.c @@ -19,16 +19,15 @@ * contact@openairinterface.org */ +#include #include #include #include #include -#include -#include -#include - #include "common/utils/LOG/log.h" +#include "byte_array.h" +#include "openair3//SECU//aes_128_ctr.h" #include "assertions.h" #include "osa_defs.h" @@ -44,10 +43,13 @@ int stream_encrypt_eea0(stream_cipher_t *stream_cipher, uint8_t **out) DevAssert(stream_cipher != NULL); DevAssert(out != NULL); - LOG_D(OSA, "Entering stream_encrypt_eea0, bits length %u, bearer %u, " - "count %u, direction %s\n", stream_cipher->blength, - stream_cipher->bearer, stream_cipher->count, stream_cipher->direction == SECU_DIRECTION_DOWNLINK ? - "Downlink" : "Uplink"); + LOG_D(OSA, + "Entering stream_encrypt_eea0, bits length %u, bearer %u, " + "count %u, direction %s\n", + stream_cipher->blength, + stream_cipher->bearer, + stream_cipher->count, + stream_cipher->direction == SECU_DIRECTION_DOWNLINK ? "Downlink" : "Uplink"); byte_length = (stream_cipher->blength + 7) >> 3; @@ -59,7 +61,7 @@ int stream_encrypt_eea0(stream_cipher_t *stream_cipher, uint8_t **out) data = *out; } - memcpy (data, stream_cipher->message, byte_length); + memcpy(data, stream_cipher->message, byte_length); return 0; } @@ -67,32 +69,32 @@ int stream_encrypt_eea0(stream_cipher_t *stream_cipher, uint8_t **out) int stream_encrypt_eea1(stream_cipher_t *stream_cipher, uint8_t **out) { osa_snow_3g_context_t snow_3g_context; - int n ; - int i = 0; - uint32_t zero_bit = 0; + int n; + int i = 0; + uint32_t zero_bit = 0; uint32_t *KS; - uint32_t K[4],IV[4]; + uint32_t K[4], IV[4]; DevAssert(stream_cipher != NULL); DevAssert(stream_cipher->key != NULL); DevAssert(stream_cipher->key_length == 16); DevAssert(out != NULL); - n = ( stream_cipher->blength + 31 ) / 32; + n = (stream_cipher->blength + 31) / 32; zero_bit = stream_cipher->blength & 0x7; memset(&snow_3g_context, 0, sizeof(snow_3g_context)); /*Initialisation*/ /* Load the confidentiality key for SNOW 3G initialization as in section 3.4. */ - memcpy(K+3,stream_cipher->key+0,4); /*K[3] = key[0]; we assume - K[3]=key[0]||key[1]||...||key[31] , with key[0] the - * most important bit of key*/ - memcpy(K+2,stream_cipher->key+4,4); /*K[2] = key[1];*/ - memcpy(K+1,stream_cipher->key+8,4); /*K[1] = key[2];*/ - memcpy(K+0,stream_cipher->key+12,4); /*K[0] = key[3]; we assume - K[0]=key[96]||key[97]||...||key[127] , with key[127] the - * least important bit of key*/ + memcpy(K + 3, stream_cipher->key + 0, 4); /*K[3] = key[0]; we assume + K[3]=key[0]||key[1]||...||key[31] , with key[0] the + * most important bit of key*/ + memcpy(K + 2, stream_cipher->key + 4, 4); /*K[2] = key[1];*/ + memcpy(K + 1, stream_cipher->key + 8, 4); /*K[1] = key[2];*/ + memcpy(K + 0, stream_cipher->key + 12, 4); /*K[0] = key[3]; we assume + K[0]=key[96]||key[97]||...||key[127] , with key[127] the + * least important bit of key*/ K[3] = hton_int32(K[3]); K[2] = hton_int32(K[2]); K[1] = hton_int32(K[1]); @@ -106,26 +108,25 @@ int stream_encrypt_eea1(stream_cipher_t *stream_cipher, uint8_t **out) /* Run SNOW 3G algorithm to generate sequence of key stream bits KS*/ osa_snow3g_initialize(K, IV, &snow_3g_context); - KS = (uint32_t *)malloc(4*n); - osa_snow3g_generate_key_stream(n,(uint32_t*)KS, &snow_3g_context); + KS = (uint32_t *)malloc(4 * n); + osa_snow3g_generate_key_stream(n, (uint32_t *)KS, &snow_3g_context); if (zero_bit > 0) { - KS[n - 1] = KS[n - 1] & (uint32_t)(0xFFFFFFFF << (8 - zero_bit)); } - for (i=0; imessage[i] ^= *(((uint8_t*)KS)+i); + for (i = 0; i < n * 4; i++) { + stream_cipher->message[i] ^= *(((uint8_t *)KS) + i); } if (zero_bit > 0) { - int ceil_index = (stream_cipher->blength+7) >> 3; + int ceil_index = (stream_cipher->blength + 7) >> 3; stream_cipher->message[ceil_index - 1] = stream_cipher->message[ceil_index - 1] & (uint8_t)(0xFF << (8 - zero_bit)); } @@ -136,91 +137,32 @@ int stream_encrypt_eea1(stream_cipher_t *stream_cipher, uint8_t **out) int stream_encrypt_eea2(stream_cipher_t *stream_cipher, uint8_t **out) { - uint8_t m[16]; - uint32_t local_count; - - void *ctx; - uint8_t *data = NULL; - - uint32_t zero_bit = 0; - uint32_t byte_length; - DevAssert(stream_cipher != NULL); - DevAssert(out != NULL); - - LOG_D(OSA, "Entering stream_encrypt_eea2, bits length %u, bearer %u, " - "count %u, direction %s\n", stream_cipher->blength, - stream_cipher->bearer, stream_cipher->count, stream_cipher->direction == SECU_DIRECTION_DOWNLINK ? - "Downlink" : "Uplink"); - - zero_bit = stream_cipher->blength & 0x7; - - byte_length = stream_cipher->blength >> 3; - - if (zero_bit > 0) - byte_length += 1; - - ctx = malloc(nettle_aes128.context_size); + DevAssert(stream_cipher->key != NULL); + DevAssert(stream_cipher->key_length == 32); + DevAssert(stream_cipher->bearer < 32); + DevAssert(stream_cipher->direction < 2); + DevAssert(stream_cipher->message != NULL); + DevAssert(stream_cipher->blength > 7); if (*out == NULL) { - /* User provided output buffer */ - data = malloc(byte_length); - *out = data; - } else { - data = *out; + *out = calloc(1, (stream_cipher->blength >> 3) + 1); + DevAssert(*out != NULL && "Memory exhausted"); } - local_count = hton_int32(stream_cipher->count); - - memset(m, 0, sizeof(m)); - memcpy(&m[0], &local_count, 4); - m[4] = ((stream_cipher->bearer & 0x1F) << 3) | - ((stream_cipher->direction & 0x01) << 2); - /* Other bits are 0 */ - -#if defined(SECU_DEBUG) - { - int i; - char payload[6 * byte_length + 1]; - int index = 0; - - for (i = 0; i < byte_length; i++) - index += sprintf(&payload[index], "0x%02x ", stream_cipher->message[i]); - - LOG_D(OSA, "Original message: %s\n", payload); - } -#endif - -#if NETTLE_VERSION_MAJOR < 3 - nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length, - stream_cipher->key); -#else - nettle_aes128.set_encrypt_key(ctx, - stream_cipher->key); -#endif - - nettle_ctr_crypt(ctx, nettle_aes128.encrypt, - nettle_aes128.block_size, m, - byte_length, data, stream_cipher->message); - - if (zero_bit > 0) - data[byte_length - 1] = data[byte_length - 1] & (uint8_t)(0xFF << (8 - zero_bit)); - - free(ctx); - -#if defined(SECU_DEBUG) - { - int i; - char payload[6 * byte_length + 1]; - int index = 0; - - for (i = 0; i < byte_length; i++) - index += sprintf(&payload[index], "0x%02x ", data[i]); - - LOG_D(OSA, "Encrypted message: %s\n", payload); - } -#endif + aes_128_t p = {0}; + memcpy(p.key, stream_cipher->key, stream_cipher->key_length); + p.type = AES_INITIALIZATION_VECTOR_16; + p.iv16.d.count = htonl(stream_cipher->count); + p.iv16.d.bearer = stream_cipher->bearer; + p.iv16.d.direction = stream_cipher->direction; + DevAssert((stream_cipher->blength & 0x07) == 0 && "Cipher length must be multiple of one octet"); + const uint32_t byte_lenght = stream_cipher->blength >> 3; + // Precondition: out must have enough space, at least as much as the input + const size_t len_out = byte_lenght; + byte_array_t msg = {.buf = stream_cipher->message, .len =byte_lenght}; + aes_128_ctr(&p, msg, len_out, *out); return 0; } diff --git a/openair2/UTIL/OSA/osa_stream_eia.c b/openair2/UTIL/OSA/osa_stream_eia.c index 980a4ae3c1..da4fd23e18 100644 --- a/openair2/UTIL/OSA/osa_stream_eia.c +++ b/openair2/UTIL/OSA/osa_stream_eia.c @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#include #include #include #include @@ -26,12 +27,9 @@ #include #include "assertions.h" +#include "common/utils/LOG/log.h" -#include -#include -#include - -#include "common/utils//LOG/log.h" +#include "openair3/SECU/aes_128_cbc_cmac.h" #include "osa_defs.h" #include "osa_snow3g.h" @@ -49,7 +47,7 @@ */ uint64_t OSA_MUL64x(uint64_t V, uint64_t c) { - if ( V & 0x8000000000000000 ) + if (V & 0x8000000000000000) return (V << 1) ^ c; else return V << 1; @@ -65,10 +63,10 @@ function. */ uint64_t OSA_MUL64xPOW(uint64_t V, uint32_t i, uint64_t c) { - if ( i == 0) + if (i == 0) return V; else - return OSA_MUL64x( OSA_MUL64xPOW(V,i-1,c) , c); + return OSA_MUL64x(OSA_MUL64xPOW(V, i - 1, c), c); } /* OSA_MUL64. * Input V: a 64-bit input. @@ -84,33 +82,32 @@ uint64_t OSA_MUL64(uint64_t V, uint64_t P, uint64_t c) uint64_t result = 0; int i = 0; - for ( i=0; i<64; i++) { - if( ( P>>i ) & 0x1 ) - result ^= OSA_MUL64xPOW(V,i,c); + for (i = 0; i < 64; i++) { + if ((P >> i) & 0x1) + result ^= OSA_MUL64xPOW(V, i, c); } return result; } /* osa_mask32bit. -* Input n: an integer in 1-32. -* Output : a 32 bit mask. -* Prepares a 32 bit mask with required number of 1 bits on the MSB side. -*/ + * Input n: an integer in 1-32. + * Output : a 32 bit mask. + * Prepares a 32 bit mask with required number of 1 bits on the MSB side. + */ uint32_t osa_mask32bit(int n) { - uint32_t mask=0x0; + uint32_t mask = 0x0; - if ( n%32 == 0 ) + if (n % 32 == 0) return 0xffffffff; while (n--) - mask = (mask>>1) ^ 0x80000000; + mask = (mask >> 1) ^ 0x80000000; return mask; } - /*! * @brief Create integrity cmac t for a given message. * @param[in] stream_cipher Structure containing various variables to setup encoding @@ -119,29 +116,29 @@ uint32_t osa_mask32bit(int n) int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4]) { osa_snow_3g_context_t snow_3g_context; - uint32_t K[4],IV[4], z[5]; - int i=0,D; - uint32_t MAC_I = 0; - uint64_t EVAL; - uint64_t V; - uint64_t P; - uint64_t Q; - uint64_t c; - uint64_t M_D_2; - int rem_bits; - uint32_t mask = 0; - uint32_t *message; + uint32_t K[4], IV[4], z[5]; + int i = 0, D; + uint32_t MAC_I = 0; + uint64_t EVAL; + uint64_t V; + uint64_t P; + uint64_t Q; + uint64_t c; + uint64_t M_D_2; + int rem_bits; + uint32_t mask = 0; + uint32_t *message; - message = (uint32_t*)stream_cipher->message; /* To operate 32 bit message internally. */ + message = (uint32_t *)stream_cipher->message; /* To operate 32 bit message internally. */ /* Load the Integrity Key for SNOW3G initialization as in section 4.4. */ - memcpy(K+3,stream_cipher->key+0,4); /*K[3] = key[0]; we assume - K[3]=key[0]||key[1]||...||key[31] , with key[0] the - * most important bit of key*/ - memcpy(K+2,stream_cipher->key+4,4); /*K[2] = key[1];*/ - memcpy(K+1,stream_cipher->key+8,4); /*K[1] = key[2];*/ - memcpy(K+0,stream_cipher->key+12,4); /*K[0] = key[3]; we assume - K[0]=key[96]||key[97]||...||key[127] , with key[127] the - * least important bit of key*/ + memcpy(K + 3, stream_cipher->key + 0, 4); /*K[3] = key[0]; we assume + K[3]=key[0]||key[1]||...||key[31] , with key[0] the + * most important bit of key*/ + memcpy(K + 2, stream_cipher->key + 4, 4); /*K[2] = key[1];*/ + memcpy(K + 1, stream_cipher->key + 8, 4); /*K[1] = key[2];*/ + memcpy(K + 0, stream_cipher->key + 12, 4); /*K[0] = key[3]; we assume + K[0]=key[96]||key[97]||...||key[127] , with key[127] the + * least important bit of key*/ K[3] = hton_int32(K[3]); K[2] = hton_int32(K[2]); K[1] = hton_int32(K[1]); @@ -150,45 +147,45 @@ int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4] section 4.4. */ IV[3] = (uint32_t)stream_cipher->count; IV[2] = ((((uint32_t)stream_cipher->bearer) & 0x0000001F) << 27); - IV[1] = (uint32_t)(stream_cipher->count) ^ ( (uint32_t)(stream_cipher->direction) << 31 ) ; + IV[1] = (uint32_t)(stream_cipher->count) ^ ((uint32_t)(stream_cipher->direction) << 31); IV[0] = ((((uint32_t)stream_cipher->bearer) & 0x0000001F) << 27) ^ ((uint32_t)(stream_cipher->direction & 0x00000001) << 15); - //printf ("K:\n"); - //hexprint(K, 16); - //printf ("K[0]:%08X\n",K[0]); - //printf ("K[1]:%08X\n",K[1]); - //printf ("K[2]:%08X\n",K[2]); - //printf ("K[3]:%08X\n",K[3]); + // printf ("K:\n"); + // hexprint(K, 16); + // printf ("K[0]:%08X\n",K[0]); + // printf ("K[1]:%08X\n",K[1]); + // printf ("K[2]:%08X\n",K[2]); + // printf ("K[3]:%08X\n",K[3]); - //printf ("IV:\n"); - //hexprint(IV, 16); - //printf ("IV[0]:%08X\n",IV[0]); - //printf ("IV[1]:%08X\n",IV[1]); - //printf ("IV[2]:%08X\n",IV[2]); - //printf ("IV[3]:%08X\n",IV[3]); + // printf ("IV:\n"); + // hexprint(IV, 16); + // printf ("IV[0]:%08X\n",IV[0]); + // printf ("IV[1]:%08X\n",IV[1]); + // printf ("IV[2]:%08X\n",IV[2]); + // printf ("IV[3]:%08X\n",IV[3]); z[0] = z[1] = z[2] = z[3] = z[4] = 0; /* Run SNOW 3G to produce 5 keystream words z_1, z_2, z_3, z_4 and z_5. */ osa_snow3g_initialize(K, IV, &snow_3g_context); osa_snow3g_generate_key_stream(5, z, &snow_3g_context); - //printf ("z[0]:%08X\n",z[0]); - //printf ("z[1]:%08X\n",z[1]); - //printf ("z[2]:%08X\n",z[2]); - //printf ("z[3]:%08X\n",z[3]); - //printf ("z[4]:%08X\n",z[4]); + // printf ("z[0]:%08X\n",z[0]); + // printf ("z[1]:%08X\n",z[1]); + // printf ("z[2]:%08X\n",z[2]); + // printf ("z[3]:%08X\n",z[3]); + // printf ("z[4]:%08X\n",z[4]); P = ((uint64_t)z[0] << 32) | (uint64_t)z[1]; Q = ((uint64_t)z[2] << 32) | (uint64_t)z[3]; - //printf ("P:%16lX\n",P); - //printf ("Q:%16lX\n",Q); + // printf ("P:%16lX\n",P); + // printf ("Q:%16lX\n",Q); /* Calculation */ - D = ceil( stream_cipher->blength / 64.0 ) + 1; - //printf ("D:%d\n",D); + D = ceil(stream_cipher->blength / 64.0) + 1; + // printf ("D:%d\n",D); EVAL = 0; c = 0x1b; /* for 0 <= i <= D-3 */ - for (i=0; i 32) { - M_D_2 = ( (uint64_t) hton_int32(message[2*(D-2)]) << 32 ) | - (uint64_t) (hton_int32(message[2*(D-2)+1]) & mask); + M_D_2 = ((uint64_t)hton_int32(message[2 * (D - 2)]) << 32) | (uint64_t)(hton_int32(message[2 * (D - 2) + 1]) & mask); } else { - M_D_2 = ( (uint64_t) hton_int32(message[2*(D-2)]) & mask) << 32 ; + M_D_2 = ((uint64_t)hton_int32(message[2 * (D - 2)]) & mask) << 32; } V = EVAL ^ M_D_2; - EVAL = OSA_MUL64(V,P,c); + EVAL = OSA_MUL64(V, P, c); /* for D-1 */ EVAL ^= stream_cipher->blength; /* Multiply by Q */ - EVAL = OSA_MUL64(EVAL,Q,c); + EVAL = OSA_MUL64(EVAL, Q, c); MAC_I = (uint32_t)(EVAL >> 32) ^ z[4]; - //printf ("MAC_I:%16X\n",MAC_I); + // printf ("MAC_I:%16X\n",MAC_I); MAC_I = hton_int32(MAC_I); memcpy(out, &MAC_I, 4); return 0; @@ -221,65 +217,28 @@ int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4] int stream_compute_integrity_eia2(stream_cipher_t *stream_cipher, uint8_t out[4]) { - uint8_t *m; - uint32_t local_count; - size_t size = 4; - - uint8_t data[16]; - - CMAC_CTX *cmac_ctx; - - uint32_t zero_bit = 0; - uint32_t m_length; - DevAssert(stream_cipher != NULL); - DevAssert(stream_cipher->key != NULL); + ; + DevAssert((stream_cipher->blength & 0x7) == 0); + DevAssert(stream_cipher->key_length == 16 && "k_iv.key and stream_cipher mismatch"); + DevAssert(stream_cipher->bearer < 32); + DevAssert(stream_cipher->direction < 2); - memset(data, 0, 16); + aes_128_t k_iv = {0}; + memcpy(k_iv.key, stream_cipher->key, sizeof(k_iv.key)); + k_iv.type = AES_INITIALIZATION_VECTOR_8; - zero_bit = stream_cipher->blength & 0x7; + k_iv.iv8.d.bearer = stream_cipher->bearer; + k_iv.iv8.d.direction = stream_cipher->direction; + k_iv.iv8.d.count = htonl(stream_cipher->count); - m_length = stream_cipher->blength >> 3; + const size_t m_length = stream_cipher->blength >> 3; - if (zero_bit > 0) - m_length += 1; - - local_count = hton_int32(stream_cipher->count); - - m = calloc(m_length + 8, sizeof(uint8_t)); - - memcpy(&m[0], &local_count, 4); - m[4] = ((stream_cipher->bearer & 0x1F) << 3) | ((stream_cipher->direction & 0x01) << 2); - - memcpy(&m[8], stream_cipher->message, m_length); - -#if defined(SECU_DEBUG) - { - int i; - char payload[6 * sizeof(m) + 1]; - int index = 0; - LOG_T(OSA, "Blength: %u, Zero bits: %u\n", - stream_cipher->blength, zero_bit); - - for (i = 0; i < sizeof(m); i++) - index += sprintf(&payload[index], "0x%02x ", m[i]); - - LOG_D(OSA, "Payload: %s\n", payload); - } -#endif - - cmac_ctx = CMAC_CTX_new(); - - CMAC_Init(cmac_ctx, stream_cipher->key, stream_cipher->key_length, EVP_aes_128_cbc(), NULL); - CMAC_Update(cmac_ctx, m, m_length + 8); - - CMAC_Final(cmac_ctx, data, &size); - - CMAC_CTX_free(cmac_ctx); - - memcpy(out, data, 4); - free(m); + uint8_t result[16] = {0}; + byte_array_t msg = {.len = m_length, .buf = stream_cipher->message }; + aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result); + memcpy(out, result, 4); return 0; } @@ -307,10 +266,18 @@ int stream_check_integrity(uint8_t algorithm, stream_cipher_t *stream_cipher, ui } if (memcmp(result, expected, 4) != 0) { - LOG_E(OSA, "Mismatch found in integrity for algorithm %u,\n" + LOG_E(OSA, + "Mismatch found in integrity for algorithm %u,\n" "\tgot %02x.%02x.%02x.%02x, expecting %02x.%02x.%02x.%02x\n", - algorithm, result[0], result[1], result[2], result[3], expected[0], - expected[1], expected[2], expected[3]); + algorithm, + result[0], + result[1], + result[2], + result[3], + expected[0], + expected[1], + expected[2], + expected[3]); return -1; } } diff --git a/openair3/DOCS/Latex/EPC/EPC.pdf b/openair3/DOCS/Latex/EPC/EPC.pdf deleted file mode 100644 index 598796e128..0000000000 Binary files a/openair3/DOCS/Latex/EPC/EPC.pdf and /dev/null differ diff --git a/openair3/DOCS/Latex/EPC/EPC.tex b/openair3/DOCS/Latex/EPC/EPC.tex index f1df0a6a37..97e4f52565 100644 --- a/openair3/DOCS/Latex/EPC/EPC.tex +++ b/openair3/DOCS/Latex/EPC/EPC.tex @@ -544,7 +544,6 @@ Before compiling the core EPC, some packages should be installed on the platform \item flex and bison \item openssl-dev \item asn1c (see section \ref{sec:asn1c}) - \item libnettle (see section \ref{sec:libnettle}) \item freediameter (see section \ref{sec:freediameter}) and gnutls 3.1.0 (see section \ref{sec:gnutls}) \end{itemize} @@ -562,28 +561,6 @@ openssl-dev -y \subsection{ASN1c} \label{sec:asn1c} -\subsection{libnettle} -\label{sec:libnettle} - -The nettle library is used by freediameter for certificate encryption and by core -EPC for key derivation. -\begin{lstlisting} -wget ftp://ftp.lysator.liu.se/pub/security/lsh/nettle-2.5.tar.gz -gunzip nettle-2.5.tar.gz -tar -xvf nettle-2.5.tar -cd nettle-2.5/ -./configure --disable-openssl --enable-shared -make -make check -sudo make install -\end{lstlisting} -The commands provided above will download the required packages sources, configure -and install them on the system. -Note that any packages which is not in the Ubuntu repository is installed by default -in /usr/local instead of /usr. -This behaviour can be overriden at configuration time by providing --prefix=/usr to -the configuration script (configure). - \subsection{gnutls} \label{sec:gnutls} diff --git a/openair3/MME_APP/mme_app.c b/openair3/MME_APP/mme_app.c index 2c1d524c15..43a5df2ac8 100644 --- a/openair3/MME_APP/mme_app.c +++ b/openair3/MME_APP/mme_app.c @@ -40,7 +40,8 @@ # include "intertask_interface.h" # include "s1ap_eNB.h" -#include "sctp_eNB_task.h" +# include "sctp_eNB_task.h" +# include "openair3/ocp-gtpu/gtp_itf.h" # include "x2ap_eNB.h" # include "x2ap_messages_types.h" diff --git a/openair3/NAS/COMMON/nr_common.c b/openair3/NAS/COMMON/nr_common.c index 736d75f6cc..590ccf65ae 100644 --- a/openair3/NAS/COMMON/nr_common.c +++ b/openair3/NAS/COMMON/nr_common.c @@ -23,6 +23,7 @@ #include #include +#include void servingNetworkName(uint8_t *msg, char * imsiStr, int nmc_size) { //SNN-network-identifier in TS 24.501 @@ -59,8 +60,12 @@ int resToresStar(uint8_t *msg, uicc_t* uicc) { uint8_t ckik[sizeof(uicc->ck) +sizeof(uicc->ik)]; memcpy(ckik, uicc->ck, sizeof(uicc->ck)); memcpy(ckik+sizeof(uicc->ck),uicc->ik, sizeof(uicc->ik)); - uint8_t out[32]; - kdf(S, ptr-S, ckik, 32, out, sizeof(out)); + uint8_t out[32] = {0}; + assert(ptr-S == 32); + //kdf(S, ptr-S, ckik, 32, out, sizeof(out)); + byte_array_t data = {.buf = ckik, .len = 32}; + kdf(S, data, 32, out); + memcpy(msg, out+16, 16); return 16; } diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 8a600e0cf9..b24359a232 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -37,6 +37,7 @@ #include "nr_nas_msg_sim.h" #include "aka_functions.h" #include "secu_defs.h" +#include "kdf.h" #include "PduSessionEstablishRequest.h" #include "PduSessionEstablishmentAccept.h" #include "intertask_interface.h" @@ -188,18 +189,20 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16 oldS[33] = 0x08; - uint8_t key[32]; + uint8_t key[32] = {0}; memcpy(&key[0], ck, 16); memcpy(&key[16], ik, 16); //KEY - uint8_t out[32]; - kdf(key, 32, S, 31 + netNamesize, out, 32); - for (int i = 0; i < 16; i++) - output[i] = out[16 + i]; + uint8_t out[32] = {0}; + + byte_array_t data = {.buf = S, .len = 31 + netNamesize}; + kdf(key, data, 32, out); + + memcpy(output, out + 16, 16); } void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32], uicc_t *uicc) { uint8_t S[100]={0}; - uint8_t key[32]; + uint8_t key[32] = {0}; memcpy(&key[0], ck, 16); memcpy(&key[16], ik, 16); //KEY @@ -213,7 +216,9 @@ void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[ } S[9 + netNamesize] = 0x00; S[10 + netNamesize] = 0x06; - kdf(key, 32, S, 11 + netNamesize, kausf, 32); + + byte_array_t data = {.buf = S, .len = 11 + netNamesize}; + kdf(key, data, 32, kausf); } void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], uicc_t *uicc) { @@ -223,12 +228,14 @@ void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], uicc_t *uicc) { int netNamesize = strlen((char*)S+1); S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8); S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff); - kdf(kausf, 32, S, 3 + netNamesize, kseaf, 32); + + byte_array_t data = {.buf = S , .len = 3 + netNamesize}; + kdf(kausf, data, 32, kseaf); } void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba, uicc_t* uicc) { int imsiLen = strlen(uicc->imsiStr); - uint8_t S[100]; + uint8_t S[100] = {0}; S[0] = 0x6D; //FC = 0x6D memcpy(&S[1], uicc->imsiStr, imsiLen ); S[1 + imsiLen] = (uint8_t)((imsiLen & 0xff00) >> 8); @@ -237,12 +244,14 @@ void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba, uicc_t* uicc) { S[4 + imsiLen] = (abba & 0xff00) >> 8; S[5 + imsiLen] = 0x00; S[6 + imsiLen] = 0x02; - kdf(kseaf, 32, S, 7 + imsiLen, kamf, 32); + + byte_array_t data = {.buf = S, .len = 7 + imsiLen}; + kdf(kseaf, data, 32, kamf); } //------------------------------------------------------------------------------ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t kamf[32], uint8_t *knas_int) { - uint8_t S[20]; + uint8_t S[20] = {0}; uint8_t out[32] = { 0 }; S[0] = 0x69; //FC S[1] = (uint8_t)(nas_alg_type & 0xFF); @@ -251,19 +260,20 @@ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t S[4] = nas_alg_id; S[5] = 0x00; S[6] = 0x01; - kdf(kamf, 32, S, 7, out, 32); - for (int i = 0; i < 16; i++) - knas_int[i] = out[16 + i]; + + byte_array_t data = {.buf = S, .len = 7}; + kdf(kamf, data, 32, out); + + memcpy(knas_int, out+16, 16); } void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){ /* Compute the KDF input parameter * S = FC(0x6E) || UL NAS Count || 0x00 0x04 || 0x01 || 0x00 0x01 */ - uint8_t input[32]; + uint8_t input[32] = {0}; // uint16_t length = 4; // int offset = 0; - uint8_t out[32] = { 0 }; LOG_TRACE(INFO, "%s with count= %d", __FUNCTION__, count); memset(input, 0, 32); @@ -282,9 +292,9 @@ void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){ input[8] = 0; input[9] = 1; - kdf(kamf, 32, input, 10, out, 32); - for (int i = 0; i < 32; i++) - kgnb[i] = out[i]; + byte_array_t data = {.buf = input, .len = 10}; + kdf(kamf, data, 32, kgnb); + printf("kgnb : "); for(int pp=0;pp<32;pp++) printf("%02x ",kgnb[pp]); diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index a387580b60..55b269f413 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -67,6 +67,7 @@ Description Defines the authentication EMM procedure executed by the #include "usim_api.h" #include "secu_defs.h" +#include "kdf.h" #include "Authentication.h" #include "executables/lte-softmodem.h" @@ -982,14 +983,10 @@ static int _authentication_kasme(const OctetString *autn, input_s[4],input_s[5],input_s[6],input_s[7], input_s[8],input_s[9],input_s[10],input_s[11], input_s[12],input_s[13]); - /* TODO !!! Compute the Kasme key */ - // todo_hmac_256(key, input_s, kasme->value); - kdf(key, - ck->length + ik->length , /*key_length*/ - input_s, - offset, - kasme->value, - kasme->length); + + assert(ck->length + ik->length == 32); + byte_array_t data = {.len = offset, .buf = input_s}; + kdf(key, data, kasme->length, kasme->value); LOG_TRACE(INFO,"EMM-PROC KASME (l=%d)%s", kasme->length, diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index fd3332669b..3386499663 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -63,6 +63,7 @@ Description Defines the security mode control EMM procedure executed by the # include "assertions.h" #include "secu_defs.h" +#include "kdf.h" #include "SecurityModeControl.h" #if defined(NAS_BUILT_IN_UE) @@ -484,7 +485,9 @@ static int _security_kenb(const OctetString *kasme, OctetString *kenb, input[5] = 0; input[6] = 4; - kdf(kasme->value, 32, input, 7, kenb->value, 32); + byte_array_t data = {.len = 7, .buf = input}; + kdf(kasme->value, data, 32, kenb->value); + kenb->length = 32; return (RETURNok); } @@ -536,8 +539,12 @@ static int _security_kdf(const OctetString *kasme, OctetString *key, input[5] = 0x00; input[6] = 0x01; + assert(kasme->length == 32); + byte_array_t data = {.len = 7, .buf=input}; /* Compute the derived key */ - kdf(kasme->value, kasme->length, input, 7, output, 32); + kdf(kasme->value, data, 32, output); + + memcpy(key->value, &output[31 - key->length + 1], key->length); return (RETURNok); } diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index ab2503f1d5..47f4b8445d 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -48,10 +48,7 @@ #include "conversions.h" #include "NGAP_NonDynamic5QIDescriptor.h" -static -int ngap_gNB_handle_ng_setup_response(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu); +static int ngap_gNB_handle_ng_setup_response(uint32_t ssoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu); static int ngap_gNB_handle_ng_setup_failure(uint32_t assoc_id, uint32_t stream, @@ -188,8 +185,7 @@ void ngap_handle_ng_setup_message(ngap_gNB_amf_data_t *amf_desc_p, int sctp_shut /* If there are no more associated AMF, inform gNB app */ if (amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb == 0) { - MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_DEREGISTERED_GNB_IND); + MessageDef *message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_DEREGISTERED_GNB_IND); NGAP_DEREGISTERED_GNB_IND(message_p).nb_amf = 0; itti_send_msg_to_task(TASK_GNB_APP, amf_desc_p->ngap_gNB_instance->instance, message_p); } @@ -206,8 +202,7 @@ void ngap_handle_ng_setup_message(ngap_gNB_amf_data_t *amf_desc_p, int sctp_shut /* If there are no more pending messages, inform gNB app */ if (amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb == 0) { - MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_REGISTER_GNB_CNF); + MessageDef *message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_REGISTER_GNB_CNF); NGAP_REGISTER_GNB_CNF(message_p).nb_amf = amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb; itti_send_msg_to_task(TASK_GNB_APP, amf_desc_p->ngap_gNB_instance->instance, message_p); } @@ -838,7 +833,6 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, int i; ngap_gNB_amf_data_t *amf_desc_p = NULL; ngap_gNB_ue_context_t *ue_desc_p = NULL; - MessageDef *message_p = NULL; NGAP_InitialContextSetupRequest_t *container; NGAP_InitialContextSetupRequestIEs_t *ie; NGAP_RAN_UE_NGAP_ID_t ran_ue_ngap_id; @@ -890,20 +884,21 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, ue_desc_p->rx_stream = stream; ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id; - message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_INITIAL_CONTEXT_SETUP_REQ); - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; + MessageDef *message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_INITIAL_CONTEXT_SETUP_REQ); + ngap_initial_context_setup_req_t * msg=&NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p); + msg->ue_initial_id = ue_desc_p->ue_initial_id; ue_desc_p->ue_initial_id = 0; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).gNB_ue_ngap_id = ue_desc_p->gNB_ue_ngap_id; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).amf_ue_ngap_id = ue_desc_p->amf_ue_ngap_id; + msg->gNB_ue_ngap_id = ue_desc_p->gNB_ue_ngap_id; + msg->amf_ue_ngap_id = ue_desc_p->amf_ue_ngap_id; /* id-UEAggregateMaximumBitRate */ NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate, false); if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitRate.uEAggregateMaximumBitRateUL), - &(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_ul)); + &(msg->ue_ambr.br_ul)); asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitRate.uEAggregateMaximumBitRateDL), - &(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_dl)); + &(msg->ue_ambr.br_dl)); } else { NGAP_ERROR("could not found NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate\n"); } @@ -914,12 +909,12 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, NGAP_ProtocolIE_ID_id_GUAMI, true); if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - TBCD_TO_MCC_MNC(&ie->value.choice.GUAMI.pLMNIdentity, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.mcc, - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.mnc, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.mnc_len); + TBCD_TO_MCC_MNC(&ie->value.choice.GUAMI.pLMNIdentity, msg->guami.mcc, + msg->guami.mnc, msg->guami.mnc_len); - OCTET_STRING_TO_INT8(&ie->value.choice.GUAMI.aMFRegionID, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.amf_region_id); - OCTET_STRING_TO_INT16(&ie->value.choice.GUAMI.aMFSetID, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.amf_set_id); - OCTET_STRING_TO_INT8(&ie->value.choice.GUAMI.aMFPointer, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.amf_pointer); + OCTET_STRING_TO_INT8(&ie->value.choice.GUAMI.aMFRegionID, msg->guami.amf_region_id); + OCTET_STRING_TO_INT16(&ie->value.choice.GUAMI.aMFSetID, msg->guami.amf_set_id); + OCTET_STRING_TO_INT8(&ie->value.choice.GUAMI.aMFPointer, msg->guami.amf_pointer); } else {/* ie != NULL */ return -1; } @@ -928,7 +923,7 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtReq, false); if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_of_pdusessions = + msg->nb_of_pdusessions = ie->value.choice.PDUSessionResourceSetupListCxtReq.list.count; for (i = 0; i < ie->value.choice.PDUSessionResourceSetupListCxtReq.list.count; i++) { @@ -938,19 +933,19 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, NGAP_PDUSessionResourceSetupRequestTransferIEs_t *pdusessionTransfer_ies = NULL; item_p = (NGAP_PDUSessionResourceSetupItemCxtReq_t *)ie->value.choice.PDUSessionResourceSetupListCxtReq.list.array[i]; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].pdusession_id = item_p->pDUSessionID; + msg->pdusession_param[i].pdusession_id = item_p->pDUSessionID; if (item_p->nAS_PDU != NULL) { /* Only copy NAS pdu if present */ - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.length = item_p->nAS_PDU->size; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.buffer = + msg->pdusession_param[i].nas_pdu.length = item_p->nAS_PDU->size; + msg->pdusession_param[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU->size); - memcpy(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.buffer, + memcpy(msg->pdusession_param[i].nas_pdu.buffer, item_p->nAS_PDU->buf, item_p->nAS_PDU->size); NGAP_DEBUG("Received NAS message with the PDUSESSION setup procedure\n"); } else { - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.length = 0; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.buffer = NULL; + msg->pdusession_param[i].nas_pdu.length = 0; + msg->pdusession_param[i].nas_pdu.buffer = NULL; } @@ -979,14 +974,14 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, gTPTunnel_p = pdusessionTransfer_ies->value.choice.UPTransportLayerInformation.choice.gTPTunnel; /* Set the transport layer address */ - memcpy(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].upf_addr.buffer, + memcpy(msg->pdusession_param[i].upf_addr.buffer, gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size); - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].upf_addr.length = + msg->pdusession_param[i].upf_addr.length = gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused; /* GTP tunnel endpoint ID */ - OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].gtp_teid); + OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, msg->pdusession_param[i].gtp_teid); } break; @@ -1001,7 +996,7 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, /* mandatory PDUSessionType */ case NGAP_ProtocolIE_ID_id_PDUSessionType: - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; + msg->pdusession_param[i].upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; break; /* optional SecurityIndication */ @@ -1021,25 +1016,25 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count > 0); DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count <= NGAP_maxnoofQosFlows); - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; + msg->pdusession_param[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; for(int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; qosIdx++) { qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.array[qosIdx]; /* Set the QOS informations */ - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; + msg->pdusession_param[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){ if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){ - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].fiveQI = + msg->pdusession_param[i].qos[qosIdx].fiveQI = (uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI; } } - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.priority_level = + msg->pdusession_param[i].qos[qosIdx].allocation_retention_priority.priority_level = qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability = + msg->pdusession_param[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability = qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionCapability; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability = + msg->pdusession_param[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability = qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionVulnerability; } } @@ -1051,14 +1046,14 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, break; default: - NGAP_ERROR("could not found protocolIEs id %ld\n", pdusessionTransfer_ies->id); + NGAP_ERROR("Not found protocolIEs id %ld\n", pdusessionTransfer_ies->id); return -1; } } } /* for i... */ } else {/* ie != NULL */ - NGAP_ERROR("could not found NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtReq\n"); + NGAP_ERROR("Not found NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtReq\n"); } /* id-AllowedNSSAI */ @@ -1075,35 +1070,35 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, if (ie == NULL) { NGAP_WARN("AllowedNSSAI not present, forging 2 NSSAI\n"); - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_allowed_nssais = 2; + msg->nb_allowed_nssais = 2; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sST = 01; + msg->allowed_nssai[0].sST = 01; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sD_flag = 1; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sD[0] = 01; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sD[1] = 02; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sD[2] = 03; + msg->allowed_nssai[0].sD_flag = 1; + msg->allowed_nssai[0].sD[0] = 01; + msg->allowed_nssai[0].sD[1] = 02; + msg->allowed_nssai[0].sD[2] = 03; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sST = 01; + msg->allowed_nssai[1].sST = 01; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD_flag = 1; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[0] = 00;//11; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[1] = 00;//22; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[2] = 01;//33; + msg->allowed_nssai[1].sD_flag = 1; + msg->allowed_nssai[1].sD[0] = 00;//11; + msg->allowed_nssai[1].sD[1] = 00;//22; + msg->allowed_nssai[1].sD[2] = 01;//33; } else { NGAP_INFO("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count); - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_allowed_nssais = ie->value.choice.AllowedNSSAI.list.count; + msg->nb_allowed_nssais = ie->value.choice.AllowedNSSAI.list.count; for(i = 0; i < ie->value.choice.AllowedNSSAI.list.count; i++) { allow_nssai_item_p = ie->value.choice.AllowedNSSAI.list.array[i]; - OCTET_STRING_TO_INT8(&allow_nssai_item_p->s_NSSAI.sST, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sST); + OCTET_STRING_TO_INT8(&allow_nssai_item_p->s_NSSAI.sST, msg->allowed_nssai[i].sST); if(allow_nssai_item_p->s_NSSAI.sD != NULL) { - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD_flag = 1; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD[0] = allow_nssai_item_p->s_NSSAI.sD->buf[0]; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD[1] = allow_nssai_item_p->s_NSSAI.sD->buf[1]; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD[2] = allow_nssai_item_p->s_NSSAI.sD->buf[2]; + msg->allowed_nssai[i].sD_flag = 1; + msg->allowed_nssai[i].sD[0] = allow_nssai_item_p->s_NSSAI.sD->buf[0]; + msg->allowed_nssai[i].sD[1] = allow_nssai_item_p->s_NSSAI.sD->buf[1]; + msg->allowed_nssai[i].sD[2] = allow_nssai_item_p->s_NSSAI.sD->buf[2]; } } } @@ -1116,13 +1111,13 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, NGAP_ProtocolIE_ID_id_UESecurityCapabilities, true); if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.nRencryption_algorithms = + msg->security_capabilities.nRencryption_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.nRencryptionAlgorithms); - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.nRintegrity_algorithms = + msg->security_capabilities.nRintegrity_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.nRintegrityProtectionAlgorithms); - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.eUTRAencryption_algorithms = + msg->security_capabilities.eUTRAencryption_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.eUTRAencryptionAlgorithms); - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.eUTRAintegrity_algorithms = + msg->security_capabilities.eUTRAintegrity_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.eUTRAintegrityProtectionAlgorithms); } else {/* ie != NULL */ return -1; @@ -1133,7 +1128,7 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, NGAP_ProtocolIE_ID_id_SecurityKey, true); if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - memcpy(&NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key, + memcpy(&msg->security_key, ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); } else {/* ie != NULL */ @@ -1148,11 +1143,11 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, NGAP_MobilityRestrictionList_t *mobility_rest_list_p = NULL; mobility_rest_list_p = &ie->value.choice.MobilityRestrictionList; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).mobility_restriction_flag = 1; + msg->mobility_restriction_flag = 1; TBCD_TO_MCC_MNC(&mobility_rest_list_p->servingPLMN, - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).mobility_restriction.serving_plmn.mcc, - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).mobility_restriction.serving_plmn.mnc, - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).mobility_restriction.serving_plmn.mnc_digit_length); + msg->mobility_restriction.serving_plmn.mcc, + msg->mobility_restriction.serving_plmn.mnc, + msg->mobility_restriction.serving_plmn.mnc_digit_length); } @@ -1162,10 +1157,10 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ if(ie->value.choice.NAS_PDU.size > 0) { - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nas_pdu_flag = 1; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nas_pdu.length = ie->value.choice.NAS_PDU.size; - NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nas_pdu.buffer = malloc(sizeof(uint8_t) * ie->value.choice.NAS_PDU.size); - memcpy(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nas_pdu.buffer, + msg->nas_pdu_flag = 1; + msg->nas_pdu.length = ie->value.choice.NAS_PDU.size; + msg->nas_pdu.buffer = malloc(sizeof(uint8_t) * ie->value.choice.NAS_PDU.size); + memcpy(msg->nas_pdu.buffer, ie->value.choice.NAS_PDU.buf, ie->value.choice.NAS_PDU.size); } } @@ -1259,7 +1254,6 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, NGAP_RAN_UE_NGAP_ID_t ran_ue_ngap_id; ngap_gNB_amf_data_t *amf_desc_p = NULL; ngap_gNB_ue_context_t *ue_desc_p = NULL; - MessageDef *message_p = NULL; NGAP_PDUSessionResourceSetupRequest_t *container; NGAP_PDUSessionResourceSetupRequestIEs_t *ie; DevAssert(pdu != NULL); @@ -1313,17 +1307,26 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, (uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id); } - message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_SETUP_REQ); - NGAP_PDUSESSION_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; + MessageDef * message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_SETUP_REQ); + ngap_pdusession_setup_req_t * msg=&NGAP_PDUSESSION_SETUP_REQ(message_p); + msg->ue_initial_id = ue_desc_p->ue_initial_id; ue_desc_p->ue_initial_id = 0; - NGAP_PDUSESSION_SETUP_REQ(message_p).gNB_ue_ngap_id = ue_desc_p->gNB_ue_ngap_id; - NGAP_PDUSESSION_SETUP_REQ(message_p).amf_ue_ngap_id = ue_desc_p->amf_ue_ngap_id; + msg->gNB_ue_ngap_id = ue_desc_p->gNB_ue_ngap_id; + msg->amf_ue_ngap_id = ue_desc_p->amf_ue_ngap_id; + + /* UE Aggregated Maximum Bitrate */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate, true); + asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitRate.uEAggregateMaximumBitRateUL), + &msg->ueAggMaxBitRateUplink); + asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitRate.uEAggregateMaximumBitRateDL), + &msg->ueAggMaxBitRateDownlink); NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSUReq, true); if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - NGAP_PDUSESSION_SETUP_REQ(message_p).nb_pdusessions_tosetup = + msg->nb_pdusessions_tosetup = ie->value.choice.PDUSessionResourceSetupListSUReq.list.count; for (int i = 0; i < ie->value.choice.PDUSessionResourceSetupListSUReq.list.count; i++) { @@ -1332,20 +1335,29 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, NGAP_PDUSessionResourceSetupRequestTransfer_t *pdusessionTransfer_p = NULL; NGAP_PDUSessionResourceSetupRequestTransferIEs_t *pdusessionTransfer_ies = NULL; + // PDU session ID item_p = (NGAP_PDUSessionResourceSetupItemSUReq_t *)ie->value.choice.PDUSessionResourceSetupListSUReq.list.array[i]; - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].pdusession_id = item_p->pDUSessionID; + msg->pdusession_setup_params[i].pdusession_id = item_p->pDUSessionID; + // S-NSSAI + OCTET_STRING_TO_INT8(&item_p->s_NSSAI.sST, msg->allowed_nssai[i].sST); + if(item_p->s_NSSAI.sD != NULL) { + msg->allowed_nssai[i].sD_flag = 1; + msg->allowed_nssai[i].sD[0] = item_p->s_NSSAI.sD->buf[0]; + msg->allowed_nssai[i].sD[1] = item_p->s_NSSAI.sD->buf[1]; + msg->allowed_nssai[i].sD[2] = item_p->s_NSSAI.sD->buf[2]; + } // check for the NAS PDU if (item_p->pDUSessionNAS_PDU->size > 0 ) { - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.length = item_p->pDUSessionNAS_PDU->size; - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionNAS_PDU->size); - memcpy(NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.buffer, + msg->pdusession_setup_params[i].nas_pdu.length = item_p->pDUSessionNAS_PDU->size; + msg->pdusession_setup_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionNAS_PDU->size); + memcpy(msg->pdusession_setup_params[i].nas_pdu.buffer, item_p->pDUSessionNAS_PDU->buf, item_p->pDUSessionNAS_PDU->size); - // NGAP_INFO("received a NAS PDU with size %d (%02x.%02x)\n",NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.length, item_p->nAS_PDU.buf[0], item_p->nAS_PDU.buf[1]); + // NGAP_INFO("received a NAS PDU with size %d (%02x.%02x)\n",msg->pdusession_setup_params[i].nas_pdu.length, item_p->nAS_PDU.buf[0], item_p->nAS_PDU.buf[1]); } else { - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.length = 0; - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.buffer = NULL; + msg->pdusession_setup_params[i].nas_pdu.length = 0; + msg->pdusession_setup_params[i].nas_pdu.buffer = NULL; NGAP_WARN("NAS PDU is not provided, generate a PDUSESSION_SETUP Failure (TBD) back to AMF \n"); } @@ -1374,10 +1386,10 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, NGAP_GTPTunnel_t *gTPTunnel_p; gTPTunnel_p = pdusessionTransfer_ies->value.choice.UPTransportLayerInformation.choice.gTPTunnel; /* The transport layer address for the IP packets */ - OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].gtp_teid); - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].upf_addr.length = + OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, msg->pdusession_setup_params[i].gtp_teid); + msg->pdusession_setup_params[i].upf_addr.length = gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused; - memcpy(NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].upf_addr.buffer , + memcpy(msg->pdusession_setup_params[i].upf_addr.buffer , gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size); } break; @@ -1392,7 +1404,7 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, /* mandatory PDUSessionType */ case NGAP_ProtocolIE_ID_id_PDUSessionType: - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; + msg->pdusession_setup_params[i].upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; break; /* optional SecurityIndication */ @@ -1412,24 +1424,28 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count > 0); DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count <= NGAP_maxnoofQosFlows); - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; + msg->pdusession_setup_params[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; for(int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; qosIdx++){ qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.array[qosIdx]; /* Set the QOS informations */ - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; + msg->pdusession_setup_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){ + msg->pdusession_setup_params[i].qos[qosIdx].fiveQI_type = non_dynamic; if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){ - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].fiveQI = + msg->pdusession_setup_params[i].qos[qosIdx].fiveQI = (uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI; } + } else if (qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_dynamic5QI) + { + msg->pdusession_setup_params[i].qos[qosIdx].fiveQI_type = dynamic; } - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.priority_level = + msg->pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.priority_level = qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP; - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability = + msg->pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability = qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionCapability; - NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability = + msg->pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability = qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionVulnerability; } } @@ -1461,7 +1477,6 @@ int ngap_gNB_handle_paging(uint32_t assoc_id, ngap_gNB_amf_data_t *amf_desc_p = NULL; ngap_gNB_instance_t *ngap_gNB_instance = NULL; - MessageDef *message_p = NULL; NGAP_Paging_t *container; NGAP_PagingIEs_t *ie; DevAssert(pdu != NULL); @@ -1490,42 +1505,44 @@ int ngap_gNB_handle_paging(uint32_t assoc_id, return -1; } - message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PAGING_IND); + MessageDef *message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PAGING_IND); + ngap_paging_ind_t * msg=&NGAP_PAGING_IND(message_p); + /* convert NGAP_PagingIEs_t to ngap_paging_ind_t */ /* id-UEIdentityIndexValue : convert UE Identity Index value */ NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container, NGAP_ProtocolIE_ID_id_UEPagingIdentity, true); if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - OCTET_STRING_TO_INT16(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->aMFSetID, NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_set_id); - OCTET_STRING_TO_INT8(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->aMFPointer, NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_pointer); - OCTET_STRING_TO_INT32(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->fiveG_TMSI, NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.m_tmsi); + OCTET_STRING_TO_INT16(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->aMFSetID, msg->ue_paging_identity.s_tmsi.amf_set_id); + OCTET_STRING_TO_INT8(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->aMFPointer, msg->ue_paging_identity.s_tmsi.amf_pointer); + OCTET_STRING_TO_INT32(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->fiveG_TMSI, msg->ue_paging_identity.s_tmsi.m_tmsi); NGAP_DEBUG("[SCTP %d] Received Paging Identity amf_set_id %d, amf_pointer %d, m_tmsi %d\n", assoc_id, - NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_set_id, - NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_pointer, - NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.m_tmsi); + msg->ue_paging_identity.s_tmsi.amf_set_id, + msg->ue_paging_identity.s_tmsi.amf_pointer, + msg->ue_paging_identity.s_tmsi.m_tmsi); } else { return -1; } - NGAP_PAGING_IND(message_p).paging_drx = NGAP_PAGING_DRX_256; + msg->paging_drx = NGAP_PAGING_DRX_256; /* id-pagingDRX */ NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container, NGAP_ProtocolIE_ID_id_PagingDRX, false); /* optional */ if (ie) { - NGAP_PAGING_IND(message_p).paging_drx = ie->value.choice.PagingDRX; + msg->paging_drx = ie->value.choice.PagingDRX; } else { - NGAP_PAGING_IND(message_p).paging_drx = NGAP_PAGING_DRX_256; + msg->paging_drx = NGAP_PAGING_DRX_256; } - memset (&NGAP_PAGING_IND(message_p).plmn_identity[0], 0, sizeof(plmn_identity_t)*256); - memset (&NGAP_PAGING_IND(message_p).tac[0], 0, sizeof(int16_t)*256); - NGAP_PAGING_IND(message_p).tai_size = 0; + memset (&msg->plmn_identity[0], 0, sizeof(plmn_identity_t)*256); + memset (&msg->tac[0], 0, sizeof(int16_t)*256); + msg->tai_size = 0; /* id-TAIList */ NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container, NGAP_ProtocolIE_ID_id_TAIListForPaging, true); @@ -1536,15 +1553,15 @@ int ngap_gNB_handle_paging(uint32_t assoc_id, for (int i = 0; i < ie->value.choice.TAIListForPaging.list.count; i++) { NGAP_TAIListForPagingItem_t *item_p; item_p = (NGAP_TAIListForPagingItem_t *)ie->value.choice.TAIListForPaging.list.array[i]; - TBCD_TO_MCC_MNC(&(item_p->tAI.pLMNIdentity), NGAP_PAGING_IND(message_p).plmn_identity[i].mcc, - NGAP_PAGING_IND(message_p).plmn_identity[i].mnc, - NGAP_PAGING_IND(message_p).plmn_identity[i].mnc_digit_length); - OCTET_STRING_TO_INT16(&(item_p->tAI.tAC), NGAP_PAGING_IND(message_p).tac[i]); - NGAP_PAGING_IND(message_p).tai_size++; + TBCD_TO_MCC_MNC(&(item_p->tAI.pLMNIdentity), msg->plmn_identity[i].mcc, + msg->plmn_identity[i].mnc, + msg->plmn_identity[i].mnc_digit_length); + OCTET_STRING_TO_INT16(&(item_p->tAI.tAC), msg->tac[i]); + msg->tai_size++; NGAP_DEBUG("[SCTP %d] Received Paging: MCC %d, MNC %d, TAC %d\n", assoc_id, - NGAP_PAGING_IND(message_p).plmn_identity[i].mcc, - NGAP_PAGING_IND(message_p).plmn_identity[i].mnc, - NGAP_PAGING_IND(message_p).tac[i]); + msg->plmn_identity[i].mcc, + msg->plmn_identity[i].mnc, + msg->tac[i]); } } else { return -1; @@ -1552,10 +1569,10 @@ int ngap_gNB_handle_paging(uint32_t assoc_id, //paging parameter values NGAP_DEBUG("[SCTP %d] Received Paging parameters: Paging Identity amf_set_id %d amf_pointer %d m_tmsi %d paging_drx %d paging_priority %d\n",assoc_id, - NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_set_id, - NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_pointer, - NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.m_tmsi, - NGAP_PAGING_IND(message_p).paging_drx, NGAP_PAGING_IND(message_p).paging_priority); + msg->ue_paging_identity.s_tmsi.amf_set_id, + msg->ue_paging_identity.s_tmsi.amf_pointer, + msg->ue_paging_identity.s_tmsi.m_tmsi, + msg->paging_drx, msg->paging_priority); /* send message to RRC */ itti_send_msg_to_task(TASK_RRC_GNB, ngap_gNB_instance->instance, message_p); @@ -1570,7 +1587,6 @@ int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id, int i, nb_of_pdusessions_failed; ngap_gNB_amf_data_t *amf_desc_p = NULL; ngap_gNB_ue_context_t *ue_desc_p = NULL; - MessageDef *message_p = NULL; NGAP_PDUSessionResourceModifyRequest_t *container; NGAP_PDUSessionResourceModifyRequestIEs_t *ie; NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; @@ -1617,8 +1633,9 @@ int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id, if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { NGAP_WARN("UE context amf_ue_ngap_id is different form that of the message (%ld != %ld)", (uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP); - NGAP_PDUSESSION_MODIFY_RESP (message_p).gNB_ue_ngap_id = gnb_ue_ngap_id; + MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP); + ngap_pdusession_modify_resp_t* msg=&NGAP_PDUSESSION_MODIFY_RESP(message_p); + msg->gNB_ue_ngap_id = gnb_ue_ngap_id; NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModReq, true); @@ -1627,32 +1644,32 @@ int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id, NGAP_PDUSessionResourceModifyItemModReq_t *item_p; item_p = (NGAP_PDUSessionResourceModifyItemModReq_t *)ie->value.choice.PDUSessionResourceModifyListModReq.list.array[nb_of_pdusessions_failed]; - NGAP_PDUSESSION_MODIFY_RESP(message_p).pdusessions_failed[nb_of_pdusessions_failed].pdusession_id = item_p->pDUSessionID; - NGAP_PDUSESSION_MODIFY_RESP(message_p).pdusessions_failed[nb_of_pdusessions_failed].cause = NGAP_Cause_PR_radioNetwork; - NGAP_PDUSESSION_MODIFY_RESP(message_p).pdusessions_failed[nb_of_pdusessions_failed].cause_value = NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID; + msg->pdusessions_failed[nb_of_pdusessions_failed].pdusession_id = item_p->pDUSessionID; + msg->pdusessions_failed[nb_of_pdusessions_failed].cause = NGAP_Cause_PR_radioNetwork; + msg->pdusessions_failed[nb_of_pdusessions_failed].cause_value = NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID; } } else { return -1; } - NGAP_PDUSESSION_MODIFY_RESP(message_p).nb_of_pdusessions_failed = nb_of_pdusessions_failed; - ngap_gNB_pdusession_modify_resp(amf_desc_p->ngap_gNB_instance->instance, - &NGAP_PDUSESSION_MODIFY_RESP(message_p)); + msg->nb_of_pdusessions_failed = nb_of_pdusessions_failed; + ngap_gNB_pdusession_modify_resp(amf_desc_p->ngap_gNB_instance->instance,msg); itti_free(TASK_RRC_GNB,message_p); message_p = NULL; return -1; } - message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_MODIFY_REQ); - NGAP_PDUSESSION_MODIFY_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; - NGAP_PDUSESSION_MODIFY_REQ(message_p).amf_ue_ngap_id = amf_ue_ngap_id; - NGAP_PDUSESSION_MODIFY_REQ(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id; + MessageDef *message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_MODIFY_REQ); + ngap_pdusession_modify_req_t * msg=&NGAP_PDUSESSION_MODIFY_REQ(message_p); + msg->ue_initial_id = ue_desc_p->ue_initial_id; + msg->amf_ue_ngap_id = amf_ue_ngap_id; + msg->gNB_ue_ngap_id = gnb_ue_ngap_id; /* id-PDUSessionResourceModifyListModReq */ NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModReq, true); if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - NGAP_PDUSESSION_MODIFY_REQ(message_p).nb_pdusessions_tomodify = + msg->nb_pdusessions_tomodify = ie->value.choice.PDUSessionResourceModifyListModReq.list.count; for (i = 0; i < ie->value.choice.PDUSessionResourceModifyListModReq.list.count; i++) { @@ -1663,17 +1680,17 @@ int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id, item_p = (NGAP_PDUSessionResourceModifyItemModReq_t *)ie->value.choice.PDUSessionResourceModifyListModReq.list.array[i]; - NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].pdusession_id = item_p->pDUSessionID; + msg->pdusession_modify_params[i].pdusession_id = item_p->pDUSessionID; // check for the NAS PDU if (item_p->nAS_PDU != NULL && item_p->nAS_PDU->size > 0 ) { - NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.length = item_p->nAS_PDU->size; - NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU->size); - memcpy(NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.buffer, + msg->pdusession_modify_params[i].nas_pdu.length = item_p->nAS_PDU->size; + msg->pdusession_modify_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU->size); + memcpy(msg->pdusession_modify_params[i].nas_pdu.buffer, item_p->nAS_PDU->buf, item_p->nAS_PDU->size); } else { - NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.length = 0; - NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.buffer = NULL; + msg->pdusession_modify_params[i].nas_pdu.length = 0; + msg->pdusession_modify_params[i].nas_pdu.buffer = NULL; continue; } @@ -1718,25 +1735,25 @@ int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id, DevAssert(pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count > 0); DevAssert(pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count <= NGAP_maxnoofQosFlows); - NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count; + msg->pdusession_modify_params[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count; for(int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count; qosIdx++) { qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.array[qosIdx]; /* Set the QOS informations */ - NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; + msg->pdusession_modify_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; if(qosFlowItem_p->qosFlowLevelQosParameters) { if (qosFlowItem_p->qosFlowLevelQosParameters->qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI) { - NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].fiveQI = + msg->pdusession_modify_params[i].qos[qosIdx].fiveQI = qosFlowItem_p->qosFlowLevelQosParameters->qosCharacteristics.choice.nonDynamic5QI->fiveQI; } else if (qosFlowItem_p->qosFlowLevelQosParameters->qosCharacteristics.present == NGAP_QosCharacteristics_PR_dynamic5QI) { // TODO } - NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.priority_level = + msg->pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.priority_level = qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.priorityLevelARP; - NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability = + msg->pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability = qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.pre_emptionCapability; - NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability = + msg->pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability = qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.pre_emptionVulnerability; } } @@ -1784,7 +1801,6 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id, int i; ngap_gNB_amf_data_t *amf_desc_p = NULL; ngap_gNB_ue_context_t *ue_desc_p = NULL; - MessageDef *message_p = NULL; NGAP_PDUSessionResourceReleaseCommand_t *container; NGAP_PDUSessionResourceReleaseCommandIEs_t *ie; NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; @@ -1841,22 +1857,24 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id, NGAP_DEBUG("[SCTP %d] Received pdu session release command for gNB_UE_NGAP_ID %lu amf_ue_ngap_id %lu\n", assoc_id, gnb_ue_ngap_id, amf_ue_ngap_id); - message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_RELEASE_COMMAND); - NGAP_PDUSESSION_RELEASE_COMMAND(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id; - NGAP_PDUSESSION_RELEASE_COMMAND(message_p).amf_ue_ngap_id = amf_ue_ngap_id; + MessageDef * message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_RELEASE_COMMAND); + ngap_pdusession_release_command_t * msg=&NGAP_PDUSESSION_RELEASE_COMMAND(message_p); + + msg->gNB_ue_ngap_id = gnb_ue_ngap_id; + msg->amf_ue_ngap_id = amf_ue_ngap_id; /* id-NAS-PDU */ NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceReleaseCommandIEs_t, ie, container, NGAP_ProtocolIE_ID_id_NAS_PDU, false); if(ie && ie->value.choice.NAS_PDU.size > 0) { - NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.length = ie->value.choice.NAS_PDU.size; - NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.buffer = malloc(sizeof(uint8_t) * ie->value.choice.NAS_PDU.size); - memcpy(NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.buffer, + msg->nas_pdu.length = ie->value.choice.NAS_PDU.size; + msg->nas_pdu.buffer = malloc(sizeof(uint8_t) * ie->value.choice.NAS_PDU.size); + memcpy(msg->nas_pdu.buffer, ie->value.choice.NAS_PDU.buf, ie->value.choice.NAS_PDU.size); } else { - NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.length = 0; - NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.buffer = NULL; + msg->nas_pdu.length = 0; + msg->nas_pdu.buffer = NULL; } /* id-PDUSessionResourceToReleaseListRelCmd */ @@ -1864,22 +1882,22 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id, NGAP_ProtocolIE_ID_id_PDUSessionResourceToReleaseListRelCmd, true); if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nb_pdusessions_torelease = ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count; + msg->nb_pdusessions_torelease = ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count; for (i = 0; i < ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count; i++) { NGAP_PDUSessionResourceToReleaseItemRelCmd_t *item_p; item_p = (NGAP_PDUSessionResourceToReleaseItemRelCmd_t *)ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.array[i]; - NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].pdusession_id = item_p->pDUSessionID; + msg->pdusession_release_params[i].pdusession_id = item_p->pDUSessionID; if(item_p->pDUSessionResourceReleaseCommandTransfer.size > 0) { - NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_length = item_p->pDUSessionResourceReleaseCommandTransfer.size; - NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionResourceReleaseCommandTransfer.size); - memcpy(NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer, + msg->pdusession_release_params[i].transfer_length = item_p->pDUSessionResourceReleaseCommandTransfer.size; + msg->pdusession_release_params[i].transfer_buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionResourceReleaseCommandTransfer.size); + memcpy(msg->pdusession_release_params[i].transfer_buffer, item_p->pDUSessionResourceReleaseCommandTransfer.buf, item_p->pDUSessionResourceReleaseCommandTransfer.size); }else { - NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_length = 0; - NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer = NULL; + msg->pdusession_release_params[i].transfer_length = 0; + msg->pdusession_release_params[i].transfer_buffer = NULL; NGAP_ERROR("[NGAP] Received pdu session release command for pDUSessionResourceReleaseCommandTransfer is NULL!\n"); } NGAP_DEBUG("[NGAP] Received pdu session release command for pDUSessionID id %ld\n", item_p->pDUSessionID); diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index 49a0674bdf..14128dd53e 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -617,10 +617,7 @@ sctp_handle_new_association_req( } //------------------------------------------------------------------------------ -static void sctp_send_data( - instance_t instance, - task_id_t task_id, - sctp_data_req_t *sctp_data_req_p) +static void sctp_send_data(sctp_data_req_t *sctp_data_req_p) { struct sctp_cnx_list_elm_s *sctp_cnx = NULL; @@ -660,10 +657,7 @@ static void sctp_send_data( } //------------------------------------------------------------------------------ -static int sctp_close_association( - const instance_t instance, - const task_id_t requestor, - sctp_close_association_t *close_association_p) +static int sctp_close_association(sctp_close_association_t *close_association_p) { struct sctp_cnx_list_elm_s *sctp_cnx = NULL; @@ -1152,10 +1146,8 @@ static void sctp_eNB_process_itti_msg() break; case SCTP_CLOSE_ASSOCIATION: - sctp_close_association(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - ITTI_MSG_ORIGIN_ID(received_msg), - &received_msg->ittiMsg.sctp_close_association); - break; + sctp_close_association(&received_msg->ittiMsg.sctp_close_association); + break; case TERMINATE_MESSAGE: SCTP_WARN("*** Exiting SCTP thread\n"); @@ -1163,9 +1155,7 @@ static void sctp_eNB_process_itti_msg() break; case SCTP_DATA_REQ: { - sctp_send_data(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - ITTI_MSG_ORIGIN_ID(received_msg), - &received_msg->ittiMsg.sctp_data_req); + sctp_send_data(&received_msg->ittiMsg.sctp_data_req); } break; diff --git a/openair3/SECU/aes_128.h b/openair3/SECU/aes_128.h new file mode 100644 index 0000000000..7f7e550419 --- /dev/null +++ b/openair3/SECU/aes_128.h @@ -0,0 +1,88 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef AES_128_OAI_H +#define AES_128_OAI_H + +#include +#include +#include + +// see 33.401 B.2.3 for the input to 128-EIA2 +// (which is identical to 128-NIA2, see 33.501 D.3.1.3) + +typedef struct { + uint32_t count; + uint8_t padding: 2; + uint8_t direction: 1; + uint8_t bearer: 5; + uint8_t pad_8; + uint16_t pad_16; + uint64_t pad_64; +} data_iv16_t; + +typedef struct{ + union{ + data_iv16_t d; + uint8_t iv[16]; + }; +} iv16_t; + +typedef struct { + uint32_t count; + uint8_t padding: 2; + uint8_t direction: 1; + uint8_t bearer: 5; + uint8_t pad_8; + uint16_t pad_16; +} data_iv8_t; + +typedef struct{ + union{ + data_iv8_t d; + uint8_t iv[8]; + }; +} iv8_t; + +typedef enum{ + AES_INITIALIZATION_VECTOR_8, + AES_INITIALIZATION_VECTOR_16, + + AES_INITIALIZATION_VECTOR_END, +} iv_e; + +#if __BYTE_ORDER == __BIG_ENDIAN +static_assert(0 != 0, "The struct iv_t needs little endianness"); +#endif + +// static_assert((16 == sizeof(iv_t)) , "Initialization Vector needs to have an AES_BLOCK_SIZE" ); + +typedef struct { + uint8_t key[16]; + iv_e type; + union{ + iv8_t iv8; + iv16_t iv16; + }; +} aes_128_t; + +#endif + diff --git a/openair3/SECU/aes_128_cbc_cmac.c b/openair3/SECU/aes_128_cbc_cmac.c new file mode 100644 index 0000000000..6b02f1673a --- /dev/null +++ b/openair3/SECU/aes_128_cbc_cmac.c @@ -0,0 +1,254 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include +#include "aes_128_cbc_cmac.h" + +#include "common/utils/assertions.h" +#include + +#if OPENSSL_VERSION_MAJOR >= 3 +// code for version 3.0 or greater +#include + +static +const char *propq = NULL; + +void aes_128_cbc_cmac(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]) +{ + OSSL_LIB_CTX* library_context = OSSL_LIB_CTX_new(); + DevAssert(library_context != NULL); + + /* Fetch the CMAC implementation */ + EVP_MAC* mac = EVP_MAC_fetch(library_context, "CMAC", propq); + DevAssert(mac != NULL); + + /* Create a context for the CMAC operation */ + EVP_MAC_CTX* mctx = EVP_MAC_CTX_new(mac); + DevAssert(mctx != NULL); + + // The underlying cipher to be used + char cipher_name[] = "aes128"; + + OSSL_PARAM params[2] = {0}; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, cipher_name, + sizeof(cipher_name)); + params[1] = OSSL_PARAM_construct_end(); + + /* Initialise the CMAC operation */ + int rc = EVP_MAC_init(mctx, k_iv->key, sizeof(k_iv->key), params); + DevAssert(rc != 0); + + size_t sz_iv = 0; + uint8_t* iv = NULL; + if(k_iv->type == AES_INITIALIZATION_VECTOR_8){ + sz_iv = 8; + iv = (uint8_t*)k_iv->iv8.iv; + } else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) { + sz_iv = 16; + iv = (uint8_t*)k_iv->iv16.iv; + } else { + DevAssert(0!=0 && "Unknwon Initialization vector"); + } + + /* Make one or more calls to process the data to be authenticated */ + rc = EVP_MAC_update(mctx, iv, sz_iv); + DevAssert(rc != 0); + + /* Make one or more calls to process the data to be authenticated */ + rc = EVP_MAC_update(mctx, msg.buf, msg.len); + DevAssert(rc != 0); + + /* Make a call to the final with a NULL buffer to get the length of the MAC */ + size_t out_len = 0; + rc = EVP_MAC_final(mctx, out, &out_len, len_out); + DevAssert(rc != 0); + + EVP_MAC_CTX_free(mctx); + EVP_MAC_free(mac); + OSSL_LIB_CTX_free(library_context); +} + +cbc_cmac_ctx_t init_aes_128_cbc_cmac(uint8_t key[16]) +{ + DevAssert(key != NULL); + + OSSL_LIB_CTX* library_context = OSSL_LIB_CTX_new(); + DevAssert(library_context != NULL); + + /* Fetch the CMAC implementation */ + EVP_MAC* mac = EVP_MAC_fetch(library_context, "CMAC", propq); + DevAssert(mac != NULL); + + cbc_cmac_ctx_t ctx = {.lib_ctx = library_context, .mac = mac }; + + assert(16 == sizeof(ctx.key)); + memcpy(ctx.key, key, 16); + + return ctx; +} + +void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]) +{ + DevAssert(ctx != NULL); + DevAssert(k_iv != NULL); + /* Create a context for the CMAC operation */ + EVP_MAC_CTX* mctx = EVP_MAC_CTX_new(ctx->mac); + DevAssert(mctx != NULL); + + // The underlying cipher to be used + char cipher_name[] = "aes128"; + + OSSL_PARAM params[2] = {0}; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, cipher_name, + sizeof(cipher_name)); + params[1] = OSSL_PARAM_construct_end(); + + /* Initialise the CMAC operation */ + int rc = EVP_MAC_init(mctx, k_iv->key, sizeof(k_iv->key), params); + DevAssert(rc != 0); + + size_t sz_iv = 0; + uint8_t* iv = NULL; + if(k_iv->type == AES_INITIALIZATION_VECTOR_8){ + sz_iv = 8; + iv = (uint8_t*)k_iv->iv8.iv; + } else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) { + sz_iv = 16; + iv = (uint8_t*)k_iv->iv16.iv; + } else { + DevAssert(0!=0 && "Unknwon Initialization vector"); + } + + /* Make one or more calls to process the data to be authenticated */ + rc = EVP_MAC_update(mctx, iv, sz_iv); + DevAssert(rc != 0); + + /* Make one or more calls to process the data to be authenticated */ + rc = EVP_MAC_update(mctx, msg.buf, msg.len); + DevAssert(rc != 0); + + /* Make a call to the final with a NULL buffer to get the length of the MAC */ + size_t out_len = 0; + rc = EVP_MAC_final(mctx, out, &out_len, len_out); + DevAssert(rc != 0); + + EVP_MAC_CTX_free(mctx); +} + +void free_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx) +{ + DevAssert(ctx != NULL); + EVP_MAC_free(ctx->mac); + OSSL_LIB_CTX_free(ctx->lib_ctx); +} + +#else +// code for 1.1.x or lower + +void aes_128_cbc_cmac(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]) +{ + DevAssert(k_iv != NULL); + + CMAC_CTX *ctx = CMAC_CTX_new(); + DevAssert(ctx != NULL); + + CMAC_Init(ctx, k_iv->key, sizeof(k_iv->key), EVP_aes_128_cbc(), NULL); + + size_t sz_iv = 0; + uint8_t* iv = NULL; + if(k_iv->type == AES_INITIALIZATION_VECTOR_8){ + sz_iv = 8; + iv = (uint8_t*)k_iv->iv8.iv; + } else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) { + sz_iv = 16; + iv = (uint8_t*)k_iv->iv16.iv; + } else { + DevAssert(0!=0 && "Unknwon Initialization vector"); + } + + CMAC_Update(ctx, iv, sz_iv); + + CMAC_Update(ctx, msg.buf, msg.len); + size_t len_res = 0; + CMAC_Final(ctx, out, &len_res); + DevAssert(len_res <= len_out); + + CMAC_CTX_free(ctx); +} + +cbc_cmac_ctx_t init_aes_128_cbc_cmac(uint8_t key[16]) +{ + DevAssert(key != NULL); + cbc_cmac_ctx_t ctx = {.lib_ctx = NULL, .mac = NULL }; + + ctx.mac = CMAC_CTX_new(); + DevAssert(ctx.mac != NULL); + + //assert(16 == sizeof(ctx.key)); + memcpy(ctx.key, key, 16); //sizeof(ctx.key)); + + CMAC_Init(ctx.mac, ctx.key, 16, EVP_aes_128_cbc(), NULL); + return ctx; +} + +void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]) +{ + DevAssert(ctx != NULL); + DevAssert(k_iv != NULL); + + //From https://man.openbsd.org/CMAC_Init.3 + //If ctx is already initialized, CMAC_Init() can be called again with key, + //cipher, and impl all set to NULL and key_len set to 0. In that case, any + //data already processed is discarded and ctx is re-initialized to start + //reading data anew. + CMAC_Init(ctx->mac, NULL, 0, NULL, NULL); + + size_t sz_iv = 0; + uint8_t* iv = NULL; + if(k_iv->type == AES_INITIALIZATION_VECTOR_8){ + sz_iv = 8; + iv = (uint8_t*)k_iv->iv8.iv; + } else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) { + sz_iv = 16; + iv = (uint8_t*)k_iv->iv16.iv; + } else { + DevAssert(0!=0 && "Unknwon Initialization vector"); + } + + CMAC_Update(ctx->mac, iv, sz_iv); + + CMAC_Update(ctx->mac, msg.buf, msg.len); + size_t len_res = 0; + CMAC_Final(ctx->mac, out, &len_res); + DevAssert(len_res <= len_out); +} + +void free_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx) +{ + DevAssert(ctx != NULL); + CMAC_CTX_free(ctx->mac); +} + +#endif + diff --git a/openair3/SECU/aes_128_cbc_cmac.h b/openair3/SECU/aes_128_cbc_cmac.h new file mode 100644 index 0000000000..b5118118c3 --- /dev/null +++ b/openair3/SECU/aes_128_cbc_cmac.h @@ -0,0 +1,48 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + +#ifndef AES_128_CBC_CMAC_H +#define AES_128_CBC_CMAC_H + +#include "aes_128.h" +#include "common/utils/ds/byte_array.h" + + +#include +#include + +typedef struct { + void* lib_ctx; + void* mac; + uint8_t key[16]; +} cbc_cmac_ctx_t ; + +void aes_128_cbc_cmac(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]); + +cbc_cmac_ctx_t init_aes_128_cbc_cmac(uint8_t key[16]); + +void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]); + +void free_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx); + +#endif + diff --git a/openair3/SECU/aes_128_ctr.c b/openair3/SECU/aes_128_ctr.c new file mode 100644 index 0000000000..4caf6ee3cf --- /dev/null +++ b/openair3/SECU/aes_128_ctr.c @@ -0,0 +1,62 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +// TS 133 401 pag. 88 + +#include "aes_128_ctr.h" +#include "common/utils/assertions.h" +#include +#include +#include + +void aes_128_ctr(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]) +{ + DevAssert(k_iv != NULL); + + DevAssert(sizeof(iv16_t) == AES_BLOCK_SIZE); + DevAssert(k_iv->type == AES_INITIALIZATION_VECTOR_16); + + // Create and initialise the context + EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); + DevAssert(ctx != NULL); + + // Set IV length if default 12 bytes (96 bits) is not appropriate + // int rc = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CTR_SET_IVLEN, 16, NULL)) + + // Initialise the encryption operation. + int rc = EVP_EncryptInit_ex(ctx, EVP_aes_128_ctr(), NULL, k_iv->key, k_iv->iv16.iv); + DevAssert(rc == 1); + + OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == AES_BLOCK_SIZE); + + int len_ev = 0; + rc = EVP_EncryptUpdate(ctx, out, &len_ev, msg.buf, msg.len); + DevAssert(!(len_ev > len_out) && "Buffer overflow"); + + // Finalise the encryption. Normally ciphertext bytes may be written at + // this stage, but this does not occur in GCM mode + rc = EVP_EncryptFinal_ex(ctx, out + len_ev, &len_ev); + DevAssert(rc == 1); + + // Get the tag + // rc == EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)) + EVP_CIPHER_CTX_free(ctx); +} diff --git a/openair3/SECU/aes_128_ctr.h b/openair3/SECU/aes_128_ctr.h new file mode 100644 index 0000000000..24bad85664 --- /dev/null +++ b/openair3/SECU/aes_128_ctr.h @@ -0,0 +1,33 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef AES_128_CTR_OAI_H +#define AES_128_CTR_OAI_H + +#include "aes_128.h" +#include "common/utils/ds/byte_array.h" +#include +#include +#include + +void aes_128_ctr(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]); + +#endif diff --git a/openair3/SECU/kdf.c b/openair3/SECU/kdf.c index 1073df8ebe..8bead9158d 100644 --- a/openair3/SECU/kdf.c +++ b/openair3/SECU/kdf.c @@ -19,87 +19,18 @@ * contact@openairinterface.org */ +#include "common/utils/assertions.h" +#include "openair3/SECU/sha_256_hmac.h" #include #include #include -#include -#include "security_types.h" -#include "secu_defs.h" +#include "kdf.h" -void kdf(const uint8_t *key, uint16_t key_len, uint8_t *s, uint16_t s_len, uint8_t *out, - uint16_t out_len) +void kdf(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]) { - struct hmac_sha256_ctx ctx; - - memset(&ctx, 0, sizeof(ctx)); - - hmac_sha256_set_key(&ctx, key_len, key); - hmac_sha256_update(&ctx, s_len, s); - hmac_sha256_digest(&ctx, out_len, out); + // Do we still need kdf function? + sha_256_hmac(key, data, len, out); } -#ifndef NAS_UE -int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB) -{ - uint8_t s[7]; - - // FC - s[0] = FC_KENB; - // P0 = Uplink NAS count - s[1] = (nas_count & 0xff000000) >> 24; - s[2] = (nas_count & 0x00ff0000) >> 16; - s[3] = (nas_count & 0x0000ff00) >> 8; - s[4] = (nas_count & 0x000000ff); - - // Length of NAS count - s[5] = 0x00; - s[6] = 0x04; - - kdf(kasme, 32, s, 7, keNB, 32); - - return 0; -} -#endif - -int derive_keNB_star( - const uint8_t *kenb_32, - const uint16_t pci, - const uint32_t earfcn_dl, - const bool is_rel8_only, - uint8_t *kenb_star) -{ - // see 33.401 section A.5 KeNB* derivation function - uint8_t s[10] = {0}; - - // FC = 0x13 - s[0] = FC_KENB_STAR; - // P0 = PCI (target physical cell id) - s[1] = (pci & 0x0000ff00) >> 8; - s[2] = (pci & 0x000000ff); - // L0 = length of PCI (i.e. 0x00 0x02) - s[3] = 0x00; - s[4] = 0x02; - // P1 = EARFCN-DL (target physical cell downlink frequency) - if (is_rel8_only) { - s[5] = (earfcn_dl & 0x0000ff00) >> 8; - s[6] = (earfcn_dl & 0x000000ff); - s[7] = 0x00; - s[8] = 0x02; - kdf (kenb_32, 32, s, 9, kenb_star, 32); - } else { - s[5] = (earfcn_dl & 0x00ff0000) >> 16; - s[6] = (earfcn_dl & 0x0000ff00) >> 8; - s[7] = (earfcn_dl & 0x000000ff); - s[8] = 0x00; - s[9] = 0x03; - kdf (kenb_32, 32, s, 10, kenb_star, 32); - } - // L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between 65536 and 262143) - // NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8 - // entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This - // would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the - // EARFCN-DL. - return 0; -} diff --git a/openair3/SECU/kdf.h b/openair3/SECU/kdf.h new file mode 100644 index 0000000000..9567296bd2 --- /dev/null +++ b/openair3/SECU/kdf.h @@ -0,0 +1,34 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef KEY_DERIVATION_FUNCTION_OSA_H +#define KEY_DERIVATION_FUNCTION_OSA_H + +#include +#include +#include "byte_array.h" + +void kdf(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]); + +#endif + + + diff --git a/openair3/SECU/key_nas_deriver.c b/openair3/SECU/key_nas_deriver.c index 59546be081..18cdb3d000 100644 --- a/openair3/SECU/key_nas_deriver.c +++ b/openair3/SECU/key_nas_deriver.c @@ -26,6 +26,7 @@ #include "security_types.h" #include "secu_defs.h" +#include "kdf.h" #define SECU_DEBUG 1 /*! @@ -79,7 +80,9 @@ int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, printf("\n"); #endif - kdf(kasme, 32, s, 7, out, 32); + //kdf(kasme, 32, s, 7, out, 32); + byte_array_t data = {.len = 7, .buf = s}; + kdf(kasme, data, 32, out); memcpy(knas, &out[31-16+1], 16); diff --git a/openair3/SECU/nas_stream_eea1.c b/openair3/SECU/nas_stream_eea1.c index efe924851f..e70d49ea2c 100644 --- a/openair3/SECU/nas_stream_eea1.c +++ b/openair3/SECU/nas_stream_eea1.c @@ -24,10 +24,6 @@ #include #include -#include -#include -#include - #include "assertions.h" #include "conversions.h" #include "secu_defs.h" diff --git a/openair3/SECU/nas_stream_eea2.c b/openair3/SECU/nas_stream_eea2.c index 0cd3d91761..4eeb24b775 100644 --- a/openair3/SECU/nas_stream_eea2.c +++ b/openair3/SECU/nas_stream_eea2.c @@ -19,84 +19,40 @@ * contact@openairinterface.org */ +#include #include #include #include #include -#include -#include -#include - +#include "aes_128_ctr.h" #include "assertions.h" #include "conversions.h" #include "secu_defs.h" -// #define SECU_DEBUG - int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out) { - uint8_t m[16]; - uint32_t local_count; - - void *ctx; - uint8_t *data; - - uint32_t zero_bit = 0; - uint32_t byte_length; - DevAssert(stream_cipher != NULL); - DevAssert(out != NULL); + DevAssert(stream_cipher->key != NULL); + DevAssert(stream_cipher->key_length == 32); + DevAssert(stream_cipher->bearer < 32); + DevAssert(stream_cipher->direction < 2); + DevAssert(stream_cipher->message != NULL); + DevAssert(stream_cipher->blength > 7); - zero_bit = stream_cipher->blength & 0x7; + aes_128_t p = {0}; + memcpy(p.key, stream_cipher->key, stream_cipher->key_length); + p.type = AES_INITIALIZATION_VECTOR_16; + p.iv16.d.count = htonl(stream_cipher->count); + p.iv16.d.bearer = stream_cipher->bearer; + p.iv16.d.direction = stream_cipher->direction; - byte_length = stream_cipher->blength >> 3; - - if (zero_bit > 0) - byte_length += 1; - - ctx = malloc(nettle_aes128.context_size); - data = malloc(byte_length); - - local_count = hton_int32(stream_cipher->count); - - memset(m, 0, sizeof(m)); - memcpy(&m[0], &local_count, 4); - m[4] = ((stream_cipher->bearer & 0x1F) << 3) | - ((stream_cipher->direction & 0x01) << 2); - /* Other bits are 0 */ - -#if defined(SECU_DEBUG) - { - int i; - printf("Blength: %u, Zero bits: %u\n", stream_cipher->blength, zero_bit); - - for (i = 0; i < sizeof(m); i++) - printf("0x%02x ", m[i]); - - printf("\n"); - } -#endif - -#if NETTLE_VERSION_MAJOR < 3 - nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length, - stream_cipher->key); -#else - nettle_aes128.set_encrypt_key(ctx, - stream_cipher->key); -#endif - - nettle_ctr_crypt(ctx, nettle_aes128.encrypt, - nettle_aes128.block_size, m, - byte_length, data, stream_cipher->message); - - if (zero_bit > 0) - data[byte_length - 1] = data[byte_length - 1] & (uint8_t)(0xFF << (8 - zero_bit)); - - - memcpy(out, data, byte_length); - free(data); - free(ctx); + DevAssert((stream_cipher->blength & 0x07) == 0); + const uint32_t byte_lenght = stream_cipher->blength >> 3; + // Precondition: out must have enough space, at least as much as the input + const size_t len_out = byte_lenght; + byte_array_t msg = {.buf = stream_cipher->message, .len = byte_lenght}; + aes_128_ctr(&p, msg, len_out, out); return 0; } diff --git a/openair3/SECU/nas_stream_eia2.c b/openair3/SECU/nas_stream_eia2.c index a2ec6a6dd4..4c7951a0f5 100644 --- a/openair3/SECU/nas_stream_eia2.c +++ b/openair3/SECU/nas_stream_eia2.c @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#include #include #include #include @@ -26,15 +27,8 @@ #include "secu_defs.h" -#include -#include -#include - -// test -#include -#include -#include - +#include +#include "aes_128_cbc_cmac.h" #include "assertions.h" #include "conversions.h" @@ -45,84 +39,28 @@ * @param[in] stream_cipher Structure containing various variables to setup encoding * @param[out] out For EIA2 the output string is 32 bits long */ + int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) { - uint8_t *m = NULL; - uint32_t local_count; - size_t size = 4; - uint8_t data[16]; - CMAC_CTX *cmac_ctx = NULL; - const EVP_CIPHER *cipher = EVP_aes_128_cbc(); - uint32_t zero_bit = 0; - uint32_t m_length; - int ret; - DevAssert(stream_cipher != NULL); - DevAssert(stream_cipher->key != NULL); - DevAssert(stream_cipher->key_length > 0); - DevAssert(out != NULL); + DevAssert(stream_cipher->message != NULL); + DevAssert(stream_cipher->bearer < 32); + DevAssert(stream_cipher->key_length == 16); + DevAssert((stream_cipher->blength & 0x7) == 0); - memset(data, 0, 16); - - zero_bit = stream_cipher->blength & 0x7; - - m_length = stream_cipher->blength >> 3; - - if (zero_bit > 0) - m_length += 1; - - local_count = hton_int32(stream_cipher->count); - - m = calloc(m_length + 8, sizeof(uint8_t)); - - memcpy(&m[0], &local_count, 4); - m[4] = ((stream_cipher->bearer & 0x1F) << 3) | ((stream_cipher->direction & 0x01) << 2); - - memcpy(&m[8], stream_cipher->message, m_length); - -#if defined(SECU_DEBUG) - { - int i; - printf("Byte length: %u, Zero bits: %u\nm: ", m_length + 8, zero_bit); - - for (i = 0; i < m_length + 8; i++) - printf("%02x", m[i]); - - printf("\nKey:"); - - for (i = 0; i < stream_cipher->key_length; i++) - printf("%02x", stream_cipher->key[i]); - - printf("\nMessage:"); - - for (i = 0; i < m_length; i++) - printf("%02x", stream_cipher->message[i]); - - printf("\n"); - } -#endif - - cmac_ctx = CMAC_CTX_new(); - ret = CMAC_Init(cmac_ctx, stream_cipher->key, stream_cipher->key_length, cipher, NULL); - ret = CMAC_Update(cmac_ctx, m, m_length + 8); - (void)ret; /* avoid gcc warning "set but not used" */ - CMAC_Final(cmac_ctx, data, &size); - CMAC_CTX_free(cmac_ctx); - -#if defined(SECU_DEBUG) - { - int i; - printf("out: "); - - for (i = 0; i < size; i++) - printf("%02x", data[i]); - - printf("\n"); - } -#endif - - memcpy(out, data, 4); - free(m); + aes_128_t k_iv = {0}; + memcpy(&k_iv.key, stream_cipher->key, sizeof(k_iv.key)); + k_iv.type = AES_INITIALIZATION_VECTOR_8; + k_iv.iv8.d.bearer = stream_cipher->bearer; + k_iv.iv8.d.direction = stream_cipher->direction; + k_iv.iv8.d.count = htonl(stream_cipher->count); + size_t const m_length = stream_cipher->blength >> 3; + uint8_t result[16] = {0}; + byte_array_t msg = {.buf = stream_cipher->message, .len = m_length }; + aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result); + + memcpy(out, result, 4); return 0; } + diff --git a/openair3/SECU/secu_defs.c b/openair3/SECU/secu_defs.c new file mode 100644 index 0000000000..00cf23187e --- /dev/null +++ b/openair3/SECU/secu_defs.c @@ -0,0 +1,96 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + +#include "secu_defs.h" +#include "kdf.h" + +#ifndef NAS_UE +int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB) +{ + uint8_t s[7] = {0}; + + // FC + s[0] = FC_KENB; + // P0 = Uplink NAS count + s[1] = (nas_count & 0xff000000) >> 24; + s[2] = (nas_count & 0x00ff0000) >> 16; + s[3] = (nas_count & 0x0000ff00) >> 8; + s[4] = (nas_count & 0x000000ff); + + // Length of NAS count + s[5] = 0x00; + s[6] = 0x04; + + // kdf(kasme, 32, s, 7, keNB, 32); + byte_array_t data = {.buf = s, .len = 7}; + kdf(kasme, data, 32, keNB); + + return 0; +} +#endif + +int derive_keNB_star( + const uint8_t *kenb_32, + const uint16_t pci, + const uint32_t earfcn_dl, + const bool is_rel8_only, + uint8_t *kenb_star) +{ + // see 33.401 section A.5 KeNB* derivation function + uint8_t s[10] = {0}; + byte_array_t data = {.buf = s}; + // FC = 0x13 + s[0] = FC_KENB_STAR; + // P0 = PCI (target physical cell id) + s[1] = (pci & 0x0000ff00) >> 8; + s[2] = (pci & 0x000000ff); + // L0 = length of PCI (i.e. 0x00 0x02) + s[3] = 0x00; + s[4] = 0x02; + // P1 = EARFCN-DL (target physical cell downlink frequency) + if (is_rel8_only) { + s[5] = (earfcn_dl & 0x0000ff00) >> 8; + s[6] = (earfcn_dl & 0x000000ff); + s[7] = 0x00; + s[8] = 0x02; +// kdf (kenb_32, 32, s, 9, kenb_star, 32); + data.len = 9; + } else { + s[5] = (earfcn_dl & 0x00ff0000) >> 16; + s[6] = (earfcn_dl & 0x0000ff00) >> 8; + s[7] = (earfcn_dl & 0x000000ff); + s[8] = 0x00; + s[9] = 0x03; + //kdf (kenb_32, 32, s, 10, kenb_star, 32); + data.len = 10; + } + + kdf (kenb_32, data, 32, kenb_star); + + // L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between 65536 and 262143) + // NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8 + // entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This + // would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the + // EARFCN-DL. + return 0; +} + diff --git a/openair3/SECU/secu_defs.h b/openair3/SECU/secu_defs.h index 8ec05f3daf..7817db30d3 100644 --- a/openair3/SECU/secu_defs.h +++ b/openair3/SECU/secu_defs.h @@ -24,6 +24,7 @@ #include "security_types.h" #include +#include #define EIA0_ALG_ID 0x00 #define EIA1_128_ALG_ID 0x01 @@ -36,13 +37,6 @@ #define SECU_DIRECTION_UPLINK 0 #define SECU_DIRECTION_DOWNLINK 1 -void kdf(const uint8_t *key, - uint16_t key_len, - uint8_t *s, - uint16_t s_len, - uint8_t *out, - uint16_t out_len); - int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB); int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl, diff --git a/openair3/SECU/sha_256_hmac.c b/openair3/SECU/sha_256_hmac.c new file mode 100644 index 0000000000..ae49b1d1a2 --- /dev/null +++ b/openair3/SECU/sha_256_hmac.c @@ -0,0 +1,95 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "common/utils/assertions.h" +#include "sha_256_hmac.h" + +#include + +#if OPENSSL_VERSION_MAJOR >= 3 +// code for version 3.0 or greater + +#include + +void sha_256_hmac(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]) +{ + DevAssert(key != NULL); + DevAssert(data.buf != NULL); + DevAssert(data.len != 0); + DevAssert(len != 0); + + OSSL_LIB_CTX* library_context = OSSL_LIB_CTX_new(); + DevAssert(library_context != NULL); + + // A property query used for selecting the MAC implementation. + const char* propq = NULL; + // Fetch the HMAC implementation + EVP_MAC* mac = EVP_MAC_fetch(library_context, "HMAC", propq); + DevAssert(mac != NULL); + + // Create a context for the HMAC operation + EVP_MAC_CTX* mctx = EVP_MAC_CTX_new(mac); + DevAssert(mctx != NULL); + + // The underlying digest to be used + OSSL_PARAM params[2] = {0}; + char digest_name[] = "SHA2-256"; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, digest_name, sizeof(digest_name)); + params[1] = OSSL_PARAM_construct_end(); + + // Initialise the HMAC operation + int rc = EVP_MAC_init(mctx, key, 32, params); + DevAssert(rc == 1); + + // Make one or more calls to process the data to be authenticated + rc = EVP_MAC_update(mctx, data.buf, data.len); + DevAssert(rc == 1); + + // Make one call to the final to get the MAC + rc = EVP_MAC_final(mctx, out, &len, len); + DevAssert(rc == 1); + + // OpenSSL free functions will ignore NULL arguments + EVP_MAC_CTX_free(mctx); + EVP_MAC_free(mac); + OSSL_LIB_CTX_free(library_context); +} +#else +// code for 1.1.x or lower +void sha_256_hmac(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]) +{ + DevAssert(key != NULL); + DevAssert(data.buf != NULL); + DevAssert(data.len != 0); + DevAssert(len != 0); + + HMAC_CTX* ctx = HMAC_CTX_new(); + + HMAC_Init_ex(ctx, key, 32, EVP_sha256(), NULL); + + HMAC_Update(ctx, data.buf, data.len); + + HMAC_Final(ctx, out, (uint32_t*)&len); + + HMAC_CTX_free(ctx); +} + +#endif diff --git a/openair3/SECU/sha_256_hmac.h b/openair3/SECU/sha_256_hmac.h new file mode 100644 index 0000000000..79413763ea --- /dev/null +++ b/openair3/SECU/sha_256_hmac.h @@ -0,0 +1,33 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef SHA_256_HMAC_OAI_H +#define SHA_256_HMAC_OAI_H + +#include +#include + +#include "byte_array.h" + +void sha_256_hmac(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]); + +#endif + diff --git a/openair3/TEST/Makefile.am b/openair3/TEST/Makefile.am index 211c7e62f2..1c00d33420 100644 --- a/openair3/TEST/Makefile.am +++ b/openair3/TEST/Makefile.am @@ -43,8 +43,7 @@ if HAVE_CHECK TESTS = \ test_kdf \ test_aes128_cmac_encrypt \ - test_aes128_ctr_encrypt \ - test_aes128_ctr_decrypt \ + test_aes128_ctr \ test_secu_kenb \ test_secu_knas \ test_secu_knas_encrypt_eea1 \ @@ -68,8 +67,7 @@ common_ldadd = $(top_builddir)/SECU/libsecu.la \ check_PROGRAMS = \ test_kdf \ test_aes128_cmac_encrypt \ - test_aes128_ctr_encrypt \ - test_aes128_ctr_decrypt \ + test_aes128_ctr \ test_secu_kenb \ test_secu_knas \ test_secu_knas_encrypt_eea1 \ diff --git a/openair3/TEST/test_aes128_ctr.c b/openair3/TEST/test_aes128_ctr.c new file mode 100644 index 0000000000..b29b0d2e16 --- /dev/null +++ b/openair3/TEST/test_aes128_ctr.c @@ -0,0 +1,265 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +// TS 133 401 pag. 88 + +#include "../../common/utils/assertions.h" +#include "../SECU/aes_128_ctr.h" +#include + +#include +#include + +void test_1(void) +{ + aes_128_ctr_t p = { + .key = {0xd3, 0xc5, 0xd5, 0x92, 0x32, 0x7f, 0xb1, 0x1c, 0x40, 0x35, 0xc6, 0x68, 0x0a, 0xf8, 0xc6, 0xd1}, + .iv_p.count = ntohl(965368244), // {0x39, 0x8a, 0x59, 0xb4}, //965368244, // + .iv_p.bearer = 21, //{0x15}, + .iv_p.direction = 1 // {0x01} + }; + + uint8_t text[32] = {0x98, 0x1b, 0xa6, 0x82, 0x4c, 0x1b, 0xfb, 0x1a, 0xb4, 0x85, 0x47, 0x20, 0x29, 0xb7, 0x1d, 0x80, + 0x8c, 0xe3, 0x3e, 0x2c, 0xc3, 0xc0, 0xb5, 0xfc, 0x1f, 0x3d, 0xe8, 0xa6, 0xdc, 0x66, 0xb1, 0xf0}; + + uint8_t out[32] = {0}; + + // Cipher + aes_128_ctr(&p, 32, text, 32, out); + + uint8_t result[32] = {0xe9, 0xfe, 0xd8, 0xa6, 0x3d, 0x15, 0x53, 0x04, 0xd7, 0x1d, 0xf2, 0x0b, 0xf3, 0xe8, 0x22, 0x14, + 0xb2, 0x0e, 0xd7, 0xda, 0xd2, 0xf2, 0x33, 0xdc, 0x3c, 0x22, 0xd7, 0xbd, 0xee, 0xed, 0x8e, 0x78}; + + int rc = memcmp(out, result, 32); + DevAssert(rc == 0 && "Ciphering did not produce the expected results"); + + uint8_t text_decipher[32] = {0}; + + // Decipher + aes_128_ctr(&p, 32, out, 32, text_decipher); + + rc = memcmp(text, text_decipher, 32); + DevAssert(rc == 0 && "Text and deciphered text do not match"); +} + +void test_2(void) +{ + aes_128_ctr_t p = { + .key = {0x2b, 0xd6, 0x45, 0x9f, 0x82, 0xc4, 0x40, 0xe0, 0x95, 0x2c, 0x49, 0x10, 0x48, 0x05, 0xff, 0x48}, + .iv_p.count = ntohl(3329599051), // c675a64b , // + .iv_p.bearer = 12, //{0x0c}, + .iv_p.direction = 1 // {0x01} + }; + + uint8_t text[100] = {0x7e, 0xc6, 0x12, 0x72, 0x74, 0x3b, 0xf1, 0x61, 0x47, 0x26, 0x44, 0x6a, 0x6c, 0x38, 0xce, 0xd1, 0x66, 0xf6, 0xca, 0x76, 0xeb, 0x54, 0x30, 0x04, 0x42, + 0x86, 0x34, 0x6c, 0xef, 0x13, 0x0f, 0x92, 0x92, 0x2b, 0x03, 0x45, 0x0d, 0x3a, 0x99, 0x75, 0xe5, 0xbd, 0x2e, 0xa0, 0xeb, 0x55, 0xad, 0x8e, 0x1b, 0x19, + 0x9e, 0x3e, 0xc4, 0x31, 0x60, 0x20, 0xe9, 0xa1, 0xb2, 0x85, 0xe7, 0x62, 0x79, 0x53, 0x59, 0xb7, 0xbd, 0xfd, 0x39, 0xbe, 0xf4, 0xb2, 0x48, 0x45, 0x83, + 0xd5, 0xaf, 0xe0, 0x82, 0xae, 0xe6, 0x38, 0xbf, 0x5f, 0xd5, 0xa6, 0x06, 0x19, 0x39, 0x01, 0xa0, 0x8f, 0x4a, 0xb4, 0x1a, 0xab, 0x9b, 0x13, 0x48, 0x80}; + + uint8_t out[100] = {0}; + aes_128_ctr(&p, 100, text, 100, out); + + uint8_t result[100] = {0x59, 0x61, 0x60, 0x53, 0x53, 0xc6, 0x4b, 0xdc, 0xa1, 0x5b, 0x19, 0x5e, 0x28, 0x85, 0x53, 0xa9, 0x10, 0x63, 0x25, 0x06, 0xd6, 0x20, 0x0a, 0xa7, 0x90, + 0xc4, 0xc8, 0x06, 0xc9, 0x99, 0x04, 0xcf, 0x24, 0x45, 0xcc, 0x50, 0xbb, 0x1c, 0xf1, 0x68, 0xa4, 0x96, 0x73, 0x73, 0x4e, 0x08, 0x1b, 0x57, 0xe3, 0x24, + 0xce, 0x52, 0x59, 0xc0, 0xe7, 0x8d, 0x4c, 0xd9, 0x7b, 0x87, 0x09, 0x76, 0x50, 0x3c, 0x09, 0x43, 0xf2, 0xcb, 0x5a, 0xe8, 0xf0, 0x52, 0xc7, 0xb7, 0xd3, + 0x92, 0x23, 0x95, 0x87, 0xb8, 0x95, 0x60, 0x86, 0xbc, 0xab, 0x18, 0x83, 0x60, 0x42, 0xe2, 0xe6, 0xce, 0x42, 0x43, 0x2a, 0x17, 0x10, 0x5c, 0x53, 0xd0}; + + int rc = memcmp(out, result, 99); + DevAssert(rc == 0 && "Ciphering did not produce the expected results"); + + uint8_t text_decipher[100] = {0}; + aes_128_ctr(&p, 99, out, 99, text_decipher); + + rc = memcmp(text, text_decipher, 99); + DevAssert(rc == 0 && "Text and deciphered text do not match"); +} + +void test_3(void) +{ + aes_128_ctr_t p = {.key = {0x0a, 0x8b, 0x6b, 0xd8, 0xd9, 0xb0, 0x8b, 0x08, 0xd6, 0x4e, 0x32, 0xd1, 0x81, 0x77, 0x77, 0xfb}, + .iv_p.count = ntohl(1414351309), // 544d49cd + .iv_p.bearer = 4, + .iv_p.direction = 0}; + + uint8_t text[40] = {0xfd, 0x40, 0xa4, 0x1d, 0x37, 0x0a, 0x1f, 0x65, 0x74, 0x50, 0x95, 0x68, 0x7d, 0x47, 0xba, 0x1d, 0x36, 0xd2, 0x34, 0x9e, + 0x23, 0xf6, 0x44, 0x39, 0x2c, 0x8e, 0xa9, 0xc4, 0x9d, 0x40, 0xc1, 0x32, 0x71, 0xaf, 0xf2, 0x64, 0xd0, 0xf2, 0x48, 0x00}; + + // Cipher + uint8_t out[40] = {0}; + aes_128_ctr(&p, 40, text, 40, out); + + uint8_t result[40] = {0x75, 0x75, 0x0d, 0x37, 0xb4, 0xbb, 0xa2, 0xa4, 0xde, 0xdb, 0x34, 0x23, 0x5b, 0xd6, 0x8c, 0x66, 0x45, 0xac, 0xda, 0xac, + 0xa4, 0x81, 0x38, 0xa3, 0xb0, 0xc4, 0x71, 0xe2, 0xa7, 0x04, 0x1a, 0x57, 0x64, 0x23, 0xd2, 0x92, 0x72, 0x87, 0xf0, 0x00}; + + int rc = memcmp(out, result, 39); + DevAssert(rc == 0 && "Ciphering did not produce the expected results"); + + // Decipher + uint8_t text_decipher[40] = {0}; + aes_128_ctr(&p, 40, out, 40, text_decipher); + + rc = memcmp(text, text_decipher, 39); + DevAssert(rc == 0 && "Text and deciphered text do not match"); +} + +void test_4(void) +{ + aes_128_ctr_t p = {.key = {0xaa, 0x1f, 0x95, 0xae, 0xa5, 0x33, 0xbc, 0xb3, 0x2e, 0xb6, 0x3b, 0xf5, 0x2d, 0x8f, 0x83, 0x1a}, + .iv_p.count = ntohl(1926809201), // 72d8c671 + .iv_p.bearer = 16, + .iv_p.direction = 1}; + + uint8_t text[128] = {0xfb, 0x1b, 0x96, 0xc5, 0xc8, 0xba, 0xdf, 0xb2, 0xe8, 0xe8, 0xed, 0xfd, 0xe7, 0x8e, 0x57, 0xf2, 0xad, 0x81, 0xe7, 0x41, 0x03, 0xfc, 0x43, 0x0a, 0x53, 0x4d, + 0xcc, 0x37, 0xaf, 0xce, 0xc7, 0x0e, 0x15, 0x17, 0xbb, 0x06, 0xf2, 0x72, 0x19, 0xda, 0xe4, 0x90, 0x22, 0xdd, 0xc4, 0x7a, 0x06, 0x8d, 0xe4, 0xc9, 0x49, 0x6a, + 0x95, 0x1a, 0x6b, 0x09, 0xed, 0xbd, 0xc8, 0x64, 0xc7, 0xad, 0xbd, 0x74, 0x0a, 0xc5, 0x0c, 0x02, 0x2f, 0x30, 0x82, 0xba, 0xfd, 0x22, 0xd7, 0x81, 0x97, 0xc5, + 0xd5, 0x08, 0xb9, 0x77, 0xbc, 0xa1, 0x3f, 0x32, 0xe6, 0x52, 0xe7, 0x4b, 0xa7, 0x28, 0x57, 0x60, 0x77, 0xce, 0x62, 0x8c, 0x53, 0x5e, 0x87, 0xdc, 0x60, 0x77, + 0xba, 0x07, 0xd2, 0x90, 0x68, 0x59, 0x0c, 0x8c, 0xb5, 0xf1, 0x08, 0x8e, 0x08, 0x2c, 0xfa, 0x0e, 0xc9, 0x61, 0x30, 0x2d, 0x69, 0xcf, 0x3d, 0x44}; + + // Cipher + uint8_t out[128] = {0}; + aes_128_ctr(&p, 128, text, 128, out); + + uint8_t result[128] = {0xdf, 0xb4, 0x40, 0xac, 0xb3, 0x77, 0x35, 0x49, 0xef, 0xc0, 0x46, 0x28, 0xae, 0xb8, 0xd8, 0x15, 0x62, 0x75, 0x23, 0x0b, 0xdc, 0x69, 0x0d, 0x94, 0xb0, 0x0d, + 0x8d, 0x95, 0xf2, 0x8c, 0x4b, 0x56, 0x30, 0x7f, 0x60, 0xf4, 0xca, 0x55, 0xeb, 0xa6, 0x61, 0xeb, 0xba, 0x72, 0xac, 0x80, 0x8f, 0xa8, 0xc4, 0x9e, 0x26, 0x78, + 0x8e, 0xd0, 0x4a, 0x5d, 0x60, 0x6c, 0xb4, 0x18, 0xde, 0x74, 0x87, 0x8b, 0x9a, 0x22, 0xf8, 0xef, 0x29, 0x59, 0x0b, 0xc4, 0xeb, 0x57, 0xc9, 0xfa, 0xf7, 0xc4, + 0x15, 0x24, 0xa8, 0x85, 0xb8, 0x97, 0x9c, 0x42, 0x3f, 0x2f, 0x8f, 0x8e, 0x05, 0x92, 0xa9, 0x87, 0x92, 0x01, 0xbe, 0x7f, 0xf9, 0x77, 0x7a, 0x16, 0x2a, 0xb8, + 0x10, 0xfe, 0xb3, 0x24, 0xba, 0x74, 0xc4, 0xc1, 0x56, 0xe0, 0x4d, 0x39, 0x09, 0x72, 0x09, 0x65, 0x3a, 0xc3, 0x3e, 0x5a, 0x5f, 0x2d, 0x88, 0x64}; + + int rc = memcmp(out, result, 127); + DevAssert(rc == 0 && "Ciphering did not produce the expected results"); + + // Decipher + uint8_t text_decipher[128] = {0}; + aes_128_ctr(&p, 128, out, 128, text_decipher); + + rc = memcmp(text, text_decipher, 127); + DevAssert(rc == 0 && "Text and deciphered text do not match"); +} + +void test_5(void) +{ + aes_128_ctr_t p = {.key = {0x96, 0x18, 0xae, 0x46, 0x89, 0x1f, 0x86, 0x57, 0x8e, 0xeb, 0xe9, 0x0e, 0xf7, 0xa1, 0x20, 0x2e}, + .iv_p.count = ntohl(3329599051), // c675a64b + .iv_p.bearer = 12, + .iv_p.direction = 1}; + + uint8_t text[156] = {0x8d, 0xaa, 0x17, 0xb1, 0xae, 0x05, 0x05, 0x29, 0xc6, 0x82, 0x7f, 0x28, 0xc0, 0xef, 0x6a, 0x12, 0x42, 0xe9, 0x3f, 0x8b, 0x31, 0x4f, 0xb1, 0x8a, 0x77, 0xf7, + 0x90, 0xae, 0x04, 0x9f, 0xed, 0xd6, 0x12, 0x26, 0x7f, 0xec, 0xae, 0xfc, 0x45, 0x01, 0x74, 0xd7, 0x6d, 0x9f, 0x9a, 0xa7, 0x75, 0x5a, 0x30, 0xcd, 0x90, 0xa9, + 0xa5, 0x87, 0x4b, 0xf4, 0x8e, 0xaf, 0x70, 0xee, 0xa3, 0xa6, 0x2a, 0x25, 0x0a, 0x8b, 0x6b, 0xd8, 0xd9, 0xb0, 0x8b, 0x08, 0xd6, 0x4e, 0x32, 0xd1, 0x81, 0x77, + 0x77, 0xfb, 0x54, 0x4d, 0x49, 0xcd, 0x49, 0x72, 0x0e, 0x21, 0x9d, 0xbf, 0x8b, 0xbe, 0xd3, 0x39, 0x04, 0xe1, 0xfd, 0x40, 0xa4, 0x1d, 0x37, 0x0a, 0x1f, 0x65, + 0x74, 0x50, 0x95, 0x68, 0x7d, 0x47, 0xba, 0x1d, 0x36, 0xd2, 0x34, 0x9e, 0x23, 0xf6, 0x44, 0x39, 0x2c, 0x8e, 0xa9, 0xc4, 0x9d, 0x40, 0xc1, 0x32, 0x71, 0xaf, + 0xf2, 0x64, 0xd0, 0xf2, 0x48, 0x41, 0xd6, 0x46, 0x5f, 0x09, 0x96, 0xff, 0x84, 0xe6, 0x5f, 0xc5, 0x17, 0xc5, 0x3e, 0xfc, 0x33, 0x63, 0xc3, 0x84, 0x92, 0xa8}; + + // Cipher + uint8_t out[156] = {0}; + aes_128_ctr(&p, 156, text, 156, out); + + uint8_t result[156] = {0x91, 0x9c, 0x8c, 0x33, 0xd6, 0x67, 0x89, 0x70, 0x3d, 0x05, 0xa0, 0xd7, 0xce, 0x82, 0xa2, 0xae, 0xac, 0x4e, 0xe7, 0x6c, 0x0f, 0x4d, 0xa0, 0x50, 0x33, 0x5e, + 0x8a, 0x84, 0xe7, 0x89, 0x7b, 0xa5, 0xdf, 0x2f, 0x36, 0xbd, 0x51, 0x3e, 0x3d, 0x0c, 0x85, 0x78, 0xc7, 0xa0, 0xfc, 0xf0, 0x43, 0xe0, 0x3a, 0xa3, 0xa3, 0x9f, + 0xba, 0xad, 0x7d, 0x15, 0xbe, 0x07, 0x4f, 0xaa, 0x5d, 0x90, 0x29, 0xf7, 0x1f, 0xb4, 0x57, 0xb6, 0x47, 0x83, 0x47, 0x14, 0xb0, 0xe1, 0x8f, 0x11, 0x7f, 0xca, + 0x10, 0x67, 0x79, 0x45, 0x09, 0x6c, 0x8c, 0x5f, 0x32, 0x6b, 0xa8, 0xd6, 0x09, 0x5e, 0xb2, 0x9c, 0x3e, 0x36, 0xcf, 0x24, 0x5d, 0x16, 0x22, 0xaa, 0xfe, 0x92, + 0x1f, 0x75, 0x66, 0xc4, 0xf5, 0xd6, 0x44, 0xf2, 0xf1, 0xfc, 0x0e, 0xc6, 0x84, 0xdd, 0xb2, 0x13, 0x49, 0x74, 0x76, 0x22, 0xe2, 0x09, 0x29, 0x5d, 0x27, 0xff, + 0x3f, 0x95, 0x62, 0x33, 0x71, 0xd4, 0x9b, 0x14, 0x7c, 0x0a, 0xf4, 0x86, 0x17, 0x1f, 0x22, 0xcd, 0x04, 0xb1, 0xcb, 0xeb, 0x26, 0x58, 0x22, 0x3e, 0x69, 0x38}; + + int rc = memcmp(out, result, 155); + DevAssert(rc == 0 && "Ciphering did not produce the expected results"); + + // Decipher + uint8_t text_decipher[156] = {0}; + aes_128_ctr(&p, 156, out, 156, text_decipher); + + rc = memcmp(text, text_decipher, 155); + DevAssert(rc == 0 && "Text and deciphered text do not match"); +} + +void test_6(void) +{ + aes_128_ctr_t p = {.key = {0x54, 0xf4, 0xe2, 0xe0, 0x4c, 0x83, 0x78, 0x6e, 0xec, 0x8f, 0xb5, 0xab, 0xe8, 0xe3, 0x65, 0x66}, + .iv_p.count = ntohl(2896491791), // aca4f50f + .iv_p.bearer = 11, + .iv_p.direction = 0}; + + uint8_t text[512] = {0x40, 0x98, 0x1b, 0xa6, 0x82, 0x4c, 0x1b, 0xfb, 0x42, 0x86, 0xb2, 0x99, 0x78, 0x3d, 0xaf, 0x44, 0x2c, 0x09, 0x9f, 0x7a, 0xb0, 0xf5, 0x8d, 0x5c, 0x8e, 0x46, 0xb1, 0x04, 0xf0, + 0x8f, 0x01, 0xb4, 0x1a, 0xb4, 0x85, 0x47, 0x20, 0x29, 0xb7, 0x1d, 0x36, 0xbd, 0x1a, 0x3d, 0x90, 0xdc, 0x3a, 0x41, 0xb4, 0x6d, 0x51, 0x67, 0x2a, 0xc4, 0xc9, 0x66, 0x3a, 0x2b, + 0xe0, 0x63, 0xda, 0x4b, 0xc8, 0xd2, 0x80, 0x8c, 0xe3, 0x3e, 0x2c, 0xcc, 0xbf, 0xc6, 0x34, 0xe1, 0xb2, 0x59, 0x06, 0x08, 0x76, 0xa0, 0xfb, 0xb5, 0xa4, 0x37, 0xeb, 0xcc, 0x8d, + 0x31, 0xc1, 0x9e, 0x44, 0x54, 0x31, 0x87, 0x45, 0xe3, 0xfa, 0x16, 0xbb, 0x11, 0xad, 0xae, 0x24, 0x88, 0x79, 0xfe, 0x52, 0xdb, 0x25, 0x43, 0xe5, 0x3c, 0xf4, 0x45, 0xd3, 0xd8, + 0x28, 0xce, 0x0b, 0xf5, 0xc5, 0x60, 0x59, 0x3d, 0x97, 0x27, 0x8a, 0x59, 0x76, 0x2d, 0xd0, 0xc2, 0xc9, 0xcd, 0x68, 0xd4, 0x49, 0x6a, 0x79, 0x25, 0x08, 0x61, 0x40, 0x14, 0xb1, + 0x3b, 0x6a, 0xa5, 0x11, 0x28, 0xc1, 0x8c, 0xd6, 0xa9, 0x0b, 0x87, 0x97, 0x8c, 0x2f, 0xf1, 0xca, 0xbe, 0x7d, 0x9f, 0x89, 0x8a, 0x41, 0x1b, 0xfd, 0xb8, 0x4f, 0x68, 0xf6, 0x72, + 0x7b, 0x14, 0x99, 0xcd, 0xd3, 0x0d, 0xf0, 0x44, 0x3a, 0xb4, 0xa6, 0x66, 0x53, 0x33, 0x0b, 0xcb, 0xa1, 0x10, 0x5e, 0x4c, 0xec, 0x03, 0x4c, 0x73, 0xe6, 0x05, 0xb4, 0x31, 0x0e, + 0xaa, 0xad, 0xcf, 0xd5, 0xb0, 0xca, 0x27, 0xff, 0xd8, 0x9d, 0x14, 0x4d, 0xf4, 0x79, 0x27, 0x59, 0x42, 0x7c, 0x9c, 0xc1, 0xf8, 0xcd, 0x8c, 0x87, 0x20, 0x23, 0x64, 0xb8, 0xa6, + 0x87, 0x95, 0x4c, 0xb0, 0x5a, 0x8d, 0x4e, 0x2d, 0x99, 0xe7, 0x3d, 0xb1, 0x60, 0xde, 0xb1, 0x80, 0xad, 0x08, 0x41, 0xe9, 0x67, 0x41, 0xa5, 0xd5, 0x9f, 0xe4, 0x18, 0x9f, 0x15, + 0x42, 0x00, 0x26, 0xfe, 0x4c, 0xd1, 0x21, 0x04, 0x93, 0x2f, 0xb3, 0x8f, 0x73, 0x53, 0x40, 0x43, 0x8a, 0xaf, 0x7e, 0xca, 0x6f, 0xd5, 0xcf, 0xd3, 0xa1, 0x95, 0xce, 0x5a, 0xbe, + 0x65, 0x27, 0x2a, 0xf6, 0x07, 0xad, 0xa1, 0xbe, 0x65, 0xa6, 0xb4, 0xc9, 0xc0, 0x69, 0x32, 0x34, 0x09, 0x2c, 0x4d, 0x01, 0x8f, 0x17, 0x56, 0xc6, 0xdb, 0x9d, 0xc8, 0xa6, 0xd8, + 0x0b, 0x88, 0x81, 0x38, 0x61, 0x6b, 0x68, 0x12, 0x62, 0xf9, 0x54, 0xd0, 0xe7, 0x71, 0x17, 0x48, 0x78, 0x0d, 0x92, 0x29, 0x1d, 0x86, 0x29, 0x99, 0x72, 0xdb, 0x74, 0x1c, 0xfa, + 0x4f, 0x37, 0xb8, 0xb5, 0x6c, 0xdb, 0x18, 0xa7, 0xca, 0x82, 0x18, 0xe8, 0x6e, 0x4b, 0x4b, 0x71, 0x6a, 0x4d, 0x04, 0x37, 0x1f, 0xbe, 0xc2, 0x62, 0xfc, 0x5a, 0xd0, 0xb3, 0x81, + 0x9b, 0x18, 0x7b, 0x97, 0xe5, 0x5b, 0x1a, 0x4d, 0x7c, 0x19, 0xee, 0x24, 0xc8, 0xb4, 0xd7, 0x72, 0x3c, 0xfe, 0xdf, 0x04, 0x5b, 0x8a, 0xca, 0xe4, 0x86, 0x95, 0x17, 0xd8, 0x0e, + 0x50, 0x61, 0x5d, 0x90, 0x35, 0xd5, 0xd9, 0xc5, 0xa4, 0x0a, 0xf6, 0x02, 0x28, 0x0b, 0x54, 0x25, 0x97, 0xb0, 0xcb, 0x18, 0x61, 0x9e, 0xeb, 0x35, 0x92, 0x57, 0x59, 0xd1, 0x95, + 0xe1, 0x00, 0xe8, 0xe4, 0xaa, 0x0c, 0x38, 0xa3, 0xc2, 0xab, 0xe0, 0xf3, 0xd8, 0xff, 0x04, 0xf3, 0xc3, 0x3c, 0x29, 0x50, 0x69, 0xc2, 0x36, 0x94, 0xb5, 0xbb, 0xea, 0xcd, 0xd5, + 0x42, 0xe2, 0x8e, 0x8a, 0x94, 0xed, 0xb9, 0x11, 0x9f, 0x41, 0x2d, 0x05, 0x4b, 0xe1, 0xfa, 0x72, 0x00, 0xb0, 0x90, 0x00}; + + // Cipher + uint8_t out[512] = {0}; + aes_128_ctr(&p, 512, text, 512, out); + + uint8_t result[512] = {0x5c, 0xb7, 0x2c, 0x6e, 0xdc, 0x87, 0x8f, 0x15, 0x66, 0xe1, 0x02, 0x53, 0xaf, 0xc3, 0x64, 0xc9, 0xfa, 0x54, 0x0d, 0x91, 0x4d, 0xb9, 0x4c, 0xbe, 0xe2, 0x75, 0xd0, 0x91, 0x7c, + 0xa6, 0xaf, 0x0d, 0x77, 0xac, 0xb4, 0xef, 0x3b, 0xbe, 0x1a, 0x72, 0x2b, 0x2e, 0xf5, 0xbd, 0x1d, 0x4b, 0x8e, 0x2a, 0xa5, 0x02, 0x4e, 0xc1, 0x38, 0x8a, 0x20, 0x1e, 0x7b, 0xce, + 0x79, 0x20, 0xae, 0xc6, 0x15, 0x89, 0x5f, 0x76, 0x3a, 0x55, 0x64, 0xdc, 0xc4, 0xc4, 0x82, 0xa2, 0xee, 0x1d, 0x8b, 0xfe, 0xcc, 0x44, 0x98, 0xec, 0xa8, 0x3f, 0xbb, 0x75, 0xf9, + 0xab, 0x53, 0x0e, 0x0d, 0xaf, 0xbe, 0xde, 0x2f, 0xa5, 0x89, 0x5b, 0x82, 0x99, 0x1b, 0x62, 0x77, 0xc5, 0x29, 0xe0, 0xf2, 0x52, 0x9d, 0x7f, 0x79, 0x60, 0x6b, 0xe9, 0x67, 0x06, + 0x29, 0x6d, 0xed, 0xfa, 0x9d, 0x74, 0x12, 0xb6, 0x16, 0x95, 0x8c, 0xb5, 0x63, 0xc6, 0x78, 0xc0, 0x28, 0x25, 0xc3, 0x0d, 0x0a, 0xee, 0x77, 0xc4, 0xc1, 0x46, 0xd2, 0x76, 0x54, + 0x12, 0x42, 0x1a, 0x80, 0x8d, 0x13, 0xce, 0xc8, 0x19, 0x69, 0x4c, 0x75, 0xad, 0x57, 0x2e, 0x9b, 0x97, 0x3d, 0x94, 0x8b, 0x81, 0xa9, 0x33, 0x7c, 0x3b, 0x2a, 0x17, 0x19, 0x2e, + 0x22, 0xc2, 0x06, 0x9f, 0x7e, 0xd1, 0x16, 0x2a, 0xf4, 0x4c, 0xde, 0xa8, 0x17, 0x60, 0x36, 0x65, 0xe8, 0x07, 0xce, 0x40, 0xc8, 0xe0, 0xdd, 0x9d, 0x63, 0x94, 0xdc, 0x6e, 0x31, + 0x15, 0x3f, 0xe1, 0x95, 0x5c, 0x47, 0xaf, 0xb5, 0x1f, 0x26, 0x17, 0xee, 0x0c, 0x5e, 0x3b, 0x8e, 0xf1, 0xad, 0x75, 0x74, 0xed, 0x34, 0x3e, 0xdc, 0x27, 0x43, 0xcc, 0x94, 0xc9, + 0x90, 0xe1, 0xf1, 0xfd, 0x26, 0x42, 0x53, 0xc1, 0x78, 0xde, 0xa7, 0x39, 0xc0, 0xbe, 0xfe, 0xeb, 0xcd, 0x9f, 0x9b, 0x76, 0xd4, 0x9c, 0x10, 0x15, 0xc9, 0xfe, 0xcf, 0x50, 0xe5, + 0x3b, 0x8b, 0x52, 0x04, 0xdb, 0xcd, 0x3e, 0xed, 0x86, 0x38, 0x55, 0xda, 0xbc, 0xdc, 0xc9, 0x4b, 0x31, 0xe3, 0x18, 0x02, 0x15, 0x68, 0x85, 0x5c, 0x8b, 0x9e, 0x52, 0xa9, 0x81, + 0x95, 0x7a, 0x11, 0x28, 0x27, 0xf9, 0x78, 0xba, 0x96, 0x0f, 0x14, 0x47, 0x91, 0x1b, 0x31, 0x7b, 0x55, 0x11, 0xfb, 0xcc, 0x7f, 0xb1, 0x3a, 0xc1, 0x53, 0xdb, 0x74, 0x25, 0x11, + 0x17, 0xe4, 0x86, 0x1e, 0xb9, 0xe8, 0x3b, 0xff, 0xff, 0xc4, 0xeb, 0x77, 0x55, 0x57, 0x90, 0x38, 0xe5, 0x79, 0x24, 0xb1, 0xf7, 0x8b, 0x3e, 0x1a, 0xd9, 0x0b, 0xab, 0x2a, 0x07, + 0x87, 0x1b, 0x72, 0xdb, 0x5e, 0xef, 0x96, 0xc3, 0x34, 0x04, 0x49, 0x66, 0xdb, 0x0c, 0x37, 0xca, 0xfd, 0x1a, 0x89, 0xe5, 0x64, 0x6a, 0x35, 0x80, 0xeb, 0x64, 0x65, 0xf1, 0x21, + 0xdc, 0xe9, 0xcb, 0x88, 0xd8, 0x5b, 0x96, 0xcf, 0x23, 0xcc, 0xcc, 0xd4, 0x28, 0x07, 0x67, 0xbe, 0xe8, 0xee, 0xb2, 0x3d, 0x86, 0x52, 0x46, 0x1d, 0xb6, 0x49, 0x31, 0x03, 0x00, + 0x3b, 0xaf, 0x89, 0xf5, 0xe1, 0x82, 0x61, 0xea, 0x43, 0xc8, 0x4a, 0x92, 0xeb, 0xff, 0xff, 0xe4, 0x90, 0x9d, 0xc4, 0x6c, 0x51, 0x92, 0xf8, 0x25, 0xf7, 0x70, 0x60, 0x0b, 0x96, + 0x02, 0xc5, 0x57, 0xb5, 0xf8, 0xb4, 0x31, 0xa7, 0x9d, 0x45, 0x97, 0x7d, 0xd9, 0xc4, 0x1b, 0x86, 0x3d, 0xa9, 0xe1, 0x42, 0xe9, 0x00, 0x20, 0xcf, 0xd0, 0x74, 0xd6, 0x92, 0x7b, + 0x7a, 0xb3, 0xb6, 0x72, 0x5d, 0x1a, 0x6f, 0x3f, 0x98, 0xb9, 0xc9, 0xda, 0xa8, 0x98, 0x2a, 0xff, 0x06, 0x78, 0x28, 0x00}; + + int rc = memcmp(out, result, 483); + DevAssert(rc == 0 && "Ciphering did not produce the expected results"); + + // Decipher + uint8_t text_decipher[512] = {0}; + aes_128_ctr(&p, 512, out, 512, text_decipher); + + rc = memcmp(text, text_decipher, 483); + DevAssert(rc == 0 && "Text and deciphered text do not match"); +} + +void doit(void) +{ + test_1(); + printf("AES-128: Test 1 passed\n"); + test_2(); + printf("AES-128: Test 2 passed\n"); + test_3(); + printf("AES-128: Test 3 passed\n"); + test_4(); + printf("AES-128: Test 4 passed\n"); + test_5(); + printf("AES-128: Test 5 passed\n"); + test_6(); + printf("AES-128: Test 6 passed\n"); +} diff --git a/openair3/TEST/test_aes128_ctr_decrypt.c b/openair3/TEST/test_aes128_ctr_decrypt.c deleted file mode 100644 index 928853c9ba..0000000000 --- a/openair3/TEST/test_aes128_ctr_decrypt.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include -#include -#include -#include - -#include "test_util.h" - -#include "secu_defs.h" - -#include -#include -#include - -static -void test_uncipher_ctr(const struct nettle_cipher *cipher, const uint8_t *key, - unsigned key_length, const uint8_t *cipheredtext, - unsigned length, const uint8_t *cleartext, const uint8_t *ictr) -{ - void *ctx = malloc(cipher->context_size); - uint8_t *data = malloc(length); - uint8_t *ctr = malloc(cipher->block_size); - -#if NETTLE_VERSION_MAJOR < 3 - cipher->set_encrypt_key(ctx, key_length, key); -#else - cipher->set_encrypt_key(ctx, key); -#endif - - memcpy(ctr, ictr, cipher->block_size); - - ctr_crypt(ctx, cipher->encrypt, - cipher->block_size, ctr, - length, data, cipheredtext); - - if (compare_buffer(data, length, cleartext, length) != 0) { - fail("Fail: test_uncipher_ctr\n"); - } - - free(ctx); - free(data); - free(ctr); -} - -void doit (void) -{ - /* From NIST spec 800-38a on AES modes, - * - * http://csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38A.pdf - * - * F.5 CTR Example Vectors - */ - /* F.5.1 CTR-AES128.Encrypt */ - test_uncipher_ctr(&nettle_aes128, - HL("2b7e151628aed2a6abf7158809cf4f3c"), - HL("6bc1bee22e409f96e93d7e117393172a" - "ae2d8a571e03ac9c9eb76fac45af8e51" - "30c81c46a35ce411e5fbc1191a0a52ef" - "f69f2445df4f9b17ad2b417be66c3710"), - H("874d6191b620e3261bef6864990db6ce" - "9806f66b7970fdff8617187bb9fffdff" - "5ae4df3edbd5d35e5b4f09020db03eab" - "1e031dda2fbe03d1792170a0f3009cee"), - H("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")); -} diff --git a/openair3/TEST/test_aes128_ctr_encrypt.c b/openair3/TEST/test_aes128_ctr_encrypt.c deleted file mode 100644 index 071aa603a9..0000000000 --- a/openair3/TEST/test_aes128_ctr_encrypt.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include -#include -#include -#include - -#include "test_util.h" - -#include "secu_defs.h" - -#include -#include -#include - -static void test_cipher_ctr(const struct nettle_cipher *cipher, const uint8_t *key, - unsigned key_length, const uint8_t *cleartext, unsigned length, - const uint8_t *ciphertext, const uint8_t *ictr) -{ - void *ctx = malloc(cipher->context_size); - uint8_t *data = malloc(length); - uint8_t *ctr = malloc(cipher->block_size); - -#if NETTLE_VERSION_MAJOR < 3 - cipher->set_encrypt_key(ctx, key_length, key); -#else - cipher->set_encrypt_key(ctx, key); -#endif - - memcpy(ctr, ictr, cipher->block_size); - - ctr_crypt(ctx, cipher->encrypt, - cipher->block_size, ctr, - length, data, cleartext); - - if (compare_buffer(data, length, ciphertext, length) != 0) { - fail("Fail: test_cipher_ctr"); - } - - free(ctx); - free(data); - free(ctr); -} - -void doit (void) -{ - /* From NIST spec 800-38a on AES modes, - * - * http://csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38A.pdf - * - * F.5 CTR Example Vectors - */ - /* F.5.1 CTR-AES128.Encrypt */ - test_cipher_ctr(&nettle_aes128, - HL("2b7e151628aed2a6abf7158809cf4f3c"), - HL("6bc1bee22e409f96e93d7e117393172a" - "ae2d8a571e03ac9c9eb76fac45af8e51" - "30c81c46a35ce411e5fbc1191a0a52ef" - "f69f2445df4f9b17ad2b417be66c3710"), - H("874d6191b620e3261bef6864990db6ce" - "9806f66b7970fdff8617187bb9fffdff" - "5ae4df3edbd5d35e5b4f09020db03eab" - "1e031dda2fbe03d1792170a0f3009cee"), - H("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")); -} diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 8045e7f635..b598a29c16 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -94,7 +94,6 @@ typedef struct Gtpv1uExtHeader { #define GTP_END_MARKER (254) #define GTP_GPDU (255) - typedef struct gtpv1u_bearer_s { /* TEID used in dl and ul */ teid_t teid_incoming; ///< eNB TEID @@ -127,8 +126,7 @@ class gtpEndPoint { uint8_t foundAddr[20]; int foundAddrLen; int ipVersion; - map ue2te_mapping; - map te2ue_mapping; + map ue2te_mapping; // we use the same port number for source and destination address // this allow using non standard gtp port number (different from 2152) // and so, for example tu run 4G and 5G cores on one system @@ -142,7 +140,7 @@ class gtpEndPoints { pthread_mutex_t gtp_lock=PTHREAD_MUTEX_INITIALIZER; // the instance id will be the Linux socket handler, as this is uniq map instances; - + map te2ue_mapping; gtpEndPoints() { unsigned int seed; fill_random(&seed, sizeof(seed)); @@ -593,22 +591,17 @@ teid_t newGtpuCreateTunnel(instance_t instance, teid_t incoming_teid=gtpv1uNewTeid(); - while ( inst->te2ue_mapping.find(incoming_teid) != inst->te2ue_mapping.end() ) { + while (globGtp.te2ue_mapping.find(incoming_teid) != globGtp.te2ue_mapping.end()) { LOG_W(GTPU, "[%ld] generated a random Teid that exists, re-generating (%x)\n", instance, incoming_teid); incoming_teid=gtpv1uNewTeid(); }; - inst->te2ue_mapping[incoming_teid].ue_id=ue_id; - - inst->te2ue_mapping[incoming_teid].incoming_rb_id= incoming_bearer_id; - - inst->te2ue_mapping[incoming_teid].outgoing_teid= outgoing_teid; - - inst->te2ue_mapping[incoming_teid].callBack=callBack; - - inst->te2ue_mapping[incoming_teid].callBackSDAP = callBackSDAP; - - inst->te2ue_mapping[incoming_teid].pdusession_id = (uint8_t)outgoing_bearer_id; + globGtp.te2ue_mapping[incoming_teid].ue_id = ue_id; + globGtp.te2ue_mapping[incoming_teid].incoming_rb_id = incoming_bearer_id; + globGtp.te2ue_mapping[incoming_teid].outgoing_teid = outgoing_teid; + globGtp.te2ue_mapping[incoming_teid].callBack = callBack; + globGtp.te2ue_mapping[incoming_teid].callBackSDAP = callBackSDAP; + globGtp.te2ue_mapping[incoming_teid].pdusession_id = (uint8_t)outgoing_bearer_id; gtpv1u_bearer_t *tmp=&inst->ue2te_mapping[ue_id].bearers[outgoing_bearer_id]; @@ -641,13 +634,14 @@ teid_t newGtpuCreateTunnel(instance_t instance, pthread_mutex_unlock(&globGtp.gtp_lock); char ip4[INET_ADDRSTRLEN]; char ip6[INET6_ADDRSTRLEN]; - LOG_I(GTPU, "[%ld] Created tunnel for UE ID %lu, teid for DL: %x, teid for UL %x to remote IPv4: %s, IPv6 %s\n", + LOG_I(GTPU, + "[%ld] Created tunnel for UE ID %lu, teid for incoming: %x, teid for outgoing %x to remote IPv4: %s, IPv6 %s\n", instance, ue_id, tmp->teid_incoming, tmp->teid_outgoing, - inet_ntop(AF_INET,(void *)&tmp->outgoing_ip_addr, ip4,INET_ADDRSTRLEN ), - inet_ntop(AF_INET6,(void *)&tmp->outgoing_ip6_addr.s6_addr, ip6, INET6_ADDRSTRLEN)); + inet_ntop(AF_INET, (void *)&tmp->outgoing_ip_addr, ip4, INET_ADDRSTRLEN), + inet_ntop(AF_INET6, (void *)&tmp->outgoing_ip6_addr.s6_addr, ip6, INET6_ADDRSTRLEN)); return incoming_teid; } @@ -795,7 +789,7 @@ int newGtpuDeleteAllTunnels(instance_t instance, ue_id_t ue_id) { for (auto j=ptrUe->second.bearers.begin(); j!=ptrUe->second.bearers.end(); ++j) { - inst->te2ue_mapping.erase(j->second.teid_incoming); + globGtp.te2ue_mapping.erase(j->second.teid_incoming); nb++; } @@ -826,7 +820,7 @@ int newGtpuDeleteTunnels(instance_t instance, ue_id_t ue_id, int nbTunnels, pdus if ( ptr2 == ptrUe->second.bearers.end() ) { LOG_E(GTPU,"[%ld] GTP-U instance: delete of not existing tunnel UE ID:RAB: %ld/%x\n", instance, ue_id, pdusession_id[i]); } else { - inst->te2ue_mapping.erase(ptr2->second.teid_incoming); + globGtp.te2ue_mapping.erase(ptr2->second.teid_incoming); nb++; } } @@ -913,9 +907,9 @@ static int Gtpv1uHandleEndMarker(int h, // the socket Linux file handler is the instance id getInstRetInt(h); - auto tunnel=inst->te2ue_mapping.find(ntohl(msgHdr->teid)); + auto tunnel = globGtp.te2ue_mapping.find(ntohl(msgHdr->teid)); - if ( tunnel == inst->te2ue_mapping.end() ) { + if (tunnel == globGtp.te2ue_mapping.end()) { LOG_E(GTPU,"[%d] Received a incoming packet on unknown teid (%x) Dropping!\n", h, msgHdr->teid); pthread_mutex_unlock(&globGtp.gtp_lock); return GTPNOK; @@ -973,10 +967,9 @@ static int Gtpv1uHandleGpdu(int h, pthread_mutex_lock(&globGtp.gtp_lock); // the socket Linux file handler is the instance id getInstRetInt(h); + auto tunnel = globGtp.te2ue_mapping.find(ntohl(msgHdr->teid)); - auto tunnel=inst->te2ue_mapping.find(ntohl(msgHdr->teid)); - - if ( tunnel == inst->te2ue_mapping.end() ) { + if (tunnel == globGtp.te2ue_mapping.end()) { LOG_E(GTPU,"[%d] Received a incoming packet on unknown teid (%x) Dropping!\n", h, ntohl(msgHdr->teid)); pthread_mutex_unlock(&globGtp.gtp_lock); return GTPNOK; @@ -1143,10 +1136,7 @@ static int Gtpv1uHandleGpdu(int h, * according to TS 38.425: Fig. 5.5.2.2-1 and section 5.5.3.24*/ extensionHeader->length = 1+sizeof(DlDataDeliveryStatus_flagsT)+3+1+1; gtpv1uCreateAndSendMsg( - h, peerIp, peerPort, GTP_GPDU, - inst->te2ue_mapping[ntohl(msgHdr->teid)].outgoing_teid, - NULL, 0, false, false, 0, 0, NR_RAN_CONTAINER, - extensionHeader->buffer, extensionHeader->length); + h, peerIp, peerPort, GTP_GPDU, globGtp.te2ue_mapping[ntohl(msgHdr->teid)].outgoing_teid, NULL, 0, false, false, 0, 0, NR_RAN_CONTAINER, extensionHeader->buffer, extensionHeader->length); } LOG_D(GTPU,"[%d] Received a %d bytes packet for: teid:%x\n", h, @@ -1224,19 +1214,19 @@ void *gtpv1uTask(void *args) { if (message_p != NULL ) { openAddr_t addr= {0}; - - switch (ITTI_MSG_ID(message_p)) { - // DATA TO BE SENT TO UDP + const instance_t myInstance = ITTI_MSG_DESTINATION_INSTANCE(message_p); + const int msgType = ITTI_MSG_ID(message_p); + LOG_D(GTPU, "GTP-U received %s for instance %ld\n", messages_info[msgType].name, myInstance); + switch (msgType) { + // DATA TO BE SENT TO UDP case GTPV1U_TUNNEL_DATA_REQ: { - gtpv1uSend(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)), - >PV1U_TUNNEL_DATA_REQ(message_p), false, false); + gtpv1uSend(compatInst(myInstance), >PV1U_TUNNEL_DATA_REQ(message_p), false, false); } break; case GTPV1U_DU_BUFFER_REPORT_REQ:{ - gtpv1uSendDlDeliveryStatus(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)), - >PV1U_DU_BUFFER_REPORT_REQ(message_p)); + gtpv1uSendDlDeliveryStatus(compatInst(myInstance), >PV1U_DU_BUFFER_REPORT_REQ(message_p)); } break; @@ -1248,8 +1238,7 @@ void *gtpv1uTask(void *args) { break; case GTPV1U_ENB_END_MARKER_REQ: - gtpv1uEndTunnel(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)), - >PV1U_TUNNEL_DATA_REQ(message_p)); + gtpv1uEndTunnel(compatInst(myInstance), >PV1U_TUNNEL_DATA_REQ(message_p)); itti_free(TASK_GTPV1_U, GTPV1U_TUNNEL_DATA_REQ(message_p).buffer); break; diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h index 86d719c200..8729be9fa5 100644 --- a/openair3/ocp-gtpu/gtp_itf.h +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -93,8 +93,8 @@ extern "C" { gtpCallbackSDAP callBackSDAP); void GtpuUpdateTunnelOutgoingAddressAndTeid(instance_t instance, - ue_id_t ue_id, - ebi_t bearer_id, + ue_id_t ue_id, + ebi_t bearer_id, in_addr_t newOutgoingAddr, teid_t newOutgoingTeid); @@ -149,7 +149,7 @@ extern "C" { //RB_ENTRY(gtpv1u_ue_data_s) gtpv1u_ue_node; } gtpv1u_ue_data_t; - + #ifdef __cplusplus } #endif diff --git a/radio/USRP/USERSPACE/LIB/usrp_lib.cpp b/radio/USRP/USERSPACE/LIB/usrp_lib.cpp index 4168436295..c3cc7c2007 100644 --- a/radio/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/radio/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -320,21 +320,31 @@ static int trx_usrp_start(openair0_device *device) { return 0; } -static void trx_usrp_send_end_of_burst(usrp_state_t *s) { +static void trx_usrp_send_end_of_burst(usrp_state_t *s) +{ // if last packet sent was end of burst no need to do anything. otherwise send end of burst packet if (s->tx_md.end_of_burst) return; - s->tx_md.end_of_burst = true; s->tx_md.start_of_burst = false; s->tx_md.has_time_spec = false; + s->tx_stream->send("", 0, s->tx_md); +} - int32_t dummy = 0; - std::vector buffs; - for (size_t ch = 0; ch < s->tx_stream->get_num_channels(); ch++) - buffs.push_back(&dummy); // same buffer for each channel +static void trx_usrp_finish_rx(usrp_state_t *s) +{ + /* finish rx by sending STREAM_MODE_STOP_CONTINUOUS */ + uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + s->rx_stream->issue_stream_cmd(cmd); - s->tx_stream->send(buffs, 0, s->tx_md); + /* collect all remaining samples (not sure if needed) */ + size_t samples; + uint8_t buf[1024]; + std::vector buff_ptrs; + for (size_t i = 0; i < s->usrp->get_rx_num_channels(); i++) buff_ptrs.push_back(buf); + do { + samples = s->rx_stream->recv(buff_ptrs, sizeof(buf)/4, s->rx_md); + } while (samples > 0); } static void trx_usrp_write_reset(openair0_thread_t *wt); @@ -355,10 +365,13 @@ static void trx_usrp_end(openair0_device *device) { if (usrp_tx_thread != 0) trx_usrp_write_reset(&device->write_thread); + /* finish tx and rx */ trx_usrp_send_end_of_burst(s); - s->tx_stream->~tx_streamer(); - s->rx_stream->~rx_streamer(); - s->usrp->~multi_usrp(); + trx_usrp_finish_rx(s); + /* set tx_stream, rx_stream, and usrp to NULL to clear/free them */ + s->tx_stream = NULL; + s->rx_stream = NULL; + s->usrp = NULL; free(s); device->priv = NULL; device->trx_start_func = NULL; @@ -1405,8 +1418,14 @@ extern "C" { // create tx & rx streamer uhd::stream_args_t stream_args_rx("sc16", "sc16"); + for (int i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); + int samples=openair0_cfg[0].sample_rate; - int max=s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps(); + int max=s->rx_stream->get_max_num_samps(); samples/=10000; LOG_I(HW,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples); @@ -1415,14 +1434,8 @@ extern "C" { } LOG_I(HW,"rx_max_num_samps %zu\n", - s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); + s->rx_stream->get_max_num_samps()); - for (int i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); uhd::stream_args_t stream_args_tx("sc16", "sc16"); for (int i = 0; i