Compare commits

..

148 Commits

Author SHA1 Message Date
Ejaz Ahmed
b900b38448 Fixed merge conflicts 2024-08-02 02:14:49 +00:00
Ejaz Ahmed
35f918effd Created initial data structures for HARQ
Following changes are made:
1) Added essential data structures for HARQ
2) Moved gNB specific list functions to common file
3) Implemented preconfigurations for HARQ
4) Developed thread lock functions for NR_UE_SL_SCHED
5) Included header files for common moved functions in gNB code
2024-07-31 15:38:21 +00:00
Ejaz Ahmed
af49a21e95 Fixed order of SL UE phy params initializations 2024-07-31 15:37:55 +00:00
Ejaz Ahmed
093b212878 Fixed PSFCH issue in sci_payload in case of psfch_period zero 2024-07-31 15:37:18 +00:00
Ejaz Ahmed
b7e2cb3c93 Fixed line spacing 2024-07-31 15:37:00 +00:00
Ejaz Ahmed
396d8f6eb5 Added PSFCH in sci_payload 2024-07-31 15:36:42 +00:00
Ejaz Ahmed
12c1fb2069 Added code to send synchronization information from nearby to syncref
Added code to send synchronization information from nearby to syncref
within reserved bit of sci1. Syncref starts sending SLSCH once syncref
receives synchronization information.
2024-07-31 15:36:04 +00:00
Melissa
15f8f5aeea Merge branch 'episys/ea/nearby_ue_sync_ref_ue_indication' into 'episys/sl-eurecom2'
Added code to send sync information from nearby to syncref

See merge request aburger/openairinterface5g!277
2024-07-11 19:08:35 +00:00
Ejaz Ahmed
30ce40cf03 Fixed PSFCH issue in sci_payload in case of psfch_period zero 2024-07-10 19:51:30 +00:00
Ejaz Ahmed
23300df806 Fixed line spacing 2024-07-10 18:10:03 +00:00
Ejaz Ahmed
d9acb85bfa Added PSFCH in sci_payload 2024-07-10 17:58:43 +00:00
Ejaz Ahmed
ec7b44e6dd Added code to send synchronization information from nearby to syncref
Added code to send synchronization information from nearby to syncref
within reserved bit of sci1. Syncref starts sending SLSCH once syncref
receives synchronization information.
2024-07-08 19:58:36 +00:00
Ejaz Ahmed
07e1e3a968 Updated Tx params based on CQI report; Enabled support for MCS 1-16; Fixed SNR estimation
Following changes are made in this merge:

1) Updated Tx params based on received CQI report
2) Added SNR estimation based on signal power and noise power
3) Modified calculation of G to support MCS 1-16: G calculation method is modified in nr_get_G_SL to support different modulation orders, (Qm = 2 or 4), while keeping modulation order of 2 for dmrs, sci1 and sci2
4) In case of modulation order of 4, symbol 1 was crashing while reading rxF in nr_ulsch_16qam_llr() due to null pointer: fixed by introducing temp variable for recreating the symbol by inserting zeros on SCI1 and SCI2 REs, then complete symbol is passed for LLR computation along with a temporary LLR variable to collect the output of the LLR function for symbol 1. Next LLRs output related to Zero portions (SCI1 and SCI2 REs) of input is trimmed and passed only the LLR output of SLSCH REs to layer de-mapping function
5) Changed data rate computation for SCI2 based on fixed mcs (equivalent to mod_order of 2) at both rx and tx
6) Updated format of sci2 in nr_sci_size() on rx to make the sci2_payload_len same as on tx side
7) Replaced array index expression of a list, holding CQI data structure, with a variable
8) Moved CQI tables and functions from gNB files to common mac file so that both gNB and UE can access.
9) Tested on RFSIM with channel model AWGN noise power of -10 and ploss of 5
10) Cleaned code
2024-06-20 14:44:17 +00:00
Ejaz Ahmed
cc7c0b7968 Updated configurations; formatted logs 2024-06-20 14:25:36 +00:00
Melissa
076c83b6f2 Merge branch 'episys/ea/Fixed_SNR_and_MCS_1_16_issues' into 'episys/sl-eurecom2'
Enabled support for MCS 1-16; Fixed SNR estimation

See merge request aburger/openairinterface5g!276
2024-06-20 13:49:47 +00:00
Ejaz Ahmed
616f759661 Enabled support for MCS 1-16; Fixed SNR estimation 2024-06-20 13:49:47 +00:00
matilde.costa
61e62abb7f Added non-ip types to ip_traffic_type_t 2024-06-06 14:06:28 +00:00
Ejaz Ahmed
bb35caebed Fixed interface's name conflicts; restricted tx and rx operations in specific slots to fix an issue in USRP. 2024-06-06 13:56:59 +00:00
Melissa
1ff86924ff Merge branch 'episys/ea/usrp_debugging_psfch_csi_rs' into 'episys/sl-eurecom2'
Fixed interface's name conflicts; restricted tx and rx  operations in specific slots to fix an issue in USRP.

See merge request aburger/openairinterface5g!274
2024-05-30 22:38:11 +00:00
Ejaz Ahmed
e13e26759e Fixed interface's name conflicts; restricted tx and rx operations in specific slots to fix an issue in USRP. 2024-05-30 22:38:11 +00:00
matilde.costa
9588e10de0 Added non-ip types to ip_traffic_type_t 2024-05-17 14:58:54 +02:00
Ejaz Ahmed
885d5cd426 Updated logs & fixed spacing issues 2024-05-03 16:48:43 -07:00
Matilde Costa
6536425c4b rlc/pdcp threads with -1 affinity 2024-05-03 16:30:53 -07:00
Ejaz Ahmed
c7e08dffbe Added separate conf files for sync_ref & nearby ue; reverted tx scheduling conditions 2024-05-03 16:23:03 -07:00
Ejaz Ahmed
d2475e0dd6 Added separate conf files for sync_ref & nearby ue; reverted tx scheduling conditions 2024-05-01 16:46:52 -07:00
Ejaz Ahmed
c584baf9e1 Merge branch 'episys/sl-eurecom2' into eurecom/sl-eurecom2
Following modifications are included in this merge:
1) Implemented CSI reporting
2) Developed a measurement function of SNR and computed CQI based on
that
3) Simplified functions
4) Improved logging
5) Cleaned code
6) Fixed pointers issues
2024-04-30 10:52:54 -07:00
Melissa
6fcda3dcc0 Merge branch 'episys/ea/5g_sidelink_csi' into 'episys/sl-eurecom2'
Implemented measurement of SNR and computed CQI; Updated tx and rx code of CSI reporting

See merge request aburger/openairinterface5g!273
2024-04-30 15:50:27 +00:00
Ejaz Ahmed
3e81184deb Implemented measurement of SNR and computed CQI; Updated tx and rx code of CSI reporting 2024-04-30 15:50:27 +00:00
matilde.costa
4e2b8ddb92 fix nas_config in rrc sl preconfiguration for tun interface name 2024-04-25 15:39:15 +02:00
Matilde Costa
e8ca12049a rlc/pdcp threads with -1 affinity 2024-04-25 11:08:02 +02:00
Raymond Knopp
e9ff59611d check of PSFCH pointer in ue_scheduler 2024-04-28 21:42:27 +02:00
Raymond Knopp
fb6baf3f76 check for PSFCH pointer definition 2024-04-28 21:26:19 +02:00
Raymond Knopp
18e9694f31 more debugging removal 2024-04-22 16:19:47 +02:00
Raymond Knopp
183e029c8c removed some logging 2024-04-22 16:16:37 +02:00
Raymond Knopp
da97a8f016 debugging info 2024-04-22 15:47:24 +02:00
Raymond Knopp
1a470d5af6 logging for debug 2024-04-26 16:52:15 +02:00
Ejaz Ahmed
c4250dcd2b Fixed MAC subpdu header; fixed multiple interface issue 2024-04-19 11:56:47 -07:00
Ejaz Ahmed
4c4a667fd6 Bug fixed and freed memorey in case of no psfch; set two interfaces 2024-04-19 11:31:44 -07:00
Melissa
da6f3251f3 Merge branch 'episys/ea/fix_mac_subheaders_length_issue' into 'episys/sl-eurecom2'
Fixed NR_SLSCH_MAC_SUBHEADER processing issue

See merge request aburger/openairinterface5g!272
2024-04-19 16:53:50 +00:00
Raymond Knopp
c534570eec added srcid to nas_config for SL 2024-04-19 16:27:32 +02:00
Raymond Knopp
9642a70e6d testing and bugfixing 2024-04-19 16:10:35 +02:00
Raymond Knopp
1c84699e00 handled freeing of PSFCH information in case PSFCH_Period = 0 2024-04-23 06:07:18 +02:00
Ejaz Ahmed
9d8db83ebd Fixed spacing 2024-04-18 16:11:54 -07:00
Ejaz Ahmed
9ceb3ddf93 Merge branch 'episys/sl-eurecom2' into episys/ea/fix_mac_subheaders_length_issue 2024-04-18 16:08:07 -07:00
Melissa
289991b0fe Merge branch 'episys/ea/fix_errors_with_disabled_psfch' into 'episys/sl-eurecom2'
Enabled No PSFCH Support

See merge request aburger/openairinterface5g!271
2024-04-18 22:21:44 +00:00
Ejaz Ahmed
38a43f3be6 Updated comment 2024-04-18 13:06:40 -07:00
Ejaz Ahmed
6fc72eae0f Reverted the debugging logs 2024-04-18 13:00:58 -07:00
Ejaz Ahmed
14420f24cb Additional conditions on rx csi-rs scheduling 2024-04-18 11:59:50 -07:00
Ejaz Ahmed
53aa746075 Fixing errors in case of 12 PSSCH symbols and 3 PSCCH channels 2024-04-17 19:50:15 -07:00
Ejaz Ahmed
4e10e4fa2c Fixed MAC subPDU header length issue 2024-04-17 11:59:34 -07:00
Ejaz Ahmed
9879c13cd4 Added option in conf file to activate/deactivate csi-rs 2024-04-17 10:36:00 -07:00
Ejaz Ahmed
63454cebf8 Added option in conf file to activate/deactivate csi-rs 2024-04-17 10:30:31 -07:00
Ejaz Ahmed
813b600305 Implemented CSI-RS transmission and reception. 2024-04-16 19:26:01 -07:00
Ejaz Ahmed
9f9dadf621 Replaced slots per frame variable to use appropriate one 2024-04-16 19:25:23 -07:00
Melissa
bb13bfa195 Merge branch 'episys/ea/5g_sidelink_csi_rs' into 'episys/sl-eurecom2'
Implemented CSI-RS transmission and reception.

See merge request aburger/openairinterface5g!270
2024-04-16 22:43:25 +00:00
Ejaz Ahmed
ee7244ca05 Implemented CSI-RS transmission and reception. 2024-04-16 22:43:25 +00:00
Ejaz Ahmed
05604174e0 Replaced slots per frame variable to use appropriate one 2024-03-19 12:22:35 -07:00
Ejaz Ahmed
cbcd09cbca Merge branch 'episys/ea/mac_headers_validation' into episys/sl-eurecom2 2024-02-23 08:35:42 -08:00
Ejaz Ahmed
4af8be50bd Added condition to check remaining buffer before creating MAC CE 2024-02-23 08:34:43 -08:00
Ejaz Ahmed
ef9f804da7 Adjusted loop execution to fix muliple SDUs placement before MAC CEs and padding 2024-02-22 14:30:41 -08:00
Ejaz Ahmed
a465e39bb9 Fixed issue with multiple SDUs placement before MAC CEs 2024-02-22 14:14:56 -08:00
Melissa
3370570ecd Merge branch 'episys/ea/mac_headers_validation' into 'episys/sl-eurecom2'
Added SLSCH MAC sub-header, updated MAC sub-headers based on spec. 38321

See merge request aburger/openairinterface5g!269
2024-02-22 00:22:39 +00:00
Ejaz Ahmed
29b74e7410 Added SLSCH MAC sub-header, updated MAC sub-headers based on spec. 38321 2024-02-22 00:22:39 +00:00
Ejaz Ahmed
3fa03965a1 reverted some changes; added sec label, modified variable name 2024-02-21 11:49:31 -08:00
Ejaz Ahmed
d7b1a78e71 Merge branch 'episys/sl-eurecom2' into episys/ea/mac_headers_validation
Following changes are made:
1) Added instructions in rfsim README.md for running
rfsimulator with updated sl_preconfiguration.conf location
2024-02-21 11:32:25 -08:00
Ejaz Ahmed
a2e75e10d3 Merge branch 'eurecom/sl-eurecom2' into episys/sl-eurecom2 2024-02-21 11:30:54 -08:00
Ejaz Ahmed
714629c26f Added SLSCH MAC subheader, updated MAC subheaders based on spec. 38321
Following changes are made:
1) Added SLSCH MAC subheader
2) Validated MAC SDU subheader
3) Added SL_BSR subheader
4) Modified & validated MAC subheaders processing on tx and rx
2024-02-21 11:17:13 -08:00
Ejaz Ahmed
9e686e448d 5G sidelink PSFCH Tx implementation
Updates covered in this commit:
1) Computed feedback slot based on PSFCH time gap, PSFCH period and HARQ
	    feedback
2) Generated PSFCH pdu
3) Implemented PSFCH scheduling
4) Allocated PRBs based on slot and subchannel
5) Updated data structures accordingly
6) Modified configuration computation for PSFCH PRB set
7) Changed computation for number of PSFCH symbols
8) Moved sl_preconfiguration.conf under NR-SIDELINK/CONF
2024-02-16 10:50:02 -08:00
Melissa
5a88bb670a Merge branch 'episys/ea/psfch_configurations' into 'episys/sl-eurecom2'
Removed send_psfch_with_pucch command line argument

See merge request aburger/openairinterface5g!267
2024-02-16 09:13:22 -08:00
Melissa
b4a314b64e Updated prconfiguration code & Moved configuration file 2024-02-16 09:13:01 -08:00
Deokseong "David" Kim
6be609a59f picked 907130d9 2024-02-16 09:00:36 -08:00
Ejaz Ahmed
69c357655e Fixed spacing issue 2024-02-15 10:20:55 -08:00
Melissa
45dd2a7fb0 Merge branch 'episys/ea/tx_psfch' into 'episys/sl-eurecom2'
PSFCH Tx implementation: PSFCH PDU generation, scheduling and PRBs allocation

See merge request aburger/openairinterface5g!268
2024-02-15 16:30:42 +00:00
Ejaz Ahmed
b5dd8de98f PSFCH Tx implementation: PSFCH PDU generation, scheduling and PRBs allocation 2024-02-15 16:30:42 +00:00
Melissa
a42a4d1a06 Merge branch 'episys/ea/psfch_configurations' into 'episys/sl-eurecom2'
Removed send_psfch_with_pucch command line argument

See merge request aburger/openairinterface5g!267
2024-01-30 16:50:45 +00:00
Ejaz Ahmed
3c485239ba Removed resetting of psfch based on pucch based psfch transmission 2024-01-30 16:46:22 +00:00
Ejaz Ahmed
14b972e878 Removed header file 2024-01-30 16:44:25 +00:00
Ejaz Ahmed
aff9391806 Merge branch 'episys/sl-eurecom2' into episys/ea/psfch_configurations 2024-01-30 16:43:41 +00:00
Ejaz Ahmed
c734cfab93 Removed help MACRO for command line psfch argument 2024-01-30 16:30:14 +00:00
Ejaz Ahmed
3dd8395c8f Removed flag for send_psfch_with_pucch 2024-01-30 16:24:03 +00:00
Ejaz Ahmed
99a750d672 Merge branch 'episys/ea/psfch_configurations' of gitlab.int-episci.com:aburger/openairinterface5g into episys/ea/psfch_configurations 2024-01-30 15:09:46 +00:00
Ejaz Ahmed
82dfb5c4ec Reverteunnecessary changes 2024-01-30 15:09:13 +00:00
Melissa
7fd180f30b Merge branch 'episys/ea/psfch_configurations' into 'episys/sl-eurecom2'
Added functionality to read PSFCH configurations from conf file

See merge request aburger/openairinterface5g!266
2024-01-30 15:09:11 +00:00
Ejaz Ahmed
f52f258eec Added functionality to read PSFCH configurations from conf file 2024-01-30 15:09:11 +00:00
Melissa Elkadi
fdad2f7d17 Fixing more white space 2024-01-30 13:59:32 +00:00
Melissa Elkadi
1245c05385 Reverting whitespace changes 2024-01-30 13:58:00 +00:00
Melissa Elkadi
e534761719 updating the name of psfch_pucch variable and clean up 2024-01-30 13:54:13 +00:00
Ejaz Ahmed
2976628409 Added PSFCH configurations; Ignored number of psfch symbols
a) Added PSFCH configurations in conf file for TX resource pool;
b) In case of pucch based psfch transmission, ignored number of psfch
symbols for number of pssch symbols calculation
2024-01-30 02:59:55 +00:00
Ejaz Ahmed
34aede6ee5 Moved conf file to conf directory; long bit replace with hex numbers 2024-01-27 17:32:28 +00:00
Ejaz Ahmed
d2bbbb16ad Temporarily Removed number of PSFCH symbols from number of PSSCH symbhols computation 2024-01-26 21:05:49 +00:00
Ejaz Ahmed
7e83f75d21 Added functionality to take PSFCH Preconfigurations from conf file 2024-01-26 20:36:53 +00:00
Ejaz Ahmed
c4706eda69 Added further logs 2024-01-25 19:56:47 +00:00
Ejaz Ahmed
28f2129d3e Added harq_feedback condition; Added more logs 2024-01-25 17:14:57 +00:00
Ejaz Ahmed
238a7837cf Added updated configuration file for psfch 2024-01-24 20:25:40 +00:00
Ejaz Ahmed
e474090459 Added sl_preconfiguration file 2024-01-24 18:44:10 +00:00
Ejaz Ahmed
6f5205ec1c Commented out Rx to Tx notification mechanism; added configurations 2024-01-24 18:38:38 +00:00
Ejaz Ahmed
f5250c1ec4 Added but commented out due to issue with slsch reception 2024-01-23 21:22:43 +00:00
Ejaz Ahmed
156b806abb Updated code for psfch tx side 2024-01-15 22:49:53 +00:00
Ejaz Ahmed
d4e030cc3b Added more parameters in psfch pdu 2024-01-09 02:04:07 +00:00
Ejaz Ahmed
cb17a2530c Added Pre-configurations, created psfch pdu, scheduled psfch for transmission 2024-01-06 01:37:14 +00:00
Deokseong "David" Kim
907130d999 Merge branch 'episys/ea/fixed_pscch_slot_conflict_psbch' into 'episys/sl-eurecom2'
Fixed issue with reception of PSBCH

See merge request aburger/openairinterface5g!265
2023-12-21 18:03:08 +00:00
Ejaz Ahmed
d201d89c94 Fixed issue with reception of PSBCH 2023-12-21 18:03:08 +00:00
Raymond Knopp
5cc6d9e5c3 Merge branch 'sl-eurecom2' of https://gitlab.eurecom.fr/oai/openairinterface5g into sl-eurecom2 2023-10-14 07:19:44 +02:00
Raymond Knopp
1a815f7e15 warnings 2023-10-14 07:19:29 +02:00
ue1
05cb48d29c GPIO changes 2023-10-13 16:00:35 -04:00
Raymond Knopp
911bd2be5d removed some assertions after bogus reception of PSCCH 2023-10-13 16:34:24 +02:00
ue1
5ea68eb132 Merge branch 'sl-eurecom2' of https://gitlab.eurecom.fr/oai/openairinterface5g into sl-eurecom2 2023-10-13 09:36:05 -04:00
ue1
94188666ce removed some assertions 2023-10-13 09:35:43 -04:00
Raymond Knopp
a6d86ea8c9 Merge branch 'sl-eurecom2' of https://gitlab.eurecom.fr/oai/openairinterface5g into sl-eurecom2 2023-10-13 09:12:33 -04:00
Raymond Knopp
d3702751ec removal of logs 2023-10-13 09:12:13 -04:00
ue1
63b3d8a92f testing 2023-10-13 08:25:31 -04:00
Raymond Knopp
597c897977 improving stat 2023-10-13 06:33:18 -04:00
Raymond Knopp
d1bbbb5dd3 analytics of PSCCH/PSSCH 2023-10-12 11:50:16 +02:00
Raymond Knopp
18853ab6cc supression of logs 2023-10-12 08:11:06 +02:00
Raymond Knopp
9cc948635c Merge branch 'sl-eurecom2' of https://gitlab.eurecom.fr/oai/openairinterface5g into sl-eurecom2 2023-10-12 07:41:57 +02:00
Raymond Knopp
93d4a07932 TX path MAC PDU fix 2023-10-12 07:41:35 +02:00
Raymond Knopp
6bfe76b086 MAC pdu fixes, testing RX patch of rlc/pdcp/sdap 2023-10-12 07:40:39 +02:00
Raymond Knopp
e568b2c85a fix for MAC subheader handling in SL 2023-10-12 00:35:49 +02:00
Raymond Knopp
435b636d89 minor changes 2023-10-11 22:20:12 +02:00
Raymond Knopp
84504a38a0 small fixes for LCID/SLRB ids 2023-10-11 06:28:31 -04:00
ue1
4bd3007565 removal of many debugging logs, added pscch/pssch statistics, TX/RX switching time increase (3->4 slots 2023-10-11 05:25:12 -04:00
Raymond Knopp
dad4240016 merged pdcp/rlc components to current L1/L2 2023-10-09 23:08:11 +02:00
Raymond Knopp
2cda03b016 compilation ok 2023-10-09 22:44:08 +02:00
Raymond Knopp
198c319788 intermediate commit 2023-10-05 21:20:58 +02:00
Raymond Knopp
18d720f377 fixed issue with demux of SCI1/SCI2/SLSCH in SLSCH receiver. Added skeleton for MAC parsing on RX for SL. 2023-10-02 02:58:40 +02:00
Raymond Knopp
ba6a8554a3 minor changes 2023-09-28 21:14:48 +02:00
Raymond Knopp
ffda9c758a removed logs and added a bit more temporary debugging for SCI2 2023-09-18 15:49:13 +02:00
Raymond Knopp
60a7eb326c adding color defs for printing 2023-09-18 10:07:37 +02:00
Raymond Knopp
6a5a9f18bf testing sci2/slsch 2023-09-18 09:34:51 +02:00
Raymond Knopp
4bf5166aed integration of PSSCH with PUSCH TX 2023-09-07 21:38:38 +02:00
Raymond Knopp
d4e30b972b PSCCH RX testing 2 2023-08-25 09:19:13 +02:00
Raymond Knopp
858a13119b sci1a RX testing 2023-08-24 21:56:32 +02:00
Raymond Knopp
5b16b58496 debugging memory leaks 2023-08-22 00:27:26 +02:00
Raymond Knopp
0588003034 testing SCI1A 2023-08-21 21:02:30 +02:00
Raymond Knopp
b8d9da2e81 sci/slsch mac step1 2023-08-19 08:58:44 +02:00
Raymond Knopp
8199a1e093 fixes after merge with NR_SL_PSBCH_2 2023-08-03 23:26:54 +02:00
Raymond Knopp
7efe5880a1 Merge branch 'NR_SL_PSBCH_2' into sl-eurecom2 2023-08-03 15:50:49 +02:00
Raymond Knopp
b9caf3ecc4 Merge branch 'NR_SL_PSBCH_2' of https://gitlab.eurecom.fr/oai/openairinterface5g into NR_SL_PSBCH_2 2023-08-03 15:50:02 +02:00
Raghavendra Dinavahi
4ca508228f Enable SCOPE for PSBCH
- PSBCH LLR, PSBCH IQ, PSBCH RSRP, CIR added in scope.
	- use --dqt or --d  option to enable scope on the RX UE
	- -d option does not show RSRP
2023-08-03 14:55:16 +02:00
Raymond Knopp
9ecd473a41 Merge branch 'sl_eurecom_integration' into sl-eurecom2
Conflicts:
	CMakeLists.txt
2023-08-03 10:21:42 +02:00
Raymond Knopp
f32c759ecf modifications to allow running SL without --phy-test flag 2023-08-03 10:19:07 +02:00
Raghavendra Dinavahi
88b6cdd209 Changes for Sidelink RFSIM testing
- UE1 is a SYNC REFERENCE UE - TX PSBCH
	   started using command -
		sudo RFSIMULATOR=server ./nr-uesoftmodem --rfsim --phy-test --sl-mode 2 --sync-ref
	- UE2 syncs onto UE1 - RX PSBCH and continues to receive PSBCH
	   started using command -
		sudo ./nr-uesoftmodem --rfsim --phy-test --sl-mode 2
	- In the default use case 2 Sidelink SSBs sent over 16 frames.
2023-08-02 02:30:21 +02:00
Raghavendra Dinavahi
8bb2f3991b Sidelink SLSS SEARCH Procedure 2023-08-02 02:28:25 +02:00
Raghavendra Dinavahi
4d369a6993 Sidelink config MAC->PHY, PSBCH scheduler and supporting functions
- Phy config update and Sidelink frame parameters initialisation
	- PSBCH scheduler to trigger TX PSBCH/RX PSBCH actions
	- Sidelink indication with rx ind to trigger send SL-MIB to MAC
2023-08-02 02:28:25 +02:00
Raghavendra Dinavahi
70f586cb3c Sidelink configuration passed from RRC->MAC, defined interface functions
- Phy configuration will be prepared by MAC
	- Sidelink preconfiguration parameters passed from RRC->MAC
	- Only 1 SSB TA allocation used
	- psbch payload prepared by MAC after receiving the tx slss req
2023-08-02 02:28:25 +02:00
Raghavendra Dinavahi
745cc733ea PSBCH RX TX changes
- RX/TX Phy processing accg to 38.211, 38.212 Rel16
	- Rate matching fix from Ralf to address 1782 bits
		- do not try to group the last bits, process them manually
	- PSBCH simulator used to validate TX/RX phy processing
2023-08-02 02:28:25 +02:00
Raymond Knopp
ee7aacf2ca sci development 2023-07-26 21:08:48 +02:00
Raymond Knopp
fef6303cc9 initial commit of SCI encoding 2023-07-22 23:07:11 +02:00
280 changed files with 15571 additions and 6754 deletions

View File

@@ -1,34 +1,5 @@
# RELEASE NOTES: #
## [v2.0.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.0.0) -> August 2023. ##
This release adds support for 5G and maintains previous features:
* 5G SA in gNB
- PHY, MAC, RLC, PDCP, SDAP, RRC layers
- 2x2 MIMO and 256-QAM for UL/DL
- 15 and 30 kHz subcarrier spacings; 10-100 MHz bandwidths
- Up to 800Mbps throughput or 5ms latency
- F1, basic E1, 5G FAPI (SCF 222.10.02), split 8 split options
- Handling of up to 16 UEs
- RRC procedures for connection setup, multiple PDU sessions, reestablishment
* 5G SA in UE
- PHY, MAC, RLC, PDCP, SDAP, RRC layers
- 2x2 MIMO and 256-QAM for UL/DL
- 15 and 30 kHz subcarrier spacings; 10-100 MHz bandwidths
- Custom FAPI-like MAC/PHY interface
- RRC procedures for connection setup and cell measurement
* Basic 5G NSA in gNB
- X2 sgNB Addition Request between OAI eNB and gNB
* 4G eNB and UE
- Bugfixes in fairRR scheduler (eNB)
- Non-standard F1 midhaul removed (eNB)
- FlexRAN removed (eNB)
- Sync fixes (UE)
* LTE-M supported
* Support for AW2S devices, RFsimulator channel emulation support
For more information on supported features, please refer to the [feature set](doc/FEATURE_SET.md).
## [v1.2.1](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.2.1) -> February 2020. ##
* Bug fix for mutex lock for wake-up signal

View File

@@ -163,8 +163,8 @@ set(CMAKE_CXX_FLAGS
add_boolean_option(SANITIZE_ADDRESS False "enable the address sanitizer (ASan)" ON)
if (SANITIZE_ADDRESS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fno-common")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fno-common")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fstack-check -fno-omit-frame-pointer -fno-common")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fstack-check -fno-omit-frame-pointer -fno-common")
# There seems to be some incompatibility with pthread_create and the RT scheduler, which
# results in pthread_create hanging.
#
@@ -256,11 +256,8 @@ add_definitions("-DPACKAGE_BUGREPORT=\"openair4g-devel@lists.eurecom.fr\"")
# Debug related options
#########################################
add_boolean_option(DEBUG_ASN1 False "Enable ASN1 debug logs" OFF)
# asn1c skeletons have hardcoded this flag to make customized debug logs
# OAI uses this feature to re-use OAI LOG_I(ASN1, ...)
# see common/utils/config.h
add_boolean_option(TRACE_ASN1C_ENC_DEC OFF "Enable ASN1 encoder/decoder debug traces via OAI logging system" ON)
add_boolean_option(DEBUG_ASN1 False "ASN1 coder/decoder Debug" OFF)
#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, not found in code, commented out, to be removed
add_boolean_option(T_TRACER True "Activate the T tracer, a debugging/monitoring framework" ON)
add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs" ON)
add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace" ON)
@@ -270,6 +267,12 @@ set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti)
add_library(ITTI ${OCP_ITTI}/intertask_interface.cpp)
target_link_libraries(ITTI PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
# asn1c skeletons have hardcoded this flag to make customized debug logs
# OAI uses this feature to re-use OAI LOG_I(ASN1, ...)
if (DEBUG_ASN1C)
add_definitions(-DHAVE_CONFIG_H)
endif()
# asn1c skeletons need this
add_definitions(-DHAVE_NETINET_IN_H)
@@ -413,7 +416,6 @@ target_link_libraries(x2ap PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
set(F1AP_DIR ${OPENAIR2_DIR}/F1AP)
add_library(f1ap
${F1AP_DIR}/f1ap_common.c
${F1AP_DIR}/f1ap_ids.c
${F1AP_DIR}/f1ap_cu_interface_management.c
${F1AP_DIR}/f1ap_cu_paging.c
${F1AP_DIR}/f1ap_cu_rrc_message_transfer.c
@@ -432,7 +434,7 @@ add_library(f1ap
${F1AP_DIR}/f1ap_itti_messaging.c)
target_include_directories(f1ap PUBLIC F1AP_DIR)
target_link_libraries(f1ap PUBLIC asn1_f1ap)
target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE)
target_link_libraries(f1ap PRIVATE ngap nr_rrc)
# LPP
##############
@@ -624,7 +626,7 @@ add_library(UTIL
${OPENAIR_DIR}/common/utils/time_meas.c
${OPENAIR_DIR}/common/utils/time_stat.c
)
target_link_libraries(UTIL PUBLIC ${T_LIB} pthread)
target_link_libraries(UTIL PUBLIC ${T_LIB})
set(SECURITY_SRC
${OPENAIR3_DIR}/SECU/secu_defs.c
@@ -687,6 +689,7 @@ target_link_libraries(SCHED_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
set(SCHED_SRC_NR_UE
${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c
${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue_sl.c
${OPENAIR1_DIR}/SCHED_NR_UE/fapi_nr_ue_l1.c
${OPENAIR1_DIR}/SCHED_NR_UE/phy_frame_config_nr_ue.c
${OPENAIR1_DIR}/SCHED_NR_UE/harq_nr.c
@@ -1058,8 +1061,19 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/sss_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/cic_filter_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psfch_tx.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pscch_tx.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci_tools.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -1079,11 +1093,14 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_measurements_gNB.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
# ${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
@@ -1118,8 +1135,8 @@ target_link_libraries(PHY_COMMON PRIVATE asn1_lte_rrc_hdrs)
add_library(PHY ${PHY_SRC})
target_link_libraries(PHY PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
pkg_check_modules(blas REQUIRED blas)
pkg_check_modules(lapacke REQUIRED lapacke)
#pkg_check_modules(blas REQUIRED blas)
#pkg_check_modules(lapacke REQUIRED lapacke)
add_library(PHY_UE ${PHY_SRC_UE})
target_link_libraries(PHY_UE PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
@@ -1185,6 +1202,18 @@ set(RLC_V2
${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_sdu.c
)
set(NR_RLC_SRC
${OPENAIR2_DIR}/LAYER2/nr_rlc/asn1_utils.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_am.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_tm.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_um.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_oai_api.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_pdu.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_sdu.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_ue_manager.c
)
set(NR_PDCP_SRC
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
@@ -1242,6 +1271,7 @@ set(L2_LTE_SRC
)
set(L2_NR_SRC
${NR_RLC_SRC}
${NR_PDCP_SRC}
${NR_SDAP_SRC}
${NR_RRC_DIR}/rrc_gNB.c
@@ -1279,6 +1309,7 @@ set(L2_RRC_SRC_UE
)
set(NR_L2_SRC_UE
${NR_RLC_SRC}
${NR_PDCP_SRC}
${NR_SDAP_SRC}
${NR_UE_RRC_DIR}/L2_interface_ue.c
@@ -1336,7 +1367,7 @@ set (MAC_NR_SRC
set (MAC_SRC_UE
${PHY_INTERFACE_DIR}/phy_stub_UE.c
# ${PHY_INTERFACE_DIR}/phy_stub_UE.c
${PHY_INTERFACE_DIR}/queue_t.c
${MAC_DIR}/main_ue.c
${MAC_DIR}/ue_procedures.c
@@ -1350,13 +1381,17 @@ set (MAC_NR_SRC_UE
${NR_UE_PHY_INTERFACE_DIR}/NR_IF_Module.c
${NR_UE_PHY_INTERFACE_DIR}/NR_Packet_Drop.c
${NR_UE_MAC_DIR}/config_ue.c
${NR_UE_MAC_DIR}/config_ue_sl.c
${NR_UE_MAC_DIR}/mac_vars.c
${NR_UE_MAC_DIR}/main_ue_nr.c
${NR_UE_MAC_DIR}/nr_ue_procedures.c
${NR_UE_MAC_DIR}/nr_ue_procedures_sl.c
${NR_UE_MAC_DIR}/nr_ue_scheduler.c
${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c
${NR_UE_MAC_DIR}/nr_ra_procedures.c
${NR_UE_MAC_DIR}/nr_ue_power_procedures.c
${NR_UE_MAC_DIR}/nr_ue_sci_slsch.c
${NR_UE_MAC_DIR}/nr_slsch_scheduler.c
)
set (ENB_APP_SRC
@@ -1431,12 +1466,13 @@ add_library(e1_pdcp_if
target_link_libraries(e1_pdcp_if PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap nr_rlc)
target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap)
if(E2_AGENT)
target_link_libraries(L2_NR PUBLIC e2_agent e2_ran_func)
target_compile_definitions(L2_NR PRIVATE E2_AGENT)
endif()
add_library(L2_LTE_NR
${L2_RRC_SRC}
${MAC_SRC}
@@ -1465,7 +1501,7 @@ endif()
target_link_libraries(L2_UE PRIVATE asn1_lte_rrc_hdrs)
add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} )
target_link_libraries(NR_L2_UE PRIVATE f1ap nr_rlc)
target_link_libraries(NR_L2_UE PRIVATE f1ap)
target_link_libraries(NR_L2_UE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_library(MAC_NR_COMMON
@@ -2208,6 +2244,24 @@ target_link_libraries(nr_pbchsim PRIVATE
)
target_link_libraries(nr_pbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_executable(nr_psbchsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/psbchsim.c
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/executables/softmodem-common.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${NR_UE_RRC_DIR}/rrc_nsa.c
${NFAPI_USER_DIR}/nfapi.c
${NFAPI_USER_DIR}/gnb_ind_vars.c
${PHY_INTERFACE_DIR}/queue_t.c
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_psbchsim PRIVATE
-Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl shlib_loader
)
target_link_libraries(nr_psbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
#PUCCH ---> Prashanth
add_executable(nr_pucchsim
@@ -2433,16 +2487,6 @@ make_driver(ue_ip ${OPENAIR2_DIR}/NETWORK_DRIVER/UE_IP ${ue_ip_src})
include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt)
set(ENABLE_TESTS OFF CACHE STRING "Activate build of tests")
set_property(CACHE ENABLE_TESTS PROPERTY TYPE BOOL)
if(ENABLE_TESTS)
# activates globally adding tests such that they can be run using ctest
enable_testing()
# meta-target: each test is supposed to add_dependencies(tests ${NEWTEST})
# then, it is possible to build and execute all tests using "ninja tests && ctest"
add_custom_target(tests)
endif()
add_subdirectory(common)
add_subdirectory(doc)
add_subdirectory(openair1)

View File

@@ -12,10 +12,6 @@
<a href="https://getfedora.org/en/workstation/"><img src="https://img.shields.io/badge/OS-Fedore37-Green" alt="Supported OS Fedora 37"></a>
</p>
<p align="center">
<a href="https://gitlab.eurecom.fr/oai/openairinterface5g/-/releases"><img alt="GitLab Release (custom instance)" src="https://img.shields.io/gitlab/v/release/oai/openairinterface5g?gitlab_url=https%3A%2F%2Fgitlab.eurecom.fr&include_prereleases&sort=semver"></a>
</p>
<p align="center">
<a href="https://jenkins-oai.eurecom.fr/job/RAN-Container-Parent/"><img src="https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins-oai.eurecom.fr%2Fjob%2FRAN-Container-Parent%2F&label=build%20Images"></a>
</p>

View File

@@ -103,6 +103,7 @@ pipeline {
gitCommitAuthorEmailAddr = sh returnStdout: true, script: 'git log -n1 --pretty=format:%ae ${GIT_COMMIT}'
gitCommitAuthorEmailAddr = gitCommitAuthorEmailAddr.trim()
echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}"
sh "git log -n1 --pretty=format:\"%s\" > .git/CI_COMMIT_MSG"
}
}
}
@@ -287,7 +288,7 @@ pipeline {
when { expression {do4Gtest} }
steps {
script {
triggerSlaveJob ('RAN-LTE-FDD-LTEBOX-Container', 'LTE-FDD-LTEBOX-Container')
triggerSlaveJob ('RAN-LTE-FDD-LTEBOX-Container', 'RAN-LTE-FDD-LTEBOX-Container')
}
}
post {
@@ -303,32 +304,11 @@ pipeline {
}
}
}
// Pipeline to test OAI LTE-UE
stage ("LTE-B200-FDD-OAIUE-OAICN4G-Container") {
when { expression {do4Gtest} }
steps {
script {
triggerSlaveJob ('RAN-LTE-FDD-OAIUE-OAICN4G-Container', 'LTE-FDD-OAIUE-OAICN4G-Container')
}
}
post {
always {
script {
finalizeSlaveJob('RAN-LTE-FDD-OAIUE-OAICN4G-Container')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("LTE-B200-TDD-LTEBOX-Container") {
when { expression {do4Gtest} }
steps {
script {
triggerSlaveJob ('RAN-LTE-TDD-LTEBOX-Container', 'LTE-TDD-LTEBOX-Container')
triggerSlaveJob ('RAN-LTE-TDD-LTEBOX-Container', 'RAN-LTE-TDD-LTEBOX-Container')
}
}
post {
@@ -488,7 +468,7 @@ pipeline {
when { expression {do5Gtest} }
steps {
script {
triggerSlaveJob ('RAN-SA-OAIUE-CN5G', 'SA-OAIUE-CN5G')
triggerSlaveJob ('RAN-SA-OAIUE-CN5G', 'RAN-SA-OAIUE-CN5G')
}
}
post {
@@ -524,6 +504,24 @@ pipeline {
}
}
post {
always {
script {
def eSubject = JOB_NAME + ' - Build # ' + BUILD_ID + ' - ' + currentBuild.result + '!'
def eBody = "Hi,\n\n"
eBody += "Here are attached HTML report files for " + JOB_NAME + " - Build # " + BUILD_ID + " - " + currentBuild.result + "!\n\n"
eBody += "Regards,\n"
eBody += "OAI CI Team"
emailext attachmentsPattern: '*results*.html',
body: eBody,
replyTo: 'no-reply@openairinterface.org',
subject: eSubject,
to: gitCommitAuthorEmailAddr
if (fileExists('.git/CI_COMMIT_MSG')) {
sh "rm -f .git/CI_COMMIT_MSG"
}
}
}
success {
script {
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ")"

View File

@@ -49,75 +49,75 @@ adb_ue_2:
amarisoft_ue:
Host: amariue
InitScript: /root/2023-06-10/lteue-linux-2023-06-10/lteue /root/oaicicd/ran_sa_aw2s_asue/aw2s-multi-20897-2x2.cfg &
TermScript: /root/2023-06-10/libs/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2
InitScript: /root/NV18-06-2022/lteue-linux-2023-03-17/lteue /root/oaicicd/ran_sa_aw2s_asue/aw2s-multi-20897-2x2.cfg &
TermScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2
amarisoft_ue_1:
Host: amariue
AttachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":1}'
DetachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":1}'
AttachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":1}'
DetachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":1}'
NetworkScript: ip netns exec ue1 ip a show dev pdn0
CmdPrefix: ip netns exec ue1
MTU: 1500
amarisoft_ue_2:
Host: amariue
AttachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":2}'
DetachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":2}'
AttachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":2}'
DetachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":2}'
NetworkScript: ip netns exec ue2 ip a show dev pdn0
CmdPrefix: ip netns exec ue2
MTU: 1500
amarisoft_ue_3:
Host: amariue
AttachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":3}'
DetachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":3}'
AttachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":3}'
DetachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":3}'
NetworkScript: ip netns exec ue3 ip a show dev pdn0
CmdPrefix: ip netns exec ue3
MTU: 1500
amarisoft_ue_4:
Host: amariue
AttachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":4}'
DetachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":4}'
AttachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":4}'
DetachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":4}'
NetworkScript: ip netns exec ue4 ip a show dev pdn0
CmdPrefix: ip netns exec ue4
MTU: 1500
amarisoft_ue_5:
Host: amariue
AttachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":5}'
DetachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":5}'
AttachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":5}'
DetachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":5}'
NetworkScript: ip netns exec ue5 ip a show dev pdn0
CmdPrefix: ip netns exec ue5
MTU: 1500
amarisoft_ue_6:
Host: amariue
AttachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":6}'
DetachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":6}'
AttachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":6}'
DetachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":6}'
NetworkScript: ip netns exec ue6 ip a show dev pdn0
CmdPrefix: ip netns exec ue6
MTU: 1500
amarisoft_ue_7:
Host: amariue
AttachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":7}'
DetachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":7}'
AttachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":7}'
DetachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":7}'
NetworkScript: ip netns exec ue7 ip a show dev pdn0
CmdPrefix: ip netns exec ue7
MTU: 1500
amarisoft_ue_8:
Host: amariue
AttachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":8}'
DetachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":8}'
AttachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":8}'
DetachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":8}'
NetworkScript: ip netns exec ue8 ip a show dev pdn0
CmdPrefix: ip netns exec ue8
MTU: 1500
amarisoft_ue_9:
Host: amariue
AttachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":9}'
DetachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":9}'
AttachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":9}'
DetachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":9}'
NetworkScript: ip netns exec ue9 ip a show dev pdn0
CmdPrefix: ip netns exec ue9
MTU: 1500
amarisoft_ue_10:
Host: amariue
AttachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":10}'
DetachScript: /root/2023-06-10/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":10}'
AttachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":10}'
DetachScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":10}'
NetworkScript: ip netns exec ue10 ip a show dev pdn0
CmdPrefix: ip netns exec ue10
MTU: 1500
@@ -130,13 +130,6 @@ oai_ue_caracal:
IF: oaitun_ue1
MTU: 1500
lte_oai_ue_carabe:
Host: carabe
NetworkScript: docker exec lte-b200-ue-fdd-10Mhz-tm1 ip a show dev oaitun_ue1
CmdPrefix: docker exec lte-b200-ue-fdd-10Mhz-tm1
IF: oaitun_ue1
MTU: 1500
rfsim5g_gnb_nos1:
Host: localhost
NetworkScript: docker exec rfsim5g-oai-gnb ip a show dev oaitun_enb1

View File

@@ -742,7 +742,6 @@ class Containerize():
if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
logging.debug('\u001B[1m Pulling image(s) on server: ' + lIpAddr + '\u001B[0m')
myCmd = cls_cmd.getConnection(lIpAddr)
imagePrefix = 'porcepix.sboai.cs.eurecom.fr'
response = myCmd.run(f'docker login -u oaicicd -p oaicicd {imagePrefix}')
@@ -904,7 +903,7 @@ class Containerize():
cnt = 0
while (cnt < 20):
mySSH.command('docker logs ' + containerName + ' | egrep --text --color=never -i "wait|sync|Starting"', '\$', 30)
result = re.search('got sync|Starting E1AP at CU UP|Starting F1AP at CU|Got sync|Waiting for RUs to be configured', mySSH.getBefore())
result = re.search('got sync|Starting F1AP at CU|Got sync|Waiting for RUs to be configured', mySSH.getBefore())
if result is None:
time.sleep(6)
cnt += 1
@@ -1006,7 +1005,7 @@ class Containerize():
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE)
self.exitStatus = 1
# use function for UE log analysis, when oai-nr-ue container is used
elif 'oai-nr-ue' in services or 'lte_ue0' in services:
elif 'oai-nr-ue' in services:
self.exitStatus == 0
logging.debug('\u001B[1m Analyzing UE logfile ' + filename + ' \u001B[0m')
logStatus = cls_oaicitest.OaiCiTest().AnalyzeLogFile_UE(f'{filename}', HTML, RAN)

View File

@@ -469,8 +469,8 @@ class HTMLManagement():
self.htmlFile.write(' <td bgcolor = "orange" >')
else:
self.htmlFile.write(' <td>')
for i in infoList: # add custom style to have elements side-by-side to reduce need for vertical space
self.htmlFile.write(f' <pre style="display: inline flow-root list-item; margin: 0 3px 0 3px; min-width: 24em;">{i}</pre>')
for i in infoList:
self.htmlFile.write(f' <pre>{i}</pre>')
self.htmlFile.write(' </td>')
self.htmlFile.write(' </tr>\n')

View File

@@ -43,7 +43,7 @@ import logging
import datetime
import signal
import statistics as stat
from multiprocessing import SimpleQueue
from multiprocessing import Process, Lock, SimpleQueue
import concurrent.futures
#import our libs
@@ -494,6 +494,15 @@ class OaiCiTest():
messages = [f.result() for f in futures]
HTML.CreateHtmlTestRowQueue('NA', 'OK', messages)
def ping_iperf_wrong_exit(self, lock, UE_IPAddress, device_id, statusQueue, message):
logging.error(f"ue {device_id} {UE_IPAddress}: {message}")
lock.acquire()
statusQueue.put(-1)
statusQueue.put(device_id)
statusQueue.put(UE_IPAddress)
statusQueue.put(message)
lock.release()
def Ping_common(self, EPC, ue, RAN):
# Launch ping on the EPC side (true for ltebox and old open-air-cn)
ping_status = 0
@@ -608,7 +617,7 @@ class OaiCiTest():
def Iperf_ComputeModifiedBW(self, idx, ue_num):
result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(self.iperf_args))
if result is None:
logging.error('\u001B[1;37;41m Iperf bandwidth Not Found! \u001B[0m')
logging.debug('\u001B[1;37;41m Iperf bandwidth Not Found! \u001B[0m')
sys.exit(1)
iperf_bandwidth = result.group('iperf_bandwidth')
if self.iperf_profile == 'balanced':
@@ -626,11 +635,11 @@ class OaiCiTest():
iperf_bandwidth_str_new = f"-b {'%.2f' % iperf_bandwidth_new}"
result = re.sub(iperf_bandwidth_str, iperf_bandwidth_str_new, str(self.iperf_args))
if result is None:
logging.error('\u001B[1;37;41m Calculate Iperf bandwidth Failed! \u001B[0m')
logging.debug('\u001B[1;37;41m Calculate Iperf bandwidth Failed! \u001B[0m')
sys.exit(1)
return result
def Iperf_analyzeV2TCPOutput(self, SSH, filename):
def Iperf_analyzeV2TCPOutput(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options,EPC,SSH, filename):
SSH.command(f'awk -f /tmp/tcp_iperf_stats.awk {filename}', '\$', 5)
result = re.search('Avg Bitrate : (?P<average>[0-9\.]+ Mbits\/sec) Max Bitrate : (?P<maximum>[0-9\.]+ Mbits\/sec) Min Bitrate : (?P<minimum>[0-9\.]+ Mbits\/sec)', SSH.getBefore())
@@ -638,34 +647,44 @@ class OaiCiTest():
avgbitrate = result.group('average')
maxbitrate = result.group('maximum')
minbitrate = result.group('minimum')
lock.acquire()
logging.debug(f'\u001B[1;37;44m TCP iperf result ({UE_IPAddress}) \u001B[0m')
msg = 'TCP Stats :\n'
if avgbitrate is not None:
logging.debug(f'\u001B[1;34m Avg Bitrate : {avgbitrate} \u001B[0m')
msg += f'Avg Bitrate : {avgbitrate} \n'
if maxbitrate is not None:
logging.debug(f'\u001B[1;34m Max Bitrate : {maxbitrate} \u001B[0m')
msg += f'Max Bitrate : {maxbitrate} \n'
if minbitrate is not None:
logging.debug(f'\u001B[1;34m Min Bitrate : {minbitrate} \u001B[0m')
msg += f'Min Bitrate : {minbitrate} \n'
return (True, msg)
statusQueue.put(0)
statusQueue.put(device_id)
statusQueue.put(UE_IPAddress)
statusQueue.put(msg)
lock.release()
return (False, "could not analyze log file")
return 0
def Iperf_analyzeV2Output(self, iperf_real_options, EPC, SSH):
def Iperf_analyzeV2Output(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options,EPC,SSH):
result = re.search('-u', str(iperf_real_options))
if result is None:
logging.debug('Into Iperf_analyzeV2TCPOutput client')
filename = f'{EPC.SourceCodePath}/scripts/iperf_{self.testCase_id}_{device_id}.log'
response = self.Iperf_analyzeV2TCPOutput(SSH, filename)
response = self.Iperf_analyzeV2TCPOutput(lock, UE_IPAddress, device_id, statusQueue, iperf_real_options, EPC, SSH, filename)
logging.debug(f'Iperf_analyzeV2TCPOutput response returned value = {response}')
return response
result = re.search('Server Report:', SSH.getBefore())
if result is None:
result = re.search('read failed: Connection refused', SSH.getBefore())
if result is not None:
msg = 'Could not connect to iperf server!'
return (False, msg)
logging.debug('\u001B[1;37;41m Could not connect to iperf server! \u001B[0m')
else:
msg = 'Server Report and Connection refused Not Found!'
return (False, msg)
logging.debug('\u001B[1;37;41m Server Report and Connection refused Not Found! \u001B[0m')
return -1
# Computing the requested bandwidth in float
result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(iperf_real_options))
if result is not None:
@@ -689,11 +708,14 @@ class OaiCiTest():
bitrate = result.group('bitrate')
packetloss = result.group('packetloss')
jitter = result.group('jitter')
lock.acquire()
logging.debug(f'\u001B[1;37;44m iperf result {UE_IPAddress} \u001B[0m')
iperfStatus = True
msg = f'Req Bitrate : {req_bandwidth} \n'
logging.debug(f'\u001B[1;34m Req Bitrate : {req_bandwidth} \u001B[0m')
if bitrate is not None:
msg += f'Bitrate : {bitrate} \n'
logging.debug(f'\u001B[1;34m Bitrate : {bitrate} \u001B[0m')
result = re.search('(?P<real_bw>[0-9\.]+) [KMG]bits/sec', str(bitrate))
if result is not None:
actual_bw = float(str(result.group('real_bw')))
@@ -709,37 +731,50 @@ class OaiCiTest():
br_loss = 100 * actual_bw / req_bw
bitperf = '%.2f ' % br_loss
msg += f'Bitrate Perf: {bitperf} %\n'
logging.debug(f'\u001B[1;34m Bitrate Perf: {bitperf} %\u001B[0m')
if packetloss is not None:
msg += f'Packet Loss : {packetloss} %\n'
logging.debug(f'\u001B[1;34m Packet Loss : {packetloss} %\u001B[0m')
if float(packetloss) > float(self.iperf_packetloss_threshold):
msg += 'Packet Loss too high!\n'
logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m')
iperfStatus = False
if jitter is not None:
msg += f'Jitter : {jitter} \n'
return (iperfStatus, msg)
logging.debug(f'\u001B[1;34m Jitter : {jitter} \u001B[0m')
if (iperfStatus):
statusQueue.put(0)
else:
statusQueue.put(-1)
statusQueue.put(device_id)
statusQueue.put(UE_IPAddress)
statusQueue.put(msg)
lock.release()
return 0
else:
return (False, "could not analyze server log")
return -2
def Iperf_analyzeV2BIDIR(self, server_filename, client_filename):
def Iperf_analyzeV2BIDIR(self, lock, UE_IPAddress, device_id, statusQueue,server_filename,client_filename):
#check the 2 files are here
if (not os.path.isfile(client_filename)) or (not os.path.isfile(server_filename)):
return (False, 'Bidir TCP: Client or Server Log File not present')
self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Bidir TCP : Client or Server Log File not present')
return
#check the 2 files size
if (os.path.getsize(client_filename)==0) and (os.path.getsize(server_filename)==0):
return (False, 'Bidir TCP: Client and Server Log File are empty')
self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Bidir TCP : Client and Server Log File are empty')
return
report_msg = ''
report_msg='TCP BIDIR Report:\n'
#if client is not empty, all the info is in, otherwise we ll use the server file to get some partial info
client_filesize = os.path.getsize(client_filename)
if client_filesize == 0:
report_msg+="Client file (UE) present but !!! EMPTY !!!\n"
report_msg+="Partial report from server file"
report_msg+="Partial report from server file\n"
filename = server_filename
else :
report_msg+="Report from client file (UE)"
report_msg+="Report from client file (UE)\n"
filename = client_filename
report=[] #used to check if relevant lines were found
@@ -749,19 +784,32 @@ class OaiCiTest():
result = re.search(rf'^\[\s+\d+\](?P<direction>\[.+\]).*\s+(?P<bitrate>[0-9\.]+ [KMG]bits\/sec).*\s+(?P<role>\bsender|receiver\b)', str(line))
if result is not None:
report.append(str(line))
report_msg += f"\n{result.group('role')} {result.group('direction')}\t: {result.group('bitrate')}"
if len(report) == 0:
return (False, 'Bidir TCP: Could not analyze from Log file')
report_msg+=result.group('role') + ' ' + result.group('direction')+ '\t = ' +result.group('bitrate')+'\n'
if len(report)>0:
lock.acquire()
statusQueue.put(0)
statusQueue.put(device_id)
statusQueue.put(UE_IPAddress)
statusQueue.put(report_msg)
logging.debug(f'\u001B[1;37;45m TCP Bidir Iperf Result ({UE_IPAddress}) \u001B[0m')
for rLine in report_msg.split('\n'):
logging.debug(f'\u001B[1;35m {rLine} \u001B[0m')
lock.release()
else:
self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Bidir TCP : Could not analyze from Log file')
return (True, report_msg)
def Iperf_analyzeV2Server(self, iperf_real_options, filename, type):
def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options, filename,type):
if (not os.path.isfile(filename)):
return (False, 'Could not analyze from server log')
self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log')
return
# Computing the requested bandwidth in float
result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(iperf_real_options))
if result is None:
return (False, 'Could not compute Iperf bandwidth!')
logging.debug('Iperf bandwidth Not Found!')
self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not compute Iperf bandwidth!')
return
else:
req_bandwidth = result.group('iperf_bandwidth')
req_bw = float(req_bandwidth)
@@ -808,8 +856,6 @@ class OaiCiTest():
br_sum = curr_br + br_sum
ji_sum = float(ji[0]) + ji_sum
server_file.close()
if (row_idx > 0):
br_sum = br_sum / row_idx
ji_sum = ji_sum / row_idx
@@ -830,25 +876,87 @@ class OaiCiTest():
pl = float(100 * pl_sum / ps_sum)
packetloss = '%2.1f ' % (pl)
packetloss += '%'
result = float(br_loss) >= float(self.iperf_bitrate_threshold) and float(pl) <= float(self.iperf_packetloss_threshold)
#checking packet loss compliance
if float(pl) > float(self.iperf_packetloss_threshold):
pal_too_high_msg = 'Packet Loss too high : tested = '+packetloss+', target = '+self.iperf_packetloss_threshold+'%'
else:
pal_too_high_msg='Packet Loss value is within acceptance range'
#checking bitrate perf compliance
if float(br_loss) < float(self.iperf_bitrate_threshold):
bit_too_low_msg = 'Bitrate too low : tested = '+bitperf+', target = '+self.iperf_bitrate_threshold+'%'
else:
bit_too_low_msg='Bitrate perf value is within acceptance range'
lock.acquire()
if (float(br_loss) < float(self.iperf_bitrate_threshold)) and (float(pl) > float(self.iperf_packetloss_threshold)):
statusQueue.put(-1)
elif (float(br_loss) < float(self.iperf_bitrate_threshold)) or (float(pl) > float(self.iperf_packetloss_threshold)):
statusQueue.put(1)
else:
statusQueue.put(0)
statusQueue.put(device_id)
statusQueue.put(UE_IPAddress)
req_msg = f'Req Bitrate : {req_bandwidth}'
bir_msg = f'Bitrate : {bitrate}'
brl_msg = f'Bitrate Perf: {bitperf}'
if float(br_loss) < float(self.iperf_bitrate_threshold):
brl_msg += f' (too low! <{self.iperf_bitrate_threshold}%)'
jit_msg = f'Jitter : {jitter}'
pal_msg = f'Packet Loss : {packetloss}'
if float(pl) > float(self.iperf_packetloss_threshold):
pal_msg += f' (too high! >{self.iperf_packetloss_threshold}%)'
return (result, f'{req_msg}\n{bir_msg}\n{brl_msg}\n{jit_msg}\n{pal_msg}')
statusQueue.put(f'{req_msg}\n{bir_msg}\n{brl_msg}\n{jit_msg}\n{pal_msg}\n{pal_too_high_msg}\n{bit_too_low_msg}\n')
logging.debug(f'\u001B[1;37;45m iperf result ({UE_IPAddress}) \u001B[0m')
logging.debug(f'\u001B[1;35m {req_msg} \u001B[0m')
logging.debug(f'\u001B[1;35m {bir_msg} \u001B[0m')
logging.debug(f'\u001B[1;35m {brl_msg} \u001B[0m')
logging.debug(f'\u001B[1;35m {jit_msg} \u001B[0m')
logging.debug(f'\u001B[1;35m {pal_msg} \u001B[0m')
logging.debug(f'\u001B[1;35m {pal_too_high_msg} \u001B[0m')
logging.debug(f'\u001B[1;35m {bit_too_low_msg} \u001B[0m')
lock.release()
else:
return (False, 'Could not analyze from server log')
self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log')
def Iperf_Module(self, EPC, ue, RAN, idx, ue_num):
ueIP = ue.getIP()
if not ueIP:
return (False, f"UE {ue.getName()} has no IP address")
server_file.close()
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())
if result is None:
result = re.search('(?P<error>iperf: error - [a-zA-Z0-9 :]+)', SSH.getBefore())
lock.acquire()
statusQueue.put(-1)
statusQueue.put(device_id)
statusQueue.put(UE_IPAddress)
if result is not None:
logging.debug(f"\u001B[1;37;41m {result.group('error')} \u001B[0m")
statusQueue.put(result.group('error'))
else:
logging.debug('\u001B[1;37;41m Bitrate and/or Packet Loss Not Found! \u001B[0m')
statusQueue.put('Bitrate and/or Packet Loss Not Found!')
lock.release()
bitrate = result.group('bitrate')
packetloss = result.group('packetloss')
lock.acquire()
logging.debug(f'\u001B[1;37;44m iperf result ({UE_IPAddress}) \u001B[0m')
logging.debug(f'\u001B[1;34m Bitrate : {bitrate} \u001B[0m')
msg = f'Bitrate : {bitrate} \n'
iperfStatus = True
if packetloss is not None:
logging.debug(f'\u001B[1;34m Packet Loss : {packetloss} %\u001B[0m')
msg += f'Packet Loss : {packetloss} %\n'
if float(packetloss) > float(self.iperf_packetloss_threshold):
logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m')
msg += 'Packet Loss too high!\n'
iperfStatus = False
if (iperfStatus):
statusQueue.put(0)
else:
statusQueue.put(-1)
statusQueue.put(device_id)
statusQueue.put(UE_IPAddress)
statusQueue.put(msg)
lock.release()
def Iperf_Module(self, lock, statusQueue, EPC, ue, RAN, idx, ue_num):
SSH = sshconnection.SSHConnection()
server_filename = f'iperf_server_{self.testCase_id}_{ue.getName()}.log'
client_filename = f'iperf_client_{self.testCase_id}_{ue.getName()}.log'
@@ -879,18 +987,16 @@ class OaiCiTest():
# hack: the ADB UEs don't have iperf in $PATH, so we need to hardcode for the moment
iperf_ue = '/data/local/tmp/iperf' if re.search('adb', ue.getName()) else 'iperf'
ue_header = f'UE {ue.getName()} ({ueIP})'
if self.iperf_direction == "DL":
logging.debug("Iperf in DL requested")
cmd = cls_cmd.getConnection(ue.getHost())
cmd.run(f'rm {server_filename}')
cmd.run(f'{ue.getCmdPrefix()} {iperf_ue} -s -B {ueIP} {udpSwitch} -i 1 -t {iperf_time * 1.5} {port} &> /tmp/{server_filename} &')
cmd.run(f'{ue.getCmdPrefix()} {iperf_ue} -s -B {ue.getIP()} {udpSwitch} -i 1 -t {iperf_time * 1.5} {port} &> /tmp/{server_filename} &')
cmd.close()
cmd = cls_cmd.getConnection(EPC.IPAddress)
cmd.run(f'rm {EPC.SourceCodePath}/{client_filename}')
cmd.run(f'{cn_iperf_prefix} iperf -c {ueIP} {iperf_opt} {port} &> {EPC.SourceCodePath}/{client_filename}', timeout=iperf_time * 1.5)
cmd.run(f'{cn_iperf_prefix} iperf -c {ue.getIP()} {iperf_opt} {port} &> {EPC.SourceCodePath}/{client_filename}', timeout=iperf_time * 1.5)
cmd.copyin(f'{EPC.SourceCodePath}/{client_filename}', client_filename)
cmd.close()
@@ -899,10 +1005,10 @@ class OaiCiTest():
cmd.close()
if udpIperf:
status, msg = self.Iperf_analyzeV2Server(iperf_opt, server_filename, 1)
self.Iperf_analyzeV2Server(lock, ue.getIP(), ue.getName(), statusQueue, iperf_opt, server_filename, 1)
else:
cmd = cls_cmd.getConnection(EPC.IPAddress)
status, msg = self.Iperf_analyzeV2TCPOutput(cmd, f"{EPC.SourceCodePath}/{client_filename}")
self.Iperf_analyzeV2TCPOutput(lock, ue.getIP(), ue.getName(), statusQueue, iperf_opt, EPC, cmd, f"{EPC.SourceCodePath}/{client_filename}")
cmd.close()
elif self.iperf_direction == "UL":
@@ -914,7 +1020,7 @@ class OaiCiTest():
cmd = cls_cmd.getConnection(ue.getHost())
cmd.run(f'rm /tmp/{client_filename}')
cmd.run(f'{ue.getCmdPrefix()} {iperf_ue} -B {ueIP} -c {cn_target_ip} {iperf_opt} {port} &> /tmp/{client_filename}', timeout=iperf_time*1.5)
cmd.run(f'{ue.getCmdPrefix()} {iperf_ue} -B {ue.getIP()} -c {cn_target_ip} {iperf_opt} {port} &> /tmp/{client_filename}', timeout=iperf_time*1.5)
cmd.copyin(f'/tmp/{client_filename}', client_filename)
cmd.close()
@@ -923,10 +1029,10 @@ class OaiCiTest():
cmd.close()
if udpIperf:
status, msg = self.Iperf_analyzeV2Server(iperf_opt, server_filename, 1)
self.Iperf_analyzeV2Server(lock, ue.getIP(), ue.getName(), statusQueue, iperf_opt, server_filename, 1)
else:
cmd = cls_cmd.getConnection(ue.getHost())
status, msg = self.Iperf_analyzeV2TCPOutput(cmd, f"/tmp/{client_filename}")
self.Iperf_analyzeV2TCPOutput(lock, ue.getIP(), ue.getName(), statusQueue, iperf_opt, EPC, cmd, f"/tmp/{client_filename}")
cmd.close()
elif self.iperf_direction=="BIDIR":
@@ -938,7 +1044,7 @@ class OaiCiTest():
cmd = cls_cmd.getConnection(ue.getHost())
cmd.run(f'rm /tmp/{client_filename}')
cmd.run(f'iperf3 -B {ueIP} -c {cn_target_ip} {iperf_opt} {port} &> /tmp/{client_filename}', timeout=iperf_time*1.5)
cmd.run(f'iperf3 -B {ue.getIP()} -c {cn_target_ip} {iperf_opt} {port} &> /tmp/{client_filename}', timeout=iperf_time*1.5)
cmd.copyin(f'/tmp/{client_filename}', client_filename)
cmd.close()
@@ -946,32 +1052,129 @@ class OaiCiTest():
cmd.copyin(f'{EPC.SourceCodePath}/{server_filename}', server_filename)
cmd.close()
status, msg = self.Iperf_analyzeV2BIDIR(server_filename, client_filename)
self.Iperf_analyzeV2BIDIR(lock, ue.getHost(), ue.getName(), statusQueue, server_filename, client_filename)
elif self.iperf_direction == "IPERF3":
cmd = cls_cmd.getConnection(ue.getHost())
cmd.run(f'rm /tmp/{server_filename}', reportNonZero=False)
port = f'{5002+idx}'
cmd.run(f'{ue.getCmdPrefix()} iperf3 -B {ueIP} -c {cn_target_ip} -p {port} {iperf_opt} --get-server-output &> /tmp/{server_filename}', timeout=iperf_time*1.5)
cmd.run(f'{ue.getCmdPrefix()} iperf3 -B {ue.getIP()} -c {cn_target_ip} -p {port} {iperf_opt} --get-server-output &> /tmp/{server_filename}', timeout=iperf_time*1.5)
cmd.copyin(f'/tmp/{server_filename}', server_filename)
cmd.close()
if udpIperf:
status, msg = self.Iperf_analyzeV2Server(iperf_opt, server_filename, 1)
self.Iperf_analyzeV2Server(lock, ue.getIP(), ue.getName(), statusQueue, iperf_opt, server_filename, 1)
else:
cmd = cls_cmd.getConnection(EPC.IPAddress)
status, msg = self.Iperf_analyzeV2TCPOutput(cmd, f'/tmp/{server_filename}')
self.Iperf_analyzeV2TCPOutput(lock, ue.getIP(), ue.getName(), statusQueue, iperf_opt, EPC, cmd, f'/tmp/{server_filename}')
cmd.close()
else :
raise Exception("Incorrect or missing IPERF direction in XML")
logging.info(f'\u001B[1;37;45m iperf result for {ue_header}\u001B[0m')
for l in msg.split('\n'):
logging.info(f'\u001B[1;35m {l} \u001B[0m')
return (status, f'{ue_header}\n{msg}')
def IperfNoS1(self,HTML,RAN,EPC,CONTAINERS):
raise 'IperfNoS1 not implemented'
SSH = sshconnection.SSHConnection()
if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
check_eNB = True
check_OAI_UE = True
server_on_enb = re.search('-R', str(self.iperf_args))
if server_on_enb is not None:
iServerIPAddr = RAN.eNBIPAddress
iServerUser = RAN.eNBUserName
iServerPasswd = RAN.eNBPassword
iClientIPAddr = self.UEIPAddress
iClientUser = self.UEUserName
iClientPasswd = self.UEPassword
else:
iServerIPAddr = self.UEIPAddress
iServerUser = self.UEUserName
iServerPasswd = self.UEPassword
iClientIPAddr = RAN.eNBIPAddress
iClientUser = RAN.eNBUserName
iClientPasswd = RAN.eNBPassword
if self.iperf_options != 'sink':
# Starting the iperf server
SSH.open(iServerIPAddr, iServerUser, iServerPasswd)
# args SHALL be "-c client -u any"
# -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1
# -B 10.0.1.1 -u -s -i 1 -fm
server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args))
server_options = server_options.replace('-c','-B')
SSH.command(f'rm -f /tmp/tmp_iperf_server_{self.testCase_id}.log', '\$', 5)
SSH.command(f'echo $USER; nohup iperf {server_options} > /tmp/tmp_iperf_server_{self.testCase_id}.log 2>&1 &', iServerUser, 5)
time.sleep(0.5)
SSH.close()
# Starting the iperf client
modified_options = self.Iperf_ComputeModifiedBW(0, 1)
modified_options = modified_options.replace('-R','')
iperf_time = self.Iperf_ComputeTime()
SSH.open(iClientIPAddr, iClientUser, iClientPasswd)
SSH.command(f'rm -f /tmp/tmp_iperf_{self.testCase_id}.log', '\$', 5)
iperf_status = SSH.command(f'stdbuf -o0 iperf {modified_options} 2>&1 | stdbuf -o0 tee /tmp/tmp_iperf_{self.testCase_id}.log', '\$', int(iperf_time)*5.0)
status_queue = SimpleQueue()
lock = Lock()
if iperf_status < 0:
message = 'iperf on OAI UE crashed due to TIMEOUT !'
logging.debug(f'\u001B[1;37;41m {message} \u001B[0m')
clientStatus = -2
else:
if self.iperf_options == 'sink':
clientStatus = 0
status_queue.put(0)
status_queue.put('OAI-UE')
status_queue.put('10.0.1.2')
status_queue.put('Sink Test : no check')
else:
clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options, EPC,SSH)
SSH.close()
# Stopping the iperf server
if self.iperf_options != 'sink':
SSH.open(iServerIPAddr, iServerUser, iServerPasswd)
SSH.command('killall --signal SIGKILL iperf', '\$', 5)
time.sleep(0.5)
SSH.close()
if (clientStatus == -1):
if (os.path.isfile(f'iperf_server_{self.testCase_id}.log')):
os.remove(f'iperf_server_{self.testCase_id}.log')
SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, f'/tmp/tmp_iperf_server_{self.testCase_id}.log', f'iperf_server_{self.testCase_id}_OAI-UE.log')
filename=f'iperf_server_{self.testCase_id}_OAI-UE.log'
self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options,filename,0)
# copying on the EPC server for logCollection
if (clientStatus == -1):
copyin_res = SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, f'/tmp/tmp_iperf_server_{self.testCase_id}.log', f'iperf_server_{self.testCase_id}_OAI-UE.log')
if (copyin_res == 0):
SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, f'iperf_server_{self.testCase_id}_OAI-UE.log', f'{EPC.SourceCodePath}/scripts')
copyin_res = SSH.copyin(iClientIPAddr, iClientUser, iClientPasswd, f'/tmp/tmp_iperf_{self.testCase_id}.log', f'iperf_{self.testCase_id}_OAI-UE.log')
if (copyin_res == 0):
SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, f'iperf_{self.testCase_id}_OAI-UE.log', f'{EPC.SourceCodePath}/scripts')
iperf_noperf = False
if status_queue.empty():
iperf_status = False
else:
iperf_status = True
messages = []
while (not status_queue.empty()):
count = status_queue.get()
if (count < 0):
iperf_status = False
if (count > 0):
iperf_noperf = True
device_id = status_queue.get()
ip_addr = status_queue.get()
message = status_queue.get()
messages.append(f'UE ({device_id})\nIP Address : {ip_addr}\n{message}')
if (iperf_noperf and iperf_status):
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', messages)
elif (iperf_status):
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', messages)
else:
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', messages)
self.AutoTerminateUEandeNB(HTML,RAN,EPC,CONTAINERS)
def Iperf(self,HTML,RAN,EPC,CONTAINERS):
result = re.search('noS1', str(RAN.Initialize_eNB_args))
@@ -984,18 +1187,64 @@ class OaiCiTest():
logging.debug(f'Iperf: iperf_args "{self.iperf_args}" iperf_direction "{self.iperf_direction}" iperf_packetloss_threshold "{self.iperf_packetloss_threshold}" iperf_bitrate_threshold "{self.iperf_bitrate_threshold}" iperf_profile "{self.iperf_profile}" iperf_options "{self.iperf_options}"')
ues = [cls_module_ue.Module_UE(n.strip()) for n in self.ue_ids]
ues = []
for ue_name in self.ue_ids:
ue = cls_module_ue.Module_UE(ue_name)
if not ue.getIP():
logging.error("no IP addresses returned")
HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,EPC,CONTAINERS)
ues.append(ue)
logging.debug(ues)
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = [executor.submit(self.Iperf_Module, EPC, ue, RAN, i, len(ues)) for i, ue in enumerate(ues)]
results = [f.result() for f in futures]
# each result in results is a tuple, first member goes to successes, second to messages
successes, messages = map(list, zip(*results))
if len(successes) == len(ues) and all(successes):
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', messages)
else:
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', messages)
self.dummyIperfVersion = '2.0.10'
#cmd = 'iperf --version'
#logging.debug(cmd + '\n')
#iperfStdout = subprocess.check_output(cmd, shell=True, universal_newlines=True)
#result = re.search('iperf version 2.0.5', str(iperfStdout.strip()))
#if result is not None:
# dummyIperfVersion = '2.0.5'
#result = re.search('iperf version 2.0.10', str(iperfStdout.strip()))
#if result is not None:
# dummyIperfVersion = '2.0.10'
multi_jobs = []
ue_num = len(ues)
i = 0
lock = Lock()
status_queue = SimpleQueue()
for ue in ues:
p = Process(target = self.Iperf_Module ,args = (lock, status_queue, EPC, ue, RAN, i, ue_num))
p.daemon = True
p.start()
multi_jobs.append(p)
i = i + 1
for job in multi_jobs:
job.join()
if (status_queue.empty()):
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB(HTML,RAN,EPC,CONTAINERS)
else:
iperf_status = True
iperf_noperf = False
messages = []
while (not status_queue.empty()):
count = status_queue.get()
if (count < 0):
iperf_status = False
if (count > 0):
iperf_noperf = True
device_id = status_queue.get()
ip_addr = status_queue.get()
msg = status_queue.get()
messages.append(f'UE ({device_id})\nIP Address : {ip_addr}\n{msg}')
if (iperf_noperf and iperf_status):
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', messages)
elif (iperf_status):
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', messages)
else:
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', messages)
self.AutoTerminateUEandeNB(HTML,RAN,EPC,CONTAINERS)
def AnalyzeLogFile_UE(self, UElogFile,HTML,RAN):
if (not os.path.isfile(f'./{UElogFile}')):

View File

@@ -237,7 +237,7 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
sdr_addrs = "mgmt_addr=172.21.19.13,addr=192.168.80.250";
sdr_addrs = "mgmt_addr=172.21.19.13,addr=192.168.10.2";
}
);

View File

@@ -237,7 +237,7 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
sdr_addrs = "mgmt_addr=172.21.19.13,addr=192.168.80.250";
sdr_addrs = "mgmt_addr=172.21.19.13,addr=192.168.10.2";
}
);

View File

@@ -237,7 +237,7 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
sdr_addrs = "mgmt_addr=172.21.19.13,addr=192.168.80.250";
sdr_addrs = "mgmt_addr=172.21.19.13,addr=192.168.10.2";
}
);

View File

@@ -1,219 +0,0 @@
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
Num_Threads_PUSCH = 8;
sa = 1;
gNBs =
(
{
////////// Identification parameters:
gNB_CU_ID = 0xe00;
# cell_type = "CELL_MACRO_GNB";
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 222; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
nr_cellid = 12345678L;
force_256qam_off = 1;
tr_s_preference = "f1";
local_s_if_name = "eth0";
local_s_address = "192.168.68.194";
remote_s_address = "192.168.68.195";
local_s_portc = 501;
local_s_portd = 2153;
remote_s_portc = 500;
remote_s_portd = 2153;
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641280;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640008;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=27,L=48 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 11;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ( { ipv4 = "172.21.16.137";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
E1_INTERFACE =
(
{
type = "cp";
ipv4_cucp = "192.168.68.194";
port_cucp = 38462;
ipv4_cuup = "192.168.68.196";
port_cuup = 38462;
}
)
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "eth0";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.68.194";
};
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config : {
global_log_level = "info";
};

View File

@@ -1,78 +0,0 @@
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
sa = 1;
gNBs =
(
{
////////// Identification parameters:
gNB_CU_ID = 0xe00;
# cell_type = "CELL_MACRO_GNB";
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 222; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
tr_s_preference = "f1";
local_s_if_name = "lo";
local_s_address = "192.168.68.196";
remote_s_address = "192.168.68.195";
local_s_portc = 501;
local_s_portd = 2153;
remote_s_portc = 500;
remote_s_portd = 2153;
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
E1_INTERFACE =
(
{
type = "up";
ipv4_cucp = "192.168.68.194";
ipv4_cuup = "192.168.68.196";
}
)
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.68.196";
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.68.196";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config: {
global_log_level = "info";
};

View File

@@ -218,6 +218,15 @@ THREAD_STRUCT = (
}
);
log_config : {
global_log_level = "info";
};
log_config :
{
global_log_level ="info";
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
f1ap_log_level ="debug";
ngap_log_level ="debug";
};

View File

@@ -1,45 +0,0 @@
# List of known PLMNS
PLMN: {
PLMN0: {
FULLNAME="OpenAirInterface";
SHORTNAME="OAICN";
MNC="92";
MCC="208";
};
};
UE0:
{
USER: {
IMEI="356113022094149";
MANUFACTURER="OAI";
MODEL="LTE SoftModem";
PIN="0000";
};
SIM: {
MSIN="1000000003";
USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f";
OPC="c42449363bbad02b66d16bc975d77cc1";
MSISDN="001011234561010";
};
# Home PLMN Selector with Access Technology
HPLMN= "20892";
# User controlled PLMN Selector with Access Technology
UCPLMN_LIST = ();
# Operator PLMN List
OPLMN_LIST = ("20892");
# Operator controlled PLMN Selector with Access Technology
OCPLMN_LIST = ();
# Forbidden plmns
FPLMN_LIST = ();
# Equivalent home plmns
EHPLMN_LIST = ();
};

View File

@@ -135,6 +135,8 @@ then
exit $STATUS
fi
git log -n1 --pretty=format:\"%s\" > .git/CI_COMMIT_MSG
git merge --ff $TARGET_COMMIT_ID -m "Temporary merge for CI"
STATUS=`git status | egrep -c "You have unmerged paths.|fix conflicts"`

View File

@@ -643,7 +643,7 @@ class EPCManagement():
mySSH = SSH.SSHConnection()
mySSH.open(self.IPAddress, self.UserName, self.Password)
mySSH.command('docker-compose --version', '\$', 5)
result = re.search('docker-compose version 1|Docker Compose version v2', mySSH.getBefore())
result = re.search('docker-compose version 1', mySSH.getBefore())
if result is None:
mySSH.close()
HTML.CreateHtmlTestRow(self.Type, 'KO', CONST.INVALID_PARAMETER)
@@ -659,7 +659,6 @@ class EPCManagement():
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
mySSH.command('if [ -d ' + self.SourceCodePath + '/logs ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/logs ; fi', '\$', 5)
mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts ' + self.SourceCodePath + '/logs', '\$', 5)
mySSH.command('rm -f ' + self.SourceCodePath + '/*.log', '\$', 5)
# deploying and configuring the cassandra database
# container names and services are currently hard-coded.

View File

@@ -120,7 +120,6 @@ Replaces xml_files/enb_usrp210_band7_test_05mhz_tm1.xml
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<direction>DL</direction>
<id>adb_ue_1 adb_ue_2</id>
</testCase>
@@ -179,7 +178,6 @@ Replaces xml_files/enb_usrp210_band7_test_05mhz_tm1.xml
<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 9M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
<direction>UL</direction>
<id>adb_ue_1</id>

View File

@@ -128,7 +128,6 @@
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<direction>DL</direction>
<id>adb_ue_1 adb_ue_2</id>
</testCase>
@@ -157,7 +156,6 @@
<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 9M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<iperf_profile>balanced</iperf_profile>
<direction>UL</direction>
<id>adb_ue_1 adb_ue_2</id>
@@ -168,7 +166,6 @@
<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 9M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
<direction>UL</direction>
<id>adb_ue_1</id>

View File

@@ -114,7 +114,6 @@ Replaces xml_files/enb_usrp210_band7_test_10mhz_tm1.xml
<desc>iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 30M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<iperf_profile>balanced</iperf_profile>
<direction>DL</direction>
<id>adb_ue_1 adb_ue_2</id>

View File

@@ -107,7 +107,6 @@ Replaces xml_files/enb_usrp210_band7_test_10mhz_tm1.xml
<desc>iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 30M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<iperf_profile>balanced</iperf_profile>
<direction>DL</direction>
<id>adb_ue_1 adb_ue_2</id>

View File

@@ -1,174 +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-fdd-10-tm1</htmlTabRef>
<htmlTabName>Test-FDD-10MHz-TM1</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
100000
100001
111110
111111
030111
000001
030311
000002
040511 040613 040616 040651
030411
000001
030211
200000
200001
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111110">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<test_svr_id>0</test_svr_id>
<images_to_pull>oai-enb</images_to_pull>
</testCase>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<test_svr_id>1</test_svr_id>
<images_to_pull>oai-lte-ue</images_to_pull>
</testCase>
<testCase id="100000">
<class>Custom_Command</class>
<desc>Disable Sleep States (hutch)</desc>
<node>hutch</node>
<command>sudo cpupower idle-set -D 0</command>
</testCase>
<testCase id="100001">
<class>Custom_Command</class>
<desc>Disable Sleep States (carabe)</desc>
<node>carabe</node>
<command>sudo cpupower idle-set -D 0</command>
</testCase>
<testCase id="200000">
<class>Custom_Command</class>
<desc>Enable Sleep States (hutch)</desc>
<node>hutch</node>
<command>sudo cpupower idle-set -E</command>
</testCase>
<testCase id="200001">
<class>Custom_Command</class>
<desc>Enable Sleep States (carabe)</desc>
<node>carabe</node>
<command>sudo cpupower idle-set -E</command>
</testCase>
<testCase id="030111">
<class>Deploy_Object</class>
<desc>Deploy eNB (FDD/Band7/10MHz/B200) in a container</desc>
<yaml_path>ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_magma</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="030311">
<class>Deploy_Object</class>
<desc>Deploy LTE-UE (FDD/Band7/10MHz/B200) in a container</desc>
<yaml_path>ci-scripts/yaml_files/lte_b200_fdd_10Mhz_oai_ue_magma</yaml_path>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</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>10</idle_sleep_time_in_sec>
</testCase>
<testCase id="030211">
<class>Undeploy_Object</class>
<desc>Undeploy eNB</desc>
<yaml_path>ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_magma</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="030411">
<class>Undeploy_Object</class>
<desc>Undeploy LTE-UE</desc>
<yaml_path>ci-scripts/yaml_files/lte_b200_fdd_10Mhz_oai_ue_magma</yaml_path>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
</testCase>
<testCase id="040511">
<class>Ping</class>
<desc>ping (10MHz - 20 sec)</desc>
<ping_args>-c 20 192.168.61.200</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
<id>lte_oai_ue_carabe</id>
</testCase>
<testCase id="040613">
<class>Iperf</class>
<desc>iperf (10MHz - DL/10Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 10M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
<direction>DL</direction>
<id>lte_oai_ue_carabe</id>
</testCase>
<testCase id="040616">
<class>Iperf</class>
<desc>iperf (10MHz - DL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
<direction>DL</direction>
<id>lte_oai_ue_carabe</id>
</testCase>
<testCase id="040651">
<class>Iperf</class>
<desc>iperf (10MHz - UL/10Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 10M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
<direction>UL</direction>
<id>lte_oai_ue_carabe</id>
</testCase>
<testCase id="040654">
<class>Iperf</class>
<desc>iperf (10MHz - UL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
<direction>UL</direction>
<id>lte_oai_ue_carabe</id>
</testCase>
</testCaseList>

View File

@@ -1,45 +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>images-clean-up</htmlTabRef>
<htmlTabName>Images Clean-Up</htmlTabName>
<htmlTabIcon>trash</htmlTabIcon>
<TestCaseRequestedList>
222222
333333
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<desc>Clean Test Images on eNB Test Server</desc>
<test_svr_id>0</test_svr_id>
</testCase>
<testCase id="333333">
<class>Clean_Test_Server_Images</class>
<desc>Clean Test Images on LTE-UE Test Server</desc>
<test_svr_id>1</test_svr_id>
</testCase>
</testCaseList>

View File

@@ -113,7 +113,6 @@ Replaces xml_files/enb_usrp210_band7_test_10mhz_tm1.xml
<desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 70M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<iperf_profile>balanced</iperf_profile>
<direction>DL</direction>
<id>adb_ue_1 adb_ue_2</id>

View File

@@ -121,7 +121,6 @@ Replaces xml_files/enb_usrp210_band40_test_05mhz_tm1.xml
<desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced)</desc>
<iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<iperf_profile>balanced</iperf_profile>
<direction>DL</direction>
<id>adb_ue_1 adb_ue_2</id>

View File

@@ -129,7 +129,6 @@
<desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced)</desc>
<iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<iperf_profile>balanced</iperf_profile>
<direction>DL</direction>
<id>adb_ue_1 adb_ue_2</id>

View File

@@ -111,7 +111,6 @@ Replaces xml_files/enb_usrp210_band40_test_10mhz_tm1.xml
<desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(balanced)</desc>
<iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<iperf_profile>balanced</iperf_profile>
<direction>DL</direction>
<id>adb_ue_1 adb_ue_2</id>

View File

@@ -113,7 +113,6 @@ Replaces xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml
<desc>iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(balanced)</desc>
<iperf_args>-u -b 27.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<iperf_profile>balanced</iperf_profile>
<direction>DL</direction>
<id>adb_ue_1 adb_ue_2</id>
@@ -124,7 +123,6 @@ Replaces xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml
<desc>iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 27.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
<direction>DL</direction>
<id>adb_ue_1</id>
@@ -135,7 +133,6 @@ Replaces xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml
<desc>iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(unbalanced)</desc>
<iperf_args>-u -b 27.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
<iperf_profile>unbalanced</iperf_profile>
<direction>DL</direction>
<id>adb_ue_1 adb_ue_2</id>

View File

@@ -111,7 +111,7 @@
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
</testCase>
@@ -168,14 +168,14 @@
<class>Custom_Command</class>
<desc>Trigger Reestablishment</desc>
<node>ofqot</node>
<command>echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'</command>
<command>echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'force-remove UE RNTI [0-9a-f]{4} from RLC to trigger reestablishment'</command>
<command_fail>yes</command_fail>
</testCase>
<testCase id="060002">
<class>Custom_Command</class>
<desc>Verify Reestablishment</desc>
<node>ofqot</node>
<command>echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'</command>
<command>echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1 reconf_after_reestab 1'</command>
<command_fail>yes</command_fail>
</testCase>

View File

@@ -1,166 +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-F1-E1-B200</htmlTabRef>
<htmlTabName>40 MHz TDD F1+E1 SA</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
333333
300000
310000
330101
330102
330103
310001
350000
370001
370000
370002
310011
310002
330201
200000
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="333333">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<test_svr_id>0</test_svr_id>
<images_to_pull>oai-gnb oai-nr-cuup</images_to_pull>
</testCase>
<testCase id="310000">
<class>Initialize_UE</class>
<desc>Initialize Quectel</desc>
<id>idefix</id>
</testCase>
<testCase id="310002">
<class>Terminate_UE</class>
<desc>Terminate Quectel</desc>
<id>idefix</id>
</testCase>
<testCase id="310001">
<class>Attach_UE</class>
<desc>Attach Quectel</desc>
<id>idefix</id>
</testCase>
<testCase id="310011">
<class>Detach_UE</class>
<desc>Detach Quectel</desc>
<id>idefix</id>
</testCase>
<testCase id="330101">
<class>Deploy_Object</class>
<desc>Deploy gNB-CU-CP in a container</desc>
<yaml_path>ci-scripts/yaml_files/sa_e1_b200_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<services>gnb_cucp</services>
</testCase>
<testCase id="330102">
<class>Deploy_Object</class>
<desc>Deploy gNB-CU-UP in a container</desc>
<yaml_path>ci-scripts/yaml_files/sa_e1_b200_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<services>gnb_cuup</services>
</testCase>
<testCase id="330103">
<class>Deploy_Object</class>
<desc>Deploy gNB-DU (TDD/Band78/40MHz/B200) in a container</desc>
<yaml_path>ci-scripts/yaml_files/sa_e1_b200_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<services>gnb_du_tdd</services>
</testCase>
<testCase id="300000">
<class>Custom_Command</class>
<desc>Disable Sleep States</desc>
<node>ofqot</node>
<command>sudo cpupower idle-set -D 0</command>
</testCase>
<testCase id="200000">
<class>Custom_Command</class>
<desc>Enable Sleep States</desc>
<node>ofqot</node>
<command>sudo cpupower idle-set -E</command>
</testCase>
<testCase id="350000">
<class>Ping</class>
<desc>Ping: 20pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 20 %cn_ip%</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>25</ping_rttavg_threshold>
</testCase>
<testCase id="370000">
<class>Iperf</class>
<desc>iperf (DL/80Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 80M -t 30 -i 1 -fm</iperf_args>
<direction>DL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>10</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="370001">
<class>Iperf</class>
<desc>iperf (UL/8Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 8M -t 30 -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="370002">
<class>Iperf</class>
<desc>iperf (BIDIR TCP)(10 sec)(single-ue profile)</desc>
<iperf_args>-t 20 --bidir</iperf_args>
<direction>BIDIR</direction>
<id>idefix</id>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="330201">
<class>Undeploy_Object</class>
<desc>Undeploy CU-DU</desc>
<yaml_path>ci-scripts/yaml_files/sa_e1_b200_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<d_retx_th>10,100,100,100</d_retx_th>
<u_retx_th>10,100,100,100</u_retx_th>
</testCase>
</testCaseList>

View File

@@ -1,48 +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-F1-E1-B200-terminate</htmlTabRef>
<htmlTabName>Tear-down</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
330201
222222
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="330201">
<class>Undeploy_Object</class>
<desc>Undeploy CU-CP/CU-UP/DU</desc>
<yaml_path>ci-scripts/yaml_files/sa_e1_b200_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<desc>Clean Test Images on Test Server</desc>
<test_svr_id>0</test_svr_id>
</testCase>
</testCaseList>

View File

@@ -39,22 +39,22 @@
110011
110001
150001
160001
100002
160002
150001
110011
110001
150000
170001
170000
170002
110011
110002
100001
130201
200000
</TestCaseRequestedList>
<!--
070001
070000
070002
050002
050003
-->
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="110000">
@@ -118,7 +118,7 @@
<testCase id="100002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
</testCase>
<testCase id="150000">
@@ -159,19 +159,19 @@
<testCase id="170000">
<class>Iperf</class>
<desc>iperf (DL/80Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 80M -t 30 -i 1 -fm</iperf_args>
<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>10</iperf_packetloss_threshold>
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="170001">
<class>Iperf</class>
<desc>iperf (UL/8Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 8M -t 30 -i 1 -fm</iperf_args>
<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>
@@ -181,36 +181,21 @@
<testCase id="170002">
<class>Iperf</class>
<desc>iperf (BIDIR TCP)(20 sec)(single-ue profile)</desc>
<iperf_args>-t 20 --bidir</iperf_args>
<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="160001">
<class>Custom_Command</class>
<desc>Trigger Reestablishment (on DU)</desc>
<node>ofqot</node>
<command>echo ci force_reestab | nc -N 192.168.68.195 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'</command>
<command_fail>yes</command_fail>
</testCase>
<testCase id="160002">
<class>Custom_Command</class>
<desc>Verify Reestablishment (on CU)</desc>
<node>ofqot</node>
<command>echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'</command>
<command_fail>yes</command_fail>
</testCase>
<testCase id="130201">
<class>Undeploy_Object</class>
<desc>Undeploy CU-DU</desc>
<yaml_path>ci-scripts/yaml_files/sa_f1_b200_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<d_retx_th>10,100,100,100</d_retx_th>
<u_retx_th>10,100,100,100</u_retx_th>
<d_retx_th>1,100,100,100</d_retx_th>
<u_retx_th>1,100,100,100</u_retx_th>
</testCase>
</testCaseList>

View File

@@ -27,6 +27,7 @@
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
230201
222222
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
@@ -38,4 +39,10 @@
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<desc>Clean Test Images on Test Server</desc>
<test_svr_id>0</test_svr_id>
</testCase>
</testCaseList>

View File

@@ -105,7 +105,7 @@
<testCase id="200002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
</testCase>
@@ -162,14 +162,14 @@
<class>Custom_Command</class>
<desc>Trigger Reestablishment</desc>
<node>ofqot</node>
<command>echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'</command>
<command>echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'force-remove UE RNTI [0-9a-f]{4} from RLC to trigger reestablishment'</command>
<command_fail>yes</command_fail>
</testCase>
<testCase id="260002">
<class>Custom_Command</class>
<desc>Verify Reestablishment</desc>
<node>ofqot</node>
<command>echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'</command>
<command>echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1 reconf_after_reestab 1'</command>
<command_fail>yes</command_fail>
</testCase>

View File

@@ -52,7 +52,7 @@
<testCase id="090102">
<class>Initialize_OAI_UE</class>
<desc>Initialize NR UE USRP</desc>
<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 50 --log_config.global_log_options level,nocolor,time</Initialize_OAI_UE_args>
<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 50 --rrc_config_path . --log_config.global_log_options level,nocolor,time</Initialize_OAI_UE_args>
<air_interface>NR</air_interface>
</testCase>

View File

@@ -52,7 +52,7 @@
<testCase id="090104">
<class>Initialize_OAI_UE</class>
<desc>Initialize NR UE USRP</desc>
<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --log_config.global_log_options level,nocolor,time</Initialize_OAI_UE_args>
<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --rrc_config_path . --log_config.global_log_options level,nocolor,time</Initialize_OAI_UE_args>
<air_interface>NR</air_interface>
</testCase>

View File

@@ -1,39 +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>epc-deploy-tab</htmlTabRef>
<htmlTabName>EPC-Deploy</htmlTabName>
<htmlTabIcon>log-in</htmlTabIcon>
<TestCaseRequestedList>
000100
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="000100">
<class>Deploy_EPC</class>
<desc>Deploy all EPC containers</desc>
<parameters>yaml_files/magma_lte_20892</parameters>
</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>epc-undeploy-tab</htmlTabRef>
<htmlTabName>EPC-Undeploy</htmlTabName>
<htmlTabIcon>log-out</htmlTabIcon>
<TestCaseRequestedList>
000200
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="000200">
<class>Undeploy_EPC</class>
<desc>Undeploy all EPC containers</desc>
</testCase>
</testCaseList>

View File

@@ -23,7 +23,7 @@ services:
privileged: true
container_name: rfsim5g-oai-nr-ue
environment:
USE_ADDITIONAL_OPTIONS: --phy-test --rfsim --noS1 --reconfig-file etc/rrc/reconfig.raw --rbconfig-file etc/rrc/rbconfig.raw --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --phy-test --rfsim --noS1 --rrc_config_path etc/rrc/ --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
- rrc.config:/opt/oai-nr-ue/etc/rrc/

View File

@@ -23,7 +23,7 @@ services:
privileged: true
container_name: rfsim5g-oai-nr-ue
environment:
USE_ADDITIONAL_OPTIONS: --do-ra --rfsim --noS1 --reconfig-file etc/rrc/reconfig.raw --rbconfig-file etc/rrc/rbconfig.raw --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --do-ra --rfsim --noS1 --rrc_config_path etc/rrc/ --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
- rrc.config:/opt/oai-nr-ue/etc/rrc/

View File

@@ -23,7 +23,7 @@ services:
privileged: true
container_name: rfsim5g-oai-nr-ue
environment:
USE_ADDITIONAL_OPTIONS: --do-ra --rfsim --noS1 --reconfig-file etc/rrc/reconfig.raw --rbconfig-file etc/rrc/rbconfig.raw --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --do-ra --rfsim --noS1 --rrc_config_path etc/rrc/ --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
- rrc.config:/opt/oai-nr-ue/etc/rrc/

View File

@@ -1,21 +0,0 @@
version: '3.8'
services:
lte_ue0:
image: oai-lte-ue:latest
privileged: true
container_name: lte-b200-ue-fdd-10Mhz-tm1
environment:
USE_B2XX: 'yes'
USE_ADDITIONAL_OPTIONS: -C 2680000000 -r 50 --ue-rxgain 120 --ue-txgain 0 --ue-max-power 0 --ue-scan-carrier --log_config.global_log_options level,nocolor,time
volumes:
- ../../conf_files/lteue.usim-ci-magma.conf:/opt/oai-lte-ue/etc/ue_usim.conf
- /dev:/dev
network_mode: "host"
healthcheck:
# pgrep does NOT work
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
interval: 10s
timeout: 5s
retries: 5

View File

@@ -1,20 +0,0 @@
version: '3.8'
services:
enb_mono_fdd:
image: oai-enb:latest
privileged: true
container_name: lte-b200-enb-fdd-10Mhz-tm1
environment:
USE_B2XX: 'yes'
USE_ADDITIONAL_OPTIONS: --RUs.[0].max_rxgain 120 --eNBs.[0].mme_ip_address.[0].ipv4 192.168.61.195 --log_config.global_log_options level,nocolor,time,line_num,function
volumes:
- ../../conf_files/enb.band7.50prb.usrpb200.tm1.conf:/opt/oai-enb/etc/enb.conf
- /dev:/dev
network_mode: "host"
healthcheck:
# pgrep does NOT work
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
interval: 10s
timeout: 5s
retries: 5

View File

@@ -1,198 +0,0 @@
version: '3.8'
services:
cassandra:
image: cassandra:2.1
container_name: prod-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: prod-db-init
depends_on: [cassandra]
deploy:
restart_policy:
condition: on-failure
max_attempts: 10
networks:
private_net:
ipv4_address: 192.168.68.4
volumes:
- ./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: oaisoftwarealliance/oai-hss:develop
container_name: prod-oai-hss
privileged: true
depends_on: [cassandra]
networks:
private_net:
ipv4_address: 192.168.68.3
public_net:
ipv4_address: 192.168.61.194
environment:
TZ: Europe/Paris
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: oai2.ipv4
FIRST_IMSI: 208921000000001
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: prod-redis
privileged: true
networks:
public_net:
ipv4_address: 192.168.61.198
volumes:
- ./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.198 -p 6380 ping"
interval: 10s
timeout: 5s
retries: 5
magma_mme:
image: magma-mme:production
container_name: prod-magma-mme
hostname: mme
privileged: true
depends_on: [oai_hss, redis]
networks:
public_net:
ipv4_address: 192.168.61.195
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:
- ./mme_fd.sprint.conf:/magma-mme/etc/mme_fd.conf.tmplt
- ./mme.conf:/magma-mme/etc/mme.conf
- ./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: oaisoftwarealliance/oai-spgwc:develop
privileged: true
depends_on: [magma_mme]
container_name: prod-oai-spgwc
networks:
public_net:
ipv4_address: 192.168.61.196
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: oai2.ipv4
DEFAULT_APN_NI_1: oai.ipv4
UE_IP_ADDRESS_POOL_1: '12.1.1.2 - 12.1.1.254'
UE_IP_ADDRESS_POOL_2: '12.0.0.2 - 12.0.0.254'
MCC: '208'
MNC: '92'
MNC03: '092'
TAC: 1
GW_ID: 1
REALM: openairinterface.org
UE_MTU_IPV4: 1500
healthcheck:
test: /bin/bash -c "pgrep oai_spgwc"
interval: 10s
timeout: 5s
retries: 5
oai_spgwu:
image: oaisoftwarealliance/oai-spgwu-tiny:develop
privileged: true
container_name: prod-oai-spgwu-tiny
depends_on: [oai_spgwc]
networks:
public_net:
ipv4_address: 192.168.61.197
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.196
NETWORK_UE_IP: '12.1.1.0/24'
NETWORK_UE_NAT_OPTION: 'yes'
MCC: '208'
MNC: '92'
MNC03: '092'
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: oaisoftwarealliance/trf-gen-cn5g:focal
privileged: true
container_name: prod-trf-gen
networks:
public_net:
ipv4_address: 192.168.61.200
entrypoint: /bin/bash -c "ip route add 12.1.1.0/24 via 192.168.61.197 dev eth0; sleep infinity"
healthcheck:
test: /bin/bash -c "ip route | grep '12.1.1.0'"
interval: 10s
timeout: 5s
retries: 5
networks:
private_net:
name: prod-oai-private-net
ipam:
config:
- subnet: 192.168.68.0/26
driver_opts:
com.docker.network.bridge.name: "oai-priv-net"
public_net:
name: prod-oai-public-net
ipam:
config:
- subnet: 192.168.61.192/26
driver_opts:
com.docker.network.bridge.name: "oai-pub-net"

View File

@@ -1,36 +0,0 @@
#!/bin/bash
INSTANCE=1
PREFIX='/magma-mme/etc'
MY_REALM='openairinterface.org'
declare -A MME_CONF
pushd $PREFIX
MME_CONF[@MME_S6A_IP_ADDR@]="192.168.61.195"
MME_CONF[@INSTANCE@]=$INSTANCE
MME_CONF[@PREFIX@]=$PREFIX
MME_CONF[@REALM@]=$MY_REALM
MME_CONF[@MME_FQDN@]="mme.${MME_CONF[@REALM@]}"
MME_CONF[@HSS_HOSTNAME@]='hss'
MME_CONF[@HSS_FQDN@]="${MME_CONF[@HSS_HOSTNAME@]}.${MME_CONF[@REALM@]}"
MME_CONF[@HSS_IP_ADDR@]="192.168.61.194"
cp mme_fd.conf.tmplt $PREFIX/mme_fd.conf
for K in "${!MME_CONF[@]}"; do
egrep -lRZ "$K" $PREFIX/mme_fd.conf | xargs -0 -l sed -i -e "s|$K|${MME_CONF[$K]}|g"
ret=$?;[[ ret -ne 0 ]] && echo "Tried to replace $K with ${MME_CONF[$K]}"
done
sed -i -e "s@etc/freeDiameter@etc@" /magma-mme/etc/mme_fd.conf
sed -i -e "s@bind: 127.0.0.1@bind: 192.168.61.198@" /etc/magma/redis.yml
# Generate freeDiameter certificate
popd
cd /magma-mme/scripts
./check_mme_s6a_certificate $PREFIX mme.${MME_CONF[@REALM@]}
cd /magma-mme
nohup /magma-mme/bin/sctpd > /var/log/sctpd.log 2>&1 &
sleep 5
/magma-mme/bin/oai_mme -c /magma-mme/etc/mme.conf

View File

@@ -1,133 +0,0 @@
# generated by generate_mme_config_script.py
MME :
{
REALM = "openairinterface.org"
PID_DIRECTORY = "/var/run";
MAXENB = 8; # power of 2
MAXUE = 16; # power of 2
RELATIVE_CAPACITY = 10;
EMERGENCY_ATTACH_SUPPORTED = "no";
UNAUTHENTICATED_IMSI_SUPPORTED = "no";
# EPS network feature support
EPS_NETWORK_FEATURE_SUPPORT_IMS_VOICE_OVER_PS_SESSION_IN_S1 = "no"; # DO NOT CHANGE
EPS_NETWORK_FEATURE_SUPPORT_EMERGENCY_BEARER_SERVICES_IN_S1_MODE = "no"; # DO NOT CHANGE
EPS_NETWORK_FEATURE_SUPPORT_LOCATION_SERVICES_VIA_EPC = "no"; # DO NOT CHANGE
EPS_NETWORK_FEATURE_SUPPORT_EXTENDED_SERVICE_REQUEST = "no"; # DO NOT CHANGE
# Display statistics about whole system (expressed in seconds)
MME_STATISTIC_TIMER = 10;
IP_CAPABILITY = "IPV4"; # UE PDN_TYPE
USE_STATELESS = "";
INTERTASK_INTERFACE :
{
# max queue size per task
ITTI_QUEUE_SIZE = 2000000;
};
S6A :
{
S6A_CONF = "/magma-mme/etc/mme_fd.conf"; # YOUR MME freeDiameter config file path
HSS_HOSTNAME = "hss.openairinterface.org";
HSS_REALM = "openairinterface.org";
};
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 8;
SCTP_OUTSTREAMS = 8;
};
# ------- S1AP definitions
S1AP :
{
# outcome drop timer value (seconds)
S1AP_OUTCOME_TIMER = 10;
};
# ------- MME served GUMMEIs
GUMMEI_LIST = (
{ MCC="208" ; MNC="92"; MME_GID="32768" ; MME_CODE="3"; }
);
# ------- MME served TAIs
TAI_LIST = (
{MCC="208" ; MNC="92"; TAC = "1"; }
);
TAC_LIST = (
{MCC="208" ; MNC="92"; TAC = "1"; }
);
CSFB :
{
NON_EPS_SERVICE_CONTROL = "OFF";
CSFB_MCC = "208";
CSFB_MNC = "92";
LAC = "1";
};
NAS :
{
ORDERED_SUPPORTED_INTEGRITY_ALGORITHM_LIST = [ "EIA2" , "EIA1" , "EIA0" ];
ORDERED_SUPPORTED_CIPHERING_ALGORITHM_LIST = [ "EEA0" , "EEA1" , "EEA2" ];
T3402 = 1 # in minutes (default is 12 minutes)
T3412 = 54 # in minutes (default is 54 minutes, network dependent)
T3422 = 6 # in seconds (default is 6s)
T3450 = 6 # in seconds (default is 6s)
T3460 = 6 # in seconds (default is 6s)
T3470 = 6 # in seconds (default is 6s)
T3485 = 8 # UNUSED in seconds (default is 8s)
T3486 = 8 # UNUSED in seconds (default is 8s)
T3489 = 4 # UNUSED in seconds (default is 4s)
T3495 = 8 # UNUSED in seconds (default is 8s)
};
SGS :
{
TS6_1 = 10 # in seconds (default is 10s)
TS8 = 4 # in seconds (default is 4s)
TS9 = 2 # in seconds (default is 4s)
TS10 = 4 # in seconds (default is 4s)
TS13 = 4 # in seconds (default is 4s)
};
NETWORK_INTERFACES :
{
MME_INTERFACE_NAME_FOR_S1_MME = "eth0";
MME_IPV4_ADDRESS_FOR_S1_MME = "192.168.61.195/24";
MME_INTERFACE_NAME_FOR_S11_MME = "eth0";
MME_IPV4_ADDRESS_FOR_S11_MME = "192.168.61.195/24";
MME_PORT_FOR_S11_MME = 2123;
};
LOGGING :
{
OUTPUT = "CONSOLE";
THREAD_SAFE = "no";
COLOR = "no";
SCTP_LOG_LEVEL = "ERROR";
GTPV1U_LOG_LEVEL = "INFO";
SPGW_APP_LOG_LEVEL = "INFO";
UDP_LOG_LEVEL = "INFO";
S1AP_LOG_LEVEL = "DEBUG";
NAS_LOG_LEVEL = "INFO";
MME_APP_LOG_LEVEL = "DEBUG";
GTPV2C_LOG_LEVEL = "INFO";
S11_LOG_LEVEL = "DEBUG";
S6A_LOG_LEVEL = "DEBUG";
UTIL_LOG_LEVEL = "INFO";
ITTI_LOG_LEVEL = "ERROR";
MME_SCENARIO_PLAYER_LOG_LEVEL = "ERROR";
ASN1_VERBOSITY = "INFO";
};
S-GW :
{
SGW_IPV4_ADDRESS_FOR_S11 = "192.168.61.196";
};
};

View File

@@ -1,169 +0,0 @@
# -------- Local ---------
# Uncomment if the framework cannot resolv it.
Identity = "@MME_FQDN@";
Realm = "@REALM@";
# TLS configuration (see previous section)
TLS_Cred = "@PREFIX@/freeDiameter/mme.cert.pem",
"@PREFIX@/freeDiameter/mme.key.pem";
TLS_CA = "@PREFIX@/freeDiameter/mme.cacert.pem";
# Disable use of TCP protocol (only listen and connect in SCTP)
# Default : TCP enabled
No_SCTP;
# This option is ignored if freeDiameter is compiled with DISABLE_SCTP option.
# Prefer TCP instead of SCTP for establishing new connections.
# This setting may be overwritten per peer in peer configuration blocs.
# Default : SCTP is attempted first.
Prefer_TCP;
No_IPv6;
# Overwrite the number of SCTP streams. This value should be kept low,
# especially if you are using TLS over SCTP, because it consumes a lot of
# resources in that case. See tickets 19 and 27 for some additional details on
# this.
# Limit the number of SCTP streams
SCTP_streams = 3;
# By default, freeDiameter acts as a Diameter Relay Agent by forwarding all
# messages it cannot handle locally. This parameter disables this behavior.
NoRelay;
# Use RFC3588 method for TLS protection, where TLS is negociated after CER/CEA exchange is completed
# on the unsecure connection. The alternative is RFC6733 mechanism, where TLS protects also the
# CER/CEA exchange on a dedicated secure port.
# This parameter only affects outgoing connections.
# The setting can be also defined per-peer (see Peers configuration section).
# Default: use RFC6733 method with separate port for TLS.
#TLS_old_method;
AppServThreads = 4;
# Specify the addresses on which to bind the listening server. This must be
# specified if the framework is unable to auto-detect these addresses, or if the
# auto-detected values are incorrect. Note that the list of addresses is sent
# in CER or CEA message, so one should pay attention to this parameter if some
# adresses should be kept hidden.
ListenOn = "@MME_S6A_IP_ADDR@";
Port = 3870;
SecPort = 5870;
# -------- Extensions ---------
# Uncomment (and create rtd.conf) to specify routing table for this peer.
#LoadExtension = "/usr/local/lib/freeDiameter/rt_default.fdx" : "rtd.conf";
#LoadExtension = "/usr/local/lib/freeDiameter/_sample.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/app_acct.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/app_diameap.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/app_radgw.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/app_redirect.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/app_sip.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dbg_interactive.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dbg_monitor.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dbg_msg_dumps.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dbg_msg_timings.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dbg_rt.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_3gpp2_avps.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_CreditControl.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_CxDx.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Gx.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_NAS.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Ro.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Rx.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_S6mS6n.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_SGd.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_SLh.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Sd.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Sh.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_T4.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_T6aT6bT7.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Tsp.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_dcca.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_dcca_3gpp.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_dcca_starent.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_draftload_avps.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_eap.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_etsi283034_avps.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_legacy_xml.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_mip6a.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_mip6i.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_nas_mipv6.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_nasreq.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc4004_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc4006bis_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc4072_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc4590_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc5447_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc5580_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc5777_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc5778_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc6734_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc6942_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc7155_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc7683_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc7944_avps.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_sip.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29061_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29128_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29154_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29173_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29212_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29214_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29215_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29217_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29229_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29272_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29273_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29329_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29336_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29337_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29338_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29343_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29344_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29345_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29368_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29468_avps.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts32299_avps.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/rt_busypeers.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/rt_default.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/rt_ereg.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/rt_ignore_dh.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/rt_load_balance.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/rt_randomize.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/rt_redirect.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/test_acct.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/test_app.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/test_hss.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/test_netemul.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/test_rt_any.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/test_sip.fdx";
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Rf.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_S6as6d.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_S6t.fdx";
LoadExtension = "/usr/local/lib/freeDiameter/dict_S6c.fdx";
# -------- Peers ---------
# The framework will actively attempt to establish and maintain a connection
# with the peers listed here.
# For only accepting incoming connections, see the acl_wl.fx extension.
# ConnectPeer
# Declare a remote peer to which this peer must maintain a connection.
# In addition, this allows specifying non-default parameters for this peer only
# (for example disable SCTP with this peer, or use RFC3588-flavour TLS).
# Note that by default, if a peer is not listed as a ConnectPeer entry, an
# incoming connection from this peer will be rejected. If you want to accept
# incoming connections from other peers, see the acl_wl.fdx? extension which
# allows exactly this.
ConnectPeer= "@HSS_FQDN@" { ConnectTo = "@HSS_IP_ADDR@"; No_SCTP ; No_IPv6; Prefer_TCP; No_TLS; port = 3868;};

View File

@@ -1,33 +0,0 @@
#
# Copyright (c) 2016-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.
# Jinja template for Redis configuration
# See the default config file for options and explanations:
# https://github.com/antirez/redis/blob/unstable/redis.conf
# TODO: make sensible, production-aware config decisions
bind 192.168.61.198
port 6380
daemonize no
loglevel notice
timeout 0
databases 1
dbfilename redis_dump.rdb
dir /data
# Save the DB on disk
save 900 1
save 300 10
save 60 1000

View File

@@ -1,68 +0,0 @@
version: '3.8'
services:
gnb_cucp:
image: oai-gnb:latest
privileged: true
container_name: sa-cucp-gnb
environment:
USE_ADDITIONAL_OPTIONS: --sa --log_config.global_log_options level,nocolor,time,line_num,function
volumes:
- ../../conf_files/gnb-cucp.sa.f1.quectel.conf:/opt/oai-gnb/etc/gnb.conf
networks:
public_net:
ipv4_address: 192.168.68.194
healthcheck:
# pgrep does NOT work
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
interval: 10s
timeout: 5s
retries: 5
gnb_cuup:
image: oai-nr-cuup:latest
privileged: true
container_name: sa-cuup-gnb
environment:
USE_ADDITIONAL_OPTIONS: --sa --log_config.global_log_options level,nocolor,time,line_num,function
volumes:
- ../../conf_files/gnb-cuup.sa.f1.quectel.conf:/opt/oai-gnb/etc/gnb.conf
networks:
public_net:
ipv4_address: 192.168.68.196
healthcheck:
# pgrep does NOT work
test: /bin/bash -c "ps aux | grep -v grep | grep -c nr-cuup"
interval: 10s
timeout: 5s
retries: 5
gnb_du_tdd:
image: oai-gnb:latest
privileged: true
container_name: sa-du-b200-gnb
environment:
USE_B2XX: 'yes'
USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14
volumes:
- ../../conf_files/gnb-du.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf
- /dev:/dev
networks:
public_net:
ipv4_address: 192.168.68.195
#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

@@ -6,9 +6,11 @@ services:
privileged: true
container_name: sa-cu-gnb
environment:
USE_ADDITIONAL_OPTIONS: --sa --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function
USE_B2XX: 'yes'
USE_ADDITIONAL_OPTIONS: --sa --log_config.global_log_options level,nocolor,time,line_num,function
volumes:
- ../../conf_files/gnb-cu.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf
- /dev:/dev
networks:
public_net:
ipv4_address: 192.168.68.194
@@ -26,7 +28,7 @@ services:
container_name: sa-du-b200-gnb
environment:
USE_B2XX: 'yes'
USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14
USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14
volumes:
- ../../conf_files/gnb-du.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf
- /dev:/dev

View File

@@ -120,8 +120,6 @@ Options:
Builds Coverity-Scan objects for upload
--disable-deadline
Disables deadline scheduler of Linux kernel (>=3.14.x).
--trace-asn1c-enc-dec
Output asn1c logging traces via OAI logging system.
--enable-deadline
Enable deadline scheduler of Linux kernel (>=3.14.x).
--disable-cpu-affinity
@@ -317,7 +315,7 @@ function main() {
-P | --phy_simulators)
SIMUS_PHY=1
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
TARGET_LIST="$TARGET_LIST dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim"
TARGET_LIST="$TARGET_LIST dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_psbchsim"
echo_info "Will compile dlsim, ulsim, ..."
shift;;
-s | --check)
@@ -418,10 +416,6 @@ function main() {
sleep 2
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_MEMORY=ON -DSANITIZE_ADDRESS=OFF -DSANITIZE_UNDEFINED=OFF"
shift;;
--trace-asn1c-enc-dec)
CMAKE_CMD="$CMAKE_CMD -DTRACE_ASN1C_ENC_DEC=ON"
echo_info "Enabling asn1c internal traces via OAI logging system"
shift 1;;
-h | --help)
print_help
exit 1;;
@@ -529,7 +523,7 @@ function main() {
echo_info "Doxygen generation log is located here: $doxygen_log"
echo_info "Generating Doxygen files....please wait"
(
$CMAKE --build . --target doc
cmake3 --build . --target doc
) >& $doxygen_log
fi

View File

@@ -32,7 +32,7 @@ OS_DISTRO=$(grep "^ID=" /etc/os-release | sed "s/ID=//" | sed "s/\"//g")
OS_RELEASE=$(grep "^VERSION_ID=" /etc/os-release | sed "s/VERSION_ID=//" | sed "s/\"//g")
case "$OS_DISTRO" in
fedora) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;;
rhel) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake3" ;;
rhel) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;;
rocky) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;;
centos) OS_BASEDISTRO="centos"; INSTALLER="yum"; CMAKE="cmake3" ;;
debian) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;;
@@ -226,11 +226,11 @@ compilations() {
local verbose=$([ "$VERBOSE_COMPILE" == "1" ] && echo "-v" || echo "")
echo cd $OPENAIR_DIR/cmake_targets/$dir/build
cd $OPENAIR_DIR/cmake_targets/$dir/build
echo_info "Running \"$CMAKE --build . $verbose --target $targets -- -j$(nproc)\"" $green
echo_info "Running \"cmake --build . $verbose --target $targets -- -j$(nproc)\"" $green
echo "Log file for compilation is being written to: $dlog/$logfile"
set +e
{
$CMAKE --build . $verbose --target $targets -- -j$(nproc)
cmake --build . $verbose --target $targets -- -j$(nproc)
ret=$?
} > $dlog/$logfile 2>&1
if [ "$VERBOSE_CI" == "1" ]; then

View File

@@ -45,7 +45,6 @@
#include "common/config/config_userapi.h"
#include <time.h>
#include <sys/time.h>
#include <stdatomic.h>
#include "common/utils/LOG/log_extern.h"
// main log variables
@@ -283,7 +282,7 @@ void log_getconfig(log_t *g_log)
int ret = config_get( logparams_defaults,sizeof(logparams_defaults)/sizeof(paramdef_t),CONFIG_STRING_LOG_PREFIX);
if (ret <0) {
fprintf(stderr,"[LOG] init aborted, configuration couldn't be performed\n");
fprintf(stderr,"[LOG] init aborted, configuration couldn't be performed");
return;
}
@@ -811,7 +810,7 @@ void logClean (void)
}
}
static atomic_bool stop_flush_mem_to_file = false;
extern int oai_exit;
void flush_mem_to_file(void)
{
int fp;
@@ -822,7 +821,7 @@ void flush_mem_to_file(void)
pthread_setname_np( pthread_self(), "flush_mem_to_file");
while (!atomic_load(&stop_flush_mem_to_file)) {
while (!oai_exit) {
pthread_mutex_lock(&log_mem_lock);
log_mem_write_flag=0;
pthread_cond_wait(&log_mem_notify, &log_mem_lock);
@@ -982,7 +981,6 @@ void close_log_mem(void){
char f_name[1024];
if(log_mem_flag==1){
atomic_store(&stop_flush_mem_to_file, false);
log_mem_d[0].enable_flag=0;
log_mem_d[1].enable_flag=0;
usleep(10); // wait for log writing

View File

@@ -969,25 +969,25 @@ ID = LEGACY_OSA_TRACE
GROUP = ALL:LEGACY_OSA:LEGACY_GROUP_TRACE:LEGACY
FORMAT = string,log
ID = LEGACY_ASN1_INFO
DESC = ASN1 legacy logs - info level
GROUP = ALL:LEGACY_ASN1:LEGACY_GROUP_INFO:LEGACY
ID = LEGACY_ASN_INFO
DESC = ASN legacy logs - info level
GROUP = ALL:LEGACY_ASN:LEGACY_GROUP_INFO:LEGACY
FORMAT = string,log
ID = LEGACY_ASN1_ERROR
DESC = ASN1 legacy logs - error level
GROUP = ALL:LEGACY_ASN1:LEGACY_GROUP_ERROR:LEGACY
ID = LEGACY_ASN_ERROR
DESC = ASN legacy logs - error level
GROUP = ALL:LEGACY_ASN:LEGACY_GROUP_ERROR:LEGACY
FORMAT = string,log
ID = LEGACY_ASN1_WARNING
DESC = ASN1 legacy logs - warning level
GROUP = ALL:LEGACY_ASN1:LEGACY_GROUP_WARNING:LEGACY
ID = LEGACY_ASN_WARNING
DESC = ASN legacy logs - warning level
GROUP = ALL:LEGACY_ASN:LEGACY_GROUP_WARNING:LEGACY
FORMAT = string,log
ID = LEGACY_ASN1_DEBUG
DESC = ASN1 legacy logs - debug level
GROUP = ALL:LEGACY_ASN1:LEGACY_GROUP_DEBUG:LEGACY
ID = LEGACY_ASN_DEBUG
DESC = ASN legacy logs - debug level
GROUP = ALL:LEGACY_ASN:LEGACY_GROUP_DEBUG:LEGACY
FORMAT = string,log
ID = LEGACY_ASN1_TRACE
DESC = ASN1 legacy logs - trace level
GROUP = ALL:LEGACY_ASN1:LEGACY_GROUP_TRACE:LEGACY
ID = LEGACY_ASN_TRACE
DESC = ASN legacy logs - trace level
GROUP = ALL:LEGACY_ASN:LEGACY_GROUP_TRACE:LEGACY
FORMAT = string,log
ID = LEGACY_SIM_INFO

View File

@@ -1,4 +1,4 @@
add_library(tracer_utils OBJECT configuration.c database.c event.c handler.c utils.c)
add_library(tracer_utils OBJECT config.c database.c event.c handler.c utils.c)
target_link_libraries(tracer_utils PUBLIC m pthread)
add_library(tracer_events OBJECT event_selector.c)

View File

@@ -10,7 +10,7 @@ all: record replay extract_config textlog enb ue vcd macpdu2wireshark \
extract_input_subframe extract_output_subframe to_vcd extract multi \
gnb
record: utils.o record.o database.o configuration.o
record: utils.o record.o database.o config.o
$(CC) $(CFLAGS) -o record $^ $(LIBS)
replay: utils.o replay.o
@@ -20,48 +20,48 @@ extract_config: extract_config.o
$(CC) $(CFLAGS) -o extract_config $^ $(LIBS)
extract_input_subframe: extract_input_subframe.o database.o event.o utils.o \
configuration.o
config.o
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
extract_output_subframe: extract_output_subframe.o database.o event.o utils.o \
configuration.o
config.o
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
extract: extract.o database.o event.o utils.o configuration.o
extract: extract.o database.o event.o utils.o config.o
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
textlog: utils.o textlog.o database.o event.o handler.o configuration.o \
textlog: utils.o textlog.o database.o event.o handler.o config.o \
event_selector.o view/view.a gui/gui.a logger/logger.a \
filter/filter.a
$(CC) $(CFLAGS) -o textlog $^ $(LIBS) $(XLIBS)
enb: utils.o enb.o database.o event.o handler.o configuration.o \
enb: utils.o enb.o database.o event.o handler.o config.o \
event_selector.o view/view.a gui/gui.a logger/logger.a \
filter/filter.a
$(CC) $(CFLAGS) -o enb $^ $(LIBS) $(XLIBS)
ue: utils.o ue.o database.o event.o handler.o configuration.o \
ue: utils.o ue.o database.o event.o handler.o config.o \
event_selector.o view/view.a gui/gui.a logger/logger.a \
filter/filter.a
$(CC) $(CFLAGS) -o ue $^ $(LIBS) $(XLIBS)
vcd: utils.o vcd.o database.o event.o handler.o configuration.o \
vcd: utils.o vcd.o database.o event.o handler.o config.o \
event_selector.o view/view.a gui/gui.a logger/logger.a \
filter/filter.a
$(CC) $(CFLAGS) -o vcd $^ $(LIBS) $(XLIBS)
to_vcd: to_vcd.o database.o event.o handler.o utils.o configuration.o \
to_vcd: to_vcd.o database.o event.o handler.o utils.o config.o \
logger/logger.a filter/filter.a
$(CC) $(CFLAGS) -o to_vcd $^ $(LIBS)
macpdu2wireshark: macpdu2wireshark.o database.o utils.o handler.o event.o \
configuration.o
config.o
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
multi: multi.o utils.o database.o configuration.o
multi: multi.o utils.o database.o config.o
$(CC) $(CFLAGS) -o multi $^ $(LIBS)
gnb: utils.o gnb.o database.o event.o handler.o configuration.o \
gnb: utils.o gnb.o database.o event.o handler.o config.o \
view/view.a gui/gui.a logger/logger.a \
filter/filter.a
$(CC) $(CFLAGS) -o gnb $^ $(LIBS) $(XLIBS)

View File

@@ -1,4 +1,4 @@
#include "configuration.h"
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -14,7 +14,7 @@
#include "utils.h"
#include "event_selector.h"
#include "openair_logo.h"
#include "configuration.h"
#include "config.h"
/****************************************************************************/
/* conversion from rnti to "ue_id" (which does not really exists) */

View File

@@ -1,7 +1,7 @@
#include "event.h"
#include "database.h"
#include "utils.h"
#include "configuration.h"
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -4,7 +4,7 @@
#include <fcntl.h>
#include "database.h"
#include "event.h"
#include "configuration.h"
#include "config.h"
void usage(void)
{

View File

@@ -4,7 +4,7 @@
#include <fcntl.h>
#include "database.h"
#include "event.h"
#include "configuration.h"
#include "config.h"
void usage(void)
{

View File

@@ -4,7 +4,7 @@
#include <fcntl.h>
#include "database.h"
#include "event.h"
#include "configuration.h"
#include "config.h"
void usage(void)
{

View File

@@ -6,7 +6,7 @@
#include "database.h"
#include "event.h"
#include "handler.h"
#include "configuration.h"
#include "config.h"
#include "logger/logger.h"
#include "gui/gui.h"
#include "utils.h"

View File

@@ -5,18 +5,18 @@ LIBS=-lX11 -lm -lpng -lXft
all: dump_nack_signal time_meas timeplot multi-rru-clean
dump_nack_signal: ../utils.o ../database.o ../configuration.o ../event.o \
dump_nack_signal: ../utils.o ../database.o ../config.o ../event.o \
dump_nack_signal.o
$(CC) $(CFLAGS) -o dump_nack_signal $^ $(LIBS)
time_meas: ../utils.o ../database.o ../configuration.o ../event.o \
time_meas: ../utils.o ../database.o ../config.o ../event.o \
time_meas.o
$(CC) $(CFLAGS) -o time_meas $^ $(LIBS)
timplot: timeplot.o
$(CC) $(CFLAGS) -o timeplot $^ $(LIBS)
multi-rru-clean: ../utils.o ../database.o ../event.o ../configuration.o multi-rru-clean.o
multi-rru-clean: ../utils.o ../database.o ../event.o ../config.o multi-rru-clean.o
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
.PHONY: all

View File

@@ -7,7 +7,7 @@
#include "database.h"
#include "event.h"
#include "handler.h"
#include "configuration.h"
#include "config.h"
#include "utils.h"
#include "packet-mac-lte.h"

View File

@@ -8,7 +8,7 @@
#include "database.h"
#include "utils.h"
#include "../T.h"
#include "configuration.h"
#include "config.h"
#define DEFAULT_LOCAL_PORT 2022

View File

@@ -6,7 +6,7 @@
#include "database.h"
#include "utils.h"
#include "../T_defs.h"
#include "configuration.h"
#include "config.h"
void usage(void)
{

View File

@@ -11,7 +11,7 @@
#include "gui/gui.h"
#include "utils.h"
#include "event_selector.h"
#include "configuration.h"
#include "config.h"
typedef struct {
int socket;

View File

@@ -8,7 +8,7 @@
#include "database.h"
#include "utils.h"
#include "handler.h"
#include "configuration.h"
#include "config.h"
#include "logger/logger.h"
#include "view/view.h"

View File

@@ -14,7 +14,7 @@
#include "utils.h"
#include "event_selector.h"
#include "openair_logo.h"
#include "configuration.h"
#include "config.h"
typedef struct {
view *phyview;

View File

@@ -11,7 +11,7 @@
#include "gui/gui.h"
#include "utils.h"
#include "event_selector.h"
#include "configuration.h"
#include "config.h"
typedef struct {
int socket;

8
common/utils/colors.h Normal file
View File

@@ -0,0 +1,8 @@
#define KNRM "\x1B[0m"
#define KRED "\x1B[31m"
#define KGRN "\x1B[32m"
#define KYEL "\x1B[33m"
#define KBLU "\x1B[34m"
#define KMAG "\x1B[35m"
#define KCYN "\x1B[36m"
#define KWHT "\x1B[37m"

View File

@@ -22,15 +22,12 @@
#ifndef UTILS_CONFIG_H_ASN1
#define UTILS_CONFIG_H_ASN1
// This is hard coded file name "config.h" in asn1c skeletons
// 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 is the case for OAI).
* This allows to trace the asn1c encoder and decoder at execution time using
* the regular OAI logging system, i.e., LOG_I(ASN1, ...);
*
* to enable it, at compilation time, see ./build_oai --enable-asn1c-debug
* included. This logs asn1c encoder and decoder traces at execution time using
* the regular OAI logging system, i.e., LOG_I(ASN1...);
*
* 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.
@@ -50,7 +47,7 @@
*/
#include "common/utils/LOG/log.h"
#if TRACE_ASN1C_ENC_DEC
#if DEBUG_ASN1C
#define ASN_DEBUG(x...) do{ LOG_I(ASN1,x);LOG_I(ASN1,"\n"); } while(false)
#else
#define ASN_DEBUG(x...)

View File

@@ -33,6 +33,7 @@
#include <stdint.h>
#include "assertions.h"
#include "nr_common.h"
#include "executables/nr-uesoftmodem.h"
const char *duplex_mode[]={"FDD","TDD"};
@@ -232,6 +233,42 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB) {
}
/* This function converts the FRIV to a start sub-channel and length in subchannels */
/* for sl_MaxNumPerReserve = 2, the sequence from 38.214 for Lsc = 1,2,3, ...
* goes like startsc + (0,N_subch,N_subch +(N_subch-1), N_subch + (N_subch-1) + (N_subch-2), ...)
*
* This is only done for sl_MaxNumPerReserve = 2
* */
void convNRFRIV(int FRIV,
int N_subch,
long sl_MaxNumPerReserve,
uint16_t *Lsc,
uint16_t *startsc,
uint16_t *startsc2) {
if (sl_MaxNumPerReserve == 2) {
*Lsc=1;
int prevN=0;
int N=N_subch;
while (FRIV>N) {
*Lsc = *Lsc+1;
prevN = N;
N += (N_subch - *Lsc + 1);
}
if (startsc) *startsc = FRIV-prevN;
} else {
*Lsc=1;
int prevN=0;
int N=N_subch;
while (FRIV>N) {
*Lsc = *Lsc + 1;
prevN = N;
N += ((N_subch - *Lsc + 1)*(N_subch - *Lsc + 1));
}
int tmp1 = FRIV - prevN; // This holds startsc1 + startsc2*(N_subch - *Lsc + 1)
if (startsc2) *startsc2 = tmp1 / (N_subch - *Lsc + 1);
if (startsc) *startsc = tmp1 % (N_subch - *Lsc + 1);
}
}
int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB) {
int tmp = locationAndBandwidth/N_RB;
int tmp2 = locationAndBandwidth%N_RB;
@@ -240,16 +277,11 @@ int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB) {
}
/* TS 38.214 ch. 6.1.2.2.2 - Resource allocation type 1 for DL and UL */
int PRBalloc_to_locationandbandwidth0(int NPRB, int RBstart, int BWPsize)
{
AssertFatal(NPRB>0 && (NPRB + RBstart <= BWPsize),
"Illegal NPRB/RBstart Configuration (%d,%d) for BWPsize %d\n",
NPRB, RBstart, BWPsize);
int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize) {
AssertFatal(NPRB>0 && (NPRB + RBstart <= BWPsize),"Illegal NPRB/RBstart Configuration (%d,%d) for BWPsize %d\n",NPRB,RBstart,BWPsize);
if (NPRB <= 1 + (BWPsize >> 1))
return (BWPsize * (NPRB - 1) + RBstart);
else
return (BWPsize * (BWPsize + 1 - NPRB) + (BWPsize - 1 - RBstart));
if (NPRB <= 1+(BWPsize>>1)) return(BWPsize*(NPRB-1)+RBstart);
else return(BWPsize*(BWPsize+1-NPRB) + (BWPsize-1-RBstart));
}
int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart) {
@@ -356,7 +388,7 @@ int get_dmrs_port(int nl, uint16_t dmrs_ports)
}
}
}
AssertFatal(p>-1,"No dmrs port corresponding to layer %d found\n",nl);
if (p==-1) LOG_E(NR_PHY,"No dmrs port corresponding to layer %d found\n",nl);
return p;
}
@@ -738,3 +770,60 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
AssertFatal(sco % scs_scaling == 0, "ssb offset %d can create frequency offset\n", sco);
return ssb_offset_point_a;
}
#define MAX_EL_213_9_3_2 19
const float tab38_213_9_3_2[MAX_EL_213_9_3_2] = {1.125,1.250,1.375,1.625,1.750,2.000,2.250,2.500,2.875,3.125,3.500,4.000,5.000,6.250,8.000,10.000,12.625,15.875,20.000};
int get_NREsci2(const int sci2_alpha,
const int sci2_payload_len,
const int sci2_beta_offset,
const int pssch_numsym,
const int pscch_numsym,
const int pscch_numrbs,
const int l_subch,
const int subchannel_size,
const int mcs,
const int mcs_tb_ind) {
float Osci2 = (float)sci2_payload_len;
AssertFatal(sci2_beta_offset < MAX_EL_213_9_3_2, "illegal sci2_beta_offset %d\n",sci2_beta_offset);
float beta_offset_sci2 = tab38_213_9_3_2[sci2_beta_offset];
uint32_t R10240 = nr_get_code_rate_ul(mcs,mcs_tb_ind);
uint32_t tmp = (uint32_t)ceil((Osci2 + 24)*beta_offset_sci2/((float)R10240/5120));
float tmp2 = 12.0*pssch_numsym;
int N_REsci1 = 12*pscch_numrbs*pscch_numsym;
tmp2 *= l_subch*subchannel_size;
tmp2 -= N_REsci1;
tmp2 *= ((float)sci2_alpha/100.0);
return min(tmp,(int)ceil(tmp2));
}
int get_NREsci2_2(const int sci2_alpha,
const int sci2_payload_len,
const int sci2_beta_offset,
const int pssch_numsym,
const int pscch_numsym,
const int pscch_numrbs,
const int l_subch,
const int subchannel_size,
const int target_coderate,
const int mcs_table_index) {
float Osci2 = (float)sci2_payload_len;
AssertFatal(sci2_beta_offset < MAX_EL_213_9_3_2, "illegal sci2_beta_offset %d\n",sci2_beta_offset);
float beta_offset_sci2 = tab38_213_9_3_2[sci2_beta_offset];
uint32_t R10240 = get_softmodem_params()->sl_mode ? nr_get_code_rate_ul(1, mcs_table_index) : target_coderate;
uint32_t tmp = (uint32_t)ceil((Osci2 + 24)*beta_offset_sci2/((float)R10240/5120));
float tmp2 = 12.0*pssch_numsym;
int N_REsci1 = 12*pscch_numrbs*pscch_numsym;
tmp2 *= l_subch*subchannel_size;
tmp2 -= N_REsci1;
tmp2 *= ((float)sci2_alpha/100.0);
return min(tmp,(int)ceil(tmp2));
}

View File

@@ -90,6 +90,7 @@ frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index);
uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex);
int NRRIV2BW(int locationAndBandwidth,int N_RB);
int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
void convNRFRIV(int FRIV, int N_subch, long sl_MaxNumPerReserve, uint16_t *Lsc, uint16_t *startsc, uint16_t *startsc2);
int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize);
int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart);
int get_subband_size(int NPRB,int size);
@@ -113,7 +114,21 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
uint32_t absoluteFrequencyPointA,
int ssbSubcarrierSpacing,
int frequency_range);
int get_NREsci2(const int sci2_alpha,
const int sci2_payload_len,
const int sci2_beta_offset,
const int pssch_numsym,
const int pscch_numsym,
const int pscch_numrbs,
const int l_subch,
const int subchannel_size,
const int mcs,
const int mcs_tb_ind);
int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA);
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))

View File

@@ -231,8 +231,9 @@ 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);
LOG_I(UTIL,"Creating thread %s with affinity %d and priority %d\n",name,affinity,priority);
size_t stacksize;
pthread_attr_getstacksize(&attr,&stacksize);
LOG_I(UTIL,"Creating thread %s with affinity %d and priority %d, stacksize %d\n",name,affinity,priority,(int) stacksize);
if (checkIfFedoraDistribution())
if (checkIfGenericKernelOnFedora())

View File

@@ -47,7 +47,6 @@
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <sys/time.h>
@@ -58,20 +57,20 @@
#include "executables/softmodem-common.h"
#include <readline/history.h>
#include "telnetsrv_phycmd.h"
#include "telnetsrv_proccmd.h"
static char *telnet_defstatmod[] = {"softmodem", "phy", "loader", "measur"};
static char *telnet_defstatmod[] = {"softmodem","phy","loader","measur"};
static telnetsrv_params_t telnetparams;
#define TELNETSRV_OPTNAME_STATICMOD "staticmod"
#define TELNETSRV_OPTNAME_SHRMOD "shrmod"
#define TELNETSRV_OPTNAME_STATICMOD "staticmod"
#define TELNETSRV_OPTNAME_SHRMOD "shrmod"
// clang-format off
paramdef_t telnetoptions[] = {
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* configuration parameters for telnet utility */
/* optname helpstr paramflags XXXptr defXXXval type
numelt */
/* configuration parameters for telnet utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
{"listenaddr", "<listen ip address>\n", 0, .uptr = &telnetparams.listenaddr, .defstrval = "0.0.0.0", TYPE_IPV4ADDR, 0},
{"listenport", "<local port>\n", 0, .uptr = &telnetparams.listenport, .defuintval = 9090, TYPE_UINT, 0},
@@ -89,11 +88,10 @@ paramdef_t telnetoptions[] = {
};
// clang-format on
int get_phybsize(void)
{
int get_phybsize(void) {
return telnetparams.phyprntbuff_size;
};
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd);
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);
@@ -119,24 +117,22 @@ telnetshell_cmddef_t telnet_cmdarray[] = {
{"", "", NULL, {NULL}, 0, NULL},
};
void client_printf(const char *message, ...)
{
void client_printf(const char *message, ...) {
va_list va_args;
va_start(va_args, message);
if (telnetparams.new_socket > 0) {
vsnprintf(telnetparams.msgbuff, sizeof(telnetparams.msgbuff) - 1, message, va_args);
send(telnetparams.new_socket, telnetparams.msgbuff, strlen(telnetparams.msgbuff), MSG_NOSIGNAL);
vsnprintf(telnetparams.msgbuff,sizeof(telnetparams.msgbuff)-1,message, va_args);
send(telnetparams.new_socket,telnetparams.msgbuff, strlen(telnetparams.msgbuff), MSG_NOSIGNAL);
} else {
vprintf(message, va_args);
}
va_end(va_args);
return;
return ;
}
void set_sched(pthread_t tid, int pid, int priority)
{
void set_sched(pthread_t tid, int pid, int priority) {
int rt;
struct sched_param schedp;
int policy;
@@ -148,46 +144,44 @@ void set_sched(pthread_t tid, int pid, int priority)
sprintf(strpolicy, "%s", "RR");
schedp.sched_priority = -(priority + 100);
} else if (priority < 0 && priority > -100) {
policy = SCHED_FIFO;
sprintf(strpolicy, "%s", "fifo");
policy=SCHED_FIFO;
sprintf(strpolicy,"%s","fifo");
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
} 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
} 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)) { // idle mapped to oai priority >79
policy = SCHED_IDLE;
sprintf(strpolicy, "%s", "idle");
schedp.sched_priority = 0;
policy=SCHED_IDLE;
sprintf(strpolicy,"%s","idle");
schedp.sched_priority=0;
} else {
client_printf("Error: %i invalid priority \n", priority);
return;
}
if (tid != 0) {
if( tid != 0) {
rt = pthread_setschedparam(tid, policy, &schedp);
} else if (pid > 0) {
rt = sched_setscheduler(pid, policy, &schedp);
} else if(pid > 0) {
rt = sched_setscheduler( pid, policy,&schedp);
} else {
rt = -1;
rt= -1;
client_printf("Error: no pid or tid specified\n");
}
if (rt != 0) {
client_printf("Error %i: %s modifying sched param to %s:%i, \n", errno, strerror(errno), strpolicy, schedp.sched_priority);
} else {
client_printf("policy set to %s, priority %i\n", strpolicy, schedp.sched_priority);
client_printf("Error %i: %s modifying sched param to %s:%i, \n",
errno,strerror(errno),strpolicy,schedp.sched_priority);
} else {
client_printf("policy set to %s, priority %i\n",strpolicy,schedp.sched_priority);
if (policy == SCHED_OTHER || policy == SCHED_BATCH) {
rt = getpriority(PRIO_PROCESS, tid);
rt = getpriority(PRIO_PROCESS,tid);
if (rt != -1) {
rt = setpriority(PRIO_PROCESS, tid, niceval);
@@ -196,20 +190,21 @@ void set_sched(pthread_t tid, int pid, int priority)
client_printf("Error %i: %s trying to set nice value of thread %u to %i\n", errno, strerror(errno), tid, niceval);
}
} else {
client_printf("Error %i: %s trying to get nice value of thread %u \n", errno, strerror(errno), tid);
client_printf("Error %i: %s trying to get nice value of thread %u \n",
errno,strerror(errno),tid);
}
}
}
if (policy == SCHED_OTHER || policy == SCHED_BATCH) {
if (tid > 0 && tid != pthread_self()) {
if ( tid > 0 && tid != pthread_self()) {
client_printf("setting nice value using a thread id not implemented....\n");
} else if (pid > 0) {
errno = 0;
errno=0;
rt = setpriority(PRIO_PROCESS, pid, niceval);
if (rt != 0) {
client_printf("Error %i: %s calling setpriority, \n", errno, strerror(errno));
client_printf("Error %i: %s calling setpriority, \n",errno,strerror(errno));
} else {
client_printf("nice value set to %i\n", niceval);
}
@@ -217,8 +212,7 @@ void set_sched(pthread_t tid, int pid, int priority)
}
}
void set_affinity(pthread_t tid, int pid, int coreid)
{
void set_affinity(pthread_t tid, int pid, int coreid) {
cpu_set_t cpuset;
int rt;
CPU_ZERO(&cpuset);
@@ -229,13 +223,13 @@ void set_affinity(pthread_t tid, int pid, int coreid)
} else if (pid > 0) {
rt = sched_setaffinity((pid_t)pid, sizeof(cpu_set_t), &cpuset);
} else {
rt = -1;
rt= -1;
}
if (rt != 0) {
client_printf("Error %i: %s calling , xxx_setaffinity...\n", errno, strerror(errno));
client_printf("Error %i: %s calling , xxx_setaffinity...\n",errno,strerror(errno));
} else {
client_printf("thread %i affinity set to %i\n", (pid == 0) ? (int)tid : pid, coreid);
client_printf("thread %i affinity set to %i\n",(pid==0)?(int)tid:pid,coreid);
}
}
/*------------------------------------------------------------------------------------*/
@@ -244,10 +238,9 @@ function implementing telnet server specific commands, parameters of the
telnet_cmdarray table
*/
void redirstd(char *newfname, telnet_printfunc_t prnt)
{
void redirstd(char *newfname,telnet_printfunc_t prnt ) {
FILE *fd;
fd = freopen(newfname, "w", stdout);
fd=freopen(newfname, "w", stdout);
if (fd == NULL) {
prnt("ERROR: stdout redir to %s error %s\n", strerror(errno));
@@ -255,7 +248,7 @@ void redirstd(char *newfname, telnet_printfunc_t prnt)
prnt("stdout redirected to %s\n", newfname);
}
fd = freopen(newfname, "w", stderr);
fd=freopen(newfname, "w", stderr);
if (fd == NULL) {
prnt("ERROR: stderr redir to %s error %s\n", strerror(errno));
@@ -269,38 +262,37 @@ 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];
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];
memset(cmds, 0, sizeof(cmds));
sscanf(buff, "%9s %32s %9s %9s %9s", cmds[0], cmds[1], cmds[2], cmds[3], cmds[4]);
memset(cmds,0,sizeof(cmds));
sscanf(buff,"%9s %32s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] );
if (strncasecmp(cmds[0], "here", 4) == 0) {
if (strncasecmp(cmds[0],"here",4) == 0) {
fflush(stdout);
sprintf(stdout_str, "/proc/%i/fd/%i", getpid(), telnetparams.new_socket);
dup2(telnetparams.new_socket, fileno(stdout));
sprintf(stdout_str,"/proc/%i/fd/%i",getpid(),telnetparams.new_socket);
dup2(telnetparams.new_socket,fileno(stdout));
// freopen(stdout_str, "w", stdout);
// freopen(stdout_str, "w", stderr);
dup2(telnetparams.new_socket, fileno(stderr));
prnt("Log output redirected to this terminal (%s)\n", stdout_str);
dup2(telnetparams.new_socket,fileno(stderr));
prnt("Log output redirected to this terminal (%s)\n",stdout_str);
}
if (strncasecmp(cmds[0], "file", 4) == 0) {
if (strncasecmp(cmds[0],"file",4) == 0) {
if (cmds[1][0] == 0)
logfname = telnetparams.logfile;
else
logfname = cmds[1];
logfname=cmds[1];
prnt("Log output redirected to (%s)\n", logfname);
fflush(stdout);
redirstd(logfname, prnt);
redirstd(logfname,prnt);
}
if (strncasecmp(cmds[0], "off", 3) == 0) {
if (strncasecmp(cmds[0],"off",3) == 0) {
fflush(stdout);
redirstd("/dev/tty", prnt);
redirstd("/dev/tty",prnt);
}
return CMDSTATUS_FOUND;
@@ -311,57 +303,55 @@ 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));
sscanf(buff, "%9s %9s %9s %9s %9s", cmds[0], cmds[1], cmds[2], cmds[3], cmds[4]);
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));
sscanf(buff,"%9s %9s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] );
if (strncasecmp(cmds[0], "prio", 4) == 0) {
if (strncasecmp(cmds[0],"prio",4) == 0) {
int prio;
prio = (int)strtol(cmds[1], NULL, 0);
prio=(int)strtol(cmds[1],NULL,0);
if (errno == ERANGE)
return CMDSTATUS_VARNOTFOUND;
telnetparams.priority = prio;
set_sched(pthread_self(), 0, prio);
set_sched(pthread_self(),0,prio);
return CMDSTATUS_FOUND;
}
if (strncasecmp(cmds[0], "aff", 3) == 0) {
if (strncasecmp(cmds[0],"aff",3) == 0) {
int aff;
aff = (int)strtol(cmds[1], NULL, 0);
aff=(int)strtol(cmds[1],NULL,0);
if (errno == ERANGE)
return CMDSTATUS_VARNOTFOUND;
set_affinity(pthread_self(), 0, aff);
set_affinity(pthread_self(),0,aff);
return CMDSTATUS_FOUND;
}
return CMDSTATUS_NOTFOUND;
} /* setparam */
int history_cmd(char *buff, int debug, telnet_printfunc_t prnt)
{
char cmds[TELNET_MAX_MSGLENGTH / TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE];
memset(cmds, 0, sizeof(cmds));
sscanf(buff, "%9s %9s %9s %9s %9s", cmds[0], cmds[1], cmds[2], cmds[3], cmds[4]);
int history_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE];
memset(cmds,0,sizeof(cmds));
sscanf(buff,"%9s %9s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] );
if (strncasecmp(cmds[0],"list",4) == 0) {
HIST_ENTRY **hist = history_list();
if (hist) {
for (int i = 0; hist[i]; i++) {
prnt("%d: %s\n", i + history_base, hist[i]->line);
prnt ("%d: %s\n", i + history_base, hist[i]->line);
}
}
return CMDSTATUS_FOUND;
}
if (strncasecmp(cmds[0], "reset", 5) == 0) {
if (strncasecmp(cmds[0],"reset",5) == 0) {
clear_history();
write_history(telnetparams.histfile);
return CMDSTATUS_FOUND;
@@ -477,28 +467,21 @@ int setgetvar(int moduleindex, char getorset, char *params)
n = sscanf(params, "%9s %ms", varname, &varval);
for (i = 0; telnetparams.CmdParsers[moduleindex].var[i].varvalptr != NULL; i++) {
if (strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname,
varname,
strlen(telnetparams.CmdParsers[moduleindex].var[i].varname))
== 0) {
if (strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname, varname, strlen(telnetparams.CmdParsers[moduleindex].var[i].varname)) == 0) {
if (n > 0 && (getorset == 'g' || getorset == 'G')) {
client_printf("%s, %s = ",
telnetparams.CmdParsers[moduleindex].module,
telnetparams.CmdParsers[moduleindex].var[i].varname);
client_printf("%s, %s = ", telnetparams.CmdParsers[moduleindex].module, telnetparams.CmdParsers[moduleindex].var[i].varname);
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);
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);
}
}
}
if (n > 1 && varval != NULL) {
if (n>1 && varval != NULL) {
free(varval);
}
@@ -513,11 +496,10 @@ void telnetsrv_freetbldata(webdatadef_t *wdata)
free(wdata->lines[i].val[j]);
}
/*----------------------------------------------------------------------------------------------------*/
char *get_time(char *buff, int bufflen)
{
struct tm tmstruct;
time_t now = time(0);
strftime(buff, bufflen, "%Y-%m-%d %H:%M:%S.000", localtime_r(&now, &tmstruct));
char *get_time(char *buff,int bufflen) {
struct tm tmstruct;
time_t now = time (0);
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)
@@ -534,33 +516,32 @@ void telnet_pushcmd(telnetshell_cmddef_t *cmd, char *cmdbuff, telnet_printfunc_t
int process_command(char *buf, int iteration)
{
int i, j, k;
int i,j,k;
char modulename[TELNET_CMD_MAXSIZE];
char cmd[TELNET_CMD_MAXSIZE];
char *cmdb = NULL;
char *cmdb=NULL;
int rt;
memset(modulename, 0, sizeof(modulename));
memset(cmd, 0, sizeof(cmd));
memset(modulename,0,sizeof(modulename));
memset(cmd,0,sizeof(cmd));
if (strncasecmp(buf, "ex", 2) == 0)
if (strncasecmp(buf,"ex",2) == 0)
return CMDSTATUS_EXIT;
if (strncasecmp(buf, "help", 4) == 0) {
for (i = 0; telnetparams.CmdParsers[i].var != NULL && telnetparams.CmdParsers[i].cmd != NULL; i++) {
client_printf(" module %i = %s:\n", i, telnetparams.CmdParsers[i].module);
if (strncasecmp(buf,"help",4) == 0) {
for (i=0; telnetparams.CmdParsers[i].var != NULL && telnetparams.CmdParsers[i].cmd != NULL; i++) {
client_printf(" module %i = %s:\n",i,telnetparams.CmdParsers[i].module);
for (j = 0; telnetparams.CmdParsers[i].var[j].varvalptr != NULL; j++) {
for(j=0; telnetparams.CmdParsers[i].var[j].varvalptr != NULL ; j++) {
client_printf(" %s [get set] %s <value>\n",
telnetparams.CmdParsers[i].module,
telnetparams.CmdParsers[i].var[j].varname);
telnetparams.CmdParsers[i].module, telnetparams.CmdParsers[i].var[j].varname);
}
for (j = 0; telnetparams.CmdParsers[i].cmd[j].cmdfunc != NULL; j++) {
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].module,telnetparams.CmdParsers[i].cmd[j].cmdname,
telnetparams.CmdParsers[i].cmd[j].helpstr);
}
}
@@ -568,25 +549,25 @@ int process_command(char *buf, int iteration)
return CMDSTATUS_FOUND;
}
rt = CMDSTATUS_NOTFOUND;
j = sscanf(buf, "%19s %19s %m[^\t\n]", modulename, cmd, &cmdb);
rt=CMDSTATUS_NOTFOUND;
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 == 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)) {
if (strncasecmp(cmd, "getall", 7) == 0) {
for (j = 0; telnetparams.CmdParsers[i].var[j].varvalptr != NULL; j++) {
setgetvar(i, 'g', telnetparams.CmdParsers[i].var[j].varname);
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)) {
if (strncasecmp(cmd,"getall",7) == 0 ) {
for(j=0; telnetparams.CmdParsers[i].var[j].varvalptr != NULL ; j++) {
setgetvar(i,'g',telnetparams.CmdParsers[i].var[j].varname);
}
rt = CMDSTATUS_FOUND;
} else if (strcasecmp(cmd, "get") == 0 || strcasecmp(cmd, "set") == 0) {
rt = setgetvar(i, cmd[0], cmdb);
rt= CMDSTATUS_FOUND;
} else if (strcasecmp(cmd,"get") == 0 || strcasecmp(cmd,"set") == 0) {
rt= setgetvar(i,cmd[0],cmdb);
} 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) {
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) {
@@ -594,52 +575,49 @@ int process_command(char *buf, int iteration)
} else {
telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf);
}
rt = CMDSTATUS_FOUND;
rt= CMDSTATUS_FOUND;
}
} /* for k */
} /* else */
} /* strncmp: module name test */
else if (strncasecmp(modulename, "loop", 4) == 0) {
int f = fcntl(telnetparams.new_socket, F_GETFL);
int f1 = fcntl(telnetparams.new_socket, F_SETFL, O_NONBLOCK | f);
}/* else */
}/* strncmp: module name test */
else if (strncasecmp(modulename,"loop",4) == 0 ) {
int f = fcntl(telnetparams.new_socket,F_GETFL);
int f1=fcntl (telnetparams.new_socket, F_SETFL, O_NONBLOCK | f);
if (f < 0 || f1 < 0) {
client_printf(" Loop won't be cancelable: %s\n", strerror(errno));
if (f<0 || f1 <0) {
client_printf( " Loop won't be cancelable: %s\n",strerror(errno) );
}
for (int lc = 0; lc < telnetparams.loopcount; lc++) {
for(int lc=0; lc<telnetparams.loopcount; lc++) {
char dummybuff[20];
char tbuff[64];
client_printf(CSI "1J" CSI "1;10H " STDFMT "%s %i/%i\n",
get_time(tbuff, sizeof(tbuff)),
lc,
telnetparams.loopcount);
get_time(tbuff,sizeof(tbuff)),lc,telnetparams.loopcount );
process_command(buf + strlen("loop") + 1, lc);
errno = 0;
int rs = read(telnetparams.new_socket, dummybuff, sizeof(dummybuff));
errno=0;
int rs = read(telnetparams.new_socket,dummybuff,sizeof(dummybuff));
if (telnetparams.telnetdbg > 0)
client_printf("Received \"%s\" status %d, errno %s while running loop\n", dummybuff, rs, strerror(errno));
client_printf("Received \"%s\" status %d, errno %s while running loop\n",dummybuff,rs,strerror(errno));
if (errno != EAGAIN && errno != EWOULDBLOCK) {
client_printf(STDFMT " Loop canceled, iteration %i/%i\n", lc, telnetparams.loopcount);
lc = telnetparams.loopcount;
if ( errno != EAGAIN && errno != EWOULDBLOCK) {
client_printf( STDFMT " Loop canceled, iteration %i/%i\n",lc,telnetparams.loopcount );
lc=telnetparams.loopcount;
break;
}
usleep(telnetparams.loopdelay * 1000);
}
fcntl(telnetparams.new_socket, F_SETFL, f);
rt = CMDSTATUS_FOUND;
fcntl (telnetparams.new_socket, F_SETFL, f);
rt= CMDSTATUS_FOUND;
} /* loop */
} /* for i */
free(cmdb);
return rt;
}
void run_telnetsrv(void)
{
void run_telnetsrv(void) {
int sock;
struct sockaddr_in name;
char buf[TELNET_MAX_MSGLENGTH];
@@ -648,13 +626,13 @@ void run_telnetsrv(void)
int readc, filled;
int status;
int optval = 1;
char prompt[sizeof(TELNET_PROMPT_PREFIX) + 10];
char prompt[sizeof(TELNET_PROMPT_PREFIX)+10];
pthread_setname_np(pthread_self(), "telnet");
set_sched(pthread_self(), 0, telnetparams.priority);
set_sched(pthread_self(),0,telnetparams.priority);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
fprintf(stderr, "[TELNETSRV] Error %s on socket call\n", strerror(errno));
fprintf(stderr,"[TELNETSRV] Error %s on socket call\n",strerror(errno));
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
name.sin_family = AF_INET;
@@ -666,71 +644,74 @@ void run_telnetsrv(void)
name.sin_port = htons((unsigned short)(telnetparams.listenport));
if (bind(sock, (void *)&name, sizeof(name)))
fprintf(stderr, "[TELNETSRV] Error %s on bind call\n", strerror(errno));
if(bind(sock, (void *) &name, sizeof(name)))
fprintf(stderr,"[TELNETSRV] Error %s on bind call\n",strerror(errno));
if (listen(sock, 1) == -1)
fprintf(stderr, "[TELNETSRV] Error %s on listen call\n", strerror(errno));
if(listen(sock, 1) == -1)
fprintf(stderr,"[TELNETSRV] Error %s on listen call\n",strerror(errno));
using_history();
int plen = sprintf(prompt, "%s_%s> ", TELNET_PROMPT_PREFIX, get_softmodem_function(NULL));
int plen=sprintf(prompt,"%s_%s> ",TELNET_PROMPT_PREFIX,get_softmodem_function(NULL));
printf("\nInitializing telnet server...\n");
while ((telnetparams.new_socket = accept(sock, &cli_addr, &cli_len))) {
while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) ) {
printf("[TELNETSRV] Telnet client connected....\n");
read_history(telnetparams.histfile);
stifle_history(telnetparams.histsize);
if (telnetparams.new_socket < 0)
fprintf(stderr, "[TELNETSRV] Error %s on accept call\n", strerror(errno));
if(telnetparams.new_socket < 0)
fprintf(stderr,"[TELNETSRV] Error %s on accept call\n",strerror(errno));
while (telnetparams.new_socket > 0) {
while(telnetparams.new_socket>0) {
filled = 0;
memset(buf, 0, sizeof(buf));
memset(buf,0,sizeof(buf));
while (filled < (TELNET_MAX_MSGLENGTH - 1)) {
readc = recv(telnetparams.new_socket, buf + filled, TELNET_MAX_MSGLENGTH - filled - 1, 0);
if (!readc) {
printf("[TELNETSRV] Telnet Client disconnected, %s\n", strerror(errno));
while(filled < ( TELNET_MAX_MSGLENGTH-1)) {
readc = recv(telnetparams.new_socket, buf+filled, TELNET_MAX_MSGLENGTH-filled-1, 0);
if(!readc)
break;
}
filled += readc;
if (buf[filled - 1] == '\n') {
while (filled > 0 && isspace(buf[filled - 1]))
filled--;
buf[filled] = 0;
if(buf[filled-1] == '\n') {
buf[filled-1] = 0;
break;
}
} /* while loop to fill buffer till return entered */
}
if(!readc) {
printf ("[TELNETSRV] Telnet Client disconnected.\n");
break;
}
if (telnetparams.telnetdbg > 0)
printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled, buf);
printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled,buf);
if (buf[0] == '!') {
if (buf[1] == '!') {
sprintf(buf, "%s", "telnet history list");
sprintf(buf,"%s","telnet history list");
} else {
HIST_ENTRY *hisentry = history_get(strtol(buf + 1, NULL, 0));
HIST_ENTRY *hisentry = history_get(strtol(buf+1,NULL,0));
if (hisentry) {
char msg[TELNET_MAX_MSGLENGTH + plen + 10];
sprintf(buf, "%s", hisentry->line);
sprintf(msg, "%s %s\n", prompt, hisentry->line);
char msg[TELNET_MAX_MSGLENGTH + plen +10];
sprintf(buf,"%s",hisentry->line);
sprintf(msg,"%s %s\n",prompt, hisentry->line);
send(telnetparams.new_socket, msg, strlen(msg), MSG_NOSIGNAL);
}
}
}
if (strlen(buf) > 2) {
if (strlen(buf) > 2 ) {
status = process_command(buf, 0);
} else
status = CMDSTATUS_NOCMD;
status=CMDSTATUS_NOCMD;
if (status != CMDSTATUS_EXIT) {
if (status == CMDSTATUS_NOTFOUND) {
char msg[TELNET_MAX_MSGLENGTH + 50];
sprintf(msg, "Error: \n %s\n is not a softmodem command\n", buf);
sprintf(msg,"Error: \n %s\n is not a softmodem command\n",buf);
send(telnetparams.new_socket, msg, strlen(msg), MSG_NOSIGNAL);
} else if (status == CMDSTATUS_FOUND) {
add_history(buf);
@@ -738,7 +719,7 @@ void run_telnetsrv(void)
send(telnetparams.new_socket, prompt, strlen(prompt), MSG_NOSIGNAL);
} else {
printf("[TELNETSRV] Closing telnet connection...\n");
printf ("[TELNETSRV] Closing telnet connection...\n");
break;
}
}
@@ -746,111 +727,114 @@ void run_telnetsrv(void)
write_history(telnetparams.histfile);
clear_history();
close(telnetparams.new_socket);
printf("[TELNETSRV] Telnet server waitting for connection...\n");
printf ("[TELNETSRV] Telnet server waitting for connection...\n");
}
close(sock);
return;
}
void run_telnetclt(void)
{
void run_telnetclt(void) {
int sock;
struct sockaddr_in name;
pthread_setname_np(pthread_self(), "telnetclt");
set_sched(pthread_self(), 0, telnetparams.priority);
char prompt[sizeof(TELNET_PROMPT_PREFIX) + 10];
sprintf(prompt, "%s_%s> ", TELNET_PROMPT_PREFIX, get_softmodem_function(NULL));
set_sched(pthread_self(),0,telnetparams.priority);
char prompt[sizeof(TELNET_PROMPT_PREFIX)+10];
sprintf(prompt,"%s_%s> ",TELNET_PROMPT_PREFIX,get_softmodem_function(NULL));
name.sin_family = AF_INET;
struct in_addr addr;
inet_aton("127.0.0.1", &addr);
name.sin_addr.s_addr = addr.s_addr;
inet_aton("127.0.0.1", &addr) ;
name.sin_addr.s_addr = addr.s_addr;
name.sin_port = htons((unsigned short)(telnetparams.listenport));
while (1) {
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
fprintf(stderr, "[TELNETSRV] Error %s on socket call\n", strerror(errno));
if (connect(sock, (void *)&name, sizeof(name)))
fprintf(stderr, "[TELNETSRV] Error %s on connect call\n", strerror(errno));
fprintf(stderr,"[TELNETSRV] Error %s on socket call\n",strerror(errno));
if(connect(sock, (void *) &name, sizeof(name)))
fprintf(stderr,"[TELNETSRV] Error %s on connect call\n",strerror(errno));
struct timeval ts;
ts.tv_sec = 1; // 1 second
ts.tv_usec = 0;
while (1) {
fd_set fds;
fd_set fds;
FD_ZERO(&fds);
FD_SET(sock, &fds);
FD_SET(STDIN_FILENO, &fds);
FD_SET(STDIN_FILENO , &fds);
// wait for data
int nready = select(sock + 1, &fds, (fd_set *)0, (fd_set *)0, &ts);
int nready = select(sock + 1, &fds, (fd_set *) 0, (fd_set *) 0, &ts);
if (nready < 0) {
perror("select. Error");
break;
} else if (nready == 0) {
ts.tv_sec = 1; // 1 second
ts.tv_usec = 0;
} else if (FD_ISSET(sock, &fds)) {
int rv;
char inbuf[TELNET_MAX_MSGLENGTH * 2];
memset(inbuf, 0, sizeof(inbuf));
rv = recv(sock, inbuf, sizeof(inbuf) - 1, 0);
if (rv > 0) {
printf("%s", inbuf);
} else if (rv == 0) {
printf("Connection closed by the remote end\n\r");
break;
} else {
perror("recv error");
break;
}
} else if (FD_ISSET(STDIN_FILENO, &fds)) {
char *inbuf = NULL;
size_t inlen = 0;
inlen = getline(&inbuf, &inlen, stdin);
if (inlen > 0) {
if (send(sock, inbuf, inlen, 0) < 0)
break;
}
free(inbuf);
perror("select. Error");
break;
}
else if (nready == 0) {
ts.tv_sec = 1; // 1 second
ts.tv_usec = 0;
}
else if ( FD_ISSET(sock, &fds)) {
int rv;
char inbuf[TELNET_MAX_MSGLENGTH*2];
memset(inbuf,0,sizeof(inbuf));
rv = recv(sock , inbuf , sizeof(inbuf)-1 , 0);
if (rv > 0) {
printf("%s",inbuf);
}
else if (rv == 0) {
printf("Connection closed by the remote end\n\r");
break;
}
else {
perror("recv error");
break;
}
}
else if (FD_ISSET(STDIN_FILENO , &fds)) {
char *inbuf=NULL;
size_t inlen=0;
inlen = getline( &inbuf,&inlen, stdin);
if ( inlen > 0 ) {
if ( send(sock, inbuf,inlen, 0) < 0)
break;
}
free(inbuf);
}
}
close(sock);
}
}
return;
} /* run_telnetclt */
void poll_telnetcmdq(void *qid, void *arg)
{
notifiedFIFO_elt_t *msg = pollNotifiedFIFO((notifiedFIFO_t *)qid);
if (msg != NULL) {
telnetsrv_qmsg_t *msgdata = NotifiedFifoData(msg);
msgdata->cmdfunc(msgdata->cmdbuff, msgdata->debug, msgdata->prnt, arg);
free(msgdata->cmdbuff);
delNotifiedFIFO_elt(msg);
}
void poll_telnetcmdq(void *qid, void *arg) {
notifiedFIFO_elt_t *msg = pollNotifiedFIFO((notifiedFIFO_t *)qid);
if (msg != NULL) {
telnetsrv_qmsg_t *msgdata=NotifiedFifoData(msg);
msgdata->cmdfunc(msgdata->cmdbuff,msgdata->debug,msgdata->prnt,arg);
free(msgdata->cmdbuff);
delNotifiedFIFO_elt(msg);
}
}
/*------------------------------------------------------------------------------------------------*/
/* load the commands delivered with the telnet server
*
*
*
*/
static bool exec_moduleinit(char *modname)
{
*/
static bool exec_moduleinit(char *modname) {
void (*fptr)(void);
char initfunc[TELNET_CMD_MAXSIZE + 10];
char initfunc[TELNET_CMD_MAXSIZE+10];
if (strlen(modname) > TELNET_CMD_MAXSIZE) {
fprintf(stderr, "[TELNETSRV] module %s not loaded, name exceeds the %i size limit\n", modname, TELNET_CMD_MAXSIZE);
fprintf(stderr,"[TELNETSRV] module %s not loaded, name exceeds the %i size limit\n",
modname, TELNET_CMD_MAXSIZE);
return false;
}
sprintf(initfunc, "add_%s_cmds", modname);
fptr = dlsym(RTLD_DEFAULT, initfunc);
sprintf(initfunc,"add_%s_cmds",modname);
fptr = dlsym(RTLD_DEFAULT,initfunc);
if (fptr != NULL) {
if ( fptr != NULL) {
fptr();
return true;
}
@@ -858,11 +842,10 @@ static bool exec_moduleinit(char *modname)
return false;
}
int add_embeddedmodules(void)
{
int ret = 0;
int pindex = config_paramidx_fromname(telnetoptions, sizeof(telnetoptions) / sizeof(paramdef_t), TELNETSRV_OPTNAME_STATICMOD);
for (int i = 0; i < telnetoptions[pindex].numelt; i++) {
int add_embeddedmodules(void) {
int ret=0;
int pindex = config_paramidx_fromname(telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t), TELNETSRV_OPTNAME_STATICMOD);
for(int i=0; i<telnetoptions[pindex].numelt; i++) {
bool success = exec_moduleinit(telnetoptions[pindex].strlistptr[i]);
if (success)
ret++;
@@ -871,11 +854,10 @@ int add_embeddedmodules(void)
return ret;
}
int add_sharedmodules(void)
{
int ret = 0;
int pindex = config_paramidx_fromname(telnetoptions, sizeof(telnetoptions) / sizeof(paramdef_t), TELNETSRV_OPTNAME_SHRMOD);
for (int i = 0; i < telnetoptions[pindex].numelt; i++) {
int add_sharedmodules(void) {
int ret=0;
int pindex = config_paramidx_fromname(telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t), TELNETSRV_OPTNAME_SHRMOD);
for(int i=0; i<telnetoptions[pindex].numelt; i++) {
char *name = telnetoptions[pindex].strlistptr[i];
char libname[256];
snprintf(libname, sizeof(libname), "telnetsrv_%s", name);
@@ -891,29 +873,28 @@ int add_sharedmodules(void)
/* autoinit functions is called by the loader when the telnet shared library is
dynamically loaded
*/
int telnetsrv_autoinit(void)
{
memset(&telnetparams, 0, sizeof(telnetparams));
config_get(telnetoptions, sizeof(telnetoptions) / sizeof(paramdef_t), "telnetsrv");
int telnetsrv_autoinit(void) {
memset(&telnetparams,0,sizeof(telnetparams));
config_get( telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t),"telnetsrv");
/* possibly load a exec specific shared lib */
char *execfunc = get_softmodem_function(NULL);
char *execfunc=get_softmodem_function(NULL);
char libname[64];
sprintf(libname, "telnetsrv_%s", execfunc);
load_module_shlib(libname, NULL, 0, NULL);
if (pthread_create(&telnetparams.telnet_pthread, NULL, (void *(*)(void *))run_telnetsrv, NULL) != 0) {
fprintf(stderr, "[TELNETSRV] Error %s on pthread_create call\n", strerror(errno));
sprintf(libname,"telnetsrv_%s",execfunc);
load_module_shlib(libname,NULL,0,NULL);
if(pthread_create(&telnetparams.telnet_pthread,NULL, (void *(*)(void *))run_telnetsrv, NULL) != 0) {
fprintf(stderr,"[TELNETSRV] Error %s on pthread_create call\n",strerror(errno));
return -1;
}
add_telnetcmd("telnet", telnet_vardef, telnet_cmdarray);
add_embeddedmodules();
add_sharedmodules();
if (telnetparams.listenstdin) {
if (pthread_create(&telnetparams.telnetclt_pthread, NULL, (void *(*)(void *))run_telnetclt, NULL) != 0) {
fprintf(stderr, "[TELNETSRV] Error %s on pthread_create f() run_telnetclt \n", strerror(errno));
return -1;
if ( telnetparams.listenstdin ) {
if(pthread_create(&telnetparams.telnetclt_pthread,NULL, (void *(*)(void *))run_telnetclt, NULL) != 0) {
fprintf(stderr,"[TELNETSRV] Error %s on pthread_create f() run_telnetclt \n",strerror(errno));
return -1;
}
}
}
return 0;
}
@@ -921,13 +902,13 @@ int telnetsrv_autoinit(void)
/* add_telnetcmd is used to add a set of commands to the telnet server. A module calls this
* function at init time. the telnet server is delivered with a set of commands which
* will be loaded or not depending on the telnet section of the config file
*/
*/
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd)
{
notifiedFIFO_t *afifo = NULL;
if (modulename == NULL || var == NULL || cmd == NULL) {
fprintf(stderr, "[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n");
if( modulename == NULL || var == NULL || cmd == NULL) {
fprintf(stderr,"[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n");
return -1;
}
@@ -956,30 +937,26 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde
/* function which will be called by the shared lib loader, to check shared lib version
against main exec version. version mismatch not considered as fatal (interfaces not supposed to change)
*/
int telnetsrv_checkbuildver(char *mainexec_buildversion, char **shlib_buildversion)
{
int telnetsrv_checkbuildver(char *mainexec_buildversion, char **shlib_buildversion) {
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "standalone built: " __DATE__ __TIME__
#endif
*shlib_buildversion = PACKAGE_VERSION;
if (strcmp(mainexec_buildversion, *shlib_buildversion) != 0) {
fprintf(stderr,
"[TELNETSRV] shared lib version %s, doesn't match main version %s, compatibility should be checked\n",
mainexec_buildversion,
*shlib_buildversion);
fprintf(stderr,"[TELNETSRV] shared lib version %s, doesn't match main version %s, compatibility should be checked\n",
mainexec_buildversion,*shlib_buildversion);
}
return 0;
}
int telnetsrv_getfarray(loader_shlibfunc_t **farray)
{
int const num_func_tln_srv = 3;
int telnetsrv_getfarray(loader_shlibfunc_t **farray) {
int const num_func_tln_srv = 3;
*farray = malloc(sizeof(loader_shlibfunc_t) * num_func_tln_srv);
(*farray)[0].fname = TELNET_ADDCMD_FNAME;
(*farray)[0].fptr = (int (*)(void))add_telnetcmd;
(*farray)[1].fname = TELNET_POLLCMDQ_FNAME;
(*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;
(*farray)[2].fname = TELNET_PUSHCMD_FNAME;
(*farray)[2].fptr = (int (*)(void))telnet_pushcmd;

View File

@@ -28,17 +28,15 @@
#include <stdarg.h>
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h"
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#define TELNETSERVERCODE
#include "telnetsrv.h"
#define ERROR_MSG_RET(mSG, aRGS...) do { prnt(mSG, ##aRGS); return 1; } while (0)
static int get_single_ue_rnti_mac(void)
static int get_single_ue_rnti(void)
{
NR_UE_info_t *ue = NULL;
UE_iterator(RC.nrmac[0]->UE_info.list, it) {
@@ -50,6 +48,11 @@ static int get_single_ue_rnti_mac(void)
if (!ue)
return -1;
// verify it exists in RRC as well
rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], ue->rnti);
if (!rrcue)
return -1;
return ue->rnti;
}
@@ -58,7 +61,7 @@ int get_single_rnti(char *buf, int debug, telnet_printfunc_t prnt)
if (buf)
ERROR_MSG_RET("no parameter allowed\n");
int rnti = get_single_ue_rnti_mac();
int rnti = get_single_ue_rnti();
if (rnti < 1)
ERROR_MSG_RET("different number of UEs\n");
@@ -68,44 +71,9 @@ int get_single_rnti(char *buf, int debug, telnet_printfunc_t prnt)
int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt)
{
if (!RC.nrrrc)
ERROR_MSG_RET("no RRC present, cannot list counts\n");
rrc_gNB_ue_context_t *ue = NULL;
int rnti = -1;
if (!buf) {
rrc_gNB_ue_context_t *l = NULL;
int n = 0;
RB_FOREACH(l, rrc_nr_ue_tree_s, &RC.nrrrc[0]->rrc_ue_head) {
if (ue == NULL) ue = l;
n++;
}
if (!ue)
ERROR_MSG_RET("could not find any UE in RRC\n");
if (n > 1)
ERROR_MSG_RET("more than one UE in RRC present\n");
} else {
rnti = strtol(buf, NULL, 16);
if (rnti < 1 || rnti >= 0xfffe)
ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n");
ue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti);
if (!ue)
ERROR_MSG_RET("could not find UE with RNTI %04x in RRC\n");
}
prnt("UE RNTI %04x reestab %d reconf_after_reestab %d\n",
ue->ue_context.rnti,
ue->ue_context.ue_reestablishment_counter,
ue->ue_context.ue_reconfiguration_after_reestablishment_counter);
return 0;
}
int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt)
{
if (!RC.nrmac)
ERROR_MSG_RET("no MAC/RLC present, cannot trigger reestablishment\n");
int rnti = -1;
if (!buf) {
rnti = get_single_ue_rnti_mac();
rnti = get_single_ue_rnti();
if (rnti < 1)
ERROR_MSG_RET("no UE found\n");
} else {
@@ -114,9 +82,37 @@ int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt)
ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n");
}
nr_rlc_test_trigger_reestablishment(rnti);
rrc_gNB_ue_context_t *ue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti);
if (!ue)
ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
prnt("Reset RLC counters of UE RNTI %04x to trigger reestablishment\n", rnti);
prnt("UE RNTI %04x reestab %d reconf_after_reestab %d\n",
rnti,
ue->ue_context.ue_reestablishment_counter,
ue->ue_context.ue_reconfiguration_after_reestablishment_counter);
return 0;
}
int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt)
{
int rnti = -1;
if (!buf) {
rnti = get_single_ue_rnti();
if (rnti < 1)
ERROR_MSG_RET("no UE found\n");
} else {
rnti = strtol(buf, NULL, 16);
if (rnti < 1 || rnti >= 0xfffe)
ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n");
}
// verify it exists in RRC as well
rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti);
if (!rrcue)
ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
nr_rlc_remove_ue(rnti);
prnt("force-remove UE RNTI %04x from RLC to trigger reestablishment\n", rnti);
return 0;
}

View File

@@ -29,15 +29,17 @@
* \note
* \warning
*/
#define _GNU_SOURCE
#define _GNU_SOURCE
#include <string.h>
#include <pthread.h>
#define TELNETSERVERCODE
#include "telnetsrv.h"
#define TELNETSRV_LOADER_MAIN
#include "telnetsrv_loader.h"
int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt);
telnetshell_cmddef_t loader_cmdarray[] = {
{"show", "[params,modules]", loader_show_cmd, {(webfunc_t)loader_show_cmd}, 0, NULL},
@@ -48,38 +50,36 @@ telnetshell_cmddef_t loader_cmdarray[] = {
int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt)
{
if (buff == NULL) {
buff = "modules";
prnt("ERROR wrong loader SHOW command...\n");
return 0;
}
if (debug > 0)
prnt("loader_show_cmd received \"%s\"\n", buff);
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 || buff[0] == 0) {
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);
prnt(" Shared library build version: \"%s\"\n",
((loader_data.shlibs[i].shlib_buildversion == NULL) ? "" : loader_data.shlibs[i].shlib_buildversion));
prnt(" Shared library path: \"%s\"\n", loader_data.shlibs[i].thisshlib_path);
prnt(" %i function pointers registered:\n", loader_data.shlibs[i].numfunc);
for (int j = 0; j < loader_data.shlibs[i].numfunc; j++) {
prnt(" function %i %s at %p\n",
j,
loader_data.shlibs[i].funcarray[j].fname,
loader_data.shlibs[i].funcarray[j].fptr);
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 || 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);
prnt(" Shared library build version: \"%s\"\n", ((loader_data.shlibs[i].shlib_buildversion == NULL) ? "" : loader_data.shlibs[i].shlib_buildversion));
prnt(" Shared library path: \"%s\"\n", loader_data.shlibs[i].thisshlib_path);
prnt(" %i function pointers registered:\n", loader_data.shlibs[i].numfunc);
for (int j = 0; j < loader_data.shlibs[i].numfunc; j++) {
prnt(" function %i %s at %p\n", j, loader_data.shlibs[i].funcarray[j].fname, loader_data.shlibs[i].funcarray[j].fptr);
}
}
} else {
prnt("%s: wrong loader command...\n", buff);
}
}
} else {
prnt("%s: wrong loader command...\n", buff);
}
return 0;
return 0;
}
void add_loader_cmds(void)
{
add_telnetcmd("loader", loader_globalvardef, loader_cmdarray);
add_telnetcmd("loader", loader_globalvardef, loader_cmdarray);
}

View File

@@ -59,133 +59,135 @@
void decode_procstat(char *record, int debug, telnet_printfunc_t prnt, webdatadef_t *tdata)
{
char prntline[160];
char *procfile_fields;
char *strtokptr;
char *lptr;
int fieldcnt;
char toksep[2];
char prntline[160];
char *procfile_fields;
char *strtokptr;
char *lptr;
int fieldcnt;
char toksep[2];
fieldcnt = 0;
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 */
int priority = 0;
int nice = 0;
while (procfile_fields != NULL && fieldcnt < 42) {
long int policy;
if (strlen(procfile_fields) == 0)
continue;
fieldcnt++;
sprintf(toksep, " ");
switch (fieldcnt) {
case 1: /* id */
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 */
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_fields[0]);
break;
case 14: // time in user mode
case 15: // time in kernel mode
lptr += sprintf(lptr, "%9.9s ", procfile_fields);
break;
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_fields);
break;
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_fields);
policy = strtol(procfile_fields, NULL, 0);
char strschedp[64];
switch (policy) {
case SCHED_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:
snprintf(strschedp, sizeof(strschedp), "%s ", "other");
priority = nice - NICE_MIN; // linux nice is -20 to 19
break;
case SCHED_IDLE:
snprintf(strschedp, sizeof(strschedp), "%s ", "idle");
priority = 2 * (NICE_MAX - NICE_MIN + 1);
break;
case SCHED_BATCH:
snprintf(strschedp, sizeof(strschedp), "%s ", "batch");
priority = (NICE_MAX - NICE_MIN + 1) + nice - NICE_MIN;
break;
case SCHED_RR:
snprintf(strschedp, sizeof(strschedp), "%s ", "rt:rr");
priority = priority - 99;
break;
fieldcnt = 0;
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 */
int priority = 0;
int nice = 0;
while (procfile_fields != NULL && fieldcnt < 42) {
long int policy;
if (strlen(procfile_fields) == 0)
continue;
fieldcnt++;
sprintf(toksep, " ");
switch (fieldcnt) {
case 1: /* id */
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 */
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_fields[0]);
break;
case 14: // time in user mode
case 15: // time in kernel mode
lptr += sprintf(lptr, "%9.9s ", procfile_fields);
break;
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_fields);
break;
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_fields);
policy = strtol(procfile_fields, NULL, 0);
char strschedp[64];
switch (policy) {
case SCHED_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:
snprintf(strschedp, sizeof(strschedp), "%s ", "other");
priority = nice - NICE_MIN; // linux nice is -20 to 19
break;
case SCHED_IDLE:
snprintf(strschedp, sizeof(strschedp), "%s ", "idle");
priority = 2 * (NICE_MAX - NICE_MIN + 1);
break;
case SCHED_BATCH:
snprintf(strschedp, sizeof(strschedp), "%s ", "batch");
priority = (NICE_MAX - NICE_MIN + 1) + nice - NICE_MIN;
break;
case SCHED_RR:
snprintf(strschedp, sizeof(strschedp), "%s ", "rt:rr");
priority = priority - 99;
break;
#ifdef SCHED_DEADLINE
case SCHED_DEADLINE:
snprintf(strschedp, sizeof(strschedp), "%s ", "rt:deadline");
break;
case SCHED_DEADLINE:
snprintf(strschedp, sizeof(strschedp), "%s ", "rt:deadline");
break;
#endif
default:
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_fields = strtok_r(NULL, toksep, &strtokptr);
} /* while on proc_fields != NULL */
prnt("%s\n", prntline);
if (tdata != NULL) {
tdata->numlines++;
}
default:
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_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, webdatadef_t *tdata)
{
FILE *procfile;
char arecord[1024];
FILE *procfile;
char arecord[1024];
procfile = fopen(fname, "r");
if (procfile == NULL) {
prnt("Error: Couldn't open %s %i %s\n", fname, errno, strerror(errno));
return;
}
if (fgets(arecord, sizeof(arecord), procfile) == NULL) {
prnt("Error: Nothing read from %s %i %s\n", fname, errno, strerror(errno));
procfile=fopen(fname,"r");
if (procfile == NULL)
{
prnt("Error: Couldn't open %s %i %s\n",fname,errno,strerror(errno));
return;
}
if ( fgets(arecord,sizeof(arecord),procfile) == NULL)
{
prnt("Error: Nothing read from %s %i %s\n",fname,errno,strerror(errno));
fclose(procfile);
return;
}
fclose(procfile);
return;
}
fclose(procfile);
decode_procstat(arecord, debug, prnt, tdata);
decode_procstat(arecord, debug, prnt, tdata);
}
int nullprnt(char *fmt, ...)
@@ -195,7 +197,7 @@ int nullprnt(char *fmt, ...)
void proccmd_get_threaddata(char *buf, int debug, telnet_printfunc_t fprnt, webdatadef_t *tdata)
{
char aname[256];
char aname[256];
DIR *proc_dir;
struct dirent *entry;
@@ -284,9 +286,7 @@ int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfun
} 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");
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) {
@@ -334,9 +334,7 @@ int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfun
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[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";
}
@@ -390,126 +388,124 @@ int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt)
prnt("ERROR wrong softmodem SHOW command...\n");
return 0;
}
if (debug > 0)
prnt(" proccmd_show received %s\n", buf);
if (strcasestr(buf, "thread") != NULL) {
print_threads(buf, debug, prnt);
}
if (strcasestr(buf, "loglvl") != NULL) {
prnt("\n component level enabled output\n");
for (int i = MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
if (g_log->log_component[i].name != NULL) {
prnt("%02i %17.17s:%10.10s %s %s\n",
i,
g_log->log_component[i].name,
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),
((g_log->log_component[i].level >= 0) ? "Y" : "N"),
((g_log->log_component[i].filelog > 0) ? g_log->log_component[i].filelog_name : "stdout"));
}
}
}
if (strcasestr(buf, "logopt") != NULL) {
prnt("\n option enabled\n");
for (int i = 0; log_options[i].name != NULL; i++) {
prnt("%02i %17.17s %10.10s \n", i, log_options[i].name, ((g_log->flag & log_options[i].value) ? "Y" : "N"));
}
}
if (strcasestr(buf, "dbgopt") != NULL) {
prnt("\n module debug dumpfile\n");
for (int i = 0; log_maskmap[i].name != NULL; i++) {
prnt("%02i %17.17s %5.5s %5.5s\n",
i,
log_maskmap[i].name,
((g_log->debug_mask & log_maskmap[i].value) ? "Y" : "N"),
((g_log->dump_mask & log_maskmap[i].value) ? "Y" : "N"));
}
}
if (strcasestr(buf, "config") != NULL) {
prnt("Command line arguments:\n");
for (int i = 0; i < config_get_if()->argc; i++) {
prnt(" %02i %s\n", i, config_get_if()->argv[i]);
}
prnt("Config module flags ( -O <cfg source>:<xxx>:dbgl<flags>): 0x%08x\n", config_get_if()->rtflags);
if (debug > 0)
prnt(" proccmd_show received %s\n",buf);
if (strcasestr(buf,"thread") != NULL) {
print_threads(buf,debug,prnt);
}
if (strcasestr(buf,"loglvl") != NULL) {
prnt("\n component level enabled output\n");
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
if (g_log->log_component[i].name != NULL) {
prnt("%02i %17.17s:%10.10s %s %s\n",i ,g_log->log_component[i].name,
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),
((g_log->log_component[i].level>=0)?"Y":"N"),
((g_log->log_component[i].filelog>0)?g_log->log_component[i].filelog_name:"stdout"));
}
}
}
if (strcasestr(buf,"logopt") != NULL) {
prnt("\n option enabled\n");
for (int i=0; log_options[i].name != NULL; i++) {
prnt("%02i %17.17s %10.10s \n",i ,log_options[i].name,
((g_log->flag & log_options[i].value)?"Y":"N") );
}
}
if (strcasestr(buf,"dbgopt") != NULL) {
prnt("\n module debug dumpfile\n");
for (int i=0; log_maskmap[i].name != NULL ; i++) {
prnt("%02i %17.17s %5.5s %5.5s\n",i ,log_maskmap[i].name,
((g_log->debug_mask & log_maskmap[i].value)?"Y":"N"),
((g_log->dump_mask & log_maskmap[i].value)?"Y":"N") );
}
}
if (strcasestr(buf,"config") != NULL) {
prnt("Command line arguments:\n");
for (int i=0; i < config_get_if()->argc; i++) {
prnt(" %02i %s\n",i ,config_get_if()->argv[i]);
}
prnt("Config module flags ( -O <cfg source>:<xxx>:dbgl<flags>): 0x%08x\n", config_get_if()->rtflags);
prnt(" Print config debug msg, params values (flag %u): %s\n",
CONFIG_PRINTPARAMS,
((config_get_if()->rtflags & CONFIG_PRINTPARAMS) ? "Y" : "N"));
prnt(" Print config debug msg, memory management(flag %u): %s\n",
CONFIG_DEBUGPTR,
((config_get_if()->rtflags & CONFIG_DEBUGPTR) ? "Y" : "N"));
prnt(" Print config debug msg, command line processing (flag %u): %s\n",
CONFIG_DEBUGCMDLINE,
((config_get_if()->rtflags & CONFIG_DEBUGCMDLINE) ? "Y" : "N"));
prnt(" Don't exit if param check fails (flag %u): %s\n",
CONFIG_NOABORTONCHKF,
((config_get_if()->rtflags & CONFIG_NOABORTONCHKF) ? "Y" : "N"));
prnt("Config source: %s, parameters:\n", CONFIG_GETSOURCE);
for (int i = 0; i < config_get_if()->num_cfgP; i++) {
prnt(" %02i %s\n", i, config_get_if()->cfgP[i]);
}
prnt("Softmodem components:\n");
prnt(" %02i Ru(s)\n", RC.nb_RU);
prnt(" %02i lte RRc(s), %02i NbIoT RRC(s)\n", RC.nb_inst, RC.nb_nb_iot_rrc_inst);
prnt(" %02i lte MACRLC(s), %02i NbIoT MACRLC(s)\n", RC.nb_macrlc_inst, RC.nb_nb_iot_macrlc_inst);
prnt(" %02i lte L1, %02i NbIoT L1\n", RC.nb_L1_inst, RC.nb_nb_iot_L1_inst);
prnt(" Print config debug msg, params values (flag %u): %s\n",CONFIG_PRINTPARAMS,
((config_get_if()->rtflags & CONFIG_PRINTPARAMS) ? "Y" : "N") );
prnt(" Print config debug msg, memory management(flag %u): %s\n",CONFIG_DEBUGPTR,
((config_get_if()->rtflags & CONFIG_DEBUGPTR) ? "Y" : "N") );
prnt(" Print config debug msg, command line processing (flag %u): %s\n",CONFIG_DEBUGCMDLINE,
((config_get_if()->rtflags & CONFIG_DEBUGCMDLINE) ? "Y" : "N") );
prnt(" Don't exit if param check fails (flag %u): %s\n",CONFIG_NOABORTONCHKF,
((config_get_if()->rtflags & CONFIG_NOABORTONCHKF) ? "Y" : "N") );
prnt("Config source: %s, parameters:\n",CONFIG_GETSOURCE );
for (int i=0; i < config_get_if()->num_cfgP; i++) {
prnt(" %02i %s\n",i ,config_get_if()->cfgP[i]);
}
prnt("Softmodem components:\n");
prnt(" %02i Ru(s)\n", RC.nb_RU);
prnt(" %02i lte RRc(s), %02i NbIoT RRC(s)\n", RC.nb_inst, RC.nb_nb_iot_rrc_inst);
prnt(" %02i lte MACRLC(s), %02i NbIoT MACRLC(s)\n", RC.nb_macrlc_inst, RC.nb_nb_iot_macrlc_inst);
prnt(" %02i lte L1, %02i NbIoT L1\n", RC.nb_L1_inst, RC.nb_nb_iot_L1_inst);
for (int i = 0; i < RC.nb_inst; i++) {
prnt(" lte RRC %i: %02i CC(s) \n", i, ((RC.nb_CC == NULL) ? 0 : RC.nb_CC[i]));
}
for (int i = 0; i < RC.nb_L1_inst; i++) {
prnt(" lte L1 %i: %02i CC(s)\n", i, ((RC.nb_L1_CC == NULL) ? 0 : RC.nb_L1_CC[i]));
}
for (int i = 0; i < RC.nb_macrlc_inst; i++) {
prnt(" lte macrlc %i: %02i CC(s)\n", i, ((RC.nb_mac_CC == NULL) ? 0 : RC.nb_mac_CC[i]));
}
}
return 0;
}
for(int i=0; i<RC.nb_inst; i++) {
prnt(" lte RRC %i: %02i CC(s) \n",i,((RC.nb_CC == NULL)?0:RC.nb_CC[i]));
}
for(int i=0; i<RC.nb_L1_inst; i++) {
prnt(" lte L1 %i: %02i CC(s)\n",i,((RC.nb_L1_CC == NULL)?0:RC.nb_L1_CC[i]));
}
for(int i=0; i<RC.nb_macrlc_inst; i++) {
prnt(" lte macrlc %i: %02i CC(s)\n",i,((RC.nb_mac_CC == NULL)?0:RC.nb_mac_CC[i]));
}
}
return 0;
}
int proccmd_thread(char *buf, int debug, telnet_printfunc_t prnt)
{
int bv1, bv2;
int res;
char sv1[64];
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;
if (debug > 0)
prnt("proccmd_thread received %s\n", buf);
if (strcasestr(buf, "help") != NULL) {
prnt(PROCCMD_THREAD_HELP_STRING);
return 0;
}
res = sscanf(buf, "%i %9s %i", &bv1, sv1, &bv2);
if (debug > 0)
prnt(" proccmd_thread: %i params = %i,%s,%i\n", res, bv1, sv1, bv2);
if (res != 3) {
print_threads(buf, debug, prnt);
return 0;
}
if (strcasestr(sv1, "prio") != NULL) {
set_sched(0, bv1, bv2);
} else if (strcasestr(sv1, "aff") != NULL) {
set_affinity(0, bv1, bv2);
} else {
prnt("%s is not a valid thread command\n", sv1);
}
if (buf == NULL) {
prnt("ERROR wrong thread command...\n");
return 0;
}
bv1=0;
bv2=0;
sv1[0]=0;
if (debug > 0)
prnt("proccmd_thread received %s\n",buf);
if (strcasestr(buf,"help") != NULL) {
prnt(PROCCMD_THREAD_HELP_STRING);
return 0;
}
res=sscanf(buf,"%i %9s %i",&bv1,sv1,&bv2);
if (debug > 0)
prnt(" proccmd_thread: %i params = %i,%s,%i\n",res,bv1,sv1,bv2);
if(res != 3)
{
print_threads(buf, debug, prnt);
return 0;
}
if (strcasestr(sv1,"prio") != NULL)
{
set_sched(0,bv1, bv2);
}
else if (strcasestr(sv1,"aff") != NULL)
{
set_affinity(0,bv1, bv2);
}
else
{
prnt("%s is not a valid thread command\n",sv1);
}
return 0;
}
int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt)
{
if (debug > 0)
prnt("process module received %s\n", buf);
exit_fun("telnet server received exit command\n");
return 0;
if (debug > 0)
prnt("process module received %s\n",buf);
exit_fun("telnet server received exit command\n");
return 0;
}
int proccmd_restart(char *buf, int debug, telnet_printfunc_t prnt)
@@ -524,157 +520,154 @@ int proccmd_restart(char *buf, int debug, telnet_printfunc_t prnt)
int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt)
{
int idx1 = 0;
int idx2 = NUM_LOG_LEVEL - 1;
char *logsubcmd = NULL;
int idx1=0;
int idx2=NUM_LOG_LEVEL-1;
char *logsubcmd=NULL;
if (buf == NULL) {
prnt("ERROR wrong \"log\" command...\n");
return 0;
}
int s = sscanf(buf, "%ms %i-%i\n", &logsubcmd, &idx1, &idx2);
int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
if (debug > 0)
prnt( "proccmd_log received %s\n s=%i sub command %s\n",buf,s,((logsubcmd==NULL)?"":logsubcmd));
if (debug > 0)
prnt("proccmd_log received %s\n s=%i sub command %s\n", buf, s, ((logsubcmd == NULL) ? "" : logsubcmd));
if (s == 1 && logsubcmd != NULL) {
if (strcasestr(logsubcmd, "online") != NULL) {
if (strcasestr(buf, "noonline") != NULL) {
set_glog_onlinelog(0);
prnt("online logging disabled\n", buf);
} else {
set_glog_onlinelog(1);
prnt("online logging enabled\n", buf);
if (s == 1 && logsubcmd != NULL) {
if (strcasestr(logsubcmd,"online") != NULL) {
if (strcasestr(buf,"noonline") != NULL) {
set_glog_onlinelog(0);
prnt("online logging disabled\n",buf);
} else {
set_glog_onlinelog(1);
prnt("online logging enabled\n",buf);
}
}
} else if (strcasestr(logsubcmd, "show") != NULL) {
prnt("Available log levels: \n ");
for (int i = 0; log_level_names[i].name != NULL; i++)
prnt("%s ", log_level_names[i].name);
prnt("\n\n");
prnt("Available display options: \n ");
for (int i = 0; log_options[i].name != NULL; i++)
prnt("%s ", log_options[i].name);
prnt("\n\n");
prnt("Available debug and dump options: \n ");
for (int i = 0; log_maskmap[i].name != NULL; i++)
prnt("%s ", log_maskmap[i].name);
prnt("\n\n");
proccmd_show("loglvl", debug, prnt);
proccmd_show("logopt", debug, prnt);
proccmd_show("dbgopt", debug, prnt);
} else if (strcasestr(logsubcmd, "help") != NULL) {
prnt(PROCCMD_LOG_HELP_STRING);
} else {
prnt("%s: wrong log command...\n", logsubcmd);
}
} else if (s == 2 && logsubcmd != NULL) {
char *opt = NULL;
char *logparam = NULL;
int l;
int optbit;
else if (strcasestr(logsubcmd,"show") != NULL) {
prnt("Available log levels: \n ");
for (int i=0; log_level_names[i].name != NULL; i++)
prnt("%s ",log_level_names[i].name);
prnt("\n\n");
prnt("Available display options: \n ");
for (int i=0; log_options[i].name != NULL; i++)
prnt("%s ",log_options[i].name);
prnt("\n\n");
prnt("Available debug and dump options: \n ");
for (int i=0; log_maskmap[i].name != NULL; i++)
prnt("%s ",log_maskmap[i].name);
prnt("\n\n");
proccmd_show("loglvl",debug,prnt);
proccmd_show("logopt",debug,prnt);
proccmd_show("dbgopt",debug,prnt);
}
else if (strcasestr(logsubcmd,"help") != NULL) {
prnt(PROCCMD_LOG_HELP_STRING);
} else {
prnt("%s: wrong log command...\n",logsubcmd);
}
} else if ( s == 2 && logsubcmd != NULL) {
char *opt=NULL;
char *logparam=NULL;
int l;
int optbit;
l = sscanf(logsubcmd, "%m[^'_']_%ms", &logparam, &opt);
if (l == 2 && strcmp(logparam, "print") == 0) {
optbit = map_str_to_int(log_options, opt);
if (optbit < 0) {
prnt("option %s unknown\n", opt);
} else {
if (idx1 > 0)
SET_LOG_OPTION(optbit);
else
CLEAR_LOG_OPTION(optbit);
proccmd_show("logopt", debug, prnt);
l=sscanf(logsubcmd,"%m[^'_']_%ms",&logparam,&opt);
if (l == 2 && strcmp(logparam,"print") == 0){
optbit=map_str_to_int(log_options,opt);
if (optbit < 0) {
prnt("option %s unknown\n",opt);
} else {
if (idx1 > 0)
SET_LOG_OPTION(optbit);
else
CLEAR_LOG_OPTION(optbit);
proccmd_show("logopt",debug,prnt);
}
}
} else if (l == 2 && strcmp(logparam, "debug") == 0) {
optbit = map_str_to_int(log_maskmap, opt);
if (optbit < 0) {
prnt("module %s unknown\n", opt);
} else {
if (idx1 > 0)
SET_LOG_DEBUG(optbit);
else
CLEAR_LOG_DEBUG(optbit);
proccmd_show("dbgopt", debug, prnt);
}
} else if (l == 2 && strcmp(logparam, "dump") == 0) {
optbit = map_str_to_int(log_maskmap, opt);
if (optbit < 0) {
prnt("module %s unknown\n", opt);
} else {
if (idx1 > 0)
SET_LOG_DUMP(optbit);
else
CLEAR_LOG_DUMP(optbit);
proccmd_show("dump", debug, prnt);
}
}
if (logparam != NULL)
free(logparam);
if (opt != NULL)
free(opt);
} else if (s == 3 && logsubcmd != NULL) {
int level, enable, filelog;
char *tmpstr = NULL;
char *logparam = NULL;
int l;
else if (l == 2 && strcmp(logparam,"debug") == 0){
optbit=map_str_to_int(log_maskmap,opt);
if (optbit < 0) {
prnt("module %s unknown\n",opt);
} else {
if (idx1 > 0)
SET_LOG_DEBUG(optbit);
else
CLEAR_LOG_DEBUG(optbit);
proccmd_show("dbgopt",debug,prnt);
}
}
else if (l == 2 && strcmp(logparam,"dump") == 0){
optbit=map_str_to_int(log_maskmap,opt);
if (optbit < 0) {
prnt("module %s unknown\n",opt);
} else {
if (idx1 > 0)
SET_LOG_DUMP(optbit);
else
CLEAR_LOG_DUMP(optbit);
proccmd_show("dump", debug, prnt);
}
}
if (logparam != NULL) free(logparam);
if (opt != NULL) free(opt);
} else if ( s == 3 && logsubcmd != NULL) {
int level, enable,filelog;
char *tmpstr=NULL;
char *logparam=NULL;
int l;
level = OAILOG_DISABLE - 1;
filelog = -1;
enable = -1;
l = sscanf(logsubcmd, "%m[^'_']_%m[^'_']", &logparam, &tmpstr);
if (debug > 0)
prnt("l=%i, %s %s\n", l, ((logparam == NULL) ? "\"\"" : logparam), ((tmpstr == NULL) ? "\"\"" : tmpstr));
if (l == 2) {
if (strcmp(logparam, "level") == 0) {
level = OAILOG_DISABLE - 1;
filelog = -1;
enable=-1;
l=sscanf(logsubcmd,"%m[^'_']_%m[^'_']",&logparam,&tmpstr);
if (debug > 0)
prnt("l=%i, %s %s\n",l,((logparam==NULL)?"\"\"":logparam), ((tmpstr==NULL)?"\"\"":tmpstr));
if (l ==2 ) {
if (strcmp(logparam,"level") == 0) {
level=map_str_to_int(log_level_names,tmpstr);
if (level < 0) {
prnt("level %s unknown\n",tmpstr);
level=OAILOG_DISABLE - 1;
}
} else {
prnt("%s%s unknown log sub command \n",logparam, tmpstr);
}
} else if (l ==1 ) {
if (strcmp(logparam,"enable") == 0) {
enable=1;
} else if (strcmp(logparam,"disable") == 0) {
level=OAILOG_DISABLE;
} else if (strcmp(logparam,"file") == 0) {
filelog = 1 ;
} else if (strcmp(logparam,"nofile") == 0) {
filelog = 0 ;
} else {
prnt("%s%s unknown log sub command \n",logparam, tmpstr);
}
} else {
level = map_str_to_int(log_level_names, tmpstr);
if (level < 0) {
prnt("level %s unknown\n", tmpstr);
level = OAILOG_DISABLE - 1;
}
} else {
prnt("%s%s unknown log sub command \n", logparam, tmpstr);
prnt("%s unknown log sub command \n", logsubcmd);
}
} else if (l == 1) {
if (strcmp(logparam, "enable") == 0) {
enable = 1;
} else if (strcmp(logparam, "disable") == 0) {
level = OAILOG_DISABLE;
} else if (strcmp(logparam, "file") == 0) {
filelog = 1;
} else if (strcmp(logparam, "nofile") == 0) {
filelog = 0;
} else {
prnt("%s%s unknown log sub command \n", logparam, tmpstr);
if (logparam != NULL) free(logparam);
if (tmpstr != NULL) free(tmpstr);
for (int i=idx1; i<=idx2 ; i++) {
if (level >= OAILOG_DISABLE)
set_log(i, level);
else if ( enable == 1)
set_log(i,g_log->log_component[i].savedlevel);
else if ( filelog == 1 ) {
set_component_filelog(i);
} else if ( filelog == 0 ) {
close_component_filelog(i);
}
}
} else {
level = map_str_to_int(log_level_names, tmpstr);
prnt("%s unknown log sub command \n", logsubcmd);
}
if (logparam != NULL)
free(logparam);
if (tmpstr != NULL)
free(tmpstr);
for (int i = idx1; i <= idx2; i++) {
if (level >= OAILOG_DISABLE)
set_log(i, level);
else if (enable == 1)
set_log(i, g_log->log_component[i].savedlevel);
else if (filelog == 1) {
set_component_filelog(i);
} else if (filelog == 0) {
close_component_filelog(i);
}
}
proccmd_show("loglvl", debug, prnt);
} else {
prnt("%s: wrong log command...\n", buf);
}
proccmd_show("loglvl",debug,prnt);
} else {
prnt("%s: wrong log command...\n",buf);
}
return 0;
}
return 0;
}
/*-------------------------------------------------------------------------------------*/
void add_softmodem_cmds(void)
{
add_telnetcmd("softmodem", proc_vardef, proc_cmdarray);
add_telnetcmd("softmodem",proc_vardef,proc_cmdarray);
}

View File

@@ -26,8 +26,6 @@
#define THREAD_POOL_H
#include <stdbool.h>
#include <stdint.h>
#include <malloc.h>
#include <stdalign.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
@@ -66,10 +64,7 @@ typedef struct notifiedFIFO_elt_s {
oai_cputime_t startProcessingTime;
oai_cputime_t endProcessingTime;
oai_cputime_t returnTime;
// use alignas(32) to align msgData to 32b
// user data behind it will be aligned to 32b as well
// important! this needs to be the last member in the struct
alignas(32) void *msgData;
void *msgData;
} notifiedFIFO_elt_t;
typedef struct notifiedFIFO_s {
@@ -85,15 +80,14 @@ static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size,
uint64_t key,
notifiedFIFO_t *reponseFifo,
void (*processingFunc)(void *)) {
notifiedFIFO_elt_t *ret = (notifiedFIFO_elt_t *)memalign(32, sizeof(notifiedFIFO_elt_t) + size);
AssertFatal(NULL != ret, "out of memory\n");
notifiedFIFO_elt_t *ret;
AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) calloc(1, sizeof(notifiedFIFO_elt_t)+size+32)), "");
ret->next=NULL;
ret->key=key;
ret->reponseFifo=reponseFifo;
ret->processingFunc=processingFunc;
// We set user data piece aligend 32 bytes to be able to process it with SIMD
// msgData is aligned to 32bytes, so everything after will be as well
ret->msgData = ((uint8_t *)ret) + sizeof(notifiedFIFO_elt_t);
ret->msgData=(void *)((uint8_t*)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32);
ret->malloced=true;
return ret;
}

View File

@@ -34,7 +34,6 @@
#include <ulfius.h>
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
#include "common/config/config_userapi.h"
#include "common/utils/LOG/log.h"
#include "common/utils/websrv/websrv.h"
@@ -50,9 +49,8 @@ static websrv_params_t websrvparams;
static telnetsrv_params_t *dummy_telnetsrv_params = NULL;
paramdef_t websrvoptions[] = {
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* configuration parameters for telnet utility */
/* optname helpstr paramflags XXXptr defXXXval type
numelt */
/* configuration parameters for telnet utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
{"listenaddr", "<listen ip address>\n", 0, uptr : &websrvparams.listenaddr, defstrval : "0.0.0.0", TYPE_IPV4ADDR, 0},
{"listenport", "<local port>\n", 0, uptr : &(websrvparams.listenport), defuintval : 8090, TYPE_UINT, 0},
@@ -139,10 +137,7 @@ int websrv_callback_auth(const struct _u_request *request, struct _u_response *r
issuer_dn[libuf] = '\0';
LOG_I(UTIL, "[websrv] dn of the client: %s, dn of the issuer: %s \n", dn, issuer_dn);
} else {
LOG_I(UTIL,
"[websrv] dn of the client: %s, dn of the issuer: %s \n",
(dn == NULL) ? "null" : dn,
(issuer_dn == NULL) ? "null" : issuer_dn);
LOG_I(UTIL, "[websrv] dn of the client: %s, dn of the issuer: %s \n", (dn == NULL) ? "null" : dn, (issuer_dn == NULL) ? "null" : issuer_dn);
ulfius_set_string_body_response(response, 400, "Couldn't authenticate client");
}
free(dn);
@@ -215,19 +210,7 @@ int websrv_callback_set_moduleparams(const struct _u_request *request, struct _u
char *cname;
char *ctype;
int cmod;
ures = json_unpack_ex(jelem,
&jerror,
0,
"{s:s,s:{s:s,s:s,s:b}}",
"value",
&cvalue,
"col",
"name",
&cname,
"type",
&ctype,
"modifiable",
&cmod);
ures = json_unpack_ex(jelem, &jerror, 0, "{s:s,s:{s:s,s:s,s:b}}", "value", &cvalue, "col", "name", &cname, "type", &ctype, "modifiable", &cmod);
if (ures != 0) {
websrv_printf("cannot unpack json element %i %s\n", i, jerror.text);
} else {
@@ -332,11 +315,7 @@ int websrv_callback_newmodule(const struct _u_request *request, struct _u_respon
}
telnetsrv_params_t *telnetparams = (telnetsrv_params_t *)user_data;
for (int i = 0; i < u_map_count(request->map_url); i++) {
LOG_I(UTIL,
"[websrv] url element %i %s : %s\n",
i,
u_map_enum_keys(request->map_url)[i],
u_map_enum_values(request->map_url)[i]);
LOG_I(UTIL, "[websrv] url element %i %s : %s\n", i, u_map_enum_keys(request->map_url)[i], u_map_enum_values(request->map_url)[i]);
if (strcmp(u_map_enum_keys(request->map_url)[i], "module") == 0) {
for (int j = 0; telnetparams->CmdParsers[j].cmd != NULL; j++) {
/* found the module in the telnet server module array, it was likely not registered at init time */
@@ -357,11 +336,7 @@ int websrv_callback_okset_softmodem_cmdvar(const struct _u_request *request, str
{
LOG_I(UTIL, "[websrv] : callback_okset_softmodem_cmdvar received %s %s\n", request->http_verb, request->http_url);
for (int i = 0; i < u_map_count(request->map_header); i++)
LOG_I(UTIL,
"[websrv] header variable %i %s : %s\n",
i,
u_map_enum_keys(request->map_header)[i],
u_map_enum_values(request->map_header)[i]);
LOG_I(UTIL, "[websrv] header variable %i %s : %s\n", i, u_map_enum_keys(request->map_header)[i], u_map_enum_values(request->map_header)[i]);
int us = ulfius_add_header_to_response(response, "Access-Control-Request-Method", "POST");
if (us != U_OK) {
ulfius_set_string_body_response(response, 501, "Internal server error (ulfius_add_header_to_response)");
@@ -458,77 +433,45 @@ int websrv_processwebfunc(struct _u_response *response, cmdparser_t *modulestruc
{
LOG_I(UTIL, "[websrv] : executing command %s %s\n", modulestruct->module, cmd->cmdname);
if ((cmd->cmdflags & TELNETSRV_CMDFLAG_NEEDPARAM) && jparams == NULL) {
LOG_W(UTIL, "No parameters sent by frontend for %s %s\n", modulestruct->module, cmd->cmdname);
return 500;
LOG_W(UTIL, "No parameters sent by frontend for %s %s\n", modulestruct->module, cmd->cmdname);
return 500;
}
int http_status = 200;
char *pname[2], *pvalue[2];
size_t np = 0;
size_t np =0;
if (jparams != NULL) {
int b[2];
char *ptype[2];
json_error_t jerror;
np = json_array_size(jparams);
int jrt;
switch (np) {
case 1:
jrt = json_unpack_ex(jparams,
&jerror,
0,
"[{s:s,s:s,s:s,s,b}]",
"name",
&pname[0],
"value",
&pvalue[0],
"type",
&ptype[0],
"modifiable",
&b);
break;
case 2:
jrt = json_unpack_ex(jparams,
&jerror,
0,
"[{s:s,s:s,s:s,s,b},{s:s,s:s,s:s,s,b}]",
"name",
&pname[0],
"value",
&pvalue[0],
"type",
&ptype[0],
"modifiable",
&b[0],
"name",
&pname[1],
"value",
&pvalue[1],
"type",
&ptype[1],
"modifiable",
&b[1]);
break;
default:
http_status = 500;
break;
// json_unpack_ex(jparams, &jerror, 0, "[{s:s,s:s,s:s,s,b}]", "name", &pname, "value", &pvalue, "type", &ptype,
// "modifiable", &b);
}
if (jrt < 0 || http_status != 200) {
LOG_I(UTIL,
"[websrv], couldn't unpack jparams, module %s, command %s: %s\n",
modulestruct->module,
cmd->cmdname,
jerror.text);
websrv_printjson((char *)__FUNCTION__, jparams, websrvparams.dbglvl);
return 500;
}
int b[2];
char *ptype[2];
json_error_t jerror;
np = json_array_size(jparams);
int jrt;
switch(np) {
case 1:
jrt=json_unpack_ex(jparams, &jerror, 0, "[{s:s,s:s,s:s,s,b}]", "name", &pname[0], "value", &pvalue[0], "type", &ptype[0], "modifiable", &b);
break;
case 2:
jrt=json_unpack_ex(jparams, &jerror, 0, "[{s:s,s:s,s:s,s,b},{s:s,s:s,s:s,s,b}]",
"name", &pname[0], "value", &pvalue[0], "type", &ptype[0], "modifiable", &b[0],
"name", &pname[1], "value", &pvalue[1], "type", &ptype[1], "modifiable", &b[1]);
break;
default:
http_status=500;
break;
// json_unpack_ex(jparams, &jerror, 0, "[{s:s,s:s,s:s,s,b}]", "name", &pname, "value", &pvalue, "type", &ptype, "modifiable", &b);
}
if (jrt <0 || http_status != 200) {
LOG_I(UTIL, "[websrv], couldn't unpack jparams, module %s, command %s: %s\n", modulestruct->module, cmd->cmdname, jerror.text);
websrv_printjson((char *)__FUNCTION__, jparams, websrvparams.dbglvl);
return 500;
}
}
if (cmd->cmdflags & TELNETSRV_CMDFLAG_GETWEBTBLDATA) {
webdatadef_t wdata;
memset(&wdata, 0, sizeof(wdata));
wdata.numlines = 1;
for (int i = 0; i < np; i++) {
for (int i=0; i<np; i++) {
snprintf(wdata.columns[i].coltitle, sizeof(wdata.columns[i].coltitle) - 1, "%s", pname[i]);
wdata.numcols = np;
wdata.lines[0].val[i] = pvalue[i];
@@ -537,15 +480,8 @@ int websrv_processwebfunc(struct _u_response *response, cmdparser_t *modulestruc
websrv_gettbldata_response(response, &wdata, modulestruct->module, cmd->cmdname);
} else {
char *sptr = index(cmd->cmdname, ' ');
char cmdbuff[TELNET_CMD_MAXSIZE * 3]; // cmd + 2 parameters
snprintf(cmdbuff,
sizeof(cmdbuff) - 1,
"%s%s%s%s%s",
(sptr == NULL) ? "" : sptr,
(np > 0) ? " " : "",
(np > 0) ? pvalue[0] : "",
(np > 1) ? " " : "",
(np > 1) ? pvalue[1] : "");
char cmdbuff[TELNET_CMD_MAXSIZE*3]; //cmd + 2 parameters
snprintf(cmdbuff,sizeof(cmdbuff)-1, "%s%s%s %s",(sptr == NULL) ? "" : sptr,(sptr == NULL) ? "" : " ",(np>0) ? pvalue[0] : "",(np>1) ? pvalue[1] : "");
if (cmd->qptr != NULL) {
websrv_printf_start(response, 16384, true);
telnet_pushcmd(cmd, cmdbuff, websrv_async_printf);
@@ -600,11 +536,7 @@ int websrv_callback_exec_softmodemcmd(const struct _u_request *request, struct _
/* callback processing module url (<address>/oaisoftmodem/module/variables), get method*/
int websrv_callback_get_softmodemvar(const struct _u_request *request, struct _u_response *response, void *user_data)
{
LOG_I(UTIL,
"[websrv] : callback_get_softmodemvar received %s %s module %s\n",
request->http_verb,
request->http_url,
(user_data == NULL) ? "NULL" : ((cmdparser_t *)user_data)->module);
LOG_I(UTIL, "[websrv] : callback_get_softmodemvar received %s %s module %s\n", request->http_verb, request->http_url, (user_data == NULL) ? "NULL" : ((cmdparser_t *)user_data)->module);
if (user_data == NULL) {
ulfius_set_string_body_response(response, 500, "No variables defined for this module");
return U_CALLBACK_COMPLETE;
@@ -621,61 +553,22 @@ int websrv_callback_get_softmodemvar(const struct _u_request *request, struct _u
json_t *oneaction;
switch (modulestruct->var[j].vartype) {
case TELNET_VARTYPE_DOUBLE:
oneaction = json_pack("{s:s,s:s,s:g,s:b}",
"type",
"number",
"name",
modulestruct->var[j].varname,
"value",
*(double *)(modulestruct->var[j].varvalptr),
"modifiable",
modifiable);
oneaction = json_pack("{s:s,s:s,s:g,s:b}", "type", "number", "name", modulestruct->var[j].varname, "value", *(double *)(modulestruct->var[j].varvalptr), "modifiable", modifiable);
case TELNET_VARTYPE_INT32:
case TELNET_VARTYPE_INT16:
case TELNET_VARTYPE_INT8:
case TELNET_VARTYPE_UINT:
oneaction = json_pack("{s:s,s:s,s:i,s:b}",
"type",
"number",
"name",
modulestruct->var[j].varname,
"value",
(int)(*(int *)(modulestruct->var[j].varvalptr)),
"modifiable",
modifiable);
oneaction = json_pack("{s:s,s:s,s:i,s:b}", "type", "number", "name", modulestruct->var[j].varname, "value", (int)(*(int *)(modulestruct->var[j].varvalptr)), "modifiable", modifiable);
break;
case TELNET_VARTYPE_INT64:
oneaction = json_pack("{s:s,s:s,s:lli,s:b}",
"type",
"number",
"name",
modulestruct->var[j].varname,
"value",
(int64_t)(*(int64_t *)(modulestruct->var[j].varvalptr)),
"modifiable",
modifiable);
oneaction =
json_pack("{s:s,s:s,s:lli,s:b}", "type", "number", "name", modulestruct->var[j].varname, "value", (int64_t)(*(int64_t *)(modulestruct->var[j].varvalptr)), "modifiable", modifiable);
break;
case TELNET_VARTYPE_STRING:
oneaction = json_pack("{s:s,s:s,s:s,s:b}",
"type",
"string",
"name",
modulestruct->var[j].varname,
"value",
strval,
"modifiable",
modifiable);
oneaction = json_pack("{s:s,s:s,s:s,s:b}", "type", "string", "name", modulestruct->var[j].varname, "value", strval, "modifiable", modifiable);
break;
default:
oneaction = json_pack("{s:s,s:s,s:s,s:b}",
"type",
"???",
"name",
modulestruct->var[j].varname,
"value",
"???",
"modifiable",
modifiable);
oneaction = json_pack("{s:s,s:s,s:s,s:b}", "type", "???", "name", modulestruct->var[j].varname, "value", "???", "modifiable", modifiable);
break;
}
if (oneaction == NULL) {
@@ -708,11 +601,7 @@ int websrv_callback_get_softmodemvar(const struct _u_request *request, struct _u
/* callback processing module url (<address>/oaisoftmodem/module/commands)*/
int websrv_callback_get_softmodemcmd(const struct _u_request *request, struct _u_response *response, void *user_data)
{
LOG_I(UTIL,
"[websrv] : callback_get_softmodemcmd received %s %s module %s\n",
request->http_verb,
request->http_url,
(user_data == NULL) ? "NULL" : ((cmdparser_t *)user_data)->module);
LOG_I(UTIL, "[websrv] : callback_get_softmodemcmd received %s %s module %s\n", request->http_verb, request->http_url, (user_data == NULL) ? "NULL" : ((cmdparser_t *)user_data)->module);
if (user_data == NULL) {
ulfius_set_string_body_response(response, 500, "No commands defined for this module");
return U_CALLBACK_COMPLETE;
@@ -731,23 +620,23 @@ int websrv_callback_get_softmodemcmd(const struct _u_request *request, struct _u
snprintf(confstr, sizeof(confstr), "Confirm %s ?", modulestruct->cmd[j].cmdname);
acmd = json_pack("{s:s,s:s}", "name", modulestruct->cmd[j].cmdname, "confirm", confstr);
} else if (modulestruct->cmd[j].cmdflags & TELNETSRV_CMDFLAG_NEEDPARAM) {
char *question[] = {NULL, NULL};
char *question[] = {NULL,NULL};
char *helpcp = NULL;
json_t *jQ1 = NULL, *jQ2 = NULL;
json_t *jQ1=NULL, *jQ2=NULL;
json_t *jQs = json_array();
if (modulestruct->cmd[j].helpstr != NULL) {
helpcp = strdup(modulestruct->cmd[j].helpstr);
int ns = sscanf(helpcp, "<%m[^<>]> <%m[^<>]>", &question[0], &question[1]);
int ns=sscanf(helpcp,"<%m[^<>]> <%m[^<>]>",&question[0],&question[1]);
if (ns == 0) {
LOG_W(UTIL, "[websrv] Cannot find parameters for command %s %s\n", modulestruct->module, modulestruct->cmd[j].cmdname);
continue;
}
jQ1 = json_pack("{s:s,s:s,s:s}", "display", question[0], "pname", "P0", "type", "string");
LOG_W(UTIL, "[websrv] Cannot find parameters for command %s %s\n", modulestruct->module, modulestruct->cmd[j].cmdname);
continue;
}
jQ1=json_pack("{s:s,s:s,s:s}", "display",question[0], "pname", "P0", "type", "string");
json_array_append_new(jQs, jQ1);
if (ns > 1) {
jQ2 = json_pack("{s:s,s:s,s:s}", "display", (question[1] == NULL) ? "" : question[1], "pname", "P1", "type", "string");
json_array_append_new(jQs, jQ2);
}
if (ns >1) {
jQ2=json_pack("{s:s,s:s,s:s}","display", (question[1] == NULL) ? "" : question[1], "pname", "P1" , "type", "string");
json_array_append_new(jQs, jQ2);
}
}
acmd = json_pack("{s:s,s:o}", "name", modulestruct->cmd[j].cmdname, "question", jQs);
free(helpcp);
@@ -756,10 +645,10 @@ int websrv_callback_get_softmodemcmd(const struct _u_request *request, struct _u
} else {
acmd = json_pack("{s:s}", "name", modulestruct->cmd[j].cmdname);
}
if (acmd == NULL) {
LOG_W(UTIL, "[websrv] interface for command %s %s cannot be built\n", modulestruct->module, modulestruct->cmd[j].cmdname);
continue;
}
if ( acmd == NULL) {
LOG_W(UTIL, "[websrv] interface for command %s %s cannot be built\n", modulestruct->module, modulestruct->cmd[j].cmdname);
continue;
}
json_t *jopts = json_array();
if (modulestruct->cmd[j].cmdflags & TELNETSRV_CMDFLAG_AUTOUPDATE) {
json_array_append_new(jopts, json_string("update"));
@@ -895,13 +784,7 @@ int websrv_add_endpoint(char **http_method,
int j = 0;
int priority = (user_data == NULL) ? 10 : 1;
for (int i = 0; i < num_method; i++) {
status = ulfius_add_endpoint_by_val(&(websrvparams.instance),
http_method[i],
url_prefix,
url_format,
priority,
callback_function[i],
user_data);
status = ulfius_add_endpoint_by_val(&(websrvparams.instance), http_method[i], url_prefix, url_format, priority, callback_function[i], user_data);
if (status != U_OK) {
LOG_E(UTIL, "[websrv] cannot add endpoint %s %s/%s\n", http_method[i], url_prefix, url_format);
} else {
@@ -915,15 +798,11 @@ int websrv_add_endpoint(char **http_method,
void register_module_endpoints(cmdparser_t *module)
{
int (*callback_functions_var[3])(const struct _u_request *request, struct _u_response *response, void *user_data) = {
websrv_callback_okset_softmodem_cmdvar,
websrv_callback_set_softmodemvar,
websrv_callback_get_softmodemvar};
websrv_callback_okset_softmodem_cmdvar, websrv_callback_set_softmodemvar, websrv_callback_get_softmodemvar};
char *http_methods[3] = {"OPTIONS", "POST", "GET"};
int (*callback_functions_cmd[3])(const struct _u_request *request, struct _u_response *response, void *user_data) = {
websrv_callback_okset_softmodem_cmdvar,
websrv_callback_exec_softmodemcmd,
websrv_callback_get_softmodemcmd};
websrv_callback_okset_softmodem_cmdvar, websrv_callback_exec_softmodemcmd, websrv_callback_get_softmodemcmd};
char prefixurl[TELNET_CMD_MAXSIZE + 20];
snprintf(prefixurl, TELNET_CMD_MAXSIZE + 19, "oaisoftmodem/%s", module->module);
LOG_I(UTIL, "[websrv] add endpoints %s/[variables or commands] \n", prefixurl);
@@ -963,22 +842,14 @@ void *websrv_autoinit()
websrvparams.instance.max_post_body_size = 1024;
// 1: build the first page, when receiving the "oaisoftmodem" url
ulfius_add_endpoint_by_val(&(websrvparams.instance),
"GET",
"oaisoftmodem",
"commands",
1,
&websrv_callback_get_softmodemmodules,
NULL);
ulfius_add_endpoint_by_val(&(websrvparams.instance), "GET", "oaisoftmodem", "commands", 1, &websrv_callback_get_softmodemmodules, NULL);
// 2 default_endpoint declaration, it tries to open the file with the url name as specified in the request.It looks for the file
ulfius_set_default_endpoint(&(websrvparams.instance), &websrv_callback_default, NULL);
// 3 endpoints corresponding to loaded telnet modules
int (*callback_functions_var[3])(const struct _u_request *request, struct _u_response *response, void *user_data) = {
websrv_callback_get_softmodemstatus,
websrv_callback_okset_softmodem_cmdvar,
websrv_callback_set_softmodemvar};
websrv_callback_get_softmodemstatus, websrv_callback_okset_softmodem_cmdvar, websrv_callback_set_softmodemvar};
char *http_methods[3] = {"GET", "OPTIONS", "POST"};
websrv_add_endpoint(http_methods, 3, "oaisoftmodem", "info", callback_functions_var, NULL);
@@ -988,30 +859,12 @@ void *websrv_autoinit()
}
/*4 callbacks to take care of modules not yet initialized, so not visible in telnet server data when this autoinit runs: */
ulfius_add_endpoint_by_val(&(websrvparams.instance),
"GET",
"oaisoftmodem",
"@module/commands",
10,
websrv_callback_newmodule,
telnetparams);
ulfius_add_endpoint_by_val(&(websrvparams.instance),
"GET",
"oaisoftmodem",
"@module/variables",
10,
websrv_callback_newmodule,
telnetparams);
ulfius_add_endpoint_by_val(&(websrvparams.instance), "GET", "oaisoftmodem", "@module/commands", 10, websrv_callback_newmodule, telnetparams);
ulfius_add_endpoint_by_val(&(websrvparams.instance), "GET", "oaisoftmodem", "@module/variables", 10, websrv_callback_newmodule, telnetparams);
// 5 callback to handle file request
ulfius_add_endpoint_by_val(&(websrvparams.instance), "POST", "oaisoftmodem", "file", 1, &websrv_callback_get_softmodemfile, NULL);
// 6 callback for help request
ulfius_add_endpoint_by_val(&(websrvparams.instance),
"GET",
"oaisoftmodem",
"helpfiles/@hlpfile",
2,
&websrv_callback_get_softmodemhelp,
NULL);
ulfius_add_endpoint_by_val(&(websrvparams.instance), "GET", "oaisoftmodem", "helpfiles/@hlpfile", 2, &websrv_callback_get_softmodemhelp, NULL);
// init softscope interface support */
websrv_init_scope(&websrvparams);

View File

@@ -110,41 +110,19 @@ void websrv_printjson(char *label, json_t *jsonobj, int dbglvl)
void websrv_dump_request(char *label, const struct _u_request *request, int dbglvl)
{
if (dbglvl > 0) {
LOG_I(UTIL,
"[websrv] %s, request %s, proto %s, verb %s, path %s\n",
label,
request->http_url,
request->http_protocol,
request->http_verb,
request->http_verb);
LOG_I(UTIL, "[websrv] %s, request %s, proto %s, verb %s, path %s\n", label, request->http_url, request->http_protocol, request->http_verb, request->http_verb);
if (request->map_post_body != NULL)
for (int i = 0; i < u_map_count(request->map_post_body); i++)
LOG_I(UTIL,
"[websrv] POST parameter %i %s : %s\n",
i,
u_map_enum_keys(request->map_post_body)[i],
u_map_enum_values(request->map_post_body)[i]);
LOG_I(UTIL, "[websrv] POST parameter %i %s : %s\n", i, u_map_enum_keys(request->map_post_body)[i], u_map_enum_values(request->map_post_body)[i]);
if (request->map_cookie != NULL)
for (int i = 0; i < u_map_count(request->map_cookie); i++)
LOG_I(UTIL,
"[websrv] cookie variable %i %s : %s\n",
i,
u_map_enum_keys(request->map_cookie)[i],
u_map_enum_values(request->map_cookie)[i]);
LOG_I(UTIL, "[websrv] cookie variable %i %s : %s\n", i, u_map_enum_keys(request->map_cookie)[i], u_map_enum_values(request->map_cookie)[i]);
if (request->map_header != NULL)
for (int i = 0; i < u_map_count(request->map_header); i++)
LOG_I(UTIL,
"[websrv] header variable %i %s : %s\n",
i,
u_map_enum_keys(request->map_header)[i],
u_map_enum_values(request->map_header)[i]);
LOG_I(UTIL, "[websrv] header variable %i %s : %s\n", i, u_map_enum_keys(request->map_header)[i], u_map_enum_values(request->map_header)[i]);
if (request->map_url != NULL)
for (int i = 0; i < u_map_count(request->map_url); i++)
LOG_I(UTIL,
"[websrv] url variable %i %s : %s\n",
i,
u_map_enum_keys(request->map_url)[i],
u_map_enum_values(request->map_url)[i]);
LOG_I(UTIL, "[websrv] url variable %i %s : %s\n", i, u_map_enum_keys(request->map_url)[i], u_map_enum_values(request->map_url)[i]);
}
}
/*-----------------------------------*/
@@ -185,27 +163,12 @@ int websrv_string_response(char *astring, struct _u_response *response, int http
/* set of calls to fill a buffer with a string and use this buffer in a response */
void websrv_printf_start(struct _u_response *response, int buffsize, bool async)
{
int st = -1;
for (int count = 0; count < 10; count++) {
st = pthread_mutex_trylock(&(websrv_printf_buff.mutex));
if (st == 0)
break;
usleep(100);
count++;
}
if (st != 0) {
char msg[255];
snprintf(msg, sizeof(msg) - 1, "[websrv] cannot allocate print buffer, error %s", strerror(st));
LOG_W(UTIL, "%s", msg);
websrv_string_response(msg, websrv_printf_buff.response, 500, 0);
} else {
websrv_printf_buff.buff = malloc(buffsize);
websrv_printf_buff.buffptr = websrv_printf_buff.buff;
websrv_printf_buff.buffsize = buffsize;
websrv_printf_buff.response = response;
websrv_printf_buff.async = async;
}
pthread_mutex_lock(&(websrv_printf_buff.mutex));
websrv_printf_buff.buff = malloc(buffsize);
websrv_printf_buff.buffptr = websrv_printf_buff.buff;
websrv_printf_buff.buffsize = buffsize;
websrv_printf_buff.response = response;
websrv_printf_buff.async = async;
}
void websrv_printf_atpos(int pos, const char *message, ...)
@@ -213,8 +176,7 @@ void websrv_printf_atpos(int pos, const char *message, ...)
va_list va_args;
va_start(va_args, message);
websrv_printf_buff.buffptr = websrv_printf_buff.buff + pos
+ vsnprintf(websrv_printf_buff.buff + pos, websrv_printf_buff.buffsize - pos - 1, message, va_args);
websrv_printf_buff.buffptr = websrv_printf_buff.buff + pos + vsnprintf(websrv_printf_buff.buff + pos, websrv_printf_buff.buffsize - pos - 1, message, va_args);
va_end(va_args);
return;
@@ -224,10 +186,8 @@ void websrv_printf(const char *message, ...)
{
va_list va_args;
va_start(va_args, message);
websrv_printf_buff.buffptr += vsnprintf(websrv_printf_buff.buffptr,
websrv_printf_buff.buffsize - (websrv_printf_buff.buffptr - websrv_printf_buff.buff) - 1,
message,
va_args);
websrv_printf_buff.buffptr += vsnprintf(websrv_printf_buff.buffptr, websrv_printf_buff.buffsize - (websrv_printf_buff.buffptr - websrv_printf_buff.buff) - 1, message, va_args);
va_end(va_args);
return;
}
@@ -247,10 +207,7 @@ void websrv_printf_end(int httpstatus, int dbglvl)
websrv_string_response(websrv_printf_buff.buff, websrv_printf_buff.response, httpstatus, dbglvl);
} else if (httpstatus < 1000) {
LOG_W(UTIL, "[websrv] %s\n", websrv_printf_buff.buff);
ulfius_set_binary_body_response(websrv_printf_buff.response,
httpstatus,
websrv_printf_buff.buff,
websrv_printf_buff.buffptr - websrv_printf_buff.buff);
ulfius_set_binary_body_response(websrv_printf_buff.response, httpstatus, websrv_printf_buff.buff, websrv_printf_buff.buffptr - websrv_printf_buff.buff);
}
free(websrv_printf_buff.buff);

View File

@@ -18,351 +18,6 @@
![Block Diagram](./oai_enb_block_diagram.png)
# OpenAirInterface 5G-NR Feature Set #
## General Parameters
The following features are valid for the gNB and the 5G-NR UE.
* Static TDD, FDD
* Normal CP
* Subcarrier spacings: 15 and 30kHz (FR1), 120kHz (FR2)
* Bandwidths: 10, 20, 40, 60, 80, 100MHz
* Intermediate downlink and uplink frequencies to interface with IF equipment
* Procedures for 2-layer DL and UL MIMO
* Slot format: 14 OFDM symbols in UL or DL
* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 supported)
* Highly efficient 3GPP compliant polar encoder and decoder
* Encoder and decoder for short blocks
* Support for UL transform precoding (SC-FDMA)
Furthermore, the gNB and UE support
* "noS1" mode (DL and UL):
- Creates TUN interface to PDCP to inject and receive user-place traffic
- No connection to the core network
* Standalone (SA) mode:
- UE can register with the 5G Core Network through the gNB, establish a PDU Session and exchange user-plane traffic
## gNB PHY
* 15kHz and 30kHz SCS for FR1 and 120kHz SCS for FR2
* Generation of NR-PSS/NR-SSS
* NR-PBCH supports multiple SSBs and flexible periodicity
* Generation of NR-PDCCH (including generation of DCI, polar encoding, scrambling, modulation, RB mapping, etc)
- common search space
- user-specific search space
- DCI formats: 00, 10, 01 and 11
* Generation of NR-PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
- PDSCH mapping type A and B
- DMRS configuration type 1 and 2
- Single and multiple DMRS symbols
- PTRS support
- Support for 1, 2 and 4 TX antennas
- Support for up to 2 layers (currently limited to DMRS configuration type 2)
- Support for 256 QAM
* NR-CSIRS Generation of sequence at PHY
* NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
- PUSCH mapping type A and B
- DMRS configuration type 1 and 2
- Single and multiple DMRS symbols
- PTRS support
- Support for up to 2 RX antenna
- Support for up to 2 layers
- Support for 256 QAM
* NR-PUCCH
- Format 0 (2 bits, for ACK/NACK and SR)
- Format 2 (mainly for CSI feedback)
* NR-SRS
- SRS signal reception
- Channel estimation (with T tracer real time monitoring)
- Power noise estimation
* NR-PRS
- Rel16 Positioning reference signal(PRS) generation and modulation
- Multiple PRS resources, one per beam is supported in FR2 TDD mode
- FR1 and FR2 support with config file
* NR-PRACH
- Formats 0,1,2,3, A1-A3, B1-B3
* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 are supported)
* Highly efficient 3GPP compliant polar encoder and decoder
* Encoder and decoder for short block
## gNB MAC
- MAC -> PHY configuration using NR FAPI P5 interface
- MAC <-> PHY data interface using FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU
- Scheduler procedures for SIB1
- Scheduler procedures for RA
- Contention Free RA procedure
- Contention Based RA procedure
- Msg3 can transfer uplink CCCH, DTCH or DCCH messages
- CBRA can be performed using MAC CE or C-RNTI
- Scheduler procedures for CSI-RS
- MAC downlink scheduler
- phy-test scheduler (fixed allocation and usable also without UE)
- regular scheduler with dynamic proportionally-fair allocation
- MCS adaptation from HARQ BLER
- MAC header generation (including timing advance)
- ACK / NACK handling and HARQ procedures for downlink
- MAC uplink scheduler
- phy-test scheduler (fixed allocation)
- regular scheduler with dynamic proportionally-fair allocation
- HARQ procedures for uplink
- Scheduler procedures for SRS reception
- Periodic SRS reception
- Channel rank computation up to 2x2 scenario
- TPMI computation based on SRS up 4 antenna ports and 2 layers
- MAC procedures to handle CSI measurement report
- evalution of RSRP report
- evaluation of CQI report
- MAC scheduling of SR reception
- Bandwidth part (BWP) operation
- Handle multiple dedicated BWPs, supports one UE
- BWP switching through RRCReconfiguration method
## gNB RLC
- Send/Receive operations according to 38.322 Rel.16
- Segmentation and reassembly procedures
- RLC Acknowledged mode supporting PDU retransmissions
- RLC Unacknowledged mode
- DRBs and SRBs establishment/handling and association with RLC entities
- Timers implementation
- Interfaces with PDCP, MAC
- Interfaces with gtp-u (data Tx/Rx over F1-U at the DU)
## gNB PDCP
- Send/Receive operations according to 38.323 Rel.16
- Integrity protection and ciphering procedures
- Sequence number management, SDU dicard and in-order delivery
- Radio bearer establishment/handling and association with PDCP entities
- Interfaces with RRC, RLC
- Interfaces with gtp-u (data Tx/Rx over N3 and F1-U interfaces)
## gNB SDAP
- Send/Receive operations according to 37.324 Rel.15
- Establishment/Handling of SDAP entities.
- Transfer of User Plane Data
- Mapping between a QoS flow and a DRB for both DL and UL
- Marking QoS flow ID in both DL and UL packets
- Reflective QoS flow to DRB mapping for UL SDAP data PDUs
## gNB RRC
- NR RRC (38.331) Rel 17 messages using new [asn1c](https://github.com/mouse07410/asn1c)
- LTE RRC (36.331) also updated to Rel 15
- Generation of CellGroupConfig (for eNB) and MIB
- Generation of system information block 1 (SIB1)
- Generation of system information block 2 (SIB2)
- Application to read configuration file and program gNB RRC
- RRC can configure PDCP, RLC, MAC
- Interface with GTP-U (tunnel creation/handling for S1-U (NSA), N3 (SA) interfaces)
- Integration of RRC messages and procedures supporting UE 5G SA connection
- RRCSetupRequest/RRCSetup/RRCSetupComplete
- RRC Uplink/Downlink Information transfer carrying NAS messages transparently
- RRC Reconfiguration/Reconfiguration complete
- RRC Reestablishment/Reestablishment complete
- Support for master cell group configuration
- Interface with NGAP for the interactions with the AMF
- Interface with F1AP for CU/DU split deployment option
- Periodic RRC measurements of serving cell (no A/B events)
## gNB X2AP
- Integration of X2AP messages and procedures for the exchanges with the eNB over X2 interface supporting the NSA setup according to 36.423 Rel. 15
- X2 setup with eNB
- Handling of SgNB Addition Request/Addition Request Acknowledge/Reconfiguration Complete
## gNB NGAP
- Integration of NGAP messages and procedures for the exchanges with the AMF over N2 interface according to 38.413 Rel. 15
- NGAP Setup request/response
- NGAP Initial UE message
- NGAP Initial context setup request/response
- NGAP Downlink/Uplink NAS transfer
- NGAP UE context release request/complete
- NGAP UE radio capability info indication
- NGAP PDU session resource setup request/response
- Interface with RRC
## gNB F1AP
- Integration of F1AP messages and procedures for the control plane exchanges between the CU and DU entities according to 38.473 Rel. 16
- F1 Setup request/response
- F1 DL/UL RRC message transfer
- F1 Initial UL RRC message transfer
- F1 UE Context setup request/response
- F1 UE Context modification request/response
- F1 UE Context release
- F1 gNB CU configuration update
- Interface with RRC
- Interface with gtp-u (tunnel creation/handling for F1-U interface)
## gNB E1AP
- Integration of E1AP messages and procedures for exchange between CU-CP and CU-UP according to 38.463 Rel. 16
- gNB-CU-UP E1 Setup Setup request/response
- E1 Bearer Context Setup
- Bearer Context Modification (gNB-CU-CP initiated)
- Interface with RRC and PDCP
## gNB GTP-U
- New GTP-U implementation supporting both N3 and F1-U interfaces according to 29.281 Rel.15
- Interfaces with RRC, F1AP for tunnel creation
- Interfaces with PDCP and RLC for data send/receive at the CU and DU respectively (F1-U interface)
- Interface with SDAP for data send/receive, capture of GTP-U Optional Header, GTP-U Extension Header and PDU Session Container.
# OpenAirInterface 5G-NR UE Feature Set #
## NR UE PHY Layer ##
* Initial synchronization
- the UE needs to know the position in frequency of the SSBs (via command line parameter in SA)
* Time tracking based on PBCH DMRS
* Frequency offset estimation based on PSS and SSS
* 15kHz and 30kHz SCS for FR1 and 120 kHz SCS for FR2
* Reception of NR-PSS/NR-SSS
* NR-PBCH supports multiple SSBs and flexible periodicity
- RSRP measurement for the strongest SSB
* Reception of NR-PDCCH (including reception of DCI, polar decoding, de-scrambling, de-modulation, RB de-mapping, etc)
- common search space configured by MIB
- user-specific search space configured by RRC
- DCI formats: 00, 10, 01 and 11
* Reception of NR-PDSCH (including Segmentation, LDPC decoding, rate de-matching, de-scrambling, de-modulation, RB de-mapping, etc).
- PDSCH mapping type A and B
- DMRS configuration type 1 and 2
- Single and multiple DMRS symbols
- PTRS support
- Support for 256 QAM
- Support for 1, 2 and 4 RX antennas
- Support for up to 2 layers (currently limited to DMRS configuration type 2)
* Measurements based on NR-CSIRS
- RSRP measurements
- RI, PMI and CQI computation
- Support for up to 4 RX antennas
- Support for up to 2 layers
* NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
- PUSCH mapping type A and B
- DMRS configuration type 1 and 2
- Single and multiple DMRS symbols
- PTRS support
- Support for 256 QAM
- Support for up to 2 TX antenna
- Support for up to 2 layers
* NR-PUCCH
- Format 0 (2 bits for ACK/NACK and SR)
- Format 2 (mainly for CSI feedback)
- Format 1 (limited testing)
- Format 3 and 4 present but old code never tested (need restructuring before verification)
* NR-SRS
- Generation of sequence at PHY
- SRS signal transmission
* NR-PRS
- PRS based Channel estimation with T tracer dumps
- Time of arrival(ToA) estimation based on channel impulse response(CIR)
- Finer ToA estimation by 16x oversampled IDFT for CIR
- Support for multiple gNB reception with gNBs synced via GPSDO
* NR-PRACH
- Formats 0,1,2,3, A1-A3, B1-B3
* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 are supported)
* Highly efficient 3GPP compliant polar encoder and decoder
* Encoder and decoder for short block
## NR UE FAPI ##
* MAC -> PHY configuration via UE FAPI P5 interface
* Basic MAC to control PHY via UE FAPI P7 interface
* PHY -> MAC indication (needs some improvement)
## NR UE Higher Layers ##
## UE MAC
* Minimum system information (MSI)
- MIB processing
- Scheduling of system information block 1 (SIB1) reception
* Random access procedure (needs improvement, there is still not a clear separation between MAC and PHY)
- Mapping SSBs to multiple ROs
- Scheduling of PRACH
- Processing of RAR
- Transmission and re-transmission of Msg3
- Msg4 and contention resolution
* DCI processing
- format 10 (RA-RNTI, C-RNTI, SI-RNTI, TC-RNTI)
- format 00 (C-RNTI, TC-RNTI)
- format 11 (C-RNTI)
- format 01 (C-RNTI)
* UCI processing
- ACK/NACK processing
- Triggering periodic SR
- CSI measurement reporting
* DLSCH scheduler
- Configuration of fapi PDU according to DCI
- HARQ procedures
* ULSCH scheduler
- Configuration of fapi PDU according to DCI
* NR-CSIRS scheduler
- Scheduling of NR-CSIRS reception
- Fill UCI for CSI measurement reporting
* Scheduler procedures for SRS transmission
- Periodic SRS transmission
* Bandwidth part (BWP) operation
- Operation in configured dedicated BWP through RRCSetup or RRCReconfiguration
## UE RLC
* Tx/Rx operations according to 38.322 Rel.16
- Segmentation and reassembly procedures
- RLC Acknowledged mode supporting PDU retransmissions
- RLC Unacknowledged mode
- DRBs and SRBs establishment and handling
- Timers implementation
- Interfaces with PDCP, MAC
## UE PDCP
* Tx/Rx operations according to 38.323 Rel.16
- Integrity protection and ciphering procedures
- Sequence number management, SDU dicard and in-order delivery
- Radio bearer establishment/handling and association with PDCP entities
- Interfaces with RRC, RLC
## UE SDAP
* Tx/Rx operations operations according to 37.324 Rel.15
- Establishment/Handling of SDAP entities.
- Transfer of User Plane Data
- Reflective Mapping
- RRC Signaling Mapping
## UE RRC
* Integration of RRC messages and procedures supporting UE 5G SA connection according to 38.331 Rel.16
- RRCSetupRequest/RRCSetup/RRCSetupComplete
- RRC Uplink/Downlink Information transfer carrying NAS messages transparently
- RRC Reconfiguration/Reconfiguration complete
- Support for master cell group configuration
- Reception of UECapabilityEnquiry, encoding and transmission of UECapability
* Interface with PDCP: configuration, DCCH and CCCH message handling
* Interface with RLC and MAC for configuration
## UE NAS
* Transfer of NAS messages between the AMF and the UE supporting the UE registration with the core network and the PDU session establishment according to 24.501 Rel.16
- Identity Request/Response
- Authentication Request/Response
- Security Mode Command/Complete
- Registration Request/Accept/Complete
- PDU Session Establishment Request/Accept
- NAS configuration and basic interfacing with RRC
# OpenAirInterface 4G LTE eNB Feature Set #
## eNB PHY Layer ##
@@ -390,15 +45,15 @@ The Physical layer implements **3GPP 36.211**, **36.212**, **36.213** and provid
FDD DL: 5 MHz, 25 PRBS/ MCS 28 | 16 - 17 Mbit/s | TM1: 17.0 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
FDD DL: 10 MHz, 50 PRBS/ MCS 28 | 34 - 35 Mbit/s | TM1: 34.0 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
FDD DL: 20 MHz, 100 PRBS/ MCS 28 | 70 Mbit/s | TM1: 69.9 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
| | |
| | |
FDD UL: 5 MHz, 25 PRBS/ MCS 20 | 9 Mbit/s | TM1: 8.28 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
FDD UL: 10 MHz, 50 PRBS/ MCS 20 | 17 Mbit/s | TM1: 18.3 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
FDD UL: 20 MHz, 100 PRBS/ MCS 20 | 35 Mbit/s | TM1: 18.6 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
| |
| |
TDD DL: 5 MHz, 25 PRBS/ MCS **XX** | 6.5 Mbit/s | TM1: 6.71 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
TDD DL: 10 MHz, 50 PRBS/ MCS **XX** | 13.5 Mbit/s | TM1: 13.6 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
TDD DL: 20 MHz, 100 PRBS/ MCS **XX** | 28.0 Mbit/s | TM1: 27.2 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
| | |
| | |
TDD UL: 5 MHz, 25 PRBS/ MCS **XX** | 2.0 Mbit/s | TM1: 3.31 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
TDD UL: 10 MHz, 50 PRBS/ MCS **XX** | 2.0 Mbit/s | TM1: 7.25 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
TDD UL: 20 MHz, 100 PRBS/ MCS **XX** | 3.0 Mbit/s | TM1: 4.21 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
@@ -411,7 +66,7 @@ TDD UL: 20 MHz, 100 PRBS/ MCS **XX** | 3.0 Mbit/s | TM1: 4.21 Mbits/s
## eNB MAC Layer ##
The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support of BCH, DLSCH, RACH, and ULSCH channels.
The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support of BCH, DLSCH, RACH, and ULSCH channels.
- RRC interface for CCCH, DCCH, and DTCH
- Proportional fair scheduler (round robin scheduler soon), with the following improvements:
@@ -431,16 +86,16 @@ The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support
The RLC layer implements a full specification of the 3GPP 36.322 release v9.3.
- RLC TM (mainly used for BCCH and CCCH)
- RLC TM (mainly used for BCCH and CCCH)
* Neither segment nor concatenate RLC SDUs
* Do not include a RLC header in the RLC PDU
* Delivery of received RLC PDUs to upper layers
- RLC UM (mainly used for DTCH)
- RLC UM (mainly used for DTCH)
* Segment or concatenate RLC SDUs according to the TB size selected by MAC
* Include a RLC header in the RLC PDU
* Duplication detection
* PDU reordering and reassembly
- RLC AM, compatible with 9.3
- RLC AM, compatible with 9.3
* Segmentation, re-segmentation, concatenation, and reassembly
* Padding
* Data transfer to the user
@@ -478,9 +133,9 @@ The RRC layer is based on **3GPP 36.331** v15.6 and implements the following fun
The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following functions:
- X2 Setup Request
- X2 Setup Response
- X2 Setup Response
- X2 Setup Failure
- Handover Request
- Handover Request
- Handover Request Acknowledge
- UE Context Release
- X2 timers (t_reloc_prep, tx2_reloc_overall)
@@ -489,16 +144,16 @@ The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following
- EN-DC is implemented
- X2AP : Handling of SgNB Addition Request / Addition Request Acknowledge / Reconfiguration Complete
- RRC : Handling of RRC Connection Reconfiguration with 5G cell info, configuration of 5G-NR measurements
- S1AP : Handling of E-RAB Modification Indication / Confirmation
- S1AP : Handling of E-RAB Modification Indication / Confirmation
## eNB/MCE M2AP ##
The M2AP layer is based on **3GPP 36.443** v14.0.1:
- M2 Setup Request
- M2 Setup Response
- M2 Setup Response
- M2 Setup Failure
- M2 Scheduling Information
- M2 Scheduling Information Response
- M2 Scheduling Information Response
- M2 Session Start Request
- M2 Session Start Response
@@ -506,7 +161,7 @@ The M2AP layer is based on **3GPP 36.443** v14.0.1:
The M3AP layer is based on **3GPP 36.444** v14.0.1:
- M3 Setup Request
- M3 Setup Response
- M3 Setup Response
- M3 Setup Failure
- M3 Session Start Request
- M3 Session Start Response
@@ -529,11 +184,11 @@ The Physical layer implements **3GPP 36.211**, **36.212**, **36.213** and provid
- All uplink (UL) channels are supported: PRACH, PUSCH, PUCCH (format 1/1a/1b), SRS, DRS
- LTE MBMS-dedicated cell (feMBMS) procedures subset for LTE release 14 (experimental)
- LTE non-MBSFN subframe (feMBMS) Carrier Adquistion Subframe-CAS procedures (PSS/SSS/PBCH/PDSH) (experimental)
- LTE MBSFN MBSFN subframe channel (feMBMS): PMCH (CS@1.25KHz) (channel estimation for 25MHz bandwidth) (experimental)
- LTE MBSFN MBSFN subframe channel (feMBMS): PMCH (CS@1.25KHz) (channel estimation for 25MHz bandwidth) (experimental)
## LTE UE MAC Layer ##
The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support of BCH, DLSCH, RACH, and ULSCH channels.
The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support of BCH, DLSCH, RACH, and ULSCH channels.
- RRC interface for CCCH, DCCH, and DTCH
- HARQ Support
@@ -541,7 +196,7 @@ The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support
- RLC interface (AM, UM)
- UL power control
- Link adaptation
- MBMS-dedicated cell (feMBMS) RRC interface for BCCH
- MBMS-dedicated cell (feMBMS) RRC interface for BCCH
- eMBMS and MBMS-dedicated cell (feMBMS) RRC interface for MCCH, MTCH
## LTE UE RLC Layer ##
@@ -568,6 +223,328 @@ The NAS layer is based on **3GPP 24.301** and implements the following functions
- ESM default/dedicated bearer, PDN connectivity, and more
# OpenAirInterface 5G-NR Feature Set #
## General Parameters ##
The following features are valid for the gNB and the 5G-NR UE.
* Static TDD,
* FDD
* Normal CP
* Subcarrier spacings: 15 and 30kHz (FR1), 120kHz (FR2)
* Bandwidths: 10, 20, 40, 80, 100MHz (273 Physical Resource Blocks)
* Intermediate downlink and uplink frequencies to interface with IF equipment
* Procedures for 2-layer DL MIMO
* Slot format: 14 OFDM symbols in UL or DL
* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 supported)
* Highly efficient 3GPP compliant polar encoder and decoder
* Encoder and decoder for short blocks
* Support for UL transform precoding (SC-FDMA)
## gNB PHY Layer ##
* 15kHz and 30kHz SCS for FR1 and 120kHz SCS for FR2
* Generation of NR-PSS/NR-SSS
* NR-PBCH supports multiple SSBs and flexible periodicity
* Generation of NR-PDCCH (including generation of DCI, polar encoding, scrambling, modulation, RB mapping, etc)
- common search space
- user-specific search space
- DCI formats: 00, 10, 01 and 11
* Generation of NR-PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
- PDSCH mapping type A and B
- DMRS configuration type 1 and 2
- Single and multiple DMRS symbols
- PTRS support
- Support for 1, 2 and 4 TX antennas
- Support for up to 2 layers (currently limited to DMRS configuration type 2)
- Support for 256 QAM
* NR-CSIRS Generation of sequence at PHY
* NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
- PUSCH mapping type A and B
- DMRS configuration type 1 and 2
- Single and multiple DMRS symbols
- PTRS support
- Support for up to 2 RX antenna
- Support for up to 2 layers
- Support for 256 QAM
* NR-PUCCH
- Format 0 (2 bits, for ACK/NACK and SR)
- Format 2 (mainly for CSI feedback)
* NR-SRS
- SRS signal reception
- Channel estimation (with T tracer real time monitoring)
- Power noise estimation
* NR-PRS
- Rel16 Positioning reference signal(PRS) generation and modulation
- Multiple PRS resources, one per beam is supported in FR2 TDD mode
- FR1 and FR2 support with config file
* NR-PRACH
- Formats 0,1,2,3, A1-A3, B1-B3
* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 are supported)
* Highly efficient 3GPP compliant polar encoder and decoder
* Encoder and decoder for short block
## gNB Higher Layers ##
**gNB MAC**
- MAC -> PHY configuration using NR FAPI P5 interface
- MAC <-> PHY data interface using FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU
- Scheduler procedures for SIB1
- Scheduler procedures for RA
- Contention Free RA procedure
- Contention Based RA procedure
- Msg3 can transfer uplink CCCH, DTCH or DCCH messages
- CBRA can be performed using MAC CE or C-RNTI
- Scheduler procedures for CSI-RS
- MAC downlink scheduler
- phy-test scheduler (fixed allocation and usable also without UE)
- regular scheduler with dynamic allocation
- MCS adaptation from HARQ BLER
- MAC header generation (including timing advance)
- ACK / NACK handling and HARQ procedures for downlink
- MAC uplink scheduler
- phy-test scheduler (fixed allocation)
- regular scheduler with dynamic allocation
- HARQ procedures for uplink
- Scheduler procedures for SRS reception
- Periodic SRS reception
- Channel rank computation up to 2x2 scenario
- TPMI computation based on SRS up 4 antenna ports and 2 layers
- MAC procedures to handle CSI measurement report
- evalution of RSRP report
- evaluation of CQI report
- MAC scheduling of SR reception
- Bandwidth part (BWP) operation
- Handle multiple dedicated BWPs
- BWP switching through RRCReconfiguration method
**gNB RLC**
- Send/Receive operations according to 38.322 Rel.16
- Segmentation and reassembly procedures
- RLC Acknowledged mode supporting PDU retransmissions
- RLC Unacknowledged mode
- DRBs and SRBs establishment/handling and association with RLC entities
- Timers implementation
- Interfaces with PDCP, MAC
- Interfaces with gtp-u (data Tx/Rx over F1-U at the DU)
**gNB PDCP**
- Send/Receive operations according to 38.323 Rel.16
- Integrity protection and ciphering procedures
- Sequence number management, SDU dicard and in-order delivery
- Radio bearer establishment/handling and association with PDCP entities
- Interfaces with RRC, RLC
- Interfaces with gtp-u (data Tx/Rx over N3 and F1-U interfaces)
**gNB SDAP**
- Send/Receive operations according to 37.324 Rel.15
- Establishment/Handling of SDAP entities.
- Transfer of User Plane Data
- Mapping between a QoS flow and a DRB for both DL and UL
- Marking QoS flow ID in both DL and UL packets
- Reflective QoS flow to DRB mapping for UL SDAP data PDUs
**gNB RRC**
- NR RRC (38.331) Rel 16 messages using new asn1c
- LTE RRC (36.331) also updated to Rel 15
- Generation of CellGroupConfig (for eNB) and MIB
- Generation of system information block 1 (SIB1)
- Generation of system information block 2 (SIB2)
- Application to read configuration file and program gNB RRC
- RRC can configure PDCP, RLC, MAC
- Interface with gtp-u (tunnel creation/handling for S1-U (NSA), N3 (SA) interfaces)
- Integration of RRC messages and procedures supporting UE 5G SA connection
- RRCSetupRequest/RRCSetup/RRCSetupComplete
- RRC Uplink/Downlink Information transfer carrying NAS messages transparently
- RRC Reconfiguration/Reconfiguration complete
- RRC Reestablishment/Reestablishment complete
- Paging
- Support for master cell group configuration
- Interface with NGAP for the interactions with the AMF
- Interface with F1AP for CU/DU split deployment option
- Periodic RRC measurements of serving cell (no A/B events)
**gNB X2AP**
- Integration of X2AP messages and procedures for the exchanges with the eNB over X2 interface supporting the NSA setup according to 36.423 Rel. 15
- X2 setup with eNB
- Handling of SgNB Addition Request / Addition Request Acknowledge / Reconfiguration Complete
**gNB NGAP**
- Integration of NGAP messages and procedures for the exchanges with the AMF over N2 interface according to 38.413 Rel. 15
- NGAP Setup request/response
- NGAP Initial UE message
- NGAP Initial context setup request/response
- NGAP Downlink/Uplink NAS transfer
- NGAP UE context release request/complete
- NGAP UE radio capability info indication
- NGAP PDU session resource setup request/response
- Interface with RRC
**gNB F1AP**
- Integration of F1AP messages and procedures for the control plane exchanges between the CU and DU entities according to 38.473 Rel. 16
- F1 Setup request/response
- F1 DL/UL RRC message transfer
- F1 Initial UL RRC message transfer
- F1 UE Context setup request/response
- F1 gNB CU configuration update
- Interface with RRC
- Interface with gtp-u (tunnel creation/handling for F1-U interface)
**gNB GTP-U**
- New gtp-u implementation supporting both N3 and F1-U interfaces according to 29.281 Rel.15
- Interfaces with RRC, F1AP for tunnel creation
- Interfaces with PDCP and RLC for data send/receive at the CU and DU respectively (F1-U interface)
- Interface with SDAP for data send/receive, capture of GTP-U Optional Header, GTP-U Extension Header and PDU Session Container.
# OpenAirInterface 5G-NR UE Feature Set #
* Supporting "noS1" mode (DL and UL):
- Creates TUN interface to PDCP to inject and receive user-place traffic
- No connection to the core network
* Supporting Standalone (SA) mode:
- UE can register with the 5G Core Network, establish a PDU Session and exchange user-plane traffic
## NR UE PHY Layer ##
* Initial synchronization
- the UE needs to know the position in frequency of the SSBs (via command line parameter in SA)
* Time tracking based on PBCH DMRS
* Frequency offset estimation based on PSS and SSS
* 15kHz and 30kHz SCS for FR1 and 120 kHz SCS for FR2
* Reception of NR-PSS/NR-SSS
* NR-PBCH supports multiple SSBs and flexible periodicity
- RSRP measurement for the strongest SSB
* Reception of NR-PDCCH (including reception of DCI, polar decoding, de-scrambling, de-modulation, RB de-mapping, etc)
- common search space configured by MIB
- user-specific search space configured by RRC
- DCI formats: 00, 10, 01 and 11
* Reception of NR-PDSCH (including Segmentation, LDPC decoding, rate de-matching, de-scrambling, de-modulation, RB de-mapping, etc).
- PDSCH mapping type A and B
- DMRS configuration type 1 and 2
- Single and multiple DMRS symbols
- PTRS support
- Support for 1, 2 and 4 RX antennas
- Support for up to 2 layers (currently limited to DMRS configuration type 2)
* Measurements based on NR-CSIRS
- RSRP measurements
- RI, PMI and CQI computation
- Support for up to 4 RX antennas
- Support for up to 2 layers
* NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
- PUSCH mapping type A and B
- DMRS configuration type 1 and 2
- Single and multiple DMRS symbols
- PTRS support
- Support for up to 2 TX antenna
- Support for up to 2 layers
* NR-PUCCH
- Format 0 (2 bits for ACK/NACK and SR)
- Format 2 (mainly for CSI feedback)
- Format 1 (limited testing)
- Format 3 and 4 present but old code never tested (need restructuring before verification)
* NR-SRS
- Generation of sequence at PHY
- SRS signal transmission
* NR-PRS
- PRS based Channel estimation with T tracer dumps
- Time of arrival(ToA) estimation based on channel impulse response(CIR)
- Finer ToA estimation by 16x oversampled IDFT for CIR
- Support for multiple gNB reception with gNBs synced via GPSDO
* NR-PRACH
- Formats 0,1,2,3, A1-A3, B1-B3
* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 are supported)
* Highly efficient 3GPP compliant polar encoder and decoder
* Encoder and decoder for short block
## NR UE FAPI ##
* MAC -> PHY configuration via UE FAPI P5 interface
* Basic MAC to control PHY via UE FAPI P7 interface
* PHY -> MAC indication (needs some improvement)
## NR UE Higher Layers ##
**UE MAC**
* Minimum system information (MSI)
- MIB processing
- Scheduling of system information block 1 (SIB1) reception
* Random access procedure (needs improvement, there is still not a clear separation between MAC and PHY)
- Mapping SSBs to multiple ROs
- Scheduling of PRACH
- Processing of RAR
- Transmission and re-transmission of Msg3
- Msg4 and contention resolution
* DCI processing
- format 10 (RA-RNTI, C-RNTI, SI-RNTI, TC-RNTI)
- format 00 (C-RNTI, TC-RNTI)
- format 11 (C-RNTI)
- format 01 (C-RNTI)
* UCI processing
- ACK/NACK processing
- Triggering periodic SR
- CSI measurement reporting
* DLSCH scheduler
- Configuration of fapi PDU according to DCI
- HARQ procedures
* ULSCH scheduler
- Configuration of fapi PDU according to DCI
* NR-CSIRS scheduler
- Scheduling of NR-CSIRS reception
- Fill UCI for CSI measurement reporting
* Scheduler procedures for SRS transmission
- Periodic SRS transmission
* Bandwidth part (BWP) operation
- Operation in configured dedicated BWP through RRCSetup or RRCReconfiguration
**UE RLC**
* Tx/Rx operations according to 38.322 Rel.16
- Segmentation and reassembly procedures
- RLC Acknowledged mode supporting PDU retransmissions
- RLC Unacknowledged mode
- DRBs and SRBs establishment and handling
- Timers implementation
- Interfaces with PDCP, MAC
**UE PDCP**
* Tx/Rx operations according to 38.323 Rel.16
- Integrity protection and ciphering procedures
- Sequence number management, SDU dicard and in-order delivery
- Radio bearer establishment/handling and association with PDCP entities
- Interfaces with RRC, RLC
**UE SDAP**
* Tx/Rx operations operations according to 37.324 Rel.15
- Establishment/Handling of SDAP entities.
- Transfer of User Plane Data
- Reflective Mapping
- RRC Signaling Mapping
**UE RRC**
* Integration of RRC messages and procedures supporting UE 5G SA connection according to 38.331 Rel.16
- RRCSetupRequest/RRCSetup/RRCSetupComplete
- RRC Uplink/Downlink Information transfer carrying NAS messages transparently
- RRC Reconfiguration/Reconfiguration complete
- Support for master cell group configuration
- Reception of UECapabilityEnquiry, encoding and transmission of UECapability
* Interface with PDCP: configuration, DCCH and CCCH message handling
* Interface with RLC and MAC for configuration
**UE NAS**
* Transfer of NAS messages between the AMF and the UE supporting the UE registration with the core network and the PDU session establishment according to 24.501 Rel.16
- Identity Request/Response
- Authentication Request/Response
- Security Mode Command/Complete
- Registration Request/Accept/Complete
- PDU Session Establishment Request/Accept
- NAS configuration and basic interfacing with RRC
[OAI wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
[OAI softmodem build procedure](BUILD.md)

View File

@@ -99,7 +99,6 @@ The other SDRs (AW2S, LimeSDR, ...) have no READMEs.
- OAI comes with an integrated [telnet server](../common/utils/telnetsrv/DOC/telnethelp.md) to monitor and control
- OAI comes with an integrated [web server](../common/utils/websrv/DOC/websrv.md)
# Testing
# CI
- [UnitTests.md](./UnitTests.md) explains the unit testing setup
- [TESTBenches.md](./TESTBenches.md) lists the CI setup and links to pipelines

View File

@@ -127,30 +127,27 @@ Some other useful paramters of the UE are
## phy-test setup with OAI UE
The OAI UE can also be used in front of a OAI gNB without the support of eNB or EPC and circumventing random access. In this case both gNB and eNB need to be run with the `--phy-test` flag. At the gNB this flag does the following
The OAI UE can also be used in front of a OAI gNB without the support of eNB or EPC. In this case both gNB and eNB need to be run with the --phy-test flag. At the gNB this flag does the following
- it reads the RRC configuration from the configuration file
- it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files `rbconfig.raw` and `reconfig.raw` in the current directory
- the MAC uses a pre-configured allocation of PDSCH and PUSCH with randomly generated payload instead of the standard scheduler. The options `-m`, `-l`, `-t`, `-M`, `-T`, `-D`, and `-U` can be used to configure this scheduler. See `./nr-softmodem -h` for more information.
- it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files rbconfig.raw and reconfig.raw
- the MAC uses a pre-configured allocation of PDSCH and PUSCH with randomly generated payload
At the UE the --phy-test flag will
- read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them.
At the UE, the `--phy-test` flag will read the binary files `rbconfig.raw` and `reconfig.raw` from the current directory and process them. If you wish to provide a different path for these files, please use the options `--reconfig-file` and `--rbconfig-file`.
```bash
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test
```
In phy-test mode it is possible to mimic the reception of UE Capabilities at gNB by passing through the command line parameter `--uecap_file` the location and file name of the input UE Capability file, e.g. `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports1.xml` (1 layer) or `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports2.xml` (2 layers).
```bash
sudo ./nr-uesoftmodem --phy-test [--reconfig-file ../../../ci-scripts/rrc-files/reconfig.raw --rbconfig-file ../../../ci-scripts/rrc-files/rbconfig.raw]
sudo ./nr-uesoftmodem --phy-test [--rrc_config_path ../../../ci-scripts/rrc-files]
```
In summary:
- If you are running on the same machine and launched the 2 executables (`nr-softmodem` and `nr-uesoftmodem`) from the same directory, nothing has to be done.
- If you launched the 2 executables from 2 different folders, just point to the location where you launched the `nr-softmodem`:
* `sudo ./nr-uesoftmodem --rfsim --phy-test --reconfig-file /the/path/where/you/launched/nr-softmodem/reconfig-file --rbconfig-file /the/path/where/you/launched/nr-softmodem/rbconfig-file --rfsimulator.serveraddr <TARGET_GNB_INTERFACE_ADDRESS>`
- If you are not running on the same machine, you need to **COPY** the two raw files
* `scp usera@machineA:/the/path/where/you/launched/nr-softmodem/r*config.raw userb@machineB:/the/path/where/you/will/launch/nr-uesoftmodem/`
* Obviously this operation should be done before launching the `nr-uesoftmodem` executable.
In phy-test mode it is possible to mimic the reception of UE Capabilities at gNB by passing through the command line parameter `--uecap_file` the location and file name of the input UE Capability file, e.g. `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports1.xml` (1 layer) or `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports2.xml` (2 layers).
You need to provide `--rrc_config_path` if you don't start the UE after the gNB
in the same directory.
## noS1 setup with OAI UE

View File

@@ -31,7 +31,7 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfap
```
### UE command
```
sudo ./nr-uesoftmodem --rfsim --phy-test -d --rfsimulator.serveraddr 127.0.0.1
sudo ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path . -d --rfsimulator.serveraddr 127.0.0.1
```
## Procedure to run NR nFAPI using Hardware (tested with USRP x310)
@@ -48,7 +48,7 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfap
```
### UE command
```
sudo ./nr-uesoftmodem --usrp-args "addr=*USRP_ADDRESS*,clock_source=external,time_source=external" --phy-test
sudo ./nr-uesoftmodem --usrp-args "addr=*USRP_ADDRESS*,clock_source=external,time_source=external" --phy-test --rrc_config_path ../../../ci-scripts/rrc-files
```

View File

@@ -21,8 +21,8 @@ After you have [built the softmodem executables](BUILD.md), go to the build dire
| **Mode** | **gNB config** | **nrUE config** |
|----------------------------- |------------------------------------------------------------------------------------------- |--------------------------- |
| **FR1 40MHz<br>30kHz SCS** | gnb0.prs.band78.fr1.106PRB.usrpx310.conf<br>gnb1.prs.band78.fr1.106PRB.usrpx310.conf | ue.nr.prs.fr1.106prb.conf |
| **FR2 100MHz<br>120kHz SCS** | gnb0.prs.band261.fr2.64PRB.usrpx310.conf<br>gnb1.prs.band261.fr2.64PRB.usrpx310.conf | ue.nr.prs.fr2.64prb.conf |
| **FR1 40MHz<br>30kHz SCS** | gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf<br>gnb1.sa.band78.fr1.106PRB.prs.usrpx310.conf | ue.nr.prs.fr1.106prb.conf |
| **FR2 100MHz<br>120kHz SCS** | gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf<br>gnb1.sa.band261.fr2.64PRB.prs.usrpx310.conf | ue.nr.prs.fr2.64prb.conf |
Under gNB and nrUE config files, parameters are configured under `prs_config` section. nrUE is capable to receive downlink PRS signal from multiple gNB simultaneously and therefore nrUE config file contains multiple `prs_config` sections, corresponding to each gNB. These parameters can be changed as per the test scenario.
@@ -64,26 +64,26 @@ In our case the output is 0 and hence we use `numactl --cpunodebind=0 --membind=
## FR1 test
Open a terminal on the host machine, and execute below command to launch gNB with **X310 USRPs**
```sudo numactl --cpunodebind=0 --membind=0 ./nr-softmodem -E -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf --phy-test```
```sudo numactl --cpunodebind=0 --membind=0 ./nr-softmodem -E -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf --phy-test```
If **N310 USRPs** are used, then run above command `without -E option` i.e without 3/4 sampling rate.<br><br>
To run using **rfsimulator**, execute following command:
```sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf --parallel-config PARALLEL_SINGLE_THREAD --noS1 --rfsim --phy-test```
```sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band78.fr1.106PRB.prs.usrpx310.conf --parallel-config PARALLEL_SINGLE_THREAD --noS1 --rfsim --phy-test```
## FR2 test
In FR2 mode, we need RF beamforming module to transmit signal in mmWave frequency range. **X310 USRPs** can be used with BasicTx daughtercard to transmit baseband signal at **Intermediate Frequncy(IF)** and then RF beamforming module would perform beamforming and the upconversion to FR2 frequencies. IF can be specified using `if_freq` in the RU section of gNB config.
If RF beamforming module is NOT present, gNB can still be launched with USRP alone; to transmit at supported `if_freq`.
```sudo numactl --cpunodebind=0 --membind=0 ./nr-softmodem -E -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band261.fr2.64PRB.usrpx310.conf --phy-test```<br><br>
```sudo numactl --cpunodebind=0 --membind=0 ./nr-softmodem -E -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf --phy-test```<br><br>
To run using **rfsimulator**, execute following command:
```sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band261.fr2.64PRB.usrpx310.conf --parallel-config PARALLEL_SINGLE_THREAD --noS1 --rfsim --phy-test```
```sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.sa.band261.fr2.64PRB.prs.usrpx310.conf --parallel-config PARALLEL_SINGLE_THREAD --noS1 --rfsim --phy-test```
## Multiple gNB scenario
PRS is primarily used for positioning and localization of the UE with multiple gNBs transmitting simultaneously. OAI PRS implementation supports multiple gNB transmission provided all the gNBs are tightely synchronized using GPSDO clock. Therefore before running this scenario, make sure the USRPs has built-in GPSDO and the GPS antennas are connected with good satellite visibility. Also every time a gNB is launched, wait until `GPS LOCKED` is printed on the terminal during gNB startup. If USRP fails to lock with GPSDO, try again until its locked.

View File

@@ -101,13 +101,10 @@ Webhook
- L2simulator: skips physical layer and uses proxy between gNB and UE, currently only ping
- [RAN-LTE-FDD-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-FDD-LTEBOX-Container/)
- hutch + B210, nano w/ ltebox + 2x UE
- tests RRC inactivity timers, different bandwidths, IF4p5 fronthaul
- [RAN-LTE-FDD-OAIUE-OAICN4G-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-FDD-OAIUE-OAICN4G-Container/)
- hutch + B210 (eNB), carabe + B210 (4G UE), nano w/ OAI 4GC
- tests OAI 4G for 10 MHz/TM1; known to be unstable
- tests RRC inactivity timers, different bandwidths
- [RAN-LTE-TDD-2x2-Container](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-LTE-TDD-2x2-Container/)
- obelix + N310, porcepix, nrmodule2 + Quectel
- TM1 and TM2 test, IF4p5 fronthaul
- TM1 and TM2 test
- [RAN-LTE-TDD-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-TDD-LTEBOX-Container/)
- starsky + B210, nano w/ ltebox + 2x UE
- TM1 over bandwidths 5, 10, 20 MHz in Band 40, default scheduler for 20 MHz
@@ -151,3 +148,23 @@ Webhook
- [RAN-SA-AmariS-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-AmariS-CN5G/)
- asterix + N310, amariue (1x UE), porcepix w/ OAI 5GC
- Amarisoft UE simulator: expected to be increased to more UEs
### RAN-CI-develop
***DEFUNCT***: automatically triggered tests, mostly 4G, to be phased out and
integrated into RAN-Container-Parent
The following defunct pipelines remain to be integrated into RAN-Container-Parent:
- eNB-CI-IF4p5-FDD-Band7-B210
- hutch + B210, nano w/ ltebox + 2x UE
- tests IF4.5 split over bandwidths 5, 10, 20 MHz in Band 7
- eNB-CI-IF4p5-TDD-Band40-B210
- starsky + B210, nano w/ ltebox + 2x UE
- tests IF4.5 split over bandwidths 5, 10, 20 MHz in Band 40
- eNB-UE-CI-MONO-FDD-Band7-B200
- hutch + B210 (eNB), carabe + B210 (4G UE), nano w/ ltebox
- tests OAI 4G for 5 MHz/TM1 with both CN and in noS1 model, MBMS; known to
be unstable
- UE-CI-FDD-Band20-B200
- starsky + B210 (sniffer)
- Sniff MIB + SIB1 of Orange, SFR

View File

@@ -1,108 +0,0 @@
# Unit Testing in OAI
OpenAirInterface uses
[ctest](https://cmake.org/cmake/help/latest/manual/ctest.1.html) for unit
testing. The cmake documentation has a
[tutorial](https://cmake.org/cmake/help/book/mastering-cmake/chapter/Testing%20With%20CMake%20and%20CTest.html)
explaining how to test with cmake and ctest; it is a suggested read, and the
following just lists the main points of how to compile the tests and how to add
new ones.
At the time of writing, only the NR RLC tests have been integrated. The author
hopes that more tests follow suit.
# How to compile tests
To compile only the tests, a special target `tests` is available. It has to be
enabled with the special cmake variable `ENABLE_TESTS`:
```bash
cd openairinterface5g
mkdir build && cd build # you can also do that in cmake_targets/ran_build/build
cmake .. -GNinja -DENABLE_TESTS=ON
ninja tests
```
Then, you can run `ctest` to run all tests:
```
$ ctest
Test project /home/richie/w/ctest/build
Start 1: nr_rlc_tests
1/1 Test #1: nr_rlc_tests ..................... Passed 0.06 sec
100% tests passed, 0 tests failed out of 1
Total Test time (real) = 0.06 sec
```
A couple of interesting variables are `--verbose`, `--output-on-failure`.
# How to add a new test
As of now, there is no dedicated testing directory. Rather, tests are together
with the sources of the corresponding (sub)system. The generic four-step
process is
1. Guard all the following steps with `if(ENABLE_TESTS)`. In a world where OAI
is tested completely, there would be many executables that would be of
tangential interest to the average user only. A "normal" build without tests
would result in less executables, due to this guard.
2. Add an executable that you want to execute. In a `CMakeLists.txt`, do for
instance `add_executable(my_test mytest.c)` where `mytest.c` contains
`main()`. You can then build this executable with `ninja/make my_test`,
given you ran `cmake -DENABLE_TESTS=ON ...` before.
3. Create a dependency to `tests` so that triggering the `tests` (`ninja/make
tests`) target will build your test: `add_dependencies(tests my_test)`.
4. Use `add_test(NAME my_new_test COMMAND my_test <options>)` to declare a new
test that will be run by `ctest` under name `my_new_test`.
In the simplest case, in an existing `CMakeLists.txt`, you might add the
following:
```
if(ENABLE_TESTS)
add_executable(my_test mytest.c)
add_dependencies(tests my_test)
add_test(NAME my_new_test COMMAND my_test) # no options required
endif()
```
Note that this might get more complicated, e.g., typically you will have to
link some library into the executable with `target_link_libraries()`, or pass
some option to the test program.
`ctest` decides if a test passed via the return code of the program. So a test
executable that always passes is `int main() { return 0; }` and one that always
fails `int main() { return 1; }`. It is left as an exercise to the reader to
include these examples into `ctest`. Other programming languages other than C
or shell scripts are possible but discouraged. Obviously, though, a test in
a mainstream non-C programming language/shell script (C++, Rust, Python, Perl)
is preferable over no test.
Let's look at a more concrete, elaborate example, the NR RLC tests.
They are located in `openair2/LAYER2/nr_rlc/tests/`. Note that due to
historical reasons, a test script `run_tests.sh` allows to run all tests from
that directory directly, which you might also use to compare to the
`cmake`/`ctest` implementation.
1. Since the tests are in a sub-directory `tests/`, the inclusion of the entire
directory is guarded in `openair2/LAYER2/nr_rlc/CMakeLists.txt` (in fact, it
might in general be a good idea to create a separate sub-directory
`tests/`!).
2. The NR RLC tests in fact consist of one "test driver program" (`test.c`)
which is compiled with different "test stimuli" into the program. In total,
there are 17 stimuli (`test1.h` to `test17.h`) with corresponding known
"good" outputs after running (in `test1.txt.gz` to `test17.txt.gz`). To
implement this, the `tests/CMakeLists.txt` creates multiple executables
`nr_rlc_test_X` via the loop over `TESTNUM`, links necessary libraries into
the test driver and a compile definition for the test stimuli.
3. For each executable, create a dependency to `tests`.
4. Finally, there is a single(!) `ctest` test that runs all the 17 test
executables at once(!). If you look at the shell script
`exec_nr_rlc_test.sh`, you see that it runs the program, filters for `TEST`,
and compares with a predefined output from each test in `testX.txt.gz`,
which is `gunzip`ed on the fly... Anyway, the actual `add_test()` definition
just tells `ctest` to run this script (in the source directory), and passes
an option where to find the executables (in the build directory). This
slight complication is due to using shell scripts. An easier way is to
directly declare the executable in `add_test()`, and `ctest` will locate and
run the executable properly.

View File

@@ -51,7 +51,6 @@ RUN apt-get update && \
python3 \
python3-six \
python3-requests \
libpython3.8 \
libusb-1.0-0 \
iputils-ping \
iproute2 \

View File

@@ -27,7 +27,6 @@
#include "common/ran_context.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "openair2/F1AP/f1ap_common.h"
#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/GNB_APP/gnb_config.h"
#include "nr_pdcp/nr_pdcp_oai_api.h"
@@ -135,7 +134,6 @@ int main(int argc, char **argv)
rc = itti_create_task(TASK_CUUP_E1, E1AP_CUUP_task, NULL);
AssertFatal(rc >= 0, "Create task for CUUP E1 failed\n");
nr_pdcp_layer_init();
cu_init_f1_ue_data(); // for CU-UP/CP mapping: we use the same
MessageDef *msg = RCconfig_NR_CU_E1(true);
AssertFatal(msg != NULL, "Send init to task for E1AP UP failed\n");
itti_send_msg_to_task(TASK_CUUP_E1, 0, msg);

View File

@@ -777,13 +777,8 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
void *txp[ru->nb_tx];
unsigned int txs;
int i;
T(T_ENB_PHY_OUTPUT_SIGNAL,
T_INT(0),
T_INT(0),
T_INT(frame),
T_INT(slot),
T_INT(0),
T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot, fp, 0)], fp->get_samples_per_slot(slot, fp) * 4));
T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot),
T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp,0)], fp->samples_per_subframe * 4));
int sf_extension = 0;
int siglen=fp->get_samples_per_slot(slot,fp);
radio_tx_burst_flag_t flags_burst = TX_BURST_INVALID;

View File

@@ -88,8 +88,6 @@
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_DISABLETIMECORR "disable UE timing correction\n"
#define CONFIG_HLP_RRC_CFG_PATH "path for RRC configuration\n"
#define CONFIG_HLP_RE_CFG_FILE "filename for reconfig.raw in phy-test mode\n"
#define CONFIG_HLP_RB_CFG_FILE "filename for rbconfig.raw in phy-test mode\n"
#define CONFIG_HLP_UECAP_FILE "path for UE Capabilities file\n"
#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n"

View File

@@ -99,7 +99,8 @@
typedef enum {
pss = 0,
pbch = 1,
si = 2
si = 2,
psbch = 3
} sync_mode_t;
static void *NRUE_phy_stub_standalone_pnf_task(void *arg);
@@ -161,6 +162,9 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
// initialize all signal buffers
init_nr_ue_signal(ue, nb_connected_gNB);
if (ue->sl_mode)
sl_ue_phy_init(ue);
// intialize transport
init_nr_ue_transport(ue);
@@ -306,11 +310,15 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
process_queued_nr_nfapi_msgs(mac, sfn_slot);
}
bool only_dl = false;
if (mac->scc == NULL && mac->scc_SIB == NULL)
only_dl = true;
int CC_id = 0;
uint8_t gNB_id = 0;
nr_uplink_indication_t ul_info;
int slots_per_frame = 20; //30 kHZ subcarrier spacing
int slot_ahead = 2; // TODO: Make this dynamic
int slot_ahead = 3; // TODO: Make this dynamic
ul_info.cc_id = CC_id;
ul_info.gNB_index = gNB_id;
ul_info.module_id = mod_id;
@@ -328,7 +336,10 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
free_and_zero(ch_info);
}
if (is_nr_DL_slot(mac->tdd_UL_DL_ConfigurationCommon,
if (only_dl ||
is_nr_DL_slot(get_softmodem_params()->nsa ?
mac->scc->tdd_UL_DL_ConfigurationCommon :
mac->scc_SIB->tdd_UL_DL_ConfigurationCommon,
ul_info.slot_rx)) {
memset(&mac->dl_info, 0, sizeof(mac->dl_info));
mac->dl_info.cc_id = CC_id;
@@ -343,7 +354,10 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort();
if (is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon,
if (!only_dl &&
is_nr_UL_slot(get_softmodem_params()->nsa ?
mac->scc->tdd_UL_DL_ConfigurationCommon :
mac->scc_SIB->tdd_UL_DL_ConfigurationCommon,
ul_info.slot_tx, mac->frame_type)) {
LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind()\n", ul_info.slot_tx);
nr_ue_ul_scheduler(&ul_info);
@@ -366,11 +380,12 @@ static void UE_synch(void *arg) {
int i, hw_slot_offset;
PHY_VARS_NR_UE *UE = syncD->UE;
sync_mode_t sync_mode = pbch;
if (UE->sl_mode == 2 && !get_nrUE_params()->sync_ref) sync_mode = psbch;
//int CC_id = UE->CC_id;
static int freq_offset=0;
UE->is_synchronized = 0;
if (UE->UE_scan == 0) {
if (UE->UE_scan == 0 && !UE->sl_mode) {
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
@@ -483,6 +498,52 @@ static void UE_synch(void *arg) {
}
break;
case psbch:
LOG_I(PHY, "[UE thread Synch] Running Sidelink Initial Synch \n");
NR_DL_FRAME_PARMS *fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
dl_carrier = fp->sl_CarrierFreq;
ul_carrier = fp->sl_CarrierFreq;
if (sl_nr_slss_search(UE, &syncD->proc, 16) == 0) {
freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
hw_slot_offset = ((UE->rx_offset<<1) / fp->samples_per_subframe * fp->slots_per_subframe) +
round((float)((UE->rx_offset<<1) % fp->samples_per_subframe)/fp->samples_per_slot0);
// rerun with new cell parameters and frequency-offset
// todo: the freq_offset computed on DL shall be scaled before being applied to UL
nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_carrier, dl_carrier, freq_offset);
LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n",
hw_slot_offset,
freq_offset,
openair0_cfg[UE->rf_map.card].rx_gain[0],
openair0_cfg[UE->rf_map.card].rx_freq[0],
openair0_cfg[UE->rf_map.card].tx_freq[0]);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0]);
if (UE->UE_scan_carrier == 1) {
UE->UE_scan_carrier = 0;
} else {
UE->is_synchronized = 1;
}
} else {
if (UE->UE_scan_carrier == 1) {
if (freq_offset >= 0)
freq_offset += 100;
freq_offset *= -1;
nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_carrier, dl_carrier, freq_offset);
LOG_I(PHY, "Sidelink Initial sync failed: trying carrier off %d Hz\n", freq_offset);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0]);
}
}
break;
case si:
default:
break;
@@ -490,15 +551,18 @@ static void UE_synch(void *arg) {
}
}
static void RU_write(nr_rxtx_thread_data_t *rxtxD) {
static void RU_write(nr_rxtx_thread_data_t *rxtxD, int sl_tx_action) {
PHY_VARS_NR_UE *UE = rxtxD->UE;
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
if (UE->sl_mode == 2)
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
void *txp[NB_ANTENNAS_TX];
int slot = proc->nr_slot_tx;
for (int i = 0; i < UE->frame_parms.nb_antennas_tx; i++)
txp[i] = (void *)&UE->common_vars.txData[i][UE->frame_parms.get_samples_slot_timestamp(slot, &UE->frame_parms, 0)];
for (int i=0; i<fp->nb_antennas_tx; i++)
txp[i] = (void *)&UE->common_vars.txData[i][fp->get_samples_slot_timestamp(proc->nr_slot_tx, fp, 0)];
radio_tx_burst_flag_t flags = TX_BURST_INVALID;
@@ -507,16 +571,32 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD) {
openair0_cfg[0].duplex_mode == duplex_mode_TDD &&
!get_softmodem_params()->continuous_tx) {
int slots_frame = UE->frame_parms.slots_per_frame;
int curr_slot = nr_ue_slot_select(&UE->nrUE_config, slot);
if (curr_slot != NR_DOWNLINK_SLOT) {
int next_slot = nr_ue_slot_select(&UE->nrUE_config, (slot + 1) % slots_frame);
int prev_slot = nr_ue_slot_select(&UE->nrUE_config, (slot + slots_frame - 1) % slots_frame);
if (prev_slot == NR_DOWNLINK_SLOT)
//Perform USRP write only in case SL Txn needs to be done.
if (UE->sl_mode == 2) {
flags = sl_tx_action ? TX_BURST_START_AND_END
: TX_BURST_INVALID;
} else {
uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots;
int nrofUplinkSlots, nrofUplinkSymbols;
if (mac->scc) {
nrofUplinkSlots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
nrofUplinkSymbols = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols;
}
else {
nrofUplinkSlots = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
nrofUplinkSymbols = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols;
}
int slot_tx_usrp = proc->nr_slot_tx;
uint8_t num_UL_slots = nrofUplinkSlots + (nrofUplinkSymbols != 0);
uint8_t first_tx_slot = tdd_period - num_UL_slots;
if (slot_tx_usrp % tdd_period == first_tx_slot)
flags = TX_BURST_START;
else if (next_slot == NR_DOWNLINK_SLOT)
else if (slot_tx_usrp % tdd_period == first_tx_slot + num_UL_slots - 1)
flags = TX_BURST_END;
else
else if (slot_tx_usrp % tdd_period > first_tx_slot)
flags = TX_BURST_MIDDLE;
}
} else {
@@ -529,10 +609,10 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD) {
proc->timestamp_tx,
txp,
rxtxD->writeBlockSize,
UE->frame_parms.nb_antennas_tx,
fp->nb_antennas_tx,
flags),"");
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
for (int i=0; i<fp->nb_antennas_tx; i++)
memset(txp[i], 0, rxtxD->writeBlockSize);
}
@@ -543,45 +623,77 @@ void processSlotTX(void *arg) {
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
nr_phy_data_tx_t phy_data = {0};
int sl_tx_action = 0;
LOG_D(PHY,"%d.%d => slot type %d\n", proc->frame_tx, proc->nr_slot_tx, proc->tx_slot_type);
if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT){
// wait for rx slots to send indication (if any) that DLSCH decoding is finished
for(int i=0; i < rxtxD->tx_wait_for_dlsch; i++) {
notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo[proc->nr_slot_tx]);
delNotifiedFIFO_elt(res);
}
if (proc->tx_slot_type == NR_SIDELINK_SLOT && UE->sl_mode == 2) {
// trigger L2 to run ue_scheduler thru IF module
// [TODO] mapping right after NR initial sync
if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
// trigger L2 to run ue_scheduler thru IF module
if(UE->if_inst != NULL && UE->if_inst->sl_indication != NULL) {
start_meas(&UE->ue_ul_indication_stats);
nr_uplink_indication_t ul_indication;
memset((void*)&ul_indication, 0, sizeof(ul_indication));
nr_sidelink_indication_t sl_indication;
memset((void*)&sl_indication, 0, sizeof(sl_indication));
ul_indication.module_id = UE->Mod_id;
ul_indication.gNB_index = proc->gNB_id;
ul_indication.cc_id = UE->CC_id;
ul_indication.frame_rx = proc->frame_rx;
ul_indication.slot_rx = proc->nr_slot_rx;
ul_indication.frame_tx = proc->frame_tx;
ul_indication.slot_tx = proc->nr_slot_tx;
ul_indication.phy_data = &phy_data;
sl_indication.module_id = UE->Mod_id;
sl_indication.gNB_index = proc->gNB_id;
sl_indication.cc_id = UE->CC_id;
sl_indication.frame_rx = proc->frame_rx;
sl_indication.slot_rx = proc->nr_slot_rx;
sl_indication.frame_tx = proc->frame_tx;
sl_indication.slot_tx = proc->nr_slot_tx;
sl_indication.phy_data = &phy_data;
sl_indication.slot_type = SIDELINK_SLOT_TYPE_TX;
LOG_D(NR_PHY,"Sending SL indication RX %d.%d TX %d.%d\n",proc->frame_rx,proc->nr_slot_rx,proc->frame_tx,proc->nr_slot_tx);
UE->if_inst->sl_indication(&sl_indication);
UE->if_inst->ul_indication(&ul_indication);
stop_meas(&UE->ue_ul_indication_stats);
}
phy_procedures_nrUE_TX(UE, proc, &phy_data);
sl_tx_action = phy_procedures_nrUE_SL_TX(UE, proc, &phy_data);
} else {
if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT){
// wait for rx slots to send indication (if any) that DLSCH decoding is finished
for(int i=0; i < rxtxD->tx_wait_for_dlsch; i++) {
notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo[proc->nr_slot_tx]);
delNotifiedFIFO_elt(res);
}
// trigger L2 to run ue_scheduler thru IF module
// [TODO] mapping right after NR initial sync
if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
start_meas(&UE->ue_ul_indication_stats);
nr_uplink_indication_t ul_indication;
memset((void*)&ul_indication, 0, sizeof(ul_indication));
ul_indication.module_id = UE->Mod_id;
ul_indication.gNB_index = proc->gNB_id;
ul_indication.cc_id = UE->CC_id;
ul_indication.frame_rx = proc->frame_rx;
ul_indication.slot_rx = proc->nr_slot_rx;
ul_indication.frame_tx = proc->frame_tx;
ul_indication.slot_tx = proc->nr_slot_tx;
ul_indication.phy_data = &phy_data;
UE->if_inst->ul_indication(&ul_indication);
stop_meas(&UE->ue_ul_indication_stats);
}
phy_procedures_nrUE_TX(UE, proc, &phy_data);
}
}
RU_write(rxtxD);
RU_write(rxtxD, sl_tx_action);
}
nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc)
{
nr_phy_data_t phy_data = {0};
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
if (UE->sl_mode == 2)
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) {
@@ -596,34 +708,48 @@ nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc)
}
/* send tick to RLC and PDCP every ms */
if (proc->nr_slot_rx % UE->frame_parms.slots_per_subframe == 0) {
if (proc->nr_slot_rx % fp->slots_per_subframe == 0) {
void nr_rlc_tick(int frame, int subframe);
void nr_pdcp_tick(int frame, int subframe);
nr_rlc_tick(proc->frame_rx, proc->nr_slot_rx / UE->frame_parms.slots_per_subframe);
nr_pdcp_tick(proc->frame_rx, proc->nr_slot_rx / UE->frame_parms.slots_per_subframe);
nr_rlc_tick(proc->frame_rx, proc->nr_slot_rx / fp->slots_per_subframe);
nr_pdcp_tick(proc->frame_rx, proc->nr_slot_rx / fp->slots_per_subframe);
}
}
if (proc->rx_slot_type == NR_DOWNLINK_SLOT || proc->rx_slot_type == NR_MIXED_SLOT) {
if (UE->sl_mode == 2) {
if (proc->rx_slot_type == NR_SIDELINK_SLOT) {
if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) {
nr_downlink_indication_t dl_indication;
nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, &phy_data);
UE->if_inst->dl_indication(&dl_indication);
if(UE->if_inst != NULL && UE->if_inst->sl_indication != NULL) {
nr_sidelink_indication_t sl_indication;
nr_fill_sl_indication(&sl_indication, NULL, NULL, proc, UE, &phy_data);
UE->if_inst->sl_indication(&sl_indication);
}
uint64_t a=rdtsc_oai();
psbch_pscch_pssch_processing(UE, proc, &phy_data);
LOG_D(PHY, "In %s: slot %d:%d, time %llu\n", __FUNCTION__, proc->frame_rx, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
}
} else {
if (proc->rx_slot_type == NR_DOWNLINK_SLOT || proc->rx_slot_type == NR_MIXED_SLOT){
if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) {
nr_downlink_indication_t dl_indication;
nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, &phy_data);
UE->if_inst->dl_indication(&dl_indication);
}
uint64_t a=rdtsc_oai();
pbch_pdcch_processing(UE, proc, &phy_data);
if (phy_data.dlsch[0].active) {
// indicate to tx thread to wait for DLSCH decoding
const int ack_nack_slot = (proc->nr_slot_rx + phy_data.dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame;
UE->tx_wait_for_dlsch[ack_nack_slot]++;
}
LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
}
uint64_t a=rdtsc_oai();
pbch_pdcch_processing(UE, proc, &phy_data);
if (phy_data.dlsch[0].active) {
// indicate to tx thread to wait for DLSCH decoding
const int ack_nack_slot = (proc->nr_slot_rx + phy_data.dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame;
UE->tx_wait_for_dlsch[ack_nack_slot]++;
}
LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx);
}
ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx);
return phy_data;
}
@@ -633,14 +759,20 @@ void UE_dl_processing(void *arg) {
PHY_VARS_NR_UE *UE = rxtxD->UE;
nr_phy_data_t *phy_data = &rxtxD->phy_data;
pdsch_processing(UE, proc, phy_data);
if (UE->sl_mode == 0)
pdsch_processing(UE, proc, phy_data);
}
void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
int16_t dummy_tx_data[UE->frame_parms.nb_antennas_tx][2*writeBlockSize]; // 2 because the function we call use pairs of int16_t implicitly as complex numbers
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
if (UE->sl_mode == 2)
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
void *dummy_tx[fp->nb_antennas_tx];
int16_t dummy_tx_data[fp->nb_antennas_tx][2*writeBlockSize]; // 2 because the function we call use pairs of int16_t implicitly as complex numbers
memset(dummy_tx_data, 0, sizeof(dummy_tx_data));
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
for (int i=0; i<fp->nb_antennas_tx; i++)
dummy_tx[i]=dummy_tx_data[i];
AssertFatal( writeBlockSize ==
@@ -648,37 +780,45 @@ void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockS
timestamp,
dummy_tx,
writeBlockSize,
UE->frame_parms.nb_antennas_tx,
fp->nb_antennas_tx,
4),"");
}
void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash) {
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
int num_frames = 2;
//In Sidelink worst case SL-SSB can be sent once in 16 frames
if (UE->sl_mode == 2) {
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
num_frames = SL_NR_PSBCH_REPETITION_IN_FRAMES;
}
void *rxp[NB_ANTENNAS_RX];
for(int x=0; x<20; x++) { // two frames for initial sync
for (int slot=0; slot<UE->frame_parms.slots_per_subframe; slot ++ ) {
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) {
for(int x=0; x< num_frames*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; x++) { // two frames for initial sync
for (int slot=0; slot<fp->slots_per_subframe; slot ++ ) {
for (int i=0; i<fp->nb_antennas_rx; i++) {
if (toTrash)
rxp[i]=malloc16(UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms)*4);
rxp[i]=malloc16(fp->get_samples_per_slot(slot,fp)*4);
else
rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) +
4*((x*UE->frame_parms.samples_per_subframe)+
UE->frame_parms.get_samples_slot_timestamp(slot,&UE->frame_parms,0));
4*((x*fp->samples_per_subframe)+
fp->get_samples_slot_timestamp(slot,fp,0));
}
AssertFatal( UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms) ==
AssertFatal( fp->get_samples_per_slot(slot,fp) ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
rxp,
UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms),
UE->frame_parms.nb_antennas_rx), "");
fp->get_samples_per_slot(slot,fp),
fp->nb_antennas_rx), "");
if (IS_SOFTMODEM_RFSIM)
dummyWrite(UE,*timestamp, UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms));
dummyWrite(UE,*timestamp, fp->get_samples_per_slot(slot,fp));
if (toTrash)
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
for (int i=0; i<fp->nb_antennas_rx; i++)
free(rxp[i]);
}
}
@@ -689,21 +829,25 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset);
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
if (UE->sl_mode == 2)
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// Resynchonize by slot (will work with numerology 1 only)
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe/2 ) {
int unitTransfer=size>UE->frame_parms.samples_per_subframe/2 ? UE->frame_parms.samples_per_subframe/2 : size ;
for ( int size=UE->rx_offset ; size > 0 ; size -= fp->samples_per_subframe/2 ) {
int unitTransfer=size>fp->samples_per_subframe/2 ? fp->samples_per_subframe/2 : size ;
AssertFatal(unitTransfer ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
(void **)UE->common_vars.rxdata,
unitTransfer,
UE->frame_parms.nb_antennas_rx),"");
fp->nb_antennas_rx),"");
}
} else {
*timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms);
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
*timestamp += fp->get_samples_per_slot(1,fp);
for ( int size=UE->rx_offset ; size > 0 ; size -= fp->samples_per_subframe ) {
int unitTransfer=size>fp->samples_per_subframe ? fp->samples_per_subframe : size ;
// we write before read because gNB waits for UE to write and both executions halt
// this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer);
@@ -712,7 +856,7 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
timestamp,
(void **)UE->common_vars.rxdata,
unitTransfer,
UE->frame_parms.nb_antennas_rx),"");
fp->nb_antennas_rx),"");
*timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write
}
}
@@ -743,6 +887,14 @@ void *UE_thread(void *arg)
void *rxp[NB_ANTENNAS_RX];
int start_rx_stream = 0;
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
sl_nr_phy_config_request_t *sl_cfg = NULL;
int is_sidelink = (UE->sl_mode == 2) ? 1 : 0;
if (is_sidelink) {
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
sl_cfg = &UE->SL_UE_PHY_PARAMS.sl_config;
openair0_cfg[0].gpio_controller = RU_GPIO_CONTROL_GENERIC;
}
AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), "");
UE->rfdevice.host_type = RAU_HOST;
UE->is_synchronized = 0;
@@ -761,7 +913,7 @@ void *UE_thread(void *arg)
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
bool syncRunning=false;
const int nb_slot_frame = UE->frame_parms.slots_per_frame;
const int nb_slot_frame = fp->slots_per_frame;
int absolute_slot=0, decoded_frame_rx=INT_MAX, trashed_frames=0;
initNotifiedFIFO(&UE->phy_config_ind);
@@ -772,6 +924,12 @@ void *UE_thread(void *arg)
initNotifiedFIFO(UE->tx_resume_ind_fifo[i]);
}
if (get_nrUE_params()->sync_ref &&
UE->sl_mode == 2) {
UE->is_synchronized = 1;
start_rx_stream = -1;
}
while (!oai_exit) {
if (syncRunning) {
@@ -780,7 +938,8 @@ void *UE_thread(void *arg)
if (res) {
syncRunning=false;
if (UE->is_synchronized) {
decoded_frame_rx = mac->mib_frame;
if (UE->sl_mode == 2) decoded_frame_rx = UE->SL_UE_PHY_PARAMS.sync_params.DFN;
else decoded_frame_rx = mac->mib_frame;
LOG_I(PHY,"UE synchronized decoded_frame_rx=%d UE->init_sync_frame=%d trashed_frames=%d\n",
decoded_frame_rx,
UE->init_sync_frame,
@@ -799,7 +958,7 @@ void *UE_thread(void *arg)
}
} else {
readFrame(UE, &timestamp, true);
trashed_frames+=2;
trashed_frames+=((UE->sl_mode)?SL_NR_PSBCH_REPETITION_IN_FRAMES:2);
}
continue;
}
@@ -825,21 +984,25 @@ void *UE_thread(void *arg)
UE->rx_offset=0;
UE->time_sync_cell=0;
// read in first symbol
AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
AssertFatal (fp->ofdm_symbol_size+fp->nb_prefix_samples0 ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void **)UE->common_vars.rxdata,
UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
UE->frame_parms.nb_antennas_rx),"");
fp->ofdm_symbol_size+fp->nb_prefix_samples0,
fp->nb_antennas_rx),"");
// we have the decoded frame index in the return of the synch process
// and we shifted above to the first slot of next frame
decoded_frame_rx++;
// we do ++ first in the regular processing, so it will be begin of frame;
absolute_slot = decoded_frame_rx * nb_slot_frame - 1;
if (UE->sl_mode == 2) {
//Set to the slot where the SL-SSB was decoded
absolute_slot += UE->SL_UE_PHY_PARAMS.sync_params.slot_offset;
}
continue;
}
absolute_slot++;
int slot_nr = absolute_slot % nb_slot_frame;
@@ -850,24 +1013,30 @@ void *UE_thread(void *arg)
curMsg.proc.nr_slot_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame;
curMsg.proc.frame_rx = (absolute_slot / nb_slot_frame) % MAX_FRAME_NUMBER;
curMsg.proc.frame_tx = ((absolute_slot + DURATION_RX_TO_TX) / nb_slot_frame) % MAX_FRAME_NUMBER;
if (mac->phy_config_request_sent) {
curMsg.proc.rx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.nr_slot_rx);
curMsg.proc.tx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.nr_slot_tx);
if (UE->phy_config_request_sent) {
if (is_sidelink) {
curMsg.proc.rx_slot_type = sl_nr_ue_slot_select(sl_cfg, curMsg.proc.frame_rx, curMsg.proc.nr_slot_rx, TDD);
curMsg.proc.tx_slot_type = sl_nr_ue_slot_select(sl_cfg, curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx, TDD);
LOG_D(NR_PHY,"Setting SL slot type to TX %d.%d %d, RX %d.%d %d\n",curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx,curMsg.proc.tx_slot_type,curMsg.proc.frame_rx, curMsg.proc.nr_slot_rx,curMsg.proc.rx_slot_type);
} else {
curMsg.proc.rx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.frame_rx, curMsg.proc.nr_slot_rx);
curMsg.proc.tx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx);
}
}
else {
curMsg.proc.rx_slot_type = NR_DOWNLINK_SLOT;
curMsg.proc.tx_slot_type = NR_DOWNLINK_SLOT;
}
int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms);
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
int firstSymSamp = get_firstSymSamp(slot_nr, fp);
for (int i=0; i<fp->nb_antennas_rx; i++)
rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp+
UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)];
fp->get_samples_slot_timestamp(slot_nr,fp,0)];
int readBlockSize, writeBlockSize;
readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms);
writeBlockSize = UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms);
readBlockSize = get_readBlockSize(slot_nr, fp);
writeBlockSize = fp->get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, fp);
if (UE->apply_timing_offset && (slot_nr == nb_slot_frame - 1)) {
const int sampShift = -(UE->rx_offset>>1);
readBlockSize -= sampShift;
@@ -880,11 +1049,11 @@ void *UE_thread(void *arg)
&timestamp,
rxp,
readBlockSize,
UE->frame_parms.nb_antennas_rx),"");
fp->nb_antennas_rx),"");
if(slot_nr == (nb_slot_frame - 1)) {
// read in first symbol of next frame and adjust for timing drift
int first_symbols = UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0; // first symbol of every frames
int first_symbols = fp->ofdm_symbol_size + fp->nb_prefix_samples0; // first symbol of every frames
if (first_symbols > 0) {
openair0_timestamp ignore_timestamp;
@@ -893,14 +1062,14 @@ void *UE_thread(void *arg)
&ignore_timestamp,
(void **)UE->common_vars.rxdata,
first_symbols,
UE->frame_parms.nb_antennas_rx),"");
fp->nb_antennas_rx),"");
} else
LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
}
// use previous timing_advance value to compute writeTimestamp
writeTimestamp = timestamp +
UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX)
fp->get_samples_slot_timestamp(slot_nr,fp,DURATION_RX_TO_TX)
- firstSymSamp - openair0_cfg[0].tx_sample_advance -
UE->N_TA_offset - timing_advance;
@@ -910,8 +1079,7 @@ void *UE_thread(void *arg)
timing_advance = UE->timing_advance;
}
if (curMsg.proc.nr_slot_tx == 0)
nr_ue_rrc_timer_trigger(UE->Mod_id, curMsg.proc.frame_tx, curMsg.proc.gNB_id);
nr_ue_rrc_timer_trigger(UE->Mod_id, curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx, curMsg.proc.gNB_id);
// Start TX slot processing here. It runs in parallel with RX slot processing
notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, &txFifo, processSlotTX);
@@ -944,17 +1112,21 @@ void *UE_thread(void *arg)
return NULL;
}
void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconfig_file)
{
void init_NR_UE(int nb_inst,
char* uecap_file,
char* rrc_config_path) {
int inst;
NR_UE_MAC_INST_t *mac_inst;
NR_UE_RRC_INST_t* rrc_inst;
for (inst=0; inst < nb_inst; inst++) {
AssertFatal((rrc_inst = nr_l3_init_ue(uecap_file, reconfig_file, rbconfig_file)) != NULL, "can not initialize RRC module\n");
AssertFatal((rrc_inst = nr_l3_init_ue(uecap_file,rrc_config_path)) != NULL, "can not initialize RRC module\n");
AssertFatal((mac_inst = nr_l2_init_ue(rrc_inst)) != NULL, "can not initialize L2 module\n");
AssertFatal((mac_inst->if_module = nr_ue_if_module_init(inst)) != NULL, "can not initialize IF module\n");
}
if (get_softmodem_params()->sl_mode) {
configure_NR_SL_Preconfig(0, get_nrUE_params()->sync_ref);
}
}
void init_NR_UE_threads(int nb_inst) {

View File

@@ -86,6 +86,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "nr_nas_msg_sim.h"
#include <openair1/PHY/MODULATION/nr_modulation.h>
#include "openair2/GNB_APP/gnb_paramdef.h"
#include "openair2/RRC/NR_UE/sl_preconfig_paramvalues.h"
extern const char *duplex_mode[];
THREAD_STRUCT thread_struct;
@@ -123,8 +124,6 @@ char *usrp_args = NULL;
char *tx_subdev = NULL;
char *rx_subdev = NULL;
char *rrc_config_path = NULL;
char *reconfig_file = NULL;
char *rbconfig_file = NULL;
char *uecap_file = NULL;
int dumpframe = 0;
@@ -264,8 +263,6 @@ static void get_options(void) {
int numparams = sizeof(cmdline_params)/sizeof(paramdef_t);
config_get(cmdline_params,numparams,NULL);
AssertFatal(rrc_config_path == NULL, "the option \"rrc_config_path\" is deprecated. Please use --reconfig-file and --rbconfig-file separately to point to files reconfig.raw and rbconfig.raw\n");
if (vcdflag > 0)
ouput_vcd = 1;
}
@@ -316,16 +313,18 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
}
void init_openair0(void) {
void init_openair0(bool is_sidelink) {
int card;
int freq_off = 0;
NR_DL_FRAME_PARMS *frame_parms = &PHY_vars_UE_g[0][0]->frame_parms;
if (is_sidelink)
frame_parms = &PHY_vars_UE_g[0][0]->SL_UE_PHY_PARAMS.sl_frame_params;
for (card=0; card<MAX_CARDS; card++) {
uint64_t dl_carrier, ul_carrier, sl_carrier;
uint64_t dl_carrier, ul_carrier;
openair0_cfg[card].configFilename = NULL;
openair0_cfg[card].threequarter_fs = frame_parms->threequarter_fs;
openair0_cfg[card].sample_rate = frame_parms->samples_per_subframe * 1e3;
openair0_cfg[card].sample_rate = IS_SOFTMODEM_RFSIM ? frame_parms->samples_per_subframe * 1e3 : 46080000;
openair0_cfg[card].samples_per_frame = frame_parms->samples_per_frame;
if (frame_parms->frame_type==TDD)
@@ -348,15 +347,14 @@ void init_openair0(void) {
openair0_cfg[card].rx_num_channels,
duplex_mode[openair0_cfg[card].duplex_mode]);
nr_get_carrier_frequencies(PHY_vars_UE_g[0][0], &dl_carrier, &ul_carrier);
if (is_sidelink) {
dl_carrier = frame_parms->dl_CarrierFreq;
ul_carrier = frame_parms->ul_CarrierFreq;
} else
nr_get_carrier_frequencies(PHY_vars_UE_g[0][0], &dl_carrier, &ul_carrier);
nr_rf_card_config_freq(&openair0_cfg[card], ul_carrier, dl_carrier, freq_off);
if (get_softmodem_params()->sl_mode == 2) {
nr_get_carrier_frequencies_sl(PHY_vars_UE_g[0][0], &sl_carrier);
nr_rf_card_config_freq(&openair0_cfg[card], sl_carrier, sl_carrier, freq_off);
}
nr_rf_card_config_gain(&openair0_cfg[card], rx_gain_off);
openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file;
@@ -476,17 +474,28 @@ int main( int argc, char **argv ) {
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
init_NR_UE(1, uecap_file, reconfig_file, rbconfig_file);
init_NR_UE(1,uecap_file,rrc_config_path);
int mode_offset = get_softmodem_params()->nsa ? NUMBER_OF_UE_MAX : 1;
uint16_t node_number = get_softmodem_params()->node_number;
ue_id_g = (node_number == 0) ? 0 : node_number - 2;
AssertFatal(ue_id_g >= 0, "UE id is expected to be nonnegative.\n");
ueinfo_t ueinfo;
char aprefix[MAX_OPTNAME_SIZE*2 + 8];
paramdef_t SL_UEINFO[] = SL_UEINFO_DESC(ueinfo);
paramlist_def_t SL_UEINFOList = {SL_CONFIG_STRING_UEINFO, NULL, 0};
sprintf(aprefix, "%s.[%d]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0);
config_getlist(&SL_UEINFOList, NULL, 0, aprefix);
sprintf(aprefix, "%s.[%i].%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0, SL_CONFIG_STRING_UEINFO, 0);
config_get(SL_UEINFO, sizeof(SL_UEINFO)/sizeof(paramdef_t), aprefix);
if(IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa || get_softmodem_params()->nsa) {
if(node_number == 0) {
if(node_number == 0 && get_softmodem_params()->sl_mode == 0) {
init_pdcp(0);
}
else {
} else if (get_softmodem_params()->sl_mode == 2) {
init_pdcp(1+ueinfo.srcid);
} else {
init_pdcp(mode_offset + ue_id_g);
}
}
@@ -526,19 +535,34 @@ int main( int argc, char **argv ) {
get_softmodem_params()->numerology,
nr_band);
}
else{
else if (get_softmodem_params()->sl_mode != 2){
DevAssert(mac->if_module != NULL && mac->if_module->phy_config_request != NULL);
mac->if_module->phy_config_request(&mac->phy_config);
mac->phy_config_request_sent = true;
fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config;
nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, mac->nr_band);
nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config,
*mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]);
}
UE[CC_id]->sl_mode = get_softmodem_params()->sl_mode;
if (UE[CC_id]->sl_mode) {
AssertFatal(UE[CC_id]->sl_mode == 2, "Only Sidelink mode 2 supported. Mode 1 not yet supported\n");
nr_UE_configure_Sidelink(0, get_nrUE_params()->sync_ref, &ueinfo);
DevAssert(mac->if_module != NULL && mac->if_module->sl_phy_config_request != NULL);
sl_nr_ue_phy_params_t *sl_phy = &UE[CC_id]->SL_UE_PHY_PARAMS;
mac->if_module->sl_phy_config_request(&mac->SL_MAC_PARAMS->sl_phy_config);
nr_init_frame_parms_ue_sl(&sl_phy->sl_frame_params,&sl_phy->sl_config,
get_nrUE_params()->threequarter_fs,
get_nrUE_params()->ofdm_offset_divisor);
}
init_nr_ue_vars(UE[CC_id], 0, abstraction_flag);
}
init_openair0();
bool is_sl = (get_softmodem_params()->sl_mode) ? 1 : 0;
init_openair0(is_sl);
// init UE_PF_PO and mutex lock
pthread_mutex_init(&ue_pf_po_mutex, NULL);
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);

View File

@@ -5,13 +5,18 @@
#include "PHY/defs_nr_UE.h"
#include "SIMULATION/ETH_TRANSPORT/proto.h"
typedef struct ueinfo {
int srcid;
int thirdOctet;
int fourthOctet;
} ueinfo_t;
#define CONFIG_HLP_IF_FREQ "IF frequency for RF, if needed\n"
#define CONFIG_HLP_IF_FREQ_OFF "UL IF frequency offset for RF, if needed\n"
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n"
#define CONFIG_HLP_OFFSET_DIV "Divisor for computing OFDM symbol offset in Rx chain (num samples in CP/<the value>). Default value is 8. To set the sample offset to 0, set this value ~ 10e6\n"
#define CONFIG_HLP_MAX_LDPC_ITERATIONS "Maximum LDPC decoder iterations\n"
#define CONFIG_HLP_SL_SYNCSOURCEUE "Sidelink UE acts as SYNC REF UE"
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
when calling config_get or config_getlist functions */
@@ -36,13 +41,11 @@
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, .iptr=&single_thread_flag, .defintval=1, TYPE_INT, 0}, \
{"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \
{"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, .uptr=&nrUE_params.ofdm_offset_divisor, .defuintval=8, TYPE_UINT32, 0}, \
{"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, .iptr=&nrUE_params.max_ldpc_iterations, .defuintval=5, TYPE_UINT8, 0}, \
{"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, .iptr=&nrUE_params.max_ldpc_iterations, .defuintval=5, TYPE_UINT8, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, .iptr=(int32_t *)&nr_dlsch_demod_shift, .defintval=0, TYPE_INT, 0}, \
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, .iptr=&vcdflag, .defintval=0, TYPE_INT, 0}, \
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, .strptr=&uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \
{"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH, 0, .strptr=&rrc_config_path, .defstrval=NULL, TYPE_STRING, 0}, \
{"reconfig-file", CONFIG_HLP_RE_CFG_FILE, 0, .strptr=&reconfig_file, .defstrval="./reconfig.raw", TYPE_STRING, 0}, \
{"rbconfig-file", CONFIG_HLP_RB_CFG_FILE, 0, .strptr=&rbconfig_file, .defstrval="./rbconfig.raw", TYPE_STRING, 0}, \
{"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH, 0, .strptr=&rrc_config_path, .defstrval="./", TYPE_STRING, 0}, \
{"ue-idx-standalone", NULL, 0, .u16ptr=&ue_idx_standalone, .defuintval=0xFFFF, TYPE_UINT16, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, .dblptr=&(rx_gain[0][0]), .defdblval=110, TYPE_DOUBLE, 0}, \
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, .dblptr=&rx_gain_off, .defdblval=0, TYPE_DOUBLE, 0}, \
@@ -63,6 +66,7 @@
{"chest-time", CONFIG_HLP_CHESTTIME, 0, .iptr=&(nrUE_params.chest_time), .defintval=0, TYPE_INT, 0}, \
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, .iptr=&(nrUE_params.no_timing_correction), .defintval=0, TYPE_INT, 0}, \
{"SLC", CONFIG_HLP_SLF, 0, .u64ptr=&(sidelink_frequency[0][0]), .defuintval=2600000000,TYPE_UINT64,0}, \
{"sync-ref", CONFIG_HLP_SL_SYNCSOURCEUE, PARAMFLAG_BOOL, .uptr=&(nrUE_params.sync_ref), .defuintval=0, TYPE_UINT32, 0}, \
}
// clang-format on
@@ -84,6 +88,7 @@ typedef struct {
int threequarter_fs;
int N_RB_DL;
int ssb_start_subcarrier;
uint32_t sync_ref;
} nrUE_params_t;
extern uint64_t get_nrUE_optmask(void);
extern uint64_t set_nrUE_optmask(uint64_t bitmask);
@@ -93,7 +98,7 @@ extern nrUE_params_t *get_nrUE_params(void);
// In nr-ue.c
extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
extern void fill_ue_band_info(void);
extern void init_NR_UE(int, char *, char *, char *);
extern void init_NR_UE(int, char*, char*);
extern void init_NR_UE_threads(int);
extern void reset_opp_meas(void);
extern void print_opp_meas(void);

View File

@@ -636,12 +636,13 @@ typedef struct
typedef struct
{
fapi_nr_max_num_of_symbol_per_slot_t *max_num_of_symbol_per_slot_list;
fapi_nr_max_num_of_symbol_per_slot_t* max_num_of_symbol_per_slot_list;
} fapi_nr_max_tdd_periodicity_t;
typedef struct
{
uint8_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10 8: ms3 9: ms4
uint8_t tdd_period_in_slots;
fapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list;
@@ -682,8 +683,7 @@ typedef struct {
fapi_nr_cell_config_t cell_config;
fapi_nr_ssb_config_t ssb_config;
fapi_nr_ssb_table_t ssb_table;
fapi_nr_tdd_table_t tdd_table_1;
fapi_nr_tdd_table_t *tdd_table_2;
fapi_nr_tdd_table_t tdd_table;
fapi_nr_prach_config_t prach_config;
} fapi_nr_config_request_t;

View File

@@ -942,6 +942,7 @@ typedef struct
uint16_t scramb_id; // ScramblingID of the CSI-RS [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->1023
uint8_t power_control_offset; // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS
uint8_t power_control_offset_ss; // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS
uint8_t measurement_bitmap;
} nfapi_nr_dl_tti_csi_rs_pdu_rel15_t;

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