Compare commits

..

120 Commits

Author SHA1 Message Date
Flavien RJ
e3b4330e58 Fix LatSeq merge conflict with remote oai-eurecom 2022-09-20 08:31:24 +02:00
Flavien RJ
caee2d8279 latseq : fix patch 2022.w20 2022-09-15 11:58:46 +02:00
Flavien RJ
f2285cce40 Apply latseq patch 2022.w20 2022-09-15 09:18:27 +02:00
Flavien RJ
0ae4644f61 Merge branch 'latseq' into HEAD 2022-09-15 09:14:19 +02:00
laurent
fda7cf2121 merge develop 2022-06-30 16:26:51 +02:00
laurent
f1ffde5395 Merge branch 'develop' of https://gitlab.eurecom.fr/oai/openairinterface5g into latseq 2022-06-30 15:36:49 +02:00
Flavien RJ
4b90221622 Fix merge conflict latseq and develop branches 2022-02-24 17:30:17 +01:00
Flavien RJdM
3e0f8c73ad Merge remote-tracking branch 'oai-eurecom/develop' into latseq 2022-02-24 16:49:37 +01:00
Flavien RJ
fb7d473383 fix build_oai -I with develop branch 2022-02-16 18:59:26 +01:00
Flavien RJ
266cf75570 little fix of build_oai 2022-02-07 15:05:22 +01:00
Flavien RJ
47494c9950 Merge remote-tracking branch 'oai-eurecom/develop' into latseq 2022-02-07 15:04:59 +01:00
Flavien RJ
37abc70eee latseq : clean up for OAI merge request 2022-02-07 09:49:22 +01:00
Flavien RJ
3c56bfc638 Merge tag '2021.w51_c' into latseq-dev
Tx proc optim ;  oaiue x300 ; NR RRC harmonization: TDA for DL and UL
2022-01-06 13:00:06 +01:00
Flavien RJ
703bda8665 latseq : commit before push request pushing
latseq-dev branch to OAI repo
2021-10-15 09:29:06 +02:00
Flavien RJ
60edb9a5b7 Merge tag '2021.w36' into latseq-dev
Bugfix nr rlc segmentation present in both NR RLC AM and NR RLC UM ;  T tracer  DLSCH DCI ; Fix computation of pointA in SIB1 ;  fix-physim-run-script-on-cluster ; fix nr-dlsim Test 21 (4x4 MIMO, 2 Layers)
2021-10-01 10:43:32 +02:00
Flavien RJ
9b064c1ab9 Merge tag '2021.w27' into latseq-dev
NR_gNB_initial_MIB_fix  ; x2_handle_sctp_shutdown
2021-07-15 12:23:22 +02:00
Flavien RJ
fcee3ceb41 latseq : centralize all scripts in one place 2021-06-16 09:05:47 +02:00
Flavien RJ
0ff491cb49 latseq : fix a warning on an incompatible size of array 2021-04-28 10:15:58 +02:00
flavien Ronteix--Jacquet dM
cb1aea9711 Merge branch 'develop' 2021.w09 into latseq-dev 2021-03-09 12:23:05 +01:00
flavien Ronteix--Jacquet dM
5606b0df7c Revert "soft-alter : create a branch for software alterated air interface"
This reverts commit 2e14dbb92b.
2021-02-09 20:59:16 +01:00
flavien Ronteix--Jacquet dM
2e14dbb92b soft-alter : create a branch for software alterated air interface 2021-02-09 20:58:37 +01:00
flavien Ronteix--Jacquet dM
6500e8077f latseq points : PHR 2021-02-02 11:20:12 +01:00
flavien Ronteix--Jacquet dM
cde95150c3 latseq points : long bsr 2021-01-25 19:45:51 +01:00
flavien Ronteix--Jacquet dM
5daa015e32 latseq points : nrb and rfi 2021-01-11 18:05:35 +01:00
flavien Ronteix--Jacquet dM
eb6ed6efbe latseq_points : a final version (without RLC UM) 2020-12-10 19:30:11 +01:00
flavien Ronteix--Jacquet dM
c7f93c90bc latseq_logs: logging system 2020-12-03 19:13:30 +01:00
flavien Ronteix--Jacquet dM
baa08960b3 latseq points : Add information points 2020-11-13 23:55:14 +01:00
flavien Ronteix--Jacquet dM
b98c6e1769 latseq : log rdtsc instead of gettimeofday
- add Synchronization points 'S'
- add script to convert rdtsc to gettimeofday using 'S'
- add call to conversion script to latseq_logs
2020-11-12 18:29:15 +01:00
flavien Ronteix--Jacquet dM
98a98485c1 latseq : log to ns instead of us 2020-11-04 17:23:48 +01:00
flavien Ronteix--Jacquet dM
7848214984 latseq tools and docs 2020-10-29 18:44:14 +01:00
flavien Ronteix--Jacquet dM
26f25dc943 latseq : fix flush error of fprintf 2020-10-29 18:43:29 +01:00
flavien Ronteix--Jacquet dM
3b6f8d584a latseq :
- cpu_freq in argument of init
- use local rdtsc
- fix time conversation
2020-10-29 18:42:52 +01:00
flavien Ronteix--Jacquet dM
2a36408c5b latseq points:
- add points in rlc_v2
- add points in gtp lib
- adapt points in mac layer
rlc_v2:
- add informations to RLC entity
2020-10-29 18:37:16 +01:00
flavien Ronteix--Jacquet dM
d22bb0c90f latseq :
- clean and release version of article
- add convert ring buffer by chunk
- validate test_latseq
2020-10-19 15:49:01 +02:00
flavien Ronteix--Jacquet dM
d39d476e62 latseq_logs : partial fix for infos yielding 2020-10-12 18:11:52 +02:00
flavien Ronteix--Jacquet dM
09995d5d8c latseq : hot fix, add a sleep to the thread 2020-10-07 18:28:25 +02:00
flavien Ronteix--Jacquet dM
e07c43a715 latseq : clean git repo 2020-09-18 11:35:05 +02:00
flavien Ronteix--Jacquet dM
42cfb03ca5 clear warnings 2020-09-17 10:21:19 +02:00
flavien Ronteix--Jacquet dM
c8b0c41871 latseq : patch before latseq publication 2020-09-17 10:20:52 +02:00
flavien Ronteix--Jacquet dM
2a658d1cdb NO-STABLE merge with main5G 2020-09-15 17:37:28 +02:00
flavien Ronteix--Jacquet dM
ca554e81c9 latseq_logs : fix Decimal, add progressbar and verbosity argument 2020-09-15 17:36:38 +02:00
flavien Ronteix--Jacquet dM
687d8cbf01 latseq : Add point of I-type for RLC am and um txbuffer 2020-09-14 18:44:22 +02:00
flavien Ronteix--Jacquet dM
138f67e342 latseq_logs : handle I-type traces 2020-09-14 13:11:15 +02:00
flavien Ronteix--Jacquet dM
b073fd22d4 Resolve merge conflict main5G-latseq-dev 2020-09-04 09:28:16 +02:00
flavien Ronteix--Jacquet dM
061dca80fe latseq : fix points 2020-09-04 09:23:22 +02:00
flavien Ronteix--Jacquet dM
cc40ca0721 Merge branch 'develop' (e31349256f) into latseq-dev 2020-09-01 12:55:24 +02:00
flavien Ronteix--Jacquet dM
c53a4e49c1 latseq_stats : add interarrival 2020-08-20 12:22:14 +02:00
flavien Ronteix--Jacquet dM
1ebe01a9c1 latseq_stats : add throughput metric 2020-07-31 22:29:48 +02:00
flavien Ronteix--Jacquet dM
ef45e448c0 latseq_stats : matrix segment/journeys after filtering 2020-07-28 20:35:48 +02:00
flavien Ronteix--Jacquet dM
383de22fc8 latseq_p : measurements for rlc_v2. NOT DONE.
Not important since rlc_v1 works and we will switch to nr_rlc.
2020-07-15 11:23:06 +02:00
flavien Ronteix--Jacquet dM
3e88f1cd77 latseq_logs : commit befor checking out 2020-07-03 18:44:25 +02:00
flavien Ronteix--Jacquet dM
b1eb810d9d latseq tools:
latseq_logs : output for latseqj fix of points' name
latseq_checker: add generation of reports of functional points in OAI code
2020-06-17 20:08:27 +02:00
flavien Ronteix--Jacquet dM
3234efec54 latseq : fix latseq point in RLC/ for experiments 2020-06-17 20:07:01 +02:00
flavien Ronteix--Jacquet dM
d2e4c33c7f Latseq : fix an error with filelog name memory 2020-06-15 19:26:22 +02:00
flavien Ronteix--Jacquet dM
c2cea21ae4 latseq tools:
- update README
-  stats parser
-  add script to convert json stream to a dsv stream
- change point yielder in latseq_logs
2020-06-03 17:37:20 +02:00
flavien Ronteix--Jacquet dM
6affc6a1d6 latseq : dynamic log filename 2020-06-03 17:33:29 +02:00
flavien Ronteix--Jacquet dM
1a60305799 latseq_stats : add -jd journeyx durations csv for plots 2020-06-02 18:18:52 +02:00
flavien Ronteix--Jacquet dM
7c6427b2e6 latseq_stats : output in csv 2020-06-01 14:48:14 +02:00
flavien Ronteix--Jacquet dM
64a39c5a11 Merge branch 'main5G' into latseq-dev 2020-05-20 10:08:00 +02:00
flavien Ronteix--Jacquet dM
4876af241c Merge remote-tracking branch 'origin/main5G' into latseq-dev 2020-05-19 15:56:39 +02:00
flavien Ronteix--Jacquet dM
2f62c6a403 latseq tools : some tests, comments and fixes 2020-05-19 12:14:37 +02:00
flavien Ronteix--Jacquet dM
7fd29ce8bb latseq_logs : add csv output 2020-05-19 10:10:12 +02:00
flavien Ronteix--Jacquet dM
3a6a6d9b4d latseq_stats : repartition du temps de trajet par point en moyenne sur les séjours (par path) 2020-05-19 09:17:36 +02:00
flavien Ronteix--Jacquet dM
3bc6d3b385 latseq_stats : debut du travail sur les stats journeys par point 2020-05-15 13:49:05 +02:00
Flavien RJdM
67dc05b35c latseq_app : Creation. Plotly + Flask. 2020-05-12 10:36:15 +02:00
flavien Ronteix--Jacquet dM
95c0d37f4a latseq tools : Full toolchain works. Readme for tools 2020-05-11 19:41:09 +02:00
flavien Ronteix--Jacquet dM
6556377a7e latseq_filter : latseq_filter component with an example 2020-05-11 13:07:38 +02:00
flavien Ronteix--Jacquet dM
cb7222d0d4 latseq_logs : match journey to a path 2020-05-11 13:06:59 +02:00
flavien Ronteix--Jacquet dM
3da0b6f6c6 latseq_stats : stats points 2020-05-11 13:06:38 +02:00
flavien Ronteix--Jacquet dM
b929a7bfba latseq_logs:
- modularisation avec des sorties en json dans le stdout
- suppression de l'ancienne version de l'algo
- suppression de la classe de stats
latseq_stats:
- création de la classe de stat
- prend en charge le json dans le stdin pour les stat sur les journeys
2020-05-07 14:12:06 +02:00
flavien Ronteix--Jacquet dM
e65c78a932 latseq :
- Test TLS buffer occupancy... 32 latseq element is sufficent
- use of sdu size to connect rlc.tx.um--rlc.seg.um... not ideal
- split ip in ip.in and ip.out
2020-05-07 09:16:58 +02:00
flavien Ronteix--Jacquet dM
f40d6e08d5 latseq_log : Use time for search depth instead of number of packet 2020-05-04 11:03:30 +02:00
flavien Ronteix--Jacquet dM
e2a75a125b latseq_logs : rec_rebuild journey algorithm refactoring for a better
detection of segmentation in the case of concatenation
Use of a tree datastruct for the segmentation to explore
2020-04-30 12:33:38 +02:00
flavien Ronteix--Jacquet dM
fe9b97f5a0 latseq_logs : comments and minor fixes 2020-04-29 14:02:59 +02:00
flavien Ronteix--Jacquet dM
10824650e3 latseq_stats:
- add statistics computation for journeys' latency
- add statistics computation for points' latency
- add procedure to display basic statistics
2020-04-28 14:24:35 +02:00
flavien Ronteix--Jacquet dM
2dc3c0a6e0 latseq_logs :
- add stuffs to latseq_log's points attribute
- some fix for rebuild_journeys_recursively
- add pickle to store instance of latseq_log class
2020-04-28 14:23:05 +02:00
flavien Ronteix--Jacquet dM
f00db789fa latseq_logs : rebuild packet journey recursively.
Not totally finshed but looks good.
2020-04-24 23:33:58 +02:00
flavien Ronteix--Jacquet dM
b0d73f24f4 latseq_logs : rebuild allmost every journeys, except case where there is a measurement point betweet to path of the fork 2020-04-24 19:03:13 +02:00
flavien Ronteix--Jacquet dM
d68b88470c latseq : first version to rebuild path ! (not a final version of the algorithm...) 2020-04-23 14:56:11 +02:00
flavien Ronteix--Jacquet dM
670acb2738 latseq_checker : misc adds 2020-04-23 14:55:33 +02:00
flavien Ronteix--Jacquet dM
ef14b3e216 latseq : drb is no longer a global id 2020-04-23 14:55:02 +02:00
flavien Ronteix--Jacquet dM
a7367ae479 latseq_logs : rebuild_packet_journey almost ready 2020-04-22 15:31:04 +02:00
flavien Ronteix--Jacquet dM
270761022b latseq : divers clean 2020-04-22 15:30:36 +02:00
flavien Ronteix--Jacquet dM
efe6b87814 latseq : - BUG FIX pour log_measure4
- les dataid convergent...
2020-04-21 12:52:50 +02:00
flavien Ronteix--Jacquet dM
520961597c latseq : travail sur les points de mesures, notamment pdcp 2020-04-17 22:26:45 +02:00
flavien Ronteix--Jacquet dM
f0fbb77f29 latseq_logs : gestion du multibranche des points 2020-04-17 22:26:05 +02:00
flavien Ronteix--Jacquet dM
f31efd81a6 latseq_logs : objectification and parsing 2020-04-16 18:28:26 +02:00
flavien Ronteix--Jacquet dM
c432a3ecd7 latseq : ajout de la taille dans les points de mesures 2020-04-15 18:23:07 +02:00
flavien Ronteix--Jacquet dM
04b98d7656 After latseq_checker 2020-04-14 20:44:05 +02:00
flavien Ronteix--Jacquet dM
248f668865 latseq-tools : ajout script traitement de log 2020-04-10 22:51:44 +02:00
flavien Ronteix--Jacquet dM
a6b4555e74 latseq : latseq checker en version bash 2020-04-10 22:21:37 +02:00
flavien Ronteix--Jacquet dM
b2af014160 latseq : work on measurement points 2020-04-10 19:08:49 +02:00
flavien Ronteix--Jacquet dM
01f1e200af tools_latseq : ajout du dossier pour les outils latseq.
Creation du checker.
2020-04-09 13:29:59 +02:00
flavien Ronteix--Jacquet dM
63be7596ab test_latseq : ajout d'un test de charge sur le writer 2020-04-07 19:25:24 +02:00
flavien Ronteix--Jacquet dM
c025693894 latseq : Ajout de point et correction d'une erreur mémoire sur un free dans le logger 2020-04-07 19:24:46 +02:00
flavien Ronteix--Jacquet dM
2116edb940 latseq : premiers points de mesures conventionnels 2020-04-03 20:28:44 +02:00
flavien Ronteix--Jacquet dM
27bb00909a latseq : version fprintf 2020-04-03 20:27:52 +02:00
ferrieux
701ad23dbc Synchronously ABORT, you modafucka !!! 2020-04-02 01:46:01 +02:00
ferrieux
5d5dc5a02a Allow for NAT on S1U ($OAINAT) 2020-04-02 01:42:47 +02:00
flavien Ronteix--Jacquet dM
221930d2bd latseq
- intégration dans oai
- points de mesures de test
2020-03-26 19:07:27 +01:00
flavien Ronteix--Jacquet dM
aeb5641181 Merge branch 'split73' into latseq-dev 2020-03-26 16:09:21 +01:00
flavien Ronteix--Jacquet dM
e73a447060 latseq : fixes before split73 update and merge 2020-03-26 13:42:18 +01:00
flavien Ronteix--Jacquet dM
fb953b8d3f latseq : utilisation de l'expansion de macro plutôt que les fonctions variadiques
test_latseq : module de mesure du temps pris par log_measure()
2020-03-25 12:01:52 +01:00
flavien Ronteix--Jacquet dM
3dde316b22 test_latseq : mesure du temps 2020-03-23 17:43:25 +01:00
flavien Ronteix--Jacquet dM
9a6c794034 test_latseq : multithread functionnel 2020-03-20 12:23:31 +01:00
flavien Ronteix--Jacquet dM
cf9d524027 latseq : premiere version fonctionnelle par test_latseq a 2020-03-19 19:15:53 +01:00
ferrieux
e4d9bba825 Small bug in argv parsing 2020-03-18 22:21:06 +01:00
flavien Ronteix--Jacquet dM
8a13dcad72 latseq : test_latseq compile 2020-03-18 18:12:30 +01:00
flavien Ronteix--Jacquet dM
58478c9fcc Makefile cleanup 2020-03-18 17:07:25 +01:00
flavien Ronteix--Jacquet dM
a639140fb9 latseq : Creation du module de test de latseq, ne compile pas 2020-03-18 13:28:28 +01:00
flavien Ronteix--Jacquet dM
e20f10b1c8 latseq : some tests 2020-03-17 19:48:42 +01:00
flavien Ronteix--Jacquet dM
d7b85f69c5 latseq :
- use of global latseq veriable instead of ptr to allocate
-  add latseq_registry
- add latseq_thread_data
- add init_thread_for_latseq
2020-03-12 16:44:09 +01:00
flavien Ronteix--Jacquet dM
5116aa509a latseq : inline stuff 2020-03-11 19:05:32 +01:00
flavien Ronteix--Jacquet dM
17fab753c4 latseq : variadic function for log_measure 2020-03-11 11:32:36 +01:00
flavien Ronteix--Jacquet dM
91afd019fc latseq : new test point in dlsch_coding 2020-03-06 16:18:14 +01:00
flavien Ronteix--Jacquet dM
1412b1dc2a latseq : check g_latseq initialized
change filelog output
2020-03-06 11:49:42 +01:00
flavien Ronteix--Jacquet dM
c0f9af4955 latseq : - change log timestamp format to timeval
- lower priority on logger pthread
2020-03-05 19:13:21 +01:00
flavien Ronteix--Jacquet dM
d148bdd4d3 latseq : first compile without warnings/errors 2020-03-04 19:52:38 +01:00
flavien Ronteix--Jacquet dM
e78b0b12de latseq : First implem, not tested yet 2020-03-04 18:14:18 +01:00
flavien Ronteix--Jacquet dM
e98bf690ff NEW Latseq moved to latseq-dev 2020-03-04 07:39:41 +01:00
501 changed files with 133922 additions and 13877 deletions

20
.gitignore vendored
View File

@@ -9,9 +9,29 @@ cmake_targets/nas_sim_tools/build/
log/
lte_build_oai/
targets/bin/
core
*.lseq
*.lcheck
*.out
# object files
*.o
*.obj
*.orig
# vscode
.vscode
.vscode/launch.json
# python virtual env
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Tags for vim/global
GPATH

1
Makefile Normal file
View File

@@ -0,0 +1 @@
include ../Makefile

View File

@@ -238,26 +238,6 @@ pipeline {
}
}
}
stage ("4G L2 Simulators") {
when { expression {doMandatoryTests} }
steps {
script {
triggerSlaveJob ('RAN-L2-Sim-Test-4G', 'Test-L2-Sim-Container-4G')
}
}
post {
always {
script {
finalizeSlaveJob('RAN-L2-Sim-Test-4G')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("5G L2 Simulators") {
when { expression {doMandatoryTests} }
steps {
@@ -298,26 +278,6 @@ pipeline {
}
}
}
stage ("SA B200 Sanity Check") {
when { expression {doMandatoryTests} }
steps {
script {
triggerSlaveJob ('RAN-SA-B200-Module-SABOX-Container', 'Test-SA-B200')
}
}
post {
always {
script {
finalizeSlaveJob('RAN-SA-B200-Module-SABOX-Container')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test OAI NR UE - OAI gNB - TDD - Band 78 - N300") {
when { expression {doMandatoryTests} }
steps {

View File

@@ -416,6 +416,29 @@ pipeline {
}
}
}
stage ("Test F1 - FDD - Band 7 - B210") {
when {
expression {doFullTestsuite}
}
steps {
script {
sh "sleep 60"
triggerSlaveJob ('eNB-CI-F1-FDD-Band7-B210', 'Test-F1-FDD-Band7')
}
}
post {
always {
script {
finalizeSlaveJob('eNB-CI-F1-FDD-Band7-B210')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test IF4p5 - TDD - Band 40 - B210") {
when {
expression {doFullTestsuite}

View File

@@ -66,7 +66,7 @@ pipeline {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.DH_Credentials}", usernameVariable: 'DH_Username', passwordVariable: 'DH_Password']
]) {
def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue", "proxy"]
def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue"]
sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1"
listOfImages.eachWithIndex { item, iindex ->
sh "docker image tag ${item}:develop ${DH_Account}/${item}:develop"

View File

@@ -36,9 +36,6 @@ def testStageName = params.pipelineTestStageName
// Name of the phone resource
def ciSmartPhoneResource = params.smartphonesResource
// Name of the phone resource
def ciEpcResource = params.epcResource
// Global Parameters. Normally they should be populated when the master job
// triggers the slave job with parameters
def eNB_Repository
@@ -54,7 +51,7 @@ pipeline {
options {
disableConcurrentBuilds()
ansiColor('xterm')
lock(extra: [[resource: ciEpcResource]], resource: ciSmartPhoneResource)
lock (ciSmartPhoneResource)
}
stages {
stage ("Verify Parameters") {
@@ -219,76 +216,6 @@ pipeline {
}
}
}
stage ("Terminate") {
parallel {
stage('Terminate UE') {
// Bypassing this stage if there are no abd server defined
when {
expression { params.ADB_IPAddress != "none" }
}
steps {
echo '\u2705 \u001B[32mTerminate UE\u001B[0m'
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
]) {
sh "python3 ci-scripts/main.py --mode=TerminateUE --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password}"
}
}
}
stage('Terminate eNB') {
steps {
echo '\u2705 \u001B[32mTerminate eNB\u001B[0m'
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
sh "python3 ci-scripts/main.py --mode=TerminateeNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
}
}
}
stage('Terminate SPGW') {
// Bypassing this stage if EPC server is not defined
when {
expression { params.EPC_IPAddress != "none" }
}
steps {
echo '\u2705 \u001B[32mTerminate SPGW\u001B[0m'
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
]) {
sh "python3 ci-scripts/main.py --mode=TerminateSPGW --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}"
}
}
}
stage('Terminate MME') {
// Bypassing this stage if EPC server is not defined
when {
expression { params.EPC_IPAddress != "none" }
}
steps {
echo '\u2705 \u001B[32mTerminate MME\u001B[0m'
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
]) {
sh "python3 ci-scripts/main.py --mode=TerminateMME --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}"
}
}
}
stage('Terminate HSS') {
// Bypassing this stage if EPC server is not defined
when {
expression { params.EPC_IPAddress != "none" }
}
steps {
echo '\u2705 \u001B[32mTerminate HSS\u001B[0m'
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
]) {
sh "python3 ci-scripts/main.py --mode=TerminateHSS --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}"
}
}
}
}
}
stage('Log Collection') {
parallel {
stage('Log Collection (eNB - Build)') {
@@ -315,7 +242,7 @@ pipeline {
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}"
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m'
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true"
@@ -332,116 +259,6 @@ pipeline {
}
}
}
stage('Log Collection (SPGW)') {
// Bypassing this stage if EPC server is not defined
when {
expression { params.EPC_IPAddress != "none" }
}
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (SPGW)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollectSPGW --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}"
echo '\u2705 \u001B[32mLog Transfer (SPGW)\u001B[0m'
sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/spgw.log.zip ./spgw.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("spgw.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "spgw.log.${env.BUILD_ID}.zip"
}
}
}
}
stage('Log Collection (MME)') {
// Bypassing this stage if EPC server is not defined
when {
expression { params.EPC_IPAddress != "none" }
}
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (MME)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollectMME --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}"
echo '\u2705 \u001B[32mLog Transfer (MME)\u001B[0m'
sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/mme.log.zip ./mme.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("mme.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "mme.log.${env.BUILD_ID}.zip"
}
}
}
}
stage('Log Collection (HSS)') {
// Bypassing this stage if EPC server is not defined
when {
expression { params.EPC_IPAddress != "none" }
}
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (HSS)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollectHSS --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}"
echo '\u2705 \u001B[32mLog Transfer (HSS)\u001B[0m'
sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/hss.log.zip ./hss.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("hss.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "hss.log.${env.BUILD_ID}.zip"
}
}
}
}
stage('Log Collection (Ping)') {
// Bypassing this stage if EPC server is not defined
when {
expression { params.EPC_IPAddress != "none" }
}
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (Ping)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollectPing --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}"
echo '\u2705 \u001B[32mLog Transfer (Ping)\u001B[0m'
sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/ping.log.zip ./ping.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("ping.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "ping.log.${env.BUILD_ID}.zip"
}
}
}
}
stage('Log Collection (Iperf)') {
// Bypassing this stage if EPC server is not defined
when {
expression { params.EPC_IPAddress != "none" }
}
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (Iperf)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollectIperf --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}"
echo '\u2705 \u001B[32mLog Transfer (Iperf)\u001B[0m'
sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/iperf.log.zip ./iperf.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("iperf.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "iperf.log.${env.BUILD_ID}.zip"
}
}
}
}
}
}
}

View File

@@ -20,9 +20,6 @@
* contact@openairinterface.org
*/
// necessary for reading JSON
import groovy.json.JsonSlurper
// Template Jenkins Declarative Pipeline script to run Test w/ RF HW
// Location of the python executor node shall be in the same subnet as the others servers
@@ -40,12 +37,12 @@ pipeline {
stages {
stage ("Launcher") {
steps {
script {
// retrieve MR that are opened nd with tag NSA
MR_LIST = sh returnStdout: true, script: 'curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100&labels=NSA" | jq -cj "[.[].iid]"'
echo "List of selected MRs: ${MR_LIST.trim()}"
def MR_ARRAY = new JsonSlurper().parseText(MR_LIST.trim())
// for every selected MR, retrieve the branch name and the latest commit
script {
//retrieve MR that are opened nd with tag NSA
MR_LIST= sh returnStdout: true, script: 'curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100&labels=NSA" | jq ".[].iid" || true '
echo "List of selected MR:\n${MR_LIST}"
def MR_ARRAY = MR_LIST.split('\n')
//for every selected MR, retrieve the branch name and the latest commit
for (MR in MR_ARRAY) {
SRC_BRANCH=sh returnStdout: true, script: """curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/${MR}" | jq ".source_branch" || true """
SRC_BRANCH=SRC_BRANCH.trim()

View File

@@ -50,7 +50,7 @@ amarisoft_ue_1:
WakeupScript : none
DetachScript : none
#end
Cmd : /root/NV18-06-2022/ue/lteue
Cmd : /root/NV17-12-21/ue/lteue
Config : /root/NV17-12-21/ue/config/oaicicd-ue-Ping-SATest.cfg
Duration : 60
Ping : /tmp/test_ue1.log
@@ -71,7 +71,7 @@ amarisoft_ue_2:
WakeupScript : none
DetachScript : none
#end
Cmd : /root/NV18-06-2022/ue/lteue
Cmd : /root/NV17-12-21/ue/lteue
Config : /root/NV17-12-21/ue/config/xxxxxxx.cfg #to be updated for an other scenario
Duration : 60
Ping :

View File

@@ -74,7 +74,6 @@ class Containerize():
self.eNB2SourceCodePath = ''
self.forcedWorkspaceCleanup = False
self.imageKind = ''
self.proxyCommit = None
self.eNB_instance = 0
self.eNB_serverId = ['', '', '']
self.yamlPath = ['', '', '']
@@ -422,143 +421,6 @@ class Containerize():
HTML.CreateHtmlTabFooter(False)
sys.exit(1)
def BuildProxy(self, HTML):
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
if self.eNB_serverId[self.eNB_instance] == '0':
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
lPassWord = self.eNBPassword
lSourcePath = self.eNBSourceCodePath
elif self.eNB_serverId[self.eNB_instance] == '1':
lIpAddr = self.eNB1IPAddress
lUserName = self.eNB1UserName
lPassWord = self.eNB1Password
lSourcePath = self.eNB1SourceCodePath
elif self.eNB_serverId[self.eNB_instance] == '2':
lIpAddr = self.eNB2IPAddress
lUserName = self.eNB2UserName
lPassWord = self.eNB2Password
lSourcePath = self.eNB2SourceCodePath
if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
if self.proxyCommit is None:
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter (need proxyCommit for proxy build)')
logging.debug('Building on server: ' + lIpAddr)
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
# Check that we are on Ubuntu
mySSH.command('hostnamectl', '\$', 5)
result = re.search('Ubuntu', mySSH.getBefore())
self.host = result.group(0)
if self.host != 'Ubuntu':
logging.error('\u001B[1m Can build proxy only on Ubuntu server\u001B[0m')
mySSH.close()
sys.exit(1)
self.cli = 'docker'
self.cliBuildOptions = '--no-cache'
# Workaround for some servers, we need to erase completely the workspace
if self.forcedWorkspaceCleanup:
mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15)
oldRanCommidID = self.ranCommitID
oldRanRepository = self.ranRepository
oldRanAllowMerge = self.ranAllowMerge
self.ranCommitID = self.proxyCommit
self.ranRepository = 'https://github.com/EpiSci/oai-lte-5g-multi-ue-proxy.git'
self.ranAllowMerge = False
self._createWorkspace(mySSH, lPassWord, lSourcePath)
# to prevent accidentally overwriting data that might be used later
self.ranCommitID = oldRanCommidID
self.ranRepository = oldRanRepository
self.ranAllowMerge = oldRanAllowMerge
# Let's remove any previous run artifacts if still there
mySSH.command(self.cli + ' image prune --force', '\$', 30)
# Remove any previous proxy image
mySSH.command(self.cli + ' image rm oai-lte-multi-ue-proxy:latest || true', '\$', 30)
tag = self.proxyCommit
logging.debug('building L2sim proxy image for tag ' + tag)
# check if the corresponding proxy image with tag exists. If not, build it
mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' proxy:' + tag, '\$', 5)
buildProxy = mySSH.getBefore().count('o such image') != 0
if buildProxy:
mySSH.command(self.cli + ' build ' + self.cliBuildOptions + ' --target oai-lte-multi-ue-proxy --tag proxy:' + tag + ' --file docker/Dockerfile.ubuntu18.04 . > cmake_targets/log/proxy-build.log 2>&1', '\$', 180)
# Note: at this point, OAI images are flattened, but we cannot do this
# here, as the flatten script is not in the proxy repo
mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' proxy:' + tag, '\$', 5)
if mySSH.getBefore().count('o such image') != 0:
logging.error('\u001B[1m Build of L2sim proxy failed\u001B[0m')
mySSH.close()
HTML.CreateHtmlTestRow('commit ' + tag, 'KO', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlTabFooter(False)
sys.exit(1)
else:
logging.debug('L2sim proxy image for tag ' + tag + ' already exists, skipping build')
# retag the build images to that we pick it up later
mySSH.command('docker image tag proxy:' + tag + ' oai-lte-multi-ue-proxy:latest', '\$', 5)
# no merge: is a push to develop, tag the image so we can push it to the registry
if not self.ranAllowMerge:
mySSH.command('docker image tag proxy:' + tag + ' proxy:develop', '\$', 5)
# we assume that the host on which this is built will also run the proxy. The proxy
# currently requires the following command, and the docker-compose up mechanism of
# the CI does not allow to run arbitrary commands. Note that the following actually
# belongs to the deployment, not the build of the proxy...
logging.warning('the following command belongs to deployment, but no mechanism exists to exec it there!')
mySSH.command('sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up', '\$', 5)
# Analyzing the logs
if buildProxy:
self.testCase_id = HTML.testCase_id
mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
mySSH.command('mkdir -p proxy_build_log_' + self.testCase_id, '\$', 5)
mySSH.command('mv log/* ' + 'proxy_build_log_' + self.testCase_id, '\$', 5)
if (os.path.isfile('./proxy_build_log_' + self.testCase_id + '.zip')):
os.remove('./proxy_build_log_' + self.testCase_id + '.zip')
if (os.path.isdir('./proxy_build_log_' + self.testCase_id)):
shutil.rmtree('./proxy_build_log_' + self.testCase_id)
mySSH.command('zip -r -qq proxy_build_log_' + self.testCase_id + '.zip proxy_build_log_' + self.testCase_id, '\$', 5)
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/build_log_' + self.testCase_id + '.zip', '.')
# don't delete such that we might recover the zips
#mySSH.command('rm -f build_log_' + self.testCase_id + '.zip','\$', 5)
# we do not analyze the logs (we assume the proxy builds fine at this stage),
# but need to have the following information to correctly display the HTML
files = {}
errorandwarnings = {}
errorandwarnings['errors'] = 0
errorandwarnings['warnings'] = 0
errorandwarnings['status'] = True
files['Target Image Creation'] = errorandwarnings
self.collectInfo['proxy'] = files
mySSH.command('docker image inspect --format=\'Size = {{.Size}} bytes\' proxy:' + tag, '\$', 5)
result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', mySSH.getBefore())
if result is not None:
imageSize = float(result.group('size')) / 1000000
logging.debug('\u001B[1m proxy size is ' + ('%.0f' % imageSize) + ' Mbytes\u001B[0m')
self.allImagesSize['proxy'] = str(round(imageSize,1)) + ' Mbytes'
else:
logging.debug('proxy size is unknown')
self.allImagesSize['proxy'] = 'unknown'
# Cleaning any created tmp volume
mySSH.command(self.cli + ' volume prune --force || true','\$', 15)
mySSH.close()
logging.info('\u001B[1m Building L2sim Proxy Image Pass\u001B[0m')
HTML.CreateHtmlTestRow('commit ' + tag, 'OK', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlNextTabHeaderTestRow(self.collectInfo, self.allImagesSize)
def Copy_Image_to_Test_Server(self, HTML):
imageTag = 'develop'
if (self.ranAllowMerge):
@@ -579,17 +441,9 @@ class Containerize():
lUserName = self.eNB2UserName
lPassWord = self.eNB2Password
lSsh.open(lIpAddr, lUserName, lPassWord)
lSsh.command('docker save ' + self.imageToCopy + ':' + imageTag + ' | gzip --fast > ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60)
ret = lSsh.copyin(lIpAddr, lUserName, lPassWord, '~/' + self.imageToCopy + '-' + imageTag + '.tar.gz', '.')
if ret != 0:
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
self.exitStatus = 1
return False
lSsh.command('docker save ' + self.imageToCopy + ':' + imageTag + ' | gzip > ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60)
lSsh.copyin(lIpAddr, lUserName, lPassWord, '~/' + self.imageToCopy + '-' + imageTag + '.tar.gz', '.')
lSsh.command('rm ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60)
if lSsh.getBefore().count('cannot remove'):
HTML.CreateHtmlTestRow('file not created by docker save', 'KO', CONST.ALL_PROCESSES_OK)
self.exitStatus = 1
return False
lSsh.close()
# Going to the Test Server
@@ -607,26 +461,15 @@ class Containerize():
lPassWord = self.eNB2Password
lSsh.open(lIpAddr, lUserName, lPassWord)
lSsh.copyout(lIpAddr, lUserName, lPassWord, './' + self.imageToCopy + '-' + imageTag + '.tar.gz', '~')
# copyout has no return code and will quit if something fails
lSsh.command('docker rmi ' + self.imageToCopy + ':' + imageTag, '\$', 10)
lSsh.command('docker load < ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60)
if lSsh.getBefore().count('o such file') or lSsh.getBefore().count('invalid tar header'):
logging.debug(lSsh.getBefore())
HTML.CreateHtmlTestRow('problem during docker load', 'KO', CONST.ALL_PROCESSES_OK)
self.exitStatus = 1
return False
lSsh.command('rm ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60)
if lSsh.getBefore().count('cannot remove'):
HTML.CreateHtmlTestRow('file not copied during scp?', 'KO', CONST.ALL_PROCESSES_OK)
self.exitStatus = 1
return False
lSsh.close()
if os.path.isfile('./' + self.imageToCopy + '-' + imageTag + '.tar.gz'):
os.remove('./' + self.imageToCopy + '-' + imageTag + '.tar.gz')
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
return True
def DeployObject(self, HTML, EPC):
if self.eNB_serverId[self.eNB_instance] == '0':
@@ -702,9 +545,6 @@ class Containerize():
logging.debug(' -- ' + str(unhealthyNb) + ' unhealthy container(s)')
logging.debug(' -- ' + str(startingNb) + ' still starting container(s)')
self.testCase_id = HTML.testCase_id
self.eNB_logFile[self.eNB_instance] = 'enb_' + self.testCase_id + '.log'
status = False
if healthyNb == 1:
cnt = 0
@@ -719,19 +559,16 @@ class Containerize():
status = True
logging.info('\u001B[1m Deploying OAI object Pass\u001B[0m')
time.sleep(10)
else:
# containers are unhealthy, so we won't start. However, logs are stored at the end
# in UndeployObject so we here store the logs of the unhealthy container to report it
mySSH.command('docker logs ' + containerName + ' > ' + lSourcePath + '/cmake_targets/' + self.eNB_logFile[self.eNB_instance], '\$', 30)
mySSH.close()
self.testCase_id = HTML.testCase_id
self.eNB_logFile[self.eNB_instance] = 'enb_' + self.testCase_id + '.log'
if status:
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
else:
self.exitStatus = 1
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
def UndeployObject(self, HTML, RAN):
if self.eNB_serverId[self.eNB_instance] == '0':
lIpAddr = self.eNBIPAddress
@@ -751,7 +588,7 @@ class Containerize():
if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
logging.debug('\u001B[1m Undeploying OAI Object from server: ' + lIpAddr + '\u001B[0m')
logging.debug('\u001B[1m Deploying OAI Object on server: ' + lIpAddr + '\u001B[0m')
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
mySSH.command('cd ' + lSourcePath + '/' + self.yamlPath[self.eNB_instance], '\$', 5)
@@ -956,26 +793,12 @@ class Containerize():
logging.debug(cmd)
subprocess.run(cmd, shell=True)
# check which containers are running for log recovery later
# if the containers are running, recover the logs!
cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml ps --all'
logging.debug(cmd)
deployStatusLogs = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=30)
# Stop the containers to shut down objects
logging.debug('\u001B[1m Stopping containers \u001B[0m')
cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml stop'
logging.debug(cmd)
try:
deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100)
except Exception as e:
self.exitStatus = 1
logging.error('Could not stop containers')
HTML.CreateHtmlTestRow('Could not stop', 'KO', CONST.ALL_PROCESSES_OK)
logging.error('\u001B[1m Undeploying OAI Object(s) FAILED\u001B[0m')
return
deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=30)
anyLogs = False
for state in deployStatusLogs.split('\n'):
for state in deployStatus.split('\n'):
res = re.search('Name|----------', state)
if res is not None:
continue

View File

@@ -1329,7 +1329,7 @@ class OaiCiTest():
SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
if self.ADBCentralized:
SSH.command('adb devices', '\$', 15)
self.UEDevices = re.findall('\r\n([A-Za-z0-9]+)\tdevice',SSH.getBefore())
self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore())
#report number and id of devices found
msg = "UEDevices found by GetAllUEDevices : " + " ".join(self.UEDevices)
logging.debug(msg)
@@ -1379,7 +1379,8 @@ class OaiCiTest():
SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
if self.ADBCentralized:
SSH.command('lsusb | egrep --colour=never "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15)
self.CatMDevices = re.findall('\r\n([A-Za-z0-9_]+)',SSH.getBefore())
#self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore())
self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore())
else:
if (os.path.isfile('./modules_list.txt')):
os.remove('./modules_list.txt')
@@ -2045,7 +2046,7 @@ class OaiCiTest():
req_bandwidth = '%.1f Gbits/sec' % req_bw
req_bw = req_bw * 1000000000
result = re.search('Server Report:\r\n(?:|\[ *\d+\].*) (?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P<packetloss>[0-9\.]+)%\))', SSH.getBefore())
result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P<packetloss>[0-9\.]+)%\))', SSH.getBefore())
if result is not None:
bitrate = result.group('bitrate')
packetloss = result.group('packetloss')
@@ -2261,7 +2262,7 @@ class OaiCiTest():
def Iperf_analyzeV3Output(self, lock, UE_IPAddress, device_id, statusQueue,SSH):
result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P<packetloss>[0-9\.]+)%\)) +(?:|receiver)\r\n(?:|\[ *\d+\] Sent \d+ datagrams)\r\niperf Done\.', SSH.getBefore())
result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P<packetloss>[0-9\.]+)%\)) +(?:|receiver)\\\\r\\\\n(?:|\[ *\d+\] Sent \d+ datagrams)\\\\r\\\\niperf Done\.', SSH.getBefore())
if result is None:
result = re.search('(?P<error>iperf: error - [a-zA-Z0-9 :]+)', SSH.getBefore())
lock.acquire()
@@ -3864,7 +3865,7 @@ class OaiCiTest():
SSH = sshconnection.SSHConnection()
SSH.open(IPAddress, UserName, Password)
SSH.command('lsb_release -a', '\$', 5)
result = re.search('Description:\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore())
result = re.search('Description:\\\\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore())
if result is not None:
OsVersion = result.group('os_type')
logging.debug('OS is: ' + OsVersion)
@@ -3882,13 +3883,13 @@ class OaiCiTest():
logging.debug('OS is: ' + OsVersion)
HTML.OsVersion[idx]=OsVersion
SSH.command('uname -r', '\$', 5)
result = re.search('uname -r\r\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', SSH.getBefore())
result = re.search('uname -r\\\\r\\\\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', SSH.getBefore())
if result is not None:
KernelVersion = result.group('kernel_version')
logging.debug('Kernel Version is: ' + KernelVersion)
HTML.KernelVersion[idx]=KernelVersion
SSH.command('dpkg --list | egrep --color=never libuhd', '\$', 5)
result = re.search('libuhd.*:amd64 *(?P<uhd_version>[0-9\.]+)', SSH.getBefore())
SSH.command('dpkg --list | egrep --color=never libuhd003', '\$', 5)
result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', SSH.getBefore())
if result is not None:
UhdVersion = result.group('uhd_version')
logging.debug('UHD Version is: ' + UhdVersion)
@@ -3901,7 +3902,7 @@ class OaiCiTest():
logging.debug('UHD Version is: ' + UhdVersion)
HTML.UhdVersion[idx]=UhdVersion
SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 180)
usrp_boards = re.findall('product: ([0-9A-Za-z]+)', SSH.getBefore())
usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', SSH.getBefore())
count = 0
for board in usrp_boards:
if count == 0:
@@ -3913,18 +3914,14 @@ class OaiCiTest():
logging.debug('USRP Board(s) : ' + UsrpBoard)
HTML.UsrpBoard[idx]=UsrpBoard
SSH.command('lscpu', '\$', 5)
result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+)', SSH.getBefore())
result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+).*Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', SSH.getBefore())
if result is not None:
CpuNb = result.group('nb_cpus')
logging.debug('nb_cpus: ' + CpuNb)
HTML.CpuNb[idx]=CpuNb
result = re.search('Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+)', SSH.getBefore())
if result is not None:
CpuModel = result.group('model')
logging.debug('model: ' + CpuModel)
HTML.CpuModel[idx]=CpuModel
result = re.search('CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', SSH.getBefore())
if result is not None:
CpuMHz = result.group('cpu_mhz') + ' MHz'
logging.debug('cpu_mhz: ' + CpuMHz)
HTML.CpuMHz[idx]=CpuMHz

View File

@@ -141,7 +141,7 @@ class PhySim:
logging.debug('oai-physim size is unknown')
# logging to OC Cluster and then switch to corresponding project
mySSH.command(f'oc login -u {ocUserName} -p {ocPassword} --server https://api.oai.cs.eurecom.fr:6443', '\$', 30)
mySSH.command(f'oc login -u {ocUserName} -p {ocPassword}', '\$', 30)
if mySSH.getBefore().count('Login successful.') == 0:
logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m')
mySSH.close()

View File

@@ -214,6 +214,52 @@ MACRLCs = (
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
thread_pool_size = 8;
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 150;
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
#beamforming 1x4 matrix:
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
#clock_src = "external";
sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
rfsimulator :
{
serveraddr = "server";
serverport = "4043";
options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs";
};
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen

View File

@@ -218,6 +218,16 @@ MACRLCs = (
}
)
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
log_config =
{
global_log_level ="info";

View File

@@ -215,6 +215,52 @@ MACRLCs = (
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
thread_pool_size = 8;
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 150;
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
#beamforming 1x4 matrix:
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
#clock_src = "external";
sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
rfsimulator :
{
serveraddr = "server";
serverport = "4043";
options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs";
};
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen

View File

@@ -235,6 +235,16 @@ MACRLCs = (
}
)
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
log_config =
{
global_log_level ="info";

View File

@@ -33,7 +33,6 @@ gNBs =
////////// Physical parameters:
min_rxtxtime = 6;
enable_sdap = 1;
pdcch_ConfigSIB1 = (
{

View File

@@ -0,0 +1,240 @@
Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "3GPP_eNODEB";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2680000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 50;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
pbch_repetition = "FALSE";
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 0;
pucch_nCS_AN = 0;
pucch_n1_AN = 0;
pdsch_referenceSignalPower = -27;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -96;
pusch_alpha = "AL1";
pucch_p0_Nominal = -104;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "10.193.4.249";
ipv6 = "";
active = "yes";
preference = "ipv4";
}
);
enable_measurement_reports = "no";
///X2
enable_x2 = "no";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth1";
ENB_IPV4_ADDRESS_FOR_S1_MME = "10.193.4.248";
ENB_INTERFACE_NAME_FOR_S1U = "eth1";
ENB_IPV4_ADDRESS_FOR_S1U = "10.193.4.248";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "10.193.4.248";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
phy_test_mode = 0;
puSch10xSnr = 160;
puCch10xSnr = 160;
#scheduler_mode = "fairRR";
#scheduler_mode = "default";
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 120;
eNB_instances = [0];
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_DISABLE";
}
);
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
FLEXRAN_INTERFACE_NAME = "lo";
FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
log_config :
{
global_log_level ="warn";
global_log_verbosity ="high";
hw_log_level ="warn";
hw_log_verbosity ="high";
phy_log_level ="warn";
phy_log_verbosity ="high";
mac_log_level ="warn";
mac_log_verbosity ="high";
rlc_log_level ="warn";
rlc_log_verbosity ="high";
pdcp_log_level ="warn";
pdcp_log_verbosity ="high";
rrc_log_level ="warn";
rrc_log_verbosity ="high";
};

View File

@@ -0,0 +1,238 @@
Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "3GPP_eNODEB";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2680000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 50;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
pbch_repetition = "FALSE";
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 0;
pucch_nCS_AN = 0;
pucch_n1_AN = 0;
pdsch_referenceSignalPower = -27;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -96;
pusch_alpha = "AL1";
pucch_p0_Nominal = -104;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "10.193.4.249";
ipv6 = "";
active = "yes";
preference = "ipv4";
}
);
enable_measurement_reports = "no";
///X2
enable_x2 = "no";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth1";
ENB_IPV4_ADDRESS_FOR_S1_MME = "10.193.4.248";
ENB_INTERFACE_NAME_FOR_S1U = "eth1";
ENB_IPV4_ADDRESS_FOR_S1U = "10.193.4.248";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "10.193.4.248";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
phy_test_mode = 0;
puSch10xSnr = 160;
puCch10xSnr = 160;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 116;
eNB_instances = [0];
sdr_addrs = "type=x300";
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_DISABLE";
}
);
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
FLEXRAN_INTERFACE_NAME = "lo";
FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
log_config :
{
global_log_level ="warn";
global_log_verbosity ="high";
hw_log_level ="warn";
hw_log_verbosity ="high";
phy_log_level ="warn";
phy_log_verbosity ="high";
mac_log_level ="warn";
mac_log_verbosity ="high";
rlc_log_level ="warn";
rlc_log_verbosity ="high";
pdcp_log_level ="warn";
pdcp_log_verbosity ="high";
rrc_log_level ="warn";
rrc_log_verbosity ="high";
};

View File

@@ -46,7 +46,6 @@ ENB_PROCESS_NOLOGFILE_TO_ANALYZE = -14
ENB_PROCESS_SLAVE_RRU_NOT_SYNCED = -15
ENB_REAL_TIME_PROCESSING_ISSUE = -16
ENB_RETX_ISSUE = -17
ENB_SHUTDOWN_NO_BYE = -18
HSS_PROCESS_FAILED = -2
HSS_PROCESS_OK = +2
MME_PROCESS_FAILED = -3

View File

@@ -253,7 +253,7 @@ class EPCManagement():
logging.debug('Starting OAI CN5G')
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5)
mySSH.command('cd /opt/oai-cn5g-fed-v1.4/docker-compose', '\$', 5)
mySSH.command('cd /opt/oai-cn5g-fed-v1.3/docker-compose', '\$', 5)
mySSH.command('python3 ./core-network.py '+self.cfgDeploy, '\$', 60)
if re.search('start-mini-as-ue', self.cfgDeploy):
dFile = 'docker-compose-mini-nrf-asue.yaml'
@@ -311,8 +311,6 @@ class EPCManagement():
tmp = str(response[0],'utf-8')
self.MmeIPAddress = tmp.rstrip()
logging.debug('AMF IP Address ' + self.MmeIPAddress)
else:
logging.error('no container with name oai-amf found, could not retrieve AMF IP address')
mySSH.close()
def CheckHSSProcess(self, status_queue):
@@ -537,7 +535,7 @@ class EPCManagement():
mySSH.command('docker logs ' + c + ' > ' + self.SourceCodePath + '/logs/' + c + '.log', '\$', 5)
logging.debug('Terminating OAI CN5G')
mySSH.command('cd /opt/oai-cn5g-fed-v1.4/docker-compose', '\$', 5)
mySSH.command('cd /opt/oai-cn5g-fed-v1.3/docker-compose', '\$', 5)
mySSH.command('python3 ./core-network.py '+self.cfgUnDeploy, '\$', 60)
mySSH.command('docker volume prune --force || true', '\$', 60)
time.sleep(2)

View File

@@ -102,7 +102,7 @@ def AssignParams(params_dict):
def GetParametersFromXML(action):
if action == 'Build_eNB' or action == 'Build_Image' or action == 'Build_Proxy':
if action == 'Build_eNB' or action == 'Build_Image':
RAN.Build_eNB_args=test.findtext('Build_eNB_args')
CONTAINERS.imageKind=test.findtext('kind')
forced_workspace_cleanup = test.findtext('forced_workspace_cleanup')
@@ -138,9 +138,6 @@ def GetParametersFromXML(action):
RAN.backgroundBuild=True
else:
RAN.backgroundBuild=False
proxy_commit = test.findtext('proxy_commit')
if proxy_commit is not None:
CONTAINERS.proxyCommit = proxy_commit
elif action == 'WaitEndBuild_eNB':
RAN.Build_eNB_args=test.findtext('Build_eNB_args')
@@ -918,16 +915,10 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
HTML=ldpc.Run_PhySim(HTML,CONST,id)
elif action == 'Build_Image':
CONTAINERS.BuildImage(HTML)
elif action == 'Build_Proxy':
CONTAINERS.BuildProxy(HTML)
elif action == 'Copy_Image_to_Test':
success = CONTAINERS.Copy_Image_to_Test_Server(HTML)
if not success:
RAN.prematureExit = True
CONTAINERS.Copy_Image_to_Test_Server(HTML)
elif action == 'Deploy_Object':
CONTAINERS.DeployObject(HTML, EPC)
if CONTAINERS.exitStatus==1:
RAN.prematureExit = True
elif action == 'Undeploy_Object':
CONTAINERS.UndeployObject(HTML, RAN)
elif action == 'Cppcheck_Analysis':

View File

@@ -374,7 +374,7 @@ class RANManagement():
mySSH.open(lIpAddr, lUserName, lPassWord)
eth_interface = 'any'
fltr = 'sctp'
logging.debug('\u001B[1m Launching tshark on xNB on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m')
logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m')
pcapfile = pcapfile_prefix + self.testCase_id + '_log.pcap'
mySSH.command('echo ' + lPassWord + ' | sudo -S rm -f /tmp/' + pcapfile , '\$', 5)
mySSH.command('echo $USER; nohup sudo -E tshark -i ' + eth_interface + ' -f "' + fltr + '" -w /tmp/' + pcapfile + ' > /dev/null 2>&1 &','\$', 5)
@@ -390,7 +390,7 @@ class RANManagement():
mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword)
eth_interface = 'any'
fltr = 'sctp'
logging.debug('\u001B[1m Launching tshark on EPC on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m')
logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m')
self.epcPcapFile = 'enb_' + self.testCase_id + '_s1log.pcap'
mySSH.command('echo ' + localEpcPassword + ' | sudo -S rm -f /tmp/' + self.epcPcapFile , '\$', 5)
mySSH.command('echo $USER; nohup sudo tshark -f "host ' + lIpAddr +'" -i ' + eth_interface + ' -f "' + fltr + '" -w /tmp/' + self.epcPcapFile + ' > /tmp/tshark.log 2>&1 &', localEpcUserName, 5)
@@ -517,7 +517,7 @@ class RANManagement():
localEpcUserName = EPC.UserName
localEpcPassword = EPC.Password
mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword)
logging.debug('\u001B[1m Stopping tshark on EPC \u001B[0m')
logging.debug('\u001B[1m Stopping tshark \u001B[0m')
mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
if self.epcPcapFile != '':
mySSH.command('echo ' + localEpcPassword + ' | sudo -S chmod 666 /tmp/' + self.epcPcapFile, '\$', 5)
@@ -644,16 +644,18 @@ class RANManagement():
time.sleep(5)
mySSH.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
#stopping tshark (valid if eNB and enabled in xml, will not harm otherwise)
logging.debug('\u001B[1m Stopping tshark on xNB \u001B[0m')
logging.debug('\u001B[1m Stopping tshark \u001B[0m')
mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
time.sleep(1)
mySSH.close()
if EPC.IPAddress != "none" and EPC.IPAddress != '':
# If tracer options is on, stopping tshark on EPC side
result = re.search('T_stdout', str(self.Initialize_eNB_args))
if (result is not None):
localEpcIpAddr = EPC.IPAddress
localEpcUserName = EPC.UserName
localEpcPassword = EPC.Password
logging.debug('\u001B[1m Stopping tshark on EPC (' + localEpcIpAddr + ') \u001B[0m')
mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword)
logging.debug('\u001B[1m Stopping tshark \u001B[0m')
mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
time.sleep(1)
if self.epcPcapFile != '':
@@ -812,7 +814,6 @@ class RANManagement():
ULRetxIssue = False
nrRrcRcfgComplete = 0
harqFeedbackPast = 0
showedByeMsg = False # last line is Bye. -> stopped properly
line_cnt=0 #log file line counter
for line in enb_log_file.readlines():
@@ -1025,12 +1026,6 @@ class RANManagement():
if result is not None:
gnb_markers[k].append(line_cnt)
# check whether e/gNB log finishes with "Bye." message
# Note that it is "=" not "|=" so not only is the regex
# asking for EOF (\Z) but we also only retain the last
# line's result
showedByeMsg = re.search(r'^Bye.\n\Z', str(line), re.MULTILINE) is not None
enb_log_file.close()
@@ -1215,13 +1210,6 @@ class RANManagement():
logging.debug('No real time stats found in the log file')
htmleNBFailureMsg += statMsg
if not showedByeMsg:
logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB did not show "Bye." message at end, it likely did not stop properly! \u001B[0m')
htmleNBFailureMsg += 'No Bye. message found, did not stop properly\n'
global_status = CONST.ENB_SHUTDOWN_NO_BYE
else:
logging.debug('"Bye." message found at end.')
else:
#Removing UE log
statMsg = '[MAC] Removing UE msg count = '+str(removing_ue)

View File

@@ -60,7 +60,7 @@ class SSHConnection():
count = 0
connect_status = False
while count < 4:
self.ssh = pexpect.spawn('ssh -o PubkeyAuthentication=yes {}@{}'.format(username,ipaddress))
self.ssh = pexpect.spawn('ssh -o PubkeyAuthentication=no {}@{}'.format(username,ipaddress))
# Longer timeout at connection due to asterix slowness
self.ssh.timeout = 25
self.sshresponse = self.ssh.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', 'Last login', pexpect.EOF, pexpect.TIMEOUT])
@@ -84,11 +84,14 @@ class SSHConnection():
else:
logging.debug('self.sshresponse = ' + str(self.sshresponse))
elif self.sshresponse == 2:
# We directly ended up on the remote server because of pubkey auth
count = 10
connect_status = True
# this expect() seems to be necessary to advance the read buffer until the prompt, or getBefore() will not return the last command
self.sshresponse = self.ssh.expect([prompt])
# Checking if we are really on the remote client defined by its IP address
self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:|inet "', prompt, 5)
result = re.search(str(ipaddress), str(self.ssh.before))
if result is None:
self.close()
else:
count = 10
connect_status = True
else:
# debug output
logging.debug(str(self.ssh.before))
@@ -269,4 +272,4 @@ class SSHConnection():
sys.exit('SCP failed')
def getBefore(self):
return self.ssh.before.decode('utf-8')
return str(self.ssh.before)

View File

@@ -1,4 +1,3 @@
- Build_Proxy
- Build_PhySim
- Run_PhySim
- Build_eNB

View File

@@ -1,42 +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
-->
<testCaseList>
<htmlTabRef>l2sim-4glte-proxy-build</htmlTabRef>
<htmlTabName>Build L2sim proxy image</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
000001
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>Build_Proxy</class>
<desc>Build L2sim Proxy Image</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
<proxy_commit>56cfdc0</proxy_commit>
</testCase>
</testCaseList>

View File

@@ -1,135 +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
-->
<testCaseList>
<htmlTabRef>l2sim-4glte-tdd</htmlTabRef>
<htmlTabName>Testing 4G LTE L2 sim - FDD eNB</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<repeatCount>2</repeatCount>
<TestCaseRequestedList>
100001
000000
000001
000002
000003
000011
200000
020001
020002
030011
030012
200001
100001
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000000">
<class>DeployGenObject</class>
<desc>Deploy Cassandra Database</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
<services>cassandra db_init</services>
<nb_healthy>1</nb_healthy>
</testCase>
<testCase id="000001">
<class>DeployGenObject</class>
<desc>Deploy OAI 4G CoreNetwork</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
<services>oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen</services>
<nb_healthy>7</nb_healthy>
</testCase>
<testCase id="000002">
<class>DeployGenObject</class>
<desc>Deploy OAI 4G eNB L2 sim</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
<services>oai_enb</services>
<nb_healthy>8</nb_healthy>
</testCase>
<testCase id="000003">
<class>DeployGenObject</class>
<desc>Deploy OAI L2 sim 4G LTE-UE 1 and Proxy</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
<services>proxy oai_ue1</services>
<nb_healthy>10</nb_healthy>
</testCase>
<testCase id="000011">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>
<testCase id="020001">
<class>PingFromContainer</class>
<desc>Ping trf-gen from LTE-UE 1</desc>
<container_name>l2sim4g-oai-lte-ue1</container_name>
<options>-I oaitun_ue1 -c 20 192.168.61.11</options>
<loss_threshold>0</loss_threshold>
</testCase>
<testCase id="020002">
<class>PingFromContainer</class>
<desc>Ping LTE-UE 1 from trf-gen</desc>
<container_name>l2sim4g-trf-gen</container_name>
<options>-c 20 12.0.0.2</options>
<loss_threshold>0</loss_threshold>
</testCase>
<testCase id="030011">
<class>IperfFromContainer</class>
<desc>Iperf UDP Downlink</desc>
<server_container_name>l2sim4g-oai-lte-ue1</server_container_name>
<client_container_name>l2sim4g-trf-gen</client_container_name>
<server_options>-B 12.0.0.2 -u -i 1 -s</server_options>
<client_options>-c 12.0.0.2 -u -i 1 -t 30 -b 1M</client_options>
</testCase>
<testCase id="030012">
<class>IperfFromContainer</class>
<desc>Iperf UDP Uplink</desc>
<server_container_name>l2sim4g-trf-gen</server_container_name>
<client_container_name>l2sim4g-oai-lte-ue1</client_container_name>
<server_options>-u -i 1 -s</server_options>
<client_options>-B 12.0.0.2 -c 192.168.61.11 -u -i 1 -t 30 -b 3M</client_options>
</testCase>
<testCase id="100001">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 4G stack</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
</testCase>
<testCase id="200000">
<class>StatsFromGenObject</class>
<desc>Statistics before Traffic Test</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
</testCase>
<testCase id="200001">
<class>StatsFromGenObject</class>
<desc>Statistics after Traffic Test</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
</testCase>
</testCaseList>

View File

@@ -1,38 +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
-->
<testCaseList>
<htmlTabRef>l2sim-4glte-down</htmlTabRef>
<htmlTabName>CleanUp 4G L2 sim - FDD eNB</htmlTabName>
<htmlTabIcon>trash</htmlTabIcon>
<TestCaseRequestedList>
100002
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="100002">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 4G stack</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
</testCase>
</testCaseList>

View File

@@ -22,7 +22,7 @@
-->
<testCaseList>
<htmlTabRef>rfsim-5gnr-f1</htmlTabRef>
<htmlTabName>CU-DU F1 split</htmlTabName>
<htmlTabName>Testing 5G NR RF sim in containers - CU-DU F1 split</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
100021

View File

@@ -22,7 +22,7 @@
-->
<testCaseList>
<htmlTabRef>rfsim-5gnr-down-f1</htmlTabRef>
<htmlTabName>CleanUp CU-DU F1 split</htmlTabName>
<htmlTabName>CleanUp 5G RF - CU-DU F1 split</htmlTabName>
<htmlTabIcon>trash</htmlTabIcon>
<TestCaseRequestedList>
100022

View File

@@ -22,7 +22,7 @@
-->
<testCaseList>
<htmlTabRef>rfsim-5gnr-fdd</htmlTabRef>
<htmlTabName>Monolithic FDD gNB with SDAP</htmlTabName>
<htmlTabName>Testing 5G NR RF sim - Monolithic FDD gNB</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<repeatCount>4</repeatCount>
<TestCaseRequestedList>

View File

@@ -22,7 +22,7 @@
-->
<testCaseList>
<htmlTabRef>rfsim-5gnr-fdd-down</htmlTabRef>
<htmlTabName>CleanUp Monolithic FDD gNB with SDAP</htmlTabName>
<htmlTabName>CleanUp 5G RF - Monolithic FDD gNB</htmlTabName>
<htmlTabIcon>trash</htmlTabIcon>
<TestCaseRequestedList>
100012

View File

@@ -22,7 +22,7 @@
-->
<testCaseList>
<htmlTabRef>rfsim-5gnr-tdd</htmlTabRef>
<htmlTabName>Monolithic TDD gNB</htmlTabName>
<htmlTabName>Testing 5G NR RF sim - Monolithic TDD gNB</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<repeatCount>4</repeatCount>
<TestCaseRequestedList>

View File

@@ -22,7 +22,7 @@
-->
<testCaseList>
<htmlTabRef>rfsim-5gnr-down</htmlTabRef>
<htmlTabName>CleanUp Monolithic TDD gNB</htmlTabName>
<htmlTabName>CleanUp 5G RF - Monolithic TDD gNB</htmlTabName>
<htmlTabIcon>trash</htmlTabIcon>
<TestCaseRequestedList>
100002

View File

@@ -1,42 +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
-->
<testCaseList>
<htmlTabRef>l2sim-4glte-5gnr-proxy-build</htmlTabRef>
<htmlTabName>Build L2sim proxy image</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
000001
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>Build_Proxy</class>
<desc>Build L2sim Proxy Image</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
<proxy_commit>56cfdc0</proxy_commit>
</testCase>
</testCaseList>

View File

@@ -53,6 +53,7 @@
<class>Initialize_UE</class>
<desc>Initialize Quectel</desc>
<id>idefix</id>
<UE_Trace>yes</UE_Trace>
</testCase>

View File

@@ -1,168 +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
-->
<testCaseList>
<htmlTabRef>TEST-SA-FR1-B200</htmlTabRef>
<htmlTabName>SA SanityCheck with QUECTEL</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
010002
030000
030101
000001
010000
000001
050000
050001
010002
000001
030201
</TestCaseRequestedList>
<!--
070001
070000
070002
050002
050003
-->
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010000">
<class>Initialize_UE</class>
<desc>Initialize Quectel</desc>
<id>idefix</id>
</testCase>
<testCase id="010002">
<class>Terminate_UE</class>
<desc>Terminate Quectel</desc>
<id>idefix</id>
</testCase>
<testCase id="030000">
<class>Copy_Image_to_Test</class>
<desc>Copy gNB image to test server</desc>
<image_name>oai-gnb</image_name>
<registry_svr_id>1</registry_svr_id>
<test_svr_id>0</test_svr_id>
</testCase>
<testCase id="030101">
<class>Deploy_Object</class>
<desc>Deploy gNB (TDD/Band78/40MHz/B200) in a container</desc>
<yaml_path>ci-scripts/yaml_files/sa_b200_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
</testCase>
<testCase id="050000">
<class>Ping</class>
<desc>Ping: 20pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>15</ping_rttavg_threshold>
</testCase>
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>15</ping_rttavg_threshold>
</testCase>
<testCase id="050002">
<class>Ping</class>
<desc>Ping: 20pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>15</ping_rttavg_threshold>
</testCase>
<testCase id="050003">
<class>Ping</class>
<desc>Ping: 100pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>15</ping_rttavg_threshold>
</testCase>
<testCase id="070000">
<class>Iperf</class>
<desc>iperf (DL/125Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 125M -t 60 -i 1 -fm</iperf_args>
<direction>DL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070001">
<class>Iperf</class>
<desc>iperf (UL/8Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 8M -t 60 -i 1 -fm</iperf_args>
<direction>UL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070002">
<class>Iperf</class>
<desc>iperf (BIDIR TCP)(10 sec)(single-ue profile)</desc>
<iperf_args>-t 10 --bidir</iperf_args>
<direction>BIDIR</direction>
<id>idefix</id>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="030201">
<class>Undeploy_Object</class>
<desc>Undeploy gNB</desc>
<yaml_path>ci-scripts/yaml_files/sa_b200_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
</testCaseList>

View File

@@ -1,42 +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
-->
<testCaseList>
<htmlTabRef>TEST-SA-FR1-B200-terminate</htmlTabRef>
<htmlTabName>SA tear-down in case of problem</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="030201">
<class>Undeploy_Object</class>
<desc>Undeploy gNB</desc>
<yaml_path>ci-scripts/yaml_files/sa_b200_gnb</yaml_path>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<image_tag>sa-test</image_tag>
</testCase>
</testCaseList>

View File

@@ -0,0 +1,111 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>test-f1-05</htmlTabRef>
<htmlTabName>Test-F1-CU-DU-05MHz</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>2</repeatCount>
<TestCaseRequestedList>
030201
040101
030142 030141 000002 040301 000002 040541 040601 040641 040401 040201 030201 030202
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="030141">
<class>Initialize_eNB</class>
<desc>Initialize DU (FDD/Band7/5MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/du.band7.tm1.25PRB.usrpb210.conf --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030142">
<class>Initialize_eNB</class>
<desc>Initialize CU (FDD/Band7/5MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/cu.band7.tm1.25PRB.conf --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate CU</desc>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030202">
<class>Terminate_eNB</class>
<desc>Terminate DU</desc>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040541">
<class>Ping</class>
<desc>ping (5MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040601">
<class>Iperf</class>
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040641">
<class>Iperf</class>
<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>60</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
</testCaseList>

View File

@@ -0,0 +1,111 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>test-f1-10</htmlTabRef>
<htmlTabName>Test-F1-CU-DU-10MHz</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>4</repeatCount>
<TestCaseRequestedList>
030201
040101
030152 030151 000002 040301 000002 040551 040611 040651 040401 040201 030201 030202
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="030151">
<class>Initialize_eNB</class>
<desc>Initialize DU (FDD/Band7/10MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/du.band7.tm1.50PRB.usrpb210.conf --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030152">
<class>Initialize_eNB</class>
<desc>Initialize CU (FDD/Band7/10MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/cu.band7.tm1.50PRB.conf --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate CU</desc>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030202">
<class>Terminate_eNB</class>
<desc>Terminate DU</desc>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040551">
<class>Ping</class>
<desc>ping (10MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040611">
<class>Iperf</class>
<desc>iperf (10MHz - DL/32Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 32M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040651">
<class>Iperf</class>
<desc>iperf (10MHz - UL/15Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>60</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
</testCaseList>

View File

@@ -0,0 +1,111 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>test-f1-20</htmlTabRef>
<htmlTabName>Test-F1-CU-DU-20MHz</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>4</repeatCount>
<TestCaseRequestedList>
030201
040101
030162 030161 000002 040301 000002 040561 040621 040661 040401 040201 030201 030202
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="030161">
<class>Initialize_eNB</class>
<desc>Initialize DU (FDD/Band7/20MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/du.band7.tm1.100PRB.usrpb210.conf --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030162">
<class>Initialize_eNB</class>
<desc>Initialize CU (FDD/Band7/20MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/cu.band7.tm1.100PRB.conf --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate CU</desc>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030202">
<class>Terminate_eNB</class>
<desc>Terminate DU</desc>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040561">
<class>Ping</class>
<desc>ping (20MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040621">
<class>Iperf</class>
<desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 70M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040661">
<class>Iperf</class>
<desc>iperf (20MHz - UL/15Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>60</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
</testCaseList>

View File

@@ -1,37 +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
-->
<testCaseList>
<htmlTabRef>5gc-closure</htmlTabRef>
<htmlTabName>5GC-Closure</htmlTabName>
<htmlTabIcon>log-out</htmlTabIcon>
<TestCaseRequestedList>
060000
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="060000">
<class>Terminate_5GCN</class>
<desc>Terminate 5GC</desc>
</testCase>
</testCaseList>

View File

@@ -1,38 +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
-->
<testCaseList>
<htmlTabRef>5gc-start-tab</htmlTabRef>
<htmlTabName>5GC-Start</htmlTabName>
<htmlTabIcon>log-in</htmlTabIcon>
<TestCaseRequestedList>
000100
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="000100">
<class>Initialize_5GCN</class>
<desc>Initialize 5GC</desc>
</testCase>
</testCaseList>

View File

@@ -26,7 +26,6 @@
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
010002
030000
040000
000002

View File

@@ -26,7 +26,6 @@
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
010002
031000
041000
000002

View File

@@ -26,7 +26,6 @@
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
010002
030000
040000
000002

View File

@@ -26,7 +26,6 @@
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
010002
040000
000002
010000

View File

@@ -26,7 +26,6 @@
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
010002
042000
000002
010000

View File

@@ -26,7 +26,6 @@
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
011002
041000
000002
011000

View File

@@ -26,7 +26,6 @@
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
010002
030000
000002
010000

View File

@@ -26,7 +26,6 @@
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
010002
030001
000002
010000

View File

@@ -1,305 +0,0 @@
version: '3.8'
services:
cassandra:
image: cassandra:2.1
container_name: l2sim4g-cassandra
networks:
private_net:
ipv4_address: 192.168.68.2
environment:
CASSANDRA_CLUSTER_NAME: "OAI HSS Cluster"
CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch
healthcheck:
test: /bin/bash -c "nodetool status"
interval: 10s
timeout: 5s
retries: 5
db_init:
image: cassandra:2.1
container_name: l2sim4g-db-init
depends_on: [cassandra]
deploy:
restart_policy:
condition: on-failure
max_attempts: 10
networks:
private_net:
ipv4_address: 192.168.68.4
volumes:
- ../4g_rfsimulator_fdd_05MHz/oai_db.cql:/home/oai_db.cql
entrypoint: /bin/bash -c "cqlsh --file /home/oai_db.cql 192.168.68.2 && echo 'OK'"
oai_hss:
image: oai-hss:latest
container_name: l2sim4g-oai-hss
privileged: true
depends_on: [cassandra]
networks:
private_net:
ipv4_address: 192.168.68.3
public_net:
ipv4_address: 192.168.61.2
environment:
REALM: openairinterface.org
HSS_FQDN: hss.openairinterface.org
PREFIX: /openair-hss/etc
cassandra_Server_IP: 192.168.68.2
OP_KEY: 1006020f0a478bf6b699f15c062e42b3
LTE_K: fec86ba6eb707ed08905757b1bb44b8f
APN1: oai.ipv4
APN2: internet
FIRST_IMSI: 208960100000001
NB_USERS: 10
healthcheck:
test: /bin/bash -c "pgrep oai_hss"
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:6.0.5
container_name: l2sim4g-redis
privileged: true
networks:
public_net:
ipv4_address: 192.168.61.6
volumes:
- ../4g_rfsimulator_fdd_05MHz/redis_extern.conf:/usr/local/etc/redis/redis.conf
entrypoint: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"
healthcheck:
test: /bin/bash -c "redis-cli -h 192.168.61.6 -p 6380 ping"
interval: 10s
timeout: 5s
retries: 5
magma_mme:
image: magma-mme:latest
container_name: l2sim4g-magma-mme
hostname: mme
privileged: true
depends_on: [oai_hss, redis]
networks:
public_net:
ipv4_address: 192.168.61.3
environment:
TZ: Europe/Paris
REALM: openairinterface.org
PREFIX: /openair-mme/etc
HSS_HOSTNAME: hss
HSS_FQDN: hss.openairinterface.org
HSS_REALM: openairinterface.org
MME_FQDN: mme.openairinterface.org
FEATURES: mme_oai
volumes:
- ../4g_rfsimulator_fdd_05MHz/mme_fd.sprint.conf:/magma-mme/etc/mme_fd.conf.tmplt
- ../4g_rfsimulator_fdd_05MHz/mme.conf:/magma-mme/etc/mme.conf
- ../4g_rfsimulator_fdd_05MHz/entrypoint.sh:/magma-mme/bin/entrypoint.sh
entrypoint: /bin/bash -c "/magma-mme/bin/entrypoint.sh"
healthcheck:
test: /bin/bash -c "pgrep oai_mme"
interval: 10s
timeout: 5s
retries: 5
oai_spgwc:
image: oai-spgwc:latest
privileged: true
depends_on: [magma_mme]
container_name: l2sim4g-oai-spgwc
networks:
public_net:
ipv4_address: 192.168.61.4
environment:
TZ: Europe/Paris
SGW_INTERFACE_NAME_FOR_S11: eth0
PGW_INTERFACE_NAME_FOR_SX: eth0
DEFAULT_DNS_IPV4_ADDRESS: 172.21.3.100
DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
PUSH_PROTOCOL_OPTION: 'true'
APN_NI_1: oai.ipv4
APN_NI_2: oai.ipv4_2
DEFAULT_APN_NI_1: oai.ipv4
UE_IP_ADDRESS_POOL_1: '12.0.0.2 - 12.0.0.254'
UE_IP_ADDRESS_POOL_2: '12.1.1.2 - 12.1.1.254'
MCC: '208'
MNC: '96'
MNC03: '096'
TAC: 1
GW_ID: 1
REALM: openairinterface.org
healthcheck:
test: /bin/bash -c "pgrep oai_spgwc"
interval: 10s
timeout: 5s
retries: 5
oai_spgwu:
image: oai-spgwu-tiny:latest
privileged: true
container_name: l2sim4g-oai-spgwu-tiny
depends_on: [oai_spgwc]
networks:
public_net:
ipv4_address: 192.168.61.5
environment:
TZ: Europe/Paris
PID_DIRECTORY: /var/run
INSTANCE: 1
SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP: eth0
PGW_INTERFACE_NAME_FOR_SGI: eth0
SGW_INTERFACE_NAME_FOR_SX: eth0
SPGWC0_IP_ADDRESS: 192.168.61.4
NETWORK_UE_IP: '12.0.0.0/24'
NETWORK_UE_NAT_OPTION: 'yes'
MCC: '208'
MNC: '96'
MNC03: '096'
TAC: 1
GW_ID: 1
REALM: openairinterface.org
healthcheck:
test: /bin/bash -c "pgrep oai_spgwu"
interval: 10s
timeout: 5s
retries: 5
trf_gen:
image: trf-gen:production
privileged: true
container_name: l2sim4g-trf-gen
networks:
public_net:
ipv4_address: 192.168.61.11
entrypoint: /bin/bash -c "ip route add 12.0.0.0/24 via 192.168.61.5 dev eth0; sleep infinity"
healthcheck:
test: /bin/bash -c "ping -c 2 192.168.61.5"
interval: 10s
timeout: 5s
retries: 5
oai_enb:
image: oai-enb:develop
privileged: true
container_name: l2sim4g-oai-enb
network_mode: "host"
environment:
TZ: Europe/Paris
USE_NFAPI_VNF: 'yes'
ENB_NAME: enb-l2sim-vnf
MCC: '208'
MNC: '96'
MNC_LENGTH: 2
TAC: 1
UTRA_BAND_ID: 7
DL_FREQUENCY_IN_MHZ: 2680
UL_FREQUENCY_OFFSET_IN_MHZ: 120
NID_CELL: 10
NB_PRB: 25
MME_S1C_IP_ADDRESS: 192.168.61.3
ENB_INTERFACE_NAME_FOR_S1_MME: eth0
ENB_IPV4_ADDRESS_FOR_S1_MME: 192.168.61.1
ENB_INTERFACE_NAME_FOR_S1U: eth0
ENB_IPV4_ADDRESS_FOR_S1U: 192.168.61.1
ENB_IPV4_ADDRESS_FOR_X2C: 192.168.61.1
FLEXRAN_ENABLED: 'no'
FLEXRAN_INTERFACE_NAME: eth0
FLEXRAN_IPV4_ADDRESS: 192.168.61.1
LOCAL_S_IF_NAME: 'lo:'
REMOTE_S_ADDRESS: 127.0.0.1
LOCAL_S_ADDRESS: 127.0.0.2
USE_ADDITIONAL_OPTIONS: --MACRLCs.[0].scheduler_mode "default" --log_config.global_log_options level,nocolor,time
healthcheck:
test: /bin/bash -c "pgrep lte-softmodem"
interval: 10s
timeout: 5s
retries: 5
proxy:
image: oai-lte-multi-ue-proxy:latest
privileged: true
container_name: "l2sim4g-proxy"
network_mode: "host"
environment:
TZ: Europe/Paris
command: "/oai-lte-multi-ue-proxy/bin/proxy 1"
depends_on:
- oai_enb
healthcheck:
test: /bin/bash -c "pgrep proxy"
interval: 10s
timeout: 5s
retries: 5
oai_ue1:
image: oai-lte-ue:develop
privileged: true
container_name: l2sim4g-oai-lte-ue1
network_mode: "host"
environment:
TZ: Europe/Paris
USE_NFAPI: 'yes'
OPENAIR_DIR: /opt/oai-nr-ue
MCC: '208'
MNC: '96'
SHORT_IMSI: '0100000001'
LTE_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
OPC: 'c42449363bbad02b66d16bc975d77cc1'
MSISDN: '001011234561010'
HPLMN: 20896
UE_NFAPI_IF_NAME: eno1
ENB_IP_ADDRESS: 127.0.0.1
LTE_UE_IP_ADDRESS: 127.0.0.1
USE_ADDITIONAL_OPTIONS: --L2-emul 5 --nokrnmod 1 --num-ues 1 --node-number 2 --log_config.global_log_options level,nocolor,time
volumes:
- ../../../openair1/SIMULATION/LTE_PHY/BLER_SIMULATIONS/AWGN/AWGN_results:/opt/oai-nr-ue/openair1/SIMULATION/LTE_PHY/BLER_SIMULATIONS/AWGN/AWGN_results
healthcheck:
test: /bin/bash -c "pgrep lte-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5
oai_ue2:
image: oai-lte-ue:develop
privileged: true
container_name: l2sim4g-oai-lte-ue2
network_mode: "host"
environment:
TZ: Europe/Paris
USE_NFAPI: 'yes'
OPENAIR_DIR: /opt/oai-nr-ue
MCC: '208'
MNC: '96'
SHORT_IMSI: '0100000002'
LTE_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
OPC: 'c42449363bbad02b66d16bc975d77cc1'
MSISDN: '001011234561010'
HPLMN: 20896
UE_NFAPI_IF_NAME: eno1
ENB_IP_ADDRESS: 127.0.0.1
LTE_UE_IP_ADDRESS: 127.0.0.1
USE_ADDITIONAL_OPTIONS: --L2-emul 5 --nokrnmod 1 --num-ues 1 --node-number 3 --log_config.global_log_options level,nocolor,time
volumes:
- ../../../openair1/SIMULATION/LTE_PHY/BLER_SIMULATIONS/AWGN/AWGN_results:/opt/oai-nr-ue/openair1/SIMULATION/LTE_PHY/BLER_SIMULATIONS/AWGN/AWGN_results
healthcheck:
test: /bin/bash -c "pgrep lte-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5
networks:
private_net:
name: l2sim4g-oai-private-net
ipam:
config:
- subnet: 192.168.68.0/26
driver_opts:
com.docker.network.bridge.name: "l2sim4g-private"
public_net:
name: l2sim4g-oai-public-net
ipam:
config:
- subnet: 192.168.61.0/26
driver_opts:
com.docker.network.bridge.name: "l2sim4g-public"

View File

@@ -2,7 +2,7 @@ version: '3.8'
services:
oai-nrf:
container_name: "l2sim-oai-nrf"
image: oai-nrf:august-dev
image: oai-nrf:latest
environment:
- NRF_INTERFACE_NAME_FOR_SBI=eth0
- NRF_INTERFACE_PORT_FOR_SBI=80
@@ -42,7 +42,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "l2sim-oai-amf"
image: oai-amf:august-dev
image: oai-amf:latest
environment:
- TZ=Europe/paris
- INSTANCE=0
@@ -110,7 +110,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "l2sim-oai-smf"
image: oai-smf:august-dev
image: oai-smf:latest
environment:
- TZ=Europe/Paris
- INSTANCE=0
@@ -156,7 +156,7 @@ services:
ipv4_address: 192.168.71.133
oai-spgwu:
container_name: "l2sim-oai-spgwu"
image: oai-spgwu-tiny:august-dev
image: oai-spgwu-tiny:latest
environment:
- TZ=Europe/Paris
- PID_DIRECTORY=/var/run

View File

@@ -2,7 +2,7 @@ version: '3.8'
services:
oai-nrf:
container_name: "rfsim5g-oai-nrf"
image: oai-nrf:august-dev
image: oai-nrf:latest
environment:
- NRF_INTERFACE_NAME_FOR_SBI=eth0
- NRF_INTERFACE_PORT_FOR_SBI=80
@@ -42,7 +42,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oai-amf:august-dev
image: oai-amf:latest
environment:
- TZ=Europe/paris
- INSTANCE=0
@@ -110,7 +110,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oai-smf:august-dev
image: oai-smf:latest
environment:
- TZ=Europe/Paris
- INSTANCE=0
@@ -156,7 +156,7 @@ services:
ipv4_address: 192.168.71.133
oai-spgwu:
container_name: "rfsim5g-oai-spgwu"
image: oai-spgwu-tiny:august-dev
image: oai-spgwu-tiny:latest
environment:
- TZ=Europe/Paris
- PID_DIRECTORY=/var/run

View File

@@ -1,44 +0,0 @@
version: '3.8'
services:
gnb_mono_tdd:
image: oai-gnb:latest
privileged: true
container_name: sa-b200-gnb
environment:
USE_SA_TDD_MONO_B2XX: 'yes'
USE_B2XX: 'yes'
GNB_NAME: gNB-in-docker
MCC: '222'
MNC: '01'
MNC_LENGTH: 2
TAC: 1
NSSAI_SST: 1
NSSAI_SD0: 1
AMF_IP_ADDRESS: 172.21.16.136
GNB_NGA_IF_NAME: eth0
GNB_NGA_IP_ADDRESS: 192.168.68.194
GNB_NGU_IF_NAME: eth0
GNB_NGU_IP_ADDRESS: 192.168.68.194
USE_ADDITIONAL_OPTIONS: --sa -E -q --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx --log_config.global_log_options level,nocolor,time,line_num,function
volumes:
- /dev:/dev
networks:
public_net:
ipv4_address: 192.168.68.194
#entrypoint: /bin/bash -c "sleep infinity"
healthcheck:
# pgrep does NOT work
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
interval: 10s
timeout: 5s
retries: 5
networks:
public_net:
name: sa-b200-gnb-net
ipam:
config:
- subnet: 192.168.68.192/26
driver_opts:
com.docker.network.bridge.name: "sa-gnb-net"

View File

@@ -271,12 +271,6 @@ if (SANITIZE_ADDRESS)
# wrong in the pthread library, or something subtly wrong in this CMakeLists.txt. Use Ubuntu 20.04 instead.
endif ()
add_boolean_option(SANITIZE_UNDEFINED False "enable the undefined behavior sanitizer (UBSan)")
if (SANITIZE_UNDEFINED)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
endif ()
add_definitions("-DASN_DISABLE_OER_SUPPORT")
#########################
@@ -334,14 +328,19 @@ add_definitions("-DPACKAGE_BUGREPORT=\"openair4g-devel@lists.eurecom.fr\"")
# Debug related options
#########################################
add_boolean_option(DEBUG_ASN1C False "ASN1 coder/decoder Debug traces, see common/utils/config.h, the logs are regular OAI logs, in the log group 'ASN'")
add_boolean_option(ASN_EMIT_DEBUG False "ASN1 coder/decoder Debug")
add_boolean_option(ASN_THREAD_SAFE True "ASN1 coder/decoder Debug")
add_boolean_option(MSG_PRINT True "print debug messages")
add_boolean_option(DISABLE_XER_PRINT False "print XER Format")
add_boolean_option(XER_PRINT False "print XER Format")
add_boolean_option(RRC_MSG_PRINT False "print RRC messages")
add_boolean_option(PDCP_MSG_PRINT False "print PDCP messages to /tmp/pdcp.log")
add_boolean_option(DEBUG_PDCP_PAYLOAD False "print PDCP PDU to stdout") # if true, make sure that global and PDCP log levels are trace
add_boolean_option(DEBUG_MAC_INTERFACE False "print MAC-RLC PDU exchange to stdout") # if true, make sure that global and PDCP log levels are trace
add_boolean_option(TRACE_RLC_PAYLOAD False "print RLC PDU to stdout") # if true, make sure that global and PDCP log levels are trace
add_boolean_option(PRINT_STATS False "This adds the possibility to see the status")
add_boolean_option(T_TRACER True "Activate the T tracer, a debugging/monitoring framework" )
add_boolean_option(LATSEQ False "Active Latency Sequence tools")
add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs")
add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace")
add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace")
@@ -354,12 +353,6 @@ add_library(ITTI
)
add_dependencies(ITTI rrc_flag)
# asn1c skeletons have hardcoded this flag to make customized debug logs
# OAI uses this feature to re-use OAI LOG_I(ASN, ...)
if (DEBUG_ASN1C)
add_definitions(-DHAVE_CONFIG_H)
endif()
##################################################
# ASN.1 grammar C code generation & dependencies #
##################################################
@@ -847,6 +840,7 @@ add_boolean_option(UE_EXPANSION False "enable UE_EXPANSION w
add_boolean_option(PHY_TX_THREAD False "enable UE_EXPANSION with max 256 UE")
add_boolean_option(PRE_SCD_THREAD False "enable UE_EXPANSION with max 256 UE")
add_boolean_option(UESIM_EXPANSION False "enable UESIM_EXPANSION with max 256 UE")
add_boolean_option(ITTI_SIM False "enable itti simulator")
########################
# Include order
@@ -1209,10 +1203,10 @@ add_library(UTIL
${OPENAIR2_DIR}/UTIL/LISTS/list2.c
${OPENAIR_DIR}/common/utils/LOG/log.c
${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.c
${OPENAIR_DIR}/common/utils/LATSEQ/latseq.c
${OPENAIR2_DIR}/UTIL/MATH/oml.c
${OPENAIR2_DIR}/UTIL/OPT/probe.c
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
${OPENAIR_DIR}/common/utils/cpustats.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/backtrace.c
@@ -1729,6 +1723,7 @@ set(PHY_MEX_UE
${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ue_measurements.c
${OPENAIR_DIR}/common/utils/LOG/log.c
${OPENAIR_DIR}/common/utils/LATSEQ/latseq.c
${OPENAIR_DIR}/common/utils/T/T.c
${OPENAIR_DIR}/common/utils/T/local_tracer.c
)
@@ -1812,15 +1807,7 @@ set(NR_PDCP_SRC
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
#hack: include these files to compile the nr phy simulators
#these files should not be here, will be removed at some point when the
#computation is done directly inside nr_pdcp_integrity_nia1.c instead
#of reusing code of osa_stream_eia.c
${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c
${OPENAIR2_DIR}/UTIL/OSA/osa_snow3g.c
${OPENAIR2_DIR}/UTIL/OSA/osa_rijndael.c
)
set(NR_SDAP_SRC
@@ -1874,8 +1861,6 @@ set(L2_NR_SRC
${NR_RRC_DIR}/rrc_gNB.c
${NR_RRC_DIR}/nr_rrc_common.c
${NR_RRC_DIR}/L2_nr_interface.c
${NR_RRC_DIR}/mac_rrc_dl_direct.c
${NR_RRC_DIR}/mac_rrc_dl_f1ap.c
${NR_RRC_DIR}/nr_rrc_config.c
${NR_RRC_DIR}/rrc_gNB_nsa.c
${NR_RRC_DIR}/rrc_gNB_internode.c
@@ -1954,9 +1939,6 @@ set (MAC_NR_SRC
${NR_GNB_MAC_DIR}/gNB_scheduler_uci.c
${NR_GNB_MAC_DIR}/gNB_scheduler_srs.c
${NR_GNB_MAC_DIR}/gNB_scheduler_RA.c
${NR_GNB_MAC_DIR}/mac_rrc_dl_handler.c
${NR_GNB_MAC_DIR}/mac_rrc_ul_direct.c
${NR_GNB_MAC_DIR}/mac_rrc_ul_f1ap.c
)
@@ -3036,7 +3018,7 @@ if (${T_TRACER})
foreach(i
#all "add_executable" definitions (except tests, rb_tool, updatefw)
lte-softmodem lte-uesoftmodem nr-softmodem
nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7
nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 nr-ittisim
ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim
syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim
nr_ulschsim ldpctest polartest smallblocktest cu_test du_test
@@ -3122,6 +3104,50 @@ add_executable(rb_tool
)
target_include_directories(rb_tool PRIVATE ${OPENAIR2_DIR}/NETWORK_DRIVER/MESH/)
# nr-ittisim
###################################################
add_executable(nr-ittisim
${rrc_h}
${nr_rrc_h}
${OPENAIR2_DIR}/GNB_APP/gnb_app.c
${OPENAIR2_DIR}/GNB_APP/gnb_config.c
${OPENAIR_DIR}/executables/nr-gnb.c
${OPENAIR_DIR}/executables/nr-ru.c
${OPENAIR2_DIR}/SIMULATION/NR_RRC/itti_sim.c
${OPENAIR_DIR}/executables/softmodem-common.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/common/utils/lte/ue_power.c
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api_to_fix.c
${XFORMSINTERFACE_SOURCE}
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries (nr-ittisim
-Wl,--start-group
UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECU_CN SECU_OSA
ITTI ${FLPT_MSG_LIB} ${FLEXRAN_AGENT_LIB} ${RAL_LIB} ${NAS_SIM_LIB} RRC_LIB NR_RRC_LIB
NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${FSPT_MSG_LIB}
PHY_NR_UE SCHED_NR_UE_LIB NR_L2_UE
-Wl,--end-group z dl)
target_link_libraries (nr-ittisim ${LIBXML2_LIBRARIES})
target_link_libraries (nr-ittisim pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
target_link_libraries (nr-ittisim ${LIB_LMS_LIBRARIES})
target_link_libraries (nr-ittisim ${T_LIB})
add_dependencies( nr-ittisim ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
# ???
####################
list(APPEND oai_nw_drv_src device.c common.c ioctl.c classifier.c tool.c)

View File

@@ -171,12 +171,10 @@ Options:
Skip build for shared libraries to reduce compilation time when building frequently for debugging purposes
--ninja
Tell cmake to use the Ninja build system. Without, will generate make files
--sanitize
Shortcut for usage of --sanitize-address --sanitize-undefined
--sanitize-address | -fsanitize=address
Enable the address sanitizer on all targets
--sanitize-undefined | -fsanitize=undefined
Enable the undefined behavior sanitizer on all targets
Enable the address sanitizer on all targets
--ittiSIM
Makes the itti simulator
-h | --help
Print this help
@@ -397,6 +395,10 @@ function main() {
CMAKE_CMD="$CMAKE_CMD -DT_TRACER=False"
echo_info "Disabling the T tracer"
shift 1;;
--enable-latseq)
CMAKE_CMD="$CMAKE_CMD -DLATSEQ=True"
echo info "Enabling Latency Sequence measures"
shift 1;;
--disable-hardware-dependency)
echo_info "Disabling hardware dependency for compiling software"
DISABLE_HARDWARE_DEPENDENCY="True"
@@ -453,15 +455,14 @@ function main() {
CMAKE_CMD="$CMAKE_CMD -GNinja"
MAKE_CMD=ninja
shift;;
--sanitize)
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True -DSANITIZE_UNDEFINED=True"
shift;;
--sanitize-address | -fsanitize=address)
grep -sq "Ubuntu 18.04" /etc/os-release && echo_error "Bug in OS with this option, see CMakeLists.txt"
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True"
shift;;
--sanitize-undefined | -fundefined=address)
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_UNDEFINED=True"
--ittiSIM)
ittiSIM=1
CMAKE_CMD="$CMAKE_CMD -DITTI_SIM=True"
echo_info "Will compile itti simulator"
shift;;
-h | --help)
print_help
@@ -616,6 +617,9 @@ function main() {
if [ "$nrUE" = 1 ] ; then
execlist="$execlist nr-uesoftmodem"
fi
if [ "$ittiSIM" = "1" ] ; then
execlist="$execlist nr-ittisim"
fi
if [[ "$execlist" == "" && "$SIMUS_PHY" != "1" ]]; then
echo_success "installing dependencies successful"

View File

@@ -197,8 +197,8 @@ check_warnings() {
#argument:
# $1: log file
check_errors() {
#we look for 'error:' in the compilation log file
error_count=`grep -c "error:" "$1"`
#we look for 'warning:' in the compilation log file
error_count=`grep "error:" "$1" | wc -l`
if [ $error_count -gt 0 ]; then
echo_error "ERROR: $error_count error. See $1"
fi
@@ -217,6 +217,7 @@ compilations() {
if [ "$MAKE_CMD" != "" ]; then
$MAKE_CMD $2
else
if [ "$VERBOSE_COMPILE" == "1" ]; then
$COV_SCAN_PREFIX make -j`nproc` $2 VERBOSE=$VERBOSE_COMPILE
else
@@ -237,9 +238,8 @@ compilations() {
echo_error "$2 compilation failed"
exit 1
fi
if [ -s "$3" ] ; then
rm -f "$4"
ln -s "$PWD/$3" "$4"
if [ -s $3 ] ; then
cp $3 $4
echo_success "$2 compiled"
check_warnings "$dlog/$2.$REL.txt"
else

View File

@@ -11,11 +11,10 @@ configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t init
* if the bit CONFIG_ENABLECMDLINEONLY is set in `initflags` then the module allows parameters to be set only via the command line. This is used for the oai UE.
```c
void end_configmodule(void)
void End_configmodule(void)
```
* Free memory which has been allocated by the configuration module for storing parameters values, when `PARAMFLAG_NOFREE` flag is not specified in the parameter definition.
* Free memory which has been allocated by the configuration module since its initialization.
* Possibly calls the `config_<config source>_end` function
This call should be used when all configurations have been read. The program will still be able to use parameter values allocated by the config module WHEN THE `PARAMFLAG_NOFREE` flag has been specified in the parameter definition. The config module can be reloaded later in the program (not fully tested as not used today)
## Retrieving parameter's values

View File

@@ -53,17 +53,13 @@ int parse_stringlist(paramdef_t *cfgoptions, char *val) {
}
free(tmpval);
AssertFatal(MAX_LIST_SIZE > numelt,
"This piece of code use fixed size arry of constant #define MAX_LIST_SIZE %d\n",
MAX_LIST_SIZE );
config_check_valptr(cfgoptions, sizeof(char*), numelt);
config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt);
cfgoptions->numelt=numelt;
atoken=strtok_r(val, ",",&tokctx);
for( int i=0; i<cfgoptions->numelt && atoken != NULL ; i++) {
snprintf(cfgoptions->strlistptr[i],DEFAULT_EXTRA_SZ,"%s",atoken);
config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(atoken)+1);
sprintf(cfgoptions->strlistptr[i],"%s",atoken);
printf_params("[LIBCONFIG] %s[%i]: %s\n", cfgoptions->optname,i,cfgoptions->strlistptr[i]);
atoken=strtok_r(NULL, ",",&tokctx);
}
@@ -88,14 +84,13 @@ int processoption(paramdef_t *cfgoptions, char *value) {
char *charptr;
case TYPE_STRING:
if (cfgoptions->numelt == 0 )
config_check_valptr(cfgoptions, 1,
strlen(tmpval)+1);
if (cfgoptions->numelt < (strlen(tmpval)+1)) {
CONFIG_PRINTF_ERROR("[CONFIG] command line option %s value too long\n",
cfgoptions->optname);
if (cfgoptions->numelt == 0 ) {
config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(tmpval)+1);
sprintf(*(cfgoptions->strptr), "%s",tmpval);
} else {
sprintf( (char *)(cfgoptions->strptr), "%s",tmpval);
}
snprintf(*cfgoptions->strptr, cfgoptions->numelt ,"%s",tmpval);
printf_cmdl("[CONFIG] %s set to %s from command line\n", cfgoptions->optname, tmpval);
optisset=1;
break;
@@ -110,7 +105,7 @@ int processoption(paramdef_t *cfgoptions, char *value) {
case TYPE_INT16:
case TYPE_UINT8:
case TYPE_INT8:
config_check_valptr(cfgoptions, sizeof(*cfgoptions->iptr), 1);
config_check_valptr(cfgoptions, (char **)&(cfgoptions->iptr),sizeof(int32_t));
config_assign_int(cfgoptions,cfgoptions->optname,(int32_t)strtol(tmpval,&charptr,0));
if( *charptr != 0) {
@@ -122,14 +117,14 @@ int processoption(paramdef_t *cfgoptions, char *value) {
case TYPE_UINT64:
case TYPE_INT64:
config_check_valptr(cfgoptions, sizeof(*cfgoptions->i64ptr), 1);
config_check_valptr(cfgoptions, (char **)&(cfgoptions->i64ptr),sizeof(uint64_t));
*(cfgoptions->i64ptr)=strtoll(tmpval,&charptr,0);
if( *charptr != 0) {
CONFIG_PRINTF_ERROR("[CONFIG] command line, option %s requires an integer argument\n",cfgoptions->optname);
}
printf_cmdl("[CONFIG] %s set to %lli from command line\n", cfgoptions->optname, (long long)*cfgoptions->i64ptr);
printf_cmdl("[CONFIG] %s set to %lli from command line\n", cfgoptions->optname, (long long)*(cfgoptions->i64ptr));
optisset=1;
break;
@@ -138,8 +133,8 @@ int processoption(paramdef_t *cfgoptions, char *value) {
break;
case TYPE_DOUBLE:
config_check_valptr(cfgoptions, sizeof(*cfgoptions->dblptr), 1);
*cfgoptions->dblptr = strtof(tmpval,&charptr);
config_check_valptr(cfgoptions, (char **)&(cfgoptions->dblptr),sizeof(double));
*(cfgoptions->dblptr) = strtof(tmpval,&charptr);
if( *charptr != 0) {
CONFIG_PRINTF_ERROR("[CONFIG] command line, option %s requires a double argument\n",cfgoptions->optname);

View File

@@ -250,46 +250,46 @@ configmodule_interface_t *load_configmodule(int argc,
modeparams=cfgmode;
cfgmode=strdup(CONFIG_LIBCONFIGFILE);
}
if (cfgptr == NULL) {
cfgptr = calloc(sizeof(configmodule_interface_t),1);
cfgptr = calloc(sizeof(configmodule_interface_t),1);
/* argv_info is used to memorize command line options which have been recognized */
/* and to detect unrecognized command line options which might have been specified */
cfgptr->argv_info = calloc(sizeof(int32_t), argc+10);
cfgptr->argv_info = calloc(sizeof(int32_t), argc+10);
/* argv[0] is the exec name, always Ok */
cfgptr->argv_info[0] |= CONFIG_CMDLINEOPT_PROCESSED;
cfgptr->argv_info[0] |= CONFIG_CMDLINEOPT_PROCESSED;
/* when OoptIdx is >0, -O option has been detected at position OoptIdx
* we must memorize arv[OoptIdx is Ok */
if (OoptIdx >= 0) {
cfgptr->argv_info[OoptIdx] |= CONFIG_CMDLINEOPT_PROCESSED;
cfgptr->argv_info[OoptIdx+1] |= CONFIG_CMDLINEOPT_PROCESSED;
}
if (OoptIdx >= 0) {
cfgptr->argv_info[OoptIdx] |= CONFIG_CMDLINEOPT_PROCESSED;
cfgptr->argv_info[OoptIdx+1] |= CONFIG_CMDLINEOPT_PROCESSED;
}
cfgptr->rtflags = cfgptr->rtflags | tmpflags;
cfgptr->argc = argc;
cfgptr->argv = argv;
cfgptr->cfgmode=strdup(cfgmode);
cfgptr->num_cfgP=0;
atoken=strtok_r(modeparams,":",&strtokctx);
cfgptr->rtflags = cfgptr->rtflags | tmpflags;
cfgptr->argc = argc;
cfgptr->argv = argv;
cfgptr->cfgmode=strdup(cfgmode);
cfgptr->num_cfgP=0;
atoken=strtok_r(modeparams,":",&strtokctx);
while ( cfgptr->num_cfgP< CONFIG_MAX_OOPT_PARAMS && atoken != NULL) {
while ( cfgptr->num_cfgP< CONFIG_MAX_OOPT_PARAMS && atoken != NULL) {
/* look for debug level in the config parameters, it is common to all config mode
and will be removed from the parameter array passed to the shared module */
char *aptr;
aptr=strcasestr(atoken,"dbgl");
char *aptr;
aptr=strcasestr(atoken,"dbgl");
if (aptr != NULL) {
cfgptr->rtflags = cfgptr->rtflags | strtol(aptr+4,NULL,0);
} else {
cfgptr->cfgP[cfgptr->num_cfgP] = strdup(atoken);
cfgptr->num_cfgP++;
}
atoken = strtok_r(NULL,":",&strtokctx);
if (aptr != NULL) {
cfgptr->rtflags = cfgptr->rtflags | strtol(aptr+4,NULL,0);
} else {
cfgptr->cfgP[cfgptr->num_cfgP] = strdup(atoken);
cfgptr->num_cfgP++;
}
printf("[CONFIG] get parameters from %s ",cfgmode);
atoken = strtok_r(NULL,":",&strtokctx);
}
printf("[CONFIG] get parameters from %s ",cfgmode);
for (i=0; i<cfgptr->num_cfgP; i++) {
printf("%s ",cfgptr->cfgP[i]);
}
@@ -336,23 +336,33 @@ void end_configmodule(void) {
cfgptr->end();
}
pthread_mutex_lock(&cfgptr->memBlocks_mutex);
printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs);
for(int i=0; i<cfgptr->numptrs ; i++) {
if (cfgptr->oneBlock[i].ptrs != NULL && cfgptr->oneBlock[i].ptrsAllocated== true && cfgptr->oneBlock[i].toFree) {
free(cfgptr->oneBlock[i].ptrs);
memset(&cfgptr->oneBlock[i], 0, sizeof(cfgptr->oneBlock[i]));
if (cfgptr->ptrs[i] != NULL && cfgptr->ptrsAllocated[i] == true) {
free(cfgptr->ptrs[i]);
cfgptr->ptrs[i]=NULL;
cfgptr->ptrsAllocated[i] = false;
}
}
cfgptr->numptrs=0;
pthread_mutex_unlock(&cfgptr->memBlocks_mutex);
if ( cfgptr->cfgmode )
free(cfgptr->cfgmode);
if ( cfgptr->argv_info )
free( cfgptr->argv_info );
cfgptr->numptrs=0;
}
}
/* free all memory used by config module */
/* should be called only at program exit */
void free_configmodule(void) {
if (cfgptr != NULL) {
end_configmodule();
if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode);
printf ("[CONFIG] free %i config parameter pointers\n",cfgptr->num_cfgP);
for (int i=0; i<cfgptr->num_cfgP; i++) {
if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]);
}
free(cfgptr);
cfgptr=NULL;
@@ -362,4 +372,3 @@ void end_configmodule(void) {

View File

@@ -41,7 +41,7 @@
#include "common/config/config_paramdesc.h"
#include "common/utils/T/T.h"
#define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O <cfgmode>:P1:P2...
#define CONFIG_MAX_ALLOCATEDPTRS 2048 // maximum number of parameters that can be dynamicaly allocated in the config module
#define CONFIG_MAX_ALLOCATEDPTRS 1024 // maximum number of parameters that can be dynamicaly allocated in the config module
/* default values for configuration module parameters */
#define CONFIG_LIBCONFIGFILE "libconfig" // use libconfig file
@@ -62,14 +62,6 @@ typedef int(*configmodule_initfunc_t)(char *cfgP[],int numP);
typedef int(*configmodule_getfunc_t)(paramdef_t *,int numparams, char *prefix);
typedef int(*configmodule_getlistfunc_t)(paramlist_def_t *, paramdef_t *,int numparams, char *prefix);
typedef void(*configmodule_endfunc_t)(void);
typedef struct oneBlock_s{
void *ptrs;
int sz;
bool toFree;
bool ptrsAllocated;
} oneBlock_t;
typedef struct configmodule_interface {
int argc;
char **argv;
@@ -81,10 +73,10 @@ typedef struct configmodule_interface {
configmodule_getfunc_t get;
configmodule_getlistfunc_t getlist;
configmodule_endfunc_t end;
pthread_mutex_t memBlocks_mutex;
uint32_t numptrs;
uint32_t rtflags;
oneBlock_t oneBlock[CONFIG_MAX_ALLOCATEDPTRS];
char *ptrs[CONFIG_MAX_ALLOCATEDPTRS];
bool ptrsAllocated[CONFIG_MAX_ALLOCATEDPTRS];
} configmodule_interface_t;
#ifdef CONFIG_LOADCONFIG_MAIN
@@ -120,15 +112,7 @@ extern configmodule_interface_t *cfgptr;
#define CONFIG_ENABLECMDLINEONLY (1<<1)
extern configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags);
/* free ressources used to read parameters, keep memory
* allocated for parameters values which has been defined with the PARAMFLAG_NOFREE flag
* should be used as soon as there is no need to read parameters but doesn't prevent
* a new config module init
*/
extern void end_configmodule(void);
/* free all config module memory, to be used at end of program as
* it will free parameters values even those specified with the PARAMFLAG_NOFREE flag */
extern void free_configmodule(void);
#define CONFIG_PRINTF_ERROR(f, x... ) if (isLogInitDone ()) { LOG_E(ENB_APP,f,x);} else {printf(f,x);}; if ( !CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) ) exit_fun("exit because configuration failed\n");

View File

@@ -96,13 +96,11 @@ typedef union checkedparam {
/* paramdef is used to describe a parameter, array of paramdef_t strustures is used as the main parameter in */
/* config apis used to retrieve parameters values */
#define MAX_LIST_SIZE 32
#define DEFAULT_EXTRA_SZ 256
typedef struct paramdef {
char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */
char *helpstr; /* help string */
unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */
union { /* pointer to the parameter value, completed by the config module */
union { /* pointer to the parameter value, completed by the config module */
char **strptr;
char **strlistptr;
uint8_t *u8ptr;

View File

@@ -52,97 +52,59 @@ configmodule_interface_t *config_get_if(void) {
return cfgptr;
}
static int managed_ptr_sz(void* ptr) {
configmodule_interface_t * cfg=config_get_if();
AssertFatal(cfg->numptrs < CONFIG_MAX_ALLOCATEDPTRS,
"This code use fixed size array as #define CONFIG_MAX_ALLOCATEDPTRS %d\n",
CONFIG_MAX_ALLOCATEDPTRS);
int i;
pthread_mutex_lock(&cfg->memBlocks_mutex);
int numptrs=cfg->numptrs;
for (i=0; i<numptrs; i++ )
if (cfg->oneBlock[i].ptrs == ptr)
break;
pthread_mutex_unlock(&cfg->memBlocks_mutex);
if ( i == numptrs )
return -1;
else
return cfg->oneBlock[i].sz;
}
char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) {
if (ptr == NULL ) {
ptr = malloc(sizeof(char *));
void *config_allocate_new(int sz, bool autoFree) {
void *ptr = calloc(sz,1);
AssertFatal(ptr, "calloc fails\n");
configmodule_interface_t * cfg=config_get_if();
// add the memory piece in the managed memory pieces list
pthread_mutex_lock(&cfg->memBlocks_mutex);
int newBlockIdx=cfg->numptrs++;
oneBlock_t* tmp=&cfg->oneBlock[newBlockIdx];
tmp->ptrs = (char *)ptr;
tmp->ptrsAllocated = true;
tmp->sz=sz;
tmp->toFree=autoFree;
pthread_mutex_unlock(&cfg->memBlocks_mutex);
return ptr;
}
if (ptr != NULL) {
*ptr=NULL;
cfgoptions->strptr=ptr;
void config_check_valptr(paramdef_t *cfgoptions, int elt_sz, int nb_elt) {
const bool toFree=!(cfgoptions->paramflags & PARAMFLAG_NOFREE);
// let's see if the value has been read
// the datamodel is more difficult than it should be
// and it is not thread safe
if (cfgoptions->voidptr) {
int sz;
if ( cfgoptions-> type == TYPE_STRING)
sz=managed_ptr_sz(*cfgoptions->strptr);
else
sz=managed_ptr_sz(cfgoptions->voidptr);
if ( sz != -1 ) // the same variable pointer has been used!
cfgoptions->numelt=sz;
}
if (cfgoptions->voidptr != NULL
&& (cfgoptions->type == TYPE_INTARRAY
|| cfgoptions->type == TYPE_UINTARRAY
|| cfgoptions->type == TYPE_STRINGLIST )) {
int sz;
if ( cfgoptions->type == TYPE_STRING ||
cfgoptions->type == TYPE_STRINGLIST )
sz=managed_ptr_sz(*cfgoptions->strptr);
else
sz=managed_ptr_sz(cfgoptions->voidptr);
if ( sz != -1) {
CONFIG_PRINTF_ERROR("[CONFIG] %s NOT SUPPORTED not NULL pointer with array types", cfgoptions->optname);
return ;
}
}
if (cfgoptions->voidptr == NULL ) {
if (cfgoptions->type == TYPE_STRING) {
// difficult datamodel
cfgoptions->strptr = config_allocate_new(sizeof(*cfgoptions->strptr), toFree);
} else if ( cfgoptions->type == TYPE_STRINGLIST) {
AssertFatal(nb_elt<MAX_LIST_SIZE,
"This piece of code use fixed size arry of constant #define MAX_LIST_SIZE %d\n",
MAX_LIST_SIZE );
cfgoptions->strlistptr= config_allocate_new(sizeof(char*)*MAX_LIST_SIZE, toFree);
for (int i=0; i<MAX_LIST_SIZE; i++)
cfgoptions->strlistptr[i]= config_allocate_new(DEFAULT_EXTRA_SZ, toFree);
if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) {
config_get_if()->ptrs[config_get_if()->numptrs] = (char *)ptr;
config_get_if()->ptrsAllocated[config_get_if()->numptrs] = true;
config_get_if()->numptrs++;
}
} else {
if ( cfgoptions->type == TYPE_INTARRAY || cfgoptions->type == TYPE_UINTARRAY )
nb_elt=max(nb_elt, MAX_LIST_SIZE); // make room if the list is larger than the default one
cfgoptions->voidptr = config_allocate_new(elt_sz*nb_elt, toFree);
CONFIG_PRINTF_ERROR("[CONFIG] %s %d option %s, cannot allocate pointer: %s \n",
__FILE__, __LINE__, cfgoptions->optname, strerror(errno));
}
}
if (cfgoptions->type == TYPE_STRING && *cfgoptions->strptr == NULL) {
*cfgoptions->strptr = config_allocate_new(nb_elt+DEFAULT_EXTRA_SZ, toFree);
cfgoptions->numelt=nb_elt+DEFAULT_EXTRA_SZ;
printf_ptrs("[CONFIG] %s ptr: 0x%08lx requested size: %i\n",cfgoptions->optname,(uintptr_t)(ptr),length);
if(cfgoptions->numelt > 0 && PARAM_ISSCALAR(cfgoptions) ) { /* already allocated */
if (*ptr != NULL) {
return *ptr;
} else {
CONFIG_PRINTF_ERROR("[CONFIG] %s %d option %s, definition error: value pointer is NULL, declared as %i bytes allocated\n",
__FILE__, __LINE__,cfgoptions->optname, cfgoptions->numelt);
}
}
printf_ptrs("[CONFIG] %s ptr: %p requested size: elt_sz: %d, nb_elt: %d\n",cfgoptions->optname, cfgoptions->voidptr, elt_sz, nb_elt);
if (*ptr == NULL) {
// LTS: dummy fix, waiting Francois full fix in 4G branch
// the issue is we don't know at this point the size we will get
// for parmeters on the command line,
// The length sould probably managed, in a later version
// 100 is a very large value for a string parameter of today OAI
if (length<100)
length=100;
*ptr = malloc(length);
if ( *ptr != NULL) {
memset(*ptr,0,length);
if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) {
config_get_if()->ptrs[config_get_if()->numptrs] = *ptr;
config_get_if()->numptrs++;
}
} else {
CONFIG_PRINTF_ERROR("[CONFIG] %s %d malloc error\n",__FILE__, __LINE__);
}
}
return *ptr;
}
void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val) {
@@ -194,7 +156,7 @@ void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val) {
}
}
void config_assign_processedint(paramdef_t *cfgoption, int val) {
cfgoption->processedvalue = config_allocate_new(sizeof(int),!(cfgoption->paramflags & PARAMFLAG_NOFREE));
cfgoption->processedvalue = malloc(sizeof(int));
if ( cfgoption->processedvalue != NULL) {
*(cfgoption->processedvalue) = val;
@@ -210,7 +172,7 @@ int config_get_processedint(paramdef_t *cfgoption) {
ret=*(cfgoption->processedvalue);
free( cfgoption->processedvalue);
cfgoption->processedvalue=NULL;
printf_params("[CONFIG] %s: set from %s to %i\n",cfgoption->optname, *cfgoption->strptr, ret);
printf_params("[CONFIG] %s: set from %s to %i\n",cfgoption->optname, *(cfgoption->strptr), ret);
} else {
fprintf (stderr,"[CONFIG] %s %d %s has no processed integer availablle\n",__FILE__, __LINE__, cfgoption->optname);
ret=0;
@@ -382,7 +344,7 @@ int config_check_intrange(paramdef_t *param) {
void print_strvalueerror(paramdef_t *param, char *fname, char **okval, int numokval) {
fprintf(stderr,"[CONFIG] %s: %s: %s invalid value, authorized values:\n ",
fname,param->optname, *param->strptr);
fname,param->optname, *(param->strptr));
for ( int i=0; i<numokval ; i++) {
fprintf(stderr, " %s",okval[i]);
@@ -398,7 +360,7 @@ int config_check_strval(paramdef_t *param) {
}
for ( int i=0; i<param->chkPptr->s3.num_okstrval ; i++) {
if( strcasecmp(*param->strptr,param->chkPptr->s3.okstrval[i] ) == 0) {
if( strcasecmp(*(param->strptr),param->chkPptr->s3.okstrval[i] ) == 0) {
return 0;
}
}
@@ -409,7 +371,7 @@ int config_check_strval(paramdef_t *param) {
int config_checkstr_assign_integer(paramdef_t *param) {
for (int i=0; i < param->chkPptr->s3a.num_okstrval ; i++) {
if (strcasecmp(*param->strptr,param->chkPptr->s3a.okstrval[i] ) == 0) {
if (strcasecmp(*(param->strptr),param->chkPptr->s3a.okstrval[i] ) == 0) {
config_assign_processedint(param, param->chkPptr->s3a.setintval[i]);
return 0;
}
@@ -431,14 +393,14 @@ int config_setdefault_string(paramdef_t *cfgoptions, char *prefix) {
if( cfgoptions->defstrval != NULL) {
status=1;
if (cfgoptions->numelt == 0 )
config_check_valptr(cfgoptions, 1, strlen(cfgoptions->defstrval)+1);
if ( cfgoptions->numelt < strlen(cfgoptions->defstrval)+1 ) {
CONFIG_PRINTF_ERROR("[CONFIG] %s size too small\n", cfgoptions->optname);
if (cfgoptions->numelt == 0 ) {
config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(cfgoptions->defstrval)+1);
sprintf(*(cfgoptions->strptr), "%s",cfgoptions->defstrval);
printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, *(cfgoptions->strptr));
} else {
sprintf((char *)(cfgoptions->strptr), "%s",cfgoptions->defstrval);
printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)(cfgoptions->strptr));
}
snprintf(*cfgoptions->strptr, cfgoptions->numelt, "%s",cfgoptions->defstrval);
printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, *cfgoptions->strptr);
}
return status;
@@ -460,7 +422,7 @@ int config_setdefault_stringlist(paramdef_t *cfgoptions, char *prefix) {
int config_setdefault_int(paramdef_t *cfgoptions, char *prefix) {
int status = 0;
config_check_valptr(cfgoptions, sizeof(*cfgoptions->iptr), 1);
config_check_valptr(cfgoptions, (char **)(&(cfgoptions->iptr)),sizeof(int32_t));
if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) {
config_assign_int(cfgoptions,cfgoptions->optname,cfgoptions->defintval);
@@ -473,7 +435,7 @@ int config_setdefault_int(paramdef_t *cfgoptions, char *prefix) {
int config_setdefault_int64(paramdef_t *cfgoptions, char *prefix) {
int status = 0;
config_check_valptr(cfgoptions, sizeof(*cfgoptions->i64ptr), 1);
config_check_valptr(cfgoptions, (char **)&(cfgoptions->i64ptr),sizeof(long long));
if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) {
*(cfgoptions->u64ptr)=cfgoptions->defuintval;
@@ -488,7 +450,7 @@ int config_setdefault_intlist(paramdef_t *cfgoptions, char *prefix) {
int status = 0;
if( cfgoptions->defintarrayval != NULL) {
config_check_valptr(cfgoptions, sizeof(cfgoptions->iptr), cfgoptions->numelt);
config_check_valptr(cfgoptions,(char **)&(cfgoptions->iptr), sizeof(int32_t *));
cfgoptions->iptr=cfgoptions->defintarrayval;
status=1;
@@ -502,7 +464,7 @@ int config_setdefault_intlist(paramdef_t *cfgoptions, char *prefix) {
int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) {
int status = 0;
config_check_valptr(cfgoptions, sizeof(*cfgoptions->dblptr), 1);
config_check_valptr(cfgoptions, (char **)&(cfgoptions->dblptr),sizeof(double));
if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) {
*(cfgoptions->dblptr)=cfgoptions->defdblval;
@@ -514,7 +476,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) {
}
int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr) {
config_check_valptr(cfgoptions, sizeof(*cfgoptions->uptr), 1);
config_check_valptr(cfgoptions,(char **)&(cfgoptions->uptr), sizeof(int));
int rst=inet_pton(AF_INET, ipv4addr,cfgoptions->uptr );
if (rst == 1 && *(cfgoptions->uptr) > 0) {

View File

@@ -51,7 +51,7 @@ extern int config_paramidx_fromname(paramdef_t *params,int numparams, char *name
/* utility functions, to be used by configuration module and/or configuration libraries */
extern configmodule_interface_t *config_get_if(void);
void config_check_valptr(paramdef_t *cfgoptions, int elt_sz, int nb_elt);
extern char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ;
extern void config_printhelp(paramdef_t *,int numparams, char *prefix);
extern int config_process_cmdline(paramdef_t *params,int numparams, char *prefix);
extern void config_assign_processedint(paramdef_t *cfgoption, int val);
@@ -86,7 +86,7 @@ extern int config_setdefault_int64(paramdef_t *cfgoptions, char *prefix);
extern int config_setdefault_intlist(paramdef_t *cfgoptions, char *prefix);
extern int config_setdefault_double(paramdef_t *cfgoptions, char *prefix);
extern int config_setdefault_ipv4addr(paramdef_t *cfgoptions, char *prefix);
void *config_allocate_new(int sz, bool autoFree);
#define CONFIG_GETCONFFILE (config_get_if()->cfgP[0])
#ifdef __cplusplus

View File

@@ -29,7 +29,6 @@
* \warning
*/
#define _GNU_SOURCE
#include <pthread.h>
#include <libconfig.h>
#include <string.h>
@@ -42,7 +41,6 @@
#include "config_libconfig_private.h"
#include "../config_userapi.h"
#include "errno.h"
#include "assertions.h"
#if ( LIBCONFIG_VER_MAJOR == 1 && LIBCONFIG_VER_MINOR < 5)
#define config_setting_lookup config_lookup_from
@@ -55,18 +53,17 @@ int read_strlist(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath
int st;
int numelt;
numelt=config_setting_length(setting);
config_check_valptr(cfgoptions, sizeof(char *), numelt);
config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt);
st=0;
AssertFatal(MAX_LIST_SIZE > numelt,
"This piece of code use fixed size arry of constant #define MAX_LIST_SIZE %d\n",
MAX_LIST_SIZE );
for (int i=0; i< numelt ; i++) {
str=config_setting_get_string_elem(setting,i);
if (str==NULL) {
printf("[LIBCONFIG] %s%i not found in config file\n", cfgoptions->optname,i);
} else {
snprintf(cfgoptions->strlistptr[i], DEFAULT_EXTRA_SZ, "%s",str);
config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(str)+1);
sprintf(cfgoptions->strlistptr[i],"%s",str);
st++;
printf_params("[LIBCONFIG] %s%i: %s\n", cfgpath,i,cfgoptions->strlistptr[i]);
}
@@ -80,8 +77,7 @@ int read_intarray(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpat
cfgoptions->numelt=config_setting_length(setting);
if (cfgoptions->numelt > 0) {
cfgoptions->iptr=config_allocate_new(cfgoptions->numelt*sizeof(*cfgoptions->iptr),
!(cfgoptions->paramflags & PARAMFLAG_NOFREE) );
cfgoptions->iptr=malloc(sizeof(int) * (cfgoptions->numelt));
for (int i=0; i< cfgoptions->numelt && cfgoptions->iptr != NULL; i++) {
cfgoptions->iptr[i]=config_setting_get_int_elem(setting,i);
@@ -127,14 +123,23 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) {
switch(cfgoptions[i].type) {
case TYPE_STRING:
if ( config_lookup_string(&(libconfig_privdata.cfg), cfgpath, (const char**)&str)) {
config_check_valptr(&(cfgoptions[i]), 1, strlen(str)+1);
if ( strlen(str)+1 > cfgoptions[i].numelt )
if ( cfgoptions[i].numelt > 0 && str != NULL && strlen(str) >= cfgoptions[i].numelt ) {
fprintf(stderr,"[LIBCONFIG] %s: %s exceeds maximum length of %i bytes, value truncated\n",
cfgpath,str,cfgoptions[i].numelt);
snprintf( *cfgoptions[i].strptr , cfgoptions[i].numelt, "%s", str);
printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath, *cfgoptions[i].strptr);
str[strlen(str)-1] = 0;
}
if (cfgoptions[i].numelt == 0 ) {
// config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1);
sprintf( *(cfgoptions[i].strptr) , "%s", str);
printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,*(cfgoptions[i].strptr) );
} else {
sprintf( (char *)(cfgoptions[i].strptr) , "%s", str);
printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,(char *)cfgoptions[i].strptr );
}
} else {
defval=config_setdefault_string(&cfgoptions[i],prefix);
defval=config_setdefault_string(&(cfgoptions[i]),prefix);
}
break;
@@ -158,7 +163,7 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) {
case TYPE_INT32:
case TYPE_MASK:
if ( config_lookup_int(&(libconfig_privdata.cfg),cfgpath, &u)) {
config_check_valptr(&(cfgoptions[i]), sizeof(*cfgoptions[i].iptr), 1);
config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].iptr)),sizeof(int32_t));
config_assign_int(&(cfgoptions[i]),cfgpath,u);
} else {
defval=config_setdefault_int(&(cfgoptions[i]),prefix);
@@ -169,14 +174,14 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) {
case TYPE_UINT64:
case TYPE_INT64:
if ( config_lookup_int64(&(libconfig_privdata.cfg),cfgpath, &llu)) {
config_check_valptr(&cfgoptions[i], sizeof(*cfgoptions[i].i64ptr), 1);
config_check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].i64ptr),sizeof(long long));
if(cfgoptions[i].type==TYPE_UINT64) {
*(cfgoptions[i].u64ptr) = (uint64_t)llu;
printf_params("[LIBCONFIG] %s: %lu\n", cfgpath,*cfgoptions[i].u64ptr);
printf_params("[LIBCONFIG] %s: %llu\n", cfgpath,(long long unsigned)(*(cfgoptions[i].u64ptr)) );
} else {
*(cfgoptions[i].i64ptr) = llu;
printf_params("[LIBCONFIG] %s: %ld\n", cfgpath,*cfgoptions[i].i64ptr);
printf_params("[LIBCONFIG] %s: %lld\n", cfgpath,(long long)(*(cfgoptions[i].i64ptr)) );
}
} else {
defval=config_setdefault_int64(&(cfgoptions[i]),prefix);
@@ -198,8 +203,8 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) {
case TYPE_DOUBLE:
if ( config_lookup_float(&(libconfig_privdata.cfg),cfgpath, &dbl)) {
config_check_valptr(&cfgoptions[i],sizeof(*cfgoptions[i].dblptr), 1);
*cfgoptions[i].dblptr = dbl;
config_check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].dblptr),sizeof(double));
*(cfgoptions[i].dblptr) = dbl;
printf_params("[LIBCONFIG] %s: %lf\n", cfgpath,*(cfgoptions[i].dblptr) );
} else {
defval=config_setdefault_double(&(cfgoptions[i]),prefix);
@@ -299,10 +304,27 @@ int config_libconfig_getlist(paramlist_def_t *ParamList,
}
if (ParamList->numelt > 0 && params != NULL) {
ParamList->paramarray = config_allocate_new(ParamList->numelt * sizeof(paramdef_t *), true);
ParamList->paramarray = malloc(ParamList->numelt * sizeof(paramdef_t *));
if ( ParamList->paramarray != NULL) {
config_get_if()->ptrs[config_get_if()->numptrs] = (char *)(ParamList->paramarray);
config_get_if()->numptrs++;
} else {
fprintf (stderr,"[LIBCONFIG] %s %d malloc error\n",__FILE__, __LINE__);
exit(-1);
}
for (i=0 ; i < ParamList->numelt ; i++) {
ParamList->paramarray[i] = config_allocate_new(numparams * sizeof(paramdef_t), true);
ParamList->paramarray[i] = malloc(numparams * sizeof(paramdef_t));
if ( ParamList->paramarray[i] != NULL) {
config_get_if()->ptrs[config_get_if()->numptrs] = (char *)(ParamList->paramarray[i]);
config_get_if()->numptrs++;
} else {
fprintf (stderr,"[LIBCONFIG] %s %d malloc error\n",__FILE__, __LINE__);
exit(-1);
}
memcpy(ParamList->paramarray[i], params, sizeof(paramdef_t)*numparams);
for (j=0; j<numparams; j++) {
@@ -324,8 +346,8 @@ int config_libconfig_init(char *cfgP[], int numP) {
config_init(&(libconfig_privdata.cfg));
libconfig_privdata.configfile = strdup((char *)cfgP[0]);
config_get_if()->numptrs=0;
pthread_mutex_init(&config_get_if()->memBlocks_mutex, NULL);
memset(config_get_if()->oneBlock,0,sizeof(config_get_if()->oneBlock));
memset(config_get_if()->ptrs,0,sizeof(void *) * CONFIG_MAX_ALLOCATEDPTRS);
memset(config_get_if()->ptrsAllocated, 0, sizeof(config_get_if()->ptrsAllocated));
/* search for include path parameter and set config file include path accordingly */
for (int i=0; i<numP; i++) {
if (strncmp(cfgP[i],"incp",4) == 0) {

264
common/utils/LATSEQ/README Normal file
View File

@@ -0,0 +1,264 @@
# LATency SEQuence analysis extension for OpenAirInterface
A tool for internal latency analysis in Base Station.
Code licenced under BSD-3. See more on https://github.com/Orange-OpenSource/LatSeq
Author : Flavien Ronteix--Jacquet (Orange Innovation), Alexandre Ferrieux (Orange Innovation)
Email : flavien.ronteixjacquet@orange.com, alexandre.ferrieux@orange.com
## Installation
- Put LatSeq extension source code in OAI code (https://gitlab.eurecom.fr/oai/openairinterface5g). We recommend to put it in the path common/utils/LATSEQ.
- In cmake_targets/CMakeLists.txt put `add_boolean_option(LATSEQ True "Active Latency Sequence tools")`. Also add Latseq to compiled source `set(UTIL_SRC... ${OPENAIR_DIR}/common/utils/LATSEQ/latseq.c`
- Put test/ in targets/TEST/LATSEQ/
- Verify installation of LatSeq with `make` in targets/TEST/LATSEQ
## Usage
0) Add init_latseq(appname) and close_latseq() in main Base Station thread at the start and end.
1) Add a new LatSeq measure point in the code with
#include "common/utils/LATSEQ/latseq.h"
#if LATSEQ
LATSEQ_P("D pdcp--rlc", "pdcp%d.rlc%d", 0, 1);
#endif
where first argument is the direction, the second the observed segment and the third argument is a string of data_identifier
1) Compile OAI code with cmake option LATSEQ at True
2) Run scanario for Uplink and Downlink
3) Process lseq traces to yield data do statistics with LatSeq tools
More in docs/Latseq.pdf
## LatSeq measurement module
For now, latseq is designed to be the more independant as possible : Means that it does not use oai LOG system (not register by logInit()) and the flag "LATSEQ" disable all lines related to latseq in the code (using #ifdef). In a second time, it could be conceivable to integrate more deeply latseq into oai code.
latseq_t, global structure for latseq embodied the latseq logging info. log_buffer is a circular buffer with 2 head index, i_write_head and i_read_head. this buffer of latseq_element_t is designed to bo mutex-less.
LATSEQ_P macro calls log_measure(). The idea is to have a low-footprint at logging explains why log_measure() should do a minimal amount of operations.
latseq_log_to_file() is the function run in the logger thread. It writes log_elements in the log file.
LATSEQ_P with direction of D (Downlink) or U (Uplink) observed the passage of a data.
LATSEQ_P with direction of I (Information) observed a scalar property at a point of code. e.g. buffer occupancy.
**We assume that**:
- All the point and latseq module run on the same machine (to don't have to synchronize clock of different machines)
- Clock give by asm rdtsc is same for all the CPU cores (constant_tsc enabled)
## TOOLS
Get scripts on https://github.com/Orange-OpenSource/LatSeq/tools
- rdtsctots : convert rdtsc timestamp to unix timestamp value
- latseq_logs : convert lseq log file into useful json file for statistics and visualization
- filter_Is.awk : filter contextual informations
- lseqj2any : generate waterfall to format gp or svg
- latseq_checker : verify constitency of Latseq points before compiling
- latseq_filter : filter output of latseq_logs
- latseq_stats : perform statistic
### latseq_checker
Checker to verify that points LATSEQ_P points are consistent.
Verify the number of argument, the emptiness, format...
ex. ./latseq_checker.sh /home/oai/
### rdtsctots
convert rdtsc value to unix timestamp value
ex. `./rdtsctots.py trace_raw.lseq > trace.lseq`
### latseq_logs
Proceeds LatSeq logs.
A *.lseq is required.
By default, builds the latseq_log object.
- Reads lseq file given in raw_input
- Cleans raw_input to inputs.
- Builds points structure and paths possible.
- Saves object related to the *.lseq files to a *.plk (pickle)
**Arguments**:
- "-h" : help
- "-C" : cleans pickle file associated to the log file and rebuild
- "-l" : required lseq file of fingerprints
- "-i" : request cleaned input measurements in the case of command line script
- "-r" returns the paths present in the log file as json.
```
{
"D": [
["ip", "pdcp.in",...],
...
],
"U": ...
}
``̀
- "-p" returns points structure as json.
Becareful, if journeys has not been rebuilt, then you do not have "duration" attibute which is used for statistics.
```
{
"layer1.point": {
"next": [layer2.point2,...],
"count": 5,
"dir": [0],
"duration": {
"journeys uid": 0.0115,
...
}
}
}
{
...
}
```
- "-j" returns journeys structure as json.
- Rebuilds journeys with rebuild_packets_journey method
- Builds out_journeys
```
{
"uid": 52,
"dir": 0,
"glob": {
"rnti": "54614",...
},
"set": [[1542, 1592409314.253678, "rlc.rx.am--pdcp.rx"],[...],...], # set of pointer to input entry
"set_ids": {
"drb": "1",...
},
"path": 0, # path according to direction and paths obtainable by -p
"completed": true,
"ts_in": 123.456,
"ts_out": 789.012
}
{
...
}
```
- "-m" returns metadata of information as list
```
20200423_143226.191801 rlc.am.txbuf occ1:drb1
20200423_143226.191802 rlc.am.txbuf occ2:drb1
...
20200423_143226.192000 rlc.um.txbuf occ15:drb2
```
- "-o" returns a latseq journey file line by line. redirects output to a file to have a *.lseqj for waterfall generation
```
#funcId ip pdcp.in pdcp.tx rlc.tx.um rlc.seg.um mac.mux mac.txreq phy.out.proc phy.in.proc mac.demux rlc.rx.um rlc.unseg.um pdcp.rx
20200423_143226.191801 D (len64) ip--pdcp.in.gtp uid0.rnti54614.drb1.gsn12
20200423_143226.191802 D (len64) pdcp.in--pdcp.tx uid0.rnti54614.drb1.gsn12.psn10
20200423_143226.191803 D (len66) pdcp.tx--rlc.tx.um uid0.rnti54614.drb1.psn10.lcid3.rsdu0
```
Requested json are printed in stdout line by line
Errors, Warnings, Informations are printed in stderr
Example of usage:
./latseq_logs.py -l ~/latseq.23042020.lseq 2>/dev/null
./latseq_logs.py -j -l ~/latseq.23042020.lseq 2>/dev/null
./latseq_logs.py -p -l ~/latseq.23042020.lseq 2>/dev/null
./latseq_logs.py -o -l ~/latseq.23042020.lseq > 23042020.lseqj 2>/dev/null
### latseq_filter
Applies a filter to a json stream.
It uses jq filters.
Help website to design jq filter : https://jqplay.org/
Takes a file with a filter or a filter as string in argument.
Example of usage:
./latseq_filter.sh journeys_downlinks_gsn.lfilter
cat journeys_downlinks_gsn.lfilter
> select(.["dir"] == 0 and .["set_ids"]["gsn"] == "18")
### latseq_stats
Performs statistics from json. Report json or print in stdout.
By default, reads on stdin. "-l" *.lseq will try to open a *.json associated.
By default, returns a json report on stdout.
Arguments:
- "-f" enables to choose format "json", "csv",...
- "-P" prints statistics formated by the latseq_stats module.
- "-sj" returns statistics on journeys
`̀``
{
"D": {
"size": 34,
"min": 0.19598,
"max": 1.187086,
"mean": 0.788976,
"stdev": 0.153623,
"quantiles": [0.694859, 0.699043, 0.834942, 0.838041, 0.955701]
}
`̀``
- "-sjpp" returns the shares of delay introduced by each point for each journeys by path.
```
{
"U02": { # Uplinks, path 0, point 2
"size": 4,
"min": 0,
"max": 0.7273,
"mean": 0.36239999999999994,
"stdev": 0.2915949673776967,
"quantiles": [
0.025005000000000003,
0.125025,
0.36114999999999997,
0.598525,
0.7015449999999999
]
}
}
```
- "-sp" returns statistics on points
```
{
"pdcp.rx": {
"dir": "U",
"size": 4,
"min": 0.01,
"max": 0.02,
"mean": 0.015,
"stdev": 0.005,
"quantiles": [0.012,...] # 5%, 25%, 50%, 75%, 95%
},
...
}
`̀``
- "-djd" returns data journeys' duration
`̀``
{
"00": { # first decimal indicates uplink/downlink followed by the journey unique id
"ts": 1587645146.191801,
"durations": 0.19598 # in ms
},
...
}
`̀``
Example of usage of the full toolchain for LatSeq Analysis Module
./latseq_logs.py -l ~/latseq.simple.lseq -j 2>/dev/null | ./latseq_filter.sh journeys_downlinks_gsn.lfilt | ./latseq_stats.py -sj --print
### lseqj2any
generate waterfall
cat uplink_burst.30102020_203233.lseqj | lseqj2any gp > uplink_burst.gp
## TEST_LATSEQ
in targets/TEST/LATSEQ test_latseq test different part of latseq module
- "h" : help menu
- "i" : test init and close latseq
- "a" : test init, capture 2 fingerprints and close
- "t" : same test as "a" but with 2 concurrent threads
- "m" : test measurement time to capture 1000000 fingerprints
- "n" : test measurement time to capture 1000 fingerprints with 1,2,3,5,10 data identifiers
- "w" : test writer speed for a simplified data collector

View File

@@ -0,0 +1,284 @@
/*
* Software Name : LatSeq
* Version: 1.0
* SPDX-FileCopyrightText: Copyright (c) 2020-2021 Orange Labs
* SPDX-License-Identifier: BSD-3-Clause
*
* This software is distributed under the BSD 3-clause,
* the text of which is available at https://opensource.org/licenses/BSD-3-Clause
* or see the "license.txt" file for more details.
*
* Author: Flavien Ronteix--Jacquet
* Software description: LatSeq measurement part core
*/
#define _GNU_SOURCE // required for pthread_setname_np()
#include "latseq.h"
/*--- GLOBALS and EXTERNS ----------------------------------------------------*/
latseq_t g_latseq;
__thread latseq_thread_data_t tls_latseq = {
.th_latseq_id = 0
}; // need to be a thread local storage variable.
pthread_t logger_thread;
pthread_t fflusher_thread;
//double cpuf; //cpu frequency in MHz -> usec. Should be initialized in main.c
extern volatile int oai_exit; //oai is ended. Close latseq
/*--- UTILS FUNCTIONS --------------------------------------------------------*/
uint64_t get_cpu_freq_cycles(void)
{
uint64_t ts = l_rdtsc();
sleep(1);
return (l_rdtsc() - ts);
}
/*--- MAIN THREAD FUNCTIONS --------------------------------------------------*/
int init_latseq(const char * appname, uint64_t cpufreq)
{
// init members
g_latseq.is_running = 0;
//synchronise time and rdtsc
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
g_latseq.time_zero = (uint64_t)ts.tv_sec * 1000000000LL + (uint64_t)ts.tv_nsec;
g_latseq.rdtsc_zero = l_rdtsc(); //check at compile time that constant_tsc is enabled in /proc/cpuinfo
if (cpufreq == 0) {
g_latseq.cpu_freq = get_cpu_freq_cycles();
} else {
g_latseq.cpu_freq = cpufreq;
}
// Open traces
char time_string[16];
strftime(time_string, sizeof (time_string), "%d%m%Y_%H%M%S", localtime(&ts.tv_sec));
g_latseq.filelog_name = (char *)malloc(LATSEQ_MAX_STR_SIZE);
sprintf(g_latseq.filelog_name, "%s.%s.lseq", appname, time_string);
//open logfile
g_latseq.outstream = fopen(g_latseq.filelog_name, "w");
if (g_latseq.outstream == NULL) {
g_latseq.is_running = 0;
printf("[LATSEQ] Error at opening log file\n");
return -1;
}
//write header
char hdr[] = "# LatSeq packet fingerprints\n# By Alexandre Ferrieux and Flavien Ronteix Jacquet\n# timestamp\tU/D\tsrc--dest\tlen:ctxtId:localId\n";
size_t ret = fwrite(hdr, sizeof(char), sizeof(hdr) - 1, g_latseq.outstream);
if (ret < 0) {
printf("[LATSEQ] Error at opening log file\n");
g_latseq.is_running = 0;
return -1;
}
fprintf(g_latseq.outstream, "%ld S rdtsc--gettimeofday %ld.%09ld\n", g_latseq.rdtsc_zero, ts.tv_sec, ts.tv_nsec);
fflush(g_latseq.outstream);
// init registry
g_latseq.local_log_buffers.read_ith_thread = 0;
g_latseq.local_log_buffers.nb_th = 0;
memset(&g_latseq.local_log_buffers.i_read_heads, 0, MAX_NB_THREAD * sizeof(unsigned int));
// init stat
g_latseq.stats.entry_counter = 0;
g_latseq.stats.bytes_counter = 0;
// init latseq_thread_t
tls_latseq.th_latseq_id = 0;
// init logger thread
g_latseq.is_running = 1;
return init_logger_latseq();
}
int init_logger_latseq(void)
{
// init thread to write buffer to file
if(pthread_create(&logger_thread, NULL, (void *) &latseq_log_to_file, NULL) > 0) {
printf("[LATSEQ] Error at starting data collector\n");
g_latseq.is_running = 0;
return -1;
}
// init thread to flush into file
pthread_create(&fflusher_thread, NULL, (void *) &fflush_latseq_periodically, NULL);
return g_latseq.is_running;
}
void latseq_print_stats(void)
{
printf("[LATSEQ] === stats ===\n");
printf("[LATSEQ] number of entry in log : %d\n", g_latseq.stats.entry_counter);
//printf("[LATSEQ] heads positions : %d (Write) : %d (Read)\n", g_latseq.i_write_head, g_latseq.i_read_head);
}
int close_latseq(void)
{
g_latseq.is_running = 0;
//Wait logger finish to write data
pthread_join(logger_thread, NULL);
//At this point, data_ids and points should be freed by the logger thread
free((char*) g_latseq.filelog_name);
if (fclose(g_latseq.outstream)){
fprintf(stderr, "[LATSEQ] error on closing %s\n", g_latseq.filelog_name);
exit(EXIT_FAILURE);
}
return 1;
}
/*--- INSTRUMENTED THREAD FUNCTIONS ------------------------------------------*/
int init_thread_for_latseq(void)
{
//Init tls_latseq for local thread
tls_latseq.i_write_head = 0; //local thread tls_latseq
//memset(tls_latseq.log_buffer, 0, sizeof(tls_latseq.log_buffer));
//Register thread in the registry
latseq_registry_t * reg = &g_latseq.local_log_buffers;
//Check if space left in registry
if (reg->nb_th >= MAX_NB_THREAD) {
g_latseq.is_running = 0;
fprintf(g_latseq.outstream, "Max instrumented thread MAX_NB_THREAD reached\n");
return -1;
}
reg->tls[reg->nb_th] = &tls_latseq;
reg->i_read_heads[reg->nb_th] = 0;
//Give id to the thread
reg->nb_th++;
tls_latseq.th_latseq_id = reg->nb_th;
return 0;
//TODO : No destroy function ? What happens when thread is stopped and data had not been written in the log file ?
}
/*--- DATA COLLECTOR THREAD FUNCTIONS ----------------------------------------*/
static int write_latseq_entry(void)
{
//reference to latseq_thread_data
latseq_thread_data_t * th = g_latseq.local_log_buffers.tls[g_latseq.local_log_buffers.read_ith_thread];
//read_head for this thread_data
unsigned int * i_read_head = &g_latseq.local_log_buffers.i_read_heads[g_latseq.local_log_buffers.read_ith_thread];
//reference to element to write
latseq_element_t * e = &th->log_buffer[(*i_read_head)%RING_BUFFER_SIZE];
char * tmps;
//Convert latseq_element to a string
tmps = calloc(LATSEQ_MAX_STR_SIZE, sizeof(char));
//Write the data identifier, e.g. do the vsprintf() here and not at measure()
//We put the first NB_DATA_IDENTIFIERS elements of array, even there are no NB_DATA_IDENTIFIERS element to write. sprintf will get the firsts...
sprintf(
tmps,
e->format,
e->data_id[0],
e->data_id[1],
e->data_id[2],
e->data_id[3],
e->data_id[4],
e->data_id[5],
e->data_id[6],
e->data_id[7],
e->data_id[8],
e->data_id[9]);
// Write into file
int ret = fprintf(g_latseq.outstream, "%ld %s %s\n",
e->ts,
e->point,
tmps);
if (ret < 0) {
g_latseq.is_running = 0;
fclose(g_latseq.outstream);
fprintf(stderr, "[LATSEQ] output log file cannot be written\n");
exit(EXIT_FAILURE);
}
#ifdef LATSEQ_DEBUG
fprintf(g_latseq.outstream, "# debug %ld.%06ld : log an entry (len %d) for %s\n", etv.tv_sec, etv.tv_usec, ret, e->point);
fprintf(g_latseq.outstream, "# info %ld.%06ld : buffer occupancy (%d / %d) for thread which embedded %s\n",etv.tv_sec, etv.tv_usec, OCCUPANCY((*(&th->i_write_head)%RING_BUFFER_SIZE), ((*i_read_head)%RING_BUFFER_SIZE)), RING_BUFFER_SIZE, e->point);
#endif
free(tmps);
// cleanup buffer element
e->ts = 0;
memset(e->data_id, 0, (sizeof(uint32_t) * e->len_id));
e->len_id = 0;
//Update read_head for the current read_ith_thread
//Update g_latseq.local_log_buffers.i_read_heads[g_latseq.local_log_buffers.read_ith_thread] head position
(*i_read_head)++;
return ret;
}
void latseq_log_to_file(void)
{
// pthread config
pthread_t thId = pthread_self();
//set name
pthread_setname_np(thId, "latseq_log_to_file");
//set priority
int prio_for_policy = 10;
pthread_setschedprio(thId, prio_for_policy);
latseq_registry_t * reg = &g_latseq.local_log_buffers;
int items_to_read = 0;
while (!oai_exit) { // run until oai is stopped
if (!g_latseq.is_running) { break; } //running flag is at 0, not running
//If no thread registered, continue and wait
if (reg->nb_th == 0) { usleep(1000); continue; }
//Select a thread to read with read_ith_thread.
// Using RR for now, WRR in near future according to occupancy
if (reg->read_ith_thread + 1 >= reg->nb_th) {
reg->read_ith_thread = 0;
} else {
reg->read_ith_thread++;
}
//If max occupancy reached for a local buffer
if (reg->tls[reg->read_ith_thread]->i_write_head < reg->i_read_heads[reg->read_ith_thread]) {
fprintf(g_latseq.outstream, "# Error\tring buffer of thread (%d) reach max occupancy of %d\n", reg->read_ith_thread, RING_BUFFER_SIZE);
}
items_to_read = CHUNK_SIZE_ITEMS;
// Write by chunk
while (reg->tls[reg->read_ith_thread]->i_write_head > reg->i_read_heads[reg->read_ith_thread] && items_to_read > 0 ) {
//printf("[debug] th %d : (%d)w (%d)r : (%d)items_to_read\n", reg->read_ith_thread, reg->tls[reg->read_ith_thread]->i_write_head, reg->i_read_heads[reg->read_ith_thread], items_to_read);
items_to_read--;
//Write pointed entry into log file
g_latseq.stats.bytes_counter += (uint32_t)write_latseq_entry();
g_latseq.stats.entry_counter++;
}
usleep(1);
} // while(!oai_exit)
//Write all remaining data
for (uint8_t i = 0; i < reg->nb_th; i++) {
reg->read_ith_thread = i;
while (reg->tls[reg->read_ith_thread]->i_write_head > reg->i_read_heads[reg->read_ith_thread])
{
g_latseq.stats.bytes_counter += (uint32_t)write_latseq_entry();
g_latseq.stats.entry_counter++;
}
}
//close_latseq(); // function to close latseq properly
//exit thread
pthread_exit(NULL);
}
void fflush_latseq_periodically(void)
{
struct timespec ts;
while(1){
sleep(1);
fflush(g_latseq.outstream);
clock_gettime(CLOCK_REALTIME, &ts);
fprintf(g_latseq.outstream, "%ld S rdtsc--gettimeofday %ld.%09ld\n", l_rdtsc(), ts.tv_sec, ts.tv_nsec);
}
pthread_exit(NULL);
}

View File

@@ -0,0 +1,409 @@
/*
* Software Name : LatSeq
* Version: 1.0
* SPDX-FileCopyrightText: Copyright (c) 2020-2021 Orange Labs
* SPDX-License-Identifier: BSD-3-Clause
*
* This software is distributed under the BSD 3-clause,
* the text of which is available at https://opensource.org/licenses/BSD-3-Clause
* or see the "license.txt" file for more details.
*
* Author: Flavien Ronteix--Jacquet
* Software description: LatSeq measurement part core
*/
#ifndef __LATSEQ_H__
#define __LATSEQ_H__
/*--- INCLUDES ---------------------------------------------------------------*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdarg.h>
#include <time.h>
#include <stdint.h>
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <pthread.h>
#include <utils.h>
/*--- DEFINE -----------------------------------------------------------------*/
#define RING_BUFFER_SIZE 1024 // Number of fingerprints in Ring Buffer
#define NB_DATA_IDENTIFIERS 10 // to update according to distinct data identifier used in point
#define LATSEQ_MAX_STR_SIZE 128 // Length for filelog_name AND latseq fingerprint string size
#define CHUNK_SIZE_ITEMS 16 // Size of chunk of ring buffer to read at data collector. 1 correspoding to full RR, RING_BUFFER_SIZE read all buffer by passage
#define MAX_NB_THREAD 32 // Maximum number of instrumented threads expected
/*--- MACRO ------------------------------------------------------------------*/
#define LATSEQ_P3(p, f, i1) do {log_measure1(p, f, (uint32_t)i1); } while(0)
#define LATSEQ_P4(p, f, i1, i2) do {log_measure2(p, f, (uint32_t)i1, (uint32_t)i2); } while(0)
#define LATSEQ_P5(p, f, i1, i2, i3) do {log_measure3(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3); } while(0)
#define LATSEQ_P6(p, f, i1, i2, i3, i4) do {log_measure4(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4);} while(0)
#define LATSEQ_P7(p, f, i1, i2, i3, i4, i5) do {log_measure5(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4, (uint32_t)i5); } while(0)
#define LATSEQ_P8(p, f, i1, i2, i3, i4, i5, i6) do {log_measure6(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4, (uint32_t)i5, (uint32_t)i6); } while(0)
#define LATSEQ_P9(p, f, i1, i2, i3, i4, i5, i6, i7) do {log_measure7(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4, (uint32_t)i5, (uint32_t)i6, (uint32_t)i7); } while(0)
#define LATSEQ_P10(p, f, i1, i2, i3, i4, i5, i6, i7, i8) do {log_measure8(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4, (uint32_t)i5, (uint32_t)i6, (uint32_t)i7, (uint32_t)i8); } while(0)
#define LATSEQ_P11(p, f, i1, i2, i3, i4, i5, i6, i7, i8, i9) do {log_measure9(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4, (uint32_t)i5, (uint32_t)i6, (uint32_t)i7, (uint32_t)i8, (uint32_t)i9); } while(0)
#define LATSEQ_P12(p, f, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10) do {log_measure10(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4, (uint32_t)i5, (uint32_t)i6, (uint32_t)i7, (uint32_t)i8, (uint32_t)i9, (uint32_t)i10); } while(0)
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,NAME,...) NAME
#define LATSEQ_P(...) GET_MACRO(__VA_ARGS__, LATSEQ_P12, LATSEQ_P11, LATSEQ_P10, LATSEQ_P9, LATSEQ_P8, LATSEQ_P7, LATSEQ_P6, LATSEQ_P5, LATSEQ_P4, LATSEQ_P3)(__VA_ARGS__)
#define OCCUPANCY(w, r) (w - r)
/*--- STRUCT -----------------------------------------------------------------*/
// A latseq element of the buffer
typedef struct latseq_element_t {
uint64_t ts; // timestamp of the measure
const char * point;
const char * format;
ushort len_id; // Number data identifiers
uint32_t data_id[NB_DATA_IDENTIFIERS]; // values for the data identifier. What is the best type ?
} latseq_element_t;
// Statistics structures for latseq
typedef struct latseq_stats_t {
uint32_t entry_counter;
uint32_t bytes_counter;
} latseq_stats_t;
//thread specific data struct
typedef struct latseq_thread_data_t {
uint8_t th_latseq_id; //Identifier of pthread for registry
latseq_element_t log_buffer[RING_BUFFER_SIZE]; //log buffer, structure mutex-less
unsigned int i_write_head; // position of writer in the log_buffer (main thread)
} latseq_thread_data_t;
//Registry of pointers to thread-specific struct latseq_data_thread
typedef struct latseq_registry_t {
uint8_t read_ith_thread;
uint8_t nb_th;
latseq_thread_data_t * tls[MAX_NB_THREAD];
unsigned int i_read_heads[MAX_NB_THREAD]; // position of reader in the ith log buffer (logger thread)
} latseq_registry_t;
// Global structure of LatSeq module
typedef struct latseq_t {
int is_running; //1 is running, 0 not running
char * filelog_name;
FILE * outstream; //Output descriptor
uint64_t time_zero; // time zero
uint64_t rdtsc_zero; //rdtsc zero
uint64_t cpu_freq; //cpu frequency
latseq_registry_t local_log_buffers; //Register of thread-specific buffers
latseq_stats_t stats; // stats of latseq instance
} latseq_t;
/*--- EXTERNS ----------------------------------------------------------------*/
extern latseq_t g_latseq; // global structure
extern __thread latseq_thread_data_t tls_latseq;
/*--- FUNCTIONS --------------------------------------------------------------*/
/** \fn int init_latseq(const char * appname);
* \brief init latency sequences module.
* \param appname app's name. The output file is appname.date_hour.lseq
* \param cpufreq. cpu frequency in cycles.
* \return -1 if error 1 otherwise
*/
int init_latseq(const char * appname, uint64_t cpufreq);
/** \fn init_logger_to_mem(void);
* \brief init thread logger
* \return -1 if error 1 otherwise
*/
int init_logger_latseq(void);
/** \fn init_thread_for_latseq(void);
* \brief init tls_latseq for local oai thread
* \return -1 if error, 0 otherwise
*/
int init_thread_for_latseq(void);
/** \fn l_rdtsc(void);
* \brief rdtsc wrapper
* \return time
*/
static __inline__ uint64_t l_rdtsc(void) {
uint32_t a, d;
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
return (((uint64_t)d)<<32) | ((uint64_t)a);
}
/** \fn get_cpu_freq_cycles(void);
* \brief Compute CPU clock in a 1 second experiment
* \return CPU clock in cycles
*/
uint64_t get_cpu_freq_cycles(void);
/*--- MEASUREMENTS -----------------------------------------------------------*/
/** \fn void log_measure(const char * point, const char *identifier);
* \brief function to log a new measure into buffer.
* From 1 to NB_DATA_IDENTIFIERS
* \param point name of the measurement point
* \param id identifier for the data pointed
* \todo measure latency introduced by this function
*/
static __inline__ void log_measure1(const char * point, const char *fmt, uint32_t i1)
{
//check if the oai thread is already registered
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
//get reference on new element
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 1;
e->data_id[0] = i1;
//Update head position
tls_latseq.i_write_head++;
}
static __inline__ void log_measure2(const char * point, const char *fmt, uint32_t i1, uint32_t i2)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 2;
e->data_id[0] = i1;
e->data_id[1] = i2;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure3(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 3;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure4(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 4;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure5(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4, uint32_t i5)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 5;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
e->data_id[4] = i5;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure6(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4, uint32_t i5, uint32_t i6)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 6;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
e->data_id[4] = i5;
e->data_id[5] = i6;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure7(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4, uint32_t i5, uint32_t i6, uint32_t i7)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 7;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
e->data_id[4] = i5;
e->data_id[5] = i6;
e->data_id[6] = i7;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure8(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4, uint32_t i5, uint32_t i6, uint32_t i7, uint32_t i8)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 8;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
e->data_id[4] = i5;
e->data_id[5] = i6;
e->data_id[6] = i7;
e->data_id[7] = i8;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure9(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4, uint32_t i5, uint32_t i6, uint32_t i7, uint32_t i8, uint32_t i9)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 9;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
e->data_id[4] = i5;
e->data_id[5] = i6;
e->data_id[6] = i7;
e->data_id[7] = i8;
e->data_id[8] = i9;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure10(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4, uint32_t i5, uint32_t i6, uint32_t i7, uint32_t i8, uint32_t i9, uint32_t i10)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 10;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
e->data_id[4] = i5;
e->data_id[5] = i6;
e->data_id[6] = i7;
e->data_id[7] = i8;
e->data_id[8] = i9;
e->data_id[9] = i10;
tls_latseq.i_write_head++;
}
/** \fn static int write_latseq_entry(void);
* \brief private function to write an entry in the log file
*/
//static int write_latseq_entry(void);
/** \fn void log_to_file(void);
* \brief function to save buffer of logs into a file
*/
void latseq_log_to_file(void);
/** \fn void fflush_latseq_periodically(void);
* \brief flush periodically into fprintf
*/
void fflush_latseq_periodically(void);
/** \fn void latseq_print_stats(void);
* \brief print some stats about latseq
*/
void latseq_print_stats(void);
/** \fn int close_latseq(void);
* \brief finish latseq measurement if a latseq is running
* \return 0 if error 1 otherwise
*/
int close_latseq(void);
/*----------------------------------------------------------------------------*/
#endif

View File

@@ -380,8 +380,8 @@ void log_getconfig(log_t *g_log)
}
int register_log_component(char *name,
char *fext,
int compidx)
char *fext,
int compidx)
{
int computed_compidx=compidx;
@@ -542,11 +542,11 @@ static inline int log_header(log_component_t *c,
char l[32];
if (flag & FLAG_FILE_LINE && flag & FLAG_FUNCT )
snprintf(l, sizeof l, "(%.23s:%d) ", func, line);
snprintf(l, sizeof l, "(%s:%d) ", func, line);
else if (flag & FLAG_FILE_LINE)
snprintf(l, sizeof l, "(%d) ", line);
else if (flag & FLAG_FUNCT)
snprintf(l, sizeof l, "(%.28s) ", func);
snprintf(l, sizeof l, "(%s) ", func);
else
l[0] = 0;
@@ -800,13 +800,15 @@ void logClean (void)
int i;
if(isLogInitDone()) {
LOG_UI(PHY,"\n");
for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
close_component_filelog(i);
}
}
}
extern int oai_exit;
extern volatile int oai_exit;//extern int oai_exit;
void flush_mem_to_file(void)
{
int fp;

View File

@@ -393,7 +393,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
/* optname help paramflags XXXptr defXXXval type numelt */
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define LOG_GLOBALPARAMS_DESC { \
{LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:&gloglevel, defstrval:log_level_names[3].name, TYPE_STRING, 0}, \
{LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[3].name, TYPE_STRING, 0}, \
{LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(consolelog), defintval:1, TYPE_INT, 0}, \
{LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0} \
}

View File

@@ -8,19 +8,22 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <signal.h>
#include "common/config/config_userapi.h"
#define QUIT(x) do { \
printf("T tracer: QUIT: %s\n", x); \
exit(1); \
} while (0)
/* array used to activate/disactivate a log */
static int T_IDs[T_NUMBER_OF_IDS];
int *T_active = T_IDs;
int T_stdout = 1;
static int T_socket;
static int local_tracer_pid;
/* T_cache
* - the T macro picks up the head of freelist and marks it busy
@@ -30,78 +33,63 @@ volatile int _T_freelist_head;
volatile int *T_freelist_head = &_T_freelist_head;
T_cache_t *T_cache;
#define GET_MESSAGE_FAIL do { \
printf("T tracer: get_message failed\n"); \
return -1; \
} while (0)
/* return -1 if error, 0 if no error */
static int get_message(int s)
{
static void get_message(int s) {
char t;
int l;
int id;
int is_on;
if (read(s, &t, 1) != 1) GET_MESSAGE_FAIL;
if (read(s, &t, 1) != 1) QUIT("get_message fails");
printf("T tracer: got mess %d\n", t);
switch (t) {
case 0:
/* toggle all those IDs */
/* optimze? (too much syscalls) */
if (read(s, &l, sizeof(int)) != sizeof(int)) GET_MESSAGE_FAIL;
if (read(s, &l, sizeof(int)) != sizeof(int)) QUIT("get_message fails");
while (l) {
if (read(s, &id, sizeof(int)) != sizeof(int)) GET_MESSAGE_FAIL;
if (read(s, &id, sizeof(int)) != sizeof(int)) QUIT("get_message fails");
T_IDs[id] = 1 - T_IDs[id];
l--;
}
break;
case 1:
/* set IDs as given */
/* optimize? */
if (read(s, &l, sizeof(int)) != sizeof(int)) GET_MESSAGE_FAIL;
if (read(s, &l, sizeof(int)) != sizeof(int)) QUIT("get_message fails");
id = 0;
while (l) {
if (read(s, &is_on, sizeof(int)) != sizeof(int))
GET_MESSAGE_FAIL;
QUIT("get_message fails");
T_IDs[id] = is_on;
id++;
l--;
}
break;
case 2:
break; /* do nothing, this message is to wait for local tracer */
}
return 0;
}
static void *T_receive_thread(void *_)
{
int err = 0;
while (!err) err = get_message(T_socket);
printf("T tracer: fatal: T tracer disabled\n");
shutdown(T_socket, SHUT_RDWR);
close(T_socket);
kill(local_tracer_pid, SIGKILL);
/* disable all traces */
memset(T_IDs, 0, sizeof(T_IDs));
static void *T_receive_thread(void *_) {
while (1) get_message(T_socket);
return NULL;
}
static void new_thread(void *(*f)(void *), void *data)
{
static void new_thread(void *(*f)(void *), void *data) {
pthread_t t;
pthread_attr_t att;
@@ -130,11 +118,27 @@ static void new_thread(void *(*f)(void *), void *data)
void T_local_tracer_main(int remote_port, int wait_for_tracer,
int local_socket, void *shm_array);
void T_init(int remote_port, int wait_for_tracer)
{
/* We monitor the tracee and the local tracer processes.
* When one dies we forcefully kill the other.
*/
#include <sys/types.h>
#include <sys/wait.h>
static void monitor_and_kill(int child1, int child2) {
int child;
int status;
child = wait(&status);
if (child == -1) perror("wait");
kill(child1, SIGKILL);
kill(child2, SIGKILL);
exit(0);
}
void T_init(int remote_port, int wait_for_tracer, int dont_fork) {
int socket_pair[2];
int s;
int child;
int child1, child2;
int i;
if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair)) {
@@ -158,40 +162,47 @@ void T_init(int remote_port, int wait_for_tracer)
for (i = 0; i < T_CACHE_SIZE; i++) T_cache[i].busy = 0;
/* child runs the local tracer and main runs the tracee */
child = fork();
/* child1 runs the local tracer and child2 (or main) runs the tracee */
child1 = fork();
if (child == -1) abort();
if (child1 == -1) abort();
if (child == 0) {
if (child1 == 0) {
close(socket_pair[1]);
T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0],
T_cache);
exit(0);
}
local_tracer_pid = child;
close(socket_pair[0]);
s = socket_pair[1];
T_socket = s;
if (dont_fork == 0) {
child2 = fork();
/* wait for first message - initial list of active T events */
if (get_message(s) == -1) {
kill(local_tracer_pid, SIGKILL);
return;
if (child2 == -1) abort();
if (child2 != 0) {
close(socket_pair[1]);
munmap(T_cache, T_CACHE_SIZE * sizeof(T_cache_t));
monitor_and_kill(child1, child2);
}
}
s = socket_pair[1];
/* wait for first message - initial list of active T events */
get_message(s);
T_socket = s;
new_thread(T_receive_thread, NULL);
}
void T_Config_Init(void)
{
int T_port = TTRACER_DEFAULT_PORTNUM;
int T_nowait = 0;
void T_Config_Init(void) {
int T_port=TTRACER_DEFAULT_PORTNUM; /* by default we wait for the tracer */
int T_nowait=0; /* default port to listen to to wait for the tracer */
int T_dont_fork=0; /* default is to fork, see 'T_init' to understand */
paramdef_t ttraceparams[] = CMDLINE_TTRACEPARAMS_DESC;
/* for a cleaner config file, TTracer params should be defined in a
* specific section...
*/
config_get(ttraceparams,
sizeof(ttraceparams) / sizeof(paramdef_t),
TTRACER_CONFIG_PREFIX);
@@ -206,5 +217,5 @@ void T_Config_Init(void)
}
if (T_stdout == 0 || T_stdout == 2)
T_init(T_port, 1-T_nowait);
T_init(T_port, 1-T_nowait, T_dont_fork);
}

View File

@@ -15,8 +15,8 @@
#include "T_IDs.h"
#define T_ACTIVE_STDOUT 2
/* known type - this is where you add new types */
#define T_INT(x) int, (x)
#define T_FLOAT(x) float, (x)
#define T_BUFFER(x, len) buffer, ((T_buffer){addr:(x), length:(len)})
@@ -111,7 +111,6 @@ typedef struct {
extern volatile int *T_freelist_head;
extern T_cache_t *T_cache;
extern int *T_active;
#define T_GET_SLOT \
T_LOCAL_busy = __sync_fetch_and_or(&T_cache[T_LOCAL_slot].busy, 0x01);
@@ -560,12 +559,14 @@ extern int *T_active;
} \
} while (0)
#define CONFIG_HLP_TPORT "tracer port\n"
#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n"
#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n"
#define CONFIG_HLP_STDOUT "print log messges on console\n"
#define TTRACER_CONFIG_PREFIX "TTracer"
#define TTRACER_CONFIG_PREFIX "TTracer"
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
/* configuration parameters for TTRACE utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
@@ -574,12 +575,15 @@ extern int *T_active;
#define CMDLINE_TTRACEPARAMS_DESC { \
{"T_port", CONFIG_HLP_TPORT, 0, iptr:&T_port, defintval:TTRACER_DEFAULT_PORTNUM, TYPE_INT, 0},\
{"T_nowait", CONFIG_HLP_NOTWAIT, PARAMFLAG_BOOL, iptr:&T_nowait, defintval:0, TYPE_INT, 0},\
{"T_dont_fork", CONFIG_HLP_TNOFORK, PARAMFLAG_BOOL, iptr:&T_dont_fork, defintval:0, TYPE_INT, 0},\
{"T_stdout", CONFIG_HLP_STDOUT, 0, iptr:&T_stdout, defintval:1, TYPE_INT, 0},\
}
void T_init(int remote_port, int wait_for_tracer);
void T_Config_Init(void);
/* log on stdout */
void T_init(int remote_port, int wait_for_tracer, int dont_fork);
void T_Config_Init(void);
#else /* T_TRACER */
/* if T_TRACER is not defined or is 0, the T is deactivated */

View File

@@ -1,71 +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
*/
#ifndef LINEAR_ALLOC_H
#define LINEAR_ALLOC_H
#include <limits.h>
typedef unsigned int uid_t;
#define UID_LINEAR_ALLOCATOR_SIZE 1024
#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE (((UID_LINEAR_ALLOCATOR_SIZE/8)/sizeof(unsigned int)) + 1)
typedef struct uid_linear_allocator_s {
unsigned int bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE];
} uid_allocator_t;
static inline void uid_linear_allocator_init(uid_allocator_t *uia) {
memset(uia, 0, sizeof(uid_allocator_t));
}
static inline uid_t uid_linear_allocator_new(uid_allocator_t *uia) {
unsigned int bit_index = 1;
uid_t uid = 0;
for (unsigned int i = 0; i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE; i++) {
if (uia->bitmap[i] != UINT_MAX) {
bit_index = 1;
uid = 0;
while ((uia->bitmap[i] & bit_index) == bit_index) {
bit_index = bit_index << 1;
uid += 1;
}
uia->bitmap[i] |= bit_index;
return uid + (i*sizeof(unsigned int)*8);
}
}
return UINT_MAX;
}
static inline void uid_linear_allocator_free(uid_allocator_t *uia, uid_t uid) {
const unsigned int i = uid/sizeof(unsigned int)/8;
const unsigned int bit = uid % (sizeof(unsigned int) * 8);
const unsigned int value = ~(1 << bit);
if (i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE) {
uia->bitmap[i] &= value;
}
}
#endif /* LINEAR_ALLOC_H */

View File

@@ -1,56 +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
*/
#ifndef UTILS_CONFIG_H_ASN1
#define UTILS_CONFIG_H_ASN1
// This is hard coded file name "config.h" and HAVE_CONFIG_H_ in asn1c skeletons
/*
* This file "config.h" will be used by asn1c if HAVE_CONFIG_H_ is defined and
* included. This logs asn1c encoder and decoder traces at execution time using
* the regular OAI logging system, i.e., LOG_I(ASN...);
*
* As it is very verbose, note that you can change the log level per module in
* source or in gdb, e.g., to only activate it for a short time.
*
* In code:
* ```
* set_log(ASN, OAI_INFO); // enable logging
* // do your encoding here
* set_log(ASN, OAI_ERR); // disable logging
* ```
*
* in gdb:
* ```
* gdb> p set_log(ASN, 1) // disable log, 1 == OAI_ERR
* gdb> p set_log(ASN, 5) // enable log, 5 == OAI_INFO
* ```
*/
#include "common/utils/LOG/log.h"
#if DEBUG_ASN1C
#define ASN_DEBUG(x...) do{ LOG_I(ASN,x);LOG_I(ASN,"\n"); } while(false)
#else
#define ASN_DEBUG(x...)
#endif
#endif /* UTILS_CONFIG_H_ASN1 */

View File

@@ -1,319 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*
* This file implements the cpu statistics for Level 1 in gnb and in UE.
* Caveats: Note that we did not merge this development into file telnetsrv_gnb_measurements.c and telnetsrv_5Gue_measurements.c
* belonging to telnetsrv shared library because we needed to provide an API for main programs exectuable without inserting a new
* dependency on the telnetsrv shared library.
*/
#define _GNU_SOURCE
#include <pthread.h>
#include <stdbool.h>
#include <errno.h>
#include <linux/sched.h>
#include "common/utils/LOG/log.h"
#include "common/utils/threadPool/thread-pool.h"
#include "cpustats.h"
#include "common/utils/time_meas.h"
#define UEL1_THREADNAME "L1_UE_stats_act"
#define GNBL1_THREADNAME "L1_stats_act"
/* ==== Global variables ==== */
// IPC communication between main thread and the statistics one
static notifiedFIFO_t GNBL1cpustats_fifo, UEL1cpustats_fifo;
static pthread_t UEL1cpustats_threadid = 0;
static pthread_t gNBL1cpustats_threadid = 0;
// data structure for communication between main thread and the statistics one
typedef struct {
unsigned int msgid;
telnet_printfunc_t prnt;
} proto_stats_msg_t;
// PHY_vars_UE_g: declared in openair1/PHY/phy_vars_nr_ue.h and defined in nr-uesoftmodem.c
extern PHY_VARS_NR_UE *** PHY_vars_UE_g;
/* ==== Static functions ==== */
/* return pointer to the global structure that contains the UE data including statistics*/
static PHY_VARS_NR_UE * getglobal_uephy(void) { return PHY_vars_UE_g[0][0]; }
// RC.nb_nr_macrlc_inst in openair2/LAYER2/NR_MAC_gNB/main.c defines the RAN_CONTEXT RC variable that defines how many instances you will have
// ru stands for 'radio unit' data structure
static RU_t *getglobal_ru(void) { return RC.ru[0];}
static void UEL1cpustats_display(telnet_printfunc_t prnt);
static void UEL1cpustats_thread_main(void);
static void gNBL1cpustats_display(telnet_printfunc_t prnt, PHY_VARS_gNB *param);
static void gNBL1cpustats_thread_main (void * param);
/* xxx: these are the same statistics but with different formatting and list of content of those displayed by
* telnetsrv_measurements.c:measurcmd_display_cpumeasures(). you could think about unifying the 2 functions.
* XXX: this implementation should be fixed using a dynamically allocated buffer instead of a plain one
* it is prone to sigSEGV
*/
static void
UEL1cpustats_display(telnet_printfunc_t prnt)
{
/* PHY_vars_UE_g:
* this global variable is allocated by nr-uesoftmodem.c and shared among threads makes the trick of passing statistics data to statistic thread
* that will consume it. There is just one instance of UE created in nr-ue.c
*/
PHY_VARS_NR_UE *ue = getglobal_uephy();
prnt("Display CPU statistics for UE Level 1\n");
char output[TELNET_MAX_MSGLENGTH];
int stroff = 0;
stroff += print_meas_log(&ue->phy_proc_tx , "L1 TX processing" , NULL, NULL, output , TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ue->ulsch_encoding_stats , "ULSCH encoding" , NULL, NULL, output + stroff, TELNET_MAX_MSGLENGTH - stroff );
stroff += print_meas_log(&ue->phy_proc_rx[0] , "L1 RX processing t0" , NULL, NULL, output + stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ue->phy_proc_rx[1] , "L1 RX processing t1" , NULL, NULL, output + stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ue->ue_ul_indication_stats , "UL Indication" , NULL, NULL, output + stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ue->rx_pdsch_stats , "PDSCH receiver" , NULL, NULL, output + stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ue->dlsch_decoding_stats[0] , "PDSCH decoding t0" , NULL, NULL, output + stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ue->dlsch_decoding_stats[1] , "PDSCH decoding t1" , NULL, NULL, output + stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ue->dlsch_deinterleaving_stats , " -> Deinterleive" , NULL, NULL, output + stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ue->dlsch_rate_unmatching_stats , " -> Rate Unmatch" , NULL, NULL, output + stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ue->dlsch_ldpc_decoding_stats , " -> LDPC Decode" , NULL, NULL, output + stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ue->dlsch_unscrambling_stats , "PDSCH unscrambling" , NULL, NULL, output + stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ue->dlsch_rx_pdcch_stats , "PDCCH handling" , NULL, NULL, output + stroff, TELNET_MAX_MSGLENGTH - stroff);
prnt("%s\n", output);
}
static void
UEL1cpustats_thread_main(void)
{
if (pthread_setname_np(pthread_self(), UEL1_THREADNAME))
LOG_E(UTIL, "Error setting name on thread %s: %s\n", UEL1_THREADNAME, strerror(errno));
struct sched_param schedp;
schedp.sched_priority = SCHED_NORMAL;
if (pthread_setschedparam(pthread_self(), SCHED_IDLE, &schedp))
LOG_E(UTIL, "Error setting priority in thread %s: %s\n", UEL1_THREADNAME, strerror(errno));
initNotifiedFIFO(&UEL1cpustats_fifo);
cpumeas(CPUMEAS_ENABLE);
while (1){
/*
* Infinite loop that waits for a message on the FIFO.
* Behind the scenes it uses blocking pthread.h:pthread_cond_wait()
*/
notifiedFIFO_elt_t *msg = pullNotifiedFIFO(&UEL1cpustats_fifo);
proto_stats_msg_t *tsm = (proto_stats_msg_t *)NotifiedFifoData(msg);
switch (tsm->msgid)
{
case TIMESTAT_MSGID_DISPLAY:
if (cpumeas(CPUMEAS_GETSTATE))
UEL1cpustats_display(tsm->prnt);
else
tsm->prnt("ERR: before displaying meaningful stats, you need to activate their generation\n");
break;
case TIMESTAT_MSGID_DISABLE:
cpumeas(CPUMEAS_DISABLE);
UEL1cpustats_threadid = 0;
pthread_exit(NULL);
break;
}
delNotifiedFIFO_elt(msg);
}
LOG_I(UTIL, "Exiting thread %s\n", UEL1_THREADNAME);
}
bool
UEL1cpustats_enable(void)
{
if (UEL1cpustats_threadid){
LOG_E(UTIL, "Thread '%s' is already running. Aborting your request to create a new one\n", UEL1_THREADNAME);
return false;
}
int rt = pthread_create(&UEL1cpustats_threadid, NULL, (void *(*)(void *))UEL1cpustats_thread_main, NULL);
if (rt != 0)
LOG_E(UTIL, "Error creating thread %s: %s\n",UEL1_THREADNAME, strerror(errno));
return (rt != 0) ? false : true;
}
void
UEL1cpustats_disable(void)
{
if (!UEL1cpustats_threadid) {
LOG_W(UTIL, "Thread '%s' is not running. Discarding your request to disable stats\n", UEL1_THREADNAME);
return;
}
notifiedFIFO_elt_t *nfe = newNotifiedFIFO_elt(sizeof(time_stats_msg_t), 0, NULL, NULL);
proto_stats_msg_t *msg = (proto_stats_msg_t *)NotifiedFifoData(nfe);
msg->msgid = TIMESTAT_MSGID_DISABLE;
pushNotifiedFIFO(&UEL1cpustats_fifo, nfe);
}
void
UEL1cpustats_measurcmd_display (telnet_printfunc_t prnt)
{
if (!UEL1cpustats_threadid) {
prnt("Thread '%s' is not running. Aborting your request to display stats, you need first to enable statistics\n", UEL1_THREADNAME);
return;
}
notifiedFIFO_elt_t *nfe = newNotifiedFIFO_elt(sizeof(time_stats_msg_t), 0, NULL, NULL);
proto_stats_msg_t *msg = (proto_stats_msg_t *)NotifiedFifoData(nfe);
msg->prnt = prnt;
msg->msgid = TIMESTAT_MSGID_DISPLAY;
pushNotifiedFIFO(&UEL1cpustats_fifo, nfe);
}
/* Display info from specific instance of gNB and from radio unit */
static void
gNBL1cpustats_display(telnet_printfunc_t prnt, PHY_VARS_gNB *gNB)
{
RU_t *ru = getglobal_ru();
char output[TELNET_MAX_MSGLENGTH];
int stroff = 0;
prnt("%s\n");
// XXX: header will be printed automatically by print_meas_log() just the first time it is called in the program. It means that if you
// use a mechanism like 'loop measur show gnb_L1', you will lose the header after the first iteration.
// You should fix the logic of 'print_meas_log() to avoid it printing any header.
stroff += print_meas_log(&gNB->phy_proc_tx , "L1 Tx processing" , NULL, NULL, output , TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&gNB->dlsch_encoding_stats , "DLSCH encoding" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&gNB->phy_proc_rx , "L1 Rx processing" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&gNB->ul_indication_stats , "UL Indication" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&gNB->rx_pusch_stats , "PUSCH inner-receiver", NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&gNB->ulsch_decoding_stats , "PUSCH decoding" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&gNB->schedule_response_stats, "Schedule Response" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
if (ru->feprx)
stroff += print_meas_log(&ru->ofdm_demod_stats , "feprx" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
if (ru->feptx_ofdm) {
stroff += print_meas_log(&ru->precoding_stats , "feptx_prec" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ru->txdataF_copy_stats , "txdataF_copy" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ru->ofdm_mod_stats , "feptx_ofdm" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ru->ofdm_total_stats , "feptx_total" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
}
if (ru->fh_north_asynch_in)
stroff += print_meas_log(&ru->rx_fhaul , "rx_fhaul" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ru->tx_fhaul , "tx_fhaul" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
if (ru->fh_north_out) {
stroff += print_meas_log(&ru->compression , "compression" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
stroff += print_meas_log(&ru->transport , "transport" , NULL, NULL, output+stroff, TELNET_MAX_MSGLENGTH - stroff);
}
prnt("%s\n", output);
}
static void
gNBL1cpustats_thread_main(void * param)
{
if (pthread_setname_np(pthread_self(), GNBL1_THREADNAME))
LOG_E(UTIL, "Error setting name on thread %s: %s\n", GNBL1_THREADNAME, strerror(errno));
struct sched_param schedp;
schedp.sched_priority = SCHED_NORMAL;
if (pthread_setschedparam(pthread_self(), SCHED_IDLE, &schedp))
LOG_E(UTIL, "Error setting priority in thread %s: %s\n", GNBL1_THREADNAME, strerror(errno));
initNotifiedFIFO(&GNBL1cpustats_fifo);
cpumeas(CPUMEAS_ENABLE);
while (1){
/*
* Infinite loop that waits for a message on the FIFO.
* Behind the scenes it uses blocking pthread.h:pthread_cond_wait()
*/
notifiedFIFO_elt_t *msg = pullNotifiedFIFO(&GNBL1cpustats_fifo);
proto_stats_msg_t *tsm = (proto_stats_msg_t *)NotifiedFifoData(msg);
switch (tsm->msgid)
{
case TIMESTAT_MSGID_DISPLAY:
if (cpumeas(CPUMEAS_GETSTATE))
gNBL1cpustats_display(tsm->prnt, (PHY_VARS_gNB *)param);
else
tsm->prnt("ERR: before displaying meaningful stats, you need to activate their generation\n");
break;
case TIMESTAT_MSGID_DISABLE:
cpumeas(CPUMEAS_DISABLE);
gNBL1cpustats_threadid = 0;
pthread_exit(NULL);
break;
}
delNotifiedFIFO_elt(msg);
}
LOG_I(UTIL, "Exiting thread '%s'\n", GNBL1_THREADNAME);
}
void
gNBL1cpustats_measurcmd_display (telnet_printfunc_t prnt)
{
if (!gNBL1cpustats_threadid) {
prnt("gNB thread %s is not running. Aborting your request to display stats as you need first to enable statistics\n", GNBL1_THREADNAME);
return;
}
notifiedFIFO_elt_t *nfe = newNotifiedFIFO_elt(sizeof(time_stats_msg_t), 0, NULL, NULL);
proto_stats_msg_t *msg = (proto_stats_msg_t *)NotifiedFifoData(nfe);
msg->prnt = prnt;
msg->msgid = TIMESTAT_MSGID_DISPLAY;
pushNotifiedFIFO(&GNBL1cpustats_fifo, nfe);
}
bool
gNBL1cpustats_enable(PHY_VARS_gNB *gNB)
{
if (gNBL1cpustats_threadid) {
LOG_E(UTIL, "Thread '%s' already running, aborting your request to create a new one\n", GNBL1_THREADNAME);
return false;
}
int rt = pthread_create(&gNBL1cpustats_threadid, NULL, (void *(*)(void *))gNBL1cpustats_thread_main, gNB);
if (rt != 0)
LOG_E(UTIL, "Error creating thread '%s': %s\n", GNBL1_THREADNAME, strerror(errno));
return (rt != 0) ? false : true;
}
void
gNBL1cpustats_disable(void)
{
if (!gNBL1cpustats_threadid) {
LOG_W(UTIL, "Thread '%s' is not running. Discarding your request to disable stats\n", GNBL1_THREADNAME);
return;
}
notifiedFIFO_elt_t *nfe = newNotifiedFIFO_elt(sizeof(time_stats_msg_t), 0, NULL, NULL);
proto_stats_msg_t *msg = (proto_stats_msg_t *)NotifiedFifoData(nfe);
msg->msgid = TIMESTAT_MSGID_DISABLE;
pushNotifiedFIFO(&GNBL1cpustats_fifo, nfe);
}

View File

@@ -1,20 +0,0 @@
#ifndef _CPUSTATS_H
#define _CPUSTATS_H
/*
* Activation, deactivation and printing functionalities of cpu statistics for UE and gNB Level 1/PHY indicators
*/
#include "common/utils/telnetsrv/telnetsrv.h"
#include "openair1/PHY/defs_nr_UE.h"
#include "openair1/PHY/defs_gNB.h"
#define UE_STATS_L1 "phycpunew"
void UEL1cpustats_measurcmd_display(telnet_printfunc_t prnt);
bool UEL1cpustats_enable(void);
void UEL1cpustats_disable(void);
#define GNB_STATS_L1 "gnb_L1"
bool gNBL1cpustats_enable(PHY_VARS_gNB *gNB);
void gNBL1cpustats_disable(void);
void gNBL1cpustats_measurcmd_display (telnet_printfunc_t prnt);
#endif

View File

@@ -37,6 +37,7 @@ typedef enum hashtable_return_code_e {
HASH_TABLE_KEY_ALREADY_EXISTS = 3,
HASH_TABLE_BAD_PARAMETER_HASHTABLE = 4,
HASH_TABLE_SYSTEM_ERROR = 5,
HASH_TABLE_NONE = 6,
HASH_TABLE_CODE_MAX
} hashtable_rc_t;

View File

@@ -281,9 +281,5 @@ void loader_reset()
shlib->numfunc = 0;
shlib->len_funcarray = 0;
}
if(loader_data.shlibpath){
free(loader_data.shlibpath);
loader_data.shlibpath=NULL;
}
free(loader_data.shlibs);
}

View File

@@ -51,11 +51,11 @@ typedef struct {
}loader_shlibdesc_t;
typedef struct {
char *mainexec_buildversion;
char *shlibpath;
uint32_t maxshlibs;
uint32_t numshlibs;
loader_shlibdesc_t *shlibs;
char *mainexec_buildversion;
char *shlibpath;
uint32_t maxshlibs;
uint32_t numshlibs;
loader_shlibdesc_t *shlibs;
}loader_data_t;
/* function type of functions which may be implemented by a module */
@@ -79,8 +79,8 @@ loader_data_t loader_data;
/* optname helpstr paramflags XXXptr defXXXval type numelt check func*/
/*----------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define LOADER_PARAMS_DESC { \
{"shlibpath", NULL, PARAMFLAG_NOFREE, strptr:&loader_data.shlibpath, defstrval:DEFAULT_PATH, TYPE_STRING, 0, NULL},\
{"maxshlibs", NULL, 0, uptr:&(loader_data.maxshlibs),defintval:DEFAULT_MAXSHLIBS, TYPE_UINT32, 0, NULL}\
{"shlibpath", NULL, PARAMFLAG_NOFREE, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0, NULL},\
{"maxshlibs", NULL, 0, uptr:&(loader_data.maxshlibs), defintval:DEFAULT_MAXSHLIBS, TYPE_UINT32, 0, NULL}\
}
/*-------------------------------------------------------------------------------------------------------------*/

View File

@@ -472,236 +472,6 @@ int get_subband_size(int NPRB,int size) {
}
void get_samplerate_and_bw(int mu,
int n_rb,
int8_t threequarter_fs,
double *sample_rate,
unsigned int *samples_per_frame,
double *tx_bw,
double *rx_bw) {
if (mu == 0) {
switch(n_rb) {
case 270:
if (threequarter_fs) {
*sample_rate=92.16e6;
*samples_per_frame = 921600;
*tx_bw = 50e6;
*rx_bw = 50e6;
} else {
*sample_rate=61.44e6;
*samples_per_frame = 614400;
*tx_bw = 50e6;
*rx_bw = 50e6;
}
case 216:
if (threequarter_fs) {
*sample_rate=46.08e6;
*samples_per_frame = 460800;
*tx_bw = 40e6;
*rx_bw = 40e6;
}
else {
*sample_rate=61.44e6;
*samples_per_frame = 614400;
*tx_bw = 40e6;
*rx_bw = 40e6;
}
break;
case 160: //30 MHz
case 133: //25 MHz
if (threequarter_fs) {
AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",n_rb);
}
else {
*sample_rate=30.72e6;
*samples_per_frame = 307200;
*tx_bw = 20e6;
*rx_bw = 20e6;
}
case 106:
if (threequarter_fs) {
*sample_rate=23.04e6;
*samples_per_frame = 230400;
*tx_bw = 20e6;
*rx_bw = 20e6;
}
else {
*sample_rate=30.72e6;
*samples_per_frame = 307200;
*tx_bw = 20e6;
*rx_bw = 20e6;
}
break;
case 52:
if (threequarter_fs) {
*sample_rate=11.52e6;
*samples_per_frame = 115200;
*tx_bw = 10e6;
*rx_bw = 10e6;
}
else {
*sample_rate=15.36e6;
*samples_per_frame = 153600;
*tx_bw = 10e6;
*rx_bw = 10e6;
}
case 25:
if (threequarter_fs) {
*sample_rate=5.76e6;
*samples_per_frame = 57600;
*tx_bw = 5e6;
*rx_bw = 5e6;
}
else {
*sample_rate=7.68e6;
*samples_per_frame = 76800;
*tx_bw = 5e6;
*rx_bw = 5e6;
}
break;
default:
AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",n_rb,mu);
}
} else if (mu == 1) {
switch(n_rb) {
case 273:
if (threequarter_fs) {
*sample_rate=184.32e6;
*samples_per_frame = 1843200;
*tx_bw = 100e6;
*rx_bw = 100e6;
} else {
*sample_rate=122.88e6;
*samples_per_frame = 1228800;
*tx_bw = 100e6;
*rx_bw = 100e6;
}
break;
case 217:
if (threequarter_fs) {
*sample_rate=92.16e6;
*samples_per_frame = 921600;
*tx_bw = 80e6;
*rx_bw = 80e6;
} else {
*sample_rate=122.88e6;
*samples_per_frame = 1228800;
*tx_bw = 80e6;
*rx_bw = 80e6;
}
break;
case 162 :
if (threequarter_fs) {
AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",n_rb);
}
else {
*sample_rate=61.44e6;
*samples_per_frame = 614400;
*tx_bw = 60e6;
*rx_bw = 60e6;
}
break;
case 133 :
if (threequarter_fs) {
AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",n_rb);
}
else {
*sample_rate=61.44e6;
*samples_per_frame = 614400;
*tx_bw = 50e6;
*rx_bw = 50e6;
}
break;
case 106:
if (threequarter_fs) {
*sample_rate=46.08e6;
*samples_per_frame = 460800;
*tx_bw = 40e6;
*rx_bw = 40e6;
}
else {
*sample_rate=61.44e6;
*samples_per_frame = 614400;
*tx_bw = 40e6;
*rx_bw = 40e6;
}
break;
case 51:
if (threequarter_fs) {
*sample_rate=23.04e6;
*samples_per_frame = 230400;
*tx_bw = 20e6;
*rx_bw = 20e6;
}
else {
*sample_rate=30.72e6;
*samples_per_frame = 307200;
*tx_bw = 20e6;
*rx_bw = 20e6;
}
break;
case 24:
if (threequarter_fs) {
*sample_rate=11.52e6;
*samples_per_frame = 115200;
*tx_bw = 10e6;
*rx_bw = 10e6;
}
else {
*sample_rate=15.36e6;
*samples_per_frame = 153600;
*tx_bw = 10e6;
*rx_bw = 10e6;
}
break;
default:
AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",n_rb,mu);
}
} else if (mu == 3) {
switch(n_rb) {
case 66:
if (threequarter_fs) {
*sample_rate=184.32e6;
*samples_per_frame = 1843200;
*tx_bw = 100e6;
*rx_bw = 100e6;
} else {
*sample_rate = 122.88e6;
*samples_per_frame = 1228800;
*tx_bw = 100e6;
*rx_bw = 100e6;
}
break;
case 32:
if (threequarter_fs) {
*sample_rate=92.16e6;
*samples_per_frame = 921600;
*tx_bw = 50e6;
*rx_bw = 50e6;
} else {
*sample_rate=61.44e6;
*samples_per_frame = 614400;
*tx_bw = 50e6;
*rx_bw = 50e6;
}
break;
default:
AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",n_rb,mu);
}
} else {
AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu);
}
}
// from start symbol index and nb or symbols to symbol occupation bitmap in a slot
uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols) {
return ((1<<nrOfSymbols)-1)<<startSymbolIndex;

View File

@@ -37,8 +37,6 @@
#include "assertions.h"
#include "PHY/defs_common.h"
#define MAX_BWP_SIZE 275
typedef struct nr_bandentry_s {
int16_t band;
uint64_t ul_min;
@@ -50,11 +48,6 @@ typedef struct nr_bandentry_s {
uint8_t deltaf_raster;
} nr_bandentry_t;
typedef enum frequency_range_e {
FR1 = 0,
FR2
} frequency_range_t;
extern const nr_bandentry_t nr_bandtable[];
static inline int get_num_dmrs(uint16_t dmrs_mask ) {
@@ -83,13 +76,6 @@ uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols);
int get_nb_periods_per_frame(uint8_t tdd_period);
int get_supported_band_index(int scs, int band, int n_rbs);
long rrc_get_max_nr_csrs(uint8_t max_rbs, long b_SRS);
void get_samplerate_and_bw(int mu,
int n_rb,
int8_t threequarter_fs,
double *sample_rate,
unsigned int *samples_per_frame,
double *tx_bw,
double *rx_bw);
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))

View File

@@ -17,4 +17,7 @@
#include "openair2/COMMON/flexran_messages_def.h"
#include "openair2/COMMON/f1ap_messages_def.h"
#include "openair2/COMMON/ngap_messages_def.h"
#if ITTI_SIM
#include "openair2/COMMON/itti_sim_messages_def.h"
#endif

View File

@@ -438,24 +438,23 @@ extern "C" {
void itti_send_terminate_message(task_id_t task_id) {
}
pthread_mutex_t signal_mutex;
static volatile bool shutting_down;
static void catch_sigterm(int) {
static const char msg[] = "\n** Caught SIGTERM, shutting down\n";
__attribute__((unused))
int unused = write(STDOUT_FILENO, msg, sizeof(msg) - 1);
pthread_mutex_unlock(&signal_mutex);
shutting_down = true;
}
void itti_wait_tasks_end(void) {
pthread_mutex_init(&signal_mutex, NULL);
pthread_mutex_lock(&signal_mutex);
shutting_down = false;
signal(SIGTERM, catch_sigterm);
signal(SIGINT, catch_sigterm);
pthread_mutex_lock(&signal_mutex);
//signal(SIGINT, catch_sigterm);
while (! shutting_down)
{
sleep(24 * 3600);
}
}
void itti_update_lte_time(uint32_t frame, uint8_t slot) {}

View File

@@ -262,6 +262,10 @@ void *rrc_enb_process_itti_msg(void *);
#include <openair3/SCTP/sctp_eNB_task.h>
#include <openair3/NGAP/ngap_gNB.h>
#ifdef ITTI_SIM
#include <openair2/COMMON/itti_sim_messages_types.h>
#endif
/*
static const char *const messages_definition_xml = {
#include <messages_xml.h>
@@ -304,11 +308,9 @@ void *rrc_enb_process_msg(void *);
TASK_DEF(TASK_BM, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_PHY_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_MAC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_MAC_GNB, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RLC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RRC_ENB_NB_IoT, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_PDCP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_PDCP_GNB, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_DATA_FORWARDING, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_END_MARKER, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL,NULL)\

View File

@@ -231,6 +231,8 @@ void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name,
int settingPriority = 1;
ret=pthread_attr_init(&attr);
AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
ret=pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
if (checkIfFedoraDistribution())
if (checkIfGenericKernelOnFedora())

View File

@@ -46,7 +46,6 @@
#include "common/utils/LOG/log.h"
#include "common/config/config_userapi.h"
#include "common/utils/cpustats.h"
#include "telnetsrv_measurements.h"
#include "telnetsrv_ltemeasur_def.h"
#include "telnetsrv_cpumeasur_def.h"
@@ -64,9 +63,7 @@ void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt);
static telnet_measurgroupdef_t nrUEmeasurgroups[] = {
// {"ue", GROUP_LTESTATS,0, measurcmd_display_macstats, {NULL}},
// {"rlc", GROUP_LTESTATS,0, measurcmd_display_rlcstats, {NULL}},
{"phycpu" , GROUP_CPUSTATS, 0, measurcmd_display_phycpu , {NULL}},
{UE_STATS_L1, GROUP_CPUSTATS, 0, UEL1cpustats_measurcmd_display, {NULL}}
{"phycpu",GROUP_CPUSTATS,0, measurcmd_display_phycpu, {NULL}},
// {"maccpu",GROUP_CPUSTATS,0, measurcmd_display_maccpu, {NULL}},
// {"pdcpcpu",GROUP_CPUSTATS,0, measurcmd_display_pdcpcpu, {NULL}},
};

View File

@@ -1,275 +0,0 @@
#define TELNETSERVERCODE
#include <stdbool.h>
#include "telnetsrv.h"
#include "telnetsrv_measurements.h"
#include "telnetsrv_ltemeasur_def.h"
#include "common/utils/cpustats.h"
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
static void gNBL2pstats_measurcmd_display(telnet_printfunc_t prnt);
static char *gNBL2pstats_gethdrline1(char * bufhdr, size_t maxlen);
static char *gNBL2pstats_gethdrline2(char * bufhdr, size_t maxlen);
static const char *scale_number (float n, int width);
/*
* caveats: 5th fiels of nrgNBmeasurgroups[] entries is NULL as we are not yet defining in this module the statistics content to
* be passed from statistics thread. That field was created for future extensibility work on reuniting statistics management.
*/
static telnet_measurgroupdef_t nrgNBmeasurgroups[] = {
{GNB_STATS_L2_MAC, GROUP_LTESTATS, 0, gNBL2pstats_measurcmd_display , {NULL}},
{GNB_STATS_L1 , GROUP_CPUSTATS, 0, gNBL1cpustats_measurcmd_display, {NULL}}
};
const char SPACE_LABEL=' ';
const char MINUS_LABEL='-';
const char * ULSCH_LABEL="[UL sch]";
const char * DLSCH_LABEL="[DL sch]";
int get_measurgroups(telnet_measurgroupdef_t **measurgroups)
{
*measurgroups = nrgNBmeasurgroups;
return sizeof(nrgNBmeasurgroups)/sizeof(telnet_measurgroupdef_t);
}
// magic numbers for the below table
#define TELNETSRV_TBL_HARQ_DL 10
#define TELNETSRV_TBL_HARQ_UL 16
// XXX: table below would need a bit of tuning to understand expected values ranges and avoid massive use of scaling functionality
static const struct itemtable_t{
int width; // field width in ASCII characters
bool tobescaled; // 1(true), 0(false) scaling the value to i.e. Kb, Mb, etc..
char *itemlabel; // the new libproc item enum identifier
enum {TELNETSRV_SCH_NONE = 0, TELNETSRV_SCH_DL, TELNETSRV_SCH_UL} scheduler;
} itemtable[] = {
{2, false, "UE" , TELNETSRV_SCH_NONE}, // UE number
{4, false, "RNTI" , TELNETSRV_SCH_NONE},
{2, false, "PH" , TELNETSRV_SCH_NONE},
{5, false, "PCMax" , TELNETSRV_SCH_NONE},
{7, false, "RSRPavg" , TELNETSRV_SCH_NONE},
{8, false, "RSRPmeas", TELNETSRV_SCH_NONE},
{3, false, "cqi" , TELNETSRV_SCH_NONE},
{2, false, "ri" , TELNETSRV_SCH_NONE},
{5, false, "pmix1" , TELNETSRV_SCH_NONE}, // uint8
{5, false, "pmix2" , TELNETSRV_SCH_NONE}, // uint8
{4, true , "HARQ" , TELNETSRV_SCH_DL }, // special case pointed by TELNETSRV_TBL_HARQ_DL. Given that we do not know how many dl_rounds elements you
// will have,width here is related to each of the dl_rounds. It is similar reasoning for UL below
{4, true , "E" , TELNETSRV_SCH_DL },
{3, false, "dtx" , TELNETSRV_SCH_DL },
{5, true , "bler" , TELNETSRV_SCH_DL }, // float
{3, false, "mcs" , TELNETSRV_SCH_DL },
{6, true , "bdlsch" , TELNETSRV_SCH_UL }, // tot bytes scheduled
{4, true , "HARQ" , TELNETSRV_SCH_UL }, // special case pointed by TELNETSRV_TBL_HARQ_UL. See HARQ for DL above
{4, true , "E" , TELNETSRV_SCH_UL },
{3, false, "dtx" , TELNETSRV_SCH_UL },
{5, true , "bler" , TELNETSRV_SCH_UL }, // float
{3, false, "mcs" , TELNETSRV_SCH_UL },
{6, true , "bulsch" , TELNETSRV_SCH_UL }, // tot bytes scheduled
{6, true , "brxtot" , TELNETSRV_SCH_UL } // tot bytes received
};
static char * gNBL2pstats_gethdrline1(char *bufhdr, size_t maxlen)
{
unsigned int idx;
int bufhdr_idx=0;
int empty_spaces = 0;
int dl_sch = 0;
int ul_sch = 0;
int width = 0;
gNB_MAC_INST *gNB = RC.nrmac[0];
for (idx=0; idx < (sizeof(itemtable)/sizeof(struct itemtable_t)); idx++)
{
if ((bufhdr_idx + itemtable[idx].width + 1) > maxlen)
return NULL;
// handling special case of HARQ configurable numbers of rounds
width = itemtable[idx].width + 1;
if (idx == TELNETSRV_TBL_HARQ_DL)
width = width * gNB->dl_bler.harq_round_max;
else if (idx == TELNETSRV_TBL_HARQ_UL)
width = width * gNB->ul_bler.harq_round_max;
switch (itemtable[idx].scheduler)
{
case TELNETSRV_SCH_NONE:
empty_spaces += width;
memset(bufhdr + bufhdr_idx, SPACE_LABEL, width);
break;
case TELNETSRV_SCH_DL:
dl_sch += width;
memset(bufhdr + bufhdr_idx, MINUS_LABEL, width);
break;
case TELNETSRV_SCH_UL:
ul_sch += width;
memset(bufhdr + bufhdr_idx, MINUS_LABEL, width);
break;
}
bufhdr_idx += width;
}
bufhdr[bufhdr_idx] = '\n';
bufhdr_idx++;
bufhdr[bufhdr_idx] = '\0';
// now, overwite some parts if there is enough space
if (dl_sch > (sizeof(DLSCH_LABEL) + 4 ))
{
bufhdr[empty_spaces + 2] = SPACE_LABEL;
memcpy(bufhdr + empty_spaces + 3, DLSCH_LABEL, strlen(DLSCH_LABEL));
bufhdr[empty_spaces + 3 + sizeof(DLSCH_LABEL)] = SPACE_LABEL;
bufhdr[empty_spaces + dl_sch - 1] = SPACE_LABEL;
}
if (ul_sch > (sizeof(ULSCH_LABEL) + 4 ))
{
bufhdr[empty_spaces + dl_sch + 2] = SPACE_LABEL;
memcpy(bufhdr + empty_spaces + dl_sch + 3, ULSCH_LABEL, strlen(ULSCH_LABEL));
bufhdr[empty_spaces + dl_sch + 3 + sizeof(ULSCH_LABEL)] = SPACE_LABEL;
bufhdr[empty_spaces + dl_sch + ul_sch - 1] = SPACE_LABEL;
}
return bufhdr;
}
static char * gNBL2pstats_gethdrline2(char *bufhdr, size_t maxlen)
{
unsigned int idx;
int printed=0;
int width;
gNB_MAC_INST *gNB = RC.nrmac[0];
for (idx=0; idx < (sizeof(itemtable)/sizeof(struct itemtable_t)); idx++)
{
if ((printed + itemtable[idx].width + 1) > maxlen)
return NULL;
width = itemtable[idx].width;
if (idx == TELNETSRV_TBL_HARQ_DL)
width = (width + 1)*gNB->dl_bler.harq_round_max - 1;
else if (idx == TELNETSRV_TBL_HARQ_UL)
width = (width + 1)*gNB->ul_bler.harq_round_max - 1;
printed += snprintf(bufhdr + printed, maxlen - printed, "%*s ", width, itemtable[idx].itemlabel);
}
bufhdr[printed] = '\n';
printed++;
bufhdr[printed] = '\0';
return bufhdr;
}
static const char *scale_number (float n, int width)
{
static char buf[128];
buf[0] = '\0';
if (width >= snprintf(buf, sizeof(buf), "%*.0f", width, n))
return buf;
char *plabel;
char scale_labels[] = { 'k', 'M', 'G', 'T', 'P', 'E', 0 };// E=exabytes are enough, no need for zettabytes and over
for (plabel = scale_labels; *plabel != 0; plabel++)
{
n /= 1000.0;
if (width >= snprintf(buf, sizeof(buf), "%*.1f%c", width - 1, n, *plabel))
return buf;
// let's retry with one decimal less to see if fits.
if (width >= snprintf(buf, sizeof(buf), "%*.0f%c", width - 1, n, *plabel))
return buf;
}
// worst case...
snprintf(buf, sizeof(buf), "%*s" , width, "?");
return buf;
}
/**
* Display UE statistics collected at gNB node related to MAC protocol (OSI Layer 2). This is for the moment limited to one instance of gNB
* This function is meant to be used in combination with 'telnet set loopd 1000' and 'loop' command prepended to the 'measur' one to provide
* refresh of 1000ms of the CLI.
*
* XXX: You should anyway consider about keeping an historic on the screen for these stats, one line per iteration,
* not overwriting like loop command does until a specific command is pressed. One idea is to implement that as option of the loop command,
* that forces to go in append instead of refreshing the position on the screen.
*
* XXX: note that max line length is TELNET_MAX_MSGLENGTH that is equal to 2048 chars. We do not check it yet in this function.
*/
static void gNBL2pstats_measurcmd_display(telnet_printfunc_t prnt)
{
const int gnb_inst = 0;
gNB_MAC_INST *gNB = RC.nrmac[gnb_inst]; // CAVEATS: using global vars as signature of this function can't be change to fit more params.
pthread_mutex_lock(&gNB->UE_info.mutex);
static char buf[1024];
prnt(gNBL2pstats_gethdrline1(buf, sizeof(buf)));
prnt(gNBL2pstats_gethdrline2(buf, sizeof(buf)));
/* loop over all the UEs registered: to each UE will be given a number that is just a progressive counter*/
int uenum = 1;
UE_iterator(gNB->UE_info.list, UE)
{
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_mac_stats_t *stats = &UE->mac_stats;
const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0;
prnt("%*d" , itemtable[0].width , uenum++);
prnt(" %0*x" , itemtable[1].width , UE->rnti);
prnt(" %*d" , itemtable[2].width , sched_ctrl->ph);
prnt(" %*d" , itemtable[3].width , sched_ctrl->pcmax);
prnt(" %*d" , itemtable[4].width , avg_rsrp);
prnt(" %*d" , itemtable[5].width , stats->num_rsrp_meas);
prnt(" %*d" , itemtable[6].width , UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb);
prnt(" %*d" , itemtable[7].width , UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.ri+1);
prnt(" %*d" , itemtable[8].width , UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1);
prnt(" %*d" , itemtable[9].width , UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2);
prnt(" ");
for (int i=0; i<gNB->dl_bler.harq_round_max; i++){
if (i!=0)
prnt("/");
prnt(scale_number(stats->dl.rounds[i], itemtable[TELNETSRV_TBL_HARQ_DL].width));
}
prnt(" %*"PRIu64"", itemtable[11].width, stats->dl.errors);
prnt(" %*d" , itemtable[12].width, stats->pucch0_DTX);
prnt(" %*.3f" , itemtable[13].width, sched_ctrl->dl_bler_stats.bler);
prnt(" %*d" , itemtable[14].width, sched_ctrl->dl_bler_stats.mcs);
prnt(" ");
prnt(scale_number(stats->dl.total_bytes, itemtable[15].width));
prnt(" ");
for (int i=0; i<gNB->ul_bler.harq_round_max; i++){
if (i!=0)
prnt("/");
prnt(scale_number(stats->ul.rounds[0], itemtable[TELNETSRV_TBL_HARQ_UL].width));
}
prnt(" %*"PRIu64"", itemtable[17].width, stats->ul.errors);
prnt(" %*d" , itemtable[18].width, stats->ulsch_DTX);
prnt(" %*.3f" , itemtable[19].width, sched_ctrl->ul_bler_stats.bler);
prnt(" %*d" , itemtable[20].width, sched_ctrl->ul_bler_stats.mcs);
prnt(" ");
prnt(scale_number(stats->ulsch_total_bytes_scheduled, itemtable[21].width));
prnt(" ");
prnt(scale_number(stats->ul.total_bytes, itemtable[22].width));
prnt("\n");
/*
* XXX-TODO: the values below
* values: stats->dl.lc_bytes[lc_id] for lc_id = 0 ..63;
* values: stats->ul.lc_bytes[lc_id] for lc_id = 0 ..63;
* were included in the previous version of the stats. We will think about including as they are too many
* to be added to one line stats display.
*/
}
pthread_mutex_unlock(&gNB->UE_info.mutex);
/*
* XXX-TODO: also the values below
* print_meas(&gNB->eNB_scheduler, "DL & UL scheduling timing stats", NULL, NULL);
* print_meas(&gNB->schedule_dlsch,"dlsch scheduler",NULL,NULL);
* print_meas(&gNB->rlc_data_req, "rlc_data_req",NULL,NULL);
* print_meas(&gNB->rlc_status_ind,"rlc_status_ind",NULL,NULL);
* were included in the previous version of the stats. They were using print_meas() to display to stderr and should be changed to
* leverage prnt() function. This can be done via using print_meas_log() that prints to buffer, but unfortunately this function will include
* the header of the fields you are printing (and we want to have just one line header, see gNBL2pstats_gethdrline2()), so you probably would
* need to create a new print function i.e. print_meas_lograw().
*/
}

View File

@@ -47,7 +47,7 @@
#include "common/utils/LOG/log.h"
#include "common/config/config_userapi.h"
#include "telnetsrv_measurements.h"
#include "common/utils/cpustats.h"
static char *grouptypes[] = {"ltestats","cpustats"};
static double cpufreq;
@@ -285,94 +285,6 @@ int measurcmd_async(char *buf, int debug, telnet_printfunc_t prnt) {
free(subcmd);
return CMDSTATUS_FOUND;
}
/**
* Parse command "measur enable STATNAME" and take action. STATNAME can be retrieved from 'measur show groups '
*
* @param[in] buf buffer containing the command to be parsed. Expected "<stats name>"
* @param[in] debug if > 0, it print debugging information on the log file for telnet
* @param[in] prnt printing function for telnet CLI
*
* @return 0(success), error code otherwise
*/
int
measurcmd_enablestats(char *buf, int debug, telnet_printfunc_t prnt)
{
char *statname = NULL;
int ret = CMDSTATUS_NOTFOUND;
if (debug > 0)
prnt("measurcmd_enablestats received %s\n", buf);
if (buf == NULL)
return ret;
if (sscanf(buf, "%ms\n", &statname) != 1){
prnt("Error parsing commandline for enable stats: %s\n", strerror(errno));
return ret;
}
if (strcmp (statname, UE_STATS_L1) == 0){
if (UEL1cpustats_enable() ==false)
prnt ("Error when enabling statistics. See log file of UE for exact cause\n");
else
ret = CMDSTATUS_FOUND;
} else if (strcmp (statname, GNB_STATS_L1) == 0){
if (gNBL1cpustats_enable(RC.gNB[0]) == false)
prnt ("Error when enabling statistics. See log file of gNB for exact cause\n");
else
ret = CMDSTATUS_FOUND;
} else if (strcmp (statname, GNB_STATS_L2_MAC) == 0){
prnt ("Nothing to do for this type of statistic. Already activated\n");
ret = CMDSTATUS_FOUND;
} else {
prnt ("ERR: unsupported stat %s\n", statname);
}
return ret;
}
/**
* Parse command "measur disable STATNAME" and take action. STATNAME can be retrieved from 'measur show groups '
*
* @param[in] buf buffer containing the command to be parsed. Expected "<stats name>"
* @param[in] debug if > 0, it print debugging information on the log file for telnet
* @param[in] prnt printing function for telnet CLI
*
* @return 0(success), error code otherwise
*/
int
measurcmd_disablestats(char *buf, int debug, telnet_printfunc_t prnt)
{
char *statname = NULL;
int ret = CMDSTATUS_NOTFOUND;
if (debug > 0)
prnt("measurcmd_disablestats received %s\n", buf);
if (buf == NULL)
return ret;
if (sscanf(buf, "%ms\n", &statname) != 1){
prnt("Error parsing commandline for disable stats: %s\n", strerror(errno));
return ret;
}
if (strcmp (statname, UE_STATS_L1) == 0){
UEL1cpustats_disable();
ret = CMDSTATUS_FOUND;
} else if (strcmp (statname, GNB_STATS_L1) == 0){
gNBL1cpustats_disable();
ret = CMDSTATUS_FOUND;
} else if (strcmp (statname, GNB_STATS_L2_MAC) == 0){
prnt ("Nothing to do for this type of statistic. They are always activated\n");
ret = CMDSTATUS_FOUND;
} else {
prnt ("ERR: unsupported statistic to be disabled: %s\n", statname);
}
return ret;
}
/*-------------------------------------------------------------------------------------*/
/* function called at telnet server init to add the measur command */

View File

@@ -79,24 +79,16 @@ typedef struct mesurgroupdef {
#define MACSTATS_NAME(valptr) #valptr
#define LTEMAC_MEASURGROUP_NAME "ltemac"
#define PHYCPU_MEASURGROUP_NAME "phycpu"
#define GNB_STATS_L2_MAC "gnb_L2"
#ifdef TELNETSRV_MEASURMENTS_MAIN
int measurcmd_show(char *buf, int debug, telnet_printfunc_t prnt);
int measurcmd_cpustats(char *buf, int debug, telnet_printfunc_t prnt);
int measurcmd_async(char *buf, int debug, telnet_printfunc_t prnt);
int measurcmd_enablestats(char *buf, int debug, telnet_printfunc_t prnt);
int measurcmd_disablestats(char *buf, int debug, telnet_printfunc_t prnt);
telnetshell_cmddef_t measur_cmdarray[] = {
{"show", "groups | <group name> | inq" , measurcmd_show},
{"cpustats", "[enable | disable]", measurcmd_cpustats},
{"enable", "<stat name>", measurcmd_enablestats},
{"disable", "<stat name>", measurcmd_disablestats},
{"async", "[enable | disable]", measurcmd_async},
{"", "", NULL}
{"cpustats","[enable | disable]",measurcmd_cpustats},
{"async","[enable | disable]",measurcmd_async},
{"","",NULL}
};
telnetshell_vardef_t measur_vardef[] = {

View File

@@ -48,14 +48,9 @@ void displayList(notifiedFIFO_t *nf) {
static inline notifiedFIFO_elt_t *pullNotifiedFifoRemember( notifiedFIFO_t *nf, struct one_thread *thr) {
mutexlock(nf->lockF);
while(!nf->outF && !thr->terminate)
while(!nf->outF)
condwait(nf->notifF, nf->lockF);
if (thr->terminate) {
mutexunlock(nf->lockF);
return NULL;
}
notifiedFIFO_elt_t *ret=nf->outF;
nf->outF=nf->outF->next;
@@ -64,7 +59,7 @@ static inline notifiedFIFO_elt_t *pullNotifiedFifoRemember( notifiedFIFO_t *nf,
// For abort feature
thr->runningOnKey=ret->key;
thr->dropJob = false;
thr->abortFlag=false;
mutexunlock(nf->lockF);
return ret;
}
@@ -76,10 +71,6 @@ void *one_thread(void *arg) {
// Infinite loop to process requests
do {
notifiedFIFO_elt_t *elt=pullNotifiedFifoRemember(&tp->incomingFifo, myThread);
if (elt == NULL) {
AssertFatal(myThread->terminate, "pullNotifiedFifoRemember() returned NULL although thread not aborted\n");
break;
}
if (tp->measurePerf) elt->startProcessingTime=rdtsc_oai();
@@ -91,15 +82,14 @@ void *one_thread(void *arg) {
// Check if the job is still alive, else it has been aborted
mutexlock(tp->incomingFifo.lockF);
if (myThread->dropJob)
if (myThread->abortFlag)
delNotifiedFIFO_elt(elt);
else
pushNotifiedFIFO(elt->reponseFifo, elt);
myThread->runningOnKey=-1;
mutexunlock(tp->incomingFifo.lockF);
}
} while (!myThread->terminate);
return NULL;
} while (true);
}
void initNamedTpool(char *params,tpool_t *pool, bool performanceMeas, char *name) {
@@ -123,6 +113,7 @@ void initNamedTpool(char *params,tpool_t *pool, bool performanceMeas, char *name
char *saveptr, * curptr;
char *parms_cpy=strdup(params);
pool->nbThreads=0;
pool->restrictRNTI=false;
curptr=strtok_r(parms_cpy,",",&saveptr);
struct one_thread * ptr;
char *tname = (name == NULL ? "Tpool" : name);
@@ -130,6 +121,10 @@ void initNamedTpool(char *params,tpool_t *pool, bool performanceMeas, char *name
int c=toupper(curptr[0]);
switch (c) {
case 'U':
pool->restrictRNTI=true;
break;
case 'N':
pool->activated=false;
break;
@@ -142,8 +137,6 @@ void initNamedTpool(char *params,tpool_t *pool, bool performanceMeas, char *name
pool->allthreads->coreID=atoi(curptr);
pool->allthreads->id=pool->nbThreads;
pool->allthreads->pool=pool;
pool->allthreads->dropJob = false;
pool->allthreads->terminate = false;
//Configure the thread scheduler policy for Linux
// set the thread name for debugging
sprintf(pool->allthreads->name,"%s%d_%d",tname,pool->nbThreads,pool->allthreads->coreID);
@@ -198,12 +191,12 @@ int main() {
tmp=pullNotifiedFIFO(&myFifo);
printf("pulled: %lu\n", tmp->key);
displayList(&myFifo);
abortNotifiedFIFOJob(&myFifo,1005);
abortNotifiedFIFO(&myFifo,1005);
printf("aborted 1005\n");
displayList(&myFifo);
pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 12345678, NULL, NULL));
displayList(&myFifo);
abortNotifiedFIFOJob(&myFifo,12345678);
abortNotifiedFIFO(&myFifo,12345678);
printf("aborted 12345678\n");
displayList(&myFifo);
@@ -272,7 +265,7 @@ int main() {
} else
printf("Empty list \n");
abortTpoolJob(&pool,510);
abortTpool(&pool,510);
} while(tmp);
*/
return 0;

View File

@@ -72,7 +72,6 @@ typedef struct notifiedFIFO_s {
notifiedFIFO_elt_t *inF;
pthread_mutex_t lockF;
pthread_cond_t notifF;
bool abortFIFO; // if set, the FIFO always returns NULL -> abort condition
} notifiedFIFO_t;
// You can use this allocator or use any piece of memory
@@ -108,7 +107,6 @@ static inline void delNotifiedFIFO_elt(notifiedFIFO_elt_t *elt) {
static inline void initNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf) {
nf->inF=NULL;
nf->outF=NULL;
nf->abortFIFO = false;
}
static inline void initNotifiedFIFO(notifiedFIFO_t *nf) {
mutexinit(nf->lockF);
@@ -131,18 +129,14 @@ static inline void pushNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf, notifiedFIF
static inline void pushNotifiedFIFO(notifiedFIFO_t *nf, notifiedFIFO_elt_t *msg) {
mutexlock(nf->lockF);
if (!nf->abortFIFO) {
pushNotifiedFIFO_nothreadSafe(nf,msg);
condsignal(nf->notifF);
}
pushNotifiedFIFO_nothreadSafe(nf,msg);
condsignal(nf->notifF);
mutexunlock(nf->lockF);
}
static inline notifiedFIFO_elt_t *pullNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf) {
if (nf->outF == NULL)
return NULL;
if (nf->abortFIFO)
return NULL;
notifiedFIFO_elt_t *ret=nf->outF;
@@ -158,9 +152,9 @@ static inline notifiedFIFO_elt_t *pullNotifiedFIFO_nothreadSafe(notifiedFIFO_t
static inline notifiedFIFO_elt_t *pullNotifiedFIFO(notifiedFIFO_t *nf) {
mutexlock(nf->lockF);
notifiedFIFO_elt_t *ret = NULL;
notifiedFIFO_elt_t *ret;
while((ret=pullNotifiedFIFO_nothreadSafe(nf)) == NULL && !nf->abortFIFO)
while((ret=pullNotifiedFIFO_nothreadSafe(nf)) == NULL)
condwait(nf->notifF, nf->lockF);
mutexunlock(nf->lockF);
@@ -173,11 +167,6 @@ static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) {
if (tmp != 0 )
return NULL;
if (nf->abortFIFO) {
mutexunlock(nf->lockF);
return NULL;
}
notifiedFIFO_elt_t *ret=pullNotifiedFIFO_nothreadSafe(nf);
mutexunlock(nf->lockF);
return ret;
@@ -200,7 +189,7 @@ static inline time_stats_t exec_time_stats_NotifiedFIFO(const notifiedFIFO_elt_t
// This function aborts all messages matching the key
// If the queue is used in thread pools, it doesn't cancels already running processing
// because the message has already been picked
static inline int abortNotifiedFIFOJob(notifiedFIFO_t *nf, uint64_t key) {
static inline int abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) {
mutexlock(nf->lockF);
int nbDeleted=0;
notifiedFIFO_elt_t **start=&nf->outF;
@@ -222,44 +211,26 @@ static inline int abortNotifiedFIFOJob(notifiedFIFO_t *nf, uint64_t key) {
return nbDeleted;
}
// This functions aborts all messages in the queue, and marks the queue as
// "aborted", such that every call to it will return NULL
static inline void abortNotifiedFIFO(notifiedFIFO_t *nf) {
mutexlock(nf->lockF);
nf->abortFIFO = true;
notifiedFIFO_elt_t **elt = &nf->outF;
while(*elt != NULL) {
notifiedFIFO_elt_t *p = *elt;
*elt = (*elt)->next;
delNotifiedFIFO_elt(p);
}
if (nf->outF == NULL)
nf->inF = NULL;
mutexunlock(nf->lockF);
condsignal(nf->notifF);
}
struct one_thread {
pthread_t threadID;
int id;
int coreID;
char name[256];
uint64_t runningOnKey;
bool dropJob;
bool terminate;
bool abortFlag;
struct thread_pool *pool;
struct one_thread *next;
};
typedef struct thread_pool {
bool activated;
int activated;
bool measurePerf;
int traceFd;
int dummyTraceFd;
uint64_t cpuCyclesMicroSec;
uint64_t startProcessingUE;
int nbThreads;
bool restrictRNTI;
notifiedFIFO_t incomingFifo;
struct one_thread *allthreads;
} tpool_t;
@@ -285,8 +256,6 @@ static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) {
static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
notifiedFIFO_elt_t *msg= pullNotifiedFIFO(responseFifo);
if (msg == NULL)
return NULL;
AssertFatal(t->traceFd, "Thread pool used while not initialized");
if (t->measurePerf)
msg->returnTime=rdtsc_oai();
@@ -312,10 +281,9 @@ static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpo
return msg;
}
static inline int abortTpoolJob(tpool_t *t, uint64_t key) {
static inline int abortTpool(tpool_t *t, uint64_t key) {
int nbRemoved=0;
notifiedFIFO_t *nf=&t->incomingFifo;
mutexlock(nf->lockF);
notifiedFIFO_elt_t **start=&nf->outF;
@@ -332,62 +300,20 @@ static inline int abortTpoolJob(tpool_t *t, uint64_t key) {
if (t->incomingFifo.outF==NULL)
t->incomingFifo.inF=NULL;
struct one_thread *thread = t->allthreads;
while (thread != NULL) {
if (thread->runningOnKey == key) {
thread->dropJob = true;
struct one_thread *ptr=t->allthreads;
while(ptr!=NULL) {
if (ptr->runningOnKey==key) {
ptr->abortFlag=true;
nbRemoved++;
}
thread = thread->next;
ptr=ptr->next;
}
mutexunlock(nf->lockF);
return nbRemoved;
}
static inline int abortTpool(tpool_t *t) {
int nbRemoved=0;
/* disables threading: if a message comes in now, we cannot have a race below
* as each thread will simply execute the message itself */
t->activated = false;
notifiedFIFO_t *nf=&t->incomingFifo;
mutexlock(nf->lockF);
nf->abortFIFO = true;
notifiedFIFO_elt_t **start=&nf->outF;
/* mark threads to abort them */
struct one_thread *thread = t->allthreads;
while (thread != NULL) {
thread->dropJob = true;
thread->terminate = true;
nbRemoved++;
thread = thread->next;
}
/* clear FIFOs */
while(*start!=NULL) {
notifiedFIFO_elt_t **request=start;
*start=(*start)->next;
delNotifiedFIFO_elt(*request);
*request = NULL;
nbRemoved++;
}
if (t->incomingFifo.outF==NULL)
t->incomingFifo.inF=NULL;
condbroadcast(t->incomingFifo.notifF);
mutexunlock(nf->lockF);
/* join threads that are still runing */
thread = t->allthreads;
while (thread != NULL) {
pthread_cancel(thread->threadID);
thread = thread->next;
}
return nbRemoved;
}
void initNamedTpool(char *params,tpool_t *pool, bool performanceMeas, char *name);
#define initTpool(PARAMPTR,TPOOLPTR, MEASURFLAG) initNamedTpool(PARAMPTR,TPOOLPTR, MEASURFLAG, NULL)
#endif

View File

@@ -1,219 +1,217 @@
# Thread pool
The **thread pool** is a working server, made of a set of worker threads that can be mapped on CPU cores. Each thread pool has an **input queue** ("**FIFO**"), from which its workers pick **jobs** (FIFO element) to execute. When a job is done, the worker sends a message to an output queue, if it has been defined.
The thread pool is a working server, made of a set of worker threads that can be mapped on CPU cores.
A selective abort allows to cancel parallel jobs. This can be useful, e.g., if a client pushed jobs, but from a response of one job, the other linked jobs become useless.
Each worker loop on pick from the same input queue jobs to do.
All the thread pool functions are thread safe. The functions executed by worker threads are provided by the thread pool client, so the client has to handle the concurrency/parallel execution of his functions.
When a job is done, the worker sends a return if a return is defined.
A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless).
All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter.
## license
Author:
Laurent Thomas, Open cells project
The owner share this piece code to Openairsoftware alliance as per OSA license terms
With contributions from Robert Schmidt, OSA
# Jobs
# jobs
A job is a message of type `notifiedFIFO_elt_t`:
A job is a message (notifiedFIFO_elt_t):
* `next`: internal FIFO chain, do not set it
* `key`: a `long int` that the client can use to identify a job or a group of messages
* `ResponseFifo`: if the client defines a response FIFO, the job will be posted back after processing
* `processingFunc`: any function (of type `void processingFunc(void *)`) that a worker will process
* `msgData`: the data passed to `processingFunc`. It can be added automatically, or you can set it to a buffer you are managing
* `malloced`: a boolean that enables internal free in the case of no return FIFO or abort feature
* next:
internal FIFO chain, do not set it
* key:
a long int that the client can use to identify a message or a group of messages
* ResponseFifo:
if the client defines a response FIFO, the message will be posted back after processing
* processingFunc:
any funtion (type void processingFunc(void *)) that the worker will launch
* msgData:
the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing
* malloced:
a boolean that enable internal free in these cases:
no return Fifo or Abort feature
The job messages can be created and destroyed with `newNotifiedFIFO_elt()` and `delNotifiedFIFO_elt()`, or managed by the client:
The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client.
* `newNotifiedFIFO_elt()`: Creates a job, that will later be used in queues/FIFO
* `delNotifiedFIFO_elt()`: Deletes a job
* `NotifiedFifoData()`: gives a pointer to the beginning of free usage memory in a job (you can put any data there, up to 'size' parameter you passed to `newNotifiedFIFO_elt()`)
# Queues of jobs
These 3 calls are not mandatory, you can also use your own memory to save the `malloc()`/`free()` that are behind these calls.
Queues are type of:
## API details
* notifiedFIFO_t that must be initialized by init_notifiedFIFO()
* No delete function is required, the creator has only to free the data of type notifiedFIFO_t
* push_notifiedFIFO() add a job in the queue
* pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking
* abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition)
### `notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size, uint64_t key, notifiedFIFO_t *reponseFifo, void (*processingFunc)(void *))`
These queues details hereafter
Creates a new job. The data part of the job will have size `size`, the job can be identified via `key`. `reponseFifo` is a FIFO queue to which the job should be pushed after being processed by a thread pool (see below for details) using function `processingFunc()`.
## Common
The function returns a pointer to an allocated job.
newNotifiedFIFO_elt()
### `void delNotifiedFIFO_elt(notifiedFIFO_elt_t *elt)`
creates a message, that will later be used in queues/FIFO
Free the memory allocated for a job `elt`.
delNotifiedFIFO_elt()
### `void *NotifiedFifoData(notifiedFIFO_elt_t *elt)`
deletes it
Returns a pointer (`void *`) to the data segment of an allocated job.
NotifiedFifoData()
# Queues of jobs (`FIFO`)
gives a pointer to the beginning of free usage memory in a message (you can put any data there, up to 'size' parameter you passed to newNotifiedFIFO_elt()
Queues can be used to enqueue messages/jobs, of type `notifiedFIFO_t`.
These 3 calls are not mandatory, you can also use your own memory to save the malloc()/free() that are behind these calls
iFirst level: non thread safe FIFO (or queues)
* `initNotifiedFIFO()`: Create a queue
* No delete function is required, the creator has only to free the data of type `notifiedFIFO_t`
* `pushNotifiedFIFO()`: Add a job to a queue
* `pullNotifiedFIFO()`: Pull a job from a queue. This call is blocking until a job arrived.
* `pollNotifiedFIFO()`: Pull a job from a queue. This call is not blocking, so it returns always very shortly
* `abortNotifiedFIFOJob()`: Allows to delete all waiting jobs that match a key (see `key` in jobs definition)
* `abortNotifiedFIFO()`: Aborts a FIFO, such that it will always return `NULL`
# low level: fast and simple
Note that in 99.9% of cases, `pull()` is better than `poll()`.
initNotifiedFIFO_nothreadSafe()
The above push/pull/poll functions are built on not-thread-safe versions of these functions that are described below.
to create a queue
## Low level: fast and simple, but not thread-safe
pushNotifiedFIFO_nothreadSafe()
* `initNotifiedFIFO_nothreadSafe()`: Create a queue
* `pushNotifiedFIFO_nothreadSafe()`: Add a element in a queue
* `pullNotifiedFIFO_nothreadSafe()`: Pull a element from a queue
Add a element in a queue
As these queues are not thread safe, there is NO blocking mechanism, neither `pull()` versus `poll()` calls
pullNotifiedFIFO_nothreadSafe()
There is no delete for a message queue: you only have to abandon the memory you allocated to call `initNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf)`
pull a element from a queue
If you malloced the memory under `nf` parameter, you have to free it.
As these queues are not thread safe, there is NO blocking mechanism, neither pull() versus poll() calls
## FIFO queue abort
There is no delete for a message queue: you only have to abandon the memory you allocated to call iinitNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf)
It is possible to *abort* the FIFO queue. In this case, any pulling/polling of jobs in the queue will return `NULL`. This can be used when stopping a program, to release multiple queues that might depend on each other (a proper design would try to avoid such dependencies, though).
So if you malloced the memory under 'nf' parameter you have to free it, if it is automatic variable (local variable) or global variable, nothing is to be done.
## API details
### `void initNotifiedFIFO(notifiedFIFO_t *nf)`
### `void initNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf)`
## thread safe queues
Initializes a FIFO queue pointed to by `nf` ("notified FIFO").
These queues are built on not thread safe queues when we need thread to thread protection
### `void pushNotifiedFIFO(notifiedFIFO_t *nf, notifiedFIFO_elt_t *msg)`
### `void pushNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf, notifiedFIFO_elt_t *msg)`
initNotifiedFIFO()
Pushes a job `msg` to the FIFO queue `nf`.
to create a queue
### `notifiedFIFO_elt_t *pullNotifiedFIFO(notifiedFIFO_t *nf)`
pushNotifiedFIFO()
Pulls a job from a FIFO queue `nf`. The returned pointer points to the job. This call is blocking, i.e., a caller will be blocked until there is a message.
Add a element in a queue
If the FIFO has been aborted, the returned pointer will be `NULL`. In other words, if the call to this functions returns `NULL`, the FIFO has been deactivated.
pullNotifiedFIFO()
### `notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf)`
### `notifiedFIFO_elt_t *pullNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf)`
pull a element from a queue, this call is blocking until a message arrived
Like `pullNotifiedFIFO()`, but non-blocking: they check if the queue `nf` contains a job, and return it. Otherwise, they return `NULL`. Note the slight difference in naming: the thread-safe function is called *poll*, not *pull*.
pollNotifiedFIFO()
Note that unlike for `pullNotifiedFIFO()`, returning `NULL` does not inform whether the queue has been aborted; the caller should manually check the `abortFIFO` flag of `nf` in this case.
pull a element from a queue, this call is not blocking, so it returns always very shortly
### `int abortNotifiedFIFOJob(notifiedFIFO_t *nf, uint64_t key)`
in 99.9% cases, pull() is better than poll()
Aborts all jobs in FIFO queue `nf` with key `key`. Jobs already under execution will be silently dropped and not put in the FIFO return queue, if any.
Returns the number of aborted jobs.
### `void abortNotifiedFIFO(notifiedFIFO_t *nf)`
Aborts the entire FIFO queue `nf`: all jobs will be dropped, and the FIFO is marked as aborted, such that a call to `pullNotifiedFIFO()` returns `NULL`.
Returns the total number of jobs that were waiting or under execution.
No delete() call, same principle as not thread safe queues
# Thread pools
## Initialization
## initialization
The clients can create one or more thread pools with `initTpool(char *params,tpool_t *pool, bool performanceMeas )` or `initNamedTpool(char *params,tpool_t *pool, bool performanceMeas , char *name)`
The clients can create one or more thread pools with
the params string structure: describes a list of cores, separated by "," that run a worker thread
* `initTpool(char *params, tpool_t *pool, bool performanceMeas)` or
* `initNamedTpool(char *params,tpool_t *pool, bool performanceMeas , char *name)`
If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related code (use negative values is allowed, so the thread will never be mapped on a specific core).
The threads are governed by the Linux real time scheduler, and their name is set automatically to `Tpool<thread index>_<core id>` if `initTpool()` is used or to `<name><thread index>_<core id>` when `initNamedTpool()` is used.
The threads are all Linux real time scheduler, their name is set automatically to `Tpool<thread index>_<core id>` if initTpool is used or to `<name><thread index>_<core id>` when initNamedTpool is used.
## Adding jobs
## adding jobs
The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO())
The client create their jobs messages as a `notifiedFIFO_elt_t`. They then push it with `pushTpool()` which internally calls `push_notifiedFIFO()`.
If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job.
If they need a return value (e.g., result of a computation), they have to create response queues with `init_notifiedFIFO()` and set this FIFO pointer in the `notifiedFIFO_elt_t` before pushing the job. This way, multiple result queues can be used in one thread pool.
## abort
## Abort
A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues.
A abort service `abortTpoolJob()` allows to abort all jobs that match a key (see a job's `key`). When the abort returns, it garanties that no job (matching the key) response will be posted on response queues.
Nevertheless, jobs already performed before the return of `abortTpoolJob()` are pushed in the response Fifo queue.
`abortTpool()` kills all jobs in the Tpool, and terminates the pool.
Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue.
## API details
Each thread pool (there can be several in the same process) should be initialized once using one of the two API's:
### `void initNamedTpool(char *params, tpool_t *pool, bool performanceMeas, char *name)`
### initNamedTpool(char *params,tpool_t *pool, bool performanceMeas,char *name)
### `void initTpool(char *params, tpool_t *pool, bool performanceMeas)`
### initTpool(char *params,tpool_t *pool, bool performanceMeas)
`params`: the configuration parameter is a string, elements separator is a comma ",". An element can be:
The `params` string describes a list of cores, separated by "," that run a worker thread. If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related core. The following options are available:
* N: if a N is in the parameter list, no threads are created
The purpose is to keep the same API in any case
* a CPU with a little number of cores,
or in debugging sessions to simplify the human work
* a number that represent a valid CPU core on the target CPU
A thread is created and stick on the core (with set affinity)
* a number that is not a valid CPU core
a floating thread is created (Linux is responsible of the real time core allocation)
* `N`: if an `N` is in the parameter list, no threads are created, and the threadpool will be disabled (jobs will be treated by each calling thread independently).
* A number that represent a valid CPU core on the target CPU, i.e., if there are `M` cores, a number within `[0,M-1]`: A thread is created and pinned to the core (with set affinity)
* `-1`: The thread will not be mapped onto a specific core (a "floating" thread)
example: "-1,-1,-1"
as there is no core number -1, the thread pool is made of 3 floating threads
be careful with fix allocation: it is hard to be more clever than Linux kernel
Example: `-1,-1,-1`: the thread pool is made of 3 floating threads.
Be careful with a fixed allocation: it is hard to be more clever than Linux kernel!
`pool` is the memory you allocated before to store the thread pool internal state (same concept as above queues)
`pool` is a pointer to the thread pool object.
`performanceMeas` is a flag to enable measurements (see also below).
`performanceMeas` is a flag to enable measurements (well described in documentation)
`name` is used to build the thread names.
### `void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg)`
### pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg)
Adds a job for processing in the thread pool.
adds a job to do in the thread pool
The job data you can set are, inside `msg`:
The msg data you can set are:
* `key`: an arbitrary key to find a job in a response queue, and which can be used to abort jobs using `abortTpoolJob()`.
* `reponseFifo`: if non-`NULL`, the message will be sent back on this queue when the job is done. If `NULL`, the thread pool automatically frees the job when it is done.
* `processingFunc`: the function to execute for this job.
* key:
a value for you that you will find back in the response
it is also the key for abortTpool()
* reponseFifo
if you set it, the message will be sent back on this queue when the job is done
if you don't set it, no return is performed, the thread pool frees the message 'msg' when the job is done
* processingFunc
the function the job will run. the function prototype is void <func>(void *memory)
the data part (the pointer returned by NotifiedFifoData(msg)) is passed to the function
it is used to send data to the processing function and also to write back results
of course, writing back results will lead you to use also a return queue (the parameter reponseFifo)
The `processingFunc` prototype is `void <func>(void *memory)`. The data part of the job (the pointer returned by `NotifiedFifoData(msg)`) is passed to the function. The job data will be updated by `processingFunc`, and the job will be pushed into return queue (the parameter `reponseFifo`).
### pullTpool() collects job result in a return queue
### `notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t)`
you collect results in one result queue: the message you gave to pushTpool(), nevertheless it has been updated by processingFunc()
Collects a job result in a return queue that has been defined in `msg` when calling `pushTpool()`, and that has been updated by `processingFunc()`. Returns the corresponding job pointer of type `notifiedFIFO_elt_t *`.
An example of multiple return queues, in eNB: I created one single thread pool (because it depends mainly on CPU hardware), but i use two return queues: one for turbo encode, one for turbo decode.
Multiple return queues might be useful. Consider the following example in the eNB: I created one single thread pool (because it depends mainly on CPU hardware), but i use two return queues: one for turbo encode, one for turbo decode. Thus, when performing Turbo encoding/decoding, jobs are pushed into a single thread pool, but will end up in different result queues, such that DL/UL processing can be separated more easily.
### tryPullTpool()
### `notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpool_t *t)`
is the same, but not blocking (pollTpool() would have been a better name)
The same as `pullTpool()` in a non-blocking fashion (an alternative name would have been `pollTpool()`).
### abortTpool()
### `int abortTpoolJob(tpool_t *t, uint64_t key)`
Is a facility to cancel work you pushed to a thread pool
Is a facility to cancel work you pushed to a thread pool: every job with a given `key` will be deleted, and results of jobs with such `key` under execution will be dropped.
I used it once: when eNB performs turbo decode, I push all segments in the thread pool.
It returns the number of aborted jobs, including the ones that are currently being executed.
I used it once: when eNB performs turbo decode, I push all segments in the thread pool. But when I get back the decoding results, if one segment can't be decoded, I don't need the results of the other segments of the same UE.
### `int abortTpool(tpool_t *t)`
Aborts the complete Tpool: cancel every work in the input queue, marks to drop existing jobs in processing, and terminates all worker threads. It is afterwards still possible to call functions such as `pushTpool()`, but each calling thread will execute the job itself.
Returns the total number of jobs that were aborted, i.e., waiting for execution or being executed.
But when I get back the decoding results, if one segment can't be decoded, I don't need the results of the other segments of the same UE.
## Performance measurements
A performance measurement is integrated: the pool will automacillay fill timestamps if you set the environement variable `threadPoolMeasurements` to a valid file name. The following measurements will be written to Linux pipe on a per-job basis:
A performance measurement is integrated:
the pool will automacillay fill timestamps:
* `creationTime`: time the request is push to the pool;
* `startProcessingTime`: time a worker start to run on the job
* `endProcessingTime`: time the worker finished the job
* `returnTime`: time the client reads the result
* creationTime:
time the request is push to the pool;
* startProcessingTime:
time a worker start to run on the job
* endProcessingTime:
time the worker finished the job
* returnTime:
time the client reads the result
The `measurement_display` tool to read the Linux pipe and display it in ASCII is provided.
In the cmake build directory, type `make/ninja measurement_display`. Use as
follows:
```
sudo threadPoolMeasurements=tpool.meas ./nr-softmodem ...
./measurement_display tpool.meas
```
if you set the environement variable:
threadPoolMeasurements to a valid file name
These measurements will be wrote to this Linux pipe.
A tool to read the linux fifo and display it in ascii is provided; compute the binay:
in cmake building directory: make/ninja measurement_display

View File

@@ -62,7 +62,7 @@ typedef struct time_stats {
oai_cputime_t in; /*!< \brief time at measure starting point */
oai_cputime_t diff; /*!< \brief average difference between time at starting point and time at endpoint*/
oai_cputime_t p_time; /*!< \brief absolute process duration */
double diff_square; /*!< \brief process duration square */
oai_cputime_t diff_square; /*!< \brief process duration square */
oai_cputime_t max; /*!< \brief maximum difference between time at starting point and time at endpoint*/
int trials; /*!< \brief number of start point - end point iterations */
int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */
@@ -156,7 +156,7 @@ static inline void stop_meas(time_stats_t *ts) {
ts->diff += (out-ts->in);
/// process duration is the difference between two clock points
ts->p_time = (out-ts->in);
ts->diff_square += ((double)out-ts->in)*((double)out-ts->in);
ts->diff_square += (out-ts->in)*(out-ts->in);
if ((out-ts->in) > ts->max)
ts->max = out-ts->in;

View File

@@ -440,10 +440,6 @@ The following features are valid for the gNB and the 5G-NR UE.
- PTRS support
- Support for 1, 2 and 4 RX antennas
- Support for up to 2 layers (currently limited to DMRS configuration type 2)
* Measurements based on NR-CSIRS
- RI, PMI and CQI computation
- Support for 1 and 2 RX antennas
- Support for up to 2 layers
* NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
- PUSCH mapping type A and B
- DMRS configuration type 1 and 2
@@ -492,15 +488,12 @@ The following features are valid for the gNB and the 5G-NR UE.
* UCI processing
- ACK/NACK processing
- Triggering periodic SR
- CSI measurement reporting
* DLSCH scheduler
- CSI measurement reporting (SSB RSRP only)
* DLSH scheduler
- Configuration of fapi PDU according to DCI
- HARQ procedures
* ULSCH scheduler
- Configuration of fapi PDU according to DCI
* NR-CSIRS scheduler
- Scheduling of NR-CSIRS reception
- Fill UCI for CSI measurement reporting
* Scheduler procedures for SRS transmission
- Periodic SRS transmission
* Bandwidth part (BWP) operation

48
doc/ITTISIM.md Executable file
View File

@@ -0,0 +1,48 @@
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">Running L3 ITTI simulator</font></b>
</td>
</tr>
</table>
This page is valid on the following branches:
- `develop` starting from tag `2020.w48`
# 1. Building the ITTI simulator.
The ITTI simulator is available directly from the standard build.
```bash
$ source oaienv
$ cd cmake_targets
$ sudo ./build_oai -x -w None -c -ittiSIM
```
# 2. Running the ITTI simulator.
The ITTI simulator establishes ITTI-threaded communication between the gNB RRC task and the UE RRC task.
This allows to test the sequence of NGAP/RRC/NAS messages.
The main limitations are:
- NAS is a simple stub that just sends and receives messages
- only initial Attach sequence
## 2.1. Starting the ITTI simulator
The ITTI simulator is able to run with a connected 5GC or without any.
The develop branch tag `2020.w48` only works RRC without 5GC connection.
```bash
$ sudo -E ./ran_build/build/nr-ittisim -O gnb.conf
```

View File

@@ -71,6 +71,10 @@ reboot
# https://docs.docker.com/compose/install/
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net
sudo service docker restart
```
## 2.2 OAI CN5G Setup
@@ -78,36 +82,39 @@ sudo chmod +x /usr/local/bin/docker-compose
```bash
# Git oai-cn5g-fed repository
git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed
cd ~/oai-cn5g-fed
git checkout master
./scripts/syncComponents.sh --nrf-branch develop --amf-branch develop --smf-branch develop --spgwu-tiny-branch develop --ausf-branch develop --udm-branch develop --udr-branch develop --upf-vpp-branch develop --nssf-branch develop
# Pull docker images
docker pull oaisoftwarealliance/oai-amf:develop
docker pull oaisoftwarealliance/oai-nrf:develop
docker pull oaisoftwarealliance/oai-smf:develop
docker pull oaisoftwarealliance/oai-udr:develop
docker pull oaisoftwarealliance/oai-udm:develop
docker pull oaisoftwarealliance/oai-ausf:develop
docker pull oaisoftwarealliance/oai-upf-vpp:develop
docker pull oaisoftwarealliance/oai-spgwu-tiny:develop
docker pull oaisoftwarealliance/trf-gen-cn5g:latest
docker pull oaisoftwarealliance/oai-nssf:develop
# Tag docker images
docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop
docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop
docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop
docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop
docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop
docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop
docker image tag oaisoftwarealliance/oai-upf-vpp:develop oai-upf-vpp:develop
docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop
docker image tag oaisoftwarealliance/trf-gen-cn5g:latest trf-gen-cn5g:latest
docker image tag oaisoftwarealliance/oai-nssf:develop oai-nssf:develop
```
## 2.3 OAI CN5G Configuration files
Download and copy configuration files:
- Copy [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) to `~/oai-cn5g-fed/docker-compose`
- Copy [oai_db.sql](tutorial_resources/oai_db.sql) to `~/oai-cn5g-fed/docker-compose/database`
Download and copy the configuration files to ~/oai-cn5g-fed/docker-compose:
- [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml)
- [oai_db.sql](tutorial_resources/oai_db.sql)
Change permissions on oai_db.sql to prevent mysql permission denied error:
```bash
chmod 644 ~/oai-cn5g-fed/docker-compose/database/oai_db.sql
chmod 644 ~/oai-cn5g-fed/docker-compose/oai_db.sql
```
## 2.4 SIM Card
@@ -168,7 +175,7 @@ cd cmake_targets
```bash
cd ~/oai-cn5g-fed/docker-compose
python3 core-network.py --type start-basic --scenario 1
python3 core-network.py --type start-basic --fqdn yes --scenario 1
```
## 4.2 Run OAI gNB

View File

@@ -72,6 +72,10 @@ reboot
# https://docs.docker.com/compose/install/
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net
sudo service docker restart
```
## 2.2 OAI CN5G Setup
@@ -79,36 +83,39 @@ sudo chmod +x /usr/local/bin/docker-compose
```bash
# Git oai-cn5g-fed repository
git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed
cd ~/oai-cn5g-fed
git checkout master
./scripts/syncComponents.sh --nrf-branch develop --amf-branch develop --smf-branch develop --spgwu-tiny-branch develop --ausf-branch develop --udm-branch develop --udr-branch develop --upf-vpp-branch develop --nssf-branch develop
# Pull docker images
docker pull oaisoftwarealliance/oai-amf:develop
docker pull oaisoftwarealliance/oai-nrf:develop
docker pull oaisoftwarealliance/oai-smf:develop
docker pull oaisoftwarealliance/oai-udr:develop
docker pull oaisoftwarealliance/oai-udm:develop
docker pull oaisoftwarealliance/oai-ausf:develop
docker pull oaisoftwarealliance/oai-upf-vpp:develop
docker pull oaisoftwarealliance/oai-spgwu-tiny:develop
docker pull oaisoftwarealliance/trf-gen-cn5g:latest
docker pull oaisoftwarealliance/oai-nssf:develop
# Tag docker images
docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop
docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop
docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop
docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop
docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop
docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop
docker image tag oaisoftwarealliance/oai-upf-vpp:develop oai-upf-vpp:develop
docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop
docker image tag oaisoftwarealliance/trf-gen-cn5g:latest trf-gen-cn5g:latest
docker image tag oaisoftwarealliance/oai-nssf:develop oai-nssf:develop
```
## 2.3 OAI CN5G Configuration files
Download and copy configuration files:
- Copy [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) to `~/oai-cn5g-fed/docker-compose`
- Copy [oai_db.sql](tutorial_resources/oai_db.sql) to `~/oai-cn5g-fed/docker-compose/database`
Download and copy the configuration files to ~/oai-cn5g-fed/docker-compose:
- [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml)
- [oai_db.sql](tutorial_resources/oai_db.sql)
Change permissions on oai_db.sql to prevent mysql permission denied error:
```bash
chmod 644 ~/oai-cn5g-fed/docker-compose/database/oai_db.sql
chmod 644 ~/oai-cn5g-fed/docker-compose/oai_db.sql
```
## 2.4 SIM Card
@@ -186,7 +193,7 @@ The following steps are recommended. Please change the network interface(s) as r
```bash
cd ~/oai-cn5g-fed/docker-compose
python3 core-network.py --type start-basic --scenario 1
python3 core-network.py --type start-basic --fqdn yes --scenario 1
```
## 4.2 Run OAI gNB

View File

@@ -101,6 +101,7 @@ raw incoming data is in buffer called "rxdata"
## nr_fep_full()
"front end processing" of uplink signal
performs DFT on the signal
same function (duplicates): phy_procedures_gNB_common_RX()
it computes the buffer rxdataF (for frequency) from rxdata (samples over time)
rxdataF is the rxdata in frequency domain, phase aligned
{: .func3}

View File

@@ -9,19 +9,19 @@
| Machine | IP address | Lockable Resource | Function | Connected devices |
| ------------- | --------------- | --------------------- | ------------------ | ----------------------------------------------------- |
| asterix | 172.21.16.127 | CI-Asterix-Usage | gNB (n78) | 173.21.19.14 |
| obelix | 172.21.16.128 | CI-Obelix-Usage | eNB (n40, n78), nrUE | 172.21.19.13, X300 (192.168.60.2), B200mini (30C51EB) |
| asterix | 172.21.16.127 | CI-Asterix-Usage | gNB | 173.21.19.14 |
| obelix | 172.21.16.128 | CI-Obelix-Usage | eNB, UE (5G) | 172.21.19.13, X300 (192.168.60.2), B200mini (30C51EB) |
| porcepix | 172.21.16.136 | CI-NSA-MiniBench | Executor, EPC, 5GC | -- |
| nrmodule2 | 172.21.16.139 | CI-NSA-MiniBench | Quectel | Quectel module |
| nepes | 172.21.16.137 | CI-NSA-MiniBench | gNB (n78) | B200mini (30C51D4) |
| nepes | 172.21.16.137 | CI-NSA-MiniBench | gNB | B200mini (30C51D4) |
| caracal | 172.21.16.132 | CI-Caracal | gNB/phytest | N300 (192.168.10.2) |
| idefix | 172.21.16.135 | CI-NSA-MiniBench | Quectel | Quectel module |
| amariue | 172.21.16.144 | CI-Amarisoft-UE-Usage | nrUE | Amarisoft UE simulator |
| amariue | 172.21.16.144 | CI-Amarisoft-UE-Usage | TBD | Amarisoft UE simulator |
| bellatrix | 192.168.117.115 | CI-RAN-VM-Deployment | Executor | -- |
| nano | 192.168.12.62 | CI-Bench-1-Phones | EPC, adb | 2x COTS (adb) |
| hutch | 192.168.12.19 | CI-Bench-1-Phones | eNB (B7) | B200mini (30C5239) |
| starsky | 192.168.12.18 | CI-Bench-1-Phones | eNB (B40) | b200mini (30A3E3C) |
| carabe | 192.168.12.211 | CI-Bench-2-OAI-Phone | UE (B7UE) | B200mini (30AE8C9) |
| carabe | 192.168.12.211 | CI-Bench-2-OAI-Phone | UE 4G (B) | B200mini (30AE8C9) |
Note: The available resources, and their current usage, is indicated here:
- [Lockable resources of jenkins-oai](https://jenkins-oai.eurecom.fr/lockable-resources/):
@@ -40,7 +40,7 @@ Note: The available resources, and their current usage, is indicated here:
### OTA Testbench
**Purpose**: Over-the-air 4G/5G (NSA/SA) tests
[Proper image to be followed up. TBD: add antennas/circulators]
Note: obelix and porcepix are both used in the OTA testbench and the 5G
NSA/Faraday Cage testbench!
@@ -83,19 +83,13 @@ Webhook
- caracal + N310
- pure performance test through phy-test scheduler, see command line for more
details
- [RAN-L2-Sim-Test-5G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-4G/)
- obelix (eNB, 1x UE, OAI EPC)
- L2simulator: skips physical layer and uses proxy between eNB and UE
- [RAN-L2-Sim-Test-5G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-5G/)
- obelix (gNB, 1x UE, OAI 5GC)
- L2simulator: skips physical layer and uses proxy between gNB and UE,
currently only ping
- [RAN-NSA-B200-Module-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-NSA-B200-Module-LTEBOX-Container/)
- obelix + B200, nepes + B200, idefix + Quectel, porcepix w/ ltebox
- basic NSA test
- [RAN-SA-B200-Module-SABOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-SA-B200-Module-SABOX-Container/)
- obelix + B200, nepes + B200, idefix + Quectel, porcepix w/ sabox
- basic SA test (40 MHz TDD)
- basic NSA test, known to be instable
- [RAN-PhySim-Cluster](https://jenkins-oai.eurecom.fr/job/RAN-PhySim-Cluster/)
- asterix (`Asterix-OC-oaicicd-session` resource), tests in OpenShift Cluster
- unitary simulators (`nr_dlsim`, etc.)

View File

@@ -181,6 +181,21 @@ nssai_sd=1;
}
```
Alternatively, the values can be hardcoded/edited in source file ***openair3/UICC/usim_interface.c*** through the following lines:
```bash
#define UICC_PARAMS_DESC {\
{"imsi", "USIM IMSI\n", 0, strptr:&(uicc->imsiStr), defstrval:"2089900007487", TYPE_STRING, 0 },\
{"nmc_size" "number of digits in NMC", 0, iptr:&(uicc->nmc_size), defintval:2, TYPE_INT, 0 },\
{"key", "USIM Ki\n", 0, strptr:&(uicc->keyStr), defstrval:"fec86ba6eb707ed08905757b1bb44b8f", TYPE_STRING, 0 },\
{"opc", "USIM OPc\n", 0, strptr:&(uicc->opcStr), defstrval:"c42449363bbad02b66d16bc975d77cc1", TYPE_STRING, 0 },\
{"amf", "USIM amf\n", 0, strptr:&(uicc->amfStr), defstrval:"8000", TYPE_STRING, 0 },\
{"sqn", "USIM sqn\n", 0, strptr:&(uicc->sqnStr), defstrval:"000000", TYPE_STRING, 0 },\
{"dnn", "UE dnn (apn)\n", 0, strptr:&(uicc->dnnStr), defstrval:"oai", TYPE_STRING, 0 },\
{"nssai_sst", "UE nssai\n", 0, iptr:&(uicc->nssai_sst), defintval:1, TYPE_INT, 0 }, \
{"nssai_sd", "UE nssai\n", 0, iptr:&(uicc->nssai_sd), defintval:1, TYPE_INT, 0 }, \
};
```
For interoperability with OAI or other CNs, it should be ensured that the configuration of the aforementioned parameters match the configuration of the corresponding subscribed user at the core network.

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