mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-17 06:30:31 +00:00
Compare commits
347 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ef5fafe89 | ||
|
|
9f6e46bd8a | ||
|
|
7372378732 | ||
|
|
71d20e0543 | ||
|
|
33fd2343ce | ||
|
|
48ef96959d | ||
|
|
c73ce11828 | ||
|
|
66546b7ad0 | ||
|
|
11087fff0f | ||
|
|
ffa13d99e5 | ||
|
|
ccae22f648 | ||
|
|
4e932c9248 | ||
|
|
0c9dd4d04a | ||
|
|
67a5bfaa43 | ||
|
|
501192a1f8 | ||
|
|
83d00d4c21 | ||
|
|
12504106eb | ||
|
|
3bb957722f | ||
|
|
ae2abbc6e2 | ||
|
|
544c723372 | ||
|
|
1e34ab443c | ||
|
|
519b38817a | ||
|
|
3da668576c | ||
|
|
ce46cab866 | ||
|
|
553c6377aa | ||
|
|
b42694254f | ||
|
|
50821cace3 | ||
|
|
2fb9752bff | ||
|
|
7b57a3d4ed | ||
|
|
d81b670ac2 | ||
|
|
461ba045b1 | ||
|
|
03a8ff2913 | ||
|
|
6e85528582 | ||
|
|
81ba755984 | ||
|
|
e8ca483c56 | ||
|
|
f8eba8400d | ||
|
|
6d2bd1025f | ||
|
|
36c0cf0133 | ||
|
|
7b31678bed | ||
|
|
b2ba88667a | ||
|
|
0aca093122 | ||
|
|
73f5496ffa | ||
|
|
f809e4689c | ||
|
|
5ae59cc394 | ||
|
|
def1ebc661 | ||
|
|
b57963dd2a | ||
|
|
d33ae02d39 | ||
|
|
86ba2b0822 | ||
|
|
4bfc929bad | ||
|
|
db81a3f0b9 | ||
|
|
abf14c0bb4 | ||
|
|
a1d4514ae0 | ||
|
|
d813fb8470 | ||
|
|
e2615dd886 | ||
|
|
cc24755a34 | ||
|
|
ca45cbb2b7 | ||
|
|
deb2a453c6 | ||
|
|
5a08d8109c | ||
|
|
65c858757d | ||
|
|
55003cafd2 | ||
|
|
57a7488e85 | ||
|
|
da85cf5183 | ||
|
|
32a6dd85c2 | ||
|
|
d9216265dc | ||
|
|
99ecd83133 | ||
|
|
c4958e50e8 | ||
|
|
7b16f7e863 | ||
|
|
e0c7980df5 | ||
|
|
4b002029fb | ||
|
|
27d626dc48 | ||
|
|
4fa9e2b39b | ||
|
|
fb5c768159 | ||
|
|
0966ceb70b | ||
|
|
b75d4f90b7 | ||
|
|
8cbe53b82b | ||
|
|
13e17339d3 | ||
|
|
6d457fcb56 | ||
|
|
748d4cb49a | ||
|
|
1e77b753ff | ||
|
|
2964ef7e3e | ||
|
|
7f69632bbb | ||
|
|
17af1562a8 | ||
|
|
c3378c7f84 | ||
|
|
38dca6387f | ||
|
|
4a42ff54df | ||
|
|
22d4495c20 | ||
|
|
3b93a9c5cb | ||
|
|
6407df90e2 | ||
|
|
d75da26833 | ||
|
|
b0f0106cc7 | ||
|
|
2690cbd08e | ||
|
|
868f9d9042 | ||
|
|
ad0dcfe287 | ||
|
|
7bd44da548 | ||
|
|
185e5934b7 | ||
|
|
24802ee18b | ||
|
|
8916cfdfd2 | ||
|
|
b135c1dd8f | ||
|
|
6e61c8a05a | ||
|
|
c957882da8 | ||
|
|
7404ad7a5c | ||
|
|
4e8fa01a25 | ||
|
|
ec0d3fde1c | ||
|
|
58618be544 | ||
|
|
7e7c097942 | ||
|
|
94796957e8 | ||
|
|
55d9200a48 | ||
|
|
d815edebe7 | ||
|
|
f1d18b4edb | ||
|
|
06355e9cf1 | ||
|
|
9bcf269856 | ||
|
|
9bfcbe7faa | ||
|
|
fa92bf1a79 | ||
|
|
a348ada211 | ||
|
|
e0f76e6ca6 | ||
|
|
351f069adc | ||
|
|
64f84cdd6a | ||
|
|
8bd1b3b53a | ||
|
|
2aef88960f | ||
|
|
51d6fd7ec2 | ||
|
|
f2d43636bf | ||
|
|
dbeda2d33f | ||
|
|
5d9f91997e | ||
|
|
210429f388 | ||
|
|
dc40e0dca1 | ||
|
|
fe8f418e7a | ||
|
|
98de3b9049 | ||
|
|
55d83f6045 | ||
|
|
6882b63991 | ||
|
|
45896f2583 | ||
|
|
ed6b13c759 | ||
|
|
eee4d3fc07 | ||
|
|
b8f64823bf | ||
|
|
d37952f94d | ||
|
|
12e2eded38 | ||
|
|
d910e92669 | ||
|
|
9e2f2db88c | ||
|
|
85929b7933 | ||
|
|
5673a31814 | ||
|
|
7da80421ff | ||
|
|
35e4f29cf6 | ||
|
|
c1abfcfc50 | ||
|
|
b2e8b78a01 | ||
|
|
53e160728a | ||
|
|
522f2ad140 | ||
|
|
4a26a44ee0 | ||
|
|
59722d1a91 | ||
|
|
218a524cd2 | ||
|
|
f44f105cb3 | ||
|
|
32ff4b33f1 | ||
|
|
bf0492ba87 | ||
|
|
7a9c13422a | ||
|
|
3e3b33e94c | ||
|
|
58ae227080 | ||
|
|
81a671a4f3 | ||
|
|
039c6d24bc | ||
|
|
ec80ef106f | ||
|
|
60f17d4d45 | ||
|
|
5e86379be4 | ||
|
|
62789c5161 | ||
|
|
bede89b233 | ||
|
|
4a29496988 | ||
|
|
a809a8c722 | ||
|
|
ad3ce4ddb6 | ||
|
|
72df29f225 | ||
|
|
42ab0247bf | ||
|
|
a439a0cce0 | ||
|
|
f7c9075337 | ||
|
|
15fc3ccce0 | ||
|
|
f2500d9297 | ||
|
|
72bc9baf2e | ||
|
|
6cef7a8f67 | ||
|
|
b32524dd74 | ||
|
|
a45dd3b8bc | ||
|
|
a981bb382b | ||
|
|
f17aba0f5e | ||
|
|
ca0398c5bc | ||
|
|
ab6bb2534e | ||
|
|
c875ce639c | ||
|
|
23a1d8d9bc | ||
|
|
c0f6b39da5 | ||
|
|
095be9fe6a | ||
|
|
82ebc9fa7b | ||
|
|
526720cb24 | ||
|
|
433dbcd41a | ||
|
|
20b3210062 | ||
|
|
b959af152d | ||
|
|
e5335a0188 | ||
|
|
1387bdc16e | ||
|
|
d2dfe830e7 | ||
|
|
3da8b0e5eb | ||
|
|
de0e075381 | ||
|
|
826b405d47 | ||
|
|
d761f67bcf | ||
|
|
975835804d | ||
|
|
b467fd2c68 | ||
|
|
daec2ba3ea | ||
|
|
e705c88dd5 | ||
|
|
7121bf6d05 | ||
|
|
1228608cc2 | ||
|
|
47ac986d8c | ||
|
|
8ea378eea8 | ||
|
|
2c688f230f | ||
|
|
cbec64c28f | ||
|
|
1c352f3138 | ||
|
|
5e964d660f | ||
|
|
2e66c87f4d | ||
|
|
82a771dd61 | ||
|
|
c99f52207d | ||
|
|
3555edff76 | ||
|
|
6723fc531b | ||
|
|
26cc637d1b | ||
|
|
e63f1454b3 | ||
|
|
c69d980613 | ||
|
|
4c4917442f | ||
|
|
bfb06225a5 | ||
|
|
d62892ff8a | ||
|
|
78ed7d4570 | ||
|
|
d969a124ee | ||
|
|
b68e614850 | ||
|
|
17a4dea3e1 | ||
|
|
43130b687e | ||
|
|
fdf2728d02 | ||
|
|
2783acb933 | ||
|
|
e78e720a46 | ||
|
|
2d9bac6359 | ||
|
|
2ebb462a8e | ||
|
|
8ea5fd7894 | ||
|
|
c939a9cdf5 | ||
|
|
31c9a03e83 | ||
|
|
b7b41fefc0 | ||
|
|
29c5129b0a | ||
|
|
3b0f050a33 | ||
|
|
dc6dd67827 | ||
|
|
9f10bfebf2 | ||
|
|
b34a44a4f9 | ||
|
|
0b7201244a | ||
|
|
28bd9ea4bc | ||
|
|
044ed48fc7 | ||
|
|
1b071df0bc | ||
|
|
45967c8b77 | ||
|
|
fc758069fb | ||
|
|
9be7b12654 | ||
|
|
160abd88cc | ||
|
|
e2eebc7a28 | ||
|
|
a52adaa95e | ||
|
|
ced3078e30 | ||
|
|
b7d2840e04 | ||
|
|
0a88f1a2d8 | ||
|
|
4855b4102d | ||
|
|
2dac45f1a3 | ||
|
|
e73acbc776 | ||
|
|
21d0fdb92a | ||
|
|
68e2cb7800 | ||
|
|
de24e2da1e | ||
|
|
bc4eb38eec | ||
|
|
8600b7815d | ||
|
|
8bee5da854 | ||
|
|
40bfb7b07a | ||
|
|
46c1dd511a | ||
|
|
d9cd942f3b | ||
|
|
147fb74085 | ||
|
|
7546e614c7 | ||
|
|
9a58bae112 | ||
|
|
9e99113aa1 | ||
|
|
ea4d82bc31 | ||
|
|
94efccba21 | ||
|
|
28c688b16f | ||
|
|
6d991456a9 | ||
|
|
bb840b7f7e | ||
|
|
9fecc570f8 | ||
|
|
1a5da9a1aa | ||
|
|
adb13cd4d4 | ||
|
|
9f8ebe86f4 | ||
|
|
46329a4f2d | ||
|
|
1f4dcc9fda | ||
|
|
7dda3dde08 | ||
|
|
e108aaa7db | ||
|
|
7da12ca861 | ||
|
|
2b987e8e00 | ||
|
|
c2106e49d8 | ||
|
|
0b473838fa | ||
|
|
3e15c59e00 | ||
|
|
9aa6e61197 | ||
|
|
4c58063268 | ||
|
|
25f1b46647 | ||
|
|
68ae77a79e | ||
|
|
a4ad969553 | ||
|
|
415e9e8495 | ||
|
|
5a5d8670ea | ||
|
|
9e20b2464f | ||
|
|
ea5c125dbd | ||
|
|
66646cd17a | ||
|
|
81b0df6f1d | ||
|
|
e9dadf1706 | ||
|
|
f9e45856fc | ||
|
|
0f9fcb3f0a | ||
|
|
17af664374 | ||
|
|
da3bda8bbb | ||
|
|
a5d66d1f4a | ||
|
|
4b289a53df | ||
|
|
d5eb164a20 | ||
|
|
fec25da5e7 | ||
|
|
4ec7d0a824 | ||
|
|
a873c0080a | ||
|
|
06f905853a | ||
|
|
179b8f57b3 | ||
|
|
9b1e5db390 | ||
|
|
32e5f13002 | ||
|
|
4497800fe1 | ||
|
|
6846459ea5 | ||
|
|
f7dafc4771 | ||
|
|
ee11159d5d | ||
|
|
c0a3b39688 | ||
|
|
679dcae557 | ||
|
|
b14c4b2aa6 | ||
|
|
92c534dcaa | ||
|
|
07fb404e33 | ||
|
|
a010b4d89f | ||
|
|
b340427363 | ||
|
|
654a2b7f63 | ||
|
|
b0cb9b8615 | ||
|
|
9bb75d82cf | ||
|
|
535239a5ae | ||
|
|
89b2a966ba | ||
|
|
29e2a542dd | ||
|
|
98a736c9d7 | ||
|
|
8404af8d18 | ||
|
|
7572d8cb46 | ||
|
|
db43c3e12e | ||
|
|
ea066dc0dc | ||
|
|
c0037b1f98 | ||
|
|
29aa6407be | ||
|
|
f6d4c77e75 | ||
|
|
c0e019efbd | ||
|
|
ded656208d | ||
|
|
9c36a8ebc2 | ||
|
|
1dda299dc3 | ||
|
|
c8d1b99e42 | ||
|
|
b274f3c8d3 | ||
|
|
1d7775875e | ||
|
|
3a560604ec | ||
|
|
f677cc34b3 | ||
|
|
cdab201890 | ||
|
|
20186aec26 | ||
|
|
79fc8623e3 | ||
|
|
c104b12302 |
31
.vscode/launch.json
vendored
31
.vscode/launch.json
vendored
@@ -1,31 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/cmake_targets/ran_build/build/lte-softmodem",
|
||||
"args": [
|
||||
"-O", "../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf",
|
||||
"--noS1"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}/cmake_targets",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "${workspaceFolder}/cmake_targets/sudo-gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 :
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -33,7 +33,6 @@ gNBs =
|
||||
////////// Physical parameters:
|
||||
|
||||
min_rxtxtime = 6;
|
||||
enable_sdap = 1;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
- Build_Proxy
|
||||
- Build_PhySim
|
||||
- Run_PhySim
|
||||
- Build_eNB
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -53,6 +53,7 @@
|
||||
<class>Initialize_UE</class>
|
||||
<desc>Initialize Quectel</desc>
|
||||
<id>idefix</id>
|
||||
<UE_Trace>yes</UE_Trace>
|
||||
</testCase>
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
111
ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml
Normal file
111
ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml
Normal 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>
|
||||
111
ci-scripts/xml_files/f1_usrp210_band7_test_10mhz.xml
Normal file
111
ci-scripts/xml_files/f1_usrp210_band7_test_10mhz.xml
Normal 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>
|
||||
111
ci-scripts/xml_files/f1_usrp210_band7_test_20mhz.xml
Normal file
111
ci-scripts/xml_files/f1_usrp210_band7_test_20mhz.xml
Normal 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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -26,7 +26,6 @@
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
010002
|
||||
030000
|
||||
040000
|
||||
000002
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
010002
|
||||
031000
|
||||
041000
|
||||
000002
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
010002
|
||||
030000
|
||||
040000
|
||||
000002
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
010002
|
||||
040000
|
||||
000002
|
||||
010000
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
010002
|
||||
042000
|
||||
000002
|
||||
010000
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
011002
|
||||
041000
|
||||
000002
|
||||
011000
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
010002
|
||||
030000
|
||||
000002
|
||||
010000
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
010002
|
||||
030001
|
||||
000002
|
||||
010000
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -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,9 +328,13 @@ 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
|
||||
@@ -354,12 +352,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 +839,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
|
||||
@@ -1212,7 +1205,6 @@ add_library(UTIL
|
||||
${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
|
||||
@@ -1812,15 +1804,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 +1858,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 +1936,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 +3015,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 +3101,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)
|
||||
@@ -3159,3 +3182,4 @@ ADD_CUSTOM_TARGET(oarf
|
||||
|
||||
include (${OPENAIR_DIR}/common/utils/telnetsrv/telnetsrv_CMakeLists.txt)
|
||||
include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt)
|
||||
include (${OPENAIR_DIR}/common/utils/websrv/websrv_CMakeLists.txt)
|
||||
|
||||
@@ -58,7 +58,7 @@ CMAKE_CMD="$CMAKE"
|
||||
NOAVX512="False"
|
||||
BUILD_ECLIPSE=0
|
||||
NR="False"
|
||||
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope"
|
||||
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope websrv"
|
||||
RU=0
|
||||
CMAKE_C_FLAGS=()
|
||||
CMAKE_CXX_FLAGS=()
|
||||
@@ -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
|
||||
|
||||
@@ -453,15 +451,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 +613,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"
|
||||
|
||||
@@ -237,9 +237,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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,15 @@ 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 {
|
||||
AssertFatal( ( strlen(*(cfgoptions->strptr)) < cfgoptions->numelt), "[CONFIG] Error: %s too long, %s value cannot exceed %i bytes\n",
|
||||
cfgoptions->optname,tmpval, cfgoptions->numelt) ;
|
||||
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 +107,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 +119,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 +135,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);
|
||||
|
||||
@@ -88,13 +88,32 @@ int load_config_sharedlib(configmodule_interface_t *cfgptr) {
|
||||
st = -1;
|
||||
}
|
||||
|
||||
if ( cfgptr->rtflags & CONFIG_SAVERUNCFG ) {
|
||||
sprintf (fname,"config_%s_set",cfgptr->cfgmode);
|
||||
cfgptr->set = dlsym(lib_handle,fname);
|
||||
|
||||
if (cfgptr->set == NULL ) {
|
||||
printf("[CONFIG] %s %d no function %s for config mode %s\n",
|
||||
__FILE__, __LINE__,fname, cfgptr->cfgmode);
|
||||
st = -1;
|
||||
}
|
||||
sprintf (fname,"config_%s_write_parsedcfg",cfgptr->cfgmode);
|
||||
cfgptr->write_parsedcfg = dlsym(lib_handle,fname);
|
||||
|
||||
if (cfgptr->write_parsedcfg == NULL ) {
|
||||
printf("[CONFIG] %s %d no function %s for config mode %s\n",
|
||||
__FILE__, __LINE__,fname, cfgptr->cfgmode);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf (fname,"config_%s_end",cfgptr->cfgmode);
|
||||
cfgptr->end = dlsym(lib_handle,fname);
|
||||
|
||||
if (cfgptr->getlist == NULL ) {
|
||||
if (cfgptr->end == NULL ) {
|
||||
printf("[CONFIG] %s %d no function %s for config mode %s\n",
|
||||
__FILE__, __LINE__,fname, cfgptr->cfgmode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return st;
|
||||
@@ -186,6 +205,7 @@ configmodule_interface_t *load_configmodule(int argc,
|
||||
uint32_t initflags)
|
||||
{
|
||||
char *cfgparam=NULL;
|
||||
|
||||
char *modeparams=NULL;
|
||||
char *cfgmode=NULL;
|
||||
char *strtokctx=NULL;
|
||||
@@ -193,7 +213,8 @@ configmodule_interface_t *load_configmodule(int argc,
|
||||
uint32_t tmpflags=0;
|
||||
int i;
|
||||
int OoptIdx=-1;
|
||||
|
||||
int OWoptIdx=-1;
|
||||
|
||||
printf("CMDLINE: ");
|
||||
for (int i=0; i<argc; i++)
|
||||
printf("\"%s\" ", argv[i]);
|
||||
@@ -208,7 +229,11 @@ configmodule_interface_t *load_configmodule(int argc,
|
||||
cfgparam = argv[i+1];
|
||||
OoptIdx=i;
|
||||
}
|
||||
|
||||
|
||||
char *OWopt = strstr(argv[i],"OW");
|
||||
if ( OWopt == argv[i]+2) {
|
||||
OWoptIdx=i;
|
||||
}
|
||||
if ( strstr(argv[i], "help_config") != NULL ) {
|
||||
config_printhelp(Config_Params,CONFIG_PARAMLENGTH(Config_Params),CONFIG_SECTIONNAME);
|
||||
exit(0);
|
||||
@@ -250,58 +275,67 @@ 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 reuested _(_--OW or rtflag is 5), a file with config parameters, as defined after all processing, will be created */
|
||||
if (OWoptIdx >= 0) {
|
||||
cfgptr->argv_info[OWoptIdx] |= CONFIG_CMDLINEOPT_PROCESSED;
|
||||
cfgptr->rtflags |= CONFIG_SAVERUNCFG ;
|
||||
}
|
||||
/* 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]);
|
||||
}
|
||||
|
||||
printf(", debug flags: 0x%08x\n",cfgptr->rtflags);
|
||||
|
||||
if (cfgptr->rtflags & CONFIG_PRINTPARAMS) {
|
||||
cfgptr->status = malloc(sizeof(configmodule_status_t));
|
||||
}
|
||||
if (strstr(cfgparam,CONFIG_CMDLINEONLY) == NULL) {
|
||||
i=load_config_sharedlib(cfgptr);
|
||||
|
||||
if (i == 0) {
|
||||
printf("[CONFIG] config module %s loaded\n",cfgmode);
|
||||
Config_Params[CONFIGPARAM_DEBUGFLAGS_IDX].uptr=&(cfgptr->rtflags);
|
||||
int idx = config_paramidx_fromname(Config_Params, CONFIG_PARAMLENGTH(Config_Params), CONFIGP_DEBUGFLAGS);
|
||||
Config_Params[idx].uptr=&(cfgptr->rtflags);
|
||||
idx = config_paramidx_fromname(Config_Params, CONFIG_PARAMLENGTH(Config_Params), CONFIGP_TMPDIR);
|
||||
Config_Params[idx].strptr=&(cfgptr->tmpdir);
|
||||
config_get(Config_Params,CONFIG_PARAMLENGTH(Config_Params), CONFIG_SECTIONNAME );
|
||||
} else {
|
||||
fprintf(stderr,"[CONFIG] %s %d config module \"%s\" couldn't be loaded\n", __FILE__, __LINE__,cfgmode);
|
||||
@@ -313,7 +347,10 @@ configmodule_interface_t *load_configmodule(int argc,
|
||||
cfgptr->getlist = config_cmdlineonly_getlist;
|
||||
cfgptr->end = (configmodule_endfunc_t)nooptfunc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
printf("[CONFIG] debug flags: 0x%08x\n",cfgptr->rtflags);
|
||||
|
||||
if (modeparams != NULL) free(modeparams);
|
||||
|
||||
if (cfgmode != NULL) free(cfgmode);
|
||||
@@ -326,33 +363,64 @@ configmodule_interface_t *load_configmodule(int argc,
|
||||
return cfgptr;
|
||||
}
|
||||
|
||||
/* Possibly write config file, with parameters which have been read and after command line parsing */
|
||||
void write_parsedcfg(void) {
|
||||
if ( cfgptr->status && (cfgptr->rtflags & CONFIG_SAVERUNCFG)) {
|
||||
printf_params("[CONFIG] Runtime params creation status: %i null values, %i errors, %i empty list or array, %i successfull \n",
|
||||
cfgptr->status->num_err_nullvalue,
|
||||
cfgptr->status->num_err_write,
|
||||
cfgptr->status->emptyla,
|
||||
cfgptr->status->num_write);
|
||||
|
||||
}
|
||||
if (cfgptr != NULL) {
|
||||
if (cfgptr->write_parsedcfg != NULL) {
|
||||
printf ("[CONFIG] calling config module write_parsedcfg function...\n");
|
||||
cfgptr->write_parsedcfg();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free memory allocated when reading parameters */
|
||||
/* config module could be initialized again after this call */
|
||||
void end_configmodule(void) {
|
||||
write_parsedcfg();
|
||||
if (cfgptr != NULL) {
|
||||
if (cfgptr->end != NULL) {
|
||||
printf ("[CONFIG] calling config module end function...\n");
|
||||
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->status != NULL) {
|
||||
free(cfgptr->status->debug_cfgname);
|
||||
free(cfgptr->status);
|
||||
}
|
||||
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 +430,3 @@ void end_configmodule(void) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -54,6 +54,7 @@
|
||||
#define CONFIG_DEBUGPTR (1<<1) // print memory allocation/free debug messages
|
||||
#define CONFIG_DEBUGCMDLINE (1<<2) // print command line processing messages
|
||||
#define CONFIG_NOABORTONCHKF (1<<4) // disable abort execution when parameter checking function fails
|
||||
#define CONFIG_SAVERUNCFG (1<<5) // create config file with running values, as after cfg file + command line processing
|
||||
#define CONFIG_NOEXITONHELP (1<<19) // do not exit after printing help
|
||||
#define CONFIG_HELP (1<<20) // print help message
|
||||
#define CONFIG_ABORT (1<<21) // config failed,abort execution
|
||||
@@ -61,14 +62,19 @@
|
||||
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 int(*configmodule_setfunc_t)(paramdef_t *cfgoptions, int numoptions, 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_status {
|
||||
int num_paramgroups;
|
||||
char ** paramgroups_names;
|
||||
int num_err_nullvalue;
|
||||
int emptyla;
|
||||
int num_err_read;
|
||||
int num_err_write;
|
||||
int num_read;
|
||||
int num_write;
|
||||
char *debug_cfgname;
|
||||
}configmodule_status_t;
|
||||
|
||||
typedef struct configmodule_interface {
|
||||
int argc;
|
||||
@@ -80,11 +86,15 @@ typedef struct configmodule_interface {
|
||||
configmodule_initfunc_t init;
|
||||
configmodule_getfunc_t get;
|
||||
configmodule_getlistfunc_t getlist;
|
||||
configmodule_setfunc_t set;
|
||||
configmodule_endfunc_t end;
|
||||
pthread_mutex_t memBlocks_mutex;
|
||||
configmodule_endfunc_t write_parsedcfg;
|
||||
uint32_t numptrs;
|
||||
uint32_t rtflags;
|
||||
oneBlock_t oneBlock[CONFIG_MAX_ALLOCATEDPTRS];
|
||||
char *ptrs[CONFIG_MAX_ALLOCATEDPTRS];
|
||||
bool ptrsAllocated[CONFIG_MAX_ALLOCATEDPTRS];
|
||||
char *tmpdir;
|
||||
configmodule_status_t *status; // allocated in debug mode only
|
||||
} configmodule_interface_t;
|
||||
|
||||
#ifdef CONFIG_LOADCONFIG_MAIN
|
||||
@@ -97,16 +107,19 @@ static char config_helpstr [] = "\n lte-softmodem -O [config mode]<:dbgl[debugfl
|
||||
incp parameter can be used to define the include path used for config files (@include directive)\n \
|
||||
defaults is set to the path of the main config file.\n";
|
||||
|
||||
#define CONFIG_SECTIONNAME "config"
|
||||
#define CONFIGPARAM_DEBUGFLAGS_IDX 0
|
||||
#define CONFIG_HELP_TMPDIR "<Repository to create temporary file>"
|
||||
|
||||
#define CONFIG_SECTIONNAME "config"
|
||||
#define CONFIGP_DEBUGFLAGS "debugflags"
|
||||
#define CONFIGP_TMPDIR "tmpdir"
|
||||
|
||||
static paramdef_t Config_Params[] = {
|
||||
/*-----------------------------------------------------------------------------------------------------------------------*/
|
||||
/* config parameters for config module */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*-----------------------------------------------------------------------------------------------------------------------*/
|
||||
{"debugflags", config_helpstr, 0, uptr:NULL, defintval:0, TYPE_MASK, 0},
|
||||
/*--------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* config parameters for config module */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*--------------------------------------------------------------------------------------------------------------------------*/
|
||||
{CONFIGP_DEBUGFLAGS, config_helpstr, 0, uptr:NULL, defintval:0, TYPE_MASK, 0},
|
||||
{CONFIGP_TMPDIR, CONFIG_HELP_TMPDIR,PARAMFLAG_NOFREE, strptr:NULL, defstrval:"/tmp" ,TYPE_STRING, 0},
|
||||
};
|
||||
|
||||
#else
|
||||
@@ -120,15 +133,8 @@ 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);
|
||||
extern void write_parsedcfg(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");
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#define PARAMFLAG_NOFREE (1 << 3) // don't free parameter in end function
|
||||
#define PARAMFLAG_BOOL (1 << 4) // integer param can be 0 or 1
|
||||
#define PARAMFLAG_CMDLINE_NOPREFIXENABLED (1 << 5) // on the command line, allow a parameter to be specified without the prefix
|
||||
#define PARAMFLAG_CMDLINEONLY (1 << 6) // this parameter cannot be specified in config file
|
||||
|
||||
/* Flags used by config modules to return info to calling modules and/or to for internal usage*/
|
||||
#define PARAMFLAG_MALLOCINCONFIG (1 << 15) // parameter allocated in config module
|
||||
@@ -96,13 +97,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;
|
||||
|
||||
@@ -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;
|
||||
@@ -275,6 +237,9 @@ int config_get(paramdef_t *params, int numparams, char *prefix) {
|
||||
|
||||
if (ret >= 0) {
|
||||
config_process_cmdline(params, numparams, prefix);
|
||||
if ( cfgif->rtflags & CONFIG_SAVERUNCFG ) {
|
||||
config_get_if()->set(params, numparams, prefix);
|
||||
}
|
||||
config_execcheck(params, numparams, prefix);
|
||||
}
|
||||
|
||||
@@ -309,9 +274,11 @@ int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams
|
||||
char cfgpath[MAX_OPTNAME_SIZE*2 + 6]; /* prefix.listname.[listindex] */
|
||||
|
||||
for (int i = 0; i < ParamList->numelt; ++i) {
|
||||
// TODO config_process_cmdline?
|
||||
sprintf(cfgpath, "%s.[%i]", newprefix, i);
|
||||
config_process_cmdline(ParamList->paramarray[i],numparams,cfgpath);
|
||||
if ( config_get_if()->rtflags & CONFIG_SAVERUNCFG ) {
|
||||
config_get_if()->set(ParamList->paramarray[i], numparams,cfgpath );
|
||||
}
|
||||
config_execcheck(ParamList->paramarray[i], numparams, cfgpath);
|
||||
}
|
||||
|
||||
@@ -382,7 +349,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 +365,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 +376,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 +398,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 +427,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 +440,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 +455,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 +469,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 +481,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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -29,20 +29,21 @@
|
||||
* \warning
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <pthread.h>
|
||||
#include <libconfig.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "config_libconfig.h"
|
||||
#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 +56,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 +80,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);
|
||||
@@ -91,8 +90,222 @@ int read_intarray(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpat
|
||||
|
||||
return cfgoptions->numelt;
|
||||
}
|
||||
int config_libconfig_setparams(paramdef_t *cfgoptions, int numoptions, config_setting_t * asetting, char * prefix) {
|
||||
int status;
|
||||
int errors=0;
|
||||
int notused=0;
|
||||
int emptyla=0;
|
||||
#define LIBCONFIG_NOTUSED_PARAMS "Not used? (NULL value ptr)"
|
||||
char *secprefix=(prefix==NULL)?"":prefix;
|
||||
|
||||
for(int i=0; i<numoptions; i++) {
|
||||
if (cfgoptions[i].paramflags & PARAMFLAG_CMDLINEONLY) {
|
||||
continue;
|
||||
printf_params("[LIBCONFIG] setting %s.%s skipped (command line only) \n",secprefix,cfgoptions[i].optname);
|
||||
}
|
||||
status=CONFIG_FALSE;
|
||||
config_setting_t * psetting;
|
||||
char *spath=malloc(((prefix==NULL)?0:strlen(prefix))+strlen(cfgoptions[i].optname)+10);
|
||||
sprintf(spath,"%s%s%s",secprefix, (prefix==NULL)?"":".", cfgoptions[i].optname);
|
||||
psetting = config_lookup(&(libconfig_privdata.runtcfg),spath);
|
||||
free(spath);
|
||||
if (psetting != NULL) {
|
||||
printf_params("[LIBCONFIG] setting %s.%s already created \n",secprefix,cfgoptions[i].optname);
|
||||
continue;
|
||||
}
|
||||
switch(cfgoptions[i].type) {
|
||||
case TYPE_STRING:
|
||||
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_STRING);
|
||||
if (psetting!= NULL) {
|
||||
char *value;
|
||||
if (cfgoptions[i].strptr == NULL) {
|
||||
notused++;
|
||||
value=LIBCONFIG_NOTUSED_PARAMS;
|
||||
} else {
|
||||
if (cfgoptions[i].numelt == 0 ) {
|
||||
value = *(cfgoptions[i].strptr);
|
||||
} else {
|
||||
value = (char *)(cfgoptions[i].strptr);
|
||||
}
|
||||
}
|
||||
status=config_setting_set_string(psetting, value);
|
||||
}
|
||||
break;
|
||||
case TYPE_STRINGLIST:
|
||||
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_LIST);
|
||||
if (psetting!= NULL)
|
||||
{
|
||||
if(cfgoptions[i].numelt <= 0) {
|
||||
emptyla++;
|
||||
printf_params("[LIBCONFIG], no element in list %s\n",cfgoptions[i].optname);
|
||||
status=CONFIG_TRUE;
|
||||
}
|
||||
for (int j=0; j<cfgoptions[i].numelt ; j++) {
|
||||
config_setting_t *elemsetting=config_setting_set_string_elem(psetting, -1,cfgoptions[i].strptr[j] );
|
||||
if (elemsetting == NULL) {
|
||||
fprintf(stderr,"[LIBCONFIG] Error: Creating list %s element %i value %s\n",cfgoptions[i].optname,j,cfgoptions[i].strptr[j]);
|
||||
break;
|
||||
} else
|
||||
status=CONFIG_TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_UINT8:
|
||||
case TYPE_INT8:
|
||||
case TYPE_UINT16:
|
||||
case TYPE_INT16:
|
||||
case TYPE_UINT32:
|
||||
case TYPE_INT32:
|
||||
case TYPE_MASK:
|
||||
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_INT);
|
||||
if (psetting!= NULL)
|
||||
status=config_setting_set_int(psetting, (int)*(cfgoptions[i].iptr) );
|
||||
break;
|
||||
|
||||
case TYPE_UINT64:
|
||||
case TYPE_INT64:
|
||||
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_INT64);
|
||||
if (psetting!= NULL)
|
||||
status=config_setting_set_int64(psetting, (int64_t)*(cfgoptions[i].i64ptr) );
|
||||
break;
|
||||
|
||||
case TYPE_UINTARRAY:
|
||||
case TYPE_INTARRAY:
|
||||
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_ARRAY);
|
||||
if (psetting!= NULL) {
|
||||
if(cfgoptions[i].numelt <= 0) {
|
||||
emptyla++;
|
||||
printf_params("[LIBCONFIG], no element in array %s.%s\n",secprefix,cfgoptions[i].optname);
|
||||
status=CONFIG_TRUE;
|
||||
}
|
||||
for (int j=0; j<cfgoptions[i].numelt ; j++) {
|
||||
config_setting_t *elemsetting=config_setting_set_int_elem(psetting, -1,(int)(cfgoptions[i].iptr[j]) );
|
||||
if (elemsetting == NULL) {
|
||||
fprintf(stderr,"[LIBCONFIG] Error: Creating array %s.%s, at index %i value %i\n",secprefix,cfgoptions[i].optname,j,(int)(cfgoptions[i].iptr[j]));
|
||||
break;
|
||||
} else
|
||||
status=CONFIG_TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_DOUBLE:
|
||||
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_FLOAT);
|
||||
if (psetting!= NULL)
|
||||
status=config_setting_set_float(psetting, (double)*(cfgoptions[i].dblptr) );
|
||||
break;
|
||||
|
||||
case TYPE_IPV4ADDR:
|
||||
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_STRING);
|
||||
if (psetting!= NULL) {
|
||||
char ipstr[INET_ADDRSTRLEN];
|
||||
if (inet_ntop(AF_INET, cfgoptions[i].uptr, ipstr, INET_ADDRSTRLEN) == NULL) {
|
||||
notused++;
|
||||
sprintf(ipstr,"undef");
|
||||
} else {
|
||||
status=config_setting_set_string(psetting, ipstr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_LIST:
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr,"[LIBCONFIG] %s.%s type %i not supported\n",secprefix,cfgoptions[i].optname ,cfgoptions[i].type);
|
||||
status=CONFIG_FALSE;
|
||||
break;
|
||||
} /* switch on param type */
|
||||
if (status != CONFIG_TRUE) {
|
||||
errors++;
|
||||
fprintf(stderr,"[LIBCONFIG] Error creating setting %i: %s.%s type %i\n",i,secprefix,cfgoptions[i].optname ,cfgoptions[i].type);
|
||||
}
|
||||
}
|
||||
printf_params("[LIBCONFIG], in group \"%s\" %i settings \n",secprefix,numoptions);
|
||||
if (notused > 0)
|
||||
printf_params("[LIBCONFIG], ..... %i settings with NULL value pointer\n",notused);
|
||||
if (errors >0)
|
||||
fprintf(stderr,"[LIBCONFIG] .....%i settings creation errors \n",errors);
|
||||
if (emptyla >0)
|
||||
fprintf(stderr,"[LIBCONFIG] .....%i empty lists or arrays settings \n",emptyla);
|
||||
|
||||
if ( cfgptr->status ) {
|
||||
cfgptr->status->num_err_nullvalue += notused;
|
||||
cfgptr->status->num_err_write += errors;
|
||||
cfgptr->status->num_write += numoptions;
|
||||
cfgptr->status->emptyla += emptyla;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
int config_libconfig_set(paramdef_t *cfgoptions, int numoptions, char *prefix ) {
|
||||
char *tokctx1=NULL;
|
||||
int listidx=-1;
|
||||
char *prefixbck=NULL;
|
||||
char *prefix_elem1=NULL;
|
||||
config_setting_t * asetting = config_root_setting (&(libconfig_privdata.runtcfg));
|
||||
if (prefix != NULL) {
|
||||
prefixbck=strdup(prefix);
|
||||
prefix_elem1 = strtok_r(prefixbck, ".", &tokctx1);
|
||||
}
|
||||
printf_params("[LIBCONFIG], processing prefix %s\n",(prefix==NULL)?"NULL":prefix);
|
||||
|
||||
/* parse the prefix , possibly creating groups, lists and list elements */
|
||||
while (prefix_elem1 != NULL) {
|
||||
int n1=strlen(prefix_elem1);
|
||||
char *prefix_elem2 = prefix_elem1+n1+1 ;
|
||||
printf_params("[LIBCONFIG], processing elem1 %s elem2 %s\n",prefix_elem1,prefix_elem2);
|
||||
/* prefix (the path to the parameter name) may contain groups and elements from a list, which are specified with [] */
|
||||
if (prefix_elem2[0] != '[') { // not a list
|
||||
|
||||
config_setting_t *tmpset = config_setting_lookup(asetting,prefix_elem1);
|
||||
if (tmpset == NULL)
|
||||
asetting = config_setting_add (asetting, prefix_elem1, CONFIG_TYPE_GROUP);
|
||||
else
|
||||
asetting = tmpset;
|
||||
printf_params("[LIBCONFIG], creating or looking for group %s: %s\n",prefix_elem1,(asetting==NULL)?"NOK":"OK");
|
||||
} else { // a list
|
||||
listidx=(int)strtol(prefix_elem2+1,NULL,10);
|
||||
if (errno == EINVAL || errno == ERANGE) {
|
||||
printf_params("[LIBCONFIG], Error %s looking for list index in %s \n",strerror(errno), prefix_elem2);
|
||||
break;
|
||||
}
|
||||
config_setting_t *tmpset = config_setting_lookup(asetting,prefix_elem1);
|
||||
if (tmpset == NULL)
|
||||
asetting = config_setting_add (asetting, prefix_elem1, CONFIG_TYPE_LIST);
|
||||
else
|
||||
asetting = tmpset;
|
||||
printf_params("[LIBCONFIG], creating or looking for list %s: %s\n",prefix_elem1,(asetting==NULL)?"NOK":"OK");
|
||||
if (asetting != NULL) {
|
||||
tmpset = config_setting_get_elem (asetting, listidx);
|
||||
if (tmpset == NULL)
|
||||
asetting = config_setting_add (asetting, NULL, CONFIG_TYPE_GROUP);
|
||||
else
|
||||
asetting = tmpset;
|
||||
printf_params("[LIBCONFIG], creating or looking for list element %i: %s\n",listidx,(asetting==NULL)?"NOK":"OK");
|
||||
}
|
||||
prefix_elem1 = strtok_r(NULL, ".", &tokctx1); //skip the [x] elements we already took care of it
|
||||
if (prefix_elem1 == NULL) {
|
||||
fprintf(stderr, "[LICONFIG] End of parsing %s \n",prefix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (asetting == NULL) {
|
||||
fprintf(stderr,"[LIBCONFIG] Error creating setting %s %s %i\n",prefix_elem1,prefix_elem2,listidx);
|
||||
}
|
||||
prefix_elem1 = strtok_r(NULL, ".", &tokctx1);
|
||||
}
|
||||
free(prefixbck);
|
||||
if (asetting != NULL) {
|
||||
config_libconfig_setparams(cfgoptions, numoptions,asetting,prefix);
|
||||
printf_params("[LIBCONFIG] %i settings added in group %s\n",numoptions,(prefix==NULL)?"":prefix);
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr,"[LIBCONFIG] Error parsing %s params, skipped...\n",(prefix==NULL)?"":prefix);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) {
|
||||
@@ -127,14 +340,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 +380,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 +391,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 +420,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 +521,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 +563,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) {
|
||||
@@ -354,14 +593,43 @@ int config_libconfig_init(char *cfgP[], int numP) {
|
||||
free(tmppath);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* possibly init a libconfig struct for saving really used params */
|
||||
if( cfgptr->rtflags & CONFIG_SAVERUNCFG ) {
|
||||
config_init ( &(libconfig_privdata.runtcfg));
|
||||
// config_set_options (&(libconfig_privdata.runtcfg), CONFIG_OPTION_ALLOW_OVERRIDES, CONFIG_TRUE);
|
||||
}
|
||||
free(tmppath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void config_libconfig_write_parsedcfg(void) {
|
||||
if( cfgptr->rtflags & CONFIG_SAVERUNCFG ) {
|
||||
char *fname=strdup(libconfig_privdata.configfile);
|
||||
int newcfgflen = strlen( libconfig_privdata.configfile) + strlen(cfgptr->tmpdir) + 20;
|
||||
cfgptr->status->debug_cfgname = realloc(cfgptr->status->debug_cfgname, newcfgflen);
|
||||
time_t t = time(NULL);
|
||||
struct tm tm = *localtime(&t);
|
||||
snprintf (cfgptr->status->debug_cfgname,newcfgflen, "%s/%s-run%d_%02d_%02d_%02d%02d",cfgptr->tmpdir,basename(fname),
|
||||
tm.tm_year + 1900,tm.tm_mon + 1,tm.tm_mday, tm.tm_hour, tm.tm_min);
|
||||
if ( config_write_file (&(libconfig_privdata.runtcfg) , cfgptr->status->debug_cfgname) != CONFIG_TRUE) {
|
||||
fprintf(stderr,"[LIBCONFIG] %s %d file %s - line %d: %s\n",__FILE__, __LINE__,
|
||||
cfgptr->status->debug_cfgname, config_error_line(&(libconfig_privdata.runtcfg)),
|
||||
config_error_text(&(libconfig_privdata.runtcfg)));
|
||||
} else {
|
||||
printf("[LIBCONFIG] file %s created successfully\n", cfgptr->status->debug_cfgname);
|
||||
}
|
||||
free(fname);
|
||||
} else {
|
||||
printf("[LIBCONFIG] Cannot create config file after parsing: CONFIG_SAVERUNCFG flag not specified\n");
|
||||
}
|
||||
}
|
||||
|
||||
void config_libconfig_end(void ) {
|
||||
config_destroy(&(libconfig_privdata.cfg));
|
||||
|
||||
if( cfgptr->rtflags & CONFIG_SAVERUNCFG ) {
|
||||
config_destroy(&(libconfig_privdata.runtcfg));
|
||||
}
|
||||
if ( libconfig_privdata.configfile != NULL ) {
|
||||
free(libconfig_privdata.configfile);
|
||||
libconfig_privdata.configfile=NULL;
|
||||
|
||||
@@ -40,12 +40,11 @@ extern "C"
|
||||
|
||||
#include "common/config/config_paramdesc.h"
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct libconfig_privatedata {
|
||||
char *configfile;
|
||||
config_t cfg;
|
||||
config_t runtcfg;
|
||||
} libconfig_privatedata_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -302,8 +302,8 @@ void log_getconfig(log_t *g_log)
|
||||
|
||||
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) {
|
||||
if(g_log->log_component[i].name == NULL) {
|
||||
g_log->log_component[i].name = malloc(16);
|
||||
sprintf((char *)g_log->log_component[i].name,"comp%i?",i);
|
||||
g_log->log_component[i].name = calloc(1,16);
|
||||
snprintf((char *)g_log->log_component[i].name,15,"undefcomp%i",i);
|
||||
logparams_logfile[i].paramflags = PARAMFLAG_DONOTREAD;
|
||||
logparams_level[i].paramflags = PARAMFLAG_DONOTREAD;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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} \
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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}\
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
@@ -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)\
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -80,6 +80,7 @@ paramdef_t telnetoptions[] = {
|
||||
{"loopdelay", "<loop command delay (ms)>\n", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 },
|
||||
{"histfile", "<history file name>\n", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 },
|
||||
{"histsize", "<history sizes>\n", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 },
|
||||
{"logfile", "log file hen redirecting", PARAMFLAG_NOFREE, strptr:&(telnetparams.logfile), defstrval:"oaisoftmodem.log", TYPE_STRING, 0 },
|
||||
{"phypbsize", "<phy dump buff size (bytes)>\n",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 },
|
||||
{TELNETSRV_OPTNAME_STATICMOD, "<static modules selection>\n", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))},
|
||||
{TELNETSRV_OPTNAME_SHRMOD, "<dynamic modules selection>\n", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 }
|
||||
@@ -90,25 +91,31 @@ int get_phybsize(void) {
|
||||
};
|
||||
int add_telnetcmd(char *modulename,telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd );
|
||||
int setoutput(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
int wsetoutput(char *buff, int debug, telnet_printfunc_t prnt, ... );
|
||||
int setparam(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
int wsetparam(char *buff, int debug, telnet_printfunc_t prnt, ... );
|
||||
int history_cmd(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
|
||||
|
||||
telnetshell_vardef_t telnet_vardef[] = {
|
||||
{"debug",TELNET_VARTYPE_INT32,&telnetparams.telnetdbg},
|
||||
{"prio",TELNET_VARTYPE_INT32,&telnetparams.priority},
|
||||
{"loopc",TELNET_VARTYPE_INT32,&telnetparams.loopcount},
|
||||
{"loopd",TELNET_VARTYPE_INT32,&telnetparams.loopdelay},
|
||||
{"phypb",TELNET_VARTYPE_INT32,&telnetparams.phyprntbuff_size},
|
||||
{"hsize",TELNET_VARTYPE_INT32,&telnetparams.histsize},
|
||||
{"hfile",TELNET_VARTYPE_STRING,&telnetparams.histfile},
|
||||
{"",0,NULL}
|
||||
{"debug", TELNET_VARTYPE_INT32,0,&telnetparams.telnetdbg},
|
||||
{"prio", TELNET_VARTYPE_INT32,0,&telnetparams.priority},
|
||||
{"loopc", TELNET_VARTYPE_INT32,0,&telnetparams.loopcount},
|
||||
{"loopd", TELNET_VARTYPE_INT32,0,&telnetparams.loopdelay},
|
||||
{"phypb", TELNET_VARTYPE_INT32,0,&telnetparams.phyprntbuff_size},
|
||||
{"hsize", TELNET_VARTYPE_INT32,0,&telnetparams.histsize},
|
||||
{"hfile", TELNET_VARTYPE_STRING,TELNET_CHECKVAL_RDONLY,&telnetparams.histfile},
|
||||
{"logfile",TELNET_VARTYPE_STRING,0,&telnetparams.logfile},
|
||||
{"",0,0,NULL}
|
||||
};
|
||||
|
||||
telnetshell_cmddef_t telnet_cmdarray[] = {
|
||||
{"redirlog","[here,file,off]",setoutput},
|
||||
{"param","[prio]",setparam},
|
||||
{"history","[list,reset]",history_cmd},
|
||||
{"","",NULL},
|
||||
{"redirlog","[here,file,off]",setoutput,{NULL},TELNETSRV_CMDFLAG_TELNETONLY,NULL},
|
||||
{"redirlog file","",setoutput,{NULL},TELNETSRV_CMDFLAG_WEBSRVONLY,NULL},
|
||||
{"redirlog off","",setoutput,{NULL},TELNETSRV_CMDFLAG_WEBSRVONLY,NULL},
|
||||
{"param","[prio]",setparam,{wsetparam},0,NULL},
|
||||
{"history","[list,reset]",history_cmd,{NULL},TELNETSRV_CMDFLAG_TELNETONLY,NULL},
|
||||
{"","",NULL,{NULL},0,NULL},
|
||||
};
|
||||
|
||||
|
||||
@@ -127,36 +134,40 @@ void client_printf(const char *message, ...) {
|
||||
return ;
|
||||
}
|
||||
|
||||
#define NICE_MAX 19
|
||||
#define NICE_MIN -20
|
||||
|
||||
void set_sched(pthread_t tid, int pid, int priority) {
|
||||
int rt;
|
||||
struct sched_param schedp;
|
||||
int policy;
|
||||
char strpolicy[10];
|
||||
int niceval=0;
|
||||
|
||||
//sched_get_priority_max(SCHED_FIFO)
|
||||
if (priority < NICE_MIN) {
|
||||
if (priority < -100 && priority > -200) { //RR priority 1 to 99 (high) mapped to oai priority -101 to -199 (high)
|
||||
policy=SCHED_RR;
|
||||
sprintf(strpolicy,"%s","RR");
|
||||
schedp.sched_priority= -(priority + 100 );
|
||||
} else if (priority < 0 && priority > -100 ) {
|
||||
policy=SCHED_FIFO;
|
||||
sprintf(strpolicy,"%s","fifo");
|
||||
schedp.sched_priority= NICE_MIN - priority ;
|
||||
|
||||
if ( (schedp.sched_priority < sched_get_priority_min(SCHED_FIFO)) ||
|
||||
(schedp.sched_priority > sched_get_priority_max(SCHED_FIFO)) ) {
|
||||
client_printf("Error: %i invalid prio, should be %i to %i, \n",
|
||||
priority, NICE_MIN -sched_get_priority_min(SCHED_FIFO),
|
||||
NICE_MIN - sched_get_priority_max(SCHED_FIFO) );
|
||||
}
|
||||
} else if (priority > NICE_MAX) {
|
||||
schedp.sched_priority= -priority ;//fifo priority 1 to 99 (high) mapped to oai priority -1 to -99 (high)
|
||||
} else if (priority >= 0 && priority <= (NICE_MAX-NICE_MIN)) { // other (normal) nice value -20 to 19 mapped to oai priority 0 to 39
|
||||
policy=SCHED_OTHER;
|
||||
sprintf(strpolicy,"%s","other");
|
||||
schedp.sched_priority=0;
|
||||
niceval=priority+NICE_MIN;
|
||||
} else if (priority > NICE_MAX-NICE_MIN && priority <= (2*(NICE_MAX-NICE_MIN)+1) ) {// batch (normal) nice value -20 to 19 mapped to oai priority 40 to 79
|
||||
policy=SCHED_BATCH;
|
||||
sprintf(strpolicy,"%s","batch");
|
||||
niceval=priority+NICE_MIN-(NICE_MAX-NICE_MIN+1);
|
||||
schedp.sched_priority=0;
|
||||
} else if (priority > (2*(NICE_MAX-NICE_MIN)+1)){// fifo mapped to oai priority 80
|
||||
policy=SCHED_IDLE;
|
||||
sprintf(strpolicy,"%s","idle");
|
||||
schedp.sched_priority=0;
|
||||
} else {
|
||||
policy=SCHED_OTHER;
|
||||
sprintf(strpolicy,"%s","other");
|
||||
schedp.sched_priority=0;
|
||||
client_printf("Error: %i invalid priority \n",priority );
|
||||
return;
|
||||
}
|
||||
|
||||
if( tid != 0) {
|
||||
rt = pthread_setschedparam(tid, policy, &schedp);
|
||||
} else if(pid > 0) {
|
||||
@@ -172,15 +183,15 @@ void set_sched(pthread_t tid, int pid, int priority) {
|
||||
} else {
|
||||
client_printf("policy set to %s, priority %i\n",strpolicy,schedp.sched_priority);
|
||||
|
||||
if ( policy==SCHED_OTHER) {
|
||||
if ( policy==SCHED_OTHER || policy==SCHED_BATCH ) {
|
||||
rt = getpriority(PRIO_PROCESS,tid);
|
||||
|
||||
if (rt != -1) {
|
||||
rt = setpriority(PRIO_PROCESS,tid,priority);
|
||||
rt = setpriority(PRIO_PROCESS,tid,niceval);
|
||||
|
||||
if (rt < 0) {
|
||||
client_printf("Error %i: %s trying to set nice value of thread %u to %i\n",
|
||||
errno,strerror(errno),tid,priority);
|
||||
errno,strerror(errno),tid,niceval);
|
||||
}
|
||||
} else {
|
||||
client_printf("Error %i: %s trying to get nice value of thread %u \n",
|
||||
@@ -189,17 +200,17 @@ void set_sched(pthread_t tid, int pid, int priority) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( policy == SCHED_OTHER) {
|
||||
if ( policy == SCHED_OTHER || policy==SCHED_BATCH) {
|
||||
if ( tid > 0 && tid != pthread_self()) {
|
||||
client_printf("setting nice value using a thread id not implemented....\n");
|
||||
} else if (pid > 0) {
|
||||
errno=0;
|
||||
rt = setpriority(PRIO_PROCESS,pid,priority);
|
||||
rt = setpriority(PRIO_PROCESS,pid,niceval);
|
||||
|
||||
if (rt != 0) {
|
||||
client_printf("Error %i: %s calling setpriority, \n",errno,strerror(errno));
|
||||
} else {
|
||||
client_printf("nice value set to %i\n",priority);
|
||||
client_printf("nice value set to %i\n",niceval);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,20 +247,29 @@ void redirstd(char *newfname,telnet_printfunc_t prnt ) {
|
||||
fd=freopen(newfname, "w", stdout);
|
||||
|
||||
if (fd == NULL) {
|
||||
prnt("ERROR: stdout redir to %s error %s",strerror(errno));
|
||||
prnt("ERROR: stdout redir to %s error %s\n",strerror(errno));
|
||||
} else {
|
||||
prnt("stdout redirected to %s\n",newfname);
|
||||
}
|
||||
|
||||
fd=freopen(newfname, "w", stderr);
|
||||
|
||||
if (fd == NULL) {
|
||||
prnt("ERROR: stderr redir to %s error %s",strerror(errno));
|
||||
prnt("ERROR: stderr redir to %s error %s\n",strerror(errno));
|
||||
} else {
|
||||
prnt("stderr redirected to %s\n",newfname);
|
||||
}
|
||||
}
|
||||
|
||||
int wsetoutput(char *buffer, int debug, telnet_printfunc_t prnt, ... ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setoutput(char *buff, int debug, telnet_printfunc_t prnt) {
|
||||
char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE];
|
||||
char *logfname;
|
||||
char stdout_str[64];
|
||||
#define LOGFILE "logfile.log"
|
||||
|
||||
memset(cmds,0,sizeof(cmds));
|
||||
sscanf(buff,"%9s %32s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] );
|
||||
|
||||
@@ -265,10 +285,10 @@ int setoutput(char *buff, int debug, telnet_printfunc_t prnt) {
|
||||
|
||||
if (strncasecmp(cmds[0],"file",4) == 0) {
|
||||
if (cmds[1][0] == 0)
|
||||
logfname=LOGFILE;
|
||||
logfname=telnetparams.logfile;
|
||||
else
|
||||
logfname=cmds[1];
|
||||
|
||||
prnt("Log output redirected to (%s)\n",logfname);
|
||||
fflush(stdout);
|
||||
redirstd(logfname,prnt);
|
||||
}
|
||||
@@ -281,6 +301,10 @@ int setoutput(char *buff, int debug, telnet_printfunc_t prnt) {
|
||||
return CMDSTATUS_FOUND;
|
||||
} /* setoutput */
|
||||
|
||||
int wsetparam(char *buff, int debug, telnet_printfunc_t prnt, ...) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setparam(char *buff, int debug, telnet_printfunc_t prnt) {
|
||||
char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE];
|
||||
memset(cmds,0,sizeof(cmds));
|
||||
@@ -344,6 +368,98 @@ int history_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
|
||||
/*
|
||||
generic commands available for all modules loaded by the server
|
||||
*/
|
||||
char *telnet_getvarvalue(telnetshell_vardef_t *var, int varindex) {
|
||||
char *val;
|
||||
switch(var[varindex].vartype) {
|
||||
case TELNET_VARTYPE_INT32:
|
||||
val=malloc(64);
|
||||
snprintf(val,64,"%i",*(int32_t *)(var[varindex].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT64:
|
||||
val=malloc(128);
|
||||
snprintf(val,128,"%lli",(long long)*(int64_t *)(var[varindex].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT16:
|
||||
val=malloc(16);
|
||||
snprintf(val,16,"%hi",*(short *)(var[varindex].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT8:
|
||||
val=malloc(16);
|
||||
snprintf(val,16,"%i",(int)(*(int8_t *)(var[varindex].varvalptr)));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_UINT:
|
||||
val=malloc(64);
|
||||
snprintf(val,64,"%u",*(unsigned int *)(var[varindex].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_DOUBLE:
|
||||
val=malloc(32);
|
||||
snprintf(val,32,"%g\n",*(double *)(var[varindex].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_STRING:
|
||||
val = strdup(*(char **)(var[varindex].varvalptr));
|
||||
break;
|
||||
|
||||
default:
|
||||
val=malloc(64);
|
||||
snprintf(val,64,"ERR:var %i unknown type",varindex);
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
int telnet_setvarvalue(telnetshell_vardef_t *var,char *strval, telnet_printfunc_t prnt ) {
|
||||
int st=0;
|
||||
switch(var->vartype) {
|
||||
case TELNET_VARTYPE_INT32:
|
||||
*(int *)(var->varvalptr) = (int)strtol(strval,NULL,0);
|
||||
if (prnt != NULL)
|
||||
prnt("%i\n",*(int *)(var->varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT16:
|
||||
*(short *)(var->varvalptr) = (short)strtol(strval,NULL,0);
|
||||
if (prnt != NULL)
|
||||
prnt("%hi\n",*(short *)(var->varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT8:
|
||||
*(char *)(var->varvalptr) = (char)strtol(strval,NULL,0);
|
||||
if (prnt != NULL)
|
||||
prnt("%i\n",*(int *)(var->varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_UINT:
|
||||
*(unsigned int *)(var->varvalptr) = (unsigned int)strtol(strval,NULL,0);
|
||||
if (prnt != NULL)
|
||||
prnt("%u\n",*(unsigned int *)(var->varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_DOUBLE:
|
||||
*(double *)(var->varvalptr) = strtod(strval,NULL);
|
||||
if (prnt != NULL)
|
||||
prnt("%g\n",*(double *)(var->varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_STRING:
|
||||
sprintf(*(char **)(var->varvalptr),"%s", strval);
|
||||
if (prnt != NULL)
|
||||
prnt("\"%s\"\n",*(char **)(var->varvalptr));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (prnt != NULL)
|
||||
prnt("unknown type\n");
|
||||
st=-1;
|
||||
break;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
int setgetvar(int moduleindex,char getorset,char *params) {
|
||||
int n,i;
|
||||
@@ -357,81 +473,15 @@ int setgetvar(int moduleindex,char getorset,char *params) {
|
||||
if (n > 0 && (getorset == 'g' || getorset == 'G')) {
|
||||
client_printf("%s, %s = ", telnetparams.CmdParsers[moduleindex].module,
|
||||
telnetparams.CmdParsers[moduleindex].var[i].varname );
|
||||
|
||||
switch(telnetparams.CmdParsers[moduleindex].var[i].vartype) {
|
||||
case TELNET_VARTYPE_INT32:
|
||||
client_printf("%i\n",*(int32_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT64:
|
||||
client_printf("%lli\n",*(int64_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT16:
|
||||
client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT8:
|
||||
client_printf("%i\n",(int)(*(int8_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_UINT:
|
||||
client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_DOUBLE:
|
||||
client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_STRING:
|
||||
client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
default:
|
||||
client_printf("unknown type\n");
|
||||
break;
|
||||
}
|
||||
char *strval=telnet_getvarvalue(telnetparams.CmdParsers[moduleindex].var, i);
|
||||
client_printf("%s\n",strval);
|
||||
free(strval);
|
||||
}
|
||||
|
||||
if (n > 1 && (getorset == 's' || getorset == 'S')) {
|
||||
client_printf("%s, %s set to \n", telnetparams.CmdParsers[moduleindex].module,
|
||||
telnetparams.CmdParsers[moduleindex].var[i].varname);
|
||||
telnet_setvarvalue(&(telnetparams.CmdParsers[moduleindex].var[i]),varval, client_printf);
|
||||
|
||||
switch(telnetparams.CmdParsers[moduleindex].var[i].vartype) {
|
||||
case TELNET_VARTYPE_INT32:
|
||||
*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (int)strtol(varval,NULL,0);
|
||||
client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT16:
|
||||
*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (short)strtol(varval,NULL,0);
|
||||
client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT8:
|
||||
*(char *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (char)strtol(varval,NULL,0);
|
||||
client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_UINT:
|
||||
*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (unsigned int)strtol(varval,NULL,0);
|
||||
client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_DOUBLE:
|
||||
*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = strtod(varval,NULL);
|
||||
client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_STRING:
|
||||
sprintf(*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr),"%s", varval);
|
||||
client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
default:
|
||||
client_printf("unknown type\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -442,6 +492,13 @@ int setgetvar(int moduleindex,char getorset,char *params) {
|
||||
|
||||
return CMDSTATUS_VARNOTFOUND;
|
||||
}
|
||||
|
||||
void telnetsrv_freetbldata(webdatadef_t *wdata) {
|
||||
for(int i=0;i< wdata->numlines; i++)
|
||||
for(int j=0;j< wdata->numcols ; j++)
|
||||
if ( wdata->columns[j].coltype & TELNET_VAR_NEEDFREE )
|
||||
free(wdata->lines[i].val[j]);
|
||||
}
|
||||
/*----------------------------------------------------------------------------------------------------*/
|
||||
char *get_time(char *buff,int bufflen) {
|
||||
struct tm tmstruct;
|
||||
@@ -449,6 +506,16 @@ char *get_time(char *buff,int bufflen) {
|
||||
strftime (buff, bufflen, "%Y-%m-%d %H:%M:%S.000", localtime_r(&now,&tmstruct));
|
||||
return buff;
|
||||
}
|
||||
void telnet_pushcmd(telnetshell_cmddef_t *cmd, char *cmdbuff, telnet_printfunc_t prnt) {
|
||||
notifiedFIFO_elt_t *msg =newNotifiedFIFO_elt(sizeof(telnetsrv_qmsg_t),0,NULL,NULL);
|
||||
telnetsrv_qmsg_t *cmddata=NotifiedFifoData(msg);
|
||||
cmddata->cmdfunc=(qcmdfunc_t)cmd->cmdfunc;
|
||||
cmddata->prnt=prnt;
|
||||
cmddata->debug=telnetparams.telnetdbg;
|
||||
if (cmdbuff != NULL)
|
||||
cmddata->cmdbuff=strdup(cmdbuff);
|
||||
pushNotifiedFIFO(cmd->qptr, msg);
|
||||
}
|
||||
|
||||
int process_command(char *buf) {
|
||||
int i,j,k;
|
||||
@@ -459,7 +526,7 @@ int process_command(char *buf) {
|
||||
int rt;
|
||||
memset(modulename,0,sizeof(modulename));
|
||||
memset(cmd,0,sizeof(cmd));
|
||||
|
||||
extern char **environ;
|
||||
|
||||
if (strncasecmp(buf,"ex",2) == 0)
|
||||
return CMDSTATUS_EXIT;
|
||||
@@ -474,6 +541,8 @@ int process_command(char *buf) {
|
||||
}
|
||||
|
||||
for(j=0; telnetparams.CmdParsers[i].cmd[j].cmdfunc != NULL ; j++) {
|
||||
if ( telnetparams.CmdParsers[i].cmd[j].cmdflags & TELNETSRV_CMDFLAG_WEBSRVONLY )
|
||||
continue;
|
||||
client_printf(" %s %s %s\n",
|
||||
telnetparams.CmdParsers[i].module,telnetparams.CmdParsers[i].cmd[j].cmdname,
|
||||
telnetparams.CmdParsers[i].cmd[j].helpstr);
|
||||
@@ -489,7 +558,7 @@ int process_command(char *buf) {
|
||||
j = sscanf(buf,"%19s %19s %m[^\t\n]",modulename,cmd,&cmdb);
|
||||
|
||||
if (telnetparams.telnetdbg > 0)
|
||||
printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb);
|
||||
printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,(cmdb==NULL)?"":cmdb);
|
||||
|
||||
for (i=0; j>=2 && telnetparams.CmdParsers[i].var != NULL && telnetparams.CmdParsers[i].cmd != NULL; i++) {
|
||||
if ( (strncasecmp(telnetparams.CmdParsers[i].module,modulename,strlen(telnetparams.CmdParsers[i].module)) == 0)) {
|
||||
@@ -504,14 +573,10 @@ int process_command(char *buf) {
|
||||
} else {
|
||||
for (k=0 ; telnetparams.CmdParsers[i].cmd[k].cmdfunc != NULL ; k++) {
|
||||
if (strncasecmp(cmd, telnetparams.CmdParsers[i].cmd[k].cmdname,sizeof(telnetparams.CmdParsers[i].cmd[k].cmdname)) == 0) {
|
||||
if (telnetparams.CmdParsers[i].cmd[k].cmdflags & TELNETSRV_CMDFLAG_WEBSRVONLY)
|
||||
continue;
|
||||
if (telnetparams.CmdParsers[i].cmd[k].qptr != NULL) {
|
||||
notifiedFIFO_elt_t *msg =newNotifiedFIFO_elt(sizeof(telnetsrv_qmsg_t),0,NULL,NULL);
|
||||
telnetsrv_qmsg_t *cmddata=NotifiedFifoData(msg);
|
||||
cmddata->cmdfunc=(qcmdfunc_t)telnetparams.CmdParsers[i].cmd[k].cmdfunc;
|
||||
cmddata->prnt=client_printf;
|
||||
cmddata->debug=telnetparams.telnetdbg;
|
||||
cmddata->cmdbuff=strdup(cmdb);
|
||||
pushNotifiedFIFO(telnetparams.CmdParsers[i].cmd[k].qptr, msg);
|
||||
telnet_pushcmd(&(telnetparams.CmdParsers[i].cmd[k]), cmdb,client_printf );
|
||||
} else {
|
||||
telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf);
|
||||
}
|
||||
@@ -859,12 +924,14 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde
|
||||
strncpy(telnetparams.CmdParsers[i].module,modulename,sizeof(telnetparams.CmdParsers[i].module)-1);
|
||||
telnetparams.CmdParsers[i].cmd = cmd;
|
||||
telnetparams.CmdParsers[i].var = var;
|
||||
if (cmd->cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
|
||||
for (int j=0; cmd[j].cmdfunc != NULL ;j++) {
|
||||
if (cmd[j].cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
|
||||
if (afifo == NULL) {
|
||||
afifo = malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(afifo);
|
||||
}
|
||||
cmd->qptr = afifo;
|
||||
cmd[j].qptr = afifo;
|
||||
}
|
||||
}
|
||||
printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n",
|
||||
i,telnetparams.CmdParsers[i].module);
|
||||
@@ -894,10 +961,16 @@ int telnetsrv_checkbuildver(char *mainexec_buildversion, char **shlib_buildvers
|
||||
}
|
||||
|
||||
int telnetsrv_getfarray(loader_shlibfunc_t **farray) {
|
||||
*farray=malloc(sizeof(loader_shlibfunc_t)*2);
|
||||
*farray=malloc(sizeof(loader_shlibfunc_t)*3);
|
||||
(*farray)[0].fname=TELNET_ADDCMD_FNAME;
|
||||
(*farray)[0].fptr=(int (*)(void) )add_telnetcmd;
|
||||
(*farray)[1].fname=TELNET_POLLCMDQ_FNAME;
|
||||
(*farray)[1].fptr=(int (*)(void) )poll_telnetcmdq;
|
||||
return ( 2);
|
||||
(*farray)[2].fname=TELNET_PUSHCMD_FNAME;
|
||||
(*farray)[2].fptr=(int (*)(void) )telnet_pushcmd;
|
||||
return ( 3);
|
||||
}
|
||||
/* for webserver interface, needs access to some telnet server paramaters */
|
||||
telnetsrv_params_t *get_telnetsrv_params(void) {
|
||||
return &telnetparams;
|
||||
}
|
||||
|
||||
@@ -48,19 +48,55 @@
|
||||
#define CMDSTATUS_VARNOTFOUND 3
|
||||
#define CMDSTATUS_NOTFOUND 4
|
||||
|
||||
/* definitions to store 2 dim table, used to store command results before */
|
||||
/* displaying them either on console or web page */
|
||||
#define TELNET_MAXLINE_NUM 100
|
||||
#define TELNET_MAXCOL_NUM 10
|
||||
|
||||
typedef struct col {
|
||||
char coltitle[TELNET_CMD_MAXSIZE];
|
||||
unsigned int coltype;
|
||||
} acol_t;
|
||||
|
||||
typedef struct line {
|
||||
char *val[TELNET_MAXCOL_NUM];
|
||||
} aline_t;
|
||||
|
||||
typedef struct webdatadef {
|
||||
char tblname[TELNET_HELPSTR_SIZE];
|
||||
int numlines;
|
||||
int numcols;
|
||||
acol_t columns[TELNET_MAXCOL_NUM];
|
||||
aline_t lines[TELNET_MAXLINE_NUM];
|
||||
} webdatadef_t;
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* structure to be used when adding a module to the telnet server */
|
||||
/* This is the second parameter of the add_telnetcmd function, which can be used */
|
||||
/* to add a set of new command to the telnet server shell */
|
||||
typedef void(*telnet_printfunc_t)(const char* format, ...);
|
||||
typedef int(*cmdfunc_t)(char*, int, telnet_printfunc_t prnt);
|
||||
typedef int(*webfunc_t)(char *cmdbuff, int debug, telnet_printfunc_t prnt, ... );
|
||||
typedef int(*webfunc_getdata_t)(char *cmdbuff, int debug, void *data,telnet_printfunc_t prnt);
|
||||
typedef int(*qcmdfunc_t)(char*, int, telnet_printfunc_t prnt,void *arg);
|
||||
|
||||
#define TELNETSRV_CMDFLAG_PUSHINTPOOLQ (1<<0) // ask the telnet server to push the command in a thread pool queue
|
||||
#define TELNETSRV_CMDFLAG_PUSHINTPOOLQ (1<<0) // ask the telnet server to push the command in a thread pool queue
|
||||
#define TELNETSRV_CMDFLAG_GETWEBDATA (1<<1) // When called from web server, use the getdata variant of the function
|
||||
#define TELNETSRV_CMDFLAG_TELNETONLY (1<<2) // Command only for telnet client connections
|
||||
#define TELNETSRV_CMDFLAG_WEBSRVONLY (1<<3) // Command only for web server connections
|
||||
#define TELNETSRV_CMDFLAG_CONFEXEC (1<<4) // Ask for confirm before exec
|
||||
#define TELNETSRV_CMDFLAG_GETWEBTBLDATA (1<<8) // When called from web server, use the get table data variant of the function
|
||||
#define TELNETSRV_CMDFLAG_PRINTWEBTBLDATA (1<<9) // websrv Print as a single column table
|
||||
#define TELNETSRV_CMDFLAG_NEEDPARAM (1<<10) // websrv: The command needs a parameter
|
||||
#define TELNETSRV_CMDFLAG_WEBSRV_SETRETURNTBL (1<<11) // websrv: set callback returns a new table
|
||||
#define TELNETSRV_CMDFLAG_AUTOUPDATE (1<<12) // command can be re-submitted automatically for result update
|
||||
typedef struct cmddef {
|
||||
char cmdname[TELNET_CMD_MAXSIZE];
|
||||
char helpstr[TELNET_HELPSTR_SIZE];
|
||||
cmdfunc_t cmdfunc;
|
||||
cmdfunc_t cmdfunc;
|
||||
union {
|
||||
webfunc_t webfunc;
|
||||
webfunc_getdata_t webfunc_getdata;
|
||||
};
|
||||
unsigned int cmdflags;
|
||||
void *qptr;
|
||||
} telnetshell_cmddef_t;
|
||||
@@ -78,6 +114,8 @@ typedef struct telnetsrv_qmsg {
|
||||
/*structure to be used when adding a module to the telnet server */
|
||||
/* This is the first parameter of the add_telnetcmd function, which can be used */
|
||||
/* to add a set of new variables which can be got/set from the telnet server shell */
|
||||
/* var type: bits 0-3, type value (1 to 15)
|
||||
* type modifier, bits 4-31 */
|
||||
#define TELNET_VARTYPE_INT32 1
|
||||
#define TELNET_VARTYPE_INT16 2
|
||||
#define TELNET_VARTYPE_INT64 3
|
||||
@@ -85,10 +123,18 @@ typedef struct telnetsrv_qmsg {
|
||||
#define TELNET_VARTYPE_DOUBLE 5
|
||||
#define TELNET_VARTYPE_INT8 6
|
||||
#define TELNET_VARTYPE_UINT 7
|
||||
|
||||
#define TELNET_CHECKVAL_RDONLY 16
|
||||
#define TELNET_CHECKVAL_BOOL 32
|
||||
#define TELNET_VAR_NEEDFREE 64
|
||||
#define TELNET_CHECKVAL_LOGLVL 128
|
||||
#define TELNET_CHECKVAL_SIMALGO 256
|
||||
typedef struct variabledef {
|
||||
char varname[TELNET_CMD_MAXSIZE];
|
||||
char vartype;
|
||||
char checkval;
|
||||
void *varvalptr;
|
||||
|
||||
} telnetshell_vardef_t;
|
||||
|
||||
|
||||
@@ -113,6 +159,7 @@ typedef struct {
|
||||
int priority; // server running priority
|
||||
char *histfile; // command history
|
||||
int histsize; // command history length
|
||||
char *logfile; // filename to use when redirecting output to file
|
||||
int new_socket; // socket of the client connection
|
||||
int logfilefd; // file id of the log file when log output is redirected to a file
|
||||
int saved_stdout; // file id of the previous stdout, used to be able to restore original stdout
|
||||
@@ -145,14 +192,25 @@ VT escape sequence definition, for smarter display....
|
||||
#define STDFMT "\x1b[0m"
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*/
|
||||
#define TELNET_ADDCMD_FNAME "add_telnetcmd"
|
||||
#define NICE_MAX 19
|
||||
#define NICE_MIN -20
|
||||
#define TELNET_ADDCMD_FNAME "add_telnetcmd"
|
||||
#define TELNET_POLLCMDQ_FNAME "poll_telnetcmdq"
|
||||
#define TELNET_PUSHCMD_FNAME "telnet_pushcmd"
|
||||
typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *);
|
||||
typedef void(*poll_telnetcmdq_func_t)(void *qid,void *arg);
|
||||
typedef void(*push_telnetcmd_func_t)(telnetshell_cmddef_t *cmd, char *cmdbuff, telnet_printfunc_t prnt);
|
||||
#ifdef TELNETSERVERCODE
|
||||
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd);
|
||||
void set_sched(pthread_t tid, int pid,int priority);
|
||||
void set_affinity(pthread_t tid, int pid, int coreid);
|
||||
extern int get_phybsize(void);
|
||||
#endif
|
||||
#ifdef WEBSERVERCODE
|
||||
extern void telnet_pushcmd(telnetshell_cmddef_t *cmd, char *cmdbuff, telnet_printfunc_t prnt);
|
||||
extern telnetsrv_params_t *get_telnetsrv_params(void);
|
||||
extern char *telnet_getvarvalue(telnetshell_vardef_t *var, int varindex);
|
||||
extern int telnet_setvarvalue(telnetshell_vardef_t *var,char *strval, telnet_printfunc_t prnt ) ;
|
||||
extern void telnetsrv_freetbldata(webdatadef_t *wdata);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -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}},
|
||||
};
|
||||
|
||||
@@ -30,6 +30,6 @@ endforeach()
|
||||
|
||||
install(TARGETS telnetsrv DESTINATION bin)
|
||||
|
||||
if (EXISTS "${OPENAIR_BUILD_DIR}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/ran_build/build")
|
||||
install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/ran_build/build)
|
||||
endif (EXISTS "${OPENAIR_BUILD_DIR}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/ran_build/build")
|
||||
if (EXISTS "${OPENAIR_CMAKE}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_CMAKE}/ran_build/build")
|
||||
install(TARGETS telnetsrv DESTINATION ${OPENAIR_CMAKE}/ran_build/build)
|
||||
endif (EXISTS "${OPENAIR_CMAKE}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_CMAKE}/ran_build/build")
|
||||
|
||||
@@ -110,9 +110,8 @@ int dump_phyvars(char *buf, int debug, telnet_printfunc_t prnt) {
|
||||
|
||||
|
||||
telnetshell_cmddef_t phy_cmdarray[] = {
|
||||
{"disp","[phycnt,uedump,uestat UE<x>]", dump_phyvars},
|
||||
|
||||
{"","",NULL},
|
||||
{"disp","[phycnt,uedump,uestat UE<x>]", dump_phyvars,{NULL},0,NULL},
|
||||
{"","",NULL,{NULL},0,NULL},
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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().
|
||||
*/
|
||||
}
|
||||
@@ -42,24 +42,29 @@
|
||||
|
||||
int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
telnetshell_cmddef_t loader_cmdarray[] = {
|
||||
{"show","[params,modules]",loader_show_cmd},
|
||||
{"","",NULL},
|
||||
{"show","[params,modules]",loader_show_cmd,{(webfunc_t)loader_show_cmd},0,NULL},
|
||||
{"","",NULL,{NULL},0,NULL},
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (buff == NULL) {
|
||||
prnt("ERROR wrong loader SHOW command...\n");
|
||||
return 0;
|
||||
}
|
||||
if (debug > 0)
|
||||
prnt( "loader_show_cmd received %s\n",buff);
|
||||
|
||||
|
||||
if (strcasestr(buff,"params") != NULL) {
|
||||
prnt( "loader parameters:\n");
|
||||
prnt( " Main executable build version: \"%s\"\n", loader_data.mainexec_buildversion);
|
||||
prnt( " Default shared lib path: \"%s\"\n", loader_data.shlibpath);
|
||||
prnt( " Max number of shared lib : %i\n", loader_data.maxshlibs);
|
||||
}
|
||||
else if (strcasestr(buff,"modules") != NULL) {
|
||||
else if (strcasestr(buff,"modules") != NULL || buff[0]==0 || strcasestr(buff,"show") != NULL) {
|
||||
prnt( "%i shared lib have been dynamicaly loaded by the oai loader\n", loader_data.numshlibs);
|
||||
for (int i=0 ; i<loader_data.numshlibs ; i++) {
|
||||
prnt( " Module %i: %s\n", i,loader_data.shlibs[i].name);
|
||||
|
||||
@@ -39,11 +39,11 @@
|
||||
|
||||
|
||||
telnetshell_vardef_t loader_globalvardef[] = {
|
||||
{"mainversion",TELNET_VARTYPE_STRING,&(loader_data.mainexec_buildversion)},
|
||||
{"defpath",TELNET_VARTYPE_STRING,&(loader_data.shlibpath)},
|
||||
{"maxshlibs",TELNET_VARTYPE_INT32,&(loader_data.maxshlibs)},
|
||||
{"numshlibs",TELNET_VARTYPE_INT32,&(loader_data.numshlibs)},
|
||||
{"",0,NULL}
|
||||
{"mainversion",TELNET_VARTYPE_STRING,TELNET_CHECKVAL_RDONLY, &(loader_data.mainexec_buildversion)},
|
||||
{"defpath",TELNET_VARTYPE_STRING,TELNET_CHECKVAL_RDONLY,&(loader_data.shlibpath)},
|
||||
{"maxshlibs",TELNET_VARTYPE_INT32,TELNET_CHECKVAL_RDONLY,&(loader_data.maxshlibs)},
|
||||
{"numshlibs",TELNET_VARTYPE_INT32,TELNET_CHECKVAL_RDONLY,&(loader_data.numshlibs)},
|
||||
{"",0,0,NULL}
|
||||
};
|
||||
telnetshell_vardef_t *loader_modulesvardef;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -79,28 +79,20 @@ 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[] = {
|
||||
{"",0,NULL}
|
||||
{"",0,0,NULL}
|
||||
};
|
||||
/* function to be implemented in any telnetsrv_xxx_measurements.c sources
|
||||
to allow common measurment code to access measurments data */
|
||||
|
||||
@@ -53,7 +53,7 @@ telnetshell_vardef_t phy_vardef[] = {
|
||||
//{"txshift",TELNET_VARTYPE_INT32,NULL},
|
||||
//{"rachemin",TELNET_VARTYPE_INT32,NULL},
|
||||
//{"rachdmax",TELNET_VARTYPE_INT32,NULL},
|
||||
{"",0,NULL}
|
||||
{"",0,0,NULL}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
@@ -57,89 +57,121 @@
|
||||
#include "openair1/PHY/phy_extern.h"
|
||||
#include "telnetsrv_proccmd.h"
|
||||
|
||||
void decode_procstat(char *record, int debug, telnet_printfunc_t prnt)
|
||||
void decode_procstat(char *record, int debug, telnet_printfunc_t prnt,webdatadef_t *tdata)
|
||||
{
|
||||
char prntline[160];
|
||||
char *procfile_fiels;
|
||||
char *procfile_fields;
|
||||
char *strtokptr;
|
||||
char *lptr;
|
||||
int fieldcnt;
|
||||
char toksep[2];
|
||||
|
||||
fieldcnt=0;
|
||||
procfile_fiels =strtok_r(record," ",&strtokptr);
|
||||
procfile_fields =strtok_r(record," ",&strtokptr);
|
||||
lptr= prntline;
|
||||
/*http://man7.org/linux/man-pages/man5/proc.5.html gives the structure of the stat file */
|
||||
|
||||
while( procfile_fiels != NULL && fieldcnt < 42) {
|
||||
int priority=0;
|
||||
int nice=0;
|
||||
while( procfile_fields != NULL && fieldcnt < 42) {
|
||||
long int policy;
|
||||
if (strlen(procfile_fiels) == 0)
|
||||
if (strlen(procfile_fields) == 0)
|
||||
continue;
|
||||
fieldcnt++;
|
||||
sprintf(toksep," ");
|
||||
switch(fieldcnt) {
|
||||
case 1: /* id */
|
||||
lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
|
||||
sprintf(toksep,")");
|
||||
if (tdata != NULL) {
|
||||
tdata->lines[tdata->numlines].val[0]=strdup(procfile_fields);
|
||||
}
|
||||
lptr+=sprintf(lptr,"%9.9s ",procfile_fields);
|
||||
sprintf(toksep,")");
|
||||
break;
|
||||
case 2: /* name */
|
||||
lptr+=sprintf(lptr,"%20.20s ",procfile_fiels+1);
|
||||
if (tdata != NULL) {
|
||||
tdata->lines[tdata->numlines].val[1]=strdup(procfile_fields);
|
||||
}
|
||||
lptr+=sprintf(lptr,"%20.20s ",procfile_fields+1);
|
||||
break;
|
||||
case 3: //thread state
|
||||
lptr+=sprintf(lptr," %c ",procfile_fiels[0]);
|
||||
lptr+=sprintf(lptr," %c ",procfile_fields[0]);
|
||||
break;
|
||||
case 14: //time in user mode
|
||||
case 15: //time in kernel mode
|
||||
lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
|
||||
lptr+=sprintf(lptr,"%9.9s ",procfile_fields);
|
||||
break;
|
||||
case 18: //priority
|
||||
case 19: //nice
|
||||
lptr+=sprintf(lptr,"%3.3s ",procfile_fiels);
|
||||
case 18: //priority column index 2 in tdata, -2 to -100 (1, min to 99, highest prio)
|
||||
priority=strtol(procfile_fields,NULL,0);
|
||||
case 19: //nice column index 3 in tdata 0 to 39 (-20, highest prio, to 19)
|
||||
if (tdata != NULL) {
|
||||
tdata->lines[tdata->numlines].val[fieldcnt-16]=strdup(procfile_fields);
|
||||
}
|
||||
lptr+=sprintf(lptr,"%3.3s ",procfile_fields);
|
||||
nice=strtol(procfile_fields,NULL,0);
|
||||
break;
|
||||
case 23: //vsize
|
||||
lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
|
||||
lptr+=sprintf(lptr,"%9.9s ",procfile_fields);
|
||||
break;
|
||||
case 39: //processor
|
||||
lptr+=sprintf(lptr," %2.2s ",procfile_fiels);
|
||||
case 39: //processor
|
||||
if (tdata != NULL) {
|
||||
tdata->lines[tdata->numlines].val[4]=strdup(procfile_fields);
|
||||
}
|
||||
lptr+=sprintf(lptr," %2.2s ",procfile_fields);
|
||||
break;
|
||||
case 41: //policy
|
||||
lptr+=sprintf(lptr,"%3.3s ",procfile_fiels);
|
||||
policy=strtol(procfile_fiels,NULL,0);
|
||||
lptr+=sprintf(lptr,"%3.3s ",procfile_fields);
|
||||
policy=strtol(procfile_fields,NULL,0);
|
||||
char strschedp[64];
|
||||
switch(policy) {
|
||||
case SCHED_FIFO:
|
||||
lptr+=sprintf(lptr,"%s ","rt: fifo");
|
||||
snprintf(strschedp,sizeof(strschedp),"%s ","rt:fifo");
|
||||
priority= priority+1; //in /proc file system priority 1 to 99 mapped to -2 to -100
|
||||
break;
|
||||
case SCHED_OTHER:
|
||||
lptr+=sprintf(lptr,"%s ","other");
|
||||
snprintf(strschedp,sizeof(strschedp),"%s ","other");
|
||||
priority=nice-NICE_MIN; // linux nice is -20 to 19
|
||||
break;
|
||||
case SCHED_IDLE:
|
||||
lptr+=sprintf(lptr,"%s ","idle");
|
||||
snprintf(strschedp,sizeof(strschedp),"%s ","idle");
|
||||
priority=2*(NICE_MAX-NICE_MIN+1);
|
||||
break;
|
||||
case SCHED_BATCH:
|
||||
lptr+=sprintf(lptr,"%s ","batch");
|
||||
snprintf(strschedp,sizeof(strschedp),"%s ","batch");
|
||||
priority=(NICE_MAX-NICE_MIN+1)+nice-NICE_MIN;
|
||||
break;
|
||||
case SCHED_RR:
|
||||
lptr+=sprintf(lptr,"%s ","rt: rr");
|
||||
snprintf(strschedp,sizeof(strschedp),"%s ","rt:rr");
|
||||
priority= priority-99 ;
|
||||
break;
|
||||
#ifdef SCHED_DEADLINE
|
||||
case SCHED_DEADLINE:
|
||||
lptr+=sprintf(lptr,"%s ","rt: deadline");
|
||||
snprintf(strschedp,sizeof(strschedp),"%s ","rt:deadline");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
lptr+=sprintf(lptr,"%s ","????");
|
||||
snprintf(strschedp,sizeof(strschedp),"%s ","????");
|
||||
break;
|
||||
}
|
||||
lptr+=sprintf(lptr,"%s ",strschedp);
|
||||
if (tdata != NULL) {
|
||||
tdata->lines[tdata->numlines].val[5]=strdup(strschedp);
|
||||
tdata->lines[tdata->numlines].val[6]=malloc(10);
|
||||
snprintf(tdata->lines[tdata->numlines].val[6],9,"%i",priority);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}/* switch on fieldcnr */
|
||||
procfile_fiels =strtok_r(NULL,toksep,&strtokptr);
|
||||
procfile_fields =strtok_r(NULL,toksep,&strtokptr);
|
||||
} /* while on proc_fields != NULL */
|
||||
prnt("%s\n",prntline);
|
||||
if (tdata != NULL) {
|
||||
tdata->numlines++;
|
||||
}
|
||||
} /*decode_procstat */
|
||||
|
||||
void read_statfile(char *fname,int debug, telnet_printfunc_t prnt)
|
||||
|
||||
|
||||
void read_statfile(char *fname,int debug, telnet_printfunc_t prnt, webdatadef_t *tdata)
|
||||
{
|
||||
FILE *procfile;
|
||||
char arecord[1024];
|
||||
@@ -157,21 +189,55 @@ char arecord[1024];
|
||||
return;
|
||||
}
|
||||
fclose(procfile);
|
||||
decode_procstat(arecord, debug, prnt);
|
||||
decode_procstat(arecord, debug, prnt,tdata);
|
||||
}
|
||||
|
||||
void print_threads(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
int nullprnt(char *fmt,...) {
|
||||
return 0;
|
||||
}
|
||||
void proccmd_get_threaddata(char *buf, int debug, telnet_printfunc_t fprnt,webdatadef_t *tdata)
|
||||
{
|
||||
char aname[256];
|
||||
|
||||
DIR *proc_dir;
|
||||
struct dirent *entry;
|
||||
telnet_printfunc_t prnt = (fprnt != NULL)?fprnt:(telnet_printfunc_t)nullprnt;
|
||||
if (tdata != NULL) {
|
||||
tdata->numcols=7;
|
||||
snprintf(tdata->columns[0].coltitle,sizeof(tdata->columns[0].coltitle),"thread id");
|
||||
tdata->columns[0].coltype=TELNET_VARTYPE_STRING|TELNET_CHECKVAL_RDONLY|TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[1].coltitle,sizeof(tdata->columns[1].coltitle),"thread name");
|
||||
tdata->columns[1].coltype=TELNET_VARTYPE_STRING|TELNET_CHECKVAL_RDONLY|TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[2].coltitle,sizeof(tdata->columns[2].coltitle),"priority");
|
||||
tdata->columns[2].coltype=TELNET_VARTYPE_STRING|TELNET_CHECKVAL_RDONLY|TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[3].coltitle,sizeof(tdata->columns[3].coltitle),"nice");
|
||||
tdata->columns[3].coltype=TELNET_VARTYPE_STRING|TELNET_CHECKVAL_RDONLY|TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[4].coltitle,sizeof(tdata->columns[4].coltitle),"core");
|
||||
tdata->columns[4].coltype=TELNET_VARTYPE_STRING|TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[5].coltitle,sizeof(tdata->columns[5].coltitle),"sched policy");
|
||||
tdata->columns[5].coltype=TELNET_VARTYPE_STRING|TELNET_CHECKVAL_RDONLY|TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[5].coltitle,sizeof(tdata->columns[5].coltitle),"sched policy");
|
||||
tdata->columns[6].coltype=TELNET_VARTYPE_STRING|TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[6].coltitle,sizeof(tdata->columns[6].coltitle),"oai priority");
|
||||
tdata->numlines=0;
|
||||
}
|
||||
|
||||
unsigned int eax=11,ebx=0,ecx=1,edx=0;
|
||||
|
||||
asm volatile("cpuid"
|
||||
: "=a" (eax),
|
||||
"=b" (ebx),
|
||||
"=c" (ecx),
|
||||
"=d" (edx)
|
||||
: "0" (eax), "2" (ecx)
|
||||
: );
|
||||
|
||||
prnt("System has %d cores %d threads %d Actual threads",eax,ebx,edx);
|
||||
|
||||
|
||||
|
||||
prnt(" id name state USRmod KRNmod prio nice vsize proc pol \n\n");
|
||||
prnt("\n id name state USRmod KRNmod prio nice vsize proc pol \n\n");
|
||||
snprintf(aname, sizeof(aname), "/proc/%d/stat", getpid());
|
||||
read_statfile(aname,debug,prnt);
|
||||
read_statfile(aname,debug,prnt,NULL);
|
||||
prnt("\n");
|
||||
snprintf(aname, sizeof(aname), "/proc/%d/task", getpid());
|
||||
proc_dir = opendir(aname);
|
||||
@@ -181,20 +247,150 @@ struct dirent *entry;
|
||||
return;
|
||||
}
|
||||
|
||||
while ((entry = readdir(proc_dir)) != NULL)
|
||||
{
|
||||
if(entry->d_name[0] == '.')
|
||||
continue;
|
||||
snprintf(aname, sizeof(aname), "/proc/%d/task/%.*s/stat", getpid(),(int)(sizeof(aname)-24),entry->d_name);
|
||||
read_statfile(aname,debug,prnt);
|
||||
} /* while entry != NULL */
|
||||
while ((entry = readdir(proc_dir)) != NULL){
|
||||
if(entry->d_name[0] != '.') {
|
||||
snprintf(aname, sizeof(aname), "/proc/%d/task/%.*s/stat", getpid(),(int)(sizeof(aname)-24),entry->d_name);
|
||||
read_statfile(aname,debug,prnt,tdata);
|
||||
}
|
||||
} /* while entry != NULL */
|
||||
closedir(proc_dir);
|
||||
} /* print_threads */
|
||||
void print_threads(char *buf, int debug, telnet_printfunc_t prnt) {
|
||||
proccmd_get_threaddata(buf,debug,prnt,NULL);
|
||||
}
|
||||
|
||||
int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfunc_t prnt) {
|
||||
webdatadef_t *logsdata = ( webdatadef_t *) data;
|
||||
if (strncmp(cmdbuff,"set",3) == 0) {
|
||||
telnet_printfunc_t printfunc = (prnt != NULL)?prnt:( telnet_printfunc_t)printf;
|
||||
if (strcasestr(cmdbuff,"loglvl") != NULL) {
|
||||
int level=map_str_to_int(log_level_names,logsdata->lines[0].val[1]);
|
||||
int enabled=(strcmp(logsdata->lines[0].val[2],"true")==0)?1:0;
|
||||
int loginfile=(strcmp(logsdata->lines[0].val[3],"true")==0)?1:0;
|
||||
set_log(logsdata->numlines, level);
|
||||
if (enabled==0)
|
||||
set_log(logsdata->numlines, OAILOG_DISABLE);
|
||||
if ( loginfile == 1 ) {
|
||||
set_component_filelog(logsdata->numlines);
|
||||
} else {
|
||||
close_component_filelog(logsdata->numlines);
|
||||
}
|
||||
printfunc("%s log level %s is %s, output to %s\n",logsdata->lines[0].val[0],
|
||||
logsdata->lines[0].val[1], enabled?"enabled":"disabled",loginfile?g_log->log_component[logsdata->numlines].filelog_name :"stdout");
|
||||
}
|
||||
if (strcasestr(cmdbuff,"logopt") != NULL) {
|
||||
int optbit=map_str_to_int(log_options,logsdata->lines[0].val[0]);
|
||||
if (optbit < 0) {
|
||||
printfunc("option %s unknown\n",logsdata->lines[0].val[0]);
|
||||
} else {
|
||||
if(strcmp(logsdata->lines[0].val[1],"true")==0) {
|
||||
SET_LOG_OPTION(optbit);
|
||||
} else {
|
||||
CLEAR_LOG_OPTION(optbit);
|
||||
}
|
||||
printfunc("%s log option %s\n",logsdata->lines[0].val[0],(strcmp(logsdata->lines[0].val[1],"true")==0)?"enabled":"disabled");
|
||||
}
|
||||
}
|
||||
if (strcasestr(cmdbuff,"dbgopt") != NULL) {
|
||||
int optbit=map_str_to_int(log_maskmap,logsdata->lines[0].val[0]);
|
||||
if (optbit < 0) {
|
||||
printfunc("debug option %s unknown\n",logsdata->lines[0].val[0]);
|
||||
} else {
|
||||
if(strcmp(logsdata->lines[0].val[1],"true")==0)
|
||||
SET_LOG_DEBUG(optbit);
|
||||
else
|
||||
CLEAR_LOG_DEBUG(optbit);
|
||||
if(strcmp(logsdata->lines[0].val[2],"true")==0)
|
||||
SET_LOG_DUMP(optbit);
|
||||
else
|
||||
CLEAR_LOG_DUMP(optbit);
|
||||
printfunc("%s debug %s dump %s\n",logsdata->lines[0].val[0],
|
||||
(strcmp(logsdata->lines[0].val[1],"true")==0)?"enabled":"disabled",
|
||||
(strcmp(logsdata->lines[0].val[2],"true")==0)?"enabled":"disabled");
|
||||
}
|
||||
}
|
||||
if (strcasestr(cmdbuff,"threadsched") != NULL) {
|
||||
unsigned int tid=strtoll(logsdata->lines[0].val[0],NULL,0);
|
||||
unsigned int core=strtoll(logsdata->lines[0].val[4],NULL,0);
|
||||
int priority=strtoll(logsdata->lines[0].val[6],NULL,0);
|
||||
printfunc("Thread %s id %u set affinity to core %u\n",logsdata->lines[0].val[0],tid,core);
|
||||
set_affinity( 0,(pid_t)tid, core) ;
|
||||
set_sched(0, (pid_t)tid, priority) ;
|
||||
}
|
||||
} else { /* end of set, => show */
|
||||
if (strcasestr(cmdbuff,"loglvl") != NULL) {
|
||||
|
||||
logsdata->numcols=4;
|
||||
logsdata->numlines=0;
|
||||
snprintf(logsdata->columns[0].coltitle,TELNET_CMD_MAXSIZE,"component");
|
||||
logsdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY;
|
||||
snprintf(logsdata->columns[1].coltitle,TELNET_CMD_MAXSIZE,"level");
|
||||
logsdata->columns[1].coltype = TELNET_VARTYPE_STRING|TELNET_CHECKVAL_LOGLVL;
|
||||
snprintf(logsdata->columns[2].coltitle,TELNET_CMD_MAXSIZE,"enabled");
|
||||
logsdata->columns[2].coltype = TELNET_CHECKVAL_BOOL;
|
||||
snprintf(logsdata->columns[3].coltitle,TELNET_CMD_MAXSIZE,"in file");
|
||||
logsdata->columns[3].coltype = TELNET_CHECKVAL_BOOL;
|
||||
|
||||
|
||||
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
||||
if (g_log->log_component[i].name != NULL) {
|
||||
logsdata->numlines++;
|
||||
logsdata->lines[i].val[0]= (char *)(g_log->log_component[i].name);
|
||||
|
||||
logsdata->lines[i].val[1]=map_int_to_str(log_level_names,(g_log->log_component[i].level>=0)?g_log->log_component[i].level:g_log->log_component[i].savedlevel);
|
||||
logsdata->lines[i].val[2]=(g_log->log_component[i].level>=0)?"true":"false";
|
||||
logsdata->lines[i].val[3]=(g_log->log_component[i].filelog>0)?"true":"false";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strcasestr(cmdbuff,"dbgopt") != NULL) {
|
||||
webdatadef_t *logsdata = ( webdatadef_t *) data;
|
||||
logsdata->numcols=3;
|
||||
logsdata->numlines=0;
|
||||
snprintf(logsdata->columns[0].coltitle,TELNET_CMD_MAXSIZE,"module");
|
||||
logsdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY;
|
||||
snprintf(logsdata->columns[1].coltitle,TELNET_CMD_MAXSIZE,"debug");
|
||||
logsdata->columns[1].coltype = TELNET_CHECKVAL_BOOL;
|
||||
snprintf(logsdata->columns[2].coltitle,TELNET_CMD_MAXSIZE,"dump");
|
||||
logsdata->columns[2].coltype = TELNET_CHECKVAL_BOOL;
|
||||
|
||||
for (int i=0; log_maskmap[i].name != NULL ; i++) {
|
||||
logsdata->numlines++;
|
||||
logsdata->lines[i].val[0]= log_maskmap[i].name;
|
||||
logsdata->lines[i].val[1]= (g_log->debug_mask & log_maskmap[i].value)?"true":"false";
|
||||
logsdata->lines[i].val[2]=(g_log->dump_mask & log_maskmap[i].value)?"true":"false";
|
||||
}
|
||||
}
|
||||
|
||||
if (strcasestr(cmdbuff,"logopt") != NULL) {
|
||||
webdatadef_t *logsdata = ( webdatadef_t *) data;
|
||||
logsdata->numcols=2;
|
||||
logsdata->numlines=0;
|
||||
snprintf(logsdata->columns[0].coltitle,TELNET_CMD_MAXSIZE,"option");
|
||||
logsdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY;
|
||||
snprintf(logsdata->columns[1].coltitle,TELNET_CMD_MAXSIZE,"enabled");
|
||||
logsdata->columns[1].coltype = TELNET_CHECKVAL_BOOL;
|
||||
|
||||
for (int i=0; log_options[i].name != NULL; i++) {
|
||||
logsdata->numlines++;
|
||||
logsdata->lines[i].val[0]=log_options[i].name;
|
||||
logsdata->lines[i].val[1]=(g_log->flag & log_options[i].value)?"true":"false";
|
||||
}
|
||||
}
|
||||
if (strcasestr(cmdbuff,"threadsched") != NULL) {
|
||||
proccmd_get_threaddata(cmdbuff, debug, prnt, ( webdatadef_t *) data);
|
||||
}
|
||||
} // show
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
|
||||
if (buf == NULL) {
|
||||
prnt("ERROR wrong softmodem SHOW command...\n");
|
||||
return 0;
|
||||
}
|
||||
if (debug > 0)
|
||||
prnt(" proccmd_show received %s\n",buf);
|
||||
if (strcasestr(buf,"thread") != NULL) {
|
||||
@@ -270,6 +466,10 @@ int bv1,bv2;
|
||||
int res;
|
||||
char sv1[64];
|
||||
|
||||
if (buf == NULL) {
|
||||
prnt("ERROR wrong thread command...\n");
|
||||
return 0;
|
||||
}
|
||||
bv1=0;
|
||||
bv2=0;
|
||||
sv1[0]=0;
|
||||
@@ -284,7 +484,7 @@ char sv1[64];
|
||||
prnt(" proccmd_thread: %i params = %i,%s,%i\n",res,bv1,sv1,bv2);
|
||||
if(res != 3)
|
||||
{
|
||||
prnt("softmodem thread needs 3 params, %i received\n",res);
|
||||
print_threads(buf, debug, prnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -307,11 +507,20 @@ int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (debug > 0)
|
||||
prnt("process module received %s\n",buf);
|
||||
|
||||
end_configmodule();
|
||||
exit_fun("telnet server received exit command\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int proccmd_restart(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (debug > 0)
|
||||
prnt("process module received %s\n",buf);
|
||||
end_configmodule();
|
||||
configmodule_interface_t *cfg = config_get_if();
|
||||
execvpe(cfg->argv[0],cfg->argv ,environ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
@@ -396,7 +605,7 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
|
||||
SET_LOG_DUMP(optbit);
|
||||
else
|
||||
CLEAR_LOG_DUMP(optbit);
|
||||
proccmd_show("dbgopt",debug,prnt);
|
||||
proccmd_show("dump",debug,prnt);
|
||||
}
|
||||
}
|
||||
if (logparam != NULL) free(logparam);
|
||||
@@ -435,7 +644,7 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
|
||||
} else {
|
||||
prnt("%s%s unknown log sub command \n",logparam, tmpstr);
|
||||
}
|
||||
} else {
|
||||
} else {level=map_str_to_int(log_level_names,tmpstr);
|
||||
prnt("%s unknown log sub command \n",logsubcmd);
|
||||
}
|
||||
if (logparam != NULL) free(logparam);
|
||||
@@ -459,6 +668,7 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
|
||||
void add_softmodem_cmds(void)
|
||||
|
||||
@@ -44,9 +44,11 @@
|
||||
extern int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt);
|
||||
extern int proccmd_thread(char *buf, int debug, telnet_printfunc_t prnt);
|
||||
extern int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt);
|
||||
extern int proccmd_restart(char *buf, int debug, telnet_printfunc_t prnt);
|
||||
extern int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt);
|
||||
extern int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data,telnet_printfunc_t prnt);
|
||||
telnetshell_vardef_t proc_vardef[] = {
|
||||
{"",0,NULL}
|
||||
{"",0,0,NULL}
|
||||
};
|
||||
#define PROCCMD_LOG_HELP_STRING " log sub commands: \n\
|
||||
show: display current log configuration \n\
|
||||
@@ -65,18 +67,26 @@ telnetshell_vardef_t proc_vardef[] = {
|
||||
#define PROCCMD_THREAD_HELP_STRING " thread sub commands: \n\
|
||||
<thread id> aff <core> : set affinity of thread <thread id> to core <core> \n\
|
||||
<thread id> prio <prio> : set scheduling parameters for thread <thread id> \n\
|
||||
if prio < -20: linux scheduling policy set to FIFO, \n\
|
||||
with priority = -20 - prio \n\
|
||||
if prio > 19: linux scheduling policy set to OTHER, \n\
|
||||
with priority (nice value) = prio \n\
|
||||
-100 < prio < 0: linux scheduling policy set to FIFO, priority -prio, \n\
|
||||
-200 < prio < -100: linux scheduling policy set to RR, priority -(prio+100), \n\
|
||||
0 <= prio < 40: linux scheduling policy set to NORMAL, nice value prio-20 \n\
|
||||
40 <= prio < 80: linux scheduling policy set to BATCH, nice value prio-60 \n\
|
||||
prio >=80: linux scheduling policy set to IDLE \n\
|
||||
use \"softmodem show thread\" to get <thread id> \n"
|
||||
|
||||
|
||||
telnetshell_cmddef_t proc_cmdarray[] = {
|
||||
{"show","loglvl|thread|config", proccmd_show},
|
||||
{"log","(enter help for details)", proccmd_log},
|
||||
{"thread","(enter help for details)", proccmd_thread},
|
||||
{"exit","", proccmd_exit},
|
||||
{"show","loglvl|thread|config", proccmd_show,{(webfunc_t)proccmd_websrv_getdata},TELNETSRV_CMDFLAG_TELNETONLY,NULL},
|
||||
{"log","(enter help for details)", proccmd_log, {NULL},TELNETSRV_CMDFLAG_TELNETONLY,NULL},
|
||||
{"show loglvl","", proccmd_log,{(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_WEBSRVONLY|TELNETSRV_CMDFLAG_GETWEBTBLDATA,NULL},
|
||||
{"show logopt","", proccmd_log,{(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_WEBSRVONLY|TELNETSRV_CMDFLAG_GETWEBTBLDATA,NULL},
|
||||
{"show dbgopt","", proccmd_log,{(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_WEBSRVONLY|TELNETSRV_CMDFLAG_GETWEBTBLDATA,NULL},
|
||||
{"show config","", proccmd_show,{(webfunc_t)proccmd_show}, TELNETSRV_CMDFLAG_WEBSRVONLY,NULL},
|
||||
{"show thread","", proccmd_thread,{(webfunc_t)proccmd_show},TELNETSRV_CMDFLAG_WEBSRVONLY|TELNETSRV_CMDFLAG_AUTOUPDATE,NULL},
|
||||
{"thread","(enter help for details)",proccmd_thread,{NULL},TELNETSRV_CMDFLAG_TELNETONLY,NULL},
|
||||
{"show threadsched","",proccmd_show,{(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_WEBSRVONLY|TELNETSRV_CMDFLAG_GETWEBTBLDATA,NULL},
|
||||
{"exit","", proccmd_exit,{NULL},TELNETSRV_CMDFLAG_CONFEXEC,NULL},
|
||||
{"restart","",proccmd_restart,{NULL},TELNETSRV_CMDFLAG_CONFEXEC,NULL},
|
||||
{"","",NULL},
|
||||
};
|
||||
#else
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
7
common/utils/websrv/DOC/websrv.md
Normal file
7
common/utils/websrv/DOC/websrv.md
Normal file
@@ -0,0 +1,7 @@
|
||||
The oai web server is an optional monitoring and debugging tool. It gives access to the same functionalities as the telnet server via a web interface
|
||||
|
||||
* [Using the web server](webserverusage.md)
|
||||
* [enhancing the webserver](webserverdevcmd.md)
|
||||
* [web server architecture ](webserverarch.md)
|
||||
|
||||
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
|
||||
31
common/utils/websrv/DOC/websrvarch.md
Normal file
31
common/utils/websrv/DOC/websrvarch.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# telnet server principles
|
||||
|
||||
The oai telnet server is implemented in shared libraries to be loaded by the [oai shared library loader](loader). `libtelnetsrv.so ` contains the code common to all oai softmodem executables, where `libtelnetsrv_<app>.so` contains the code specific to the executable identified by `app`.
|
||||
|
||||
| `<app>` | executable |
|
||||
| :-----: | :---------------: |
|
||||
| enb | `lte-softmodem` |
|
||||
| gnb | `nr-softmodem` |
|
||||
| 4Gue | `lte-uesoftmodem` |
|
||||
| 5Gue | `nr-uesoftmodem` |
|
||||
|
||||
The implementation includes a `telnetsrv_autoinit` function which is automatically called at load time, starts the telnet server and registers a first set of commands, which are delivered with the server (telnet, softmodem, loader). it also uses the `get_softmodem_function` call to retrieve the running executable id and possibly loads the corresponding `libtelnetsrv_<app>.so`library.
|
||||
|
||||
Currently the telnet server only supports one user connection. The same dedicated thread is used to wait for a user connection and process the input received from this connection.
|
||||
|
||||
The telnet server provides an API which can be used by any oai component to add new CLI commands to the server. A pre-defined command can be used to get or set a list of variables.
|
||||
|
||||
|
||||
|
||||
# telnet server source files
|
||||
|
||||
telnet server source files are located in [common/utils/telnetsrv](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv)
|
||||
|
||||
1. [telnetsrv.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.c) contains the telnet server implementation, including the implementation of the `telnet` CLI command. This implementation is compatible with all softmodem executables and is in charge of loading any additional `libtelnetsrv_<app> .so` containing code specific to the running executables.
|
||||
1. [telnetsrv.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.h) is the telnet server include file containing both private and public data type definitions. It also contains API prototypes for functions that are used to register a new command in the server.
|
||||
1. `telnetsrv_<XXX\>.c`: implementation of \<XXX\> CLI command which are delivered with the telnet server and are common to all softmodem executables.
|
||||
1. `telnetsrv_<XXX\>.h`: include file for the implementation of XXX CLI command. Usually included only in the corresponding `.c`file
|
||||
1. `telnetsrv_<app>_<XXX>.c`: implementation of \<XXX\> CLI command specific to the executable identified by \<app\>.These sources are used to create `libtelnetsrv_<app>.so` at build time.
|
||||
1. [telnetsrv_CMakeLists.txt](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/telnetsrv/telnetsrv_CMakeLists.txt): CMakelists file containing the cmake instructions to build the telnet server. this file is included in the [global oai CMakelists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt).
|
||||
|
||||
[oai telnet server home](telnetsrv.md)
|
||||
40
common/utils/websrv/DOC/websrvuse.md
Normal file
40
common/utils/websrv/DOC/websrvuse.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# starting the softmodem with the telnet server
|
||||
By default the embedded telnet server, which is implemented in a shared library, is not built. It can be built after compiling the softmodem executable using the `build_oai` script:
|
||||
|
||||
```bash
|
||||
cd \<oai repository\>/openairinterface5g
|
||||
source oaienv
|
||||
cd cmake_targets
|
||||
./build_oai --build-lib telnetsrv
|
||||
```
|
||||
|
||||
This will create the `libtelnetsrv.so` and `libtelnetsrv_<app> file in the `targets/bin` and `cmake_targets/ran_build/build` sub directories of the oai repository. <app> can be "enb", "gnb", "4GUE" or "5GUE", each library containing functions specific to a given executable.
|
||||
|
||||
When starting the softmodem, you must specify the **_\-\-telnetsrv_** option to load and start the telnet server. The telnet server is loaded via the [oai shared library loader](loader).
|
||||
|
||||
# using the Command Line Interface
|
||||
By default the telnet server listen on all the ip addresses configured on the system and on port 9090. This behavior can be changed using the `listenaddr` and `listenport` parameters.
|
||||
The telnet server includes a basic help, listing available commands and some commands also provide a specific detailed help sub-command.
|
||||
Below are examples of telnet sessions:
|
||||
|
||||
* [getting help](telnethelp.md)
|
||||
* [using the history](telnethist.md)
|
||||
* [using the get and set commands](telnetgetset.md)
|
||||
* [using the loop command](telnetloop.md)
|
||||
* [loader command](telnetloader.md)
|
||||
* [log command](telnetlog.md)
|
||||
* [measur command](telnetmeasur.md)
|
||||
|
||||
# telnet server parameters
|
||||
The telnet server is using the [oai configuration module](Config/Rtusage). Telnet parameters must be specified in the `telnetsrv` section. Some parameters can be modified via the telnet telnet server command, as specified in the last column of the following table.
|
||||
|
||||
| name | type | default | description | dynamic |
|
||||
|:---:|:---:|:---:|:----|:----:|
|
||||
| `listenaddr` | `ipV4 address, ascii format` | "0.0.0.0" | local address the server is listening on| N |
|
||||
| `listenport` | `integer` | 9090 | port number the server is listening on | N |
|
||||
| `loopcount` | `integer` | 10 | number of iterations for the loop command | Y |
|
||||
| `loopdelay` | `integer` | 5000 | delay (in ms) between 2 loop command iterations | Y |
|
||||
| `histfile` | `character string` | "oaitelnet.history" | file used for command history persistency | Y |
|
||||
| `histfsize` | `integer` | 50 | maximum number of commands saved in the history | Y |
|
||||
|
||||
[oai telnet server home](telnetsrv.md)
|
||||
17
common/utils/websrv/frontend/.browserslistrc
Normal file
17
common/utils/websrv/frontend/.browserslistrc
Normal file
@@ -0,0 +1,17 @@
|
||||
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
||||
# For additional information regarding the format and rule options, please see:
|
||||
# https://github.com/browserslist/browserslist#queries
|
||||
|
||||
# For the full list of supported browsers by the Angular framework, please see:
|
||||
# https://angular.io/guide/browser-support
|
||||
|
||||
# You can see what browsers were selected by your queries by running:
|
||||
# npx browserslist
|
||||
|
||||
last 1 Chrome version
|
||||
last 1 Firefox version
|
||||
last 2 Edge major versions
|
||||
last 2 Safari major versions
|
||||
last 2 iOS major versions
|
||||
Firefox ESR
|
||||
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user