Compare commits

..

347 Commits

Author SHA1 Message Date
El Mghazli Yacine
1ef5fafe89 logger component 2022-10-10 10:15:51 +02:00
frtabu
9f6e46bd8a Add backend memory cleanup when stopping scope, minor enhancements frontend interface 2022-10-07 20:01:01 +02:00
El Mghazli Yacine
7372378732 detail 2022-10-06 18:38:45 +02:00
El Mghazli Yacine
71d20e0543 removed logger components 2022-10-06 18:03:42 +02:00
El Mghazli Yacine
33fd2343ce removed charts folder 2022-10-06 18:02:05 +02:00
El Mghazli Yacine
48ef96959d removed scop2 and ws2 2022-10-06 17:07:29 +02:00
El Mghazli Yacine
c73ce11828 Merge branch 'rxws' of https://gitlab.eurecom.fr/oai/openairinterface5g into rxws 2022-10-06 15:15:46 +02:00
El Mghazli Yacine
66546b7ad0 send message fixed 2022-10-06 15:15:25 +02:00
El Mghazli Yacine
11087fff0f details 2022-10-06 15:15:25 +02:00
El Mghazli Yacine
ffa13d99e5 scope2 working like scope 2022-10-06 15:15:25 +02:00
yacine
ccae22f648 serdes to be tested 2022-10-06 15:15:25 +02:00
yacine
4e932c9248 build OK 2022-10-06 15:15:25 +02:00
yacine
0c9dd4d04a scope2 2022-10-06 15:12:23 +02:00
El Mghazli Yacine
67a5bfaa43 initial commit WIP 2022-10-06 15:12:23 +02:00
El Mghazli Yacine
501192a1f8 send message fixed 2022-10-06 15:12:06 +02:00
frtabu
83d00d4c21 scope waterfall enhancements 2022-10-06 15:09:38 +02:00
El Mghazli Yacine
12504106eb details 2022-10-04 15:15:48 +02:00
El Mghazli Yacine
3bb957722f scope2 working like scope 2022-10-04 12:58:41 +02:00
yacine
ae2abbc6e2 serdes to be tested 2022-10-02 23:42:22 +02:00
yacine
544c723372 build OK 2022-10-01 01:10:29 +02:00
yacine
1e34ab443c Merge branch 'rxws' of https://gitlab.eurecom.fr/oai/openairinterface5g into rxws 2022-10-01 00:51:03 +02:00
yacine
519b38817a scope2 2022-10-01 00:50:41 +02:00
El Mghazli Yacine
3da668576c initial commit WIP 2022-10-01 00:50:41 +02:00
yacine
ce46cab866 scope2 2022-10-01 00:48:51 +02:00
frtabu
553c6377aa waterfall implem going on.... 2022-09-30 19:13:29 +02:00
El Mghazli Yacine
b42694254f initial commit WIP 2022-09-30 19:07:20 +02:00
frtabu
50821cace3 switch to 16bits value for LLR data, start watterfall view implem 2022-09-29 19:40:52 +02:00
frtabu
2fb9752bff llr view enhancements 2022-09-28 19:33:42 +02:00
frtabu
7b57a3d4ed hardening websocket connection 2022-09-28 16:23:44 +02:00
frtabu
d81b670ac2 scope: llr view debug 2022-09-22 16:41:46 +02:00
yacine nokia
461ba045b1 use env backend for ws:// 2022-09-20 15:32:27 +02:00
frtabu
03a8ff2913 init fix scope availibility Pb 2022-09-20 14:31:59 +02:00
frtabu
6e85528582 scope interface modifications 2022-09-20 12:17:37 +02:00
frtabu
81ba755984 more scope updates 2022-09-19 11:25:35 +02:00
frtabu
e8ca483c56 scope front-end and back-end fixes and enhancements 2022-09-13 19:48:17 +02:00
frtabu
f8eba8400d scope chart display enhancements 2022-09-09 18:52:05 +02:00
frtabu
6d2bd1025f Add frontend chart options to improve GUI and perf 2022-09-07 19:50:56 +02:00
frtabu
36c0cf0133 scope data transfer debug 2022-09-06 19:47:57 +02:00
frtabu
7b31678bed fix frontend bug and add signal selection 2022-09-05 19:33:04 +02:00
frtabu
b2ba88667a scope gui enhancement, implement backend scope interface suport via regular http, websocket reserved for scope data transfers , frontend broken, init Pb 2022-08-26 17:14:41 +02:00
frtabu
0aca093122 start Restructure scope support code to move to regular http request control protocol, websocket being used for data 2022-08-24 19:38:36 +02:00
frtabu
73f5496ffa scope iq transfer implem and test 2022-08-23 19:19:53 +02:00
frtabu
f809e4689c angular update and ng2-charts integration completed 2022-07-26 19:15:00 +02:00
frtabu
5ae59cc394 Angular update 2022-07-26 15:16:02 +02:00
frtabu
def1ebc661 angular update 2022-07-26 13:18:22 +02:00
frtabu
b57963dd2a remove package_lock.json from git 2022-07-26 13:12:59 +02:00
frtabu
d33ae02d39 Angular update and start importing ng2-charts 2022-07-26 12:45:38 +02:00
frtabu
86ba2b0822 angular update 2022-07-25 17:55:41 +02:00
frtabu
4bfc929bad angular update 2022-07-25 15:33:48 +02:00
frtabu
db81a3f0b9 angular update 2022-07-25 15:31:18 +02:00
frtabu
abf14c0bb4 angular update 2022-07-25 15:28:26 +02:00
frtabu
a1d4514ae0 angular update 2022-07-25 15:26:05 +02:00
frtabu
d813fb8470 angular upgrade 2022-07-25 15:23:01 +02:00
frtabu
e2615dd886 angular update 2022-07-25 15:21:04 +02:00
frtabu
cc24755a34 angular update 2022-07-25 14:33:20 +02:00
frtabu
ca45cbb2b7 Angular update 2022-07-25 14:27:54 +02:00
frtabu
deb2a453c6 angular update for chart lib 2022-07-25 14:19:49 +02:00
frtabu
5a08d8109c websrv softscope interface, implement data messages 2022-07-22 19:54:08 +02:00
frtabu
65c858757d scope implem going on 2022-07-11 20:11:07 +02:00
frtabu
55003cafd2 Merge branch 'websrv' of https://gitlab.eurecom.fr/oai/openairinterface5g into websrv 2022-07-11 00:53:53 +02:00
frtabu
57a7488e85 Fix modifiable string bug and minor GUI update 2022-07-11 00:38:08 +02:00
yacine nokia
da85cf5183 Merge branch 'websrv' of gitlab.eurecom.fr:oai/openairinterface5g into websrv 2022-07-09 20:12:32 +02:00
yacine nokia
32a6dd85c2 fix string issue 2022-07-09 20:12:15 +02:00
frtabu
d9216265dc Merge branch 'websrv' of https://gitlab.eurecom.fr/oai/openairinterface5g into websrv
after rebase onto develop.
2022-07-08 20:00:53 +02:00
yacine nokia
99ecd83133 firefox debugger 2022-07-08 12:28:14 +02:00
frtabu
c4958e50e8 vertical scroll bar in grid tile 2022-07-08 12:19:07 +02:00
frtabu
7b16f7e863 Fix build error when libulfius not found (remove REQUIRED keyword in CMakelist) 2022-07-08 12:17:44 +02:00
El Mghazli Yacine
e0c7980df5 websrv working 2022-07-08 12:17:44 +02:00
frtabu
4b002029fb Remove telnet server dependency 2022-07-08 12:17:44 +02:00
frtabu
27d626dc48 exclude authentication code from websrv.c to workaround ubuntu18 compilation Pb 2022-07-08 12:17:44 +02:00
frtabu
4fa9e2b39b merge channel algo validation frontend and implement simuType variable type in backend - doesn't work and breaks modifiable string which are no more modifiable 2022-07-08 12:17:44 +02:00
El Mghazli Yacine
fb5c768159 predefs$ 2022-07-08 12:13:24 +02:00
El Mghazli Yacine
0966ceb70b predefs$ 2022-07-08 12:12:28 +02:00
El Mghazli Yacine
b75d4f90b7 loglvl 2022-07-08 12:07:09 +02:00
El Mghazli Yacine
8cbe53b82b paramCtrl 2022-07-08 12:03:30 +02:00
El Mghazli Yacine
13e17339d3 removed paramFC 2022-07-08 11:53:57 +02:00
El Mghazli Yacine
6d457fcb56 removed paramFC 2022-07-08 11:47:22 +02:00
yacine nokia
748d4cb49a localhost dev env 2022-07-08 11:46:16 +02:00
El Mghazli Yacine
1e77b753ff fixed table set 2022-07-08 11:33:50 +02:00
El Mghazli Yacine
2964ef7e3e paramCtrl 2022-07-08 11:33:50 +02:00
El Mghazli Yacine
7f69632bbb removed paramFC 2022-07-08 11:33:50 +02:00
frtabu
17af1562a8 scope implem ongoing.. 2022-07-08 11:33:50 +02:00
frtabu
c3378c7f84 Scope implem going on , front and back 2022-07-08 11:33:50 +02:00
El Mghazli Yacine
38dca6387f cleanup api (details) 2022-07-08 11:33:50 +02:00
frtabu
4a42ff54df log level validation , backend implem 2022-07-08 11:33:50 +02:00
El Mghazli Yacine
22d4495c20 !!!! major refactoring !!!! 2022-07-08 11:33:50 +02:00
frtabu
3b93a9c5cb minor fixes in scope frontend/backend 2022-07-08 11:33:50 +02:00
frtabu
6407df90e2 websocket binary message and scope interface 2022-07-08 11:33:50 +02:00
frtabu
d75da26833 start implem websocket interface with frontend 2022-07-08 11:33:50 +02:00
El Mghazli Yacine
b0f0106cc7 better rows with pristine 2022-07-08 11:33:50 +02:00
El Mghazli Yacine
2690cbd08e ws server address 2022-07-08 11:33:50 +02:00
El Mghazli Yacine
868f9d9042 ng serve OK 2022-07-08 11:33:50 +02:00
El Mghazli Yacine
ad0dcfe287 ng serve OK 2022-07-08 11:33:50 +02:00
El Mghazli Yacine
7bd44da548 initial commit - build NOK 2022-07-08 11:33:50 +02:00
El Mghazli Yacine
185e5934b7 pristine 2022-07-08 11:33:50 +02:00
frtabu
24802ee18b updatable result (frontend) 2022-07-08 11:33:50 +02:00
frtabu
8916cfdfd2 implement updatte results in frontend, ongoing 2022-07-08 11:33:49 +02:00
frtabu
b135c1dd8f start fixing https implem in backend 2022-07-08 11:33:49 +02:00
frtabu
6e61c8a05a Add access to parsed config file 2022-07-08 11:33:49 +02:00
frtabu
c957882da8 backend and frontend implementation of downloading config file 2022-07-08 11:33:49 +02:00
frtabu
7404ad7a5c commands with params... working now 2022-07-08 11:33:49 +02:00
frtabu
4e8fa01a25 frontend dialog test 2022-07-08 11:33:49 +02:00
frtabu
ec0d3fde1c command with parameters... 2022-07-08 11:33:49 +02:00
frtabu
58618be544 on going with command with parameter 2022-07-08 11:33:49 +02:00
frtabu
7e7c097942 going on with command parameter 2022-07-08 11:33:49 +02:00
frtabu
94796957e8 commands with a parameter, going on.... 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
55d9200a48 trying questions 2022-07-08 11:33:49 +02:00
frtabu
d815edebe7 command with parameter going on 2022-07-08 11:33:49 +02:00
frtabu
f1d18b4edb command with param implementation in frontend, beginning 2022-07-08 11:33:49 +02:00
frtabu
06355e9cf1 rontend Question Dialog 2022-07-08 11:33:49 +02:00
frtabu
9bcf269856 Implementing commands with question like when modifying a channel model (ask which model) 2022-07-08 11:33:49 +02:00
frtabu
9bfcbe7faa implemebtation of softmodem threads commands 2022-07-08 11:33:49 +02:00
frtabu
fa92bf1a79 Dialog enhancements in frontend 2022-07-08 11:33:49 +02:00
frtabu
a348ada211 fix log modifications in backend, allow Dialog resize and move 2022-07-08 11:33:49 +02:00
frtabu
e0f76e6ca6 implement log options modif in backend 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
351f069adc window.location.port 2022-07-08 11:33:49 +02:00
frtabu
64f84cdd6a implementation of command modifying module parameters, step 1, decode json sent by fronthaul 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
8bd1b3b53a boolean as string for setRow 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
2aef88960f http://' + window.location.hostname + ':8090' 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
51d6fd7ec2 v1 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
f2d43636bf better fields and buttons 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
dbeda2d33f table disapears when no rows 2022-07-08 11:33:49 +02:00
frtabu
5d9f91997e Modify status info , add redir log commands 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
210429f388 set disabled if all row is not modifiable 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
dc40e0dca1 fixed cmd results tile now disapears 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
fe8f418e7a fixed boolean enabled 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
98de3b9049 fixed 2 posts 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
55d83f6045 button and readonly 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
6882b63991 fixed rawIndex 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
45896f2583 row.paramsFA.controls 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
ed6b13c759 IRow2 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
eee4d3fc07 setRow$ in API 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
b8f64823bf setParam$ 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
d37952f94d setParam$ 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
12e2eded38 confirm button ok 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
d910e92669 height 80% display 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
9e2f2db88c table OK 2022-07-08 11:33:49 +02:00
frtabu
85929b7933 fix empty array format 2022-07-08 11:33:49 +02:00
frtabu
5673a31814 fix new IRespCmd json format in backend 2022-07-08 11:33:49 +02:00
frtabu
7da80421ff table response implementation fix (backend) 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
35e4f29cf6 display fix 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
c1abfcfc50 confirm dialog 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
b2e8b78a01 dynamic table WIP 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
53e160728a cleanup rowCtrl 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
522f2ad140 dynamic tables 2022-07-08 11:33:49 +02:00
frtabu
4a26a44ee0 Table Response implementation in backend 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
59722d1a91 confirm dialog before sending cmd 2022-07-08 11:33:49 +02:00
frtabu
218a524cd2 display array fix 2022-07-08 11:33:49 +02:00
frtabu
f44f105cb3 more commands implementation in backend 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
32ff4b33f1 "prod": "ng serve --configuration=production" 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
bf0492ba87 table display 2022-07-08 11:33:49 +02:00
frtabu
7a9c13422a fix json format in log response 2022-07-08 11:33:49 +02:00
frtabu
3e3b33e94c test table reslt with log command 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
58ae227080 tables and new API with IColumn and IRow 2022-07-08 11:33:49 +02:00
frtabu
81a671a4f3 implementation of log command 2022-07-08 11:33:49 +02:00
frtabu
039c6d24bc Adapt command response structure 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
ec80ef106f details 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
60f17d4d45 ilogs 2022-07-08 11:33:49 +02:00
frtabu
5e86379be4 implement mechanism for simple string response 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
62789c5161 openDialog 2022-07-08 11:33:49 +02:00
frtabu
bede89b233 command processing implementation 2022-07-08 11:33:49 +02:00
frtabu
4a29496988 better variable type processing 2022-07-08 11:33:49 +02:00
frtabu
a809a8c722 modify telnet server structure to support command execution from the webserver 2022-07-08 11:33:49 +02:00
frtabu
ad3ce4ddb6 json boolean fix 2022-07-08 11:33:49 +02:00
frtabu
72df29f225 fix backend commands response body 2022-07-08 11:33:49 +02:00
frtabu
42ab0247bf backend implementation of variable modifications 2022-07-08 11:33:49 +02:00
frtabu
a439a0cce0 Add OPTIONS http method support, used before POST by frontend. 2022-07-08 11:33:49 +02:00
frtabu
f7c9075337 change endpoint registration mechanism 2022-07-08 11:33:49 +02:00
frtabu
15fc3ccce0 More debug messages in backend 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
f2500d9297 fixed cmds display 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
72bc9baf2e fixed API variables calls 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
6cef7a8f67 APIv2.2 2022-07-08 11:33:49 +02:00
Raymond Knopp
b32524dd74 Adapt to new frontend interface 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
a45dd3b8bc yacine s'adapte grace a sa flaxibilité legendaire 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
a981bb382b APIv2.2 2022-07-08 11:33:49 +02:00
frtabu
f17aba0f5e config module fixes and websrv modif 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
ca0398c5bc APIv2.1 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
ab6bb2534e webserv APIv2 (frontend part) 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
c875ce639c working with first API version 2022-07-08 11:33:49 +02:00
frtabu
23a1d8d9bc fix config file generation to sip command line only options 2022-07-08 11:33:49 +02:00
frtabu
c0f6b39da5 config module enhancement,step 2 2022-07-08 11:33:49 +02:00
frtabu
095be9fe6a config module enhancement, next step 2022-07-08 11:33:49 +02:00
frtabu
82ebc9fa7b config module enhancement (dump of running config): start implem. 2022-07-08 11:33:49 +02:00
Raymond Knopp
526720cb24 add websrv as optional lib and frontend as independant target in oai build 2022-07-08 11:33:49 +02:00
frtabu
433dbcd41a websrv backend implementation next step 2022-07-08 11:33:49 +02:00
frtabu
20b3210062 json format sync with frontend 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
b959af152d backend env 2022-07-08 11:33:49 +02:00
frtabu
e5335a0188 Tested init with front end 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
1387bdc16e api first test 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
d2dfe830e7 display ok 2022-07-08 11:33:49 +02:00
frtabu
3da8b0e5eb Add https support and front-end url support 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
de0e075381 rudiments ok 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
826b405d47 ng build OK 2022-07-08 11:33:49 +02:00
frtabu
d761f67bcf go on websrv implem 2022-07-08 11:33:49 +02:00
frtabu
975835804d Initial implem web interface for telnet server 2022-07-08 11:33:49 +02:00
El Mghazli Yacine
b467fd2c68 updated tslib 2022-07-08 11:30:26 +02:00
El Mghazli Yacine
daec2ba3ea initial commit 2022-07-08 11:30:26 +02:00
El Mghazli Yacine
e705c88dd5 cleanup 2022-07-08 11:30:26 +02:00
El Mghazli Yacine
7121bf6d05 updated angular successfully 2022-07-08 11:30:26 +02:00
El Mghazli Yacine
1228608cc2 ng update 2022-07-08 11:30:26 +02:00
El Mghazli Yacine
47ac986d8c ng update 2022-07-08 11:30:26 +02:00
El Mghazli Yacine
8ea378eea8 ngx initial commit before upgrade 2022-07-08 11:30:26 +02:00
El Mghazli Yacine
2c688f230f Merge branch 'websrv' of gitlab.eurecom.fr:oai/openairinterface5g into websrv 2022-07-08 10:49:03 +02:00
El Mghazli Yacine
cbec64c28f websrv working 2022-07-08 10:49:00 +02:00
frtabu
1c352f3138 vertical scroll bar in grid tile 2022-07-08 01:43:00 +02:00
frtabu
5e964d660f Fix build error when libulfius not found (remove REQUIRED keyword in CMakelist) 2022-07-07 19:52:13 +02:00
frtabu
2e66c87f4d Remove telnet server dependency 2022-07-06 11:49:29 +02:00
frtabu
82a771dd61 exclude authentication code from websrv.c to workaround ubuntu18 compilation Pb 2022-07-06 10:13:45 +02:00
frtabu
c99f52207d merge channel algo validation frontend and implement simuType variable type in backend - doesn't work and breaks modifiable string which are no more modifiable 2022-07-05 13:35:05 +02:00
El Mghazli Yacine
3555edff76 Merge branch 'validators' of gitlab.eurecom.fr:oai/openairinterface5g into validators 2022-07-04 17:02:21 +02:00
El Mghazli Yacine
6723fc531b predefs$ 2022-07-04 17:02:11 +02:00
El Mghazli Yacine
26cc637d1b predefs$ 2022-07-04 16:57:42 +02:00
frtabu
e63f1454b3 Merge branch 'websrv' of https://gitlab.eurecom.fr/oai/openairinterface5g into websrv 2022-07-04 16:45:53 +02:00
El Mghazli Yacine
c69d980613 loglvl 2022-07-01 15:02:18 +02:00
frtabu
4c4917442f Merge branch 'websrv' of https://gitlab.eurecom.fr/oai/openairinterface5g into websrv 2022-07-01 14:14:42 +02:00
frtabu
bfb06225a5 Merge branch 'websrv' of https://gitlab.eurecom.fr/oai/openairinterface5g into websrv 2022-07-01 14:13:33 +02:00
El Mghazli Yacine
d62892ff8a Merge branch 'validators' of gitlab.eurecom.fr:oai/openairinterface5g into validators 2022-07-01 11:51:50 +02:00
El Mghazli Yacine
78ed7d4570 fixed table set 2022-07-01 11:47:57 +02:00
El Mghazli Yacine
d969a124ee paramCtrl 2022-06-30 17:09:45 +02:00
El Mghazli Yacine
b68e614850 removed paramFC 2022-06-30 17:09:45 +02:00
El Mghazli Yacine
17a4dea3e1 paramCtrl 2022-06-30 16:45:55 +02:00
frtabu
43130b687e scope implem ongoing.. 2022-06-30 00:21:27 +02:00
frtabu
fdf2728d02 Scope implem going on , front and back 2022-06-29 23:07:25 +02:00
frtabu
2783acb933 Scope implem going on , front and back 2022-06-29 20:22:16 +02:00
El Mghazli Yacine
e78e720a46 Merge branch 'validators' of gitlab.eurecom.fr:oai/openairinterface5g into validators 2022-06-28 12:13:49 +02:00
El Mghazli Yacine
2d9bac6359 removed paramFC 2022-06-28 12:13:39 +02:00
El Mghazli Yacine
2ebb462a8e removed paramFC 2022-06-28 12:10:07 +02:00
frtabu
8ea5fd7894 Merge branch 'websrv' of https://gitlab.eurecom.fr/oai/openairinterface5g into websrv 2022-06-28 11:38:36 +02:00
frtabu
c939a9cdf5 log level validation , backend implem 2022-06-28 11:35:45 +02:00
El Mghazli Yacine
31c9a03e83 cleanup api (details) 2022-06-28 11:19:28 +02:00
El Mghazli Yacine
b7b41fefc0 !!!! major refactoring !!!! 2022-06-27 18:30:54 +02:00
frtabu
29c5129b0a minor fixes in scope frontend/backend 2022-06-27 00:34:03 +02:00
frtabu
3b0f050a33 websocket binary message and scope interface 2022-06-26 02:11:03 +02:00
frtabu
dc6dd67827 start implem websocket interface with frontend 2022-06-24 19:42:33 +02:00
El Mghazli Yacine
9f10bfebf2 better rows with pristine 2022-06-23 16:32:37 +02:00
El Mghazli Yacine
b34a44a4f9 ws server address 2022-06-23 14:40:53 +02:00
El Mghazli Yacine
0b7201244a ng serve OK 2022-06-22 23:06:18 +02:00
El Mghazli Yacine
28bd9ea4bc ng serve OK 2022-06-22 23:06:05 +02:00
El Mghazli Yacine
044ed48fc7 initial commit - build NOK 2022-06-22 19:39:04 +02:00
El Mghazli Yacine
1b071df0bc pristine 2022-06-22 10:13:05 +02:00
frtabu
45967c8b77 updatable result (frontend) 2022-06-17 18:04:55 +02:00
frtabu
fc758069fb implement updatte results in frontend, ongoing 2022-06-17 18:04:55 +02:00
frtabu
9be7b12654 start fixing https implem in backend 2022-06-17 18:04:55 +02:00
frtabu
160abd88cc Add access to parsed config file 2022-06-17 18:04:55 +02:00
frtabu
e2eebc7a28 backend and frontend implementation of downloading config file 2022-06-17 18:04:55 +02:00
frtabu
a52adaa95e commands with params... working now 2022-06-17 18:04:55 +02:00
frtabu
ced3078e30 frontend dialog test 2022-06-17 18:04:55 +02:00
frtabu
b7d2840e04 command with parameters... 2022-06-17 18:04:55 +02:00
frtabu
0a88f1a2d8 on going with command with parameter 2022-06-17 18:04:55 +02:00
frtabu
4855b4102d going on with command parameter 2022-06-17 18:04:55 +02:00
frtabu
2dac45f1a3 commands with a parameter, going on.... 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
e73acbc776 trying questions 2022-06-17 18:04:55 +02:00
frtabu
21d0fdb92a command with parameter going on 2022-06-17 18:04:55 +02:00
frtabu
68e2cb7800 command with param implementation in frontend, beginning 2022-06-17 18:04:55 +02:00
frtabu
de24e2da1e rontend Question Dialog 2022-06-17 18:04:55 +02:00
frtabu
bc4eb38eec Implementing commands with question like when modifying a channel model (ask which model) 2022-06-17 18:04:55 +02:00
frtabu
8600b7815d implemebtation of softmodem threads commands 2022-06-17 18:04:55 +02:00
frtabu
8bee5da854 Dialog enhancements in frontend 2022-06-17 18:04:55 +02:00
frtabu
40bfb7b07a fix log modifications in backend, allow Dialog resize and move 2022-06-17 18:04:55 +02:00
frtabu
46c1dd511a implement log options modif in backend 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
d9cd942f3b window.location.port 2022-06-17 18:04:55 +02:00
frtabu
147fb74085 implementation of command modifying module parameters, step 1, decode json sent by fronthaul 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
7546e614c7 boolean as string for setRow 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
9a58bae112 http://' + window.location.hostname + ':8090' 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
9e99113aa1 v1 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
ea4d82bc31 better fields and buttons 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
94efccba21 table disapears when no rows 2022-06-17 18:04:55 +02:00
frtabu
28c688b16f Modify status info , add redir log commands 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
6d991456a9 set disabled if all row is not modifiable 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
bb840b7f7e fixed cmd results tile now disapears 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
9fecc570f8 fixed boolean enabled 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
1a5da9a1aa fixed 2 posts 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
adb13cd4d4 button and readonly 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
9f8ebe86f4 fixed rawIndex 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
46329a4f2d row.paramsFA.controls 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
1f4dcc9fda IRow2 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
7dda3dde08 setRow$ in API 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
e108aaa7db setParam$ 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
7da12ca861 setParam$ 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
2b987e8e00 confirm button ok 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
c2106e49d8 height 80% display 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
0b473838fa table OK 2022-06-17 18:04:55 +02:00
frtabu
3e15c59e00 fix empty array format 2022-06-17 18:04:55 +02:00
frtabu
9aa6e61197 fix new IRespCmd json format in backend 2022-06-17 18:04:55 +02:00
frtabu
4c58063268 table response implementation fix (backend) 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
25f1b46647 display fix 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
68ae77a79e confirm dialog 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
a4ad969553 dynamic table WIP 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
415e9e8495 cleanup rowCtrl 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
5a5d8670ea dynamic tables 2022-06-17 18:04:55 +02:00
frtabu
9e20b2464f Table Response implementation in backend 2022-06-17 18:04:55 +02:00
El Mghazli Yacine
ea5c125dbd confirm dialog before sending cmd 2022-06-17 18:04:55 +02:00
frtabu
66646cd17a display array fix 2022-06-17 18:04:54 +02:00
frtabu
81b0df6f1d more commands implementation in backend 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
e9dadf1706 "prod": "ng serve --configuration=production" 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
f9e45856fc table display 2022-06-17 18:04:54 +02:00
frtabu
0f9fcb3f0a fix json format in log response 2022-06-17 18:04:54 +02:00
frtabu
17af664374 test table reslt with log command 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
da3bda8bbb tables and new API with IColumn and IRow 2022-06-17 18:04:54 +02:00
frtabu
a5d66d1f4a implementation of log command 2022-06-17 18:04:54 +02:00
frtabu
4b289a53df Adapt command response structure 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
d5eb164a20 details 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
fec25da5e7 ilogs 2022-06-17 18:04:54 +02:00
frtabu
4ec7d0a824 implement mechanism for simple string response 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
a873c0080a openDialog 2022-06-17 18:04:54 +02:00
frtabu
06f905853a command processing implementation 2022-06-17 18:04:54 +02:00
frtabu
179b8f57b3 better variable type processing 2022-06-17 18:04:54 +02:00
frtabu
9b1e5db390 modify telnet server structure to support command execution from the webserver 2022-06-17 18:04:54 +02:00
frtabu
32e5f13002 json boolean fix 2022-06-17 18:04:54 +02:00
frtabu
4497800fe1 fix backend commands response body 2022-06-17 18:04:54 +02:00
frtabu
6846459ea5 backend implementation of variable modifications 2022-06-17 18:04:54 +02:00
frtabu
f7dafc4771 Add OPTIONS http method support, used before POST by frontend. 2022-06-17 18:04:54 +02:00
frtabu
ee11159d5d change endpoint registration mechanism 2022-06-17 18:04:54 +02:00
frtabu
c0a3b39688 More debug messages in backend 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
679dcae557 fixed cmds display 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
b14c4b2aa6 fixed API variables calls 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
92c534dcaa APIv2.2 2022-06-17 18:04:54 +02:00
Raymond Knopp
07fb404e33 Adapt to new frontend interface 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
a010b4d89f yacine s'adapte grace a sa flaxibilité legendaire 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
b340427363 APIv2.2 2022-06-17 18:04:54 +02:00
frtabu
654a2b7f63 config module fixes and websrv modif 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
b0cb9b8615 APIv2.1 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
9bb75d82cf webserv APIv2 (frontend part) 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
535239a5ae working with first API version 2022-06-17 18:04:54 +02:00
frtabu
89b2a966ba fix config file generation to sip command line only options 2022-06-17 18:04:54 +02:00
frtabu
29e2a542dd config module enhancement,step 2 2022-06-17 18:04:54 +02:00
frtabu
98a736c9d7 config module enhancement, next step 2022-06-17 18:04:54 +02:00
frtabu
8404af8d18 config module enhancement (dump of running config): start implem. 2022-06-17 18:04:54 +02:00
Raymond Knopp
7572d8cb46 add websrv as optional lib and frontend as independant target in oai build 2022-06-17 18:04:54 +02:00
frtabu
db43c3e12e websrv backend implementation next step 2022-06-17 18:04:54 +02:00
frtabu
ea066dc0dc json format sync with frontend 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
c0037b1f98 backend env 2022-06-17 18:04:54 +02:00
frtabu
29aa6407be Tested init with front end 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
f6d4c77e75 api first test 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
c0e019efbd display ok 2022-06-17 18:04:54 +02:00
frtabu
ded656208d Add https support and front-end url support 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
9c36a8ebc2 rudiments ok 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
1dda299dc3 ng build OK 2022-06-17 18:04:54 +02:00
frtabu
c8d1b99e42 go on websrv implem 2022-06-17 18:04:54 +02:00
frtabu
b274f3c8d3 Initial implem web interface for telnet server 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
1d7775875e updated tslib 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
3a560604ec initial commit 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
f677cc34b3 cleanup 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
cdab201890 updated angular successfully 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
20186aec26 ng update 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
79fc8623e3 ng update 2022-06-17 18:04:54 +02:00
El Mghazli Yacine
c104b12302 ngx initial commit before upgrade 2022-06-17 18:04:54 +02:00
420 changed files with 165559 additions and 11324 deletions

31
.vscode/launch.json vendored
View File

@@ -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
}
]
}
]
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,42 +0,0 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>l2sim-4glte-proxy-build</htmlTabRef>
<htmlTabName>Build L2sim proxy image</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
000001
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>Build_Proxy</class>
<desc>Build L2sim Proxy Image</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
<proxy_commit>56cfdc0</proxy_commit>
</testCase>
</testCaseList>

View File

@@ -1,135 +0,0 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>l2sim-4glte-tdd</htmlTabRef>
<htmlTabName>Testing 4G LTE L2 sim - FDD eNB</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<repeatCount>2</repeatCount>
<TestCaseRequestedList>
100001
000000
000001
000002
000003
000011
200000
020001
020002
030011
030012
200001
100001
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000000">
<class>DeployGenObject</class>
<desc>Deploy Cassandra Database</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
<services>cassandra db_init</services>
<nb_healthy>1</nb_healthy>
</testCase>
<testCase id="000001">
<class>DeployGenObject</class>
<desc>Deploy OAI 4G CoreNetwork</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
<services>oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen</services>
<nb_healthy>7</nb_healthy>
</testCase>
<testCase id="000002">
<class>DeployGenObject</class>
<desc>Deploy OAI 4G eNB L2 sim</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
<services>oai_enb</services>
<nb_healthy>8</nb_healthy>
</testCase>
<testCase id="000003">
<class>DeployGenObject</class>
<desc>Deploy OAI L2 sim 4G LTE-UE 1 and Proxy</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
<services>proxy oai_ue1</services>
<nb_healthy>10</nb_healthy>
</testCase>
<testCase id="000011">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>
<testCase id="020001">
<class>PingFromContainer</class>
<desc>Ping trf-gen from LTE-UE 1</desc>
<container_name>l2sim4g-oai-lte-ue1</container_name>
<options>-I oaitun_ue1 -c 20 192.168.61.11</options>
<loss_threshold>0</loss_threshold>
</testCase>
<testCase id="020002">
<class>PingFromContainer</class>
<desc>Ping LTE-UE 1 from trf-gen</desc>
<container_name>l2sim4g-trf-gen</container_name>
<options>-c 20 12.0.0.2</options>
<loss_threshold>0</loss_threshold>
</testCase>
<testCase id="030011">
<class>IperfFromContainer</class>
<desc>Iperf UDP Downlink</desc>
<server_container_name>l2sim4g-oai-lte-ue1</server_container_name>
<client_container_name>l2sim4g-trf-gen</client_container_name>
<server_options>-B 12.0.0.2 -u -i 1 -s</server_options>
<client_options>-c 12.0.0.2 -u -i 1 -t 30 -b 1M</client_options>
</testCase>
<testCase id="030012">
<class>IperfFromContainer</class>
<desc>Iperf UDP Uplink</desc>
<server_container_name>l2sim4g-trf-gen</server_container_name>
<client_container_name>l2sim4g-oai-lte-ue1</client_container_name>
<server_options>-u -i 1 -s</server_options>
<client_options>-B 12.0.0.2 -c 192.168.61.11 -u -i 1 -t 30 -b 3M</client_options>
</testCase>
<testCase id="100001">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 4G stack</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
</testCase>
<testCase id="200000">
<class>StatsFromGenObject</class>
<desc>Statistics before Traffic Test</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
</testCase>
<testCase id="200001">
<class>StatsFromGenObject</class>
<desc>Statistics after Traffic Test</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
</testCase>
</testCaseList>

View File

@@ -1,38 +0,0 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>l2sim-4glte-down</htmlTabRef>
<htmlTabName>CleanUp 4G L2 sim - FDD eNB</htmlTabName>
<htmlTabIcon>trash</htmlTabIcon>
<TestCaseRequestedList>
100002
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="100002">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 4G stack</desc>
<yaml_path>yaml_files/4g_l2sim_fdd</yaml_path>
</testCase>
</testCaseList>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,42 +0,0 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>l2sim-4glte-5gnr-proxy-build</htmlTabRef>
<htmlTabName>Build L2sim proxy image</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
000001
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>Build_Proxy</class>
<desc>Build L2sim Proxy Image</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
<proxy_commit>56cfdc0</proxy_commit>
</testCase>
</testCaseList>

View File

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

View File

@@ -1,168 +0,0 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>TEST-SA-FR1-B200</htmlTabRef>
<htmlTabName>SA SanityCheck with QUECTEL</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
010002
030000
030101
000001
010000
000001
050000
050001
010002
000001
030201
</TestCaseRequestedList>
<!--
070001
070000
070002
050002
050003
-->
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010000">
<class>Initialize_UE</class>
<desc>Initialize Quectel</desc>
<id>idefix</id>
</testCase>
<testCase id="010002">
<class>Terminate_UE</class>
<desc>Terminate Quectel</desc>
<id>idefix</id>
</testCase>
<testCase id="030000">
<class>Copy_Image_to_Test</class>
<desc>Copy gNB image to test server</desc>
<image_name>oai-gnb</image_name>
<registry_svr_id>1</registry_svr_id>
<test_svr_id>0</test_svr_id>
</testCase>
<testCase id="030101">
<class>Deploy_Object</class>
<desc>Deploy gNB (TDD/Band78/40MHz/B200) in a container</desc>
<yaml_path>ci-scripts/yaml_files/sa_b200_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
</testCase>
<testCase id="050000">
<class>Ping</class>
<desc>Ping: 20pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>15</ping_rttavg_threshold>
</testCase>
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>15</ping_rttavg_threshold>
</testCase>
<testCase id="050002">
<class>Ping</class>
<desc>Ping: 20pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>15</ping_rttavg_threshold>
</testCase>
<testCase id="050003">
<class>Ping</class>
<desc>Ping: 100pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>15</ping_rttavg_threshold>
</testCase>
<testCase id="070000">
<class>Iperf</class>
<desc>iperf (DL/125Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 125M -t 60 -i 1 -fm</iperf_args>
<direction>DL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070001">
<class>Iperf</class>
<desc>iperf (UL/8Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 8M -t 60 -i 1 -fm</iperf_args>
<direction>UL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070002">
<class>Iperf</class>
<desc>iperf (BIDIR TCP)(10 sec)(single-ue profile)</desc>
<iperf_args>-t 10 --bidir</iperf_args>
<direction>BIDIR</direction>
<id>idefix</id>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="030201">
<class>Undeploy_Object</class>
<desc>Undeploy gNB</desc>
<yaml_path>ci-scripts/yaml_files/sa_b200_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
</testCaseList>

View File

@@ -1,42 +0,0 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>TEST-SA-FR1-B200-terminate</htmlTabRef>
<htmlTabName>SA tear-down in case of problem</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="030201">
<class>Undeploy_Object</class>
<desc>Undeploy gNB</desc>
<yaml_path>ci-scripts/yaml_files/sa_b200_gnb</yaml_path>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<image_tag>sa-test</image_tag>
</testCase>
</testCaseList>

View File

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

View File

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

View File

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

View File

@@ -1,37 +0,0 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>5gc-closure</htmlTabRef>
<htmlTabName>5GC-Closure</htmlTabName>
<htmlTabIcon>log-out</htmlTabIcon>
<TestCaseRequestedList>
060000
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="060000">
<class>Terminate_5GCN</class>
<desc>Terminate 5GC</desc>
</testCase>
</testCaseList>

View File

@@ -1,38 +0,0 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>5gc-start-tab</htmlTabRef>
<htmlTabName>5GC-Start</htmlTabName>
<htmlTabIcon>log-in</htmlTabIcon>
<TestCaseRequestedList>
000100
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="000100">
<class>Initialize_5GCN</class>
<desc>Initialize 5GC</desc>
</testCase>
</testCaseList>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -271,12 +271,6 @@ if (SANITIZE_ADDRESS)
# wrong in the pthread library, or something subtly wrong in this CMakeLists.txt. Use Ubuntu 20.04 instead.
endif ()
add_boolean_option(SANITIZE_UNDEFINED False "enable the undefined behavior sanitizer (UBSan)")
if (SANITIZE_UNDEFINED)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
endif ()
add_definitions("-DASN_DISABLE_OER_SUPPORT")
#########################
@@ -334,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)

View File

@@ -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"

View File

@@ -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

View File

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

View File

@@ -53,17 +53,13 @@ int parse_stringlist(paramdef_t *cfgoptions, char *val) {
}
free(tmpval);
AssertFatal(MAX_LIST_SIZE > numelt,
"This piece of code use fixed size arry of constant #define MAX_LIST_SIZE %d\n",
MAX_LIST_SIZE );
config_check_valptr(cfgoptions, sizeof(char*), numelt);
config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt);
cfgoptions->numelt=numelt;
atoken=strtok_r(val, ",",&tokctx);
for( int i=0; i<cfgoptions->numelt && atoken != NULL ; i++) {
snprintf(cfgoptions->strlistptr[i],DEFAULT_EXTRA_SZ,"%s",atoken);
config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(atoken)+1);
sprintf(cfgoptions->strlistptr[i],"%s",atoken);
printf_params("[LIBCONFIG] %s[%i]: %s\n", cfgoptions->optname,i,cfgoptions->strlistptr[i]);
atoken=strtok_r(NULL, ",",&tokctx);
}
@@ -88,14 +84,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);

View File

@@ -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) {

View File

@@ -41,7 +41,7 @@
#include "common/config/config_paramdesc.h"
#include "common/utils/T/T.h"
#define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O <cfgmode>:P1:P2...
#define CONFIG_MAX_ALLOCATEDPTRS 2048 // maximum number of parameters that can be dynamicaly allocated in the config module
#define CONFIG_MAX_ALLOCATEDPTRS 1024 // maximum number of parameters that can be dynamicaly allocated in the config module
/* default values for configuration module parameters */
#define CONFIG_LIBCONFIGFILE "libconfig" // use libconfig file
@@ -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");

View File

@@ -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;

View File

@@ -52,97 +52,59 @@ configmodule_interface_t *config_get_if(void) {
return cfgptr;
}
static int managed_ptr_sz(void* ptr) {
configmodule_interface_t * cfg=config_get_if();
AssertFatal(cfg->numptrs < CONFIG_MAX_ALLOCATEDPTRS,
"This code use fixed size array as #define CONFIG_MAX_ALLOCATEDPTRS %d\n",
CONFIG_MAX_ALLOCATEDPTRS);
int i;
pthread_mutex_lock(&cfg->memBlocks_mutex);
int numptrs=cfg->numptrs;
for (i=0; i<numptrs; i++ )
if (cfg->oneBlock[i].ptrs == ptr)
break;
pthread_mutex_unlock(&cfg->memBlocks_mutex);
if ( i == numptrs )
return -1;
else
return cfg->oneBlock[i].sz;
}
char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) {
if (ptr == NULL ) {
ptr = malloc(sizeof(char *));
void *config_allocate_new(int sz, bool autoFree) {
void *ptr = calloc(sz,1);
AssertFatal(ptr, "calloc fails\n");
configmodule_interface_t * cfg=config_get_if();
// add the memory piece in the managed memory pieces list
pthread_mutex_lock(&cfg->memBlocks_mutex);
int newBlockIdx=cfg->numptrs++;
oneBlock_t* tmp=&cfg->oneBlock[newBlockIdx];
tmp->ptrs = (char *)ptr;
tmp->ptrsAllocated = true;
tmp->sz=sz;
tmp->toFree=autoFree;
pthread_mutex_unlock(&cfg->memBlocks_mutex);
return ptr;
}
if (ptr != NULL) {
*ptr=NULL;
cfgoptions->strptr=ptr;
void config_check_valptr(paramdef_t *cfgoptions, int elt_sz, int nb_elt) {
const bool toFree=!(cfgoptions->paramflags & PARAMFLAG_NOFREE);
// let's see if the value has been read
// the datamodel is more difficult than it should be
// and it is not thread safe
if (cfgoptions->voidptr) {
int sz;
if ( cfgoptions-> type == TYPE_STRING)
sz=managed_ptr_sz(*cfgoptions->strptr);
else
sz=managed_ptr_sz(cfgoptions->voidptr);
if ( sz != -1 ) // the same variable pointer has been used!
cfgoptions->numelt=sz;
}
if (cfgoptions->voidptr != NULL
&& (cfgoptions->type == TYPE_INTARRAY
|| cfgoptions->type == TYPE_UINTARRAY
|| cfgoptions->type == TYPE_STRINGLIST )) {
int sz;
if ( cfgoptions->type == TYPE_STRING ||
cfgoptions->type == TYPE_STRINGLIST )
sz=managed_ptr_sz(*cfgoptions->strptr);
else
sz=managed_ptr_sz(cfgoptions->voidptr);
if ( sz != -1) {
CONFIG_PRINTF_ERROR("[CONFIG] %s NOT SUPPORTED not NULL pointer with array types", cfgoptions->optname);
return ;
}
}
if (cfgoptions->voidptr == NULL ) {
if (cfgoptions->type == TYPE_STRING) {
// difficult datamodel
cfgoptions->strptr = config_allocate_new(sizeof(*cfgoptions->strptr), toFree);
} else if ( cfgoptions->type == TYPE_STRINGLIST) {
AssertFatal(nb_elt<MAX_LIST_SIZE,
"This piece of code use fixed size arry of constant #define MAX_LIST_SIZE %d\n",
MAX_LIST_SIZE );
cfgoptions->strlistptr= config_allocate_new(sizeof(char*)*MAX_LIST_SIZE, toFree);
for (int i=0; i<MAX_LIST_SIZE; i++)
cfgoptions->strlistptr[i]= config_allocate_new(DEFAULT_EXTRA_SZ, toFree);
if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) {
config_get_if()->ptrs[config_get_if()->numptrs] = (char *)ptr;
config_get_if()->ptrsAllocated[config_get_if()->numptrs] = true;
config_get_if()->numptrs++;
}
} else {
if ( cfgoptions->type == TYPE_INTARRAY || cfgoptions->type == TYPE_UINTARRAY )
nb_elt=max(nb_elt, MAX_LIST_SIZE); // make room if the list is larger than the default one
cfgoptions->voidptr = config_allocate_new(elt_sz*nb_elt, toFree);
CONFIG_PRINTF_ERROR("[CONFIG] %s %d option %s, cannot allocate pointer: %s \n",
__FILE__, __LINE__, cfgoptions->optname, strerror(errno));
}
}
if (cfgoptions->type == TYPE_STRING && *cfgoptions->strptr == NULL) {
*cfgoptions->strptr = config_allocate_new(nb_elt+DEFAULT_EXTRA_SZ, toFree);
cfgoptions->numelt=nb_elt+DEFAULT_EXTRA_SZ;
printf_ptrs("[CONFIG] %s ptr: 0x%08lx requested size: %i\n",cfgoptions->optname,(uintptr_t)(ptr),length);
if(cfgoptions->numelt > 0 && PARAM_ISSCALAR(cfgoptions) ) { /* already allocated */
if (*ptr != NULL) {
return *ptr;
} else {
CONFIG_PRINTF_ERROR("[CONFIG] %s %d option %s, definition error: value pointer is NULL, declared as %i bytes allocated\n",
__FILE__, __LINE__,cfgoptions->optname, cfgoptions->numelt);
}
}
printf_ptrs("[CONFIG] %s ptr: %p requested size: elt_sz: %d, nb_elt: %d\n",cfgoptions->optname, cfgoptions->voidptr, elt_sz, nb_elt);
if (*ptr == NULL) {
// LTS: dummy fix, waiting Francois full fix in 4G branch
// the issue is we don't know at this point the size we will get
// for parmeters on the command line,
// The length sould probably managed, in a later version
// 100 is a very large value for a string parameter of today OAI
if (length<100)
length=100;
*ptr = malloc(length);
if ( *ptr != NULL) {
memset(*ptr,0,length);
if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) {
config_get_if()->ptrs[config_get_if()->numptrs] = *ptr;
config_get_if()->numptrs++;
}
} else {
CONFIG_PRINTF_ERROR("[CONFIG] %s %d malloc error\n",__FILE__, __LINE__);
}
}
return *ptr;
}
void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val) {
@@ -194,7 +156,7 @@ void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val) {
}
}
void config_assign_processedint(paramdef_t *cfgoption, int val) {
cfgoption->processedvalue = config_allocate_new(sizeof(int),!(cfgoption->paramflags & PARAMFLAG_NOFREE));
cfgoption->processedvalue = malloc(sizeof(int));
if ( cfgoption->processedvalue != NULL) {
*(cfgoption->processedvalue) = val;
@@ -210,7 +172,7 @@ int config_get_processedint(paramdef_t *cfgoption) {
ret=*(cfgoption->processedvalue);
free( cfgoption->processedvalue);
cfgoption->processedvalue=NULL;
printf_params("[CONFIG] %s: set from %s to %i\n",cfgoption->optname, *cfgoption->strptr, ret);
printf_params("[CONFIG] %s: set from %s to %i\n",cfgoption->optname, *(cfgoption->strptr), ret);
} else {
fprintf (stderr,"[CONFIG] %s %d %s has no processed integer availablle\n",__FILE__, __LINE__, cfgoption->optname);
ret=0;
@@ -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) {

View File

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

View File

@@ -29,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;

View File

@@ -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

View File

@@ -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;

View File

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

View File

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

View File

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

View File

@@ -1,71 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef LINEAR_ALLOC_H
#define LINEAR_ALLOC_H
#include <limits.h>
typedef unsigned int uid_t;
#define UID_LINEAR_ALLOCATOR_SIZE 1024
#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE (((UID_LINEAR_ALLOCATOR_SIZE/8)/sizeof(unsigned int)) + 1)
typedef struct uid_linear_allocator_s {
unsigned int bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE];
} uid_allocator_t;
static inline void uid_linear_allocator_init(uid_allocator_t *uia) {
memset(uia, 0, sizeof(uid_allocator_t));
}
static inline uid_t uid_linear_allocator_new(uid_allocator_t *uia) {
unsigned int bit_index = 1;
uid_t uid = 0;
for (unsigned int i = 0; i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE; i++) {
if (uia->bitmap[i] != UINT_MAX) {
bit_index = 1;
uid = 0;
while ((uia->bitmap[i] & bit_index) == bit_index) {
bit_index = bit_index << 1;
uid += 1;
}
uia->bitmap[i] |= bit_index;
return uid + (i*sizeof(unsigned int)*8);
}
}
return UINT_MAX;
}
static inline void uid_linear_allocator_free(uid_allocator_t *uia, uid_t uid) {
const unsigned int i = uid/sizeof(unsigned int)/8;
const unsigned int bit = uid % (sizeof(unsigned int) * 8);
const unsigned int value = ~(1 << bit);
if (i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE) {
uia->bitmap[i] &= value;
}
}
#endif /* LINEAR_ALLOC_H */

View File

@@ -1,56 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef UTILS_CONFIG_H_ASN1
#define UTILS_CONFIG_H_ASN1
// This is hard coded file name "config.h" and HAVE_CONFIG_H_ in asn1c skeletons
/*
* This file "config.h" will be used by asn1c if HAVE_CONFIG_H_ is defined and
* included. This logs asn1c encoder and decoder traces at execution time using
* the regular OAI logging system, i.e., LOG_I(ASN...);
*
* As it is very verbose, note that you can change the log level per module in
* source or in gdb, e.g., to only activate it for a short time.
*
* In code:
* ```
* set_log(ASN, OAI_INFO); // enable logging
* // do your encoding here
* set_log(ASN, OAI_ERR); // disable logging
* ```
*
* in gdb:
* ```
* gdb> p set_log(ASN, 1) // disable log, 1 == OAI_ERR
* gdb> p set_log(ASN, 5) // enable log, 5 == OAI_INFO
* ```
*/
#include "common/utils/LOG/log.h"
#if DEBUG_ASN1C
#define ASN_DEBUG(x...) do{ LOG_I(ASN,x);LOG_I(ASN,"\n"); } while(false)
#else
#define ASN_DEBUG(x...)
#endif
#endif /* UTILS_CONFIG_H_ASN1 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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;
}

View File

@@ -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

View File

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

View File

@@ -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")

View File

@@ -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},
};

View File

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

View File

@@ -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);

View File

@@ -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;

View File

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

View File

@@ -79,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 */

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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)

View 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)

View 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)

View 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