Compare commits

..

27 Commits

Author SHA1 Message Date
Nick Hedberg
4b46dfb9f0 Assign antenna ports correctly for 1 and 2 layers for aerial. 2025-10-02 11:47:53 +00:00
francescomani
75079c0fb6 fix max feedback time parameter (needs to be computed every time we have that information) 2025-09-19 09:46:45 +00:00
Nick Hedberg
d679f2e5b0 Add T_Tracer message also in openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c 2025-09-19 08:17:48 +00:00
Nick Hedberg
56d2219455 Temporary workaround for SRS scheduling 2025-09-18 13:16:44 +00:00
Nick Hedberg
cd071a8d22 More changes from !3610 to avoid unpacking report=0 2025-09-10 09:43:22 +00:00
Nick Hedberg
46a3f67d6b Fix unpacking for zero-length PDUs. Also in !3610 2025-09-10 09:10:44 +00:00
Nick Hedberg
d9cb69179a Merge branch 'ARC1.6_integration' of gitlab.eurecom.fr:oai/openairinterface5g into ARC1.6_integration 2025-08-29 14:46:02 +00:00
Nick Hedberg
a7a7fedb74 Populate sampled_ue_antennas in SRS PDU. We now get 2 UL layers OTA 2025-08-29 14:45:17 +00:00
Nick Hedberg
2d11264146 Remove min PRBs for 40MHz config 2025-07-31 14:06:24 +00:00
Nick Hedberg
141e1cab21 Merge branch 'ARC1.6_integration' of gitlab.eurecom.fr:oai/openairinterface5g into ARC1.6_integration 2025-07-31 14:01:47 +00:00
Nick Hedberg
08bd03c2bf Remove min PRB allocation 2025-07-31 13:59:08 +00:00
Fredrik Molander
bbb0c05149 add config 2025-07-29 19:24:56 +00:00
Fredrik Molander
66748664e9 add config 2025-07-29 19:24:28 +00:00
Fredrik Molander
2b89147704 add docker compose and L2 configs for dual cell 2025-07-29 19:15:46 +00:00
Fredrik Molander
b239a7af87 change fapi poll thread cpu affinity 2025-07-29 08:45:25 +00:00
Fredrik Molander
9e8e055eff Change cubb tag to 25-2 and moved l2 cpu affinity 2025-07-29 08:42:58 +00:00
Fredrik Molander
54593afeb5 fixed typo and removed "mgmt_addr=10.31.66.112" 2025-07-21 20:41:17 +00:00
Fredrik Molander
44515a3dcb added configs for nrue 2025-07-21 20:41:17 +00:00
Fredrik Molander
9400a31bf5 changed oai-ext-dn tag to remove arm tag 2025-07-21 20:41:17 +00:00
Fredrik Molander
962ceeeb45 changed cubb image name
changed oai image name
2025-07-21 20:41:17 +00:00
Fredrik Molander
68040b4d61 added comments
changed default dir for pcap
changed the build dir.
2025-07-21 20:41:17 +00:00
Nicholas Hedberg
bd06b921f9 Add 40MHz configuration 2025-07-21 20:41:17 +00:00
Fredrik Molander
d57635653b Updates aerial 25-1 and CN arm support 2025-07-21 20:41:17 +00:00
Fredrik Molander
2670f8178d Update docker-compose-cn-gh.yaml to uset prebuild arm images 2025-07-21 20:41:17 +00:00
Fredrik Molander
5b79e32318 add ip route for 12.1.1.0/24 2025-07-21 20:41:17 +00:00
Fredrik Molander
0322477d39 Change SMC-GH default config. After 24-1 use P5G_FXN_GH. 2025-07-21 20:41:17 +00:00
Fredrik Molander
a34379b549 Added docker compose configs for GH. 2025-07-21 20:41:17 +00:00
237 changed files with 5967 additions and 11721 deletions

1
.gitignore vendored
View File

@@ -5,6 +5,7 @@
cmake_targets/log/
cmake_targets/*/build/
cmake_targets/ran_build/
cmake_targets/nas_sim_tools/build/
log/
lte_build_oai/

View File

@@ -36,8 +36,6 @@ if(NOT DEFINED ENV{CPM_SOURCE_CACHE})
endif()
include("cmake_targets/CPM.cmake")
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
##############################
### CCache: reduce compilation time
##############################
@@ -174,7 +172,7 @@ else ()
endif()
# add autotools definitions that were maybe used!
add_definitions(-DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP)
add_definitions("-DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP")
# we need -rdynamic to incorporate all symbols in shared objects, see man page
set(commonOpts "-pipe -fPIC -Wall -fno-strict-aliasing -rdynamic")
@@ -850,7 +848,6 @@ set(PHY_SRC_COMMON
${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c
${OPENAIR1_DIR}/PHY/TOOLS/get_sin_cos.c
${OPENAIR1_DIR}/PHY/TOOLS/oai_arith_operations.c
${OPENAIR1_DIR}/PHY/log_tools.c
)
set(PHY_SRC
@@ -1409,14 +1406,12 @@ add_library(MME_APP ${MME_APP_SRC})
target_link_libraries(MME_APP PRIVATE m2ap m3ap)
target_link_libraries(MME_APP PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
find_package(sctp REQUIRED)
set(SCTP_SRC
${OPENAIR3_DIR}/SCTP/sctp_common.c
${OPENAIR3_DIR}/SCTP/sctp_eNB_task.c
${OPENAIR3_DIR}/SCTP/sctp_eNB_itti_messaging.c
)
add_library(SCTP_CLIENT ${SCTP_SRC})
target_link_libraries(SCTP_CLIENT PRIVATE sctp::sctp)
target_link_libraries(SCTP_CLIENT PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
set(NAS_SRC ${OPENAIR3_DIR}/NAS/)
@@ -1715,6 +1710,7 @@ include_directories("${NFAPI_DIR}/pnf_sim/inc")
add_library(oai_iqplayer MODULE
${OPENAIR_DIR}/radio/iqplayer/iqplayer_lib.c
)
set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
#################################
# add executables for operation
@@ -1761,7 +1757,7 @@ target_link_libraries(lte-softmodem PRIVATE
${NAS_UE_LIB} ITTI SIMU shlib_loader
-Wl,--end-group z dl)
target_link_libraries(lte-softmodem PRIVATE pthread m CONFIG_LIB rt)
target_link_libraries(lte-softmodem PRIVATE pthread m CONFIG_LIB rt sctp)
target_link_libraries(lte-softmodem PRIVATE ${T_LIB})
target_link_libraries(lte-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(lte-softmodem PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapacke_LIBRARIES} ${lapack_LIBRARIES})
@@ -1817,7 +1813,7 @@ target_link_libraries(lte-uesoftmodem PRIVATE
${NAS_UE_LIB} ITTI shlib_loader
-Wl,--end-group z dl)
target_link_libraries(lte-uesoftmodem PRIVATE pthread m CONFIG_LIB rt)
target_link_libraries(lte-uesoftmodem PRIVATE pthread m CONFIG_LIB rt sctp)
target_link_libraries(lte-uesoftmodem PRIVATE ${T_LIB})
target_link_libraries(lte-uesoftmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(lte-uesoftmodem PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapacke_LIBRARIES} ${lapack_LIBRARIES})
@@ -1854,7 +1850,7 @@ target_link_libraries(nr-softmodem PRIVATE
time_management
-Wl,--end-group z dl)
target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt)
target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt sctp)
target_link_libraries(nr-softmodem PRIVATE ${T_LIB})
target_link_libraries(nr-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(nr-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
@@ -1891,7 +1887,7 @@ target_link_libraries(nr-cuup PRIVATE
CONFIG_LIB ITTI SCTP_CLIENT
GTPV1U e1ap f1ap
time_management
z dl pthread shlib_loader ${T_LIB})
z sctp dl pthread shlib_loader ${T_LIB})
target_link_libraries(nr-cuup PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
if(E2_AGENT)
target_link_libraries(nr-cuup PRIVATE e2_agent e2_agent_arg e2_ran_func_cuup)
@@ -2185,4 +2181,3 @@ add_subdirectory(openair1)
add_subdirectory(openair2)
add_subdirectory(openair3)
add_subdirectory(radio)
add_subdirectory(tests)

View File

@@ -835,13 +835,11 @@ def finalizeSlaveJob(jobName) {
selector: lastCompleted())
if (fileExists(fileName)) {
sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' ${fileName}"
} else {
sh "echo \"could not copy results from ${jobName}, please check pipeline ${BUILD_URL}\" > ${fileName}"
archiveArtifacts artifacts: fileName
// BUILD_URL is like http://server:port/jenkins/job/foo/15/
// no need to add a prefixed '/'
artifactUrl += 'artifact/' + fileName
}
archiveArtifacts artifacts: fileName
// BUILD_URL is like http://server:port/jenkins/job/foo/15/
// no need to add a prefixed '/'
artifactUrl += 'artifact/' + fileName
}
artifactUrl = "\n * [${jobName}](${artifactUrl})"
return artifactUrl

View File

@@ -216,6 +216,24 @@ pipeline {
}
stage('Log Collection') {
parallel {
stage('Log Collection (eNB - Build)') {
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (eNB - Build)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
echo '\u2705 \u001B[32mLog Transfer (eNB - Build)\u001B[0m'
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("build.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "build.log.${env.BUILD_ID}.zip"
}
}
}
}
stage('Log Collection (eNB - Run)') {
steps {
withCredentials([

View File

@@ -222,6 +222,24 @@ pipeline {
}
stage('Log Collection') {
parallel {
stage('Log Collection (eNB - Build)') {
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (eNB - Build)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
echo '\u2705 \u001B[32mLog Transfer (eNB - Build)\u001B[0m'
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("build.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "build.log.${env.BUILD_ID}.zip"
}
}
}
}
stage('Log Collection (eNB - Run)') {
steps {
withCredentials([

View File

@@ -210,6 +210,24 @@ pipeline {
}
stage('Log Collection') {
parallel {
stage('Log Collection (eNB - Build)') {
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (eNB - Build)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
echo '\u2705 \u001B[32mLog Transfer (eNB - Build)\u001B[0m'
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("build.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "build.log.${env.BUILD_ID}.zip"
}
}
}
}
stage('Log Collection (eNB - Run)') {
steps {
withCredentials([

View File

@@ -227,6 +227,24 @@ pipeline {
}
stage('Log Collection') {
parallel {
stage('Log Collection (eNB - Build)') {
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (eNB - Build)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
echo '\u2705 \u001B[32mLog Transfer (eNB - Build)\u001B[0m'
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("build.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "build.log.${env.BUILD_ID}.zip"
}
}
}
}
stage('Log Collection (eNB - Run)') {
steps {
withCredentials([

View File

@@ -5,7 +5,7 @@
{
#define N_ANTENNA_DL 1
#define N_ANTENNA_UL 1
#define DL_ARFCN 627360
#define DL_ARFCN 631296
#define TDD 1
log_options: "all.level=debug,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1",

View File

@@ -5,12 +5,10 @@ idefix:
AttachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 wup
DetachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 detach
NetworkScript: ip a show dev wwan0
#Tracing:
# Start: 'sudo rm -f ci_qlog/*; nohup sudo -b QLog/QLog -s ci_qlog -f NR5G.cfg &'
# Stop: 'sudo killall QLog'
# Collect: 'sudo mv ci_qlog/* %%log_dir%%/'
IF: wwan0
MTU: 1500
Trace: True
LogStore: /media/usb-drive/ci_qlogs
up2:
Host: up2
@@ -48,6 +46,7 @@ adb_ue_1:
NetworkScript: adb -s R3CM40LZPHT shell "ip address show | grep rmnet_data0"
CmdPrefix: adb -s R3CM40LZPHT shell
MTU: 1500
LogStore: /media/usb-drive/ci_adb_1-logs
adb_ue_2:
Host: nano
InitScript: /home/oaicicd/ci_ctl_adb.sh initialize 5200c00db4413517
@@ -60,6 +59,7 @@ adb_ue_2:
NetworkScript: adb -s 5200c00db4413517 shell "ip address show | grep rmnet"
CmdPrefix: adb -s 5200c00db4413517 shell
MTU: 1500
LogStore: /media/usb-drive/ci_adb_2-logs
oc-cn5g:
Host: avra
@@ -147,16 +147,12 @@ ltebox-nepes:
amarisoft_ue:
Host: amariue
InitScript: /root/lteue-linux-2025-03-15/lteue /root/oaicicd/ran_sa_aw2s_asue_20MHz/aw2s-multi-00102-20.cfg &
InitScript: /root/lteue-linux-2025-03-15/lteue /root/oaicicd/ran_sa_aw2s_asue/aw2s-multi-00102-20.cfg &
TermScript: /root/lteue-linux-2025-03-15/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2
NetworkScript: ip netns exec ue1 ip a show dev pdn0
#Tracing:
# Start: '' # nothing to be done
# Stop: '' # nothing to be done
# Collect: 'cp /tmp/ue.log %%log_dir%%'
amarisoft_ue_2x2:
Host: amariue
InitScript: /root/lteue-linux-2025-03-15/lteue /root/oaicicd/ran_sa_aw2s_asue_20MHz_2x2/aw2s-multi-00102-2x2-v2.cfg &
InitScript: /root/lteue-linux-2025-03-15/lteue /root/oaicicd/ran_sa_aw2s_asue_2x2/aw2s-multi-00102-2x2-v2.cfg &
TermScript: /root/lteue-linux-2025-03-15/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2
NetworkScript: ip netns exec ue1 ip a show dev pdn0
amarisoft_ue_fhi72:
@@ -305,15 +301,6 @@ rfsim5g_ue:
AttachScript: docker start rfsim5g-oai-nr-ue
DetachScript: docker stop rfsim5g-oai-nr-ue
MTU: 1500
# for tests with second PDU session ID 2, needs to match requested PDU session name
rfsim5g_ue_pdu_2:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue1p2
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue1p2
AttachScript: docker start rfsim5g-oai-nr-ue
DetachScript: docker stop rfsim5g-oai-nr-ue
MTU: 1500
rfsim5g_ue2:
Host: "%%current_host%%"

View File

@@ -84,7 +84,7 @@ class Analysis():
return success,msg
def analyze_oc_physim(result_junit, details_json, logPath):
def analyze_oc_physim(result_junit, details_json):
try:
tree = ET.parse(result_junit)
root = tree.getroot()
@@ -124,7 +124,7 @@ class Analysis():
output = test.findtext("system-out")
output_check = "exceeds the threshold" not in output
# collect logs
log_dir = f'{logPath}/{test_exec}'
log_dir = f'../cmake_targets/log/{test_exec}'
os.makedirs(log_dir, exist_ok=True)
with open(f'{log_dir}/{test_name}.log', 'w') as f:
f.write(output)

View File

@@ -1,44 +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
# */
import os
from typing import NamedTuple
import logging
class TestCaseCtx(NamedTuple):
count: int
test_id: int
logPath: str
def Default(logPath):
return TestCaseCtx(123, 112233, logPath)
def baseFilename(self):
# typically, the test ID is of form 001234 (6 digits)
return f"{self.logPath}/{self.count}-{self.test_id:06d}"
def archiveArtifact(cmd, ctx, remote_path):
base = os.path.basename(remote_path)
local = f"{ctx.baseFilename()}-{base}"
logging.info(f"Archive artifact '{local}'")
success = cmd.copyin(remote_path, local)
if success:
cmd.run(f'rm {remote_path}', silent=True)
return local if success else None

View File

@@ -39,7 +39,6 @@ import constants as CONST
import helpreadme as HELP
import cls_containerize
import cls_cmd
from cls_ci_helper import archiveArtifact
IMAGE_REGISTRY_SERVICE_NAME = "image-registry.openshift-image-registry.svc"
NAMESPACE = "oaicicd-ran"
@@ -208,12 +207,7 @@ class Cluster:
HTML.CreateHtmlTestRowQueue(param, 'KO', [msg])
return success
def _retrieveOCLog(self, ctx, job, lSourcePath, image):
fn = f'{lSourcePath}/cmake_targets/log/{image}.log'
self.cmd.run(f'oc logs {job} &> {fn}')
return (image, archiveArtifact(self.cmd, ctx, fn))
def BuildClusterImage(self, ctx, HTML):
def BuildClusterImage(self, HTML):
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
HELP.GenericHelp(CONST.Version)
raise ValueError(f'Insufficient Parameter: ranRepository {self.ranRepository} ranBranch {ranBranch} ranCommitID {self.ranCommitID}')
@@ -286,27 +280,22 @@ class Cluster:
self._recreate_entitlements()
status = True # flag to abandon compiling if any image fails
log_files = []
build_metrics = f"{lSourcePath}/cmake_targets/log/build-metrics.log"
attemptedImages = []
if forceBaseImageBuild:
self._recreate_is_tag('ran-base', baseTag, 'openshift/ran-base-is.yaml')
self._recreate_bc('ran-base', baseTag, 'openshift/ran-base-bc.yaml')
ranbase_job = self._start_build('ran-base')
attemptedImages += ['ran-base']
status = ranbase_job is not None and self._wait_build_end([ranbase_job], 1000)
if not status: logging.error('failure during build of ran-base')
log_files.append(self._retrieveOCLog(ctx, ranbase_job, lSourcePath, 'ran-base'))
self.cmd.run(f'oc logs {ranbase_job} &> cmake_targets/log/ran-base.log') # cannot use cmd.run because of redirect
# recover logs by mounting image
self._retag_image_statement('ran-base', 'ran-base', baseTag, 'openshift/ran-base-log-retrieval.yaml')
pod = self._deploy_pod('openshift/ran-base-log-retrieval.yaml')
if pod is not None:
logdir = f'{lSourcePath}/cmake_targets/log/ran-base'
self.cmd.run(f'mkdir -p {logdir}')
self.cmd.run(f'oc rsync {pod}:/oai-ran/cmake_targets/log/ {logdir}')
self.cmd.run(f'mkdir -p cmake_targets/log/ran-base')
self.cmd.run(f'oc rsync {pod}:/oai-ran/cmake_targets/log/ cmake_targets/log/ran-base')
self._undeploy_pod('openshift/ran-base-log-retrieval.yaml')
ret = self.cmd.run(f'ls {logdir}')
for f in ret.stdout.splitlines():
archiveArtifact(self.cmd, ctx, f"{logdir}/{f}")
else:
status = False
@@ -315,24 +304,27 @@ class Cluster:
self._recreate_bc('oai-physim', imageTag, 'openshift/oai-physim-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.phySim.rhel9')
physim_job = self._start_build('oai-physim')
attemptedImages += ['oai-physim']
self._recreate_is_tag('ran-build', imageTag, 'openshift/ran-build-is.yaml')
self._recreate_bc('ran-build', imageTag, 'openshift/ran-build-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.build.rhel9')
ranbuild_job = self._start_build('ran-build')
attemptedImages += ['ran-build']
self._recreate_is_tag('oai-clang', imageTag, 'openshift/oai-clang-is.yaml')
self._recreate_bc('oai-clang', imageTag, 'openshift/oai-clang-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.clang.rhel9')
clang_job = self._start_build('oai-clang')
attemptedImages += ['oai-clang']
wait = ranbuild_job is not None and physim_job is not None and clang_job is not None and self._wait_build_end([ranbuild_job, physim_job, clang_job], 1200)
if not wait: logging.error('error during build of ranbuild_job or physim_job or clang_job')
status = status and wait
log_files.append(self._retrieveOCLog(ctx, ranbuild_job, lSourcePath, 'ran-build'))
log_files.append(self._retrieveOCLog(ctx, physim_job, lSourcePath, 'oai-physim'))
log_files.append(self._retrieveOCLog(ctx, clang_job, lSourcePath, 'oai-clang'))
self.cmd.run(f'oc get pods.metrics.k8s.io &>> {build_metrics}')
self.cmd.run(f'oc logs {ranbuild_job} &> cmake_targets/log/ran-build.log')
self.cmd.run(f'oc logs {physim_job} &> cmake_targets/log/oai-physim.log')
self.cmd.run(f'oc logs {clang_job} &> cmake_targets/log/oai-clang.log')
self.cmd.run(f'oc get pods.metrics.k8s.io &>> cmake_targets/log/build-metrics.log')
if status:
self._recreate_is_tag('oai-enb', imageTag, 'openshift/oai-enb-is.yaml')
@@ -340,66 +332,72 @@ class Cluster:
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.eNB.rhel9')
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.eNB.rhel9')
enb_job = self._start_build('oai-enb')
attemptedImages += ['oai-enb']
self._recreate_is_tag('oai-gnb', imageTag, 'openshift/oai-gnb-is.yaml')
self._recreate_bc('oai-gnb', imageTag, 'openshift/oai-gnb-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.rhel9')
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.gNB.rhel9')
gnb_job = self._start_build('oai-gnb')
attemptedImages += ['oai-gnb']
self._recreate_is_tag('oai-gnb-aw2s', imageTag, 'openshift/oai-gnb-aw2s-is.yaml')
self._recreate_bc('oai-gnb-aw2s', imageTag, 'openshift/oai-gnb-aw2s-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.aw2s.rhel9')
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.gNB.aw2s.rhel9')
gnb_aw2s_job = self._start_build('oai-gnb-aw2s')
attemptedImages += ['oai-gnb-aw2s']
wait = enb_job is not None and gnb_job is not None and gnb_aw2s_job is not None and self._wait_build_end([enb_job, gnb_job, gnb_aw2s_job], 800)
if not wait: logging.error('error during build of eNB/gNB')
status = status and wait
# recover logs
log_files.append(self._retrieveOCLog(ctx, enb_job, lSourcePath, 'oai-enb'))
log_files.append(self._retrieveOCLog(ctx, gnb_job, lSourcePath, 'oai-gnb'))
log_files.append(self._retrieveOCLog(ctx, gnb_aw2s_job, lSourcePath, 'oai-gnb-aw2s'))
self.cmd.run(f'oc get pods.metrics.k8s.io &>> {build_metrics}')
self.cmd.run(f'oc logs {enb_job} &> cmake_targets/log/oai-enb.log')
self.cmd.run(f'oc logs {gnb_job} &> cmake_targets/log/oai-gnb.log')
self.cmd.run(f'oc logs {gnb_aw2s_job} &> cmake_targets/log/oai-gnb-aw2s.log')
self._recreate_is_tag('oai-nr-cuup', imageTag, 'openshift/oai-nr-cuup-is.yaml')
self._recreate_bc('oai-nr-cuup', imageTag, 'openshift/oai-nr-cuup-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.nr-cuup.rhel9')
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.nr-cuup.rhel9')
nr_cuup_job = self._start_build('oai-nr-cuup')
attemptedImages += ['oai-nr-cuup']
self._recreate_is_tag('oai-lte-ue', imageTag, 'openshift/oai-lte-ue-is.yaml')
self._recreate_bc('oai-lte-ue', imageTag, 'openshift/oai-lte-ue-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.lteUE.rhel9')
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.lteUE.rhel9')
lteue_job = self._start_build('oai-lte-ue')
attemptedImages += ['oai-lte-ue']
self._recreate_is_tag('oai-nr-ue', imageTag, 'openshift/oai-nr-ue-is.yaml')
self._recreate_bc('oai-nr-ue', imageTag, 'openshift/oai-nr-ue-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.nrUE.rhel9')
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.nrUE.rhel9')
nrue_job = self._start_build('oai-nr-ue')
attemptedImages += ['oai-nr-ue']
wait = nr_cuup_job is not None and lteue_job is not None and nrue_job is not None and self._wait_build_end([nr_cuup_job, lteue_job, nrue_job], 800)
if not wait: logging.error('error during build of nr-cuup/lteUE/nrUE')
status = status and wait
# recover logs
log_files.append(self._retrieveOCLog(ctx, nr_cuup_job, lSourcePath, 'oai-nr-cuup'))
log_files.append(self._retrieveOCLog(ctx, lteue_job, lSourcePath, 'oai-lte-ue'))
log_files.append(self._retrieveOCLog(ctx, nrue_job, lSourcePath, 'oai-nr-ue'))
self.cmd.run(f'oc get pods.metrics.k8s.io &>> {build_metrics}')
self.cmd.run(f'oc logs {nr_cuup_job} &> cmake_targets/log/oai-nr-cuup.log')
self.cmd.run(f'oc logs {lteue_job} &> cmake_targets/log/oai-lte-ue.log')
self.cmd.run(f'oc logs {nrue_job} &> cmake_targets/log/oai-nr-ue.log')
self.cmd.run(f'oc get pods.metrics.k8s.io &>> cmake_targets/log/build-metrics.log')
if status:
self._recreate_is_tag('ran-build-fhi72', imageTag, 'openshift/ran-build-fhi72-is.yaml')
self._recreate_bc('ran-build-fhi72', imageTag, 'openshift/ran-build-fhi72-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.build.fhi72.rhel9')
ranbuildfhi72_job = self._start_build('ran-build-fhi72')
attemptedImages += ['ran-build-fhi72']
wait = ranbuildfhi72_job is not None and self._wait_build_end([ranbuildfhi72_job], 1200)
if not wait: logging.error('error during build of ranbuildfhi72_job')
status = status and wait
log_files.append(self._retrieveOCLog(ctx, ranbuildfhi72_job, lSourcePath, 'ran-build-fhi72'))
self.cmd.run(f'oc get pods.metrics.k8s.io &>> {build_metrics}')
self.cmd.run(f'oc logs {ranbuildfhi72_job} &> cmake_targets/log/ran-build-fhi72.log')
self.cmd.run(f'oc get pods.metrics.k8s.io &>> cmake_targets/log/build-metrics.log')
if status:
self._recreate_is_tag('oai-gnb-fhi72', imageTag, 'openshift/oai-gnb-fhi72-is.yaml')
@@ -407,17 +405,19 @@ class Cluster:
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.fhi72.rhel9')
self._retag_image_statement('ran-build-fhi72', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build-fhi72', imageTag, 'docker/Dockerfile.gNB.fhi72.rhel9')
gnb_fhi72_job = self._start_build('oai-gnb-fhi72')
attemptedImages += ['oai-gnb-fhi72']
wait = gnb_fhi72_job is not None and self._wait_build_end([gnb_fhi72_job], 600)
if not wait: logging.error('error during build of gNB-fhi72')
status = status and wait
# recover logs
log_files.append(self._retrieveOCLog(ctx, gnb_fhi72_job, lSourcePath, 'oai-gnb-fhi72'))
self.cmd.run(f'oc get pods.metrics.k8s.io &>> {build_metrics}')
self.cmd.run(f'oc logs {gnb_fhi72_job} &> cmake_targets/log/oai-gnb-fhi72.log')
self.cmd.run(f'oc get pods.metrics.k8s.io &>> cmake_targets/log/build-metrics.log')
# split and analyze logs
imageSize = {}
for image, _ in log_files:
for image in attemptedImages:
self.cmd.run(f'mkdir -p cmake_targets/log/{image}')
tag = imageTag if image != 'ran-base' else baseTag
size = self._get_image_size(image, tag)
if size <= 0:
@@ -428,14 +428,12 @@ class Cluster:
imageSize[image] = f'{sizeMb:.1f} Mbytes (uncompressed: ~{sizeMb*2.5:.1f} Mbytes)'
logging.info(f'\u001B[1m{image} size is {imageSize[image]}\u001B[0m')
archiveArtifact(self.cmd, ctx, build_metrics)
logfile = f'{lSourcePath}/cmake_targets/log/image_registry.log'
grep_exp = r"\|".join([i for i,f in log_files])
self.cmd.run(f'oc get images | grep -e \'{grep_exp}\' &> {logfile}');
archiveArtifact(self.cmd, ctx, logfile)
logfile = f'{lSourcePath}/cmake_targets/log/build_pod_summary.log'
self.cmd.run(f'for pod in $(oc get pods | tail -n +2 | awk \'{{print $1}}\'); do oc get pod $pod -o json &>> {logfile}; done')
archiveArtifact(self.cmd, ctx, logfile)
grep_exp = r"\|".join(attemptedImages)
self.cmd.run(f'oc get images | grep -e \'{grep_exp}\' &> cmake_targets/log/image_registry.log');
self.cmd.run(f'for pod in $(oc get pods | tail -n +2 | awk \'{{print $1}}\'); do oc get pod $pod -o json &>> cmake_targets/log/build_pod_summary.log; done')
build_log_name = f'build_log_{self.testCase_id}'
cls_containerize.CopyLogsToExecutor(self.cmd, lSourcePath, build_log_name)
self.cmd.run('for pod in $(oc get pods | tail -n +2 | awk \'{print $1}\'); do oc delete pod ${pod}; done')
@@ -444,7 +442,7 @@ class Cluster:
self.cmd.close()
# Analyze the logs
collectInfo = cls_containerize.AnalyzeBuildLogs(log_files, status)
collectInfo = cls_containerize.AnalyzeBuildLogs(build_log_name, attemptedImages, status)
for img in collectInfo:
for f in collectInfo[img]:
status = status and collectInfo[img][f]['status']
@@ -460,16 +458,9 @@ class Cluster:
HTML.CreateHtmlNextTabHeaderTestRow(collectInfo, imageSize)
# TODO fix groovy script, remove the following.
# the groovy scripts expects all logs in
# <jenkins-workspace>/<pipeline>/ci-scripts, so copy it there
with cls_cmd.LocalCmd() as c:
c.run(f'mkdir -p {os.getcwd()}/test_log_{ctx.test_id}/')
c.run(f'cp -r {ctx.logPath} {os.getcwd()}/test_log_{ctx.test_id}/')
return status
def deploy_oc_physim(self, ctx, HTML, oc_release, svr_id):
def deploy_oc_physim(self, HTML, oc_release, svr_id):
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
HELP.GenericHelp(CONST.Version)
raise ValueError(f'Insufficient Parameter: ranRepository {self.ranRepository} ranBranch {self.ranBranch} ranCommitID {self.ranCommitID}')
@@ -479,13 +470,17 @@ class Cluster:
options = f"oaicicd-core-for-ci-ran {oc_release} {image_tag} {self.eNBSourceCodePath}"
ret = cls_cmd.runScript(svr_id, script, 600, options)
logging.debug(f'"{script}" finished with code {ret.returncode}, output:\n{ret.stdout}')
log_dir = f'{os.getcwd()}/../cmake_targets/log'
os.makedirs(log_dir, exist_ok=True)
result_junit = f'{oc_release}-run.xml'
details_json = f'{oc_release}-tests.json'
with cls_cmd.getConnection(svr_id) as ssh:
details_json = archiveArtifact(ssh, ctx, f'{self.eNBSourceCodePath}/ci-scripts/{oc_release}-tests.json')
result_junit = archiveArtifact(ssh, ctx, f'{self.eNBSourceCodePath}/ci-scripts/{oc_release}-run.xml')
archiveArtifact(ssh, ctx, f'{self.eNBSourceCodePath}/ci-scripts/physim_log.txt')
archiveArtifact(ssh, ctx, f'{self.eNBSourceCodePath}/ci-scripts/physim_pods_summary.txt')
archiveArtifact(ssh, ctx, f'{self.eNBSourceCodePath}/ci-scripts/LastTestsFailed.log')
test_status, test_summary, test_result = cls_analysis.Analysis.analyze_oc_physim(result_junit, details_json, ctx.logPath)
ssh.copyin(src=f'{self.eNBSourceCodePath}/ci-scripts/{details_json}', tgt=f'{log_dir}/{details_json}')
ssh.copyin(src=f'{self.eNBSourceCodePath}/ci-scripts/{result_junit}', tgt=f'{log_dir}/{result_junit}')
ssh.copyin(src=f'{self.eNBSourceCodePath}/ci-scripts/physim_log.txt', tgt=f'{log_dir}/physim_log.txt')
ssh.copyin(src=f'{self.eNBSourceCodePath}/ci-scripts/physim_pods_summary.txt', tgt=f'{log_dir}/physim_pods_summary.txt')
ssh.copyin(src=f'{self.eNBSourceCodePath}/ci-scripts/LastTestsFailed.log', tgt=f'{log_dir}/LastTestsFailed.log')
test_status, test_summary, test_result = cls_analysis.Analysis.analyze_oc_physim(f'{log_dir}/{result_junit}', f'{log_dir}/{details_json}')
if test_summary:
if test_status:
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)

View File

@@ -46,7 +46,6 @@ import cls_cmd
import helpreadme as HELP
import constants as CONST
import cls_oaicitest
from cls_ci_helper import archiveArtifact
#-----------------------------------------------------------
# Helper functions used here and in other classes
@@ -82,26 +81,67 @@ def CreateTag(ranCommitID, ranBranch, ranAllowMerge):
tagToUse = f'develop-{shortCommit}'
return tagToUse
def AnalyzeBuildLogs(logfiles, globalStatus):
def CopyLogsToExecutor(cmd, sourcePath, log_name):
cmd.cd(f'{sourcePath}/cmake_targets')
cmd.run(f'rm -f {log_name}.zip')
cmd.run(f'mkdir -p {log_name}')
cmd.run(f'mv log/* {log_name}')
cmd.run(f'zip -r -qq {log_name}.zip {log_name}')
# copy zip to executor for analysis
if (os.path.isfile(f'./{log_name}.zip')):
os.remove(f'./{log_name}.zip')
if (os.path.isdir(f'./{log_name}')):
shutil.rmtree(f'./{log_name}')
cmd.copyin(src=f'{sourcePath}/cmake_targets/{log_name}.zip', tgt=f'{os.getcwd()}/{log_name}.zip')
cmd.run(f'rm -f {log_name}.zip')
ZipFile(f'{log_name}.zip').extractall('.')
def AnalyzeBuildLogs(buildRoot, images, globalStatus):
collectInfo = {}
for image, lf in logfiles:
for image in images:
files = {}
errorandwarnings = {}
committed = False
tagged = False
with open(lf, mode='r') as inputfile:
for line in inputfile:
lineHasTag = re.search(f'Successfully tagged {image}:', str(line)) is not None
lineHasTag2 = re.search(f'naming to docker.io/library/{image}:', str(line)) is not None
tagged = tagged or lineHasTag or lineHasTag2
# the OpenShift Cluster builder prepends image registry URL
lineHasCommit = re.search(r'COMMIT [a-zA-Z0-9\.:/\-]*' + image, str(line)) is not None
committed = committed or lineHasCommit
errorandwarnings['errors'] = 0 if committed or tagged else 1
errorandwarnings['warnings'] = 0
errorandwarnings['status'] = committed or tagged
logging.info(f"Analyzing {image}, file {lf}: {errorandwarnings}")
files['Target Image Creation'] = errorandwarnings
file_list = [f for f in os.listdir(f'{buildRoot}/{image}') if os.path.isfile(os.path.join(f'{buildRoot}/{image}', f)) and f.endswith('.txt')]
# Analyze the "sub-logs" of every target image
for fil in file_list:
errorandwarnings = {}
warningsNo = 0
errorsNo = 0
with open(f'{buildRoot}/{image}/{fil}', mode='r') as inputfile:
for line in inputfile:
result = re.search(' ERROR ', str(line))
if result is not None:
errorsNo += 1
result = re.search(' error:', str(line))
if result is not None:
errorsNo += 1
result = re.search(' WARNING ', str(line))
if result is not None:
warningsNo += 1
result = re.search(' warning:', str(line))
if result is not None:
warningsNo += 1
errorandwarnings['errors'] = errorsNo
errorandwarnings['warnings'] = warningsNo
errorandwarnings['status'] = globalStatus
files[fil] = errorandwarnings
# Analyze the target image
if os.path.isfile(f'{buildRoot}/{image}.log'):
errorandwarnings = {}
committed = False
tagged = False
with open(f'{buildRoot}/{image}.log', mode='r') as inputfile:
for line in inputfile:
lineHasTag = re.search(f'Successfully tagged {image}:', str(line)) is not None
lineHasTag2 = re.search(f'naming to docker.io/library/{image}:', str(line)) is not None
tagged = tagged or lineHasTag or lineHasTag2
# the OpenShift Cluster builder prepends image registry URL
lineHasCommit = re.search(f'COMMIT [a-zA-Z0-9\.:/\-]*{image}', str(line)) is not None
committed = committed or lineHasCommit
errorandwarnings['errors'] = 0 if committed or tagged else 1
errorandwarnings['warnings'] = 0
errorandwarnings['status'] = committed or tagged
files['Target Image Creation'] = errorandwarnings
collectInfo[image] = files
return collectInfo
@@ -162,10 +202,12 @@ def GetServices(ssh, requested, file):
else:
return requested
def CopyinServiceLog(ssh, lSourcePath, svcName, wd_yaml, ctx):
remote_filename = f"{lSourcePath}/cmake_targets/log/{svcName}.logs"
def CopyinServiceLog(ssh, lSourcePath, yaml, svcName, wd_yaml, filename):
remote_filename = f"{lSourcePath}/cmake_targets/log/{filename}"
ssh.run(f'docker compose -f {wd_yaml} logs {svcName} --no-log-prefix &> {remote_filename}')
return archiveArtifact(ssh, ctx, remote_filename)
local_dir = f"{os.getcwd()}/../cmake_targets/log/{yaml}"
local_filename = f"{local_dir}/{filename}"
return ssh.copyin(remote_filename, local_filename)
def GetRunningServices(ssh, file):
ret = ssh.run(f'docker compose -f {file} config --services')
@@ -187,13 +229,14 @@ def GetRunningServices(ssh, file):
logging.info(f'stopping services: {running_services}')
return running_services
def CheckLogs(self, filename, HTML, RAN):
def CheckLogs(self, yaml, service_name, HTML, RAN):
logPath = f'{os.getcwd()}/../cmake_targets/log/{yaml}'
filename = f'{logPath}/{service_name}-{HTML.testCase_id}.log'
success = True
name = os.path.basename(filename)
if (any(sub in name for sub in ['oai_ue','oai-nr-ue','lte_ue'])):
if (any(sub in service_name for sub in ['oai_ue','oai-nr-ue','lte_ue'])):
logging.debug(f'\u001B[1m Analyzing UE logfile {filename} \u001B[0m')
logStatus = cls_oaicitest.OaiCiTest().AnalyzeLogFile_UE(filename, HTML, RAN)
opt = f"UE log analysis ({name})"
opt = f"UE log analysis for service {service_name}"
# usage of htmlUEFailureMsg/htmleNBFailureMsg is because Analyze log files
# abuse HTML to store their reports, and we here want to put custom options,
# which is not possible with CreateHtmlTestRow
@@ -204,13 +247,13 @@ def CheckLogs(self, filename, HTML, RAN):
else:
HTML.CreateHtmlTestRowQueue(opt, 'OK', [HTML.htmlUEFailureMsg])
HTML.htmlUEFailureMsg = ""
elif 'nv-cubb' in name:
elif service_name == 'nv-cubb':
msg = 'Undeploy PNF/Nvidia CUBB'
HTML.CreateHtmlTestRow(msg, 'OK', CONST.ALL_PROCESSES_OK)
elif (any(sub in name for sub in ['enb','rru','rcc','cu','du','gnb'])):
elif (any(sub in service_name for sub in ['enb','rru','rcc','cu','du','gnb'])):
logging.debug(f'\u001B[1m Analyzing XnB logfile {filename}\u001B[0m')
logStatus = RAN.AnalyzeLogFile_eNB(filename, HTML, self.ran_checkers)
opt = f"xNB log analysis ({name})"
opt = f"xNB log analysis for service {service_name}"
if (logStatus < 0):
HTML.CreateHtmlTestRowQueue(opt, 'KO', [HTML.htmleNBFailureMsg])
success = False
@@ -218,9 +261,9 @@ def CheckLogs(self, filename, HTML, RAN):
HTML.CreateHtmlTestRowQueue(opt, 'OK', [HTML.htmleNBFailureMsg])
HTML.htmleNBFailureMsg = ""
else:
logging.info(f"Skipping analysis of log '{filename}': no submatch for xNB/UE")
HTML.CreateHtmlTestRowQueue(f"file {name}", 'OK', ["no analysis function"])
logging.debug(f"log check: file {filename} passed analysis {success}")
logging.info(f'Skipping to analyze log for service name {service_name}')
HTML.CreateHtmlTestRowQueue(f"service {service_name}", 'OK', ["no analysis function"])
logging.debug(f"log check: service {service_name} passed analysis {success}")
return success
#-----------------------------------------------------------
@@ -256,6 +299,8 @@ class Containerize():
self.services = ['', '', '']
self.deploymentTag = ''
self.testCase_id = ''
self.cli = ''
self.cliBuildOptions = ''
self.dockerfileprefix = ''
@@ -285,12 +330,11 @@ class Containerize():
raise ValueError(f'Insufficient Parameter: IP/node {ip}, path {path}')
return (ip, path)
def BuildImage(self, ctx, HTML):
def BuildImage(self, HTML):
svr = self.eNB_serverId[self.eNB_instance]
lIpAddr, lSourcePath = self.GetCredentials(svr)
logging.debug('Building on server: ' + lIpAddr)
cmd = cls_cmd.getConnection(lIpAddr)
log_files = []
# Checking the hostname to get adapted on cli and dockerfileprefixes
cmd.run('hostnamectl')
@@ -346,6 +390,7 @@ class Containerize():
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue', ''))
imageNames.append(('oai-gnb-aerial', 'gNB.aerial', 'oai-gnb-aerial', ''))
self.testCase_id = HTML.testCase_id
cmd.cd(lSourcePath)
# if asterix, copy the entitlement and subscription manager configurations
if self.host == 'Red Hat':
@@ -375,24 +420,13 @@ class Containerize():
# Let's remove any previous run artifacts if still there
cmd.run(f"{self.cli} image prune --force")
for image,pattern,name,option in imageNames:
cmd.run(f"{self.cli} image rm {name}:{imageTag}", reportNonZero=False)
cmd.run(f"{self.cli} image rm {name}:{imageTag}")
# Build the base image only on Push Events (not on Merge Requests)
# On when the base image docker file is being modified.
if forceBaseImageBuild:
cmd.run(f"{self.cli} image rm {baseImage}:{baseTag}")
logfile = f'{lSourcePath}/cmake_targets/log/ran-base.docker.log'
cmd.run(f"{self.cli} build {self.cliBuildOptions} --target {baseImage} --tag {baseImage}:{baseTag} --file docker/Dockerfile.base{self.dockerfileprefix} . &> {logfile}", timeout=1600)
t = ("ran-base", archiveArtifact(cmd, ctx, logfile))
log_files.append(t)
# Recover build logs, for the moment only possible when build is successful
cmd.run(f"{self.cli} create --name test {baseImage}:{baseTag}")
cmd.run("mkdir -p cmake_targets/log/ran-base")
logfile = f'{lSourcePath}/cmake_targets/log/ran-base.log'
cmd.run(f"{self.cli} cp test:/oai-ran/cmake_targets/log/all.txt {logfile}")
cmd.run(f"{self.cli} rm -f test")
archiveArtifact(cmd, ctx, logfile)
cmd.run(f"{self.cli} build {self.cliBuildOptions} --target {baseImage} --tag {baseImage}:{baseTag} --file docker/Dockerfile.base{self.dockerfileprefix} . &> cmake_targets/log/ran-base.log", timeout=1600)
# First verify if the base image was properly created.
ret = cmd.run(f"{self.cli} image inspect --format=\'Size = {{{{.Size}}}} bytes\' {baseImage}:{baseTag}")
allImagesSize = {}
@@ -407,7 +441,7 @@ class Containerize():
HTML.CreateHtmlTabFooter(False)
return False
else:
result = re.search(r'Size *= *(?P<size>[0-9\-]+) *bytes', cmd.getBefore())
result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', cmd.getBefore())
if result is not None:
size = float(result.group("size")) / 1000000
imageSizeStr = f'{size:.1f}'
@@ -416,9 +450,17 @@ class Containerize():
else:
logging.debug('ran-base size is unknown')
# Recover build logs, for the moment only possible when build is successful
cmd.run(f"{self.cli} create --name test {baseImage}:{baseTag}")
cmd.run("mkdir -p cmake_targets/log/ran-base")
cmd.run(f"{self.cli} cp test:/oai-ran/cmake_targets/log/. cmake_targets/log/ran-base")
cmd.run(f"{self.cli} rm -f test")
# Build the target image(s)
status = True
attemptedImages = ['ran-base']
for image,pattern,name,option in imageNames:
attemptedImages += [name]
# the archived Dockerfiles have "ran-base:latest" as base image
# we need to update them with proper tag
cmd.run(f'git checkout -- docker/Dockerfile.{pattern}{self.dockerfileprefix}')
@@ -432,18 +474,15 @@ class Containerize():
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
if image == 'oai-gnb-aerial':
cmd.run('cp -f /opt/nvidia-ipc/nvipc.src.2025.05.20.tar.gz .')
logfile = f'{lSourcePath}/cmake_targets/log/{name}.docker.log'
ret = cmd.run(f'{self.cli} build {self.cliBuildOptions} --target {image} --tag {name}:{imageTag} --file docker/Dockerfile.{pattern}{self.dockerfileprefix} {option} . > {logfile} 2>&1', timeout=1200)
t = (name, archiveArtifact(cmd, ctx, logfile))
log_files.append(t)
ret = cmd.run(f'{self.cli} build {self.cliBuildOptions} --target {image} --tag {name}:{imageTag} --file docker/Dockerfile.{pattern}{self.dockerfileprefix} {option} . > cmake_targets/log/{name}.log 2>&1', timeout=1200)
if image == 'oai-gnb-aerial':
cmd.run('rm -f nvipc.src.2025.05.20.tar.gz')
if image == 'ran-build' or image == 'ran-build-asan' or image == 'ran-build-fhi72':
if image == 'ran-build' and ret.returncode == 0:
cmd.run(f"docker run --name test-log -d {name}:{imageTag} /bin/true")
logfile = f'{lSourcePath}/{image}.ninja.log'
cmd.run(f"docker cp test-log:/oai-ran/cmake_targets/log/all.txt {logfile}")
cmd.run(f"docker cp test-log:/oai-ran/cmake_targets/log/ cmake_targets/log/{name}/")
cmd.run(f"docker rm -f test-log")
archiveArtifact(cmd, ctx, logfile)
else:
cmd.run(f"mkdir -p cmake_targets/log/{name}")
# check the status of the build
ret = cmd.run(f"{self.cli} image inspect --format=\'Size = {{{{.Size}}}} bytes\' {name}:{imageTag}")
if ret.returncode != 0:
@@ -454,7 +493,7 @@ class Containerize():
allImagesSize[name] = 'N/A -- Build Failed'
break
else:
result = re.search(r'Size *= *(?P<size>[0-9\-]+) *bytes', cmd.getBefore())
result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', cmd.getBefore())
if result is not None:
size = float(result.group("size")) / 1000000 # convert to MB
imageSizeStr = f'{size:.1f}'
@@ -477,10 +516,13 @@ class Containerize():
logging.debug(cmd.run("df -h").stdout)
logging.debug(cmd.run("docker system df").stdout)
# create a zip with all logs
build_log_name = f'build_log_{self.testCase_id}'
CopyLogsToExecutor(cmd, lSourcePath, build_log_name)
cmd.close()
# Analyze the logs
collectInfo = AnalyzeBuildLogs(log_files, status)
collectInfo = AnalyzeBuildLogs(build_log_name, attemptedImages, status)
if status:
logging.info('\u001B[1m Building OAI Image(s) Pass\u001B[0m')
@@ -494,12 +536,13 @@ class Containerize():
HTML.CreateHtmlTabFooter(False)
return False
def BuildProxy(self, ctx, HTML):
def BuildProxy(self, HTML):
svr = self.eNB_serverId[self.eNB_instance]
lIpAddr, lSourcePath = self.GetCredentials(svr)
logging.debug('Building on server: ' + lIpAddr)
ssh = cls_cmd.getConnection(lIpAddr)
self.testCase_id = HTML.testCase_id
oldRanCommidID = self.ranCommitID
oldRanRepository = self.ranRepository
oldRanAllowMerge = self.ranAllowMerge
@@ -525,10 +568,15 @@ class Containerize():
if not success:
raise Exception("could not clone proxy repository")
fullpath = f'{lSourcePath}/proxy_build.log'
filename = f'build_log_{self.testCase_id}'
fullpath = f'{lSourcePath}/{filename}'
ssh.run(f'docker build --target oai-lte-multi-ue-proxy --tag proxy:{tag} --file {lSourcePath}/docker/Dockerfile.ubuntu18.04 {lSourcePath} > {fullpath} 2>&1')
archiveArtifact(ssh, ctx, fullpath)
ssh.run(f'zip -r -qq {fullpath}.zip {fullpath}')
local_file = f"{os.getcwd()}/../cmake_targets/log/{filename}.zip"
ssh.copyin(f'{fullpath}.zip', local_file)
# don't delete such that we might recover the zips
#ssh.run(f'rm -f {fullpath}.zip')
ssh.run('docker image prune --force')
ret = ssh.run(f'docker image inspect --format=\'Size = {{{{.Size}}}} bytes\' proxy:{tag}')
@@ -568,7 +616,7 @@ class Containerize():
collectInfo = {}
collectInfo['proxy'] = files
ret = ssh.run(f'docker image inspect --format=\'Size = {{{{.Size}}}} bytes\' proxy:{tag}')
result = re.search(r'Size *= *(?P<size>[0-9\-]+) *bytes', ret.stdout)
result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', ret.stdout)
# Cleaning any created tmp volume
ssh.run('docker volume prune --force')
ssh.close()
@@ -590,7 +638,7 @@ class Containerize():
HTML.CreateHtmlTabFooter(False)
return False
def BuildRunTests(self, ctx, HTML):
def BuildRunTests(self, HTML):
svr = self.eNB_serverId[self.eNB_instance]
lIpAddr, lSourcePath = self.GetCredentials(svr)
logging.debug('Building on server: ' + lIpAddr)
@@ -607,6 +655,7 @@ class Containerize():
if self.forcedWorkspaceCleanup:
cmd.run(f'sudo -S rm -Rf {lSourcePath}')
self.testCase_id = HTML.testCase_id
# check that ran-base image exists as we expect it
baseImage = 'ran-base'
@@ -626,10 +675,10 @@ class Containerize():
# build ran-unittests image
dockerfile = "ci-scripts/docker/Dockerfile.unittest.ubuntu22"
logfile = f'{lSourcePath}/cmake_targets/log/unittest-build.log'
ret = cmd.run(f'docker build --progress=plain --tag ran-unittests:{baseTag} --file {dockerfile} . &> {logfile}')
archiveArtifact(cmd, ctx, logfile)
ret = cmd.run(f'docker build --progress=plain --tag ran-unittests:{baseTag} --file {dockerfile} . &> {lSourcePath}/cmake_targets/log/unittest-build.log')
if ret.returncode != 0:
build_log_name = f'build_log_{self.testCase_id}'
CopyLogsToExecutor(cmd, lSourcePath, build_log_name)
logging.error(f'Cannot build unit tests')
HTML.CreateHtmlTestRow("Unit test build failed", 'KO', [dockerfile])
HTML.CreateHtmlTabFooter(False)
@@ -638,15 +687,10 @@ class Containerize():
HTML.CreateHtmlTestRowQueue("Build unit tests", 'OK', [dockerfile])
# it worked, build and execute tests, and close connection
# I would like to run it with --rm and mount the ctest result directory to avoid 'docker cp'
# below, but then permissions are messed up and we can't remove the directory without sudo
# making the next pipeline fail
ret = cmd.run(f'docker run -a STDOUT --workdir /oai-ran/build/ --env LD_LIBRARY_PATH=/oai-ran/build/ --name ran-unittests ran-unittests:{baseTag} ctest --no-label-summary -j$(nproc)')
cmd.run('docker cp ran-unittests:/oai-ran/build/Testing/Temporary/LastTest.log .')
archiveArtifact(cmd, ctx, f'{lSourcePath}/LastTest.log')
cmd.run('docker cp ran-unittests:/oai-ran/build/Testing/Temporary/LastTestsFailed.log .')
archiveArtifact(cmd, ctx, f'{lSourcePath}/LastTestsFailed.log')
cmd.run('docker rm ran-unittests')
ret = cmd.run(f'docker run -a STDOUT --workdir /oai-ran/build/ --env LD_LIBRARY_PATH=/oai-ran/build/ --rm ran-unittests:{baseTag} ctest --no-label-summary -j$(nproc)')
cmd.run(f'docker rmi ran-unittests:{baseTag}')
build_log_name = f'build_log_{self.testCase_id}'
CopyLogsToExecutor(cmd, lSourcePath, build_log_name)
cmd.close()
if ret.returncode == 0:
@@ -779,14 +823,18 @@ class Containerize():
HTML.CreateHtmlTestRowQueue('N/A', 'KO', ["cannot create workspace"])
return success
def DeployObject(self, ctx, HTML):
def DeployObject(self, HTML):
svr = self.eNB_serverId[self.eNB_instance]
num_attempts = self.num_attempts
lIpAddr, lSourcePath = self.GetCredentials(svr)
logging.debug(f'Deploying OAI Object on server: {lIpAddr}')
yaml = self.yamlPath[self.eNB_instance].strip('/')
# creating the log folder by default
local_dir = f"{os.getcwd()}/../cmake_targets/log/{yaml.split('/')[-1]}"
os.system(f'mkdir -p {local_dir}')
wd = f'{lSourcePath}/{yaml}'
wd_yaml = f'{wd}/docker-compose.y*ml'
yaml_dir = yaml.split('/')[-1]
with cls_cmd.getConnection(lIpAddr) as ssh:
services = GetServices(ssh, self.services[self.eNB_instance], wd_yaml)
if services == [] or services == ' ' or services == None:
@@ -813,7 +861,7 @@ class Containerize():
logging.warning(warning_msg)
HTML.CreateHtmlTestRowQueue('N/A', 'NOK', [warning_msg])
for svc in services.split():
CopyinServiceLog(ssh, lSourcePath, svc, wd_yaml, ctx)
CopyinServiceLog(ssh, lSourcePath, yaml_dir, svc, wd_yaml, f'{svc}-{HTML.testCase_id}-attempt{attempt}.log')
ssh.run(f'docker compose -f {wd_yaml} down -- {services}')
imagesInfo = info.stdout.splitlines()[1:]
logging.debug(f'{info.stdout.splitlines()[1:]}')
@@ -823,12 +871,13 @@ class Containerize():
HTML.CreateHtmlTestRowQueue('N/A', 'KO', ['\n'.join(imagesInfo)])
return deployed
def UndeployObject(self, ctx, HTML, RAN):
def UndeployObject(self, HTML, RAN):
svr = self.eNB_serverId[self.eNB_instance]
lIpAddr, lSourcePath = self.GetCredentials(svr)
logging.debug(f'\u001B[1m Undeploying OAI Object from server: {lIpAddr}\u001B[0m')
yaml = self.yamlPath[self.eNB_instance].strip('/')
wd = f'{lSourcePath}/{yaml}'
yaml_dir = yaml.split('/')[-1]
with cls_cmd.getConnection(lIpAddr) as ssh:
ExistEnvFilePrint(ssh, wd)
services = GetRunningServices(ssh, f"{wd}/docker-compose.y*ml")
@@ -836,7 +885,7 @@ class Containerize():
if services is not None:
all_serv = " ".join([s for s, _ in services])
ssh.run(f'docker compose -f {wd}/docker-compose.y*ml stop -- {all_serv}')
copyin_res = [CopyinServiceLog(ssh, lSourcePath, s, f"{wd}/docker-compose.y*ml", ctx) for s, _ in services]
copyin_res = all(CopyinServiceLog(ssh, lSourcePath, yaml_dir, s, f"{wd}/docker-compose.y*ml", f'{s}-{HTML.testCase_id}.log') for s, c in services)
else:
logging.warning('could not identify services to stop => no log file')
ssh.run(f'docker compose -f {wd}/docker-compose.y*ml down -v')
@@ -845,7 +894,7 @@ class Containerize():
HTML.CreateHtmlTestRowQueue('N/A', 'KO', ['Could not copy logfile(s)'])
return False
else:
log_results = [CheckLogs(self, f, HTML, RAN) for f in copyin_res]
log_results = [CheckLogs(self, yaml_dir, s, HTML, RAN) for s, _ in services]
success = all(log_results)
if success:
logging.info('\u001B[1m Undeploying OAI Object Pass\u001B[0m')

View File

@@ -29,7 +29,6 @@ import yaml
import re
import cls_cmd
from cls_ci_helper import archiveArtifact
def listify(s):
if s is None:
@@ -115,7 +114,8 @@ class CoreNetwork:
logging.info(f'deployed core network {self}, pingable IP address {ip}')
return True, output
def _collect_logs(self, ctx):
def _collect_logs(self, log_dir):
logging.info(f'collecting logs into (local) {log_dir}')
remote_dir = "/tmp/cn-undeploy-logs"
with cls_cmd.getConnection(self._host) as c:
# create a directory for log collection
@@ -134,17 +134,18 @@ class CoreNetwork:
logging.error("cannot enumerate log files")
return []
log_files = []
# copy them to the executor one by one
# copy them to the executor one by one, and store in log_dir
for f in ret.stdout.split("\n"):
name = archiveArtifact(c, ctx, f)
log_files.append(name)
l = f.replace(remote_dir, log_dir)
c.copyin(f, l)
log_files.append(l)
c.run(f'rm -rf {remote_dir}')
return log_files
def undeploy(self, ctx=None):
def undeploy(self, log_dir=None):
log_files = []
if ctx is not None:
log_files = self._collect_logs(ctx)
if log_dir is not None:
log_files = self._collect_logs(log_dir)
else:
logging.warning("no directory for log collection specified, cannot retrieve core network logs")
logging.info(f'undeploy core network {self}')

View File

@@ -32,7 +32,6 @@ import re
import yaml
import cls_cmd
from cls_ci_helper import archiveArtifact
class Module_UE:
@@ -60,31 +59,26 @@ class Module_UE:
}
self.interface = m.get('IF')
self.MTU = m.get('MTU')
self.trace = m.get('trace') == True
self.logStore = m.get('LogStore')
self.cmd_prefix = m.get('CmdPrefix')
logging.info(f'initialized UE {self} from {filename}')
t = m.get('Tracing')
self.trace = t is not None
if self.trace:
if t.get('Start') is None or t.get('Stop') is None or t.get('Collect')is None :
raise ValueError("need to have Start/Stop/Collect for tracing")
self.cmd_dict["traceStart"] = t.get('Start')
self.cmd_dict["traceStop"] = t.get('Stop')
self._logCollect = t.get('Collect')
if "%%log_dir%%" not in self._logCollect:
raise ValueError(f"(At least one) LogCollect expression for {module_name} must contain \"%%log_dir%%\"")
def __str__(self):
return f"{self.module_name}@{self.host}"
return f"{self.module_name}@{self.host} [IP: {self.getIP()}]"
def __repr__(self):
return self.__str__()
def _command(self, cmd, silent=False, reportNonZero=True):
def _command(self, cmd, silent = False):
if cmd is None:
raise Exception("no command provided")
with cls_cmd.getConnection(self.host) as c:
response = c.run(cmd, silent=silent, reportNonZero=reportNonZero)
if self.host == "" or self.host == "localhost":
c = cls_cmd.LocalCmd()
else:
c = cls_cmd.RemoteCmd(self.host)
response = c.run(cmd, silent=silent)
c.close()
return response
#-----------------$
@@ -92,23 +86,25 @@ class Module_UE:
#-----------------$
def initialize(self):
if self.trace:
raise Exception("UE tracing not implemented yet")
self._enableTrace()
# we first terminate to make sure the UE has been stopped
if self.cmd_dict["detach"]:
self._command(self.cmd_dict["detach"], silent=True)
self._command(self.cmd_dict["terminate"], silent=True)
ret = self._command(self.cmd_dict["initialize"])
logging.info(f'For command: {ret.args} | return output: {ret.stdout} | Code: {ret.returncode}')
if self.trace:
self._enableTrace()
# Here each UE returns differently for the successful initialization, requires check based on UE
return ret.returncode == 0
def terminate(self, ctx=None):
def terminate(self):
self._command(self.cmd_dict["terminate"])
if self.trace and ctx is not None:
if self.trace:
raise Exception("UE tracing not implemented yet")
self._disableTrace()
return self._collectTrace(ctx)
return self._logCollect()
return None
def attach(self, attach_tries = 4, attach_timeout = 60):
@@ -117,11 +113,10 @@ class Module_UE:
self._command(self.cmd_dict["attach"])
timeout = attach_timeout
logging.debug("Waiting for IP address to be assigned")
ip = self.getIP(silent=False, reportNonZero=True)
while timeout > 0 and not ip:
time.sleep(1)
timeout -= 1
ip = self.getIP(silent=True, reportNonZero=False)
time.sleep(5)
timeout -= 5
ip = self.getIP()
if ip:
break
logging.warning(f"UE did not receive IP address after {attach_timeout} s, detaching")
@@ -165,8 +160,8 @@ class Module_UE:
logging.error(message)
return False
def getIP(self, silent=True, reportNonZero=True):
output = self._command(self.cmd_dict["getNetwork"], silent=silent, reportNonZero=reportNonZero)
def getIP(self):
output = self._command(self.cmd_dict["getNetwork"], silent=True)
result = re.search(r'inet (?P<ip>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', output.stdout)
if result and result.group('ip'):
ip = result.group('ip')
@@ -196,33 +191,10 @@ class Module_UE:
return self.cmd_prefix if self.cmd_prefix else ""
def _enableTrace(self):
logging.info(f'UE {self}: start UE tracing')
self._command(self.cmd_dict["traceStart"])
raise Exception("not implemented")
def _disableTrace(self):
logging.info(f'UE {self}: stop UE tracing')
self._command(self.cmd_dict["traceStop"])
raise Exception("not implemented")
def _collectTrace(self, ctx):
remote_dir = "/tmp/ue-trace-logs"
with cls_cmd.getConnection(self.host) as c:
# create a directory for log collection
c.run(f'rm -rf {remote_dir}')
ret = c.run(f'mkdir {remote_dir}')
if ret.returncode != 0:
logging.error("cannot create directory for log collection")
return []
log_cmd = self._logCollect.replace('%%log_dir%%', remote_dir)
self._command(log_cmd)
# enumerate collected files
ret = c.run(f'ls {remote_dir}/*')
if ret.returncode != 0:
logging.error("cannot enumerate log files")
return []
log_files = []
# copy them to the executor one by one, and store in log_dir
for f in ret.stdout.split("\n"):
name = archiveArtifact(c, ctx, f)
log_files.append(name)
c.run(f'rm -rf {remote_dir}')
return log_files
def _logCollect(self):
raise Exception("not implemented")

View File

@@ -28,24 +28,26 @@ import cls_cmd
import cls_oai_html
import cls_analysis
import constants as CONST
from cls_ci_helper import archiveArtifact
DPDK_PATH = '/opt/dpdk-t2-22.11.0'
LOG_PATH_PHYSIM = 'phy_sim_logs'
class Native():
def Build(ctx, test_case, HTML, host, directory, options):
def Build(test_case, HTML, host, directory, options):
logging.debug(f'Building on server: {host}')
HTML.testCase_id = test_case
with cls_cmd.getConnection(host) as ssh:
base = f"{directory}/cmake_targets"
ret = ssh.run(f"C_INCLUDE_PATH={DPDK_PATH}/include/ PKG_CONFIG_PATH={DPDK_PATH}/lib64/pkgconfig/ {base}/build_oai {options} > {base}/build_oai.log", timeout=900)
ret = ssh.run(f"{base}/build_oai {options} > {base}/log/build_oai.log", timeout=900)
success = ret.returncode == 0
logs = ssh.run(f"cat {base}/build_oai.log", silent=True)
logs = ssh.run(f"cat {base}/log/build_oai.log", silent=True)
logging.debug(f"build finished with code {ret.returncode}, output:\n{logs.stdout}")
archiveArtifact(ssh, ctx, f'{base}/build_oai.log')
# create log directory, and copy build logs
target = f"{base}/build_log_{test_case}/"
ssh.run(f"mkdir -p {target}")
ssh.run(f"mv {base}/log/* {target}")
# check if build artifacts are there
# NOTE: build_oai should fail with exit code if it could not build, but it does not
@@ -65,14 +67,15 @@ class Native():
HTML.CreateHtmlTestRow(options, 'KO', CONST.ALL_PROCESSES_OK)
return success
def Run_Physim(ctx, HTML, host, directory, options, physim_test, threshold):
def Run_Physim(HTML, host, directory, options, physim_test, threshold):
logging.debug(f'Runnin {physim_test} on server: {host}')
workSpacePath = f'{directory}/cmake_targets'
runLogFile=f'{workSpacePath}/physim.log'
os.system(f'mkdir -p ./{LOG_PATH_PHYSIM}')
runLogFile=f'physim_{HTML.testCase_id}.log'
with cls_cmd.getConnection(host) as cmd:
cmd.run(f'sudo LD_LIBRARY_PATH=.:{DPDK_PATH}/lib64/ {workSpacePath}/ran_build/build/{physim_test} {options} >> {runLogFile}')
physim_file = archiveArtifact(cmd, ctx, runLogFile)
success, msg = cls_analysis.Analysis.analyze_physim(physim_file, physim_test, options, threshold)
cmd.run(f'sudo {workSpacePath}/ran_build/build/{physim_test} {options} >> {workSpacePath}/{runLogFile}')
cmd.copyin(src=f'{workSpacePath}/{runLogFile}', tgt=f'{LOG_PATH_PHYSIM}/{runLogFile}')
success, msg = cls_analysis.Analysis.analyze_physim(f'{LOG_PATH_PHYSIM}/{runLogFile}', physim_test, options, threshold)
if success:
HTML.CreateHtmlTestRowQueue(options, 'OK', [msg])
else:

View File

@@ -47,7 +47,6 @@ import constants as CONST
import cls_module
import cls_corenetwork
import cls_cmd
from cls_ci_helper import archiveArtifact
#-----------------------------------------------------------
# Helper functions used here and in other classes
@@ -84,29 +83,6 @@ def Iperf_ComputeTime(args):
raise Exception('Iperf time not found!')
return int(result.group('iperf_time'))
def convert_to_mbps(value, magnitude):
value = float(value)
if magnitude == 'K' or magnitude == 'k':
return value / 1000
elif magnitude == 'M':
return value
elif magnitude == 'G':
return value * 1000
else:
return value
def extract_iperf_data(res):
if not res:
return None
bitrate_val = res.group('bitrate')
magnitude = res.group('magnitude')
return {
'bitrate_mbps': convert_to_mbps(bitrate_val, magnitude),
'jitter': res.group('jitter'),
'packetloss': res.group('packetloss'),
'bitrate_disp': f'{float(bitrate_val):.2f} {magnitude}bps'
}
def Iperf_analyzeV3TCPJson(filename, iperf_tcp_rate_target):
try:
with open(filename) as f:
@@ -154,36 +130,53 @@ def Iperf_analyzeV3BIDIRJson(filename):
return (True, msg)
def Iperf_analyzeV3UDP(filename, iperf_bitrate_threshold, iperf_packetloss_threshold, target_bitrate):
if not os.path.isfile(filename):
if (not os.path.isfile(filename)):
return (False, 'Iperf3 UDP: Log file not present')
if os.path.getsize(filename) == 0:
if (os.path.getsize(filename)==0):
return (False, 'Iperf3 UDP: Log file is empty')
sender_data = None
receiver_data = None
sender_bitrate = None
receiver_bitrate = None
with open(filename, 'r') as server_file:
for line in server_file:
res_sender = re.search(r'(?P<bitrate>[0-9\.]+)\s+(?P<magnitude>[kKMG]?)bits\/sec\s+(?P<jitter>[0-9\.]+\s+ms)\s+(?P<lostPack>-?\d+)/(?P<sentPack>-?\d+)\s+\((?P<packetloss>[0-9\.eE\-\+]+).*?\s+(sender)', line)
res_receiver = re.search(r'(?P<bitrate>[0-9\.]+)\s+(?P<magnitude>[kKMG]?)bits\/sec\s+(?P<jitter>[0-9\.]+\s+ms)\s+(?P<lostPack>-?\d+)/(?P<receivedPack>-?\d+)\s+\((?P<packetloss>[0-9\.eE\-\+]+)%\).*?(receiver)', line)
if res_sender:
sender_data = extract_iperf_data(res_sender)
if res_receiver:
receiver_data = extract_iperf_data(res_receiver)
if not sender_data or not receiver_data:
return (False, 'Could not analyze iperf report')
for line in server_file.readlines():
res_sender = re.search(r'(?P<bitrate>[0-9\.]+)\s+(?P<unit>[KMG]?bits\/sec)\s+(?P<jitter>[0-9\.]+\s+ms)\s+(?P<lostPack>-?\d+)/(?P<sentPack>-?\d+) \((?P<lost>[0-9\.]+).*?\s+(sender)', line)
res_receiver = re.search(r'(?P<bitrate>[0-9\.]+)\s+(?P<unit>[KMG]?bits\/sec)\s+(?P<jitter>[0-9\.]+\s+ms)\s+(?P<lostPack>-?\d+)/(?P<receivedPack>-?\d+)\s+\((?P<lost>[0-9\.]+)%\).*?(receiver)', line)
if res_sender is not None:
sender_bitrate = res_sender.group('bitrate')
sender_unit = res_sender.group('unit')
sender_jitter = res_sender.group('jitter')
sender_lostPack = res_sender.group('lostPack')
sender_sentPack = res_sender.group('sentPack')
sender_packetloss = res_sender.group('lost')
if res_receiver is not None:
receiver_bitrate = res_receiver.group('bitrate')
receiver_unit = res_receiver.group('unit')
receiver_jitter = res_receiver.group('jitter')
receiver_lostPack = res_receiver.group('lostPack')
receiver_receivedPack = res_receiver.group('receivedPack')
receiver_packetloss = res_receiver.group('lost')
br_perf = 100 * receiver_data['bitrate_mbps'] / float(target_bitrate)
br_perf_str = f'{br_perf:.2f}%'
req_msg = f"Sender Bitrate : {sender_data['bitrate_disp']}"
bir_msg = f"Receiver Bitrate: {receiver_data['bitrate_disp']} ({br_perf_str})"
jit_msg = f"Jitter : {receiver_data['jitter']}"
pal_msg = f"Packet Loss : {receiver_data['packetloss']}%"
if br_perf < float(iperf_bitrate_threshold):
bir_msg += f' (too low! < {iperf_bitrate_threshold}%)'
if float(receiver_data['packetloss']) > float(iperf_packetloss_threshold):
pal_msg += f' (too high! > {iperf_packetloss_threshold}%)'
result = br_perf >= float(iperf_bitrate_threshold) and float(receiver_data['packetloss']) <= float(iperf_packetloss_threshold)
return (result, f'{req_msg}\n{bir_msg}\n{jit_msg}\n{pal_msg}')
if receiver_bitrate is not None and sender_bitrate is not None:
if sender_unit == 'Kbits/sec':
sender_bitrate = float(sender_bitrate) / 1000
if receiver_unit == 'Kbits/sec':
receiver_bitrate = float(receiver_bitrate) / 1000
br_perf = 100 * float(receiver_bitrate) / float(target_bitrate)
br_perf = '%.2f ' % br_perf
sender_bitrate = '%.2f ' % float(sender_bitrate)
receiver_bitrate = '%.2f ' % float(receiver_bitrate)
req_msg = f'Sender Bitrate : {sender_bitrate} Mbps'
bir_msg = f'Receiver Bitrate: {receiver_bitrate} Mbps'
brl_msg = f'{br_perf}%'
jit_msg = f'Jitter : {receiver_jitter}'
pal_msg = f'Packet Loss : {receiver_packetloss} %'
if float(br_perf) < float(iperf_bitrate_threshold):
brl_msg = f'too low! < {iperf_bitrate_threshold}%'
if float(receiver_packetloss) > float(iperf_packetloss_threshold):
pal_msg += f' (too high! > {iperf_packetloss_threshold}%)'
result = float(br_perf) >= float(iperf_bitrate_threshold) and float(receiver_packetloss) <= float(iperf_packetloss_threshold)
return (result, f'{req_msg}\n{bir_msg} ({brl_msg})\n{jit_msg}\n{pal_msg}')
else:
return (False, 'Could not analyze iperf report')
def Iperf_analyzeV2UDP(server_filename, iperf_bitrate_threshold, iperf_packetloss_threshold, target_bitrate):
result = None
@@ -197,9 +190,12 @@ def Iperf_analyzeV2UDP(server_filename, iperf_bitrate_threshold, iperf_packetlos
result = re.search(statusTemplate, str(line)) or result
if result is None:
return (False, 'Could not parse server report!')
bitrate_val = float(result.group('bitrate'))
magnitude = result.group('magnitude')
bitrate = convert_to_mbps(bitrate_val, magnitude)
bitrate = float(result.group('bitrate'))
magn = result.group('magnitude')
if magn == "k" or magn == "K":
bitrate /= 1000
elif magn == "G": # we assume bitrate in Mbps, therefore it must be G now
bitrate *= 1000
jitter = float(result.group('jitter'))
packetloss = float(result.group('packetloss'))
br_perf = float(bitrate)/float(target_bitrate) * 100
@@ -260,7 +256,9 @@ class OaiCiTest():
self.ranAllowMerge = False
self.ranTargetBranch = ''
self.testCase_id = ''
self.testXMLfiles = []
self.desc = ''
self.ping_args = ''
self.ping_packetloss_threshold = ''
self.ping_rttavg_threshold =''
@@ -354,7 +352,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue('NA', 'OK', messages)
return True
def Ping_common(self, ctx, cn, ue):
def Ping_common(self, cn, ue, logPath):
ping_status = 0
ueIP = ue.getIP()
if not ueIP:
@@ -362,12 +360,13 @@ class OaiCiTest():
svrIP = cn.getIP()
if not svrIP:
return (False, f"CN {cn.getName()} has no IP address")
ping_log_file = f'/tmp/ping_{ue.getName()}.log'
ping_log_file = f'ping_{self.testCase_id}_{ue.getName()}.log'
ping_time = re.findall(r"-c *(\d+)",str(self.ping_args))
local_ping_log_file = f'{logPath}/{ping_log_file}'
if re.search('%cn_ip%', self.ping_args) or re.search(r'[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+', self.ping_args):
raise Exception(f"ping_args should not have IP address: {self.ping_args}")
interface = f'-I {ue.getIFName()}' if ue.getIFName() else ''
ping_cmd = f'{ue.getCmdPrefix()} ping {interface} {self.ping_args} {svrIP} 2>&1 | tee {ping_log_file}'
ping_cmd = f'{ue.getCmdPrefix()} ping {interface} {self.ping_args} {svrIP} 2>&1 | tee /tmp/{ping_log_file}'
cmd = cls_cmd.getConnection(ue.getHost())
response = cmd.run(ping_cmd, timeout=int(ping_time[0])*1.5)
ue_header = f'UE {ue.getName()} ({ueIP})'
@@ -375,7 +374,8 @@ class OaiCiTest():
message = ue_header + ': ping crashed: TIMEOUT?'
return (False, message)
local_ping_log_file = archiveArtifact(cmd, ctx, ping_log_file)
#copy the ping log file to have it locally for analysis (ping stats)
cmd.copyin(src=f'/tmp/{ping_log_file}', tgt=local_ping_log_file)
cmd.close()
with open(local_ping_log_file, 'r') as f:
@@ -415,13 +415,18 @@ class OaiCiTest():
return (True, message)
def Ping(self, ctx, HTML, infra_file="ci_infra.yaml"):
def Ping(self, HTML, CONTAINERS, infra_file="ci_infra.yaml"):
if self.ue_ids == [] or self.svr_id == None:
raise Exception("no module names in self.ue_ids or/and self.svr_id provided")
# Creating destination log folder if needed on the python executor workspace
with cls_cmd.getConnection('localhost') as local:
ymlPath = CONTAINERS.yamlPath[0].split('/')
logPath = f'{os.getcwd()}/../cmake_targets/log/{ymlPath[-1]}'
local.run(f'mkdir -p {logPath}', silent=True)
ues = [cls_module.Module_UE(ue_id, server_name, infra_file) for ue_id, server_name in zip(self.ue_ids, self.nodes)]
cn = cls_corenetwork.CoreNetwork(self.svr_id, self.svr_node, filename=infra_file)
with concurrent.futures.ThreadPoolExecutor(max_workers=64) as executor:
futures = [executor.submit(self.Ping_common, ctx, cn, ue) for ue in ues]
futures = [executor.submit(self.Ping_common, cn, ue, logPath) for ue in ues]
results = [f.result() for f in futures]
# each result in results is a tuple, first member goes to successes, second to messages
successes, messages = map(list, zip(*results))
@@ -442,7 +447,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', messages)
return success
def Iperf_Module(self, ctx, cn, ue, idx, ue_num):
def Iperf_Module(self, cn, ue, idx, ue_num, logPath):
ueIP = ue.getIP()
if not ueIP:
return (False, f"UE {ue.getName()} has no IP address")
@@ -455,7 +460,7 @@ class OaiCiTest():
serverReport = ""
udpIperf = re.search('-u', iperf_opt) is not None
bidirIperf = re.search('--bidir', iperf_opt) is not None
client_filename = f'/tmp/iperf_client_{ue.getName()}.log'
client_filename = f'iperf_client_{self.testCase_id}_{ue.getName()}.log'
if udpIperf:
target_bitrate, iperf_opt = Iperf_ComputeModifiedBW(idx, ue_num, self.iperf_profile, self.iperf_args)
# note: for UDP testing we don't want to use json report - reports 0 Mbps received bitrate
@@ -470,11 +475,14 @@ class OaiCiTest():
port = 5002 + idx
# note: some core setups start an iperf3 server automatically, indicated in ci_infra by runIperf3Server: False`
t = iperf_time * 2.5
cmd_ue.run(f'rm {client_filename}', reportNonZero=False, silent=True)
cmd_ue.run(f'rm /tmp/{client_filename}', reportNonZero=False, silent=True)
if cn.runIperf3Server():
cmd_svr.run(f'{cn.getCmdPrefix()} timeout -vk3 {t} iperf3 -s -B {svrIP} -p {port} -1 {jsonReport} >> /dev/null &', timeout=t)
cmd_ue.run(f'{ue.getCmdPrefix()} timeout -vk3 {t} {iperf_ue} -B {ueIP} -c {svrIP} -p {port} {iperf_opt} {jsonReport} {serverReport} -O 5 >> {client_filename}', timeout=t)
dest_filename = archiveArtifact(cmd_ue, ctx, client_filename)
cmd_ue.run(f'{ue.getCmdPrefix()} timeout -vk3 {t} {iperf_ue} -B {ueIP} -c {svrIP} -p {port} {iperf_opt} {jsonReport} {serverReport} -O 5 >> /tmp/{client_filename}', timeout=t)
# note: copy iperf3 log to the current directory for log analysis and log collection
dest_filename = f'{logPath}/{client_filename}'
cmd_ue.copyin(f'/tmp/{client_filename}', dest_filename)
cmd_ue.run(f'rm /tmp/{client_filename}', reportNonZero=False, silent=True)
if udpIperf:
status, msg = Iperf_analyzeV3UDP(dest_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate)
elif bidirIperf:
@@ -484,15 +492,20 @@ class OaiCiTest():
return (status, f'{ue_header}\n{msg}')
def Iperf(self, ctx, HTML, infra_file="ci_infra.yaml"):
def Iperf(self, HTML, CONTAINERS, infra_file="ci_infra.yaml"):
logging.debug(f'Iperf: iperf_args "{self.iperf_args}" iperf_packetloss_threshold "{self.iperf_packetloss_threshold}" iperf_bitrate_threshold "{self.iperf_bitrate_threshold}" iperf_profile "{self.iperf_profile}" iperf_options "{self.iperf_options}"')
if self.ue_ids == [] or self.svr_id == None:
raise Exception("no module names in self.ue_ids or/and self.svr_id provided")
# create log directory on executor node
with cls_cmd.getConnection('localhost') as local:
ymlPath = CONTAINERS.yamlPath[0].split('/')
logPath = f'{os.getcwd()}/../cmake_targets/log/{ymlPath[-1]}'
local.run(f'mkdir -p {logPath}', silent=True)
ues = [cls_module.Module_UE(ue_id, server_name, infra_file) for ue_id, server_name in zip(self.ue_ids, self.nodes)]
cn = cls_corenetwork.CoreNetwork(self.svr_id, self.svr_node, filename=infra_file)
with concurrent.futures.ThreadPoolExecutor(max_workers=64) as executor:
futures = [executor.submit(self.Iperf_Module, ctx, cn, ue, i, len(ues)) for i, ue in enumerate(ues)]
futures = [executor.submit(self.Iperf_Module, cn, ue, i, len(ues), logPath) for i, ue in enumerate(ues)]
results = [f.result() for f in futures]
# each result in results is a tuple, first member goes to successes, second to messages
successes, messages = map(list, zip(*results))
@@ -513,7 +526,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', messages)
return success
def Iperf2_Unidir(self, ctx, HTML, infra_file="ci_infra.yaml"):
def Iperf2_Unidir(self, HTML, CONTAINERS, infra_file="ci_infra.yaml"):
if self.ue_ids == [] or self.svr_id == None or len(self.ue_ids) != 1:
raise Exception("no module names in self.ue_ids or/and self.svr_id provided, multi UE scenario not supported")
ue = cls_module.Module_UE(self.ue_ids[0].strip(),self.nodes[0].strip(), infra_file)
@@ -524,17 +537,23 @@ class OaiCiTest():
svrIP = cn.getIP()
if not svrIP:
return False
server_filename = f'/tmp/iperf_server_{ue.getName()}.log'
server_filename = f'iperf_server_{self.testCase_id}_{ue.getName()}.log'
ymlPath = CONTAINERS.yamlPath[0].split('/')
logPath = f'{os.getcwd()}/../cmake_targets/log/{ymlPath[-1]}'
iperf_time = Iperf_ComputeTime(self.iperf_args)
target_bitrate, iperf_opt = Iperf_ComputeModifiedBW(0, 1, self.iperf_profile, self.iperf_args)
t = iperf_time*2.5
with cls_cmd.getConnection('localhost') as local:
local.run(f'mkdir -p {logPath}')
with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(cn.getHost()) as cmd_svr:
cmd_ue.run(f'rm {server_filename}', reportNonZero=False)
cmd_ue.run(f'{ue.getCmdPrefix()} timeout -vk3 {t} iperf -B {ueIP} -s -u -i1 >> {server_filename} &', timeout=t)
cmd_ue.run(f'rm /tmp/{server_filename}', reportNonZero=False)
cmd_ue.run(f'{ue.getCmdPrefix()} timeout -vk3 {t} iperf -B {ueIP} -s -u -i1 >> /tmp/{server_filename} &', timeout=t)
cmd_svr.run(f'{cn.getCmdPrefix()} timeout -vk3 {t} iperf -c {ueIP} -B {svrIP} {iperf_opt} -i1 >> /dev/null', timeout=t)
localPath = f'{os.getcwd()}'
local = archiveArtifact(cmd_ue, ctx, server_filename)
success, msg = Iperf_analyzeV2UDP(local, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate)
# note: copy iperf2 log to the directory for log collection
cmd_ue.copyin(f'/tmp/{server_filename}', f'{logPath}/{server_filename}')
cmd_ue.run(f'rm /tmp/{server_filename}', reportNonZero=False)
success, msg = Iperf_analyzeV2UDP(f'{logPath}/{server_filename}', self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate)
ue_header = f'UE {ue.getName()} ({ueIP})'
logging.info(f'\u001B[1;37;45m iperf result for {ue_header}\u001B[0m')
for l in msg.split('\n'):
@@ -816,17 +835,17 @@ class OaiCiTest():
global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC
return global_status
def TerminateUE(self, ctx, HTML):
def TerminateUE(self, HTML):
ues = [cls_module.Module_UE(n.strip()) for n in self.ue_ids]
with concurrent.futures.ThreadPoolExecutor(max_workers=64) as executor:
futures = [executor.submit(ue.terminate, ctx) for ue in ues]
futures = [executor.submit(ue.terminate) for ue in ues]
archives = [f.result() for f in futures]
archive_info = [f'Log at: {a}' if a else 'No log available' for a in archives]
messages = [f"UE {ue.getName()}: {log}" for (ue, log) in zip(ues, archive_info)]
HTML.CreateHtmlTestRowQueue(f'N/A', 'OK', messages)
return True
def DeployCoreNetwork(cn_id, ctx, HTML):
def DeployCoreNetwork(cn_id, HTML):
core_name = cn_id.strip()
cn = cls_corenetwork.CoreNetwork(core_name)
success, output = cn.deploy()
@@ -840,11 +859,41 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(core_name, 'KO', [msg])
return success
def UndeployCoreNetwork(cn_id, ctx, HTML):
def UndeployCoreNetwork(cn_id, HTML):
# Ping, Iperf, DeployObject put logs into a path based on YAML. We
# can't do this here (because there is no yaml), so hardcode a path for
# "cn_logs" for the moment
logPath = f'{os.getcwd()}/../cmake_targets/log/cn_logs'
with cls_cmd.getConnection('localhost') as local:
local.run(f'mkdir -p {logPath}', silent=True)
core_name = cn_id.strip()
cn = cls_corenetwork.CoreNetwork(core_name)
logs, output = cn.undeploy(ctx=ctx)
logs, output = cn.undeploy(log_dir=logPath)
logging.info(f"undeployed core network {core_name}, logs {logs}, output:\n{output}")
message = "Log files:\n" + "\n".join([os.path.basename(l) for l in logs])
message = "Log files: " + ", ".join([os.path.basename(l) for l in logs])
HTML.CreateHtmlTestRowQueue(core_name, 'OK', [message])
return True
def LogCollectBuild(self,RAN):
# Some pipelines are using "none" IP / Credentials
# In that case, just forget about it
if RAN.eNBIPAddress == 'none':
sys.exit(0)
if (RAN.eNBIPAddress != '' and RAN.eNBUserName != '' and RAN.eNBPassword != ''):
IPAddress = RAN.eNBIPAddress
UserName = RAN.eNBUserName
Password = RAN.eNBPassword
SourceCodePath = RAN.eNBSourceCodePath
else:
sys.exit('Insufficient Parameter')
with cls_cmd.getConnection(IPAddress) as cmd:
d = f'{SourceCodePath}/cmake_targets'
cmd.run(f'rm -f {d}/build.log.zip')
cmd.run(f'cd {d} && zip -r build.log.zip build_log_*/*')
def ShowTestID(self):
logging.info(f'\u001B[1m----------------------------------------\u001B[0m')
logging.info(f'\u001B[1m Test ID: {self.testCase_id} \u001B[0m')
logging.info(f'\u001B[1m {self.desc} \u001B[0m')
logging.info(f'\u001B[1m----------------------------------------\u001B[0m')

View File

@@ -43,7 +43,6 @@ from pathlib import Path
import helpreadme as HELP
import constants as CONST
import cls_cmd
from cls_ci_helper import archiveArtifact
#-----------------------------------------------------------
# Class Declaration
@@ -81,7 +80,7 @@ class StaticCodeAnalysis():
self.eNBPassword = ''
self.eNBSourceCodePath = ''
def CppCheckAnalysis(self, ctx, HTML):
def CppCheckAnalysis(self, HTML):
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
@@ -104,7 +103,7 @@ class StaticCodeAnalysis():
full_ran_repo_name = self.ranRepository + '.git'
cmd.cd(lSourcePath)
logDir = f'{lSourcePath}/cmake_targets/log'
logDir = f'{lSourcePath}/cmake_targets/build_log_{self.testCase_id}'
cmd.run(f'mkdir -p {logDir}')
cmd.run('docker image rm oai-cppcheck:bionic oai-cppcheck:focal')
cmd.run(f'sed -e "s@xenial@bionic@" {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.xenial > {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.bionic')
@@ -113,21 +112,31 @@ class StaticCodeAnalysis():
cmd.run(f'docker build --tag oai-cppcheck:focal --file {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.focal . > {logDir}/cppcheck-focal.txt 2>&1')
cmd.run('docker image rm oai-cppcheck:bionic oai-cppcheck:focal')
bionic = archiveArtifact(cmd, ctx, f'{logDir}/cppcheck-bionic.txt')
focal = archiveArtifact(cmd, ctx, f'{logDir}/cppcheck-focal.txt')
# Analyzing the logs
cmd.copyin(f'{logDir}/cppcheck-bionic.txt', 'cppcheck-bionic.txt')
cmd.copyin(f'{logDir}/cppcheck-focal.txt', 'cppcheck-focal.txt')
cmd.close()
CCR = CppCheckResults()
CCR_ref = CppCheckResults()
vId = 0
for variant in CCR.variants:
filename = ctx.baseFilename() + '-cppcheck-'+ variant + '.txt'
logging.info(f"will check file '{filename}'")
if not os.path.isfile(filename):
raise FileNotFoundError(f"{filename} is not a file")
else:
refAvailable = False
if self.ranAllowMerge:
refFolder = str(Path.home()) + '/cppcheck-references'
if (os.path.isfile(refFolder + '/cppcheck-'+ variant + '.txt')):
refAvailable = True
with open(refFolder + '/cppcheck-'+ variant + '.txt', 'r') as refFile:
for line in refFile:
ret = re.search(' (?P<nb_errors>[0-9\.]+) errors', str(line))
if ret is not None:
CCR_ref.nbErrors[vId] = int(ret.group('nb_errors'))
ret = re.search(' (?P<nb_warnings>[0-9\.]+) warnings', str(line))
if ret is not None:
CCR_ref.nbWarnings[vId] = int(ret.group('nb_warnings'))
if (os.path.isfile('./cppcheck-'+ variant + '.txt')):
xmlStart = False
with open(filename, 'r') as logfile:
with open('./cppcheck-'+ variant + '.txt', 'r') as logfile:
for line in logfile:
ret = re.search('cppcheck version="(?P<version>[0-9\.]+)"', str(line))
if ret is not None:
@@ -176,6 +185,26 @@ class StaticCodeAnalysis():
vMsg += ' Wrong Scanf Nb Args: ' + str(CCR.nbWrongScanfArg[vId]) + '\n'
for vLine in vMsg.split('\n'):
logging.debug(vLine)
if self.ranAllowMerge and refAvailable:
if CCR_ref.nbErrors[vId] == CCR.nbErrors[vId]:
logging.debug(' No change in number of errors')
elif CCR_ref.nbErrors[vId] > CCR.nbErrors[vId]:
logging.debug(' Good! Decrease in number of errors')
else:
logging.debug(' Bad! increase in number of errors')
if CCR_ref.nbWarnings[vId] == CCR.nbWarnings[vId]:
logging.debug(' No change in number of warnings')
elif CCR_ref.nbWarnings[vId] > CCR.nbWarnings[vId]:
logging.debug(' Good! Decrease in number of warnings')
else:
logging.debug(' Bad! increase in number of warnings')
# Create new reference file
if not self.ranAllowMerge:
refFolder = str(Path.home()) + '/cppcheck-references'
if not os.path.isdir(refFolder):
os.mkdir(refFolder)
with open(refFolder + '/cppcheck-'+ variant + '.txt', 'w') as refFile:
refFile.write(vMsg)
vId += 1
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
@@ -184,7 +213,7 @@ class StaticCodeAnalysis():
return True
def LicenceAndFormattingCheck(self, ctx, HTML):
def LicenceAndFormattingCheck(self, HTML):
# Workspace is no longer recreated from scratch.
# It implies that this method shall be called last within a build pipeline
# where workspace is already created
@@ -209,7 +238,7 @@ class StaticCodeAnalysis():
else:
check_options += f' --build-arg TARGET_BRANCH={self.ranTargetBranch}'
logDir = f'{lSourcePath}/cmake_targets/log/'
logDir = f'{lSourcePath}/cmake_targets/build_log_{self.testCase_id}'
cmd.run(f'mkdir -p {logDir}')
cmd.run('docker image rm oai-formatting-check:latest')
cmd.run(f'docker build --target oai-formatting-check --tag oai-formatting-check:latest {check_options} --file {lSourcePath}/ci-scripts/docker/Dockerfile.formatting.bionic {lSourcePath} > {logDir}/oai-formatting-check.txt 2>&1')
@@ -218,11 +247,12 @@ class StaticCodeAnalysis():
cmd.run('docker image prune --force')
cmd.run('docker volume prune --force')
file = archiveArtifact(cmd, ctx, f'{logDir}/oai-formatting-check.txt')
# Analyzing the logs
cmd.copyin(f'{logDir}/oai-formatting-check.txt', 'oai-formatting-check.txt')
cmd.close()
finalStatus = 0
if (os.path.isfile(file)):
if (os.path.isfile('./oai-formatting-check.txt')):
analyzed = False
nbFilesNotFormatted = 0
listFiles = False
@@ -233,7 +263,7 @@ class StaticCodeAnalysis():
gnuGplLicenceFiles = []
suspectLicence = False
suspectLicenceFiles = []
with open(file, 'r') as logfile:
with open('./oai-formatting-check.txt', 'r') as logfile:
for line in logfile:
ret = re.search('./ci-scripts/checkCodingFormattingRules.sh', str(line))
if ret is not None:

View File

@@ -23,7 +23,9 @@ gNBs =
local_s_address = "192.168.71.150";
remote_s_address = "192.168.71.171";
local_s_portc = 501;
local_s_portd = 2153;
remote_s_portc = 500;
remote_s_portd = 2153;
# ------- SCTP definitions

View File

@@ -23,7 +23,9 @@ gNBs =
local_s_address = "127.0.0.4";
remote_s_address = "127.0.0.5";
local_s_portc = 501;
local_s_portd = 2153;
remote_s_portc = 500;
remote_s_portd = 2153;
# ------- SCTP definitions

View File

@@ -23,7 +23,9 @@ gNBs =
local_s_address = "192.168.71.150";
remote_s_address = "0.0.0.0"; # multiple DUs
local_s_portc = 501;
local_s_portd = 2152;
remote_s_portc = 500;
remote_s_portd = 2152;
# ------- SCTP definitions

View File

@@ -23,7 +23,9 @@ gNBs =
local_s_address = "127.0.0.4";
remote_s_address = "127.0.0.5";
local_s_portc = 501;
local_s_portd = 2153;
remote_s_portc = 500;
remote_s_portd = 2153;
# ------- SCTP definitions

View File

@@ -22,7 +22,9 @@ gNBs =
local_s_address = "192.168.72.161";
remote_s_address = "192.168.72.171";
local_s_portc = 501;
local_s_portd = 2153;
remote_s_portc = 500;
remote_s_portd = 2153;
# ------- SCTP definitions

View File

@@ -22,7 +22,9 @@ gNBs =
local_s_address = "127.0.0.6";
remote_s_address = "127.0.0.5";
local_s_portc = 501;
local_s_portd = 2153;
remote_s_portc = 500;
remote_s_portd = 2153;
# ------- SCTP definitions

View File

@@ -163,7 +163,9 @@ MACRLCs = (
tr_n_preference = "f1";
local_n_address = "127.0.0.5";
remote_n_address = "127.0.0.4";
local_n_portc = 500;
local_n_portd = 2153;
remote_n_portc = 501;
remote_n_portd = 2153;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;

View File

@@ -168,7 +168,9 @@ MACRLCs = (
tr_n_preference = "f1";
local_n_address = "192.168.71.171";
remote_n_address = "192.168.71.150";
local_n_portc = 500;
local_n_portd = 2153;
remote_n_portc = 501;
remote_n_portd = 2153;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;

View File

@@ -34,9 +34,11 @@ gNBs =
# downlinkConfigCommon
#frequencyInfoDL
absoluteFrequencySSB = 641280; # GSCN: 7929, Freq: 3619.200 MHz
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641280;
dl_frequencyBand = 78;
dl_absoluteFrequencyPointA = 640752; # 3611.280 MHz
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640008;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
@@ -45,12 +47,13 @@ gNBs =
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
initialDLBWPlocationAndBandwidth = 13750; # RBstart=0, L=51 (275*(L-1))+RBstart
# 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 = 10;
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
@@ -65,7 +68,7 @@ gNBs =
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 13750; # RBstart=0, L=51 (275*(L-1))+RBstart
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
@@ -149,18 +152,6 @@ gNBs =
);
servingCellConfigDedicated = ({
dl_bwp-Id_1 = 1;
dl_bwp1_locationAndBandwidth = 28875; # RBstart=0, L=106 (275*(L-1))+RBstart
dl_bwp1_subcarrierSpacing = 1;
firstActiveDownlinkBWP-Id = 1;
defaultDownlinkBWP-Id = 1;
ul_bwp-Id_1 = 1;
ul_bwp1_locationAndBandwidth = 28875; # RBstart=0, L=106 (275*(L-1))+RBstart
ul_bwp1_subcarrierSpacing = 1;
firstActiveUplinkBWP-Id = 1;
});
# ------- SCTP definitions
SCTP :
@@ -204,7 +195,9 @@ MACRLCs = (
tr_n_preference = "f1";
local_n_address = "127.0.0.5";
remote_n_address = "127.0.0.4";
local_n_portc = 500;
local_n_portd = 2153;
remote_n_portc = 501;
remote_n_portd = 2153;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;

View File

@@ -31,11 +31,11 @@ gNBs =
# downlinkConfigCommon
#frequencyInfoDL
# this is 4412.64 MHz
absoluteFrequencySSB = 694176;
dl_frequencyBand = 79;
# this is 4400.94 MHz
dl_absoluteFrequencyPointA = 693396;
# this is 3319.68 MHz
absoluteFrequencySSB = 621312;
dl_frequencyBand = 78;
# this is 3300.6 MHz
dl_absoluteFrequencyPointA = 620040;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
@@ -55,7 +55,7 @@ gNBs =
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 79;
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing

View File

@@ -31,11 +31,11 @@ gNBs =
# downlinkConfigCommon
#frequencyInfoDL
# this is 4435.68 MHz
absoluteFrequencySSB = 695712;
dl_frequencyBand = 79;
# this is 4400.94 MHz
dl_absoluteFrequencyPointA = 693396;
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 621312;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 620040;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
@@ -55,7 +55,7 @@ gNBs =
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 79;
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing

View File

@@ -33,11 +33,11 @@ gNBs =
# downlinkConfigCommon
#frequencyInfoDL
# this is 4458.72 MHz
absoluteFrequencySSB = 697248;
dl_frequencyBand = 79;
# this is 4400.94 MHz
dl_absoluteFrequencyPointA = 693396;
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 621312;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 620040;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
@@ -57,7 +57,7 @@ gNBs =
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 79;
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing

View File

@@ -16,6 +16,7 @@ gNBs =
////////// Physical parameters:
sib1_tda = 5;
min_rxtxtime = 6;
num_dlharq = 32;
num_ulharq = 32;
@@ -149,8 +150,6 @@ gNBs =
#ext2
#ntn_Config_r17
# This can be of values {s5, s10, s15, s20, s25, s30, s35, s40, s45, s50, s55, s60, s120, s180, s240, s900}
ntn-UlSyncValidityDuration-r17 = 5;
cellSpecificKoffset_r17 = 40;
ta-Common-r17 = 4627000; # 18.84 ms
ta-CommonDrift-r17 = -230000; # -46 µs/s

View File

@@ -16,6 +16,7 @@ gNBs =
////////// Physical parameters:
sib1_tda = 5;
min_rxtxtime = 6;
disable_harq = 1;
cu_sibs = [2];

View File

@@ -35,8 +35,8 @@ gNBs =
# downlinkConfigCommon
#frequencyInfoDL
dl_frequencyBand = 78;
absoluteFrequencySSB = 628320;
dl_absoluteFrequencyPointA = 627062;
absoluteFrequencySSB = 634080;
dl_absoluteFrequencyPointA = 632808;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
@@ -197,7 +197,7 @@ RUs = (
local_rf = "yes";
nb_tx = 1;
nb_rx = 1;
att_tx = 10;
att_tx = 0;
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;

View File

@@ -34,11 +34,11 @@ gNBs =
# downlinkConfigCommon
#frequencyInfoDL
# this is 3410.400 MHz
absoluteFrequencySSB = 627360;
# this is 3469.44 MHz => 301 REs from PointA 25 PRBs + 1 RE
absoluteFrequencySSB = 631296;
dl_frequencyBand = 78;
# this is 3401.220 MHz
dl_absoluteFrequencyPointA = 626748;
# this is 3469.44 - (51*12*30e-3/2) = 3460.26 MHz
dl_absoluteFrequencyPointA = 630684;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing

View File

@@ -1,10 +1,8 @@
uicc0 = {
imsi = "208970100001127";
imsi = "001010000000001";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "c42449363bbad02b66d16bc975d77cc1";
dnn= "oai";
nssai_sst=1;
nssai_sd=66051;
#nssai_sst=1;
}
thread-pool = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"

View File

@@ -43,10 +43,8 @@ import cls_containerize #class Containerize for all container-based operations
import cls_static_code_analysis #class for static code analysis
import cls_cluster # class for building/deploying on cluster
import cls_native # class for all native/source-based operations
from cls_ci_helper import TestCaseCtx
import ran
import cls_cmd
import cls_oai_html
@@ -93,7 +91,7 @@ def AssignParams(params_dict):
setattr(RAN, key, value)
setattr(HTML, key, value)
def ExecuteActionWithParam(action, ctx):
def ExecuteActionWithParam(action):
global RAN
global HTML
global CONTAINERS
@@ -136,15 +134,15 @@ def ExecuteActionWithParam(action, ctx):
if proxy_commit is not None:
CONTAINERS.proxyCommit = proxy_commit
if action == 'Build_eNB':
success = cls_native.Native.Build(ctx, HTML.testCase_id, HTML, RAN.eNBIPAddress, RAN.eNBSourceCodePath, RAN.Build_eNB_args)
success = cls_native.Native.Build(HTML.testCase_id, HTML, RAN.eNBIPAddress, RAN.eNBSourceCodePath, RAN.Build_eNB_args)
elif action == 'Build_Image':
success = CONTAINERS.BuildImage(ctx, HTML)
success = CONTAINERS.BuildImage(HTML)
elif action == 'Build_Proxy':
success = CONTAINERS.BuildProxy(ctx, HTML)
success = CONTAINERS.BuildProxy(HTML)
elif action == 'Build_Cluster_Image':
success = CLUSTER.BuildClusterImage(ctx, HTML)
success = CLUSTER.BuildClusterImage(HTML)
elif action == 'Build_Run_Tests':
success = CONTAINERS.BuildRunTests(ctx, HTML)
success = CONTAINERS.BuildRunTests(HTML)
elif action == 'Initialize_eNB':
datalog_rt_stats_file=test.findtext('rt_stats_cfg')
@@ -206,7 +204,7 @@ def ExecuteActionWithParam(action, ctx):
RAN.air_interface[RAN.eNB_instance] = 'lte-softmodem'
else:
RAN.air_interface[RAN.eNB_instance] = air_interface.lower() +'-softmodem'
success = RAN.TerminateeNB(ctx, HTML)
success = RAN.TerminateeNB(HTML)
elif action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Terminate_UE' or action == 'CheckStatusUE' or action == 'DataEnable_UE' or action == 'DataDisable_UE':
CiTestObj.ue_ids = test.findtext('id').split(' ')
@@ -228,7 +226,7 @@ def ExecuteActionWithParam(action, ctx):
elif action == 'Detach_UE':
success = CiTestObj.DetachUE(HTML)
elif action == 'Terminate_UE':
success = CiTestObj.TerminateUE(ctx, HTML)
success = CiTestObj.TerminateUE(HTML)
elif action == 'CheckStatusUE':
success = CiTestObj.CheckStatusUE(HTML)
elif action == 'DataEnable_UE':
@@ -255,7 +253,7 @@ def ExecuteActionWithParam(action, ctx):
else:
CiTestObj.nodes = [None] * len(CiTestObj.ue_ids)
ping_rttavg_threshold = test.findtext('ping_rttavg_threshold') or ''
success = CiTestObj.Ping(ctx, HTML)
success = CiTestObj.Ping(HTML, CONTAINERS)
elif action == 'Iperf' or action == 'Iperf2_Unidir':
CiTestObj.iperf_args = test.findtext('iperf_args')
@@ -286,9 +284,9 @@ def ExecuteActionWithParam(action, ctx):
logging.error('test-case has wrong option ' + CiTestObj.iperf_options)
CiTestObj.iperf_options = 'check'
if action == 'Iperf':
success = CiTestObj.Iperf(ctx, HTML)
success = CiTestObj.Iperf(HTML, CONTAINERS)
elif action == 'Iperf2_Unidir':
success = CiTestObj.Iperf2_Unidir(ctx, HTML)
success = CiTestObj.Iperf2_Unidir(HTML, CONTAINERS)
elif action == 'IdleSleep':
st = test.findtext('idle_sleep_time_in_sec') or "5"
@@ -297,12 +295,12 @@ def ExecuteActionWithParam(action, ctx):
elif action == 'Deploy_Run_PhySim':
oc_release = test.findtext('oc_release')
svr_id = test.findtext('svr_id') or None
success = CLUSTER.deploy_oc_physim(ctx, HTML, oc_release, svr_id)
success = CLUSTER.deploy_oc_physim(HTML, oc_release, svr_id)
elif action == 'DeployCoreNetwork' or action == 'UndeployCoreNetwork':
cn_id = test.findtext('cn_id')
core_op = getattr(cls_oaicitest.OaiCiTest, action)
success = core_op(cn_id, ctx, HTML)
success = core_op(cn_id, HTML)
elif action == 'Deploy_Object' or action == 'Undeploy_Object' or action == "Create_Workspace":
eNB_instance=test.findtext('eNB_instance')
@@ -330,9 +328,9 @@ def ExecuteActionWithParam(action, ctx):
CONTAINERS.num_attempts = int(test.findtext('num_attempts') or 1)
CONTAINERS.deploymentTag = cls_containerize.CreateTag(CONTAINERS.ranCommitID, CONTAINERS.ranBranch, CONTAINERS.ranAllowMerge)
if action == 'Deploy_Object':
success = CONTAINERS.DeployObject(ctx, HTML)
success = CONTAINERS.DeployObject(HTML)
elif action == 'Undeploy_Object':
success = CONTAINERS.UndeployObject(ctx, HTML, RAN)
success = CONTAINERS.UndeployObject(HTML, RAN)
elif action == 'Create_Workspace':
if force_local:
# Do not create a working directory when running locally. Current repo directory will be used
@@ -343,13 +341,13 @@ def ExecuteActionWithParam(action, ctx):
physim_options = test.findtext('physim_run_args')
physim_test = test.findtext('physim_test')
physim_threshold = test.findtext('physim_time_threshold') or 'inf'
success = cls_native.Native.Run_Physim(ctx, HTML, RAN.eNBIPAddress, RAN.eNBSourceCodePath, physim_options, physim_test, physim_threshold)
success = cls_native.Native.Run_Physim(HTML, RAN.eNBIPAddress, RAN.eNBSourceCodePath, physim_options, physim_test, physim_threshold)
elif action == 'LicenceAndFormattingCheck':
success = SCA.LicenceAndFormattingCheck(ctx, HTML)
success = SCA.LicenceAndFormattingCheck(HTML)
elif action == 'Cppcheck_Analysis':
success = SCA.CppCheckAnalysis(ctx, HTML)
success = SCA.CppCheckAnalysis(HTML)
elif action == 'Push_Local_Registry':
svr_id = test.findtext('svr_id')
@@ -409,11 +407,10 @@ def test_in_list(test, list):
def receive_signal(signum, frame):
sys.exit(1)
def ShowTestID(ctx, desc):
logging.info(f'\u001B[1m----------------------------------------\u001B[0m')
logging.info(f'\u001B[1m Test ID: {ctx.test_id} (#{ctx.count}) \u001B[0m')
logging.info(f'\u001B[1m {desc} \u001B[0m')
logging.info(f'\u001B[1m----------------------------------------\u001B[0m')
#-----------------------------------------------------------
# MAIN PART
@@ -469,7 +466,15 @@ if py_param_file_present == True:
cwd = os.getcwd()
if re.match('^TerminateeNB$', mode, re.IGNORECASE):
logging.warning("Option TerminateeNB ignored")
if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
if RAN.eNBIPAddress == 'none':
sys.exit(0)
RAN.eNB_instance=0
RAN.eNB_serverId[0]='0'
RAN.eNBSourceCodePath='/tmp/'
RAN.TerminateeNB(HTML)
elif re.match('^TerminateHSS$', mode, re.IGNORECASE):
logging.warning("Option TerminateHSS ignored")
elif re.match('^TerminateMME$', mode, re.IGNORECASE):
@@ -477,7 +482,12 @@ elif re.match('^TerminateMME$', mode, re.IGNORECASE):
elif re.match('^TerminateSPGW$', mode, re.IGNORECASE):
logging.warning("Option TerminateSPGW ignored")
elif re.match('^LogCollectBuild$', mode, re.IGNORECASE):
logging.warning("Option LogCollectBuild ignored")
if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '':
logging.warning("nothing to collect (eNBIPAddress/eNBUserName/eNBPassword/eNBSourceCodePath is '')")
sys.exit(0)
if RAN.eNBIPAddress == 'none':
sys.exit(0)
CiTestObj.LogCollectBuild(RAN)
elif re.match('^LogCollecteNB$', mode, re.IGNORECASE):
if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '':
HELP.GenericHelp(CONST.Version)
@@ -555,16 +565,6 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
else:
xml_test_file = cwd + "/" + CiTestObj.testXMLfiles[0]
# directory where all log artifacts will be placed
logPath = f"{cwd}/../cmake_targets/log/{CiTestObj.testXMLfiles[0].split('/')[-1]}.d"
# we run from within ci-scripts, but the logPath is absolute, so replace
# the ci-scripts/..; if it does not exist, nothing will happen
logPath = logPath.replace(r'/ci-scripts/..', '')
logging.info(f"placing all artifacts for this run in {logPath}/")
with cls_cmd.LocalCmd() as c:
c.run(f"rm -rf {logPath}")
c.run(f"mkdir -p {logPath}")
xmlTree = ET.parse(xml_test_file)
xmlRoot = xmlTree.getroot()
@@ -615,32 +615,29 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
task_set_succeeded = True
HTML.startTime=int(round(time.time() * 1000))
i = 0
for test_case_id in todo_tests:
for test in all_tests:
id = test.get('id')
if test_case_id != id:
continue
i += 1
CiTestObj.testCase_id = id
ctx = TestCaseCtx(i, int(id), logPath)
HTML.testCase_id=CiTestObj.testCase_id
desc = test.findtext('desc')
CiTestObj.desc = test.findtext('desc')
always_exec = test.findtext('always_exec') in ['True', 'true', 'Yes', 'yes']
may_fail = test.findtext('may_fail') in ['True', 'true', 'Yes', 'yes']
HTML.desc = desc
HTML.desc=CiTestObj.desc
action = test.findtext('class')
if (CheckClassValidity(xml_class_list, action, id) == False):
task_set_succeeded = False
continue
ShowTestID(ctx, desc)
CiTestObj.ShowTestID()
if not task_set_succeeded and not always_exec:
msg = f"skipping test due to prior error"
logging.warning(msg)
HTML.CreateHtmlTestRowQueue(msg, "SKIP", [])
break
try:
test_succeeded = ExecuteActionWithParam(action, ctx)
test_succeeded = ExecuteActionWithParam(action)
if not test_succeeded and may_fail:
logging.warning(f"test ID {test_case_id} action {action} may or may not fail, proceeding despite error")
elif not test_succeeded:

View File

@@ -46,7 +46,6 @@ import cls_cmd
import sshconnection as SSH
import helpreadme as HELP
import constants as CONST
from cls_ci_helper import archiveArtifact
#-----------------------------------------------------------
# Class Declaration
@@ -125,6 +124,7 @@ class RANManagement():
self.testCase_id = HTML.testCase_id
mySSH = SSH.SSHConnection()
cwd = os.getcwd()
mySSH.open(lIpAddr, lUserName, lPassWord)
mySSH.command('cd ' + lSourcePath, '\$', 5)
@@ -249,7 +249,42 @@ class RANManagement():
logging.debug('\u001B[1m Initialize eNB/gNB Completed\u001B[0m')
return enbDidSync
def TerminateeNB(self, ctx, HTML):
def CheckeNBProcess(self, status_queue):
# At least the instance 0 SHALL be on!
if self.eNBstatuses[0] == 0:
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
lPassWord = self.eNBPassword
elif self.eNBstatuses[0] == 1:
lIpAddr = self.eNB1IPAddress
lUserName = self.eNB1UserName
lPassWord = self.eNB1Password
elif self.eNBstatuses[0] == 2:
lIpAddr = self.eNB2IPAddress
lUserName = self.eNB2UserName
lPassWord = self.eNB2Password
else:
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
lPassWord = self.eNBPassword
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
if self.air_interface[self.eNB_instance] == '':
pattern = 'softmodem'
else:
pattern = self.air_interface[self.eNB_instance]
mySSH.command('stdbuf -o0 ps -aux | grep --color=never ' + pattern + ' | grep -v grep', '\$', 5)
result = re.search(pattern, mySSH.getBefore())
success = result is not None
if not success:
logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m')
status_queue.put(CONST.ENB_PROCESS_FAILED)
else:
status_queue.put(CONST.ENB_PROCESS_OK)
mySSH.close()
return success
def TerminateeNB(self, HTML):
if self.eNB_serverId[self.eNB_instance] == '0':
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
@@ -321,11 +356,13 @@ class RANManagement():
fileToAnalyze = self.eNBLogFiles[int(self.eNB_instance)]
self.eNBLogFiles[int(self.eNB_instance)] = ''
if analyzeFile:
with cls_cmd.getConnection(lIpAddr) as cmd:
file = archiveArtifact(cmd, ctx, lSourcePath + '/cmake_targets/' + fileToAnalyze)
archiveArtifact(cmd, ctx, lSourcePath + '/cmake_targets/nrL1_stats.log')
archiveArtifact(cmd, ctx, lSourcePath + '/cmake_targets/nrMAC_stats.log')
if file is None:
#*stats.log files + pickle + png
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/*stats.log', '.')
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/*.pickle', '.')
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/*.png', '.')
#
copyin_res = mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + fileToAnalyze, '.')
if (copyin_res == -1):
logging.debug('\u001B[1;37;41m Could not copy ' + nodeB_prefix + 'NB logfile to analyze it! \u001B[0m')
HTML.htmleNBFailureMsg='Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!'
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE)
@@ -338,8 +375,8 @@ class RANManagement():
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './nrL1_stats.log', self.eNBSourceCodePath + '/cmake_targets/')
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './nrMAC_stats.log', self.eNBSourceCodePath + '/cmake_targets/')
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/')
logging.debug('\u001B[1m Analyzing ' + nodeB_prefix + 'NB logfile \u001B[0m ' + file)
logStatus = self.AnalyzeLogFile_eNB(file, HTML, self.ran_checkers)
logging.debug('\u001B[1m Analyzing ' + nodeB_prefix + 'NB logfile \u001B[0m ' + fileToAnalyze)
logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze, HTML, self.ran_checkers)
if (logStatus < 0):
HTML.CreateHtmlTestRow('N/A', 'KO', logStatus)
#display rt stats for gNB only
@@ -697,16 +734,11 @@ class RANManagement():
datalog_rt_stats = yaml.load(f,Loader=yaml.FullLoader)
rt_keys = datalog_rt_stats['Ref'] #we use the keys from the Ref field
# nrL1_stats.log/nrMAC_stats.log should be in the same directory as main log file
# currently the link is only implicit as below based on pattern matching
# I will rework this to give the file explicitly
l1_stats_fn = re.sub(r'enb_[0-9]+', 'nrL1_stats', eNBlogFile)
mac_stats_fn = re.sub(r'enb_[0-9]+', 'nrMAC_stats', eNBlogFile)
if os.path.isfile(l1_stats_fn) and os.path.isfile(mac_stats_fn):
if os.path.isfile('./nrL1_stats.log') and os.path.isfile('./nrMAC_stats.log'):
# don't use CI-nrL1_stats.log, as this will increase the processing time for
# no reason, we just need the last occurence
nrL1_stats = open(l1_stats_fn, 'r')
nrMAC_stats = open(mac_stats_fn, 'r')
nrL1_stats = open('./nrL1_stats.log', 'r')
nrMAC_stats = open('./nrMAC_stats.log', 'r')
for line in nrL1_stats.readlines():
for k in rt_keys:
result = re.search(k, line)
@@ -726,7 +758,7 @@ class RANManagement():
nrL1_stats.close()
nrMAC_stats.close()
else:
logging.debug(f"NR Stats files for RT analysis not found: {l1_stats_fn}, {mac_stats_fn}")
logging.debug("NR Stats files for RT analysis not found")
#stdout log file and stat log files analysis completed
logging.debug(' File analysis (stdout, stats) completed')

View File

@@ -1,34 +0,0 @@
test:
Host: localhost
InitScript: ""
TermScript: ""
AttachScript: "true"
DetachScript: "true"
NetworkScript: ip a show dev lo
IF: lo
MTU: 65536
test-fail:
Host: localhost
InitScript: ""
TermScript: ""
AttachScript: "false"
DetachScript: "true"
NetworkScript: ip a show dev TESTDEVICEDOESNOTEXIST
IF: TESTDEVICEDOESNOTEXIST
MTU: 123
test-trace:
Host: localhost
InitScript: ""
TermScript: ""
AttachScript: "true"
DetachScript: "true"
Tracing:
# tttf: temp-trace-test-file
Start: "rm -f /tmp/tttf; for i in {1..8}; do echo $i >> /tmp/tttf; sleep 1; done &"
Stop: "while [[ $(wc -l /tmp/tttf) < 4 ]]; do sleep 1; done"
Collect: "cp /tmp/tttf %%log_dir%%"
NetworkScript: ip a show dev lo
IF: lo
MTU: 65536

View File

@@ -6,22 +6,14 @@ logging.basicConfig(
format="[%(asctime)s] %(levelname)8s: %(message)s"
)
import os
import tempfile
import unittest
sys.path.append('./') # to find OAI imports below
import cls_corenetwork
from cls_ci_helper import TestCaseCtx
import cls_cmd
class TestCoreNetwork(unittest.TestCase):
def setUp(self):
self.ctx = TestCaseCtx.Default(tempfile.mkdtemp())
def tearDown(self):
with cls_cmd.LocalCmd() as c:
c.run(f'rm -rf {self.ctx.logPath}')
def test_simple_core(self):
c = cls_corenetwork.CoreNetwork("test", filename="tests/config/test_core_infra.yaml")
success, output = c.deploy()
@@ -30,14 +22,14 @@ class TestCoreNetwork(unittest.TestCase):
# should not have it set in config
self.assertTrue(c.runIperf3Server())
self.assertEqual(c.getIP(), "127.0.0.1")
log_files, output = c.undeploy(self.ctx)
log_files, output = c.undeploy(log_dir="/tmp")
self.assertEqual(output, "undeploy")
with cls_cmd.LocalCmd() as cmd:
# there must be one log file for this (test) core
self.assertEqual(len(log_files), 1)
# undeploy uses archiveArtifact(), which writes to {prefix}-logs
# test core writes to %%log_dir%%/logs, which expands to /tmp/logs
l = log_files[0]
self.assertEqual(l, f"{self.ctx.baseFilename()}-logs")
self.assertEqual(l, "/tmp/logs")
ret = cmd.run(f"cat {l}")
self.assertEqual(ret.returncode, 0) # command must succeed
self.assertEqual(ret.stdout, "logs") # output should be "logs"
@@ -47,14 +39,14 @@ class TestCoreNetwork(unittest.TestCase):
success, _ = c.deploy()
self.assertTrue(success)
self.assertFalse(c.runIperf3Server())
c.undeploy(None)
c.undeploy(log_dir="/tmp")
def test_core_fail(self):
c = cls_corenetwork.CoreNetwork("test_fail", filename="tests/config/test_core_infra.yaml")
success, _ = c.deploy()
self.assertFalse(success)
# undeployment should still work
c.undeploy(None)
c.undeploy(log_dir="/tmp")
def test_core_script(self):
c = cls_corenetwork.CoreNetwork("test_script", filename="tests/config/test_core_infra.yaml")

View File

@@ -6,7 +6,6 @@ logging.basicConfig(
format="[%(asctime)s] %(levelname)8s: %(message)s"
)
import os
import tempfile
os.system(f'rm -rf cmake_targets')
os.system(f'mkdir -p cmake_targets/log')
import unittest
@@ -15,7 +14,6 @@ sys.path.append('./') # to find OAI imports below
import cls_oai_html
import cls_oaicitest
import cls_containerize
from cls_ci_helper import TestCaseCtx
import ran
import cls_cmd
@@ -50,16 +48,12 @@ class TestDeploymentMethods(unittest.TestCase):
self.cont.eNBPassword = None
self.cont.eNBSourceCodePath = os.getcwd()
self.cont.num_attempts = 3
self.ctx = TestCaseCtx.Default(tempfile.mkdtemp())
def tearDown(self):
with cls_cmd.LocalCmd() as c:
c.run(f'rm -rf {self.ctx.logPath}')
def test_deploy(self):
self.cont.yamlPath[0] = 'tests/simple-dep/'
self.cont.deploymentTag = "noble"
deploy = self.cont.DeployObject(self.ctx, self.html)
undeploy = self.cont.UndeployObject(self.ctx, self.html, self.ran)
deploy = self.cont.DeployObject(self.html)
undeploy = self.cont.UndeployObject(self.html, self.ran)
self.assertTrue(deploy)
self.assertTrue(undeploy)
@@ -67,8 +61,8 @@ class TestDeploymentMethods(unittest.TestCase):
# fails reliably
old = self.cont.yamlPath
self.cont.yamlPath[0] = 'tests/simple-fail/'
deploy = self.cont.DeployObject(self.ctx, self.html)
self.cont.UndeployObject(self.ctx, self.html, self.ran)
deploy = self.cont.DeployObject(self.html)
self.cont.UndeployObject(self.html, self.ran)
self.assertFalse(deploy)
self.cont.yamlPath = old
@@ -76,8 +70,8 @@ class TestDeploymentMethods(unittest.TestCase):
# fails reliably
old = self.cont.yamlPath
self.cont.yamlPath[0] = 'tests/simple-fail-2svc/'
deploy = self.cont.DeployObject(self.ctx, self.html)
self.cont.UndeployObject(self.ctx, self.html, self.ran)
deploy = self.cont.DeployObject(self.html)
self.cont.UndeployObject(self.html, self.ran)
self.assertFalse(deploy)
self.cont.yamlPath = old
@@ -85,8 +79,8 @@ class TestDeploymentMethods(unittest.TestCase):
self.cont.yamlPath[0] = 'yaml_files/5g_rfsimulator_tdd_dora'
self.cont.services[0] = "oai-gnb"
self.cont.deploymentTag = 'develop-12345678'
deploy = self.cont.DeployObject(self.ctx, self.html)
undeploy = self.cont.UndeployObject(self.ctx, self.html, self.ran)
deploy = self.cont.DeployObject(self.html)
undeploy = self.cont.UndeployObject(self.html, self.ran)
self.assertTrue(deploy)
self.assertTrue(undeploy)
@@ -94,8 +88,8 @@ class TestDeploymentMethods(unittest.TestCase):
self.cont.yamlPath[0] = 'yaml_files/5g_rfsimulator_tdd_dora'
self.cont.services[0] = "oai-gnb oai-nr-ue"
self.cont.deploymentTag = 'develop-12345678'
deploy = self.cont.DeployObject(self.ctx, self.html)
undeploy = self.cont.UndeployObject(self.ctx, self.html, self.ran)
deploy = self.cont.DeployObject(self.html)
undeploy = self.cont.UndeployObject(self.html, self.ran)
self.assertTrue(deploy)
self.assertTrue(undeploy)
@@ -103,10 +97,10 @@ class TestDeploymentMethods(unittest.TestCase):
self.cont.yamlPath[0] = 'yaml_files/5g_rfsimulator_tdd_dora'
self.cont.services[0] = "oai-gnb"
self.cont.deploymentTag = 'develop-12345678'
deploy1 = self.cont.DeployObject(self.ctx, self.html)
deploy1 = self.cont.DeployObject(self.html)
self.cont.services[0] = "oai-nr-ue"
deploy2 = self.cont.DeployObject(self.ctx, self.html)
undeploy = self.cont.UndeployObject(self.ctx, self.html, self.ran)
deploy2 = self.cont.DeployObject(self.html)
undeploy = self.cont.UndeployObject(self.html, self.ran)
self.assertTrue(deploy1)
self.assertTrue(deploy2)
self.assertTrue(undeploy)

View File

@@ -1,4 +1,4 @@
Sender Bitrate : 524.00 Kbps
Receiver Bitrate: 524.00 Kbps (52.40%) (too low! < 99%)
Sender Bitrate : 0.52 Mbps
Receiver Bitrate: 0.52 Mbps (too low! < 99%)
Jitter : 0.026 ms
Packet Loss : 10% (too high! > 0%)
Packet Loss : 10 % (too high! > 0%)

View File

@@ -1,4 +1,4 @@
Sender Bitrate : 0.00 bps
Receiver Bitrate: 3.98 Mbps (4.97%) (too low! < 99%)
Sender Bitrate : 0.00 Mbps
Receiver Bitrate: 3.98 Mbps (too low! < 99%)
Jitter : 3.847 ms
Packet Loss : 0.038% (too high! > 0%)
Packet Loss : 0.038 % (too high! > 0%)

View File

@@ -1,4 +1,4 @@
Sender Bitrate : 1.03 Mbps
Receiver Bitrate: 0.00 bps (0.00%) (too low! < 99%)
Sender Bitrate : 1.03 Mbps
Receiver Bitrate: 0.00 Mbps (too low! < 99%)
Jitter : 0.000 ms
Packet Loss : 0%
Packet Loss : 0 %

View File

@@ -1,4 +1,4 @@
Sender Bitrate : 996.00 Kbps
Receiver Bitrate: 996.00 Kbps (99.60%)
Sender Bitrate : 1.00 Mbps
Receiver Bitrate: 1.00 Mbps (99.60 %)
Jitter : 0.029 ms
Packet Loss : 0%
Packet Loss : 0 %

View File

@@ -1,4 +1,4 @@
Sender Bitrate : 4.67 Mbps
Receiver Bitrate: 4.67 Mbps (100.00%)
Sender Bitrate : 4.67 Mbps
Receiver Bitrate: 4.67 Mbps (100.00 %)
Jitter : 3.413 ms
Packet Loss : 0%
Packet Loss : 0 %

View File

@@ -1,64 +0,0 @@
import sys
import logging
import tempfile
logging.basicConfig(
level=logging.DEBUG,
stream=sys.stdout,
format="[%(asctime)s] %(levelname)8s: %(message)s"
)
import os
import unittest
sys.path.append('./') # to find OAI imports below
import cls_module
from cls_ci_helper import TestCaseCtx
import cls_cmd
class TestModule(unittest.TestCase):
def setUp(self):
self.ctx = TestCaseCtx.Default(tempfile.mkdtemp())
def tearDown(self):
with cls_cmd.LocalCmd() as c:
c.run(f'rm -rf {self.ctx.logPath}')
def test_simple_module(self):
c = cls_module.Module_UE("test", filename="tests/config/test_module_infra.yaml")
self.assertFalse(c.trace)
success = c.initialize()
self.assertTrue(success)
ip = c.attach()
self.assertEqual(ip, "127.0.0.1")
self.assertTrue(c.checkMTU())
c.detach()
logs = c.terminate()
self.assertEqual(logs, None) # no tracing
@unittest.skip("this test takes long: it verifies the UE cannot attach")
def test_simple_fail(self):
c = cls_module.Module_UE("test-fail", filename="tests/config/test_module_infra.yaml")
success = c.initialize()
self.assertTrue(success)
ip = c.attach()
self.assertEqual(ip, None)
self.assertFalse(c.checkMTU())
c.detach()
logs = c.terminate()
self.assertEqual(logs, None) # no tracing
def test_simple_trace(self):
c = cls_module.Module_UE("test-trace", filename="tests/config/test_module_infra.yaml")
self.assertTrue(c.trace)
success = c.initialize()
self.assertTrue(success)
ip = c.attach()
self.assertEqual(ip, "127.0.0.1")
self.assertTrue(c.checkMTU())
c.detach()
tmp = tempfile.mkdtemp()
log_file = c.terminate(self.ctx)
# undeploy uses archiveArtifact(), which writes to {prefix}-logs
self.assertEqual(log_file, [f"{self.ctx.baseFilename()}-tttf"]) # matches test-trace UE collection file
if __name__ == '__main__':
unittest.main()

View File

@@ -9,13 +9,11 @@ import os
os.system(f'rm -rf cmake_targets')
os.system(f'mkdir -p cmake_targets/log')
import unittest
import tempfile
sys.path.append('./') # to find OAI imports below
import cls_oai_html
from cls_ci_helper import TestCaseCtx
import cls_oaicitest
import cls_cmd
import cls_containerize
class TestPingIperf(unittest.TestCase):
def setUp(self):
@@ -24,10 +22,7 @@ class TestPingIperf(unittest.TestCase):
self.ci = cls_oaicitest.OaiCiTest()
self.ci.ue_ids = ["test"]
self.ci.nodes = ["localhost"]
self.ctx = TestCaseCtx.Default(tempfile.mkdtemp())
def tearDown(self):
with cls_cmd.LocalCmd() as c:
c.run(f'rm -rf {self.ctx.logPath}')
self.cont = cls_containerize.Containerize()
def test_ping(self):
self.ci.ping_args = "-c3"
@@ -35,7 +30,7 @@ class TestPingIperf(unittest.TestCase):
self.ci.svr_id = "test"
infra_file = "tests/config/infra_ping_iperf.yaml"
# TODO Should need nothing but options and UE(s) to use
success = self.ci.Ping(self.ctx, self.html, infra_file=infra_file)
success = self.ci.Ping(self.html, self.cont, infra_file=infra_file)
self.assertTrue(success)
def test_iperf(self):
@@ -50,7 +45,7 @@ class TestPingIperf(unittest.TestCase):
self.ci.iperf_profile = "balanced"
infra_file = "tests/config/infra_ping_iperf.yaml"
# TODO Should need nothing but options and UE(s) to use
success = self.ci.Iperf(self.ctx, self.html, infra_file=infra_file)
success = self.ci.Iperf(self.html, self.cont, infra_file=infra_file)
self.assertTrue(success)
def test_iperf2_unidir(self):
@@ -62,22 +57,7 @@ class TestPingIperf(unittest.TestCase):
self.ci.iperf_profile = "balanced"
infra_file = "tests/config/infra_ping_iperf.yaml"
# TODO Should need nothing but options and UE(s) to use
success = self.ci.Iperf2_Unidir(self.ctx, self.html, infra_file=infra_file)
self.assertTrue(success)
def test_iperf_highrate(self):
# note: needs to be five seconds because Iperf() adds -O 3, so if it is
# too short, the server is terminated before the client loaded
# everything
self.ci.iperf_args = "-u -t 5 -b 1000M -R -O 0"
self.ci.svr_id = "test"
self.ci.svr_node = "localhost"
self.ci.iperf_packetloss_threshold = "0"
self.ci.iperf_bitrate_threshold = "0"
self.ci.iperf_profile = "balanced"
infra_file = "tests/config/infra_ping_iperf.yaml"
# TODO Should need nothing but options and UE(s) to use
success = self.ci.Iperf(self.html, self.cont, infra_file=infra_file)
success = self.ci.Iperf2_Unidir(self.html, self.cont, infra_file=infra_file)
self.assertTrue(success)
if __name__ == '__main__':

View File

@@ -108,16 +108,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
</testCase>
<testCase id="020011">
<class>Ping</class>
<desc>Ping Traffic-Gen from LTE-UE</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -126,9 +126,9 @@
<class>Ping</class>
<desc>Ping LTE-UE from Traffic-Gen</desc>
<id>rfsim4g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -141,8 +141,8 @@
<iperf_args>-u -t 30 -b 2M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
<nodes>acamas</nodes>
<svr_node>acamas</svr_node>
<nodes>cacofonix</nodes>
<svr_node>cacofonix</svr_node>
</testCase>
<testCase id="030011">
@@ -153,8 +153,8 @@
<iperf_args>-u -t 30 -b 1M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
<nodes>acamas</nodes>
<svr_node>acamas</svr_node>
<nodes>cacofonix</nodes>
<svr_node>cacofonix</svr_node>
</testCase>
<testCase id="100011">

View File

@@ -86,9 +86,9 @@
<class>Ping</class>
<desc>Ping Traffic-Gen from LTE-UE</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_enb_nos1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -97,9 +97,9 @@
<class>Ping</class>
<desc>Ping LTE-UE from eNB</desc>
<id>rfsim4g_enb_nos1</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -108,9 +108,9 @@
<class>Iperf</class>
<desc>Iperf UDP DL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_enb_nos1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<iperf_args>-u -t 30 -b 2M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -120,9 +120,9 @@
<class>Iperf</class>
<desc>Iperf UDP UL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_enb_nos1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<iperf_args>-u -t 30 -b 1M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>

View File

@@ -108,16 +108,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
</testCase>
<testCase id="020011">
<class>Ping</class>
<desc>Ping Traffic-Gen from LTE-UE</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -126,9 +126,9 @@
<class>Ping</class>
<desc>Ping LTE-UE from Traffic-Gen</desc>
<id>rfsim4g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -137,9 +137,9 @@
<class>Iperf</class>
<desc>Iperf UDP DL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<iperf_args>-u -t 30 -b 2M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -149,9 +149,9 @@
<class>Iperf</class>
<desc>Iperf UDP UL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<iperf_args>-u -t 30 -b 1M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>

View File

@@ -108,16 +108,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
</testCase>
<testCase id="020011">
<class>Ping</class>
<desc>Ping Traffic-Gen from LTE-UE</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -126,9 +126,9 @@
<class>Ping</class>
<desc>Ping LTE-UE from Traffic-Gen</desc>
<id>rfsim4g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -137,9 +137,9 @@
<class>Iperf</class>
<desc>Iperf UDP DL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<iperf_args>-u -t 30 -b 2M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -149,9 +149,9 @@
<class>Iperf</class>
<desc>Iperf UDP UL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<iperf_args>-u -t 30 -b 1M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>

View File

@@ -83,9 +83,9 @@
<class>Iperf2_Unidir</class>
<desc>Iperf2 UDP DL</desc>
<id>rfsim4g_ue_fembms</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_enb_fembms</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<iperf_args>-u -t 30 -b 2M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>

View File

@@ -83,9 +83,9 @@
<class>Iperf</class>
<desc>Iperf UDP DL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_enb_nos1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<iperf_args>-u -t 30 -b 2M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>

View File

@@ -108,9 +108,9 @@
<class>Ping</class>
<desc>Ping Traffic-Gen from LTE-UE</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -119,9 +119,9 @@
<class>Ping</class>
<desc>Ping LTE-UE from Traffic-Gen</desc>
<id>rfsim4g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -130,9 +130,9 @@
<class>Iperf</class>
<desc>Iperf UDP DL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<iperf_args>-u -t 30 -b 2M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -142,9 +142,9 @@
<class>Iperf</class>
<desc>Iperf UDP UL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>cacofonix</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>cacofonix</svr_node>
<iperf_args>-u -t 30 -b 1M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>

View File

@@ -26,6 +26,7 @@
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
111111
100001
800813
000001
000002

View File

@@ -26,6 +26,7 @@
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
111111
100001
800813
000001
000002

View File

@@ -32,8 +32,6 @@
000003
020001
020002
000004
020003
030001
030002
100001
@@ -100,24 +98,6 @@
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="000004">
<class>Attach_UE</class>
<desc>Verify 2nd PDU session is up</desc>
<id>rfsim5g_ue_pdu_2</id>
<nodes>acamas</nodes>
</testCase>
<testCase id="020003">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE on PDU session ID 2</desc>
<id>rfsim5g_ue_pdu_2</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="030001">
<class>Iperf</class>
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>

View File

@@ -30,10 +30,11 @@
310000
800813
330101
800814
330102
800815
330103
310001
400001
350000
370001
370000
@@ -146,13 +147,6 @@
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
</testCase>
<testCase id="400001">
<class>Custom_Command</class>
<desc>Check UE is on dedicated BWP ID 1</desc>
<node>ofqot</node>
<command>echo ci get_current_bwp | nc -N 127.0.0.1 9091 | grep 'DL BWP ID 1 (dedicated) UL BWP ID 1 (dedicated)'</command>
</testCase>
<testCase id="370001">
<class>Iperf</class>
<desc>iperf (UL/8Mbps/UDP)(30 sec)</desc>

View File

@@ -105,8 +105,8 @@
<testCase id="000100">
<class>Iperf</class>
<desc>iperf (DL/30Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 30M -t 30 -i 1 -R</iperf_args>
<desc>iperf (DL/20Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args>
<id>oai_ue_caracal</id>
<svr_id>oc-cn5g</svr_id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
@@ -115,8 +115,8 @@
<testCase id="000200">
<class>Iperf</class>
<desc>iperf (UL/20Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 20M -t 30 -i 1 </iperf_args>
<desc>iperf (UL/5Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 5M -t 30 -i 1 </iperf_args>
<id>oai_ue_caracal</id>
<svr_id>oc-cn5g</svr_id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>

View File

@@ -45,7 +45,7 @@
<testCase id="090101">
<class>Initialize_eNB</class>
<desc>Initialize gNB USRP</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band79.106prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 106 -t 23 -D 127 -m 28 -M 106 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.106prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 106 -t 23 -D 127 -m 28 -M 106 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<rt_stats_cfg>datalog_rt_stats.default.yaml</rt_stats_cfg>
<air_interface>NR</air_interface>
<USRP_IPAddress>192.168.20.2</USRP_IPAddress>

View File

@@ -45,7 +45,7 @@
<testCase id="390101">
<class>Initialize_eNB</class>
<desc>Initialize gNB USRP</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band79.273prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 273 -t 23 -D 127 -m 23 -M 273 -l 2 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.273prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 273 -t 23 -D 127 -m 23 -M 273 -l 2 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<rt_stats_cfg>datalog_rt_stats.100.2x2.yaml</rt_stats_cfg>
<air_interface>NR</air_interface>
<USRP_IPAddress>192.168.20.2</USRP_IPAddress>

View File

@@ -45,7 +45,7 @@
<testCase id="190101">
<class>Initialize_eNB</class>
<desc>Initialize gNB USRP</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band79.162prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 162 -t 23 -D 127 -m 23 -M 162 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.162prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 162 -t 23 -D 127 -m 23 -M 162 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<rt_stats_cfg>datalog_rt_stats.1x1.60.yaml</rt_stats_cfg>
<air_interface>NR</air_interface>
<USRP_IPAddress>192.168.20.2</USRP_IPAddress>

View File

@@ -45,7 +45,7 @@
<testCase id="290101">
<class>Initialize_eNB</class>
<desc>Initialize gNB USRP</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band79.162prb.usrpn300.phytest-dora.conf --phy-test --gNBs.[0].pdsch_AntennaPorts_XP 2 --RUs.[0].nb_tx 2 --RUs.[0].nb_rx 2 -q -U 768 -T 162 -t 23 -D 127 -m 23 -M 162 -l 2 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.162prb.usrpn300.phytest-dora.conf --phy-test --gNBs.[0].pdsch_AntennaPorts_XP 2 --RUs.[0].nb_tx 2 --RUs.[0].nb_rx 2 -q -U 768 -T 162 -t 23 -D 127 -m 23 -M 162 -l 2 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<rt_stats_cfg>datalog_rt_stats.60.2x2.yaml</rt_stats_cfg>
<air_interface>NR</air_interface>
<USRP_IPAddress>192.168.20.2</USRP_IPAddress>

View File

@@ -40,14 +40,13 @@
<mode>TesteNB</mode>
<class>Build_eNB</class>
<desc>Build gNB (USRP)</desc>
<Build_eNB_args>--gNB -w USRP --ninja -c -P --build-lib ldpc_cuda --build-lib ldpc_aal --cmake-opt -DASN1C_EXEC=/opt/asn1c/bin/asn1c</Build_eNB_args>
<Build_eNB_args>--gNB -w USRP --ninja -c -P --build-lib ldpc_cuda --build-lib ldpc_t2 --cmake-opt -DASN1C_EXEC=/opt/asn1c/bin/asn1c</Build_eNB_args>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
</testCase>
<testCase id="100000">
<class>Custom_Command</class>
<desc>Reboot USRP</desc>
<may_fail>true</may_fail>
<node>caracal</node>
<command>ssh root@192.168.20.2 reboot</command>
</testCase>

View File

@@ -62,7 +62,7 @@
<always_exec>true</always_exec>
<physim_test>nr_ulsim</physim_test>
<physim_time_threshold>100</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -m5 -r106 -R106 -C10 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -m5 -r106 -R106 -C10 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="010121">
@@ -80,7 +80,7 @@
<always_exec>true</always_exec>
<physim_test>nr_ulsim</physim_test>
<physim_time_threshold>150</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -m15 -r106 -R106 -C10 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -m15 -r106 -R106 -C10 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="010131">
@@ -98,7 +98,7 @@
<always_exec>true</always_exec>
<physim_test>nr_ulsim</physim_test>
<physim_time_threshold>250</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -m25 -r106 -R106 -C10 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -m25 -r106 -R106 -C10 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="010211">
@@ -116,7 +116,7 @@
<always_exec>true</always_exec>
<physim_test>nr_ulsim</physim_test>
<physim_time_threshold>150</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -m5 -r273 -R273 -C10 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -m5 -r273 -R273 -C10 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="010221">
@@ -134,7 +134,7 @@
<always_exec>true</always_exec>
<physim_test>nr_ulsim</physim_test>
<physim_time_threshold>350</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -m15 -r273 -R273 -C10 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -m15 -r273 -R273 -C10 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="010231">
@@ -152,7 +152,7 @@
<always_exec>true</always_exec>
<physim_test>nr_ulsim</physim_test>
<physim_time_threshold>550</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -m25 -r273 -R273 -C10 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -m25 -r273 -R273 -C10 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="010311">
@@ -170,7 +170,7 @@
<always_exec>true</always_exec>
<physim_test>nr_ulsim</physim_test>
<physim_time_threshold>250</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -m5 -r273 -R273 -C10 -W2 -z2 -y2 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -m5 -r273 -R273 -C10 -W2 -z2 -y2 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="010321">
@@ -188,7 +188,7 @@
<always_exec>true</always_exec>
<physim_test>nr_ulsim</physim_test>
<physim_time_threshold>650</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -m15 -r273 -R273 -C10 -W2 -z2 -y2 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -m15 -r273 -R273 -C10 -W2 -z2 -y2 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="010331">
@@ -206,7 +206,7 @@
<always_exec>true</always_exec>
<physim_test>nr_ulsim</physim_test>
<physim_time_threshold>1100</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -m25 -r273 -R273 -C10 -W2 -z2 -y2 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -m25 -r273 -R273 -C10 -W2 -z2 -y2 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
</testCaseList>

View File

@@ -63,7 +63,7 @@
<always_exec>true</always_exec>
<physim_test>nr_dlsim</physim_test>
<physim_time_threshold>100</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -e5 -b106 -R106 -X4,5,6,7,8,9 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -e5 -b106 -R106 -X4,5,6,7,8,9 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="000121">
@@ -81,7 +81,7 @@
<always_exec>true</always_exec>
<physim_test>nr_dlsim</physim_test>
<physim_time_threshold>100</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -e15 -b106 -R106 -X4,5,6,7,8,9 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -e15 -b106 -R106 -X4,5,6,7,8,9 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="000131">
@@ -99,7 +99,7 @@
<always_exec>true</always_exec>
<physim_test>nr_dlsim</physim_test>
<physim_time_threshold>200</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -e25 -b106 -R106 -X4,5,6,7,8,9 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -e25 -b106 -R106 -X4,5,6,7,8,9 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="000211">
@@ -117,7 +117,7 @@
<always_exec>true</always_exec>
<physim_test>nr_dlsim</physim_test>
<physim_time_threshold>150</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -e5 -b273 -R273 -X4,5,6,7,8,9 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -e5 -b273 -R273 -X4,5,6,7,8,9 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="000221">
@@ -135,7 +135,7 @@
<always_exec>true</always_exec>
<physim_test>nr_dlsim</physim_test>
<physim_time_threshold>250</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -e15 -b273 -R273 -X4,5,6,7,8,9 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -e15 -b273 -R273 -X4,5,6,7,8,9 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="000231">
@@ -153,7 +153,7 @@
<always_exec>true</always_exec>
<physim_test>nr_dlsim</physim_test>
<physim_time_threshold>400</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -e25 -b273 -R273 -X4,5,6,7,8,9 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -e25 -b273 -R273 -X4,5,6,7,8,9 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="000311">
@@ -171,7 +171,7 @@
<always_exec>true</always_exec>
<physim_test>nr_dlsim</physim_test>
<physim_time_threshold>200</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -e5 -b273 -R273 -X4,5,6,7,8,9 -x2 -z2 -y2 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -e5 -b273 -R273 -X4,5,6,7,8,9 -x2 -z2 -y2 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="000321">
@@ -189,7 +189,7 @@
<always_exec>true</always_exec>
<physim_test>nr_dlsim</physim_test>
<physim_time_threshold>500</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -e15 -b273 -R273 -X4,5,6,7,8,9 -x2 -z2 -y2 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -e15 -b273 -R273 -X4,5,6,7,8,9 -x2 -z2 -y2 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="000331">
@@ -207,7 +207,7 @@
<always_exec>true</always_exec>
<physim_test>nr_dlsim</physim_test>
<physim_time_threshold>500</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -e25 -b273 -R273 -X4,5,6,7,8,9 -x2 -z2 -y2 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -e25 -b273 -R273 -X4,5,6,7,8,9 -x2 -z2 -y2 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="000411">
@@ -225,7 +225,7 @@
<always_exec>true</always_exec>
<physim_test>nr_dlsim</physim_test>
<physim_time_threshold>200</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -e5 -b273 -R273 -X4,5,6,7,8,9 -x2 -z4 -y4 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -e5 -b273 -R273 -X4,5,6,7,8,9 -x2 -z4 -y4 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="000421">
@@ -243,7 +243,7 @@
<always_exec>true</always_exec>
<physim_test>nr_dlsim</physim_test>
<physim_time_threshold>300</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -e15 -b273 -R273 -X4,5,6,7,8,9 -x2 -z4 -y4 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -e15 -b273 -R273 -X4,5,6,7,8,9 -x2 -z4 -y4 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
<testCase id="000431">
@@ -261,6 +261,6 @@
<always_exec>true</always_exec>
<physim_test>nr_dlsim</physim_test>
<physim_time_threshold>450</physim_time_threshold>
<physim_run_args>-n1000 -s30 -S30.2 -e25 -b273 -R273 -X4,5,6,7,8,9 -x2 -z4 -y4 -P --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev af:00.0 --nrLDPC_coding_aal.dpdk_core_list 11-12 --nrLDPC_coding_aal.is_t2 1</physim_run_args>
<physim_run_args>-n1000 -s30 -S30.2 -e25 -b273 -R273 -X4,5,6,7,8,9 -x2 -z4 -y4 -P --loader.ldpc.shlibversion _t2 --nrLDPC_coding_t2.dpdk_dev d8:00.0 --nrLDPC_coding_t2.dpdk_core_list 11-12</physim_run_args>
</testCase>
</testCaseList>

View File

@@ -147,7 +147,7 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
USE_ADDITIONAL_OPTIONS: --rfsim -r 25 --numerology 0 --uicc0.imsi 208990100001100 --band 66 -C 2152680000 --CO -400000000 --ssb 48 --rfsimulator.serveraddr 192.168.71.141 --extra-pdu-id 2 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --rfsim -r 25 --numerology 0 --uicc0.imsi 208990100001100 --band 66 -C 2152680000 --CO -400000000 --ssb 48 --rfsimulator.serveraddr 192.168.71.141 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-pnf
networks:

View File

@@ -17,7 +17,7 @@ services:
#entrypoint: /bin/bash -c "sleep infinity"
environment:
TZ: Europe/Paris
USE_ADDITIONAL_OPTIONS: --usrp-args type=n3xx,name=ni-n3xx-31641B9,addr=192.168.10.2 -r 106 --numerology 1 --band 78 -C 3425010000 --ssb 509 --ue-fo-compensation --ue-rxgain 65 --tune-offset 20000000 -A 90 --log_config.global_log_options level,nocolor,time --uicc0.imsi 001020000000111 --uicc0.nssai_sd 16777215
USE_ADDITIONAL_OPTIONS: --usrp-args type=n3xx,name=ni-n3xx-31641B9,addr=192.168.10.2 -r 106 --numerology 1 --band 78 -C 3511200000 --ue-fo-compensation --ue-rxgain 65 --tune-offset 20000000 -A 90 --log_config.global_log_options level,nocolor,time --uicc0.imsi 001020000000111 --uicc0.nssai_sd 16777215
volumes:
- ../../conf_files/ue.sa.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:

View File

@@ -0,0 +1,71 @@
#!/bin/bash
# Check if cuBB_SDK is defined, if not, use default path
cuBB_Path="${cuBB_SDK:-/opt/nvidia/cuBB}"
# Run gdrcopy insmod
#cd "$cuBB_Path"/cuPHY-CP/external/gdrcopy/ || exit 1
#./insmod.sh
cd "$cuBB_Path" || exit 1
# Restart MPS
# Export variables
export CUDA_DEVICE_MAX_CONNECTIONS=8
export CUDA_MPS_PIPE_DIRECTORY=/var
export CUDA_MPS_LOG_DIRECTORY=/var
# Stop existing MPS
echo quit | sudo -E nvidia-cuda-mps-control
# Start MPS
sudo -E nvidia-cuda-mps-control -d
sudo -E echo start_server -uid 0 | sudo -E nvidia-cuda-mps-control
# Start cuphycontroller_scf
# Check if an argument is provided
if [ $# -eq 0 ]; then
# No argument provided, use default value
serverVendorAndModel=$(cat /sys/devices/virtual/dmi/id/board_vendor)
serverVendorAndModel+="-"
serverVendorAndModel+=$(cat /sys/devices/virtual/dmi/id/board_name)
echo $serverVendorAndModel
case $serverVendorAndModel in
"Dell Inc.-06V45N")
argument="P5G_FXN_R750"
;;
"GIGABYTE-MU71-SU0-00")
argument="P5G_FXN"
;;
"Supermicro-G1SMH-G")
argument="P5G_FXN_GH"
;;
*)
echo "Unrecognized server: $serverVendorAndModel"
exit
;;
esac
else
# Argument provided, use it
argument="$1"
fi
#Change this to the PCIe port used for FH communication
sed -i "s/ nic:.*/ nic: 0000:01:00.0/" ${cuBB_SDK}/cuPHY-CP/cuphycontroller/config/cuphycontroller_P5G_FXN_GH.yaml
#Change this to the MAC address of the ORU
sed -i "s/ dst_mac_addr:.*/ dst_mac_addr: 6c:ad:ad:00:02:02/" ${cuBB_SDK}/cuPHY-CP/cuphycontroller/config/cuphycontroller_P5G_FXN_GH.yaml
#Change this to the VLAN used for FH communication
sed -i "s/ vlan:.*/ vlan: 2/" ${cuBB_SDK}/cuPHY-CP/cuphycontroller/config/cuphycontroller_P5G_FXN_GH.yaml
#This value might need to be adjusted depending the the radio environment
sed -i "s/ ul_gain_calibration:.*/ ul_gain_calibration: 78.68/" ${cuBB_SDK}/cuPHY-CP/cuphycontroller/config/cuphycontroller_P5G_FXN_GH.yaml
export AERIAL_LOG_PATH=/var/log/aerial
sudo -E "$cuBB_Path"/build/cuPHY-CP/cuphycontroller/examples/cuphycontroller_scf $argument
sudo ./build/cuPHY-CP/gt_common_libs/nvIPC/tests/pcap/pcap_collect nvipc /tmp
sudo mv /tmp/nvipc*.pcap $AERIAL_LOG_PATH
#Uncomment this if using multiple nvipc interfaces
#sudo ./build/cuPHY-CP/gt_common_libs/nvIPC/tests/pcap/pcap_collect nvipc1 /tmp
#sudo mv /tmp/nvipc*.pcap /var/log/aerial/
#sleep infinity

View File

@@ -0,0 +1,228 @@
################################################################################
# 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
################################################################################
# OAI CN Configuration File
### This file can be used by all OAI NFs
### Some fields are specific to an NF and will be ignored by other NFs
### The {{ env['ENV_NAME'] }} syntax lets you define these values in a docker-compose file
### If you intend to mount this file or use a bare-metal deployment, please refer to README.md
### The README.md also defines default values and allowed values for each configuration parameter
############# Common configuration
# Log level for all the NFs
log_level:
general: debug
# If you enable registration, the other NFs will use the NRF discovery mechanism
register_nf:
general: yes
http_version: 2
############## SBI Interfaces
### Each NF takes its local SBI interfaces and remote interfaces from here, unless it gets them using NRF discovery mechanisms
nfs:
amf:
host: oai-amf
sbi:
port: 8080
api_version: v1
interface_name: eth0
n2:
interface_name: eth0
port: 38412
smf:
host: oai-smf
sbi:
port: 8080
api_version: v1
interface_name: eth0
n4:
interface_name: eth0
port: 8805
upf:
host: oai-upf
sbi:
port: 8080
api_version: v1
interface_name: eth0
n3:
interface_name: eth0
port: 2152
n4:
interface_name: eth0
port: 8805
n6:
interface_name: eth0
n9:
interface_name: eth0
port: 2152
udm:
host: oai-udm
sbi:
port: 8080
api_version: v1
interface_name: eth0
udr:
host: oai-udr
sbi:
port: 8080
api_version: v1
interface_name: eth0
ausf:
host: oai-ausf
sbi:
port: 8080
api_version: v1
interface_name: eth0
nrf:
host: oai-nrf
sbi:
port: 8080
api_version: v1
interface_name: eth0
#### Common for UDR and AMF
database:
host: mysql
user: test
type: mysql
password: test
database_name: oai_db
generate_random: true
connection_timeout: 300 # seconds
## general single_nssai configuration
## Defines YAML anchors, which are reused in the config file
snssais:
- &embb_slice1
sst: 1
############## NF-specific configuration
amf:
pid_directory: "/var/run"
amf_name: "OAI-AMF"
# This really depends on if we want to keep the "mini" version or not
support_features_options:
enable_simple_scenario: no
enable_nssf: no
enable_smf_selection: yes
use_external_udm: no
relative_capacity: 30
statistics_timer_interval: 20 #in seconds
emergency_support: false
served_guami_list:
- mcc: 001
mnc: 01
amf_region_id: 01
amf_set_id: 001
amf_pointer: 01
plmn_support_list:
- mcc: 001
mnc: 01
tac: 0x0001
nssai:
- *embb_slice1
supported_integrity_algorithms:
- "NIA1"
- "NIA2"
supported_encryption_algorithms:
- "NEA0"
- "NEA1"
- "NEA2"
smf:
ue_mtu: 1500
support_features:
use_local_subscription_info: yes # Use infos from local_subscription_info or from UDM
use_local_pcc_rules: yes # Use infos from local_pcc_rules or from PCF
# we resolve from NRF, this is just to configure usage_reporting
upfs:
- host: oai-upf
config:
enable_usage_reporting: no
ue_dns:
primary_ipv4: "1.1.1.1"
primary_ipv6: "2001:4860:4860::8888"
secondary_ipv4: "8.8.8.8"
secondary_ipv6: "2001:4860:4860::8888"
ims:
pcscf_ipv4: "192.168.70.139"
pcscf_ipv6: "fe80::7915:f408:1787:db8b"
# the DNN you configure here should be configured in "dnns"
# follows the SmfInfo datatype from 3GPP TS 29.510
smf_info:
sNssaiSmfInfoList:
- sNssai: *embb_slice1
dnnSmfInfoList:
- dnn: "oai"
- dnn: "openairinterface"
- dnn: "ims"
local_subscription_infos:
- single_nssai: *embb_slice1
dnn: "oai"
qos_profile:
5qi: 9
session_ambr_ul: "10Gbps"
session_ambr_dl: "10Gbps"
- single_nssai: *embb_slice1
dnn: "openairinterface"
qos_profile:
5qi: 9
session_ambr_ul: "10Gbps"
session_ambr_dl: "10Gbps"
- single_nssai: *embb_slice1
dnn: "ims"
qos_profile:
5qi: 9
session_ambr_ul: "10Gbps"
session_ambr_dl: "10Gbps"
upf:
support_features:
enable_bpf_datapath: no # If "on": BPF is used as datapath else simpleswitch is used, DEFAULT= off
enable_snat: yes # If "on": Source natting is done for UE, DEFAULT= off
remote_n6_gw: 127.0.0.1 # Dummy host since simple-switch does not use N6 GW
smfs:
- host: oai-smf # To be used for PFCP association in case of no-NRF
upf_info:
sNssaiUpfInfoList:
- sNssai: *embb_slice1
dnnUpfInfoList:
- dnn: "oai"
- dnn: "openairinterface"
- dnn: "ims"
## DNN configuration
dnns:
- dnn: "oai"
pdu_session_type: "IPV4"
ipv4_subnet: "12.1.1.0/24"
- dnn: "openairinterface"
pdu_session_type: "IPV4V6"
ipv4_subnet: "10.0.1.0/24"
ipv6_prefix: "2001:1:2::/64"
- dnn: "ims"
pdu_session_type: "IPV4V6"
ipv4_subnet: "10.0.9.0/24"
ipv6_prefix: "2001:1:2::/64"

View File

@@ -0,0 +1,6 @@
[general]
language=fr
tcpenable=yes
tcpbindaddr=0.0.0.0
tcpbindport=5060
srvlookup=yes

View File

@@ -0,0 +1,98 @@
[001010000000001]
fullname = user1
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010000000002]
fullname = user2
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010000000003]
fullname = user3
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010000000004]
fullname = user4
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010123456780]
fullname = user4
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010123456781]
fullname = user4
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010123456782]
fullname = user4
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010123456783]
fullname = user4
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010123456784]
fullname = user4
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010123456785]
fullname = user4
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010123456786]
fullname = user4
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010123456787]
fullname = user4
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010123456788]
fullname = user4
hassip = yes
context = users
host = dynamic
transport=udp,tcp
[001010123456789]
fullname = user4
hassip = yes
context = users
host = dynamic
transport=udp,tcp

View File

@@ -0,0 +1,368 @@
-- phpMyAdmin SQL Dump
-- version 5.1.0
-- https://www.phpmyadmin.net/
--
-- Host: 172.16.200.10:3306
-- Generation Time: Mar 22, 2021 at 10:31 AM
-- Server version: 5.7.33
-- PHP Version: 7.4.15
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `oai_db`
--
-- --------------------------------------------------------
--
-- Table structure for table `AccessAndMobilitySubscriptionData`
--
CREATE TABLE `AccessAndMobilitySubscriptionData` (
`ueid` varchar(15) NOT NULL,
`servingPlmnid` varchar(15) NOT NULL,
`supportedFeatures` varchar(50) DEFAULT NULL,
`gpsis` json DEFAULT NULL,
`internalGroupIds` json DEFAULT NULL,
`sharedVnGroupDataIds` json DEFAULT NULL,
`subscribedUeAmbr` json DEFAULT NULL,
`nssai` json DEFAULT NULL,
`ratRestrictions` json DEFAULT NULL,
`forbiddenAreas` json DEFAULT NULL,
`serviceAreaRestriction` json DEFAULT NULL,
`coreNetworkTypeRestrictions` json DEFAULT NULL,
`rfspIndex` int(10) DEFAULT NULL,
`subsRegTimer` int(10) DEFAULT NULL,
`ueUsageType` int(10) DEFAULT NULL,
`mpsPriority` tinyint(1) DEFAULT NULL,
`mcsPriority` tinyint(1) DEFAULT NULL,
`activeTime` int(10) DEFAULT NULL,
`sorInfo` json DEFAULT NULL,
`sorInfoExpectInd` tinyint(1) DEFAULT NULL,
`sorafRetrieval` tinyint(1) DEFAULT NULL,
`sorUpdateIndicatorList` json DEFAULT NULL,
`upuInfo` json DEFAULT NULL,
`micoAllowed` tinyint(1) DEFAULT NULL,
`sharedAmDataIds` json DEFAULT NULL,
`odbPacketServices` json DEFAULT NULL,
`serviceGapTime` int(10) DEFAULT NULL,
`mdtUserConsent` json DEFAULT NULL,
`mdtConfiguration` json DEFAULT NULL,
`traceData` json DEFAULT NULL,
`cagData` json DEFAULT NULL,
`stnSr` varchar(50) DEFAULT NULL,
`cMsisdn` varchar(50) DEFAULT NULL,
`nbIoTUePriority` int(10) DEFAULT NULL,
`nssaiInclusionAllowed` tinyint(1) DEFAULT NULL,
`rgWirelineCharacteristics` varchar(50) DEFAULT NULL,
`ecRestrictionDataWb` json DEFAULT NULL,
`ecRestrictionDataNb` tinyint(1) DEFAULT NULL,
`expectedUeBehaviourList` json DEFAULT NULL,
`primaryRatRestrictions` json DEFAULT NULL,
`secondaryRatRestrictions` json DEFAULT NULL,
`edrxParametersList` json DEFAULT NULL,
`ptwParametersList` json DEFAULT NULL,
`iabOperationAllowed` tinyint(1) DEFAULT NULL,
`wirelineForbiddenAreas` json DEFAULT NULL,
`wirelineServiceAreaRestriction` json DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `Amf3GppAccessRegistration`
--
CREATE TABLE `Amf3GppAccessRegistration` (
`ueid` varchar(15) NOT NULL,
`amfInstanceId` varchar(50) NOT NULL,
`supportedFeatures` varchar(50) DEFAULT NULL,
`purgeFlag` tinyint(1) DEFAULT NULL,
`pei` varchar(50) DEFAULT NULL,
`imsVoPs` json DEFAULT NULL,
`deregCallbackUri` varchar(50) NOT NULL,
`amfServiceNameDereg` json DEFAULT NULL,
`pcscfRestorationCallbackUri` varchar(50) DEFAULT NULL,
`amfServiceNamePcscfRest` json DEFAULT NULL,
`initialRegistrationInd` tinyint(1) DEFAULT NULL,
`guami` json NOT NULL,
`backupAmfInfo` json DEFAULT NULL,
`drFlag` tinyint(1) DEFAULT NULL,
`ratType` json NOT NULL,
`urrpIndicator` tinyint(1) DEFAULT NULL,
`amfEeSubscriptionId` varchar(50) DEFAULT NULL,
`epsInterworkingInfo` json DEFAULT NULL,
`ueSrvccCapability` tinyint(1) DEFAULT NULL,
`registrationTime` varchar(50) DEFAULT NULL,
`vgmlcAddress` json DEFAULT NULL,
`contextInfo` json DEFAULT NULL,
`noEeSubscriptionInd` tinyint(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `AuthenticationStatus`
--
CREATE TABLE `AuthenticationStatus` (
`ueid` varchar(20) NOT NULL,
`nfInstanceId` varchar(50) NOT NULL,
`success` tinyint(1) NOT NULL,
`timeStamp` varchar(50) NOT NULL,
`authType` varchar(25) NOT NULL,
`servingNetworkName` varchar(50) NOT NULL,
`authRemovalInd` tinyint(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `AuthenticationSubscription`
--
CREATE TABLE `AuthenticationSubscription` (
`ueid` varchar(20) NOT NULL,
`authenticationMethod` varchar(25) NOT NULL,
`encPermanentKey` varchar(50) DEFAULT NULL,
`protectionParameterId` varchar(50) DEFAULT NULL,
`sequenceNumber` json DEFAULT NULL,
`authenticationManagementField` varchar(50) DEFAULT NULL,
`algorithmId` varchar(50) DEFAULT NULL,
`encOpcKey` varchar(50) DEFAULT NULL,
`encTopcKey` varchar(50) DEFAULT NULL,
`vectorGenerationInHss` tinyint(1) DEFAULT NULL,
`n5gcAuthMethod` varchar(15) DEFAULT NULL,
`rgAuthenticationInd` tinyint(1) DEFAULT NULL,
`supi` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `AuthenticationSubscription`
--
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010000000001', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '001010000000001');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010000000002', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '001010000000002');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010000000003', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '001010000000003');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010000000004', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '001010000000004');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010123456780', '5G_AKA', '6874736969202073796d4b2079650a73', '6874736969202073796d4b2079650a73', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '8b7645883644923debfadb824021f087', NULL, NULL, NULL, NULL, '001010123456780');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010123456781', '5G_AKA', '6874736969202073796d4b2079650a73', '6874736969202073796d4b2079650a73', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '8b7645883644923debfadb824021f087', NULL, NULL, NULL, NULL, '001010123456781');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010123456782', '5G_AKA', '6874736969202073796d4b2079650a73', '6874736969202073796d4b2079650a73', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '8b7645883644923debfadb824021f087', NULL, NULL, NULL, NULL, '001010123456782');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010123456783', '5G_AKA', '6874736969202073796d4b2079650a73', '6874736969202073796d4b2079650a73', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '8b7645883644923debfadb824021f087', NULL, NULL, NULL, NULL, '001010123456783');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010123456784', '5G_AKA', '6874736969202073796d4b2079650a73', '6874736969202073796d4b2079650a73', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '8b7645883644923debfadb824021f087', NULL, NULL, NULL, NULL, '001010123456784');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010123456785', '5G_AKA', '6874736969202073796d4b2079650a73', '6874736969202073796d4b2079650a73', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '8b7645883644923debfadb824021f087', NULL, NULL, NULL, NULL, '001010123456785');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010123456786', '5G_AKA', '6874736969202073796d4b2079650a73', '6874736969202073796d4b2079650a73', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '8b7645883644923debfadb824021f087', NULL, NULL, NULL, NULL, '001010123456786');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010123456787', '5G_AKA', '6874736969202073796d4b2079650a73', '6874736969202073796d4b2079650a73', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '8b7645883644923debfadb824021f087', NULL, NULL, NULL, NULL, '001010123456787');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010123456788', '5G_AKA', '6874736969202073796d4b2079650a73', '6874736969202073796d4b2079650a73', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '8b7645883644923debfadb824021f087', NULL, NULL, NULL, NULL, '001010123456788');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('001010123456789', '5G_AKA', '6874736969202073796d4b2079650a73', '6874736969202073796d4b2079650a73', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '8b7645883644923debfadb824021f087', NULL, NULL, NULL, NULL, '001010123456789');
-- --------------------------------------------------------
--
-- Table structure for table `SdmSubscriptions`
--
CREATE TABLE `SdmSubscriptions` (
`ueid` varchar(15) NOT NULL,
`subsId` int(10) UNSIGNED NOT NULL,
`nfInstanceId` varchar(50) NOT NULL,
`implicitUnsubscribe` tinyint(1) DEFAULT NULL,
`expires` varchar(50) DEFAULT NULL,
`callbackReference` varchar(50) NOT NULL,
`amfServiceName` json DEFAULT NULL,
`monitoredResourceUris` json NOT NULL,
`singleNssai` json DEFAULT NULL,
`dnn` varchar(50) DEFAULT NULL,
`subscriptionId` varchar(50) DEFAULT NULL,
`plmnId` json DEFAULT NULL,
`immediateReport` tinyint(1) DEFAULT NULL,
`report` json DEFAULT NULL,
`supportedFeatures` varchar(50) DEFAULT NULL,
`contextInfo` json DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `SessionManagementSubscriptionData`
--
CREATE TABLE `SessionManagementSubscriptionData` (
`ueid` varchar(15) NOT NULL,
`servingPlmnid` varchar(15) NOT NULL,
`singleNssai` json NOT NULL,
`dnnConfigurations` json DEFAULT NULL,
`internalGroupIds` json DEFAULT NULL,
`sharedVnGroupDataIds` json DEFAULT NULL,
`sharedDnnConfigurationsId` varchar(50) DEFAULT NULL,
`odbPacketServices` json DEFAULT NULL,
`traceData` json DEFAULT NULL,
`sharedTraceDataId` varchar(50) DEFAULT NULL,
`expectedUeBehavioursList` json DEFAULT NULL,
`suggestedPacketNumDlList` json DEFAULT NULL,
`3gppChargingCharacteristics` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `SessionManagementSubscriptionData`
--
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010000000001', '00101', '{\"sst\": 1, \"sd\": \"16777215\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.101\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010000000002', '00101', '{\"sst\": 1, \"sd\": \"16777215\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.102\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010000000003', '00101', '{\"sst\": 1, \"sd\": \"16777215\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.103\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010000000004', '00101', '{\"sst\": 1, \"sd\": \"16777215\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.104\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010123456780', '00101', '{\"sst\": 1, \"sd\": \"0xFFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.106\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\ "sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010123456781', '00101', '{\"sst\": 1, \"sd\": \"0xFFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.107\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\ "sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010123456782', '00101', '{\"sst\": 1, \"sd\": \"0xFFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.108\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\ "sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010123456783', '00101', '{\"sst\": 1, \"sd\": \"0xFFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.109\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\ "sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010123456784', '00101', '{\"sst\": 1, \"sd\": \"0xFFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.110\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\ "sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010123456785', '00101', '{\"sst\": 1, \"sd\": \"0xFFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.111\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\ "sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010123456786', '00101', '{\"sst\": 1, \"sd\": \"0xFFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.112\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\ "sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010123456787', '00101', '{\"sst\": 1, \"sd\": \"0xFFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.113\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\ "sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010123456788', '00101', '{\"sst\": 1, \"sd\": \"0xFFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.114\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\ "sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES
('001010123456789', '00101', '{\"sst\": 1, \"sd\": \"0xFFFFFF\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.115\"}]},\"ims\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4V6\"},\ "sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 2,\"arp\":{\"priorityLevel\": 15,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"2000Mbps\", \"downlink\":\"2000Mbps\"}}}');
-- --------------------------------------------------------
--
-- Table structure for table `SmfRegistrations`
--
CREATE TABLE `SmfRegistrations` (
`ueid` varchar(15) NOT NULL,
`subpduSessionId` int(10) NOT NULL,
`smfInstanceId` varchar(50) NOT NULL,
`smfSetId` varchar(50) DEFAULT NULL,
`supportedFeatures` varchar(50) DEFAULT NULL,
`pduSessionId` int(10) NOT NULL,
`singleNssai` json NOT NULL,
`dnn` varchar(50) DEFAULT NULL,
`emergencyServices` tinyint(1) DEFAULT NULL,
`pcscfRestorationCallbackUri` varchar(50) DEFAULT NULL,
`plmnId` json NOT NULL,
`pgwFqdn` varchar(50) DEFAULT NULL,
`epdgInd` tinyint(1) DEFAULT NULL,
`deregCallbackUri` varchar(50) DEFAULT NULL,
`registrationReason` json DEFAULT NULL,
`registrationTime` varchar(50) DEFAULT NULL,
`contextInfo` json DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `SmfSelectionSubscriptionData`
--
CREATE TABLE `SmfSelectionSubscriptionData` (
`ueid` varchar(15) NOT NULL,
`servingPlmnid` varchar(15) NOT NULL,
`supportedFeatures` varchar(50) DEFAULT NULL,
`subscribedSnssaiInfos` json DEFAULT NULL,
`sharedSnssaiInfosId` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `AccessAndMobilitySubscriptionData`
--
ALTER TABLE `AccessAndMobilitySubscriptionData`
ADD PRIMARY KEY (`ueid`,`servingPlmnid`) USING BTREE;
--
-- Indexes for table `Amf3GppAccessRegistration`
--
ALTER TABLE `Amf3GppAccessRegistration`
ADD PRIMARY KEY (`ueid`);
--
-- Indexes for table `AuthenticationStatus`
--
ALTER TABLE `AuthenticationStatus`
ADD PRIMARY KEY (`ueid`);
--
-- Indexes for table `AuthenticationSubscription`
--
ALTER TABLE `AuthenticationSubscription`
ADD PRIMARY KEY (`ueid`);
--
-- Indexes for table `SdmSubscriptions`
--
ALTER TABLE `SdmSubscriptions`
ADD PRIMARY KEY (`subsId`,`ueid`) USING BTREE;
--
-- Indexes for table `SessionManagementSubscriptionData`
--
ALTER TABLE `SessionManagementSubscriptionData`
ADD PRIMARY KEY (`ueid`,`servingPlmnid`) USING BTREE;
--
-- Indexes for table `SmfRegistrations`
--
ALTER TABLE `SmfRegistrations`
ADD PRIMARY KEY (`ueid`,`subpduSessionId`) USING BTREE;
--
-- Indexes for table `SmfSelectionSubscriptionData`
--
ALTER TABLE `SmfSelectionSubscriptionData`
ADD PRIMARY KEY (`ueid`,`servingPlmnid`) USING BTREE;
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `SdmSubscriptions`
--
ALTER TABLE `SdmSubscriptions`
MODIFY `subsId` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

View File

@@ -0,0 +1,177 @@
services:
mysql:
container_name: "mysql"
image: mysql:8.0
volumes:
- ./database/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ./healthscripts/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: 5s
timeout: 2s
retries: 10
networks:
public_net:
ipv4_address: 192.168.70.131
ims:
container_name: "asterisk-ims"
image: oaisoftwarealliance/ims:latest-arm-v2
volumes:
- ./conf/sip.conf:/etc/asterisk/sip.conf
- ./conf/users.conf:/etc/asterisk/users.conf
healthcheck:
test: /bin/bash -c "pgrep asterisk"
interval: 5s
timeout: 2s
retries: 10
networks:
public_net:
ipv4_address: 192.168.70.139
oai-udr:
container_name: "oai-udr"
image: oaisoftwarealliance/oai-udr:develop-arm-v2
expose:
- 80/tcp
- 8080/tcp
volumes:
- ./conf/config.yaml:/openair-udr/etc/config.yaml
environment:
- TZ=Europe/Paris
depends_on:
- mysql
- oai-nrf
networks:
public_net:
ipv4_address: 192.168.70.136
oai-udm:
container_name: "oai-udm"
image: oaisoftwarealliance/oai-udm:develop-arm-v2
expose:
- 80/tcp
- 8080/tcp
volumes:
- ./conf/config.yaml:/openair-udm/etc/config.yaml
environment:
- TZ=Europe/Paris
depends_on:
- oai-udr
networks:
public_net:
ipv4_address: 192.168.70.137
oai-ausf:
container_name: "oai-ausf"
image: oaisoftwarealliance/oai-ausf:develop-arm-v2
expose:
- 80/tcp
- 8080/tcp
volumes:
- ./conf/config.yaml:/openair-ausf/etc/config.yaml
environment:
- TZ=Europe/Paris
depends_on:
- oai-udm
networks:
public_net:
ipv4_address: 192.168.70.138
oai-nrf:
container_name: "oai-nrf"
image: oaisoftwarealliance/oai-nrf:develop-arm-v2
expose:
- 80/tcp
- 8080/tcp
volumes:
- ./conf/config.yaml:/openair-nrf/etc/config.yaml
environment:
- TZ=Europe/Paris
networks:
public_net:
ipv4_address: 192.168.70.130
oai-amf:
container_name: "oai-amf"
image: oaisoftwarealliance/oai-amf:develop-arm-v2
expose:
- 80/tcp
- 8080/tcp
- 38412/sctp
volumes:
- ./conf/config.yaml:/openair-amf/etc/config.yaml
environment:
- TZ=Europe/Paris
depends_on:
- mysql
- oai-nrf
- oai-ausf
networks:
public_net:
ipv4_address: 192.168.70.132
oai-smf:
container_name: "oai-smf"
image: oaisoftwarealliance/oai-smf:develop-arm-v2
expose:
- 80/tcp
- 8080/tcp
- 8805/udp
volumes:
- ./conf/config.yaml:/openair-smf/etc/config.yaml
environment:
- TZ=Europe/Paris
depends_on:
- oai-nrf
- oai-amf
networks:
public_net:
ipv4_address: 192.168.70.133
oai-upf:
container_name: "oai-upf"
image: oaisoftwarealliance/oai-upf:develop-arm-v2
expose:
- 2152/udp
- 8805/udp
volumes:
- ./conf/config.yaml:/openair-upf/etc/config.yaml
environment:
- TZ=Europe/Paris
depends_on:
- oai-nrf
- oai-smf
cap_add:
- NET_ADMIN
- SYS_ADMIN
cap_drop:
- ALL
privileged: true
networks:
public_net:
ipv4_address: 192.168.70.134
oai-ext-dn:
privileged: true
init: true
container_name: oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest-arm-v2
entrypoint: /bin/bash -c \
"ip route add 10.0.0.0/16 via 192.168.70.134 dev eth0;ip route add 12.1.1.0/24 via 192.168.70.134 dev eth0; ip route; sleep infinity"
command: ["/bin/bash", "-c", "trap : SIGTERM SIGINT; sleep infinity & wait"]
healthcheck:
test: /bin/bash -c "ip r | grep 10.0.0"
interval: 5s
timeout: 2s
retries: 10
networks:
public_net:
ipv4_address: 192.168.70.135
networks:
public_net:
driver: bridge
name: oai-cn5g-public-net
ipam:
config:
- subnet: 192.168.70.128/26
driver_opts:
com.docker.network.bridge.name: "oai-cn5g"

View File

@@ -0,0 +1,118 @@
services:
nv-cubb:
container_name: nv-cubb
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities:
- gpu
network_mode: host
shm_size: 4096m
privileged: true
stdin_open: true
tty: true
volumes:
- /lib/modules:/lib/modules
- /dev/hugepages:/dev/hugepages
- /usr/src:/usr/src
- ./aerial_l1_entrypoint.sh:/opt/nvidia/cuBB/aerial_l1_entrypoint.sh
- /var/log/aerial:/var/log/aerial
- ../../../cmake_targets/share:/opt/cuBB/share
- ./L1_conf/cuphycontroller_P5G_FXN_GH.yaml:/opt/nvidia/cuBB/cuPHY-CP/cuphycontroller/config/cuphycontroller_P5G_FXN_GH.yaml
- ./L1_conf/l2_adapter_config_P5G_GH.yaml:/opt/nvidia/cuBB/cuPHY-CP/cuphycontroller/config/l2_adapter_config_P5G_GH.yaml
- ./L1_conf/nvipc_multi_instances.yaml:/opt/nvidia/cuBB/cuPHY-CP/cuphycontroller/config/nvipc_multi_instances.yaml
userns_mode: host
ipc: "shareable"
image: cubb-build:25-2
environment:
- cuBB_SDK=/opt/nvidia/cuBB
command: bash -c "sudo rm -rf /tmp/phy.log && sudo chmod +x /opt/nvidia/cuBB/aerial_l1_entrypoint.sh && /opt/nvidia/cuBB/aerial_l1_entrypoint.sh"
healthcheck:
test: ["CMD-SHELL",'grep -q "L1 is ready!" /tmp/phy.log && echo 0 || echo 1']
interval: 20s
timeout: 5s
retries: 5
c_oai-gnb-aerial-20:
image: oai-gnb-aerial:latest
#image: oai-gnb-aerial:mac_stats
depends_on:
nv-cubb:
condition: service_healthy
privileged: true
ipc: "container:nv-cubb"
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities:
- gpu
#network_mode: host
networks:
oai-cn5g-public-net:
ipv4_address: 192.168.70.140
shm_size: 4096m
stdin_open: true
tty: true
volumes:
- /lib/modules:/lib/modules
- /dev/hugepages:/dev/hugepages
- /usr/src:/usr/src
- ~/share:/opt/nvidia/cuBB/share
- /var/log/aerial:/var/log/aerial
# Use this for CBRS radios
#- ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.cbrs.aerial.conf:/opt/oai-gnb/etc/gnb.conf
- ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.273prb.aerial.20.conf:/opt/oai-gnb/etc/gnb.conf
container_name: c_oai-gnb-aerial-20
command: bash -c "chrt -r 1 taskset -c 16-21 chrt -f 99 /opt/oai-gnb/bin/nr-softmodem -q -O /opt/oai-gnb/etc/gnb.conf | tee /var/log/aerial/oai20.log"
healthcheck:
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
interval: 10s
timeout: 5s
retries: 5
c_oai-gnb-aerial-21:
image: oai-gnb-aerial:latest
#image: oai-gnb-aerial:mac_stats
depends_on:
c_oai-gnb-aerial-20:
condition: service_healthy
privileged: true
ipc: "container:nv-cubb"
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities:
- gpu
#network_mode: host
networks:
oai-cn5g-public-net:
ipv4_address: 192.168.70.141
shm_size: 4096m
stdin_open: true
tty: true
volumes:
- /lib/modules:/lib/modules
- /dev/hugepages:/dev/hugepages
- /usr/src:/usr/src
- ~/share:/opt/nvidia/cuBB/share
- /var/log/aerial:/var/log/aerial
# Use this for CBRS radios
#- ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.cbrs.aerial.conf:/opt/oai-gnb/etc/gnb.conf
- ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.273prb.aerial.21.conf:/opt/oai-gnb/etc/gnb.conf
container_name: c_oai-gnb-aerial-21
command: bash -c "chrt -r 1 taskset -c 22-37 chrt -f 99 /opt/oai-gnb/bin/nr-softmodem -q -O /opt/oai-gnb/etc/gnb.conf | tee /var/log/aerial/oai21.log"
healthcheck:
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
interval: 10s
timeout: 5s
retries: 5
networks:
oai-cn5g-public-net:
external: true

View File

@@ -0,0 +1,70 @@
services:
nv-cubb:
container_name: nv-cubb
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities:
- gpu
network_mode: host
shm_size: 4096m
privileged: true
stdin_open: true
tty: true
volumes:
- /lib/modules:/lib/modules
- /dev/hugepages:/dev/hugepages
- /usr/src:/usr/src
- ./aerial_l1_entrypoint.sh:/opt/nvidia/cuBB/aerial_l1_entrypoint.sh
- /var/log/aerial:/var/log/aerial
- ../../../cmake_targets/share:/opt/cuBB/share
userns_mode: host
ipc: "shareable"
image: cubb-build:25-2
environment:
- cuBB_SDK=/opt/nvidia/cuBB
command: bash -c "sudo rm -rf /tmp/phy.log && sudo chmod +x /opt/nvidia/cuBB/aerial_l1_entrypoint.sh && /opt/nvidia/cuBB/aerial_l1_entrypoint.sh"
healthcheck:
test: ["CMD-SHELL",'grep -q "L1 is ready!" /tmp/phy.log && echo 0 || echo 1']
interval: 20s
timeout: 5s
retries: 5
c_oai-gnb-aerial:
image: oai-gnb-aerial:latest
depends_on:
nv-cubb:
condition: service_healthy
privileged: true
ipc: "container:nv-cubb"
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities:
- gpu
network_mode: host
shm_size: 4096m
stdin_open: true
tty: true
volumes:
- /lib/modules:/lib/modules
- /dev/hugepages:/dev/hugepages
- /usr/src:/usr/src
- ~/share:/opt/nvidia/cuBB/share
- /var/log/aerial:/var/log/aerial
# Use this for CBRS radios
#- ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.cbrs.aerial.conf:/opt/oai-gnb/etc/gnb.conf
- ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.273prb.aerial.conf:/opt/oai-gnb/etc/gnb.conf
container_name: c_oai-gnb-aerial
command: bash -c "chrt -r 1 taskset -c 13-18 chrt -f 95 /opt/oai-gnb/bin/nr-softmodem -O /opt/oai-gnb/etc/gnb.conf | tee /var/log/aerial/oai.log"
#cpuset: 11-18
healthcheck:
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
interval: 10s
timeout: 5s
retries: 5

View File

@@ -0,0 +1,250 @@
services:
nv-cubb:
container_name: nv-cubb
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities:
- gpu
network_mode: host
shm_size: 4096m
privileged: true
stdin_open: true
tty: true
volumes:
- /lib/modules:/lib/modules
- /dev/hugepages:/dev/hugepages
- /usr/src:/usr/src
- ./aerial_l1_entrypoint.sh:/opt/nvidia/cuBB/aerial_l1_entrypoint.sh
- /var/log/aerial:/var/log/aerial
- ../../../cmake_targets/share:/opt/cuBB/share
userns_mode: host
ipc: "shareable"
image: cubb-build:24-1
depends_on:
oai-amf:
condition: service_healthy
environment:
- cuBB_SDK=/opt/nvidia/cuBB
command: bash -c "sudo rm -rf /tmp/phy.log && sudo chmod +x /opt/nvidia/cuBB/aerial_l1_entrypoint.sh && /opt/nvidia/cuBB/aerial_l1_entrypoint.sh"
healthcheck:
test: ["CMD-SHELL",'grep -q "L1 is ready!" /tmp/phy.log && echo 0 || echo 1']
interval: 20s
timeout: 5s
retries: 5
c_oai-gnb-aerial:
image: oai-gnb-aerial:2024.w21.ARC1.5
depends_on:
nv-cubb:
condition: service_healthy
privileged: true
ipc: "container:nv-cubb"
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities:
- gpu
network_mode: host
shm_size: 4096m
stdin_open: true
tty: true
volumes:
- /lib/modules:/lib/modules
- /dev/hugepages:/dev/hugepages
- /usr/src:/usr/src
- ~/share:/opt/nvidia/cuBB/share
- /var/log/aerial:/var/log/aerial
# Use this for CBRS radios
#- ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.cbrs.aerial.conf:/opt/oai-gnb/etc/gnb.conf
- ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.273prb.aerial.conf:/opt/oai-gnb/etc/gnb.conf
container_name: c_oai-gnb-aerial
command: bash -c "chrt -r 1 taskset -c 11-16 chrt -f 95 /opt/oai-gnb/bin/nr-softmodem -O /opt/oai-gnb/etc/gnb.conf | tee /var/log/aerial/oai.log"
#cpuset: 11-18
healthcheck:
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
interval: 10s
timeout: 5s
retries: 5
mysql:
container_name: "mysql"
image: mysql:8.0
volumes:
- ./database/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ./healthscripts/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
environment:
- TZ=UTC
- MYSQL_DATABASE=oai_db
- MYSQL_USER=test
- MYSQL_PASSWORD=test
- MYSQL_ROOT_PASSWORD=linux
healthcheck:
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
interval: 5s
timeout: 2s
retries: 10
networks:
public_net:
ipv4_address: 192.168.70.131
ims:
container_name: "asterisk-ims"
image: andrius/asterisk:latest
volumes:
- ./conf/sip.conf:/etc/asterisk/sip.conf
- ./conf/users.conf:/etc/asterisk/users.conf
healthcheck:
test: /bin/bash -c "pgrep asterisk"
interval: 5s
timeout: 2s
retries: 10
networks:
public_net:
ipv4_address: 192.168.70.139
oai-udr:
container_name: "oai-udr"
image: oai-udr:develop
expose:
- 80/tcp
- 8080/tcp
volumes:
- ./conf/config.yaml:/openair-udr/etc/config.yaml
environment:
- TZ=UTC
depends_on:
- mysql
- oai-nrf
networks:
public_net:
ipv4_address: 192.168.70.136
oai-udm:
container_name: "oai-udm"
image: oai-udm:develop
expose:
- 80/tcp
- 8080/tcp
volumes:
- ./conf/config.yaml:/openair-udm/etc/config.yaml
environment:
- TZ=UTC
depends_on:
- oai-udr
networks:
public_net:
ipv4_address: 192.168.70.137
oai-ausf:
container_name: "oai-ausf"
image: oai-ausf:develop
expose:
- 80/tcp
- 8080/tcp
volumes:
- ./conf/config.yaml:/openair-ausf/etc/config.yaml
environment:
- TZ=UTC
depends_on:
- oai-udm
networks:
public_net:
ipv4_address: 192.168.70.138
oai-nrf:
container_name: "oai-nrf"
image: oai-nrf:develop
expose:
- 80/tcp
- 8080/tcp
volumes:
- ./conf/config.yaml:/openair-nrf/etc/config.yaml
environment:
- TZ=UTC
networks:
public_net:
ipv4_address: 192.168.70.130
oai-amf:
container_name: "oai-amf"
image: oai-amf:develop
expose:
- 80/tcp
- 8080/tcp
- 38412/sctp
volumes:
- ./conf/config.yaml:/openair-amf/etc/config.yaml
environment:
- TZ=UTC
depends_on:
- mysql
- oai-nrf
- oai-ausf
networks:
public_net:
ipv4_address: 192.168.70.132
oai-smf:
container_name: "oai-smf"
image: oai-smf:develop
expose:
- 80/tcp
- 8080/tcp
- 8805/udp
volumes:
- ./conf/config.yaml:/openair-smf/etc/config.yaml
environment:
- TZ=UTC
depends_on:
- oai-nrf
- oai-amf
networks:
public_net:
ipv4_address: 192.168.70.133
oai-upf:
container_name: "oai-upf"
image: oai-upf:develop
expose:
- 2152/udp
- 8805/udp
volumes:
#- ./conf/basic_nrf_config.yaml:/openair-upf/etc/config.yaml
- ./conf/config.yaml:/openair-upf/etc/config.yaml
environment:
- TZ=UTC
depends_on:
- oai-nrf
- oai-smf
cap_add:
- NET_ADMIN
- SYS_ADMIN
cap_drop:
- ALL
privileged: true
networks:
public_net:
ipv4_address: 192.168.70.134
oai-ext-dn:
privileged: true
init: true
container_name: oai-ext-dn
image: trf-gen-cn5g:latest
entrypoint: /bin/bash -c \
"ip route add 12.1.0.0/16 via 192.168.70.134 dev eth0; ip route; sleep infinity"
command: ["/bin/bash", "-c", "trap : SIGTERM SIGINT; sleep infinity & wait"]
healthcheck:
test: /bin/bash -c "ip r | grep 12.1.0"
interval: 5s
timeout: 2s
retries: 10
networks:
public_net:
ipv4_address: 192.168.70.135
networks:
public_net:
driver: bridge
name: demo-oai-public-net
ipam:
config:
- subnet: 192.168.70.128/26
driver_opts:
com.docker.network.bridge.name: "demo-oai"

View File

@@ -0,0 +1,12 @@
#!/bin/bash
rm -rf logs
mkdir logs
grep container_name docker-compose.yaml | grep -v "#" | sed s/container_name:// | sed s/\"//g | while read -r line ; do
docker logs $line > logs/$line.log 2>&1
done
#Try but don't fail
cp /var/log/aerial/phy.log logs || :
cp /var/log/aerial/nvipc.pcap logs || :
cp cn.pcap logs || :
tar -cvzf l2plusLogs-$(date +%F-%H%M%S).tgz logs

View File

@@ -0,0 +1,46 @@
#!/bin/bash
set -eo pipefail
if [ "$MYSQL_ROOT_PASSWORD" ] && [ -z "$MYSQL_USER" ] && [ -z "$MYSQL_PASSWORD" ]; then
echo >&2 'Healthcheck error: cannot determine root password (and MYSQL_USER and MYSQL_PASSWORD were not set)'
exit 0
fi
host="$(hostname --ip-address || echo '127.0.0.1')"
user="${MYSQL_USER:-root}"
export MYSQL_PWD="${MYSQL_PASSWORD:-$MYSQL_ROOT_PASSWORD}"
args=(
# force mysql to not use the local "mysqld.sock" (test "external" connectivity)
-h"$host"
-u"$user"
--silent
)
STATUS=0
if command -v mysqladmin &> /dev/null; then
if mysqladmin "${args[@]}" ping > /dev/null; then
database_check=$(mysql -u$user -D oai_db --silent -e "SELECT * FROM AuthenticationSubscription;")
if [[ -z $database_check ]]; then
echo "Healthcheck error: oai_db not populated"
STATUS=1
fi
STATUS=0
else
echo "Healthcheck error: Mysql port inactive"
STATUS=1
fi
else
if select="$(echo 'SELECT 1' | mysql "${args[@]}")" && [ "$select" = '1' ]; then
database_check=$(mysql -u$user -D oai_db --silent -e "SELECT * FROM AuthenticationSubscription;")
if [[ -z $database_check ]]; then
echo "Healthcheck error: oai_db not populated"
STATUS=1
fi
STATUS=0
else
echo "Healthcheck error: Mysql port inactive"
STATUS=1
fi
fi
exit $STATUS

View File

@@ -0,0 +1,58 @@
services:
oai-nr-ue:
image: oai-nr-ue:w26
logging:
options:
max-file: "1"
network_mode: host
container_name: oai-nr-ue
command: "numactl --membind=1 /opt/oai-nr-ue/bin/nr-uesoftmodem"
privileged: true
cpuset: 2,4,6,8,10,12,14,16
cap_drop:
- ALL
cap_add:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
- SYS_NICE # for performance
- IPC_LOCK # for memory locking
- SYS_PTRACE # for debugging
devices:
- /dev/net/tun:/dev/net/tun
ulimits:
core: -1 # for core dumps
#entrypoint: /bin/bash -c "sleep infinity"
environment:
TZ: Europe/Paris
DISPLAY: $DISPLAY
USE_ADDITIONAL_OPTIONS: |
--usrp-args type=x4xx,addr=192.168.20.2,clock_source=internal,time_source=internal --ue-rxgain 35
--thread-pool 2,4,6,8,10,12
--log_config.global_log_options level,wall_clock,nocolor
--ssb 1478 -r 273 --numerology 1 --band 78 -C 3750000000
--ue-txgain 0
--uicc0.imsi 001010000000003
--ue-fo-compensation -A 90
# Unused options:
#--T_stdout 2
# --usrp-tx-thread-config 1
# --log_config.mac_log_level debug
# --log_config.nr_mac_log_level debug
# --usrp-tx-thread-config 1 -d
# --ue-fo-compensation
# --ssb 1478 -r 273 --numerology 1 --band 78 -C 3750000000 --sa
# --ssb 1528 -r 273 --numerology 1 --band 48 -C 3649140000 --sa
# --usrp-args type=x4xx,addr=192.168.10.2,mgmt_addr=10.31.66.220,clock_source=external,time_source=external --ue-rxgain 25
# --usrp-args type=x4xx,addr=192.168.20.2,mgmt_addr=10.31.66.112,clock_source=external,time_source=external
volumes:
- ../../conf_files/ue.sa.conf:/opt/oai-nr-ue/etc/nr-ue.conf
- ${HOME}/.Xauthority:/root/.Xauthority:rw
- /tmp/.X11-unix:/tmp/.X11-unix
- /var/log/aerial/:/var/log/aerial/
- ~/2024.w48:/oai-ran:ro
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5

View File

@@ -34,6 +34,7 @@ source "$THIS_SCRIPT_PATH"/tools/build_helper
set_openair_env
# Variables for UE data generation
gen_nvram_path=$OPENAIR_DIR/cmake_targets/ran_build/build
conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
HW=""
@@ -45,7 +46,7 @@ BUILD_DOXYGEN=0
DISABLE_HARDWARE_DEPENDENCY="False"
CMAKE_BUILD_TYPE="RelWithDebInfo"
CMAKE_CMD="$CMAKE"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_cuda ldpc_aal ldpc_xdma websrv oai_iqplayer imscope imscope_record"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_cuda ldpc_t2 ldpc_xdma websrv oai_iqplayer imscope imscope_record"
TARGET_LIST=""
BUILD_TOOL_OPT="-j$(nproc)"
@@ -92,6 +93,8 @@ Options:
Makes the NR UE softmodem
--UE-conf-nvram [configuration file]
Specify conf_nvram_path (default \"$conf_nvram_path\")
--UE-gen-nvram [output path]
Specify gen_nvram_path (default \"$gen_nvram_path\")
-w | --hardware
USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, AERIAL, None (Default)
Adds this RF board support (in external packages installation and in compilation)
@@ -241,7 +244,7 @@ function main() {
shift;;
--UE)
UE=1
TARGET_LIST="$TARGET_LIST lte-uesoftmodem conf2uedata usim nvram"
TARGET_LIST="$TARGET_LIST lte-uesoftmodem"
echo_info "Will compile UE"
shift;;
--nrUE)
@@ -256,6 +259,9 @@ function main() {
--UE-conf-nvram)
conf_nvram_path=$(readlink -f "$2")
shift 2;;
--UE-gen-nvram)
gen_nvram_path=$(readlink -f "$2")
shift 2;;
-w | --hardware)
case "$2" in
"USRP" | "BLADERF" | "LMSSDR" | "IRIS")
@@ -507,7 +513,18 @@ function main() {
fi
if [ "$UE" = 1 ] ; then
echo_info "Generate LTE USIM default sim content UE specific part"
echo_info "Compiling UE specific part"
[ "$CLEAN" = "1" ] && rm -rf $DIR/nas_sim_tools/build
mkdir -p $DIR/nas_sim_tools/build
cd $DIR/nas_sim_tools/build
${CMAKE_CMD% *} ..
compilations nas_sim_tools usim.txt "usim" "${BUILD_TOOL_OPT}"
compilations nas_sim_tools nvram.txt "nvram" "${BUILD_TOOL_OPT}"
compilations nas_sim_tools conf2uedata.txt "conf2uedata" "${BUILD_TOOL_OPT}"
# generate USIM data
if [ -f conf2uedata ]; then
install_nas_tools $conf_nvram_path $DIR/$BUILD_DIR/build "$DIR/$BUILD_DIR/build/conf2uedata.txt"

View File

@@ -0,0 +1,79 @@
cmake_minimum_required(VERSION 3.5)
project(NAS_SIM_TOOLS)
include(FindPkgConfig)
pkg_search_module(CONFIG libconfig REQUIRED)
include_directories(${CONFIG_INCLUDE_DIRS})
add_definitions(-std=gnu99)
include("../macros.cmake")
ENABLE_LANGUAGE(C)
set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -Werror -Wall -Wstrict-prototypes -g")
set(OPENAIR_DIR $ENV{OPENAIR_DIR})
set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3)
include_directories (${OPENAIR_DIR}/openair2/COMMON)
include_directories (${OPENAIR_DIR})
set(CONF2UEDATA_LIB_SRC
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.c
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_data.c
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_usim.c
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_network.c
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_plmn.c
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_parser.c
${OPENAIR_DIR}/openair3/NAS/TOOLS/fs.c
${OPENAIR_DIR}/openair3/NAS/TOOLS/display.c
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.c
${OPENAIR_DIR}/common/utils/mem/memory.c
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/OctetString.c
${OPENAIR_DIR}/common/utils/utils.c
)
include_directories(
${OPENAIR_DIR}/common/utils
${OPENAIR_DIR}/openair3/NAS/UE
${OPENAIR_DIR}/openair3/NAS/COMMON
${OPENAIR_DIR}/openair3/NAS/UE/API/USER
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM
${OPENAIR_DIR}/openair3/NAS/UE/EMM/
${OPENAIR_DIR}/openair3/NAS/UE/ESM/
${OPENAIR_DIR}/openair3/NAS/COMMON/IES/
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL
)
# conf2uedata binary
set(conf2uedata_SRC
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c
${CONF2UEDATA_LIB_SRC}
)
add_executable(conf2uedata ${conf2uedata_SRC} )
target_link_libraries(conf2uedata ${CONFIG_LIBRARIES})
# usim binary
set(usim_SRC
${OPENAIR_DIR}/openair3/NAS/TOOLS/usim.c
${CONF2UEDATA_LIB_SRC}
)
add_executable(usim ${usim_SRC} )
target_link_libraries(usim ${CONFIG_LIBRARIES})
# nvram binary
set(nvram_SRC
${OPENAIR_DIR}/openair3/NAS/TOOLS/nvram.c
${CONF2UEDATA_LIB_SRC}
)
add_executable(nvram ${nvram_SRC})
target_link_libraries(nvram ${CONFIG_LIBRARIES})

View File

@@ -0,0 +1,46 @@
# - Try to find SCTP library and headers
# Once done, this will define
#
# SCTP_FOUND - system has SCTP
# SCTP_INCLUDE_DIR - the SCTP include directories
# SCTP_LIBRARIES - link these to use SCTP
if (SCTP_INCLUDE_DIR AND SCTP_LIBRARIES)
set(SCTP_FIND_QUIETLY TRUE)
endif (SCTP_INCLUDE_DIR AND SCTP_LIBRARIES)
# Include dir
find_path(SCTP_INCLUDE_DIR
NAMES netinet/sctp.h
)
# Library
find_library(SCTP_LIBRARY
NAMES sctp
)
# Set the include dir variables and the libraries and let libfind_process do the rest.
# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
#set(SCTP_PROCESS_INCLUDES SCTP_INCLUDE_DIR)
#set(SCTP_PROCESS_LIBS SCTP_LIBRARY)
#libfind_process(SCTP)
# handle the QUIETLY and REQUIRED arguments and set SCTP_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SCTP DEFAULT_MSG SCTP_LIBRARY SCTP_INCLUDE_DIR)
# If we successfully found the sctp library then add the library to the
# SCTP_LIBRARIES cmake variable otherwise set SCTP_LIBRARIES to nothing.
IF(SCTP_FOUND)
SET( SCTP_LIBRARIES ${SCTP_LIBRARY} )
ELSE(SCTP_FOUND)
SET( SCTP_LIBRARIES )
ENDIF(SCTP_FOUND)
# Lastly make it so that the SCTP_LIBRARY and SCTP_INCLUDE_DIR variables
# only show up under the advanced options in the gui cmake applications.
MARK_AS_ADVANCED( SCTP_LIBRARY SCTP_INCLUDE_DIR )

View File

@@ -1,64 +0,0 @@
# - Try to find SCTP library and headers
#
# Imported Targets
# ^^^^^^^^^^^^^^^^
#
# This module provides the following imported targets, if found:
#
# ``sctp::sctp``
# The SCTP library
#
# Result Variables
# ^^^^^^^^^^^^^^^^
#
# this will define
#
# sctp_FOUND - system has SCTP
# sctp_INCLUDE_DIRS - the SCTP include directories
# sctp_LIBRARIES - link these to use SCTP
# Include dir
find_path(sctp_INCLUDE_DIR
NAMES netinet/sctp.h
)
# Library
find_library(sctp_LIBRARY
NAMES sctp
)
# Set the include dir variables and the libraries and let libfind_process do the rest.
# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
#set(sctp_PROCESS_INCLUDES sctp_INCLUDE_DIR)
#set(sctp_PROCESS_LIBS sctp_LIBRARY)
#libfind_process(sctp)
# handle the QUIETLY and REQUIRED arguments and set sctp_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(sctp
FOUND_VAR sctp_FOUND
REQUIRED_VARS
sctp_LIBRARY
sctp_INCLUDE_DIR
)
# If we successfully found the sctp library then add the library to the
# sctp_LIBRARIES cmake variable otherwise set sctp_LIBRARIES to nothing.
if(sctp_FOUND)
set(sctp_LIBRARIES ${sctp_LIBRARY})
set(sctp_INCLUDE_DIRS ${sctp_INCLUDE_DIR})
endif()
if(sctp_FOUND AND NOT TARGET sctp::sctp)
add_library(sctp::sctp UNKNOWN IMPORTED)
set_target_properties(sctp::sctp PROPERTIES
IMPORTED_LOCATION "${sctp_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${sctp_INCLUDE_DIRS}"
)
endif()
# Lastly make it so that the SCTP_LIBRARY and SCTP_INCLUDE_DIR variables
# only show up under the advanced options in the gui cmake applications.
mark_as_advanced(SCTP_LIBRARY SCTP_INCLUDE_DIR)

View File

@@ -177,6 +177,7 @@ clean_all_files() {
dir=$OPENAIR_DIR/cmake_targets
rm -rf $dir/ran_build $dir/ran_build_noLOG
rm -rf $dir/lte-simulators/build
rm -rf $dir/nas_sim_tools/build
rm -rf $dir/oaisim_build_oai/build $dir/oaisim_build_oai/CMakeLists.txt
rm -rf $dir/autotests/bin $dir/autotests/log $dir/autotests/*/build
}

View File

@@ -46,6 +46,7 @@ struct gNB_RRC_INST_s;
struct eNB_MAC_INST_s;
struct eNB_MAC_INST_NB_IoT_s;
struct gNB_MAC_INST_s;
struct gtpv1u_data_s;
struct RU_t_s;
typedef struct {
@@ -99,6 +100,8 @@ typedef struct {
struct eNB_MAC_INST_NB_IoT_s **nb_iot_mac;
/// NR MAC context variables
struct gNB_MAC_INST_s **nrmac;
/// GTPu descriptor
struct gtpv1u_data_s *gtpv1u_data_g;
/// RU descriptors. These describe what each radio unit is supposed to do and contain the necessary functions for fronthaul interfaces
struct RU_t_s **ru;
/// Mask to indicate fronthaul setup status of RU (hard-limit to 64 RUs)

View File

@@ -100,14 +100,12 @@ struct T_header;
/* T macro tricks */
extern int T_stdout;
#define TN(...) TN_N(__VA_ARGS__,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,\
56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,\
37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,\
18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)(__VA_ARGS__)
#define TN_N(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,\
n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n33,n34,n35,n36,n37,n38,\
n39,n40,n41,n42,n43,n44,n45,n46,n47,n48,n49,n50,n51,n52,n53,n54,n55,n56,\
n57,n58,n59,n60,n61,n62,n63,n64,n65,n66,n67,n68,n69,n70,n,...) T##n
#define TN(...) TN_N(__VA_ARGS__,39,38,37,36,35,34,33,32,31,30,29,28,27,26, \
25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7, \
6,5,4,3,2,1,0)(__VA_ARGS__)
#define TN_N(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17, \
n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32, \
n33,n34,n35,n36,n37,n38,n,...) T##n
#define T(...) do { if (T_stdout == 0 || T_stdout == 2) TN(__VA_ARGS__); } while (0)
/* type used to send arbitrary buffer data */
@@ -622,633 +620,6 @@ extern int *T_active;
} \
} while (0)
#define T41(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_COMMIT(); \
} \
} while (0)
#define T43(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_COMMIT(); \
} \
} while (0)
#define T45(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_COMMIT(); \
} \
} while (0)
#define T47(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_COMMIT(); \
} \
} while (0)
#define T49(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22,t23,x23) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_PUT_##t23(25, x23); \
T_COMMIT(); \
} \
} while (0)
#define T51(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22,t23,x23,t24,x24) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_PUT_##t23(25, x23); \
T_PUT_##t24(26, x24); \
T_COMMIT(); \
} \
} while (0)
#define T53(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22,t23,x23,t24,x24,t25,x25) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_PUT_##t23(25, x23); \
T_PUT_##t24(26, x24); \
T_PUT_##t25(27, x25); \
T_COMMIT(); \
} \
} while (0)
#define T55(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22,t23,x23,t24,x24,t25,x25,\
t26,x26) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_PUT_##t23(25, x23); \
T_PUT_##t24(26, x24); \
T_PUT_##t25(27, x25); \
T_PUT_##t26(28, x26); \
T_COMMIT(); \
} \
} while (0)
#define T57(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22,t23,x23,t24,x24,t25,x25,\
t26,x26,t27,x27) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_PUT_##t23(25, x23); \
T_PUT_##t24(26, x24); \
T_PUT_##t25(27, x25); \
T_PUT_##t26(28, x26); \
T_PUT_##t27(29, x27); \
T_COMMIT(); \
} \
} while (0)
#define T59(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22,t23,x23,t24,x24,t25,x25,\
t26,x26,t27,x27,t28,x28) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_PUT_##t23(25, x23); \
T_PUT_##t24(26, x24); \
T_PUT_##t25(27, x25); \
T_PUT_##t26(28, x26); \
T_PUT_##t27(29, x27); \
T_PUT_##t28(30, x28); \
T_COMMIT(); \
} \
} while (0)
#define T61(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22,t23,x23,t24,x24,t25,x25,\
t26,x26,t27,x27,t28,x28,t29,x29) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_PUT_##t23(25, x23); \
T_PUT_##t24(26, x24); \
T_PUT_##t25(27, x25); \
T_PUT_##t26(28, x26); \
T_PUT_##t27(29, x27); \
T_PUT_##t28(30, x28); \
T_PUT_##t29(31, x29); \
T_COMMIT(); \
} \
} while (0)
#define T63(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22,t23,x23,t24,x24,t25,x25,\
t26,x26,t27,x27,t28,x28,t29,x29,t30,x30) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_PUT_##t23(25, x23); \
T_PUT_##t24(26, x24); \
T_PUT_##t25(27, x25); \
T_PUT_##t26(28, x26); \
T_PUT_##t27(29, x27); \
T_PUT_##t28(30, x28); \
T_PUT_##t29(31, x29); \
T_PUT_##t30(32, x30); \
T_COMMIT(); \
} \
} while (0)
#define T65(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22,t23,x23,t24,x24,t25,x25,\
t26,x26,t27,x27,t28,x28,t29,x29,t30,x30,t31,x31) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_PUT_##t23(25, x23); \
T_PUT_##t24(26, x24); \
T_PUT_##t25(27, x25); \
T_PUT_##t26(28, x26); \
T_PUT_##t27(29, x27); \
T_PUT_##t28(30, x28); \
T_PUT_##t29(31, x29); \
T_PUT_##t30(32, x30); \
T_PUT_##t31(33, x31); \
T_COMMIT(); \
} \
} while (0)
#define T67(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22,t23,x23,t24,x24,t25,x25,\
t26,x26,t27,x27,t28,x28,t29,x29,t30,x30,t31,x31,t32,x32) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_PUT_##t23(25, x23); \
T_PUT_##t24(26, x24); \
T_PUT_##t25(27, x25); \
T_PUT_##t26(28, x26); \
T_PUT_##t27(29, x27); \
T_PUT_##t28(30, x28); \
T_PUT_##t29(31, x29); \
T_PUT_##t30(32, x30); \
T_PUT_##t31(33, x31); \
T_PUT_##t32(34, x32); \
T_COMMIT(); \
} \
} while (0)
#define T69(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22,t23,x23,t24,x24,t25,x25,\
t26,x26,t27,x27,t28,x28,t29,x29,t30,x30,t31,x31,t32,x32,t33,x33) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_PUT_##t23(25, x23); \
T_PUT_##t24(26, x24); \
T_PUT_##t25(27, x25); \
T_PUT_##t26(28, x26); \
T_PUT_##t27(29, x27); \
T_PUT_##t28(30, x28); \
T_PUT_##t29(31, x29); \
T_PUT_##t30(32, x30); \
T_PUT_##t31(33, x31); \
T_PUT_##t32(34, x32); \
T_PUT_##t33(35, x33); \
T_COMMIT(); \
} \
} while (0)
#define T71(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,\
t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15,t16,x16,t17,x17,\
t18,x18,t19,x19,t20,x20,t21,x21,t22,x22,t23,x23,t24,x24,t25,x25,\
t26,x26,t27,x27,t28,x28,t29,x29,t30,x30,t31,x31,t32,x32,t33,x33,t34,x34) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_PUT_##t16(18, x16); \
T_PUT_##t17(19, x17); \
T_PUT_##t18(20, x18); \
T_PUT_##t19(21, x19); \
T_PUT_##t20(22, x20); \
T_PUT_##t21(23, x21); \
T_PUT_##t22(24, x22); \
T_PUT_##t23(25, x23); \
T_PUT_##t24(26, x24); \
T_PUT_##t25(27, x25); \
T_PUT_##t26(28, x26); \
T_PUT_##t27(29, x27); \
T_PUT_##t28(30, x28); \
T_PUT_##t29(31, x29); \
T_PUT_##t30(32, x30); \
T_PUT_##t31(33, x31); \
T_PUT_##t32(34, x32); \
T_PUT_##t33(35, x33); \
T_PUT_##t34(36, x34); \
T_COMMIT(); \
} \
} while (0)
#define T_CALL_ERROR \
do { \
printf("%s:%d:%s: error calling T, you have to use T_INT() or T_XX()\n", \
@@ -1274,22 +645,6 @@ extern int *T_active;
#define T34(...) T_CALL_ERROR
#define T36(...) T_CALL_ERROR
#define T38(...) T_CALL_ERROR
#define T40(...) T_CALL_ERROR
#define T42(...) T_CALL_ERROR
#define T44(...) T_CALL_ERROR
#define T46(...) T_CALL_ERROR
#define T48(...) T_CALL_ERROR
#define T50(...) T_CALL_ERROR
#define T52(...) T_CALL_ERROR
#define T54(...) T_CALL_ERROR
#define T56(...) T_CALL_ERROR
#define T58(...) T_CALL_ERROR
#define T60(...) T_CALL_ERROR
#define T62(...) T_CALL_ERROR
#define T64(...) T_CALL_ERROR
#define T66(...) T_CALL_ERROR
#define T68(...) T_CALL_ERROR
#define T70(...) T_CALL_ERROR
/* special cases for VCD logs */

View File

@@ -111,26 +111,6 @@ ID = GNB_PHY_PUCCH_PUSCH_IQ
DESC = gNodeB input data in the frequency domain for a slot where some PUCCH or PUSCH detection was done
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,frame : int,slot : buffer,rxdataF
ID = GNB_PHY_UL_FD_PUSCH_IQ
DESC = gNodeB UL PUSCH IQ Data in the frequency domain
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm : int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot : int,Nid_cell : int,rnti : int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols : int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers : int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols : int,dmrs_port : int,dmrs_nscid : int,nb_antennas_rx : int,number_of_bits : buffer,data
ID = GNB_PHY_UL_FD_DMRS
DESC = gNodeB UL DMRS Signal in the frequency domain
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm : int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot : int,Nid_cell : int,rnti : int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols : int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers : int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols : int,dmrs_port : int,dmrs_nscid : int,nb_antennas_rx : int,number_of_bits : buffer,data
ID = GNB_PHY_UL_FD_CHAN_EST_DMRS_POS
DESC = gNodeB channel estimation in the frequency domain based on DMRS and at DMRS pilots location without any further interploation.
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm : int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot : int,Nid_cell : int,rnti : int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols : int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers : int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols : int,dmrs_port : int,dmrs_nscid : int,nb_antennas_rx : int,number_of_bits : buffer,data
ID = GNB_PHY_UL_FD_CHAN_EST_DMRS_INTERPL
DESC = gNodeB channel estimation in the frequency domain based on DMRS and interploation.
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm : int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot : int,Nid_cell : int,rnti : int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols : int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers : int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols : int,dmrs_port : int,dmrs_nscid : int,nb_antennas_rx : int,number_of_bits : buffer,dataI
ID = GNB_PHY_UL_PAYLOAD_RX_BITS
DESC = gNodeB slot payload after decoder
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm : int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot : int,Nid_cell : int,rnti : int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols : int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers : int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols : int,dmrs_port : int,dmrs_nscid : int,nb_antennas_rx : int,number_of_bits : buffer,data
ID = GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE
DESC = gNodeB channel estimation in the frequency domain
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
@@ -147,6 +127,10 @@ ID = GNB_PHY_DL_OUTPUT_SIGNAL
DESC = gNodeB output data in the freq domain for slots
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,gNB_ID : int,frame : int,slot : int,antenna : buffer,txdata
ID = GNB_MAC_UL_FREQ_CHANNEL_ESTIMATE
DESC = SRS channel estimation as signalled by FAPI
GROUP = ALL:MAC:GNB
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,rx_antennas : int,tx_antennas : buffer,chest_t
#MAC logs
ID = ENB_MAC_UE_DL_SDU
@@ -1372,14 +1356,6 @@ ID = UE_PHY_MEAS
DESC = UE PHY measurements
GROUP = ALL:PHY:GRAPHIC:HEAVY:UE
FORMAT = int,eNB_ID : int,frame : int,subframe : int,rsrp : int,rssi : int,snr: int,rx_power: int,noise_power: int,w_cqi: int,freq_offset
ID = UE_PHY_UL_PAYLOAD_TX_BITS
DESC = UE UL Tx bits in one slot before decoder and scrambler
GROUP = ALL:PHY:GRAPHIC:HEAVY:UE
FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm : int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot : int,Nid_cell : int,rnti : int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols : int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers : int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols : int,dmrs_port : int,dmrs_nscid : int,nb_antennas_tx : int,number_of_bits : buffer,data
ID = UE_PHY_UL_SCRAMBLED_TX_BITS
DESC = UE UL Tx bits in one slot after scrambler
GROUP = ALL:PHY:GRAPHIC:HEAVY:UE
FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm : int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot : int,Nid_cell : int,rnti : int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols : int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers : int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols : int,dmrs_port : int,dmrs_nscid : int,nb_antennas_tx : int,number_of_bits : buffer,data
#for debug/test - not used
ID = first

View File

@@ -8,7 +8,7 @@ XLIBS=-lX11 -lpng -lXft
all: record replay extract_config textlog enb ue vcd macpdu2wireshark \
extract_input_subframe extract_output_subframe to_vcd extract multi \
gnb t_tracer_app_gnb t_tracer_app_ue
gnb
record: utils.o record.o database.o configuration.o
$(CC) $(CFLAGS) -o record $^ $(LIBS)
@@ -65,14 +65,6 @@ gnb: utils.o gnb.o database.o event.o handler.o configuration.o \
filter/filter.a
$(CC) $(CFLAGS) -o gnb $^ $(LIBS) $(XLIBS)
t_tracer_app_gnb: utils.o t_tracer_app_gnb.o database.o event.o handler.o configuration.o \
logger/logger.a filter/filter.a
$(CC) $(CFLAGS) -o t_tracer_app_gnb $^ $(LIBS) $(XLIBS)
t_tracer_app_ue: utils.o t_tracer_app_ue.o database.o event.o handler.o configuration.o \
logger/logger.a filter/filter.a
$(CC) $(CFLAGS) -o t_tracer_app_ue $^ $(LIBS) $(XLIBS)
multi.o: ../incgen/T_IDs.h
../incgen/T_IDs.h: ../T_messages.txt
@@ -98,7 +90,7 @@ filter/filter.a:
clean:
rm -f *.o core tracer_remote textlog enb ue vcd record replay
rm -f extract_config macpdu2wireshark extract_input_subframe
rm -f extract_output_subframe to_vcd extract multi gnb t_tracer_app_gnb t_tracer_app_ue
rm -f extract_output_subframe to_vcd extract multi gnb
cd gui && $(MAKE) clean
cd view && $(MAKE) clean
cd logger && $(MAKE) clean

View File

@@ -8,7 +8,7 @@
#endif
/* maximum number of arguments for the T macro */
#define T_MAX_ARGS 72
#define T_MAX_ARGS 32
enum event_arg_type {
EVENT_INT,

View File

@@ -3,7 +3,7 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. -I..
LIBS=-lX11 -lm -lpng -lXft
all: dump_nack_signal time_meas timeplot multi-rru-clean ant0 plot-ofdm
all: dump_nack_signal time_meas timeplot multi-rru-clean
dump_nack_signal: ../utils.o ../database.o ../configuration.o ../event.o \
dump_nack_signal.o
@@ -19,25 +19,10 @@ timplot: timeplot.o
multi-rru-clean: ../utils.o ../database.o ../event.o ../configuration.o multi-rru-clean.o
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
ant0: ant0.o ../utils.o ../database.o ../configuration.o ../event.o
$(CC) $(CFLAGS) -o $@ $^ -lm
#ant0 needs good compilation, conversion to float is heavy
ant0.o: ant0.c
$(CC) $(CFLAGS) -c -o $@ $< -march=native -ffast-math -O3
plot-ofdm: plot-ofdm.o ../utils.o
$(CC) $(CFLAGS) -o $@ $^ $(LIBS) -lfftw3f
#plot-ofdm needs good compilation
plot-ofdm.o: plot-ofdm.c
$(CC) $(CFLAGS) -c -o $@ $< -march=native -ffast-math -O3
.PHONY: all
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f *.o core dump_nack_signal time_meas timeplot multi-rru-clean \
ant0 plot-ofdm
rm -f *.o core dump_nack_signal time_meas timeplot multi-rru-clean

View File

@@ -1,259 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include "database.h"
//#include "utils.h"
#include "configuration.h"
#include "event.h"
void usage(void)
{
fprintf(stderr,
"options:\n"
" -d <database file> this option is mandatory\n"
" -o <output file> this option is mandatory (use - to dump to stdout)\n"
" -ip <host> connect to given IP address (default %s)\n"
" -p <port> connect to given port (default %d)\n"
" -n <max> save maximum 'max' IQ points (may be a bit more)\n"
" -nosig don't intercept ctrl+c, ctrl+z (it may mess up when piping to another tool)\n"
" -e <event name> trace given event (default 'USRP_TX_ANT0')\n"
" -b <buffer name> trace given buffer (default 'data')\n"
" -no-timestamp don't use 'timestamp' to fill missing transmission\n"
" -scale <scale value> divide 16bits input by given value for float output (default 32768.)\n"
" -s16 output short instead of float\n",
DEFAULT_REMOTE_IP,
DEFAULT_REMOTE_PORT
);
exit(1);
}
volatile int run = 1;
static int socket = -1;
void force_stop(int x)
{
fprintf(stderr, "\ngently quit...\n");
close(socket);
socket = -1;
run = 0;
}
int main(int n, char **v)
{
char *database_filename = NULL;
char *output_filename = NULL;
FILE *out;
void *database;
char *ip = DEFAULT_REMOTE_IP;
int port = DEFAULT_REMOTE_PORT;
int *is_on;
int number_of_events;
int i;
char mt;
long max = -1;
long dumped = 0;
int nosig = 0;
char *event_name = "USRP_TX_ANT0";
char *buffer_name = "data";
int no_timestamp = 0;
float scale = 32768;
int do_float = 1;
/* write on a socket fails if the other end is closed and we get SIGPIPE */
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort();
for (i = 1; i < n; i++) {
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
if (!strcmp(v[i], "-d")) { if (i > n-2) usage(); database_filename = v[++i]; continue; }
if (!strcmp(v[i], "-o")) { if (i > n-2) usage(); output_filename = v[++i]; continue; }
if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; }
if (!strcmp(v[i], "-p")) { if (i > n-2) usage(); port = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-n")) { if (i > n-2) usage(); max = atol(v[++i]); continue; }
if (!strcmp(v[i], "-nosig")) { nosig = 1; continue; }
if (!strcmp(v[i], "-e")) { if (i > n-2) usage(); event_name = v[++i]; continue; }
if (!strcmp(v[i], "-b")) { if (i > n-2) usage(); buffer_name = v[++i]; continue; }
if (!strcmp(v[i], "-no-timestamp")) { no_timestamp = 1; continue; }
if (!strcmp(v[i], "-scale")) { if (i > n-2) usage(); scale = atof(v[++i]); continue; }
if (!strcmp(v[i], "-s16")) { do_float = 0; continue; }
usage();
}
if (database_filename == NULL) {
fprintf(stderr, "ERROR: provide a database file (-d)\n");
exit(1);
}
if (output_filename == NULL) {
fprintf(stderr, "ERROR: provide an output file (-o)\n");
exit(1);
}
database = parse_database(database_filename);
load_config_file(database_filename);
/* get the event and fields from database */
int tx_ant0_id = event_id_from_name(database, event_name);
database_event_format f = get_format(database, tx_ant0_id);
#define G(var_name, var_type, var) \
if (!strcmp(f.name[i], var_name)) { \
if (strcmp(f.type[i], var_type)) abort(); \
var = i; \
continue; \
}
int timestamp_id = -1;
int data_id = -1;
for (i = 0; i < f.count; i++) {
/* there is a typo in T_messages.txt, "timestap" instead of "timestamp" */
if (!no_timestamp)
G("timestap", "int", timestamp_id);
G(buffer_name, "buffer", data_id);
}
if ((!no_timestamp && timestamp_id == -1) || data_id == -1) {
if (data_id == -1)
fprintf(stderr, "fatal: field '%s' of event '%s' does not exist\n",
buffer_name, event_name);
if (!no_timestamp && timestamp_id == -1)
fprintf(stderr, "fatal: field 'timestamp' of event '%s' does not exist\n",
event_name);
exit(1);
}
number_of_events = number_of_ids(database);
is_on = calloc(number_of_events, sizeof(int));
if (is_on == NULL) abort();
on_off(database, event_name, is_on, 1);
/* connect to tracee */
socket = connect_to(ip, port);
/* activate trace */
mt = 1;
if (socket_send(socket, &mt, 1) == -1 ||
socket_send(socket, &number_of_events, sizeof(int)) == -1 ||
socket_send(socket, is_on, number_of_events * sizeof(int)) == -1)
abort();
/* - means to output to stdout */
if (!strcmp(output_filename, "-")) {
out = stdout;
} else {
out = fopen(output_filename, "w");
if (out == NULL) {
perror(output_filename);
exit(1);
}
}
if (!nosig) {
/* exit on ctrl+c and ctrl+z */
if (signal(SIGQUIT, force_stop) == SIG_ERR) abort();
if (signal(SIGINT, force_stop) == SIG_ERR) abort();
if (signal(SIGTSTP, force_stop) == SIG_ERR) abort();
}
OBUF ebuf = {.osize = 0, .omaxsize = 0, .obuf = NULL};
/* read messages */
unsigned int last_timestamp = 0;
int last_count = 0;
int first = 1;
/* stop if max reached */
while ((max == -1 || dumped < max) && run) {
event e;
e = get_event(socket, &ebuf, database);
if (e.type == -1) break;
if (e.type != tx_ant0_id) continue;
unsigned int timestamp = 0;
if (!no_timestamp)
timestamp = e.e[timestamp_id].i;
int count = e.e[data_id].bsize / 4;
#if 0
fprintf(stderr, "timestamp %u buffer %p count %d not transmitted %d delta %d\n",
timestamp,
e.e[data_id].b,
count,
timestamp - (last_timestamp + last_count),
timestamp - last_timestamp);
#endif
/* rfsimulator may send 1 sample with old time when a new client connects
* let's reject this packet
*/
if (!first && timestamp < last_timestamp + last_count) {
/* more than 1 sample is not accepted */
if (count != 1) {
fprintf(stderr, "fatal: past transmission detected (%d samples)\n", count);
abort();
}
fprintf(stderr, "past transmission detected (%d samples), ignore\n", count);
continue;
}
/* insert missing samples */
if (!no_timestamp && !first) {
int missing = timestamp - (last_timestamp + last_count);
if (missing < 0) abort();
while (missing) {
/* limit size of array miss[], it's allocated on the stack */
int count = missing > 65536 ? 65536 : missing;
float miss[count * 2];
memset(miss, 0, count * 2 * sizeof(float));
if (fwrite(miss, count * 2 * sizeof(float), 1, out) != 1) {
fprintf(stderr, "error writing to %s\n", output_filename);
if (strcmp(output_filename, "-"))
fclose(out);
close(socket);
exit(1);
}
dumped += count;
missing -= count;
}
}
first = 0;
if (do_float) {
/* transform to float */
float iq[count * 2];
short *iq_short = (short *)e.e[data_id].b;
for (int i = 0; i < count * 2; i++)
iq[i] = iq_short[i] / scale;
/* save */
if (fwrite(iq, count * 2 * sizeof(float), 1, out) != 1) {
fprintf(stderr, "error writing to %s\n", output_filename);
if (strcmp(output_filename, "-"))
fclose(out);
exit(1);
}
} else {
/* save directly as short */
if (fwrite(e.e[data_id].b, count * 2 * 2, 1, out) != 1) {
fprintf(stderr, "error writing to %s\n", output_filename);
if (strcmp(output_filename, "-"))
fclose(out);
exit(1);
}
}
dumped += count;
last_timestamp = timestamp;
last_count = count;
}
if (strcmp(output_filename, "-"))
fclose(out);
close(socket);
return 0;
}

View File

@@ -1,351 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <X11/Xlib.h>
#include <stdint.h>
#include <pthread.h>
#include <complex.h>
#include <fftw3.h>
#include <string.h>
#include <unistd.h>
#include "utils.h"
const int width = 14 * 20 * 4;
int height;
/* when vzoom = 1 each pixel represents 1 RE
* when 2, it is max of 2 vertical REs
* useful if height of plot is to big
* (with 106 RB we already reach 106*12 = 1272 pixels, so with even bigger
* bandwidths...)
*/
int vzoom = 1;
/* when hzoom = 1 each pixel represents 1 RE
* when 2, it is max of 2 horizontal REs
* useful to slow down display
*/
int hzoom = 1;
/* intensity is to scale the input
* normally, as float, cabs(input) is in [0..1]
* to get pixel color we *255
* but maybe it's too intense, or not enough,
* so let's have a control the user can set at will
*/
float intensity = 255;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
void lock(void)
{
pthread_mutex_lock(&m);
}
void unlock(void)
{
pthread_mutex_unlock(&m);
}
typedef struct {
Display *d;
Window w;
XImage *img;
unsigned char *img_data;
int img_pos;
} gui_t;
/* delay management begin */
long double frame_time;
void time_start(void)
{
struct timespec l;
if (clock_gettime(CLOCK_REALTIME, &l)) abort();
frame_time = l.tv_sec * 1000000000. + l.tv_nsec;
}
void delay(int fps)
{
struct timespec t;
struct timespec delay;
long double cur_time;
frame_time += 1000000000. / fps;
if (clock_gettime(CLOCK_REALTIME, &t)) abort();
cur_time = t.tv_sec * 1000000000. + t.tv_nsec;
if (frame_time < cur_time) { fprintf(stderr, "ERROR: we late\n"); return; }
delay.tv_nsec = ((uint64_t)(frame_time-cur_time)) % 1000000000;
delay.tv_sec = ((uint64_t)(frame_time-cur_time)) / 1000000000;
if (pselect(0, NULL, NULL, NULL, &delay, NULL)) { fprintf(stderr, "ERROR: pselect fails\n"); exit(1); }
}
/* delay management end */
static void *gui_thread(void *_g)
{
time_start();
gui_t *g = _g;
while (1) {
XEvent e; while (XPending(g->d)) XNextEvent(g->d, &e);
lock();
XPutImage(g->d, g->w, DefaultGC(g->d, DefaultScreen(g->d)), g->img, 0, 0, 0, 0,
width, height/vzoom);
unlock();
delay(10);
}
return 0;
}
unsigned char re_to_pixel(float re)
{
float v = fminf(255, re * intensity);
return v;
}
unsigned char mix(unsigned char a, unsigned char b)
{
return a > b ? a : b;
}
void usage(void)
{
printf("options:\n");
printf(" -f input is float, not s16\n");
printf(" -srate <sampling rate> set sampling rate (default 61440000)\n");
printf(" -prb <prb> set number of PRBs (default 106)\n");
printf(" -mu <mu> set mu (default 1, 0 is for 15KHz, 1 for 30KHz, etc.)\n");
printf(" -no-fft don't do fft, input is in frequency domain\n");
printf(" -vzoom <zoom> add some sort of vertical zoom, default 1, passing 2 divides height by 2, etc.\n");
printf(" -hzoom <zoom> add some sort of speed control, default 1, passing 2 means 2 REs per pixel, etc.\n");
printf(" -delay <delay> delay 'delay' microseconds between processing of each symbol\n");
printf(" -intensity <intensity> set intensity of data pixel (default 255.)\n");
printf(" -skip <count> skip 'count' samples at beginning\n");
exit(0);
}
int main(int n, char **v)
{
int input_is_float = 0;
int no_fft = 0;
int delay = 0;
int skip = 0;
int symbols_per_subframe;
long sampling_rate = 61440000;
int mu = 1;
int prb = 106;
/* parse command line arguments */
for (int i = 1; i < n; i++) {
if (!strcmp(v[i], "-f")) { input_is_float = 1; continue; }
if (!strcmp(v[i], "-no-fft")) { no_fft = 1; continue; }
if (!strcmp(v[i], "-vzoom")) { if (i>n-2) usage(); vzoom = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-hzoom")) { if (i>n-2) usage(); hzoom = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-delay")) { if (i>n-2) usage(); delay = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-intensity")) { if (i>n-2) usage(); intensity = atof(v[++i]); continue; }
if (!strcmp(v[i], "-srate")) { if (i>n-2) usage(); sampling_rate = atol(v[++i]); continue; }
if (!strcmp(v[i], "-prb")) { if (i>n-2) usage(); prb = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-mu")) { if (i>n-2) usage(); mu = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-skip")) { if (i>n-2) usage(); skip = atoi(v[++i]); continue; }
usage();
}
symbols_per_subframe = 14 * (1 << mu);
/* compute durations from sampling rate and mu (scs) */
/* this is 38.211 5.3.1, a bit simplified/reordered */
int ofdm_duration = sampling_rate / 15000 / (1 << mu);
int l0_cycle_prefix = sampling_rate / 480000 * (144*64 / (1 << mu) + 16*64) / 4096;
int cycle_prefix = sampling_rate / 480000 * (144*64 / (1 << mu)) / 4096;
/* small sanity check */
if (prb * 12 > ofdm_duration) {
printf("fatal: too many PRBs for this sampling rate / mu\n");
exit(1);
}
height = prb * 12;
if (height % vzoom) { fprintf(stderr, "bad vzoom for this height, try 1, 2, 4, ...\n"); return 1; }
gui_t g = { 0 };
/* open X11 display */
g.d = XOpenDisplay(0);
if (!g.d) {
fprintf(stderr, "could not open display\n");
return 1;
}
/* create window */
g.w = XCreateSimpleWindow(g.d, DefaultRootWindow(g.d), 0, 0,
width, height / vzoom, 0, WhitePixel(g.d, DefaultScreen(g.d)),
WhitePixel(g.d, DefaultScreen(g.d)));
XStoreName(g.d, g.w, "IQ");
/* enable backing store */
{
XSetWindowAttributes att;
att.backing_store = Always;
XChangeWindowAttributes(g.d, g.w, CWBackingStore, &att);
}
XSelectInput(g.d, g.w,
KeyPressMask |
ButtonPressMask |
ButtonReleaseMask |
PointerMotionMask |
ExposureMask |
StructureNotifyMask);
XMapWindow(g.d, g.w);
g.img_data = calloc(1, width * height/vzoom * 4); if (!g.img_data) abort();
g.img = XCreateImage(g.d, DefaultVisual(g.d, DefaultScreen(g.d)), 24 /*depth*/,
ZPixmap, 0 /*offset*/, (char*)g.img_data, width, height/vzoom, 8, 0);
new_thread(gui_thread, &g);
/* fft data */
int fft_size = ofdm_duration;
float complex *in = fftwf_malloc(sizeof(float complex) * fft_size);
float complex *out = fftwf_malloc(sizeof(float complex) * fft_size);
fftwf_plan p_fft = fftwf_plan_dft_1d(fft_size, in, out,
FFTW_FORWARD, FFTW_ESTIMATE);
memset(in, 0, sizeof(float complex) * fft_size);
fftwf_execute(p_fft);
int symbol = 0;
int back_color = 0;
int hpixel = 0;
if (skip) {
if (input_is_float) {
float intime[skip * 2];
if (fread(intime, skip * 8, 1, stdin) != 1) abort();
} else {
short intime[skip * 2];
if (fread(intime, skip * 4, 1, stdin) != 1) abort();
}
}
while (1) {
int cur_cycle_prefix;
if (symbol == 0 || symbol == 7 * (1 << mu))
cur_cycle_prefix = l0_cycle_prefix;
else
cur_cycle_prefix = cycle_prefix;
if (no_fft) goto without_fft;
/* input signal is in time domain, timing aligned, do FFT */
/* read time domain data */
if (input_is_float) {
float intime[(ofdm_duration + cur_cycle_prefix) * 2];
if (fread(intime, (ofdm_duration + cur_cycle_prefix) * 8, 1, stdin) != 1) break;
for (int i = 0; i < fft_size; i++)
/* skip cycle prefix */
in[i] = intime[(cur_cycle_prefix + i) * 2] + I * intime[(cur_cycle_prefix + i) * 2 + 1];
} else {
short intime[(ofdm_duration + cur_cycle_prefix) * 2];
if (fread(intime, (ofdm_duration + cur_cycle_prefix) * 4, 1, stdin) != 1) break;
for (int i = 0; i < fft_size; i++)
/* skip cycle prefix */
in[i] = intime[(cur_cycle_prefix + i) * 2] / 2048. + I * intime[(cur_cycle_prefix + i) * 2 + 1] / 2048.;
}
/* go to freq domain */
fftwf_execute(p_fft);
goto after_fft;
without_fft:
/* input data is symbols, each containing full FFT data */
if (input_is_float) {
float infreq[fft_size * 2];
if (fread(infreq, fft_size * 2 * 4, 1, stdin) != 1) break;
for (int i = 0; i < fft_size; i++)
out[i] = infreq[i * 2] + I * infreq[i * 2 + 1];
} else {
short infreq[ofdm_duration * 2];
if (fread(infreq, fft_size * 2 * 2, 1, stdin) != 1) break;
for (int i = 0; i < fft_size; i++)
out[i] = infreq[i * 2] / 2048. + I * infreq[i * 2 + 1] / 2048.;
}
after_fft:
lock();
/* extract data of this ofdm symbol */
unsigned char *p = g.img_data + g.img_pos * 4;
int front_pos = (g.img_pos + 8) % width;
unsigned char *pfront = g.img_data + front_pos * 4;
for (int i = prb * 12 - 1; i >= 0; i -= vzoom) {
/* take the max */
float out_val = 0;
for (int j = 0; j < vzoom; j++) {
int start = - prb * 12 / 2;
int pos = start + i + j;
/* neg freq are at the end of fft data array */
int pos_in_fft = pos >= 0
? pos
: pos + fft_size;
float v = cabs(out[pos_in_fft]);
if (v > out_val) out_val = v;
}
int color = re_to_pixel(out_val);
/* grey level image mixed with some background changing every slot */
unsigned char back_col[2][3] = {
{ 100, 90, 90 },
{ 100, 60, 60, }
};
if (hpixel == 0) {
p[0] = p[1] = p[2] = color;
} else {
p[0] = mix(p[0], color);
p[1] = mix(p[1], color);
p[2] = mix(p[2], color);
}
if (hpixel == hzoom - 1) {
p[0] = mix(p[0], back_col[back_color][0]);
p[1] = mix(p[1], back_col[back_color][1]);
p[2] = mix(p[2], back_col[back_color][2]);
}
p[3] = 255;
p += width * 4;
pfront[0] = 255;
pfront[1] = 128;
pfront[2] = 128;
pfront[3] = 255;
pfront += width * 4;
}
unlock();
hpixel++;
if (hpixel == hzoom) {
hpixel = 0;
g.img_pos++;
if (g.img_pos == width) g.img_pos = 0;
}
symbol++;
if (symbol == symbols_per_subframe) symbol = 0;
/* switch back color every slot */
if (symbol % 14 == 0)
back_color = 1 - back_color;
if (delay) usleep(delay);
}
return 0;
}

View File

@@ -1,64 +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
*/
/*! \file common/utils/T/tracer/shared_memory_config.h
* \brief shared memory to store data captured by T-Tracer services to be processed by data recording application
* \author Abdo Gaber
* \date 2024
* \version 1.0
* \company Emerson, NI Test and Measurement
* \email:
* \note
* \warning
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>
#ifndef _SHARED_MEMORY_CONFIG_H_
#define _SHARED_MEMORY_CONFIG_H_
#define SHMSIZE ((122.88e6 / (100 * 20)) * 1000 * 8) // Assume capture in 1000, each I+Q represented by 8 byts
// 122.88e6: 10ms at 100 MHz BW of 5G NR
// 20: 20 slots in 10ms
// subcarrier spacing: 30 KHz
// for gNB T Tracer App
#define GETKEYDIR1_gNB ("/tmp/gnb_app1")
#define GETKEYDIR2_gNB ("/tmp/gnb_app2")
#define PROJECTID_gNB (2335)
// for UET Tracer App
#define GETKEYDIR1_UE ("/tmp/ue_app1")
#define GETKEYDIR2_UE ("/tmp/ue_app2")
#define PROJECTID_UE (2336)
void err_exit(char *buf);
int create_shm(char **addrN, const char *pathname, int projectId);
void del_shm(char *addr, int shm_id);
#endif /* _SHARED_MEMORY_CONFIG_H_ */

View File

@@ -1,973 +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
*/
/*! \file common/utils/T/tracer/t_tracer_app_gnb.c
* \brief T-Tracer gnb service to capture tracee Messages from gNB, it is used by data recording application
* \author Abdo Gaber
* \date 2025
* \version 1.0
* \company Emerson, NI Test and Measurement
* \email:
* \note
* \warning
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>
#include "database.h"
#include "event.h"
#include "handler.h"
#include "logger/logger.h"
#include "utils.h"
#include "event_selector.h"
#include "configuration.h"
#include "shared_memory_config.h"
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <poll.h>
#define MAX_FRAME_INDEX 1023
#define MAX_SLOT_INDEX 19
#define DEBUG_T_Tracer
#define DEBUG_BUFFER
// Duration to discard recording in milliseconds to mitigate reading data from
// the buffer in the stack from the previous record
#define DISCARD_RECORD_DURATION_MS 10
// Combine bytes in - little-endian format
int combine_bytes(const uint8_t *bytes, size_t num_bytes)
{
int result = 0;
for (size_t i = 0; i < num_bytes; ++i) {
result |= (bytes[i] << (i * 8));
}
return result;
}
// Convert an integer to an array of bytes - little-endian format
void int_to_bytes(int num, uint8_t *bytes, size_t num_bytes)
{
for (size_t i = 0; i < num_bytes; ++i) {
bytes[i] = (num >> (i * 8)) & 0xFF;
}
}
// Check if the message is in the list of bits messages
bool is_bits_messages(int traces_bits_support_data_Collection_format_idx[], int n_bits_msgs, int msg_id)
{
for (int i = 0; i < n_bits_msgs; i++) {
if (msg_id == traces_bits_support_data_Collection_format_idx[i]) {
return true;
}
}
return false;
}
// Get the current time
struct timespec get_current_time()
{
struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
return time;
}
// Function to convert timespec to microseconds
long long timespec_to_microseconds(struct timespec time)
{
return (time.tv_sec * 1000000LL) + (time.tv_nsec / 1000);
}
// Calculate the time difference in milliseconds
double calculate_time_difference(struct timespec start, struct timespec end)
{
double start_ms = start.tv_sec * 1000.0 + start.tv_nsec / 1000000.0;
double end_ms = end.tv_sec * 1000.0 + end.tv_nsec / 1000000.0;
return end_ms - start_ms;
}
// Get Time Stamp in microseconds in YYYYMMDDHHMMSSmmmuuu format
char *get_time_stamp_usec(char time_stamp_str[])
{
// initialization to measure time stamp --This part should be moved to inilization part
time_t my_time;
struct tm *timeinfo;
time(&my_time);
struct timeval tv;
// get time stamp
timeinfo = localtime(&my_time);
gettimeofday(&tv, NULL);
// Add time stamp: yyyy mm dd hh mm ss usec
uint16_t year = timeinfo->tm_year + 1900;
uint8_t mon = timeinfo->tm_mon + 1;
uint8_t mday = timeinfo->tm_mday;
uint8_t hour = timeinfo->tm_hour;
uint8_t min = timeinfo->tm_min;
uint8_t sec = timeinfo->tm_sec;
uint16_t usec = (tv.tv_usec);
// printf ("Time stamp: %d_%d_%d_%d_%d_%d_%d \n",year,mon,mday,hour,min,sec,usec);
// sprintf(time_stamp_str, "%d_%d_%d_%d_%d_%d_%d",year,mon,mday,hour,min,sec,usec);
sprintf(time_stamp_str, "%04d%02d%02d%02d%02d%02d%06d", year, mon, mday, hour, min, sec, usec);
return time_stamp_str;
}
// Convert timestamp string to integer
int convert_time_stamp_to_int(const char *timestamp)
{
return atoi(timestamp);
}
// Split timestamp string and convert to integer
int split_time_stamp_and_convert_to_int(char time_stamp_str[], int shift, int length)
{
char time_part[length + 1]; // Buffer to hold the date part YYYYMMDD or HHMMSSmmm
// Copy the first 8 or 9 characters (YYYYMMDD) to HHMMSSmmm
strncpy(time_part, time_stamp_str + shift, length);
time_part[length] = '\0'; // Null-terminate the string
// Convert timestamp string to integer
return convert_time_stamp_to_int(time_part);
}
void err_exit(char *buf)
{
fprintf(stderr, "%s\n", buf);
exit(1);
}
// create shared memory
int create_shm(char **addrN, const char *shm_path, int projectId)
{
key_t key;
if (-1 != open(shm_path, O_CREAT, 0777)) {
key = ftok(shm_path, projectId);
} else {
err_exit("Error: open shared memory");
}
if (key < 0) {
err_exit("Error: ftok error");
}
int shm_id;
shm_id = shmget(key, SHMSIZE, IPC_CREAT | IPC_EXCL | 0664);
if (shm_id == -1) {
if (errno == EEXIST) {
printf("Error: shared memeory already exist\n");
shm_id = shmget(key, 0, 0);
printf("reference shm_id = %d\n", shm_id);
} else {
perror("errno");
err_exit("shmget error");
}
}
char *addr;
// address to attach - attach for read & write
if ((addr = shmat(shm_id, 0, 0)) == (void *)-1) {
if (shmctl(shm_id, IPC_RMID, NULL) == -1)
err_exit("Error: shmctl error");
else {
printf("Attach shared memory failed\n");
printf("remove shared memory identifier successful\n");
}
err_exit("shmat error");
}
*addrN = addr;
return shm_id;
}
// delete shared memory
void del_shm(char *addr, int shm_id)
{
if (shmdt(addr) < 0)
err_exit("shmdt error");
if (shmctl(shm_id, IPC_RMID, NULL) == -1)
err_exit("shmctl error");
else {
printf("Remove shared memory identifier successful\n");
}
}
/* this function sends the activated traces to the nr-softmodem */
void activate_traces(int socket, int number_of_events, int *is_on)
{
char t = 1;
if (socket_send(socket, &t, 1) == -1 || socket_send(socket, &number_of_events, sizeof(int)) == -1
|| socket_send(socket, is_on, number_of_events * sizeof(int)) == -1)
abort();
}
void usage(void)
{
printf(
"options:\n"
" -d <database file> this option is mandatory\n"
" -ip <host> connect to given IP address (default %s)\n"
" -p <port> connect to given port (default %d)\n",
DEFAULT_REMOTE_IP,
DEFAULT_REMOTE_PORT);
exit(1);
}
// class to store the message and the action to enable capture selected data
// 0: do not record message
// 1: record message
struct trace_struct {
char on_off_name[100];
int on_off_action;
};
// struct for trace message based on Data Collection Trace Messages Structure
// you need to define the vararibles of each message
typedef struct {
/* Data Collection Trace Message Structure */
int frame;
int slot;
int datetime_yyyymmdd;
int datetime_hhmmssmmm;
int frame_type, freq_range, subcarrier_spacing, cyclic_prefix, symbols_per_slot;
int Nid_cell, rnti;
int rb_size, rb_start, start_symbol_index, nr_of_symbols;
int qam_mod_order, mcs_index, mcs_table, nrOfLayers, transform_precoding;
int dmrs_config_type, ul_dmrs_symb_pos, number_dmrs_symbols;
int dmrs_port, dmrs_nscid, nb_antennas_rx, number_of_bits;
int data_size, data;
} event_trace_msg_data;
void setup_trace_msg_data(event_trace_msg_data *d, void *database)
{
database_event_format f;
int i;
/* Data Collection Trace Message Structure */
// FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm :
// int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot :
// int,Nid_cell : int,rnti :
// int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols :
// int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers :
// int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols :
// int,dmrs_port : int,dmrs_nscid :
// int,nb_antennas_rx : int,number_of_bits : buffer,data
// Initialize the data structure
d->frame = -1;
d->slot = -1;
d->datetime_yyyymmdd = -1;
d->datetime_hhmmssmmm = -1;
d->frame_type = -1;
d->freq_range = -1;
d->subcarrier_spacing = -1;
d->cyclic_prefix = -1;
d->symbols_per_slot = -1;
d->Nid_cell = -1;
d->rnti = -1;
d->rb_size = -1;
d->rb_start = -1;
d->start_symbol_index = -1;
d->nr_of_symbols = -1;
d->qam_mod_order = -1;
d->mcs_index = -1;
d->mcs_table = -1;
d->nrOfLayers = -1;
d->transform_precoding = -1;
d->dmrs_config_type = -1;
d->ul_dmrs_symb_pos = -1;
d->number_dmrs_symbols = -1;
d->dmrs_port = -1;
d->dmrs_nscid = -1;
d->nb_antennas_rx = -1;
d->number_of_bits = -1;
d->data = -1;
/* this macro looks for a particular element and checks its type */
#define G(var_name, var_type, var) \
if (!strcmp(f.name[i], var_name)) { \
if (strcmp(f.type[i], var_type)) { \
printf("Error: Trace Message has a bad type for %s\n", var_name); \
exit(1); \
} \
var = i; \
continue; \
}
/* ------------------------------*/
/* Create Macro for Data Collection Trace Message */
/* ------------------------------*/
// Data Collection Trace Message Structure
// Example: GNB_PHY_UL_FD_PUSCH_IQ, GNB_PHY_UL_FD_DMRS_ID,
// GNB_PHY_UL_FD_CHAN_EST_DMRS_POS, GNB_PHY_UL_FD_CHAN_EST_DMRS_INTERPL
// GNB_PHY_UL_PAYLOAD_RX_BITS
// UE_PHY_UL_SCRAMBLED_TX_BITS
// UE_PHY_UL_PAYLOAD_TX_BITS
// Get a template of any message based on Data Collection Trace Messages Structure
int Trace_MSG_ID = event_id_from_name(database, "GNB_PHY_UL_FD_PUSCH_IQ");
f = get_format(database, Trace_MSG_ID);
/* get the elements of the trace
* the value is an index in the event, see below */
// FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm :
// int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot :
// int,Nid_cell : int,rnti :
// int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols :
// int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers :
// int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols :
// int,dmrs_port : int,dmrs_nscid :
// int,nb_antennas_rx : int,number_of_bits : buffer,data
for (i = 0; i < f.count; i++) {
G("frame", "int", d->frame)
G("slot", "int", d->slot)
G("datetime_yyyymmdd", "int", d->datetime_yyyymmdd)
G("datetime_hhmmssmmm", "int", d->datetime_hhmmssmmm)
G("frame_type", "int", d->frame_type)
G("freq_range", "int", d->freq_range)
G("subcarrier_spacing", "int", d->subcarrier_spacing)
G("cyclic_prefix", "int", d->cyclic_prefix)
G("symbols_per_slot", "int", d->symbols_per_slot)
G("Nid_cell", "int", d->Nid_cell)
G("rnti", "int", d->rnti)
G("rb_size", "int", d->rb_size)
G("rb_start", "int", d->rb_start)
G("start_symbol_index", "int", d->start_symbol_index)
G("nr_of_symbols", "int", d->nr_of_symbols)
G("qam_mod_order", "int", d->qam_mod_order)
G("mcs_index", "int", d->mcs_index)
G("mcs_table", "int", d->mcs_table)
G("nrOfLayers", "int", d->nrOfLayers)
G("transform_precoding", "int", d->transform_precoding)
G("dmrs_config_type", "int", d->dmrs_config_type)
G("ul_dmrs_symb_pos", "int", d->ul_dmrs_symb_pos)
G("number_dmrs_symbols", "int", d->number_dmrs_symbols)
G("dmrs_port", "int", d->dmrs_port)
G("dmrs_nscid", "int", d->dmrs_nscid)
G("nb_antennas_rx", "int", d->nb_antennas_rx)
G("number_of_bits", "int", d->number_of_bits)
G("data", "buffer", d->data)
}
// if (d->frame == -1 || d->slot == -1) goto error;
#undef G
return;
}
// Function to check if a value is in the array
int isValueInArray(int value, int arr[], int size)
{
for (int i = 0; i < size; i++) {
if (arr[i] == value) {
return 1; // Value found
}
}
return 0; // Value not found
}
void reestablish_connection(int *socket, char *ip, int port, int number_of_events, int *is_on)
{
clear_remote_config();
if (*socket != -1)
close(*socket);
/* connect to the nr-softmodem */
*socket = connect_to(ip, port);
if (*socket == -1) {
printf("\n Failed to connect to nr-softmodem. Retrying...\n");
return;
}
printf("\n Connected");
/* activate the traces in the nr-softmodem */
activate_traces(*socket, number_of_events, is_on);
printf("\n Activated Traces in nr-softmodem");
}
int main(int n, char **v)
{
// Define and initialize an array of strings to list
// trace_msgs_support_data_Collection_format
// it is used to parse the requested messages if it is based
// on Data Collection Trace Messages Structure and supported tracer messages indices
char *traces_iq_support_data_Collection_format[] = {"GNB_PHY_UL_FD_PUSCH_IQ",
"GNB_PHY_UL_FD_DMRS",
"GNB_PHY_UL_FD_CHAN_EST_DMRS_POS",
"GNB_PHY_UL_FD_CHAN_EST_DMRS_INTERPL"};
char *traces_bits_support_data_Collection_format[] = {"GNB_PHY_UL_PAYLOAD_RX_BITS",
"UE_PHY_UL_SCRAMBLED_TX_BITS",
"UE_PHY_UL_PAYLOAD_TX_BITS"};
// extra number of records to simlify Sync between base station and UE synchronization records.
// if you have network delay, you can increase the number of records to capture
int max_sync_offset = 6; // 6 frames ~ 60 ms
// all supported messages
// Calculate the size of the combined array
int n_iq_msgs = sizeof(traces_iq_support_data_Collection_format) / sizeof(traces_iq_support_data_Collection_format[0]);
int n_bits_msgs = sizeof(traces_bits_support_data_Collection_format) / sizeof(traces_bits_support_data_Collection_format[0]);
int n_msgs_based_data_Collection_format = n_iq_msgs + n_bits_msgs;
// Create the combined array
char *traces_support_data_Collection_format[n_msgs_based_data_Collection_format];
// Copy IQ messages to the combined array
for (int i = 0; i < n_iq_msgs; i++) {
traces_support_data_Collection_format[i] = traces_iq_support_data_Collection_format[i];
}
// Copy Bits messages to the combined array
for (int i = 0; i < n_bits_msgs; i++) {
traces_support_data_Collection_format[i + n_iq_msgs] = traces_bits_support_data_Collection_format[i];
}
uint16_t msg_id = 0;
uint16_t start_frame_number = 0;
uint32_t number_records = 0; // number of records to capture, it is number of slots
// array to store the requested tracer messages indices
int req_tracer_msgs_indices[100] = {0};
// define variables --> to do: add all of them to be class of pointers
char *database_filename = NULL;
void *database;
char *ip = DEFAULT_REMOTE_IP;
char ip_address[16]; // max IP address length is 15 + 1 for null terminator
int port = DEFAULT_REMOTE_PORT;
int *is_on;
int number_of_events;
int i;
int socket = -1;
char trace_time_stamp_str[30];
// data structure for the trace messages based on Data Collection Trace Messages Structure
event_trace_msg_data trace_msg_data;
// initlization variables
unsigned int bufIdx_wr = 0;
unsigned int bufIdx_rd = 0;
uint8_t num_req_tracer_msgs = 0;
// initilaze shared memory
char *addr_wr, *addr_rd;
printf("\n Data Collection Service: Initializing shared memory ...");
printf("\n Directory 1: %s, Directory 2: %s", GETKEYDIR1_gNB, GETKEYDIR2_gNB);
printf("\n Project ID: %d\n", PROJECTID_gNB);
int shm_id_wr = create_shm(&addr_wr, GETKEYDIR1_gNB, PROJECTID_gNB);
int shm_id_rd = create_shm(&addr_rd, GETKEYDIR2_gNB, PROJECTID_gNB);
del_shm(addr_wr, shm_id_wr);
del_shm(addr_rd, shm_id_rd);
shm_id_wr = create_shm(&addr_wr, GETKEYDIR1_gNB, PROJECTID_gNB);
shm_id_rd = create_shm(&addr_rd, GETKEYDIR2_gNB, PROJECTID_gNB);
/* write on a socket fails if the other end is closed and we get SIGPIPE */
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
abort();
/* parse command line options */
// Port number and IP address are given via API and not via command line
for (i = 1; i < n; i++) {
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help"))
usage();
if (!strcmp(v[i], "-d")) {
if (i > n - 2)
usage();
database_filename = v[++i];
continue;
}
if (!strcmp(v[i], "-ip")) {
if (i > n - 2)
usage();
ip = v[++i];
continue;
}
if (!strcmp(v[i], "-p")) {
if (i > n - 2)
usage();
port = atoi(v[++i]);
continue;
}
usage();
}
if (database_filename == NULL) {
printf("ERROR: Provide a database file (-d)\n");
exit(1);
}
/* load the database T_messages.txt */
database = parse_database(database_filename);
load_config_file(database_filename);
/* an array of int for all the events defined in the database is needed */
number_of_events = number_of_ids(database);
is_on = calloc(number_of_events, sizeof(int));
if (is_on == NULL)
abort();
// Set first byte of the shared memory to 0
addr_rd[0] = 0; // important to check if we have new requested messages
// read requested tracer msg indices from memory
printf("\n Data Collection Service: Waiting for messages request ...\n");
// 0: Wait
// 1: config
// 2: record
// 3: stop
// Wait for Action Config
while (1) {
if ((uint8_t)(addr_rd[0]) == 0) {
usleep(50); // sleep for 50 us: 0.5 ms slot duration
}
// config state
else if ((uint8_t)(addr_rd[0]) == 1) {
get_time_stamp_usec(trace_time_stamp_str);
printf("\n Received config message. Time Stamp: %s", trace_time_stamp_str);
// get the IP address length in bytes
bufIdx_rd = 1;
uint8_t ip_address_length = addr_rd[bufIdx_rd];
bufIdx_rd += 1; // + 1 byte = IP address length
// read the IP address
for (int i = 0; i < ip_address_length; i++) {
ip_address[i] = addr_rd[bufIdx_rd];
bufIdx_rd += 1;
}
ip = ip_address;
// get the array bytes of the port number : 2 bytes
uint8_t port_number_bytes[2] = {addr_rd[bufIdx_rd], addr_rd[bufIdx_rd + 1]};
bufIdx_rd += 2; // + 2 bytes = start frame number
port = combine_bytes(port_number_bytes, 2);
printf("\n Parameters: IP Address length: %d, IP Address: %s, Port Number: %d \n", ip_address_length, ip_address, port);
addr_rd[0] = 0; // reset memory : to wait for record action
break;
}
}
// Establish connection to the nr-softmodem
clear_remote_config();
if (socket != -1)
close(socket);
/* connect to the nr-softmodem */
socket = connect_to(ip, port);
printf("\n Connected to nr-softmodem");
// Read Action record or stop
printf("\n Data Collection Service: Waiting for record message ...\n");
while (1) {
// wait for Action record
if ((uint8_t)(addr_rd[0]) == 0) {
usleep(50); // sleep for 50 us: 0.5 ms slot duration
}
// quit state
else if ((uint8_t)(addr_rd[0]) == 3) {
printf("\n Received 'stop' command. Exiting...");
printf("\n ");
// Clean up and exit
break;
}
// record state
else if ((uint8_t)(addr_rd[0]) == 2) {
// clear remote buffer if there is
clear_remote_config();
get_time_stamp_usec(trace_time_stamp_str);
printf("\n Received record message. Time Stamp: %s", trace_time_stamp_str);
// read number of requested messages
bufIdx_rd = 1;
num_req_tracer_msgs = addr_rd[bufIdx_rd];
bufIdx_rd += 1;
printf("\n Number of requested tracer messages: %d,", num_req_tracer_msgs);
// reset memory : action to wait for next record action
addr_rd[0] = 0;
// read tracer msg IDs - every message ID has been stored in two bytes
for (uint8_t msg_n = 0; msg_n < num_req_tracer_msgs; msg_n++) {
// get the array bytes of the tracer message ID: 2 bytes
uint8_t msg_id_bytes[2] = {addr_rd[bufIdx_rd], addr_rd[bufIdx_rd + 1]};
bufIdx_rd += 2; // + 2 bytes = message ID
msg_id = combine_bytes(msg_id_bytes, 2);
req_tracer_msgs_indices[msg_n] = msg_id;
printf(" msg_id: %d, ", msg_id);
}
// get the array bytes of the number of records: 4 bytes
uint8_t number_records_bytes[4] = {addr_rd[bufIdx_rd],
addr_rd[bufIdx_rd + 1],
addr_rd[bufIdx_rd + 2],
addr_rd[bufIdx_rd + 3]};
bufIdx_rd += 4; // + 4 bytes = number of records
number_records = combine_bytes(number_records_bytes, 4);
printf("num_records: %d, ", number_records);
// get the array bytes of the start frame number : 2 bytes
uint8_t start_frame_number_bytes[2] = {addr_rd[bufIdx_rd], addr_rd[bufIdx_rd + 1]};
bufIdx_rd += 2; // + 2 bytes = start frame number
start_frame_number = combine_bytes(start_frame_number_bytes, 2);
printf("start_frame: %d\n", start_frame_number);
/* activate the trace in this array */
printf("\n Activate Tracer messages in on_off array: ");
for (i = 0; i < num_req_tracer_msgs; i++) {
char *on_off_name = event_name_from_id(database, req_tracer_msgs_indices[i]);
on_off(database, on_off_name, is_on, 1);
printf("%d, %s, ", req_tracer_msgs_indices[i], on_off_name);
// on_off(database, "GNB_PHY_DL_OUTPUT_SIGNAL", is_on, 1);
}
// get the event IDs for the bit messages
int traces_bits_support_data_Collection_format_idx[n_bits_msgs];
for (int i = 0; i < n_bits_msgs; i++) {
traces_bits_support_data_Collection_format_idx[i] =
event_id_from_name(database, traces_bits_support_data_Collection_format[i]);
}
// all supported messages
int traces_support_data_Collection_format_idx[n_msgs_based_data_Collection_format];
for (int i = 0; i < n_msgs_based_data_Collection_format; i++) {
traces_support_data_Collection_format_idx[i] = event_id_from_name(database, traces_support_data_Collection_format[i]);
}
// setup data for the trace messages
setup_trace_msg_data(&trace_msg_data, database);
printf("\n Setup Trace Data Done");
// Get the start time
struct timespec start_time = get_current_time();
/* activate the tracee in the nr-softmodem */
activate_traces(socket, number_of_events, is_on);
printf("\n Activated Traces in nr-softmodem");
/* a buffer needed to receive events from the nr-softmodem */
OBUF ebuf = {osize : 0, omaxsize : 0, obuf : NULL};
/* read events */
int nrecord_idx = 0;
bufIdx_wr = 0;
// logic to be sure that we have a complete slot record
bool start_recording = false;
bool got_ref_frame_slot = false;
int ref_slot = 0;
int ref_frame = 0;
int slot_difference = 0;
int frame_difference = 0;
int current_frame = 0, prev_frame = 0, current_slot = 0, prev_slot = 0;
// offset to sync between base station and UE synchronization records or power measurements
int sync_offset_index = 0; // increase the index only if the index of frame changes after getting all records
// since we will use the frame differece to do extra records, we should be sure that the last slot is recorded completely
printf("\n\n Data Collection Service: Start reading messages ...");
struct pollfd event_poll_fd;
event_poll_fd.fd = socket;
event_poll_fd.events = POLLIN;
while (1) {
// stop if number of records is done
if ((nrecord_idx >= number_records) && (sync_offset_index >= max_sync_offset)) {
// We added one to the number of records to capture the last record completely if
// we have several messages enabled per slot
break;
}
int poll_ret = poll(&event_poll_fd, 1, 1); // 1 ms timeout for poll
if (poll_ret > 0 && (event_poll_fd.revents & POLLIN)) {
event e = get_event(socket, &ebuf, database);
if (e.type == -1) {
printf("\n Link broken or unexpected message received. Re-establishing connection...\n");
reestablish_connection(&socket, ip, port, number_of_events, is_on);
continue; // Skip further processing and retry
}
//-------------------------
// GNB_PHY_UL_FD_PUSCH_IQ, GNB_PHY_UL_FD_DMRS_ID, GNB_PHY_UL_FD_CHAN_EST_DMRS_POS,
// UE_PHY_UL_SCRAMBLED_TX_BITS, GNB_PHY_UL_PAYLOAD_RX_BITS, UE_PHY_UL_PAYLOAD_TX_BITS
//-------------------------
// is it a requested message
if (isValueInArray(e.type, req_tracer_msgs_indices, num_req_tracer_msgs)) {
// is it based on Data Collection Trace Messages Structure
if (isValueInArray(e.type, traces_support_data_Collection_format_idx, n_msgs_based_data_Collection_format)) {
// Start recording from the next slot to mitigate capturing partial data
// check if the current frame and slot are different from the previous frame and slot
// Then, increase the record index
if (start_recording == false) {
if (got_ref_frame_slot == false) {
ref_frame = e.e[trace_msg_data.frame].i;
ref_slot = e.e[trace_msg_data.slot].i;
printf("\nMessage Info: msg_id %s (%d) \n", event_name_from_id(database, e.type), e.type);
got_ref_frame_slot = true;
}
current_frame = e.e[trace_msg_data.frame].i;
current_slot = e.e[trace_msg_data.slot].i;
frame_difference = (current_frame - ref_frame + MAX_FRAME_INDEX + 1) % (MAX_FRAME_INDEX + 1);
slot_difference = (current_slot - ref_slot + MAX_SLOT_INDEX + 1) % (MAX_SLOT_INDEX + 1);
printf("\n First frame.slot: %d.%d, current frame.slot: %d.%d, diff frame.slot: %d.%d",
ref_frame,
ref_slot,
current_frame,
current_slot,
frame_difference,
slot_difference);
if ((ref_frame != current_frame) || (ref_slot != current_slot)) {
start_recording = true;
printf("\n Start recording from frame: %d, slot: %d ", e.e[trace_msg_data.frame].i, e.e[trace_msg_data.slot].i);
}
}
// start recording from the next frame to mitigate capturing partial data
if (start_recording == true) {
/* this is how to access the elements of the Data Collection trace messages.
* we use e.e[<element>] and then the correct suffix, here
* it's .i for the integer and .b for the buffer and .bsize for the buffer size
* see in event.h the structure event_arg
*/
unsigned char *buf = e.e[trace_msg_data.data].b;
printf("\n\nRecord number: %d", nrecord_idx);
#ifdef DEBUG_BUFFER
printf("\nBuffer index in bytes: %d", bufIdx_wr);
#endif
// add general message header: message ID,
// T-Tracer Message format
// FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm :
// int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot :
// int,Nid_cell : int,rnti :
// int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols :
// int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers :
// int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols :
// int,dmrs_port : int,dmrs_nscid :
// int,nb_antennas_rx : int,number_of_bits : buffer,data
memcpy(&addr_wr[bufIdx_wr], &e.type, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.frame].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.slot].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.datetime_yyyymmdd].i, sizeof(uint32_t));
bufIdx_wr += sizeof(uint32_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.datetime_hhmmssmmm].i, sizeof(uint32_t));
bufIdx_wr += sizeof(uint32_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.frame_type].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.freq_range].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.subcarrier_spacing].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.cyclic_prefix].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.symbols_per_slot].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.Nid_cell].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.rnti].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.rb_size].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.rb_start].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.start_symbol_index].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.nr_of_symbols].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.qam_mod_order].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.mcs_index].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.mcs_table].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.nrOfLayers].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.transform_precoding].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.dmrs_config_type].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.ul_dmrs_symb_pos].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.number_dmrs_symbols].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.dmrs_port].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.dmrs_nscid].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.nb_antennas_rx].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.number_of_bits].i, sizeof(uint32_t));
bufIdx_wr += sizeof(uint32_t);
printf("\nTime Stamp: %d_%d", e.e[trace_msg_data.datetime_yyyymmdd].i, e.e[trace_msg_data.datetime_hhmmssmmm].i);
// add message body: length in bytes + recorded data
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.data].bsize, sizeof(uint32_t));
bufIdx_wr += sizeof(uint32_t);
// read data from buffer and convert from unsigned char * array to int 16 using the right endianness
// T-tracer: Little Endian
// For BITS Messages, example: UE_PHY_UL_SCRAMBLED_TX_BITS: data in bytes
if (is_bits_messages(traces_bits_support_data_Collection_format_idx, n_bits_msgs, e.type)) {
for (int byte_idx = 0; byte_idx < e.e[trace_msg_data.data].bsize; byte_idx += 1) {
// printf("%d, ", buf[byte_idx]);
memcpy(&addr_wr[bufIdx_wr], &buf[byte_idx], sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
}
} else {
for (int byte_idx = 0; byte_idx < e.e[trace_msg_data.data].bsize; byte_idx += 2) {
// For a little-endian system:
memcpy(&addr_wr[bufIdx_wr], &buf[byte_idx], sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &buf[byte_idx + 1], sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
}
}
/*
for (int byte_idx_i = 0; byte_idx_i < e.e[d.nr_ul_fd_dmrs_data].bsize; byte_idx_i+=4) {
int16_t I = buf[byte_idx_i] | (buf[byte_idx_i+1] << 8);
int16_t Q = buf[byte_idx_i+2] | (buf[byte_idx_i+3] << 8);
printf ("idx %d, ", byte_idx_i);
printf ("\n%d", I);
printf ("\n%d", Q);
}
*/
// check if the current frame and slot are different from the previous frame and slot
// Then, increase the record index
current_frame = e.e[trace_msg_data.frame].i;
current_slot = e.e[trace_msg_data.slot].i;
// increase sync offset index if the current frame is different from the previous frame
if ((current_frame != prev_frame) && nrecord_idx >= number_records) {
sync_offset_index++;
}
if (current_frame != prev_frame || current_slot != prev_slot) {
nrecord_idx++;
// Update previous frame and slot numbers
prev_frame = current_frame;
prev_slot = current_slot;
}
#ifdef DEBUG_T_Tracer
printf("\nMessage Info: msg_id %s (%d) \n", event_name_from_id(database, e.type), e.type);
printf("frame %d, slot %d, datetime %d_%d\n",
e.e[trace_msg_data.frame].i,
e.e[trace_msg_data.slot].i,
e.e[trace_msg_data.datetime_yyyymmdd].i,
e.e[trace_msg_data.datetime_hhmmssmmm].i);
printf("frame_type %d, freq_range %d, subcarrier_spacing %d, cyclic_prefix %d, symbols_per_slot %d\n",
e.e[trace_msg_data.frame_type].i,
e.e[trace_msg_data.freq_range].i,
e.e[trace_msg_data.subcarrier_spacing].i,
e.e[trace_msg_data.cyclic_prefix].i,
e.e[trace_msg_data.symbols_per_slot].i);
printf("Nid_cell %d, rnti %d, rb_size %d, rb_start %d, start_symbol_index %d, nr_of_symbols %d\n",
e.e[trace_msg_data.Nid_cell].i,
e.e[trace_msg_data.rnti].i,
e.e[trace_msg_data.rb_size].i,
e.e[trace_msg_data.rb_start].i,
e.e[trace_msg_data.start_symbol_index].i,
e.e[trace_msg_data.nr_of_symbols].i);
printf("qam_mod_order %d, mcs_index %d, mcs_table %d, nrOfLayers %d, transform_precoding %d\n",
e.e[trace_msg_data.qam_mod_order].i,
e.e[trace_msg_data.mcs_index].i,
e.e[trace_msg_data.mcs_table].i,
e.e[trace_msg_data.nrOfLayers].i,
e.e[trace_msg_data.transform_precoding].i);
printf("dmrs_config_type %d, ul_dmrs_symb_pos %d, number_dmrs_symbols %d, dmrs_port %d, dmrs_nscid %d\n",
e.e[trace_msg_data.dmrs_config_type].i,
e.e[trace_msg_data.ul_dmrs_symb_pos].i,
e.e[trace_msg_data.number_dmrs_symbols].i,
e.e[trace_msg_data.dmrs_port].i,
e.e[trace_msg_data.dmrs_nscid].i);
printf("nb_antennas_rx %d, number_of_bits %d, data size %d\n",
e.e[trace_msg_data.nb_antennas_rx].i,
e.e[trace_msg_data.number_of_bits].i,
e.e[trace_msg_data.data].bsize);
#endif
} // End of start recording flag
} // end of if statement for the supported messages based on Data Collection Trace Messages Structure
else {
printf("ERROR: Requested Message is not based on Data Collection Trace Messages Structure\n");
printf("ERROR: Requested Message ID: %d\n", e.type);
}
} // end of if statement for the requested messages
} // end while loop of reading events
else {
// No data, just loop and check time
usleep(100); // optional: avoid busy-waiting
}
} // End of while loop to read events
// de-activate the tracee in the nr-softmodem
printf("\n De-activated Tracer message:\n");
for (i = 0; i < num_req_tracer_msgs; i++) {
char *on_off_name = event_name_from_id(database, req_tracer_msgs_indices[i]);
on_off(database, on_off_name, is_on, 0);
// printf("\n %d, %s, ", req_tracer_msgs_indices[i], on_off_name);
// on_off(database, "GNB_PHY_DL_OUTPUT_SIGNAL", is_on, 1);
}
// De-activate the tracee in the nr-softmodem
activate_traces(socket, number_of_events, is_on);
printf("\n De-activated Traces");
// Get the end time
struct timespec end_time = get_current_time();
// Calculate the time difference
double time_diff = calculate_time_difference(start_time, end_time);
printf("Total Time difference: %.2f ms\n", time_diff);
printf("Time difference per record: %.2f ms\n", time_diff / (number_records + max_sync_offset));
// discard stale or previous record data for the first DISCARD_RECORD_DURATION_MS
struct timespec record_start, record_now;
clock_gettime(CLOCK_MONOTONIC, &record_start);
while (1) {
clock_gettime(CLOCK_MONOTONIC, &record_now);
double elapsed_ms = calculate_time_difference(record_start, record_now);
if (elapsed_ms >= DISCARD_RECORD_DURATION_MS) {
break; // Stop after 10ms
}
int poll_ret = poll(&event_poll_fd, 1, 1); // 1 ms timeout for poll
if (poll_ret > 0 && (event_poll_fd.revents & POLLIN)) {
event e = get_event(socket, &ebuf, database);
printf("%d", e.type);
if (e.type == -1) {
printf("\n Link broken or unexpected message received. Re-establishing connection...\n");
reestablish_connection(&socket, ip, port, number_of_events, is_on);
continue;
}
} else {
// No data, just loop and check time
usleep(100); // optional: avoid busy-waiting
}
} // End of while loop to discard stale records
}
} // End a while loop to check for the "stop" command
// de-activate the tracee in the nr-softmodem
free_database(database);
free(is_on);
close(socket);
return 0;
}

View File

@@ -1,976 +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
*/
/*! \file common/utils/T/tracer/t_tracer_app_ue.c
* \brief T-Tracer UE service to capture tracee Messages from UE, it is used by data recording application
* \author Abdo Gaber
* \date 2025
* \version 1.0
* \company Emerson, NI Test and Measurement
* \email:
* \note
* \warning
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>
#include "database.h"
#include "event.h"
#include "handler.h"
#include "logger/logger.h"
#include "utils.h"
#include "event_selector.h"
#include "configuration.h"
#include "shared_memory_config.h"
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <poll.h>
#define MAX_FRAME_INDEX 1023
#define MAX_SLOT_INDEX 19
#define DEBUG_T_Tracer
#define DEBUG_BUFFER
// Duration to discard recording in milliseconds to mitigate stale or previous record data
#define DISCARD_RECORD_DURATION_MS 10
// #include <linux/time.h>
// Combine bytes in little-endian format
int combine_bytes(const uint8_t *bytes, size_t num_bytes)
{
int result = 0;
for (size_t i = 0; i < num_bytes; ++i) {
result |= (bytes[i] << (i * 8));
}
return result;
}
// Convert an integer to an array of bytes in little-endian format
void int_to_bytes(int num, uint8_t *bytes, size_t num_bytes)
{
for (size_t i = 0; i < num_bytes; ++i) {
bytes[i] = (num >> (i * 8)) & 0xFF;
}
}
// Check if the message is in the list of bits messages
bool is_bits_messages(int traces_bits_support_data_Collection_format_idx[], int n_bits_msgs, int msg_id)
{
for (int i = 0; i < n_bits_msgs; i++) {
if (msg_id == traces_bits_support_data_Collection_format_idx[i]) {
return true;
}
}
return false;
}
// Get the current time
struct timespec get_current_time()
{
struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
return time;
}
// Function to convert timespec to microseconds
long long timespec_to_microseconds(struct timespec time)
{
return (time.tv_sec * 1000000LL) + (time.tv_nsec / 1000);
}
// Calculate the time difference in milliseconds
double calculate_time_difference(struct timespec start, struct timespec end)
{
double start_ms = start.tv_sec * 1000.0 + start.tv_nsec / 1000000.0;
double end_ms = end.tv_sec * 1000.0 + end.tv_nsec / 1000000.0;
return end_ms - start_ms;
}
// Get Time Stamp in microseconds in YYYYMMDDHHMMSSmmmuuu format
char *get_time_stamp_usec(char time_stamp_str[])
{
// initialization to measure time stamp --This part should be moved to inilization part
time_t my_time;
struct tm *timeinfo;
time(&my_time);
struct timeval tv;
// get time stamp
timeinfo = localtime(&my_time);
gettimeofday(&tv, NULL);
// Add time stamp: yyyy mm dd hh mm ss usec
uint16_t year = timeinfo->tm_year + 1900;
uint8_t mon = timeinfo->tm_mon + 1;
uint8_t mday = timeinfo->tm_mday;
uint8_t hour = timeinfo->tm_hour;
uint8_t min = timeinfo->tm_min;
uint8_t sec = timeinfo->tm_sec;
uint16_t usec = (tv.tv_usec);
// printf ("Time stamp: %d_%d_%d_%d_%d_%d_%d \n",year,mon,mday,hour,min,sec,usec);
// sprintf(time_stamp_str, "%d_%d_%d_%d_%d_%d_%d",year,mon,mday,hour,min,sec,usec);
sprintf(time_stamp_str, "%04d%02d%02d%02d%02d%02d%06d", year, mon, mday, hour, min, sec, usec);
return time_stamp_str;
}
// Convert timestamp string to integer
int convert_time_stamp_to_int(const char *timestamp)
{
return atoi(timestamp);
}
// Split timestamp string and convert to integer
int split_time_stamp_and_convert_to_int(char time_stamp_str[], int shift, int length)
{
char time_part[length + 1]; // Buffer to hold the date part YYYYMMDD or HHMMSSmmm
// Copy the first 8 or 9 characters (YYYYMMDD) to HHMMSSmmm
strncpy(time_part, time_stamp_str + shift, length);
time_part[length] = '\0'; // Null-terminate the string
// Convert timestamp string to integer
return convert_time_stamp_to_int(time_part);
}
void err_exit(char *buf)
{
fprintf(stderr, "%s\n", buf);
exit(1);
}
// create shared memory
int create_shm(char **addrN, const char *shm_path, int projectId)
{
key_t key;
if (-1 != open(shm_path, O_CREAT, 0777)) {
key = ftok(shm_path, projectId);
} else {
err_exit("Error: open shared memory");
}
if (key < 0) {
err_exit("Error: ftok error");
}
int shm_id;
shm_id = shmget(key, SHMSIZE, IPC_CREAT | IPC_EXCL | 0664);
if (shm_id == -1) {
if (errno == EEXIST) {
printf("Error: shared memeory already exist\n");
shm_id = shmget(key, 0, 0);
printf("reference shm_id = %d\n", shm_id);
} else {
perror("errno");
err_exit("shmget error");
}
}
char *addr;
// address to attach - attach for read & write
if ((addr = shmat(shm_id, 0, 0)) == (void *)-1) {
if (shmctl(shm_id, IPC_RMID, NULL) == -1)
err_exit("Error: shmctl error");
else {
printf("Attach shared memory failed\n");
printf("remove shared memory identifier successful\n");
}
err_exit("shmat error");
}
*addrN = addr;
return shm_id;
}
// delete shared memory
void del_shm(char *addr, int shm_id)
{
if (shmdt(addr) < 0)
err_exit("shmdt error");
if (shmctl(shm_id, IPC_RMID, NULL) == -1)
err_exit("shmctl error");
else {
printf("Remove shared memory identifier successful\n");
}
}
/* this function sends the activated traces to the nr-softmodem */
void activate_traces(int socket, int number_of_events, int *is_on)
{
char t = 1;
if (socket_send(socket, &t, 1) == -1 || socket_send(socket, &number_of_events, sizeof(int)) == -1
|| socket_send(socket, is_on, number_of_events * sizeof(int)) == -1)
abort();
}
void usage(void)
{
printf(
"options:\n"
" -d <database file> this option is mandatory\n"
" -ip <host> connect to given IP address (default %s)\n"
" -p <port> connect to given port (default %d)\n",
DEFAULT_REMOTE_IP,
DEFAULT_REMOTE_PORT);
exit(1);
}
// class to store the message and the action to enable capture selected data
// 0: do not record message
// 1: record message
struct trace_struct {
char on_off_name[100];
int on_off_action;
};
// struct for trace message based on Data Collection Trace Messages Structure
// you need to define the vararibles of each message
typedef struct {
/* Data Collection Trace Message Structure */
int frame;
int slot;
int datetime_yyyymmdd;
int datetime_hhmmssmmm;
int frame_type, freq_range, subcarrier_spacing, cyclic_prefix, symbols_per_slot;
int Nid_cell, rnti;
int rb_size, rb_start, start_symbol_index, nr_of_symbols;
int qam_mod_order, mcs_index, mcs_table, nrOfLayers, transform_precoding;
int dmrs_config_type, ul_dmrs_symb_pos, number_dmrs_symbols;
int dmrs_port, dmrs_nscid, nb_antennas_tx, number_of_bits;
int data_size, data;
} event_trace_msg_data;
void setup_trace_msg_data(event_trace_msg_data *d, void *database)
{
database_event_format f;
int i;
/* Data Collection Trace Message Structure */
// FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm :
// int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot :
// int,Nid_cell : int,rnti :
// int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols :
// int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers :
// int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols :
// int,dmrs_port : int,dmrs_nscid :
// int,nb_antennas_tx : int,number_of_bits : buffer,data
// Initialize the data structure
d->frame = -1;
d->slot = -1;
d->datetime_yyyymmdd = -1;
d->datetime_hhmmssmmm = -1;
d->frame_type = -1;
d->freq_range = -1;
d->subcarrier_spacing = -1;
d->cyclic_prefix = -1;
d->symbols_per_slot = -1;
d->Nid_cell = -1;
d->rnti = -1;
d->rb_size = -1;
d->rb_start = -1;
d->start_symbol_index = -1;
d->nr_of_symbols = -1;
d->qam_mod_order = -1;
d->mcs_index = -1;
d->mcs_table = -1;
d->nrOfLayers = -1;
d->transform_precoding = -1;
d->dmrs_config_type = -1;
d->ul_dmrs_symb_pos = -1;
d->number_dmrs_symbols = -1;
d->dmrs_port = -1;
d->dmrs_nscid = -1;
d->nb_antennas_tx = -1;
d->number_of_bits = -1;
d->data = -1;
/* this macro looks for a particular element and checks its type */
#define G(var_name, var_type, var) \
if (!strcmp(f.name[i], var_name)) { \
if (strcmp(f.type[i], var_type)) { \
printf("Error: Trace Message has a bad type for %s\n", var_name); \
exit(1); \
} \
var = i; \
continue; \
}
/* ------------------------------*/
/* Create Macro for Data Collection Trace Message */
/* ------------------------------*/
// Data Collection Trace Message Structure
// Example: GNB_PHY_UL_FD_PUSCH_IQ, GNB_PHY_UL_FD_DMRS_ID,
// GNB_PHY_UL_FD_CHAN_EST_DMRS_POS, GNB_PHY_UL_FD_CHAN_EST_DMRS_INTERPL
// GNB_PHY_UL_PAYLOAD_RX_BITS
// UE_PHY_UL_SCRAMBLED_TX_BITS
// UE_PHY_UL_PAYLOAD_TX_BITS
// Get a template of any message based on Data Collection Trace Messages Structure
int Trace_MSG_ID = event_id_from_name(database, "GNB_PHY_UL_FD_PUSCH_IQ");
f = get_format(database, Trace_MSG_ID);
/* get the elements of the trace
* the value is an index in the event, see below */
// FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm :
// int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot :
// int,Nid_cell : int,rnti :
// int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols :
// int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers :
// int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols :
// int,dmrs_port : int,dmrs_nscid :
// int,nb_antennas_tx : int,number_of_bits : buffer,data
for (i = 0; i < f.count; i++) {
G("frame", "int", d->frame)
G("slot", "int", d->slot)
G("datetime_yyyymmdd", "int", d->datetime_yyyymmdd)
G("datetime_hhmmssmmm", "int", d->datetime_hhmmssmmm)
G("frame_type", "int", d->frame_type)
G("freq_range", "int", d->freq_range)
G("subcarrier_spacing", "int", d->subcarrier_spacing)
G("cyclic_prefix", "int", d->cyclic_prefix)
G("symbols_per_slot", "int", d->symbols_per_slot)
G("Nid_cell", "int", d->Nid_cell)
G("rnti", "int", d->rnti)
G("rb_size", "int", d->rb_size)
G("rb_start", "int", d->rb_start)
G("start_symbol_index", "int", d->start_symbol_index)
G("nr_of_symbols", "int", d->nr_of_symbols)
G("qam_mod_order", "int", d->qam_mod_order)
G("mcs_index", "int", d->mcs_index)
G("mcs_table", "int", d->mcs_table)
G("nrOfLayers", "int", d->nrOfLayers)
G("transform_precoding", "int", d->transform_precoding)
G("dmrs_config_type", "int", d->dmrs_config_type)
G("ul_dmrs_symb_pos", "int", d->ul_dmrs_symb_pos)
G("number_dmrs_symbols", "int", d->number_dmrs_symbols)
G("dmrs_port", "int", d->dmrs_port)
G("dmrs_nscid", "int", d->dmrs_nscid)
// bug in T-Tracer Framework, need to be checked that is why we are getting
// the right tx antennas only if we set to rx "nb_antennas_rx"
G("nb_antennas_rx", "int", d->nb_antennas_tx)
G("number_of_bits", "int", d->number_of_bits)
G("data", "buffer", d->data)
}
// if (d->frame == -1 || d->slot == -1) goto error;
#undef G
return;
}
// Function to check if a value is in the array
int isValueInArray(int value, int arr[], int size)
{
for (int i = 0; i < size; i++) {
if (arr[i] == value) {
return 1; // Value found
}
}
return 0; // Value not found
}
void reestablish_connection(int *socket, char *ip, int port, int number_of_events, int *is_on)
{
clear_remote_config();
if (*socket != -1)
close(*socket);
/* connect to the nr-softmodem */
*socket = connect_to(ip, port);
if (*socket == -1) {
printf("\n Failed to connect to nr-softmodem. Retrying...\n");
return;
}
printf("\n Connected");
/* activate the traces in the nr-softmodem */
activate_traces(*socket, number_of_events, is_on);
printf("\n Activated Traces in nr-softmodem");
}
int main(int n, char **v)
{
// Define and initialize an array of strings to list
// trace_msgs_support_data_Collection_format
// it is used to parse the requested messages if it is based
// on Data Collection Trace Messages Structure and supported tracer messages indices
char *traces_iq_support_data_Collection_format[] = {"GNB_PHY_UL_FD_PUSCH_IQ",
"GNB_PHY_UL_FD_DMRS",
"GNB_PHY_UL_FD_CHAN_EST_DMRS_POS",
"GNB_PHY_UL_FD_CHAN_EST_DMRS_INTERPL"};
char *traces_bits_support_data_Collection_format[] = {"GNB_PHY_UL_PAYLOAD_RX_BITS",
"UE_PHY_UL_SCRAMBLED_TX_BITS",
"UE_PHY_UL_PAYLOAD_TX_BITS"};
// extra number of records to simlify Sync between base station and UE synchronization records.
// if you have network delay, you can increase the number of records to capture
int max_sync_offset = 6; // 6 frames ~ 60 ms
// all supported messages
// Calculate the size of the combined array
int n_iq_msgs = sizeof(traces_iq_support_data_Collection_format) / sizeof(traces_iq_support_data_Collection_format[0]);
int n_bits_msgs = sizeof(traces_bits_support_data_Collection_format) / sizeof(traces_bits_support_data_Collection_format[0]);
int n_msgs_based_data_Collection_format = n_iq_msgs + n_bits_msgs;
// Create the combined array
char *traces_support_data_Collection_format[n_msgs_based_data_Collection_format];
// Copy IQ messages to the combined array
for (int i = 0; i < n_iq_msgs; i++) {
traces_support_data_Collection_format[i] = traces_iq_support_data_Collection_format[i];
}
// Copy Bits messages to the combined array
for (int i = 0; i < n_bits_msgs; i++) {
traces_support_data_Collection_format[i + n_iq_msgs] = traces_bits_support_data_Collection_format[i];
}
uint16_t msg_id = 0;
uint16_t start_frame_number = 0;
uint32_t number_records = 0; // number of records to capture, it is number of slots
// array to store the requested tracer messages indices
int req_tracer_msgs_indices[100] = {0};
// define variables --> to do: add all of them to be class of pointers
char *database_filename = NULL;
void *database;
char *ip = DEFAULT_REMOTE_IP;
char ip_address[16]; // max IP address length is 15 + 1 for null terminator
int port = DEFAULT_REMOTE_PORT;
int *is_on;
int number_of_events;
int i;
int socket = -1;
char trace_time_stamp_str[30];
// data structure for the trace messages based on Data Collection Trace Messages Structure
event_trace_msg_data trace_msg_data;
// initlization variables
unsigned int bufIdx_wr = 0;
unsigned int bufIdx_rd = 0;
uint8_t num_req_tracer_msgs = 0;
// initilaze shared memory
char *addr_wr, *addr_rd;
printf("\n Data Collection Service: Initializing shared memory ...");
printf("\n Directory 1: %s, Directory 2: %s", GETKEYDIR1_UE, GETKEYDIR2_UE);
printf("\n Project ID: %d\n", PROJECTID_UE);
int shm_id_wr = create_shm(&addr_wr, GETKEYDIR1_UE, PROJECTID_UE);
int shm_id_rd = create_shm(&addr_rd, GETKEYDIR2_UE, PROJECTID_UE);
del_shm(addr_wr, shm_id_wr);
del_shm(addr_rd, shm_id_rd);
shm_id_wr = create_shm(&addr_wr, GETKEYDIR1_UE, PROJECTID_UE);
shm_id_rd = create_shm(&addr_rd, GETKEYDIR2_UE, PROJECTID_UE);
/* write on a socket fails if the other end is closed and we get SIGPIPE */
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
abort();
/* parse command line options */
// Port number and IP address are given via API and not via command line
for (i = 1; i < n; i++) {
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help"))
usage();
if (!strcmp(v[i], "-d")) {
if (i > n - 2)
usage();
database_filename = v[++i];
continue;
}
if (!strcmp(v[i], "-ip")) {
if (i > n - 2)
usage();
ip = v[++i];
continue;
}
if (!strcmp(v[i], "-p")) {
if (i > n - 2)
usage();
port = atoi(v[++i]);
continue;
}
usage();
}
if (database_filename == NULL) {
printf("ERROR: Provide a database file (-d)\n");
exit(1);
}
/* load the database T_messages.txt */
database = parse_database(database_filename);
load_config_file(database_filename);
/* an array of int for all the events defined in the database is needed */
number_of_events = number_of_ids(database);
is_on = calloc(number_of_events, sizeof(int));
if (is_on == NULL)
abort();
// Set first byte of the shared memory to 0
addr_rd[0] = 0; // important to check if we have new requested messages
// read requested tracer msg indices from memory
printf("\n Data Collection Service: Waiting for messages request ...\n");
// 0: Wait
// 1: config
// 2: record
// 3: stop
// Wait for Action Config
while (1) {
if ((uint8_t)(addr_rd[0]) == 0) {
usleep(50); // sleep for 50 us: 0.5 ms slot duration
}
// config state
else if ((uint8_t)(addr_rd[0]) == 1) {
get_time_stamp_usec(trace_time_stamp_str);
printf("\n Received config message. Time Stamp: %s", trace_time_stamp_str);
// get the IP address length in bytes
bufIdx_rd = 1;
uint8_t ip_address_length = addr_rd[bufIdx_rd];
bufIdx_rd += 1; // + 1 byte = IP address length
// read the IP address
for (int i = 0; i < ip_address_length; i++) {
ip_address[i] = addr_rd[bufIdx_rd];
bufIdx_rd += 1;
}
ip = ip_address;
// get the array bytes of the port number : 2 bytes
uint8_t port_number_bytes[2] = {addr_rd[bufIdx_rd], addr_rd[bufIdx_rd + 1]};
bufIdx_rd += 2; // + 2 bytes = start frame number
port = combine_bytes(port_number_bytes, 2);
printf("\n Parameters: IP Address length: %d, IP Address: %s, Port Number: %d \n", ip_address_length, ip_address, port);
addr_rd[0] = 0; // reset memory : to wait for record action
break;
}
}
// Establish connection to the nr-softmodem
clear_remote_config();
if (socket != -1)
close(socket);
/* connect to the nr-softmodem */
socket = connect_to(ip, port);
printf("\n Connected to nr-UEsoftmodem");
// Read Action record or stop
printf("\n Data Collection Service: Waiting for record message ...\n");
while (1) {
// wait for Action record
if ((uint8_t)(addr_rd[0]) == 0) {
usleep(50); // sleep for 50 us: 0.5 ms slot duration
}
// quit state
else if ((uint8_t)(addr_rd[0]) == 3) {
printf("\n Received 'stop' command. Exiting...");
printf("\n ");
// Clean up and exit
break;
}
// record state
else if ((uint8_t)(addr_rd[0]) == 2) {
// clear remote buffer if there is
clear_remote_config();
get_time_stamp_usec(trace_time_stamp_str);
printf("\n Received record message. Time Stamp: %s", trace_time_stamp_str);
// read number of requested messages
bufIdx_rd = 1;
num_req_tracer_msgs = addr_rd[bufIdx_rd];
bufIdx_rd += 1;
printf("\n Number of requested tracer messages: %d,", num_req_tracer_msgs);
// reset memory : action to wait for next record action
addr_rd[0] = 0;
// read tracer msg IDs - every message ID has been stored in two bytes
for (uint8_t msg_n = 0; msg_n < num_req_tracer_msgs; msg_n++) {
// get the array bytes of the tracer message ID: 2 bytes
uint8_t msg_id_bytes[2] = {addr_rd[bufIdx_rd], addr_rd[bufIdx_rd + 1]};
bufIdx_rd += 2; // + 2 bytes = message ID
msg_id = combine_bytes(msg_id_bytes, 2);
req_tracer_msgs_indices[msg_n] = msg_id;
printf(" msg_id: %d, ", msg_id);
}
// get the array bytes of the number of records: 4 bytes
uint8_t number_records_bytes[4] = {addr_rd[bufIdx_rd],
addr_rd[bufIdx_rd + 1],
addr_rd[bufIdx_rd + 2],
addr_rd[bufIdx_rd + 3]};
bufIdx_rd += 4; // + 4 bytes = number of records
number_records = combine_bytes(number_records_bytes, 4);
printf("num_records: %d, ", number_records);
// get the array bytes of the start frame number : 2 bytes
uint8_t start_frame_number_bytes[2] = {addr_rd[bufIdx_rd], addr_rd[bufIdx_rd + 1]};
bufIdx_rd += 2; // + 2 bytes = start frame number
start_frame_number = combine_bytes(start_frame_number_bytes, 2);
printf("start_frame: %d\n", start_frame_number);
/* activate the trace in this array */
printf("\n Activate Tracer messages in on_off array: \n");
for (i = 0; i < num_req_tracer_msgs; i++) {
char *on_off_name = event_name_from_id(database, req_tracer_msgs_indices[i]);
on_off(database, on_off_name, is_on, 1);
printf("%d, %s, ", req_tracer_msgs_indices[i], on_off_name);
// on_off(database, "GNB_PHY_DL_OUTPUT_SIGNAL", is_on, 1);
}
// get the event IDs for the bit messages
int traces_bits_support_data_Collection_format_idx[n_bits_msgs];
for (int i = 0; i < n_bits_msgs; i++) {
traces_bits_support_data_Collection_format_idx[i] =
event_id_from_name(database, traces_bits_support_data_Collection_format[i]);
}
// all supported messages
int traces_support_data_Collection_format_idx[n_msgs_based_data_Collection_format];
for (int i = 0; i < n_msgs_based_data_Collection_format; i++) {
traces_support_data_Collection_format_idx[i] = event_id_from_name(database, traces_support_data_Collection_format[i]);
}
// setup data for the trace messages
setup_trace_msg_data(&trace_msg_data, database);
printf("\n Setup Trace Data Done");
// Get the start time
struct timespec start_time = get_current_time();
/* activate the tracee in the nr-softmodem */
activate_traces(socket, number_of_events, is_on);
printf("\n Activated Traces in nr-UEsoftmodem");
/* a buffer needed to receive events from the nr-softmodem */
OBUF ebuf = {osize : 0, omaxsize : 0, obuf : NULL};
/* read events */
int nrecord_idx = 0;
bufIdx_wr = 0;
// logic to be sure that we have a complete slot record
bool start_recording = false;
bool got_ref_frame_slot = false;
int ref_slot = 0;
int ref_frame = 0;
int slot_difference = 0;
int frame_difference = 0;
int current_frame = 0, prev_frame = 0, current_slot = 0, prev_slot = 0;
// offset to sync between base station and UE synchronization records or power measurements
int sync_offset_index = 0; // increase the index only if the index of frame changes after getting all records
// since we will use the frame differece to do extra records, we should be sure that the last slot is recorded completely
printf("\n\n Data Collection Service: Start reading messages ...");
struct pollfd event_poll_fd;
event_poll_fd.fd = socket;
event_poll_fd.events = POLLIN;
while (1) {
// stop if number of records is done
if ((nrecord_idx >= number_records) && (sync_offset_index >= max_sync_offset)) {
// We added one to the number of records to capture the last record completely
// if we have several messages enabled per slot
break;
}
int poll_ret = poll(&event_poll_fd, 1, 1); // 1 ms timeout for poll
if (poll_ret > 0 && (event_poll_fd.revents & POLLIN)) {
event e = get_event(socket, &ebuf, database);
if (e.type == -1) {
printf("\n Link broken or unexpected message received. Re-establishing connection...\n");
reestablish_connection(&socket, ip, port, number_of_events, is_on);
continue; // Skip further processing and retry
}
//-------------------------
// GNB_PHY_UL_FD_PUSCH_IQ, GNB_PHY_UL_FD_DMRS_ID, GNB_PHY_UL_FD_CHAN_EST_DMRS_POS,
// UE_PHY_UL_SCRAMBLED_TX_BITS, GNB_PHY_UL_PAYLOAD_RX_BITS, UE_PHY_UL_PAYLOAD_TX_BITS
//-------------------------
// is it a requested message
if (isValueInArray(e.type, req_tracer_msgs_indices, num_req_tracer_msgs)) {
// is it based on Data Collection Trace Messages Structure
if (isValueInArray(e.type, traces_support_data_Collection_format_idx, n_msgs_based_data_Collection_format)) {
// Start recording from the next slot to mitigate capturing partial data
// check if the current frame and slot are different from the previous frame and slot
// Then, increase the record index
if (start_recording == false) {
if (got_ref_frame_slot == false) {
ref_frame = e.e[trace_msg_data.frame].i;
ref_slot = e.e[trace_msg_data.slot].i;
printf("\nMessage Info: msg_id %s (%d) \n", event_name_from_id(database, e.type), e.type);
got_ref_frame_slot = true;
}
current_frame = e.e[trace_msg_data.frame].i;
current_slot = e.e[trace_msg_data.slot].i;
frame_difference = (current_frame - ref_frame + MAX_FRAME_INDEX + 1) % (MAX_FRAME_INDEX + 1);
slot_difference = (current_slot - ref_slot + MAX_SLOT_INDEX + 1) % (MAX_SLOT_INDEX + 1);
printf("\n First frame.slot: %d.%d, current frame.slot: %d.%d, diff frame.slot: %d.%d",
ref_frame,
ref_slot,
current_frame,
current_slot,
frame_difference,
slot_difference);
if ((ref_frame != current_frame) || (ref_slot != current_slot)) {
start_recording = true;
printf("\n Start recording from frame: %d, slot: %d ", e.e[trace_msg_data.frame].i, e.e[trace_msg_data.slot].i);
}
}
// start recording from the next frame to mitigate capturing partial data
if (start_recording == true) {
/* this is how to access the elements of the Data Collection trace messages.
* we use e.e[<element>] and then the correct suffix, here
* it's .i for the integer and .b for the buffer and .bsize for the buffer size
* see in event.h the structure event_arg
*/
unsigned char *buf = e.e[trace_msg_data.data].b;
printf("\n\nRecord number: %d", nrecord_idx);
#ifdef DEBUG_BUFFER
printf("\nBuffer index in bytes: %d", bufIdx_wr);
#endif
// add general message header: message ID,
// T-Tracer Message format
// FORMAT = int,frame : int,slot : int,datetime_yyyymmdd : int,datetime_hhmmssmmm :
// int,frame_type : int,freq_range : int,subcarrier_spacing : int,cyclic_prefix : int,symbols_per_slot :
// int,Nid_cell : int,rnti :
// int,rb_size : int,rb_start : int,start_symbol_index : int,nr_of_symbols :
// int,qam_mod_order : int,mcs_index : int,mcs_table : int,nrOfLayers :
// int,transform_precoding : int,dmrs_config_type : int,ul_dmrs_symb_pos : int,number_dmrs_symbols :
// int,dmrs_port : int,dmrs_nscid :
// int,nb_antennas_tx : int,number_of_bits : buffer,data
// printf("\nTX : %d", e.e[trace_msg_data.nb_antennas_tx].i);
memcpy(&addr_wr[bufIdx_wr], &e.type, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.frame].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.slot].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.datetime_yyyymmdd].i, sizeof(uint32_t));
bufIdx_wr += sizeof(uint32_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.datetime_hhmmssmmm].i, sizeof(uint32_t));
bufIdx_wr += sizeof(uint32_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.frame_type].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.freq_range].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.subcarrier_spacing].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.cyclic_prefix].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.symbols_per_slot].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.Nid_cell].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.rnti].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.rb_size].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.rb_start].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.start_symbol_index].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.nr_of_symbols].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.qam_mod_order].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.mcs_index].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.mcs_table].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.nrOfLayers].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.transform_precoding].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.dmrs_config_type].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.ul_dmrs_symb_pos].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.number_dmrs_symbols].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.dmrs_port].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.dmrs_nscid].i, sizeof(uint16_t));
bufIdx_wr += sizeof(uint16_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.nb_antennas_tx].i, sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.number_of_bits].i, sizeof(uint32_t));
bufIdx_wr += sizeof(uint32_t);
printf("\nTime Stamp: %d_%d", e.e[trace_msg_data.datetime_yyyymmdd].i, e.e[trace_msg_data.datetime_hhmmssmmm].i);
// add message body: length in bytes + recorded data
memcpy(&addr_wr[bufIdx_wr], &e.e[trace_msg_data.data].bsize, sizeof(uint32_t));
bufIdx_wr += sizeof(uint32_t);
// read data from buffer and convert from unsigned char * array to int 16 using the right endianness
// T-tracer: Little Endian
// For BITS Messages, example: UE_PHY_UL_SCRAMBLED_TX_BITS: data in bytes
if (is_bits_messages(traces_bits_support_data_Collection_format_idx, n_bits_msgs, e.type)) {
for (int byte_idx = 0; byte_idx < e.e[trace_msg_data.data].bsize; byte_idx += 1) {
// printf("%d, ", buf[byte_idx]);
memcpy(&addr_wr[bufIdx_wr], &buf[byte_idx], sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
}
} else {
for (int byte_idx = 0; byte_idx < e.e[trace_msg_data.data].bsize; byte_idx += 2) {
// For a little-endian system:
memcpy(&addr_wr[bufIdx_wr], &buf[byte_idx], sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
memcpy(&addr_wr[bufIdx_wr], &buf[byte_idx + 1], sizeof(uint8_t));
bufIdx_wr += sizeof(uint8_t);
}
}
/*
for (int byte_idx_i = 0; byte_idx_i < e.e[d.nr_ul_fd_dmrs_data].bsize; byte_idx_i+=4) {
int16_t I = buf[byte_idx_i] | (buf[byte_idx_i+1] << 8);
int16_t Q = buf[byte_idx_i+2] | (buf[byte_idx_i+3] << 8);
printf ("idx %d, ", byte_idx_i);
printf ("\n%d", I);
printf ("\n%d", Q);
}
*/
// check if the current frame and slot are different from the previous frame and slot
// Then, increase the record index
current_frame = e.e[trace_msg_data.frame].i;
current_slot = e.e[trace_msg_data.slot].i;
// increase sync offset index if the current frame is different from the previous frame
if ((current_frame != prev_frame) && nrecord_idx >= number_records) {
sync_offset_index++;
}
if (current_frame != prev_frame || current_slot != prev_slot) {
nrecord_idx++;
// Update previous frame and slot numbers
prev_frame = current_frame;
prev_slot = current_slot;
}
#ifdef DEBUG_T_Tracer
printf("\nMessage Info: msg_id %s (%d) \n", event_name_from_id(database, e.type), e.type);
printf("frame %d, slot %d, datetime %d_%d\n",
e.e[trace_msg_data.frame].i,
e.e[trace_msg_data.slot].i,
e.e[trace_msg_data.datetime_yyyymmdd].i,
e.e[trace_msg_data.datetime_hhmmssmmm].i);
printf("frame_type %d, freq_range %d, subcarrier_spacing %d, cyclic_prefix %d, symbols_per_slot %d\n",
e.e[trace_msg_data.frame_type].i,
e.e[trace_msg_data.freq_range].i,
e.e[trace_msg_data.subcarrier_spacing].i,
e.e[trace_msg_data.cyclic_prefix].i,
e.e[trace_msg_data.symbols_per_slot].i);
printf("Nid_cell %d, rnti %d, rb_size %d, rb_start %d, start_symbol_index %d, nr_of_symbols %d\n",
e.e[trace_msg_data.Nid_cell].i,
e.e[trace_msg_data.rnti].i,
e.e[trace_msg_data.rb_size].i,
e.e[trace_msg_data.rb_start].i,
e.e[trace_msg_data.start_symbol_index].i,
e.e[trace_msg_data.nr_of_symbols].i);
printf("qam_mod_order %d, mcs_index %d, mcs_table %d, nrOfLayers %d, transform_precoding %d\n",
e.e[trace_msg_data.qam_mod_order].i,
e.e[trace_msg_data.mcs_index].i,
e.e[trace_msg_data.mcs_table].i,
e.e[trace_msg_data.nrOfLayers].i,
e.e[trace_msg_data.transform_precoding].i);
printf("dmrs_config_type %d, ul_dmrs_symb_pos %d, number_dmrs_symbols %d, dmrs_port %d, dmrs_nscid %d\n",
e.e[trace_msg_data.dmrs_config_type].i,
e.e[trace_msg_data.ul_dmrs_symb_pos].i,
e.e[trace_msg_data.number_dmrs_symbols].i,
e.e[trace_msg_data.dmrs_port].i,
e.e[trace_msg_data.dmrs_nscid].i);
printf("nb_antennas_tx %d, number_of_bits %d, data size %d\n",
e.e[trace_msg_data.nb_antennas_tx].i,
e.e[trace_msg_data.number_of_bits].i,
e.e[trace_msg_data.data].bsize);
#endif
} // End of start recording flag
} // end of if statement for the supported messages based on Data Collection Trace Messages Structure
else {
printf("ERROR: Requested Message is not based on Data Collection Trace Messages Structure\n");
printf("ERROR: Requested Message ID: %d\n", e.type);
}
} // end of if statement for the requested messages
} // end while loop of reading events
else {
// No data, just loop and check time
usleep(100); // optional: avoid busy-waiting
}
} // End of while loop to read messages
// de-activate the tracee in the nr-softmodem
printf("\n De-activated Tracer message:\n");
for (i = 0; i < num_req_tracer_msgs; i++) {
char *on_off_name = event_name_from_id(database, req_tracer_msgs_indices[i]);
on_off(database, on_off_name, is_on, 0);
// printf("\n %d, %s, ", req_tracer_msgs_indices[i], on_off_name);
// on_off(database, "GNB_PHY_DL_OUTPUT_SIGNAL", is_on, 1);
}
// De-activate the tracee in the nr-softmodem
activate_traces(socket, number_of_events, is_on);
printf("\n De-activated Traces");
// Get the end time
struct timespec end_time = get_current_time();
// Calculate the time difference
double time_diff = calculate_time_difference(start_time, end_time);
printf("Total Time difference: %.2f ms\n", time_diff);
printf("Time difference per record: %.2f ms\n", time_diff / (number_records + max_sync_offset));
// discard stale or previous record data for the first DISCARD_RECORD_DURATION_MS
struct timespec record_start, record_now;
clock_gettime(CLOCK_MONOTONIC, &record_start);
while (1) {
clock_gettime(CLOCK_MONOTONIC, &record_now);
double elapsed_ms = calculate_time_difference(record_start, record_now);
if (elapsed_ms >= DISCARD_RECORD_DURATION_MS) {
break; // Stop after 10ms
}
int poll_ret = poll(&event_poll_fd, 1, 1); // 1 ms timeout for poll
if (poll_ret > 0 && (event_poll_fd.revents & POLLIN)) {
event e = get_event(socket, &ebuf, database);
printf("%d", e.type);
if (e.type == -1) {
printf("\n Link broken or unexpected message received. Re-establishing connection...\n");
reestablish_connection(&socket, ip, port, number_of_events, is_on);
continue;
}
} else {
// No data, just loop and check time
usleep(100); // optional: avoid busy-waiting
}
} // End of while loop to discard stale records
}
} // End a while loop to check for the "stop" command
// de-activate the tracee in the nr-softmodem
// free_database(database); //Do on one app, for example on gNB App
free(is_on);
close(socket);
return 0;
}

View File

@@ -159,7 +159,7 @@ int socket_send(int socket, void *buffer, int size) {
int get_connection(char *addr, int port) {
int s, t;
fprintf(stderr, "waiting for connection on %s:%d\n", addr, port);
printf("waiting for connection on %s:%d\n", addr, port);
s = create_listen_socket(addr, port);
t = socket_accept(s);
@@ -169,7 +169,7 @@ int get_connection(char *addr, int port) {
}
close(s);
fprintf(stderr, "connected\n");
printf("connected\n");
return t;
}
@@ -216,12 +216,12 @@ int try_connect_to(char *addr, int port) {
int connect_to(char *addr, int port) {
int s;
fprintf(stderr, "connecting to %s:%d\n", addr, port);
printf("connecting to %s:%d\n", addr, port);
again:
s = try_connect_to(addr, port);
if (s == -1) {
fprintf(stderr, "trying again in 1s\n");
printf("trying again in 1s\n");
sleep(1);
goto again;
}

View File

@@ -1,84 +0,0 @@
{
"id": 0,
"test_config": {
"test_scenario_id": "",
"test_name": "phy_ul_bler_test",
"test_mode": "rf_real_time",
"dut_type": "trad_rx"
},
"environment_emulation": {
"target_link_config": {
"ran_config": {
"uplink": {
"ul_used_signal_BW_MHz": 2.16
}
},
"wireless_channel": {
"downlink": {
"type": "rf_cable"
},
"uplink": {
"type": "statistical_var",
"statistical": {
"var_power_delay_profile": "tdl_d",
"speed_mps": 5.0,
"delay_spread_ns": 50.0,
"snr_db": 20.0,
"predef_channel_profile": null
}
},
"carrierFreqValueList_hz": [
3319680000.0
],
"ul_used_signal_BW_MHz": 2.16
}
}
},
"data_recording_config": {
"data_storage_path": "/home/user/workarea/oai_recorded_data/",
"data_file_format": "SigMF",
"enable_saving_tracer_messages_sigmf": true,
"num_records": 5,
"t_tracer_message_definition_file": "../T/T_messages.txt",
"parameter_map_file": "config/wireless_link_parameter_map.yaml",
"start_frame_number": 5,
"base_station": {
"requested_tracer_messages": [
"GNB_PHY_UL_FD_PUSCH_IQ",
"GNB_PHY_UL_FD_DMRS",
"GNB_PHY_UL_FD_CHAN_EST_DMRS_POS",
"GNB_PHY_UL_FD_CHAN_EST_DMRS_INTERPL",
"GNB_PHY_UL_PAYLOAD_RX_BITS"
],
"meta_data":{
"num_rx_antennas": 1,
"tx_gain": 48.0,
"rx_gain": 30.0,
"hw_type": "USRP X410",
"hw_subtype": "ZBX",
"seid": "328AB35"
}
},
"user_equipment": {
"requested_tracer_messages": [
"UE_PHY_UL_SCRAMBLED_TX_BITS",
"UE_PHY_UL_PAYLOAD_TX_BITS"
],
"meta_data":{
"num_tx_antennas": 1,
"tx_gain": 48.0,
"rx_gain": 40.0,
"hw_type": "USRP X410",
"hw_subtype": "ZBX",
"seid": "323F75F"
}
},
"common_meta_data": {
"sample_rate": 61440000.0,
"bandwidth": 40000000.0,
"clock_reference": "external"
},
"tracer_service_baseStation_address": "127.0.0.1:2021",
"tracer_service_userEquipment_address": "127.0.0.1:2023"
}
}

View File

@@ -1,375 +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
# */
#---------------------------------------------------------------------
# file common/utils/data_recording/config/wireless_link_parameter_map.yaml
# brief Wireless Link Parameter Map Dictionary
# author Abdo Gaber
# date 2024
# version 1.0
# company Emerson, NI Test and Measurement
# email:
# note
# warning
# Wireless Link Parameter Map
# Components:
# Transmitter: list of waveform configuration based on standard
# Parameters pair is given via this parameter map dictionary (Parameter name in Waveform creator vs that in the API ~ SigMF meta-data)
# Having a separate dictionary ease of adoption in case of:
# - Adding new parameters
# - Use different waveform creator that has Different naming scheme
# - Define your own customized standard or new wireless system
# - All changes are limited to parameter map dictionary
# the parameter name of waveform generator has the following style:
# StandardName_WaveformGenerator_parameter, i.e.
# if standard = 5gnr, WaveformGenerator: ni_rfmx_rfws, then the parameter name: 5gnr_ni_rfmx_rfws_parameter
# =====================================================================================
# ======== list of parameter pairs between waveform config and API ~ SigMF Meta-Data ===
# =====================================================================================
# List of waveform generators that generate waveforms
# key:
# standard: "name"
# generator: "link or text ... etc"
# key: Used to create parameter names in wireless_link_parameter_map
# Recommended name for each waveform generator to be given as: standard_WaveformGenerator
# Example: 5g NR waveform created using RFmx with RFWS config file: "5gnr_ni_rfmx_rfws"
# Note: The suffix "_parameter" will be added automatically
# standard name: occur in meta-data
# generator: generator description to occur in meta-data
waveform_generator:
# waveform_source: standard
5gnr_oai: # Generated using OAI
standard: "5gnr"
generator: "OpenAirInterface: https://www.openairinterface.org/"
5gnr_ni_rfmx_rfws: # Generated using NI RFmx Tool
standard: "5gnr"
generator: "NI RFmx Waveform Creator: https://www.ni.com/en-ca/shop/wireless-design-test/application-software-for-wireless-design-test-category/what-is-rfmx.html"
transmitter:
# 5G NR subfield
5gnr:
# frame number
- sigmf_parameter_name: "frame"
description: "5G NR frame number"
5gnr_oai_parameter:
name: "frame"
# slot number
- sigmf_parameter_name: "slot"
description: "5G NR slot number"
5gnr_oai_parameter:
name: "slot"
# bandwidth
- sigmf_parameter_name: "bandwidth"
description: "5G NR bandwidth"
5gnr_ni_rfmx_rfws_parameter:
name: "Bandwidth (Hz)"
5gnr_oai_parameter:
name: "bandwidth"
# Frame structure
- sigmf_parameter_name: "frame_structure"
description: "5G NR duplexing scheme FDD, TDD, user defined"
5gnr_ni_rfmx_rfws_parameter:
name: "Duplex Scheme" # not exact, since it depends if the waveform is for UL or DL
5gnr_oai_parameter:
name: "frame_type"
value_map: # simu value : SigMF value
0: "fdd"
1: "tdd"
# Link direction
- sigmf_parameter_name: "link_direction"
description: "Link direction"
5gnr_ni_rfmx_rfws_parameter:
name: "Link Direction"
# Frequency Range
- sigmf_parameter_name: "frequency_range"
description: "Frequency Range"
5gnr_ni_rfmx_rfws_parameter:
name: "Frequency Range"
value_map: # simu value : SigMF value
"Range 1": "fr1"
"Range 2": "fr2"
5gnr_oai_parameter:
name: "freq_range"
value_map: # simu value : SigMF value
0: "fr1"
1: "fr2"
# Subcarrier spacing in Hz
- sigmf_parameter_name: "subcarrier_spacing"
description: "Subcarrier spacing in Hz"
5gnr_ni_rfmx_rfws_parameter:
name: Subcarrier Spacing (Hz)
5gnr_oai_parameter:
name: subcarrier_spacing
value_map: # simu value : SigMF value
0: 15000
1: 30000
2: 60000
3: 120000
# Sampling rate in Hz
- sigmf_parameter_name: "sample_rate"
description: "Sampling rate in Hz"
5gnr_ni_rfmx_rfws_parameter:
name: "sample_rate_hz"
5gnr_oai_parameter:
name: "sample_rate"
# Cyclic prefix mode
- sigmf_parameter_name: "cp_mode"
description: "Cyclic prefix mode"
5gnr_ni_rfmx_rfws_parameter:
name: "Cyclic Prefix Mode"
5gnr_oai_parameter:
name: "cyclic_prefix"
value_map: # simu value : SigMF value
0: "normal"
1: "extended"
# cell ID
- sigmf_parameter_name: "cell_id"
description: "cell ID"
5gnr_ni_rfmx_rfws_parameter:
name: "Cell ID"
5gnr_oai_parameter:
name: "Nid_cell"
# rnti
- sigmf_parameter_name: "rnti"
description: "RNTI"
5gnr_ni_rfmx_rfws_parameter:
name: "rnti"
5gnr_oai_parameter:
name: "rnti"
# Symbols per slot
- sigmf_parameter_name: "symbols_per_slot"
description: "Symbols per slot"
5gnr_oai_parameter:
name: "symbols_per_slot"
# PUSCH: content
- sigmf_parameter_name: "pusch:content"
description: "PUSCH: content"
# PUSCH: channel code
- sigmf_parameter_name: "pusch:channel_code"
description: "PUSCH: channel code"
# PUSCH: number of PRBs
- sigmf_parameter_name: "pusch:num_prb"
description: "PUSCH Resource Block Size"
5gnr_oai_parameter:
name: "rb_size"
# PUSCH RB Start index
- sigmf_parameter_name: "pusch:start_prb"
description: "PUSCH Resource Block Start"
5gnr_oai_parameter:
name: "rb_start"
# PUSCH MAPPING type
- sigmf_parameter_name: "pusch:mapping_type"
description: "PUSCH Mapping Type"
5gnr_oai_parameter:
name: "mappingType"
value_map: # simu value : SigMF value
"NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA": "A"
"NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB": "B"
# PUSCH: OFDM symbol start index within slot
- sigmf_parameter_name: "pusch:start_ofdm_symbol"
description: "PUSCH: OFDM symbol start index within slot"
5gnr_oai_parameter:
name: "start_symbol_index"
# PUSCH: number of OFDM symbols in one slot
- sigmf_parameter_name: "pusch:num_ofdm_symbols"
description: "PUSCH: number of OFDM symbols in one slot"
5gnr_oai_parameter:
name: "nr_of_symbols"
# PUSCH: modulation
- sigmf_parameter_name: "pusch:modulation"
description: "PUSCH: modulation"
5gnr_ni_rfmx_rfws_parameter:
name: "UL Modulation Type"
value_map: # simu value : SigMF value
"8PSK": "8_psk"
"QPSK": "qpsk"
"QAM16": "16_qam"
"QAM64": "64_qam"
"QAM256": "256_qam"
"QAM1024": "1024_qam"
"Standard": ""
5gnr_oai_parameter:
name: "qam_mod_order"
value_map: # simu value : SigMF value
2 : "qpsk"
4 : "16_qam"
6 : "64_qam"
8 : "256_qam"
"Standard": ""
# PUSCH MCS Index
- sigmf_parameter_name: "pusch:mcs"
description: "PUSCH MCS Index"
5gnr_oai_parameter:
name: "mcs_index"
# PUSCH MCS Index Table
- sigmf_parameter_name: "pusch:mcs_table_index"
description: "PUSCH MCS Table Index"
5gnr_oai_parameter:
name: "mcs_table"
# PUSCH: number of transmission layers
- sigmf_parameter_name: "pusch:num_layer"
description: "PUSCH: number of transmission layers"
5gnr_oai_parameter:
name: "nrOfLayers"
# Transform Precoding
- sigmf_parameter_name: "pusch:transform_precoding"
description: "PUSCH Transform Precoding"
5gnr_oai_parameter:
name: "transform_precoding"
value_map: # simu value : SigMF value
0: "enabled"
1: "disabled"
# PUSCH DMRS: content
- sigmf_parameter_name: "pusch_dmrs:content"
description: "PUSCH DMRS: content"
#"none": "none"
#"random_qpsk": "random_qpsk"
#"compliant": "compliant"
# PUSCH DMRS: resource map configuration
- sigmf_parameter_name: "pusch_dmrs:resource_map_config"
description: "PUSCH DMRS: resource map configuration"
5gnr_oai_parameter:
name: "dmrs_config_type"
value_map:
0: "5g nr type 1"
1: "5g nr type 2"
# PUSCH DMRS: OFDM symbol start index within slot
- sigmf_parameter_name: "pusch_dmrs:start_ofdm_symbol"
description: "PUSCH DMRS: OFDM symbol start index within slot"
5gnr_oai_parameter:
# to be derived from this OAI parameter
name: "ul_dmrs_symb_pos"
# PUSCH DMRS: DMRS duration in number of OFDM symbols
- sigmf_parameter_name: "pusch_dmrs:duration_num_ofdm_symbols"
description: "PUSCH DMRS: DMRS duration in number of OFDM symbols"
5gnr_oai_parameter:
# to be derived from this OAI parameter
name: "ul_dmrs_symb_pos"
# PUSCH DMRS: OFDM symbol indices within resource grid
- sigmf_parameter_name: "pusch_dmrs:ofdm_symbol_idx"
description: "PUSCH DMRS: OFDM symbol indices within resource grid"
5gnr_oai_parameter:
# to be derived from this OAI parameter
name: "ul_dmrs_symb_pos"
# PUSCH DMRS: number of additional PUSCH DMRS positions
- sigmf_parameter_name: "pusch_dmrs:num_add_positions"
description: "PUSCH DMRS: number of additional PUSCH DMRS positions"
5gnr_oai_parameter:
# to be derived from this OAI parameter
name: "ul_dmrs_symb_pos"
# PUSCH DMRS: antenna port
- sigmf_parameter_name: "pusch_dmrs:antennna_port"
description: "PUSCH DMRS: antenna port"
5gnr_oai_parameter:
name: "dmrs_port"
# PUSCH DMRS: scrambler initialization
- sigmf_parameter_name: "pusch_dmrs:nscid"
description: "PUSCH DMRS: scrambler initialization"
5gnr_oai_parameter:
name: "dmrs_nscid"
# number of rx antennas
- sigmf_parameter_name: "num_rx_antennas"
description: "Number of Rx antennas"
5gnr_oai_parameter:
name: "nb_antennas_rx"
# number of tx antennas
- sigmf_parameter_name: "num_tx_antennas"
description: "Number of Tx antennas"
5gnr_oai_parameter:
name: "nb_antennas_tx"
channel:
# Signal-to-noise ratio (Es/N0) in dB
- sigmf_parameter_name: "snr_esn0_db"
description: "Signal-to-noise ratio (Es/N0) in dB"
# Signal-to-noise ratio (Eb/N0) in dB
- sigmf_parameter_name: "snr_ebn0_db"
description: "Signal-to-noise ratio (Eb/N0) in dB"
# Channel model
- sigmf_parameter_name: "channel_model"
description: "Fading channel model"
# Number of channel taps
- sigmf_parameter_name: "num_channel_taps"
description: "Number of channel taps"
# Channel attenuation level in dB
- sigmf_parameter_name: "channel_attenuation_db"
description: "Channel attenuation level in dB"
# Nominal delay spread in s
- sigmf_parameter_name: "delay_spread"
description: "Nominal delay spread in s"
# UE speed in m/s
- sigmf_parameter_name: "speed"
description: "UE speed in m/s"
# Carrier frequency in Hz
- sigmf_parameter_name: "carrier_frequency"
description: "Carrier frequency in Hz"
receiver:
# Frequency domain interpolation method for channel estimation
- sigmf_parameter_name: "channel_estimation_freq_interpolation"
description: "Frequency domain interpolation method for channel estimation"
# Time domain interpolation method for channel estimation
- sigmf_parameter_name: "channel_estimation_time_interpolation"
description: "Time domain interpolation method for channel estimation"
# Channel equalization method
- sigmf_parameter_name: "channel_equalization_method"
description: "Channel equalization method"
# Symbol demapping method
- sigmf_parameter_name: "symbol_demapping_method"
description: "Symbol demapping method"
# Manufacturer of the hardware used to receive the signal
- sigmf_parameter_name: "manufacturer"
description: "Manufacturer"
# Unique ID of the emitter, USRP serial number --> usrp_mboard_serial
- sigmf_parameter_name: "seid"
description: "Emitter ID (USRP serial number)"
# For USRP, use “daughterboard ID, a string read out from the device shortened by the hex ID e.g. (0x0085)
- sigmf_parameter_name: "hw_subtype"
description: "Hardware subtype (for USRP: daughterboard ID)"
# RX sync reference source ("internal", "external", "gpsdo")
- sigmf_parameter_name: "clock_reference"
description: "RX clock reference"
required_field: false
# Estimated SNR in dB
- sigmf_parameter_name: "snr_estimate_db"
description: "SNR estimate in dB"
required_field: false
# Result of coarse PSS-based timing estimation (used for synchronization)
- sigmf_parameter_name: "timing_estimate_coarse"
description: "Coarse timing estimate in samples"
required_field: false"
# Result of coarse PSS-based frequency offset estimation (used for synchronization)
- sigmf_parameter_name: "cfo_estimate_coarse"
description: "Coarse frequency estimate in Hz"
required_field: false
# Result of fine CRS-based frequency offset estimation (used for synchronization)
- sigmf_parameter_name: "cfo_estimate_fine"
description: "Fine frequency estimate in Hz"
required_field: false
# Number of transmitted payload bits
- sigmf_parameter_name: "num_payload_bits"
description: "Number of transmitted payload bits"
required_field: false
# Number of bit errors when applying traditional RX processing
- sigmf_parameter_name: "bit_errors_trad_rx"
description: "Bit errors"
required_field: false

Some files were not shown because too many files have changed in this diff Show More